原文地址 https://freetype.org/freetype2/docs/glyphs/glyphs-7.html
- 向量座標 和 畫素座標 Vectorial versus pixel coordinates
- FT_Bitmap描述符 The FT_Bitmap descriptor
- 將輪廓線轉化為點陣圖 Converting outlines into bitmaps and pixmaps
這一節的目標是展示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.
在想要將字形影像直接寫入大點陣圖的情況下,必須將輪廓線進行變換,使其向量位置與當前文字游標或字元原點相對應。