Monday, March 20, 2006

Get TEXTMETRIC from font in C#

Today I needed to get the TEXTMETRIC details for a font in c#. In C++ this was very easy but .NET does not seem to have any functions to get this information. Here is how I ended up doing it:-

[Serializable, StructLayout (LayoutKind.Sequential, CharSet = CharSet.Auto)]

public struct TEXTMETRIC

{

public int tmHeight;

public int tmAscent;

public int tmDescent;

public int tmInternalLeading;

public int tmExternalLeading;

public int tmAveCharWidth;

public int tmMaxCharWidth;

public int tmWeight;

public int tmOverhang;

public int tmDigitizedAspectX;

public int tmDigitizedAspectY;

public char tmFirstChar;

public char tmLastChar;

public char tmDefaultChar;

public char tmBreakChar;

public byte tmItalic;

public byte tmUnderlined;

public byte tmStruckOut;

public byte tmPitchAndFamily;

public byte tmCharSet;

}

[DllImport ("gdi32.dll", CharSet = CharSet.Unicode)]

static extern bool GetTextMetrics (IntPtr hdc, out TEXTMETRIC lptm);

[DllImport ("gdi32")]

private static extern IntPtr SelectObject (

IntPtr hdc,

IntPtr hObj

);



In my paint code (FontName is a string holding the name of the font)

// Get TEXTMETRIC details for font

Font font = new Font (FontName, size, FontStyle.Bold, GraphicsUnit.Pixel);

IntPtr hdc = g.GetHdc ();

IntPtr hFontOld = SelectObject (hdc, font.ToHfont ());

TEXTMETRIC tm;

GetTextMetrics (hdc, out tm);

SelectObject (hdc, hFontOld);

g.ReleaseHdc (hdc);



Then I can use the tm object to extract all the font details

PointF topleft = new PointF (x + cx, displayy + cy - (tm.tmExternalLeading + tm.tmInternalLeading));

1 comment:

gproto said...

Great post. Saved my life, really.