2013年3月9日 星期六

Harfbuzz:複雜文字排列的好幫手

經常被使用在OpenGL遊戲設計上的freetype2不只可以依照所選定字型檔來將文字點陣化,點陣化的文字接著被使用在OpenGL場景中。上面所描述的是當一個OpenGL軟體要使用文字的時候的最常見用法,也是許多線上教學會教各位的方法。

然而,freetype2所提供的layout engine無法使用OpenType所提供的許多更進階的文字繪圖指示(例如說某些阿拉伯文字)。這樣子的功能必須由更為專業的layout engine來代勞,像是pango。

仔細調查後會發現pango的相關功能是由harfbuzz所提供的。也就是,我們可以繞過又大又重的pango(使用pango會增加對glib的依賴性),直接調用harfbuzz來進行複雜文字繪圖的工作。此外,直接使用harfbuzz的程式不只可以利用系統字型(需要直接指定系統字型的檔案位置。可以用fontconfig來解決這個問題),還可以使用軟體自帶的字型檔案。

由於harfbuzz沒有文件檔案,範例檔案又寫得相當之高深(看完原始碼中util/hb-shape.cc之後的感想是:作者大人實在有夠強大!),所以只好花時間在網路上不斷的看人討論的文章。

在和harfbuzz奮鬥三天(左右)之後,找到了以下的範例檔案:

而且自己動手做了一個小程式,放在Github

我使用的流程和上面所列出的範例檔不同:首先,我把字型檔案利用mmap整個讀取進記憶體,接著利用harfbuzz載入它,用freetype2來繪製字型,最後由libpng把輸出的圖形放到png圖檔中。

當我看著由這個小巧的自製小程式所繪出的精美阿拉伯文字時,我整個人都飛躍了起來,超開心!

7 則留言:

  1. 作者已經移除這則留言。

    回覆刪除
  2. ex-sdl-cairo-freetype-harfbuzz 这个例子编译不过。 您放到Github上的例子也没有写明如何编译呢?

    回覆刪除
  3. 第3个例子已经编译过去了,十分感谢您的分享。基于0.9.16版本以上的harfbuzz。

    回覆刪除
  4. 對不起,很久都沒有時間來照顧這裡 T_T

    其實 github 連結再往上一層,可以看到 Makefile

    總之謝謝您的使用喔 ^^ 歡迎再交流^^

    回覆刪除
  5. 抱歉我看錯了

    我的github裡面有個CMakeList.txt

    這樣才對@@

    回覆刪除
  6. 哦,我之前没有使用过cmake,我下去了解一下,我有一个关于PPI设置的问题。我想模拟真实的LCD的分辨率,我知道它的PPI,比较低为84. 我如何设置SDL,harfbuzz或者freetype的参数能让和低分辨率LCD上显示效果更接近?谢谢

    回覆刪除
  7. 我想您應該可以參考 hb_font_set_scale, hb_font_set_ppem, hb_font_get_upem (harfbuzz)

    upem: unit per em, ppem: points per em (詳見http://www.truetype-typography.com/ttglossp.htm)

    或者是 FT_Set_Char_Size 以及 FT_Set_Pixel_Sizes (FreeType2)

    回覆刪除