天天看點

freetype-go學習什麼是FreeType?步驟freetype-go

它的作用是生成帶文字的png圖檔

首先解決的幾個概念:

freetype是一個可移植的,高效的字型引擎。

字型在電腦上的顯示有兩種方式:點陣和矢量。對于一個字,點陣字型儲存的是每個點的渲染資訊。這個方式的劣勢在于儲存的資料量非常大,并且對放大縮小等操作支援不好。是以出現了矢量字型。對于一個字,矢量字型儲存的是字的繪制公式。這個繪制公式包括了字型輪廓(outline)和字型精調(hint)。字型輪廓使用貝塞爾曲線來繪制出字的外部線條。在大分辨率的情況下就需要對字型進行精調了。這個繪制字的公式就叫做字型資料(glyph)。在字型檔案中,每個字對應一個glyph。那麼字型檔案中就存在一個字元映射表(charmap)。

對于矢量字型,其中用的最為廣泛的是truetype。它的擴充名一般為otf或者ttf。在windows,linux,osx上都得到廣泛支援。我們平時看到的.ttf和.ttc的字型檔案就是truetype字型。其中ttc是多個ttf的集合檔案(collection)。

truetype隻是一個字型,而要讓這個字型在螢幕上顯示,就需要字型驅動庫了。其中freetype就是這麼一種高效的字型驅動引擎。一個漢字從字型到顯示freetype大緻有幾個步驟:

加載字型

設定字型大小

加載glyph

字型對應大小等轉換

繪制字型

這裡特别注意的是freetype并不隻能驅動truetype字型,它還可以驅動其他各種矢量字型,甚至也可以驅動點陣字型。

是以freetype-go就是用go語言實作了freetype驅動。

this is an implementation of the freetype font engine in the go programming language.

代碼示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

<code>// 畫一個帶有text的圖檔</code>

<code>func (this *signer) drawstringimage(text string) (image.image, error) {</code>

<code>    </code><code>fontbytes, err := ioutil.readfile(this.fontpath)</code>

<code>    </code><code>if</code> <code>err != nil {</code>

<code>        </code><code>return</code> <code>nil, err</code>

<code>    </code><code>}</code>

<code>    </code><code>font, err := freetype.parsefont(fontbytes)</code>

<code>    </code><code>fg, bg :=  image.white, image.black</code>

<code>    </code><code>rgba := image.newrgba(image.rect(0, 0, 900, 900))</code>

<code>    </code><code>draw.draw(rgba, rgba.bounds(), bg, image.zp, draw.src)</code>

<code>    </code><code>c := freetype.newcontext()</code>

<code>    </code><code>c.setdpi(this.dpi)</code>

<code>    </code><code>c.setfont(font)</code>

<code>    </code><code>c.setfontsize(this.fontsize)</code>

<code>    </code><code>c.setclip(rgba.bounds())</code>

<code>    </code><code>c.setdst(rgba)</code>

<code>    </code><code>c.setsrc(fg)</code>

<code>    </code><code>// draw the text.</code>

<code>    </code><code>pt := freetype.pt(10, 10+int(c.pointtofix32(12)&gt;&gt;8))</code>

<code>    </code><code>for</code> <code>_, s := range strings.split(text,</code><code>"\r\n"</code><code>) {</code>

<code>        </code><code>_, err = c.drawstring(s, pt)</code>

<code>        </code><code>pt.y += c.pointtofix32(12 * 1.5)</code>

<code>    </code><code>return</code> <code>rgba, nil</code>

<code>}</code>