GDI 字体信息 TEXTMETRIC 字体结构 GLYPHMETRICS(转)
转自 https://blog.csdn.net/weixin_34087301/article/details/85556985


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;
GetTextMetrics

TGlyphMetrics = packed record
gmBlackBoxX : UINT; { the smallest rectangle width }
gmBlackBoxY : UINT; { the smallest rectangle height }
gmptGlyphOrigin : TPoint; { the smallest rectangle origin }
gmCellIncX : SHORT; { the next character cell horizontal offset }
gmCellIncY : SHORT; { the next character cell vertical offset }
end;
GetGlyphOutline
参数:
否则,返回值是GDI_ERROR。如果指定了上述之一值,但缓冲区或地址是0,则返回需要的缓冲区的字节数。
如果一个应用程序需要一种无修改的字形轮廓,应该在那些大小等于字体的em单位的字体中要求一个字符的字形轮廓,
字体的em单位值存在于结构OUTLINETEXTMETRIC的otmEMSquare成员中。
当指定GGO_GRAY2_BITMAP,返回的位图是一种双字对齐、面向行的,其值在0-4之间的字节数组。
当GGO_GRAY4_BITMAP指定时,返回的位图是一种双字对齐、面向行的,其值在0-16之间的字节数组。
当指定GGO_GRAY8_BITMAP时,返回的位图是一种双字对齐,面向行的,其值在0-64之间的字节数组。
应用程序可以指定lpMatrix参数里的2-对-2转换矩阵来将以位图格式获得的字符旋转。
// 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 );
}
浙公网安备 33010602011771号