FileModeWinding and DrawPath cause odd spikes to appear
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.
And the code sample generating this 4, its outline, and the spike (unintentional)
GraphicsPath path(FillModeWinding);
path.AddString(text,wcslen(text),&fo开发者_运维百科ntFamily,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);
Use Pen::SetLineJoin on the Pen you're using to draw the outline, and use something other than LineJoinMiter.
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():
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:
Something similar will happen with the character 'A':
EDIT: calling SetLineJoin
, as indicated in the other answer, is the way to stop this from happening.
精彩评论