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

函数功能:

该函数把程序当前的字体信息,存放到TEXTMETRIC(即MSDN原文中的specified buffer)中。

函数原型:

BOOL GetTextMetrics(HDC hdc, LPTEXTMETRIC lptm);

参数:

hdc:设备环境句柄。

lptm:指向结构TEXTMETRIC的指针,该结构用于获得字体信息。

返回值:

如果函数调用成功,返回值非零,如果函数调用失败,返回值是0。

  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

函数功能:该函数取得被选进指定设备环境的TrueType字体的字符轮廓或位图。

函数原型:DWORD GetGlyphOutline(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, CONST MAT2 *lpmat2);
参数:

hdc:设备环境句柄。

uChar:指定被返回其数据的字符。

uFormat:指定函数取得的数据的格式。可用下列值之一:各值含义为:

GGO_METRICS:函数只获得由lpgm指定的GLYPHMETRICS结构。其余缓冲区被忽徊,此值影响函数失败时返回值的含义,参见后面的返回值部分。

GGO_BITMAP:函数获得字形位图。要得到善于内存分配的信息,参见后面备注部分。

GGO_NATIVE:函数获得光栅器(rasterrizer)的本地格式的曲线数据点,并使用字体的设计单位,当指定了此值,由lpMatrix指定的任何变换都被忽略。

GGO_GRAY2_BITMAP:函数获得含5级灰色的字形位图。

GGO_GRAY4_BITMAP:函数获得含17级灰色的字形位图。

GGO_GRAY8_BITMAP:函数获得含65级灰色的字形位图。

注意:对GGO_GRAYnBITMAP值,函数获得n*n+1级灰色的字形位图。

lpgm:指向结构GLYPHMETRICS的指针,用于描述字表在字符单元的放置。

cbBuffer:指向定缓冲区的大小,该缓冲区用于复制轮廓字符的信息。如果此值为零,函数返回需要的缓冲区大小。

lpvBuffer:指向缓冲区的指针,该缓冲区用于复制轮廓字符的信息,如果此值为NULL,函数返回需要的缓冲区大小。

lpmat2:指向MAT2结构的指针,该结构为字符信息转换矩阵。该函数不能为NULL,即使nFormat已被设置为GGO_NATIVE

返回值:如果指定了GGO_BITMAP, GGO_GRAY2_BITMAP, GGO_GRAY4_BITMAP, GGO_GRAY8_BITMAP,或GGO_NATIVE值且函数调用成功,返回值将大于0,
否则,返回值是GDI_ERROR。如果指定了上述之一值,但缓冲区或地址是0,则返回需要的缓冲区的字节数。

如果GGO_METRICS被指定且函数调用失败,返回值是GDI_ERROR。

Windows NT:若想获得更多错误信息,请调用GetLastError函数。

备注:GetGlyphOutline返回的字形轮廓是一种配有网络的字形(配有网络的字形是指一种被修改的字形,使其点阵图尽可能地与字形的原始设计一致)。
如果一个应用程序需要一种无修改的字形轮廓,应该在那些大小等于字体的em单位的字体中要求一个字符的字形轮廓,
字体的em单位值存在于结构OUTLINETEXTMETRIC的otmEMSquare成员中。

由GetGlyphOutline指定GGO_BITMAP返回的字形位图是一种双字对齐、面向行的单色位图,
当指定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 );
}

原文地址:https://www.cnblogs.com/merlinzjl/p/12153134.html

时间: 2024-11-09 03:36:28

GDI 字体信息 TEXTMETRIC 字体结构 GLYPHMETRICS(转)的相关文章

java awt根据字符串的信息和字体获取所占有的像素

最近在开发一个类似报表组件的时候碰到了这个问题. 在开发这个组件的时候刚开始是使用jfreechart这个开源的工具,在经过两天的尝试以后放弃了.主要原因是如果我要拓展组件的功能,jfreechart不是很好操作,最后就自己实现了这个东西,实际上也不是很麻烦.主要使用graphics2D进行图形的绘制的. 在开发组件的时候需要将每个数据的标题给绘制在报表的下面,但是不知道这个字体的信息,也不知道这个标题有多长,这个时候就要得到这个标题的所占有的像素数了, 如果需要换行的就要换行了,并且要动态控制

把vux中的@font-face为base64格式的字体信息解码成可用的字体文件

