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をつかった日本語の描画方法はまだわからない)