0

I'm working on a project that makes it possible to draw objects on a map in c#. We make use of our own created True Typed Font (.ttf). The reason we do this is because users must be able to specify their own icons for objects if they want.

The font (letter) I'm currently drawing is a outlined map-marker as you can see in the image

Map markesr

The numbers are drawn later, but as you can see this isn't clear enough because of the background.

What I now want to do is to fill the marker white, instead of being transparent.

I draw the marker the following way:

GraphicsPath p = new GraphicsPath();
p.AddString(MarkerSymbol, markerFont.FontFamily, (int)markerFont.Style, symbolSize.Height * 0.9f, CorrectedSymbolLocation, stringFormat);
graphics.FillPath(brush, p);

I've already tried some things, like:

Region region = new Region(p);
graphics.FillRegion(new SolidBrush(Color.White), region);

I searched on the internet and I found a page mentioning a function: graphicsPath.Outline() (so in my case p.Outline()), but C# doesn't recognize this function.

Can someone tell me if it's possible what I want to try to reach, and if so, how I can achieve this?

Community
  • 1
  • 1
Vincent Hogendoorn
  • 700
  • 1
  • 7
  • 23
  • 2
    The Graphics.Clip property is a Region. You can create a Region from a GraphicsPath. Which lets you create effects [like this](https://msdn.microsoft.com/en-us/library/windows/desktop/dd183441%28v=vs.85%29.aspx). – Hans Passant Aug 27 '15 at 15:58
  • 1
    @Hans: Well, that's what he already did, but not what he wants.. He wants to fill the inner space of letters, like the interior of a letter 'O', not the stroke. – TaW Aug 27 '15 at 17:48
  • He's assuming custom letter shapes. An interior of course doesn't have to be a problem. – Hans Passant Aug 27 '15 at 17:50
  • How would you fill the letter C, X, 8, or %? – Moby Disk Aug 27 '15 at 21:19
  • 1
    Given the complete confusion about this "feature", the odds that a client will figure out how to create a property TrueType glyph are null. You avoid that NRE by letting him configure a bitmap or icon for a marker. Everybody knows how to do that, not stuck with monochrome output, no wrangling any font foundries, trivially solves your problem as well. The astronaut architect needs to be bypassed. – Hans Passant Aug 27 '15 at 22:48
  • @HansPassant, what you suggest I don't want to achieve. If you got for example the letter P, I want to fill the interior of the P. They are all unicode characters, so the user only have to define the unicode to draw the icons. The reason this must be possible in the application is because their can be different types of objects (for example hospitals, movie theatres). – Vincent Hogendoorn Aug 28 '15 at 07:22

2 Answers2

1

I finally found a solution, thanks to a blogpost found Here!

Instead of creating a bitmap, I create, as suggeste in the blog, a GraphicsPathIterator.

Instead of only creating the path and fill the path (as the code said in the question), I now add the GraphicsPathIterator.

GraphicsPath p = new GraphicsPath();
p.AddString(MarkerSymbol, markerFont.FontFamily, (int)markerFont.Style, symbolSize.Height * 0.9f, CorrectedSymbolLocation, stringFormat);

var iter = new GraphicsPathIterator(p);
while (true)
{
    var subPath = new GraphicsPath();
    bool isClosed;
    if (iter.NextSubpath(subPath, out isClosed) == 0) break;
    Region region = new Region(subPath);
    graphics.FillRegion(new SolidBrush(Color.White), region);
}
graphics.FillPath(brush, p);
Vincent Hogendoorn
  • 700
  • 1
  • 7
  • 23
0

One possible workaround is to

1 - create a Bitmap of the right size

2 - DrawString onto it

3 - use a floodfill to fill the interior.

Then use DrawImage instead of DrawString.

You will have to repeat this for each change in the FontSize or collect the Bitmaps..

I'm not sure how well this (or any other solution I can think of) would work with arbitrary font glyphs. Especially when they are open there is no clear definition of what you would want to see..

For each character you will need one or more points that sit in the interior(s).

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111