FreeType Glyph Conventions 翻译(7)——FreeType点阵图 Bitmaps

原文地址 https://freetype.org/freetype2/docs/glyphs/glyphs-7.html

这一节的目标是展示FreeType管理点阵图(bitmaps)和像素图(pixmaps)的方式,以及它们如何和之前的知识点相联系。矢量坐标和像素坐标的关系会得到解释。

矢量坐标 和 像素坐标 Vectorial versus pixel coordinates

This sub-section explains the difference 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)’.
这一小节会解释向量坐标和像素坐标的区别。为了让事情更清楚,方括号会被用于描述像素坐标,[3,5],而圆括号会用于描述矢量坐标,比如(-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。

FT_Bitmap描述符 The FT_Bitmap descriptor

在FreeType中,点阵图通过数据结构FT_Bitmap描述,我们感兴趣的字段有:

| rows       | 位图中的行数,即行数  the number of rows, i.e., lines, in the bitmap |                                                                                                                                           
| width      | 位图中的水平像素数 the number of horizontal pixels in the bitmap      |                                                                                                                                       
| pitch      | 绝对值是每行的字节数 its absolute value is the number of bytes per bitmap line; it can be either positive or negative depending on the bitmap's vertical orientation   |
| buffer     | 指向位图像素缓冲区的无类型指针 a typeless pointer to the bitmap pixel buffer     |                                                                                                                                        
| pixel_mode | 用于描述位图的像素格式的枚举;an enumeration used to describe the pixel format of the bitmap; examples are ft_pixel_mode_mono for 1-bit monochrome bitmaps and ft_pixel_mode_grays for 8-bit anti-aliased ‘gray’ values |
| num_grays  | 这只用于“gray”像素模式,它给出了用于描述抗锯齿灰度级的灰度级数量 this is only used for ‘gray’ pixel modes, it gives the number of gray levels used to describe the anti-aliased gray levels (256 by default with FreeType 2)                               |

pitch ——the level of intensity of something

Note that the sign of the pitch field 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 refers to the lower-left corner of a bitmap.
请记住,FreeType在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.
如果pitch 为正,则像素行以递减的顺序存储;像素缓冲区的第一个字节是上部位图行的一部分。

On the opposite, if the pitch is negative, the first bytes of the pixel buffer are part of the lower bitmap row.
相反,如果pitch 为负,则像素缓冲区的第一个字节是较低位图行的一部分。

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看做是跳过一行的字节数。

The ‘positive pitch’ convention is very often used, though some systems might need the other.
pitch为正的情况非常普遍,也就是说大部分情况下,像素缓冲区的第一个字节经常是左上角那(几)个像素。

To speed up memory access, pitch is in most cases a multiple of 16bit, 32bit, or even 64bit. It often happens that the pitch is thus larger than the necessary bits (or bytes) for a bitmap or pixmap row; in such cases, unused bits (or bytes) are at the very right (i.e., the end) of a row.
为了加快内存访问速度,pitch 在大多数情况下是2字节、4字节甚至8字节的倍数。pitch的值经常大于像素图一行 所需的字节;在这种情况下,未使用的位(或字节)位于一行的最右边(即末尾)。

比如 pitch是2,但一行只有一个像素,那么一行中的2个字节,最右边那个字节未被使用。
pitch还会影响monochrome图片格式的读取, 见 https://stackoverflow.com/questions/14800827/indexing-pixels-in-a-monochrome-freetype-glyph-buffer

将轮廓线转化为点阵图 Converting outlines into bitmaps and pixmaps

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:
使用FreeType可以很容易地从矢量图像生成像素图像。然而,在将轮廓线转换为点阵图之前,必须了解与轮廓线在2D平面中的定位有关的几点:

  • The glyph loader and hinter always places the outline in the 2D plane so that (0, 0) matches its character origin. This means that the glyph's outline (and corresponding bounding box) can be placed anywhere in the 2D plane (see the graphics in section III).
    字形加载器和启发器总是将轮廓线放置在2D平面中,以便(0,0)与原点匹配。这意味着字形的轮廓线(和相应的边界框)可以放置在2D平面中的任何位置(请参见第三节中的图形)。

  • The target bitmap's area is mapped to the 2D plane, with its lower left corner at (0, 0). This means that a bitmap or pixmap of dimensions [w, h] will be mapped to a 2D rectangle window delimited by (0, 0)-(w, h).
    目标位图的区域将映射到2D平面,其左下角位于(0,0)。这意味着尺寸[w,h]的位图或像素图将被映射到(0,0)-(w,h)的2D矩形窗口。

  • When scan-converting the outline, everything that falls within the bitmap window is rendered, the rest is ignored.
    当转换轮廓线时,位图窗口中的所有内容都会被渲染,其余部分将被忽略。

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.
许多开发人员在开始使用FreeType时犯的一个常见错误是,他们认为加载的轮廓可以直接呈现在足够尺寸的位图中。下图说明了出现此问题的原因。

  • The first image shows a loaded outline in the 2D plane.
    第一个图像显示了2D平面中加载的轮廓。
  • The second one shows the target window for a bitmap of arbitrary dimensions [w, h].
    第二个显示了任意维度[w,h]的位图的目标窗口。
  • The third one shows the juxtaposition of the outline and window in the 2D plane.
    第三个显示了轮廓线和窗口同时出现在2D平面中。
  • The last image shows what will really be rendered in the bitmap.
    最后一张图像显示了位图中实际渲染的内容。

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 stand-alone glyph bitmap is as follows:
例如,创建单独一个 字符图形的点阵图 的正确方法如下:

  • Get the size of the glyph bitmap. It can be computed directly from the glyph metrics, or by computing its bounding box (this is useful when a transformation has been applied to the outline after loading it, as the glyph metrics are not valid anymore).
    获取字形点阵图的大小。它可以直接从字形参数计算,也可以通过计算其边界框来计算(当加载轮廓后将变换应用于轮廓线后,这很有用,因为此时字形参数不再有效)。

  • Create the bitmap with the computed dimensions. Don't forget to fill the pixel buffer with the background color.
    使用计算的尺寸创建点阵图。不要忘记用背景色填充像素缓冲区。

  • Translate the outline so that its lower left corner matches (0, 0). Don't forget that in order to preserve hinting, one should use integer, i.e., rounded distances (of course, this isn't required if preserving hinting information doesn't matter, like with rotated text). Usually, this means translating with a vector (-ROUND(xMin), -ROUND(yMin)).
    平移轮廓线,使其左下角与(0,0)匹配。不要忘记,为了保留启发信息,应该使用整数,即取整的距离。通常,这意味着使用向量(-ROUND(xMin),-ROUNT(yMin))进行变换。

  • Call the rendering function (it can be FT_Outline_Render, for example).
    调用渲染函数(例如,它可以是FT_Outline_Render)。

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 corresponds to the current text cursor or character origin.
在想要将字形图像直接写入大点阵图的情况下,必须将轮廓线进行变换,使其矢量位置与当前文本光标或字符原点相对应。

posted @ 2024-03-26 21:43  dewxin  阅读(96)  评论(0编辑  收藏  举报