FreeTypeとは
FreeTypeはフォント描画ライブラリです。
フォントファイルのファイルパス/ファイルデータを読み込んで、指定された文字のビットマップやそれに付随する情報を取得することができます。
C言語で書かれているため、様々なOSで動かすことができます。
(少なくともWindows, macOS, Ubuntu, Android, iOSでは動作しました)
FreeTypeの準備
- ビルドする
- カラー絵文字(PNG)を読み込む場合
-
ftoption.hの#define FT_CONFIG_OPTION_USE_PNGを有効にする - この場合はlibpngが必要になる(インクルードディレクトリに追加)
-
- WindowsならVisual Studioのプロジェクトファイルを使えばOK
- 他のデスクトップOSならautogen.shとかconfigureとかmakeで普通にビルドできるはず
- iOSとmacOSなら適当にXcodeプロジェクトを作って
.cファイルを追加するだけもOK - Androidなら
CMakeFile.txtに必要な.cファイルを追加する- ビルドに必要な
.cはVisual Studioのプロジェクトを見ればわかる気がする
- ビルドに必要な
- カラー絵文字(PNG)を読み込む場合
- 作成するプログラムのプロジェクトから
- インクルードディレクトリを追加
- スタティックライブラリをリンクする
- カラー絵文字(PNG)を使う場合はlibpngもリンクする
FreeTypeの利用
一番使いたい関数を探しやすいのはここかな。
FreeTypeの基本的な使い方は以下のとおり。
- includeする
-
#include <ft2build.h>- まずincludeするべきはこれ
-
#include FT_FREETYPE_H- 他のヘッダは上みたく
#defineされてる - 必要なものを適宜includeする
- 他のヘッダは上みたく
-
-
FT_Library library;を初期化する-
FT_Init_FreeType(&library)する -
libraryはFreeTypeを使っている間はずっと使用します
-
-
FT_Face face;を用意する-
FT_New_Face(library, font_path, font_index, &face)- フォントのパスから作成する
-
FT_New_Memory_Face(library, font_data_memory, font_data_length, font_index, &face)- メモリ上のフォントデータから作成する
- ここで
font_indexはttcやotcの場合に読み込まれるフォントを指定するもの - ひとつの
libraryで複数のfaceを持てる
-
- 用意した
faceを使って色々する- グリフを取得するとか
-
FT_Face face;を破棄するFT_Done_Face(face)
-
FT_Library library;を破棄するFT_Done_FreeType(library)
フォントファイルの取得方法
フォントファイルは大抵の場合、どこかのフォルダにまとめて格納されています。
ただ、そうしたフォントファイルの管理はOSに密に結びついていることが多いです。
そのため、その場所を知るためのクロスプラットフォームな方法は存在しません。
おや、IMEのときにも似たようなことが……?
素晴らしき世界(文字列周りの平常運行)。
- Windowsではパスを取得するのが穏便な方法(DirectWrite以降)
- それよりも前のOSならバイナリを取得しましょう
- ただしMacTypeというソフトによって動かなくなります
- それよりも前のOSならバイナリを取得しましょう
- macOSではメモリ上に頑張ってフォントファイルを組み上げる
- フォントテーブルごとに取得して結合して綺麗にする
- Ubuntuなどではパスを取得
- Fontconfigというものがありましてね
FreeTypeのサンプル
基本的に必要なことは3つくらいです。
- グリフのIDを取得する
- ビットマップグリフを取得する
- アウトライングリフを取得する
他にもアウトラインを変形したり、描画オプションを指定したりといったこともできますが些細なことです。
グリフIDの取得
cmapをいい感じに読み込んで変換してくれます。
GID 0が返ってきた場合は見つからなかった場合です。
複数のフォントを使用していないならGID 0をそのまま使えばOKです。
- Unicodeのコードポイントから
FT_Get_Char_Index(face, unicode)
- UVSが付いている場合
FT_Face_GetCharVariantIndex(face, unicode, uvs)- 0が返ってきたら
FT_Get_Char_Index(face, unicode)にフォールバックする
ビットマップグリフを取得する
-
FT_Select_Size(face, size_index)-
size_indexはface->available_sizesと欲しいサイズをみて決める
-
-
FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT)- このとき
face->glyph->format == FT_GLYPH_FORMAT_BITMAPなら埋め込みビットマップ -
face->glyph->bitmapに(多くの場合モノクロの)ビットマップが入ってる
- このとき
ビットマップグリフ(カラー絵文字)を取得する
- 上の2.で
FT_Load_Glyph(face, gid, FT_LOAD_DEFAULT | FT_LOAD_COLOR)する-
FT_LOAD_COLORを追加されてる - このとき
face->glyph->format == FT_GLYPH_FORMAT_BITMAP && face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRAならカラー絵文字(PNG) -
face->glyph->bitmapにBGRAビットマップが入ってる
-
アウトライングリフを取得する
- 生のアウトラインデータを取得する場合
FT_Load_Glyph(face, gid, FT_LOAD_NO_SCALE | FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_BITMAP)- Composite GlyphはFreeTypeが処理してくれる
- 適切なサイズにスケーリング・ヒンティングしたものを取得する場合
FT_Set_Pixel_Sizes(f->face, width, height)-
FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP)-
face->glyph->outlineにアウトラインが入ってる
-
- (オプション)
face->glyph->outlineをラスタライズするFT_Render_Glyph(face->glyph, FT_RENDER_MODE_LCD)-
FT_RENDER_MODE_LCDはFT_RENDER_MODE_NORMAL等、適切なものを選ぶ
おわりに
さて、とても簡単にFreeTypeのコードの基本的な使い方について書きました。
ちなみに、縦書きをFreeTypeで適切に扱うのは難しいです。頑張ってください。
明日はICUかwxWidgetsについて書きます(多分)。