トップ > コンピューティング環境 > FreeType に関するメモ

[前ページ] [次ページ]


FreeType に関するメモ

Author: Takeshi Fujiyoshi
Last update: 2010/06/26

目次

対象バージョン

FreeType-2.3.12 で確認したものである。

インストール

ネイティブビルド

メジャーな UNIX 系の OS はパッケージシステムを持っているものが多いので、 そこからインストールするのが簡単かと。

NetBSD の場合:

# cd /usr/pkgsrc/graphics/freetype2
# make install

手動でインストールする場合は、doc/INSTALL.* を参照。 UNIX 系の OS ではソースコードを展開し、:

$ ./configure
$ make
# make install

で良いのだけど、GNU make 3.80 以上が必須らしく、 configure が GNU make のバージョンをチェックするため NetBSD のように GNU make のコマンド名が違うときは明示する必要がある。:

$ GNUMAKE=gmake ./configure
$ gmake
# gmake install

クロスビルド

FreeType の最近のバージョンはクロスビルドに正式に対応している。 詳しくはドキュメント doc/INSTALL.CROSS を参照。

以下は MinGW 用の FreeType ライブラリを UNIX 上でクロスビルドする 例である。但し、MinGW のクロスツールが mingw32-* というコマンド名で インストール済みであると仮定する:

$ cd freetype-2.3.12
$ GNUMAKE=gmake ./configure --host=mingw32 --prefix=/usr/local/mingw32
$ gmake
# gmake install

この結果、/usr/local/mingw32 以下に FreeType のライブラリ、 ヘッダファイルなどがインストールされる。

ライブラリの使い方

コード例

  1. ヘッダファイル:

    #include <ft2build.h>
    #include FT_FREETYPE_H
    
  2. ライブラリの初期化:

    FT_Library library;
    err = FT_Init_FreeType(&library);
    if (err) { エラー処理 ... }
    
  3. フォントフェースをロード:

    1. フォントファイルからロード:

      FT_Face face;
      err = FT_New_Face(library, "/any/where/mona.ttf", 0, &face);
      if (err) { エラー処理 ... }
      

      第3引数にはフェースインデックスを指定する。 フォントファイルは複数のフェースを含む場合もある。

    2. メモリ上に展開されたフォントデータからロード:

      FT_Face face;
      err = FT_New_Memory_Face(library, buffer, size, 0, &face);
      if (err) { エラー処理 ... }
      

      第2引数にはフォントデータのアドレス、第3引数にはフォントデータの サイズ、第4引数にはフェースインデックスを指定する。

  4. ピクセルサイズの指定:

    err = FT_Set_Pixel_Sizes(face, 20, 20);
    if (err) { エラー処理 ... }
    

    第2引数は横方向、第3引数は縦方向のピクセル数

  5. グリフのロード:

    int charcode = 0x3042; /* あ in UTF-32 */
    err = FT_Load_Char(face, charcode, 0);
    if (err) { エラー処理 ... }
    

    第2引数には文字コード、第3引数にはフラグを指定する。 フォントは1つ以上のキャラマップ(文字コードからグリフ番号への対応表) を持つ。デフォルトでは Unicode のキャラマップが使用される。 その場合、第2引数には UTF-32 で文字コードを指定する。

  6. ビットマップへの変換:

    err = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
    if (err) { エラー処理 ... }
    

    第2引数はフラグを指定する。FT_RENDER_MODE_MONOを指定すると モノクロ(1ピクセルに1ビット)でビットマップを生成。

    ここまでの結果、 face->glyph->bitmap_left、face->glyph->bitmap_top には現在位置から ビットマップにおける文字の左端と上端までの距離が格納される (現在位置はフォントのベースライン上の左端のことと思われる)。 face->glyph->bitmap (FT_Bitmap型)にビットマップ情報が格納される。

  7. ビットマップの処理:

    FT_Bitmap *bm = &face->glyph->bitmap;
    int row, col, bit, c;
    
    /* モノクロビットマップの場合 */
    for (row = 0; row < bm->rows; row ++) {
        for (col = 0; col < bm->pitch; col ++) {
            c = bm->buffer[bm->pitch * row + col];
            for (bit = 7; bit >= 0; bit --) {
                if (((c >> bit) & 1) == 0)
                    printf("  ");
                else
                    printf("##");
            }
        }
        printf("\n");
    }
    

