FreeTypeの使い方

# FreeTypeとは
[FreeType](https://www.freetype.org)はフォント描画ライブラリです。
フォントファイルのファイルパス/ファイルデータを読み込んで、指定された文字のビットマップやそれに付随する情報を取得することができます。
C言語で書かれているため、様々なOSで動かすことができます。
（少なくともWindows, macOS, Ubuntu, Android, iOSでは動作しました）

# FreeTypeの準備

1. ビルドする
    - カラー絵文字（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のプロジェクトを見ればわかる気がする
2. 作成するプログラムのプロジェクトから
    - インクルードディレクトリを追加
    - スタティックライブラリをリンクする
        - カラー絵文字（PNG）を使う場合はlibpngもリンクする

# FreeTypeの利用
一番使いたい関数を探しやすいのは[ここ](https://www.freetype.org/freetype2/docs/reference/ft2-index.html)かな。
FreeTypeの基本的な使い方は以下のとおり。

1. includeする
    - `#include <ft2build.h>`
        - まずincludeするべきはこれ
    - `#include FT_FREETYPE_H`
        - 他のヘッダは上みたく`#define`されてる
        - 必要なものを適宜includeする
2. `FT_Library library;`を初期化する
    - `FT_Init_FreeType(&library)`する
    - `library`はFreeTypeを使っている間はずっと使用します
3. `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`を持てる
4. 用意した`face`を使って色々する
    - グリフを取得するとか
5. `FT_Face face;`を破棄する
    - `FT_Done_Face(face)`
6. `FT_Library library;`を破棄する
    - `FT_Done_FreeType(library)`

## フォントファイルの取得方法
フォントファイルは大抵の場合、どこかのフォルダにまとめて格納されています。
ただ、そうしたフォントファイルの管理はOSに密に結びついていることが多いです。
そのため、その場所を知るためのクロスプラットフォームな方法は存在しません。
おや、IMEのときにも似たようなことが……？
素晴らしき世界（文字列周りの平常運行）。

- Windowsではパスを取得するのが穏便な方法（DirectWrite以降）
    - それよりも前のOSならバイナリを取得しましょう
        - ただしMacTypeというソフトによって動かなくなります
- 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)`にフォールバックする

## ビットマップグリフを取得する

1. `FT_Select_Size(face, size_index)`
    - `size_index`は`face->available_sizes`と欲しいサイズをみて決める
2. `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が処理してくれる
- 適切なサイズにスケーリング・ヒンティングしたものを取得する場合
    1. `FT_Set_Pixel_Sizes(f->face, width, height)`
    2. `FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP)`
        - `face->glyph->outline`にアウトラインが入ってる
    3. (オプション)`face->glyph->outline`をラスタライズする
        - `FT_Render_Glyph(face->glyph, FT_RENDER_MODE_LCD)`
        - `FT_RENDER_MODE_LCD`は`FT_RENDER_MODE_NORMAL`等、適切なものを選ぶ

# おわりに
さて、とても簡単にFreeTypeのコードの基本的な使い方について書きました。
ちなみに、縦書きをFreeTypeで適切に扱うのは難しいです。頑張ってください。

明日はICUかwxWidgetsについて書きます（多分）。