1. Glyph metrics(字形指标)
字形指标,顾名思义,指创建一个文本布局组织每个字形时描述字形如何定位的确切距离。
通常会分为两类字符布局:水平布局和垂直布局。仅有少数字体格式支持垂直布局,可以通过获取宏FT_HAS_VERTICAL是否定义来辨别是否支持。
字形指标的访问可以通过在freetype face的glyph slot第一次加载字形来访问。然后,就可以通过一个FT_Glyph_Metrics类型的结构体来访问:face->glyph->metrics。
水平布局 |
垂直布局 |
Width Height 是字符本体的包围盒的宽高。注意这两个值和布局方向有关。注意不要和FT_Size_Metrics类型中的height域混淆。
注意:后续分析均以水平布局为准。
BearingX 当前焦点(可以看做上上图中的坐标原点)到字符包围盒的水平距离。
BearingY 当前焦点到字符包围盒上边缘的垂直距离。
Advance 可以视为字符区域宽度。在一个字符作为文本一部分绘制完成后,pen(笔触)的步长,可以理解为下一个字符的原点。
在face->glyph->metrics下的metrics使用26.6pixel格式(i.e.1/64thof pixels),除非在调用FT_Load_Glyph or FT_Load_Char两支API的时候使用FT_LOAD_NO_SCALE标识。
在face->glyph (slot)下还有几个能够减轻开发者工作量的域:
Advance 是一个向量,存储字形的变换中的平移向量。当使用FT_Set_Transform来变换字形时候有用。水平布局时候的default值为metrics.horiAdvaces,0;垂直布局时候的default值为metrics.vertAdvace,0。
(注意与face->glyph->metrics下的hor-/ver-advance的区别)
linearHoriAdvance 这个域存储的是字形水平advance宽度的缩放值。事实上,glyphslot 中返回的metrics.horiAdvance值是由实际加载字形图像的字体驱动整数化之后的像素坐标(乘以64)。
linearVertAdvance
2. 管理字形图像
被加到glyph slot的字形图像可以有两种方法转换成位图:
a. 加载glyph时候使用FT_LOAD_RENDER flag
b. 调用API FT_Render_Glyph()
注意:新的字形被加载,就的就会被擦除
会有很多如下场景,你需要在你的应用中缓存glyph slot中的图像,或者在转换成位图之前需要做转换或者测量。
Freetype2 提供一个以灵活通用的方式处理字形图像的扩展接口。要使用这些接口,就需要在应用中包含FT_GLYPH_H头文件。
#includeFT_GLYPH_H
2.1 字形图像导出
FT_Glyph glyph; /* a handle to the glyph image */ ... error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NORMAL ); if ( error ) { ... } error = FT_Get_Glyph( face->glyph, &glyph ); if ( error ) { ... } |
步骤:
a. 创建一个glyph。这是一个独立字形图像的句柄/指针。
b. 以normal方式加载字形图像到face’s glyph slot。这里没有使用FT_LOAD_RENDER flag,因为我们希望获取的是可扩展的字形图像,比如后续我们可以对字体进行变换。
c. 通过调用FT_Get_Glyph将字形图像从slot拷贝到一个新的FT_Glyph对象。
重要提示:提取出的字形图和仍在slot中原始字形图格式完全一样。比如,我们从一个真实的字体文件中获取字形图是一个可扩展的矢量轮廓。我们可以通过访问glyph->format域来获取字形图像是如何被建模和存储的。
销毁glyph对象使用FT_Done_Glyph.
字形对象包括一个字形图像和一个在16.16的固定点坐标中展示字形advance的2D矢量。这个2D矢量可以通过glyph->advance来访问。
注意:不像其他的Freetype对象,字形对象不会被保持在library中,需要用户自己在不再使用的情况下销毁,而不是依赖API FT_Done_FreeType来做所有对象的清除动作。
2.2 变换和字形图拷贝
如果字形图像是可扩展的(即glyph->format不等于FT_GLYPH_FORMAT_BITMAP,等同于加载时候不使用FT_LOAD_RENDER),那么字符就有可能通过调用FT_Glyph_Transform对字符进行做变换。
对单个字形图像进行拷贝可以使用API FT_Glyph_Copy.
FT_Glyph glyph, glyph2; FT_Matrix matrix; FT_Vector delta;
... load glyph image in `glyph' ... /* copy glyph to glyph2 */ error = FT_Glyph_Copy( glyph, &glyph2 ); if ( error ) { ... could not copy (out of memory) ... }
/* translate `glyph' */ delta.x = -100 * 64; /* coordinates are in 26.6 pixel format */ delta.y = 50 * 64; FT_Glyph_Transform( glyph, 0, &delta );
/* transform glyph2 (horizontal shear) */ matrix.xx = 0x10000L; matrix.xy = 0.12 * 0x10000L; matrix.yx = 0; matrix.yy = 0x10000L; FT_Glyph_Transform( glyph2, &matrix, 0 ); |
如上是对两个字形分别作平移和旋转操作,实际中可以同时存在平移和旋转。平移是一个二维的向量,旋转是2x2的矩阵,最基本的坐标变换不做赘述。
==============================================================
笔者水平有限,如果错误,还请包含指正,谢谢!
待续。。。