Question

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.

Example of such a font-map

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.

Was it helpful?

Solution

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)
                {
                }
            }
        }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top