Click here to Skip to main content
15,891,184 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Unlike an usual font, in which all characters may have a different width, the fixed-width fonts we all use while programming have all character of the same width (depending of the font size, of course and probably of some dpi whatever settings).
I tried to programatically or otherwise get this width, but to no avail.
Graphics.MeasureString gives completely unreliable and almost random results, Font.ToLogFont method returns an object with no fields and I'm stuck.
Can someone help me?
Thank you,
Toli, fellow programmer.
Posted
Updated 3-Feb-10 8:15am
v2

In C++/Win32 you would use the GetTextMetrics() call on the device context. I assume there must be some equivalent in C#/.NET. Try a search on MSDN.
 
Share this answer
 
There is a property called AverageCharacterWidth. You can only get text metrics after you've instantiated the font and assigned a string to a resource that uses that font. Once that's done, you should be able to get all kinds of neat font info from the graphics context.
 
Share this answer
 
C#
public enum Unit : int
{
    Pixels = 0,
    Inches = 100,           // 1 inch
    Centimeters = 254,      // 2.54 cm
    Millimeters = 2540,     // 25.4 mm
    Points = 7200,          // 72 points
    HalfPoints = 14400,     // used in rtf
    QuarterPoints = 28800,  // used in rtf
    DocumentUnits = 30000,  // 300 document units
    Twips = 144000,         // used in rtf (20 twips = 1 point)
}

public static float GetCharWidth(string MonospacedFontName, 
    float RequestedFontSizeInPoints, Unit CharWidthUnit)
{
    int PointsPerInch = 72;
    int UnitFactor = 100;
    Bitmap B = new Bitmap(16, 16);  // Whatever, we only need a Graphics
    Graphics G = Graphics.FromImage(B);
    float PixelsPerInch = G.DpiX;

    // Why are we doing this?
    // Well, when we want to create a font with a certain size, 
    // the system finds the closest possible value.
    // That's why in the Visual Studio designer, for example, 
    // if you set Font.Size = 10, it actually becomes 9.75
    float GeneratedFontSizeInPoints = (int)(RequestedFontSizeInPoints * 
        PixelsPerInch) / PointsPerInch * PointsPerInch / PixelsPerInch;

    Font F = new Font(MonospacedFontName, GeneratedFontSizeInPoints, 
        FontStyle.Regular, GraphicsUnit.Point);
    // NoPadding is mandatory
    int WidthInPixels = TextRenderer.MeasureText(G, " ", F, 
        Size.Empty, TextFormatFlags.NoPadding).Width;
    F.Dispose();
    G.Dispose();
    B.Dispose();  // Clean up everything...

    // And finally, convert to the desired unit
    return (CharWidthUnit == Unit.Pixels) ? WidthInPixels : 
        WidthInPixels / PixelsPerInch * (int)CharWidthUnit / UnitFactor;
}
 
Share this answer
 
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900