libGDXの基礎１７ テキスト描画 FreeTypeFontGeneratorを使う

今回は最も基本的なものであり、実用度も高いテキスト描画を行ってみる。

#libGDXでの文字描画はBitmapFont

libGDXは文字を描画できる。ただし、BitmapFontを用意した場合だ。BitmapFontを生成するツールも付属しているため、利用するテキストが決まり切っている場合あらかじめフォントファイルからBitmapFontを生成するのが良いだろう。

しかし英語ならまだよいが、日本語などマルチバイトではすべて生成しようとすると膨大な数になってしまう。


#フォントファイルから動的にBitmapFontを作り出す

TrueTypeやOpenTypeフォントから動的にBitmapFontを生成できるものがある。それがFreeTypeFontGeneratorだ。


###セットアップ

setup.jarでFreeTypeFontにチェックを付けて実行するのが一番楽だ。

そのほかantなど高速に開発したい場合は自前で落としてくる。libGDXのバージョンに合わせてとってくるとよいだろう。
たとえば、1.9.3の場合はここにある。

http://central.maven.org/maven2/com/badlogicgames/gdx/gdx-freetype/1.9.3/
http://central.maven.org/maven2/com/badlogicgames/gdx/gdx-freetype-platform/1.9.3/

gdx-freetypeがAPIで、gdx-freetype-platformが各プラットフォームに必要なライブラリだ。
desktopはWindows、Mac、Linuxの3種類対応しているのでまずはこれを利用して開発するとよい。

###使い方

以下ではotfフォントから動的に作り出している。BitmapFontファイルを利用していない。

```java
package test.libgdx.basic17;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;

public class FontTest implements ApplicationListener{
    FreeTypeFontGenerator fontGenerator;
    BitmapFont bitmapFont;
    
    SpriteBatch batch;

    @Override
    public void create() {
        batch = new SpriteBatch();
        
        FileHandle file = Gdx.files.local("font/NotoSansCJKjp-Bold.otf");
        fontGenerator = new FreeTypeFontGenerator(file);

        FreeTypeFontGenerator.FreeTypeFontParameter param = new FreeTypeFontGenerator.FreeTypeFontParameter();
        param.size = 32;

        bitmapFont = fontGenerator.generateFont(param);
        
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        
        bitmapFont.draw(batch, "ABCDabcd\n1234567890\n@+!#$", 50, 300);
                
        batch.end();
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public void dispose() {
        batch.dispose();
        bitmapFont.dispose();
        fontGenerator.dispose();
    }
    
    public static void main(String[] args) {
        new LwjglApplication(new FontTest(), "Game", 512, 512);
    }
}

```

実行。\nで折り返しているのがわかる。
![17-1.png](https://qiita-image-store.s3.amazonaws.com/0/46371/779390c0-34e3-cef2-a86d-6766735fee7f.png)

BitmapFont、FreeTypeFontGeneratorともにdisposeを忘れぬよう。

#スタイルをいじってみる

###縁取りをしてみる

文字を白のままはあとでsetColor()が利用できて便利なのだが、最初から色を付けることもできる。縁取りの場合は2色が付くためsetColor()で自由な色を付けることはできないのであらかじめ設定しておく必要がある。

使い方は簡単。最初の生成時にパラメータを追加する。

```java
        FreeTypeFontGenerator.FreeTypeFontParameter param = new FreeTypeFontGenerator.FreeTypeFontParameter();
        param.size = 32;
        param.color = Color.CYAN;
        param.borderColor = Color.RED;
        param.borderWidth = 2;
```

実行。
![17-2.png](https://qiita-image-store.s3.amazonaws.com/0/46371/79678755-0606-c0a3-cfa9-338db0bd21e4.png)

###影もつけてみる

```java
        FreeTypeFontGenerator.FreeTypeFontParameter param = new FreeTypeFontGenerator.FreeTypeFontParameter();
        param.size = 32;
        param.color = Color.CYAN;
        param.borderColor = Color.RED;
        param.borderWidth = 2;
        param.shadowColor = Color.BLUE;
        param.shadowOffsetX = 3;
        param.shadowOffsetY = 3;
```

実行。

![17-3.png](https://qiita-image-store.s3.amazonaws.com/0/46371/604a12f4-5555-7b66-cd92-74323270499d.png)

いいかんじだ。

#日本語表示

しかし、このままでは日本語が表示できないのにいずれ気が付くだろう。
以下のコードでまるごと日本語部分が表示されないのに気が付く。

```java
        bitmapFont.draw(batch, "ABCDabcd\n1234567890\n@+!#$\nあいうえお", 50, 300);
```

FreeTypeFontParameterにその設定項目があるが、実はデフォルトであらかじめレンダリングしておく文字が決まっている。
ソースコードを読むとよい。
デフォルト値はFreeTypeFontGenerator#DEFAULT_CHARSがセットされている。ここではアルファベットと数字基本的な記号が含まれている。


そこでその値を上書きしてみる。以下の一行を付け加える。

```java
        param.characters = "ABcd1290あいお+";
```

ここで設定した文字以外表示されなくなったのがわかると思う。

![17-4.png](https://qiita-image-store.s3.amazonaws.com/0/46371/a26b3e11-4413-3506-e1ad-d997755e09f4.png)

利用するすべての文字を定義しておけば起動時に生成され問題はない。

かといってすべての利用する文字をあらかじめ定義しておくのは非常に難しい。BitmapFontに定義されていない場合、動的にBitmapFontへ文字を追加していってほしい。

それはパラメータに以下の一行を付け加えることで可能だ。

```java
        param.incremental = true;
```

![17-5.png](https://qiita-image-store.s3.amazonaws.com/0/46371/3e398c2f-4893-6d0d-9328-fe042c4cc0e4.png)

問題なく描画できた。