[翻译]-WinCE 程序设计 (3rd 版)--2.2 输出文本[6]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

创建字体
在应用可以使用非默认字体之前,该字体必须被创建并被选进设备环境里。在新字体被选进DC后,在DC里绘制的任何文本都使用这个新字体。
在Windows CE中创建字体的方法如下:
HFONT CreateFontIndirect (const LOGFONT *lplf);
该函数接受一个指向LOGFONT结构的指针,该结构必须使用您需要的字体描述来填充。
typedef struct tagLOGFONT {
    LONG lfHeight;
    LONG lfWidth;
    LONG lfEscapement;
    LONG lfOrientation;
    LONG lfWeight;
    BYTE lfItalic;
    BYTE lfUnderline;
    BYTE lfStrikeOut;
    BYTE lfCharSet;
    BYTE lfOutPrecision;
    BYTE lfClipPrecision;
    BYTE lfQuality;
    BYTE lfPitchAndFamily;
    TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;

lfHeight 规定字体在设备单位下的高度。如果该域为0,字体管理器返回使用的字体系中默认字体尺寸。对于大多数应用程序来说,您需要创建一个特殊尺寸的字体。下面的公式用于给lfHeight转换磅值:
lfHeight = –1 * (PointSize * GetDeviceCaps (hdc, LOGPIXELSY) / 72);
这里传给GetDeviceCaps的LOGPIXELSY告诉函数返回垂直方向上每英寸的逻辑像素数。72表示每英寸的磅值(磅是用于排版的计算单位)

lfWidth规定了平均字符宽度。因为字体的高度比宽度更重要,所以大多数程序都把这个值设为0。表示让字体管理器根据字体高度计算出合适的宽度。lfEscapement 和lfOrientation 规定了字符基线同X坐标轴之间以十分之一度为单位的旋转角度。lfWeight规定了从0到1000范围内的字体粗细程度,其中400是标准字体,700是加重字体。接下来的三个域规定了字体是否是斜体、下划线或者删除线。

lpCharSet规定了您选择的字符集。该域对于软件的国际版本是很重要的,因为国际版本一般都要求特定的语言字符集合。lfOutPrecision 规定Windows匹配您请求的字体的精确程度。在众多可以使用的标志当中,OUT_TT_ONLY_PRECIS标志规定创建的字体必须是TrueType字体。

lfClipPrecision规定Windows如何裁剪超出显示区域的字符。

lfQuality 可以设置为以下几种:
DEFAULT_QUALITY   默认系统质量

DRAFT_QUALITY   牺牲质量换取速度

CLEARTYPE_QUALITY   用ClearType技术绘制文本

CLEARTYPE_COMPAT_QUALITY   用ClearType技术绘制文本。对非ClearType字体使用同样的空间。

ClearType是一种为字体提供更清晰的外观的文本显示技术,该技术独立寻址红、绿、蓝LCD,它们在彩色LCD显示器上构成一个像素。根据系统的不同,有的可能不支持ClearType,有的可能对系统里的所有字体都支持。对于支持ClearType但不完全支持的系统来说,使用CLEARTYPE_QUALITY 或CLEARTYPE_COMPAT_QUALITY 可以创建用ClearType绘制的字体。因为ClearType并不改进所有字体的外观,所以您应该测试一下,看ClearType是否对您选择的字体有所改进。

lfPitchAndFamily规定了您选择的字体的字系。当您请求诸如Swiss字系--一种没有衬线的专业字体--时,使用该域很方便。再例如选择Roman字系--一种带衬线的专业字体--时,也很方便,但您要注意不要针对特定的字体。您也可以用该域来规定均衡或等宽字体,并让Windows来决定使用哪种字体来匹配传给LOGFONT结构的特定特性。最后,lfFaceName域用来指明具体字体的字体名称。当用一个填充后的LOGFONT结构调用CreateFontIndirect时,Windows根据提供的特性,创建一个最匹配的逻辑字体。为了使用该字体,需要做的最后一步是选择该字体到一个设备环境里。

选择字体到设备环境
用SelectObject 函数将字体选进DC里,函数如下所示:
HGDIOBJ SelectObject (HDC hdc, HGDIOBJ hgdiobj);
该函数不仅仅用于设置默认字体,还用在很多地方;正如您很快就会看到的,可以用该函数来选择其它GDI对象。该函数返回先前被选择的对象(在本例中返回的是先前选择的字体),应该保存该返回值以便当您用完新的字体后可以把先前的选择回DC里。代码行如下所示:
hOldFont = (HFONT)SelectObject (hdc, hFont);

当逻辑字体被选择时,系统从可使用的字体中选择最匹配的逻辑字体。对没有TrueType字体的设备,匹配的字体同指定的参数相比有一定数量的差异。因此,不要想当然的认为您请求了一个特殊字体,返回的就是准确匹配的字体。例如,您要求的字体高度可能和选进设备环境的字体高度是不一样的。

查询字体特性
为了确定选进设备环境的字体的特性,调用GetTextMetrics 函数来返回字体特性,函数原型如下:
BOOL GetTextMetrics (HDC hdc, LPTEXTMETRIC lptm);
TEXTMETRIC结构带有返回信息,该结构定义如下:
typedef struct tagTEXTMETRIC {
    LONG tmHeight;
    LONG tmAscent;
    LONG tmDescent;
    LONG tmInternalLeading;
    LONG tmExternalLeading;
    LONG tmAveCharWidth;
    LONG tmMaxCharWidth;
    LONG tmWeight;
    LONG tmOverhang;
    LONG tmDigitizedAspectX;
    LONG tmDigitizedAspectY;
    char tmFirstChar;
    char tmLastChar;
    char tmDefaultChar;
    char tmBreakChar;
    BYTE tmItalic;
    BYTE tmUnderlined;
    BYTE tmStruckOut;
    BYTE tmPitchAndFamily;
    BYTE tmCharSet;
} TEXTMETRIC;

TEXTMETRIC结构包含了LOGFONT结构中的很多域,但此时TEXTMETRIC的值是选进设备变量的字体的特性。图2-3显示了一些域同实际字符之间的关系。
图2-3(图略):TEXTMETRIC结构及其与字体的关系。

除了可以判断您是否真的获得了您需要的字体外,GetTextmetrics函数调用还有另外一个有价值的用途--确定字体高度。回忆一下TextDemo程序,行的高度是通过调用DrawText函数计算出来的。虽然那种方法很方便,但它有点慢。您可以使用TEXTMETRIC数据,以更加直接的方法来计算高度。将表示字符高度的tmHeight域与tmExternalLeading域--表示一行底部像素到下一行顶部像素之间的间距--相加,您就可以获得两行文本基线的间距了。

虽然GetTextMetrics对确定字符高度来说是很好用的,但它只提供了字体的平均宽度和最大宽度。如果需要TrueType的更多细节,可以使用函数GetCharABCWidths,函数原型如下:
BOOL GetCharABCWidths (HDC hdc, UINT uFirstChar, UINT uLastChar, LPABC lpabc);
GetCharABCWidths返回由uFirstChar 和 uLastChar 参数所确定的一系列字符的ABC宽度。该函数检查hdc参数指定的DC里的字体。ABC结构如下:
typedef struct _ABC {
    int     abcA;
    UINT    abcB;
    int     abcC;
} ABC;
abcA为在放置字符轮廓前的空白间距,abcB为字符轮廓本身的间距,abcC为字符轮廓右方的空白间距。abcA和abcC都可以是负值,用来指示缩进或者凸起。

要获得点阵字体(bitmap fonts)的宽度,可以使用GetCharWidth32函数。对指定字符范围内的每个字符,该函数返回一个字符宽度数组。

本文关键:[翻译]-WinCE 程序设计 (3rd 版)--2.2 输出文本
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top