StoryEdit 開発日誌

ウェブアプリ StoryEditを作ってましたが延期。普通のブログ。

Slick2dの中身 TrueTypeFontクラスで日本語を扱う問題

なんかTrueTypeFontで扱える文字が256個ってのが納得いかないので、slickを調査。

とりあえず,TrueTypeFontのコンストラクタを覗く。

    public TrueTypeFont(java.awt.Font font, boolean antiAlias, char[] additionalChars) {
        GLUtils.checkGLContext();

        this.font = font;
        this.fontSize = font.getSize();
        this.antiAlias = antiAlias;

        createSet( additionalChars );
    }

んでcreateSetの中身。

        if  (customCharsArray != null && customCharsArray.length > 0) {
            textureWidth *= 2;
        }

まずcustomeCharsArrayがあればtextureWidthを二倍に。
textureWidthは,TrueTypeFontのフィールドで,512に設定されている。
つまり,フォントの解像度が32*32だとすると,512は32 * 16、16*16=256マスのフォントが描けるだけのバッファが用意されることになる.(実際にはフォントの解像度は32*32に統一されているかどうかは知らないが.)

    /** Default font texture width */
    private int textureWidth = 512;

    /** Default font texture height */
    private int textureHeight = 512;

ここのwidthを2倍にするわけなので,一度にcustomCharsArrayに設定できるサイズが512*512のバッファサイズ分のようだ。このあと,このtextureWidthとHeightをもとに,BufferedImageを作る。

            BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = (Graphics2D) imgTemp.getGraphics();

そして,次に,アスキー256文字とさらにカスタムキャラクタの番号を取り出し,getFontImageから
文字のイメージをとってくる.

           /* 割愛 */
           for (int i = 0; i < 256 + customCharsLength; i++) {

                // get 0-255 characters and then custom characters
                char ch = ( i < 256 ) ? (char) i : customCharsArray[i-256];

                BufferedImage fontImage = getFontImage(ch);

           /* 割愛 */

んで描画。

               // Draw it here
                g.drawImage(fontImage, positionX, positionY, null);

                positionX += newIntObject.width;

                if( i < 256 ) { // standard characters
                    charArray[i] = newIntObject;
                } else { // custom characters
                    customChars.put( new Character( ch ), newIntObject );
                }


tmpBufferはこれで完成.このあと,tmpBufferから指定されたcharを書き込んでいき,TrueTypeFontのフォントイメージが描画される.(Intobjectというのは,widthやheightを格納するデータクラス)

つまり,256文字以上を使いたいとすると,異なるTrueTypeFontクラスをnewしなければならないようだ.
ソース内のコメントにも書いてあるが,この方法では,newの時にしか使う文字を指定できないので,obsoleteになるの理由もわかる。新しい文字がbufferになければ、そのたびにFontクラス内のイメージに追加描画するのが筋だろう。
UnicodeFontはこの点が改善されていることを期待しつつ,次の投稿ではUnicodeFontを覗いてみたい。

(しかし,UnicodeFontをつかった日本語の描画方法はまだわからない)