Talk is cheap

Windows字体大小

  • [ ]  问题的由来

    在早期的Windows中,系统字体是一种等宽字体,所有的字符的宽度都是一样的,就像早期的打字机那样。但是从Windwos3.0开始,系统字体变成了变宽字体:每个字符的宽度是不一样的,例如W要比i宽。很多相关的阅读研究表明,用变宽字体印刷的文章比用等宽字体印刷的可读性更强。其原理是当字符排列的更紧凑时,眼睛和大脑更容易注意到单词而不仅仅是一个个的字符。可想而知,从等宽字体到变宽字体导致很多Windows程序不再适用,程序员们需要学习使用字体的新技术。

系统字体是一种“点阵字体”:每个字符串由像素点构成。在某种程度上,系统字体中字符的大小取决于显示器的大小:字体的设计要求能够在显示器上起码显示25行80列字符。

  • [ ] 字符大小

既然Windows系统字体变成了变宽字体,那么如何确定字体的高度和宽度呢,这个值是多少呢?答案是:这取决于显示器的分辨率。在不同的系统分辨率下用户还可以选择不同的系统字体。程序可以通过GetTextMetrics函数来获取当前选定的字体信息。

获取字号时,首先要获取设备环境句柄,然后调用GetTextMetrics:

    hdc =GetDc(hwnd);
    GetTextMetrics(hdc,&tm);
    ReleaseDc(hwnd,hdc);
这里的&tm 是一个指针,指针指向了一个结构:TEXTMETRIC,该结构有20个字段。但是我们只关心其中的前7个字段:

    typedef struct tagTEXTMETRIC { // tm  
        LONG tmHeight; //字符高度  
        TEXTMETRIC结构字段的图示  
        TEXTMETRIC结构字段的图示 \[1\]  
        LONG tmAscent; //字符上部高度(基线以上)  
        LONG tmDescent; //字符下部高度(基线以下)  
        LONG tmInternalLeading, //由tmHeight定义的字符高度的顶部空间数目  
        LONG tmExternalLeading, //夹在两行之间的空间数目  
        LONG tmAveCharWidth, //平均字符宽度  
        LONG tmMaxCharWidth, //最宽字符的宽度  
        LONG tmWeight; //字体的粗细轻重程度  
        LONG tmOverhang, //加入某些拼接字体上的附加高度  
        LONG tmDigitizedAspectX, //字体设计所针对的设备水平方向  
        LONG tmDigitizedAspectY, //字体设计所针对的设备垂直方向  
        BCHAR tmFirstChar; //为字体定义的第一个字符  
        BCHAR tmLastChar; //为字体定义的最后一个字符  
        BCHAR tmDefaultChar; //字体中所没有字符的替代字符  
        BCHAR tmBreakChar; //用于拆字的字符  
        BYTE tmItalic, //字体为斜体时非零  
        BYTE tmUnderlined, //字体为下划线时非零  
        BYTE tmStruckOut, //字体被删去时非零  
        BYTE tmPitchAndFamily, //字体间距(低4位)和族(高4位)  
        BYTE tmCharSet; //字体的字符集  
    } TEXTMETRIC;    

在TEXTMETRIC结构中有设备环境中当前字体的各种信息。但字体的纵向尺寸仅由其中的5项决定,如图所示:

字体宽度:TEXTMETRICS结构中有两个字段描述了字符的宽度:tmAveCharWidth是小写字符的加权平均宽度,tmMaxCharWidth 是字体中最宽的字符的宽度。在等宽字体中,这两个值是一样的。

注意:系统字体的尺寸取决于Windows运行是的显示分辨率,有时还取决于用户选定的系统字号。Windowsti提供了与设备无关的图形界面,但是作为程序员需要注意:不要再程序中猜测文本的尺寸,不要使用固定值,应该通过调用GetTextMetrics函数来获取这些信息。

通常大写字符的平均宽度,按照tmAveCharWidth的1.5倍计算。

未经允许不得转载:CheapTalk » Windows字体大小
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!