在最近移动端项目中用到了vux,感觉用着还习惯,当把vux使用到PC端的时候出现了IE浏览器出现,这样的错误信息: CSS3114: @font-face 未能完成 OpenType 嵌入权限检查.权限必须是可安装的. 文件: UwCtGsNCf5NCQ0N.... 然后在IE浏览器页面中的字体图标就没有显示. 原来在vux中weiui_font.less文件中,如下写法: @font-face { font-weight: normal; font-style: normal; font-fa

第17章 文本和字体_17.4 字体枚举

17.4 字体枚举 17.4.1 枚举函数 (1)EnumFontFamiliesEx函数 参数 含义 HDC hdc handle to DC LPLOGFONT lpLogfont 传入LOGFONT结构的指针 注意:如果lfCharset=DEFAULT_CHARSET: lf.lfFaceName[0]=NULL,则枚举所有字体 FONTENUMPROC lpEnumFontFamExProc 枚举回调函数 LPARAM lParam 可以指定附加数据,会传到枚举的回调函数中 DWORD

Linux CentOS 7 安装字体库 &amp; 中文字体

最近用CentOS上,用phantomjs把html生成pdf,但是生成多次虽然文件生成了,但是内容一直是空的. 找来找去,发现和系统上支持的字体有关系. 运行了下面的命令后: yum install cabextract xorg-x11-font-utils -y 如果是英文字符,就可以生成了,但是中文还是不行. 最后参考了下面的文章终于搞定. 原文地址:http://blog.csdn.net/wlwlwlwl015/article/details/51482065 前言 报表中发现有中文

CentOS 7 安装字体库 & 中文字体

前言 报表中发现有中文乱码和中文字体不整齐(重叠)的情况,首先考虑的就是操作系统是否有中文字体,在CentOS 7中发现输入命令查看字体列表是提示命令无效:  如上图可以看出,不仅没有中文字体,连字体库都没有,那么接下来就记录一下在Linux CentOS7中如何安装字体库以及中文字体. 安装字体库 在CentOS 4.x开始用fontconfig来安装字体库,所以输入以下命令即可: yum -y install fontconfig 这时在/usr/shared目录就可以看到fonts和fon

应用键横竖屏切换;label中显示图片;不同类型设备适配的代码;UIWebView字体大小、字体颜色、背景色的设置;

最近总结的工作中遇到的小问题在这里共享 ,希望对大家能有帮助 1.横屏的一个应用在修改个人资料过程从相册取图片或者拍照的过程中,横纵屏切换引起再次进入程序时应用变纵屏的bug --------------主页面控制器中点击进入个人资料页面的地方:---------------------- - (void)changepersonIcon{ UIActionSheet*actionSheet = [[UIActionSheetalloc] initWithTitle:@"选择封面图片"

Centos7 安装字体库&amp;中文字体

1.概述 在安装一些服务的时候,会涉及到字符编码与字体的问题,字符编码一般在数据库或代码级别设置,字体一般是在系统级别设置.如安装使用jira或confluence的时候,使用一些宏的时候经常会出现乱码的问题,还有就是程序中有中文的时候,在linux系统上总会乱码. 2.安装字体库 linux系统,一般不会安装字体,报表中发现有中文乱码和中文字体不整齐(重叠)的情况,首先考虑的就是操作系统是否有中文字体,在CentOS 7中发现输入命令查看字体列表是提示命令无效: 如果有此命令,则可以通过fc-

gtk桌面环境(gnome,xfce等)中qt程序(vlc,firefox等)字体与系统字体不符的问题

原本只安装了infinality的基本字体包,一切正常,除了看视频时“跳过广告”以及豆瓣fm的歌曲名等中文显示不正常 猜想是缺少字体,于是装了infinality的extended字体包,结果问题虽然解决了,firefox标题栏字体却变丑了,明显不是设置好的系统字体. 设置qtconfig-qt4,修改trolltech.conf均无效 对比了下应该是noto字体(来自extended),于是卸掉extended字体包,标题栏显示正常,又装了wqy microhei,所有问题搞定 gtk桌面环境

被遗忘的宝藏-LaTeX发行版自带字体&amp;自己一些字体心得

KMC大作,如果用xelatex的话,这些知识仅仅作为大家了解.希望对于学习latex有所裨益.原文地址:http://bbs.ctex.org/viewthread.php?tid=43596&extra=&page=1 可能有不少人像我一样在用LaTeX不久就开始跟字体较劲.我走的是这样一个过程:- 最初用惯了Word,从而无法理解为什么LaTeX调用字体那么难:- 为了在LaTeX中调用字体,想用现有的工具一蹴而就(像TTFshape,MTFI,xGBKfonts),往往不能轻易成功