Reputation: 951
I'm trying to generate a font-map using C#'s Graphics class.
The characters are supposed to be perfectly in the middle of their rectangle in order to use them afterwards. Secondly, I want to use the biggest font-size with all characters fitting into their box.
This is my attempt at doing so. However, when I run this, the characters are not in the middle of their rectangle and it seems like they're rather attached to the upper-left corner of it, considering they're pretty jump when you go trough the different maps.
foreach (String FontName in DataHandler.GetFonts())
{
foreach (FontStyle Style in Enum.GetValues(typeof(FontStyle)))
{
try
{
Bitmap map = new Bitmap(585, 559);
Graphics g = Graphics.FromImage(map);
for (int i = 0; i < charOrder.Length; i++)
{
string character = charOrder.Substring(i, 1);
g.DrawString(character, new Font(FontName, 30 / new Font(FontName, 20).FontFamily.GetEmHeight(Style), Style), new SolidBrush(myColor), new RectangleF(new PointF((i % charactersPerRow) * 40, ((i - (i % charactersPerRow)) / charactersPerRow) * 80), new SizeF(40, 80)));
}
map.Save(OutputPath + "\\" + Style.ToString() + "_" + FontName + ".png");
}
catch (Exception)
{
}
}
}
How would I make the characters fit perfectly into in the middle of their rectangle?
EDIT: All characters of one font would have to use the same font-size, obviously.
Upvotes: 0
Views: 825
Reputation: 39122
Here's what I came up with...
int charactersPerRow = 14;
string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-=~!@#$%^&*()_+,./;'[]\\<>?:\"{}|";
int rows = (int)Math.Ceiling((decimal)chars.Length / (decimal)charactersPerRow);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
foreach (String FontName in DataHandler.GetFonts())
{
foreach (FontStyle Style in Enum.GetValues(typeof(FontStyle)))
{
try
{
Bitmap map = new Bitmap(585, 559);
using (Graphics g = Graphics.FromImage(map))
{
// each char must fit into this size:
SizeF szF = new SizeF(map.Width / charactersPerRow, map.Height / rows);
// fallback font and size
int fntSize = 8;
Font fnt = new Font(FontName, fntSize, Style);
// figure out the largest font size that will fit into "szF" above:
bool smaller = true;
while (smaller)
{
Font newFnt = new Font(FontName, fntSize, Style);
for (int i = 0; i < chars.Length; i++)
{
SizeF charSzF = g.MeasureString(chars[i].ToString(), newFnt);
if (charSzF.Width > szF.Width || charSzF.Height > szF.Height)
{
smaller = false;
break;
}
}
if (smaller)
{
if (fnt != null)
{
fnt.Dispose();
}
fnt = newFnt;
fntSize++;
}
}
// draw each char at the appropriate location:
using (SolidBrush brsh = new SolidBrush(myColor))
{
for (int i = 0; i < chars.Length; i++)
{
PointF ptF = new PointF(
(float)(i % charactersPerRow) / (float)charactersPerRow * map.Width,
((float)((int)(i / charactersPerRow)) / (float)rows) * map.Height);
g.DrawString(chars[i].ToString(), fnt, brsh, new RectangleF(ptF, szF), sf);
}
}
map.Save(OutputPath + "\\" + Style.ToString() + "_" + FontName + ".png");
}
}
catch (Exception)
{
}
}
}
Upvotes: 2