FreeType Glyph Conventions
From Mxtctp
原文链接:http://www.freetype.org/freetype2/docs/glyphs/index.html
翻译人员:HappyLiu
| 英文 | 中文 | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| FreeType Glyph Conventions
Version 2.1 | FreeType字形约定
版本2.1 | ||||||||||||||||||||||||||
| This document presents the core conventions used within the FreeType library to manage font and glyph data. It is a must-read for all developers who need to understand digital typography, especially if you want to use the FreeType 2 library in your projects. | |||||||||||||||||||||||||||
| Table of Contents
I. Basic Typographic Concepts
II. Glyph outlines
III. Glyph metrics
IV. Kerning
V. Text processing
VI. FreeType Outlines
VII. FreeType bitmaps
| 目录
一、基本印刷概念
二、字形轮廓
三、字形度量
四、字距调整
五、文本处理
六、FT轮廓
七、FT位图
| ||||||||||||||||||||||||||
| I. Basic typographic concepts | 一、基本印刷概念 | ||||||||||||||||||||||||||
| 1. Font files, format and information | 1、字体文件、格式和信息 | ||||||||||||||||||||||||||
| A font is a collection of various character images that can be used to display or print text. The images in a single font share some common properties, including look, style, serifs, etc. Typographically speaking, one has to distinguish between a font family and its multiple font faces, which usually differ in style though come from the same template. | 字体是一组可以被显示和打印的多样的字符图像,在单个字体中共享一些共有的特性,包括外表、风格、衬线等。按印刷领域的说法,它必须区别一个字体家族和多种字体外观,后者通常是从同样的模板而来,但是风格不同。 | ||||||||||||||||||||||||||
| For example, "Palatino Regular" and "Palatino Italic" are two distinct faces from the same famous family, called "Palatino" itself. | 例如,Palatino Regular 和 Palatino Italic是两种不同的外观,但是属于同样的家族Palatino。 | ||||||||||||||||||||||||||
| The single term font is nearly always used in ambiguous ways to refer to either a given family or given face, depending on the context. For example, most users of word-processors use "font" to describe a font family (e.g. "Courier", "Palatino", etc.); however most of these families are implemented through several data files depending on the file format: For TrueType, this is usually one per face (i.e. arial.ttf for "Arial Regular", ariali.ttf for "Arial Italic", etc.). The file is also called a "font" but really contains a font face. | 单个字体术语根据上下文既可以指家族也可指外观。例如,大多文字处理器的用户用字体指不同的字体家族,然而,大多这些家族根据它们的格式会通过多个数据文件实现。对于 TrueType来讲,通常是每个外观一个文件(arial.ttf对应Arial Regular外观,ariali.ttf对应Arial Italic外观)这个文件也叫字体,但是实际上只是一个字体外观。 | ||||||||||||||||||||||||||
| A digital font is thus a data file that may contain one or more font faces. For each of these, it contains character images, character metrics, as well as other kind of information important to the layout of text and the processing of specific character encodings. In some awkward formats, like Adobe's Type 1, a single font face is described through several files (i.e. one contains the character images, another one the character metrics). We will ignore this implementation issue in most parts of this document and consider digital fonts as single files, though FreeType 2.0 is able to support multiple-files fonts correctly. | 数字字体是一个可以包含一个和多个字体外观的数据文件,它们每个都包含字符图像、字符度量,以及其他各种有关文本布局和特定字符编码的重要信息。对有些难用的格式,像Adobe的Type1,一个字体外观由几个文件描述(一个包含字符映象,一个包含字符度量等)。在这里我们忽略这种情况,只考虑一个外观一个文件的情况,不过在FT2.0中,能够处理多文件字体。 | ||||||||||||||||||||||||||
| As a convenience, a font file containing more than one face is called a font collection. This case is rather rare but can be seen in many Asian fonts, which contain images for two or more representation forms of a given scripts (usually for horizontal and vertical layout. | 为了方便说明,一个包含多个外观的字体文件我们叫做字体集合,这种情况不多见,但是多数亚洲字体都是如此,它们会包含两种或多种表现形式的图像,例如横向和纵向布局。 | ||||||||||||||||||||||||||
| 2. Character images and mappings | 2、字符图像和映射 | ||||||||||||||||||||||||||
The character images are called glyphs. A single character can have several distinct images, i.e. several glyphs, depending on script, usage or context. Several characters can also take a single glyph (good examples are Roman ligatures like "fi" and "fl" which can be represented by a single glyph). The relationships between characters and glyphs can be very complex, but won't be discussed in this document. Moreover, some formats use more or less awkward schemes to store and access glyphs. For the sake of clarity, we only retain the following notions when working with FreeType:
| 字符图像叫做字形,根据书写、用法和上下文,单个字符能够有多个不同的图像,即多个字形。多个字符也可以有一个字形(例如Roman??)。字符和字形之间的关系可能是非常复杂,本文不多述。而且,多数字体格式都使用不太难用的方案存储和访问字形。为了清晰的原因,当说明FT时,保持下面的观念
| ||||||||||||||||||||||||||
| 3. Character and font metrics | 3、字符和字体度量 | ||||||||||||||||||||||||||
| Each glyph image is associated with various metrics which are used to describe how must be placed and managed when rendering text. These are described in more details in section III, they relate to glyph placement, cursor advances as well as text layout. They are extremely important to compute the flow of text when rendering a string of text. | 每个字符图像都关联多种度量,被用来在渲染文本时,描述如何放置和管理它们。在后面会有详述,它们和字形位置、光标步进和文本布局有关。它们在渲染一个文本串时计算文本流时非常重要。 | ||||||||||||||||||||||||||
| Each scalable format also contains some global metrics, expressed in notional units, to describe some properties of all glyphs in the same face. Examples for global metrics are the maximum glyph bounding box, the ascender, descender and text height for the font. | 每个可缩放的字体格式也包含一些全局的度量,用概念单位表示,描述同一种外观的所有字形的一些特性,例如最大字形外框,字体的上行字符、下行字符和文本高度等。 | ||||||||||||||||||||||||||
| Though these metrics also exist for non-scalable formats, they only apply for a set of given character dimensions and resolutions, and are usually expressed in pixels then. | 虽然这些度量也会存在于一些不可缩放格式,但它们只应用于一组指定字符维度和分辨率,并且通常用象素表示。 | ||||||||||||||||||||||||||
| II. Glyph Outlines | 二、字形轮廓 | ||||||||||||||||||||||||||
| This section describes the way scalable representations of glyph images, called outlines, are used by FreeType as well as client applications. | |||||||||||||||||||||||||||
| 1. Pixels, points and device resolutions | 1、象素、点和设备解析度 | ||||||||||||||||||||||||||
| Though it is a very common assumption when dealing with computer graphics programs, the physical dimensions of a given pixel (be it for screens or printers) are not squared. Often, the output device, be it a screen or printer, exhibits varying resolutions in both horizontal and vertical direction, and this must be taken care of when rendering text. | 当处理计算机图形程序时,指定象素的物理尺寸不是正方的。通常,输出设备是屏幕或打印机,在水平和垂直方向都有多种分辨率,当渲染文本是要注意这些情况。 | ||||||||||||||||||||||||||
| It is thus common to define a device's characteristics through two numbers expressed in dpi (dots per inch). For example, a printer with a resolution of 300x600 dpi has 300 pixels per inch in the horizontal direction, and 600 in the vertical one. The resolution of a typical computer monitor varies with its size (15" and 17" monitors don't have the same pixel sizes at 640x480), and of course the graphics mode resolution. | 定义设备的分辨率通常使用用dpi(每英寸点(dot)数)表示的两个数,例如,一个打印机的分辨率为300x600dpi表示在水平方向,每英寸有 300 个象素,在垂直方向有600个象素。一个典型的计算机显示器根据它的大小,分辨率不同(15和17显示器对640x480象素大小不同),当然图形模式分辨率也不一样。 | ||||||||||||||||||||||||||
| As a consequence, the size of text is usually given in points, rather than device-specific pixels. Points are a simple physical unit, where 1 point = 1/72th of an inch, in digital typography. As an example, most Roman books are printed with a body text whose size is somewhere between 10 and 14 points. | 所以,文本的大小通常用点(point)表示,而不是用设备特定的象素。点是一种简单的物理单位,在数字印刷中,一点等于1/72英寸。例如,大多罗马书籍使用10到14点大小印刷文字内容。 | ||||||||||||||||||||||||||
It is thus possible to compute the size of text in pixels from the size in points with the following formula:
| 可以用点数大小来计算象素数,公式如下:
| ||||||||||||||||||||||||||
| The resolution is expressed in dpi. Since horizontal and vertical resolutions may differ, a single point size usually defines a different text width and height in pixels. | 分辨率用dpi表示,因为水平和垂直分辨率可以不同,单个点数通常定义不同象素文本宽度和高度。 | ||||||||||||||||||||||||||
| Unlike what is often thought, the "size of text in pixels" is not directly related to the real dimensions of characters when they are displayed or printed. The relationship between these two concepts is a bit more complex and relate to some design choices made by the font designer. This is described in more detail in the next sub-section (see the explanations on the EM square). | |||||||||||||||||||||||||||
| 2. Vectorial representation | 2、向量表示 | ||||||||||||||||||||||||||
| The source format of outlines is a collection of closed paths called contours. Each contour delimits an outer or inner region of the glyph, and can be made of either line segments or Bézier arcs. | 字体轮廓的源格式是一组封闭的路径,叫做轮廓线。每个轮廓线划定字形的外部或内部区域,它们可以是线段或是Bezier曲线。 | ||||||||||||||||||||||||||
| The arcs are defined through control points, and can be either second-order (these are conic Béziers) or third-order (cubic Béziers) polynomials, depending on the font format. Note that conic Béziers are usually called quadratic Béziers in the literature. Hence, each point of the outline has an associated flag indicating its type (normal or control point). And scaling the points will scale the whole outline. | 曲线通过控制点定义,根据字体格式,可以是二次(conic Beziers)或三次(cubic Beziers)多项式。在文献中,conic Bezier通常称为quadratic Beziers。因此,轮廓中每个点都有一个标志表示它的类型是一般还是控制点,缩放这些点将缩放整个轮廓。 | ||||||||||||||||||||||||||
| Each glyph's original outline points are located on a grid of indivisible units. The points are usually stored in a font file as 16-bit integer grid coordinates, with the grid origin's being at (0,0); they thus range from -16384 to 16383. (Even though point coordinates can be floats in other formats such as Type 1, we will restrict our analysis to integer values for simplicity). | 每个字形最初的轮廓点放置在一个不可分割单元的网格中,点通常在字体文件中以16位整型网格坐标存储,网格的原点在(0,0),它的范围是-16384到-16383(虽然有的格式如Type1使用浮点型,但为简便起见,我们约定用整型分析)。 | ||||||||||||||||||||||||||
| The grid is always oriented like the traditional mathematical two-dimensional plane, i.e., the X axis from the left to the right, and the Y axis from bottom to top. | 网格的方向和传统数学二维平面一致,x轴从左到右,y轴从下到上。 | ||||||||||||||||||||||||||
In creating the glyph outlines, a type designer uses an imaginary square called the EM square. Typically, the EM square can be thought of as a tablet on which the characters are drawn. The square's size, i.e., the number of grid units on its sides, is very important for two reasons:
| 在创建字形轮廓时,一个字体设计者使用一个假想的正方形,叫做EM正方形。他可以想象成一个画字符的平面。正方形的大小,即它边长的网格单元是很重要的,原因是
| ||||||||||||||||||||||||||
| Note that glyphs can freely extend beyond the EM square if the font designer wants so. The EM is used as a convenience, and is a valuable convenience from traditional typography. | 注意,字形可以自由超出EM正方形。 | ||||||||||||||||||||||||||
| Grid units are very often called font units or EM units. | 网格单元通常交错字体单元或EM单元。 | ||||||||||||||||||||||||||
| As said before, pixel_size computed in the above formula does not relate directly to the size of characters on the screen. It simply is the size of the EM square if it was to be displayed. Each font designer is free to place its glyphs as it pleases him within the square. This explains why the letters of the following text have not the same height, even though they are displayed at the same point size with distinct fonts:
Comparison of font heights | 上边的象素数并不是指实际字符的大小,而是EM正方形显示的大小,所以不同字体,虽然同样大小,但是它们的高度可能不同。 | ||||||||||||||||||||||||||
| As one can see, the glyphs of the Courier family are smaller than those of Times New Roman, which themselves are slightly smaller than those of Arial, even though everything is displayed or printed at a size of 16 points. This only reflects design choices. | |||||||||||||||||||||||||||
| 3. Hinting and Bitmap rendering | 3、Hinting和位图渲染 | ||||||||||||||||||||||||||
| The outline as stored in a font file is called the "master" outline, as its points coordinates are expressed in font units. Before it can be converted into a bitmap, it must be scaled to a given size/resolution. This is done through a very simple transformation, but always creates undesirable artifacts, e.g. stems of different widths or heights in letters like "E" or "H". | 存储在一个字体文件中的轮廓叫"主"轮廓,它的点坐标用字体单元表示,在它被转换成一个位图时,它必须缩放至指定大小。这通过一个简单的转换完成,但是总会产生一些不想要的副作用,例如像字母E和H,它们主干的宽度和高度会不相同。 | ||||||||||||||||||||||||||
| As a consequence, proper glyph rendering needs the scaled points to be aligned along the target device pixel grid, through an operation called grid-fitting (often called hinting). One of its main purposes is to ensure that important widths and heights are respected throughout the whole font (for example, it is very often desirable that the "I" and the "T" have their central vertical line of the same pixel width), as well as to manage features like stems and overshoots, which can cause problems at small pixel sizes. | 所以,优秀的字形渲染过程在缩放"点"是,需要通过一个网格对齐(grid-fitting)的操作(通常叫hinting),将它们对齐到目标设备的象素网格。这主要目的之一是为了确保整个字体中,重要的宽度和高度能够一致。例如对于字符I和T来说,它们那个垂直笔划要保持同样象素宽度。另外,它的目的还有管理如stem和overshoot的特性,这在小象素字体会引起一些问题。 | ||||||||||||||||||||||||||
There are several ways to perform grid-fitting properly; most scalable formats associate some control data or programs with each glyph outline. Here is an overview:
| 有若干种方式来处理网格对齐,多数可缩放格式中,每种字形轮廓都有一些控制数据和程序。
| ||||||||||||||||||||||||||
The following table summarises the pros and cons of each scheme.
| 下面总结了每种方案的优点和缺点
| ||||||||||||||||||||||||||
| III. Glyph metrics | 三、字形度量 | ||||||||||||||||||||||||||
| 1. Baseline, pens and layouts | 1、基线、笔和布局 | ||||||||||||||||||||||||||
| The baseline is an imaginary line that is used to "guide" glyphs when rendering text. It can be horizontal (e.g. Roman, Cyrillic, Arabic, etc.) or vertical (e.g. Chinese, Japanese, Korean, etc). Moreover, to render text, a virtual point, located on the baseline, called the pen position or origin, is used to locate glyphs. | 基线是一个假想的线,用来在渲染文本时知道字形,它可以是水平(如Roman)和是垂直的(如中文)。而且,为了渲染文本,在基线上有一个虚拟的点,叫做笔位置(pen position)或原点(origin),他用来定位字形。 | ||||||||||||||||||||||||||
Each layout uses a different convention for glyph placement:
| 每种布局使用不同的规约来放置字形:
| ||||||||||||||||||||||||||
| 2. Typographic metrics and bounding boxes | 2、印刷度量和边界框 | ||||||||||||||||||||||||||
A various number of face metrics are defined for all glyphs in a given font.
| 在指定字体中,定义了多种外观度量。
| ||||||||||||||||||||||||||
Other, simpler metrics are:
|
| ||||||||||||||||||||||||||
| 3. Bearings and Advances | 3、跨距(bearing)和步进 | ||||||||||||||||||||||||||
Each glyph has also distances called bearings and advances. Their definition is constant, but their values depend on the layout, as the same glyph can be used to render text either horizontally or vertically:
| 每个字形都有叫跨距和步进的距离,它们的定义是常量,但是它们的值依赖布局,同样的字形可以用来渲染横向或纵向文字。
| ||||||||||||||||||||||||||
Here is a picture giving all the details for horizontal metrics:
| 下图是水平布局所有的度量 | ||||||||||||||||||||||||||
And here is another one for the vertical metrics:
| 下图是垂直布局的度量 | ||||||||||||||||||||||||||
| 4. The effects of grid-fitting | 4、网格对齐的效果 | ||||||||||||||||||||||||||
| Because hinting aligns the glyph's control points to the pixel grid, this process slightly modifies the dimensions of character images in ways that differ from simple scaling. | 因为hinting将字形的控制点对齐到象素网格,这个过程将稍稍修改字符图像的尺寸,和简单的缩放有所区别。 | ||||||||||||||||||||||||||
| For example, the image of the lowercase "m" letter sometimes fits a square in the master grid. However, to make it readable at small pixel sizes, hinting tends to enlarge its scaled outline in order to keep its three legs distinctly visible, resulting in a larger character bitmap. | 例如,小写字母m的图像在主网格中有时是一个正方形,但是为了使它在小象素大小情况下可以辨别,hinting试图扩大它已缩放轮廓,以让它三条腿区分开来,这将导致一个更大的字符位图。 | ||||||||||||||||||||||||||
The glyph metrics are also influenced by the grid-fitting process:
| 字形度量也会受网格对齐过程的影响:
| ||||||||||||||||||||||||||
This has some implications:
| 这有一些含义如下,
| ||||||||||||||||||||||||||
| Performing 2D transformations on glyph outlines is very easy with FreeType. However, when using translation on a hinted outlines, one should aways take care of exclusively using integer pixel distances (which means that the parameters to the FT_Outline_Translate() API should all be multiples of 64, as the point coordinates are in 26.6 fixed float format). | 在FT 中,对字形轮廓处理2D变换很简单,但是对一个已hint的轮廓,需要注意专有地使用整型象素距离(意味着FT_Outline_Translate() 函数的参数应该都乘以64,因为点坐标都是26.6固定浮点格式)。 | ||||||||||||||||||||||||||
| Otherwise, the translation will simply ruin the hinter's work, resulting in a very low quality bitmaps! | 否则,变换将破坏hinter的工作,导致非常难看的位图。 | ||||||||||||||||||||||||||
| 5. Text widths and bounding box | 5、文本宽度和边界框 | ||||||||||||||||||||||||||
| As seen before, the "origin" of a given glyph corresponds to the position of the pen on the baseline. It is not necessarily located on one of the glyph's bounding box corners, unlike many typical bitmapped font formats. In some cases, the origin can be out of the bounding box, in others, it can be within it, depending on the shape of the given glyph. | 如上所示,指定字形的原点对应基线上笔的位置,没有必要定位字形边界框的某个角,这不像多数典型的位图字体格式。有些情况,原点可以在边界框的外边,有时,也可以在里边,这要看给定的字形外形了。 | ||||||||||||||||||||||||||
| Likewise, the glyph's "advance width" is the increment to apply to the pen position during layout, and is not related to the glyph's "width", which really is the glyph's bounding width. | 同样,字形的步进宽度是在布局时应用于笔位置的增量,而不是字形的宽度,那是字形边界的宽度。 | ||||||||||||||||||||||||||
The same conventions apply to strings of text. This means that:
| 对文本串,具有相同的规约,这意味着:
| ||||||||||||||||||||||||||
| IV. Kerning | 四、字距调整 | ||||||||||||||||||||||||||
| The term kerning refers to specific information used to adjust the relative positions of coincident glyphs in a string of text. This section describes several types of kerning information, as well as the way to process them when performing text layout. | 字距调整这个术语指用来在一个文本串中调整重合字形的相对位置的特定信息。 | ||||||||||||||||||||||||||
| 1. Kerning pairs | 1、字距调整对 | ||||||||||||||||||||||||||
| Kerning consists of modifying the spacing between two successive glyphs according to their outlines. For example, a "T" and a "y" can be easily moved closer, as the top of the "y" fits nicely under the upper right bar of the "T". | 字距调整包括根据相邻字形的轮廓修改它们之间的距离。例如T和y可以贴得更近一点,因为y的上缘正好在T的右上角一横的下边。 | ||||||||||||||||||||||||||
When laying out text with only their standard widths, some consecutive glyphs seem a bit too close or too distant. For example, the space between the "A" and the "V" in the following word seems a little wider than needed.
| 当仅仅根据字形的标准宽度来布局文本,一些连续的字符看上去有点太挤和太松,例如下图中A和V的就显得距离太远。 | ||||||||||||||||||||||||||
Compare this to the same word, where the distance between these two letters has been slightly reduced:
| 比较一下下图,同样的单词,A和V的距离拉近些 | ||||||||||||||||||||||||||
As you can see, this adjustment can make a great difference. Some font faces thus include a table containing kerning distances for a set of given glyph pairs for text layout.
| 可以看到,这个调整可以导致很大的区别。有的字体外观包含一个表,它包含文本布局所需的指定字形对的字距距离。
| ||||||||||||||||||||||||||
| 2. Applying kerning | 2、应用字距调整 | ||||||||||||||||||||||||||
| Applying kerning when rendering text is a rather easy process. It merely consists in adding the scaled kern distance to the pen position before writing each next glyph. However, the typographically correct renderer must take a few more details in consideration. | 在渲染文本时应用字据调整是一个比较简单的过程,只需要在写下一个字形时,将缩放的字距加到笔位置即可。然而,正确的渲染器要考虑的更细一点。 | ||||||||||||||||||||||||||
The "sliding dot" problem is a good example: Many font faces include a kerning distance between capital letters like "T" or "F" and a following dot ("."), in order to slide the latter glyph just right to their main leg:
| "滑动点"问题是一个很好的例子:很多字体外观包括一个大写字符(如T、F)和一个点.之间的字距调整,以将点正好放置在前者的主腿的右侧。 | ||||||||||||||||||||||||||
This sometimes requires additional adjustments between the dot and the letter following it, depending on the shapes of the enclosing letters. When applying "standard" kerning adjustments, the previous sentence would become:
| 根据字符的外形,有时候需要在点和随后的字符间作附加的调整,当应用"标准"的字距调整,上面的句子如下 | ||||||||||||||||||||||||||
| This is clearly too contracted. The solution here, as exhibited in the first example, is to only slide the dots when possible. Of course, this requires a certain knowledge of the text's meaning. The above adjustments would not necessarily be welcome if we were rendering the final dot of a given paragraph. | 这显然太紧凑了。一个方案是,只在需要时滑动点,当然这需要对文本的意思有了解。如果当我们在渲染特定段落的最后一个点时,上面的调整就不适合了。 | ||||||||||||||||||||||||||
| This is only one example, and there are many others showing that a real typographer is needed to layout text properly. If not available, some kind of user interaction or tagging of the text could be used to specify some adjustments, but in all cases, this requires some support in applications and text libraries. | 这只是一个例子,还有很多其他例子显示一个真正的印刷工人需要恰当地布局文本。 | ||||||||||||||||||||||||||
For more mundane and common uses, however, we can have a very simple algorithm, which avoids the sliding dot problem, and others, though not producing optimal results. It can be seen as
| 有一个很简单地算法,可以避免滑动点问题。
| ||||||||||||||||||||||||||
| V. Text processing | 五、文本处理 | ||||||||||||||||||||||||||
| This section demonstrates how to use the concepts previously defined to render text, whatever the layout you use. | |||||||||||||||||||||||||||
| 1. Writing simple text strings | 1、书写简单文本串 | ||||||||||||||||||||||||||
In this first example, we will generate a simple string of Roman text, i.e. with a horizontal left-to-right layout. Using exclusively pixel metrics, the process looks like:
Note that kerning isn't part of this algorithm. | 在第一个例子中,我们将生成一个简单的Roman文字串,即采用水平的自左向右布局,使用专有的象素度量,这个过程如下:
注意字距调整不在这个算法中。 | ||||||||||||||||||||||||||
| 2. Sub-pixel positioning | 2、子象素定位 | ||||||||||||||||||||||||||
It is somewhat useful to use sub-pixel positioning when rendering text. This is crucial, for example, to provide semi-WYSIWYG text layouts. Text rendering is very similar to the algorithm described in subsection 1, with the following few differences:
| 在渲染文本时使用子象素定位有时很有用。这非常重要,例如为了提供半所见即所得的文本布局,文本渲染的算法和上一节很相似,但是有些区别:
| ||||||||||||||||||||||||||
Here an improved version of the algorithm:
Note that with fractional pixel positioning, the space between two given letters isn't fixed, but determined by the accumulation of previous rounding errors in glyph positioning. | 这里是算法的改进版本:
注意使用小数象素定位后,两个指定字符间的空间将不是固定的,它右先前的取整操作堆积的数决定。 | ||||||||||||||||||||||||||
| 3. Simple kerning | 3、简单字距调整 | ||||||||||||||||||||||||||
| Adding kerning to the basic text rendering algorithm is easy: When a kerning pair is found, simply add the scaled kerning distance to the pen position before step 4. Of course, the distance should be rounded in the case of algorithm 1, though it doesn't need to for algorithm 2. This gives us: | 在基本文本渲染算法上增加字距调整非常简单,当一个字距调整对发现了,简单地在第4步前,将缩放后的调整距离增加到笔位置即可。当然,这个距离在算法1需要被取整,算法2不必要。 | ||||||||||||||||||||||||||
Algorithm 1 with kerning:
| |||||||||||||||||||||||||||
Algorithm 2 with kerning:
| |||||||||||||||||||||||||||
| Of course, the algorithm described in section IV can also be applied to prevent the sliding dot problem if one wants to. | |||||||||||||||||||||||||||
| 4. Right-to-left layout | 4、自右向左布局 | ||||||||||||||||||||||||||
| The process of laying out Arabic or Hebrew text is extremely similar. The only difference is that the pen position must be decremented before the glyph rendering (remember: the advance width is always positive, even for Arabic glyphs). | 布局Arabic或Heberw文字的过程非常相似,区别只是在字形渲染前,笔位置需要减少(记住步进宽度总是正值) | ||||||||||||||||||||||||||
Right-to-left algorithm 1:
| |||||||||||||||||||||||||||
| The changes to algorithm 2, as well as the inclusion of kerning are left as an exercise to the reader. | |||||||||||||||||||||||||||
| 5. Vertical layouts | 5、垂直布局 | ||||||||||||||||||||||||||
Laying out vertical text uses exactly the same processes, with the following significant differences:
| 布局垂直文字也是同样的过程,重要的区别如下:
| ||||||||||||||||||||||||||
Here the algorithm:
| |||||||||||||||||||||||||||
| 6. WYSIWYG text layouts | 6、所见即所得布局 | ||||||||||||||||||||||||||
As you probably know, the acronym WYSIWYG stands for "What You See Is What You Get". Basically, this means that the output of a document on the screen should match "perfectly" its printed version. A true WYSIWYG system requires two things:
| |||||||||||||||||||||||||||
| It is clear that matching sizes cannot be possible if the computer has no knowledge of the physical resolutions of the display device(s) it is using. And of course, this is the most common case! That is not too unfortunate, however, because most users really don't care about this feature. Legibility is much more important. | |||||||||||||||||||||||||||
| When the Mac appeared, Apple decided to choose a resolution of 72 dpi to describe the Macintosh screen to the font sub-system (whatever the monitor used). This choice was most probably driven by the fact that, at this resolution, 1 point equals exactly 1 pixel. However, it neglected one crucial fact: As most users tend to choose a document character size between 10 and 14 points, the resultant displayed text was rather small and not too legible without scaling. Microsoft engineers took notice of this problem and chose a resolution of 96 dpi on Windows, which resulted in slightly larger, and more legible, displayed characters (for the same printed text size). | |||||||||||||||||||||||||||
| These distinct resolutions explain some differences when displaying text at the same character size on a Mac and a Windows machine. Moreover, it is not unusual to find some TrueType fonts with enhanced hinting (technical note: through delta-hinting) for the sizes of 10, 12, 14 and 16 points at 96 dpi. | |||||||||||||||||||||||||||
| The term device-independent text is, unfortunately, often abused. For example, many word processors, including MS Word, do not really use device-independent glyph positioning algorithms when laying out text. Rather, they use the target printer's resolution to compute hinted glyph metrics for the layout. Though it guarantees that the printed version is always the "nicest" it can be, especially for very low resolution printers (like dot-matrix), it has a very sad effect: Changing the printer can have dramatic effects on the whole document layout, especially if it makes strong use of justification, uses few page breaks, etc. | |||||||||||||||||||||||||||
| Because glyph metrics vary slightly when the resolution changes (due to hinting), line breaks can change enormously, when these differences accumulate over long runs of text. Try for example printing a very long document (with no page breaks) on a 300 dpi ink-jet printer, then the same one on a 3000 dpi laser printer: You will be extremely lucky if your final page count didn't change between the prints! Of course, we can still call this WYSIWYG, as long as the printer resolution is fixed. | |||||||||||||||||||||||||||
| Some applications, like Adobe Acrobat, which targeted device-independent placement from the start, do not suffer from this problem. There are two ways to achieve this: either use the scaled and unhinted glyph metrics when laying out text both in the rendering and printing processes, or simply use whatever metrics you want and store them with the text in order to get sure they are printed the same on all devices (the latter being probably the best solution, as it also enables font substitution without breaking text layouts). | |||||||||||||||||||||||||||
| Just like matching sizes, device-independent placement isn't necessarily a feature that most users want. However, it is pretty clear that for any kind of professional document processing work, it is a requirement. | |||||||||||||||||||||||||||
| VI. FreeType outlines | 六、FT轮廓 | ||||||||||||||||||||||||||
| The purpose of this section is to present the way FreeType manages vectorial outlines, as well as the most common operations that can be applied on them. | |||||||||||||||||||||||||||
| 1. FreeType outline description and structure | 1、FT轮廓描述和结构 | ||||||||||||||||||||||||||
| a. Outline curve decomposition | a. 轮廓曲线分解 | ||||||||||||||||||||||||||
| An outline is described as a series of closed contours in the 2D plane. Each contour is made of a series of line segments and Bézier arcs. Depending on the file format, these can be second-order or third-order polynomials. The former are also called quadratic or conic arcs, and they are used in the TrueType format. The latter are called cubic arcs and are mostly used in the Type 1 format. | 一个轮廓是2D平面上一系列封闭的轮廓线。每个轮廓线由一系列线段和Bezier弧组成,根据文件格式不同,曲线可以是二次和三次多项式,前者叫quadratic或conic弧,它们在TrueType格式中用到,后者叫cubic弧,多数用于Type1格式。 | ||||||||||||||||||||||||||
Each arc is described through a series of start, end, and control points. Each point of the outline has a specific tag which indicates whether it is used to describe a line segment or an arc. The tags can take the following values:
Use the FT_CURVE_TAG(tag) macro to filter out other, internally used flags. | 每条弧由一系列起点、终点和控制点描述,轮廓的每个点有一个特定的标记,表示它用来描述一个线段还是一条弧。这个标记可以有以下值:
| ||||||||||||||||||||||||||
The following rules are applied to decompose the contour's points into segments and arcs:
| 下面的规则应用于将轮廓点分解成线段和弧
| ||||||||||||||||||||||||||
Note that it is possible to mix conic and cubic arcs in a single contour, even though no current font driver produces such outlines.
| 注意,在单个轮廓线中可以混合使用conic和cubic弧,不过现在没有那种字体驱动产生这样的轮廓。 | ||||||||||||||||||||||||||
| b. Outline descriptor | b. 轮廓描述符 | ||||||||||||||||||||||||||
A FreeType outline is described through a simple structure:
| FT轮廓通过一个简单的结构描述
| ||||||||||||||||||||||||||
| Here, points is a pointer to an array of FT_Vector records, used to store the vectorial coordinates of each outline point. These are expressed in 1/64th of a pixel, which is also known as the 26.6 fixed float format. | 这里,points是一个FT_Vector记录数组的指针,用来存储每个轮廓点的向量坐标。它表示为一个象素1/64,也叫做26.6固定浮点格式。 | ||||||||||||||||||||||||||
| contours is an array of point indices used to delimit contours in the outline. For example, the first contour always starts at point 0, and ends at point contours[0]. The second contour starts at point contours[0]+1 and ends at contours[1], etc. | contours是一组点索引,用来划定轮廓的轮廓线。例如,第一个轮廓线总是从0点开始,以contours[0]点结束。第二个轮廓线从contours[0]+1点开始,以contours[1]结束,等等。 | ||||||||||||||||||||||||||
| Note that each contour is closed, and that n_points should be equal to contours[n_contours-1]+1 for a valid outline. | 注意,每条轮廓线都是封闭的,n_points应该和contours[n_controus-1]+1相同。 | ||||||||||||||||||||||||||
| Finally, tags is an array of bytes, used to store each outline point's tag. | 最后,tags是一组字节,用来存放每个轮廓的点标记。 | ||||||||||||||||||||||||||
| 2. Bounding and control box computations | 2、边界和控制框计算 | ||||||||||||||||||||||||||
| A bounding box (also called bbox) is simply a rectangle that completely encloses the shape of a given outline. The interesting case is the smallest bounding box possible, and in the following we subsume this under the term "bounding box". Because of the way arcs are defined, Bézier control points are not necessarily contained within an outline's (smallest) bounding box. | 边界框(bbox)是一个完全包含指定轮廓的矩形,所要的是最小的边界框。因为弧的定义,bezier的控制点无需包含在轮廓的边界框中。 | ||||||||||||||||||||||||||
| This situation happens when one Bézier arc is, for example, the upper edge of an outline and an "off" point happens to be above the bbox. However, it is very rare in the case of character outlines because most font designers and creation tools always place "on" points at the extrema of each curved edges, as it makes hinting much easier. | 例如轮廓的上缘是一个Bezier弧,一个off点就位于bbox的上面。不过这在字符轮廓中很少出现,因为大多字体设计者和创建工具都会在每个曲线拐点处放一个on点,这会使hinting更加容易。 | ||||||||||||||||||||||||||
| We thus define the control box (also called cbox) as the smallest possible rectangle that encloses all points of a given outline (including its "off" points). Clearly, it always includes the bbox, and equates it in most cases. | 于是我们定义了控制框(cbox),它是一个包含轮廓所有点的最小矩形,很明显,它包含bbox,通常它们是一样的。 | ||||||||||||||||||||||||||
Unlike the bbox, the cbox is much faster to compute.
| 不像 bbox,cbox计算起来非常快。 | ||||||||||||||||||||||||||
| Control and bounding boxes can be computed automatically through the functions FT_Outline_Get_CBox() and FT_Outline_Get_BBox(). The former function is always very fast, while the latter may be slow in the case of "outside" control points (as it needs to find the extreme of conic and cubic arcs for "perfect" computations). If this isn't the case, it is as fast as computing the control box. | 控制框和边界框可以通过函数FT_Outline_Get_CBox()和 FT_Outline_Get_BBox()自动计算,前者总是非常快,后者在有外界控制点的情况下会慢一点,因为需要找到conic和cubic弧的末端,如果不是这种情况,它和计算控制框一样快。 | ||||||||||||||||||||||||||
| Note also that even though most glyph outlines have equal cbox and bbox to ease hinting, this is not necessary the case anymore when a transformation like rotation is applied to them. | 注意,虽然大多字形轮廓为易于hint具有相同的cbox和bbox,这在它们进行变换以后,如旋转,就不再是这种情况了。 | ||||||||||||||||||||||||||
| 3. Coordinates, scaling and grid-fitting | 3、坐标、缩放和网格对齐 | ||||||||||||||||||||||||||
| An outline point's vectorial coordinates are expressed in the 26.6 format, i.e. in 1/64th of a pixel, hence the coordinates (1.0,-2.5) is stored as the integer pair (x:64,y:-192). | 轮廓点的向量坐标表示为26.6格式,即一个象素的1/64。因此,坐标(1.0,-2.5)存放整型对(x:64,y:-192)。 | ||||||||||||||||||||||||||
| After a master glyph outline is scaled from the EM grid to the current character dimensions, the hinter or grid-fitter is in charge of aligning important outline points (mainly edge delimiters) to the pixel grid. Even though this process is much too complex to be described in a few lines, its purpose is mainly to round point positions, while trying to preserve important properties like widths, stems, etc. | 在主字形轮廓从EM网格缩放到当前字符大小后,hinter负责对齐重要的轮廓点到象素网格。虽然这个过程很难几句话说清楚,但是它的目的也就是取整点的位置,以保持字形重要的特性,如宽度、主干等。 | ||||||||||||||||||||||||||
The following operations can be used to round vectorial distances in the 26.6 format to the grid:
| 下面的操作可以用来将26.6格式的向量距离取整到网格:
| ||||||||||||||||||||||||||
| Once a glyph outline is grid-fitted or transformed, it often is interesting to compute the glyph image's pixel dimensions before rendering it. To do so, one has to consider the following:
The scan-line converter draws all the pixels whose centers fall inside the glyph shape. It can also detect drop-outs, i.e. discontinuities coming from extremely thin shape fragments, in order to draw the "missing" pixels. These new pixels are always located at a distance less than half of a pixel but it is not easy to predict where they will appear before rendering. | 一旦一个字形轮廓经过对齐或变换,在渲染之前通常要计算字形的图像象素大小。做到这一点,必须考虑如下:
扫描线转换器画出所有中心在字形形状中的象素,他也可以检测drop-outs??? | ||||||||||||||||||||||||||
This leads to the following computations:
| 这导致如下的计算:
| ||||||||||||||||||||||||||
| By grid-fitting the bounding box, it is guaranteed that all the pixel centers that are to be drawn, including those coming from drop-out control, will be within the adjusted box. Then the box's dimensions in pixels can be computed. | 通过对齐bbox,可以保证所有的象素中心将画到,包括那些从drop-out控制来的,将在调整后的框子之中。接着,框子的象素尺寸可以计算出来。 | ||||||||||||||||||||||||||
| Note also that, when translating a grid-fitted outline, one should always use integer distances to move an outline in the 2D plane. Otherwise, glyph edges won't be aligned on the pixel grid anymore, and the hinter's work will be lost, producing very low quality bitmaps and pixmaps. | 同时注意,当平移一个对齐的轮廓,应该总是使用整型距离来移动。否则,字形的边缘将不再对齐象素网格,hinter的工作将无效,产生非常难看的位图。 | ||||||||||||||||||||||||||
| VII. FreeType bitmaps | 七、FT位图 | ||||||||||||||||||||||||||
| The purpose of this section is to present the way FreeType manages bitmaps and pixmaps, and how they relate to the concepts previously defined. The relationships between vectorial and pixel coordinates is explained. | |||||||||||||||||||||||||||
| 1. Vectorial versus pixel coordinates | 1、向量坐标和象素坐标对比 | ||||||||||||||||||||||||||
| This sub-section explains the differences between vectorial and pixel coordinates. To make things clear, brackets will be used to describe pixel coordinates, e.g. [3,5], while parentheses will be used for vectorial ones, e.g. (-2,3.5). | 这里阐述了向量坐标的象素坐标的区别,为了更清楚的说明,使用方括号来表示象素坐标,使用圆括号表示向量坐标。 | ||||||||||||||||||||||||||
| In the pixel case, as we use the Y upwards convention; the coordinate [0,0] always refers to the lower left pixel of a bitmap, while coordinate [width-1, rows-1] to its upper right pixel. | 在象素坐标中,我们使用Y轴向上的规约,坐标[0,0]总是指位图左下角象素,坐标[width-1, rows-1]是右上角象素。 | ||||||||||||||||||||||||||
| In the vectorial case, point coordinates are expressed in floating units, like (1.25, -2.3). Such a position doesn't refer to a given pixel, but simply to an immaterial point in the 2D plane. | 在向量坐标中,点坐标用浮点单位表示,如(1.25, -2.3),这个位置并不是指一个特定象素,而是在2D平面上一个非实质性的点。 | ||||||||||||||||||||||||||
| The pixels themselves are indeed square boxes of the 2D plane, whose centers lie in half pixel coordinates. For example, the lower left pixel of a bitmap is delimited by the square (0,0)-(1,1), its center being at location (0.5,0.5). | 象素其实在2D平面上是一个方块,它的中心是象素坐标值的一半,例如位图的左下角象素通过方块(0,0)-(1,1)界定,它的中心位于 (0.5,0.5)。注意这儿用的是向量坐标表示。 | ||||||||||||||||||||||||||
This introduces some differences when computing distances. For example, the length in pixels of the line [0,0]-[10,0] is 11. However, the vectorial distance between (0,0)-(10,0) covers exactly 10 pixel centers, hence its length is 10.
| 这对计算距离就会发生一些区别。例如,[0,0]-[10.0]一条线的象素长度是11,然而, (0,0)-(10,0)的向量程度覆盖了10个象素,因此它的长度是10。 | ||||||||||||||||||||||||||
| 2. FreeType bitmap and pixmap descriptor | 2、FT位图和象素图描述符 | ||||||||||||||||||||||||||
A bitmap or pixmap is described through a single structure, called FT_Bitmap, defined in the file <freetype/ftimage.h>. It is a simple descriptor whose fields are:
| 一个位图和象素图通过一个叫FT_Bitmap的单一结构描述,他定义在中,属性如下
| ||||||||||||||||||||||||||
| Note that the sign of the pitch fields determines whether the rows in the pixel buffer are stored in ascending or descending order. | pitch 属性值的正负符号确定象素缓冲中的行是升序还是降序存放。 | ||||||||||||||||||||||||||
| Remember that FreeType uses the Y upwards convention in the 2D plane, which means that a coordinate of (0,0) always refer to the lower-left corner of a bitmap. | 上面说道FT在2D平面上使用Y轴向上的规约,这意味着(0,0)总是指向位图的左下角。 | ||||||||||||||||||||||||||
| If the pitch is positive, the rows are stored in decreasing vertical position; the first bytes of the pixel buffer are part of the upper bitmap row. | 如果 picth是正值,按照向量减少的方向存储行,即象素缓冲的第一个字节表示位图最上一行的部分。 | ||||||||||||||||||||||||||
| On the opposite, if the pitch is negative, the first bytes of the pixel buffer are part of the lower bitmap row. | 如果是负值,第一个字节将表示位图最下一行的部分。 | ||||||||||||||||||||||||||
| In all cases, one can see the pitch as the byte increment needed to skip to the next lower scanline in a given bitmap buffer. | 对所有的情况,pitch可以看作是在指定位图缓冲中,跳到下一个扫描行的字节增量。 | ||||||||||||||||||||||||||
| : negative 'pitch' positive 'pitch' | |||||||||||||||||||||||||||
| The "positive pitch" convention is very often used, though some systems might need the other. | 通常都使用正pitch,当然有的系统会使用负值。 | ||||||||||||||||||||||||||
| 3. Converting outlines into bitmaps and pixmaps | 3、轮廓转换到位图和象素图 | ||||||||||||||||||||||||||
Generating a bitmap or pixmap image from a vectorial image is easy with FreeType. However, one must understand a few points regarding the positioning of the outline in the 2D plane before converting it to a bitmap:
| 使用FT从一个向量图像转换到位图和象素图非常简单,但是,在转换前,必须理解有关在2D平面上放置轮廓的一些问题:
| ||||||||||||||||||||||||||
A common mistake made by many developers when they begin using FreeType is believing that a loaded outline can be directly rendered in a bitmap of adequate dimensions. The following images illustrate why this is a problem.
| 很多使用FT的开发者都会有个误解,认为一个装入的轮廓可以直接渲染成一个适当大小的位图,下面的图像表明这个问题。
| ||||||||||||||||||||||||||
| Indeed, in nearly all cases, the loaded or transformed outline must be translated before it is rendered into a target bitmap, in order to adjust its position relative to the target window. | 实际上,几乎所有的情况,装入或变换过的轮廓必须在渲染成目标位图之前作平移操作,以调整到相对目标窗口的位置。 | ||||||||||||||||||||||||||
For example, the correct way of creating a standalone glyph bitmap is as follows
| 例如,创建一个单独的字形位图正确的方法如下:
| ||||||||||||||||||||||||||
| In the case where one wants to write glyph images directly into a large bitmap, the outlines must be translated so that their vectorial position correspond to the current text cursor/character origin. | 在将字形图像直接写入一个大位图的情况,轮廓必须经过平移,以将它们的向量位置对应到当前文本光标/字符原点上。 |

