Wrote a function that turns text into Image .

 System.Drawing.Image ImageFromText(string text, Font font, System.Drawing.Brush foreGround) { var img = new Bitmap(100, 100); using (var grp = Graphics.FromImage(img)) { grp.SmoothingMode = SmoothingMode.AntiAlias; grp.Clear(Color.White); var size = grp.MeasureString(text, font); grp.InterpolationMode = InterpolationMode.HighQualityBicubic; var sf = new StringFormat(StringFormatFlags.LineLimit | StringFormatFlags.NoClip); sf.LineAlignment = StringAlignment.Center; sf.Alignment = StringAlignment.Center; grp.DrawString(text, font, foreGround, new RectangleF(0, 0, 100, 100), sf); var gp = new GraphicsPath(); gp.AddString(text, font.FontFamily, (int)font.Style, font.SizeInPoints, new RectangleF(0, 0, 100, 100), sf); var rec = gp.GetBounds(); var p = new Pen(foreGround, 1) { LineJoin = LineJoin.Round }; grp.DrawPath(p, gp); } return img; } 

Here is the string gp.AddString(text, font.FontFamily, (int)font.Style, font.SizeInPoints, new RectangleF(0, 0, 100, 100), sf); turns the text into the Path . The problem is that the font size in this case is not respected. In the function call, I set the background with the Verdana font and size 36pt . As a result, the text and stroke should overlap, but this does not happen.

Here's what happened:

That's what happened

Why such difficulties, you ask, because you can make and fill and stroke through the Path . The fact is that according to the plans, the font size will have to be selected automatically (from the specified minimum to maximum) so that the text fits perfectly into the specified area. Graphics has a MeasureString method that will show me the size of the resulting text. But Path can not. And besides, the text that is larger in the picture has a real size (visually correlated with the letter M in the Word).


The question is how to get GraphicsPath.AddString() to draw text with the correct size?

  • Yeah, I just wanted to suggest using GraphicsPath . Let's think ... - Alexander Petrov
  • @AlexanderPetrov, hang up ... He asked himself - he answered) Understood in short. - iRumba
  • @AlexanderPetrov, but no, do not hang up ... it does not work ... the wrong result returns this function. In general, we need a way to convert pt to em - iRumba
  • @AlexanderPetrov, it seems, the problem still has other roots. em is a relative size. but since when I initialize a font, I still write its size, then these units are relative to 1. For DrawString. But for AddString no, it seems. At least by experience, I found out that if you specify size 24 for the first, then you need to specify 32 for the second, so that they are the same. But I can’t just take and insert the necessary coefficient, all of a sudden it will be different on other machines. - iRumba
  • @AlexanderPetrov, figured out again)) - iRumba

1 answer 1

Understood.

 var emSize = grp.DpiY * font.SizeInPoints / 72; gp.AddString(text, font.FontFamily, (int)font.Style, emSize, new RectangleF(0, 0, 100, 100), sf); 

The first line is the conversion of the pt dimension to em. Do not ask what the 72, I do not know. Taken from here https://stackoverflow.com/questions/2292812/font-in-graphicspath-addstring-is-smaller-than-usual-font

  • one
    1 inch = 72 typographic points - 4per