FT_Bitmap 構造体の説明

主なメンバ

以下のメンバを持つ(他にもあるが)。

  • rows - 縦方向のピクセル数(行数)
  • width - 横方向のピクセル数(桁数)
  • pitch - 1行分のビットマップデータのバイト数
  • buffer - ビットマップデータ(バイト配列)へのポインタ

ビットマップバッファの構成

ビットマップの上から m 行目(m=0,1,2,...,rows-1)のデータが buffer[pitch * m] 〜 buffer[pitch * (m + 1) -1] に格納される。即ち、

0行目のデータ buffer[0] 〜 buffer[pitch-1]
1行目のデータ buffer[pitch] 〜 buffer[pitch*2-1]
2行目のデータ buffer[pitch*2] 〜 buffer[pitch*3-1]
3行目のデータ buffer[pitch*3] 〜 buffer[pitch*4-1]
... ...
rows-1行目のデータ buffer[pitch*(rows-1)]buffer[pitch*rows-1]

となる。

各行のピクセルデータの格納され方はモノクロの場合とアンチエイリアスの 場合で異なる。以下に説明する。

モノクロの場合

1ビットに1ピクセルの情報が格納される。

各行について、左から順に最初の8ビットがバイト0に、次の8ビットが バイト1に、その次の8ビットがバイト2に、・・・、 という順序で格納される。

各バイトについて、左から順に最初のピクセルがビット7(MSB)に、 次のピクセルがビット6に、その次のピクセルがビット5に、・・・、 という順序格納される。

アンチエイリアスの場合

1バイトに1ピクセルの情報が格納される。

各行について、左から順に最初のピクセルがバイト0に、 次のピクセルがバイト1に、その次のピクセルがバイト2に、・・・ 最後のピクセルがバイト width-1 に、という順序で格納される。

それぞれの値(0〜255)は点の濃さを表している。 この値は背景色から見た文字色の濃さであることに注意して、 実際に描画すべき点の色を計算する。例えば、

  • この値(点の濃さ)を val
  • 文字色(foreground color)の RGB を fgR, fgG, fgB
  • 背景色(background color)の RGB を bgR, bgG, bgB

とすると、描画するピクセルの色の RGB は

  • R = bgR + (fgR - bgR) * val / 255
  • G = bgG + (fgG - bgG) * val / 255
  • B = bgB + (fgB - bgB) * val / 255

として計算できる。

トラブル対策覚書き

空白文字のビットマップデータがない

空白文字(0x20)をレンダリングしようとすると、 縦方向も横方向もサイズ 0 が返ってくるようである。 好きなサイズだけ空白を入れて良いと言うのだろうか。

モナーフォントを12ポイント@96dpiのサイズでレンダリングするときは ちゃんと空白文字のビットマップを返してくるみたいだが、 そのサイズのビットマップを内蔵しているからだと思われる。

12ポイントのときアンチエイリアスでビットマップがグチャグチャ

注意: FreeType-2.2.1 での話。新しいバージョンではどうなるか未確認。

モナーフォントを12ポイント@96dpiのサイズでアンチエイリアス、 即ち FT_Render_Glyph() に FT_RENDER_MODE_NORMAL を指定して レンダリングすると、ビットマップの内容がおかしくグチャグチャになる。 モノクロ(FT_RENDER_MODE_MONOを指定)の場合は問題ない。

どうもこれは、モナーフォント12ポイント@96dpiのサイズ用の モノクロビットマップを内蔵しており、アンチエイリアスのときも モノクロビットマップがロードされることによると考えられるが、 FreeType の不具合なのかモナーフォントの不具合なのかは不明。

グリフをロードする際、FT_Load_Char() の第3引数に FT_LOAD_NO_BITMAP を指定して内蔵ビットマップの使用を禁止することにより、 この問題を抑制できる。


トップ > コンピューティング環境 > FreeType に関するメモ

[前ページ] [次ページ]