I am trying to make some text in a specific part of an image in a Web Forms application. The text will be entered by the user, so I want to change the font size to make sure that it is placed in the bounding box.
I have code that does an excellent job of implementing my conceptual concepts, but now I'm trying to do it against assets from the constructor, which are larger, and I get some odd results.
I do the size calculation as follows:
StringFormat fmt = new StringFormat();
fmt.Alignment = StringAlignment.Center;
fmt.LineAlignment = StringAlignment.Near;
fmt.FormatFlags = StringFormatFlags.NoClip;
fmt.Trimming = StringTrimming.None;
int size = __startingSize;
Font font = __fonts.GetFontBySize(size);
while (GetStringBounds(text, font, fmt).IsLargerThan(__textBoundingBox))
{
context.Trace.Write("MyHandler.ProcessRequest",
"Decrementing font size to " + size + ", as size is "
+ GetStringBounds(text, font, fmt).Size()
+ " and limit is " + __textBoundingBox.Size());
size--;
if (size < __minimumSize)
{
break;
}
font = __fonts.GetFontBySize(size);
}
context.Trace.Write("MyHandler.ProcessRequest", "Writing " + text + " in "
+ font.FontFamily.Name + " at " + font.SizeInPoints + "pt, size is "
+ GetStringBounds(text, font, fmt).Size()
+ " and limit is " + __textBoundingBox.Size());
Then I use the following line to render text on an image that I take out of the file system:
g.DrawString(text, font, __brush, __textBoundingBox, fmt);
Where:
__fonts- it is PrivateFontCollection,PrivateFontCollection.GetFontBySize is an extension method that returns FontFamilyRectangleF __textBoundingBox = new RectangleF(150, 110, 212, 64);int __minimumSize = 8;int __startingSize = 48;Brush __brush = Brushes.White;int size starts at 48 and decreases within this cycleGraphics g SmoothingMode.AntiAlias TextRenderingHint.AntiAliascontext System.Web.HttpContext ( ProcessRequest IHttpHandler)
:
private static RectangleF GetStringBounds(string text, Font font,
StringFormat fmt)
{
CharacterRange[] range = { new CharacterRange(0, text.Length) };
StringFormat myFormat = fmt.Clone() as StringFormat;
myFormat.SetMeasurableCharacterRanges(range);
using (Graphics g = Graphics.FromImage(new Bitmap(
(int) __textBoundingBox.Width - 1,
(int) __textBoundingBox.Height - 1)))
{
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
Region[] regions = g.MeasureCharacterRanges(text, font,
__textBoundingBox, myFormat);
return regions[0].GetBounds(g);
}
}
public static string Size(this RectangleF rect)
{
return rect.Width + "×" + rect.Height;
}
public static bool IsLargerThan(this RectangleF a, RectangleF b)
{
return (a.Width > b.Width) || (a.Height > b.Height);
}
.
-, , , while . , , Graphics.MeasureCharacterRanges , , . ( , Unicode, , , ). - , , Graphics.MeasureCharacterRanges ( )? , post 2499067.
-, Graphics.MeasureCharacterRanges , . RectangleF , , , , . , - , GetBounds , , .
, __minimumSize while, , 24pt , Graphics.MeasureCharacterRanges , , 122px ( 64px ). , , while 18pt, Graphics.MeasureCharacterRanges , .
:
24, 193 × 122, - 212 × 64
23, - 191 × 117, - 212 × 64
22, 200 × 75 212 × 64
21, - 192 × 71, - 212 × 64
20, 198 × 68, - 212 × 64
19, - 185 × 65, - 212 × 64
VENNEGOOR HESSELINK DIN-Black 18pt, 178 × 61 212 × 64
, Graphics.MeasureCharacterRanges ? , , , , 21pt ( , Paint.Net), , , , .