tmHeight指字符高度(不包括两行字符之间的间距),tmAscent表示字符基线以上部分的高度,tmDescent表示字符基线以下部分的高度。tmInternalLeading表示字符内预留的间距包含在tmAscent中(主要用于显示重音符号等)。tmExternalLeading标准两行字符之间的间距,tmAveCharWidth表示(小写 x)字符的加权平均宽度,tmMaxCharWidth表示字符的最大宽宽度。大写字符的平均宽度通常是字符平均宽度的1.5倍。大写字母平均宽度 = tmMaxCharWith * 1.5 = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2
tmPitchFamily的低位表示字符是变宽字符还是等宽字符。1表示变宽字符,0表示等宽字符。
字符的横向大小由2个值确定:
① tmAveCharWidth,小写字母加权平均宽度。
② tmMaxCharWidth,字体中最宽字符的宽度。
对于等宽字体,tmAveCharWidth和tmMaxCharWidth这两个值相等。
大写字母的平均宽度比较复杂,如果:
① 字体是等宽字体,那么大写字母的平均宽度等于tmAveCharWidth。
② 字体是变宽字体,那么大写字母的平均宽度等于tmAveCharWidth*1.5。
判断字体是否是变宽字体,可以通过TEXTMETRIC结构中的tmPitchAndFamily域的低位判断,如果低位是1,那么是变宽字体,如果是0,那么是等宽字体。
TTextMetric = record tmHeight : Longint; { the height of a character } tmAscent : Longint; { the ascent of a character } tmDescent : Longint; { the descent of a character } tmInternalLeading : Longint; { the internal leading } tmExternalLeading : Longint; { the external leading } tmAveCharWidth : Longint; { the average character width } tmMaxCharWidth : Longint; { the maximum character width } tmWeight : Longint; { the boldness value } tmOverhang : Longint; { the overhang width } tmDigitizedAspectX : Longint; { the horizontal aspect } tmDigitizedAspectY : Longint; { the vertical aspect } tmFirstChar : WORD; { the first character } tmLastChar : WORD; { the last character } tmDefaultChar : WORD; { the default character } tmBreakChar : WORD; { the word break character } tmItalic : Byte; { the italics flag } tmUnderlined : Byte; { the underlined flag } tmStruckOut : Byte; { the strikeout flag } tmPitchAndFamily : Byte; { the pitch and family flags } tmCharSet : Byte; { the character set } end;
// Convert degrees to radians. //............................ #define RAD(x) ((x) * 3.1415927 / 180) FIXED FixedFromDouble( double d ) { long l; l = (long) ( d * 65536L ); return *(FIXED *) &l; } HBITMAP BitmapFromBits( void * lpBits, WORD width, WORD height ) { BITMAP bm; bm.bmType = 0; bm.bmWidth = width; bm.bmHeight = height; bm.bmWidthBytes = ( ( width + 31 ) >> 5 ) << 2; bm.bmPlanes = 1; bm.bmBitsPixel = 1; bm.bmBits = lpBits; return ( CreateBitmapIndirect( &bm ) ); } void GetGlyphOutlineExample( void ) { HDC hDC, hMemDC; HFONT hFont, hOldFont; GLYPHMETRICS gm; MAT2 m2; DWORD dwRet; LPBYTE lpBuf; HBITMAP hBitmap, hOldBmp; // Create a Times New Roman font. hFont = CreateFont( 32, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, “Times New Roman” ); // Retrieve the device context, select the font into it, // and create a compatible device context. hDC = GetDC( hWnd ); hMemDC = CreateCompatibleDC( hDC ); hOldFont = SelectObject( hDC, hFont ); // Set up the translation matrix to rotate the font 45 degrees. m2.eM11 = FixedFromDouble( cos( RAD(45) ) ); m2.eM12 = FixedFromDouble( sin( RAD(45) ) ); m2.eM21 = FixedFromDouble( -sin( RAD(45) ) ); m2.eM22 = FixedFromDouble( cos( RAD(45) ) ); // Retrieve the size of the bitmap and allocate memory to hold it. dwRet = GetGlyphOutline( hDC, 'A’, GGO_BITMAP, & gm, 0, NULL, &m2 ); lpBuf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwRet ); // Retrieve the bitmap for the letter 'A’. GetGlyphOutline( hDC, 'A’, GGO_BITMAP, & gm, dwRet, lpBuf, &m2 ); // Create a HBITMAP and display it. hBitmap = BitmapFromBits( lpBuf, (WORD) gm.gmBlackBoxX, (WORD) gm.gmBlackBoxY ); hOldBmp = SelectObject( hMemDC, hBitmap ); BitBlt( hDC, 10, 10, gm.gmBlackBoxX, gm.gmBlackBoxY, hMemDC, 0, 0, SRCCOPY ); // Output a normal 'A’ character. TextOut( hDC, 40, 10, “A”, 1 ); // Clean up. SelectObject( hMemDC, hOldBmp ); DeleteObject( hBitmap ); HeapFree( GetProcessHeap( ), 0, lpBuf ); SelectObject( hDC, hOldFont ); ReleaseDC( hWnd, hDC ); DeleteObject( hFont ); }
转载于:https://www.cnblogs.com/shangdawei/archive/2013/05/08/3066762.html