tags:

views:

130

answers:

2

I'm using gdiplus to "stroke" a textout. In certain circumstances, we see a "spike" appearing on the top or bottom of the graphic, and I'm not really sure why. We can minimize this by adjusting stroke width and font size, but thats not a good solution. I'm hoping someone can explain the problem to me.

Spikey Bug

And the code sample generating this 4, its outline, and the spike (unintentional)

GraphicsPath path(FillModeWinding);   

      path.AddString(text,wcslen(text),&fontFamily,StateInfo.TheFont.TheWeight,(REAL)minSize,PointF((REAL)ptStart.x, (REAL)ptStart.y),&sf);
      // Draw the outline first
      if (StateInfo.StrokeWidth > 0) {
        Gdiplus::Color strokecolor(GetRValue(StateInfo.StrokeColor), GetGValue(StateInfo.StrokeColor), GetBValue(StateInfo.StrokeColor));
        Pen pen(strokecolor,(REAL)StateInfo.StrokeWidth);      
        graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
        graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality);
        graphics.DrawPath(&pen, &path);
        }
      // Draw the text by filling the path        
      graphics.FillPath(&solidBrush, &path);
+2  A: 

I agree that the fill mode isn't the issue, I think it is just the pen width used for drawing the outline. For characters that have enclosed spaces with pointy corners (like 4 and 'A'), as the pen width used for drawing the outline gets bigger, the size of the inner shape (the little triangle in the case of the four) gets bigger too.

Eventually the inner shape will get too big to be contained by the outer shape, and will start to poke through, resulting in the artifact you see.

Here is an illustration of a fixed font size (the Impact font again) as the outline width gets bigger. There is no fill here, just a call to graphics.DrawPath():

alt text

The fill operation doesn't care about the outline width, and uses the original shape of the letter.

This partially masks the problem by covering up some of the messy outline. Here is with the fill turned on:

alt text

Something similar will happen with the character 'A':

alt text alt text

EDIT: calling SetLineJoin, as indicated in the other answer, is the way to stop this from happening.

bde
+1 for explaining clearly what the cause is. It's like using a huge pen to draw something. Sometimes the pen can be bigger than what you draw.
Amigable Clark Kant
+3  A: 

Use Pen::SetLineJoin on the Pen you're using to draw the outline, and use something other than LineJoinMiter.

+1 for providing a correct answer.
Amigable Clark Kant