FreeType之字形分析(一)

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的矩阵,最基本的坐标变换不做赘述。


==============================================================

笔者水平有限,如果错误,还请包含指正,谢谢!

待续。。。

你可能感兴趣的:(Computer,Graphics)