c00000fd
c00000fd

Reputation: 22307

How to stroke text when drawing it with DrawString function in GDI+?

There's a GDI's StrokePath API that can allow to simulate "stroking" of text using this method. I'll copy it here:

void CCanvas::DrawOutlineText( CDC& dc, const CString& Text )
{
  const int RestorePoint = dc.SaveDC();

  // Create new font
  CFont NewFont;
  NewFont.CreatePointFont( 700, TEXT( "Verdana" ), &dc );

  // Use this font
  dc.SelectObject( &NewFont );

  // Brush for pen
  LOGBRUSH lBrushForPen = { 0 };
  lBrushForPen.lbColor = RGB( 200, 150, 100 );
  lBrushForPen.lbHatch = HS_CROSS;
  lBrushForPen.lbStyle = BS_SOLID;

  // New pen for drawing outline text
  CPen OutlinePen;
  OutlinePen.CreatePen( PS_GEOMETRIC | PS_SOLID, 2, &lBrushForPen, 0, 0 );

  // Use this pen
  dc.SelectObject( &OutlinePen );

  dc.SetBkMode( TRANSPARENT );

  dc.BeginPath();
  // This text is not drawn on screen, but instead each action is being
  // recorded and stored internally as a path, since we called BeginPath
  dc.TextOut( 20, 20, Text );
  // Stop path
  dc.EndPath();

  // Now draw outline text
  dc.StrokePath();

  dc.RestoreDC( RestorePoint );
}

In my case I'm using DrawString function from GDI+ to draw text.

Does anyone know if there's an alternative to BeginPath, EndPath and StrokePath in GDI+ to simulate text stroking?

EDIT: Following the advice by jschroedl below, I tried the following:

CString str = L"Text";

Graphics grpx(dc.GetSafeHdc());

SolidBrush gdiBrush(Color(0xFF, 0xFF, 0, 0));

StringFormat gdiSF;
gdiSF.SetAlignment(StringAlignmentNear);
gdiSF.SetFormatFlags(StringFormatFlagsNoWrap | StringFormatFlagsNoFitBlackBox | 
    StringFormatFlagsNoFontFallback | StringFormatFlagsNoClip);
gdiSF.SetHotkeyPrefix(HotkeyPrefixNone);
gdiSF.SetTrimming(StringTrimmingNone);

grpx.SetTextRenderingHint(TextRenderingHintAntiAlias);
grpx.SetPixelOffsetMode(PixelOffsetModeNone);
grpx.SetInterpolationMode(InterpolationModeHighQualityBicubic);

GraphicsPath dd;
FontFamily gdiFF(L"Segoe UI");
const PointF pntF(0, 0);
dd.AddString(str, str.GetLength(), &gdiFF, FontStyleRegular, 58.0f, pntF, &gdiSF);

Pen penFF(Color(0xFF, 0xFF, 0, 0), 1.0f);
grpx.DrawPath(&penFF, &dd);

that produced quite a jagged outline (enlarged screenshot):

enter image description here

Any idea how to make it render with anti-aliasing?

Upvotes: 1

Views: 1502

Answers (1)

jschroedl
jschroedl

Reputation: 4986

I believe our code creates a GraphicsPath object, calls GraphicsPath::AddString() to get the path for the text and later draws the path with Graphics::DrawPath().

Update:

Based on the blocky text, I experimented and think this looks a bit smoother.

grpx.SetTextRenderingHint(TextRenderingHintClearTypeGridFit);
grpx.SetSmoothingMode(SmoothingModeHighQuality);
grpx.SetPixelOffsetMode(PixelOffsetModeHalf);

enter image description here

Upvotes: 0

Related Questions