The next JAVA library(6)
さて、文字の描画です。
当たり前ですが、文字の描画は、drawString()を使います。
前回と同じように、Graphics.drawString()を、こちら側のライブラリでくるんでしまいます。
しかし、ここでいくつか問題があります。
まず、Fontを何で描画するか。通常であれば、Font.getFont()でFontを取得して、それをGraphicsにsetFont()して、それから描画します。
なので、ライブラリ側のdrawString()で、Fontを引数にとって実行するようにすればそれで良いのですが、Fontというのは、ユーザ側が持ち回して使用する物でもないような気がします。
それに、getFont()の仕様が、DoCoMoとMIDPで異なるので、その辺の差異を埋めるためにも、こちら側でwrapしてやった方が良いでしょう。
protected Font _font = Font.getDefaultFont(); protected final int FONT_SMALL=0; protected final int FONT_MEDIUM=1; protected final int FONT_LARGE=2; protected int _myFont; protected void _setFont(int font){ int face = Font.FACE_SYSTEM; int style = Font.STYLE_PLAIN; int size = Font.SIZE_MEDIUM; switch(font){ #if DOCOMO case FONT_SMALL: size = Font.SIZE_TINY; break; #else case FONT_SMALL: size = Font.SIZE_SMALL; break; #endif case FONT_LARGE: size = Font.LARGE; break; } _myFont = font; #if DOCOMO _font = Font.getFont(face | style | size); #else _font = Font.getFont(face, style, size); #endif }
フォントのサイズ以外はほとんど変更することは無いので、サイズだけ指定できるようにして、あとは固定の物を使います。
DoCoMoとMIDPのフォントの違いについてですが、まず、DoCoMoで、フェイスをFACE_PROPORTIONALにすると、Font.stringWidth()で、正しい値が返ってこなくなります。
なので、SYSTEMフォントを使用することにします。
スタイルについては、通常はSTYLE_PLAINしか使わないでしょう。
で、フォントのサイズですが、DoCoMoは4種類、MIDPは3種類あります。
で、DoCoMoのTINYフォントは、MIDPのSMALLフォントと同じぐらいの大きさなので、機種ごとに分けて書いています。DoCoMoのSMALLフォントは、機種依存になるので使用しません。
これでフォントの作成については終わりですが、このフォントを取得するためのメソッドを作っていません。
これは、これから作るとかそういうのではなく、取得させません。
安全性のためにFontを隠蔽し、メソッドを作ったのに、それをわざわざ壊すような真似をしたくありません。
取得するにしても、
protected int _getFont(){ return _myFont; }
これだけで十分です。
あとは、最低限必要なメソッドだけ委譲してしまいましょう。
protected int _getFontHeight(){ return _font.getHeight(); } protected int _getStringWidth(String str){ return _font.stringWidth(str); }
これでフォント周りは全部終了です。
必要なフォントがあれば、いつものようにオーバーライドしてもらうことにしましょう。
で、やっと文字の描画です。
最初に説明したとおり、前回のdrawImage()と同じ書き方をすれば良いです。
protected void _drawString(String str, int x, int y, int c){ _drawString(_img, str, x, y, c, 0); } protected void _drawString(String str, int x, int y, int c, int point){ _drawString(_img, str, x, y, c, point); } protected void _drawString(Image img, String str, int x, int y, int c){ _drawString(img, str, x, y, c, 0); } protected void _drawString(Image img, String str, int x, int y, int c, int point){ /* 0 1 2 3 4 5 6 7 8 */ int w=_getStringWidth(str); int h=_getFontHeight(); switch(point){ case 0: break; case 1: x-=w/2; break; case 2: x-=w; break; case 3: y-=h/2; break; case 4: x-=w/2; y-=h/2; break; case 5: x-=w; y-=h/2; break; case 6: y-=h; break; case 7: x-=w/2; y-=h; break; case 8: x-=w; y-=h; break; } setColor(img, c); img.getGraphics().setFont(_font); #if DOCOMO img.getGraphics().drawString(str, x, y+_font.getAscent()); #else img.getGraphics().drawString(str, x, y, Graphics.LEFT|Graphics.TOP); #endif }
これで完成ヽ(´ー`)ノ
DoCoMoの場合は、描画の位置がベースラインになっているので、それを修正しています。
少しだけ注意しないといけないのは、drawString()の直前にsetFont()をすること。
そうしないと、DoCoMoの場合、デフォルトのフォントで表示されてしまいます。
つまり、
Graphics g1 = img1.getGraphics(); g1.setFont(font); Graphics g2 = g1; g2.drawString("ほげほげ", 0, 0);
と書いた場合、"ほげほげ"は、デフォルトフォントで表示されてしまいます。
おそらく、Graphicsの代入は、コピーコンストラクタのような機構を使って実装していて、Imageの参照先等はコピーされますが、その際にフォントがデフォルトになってしまうのでしょう。単なる予想ですが。
まあ、そういうことなので、描画する直前にsetFont()をします。Fontを外に出したくない理由としては、この辺の事情も挙げられますね。
今日はこれでおしまい。次はファイル操作かなぁ(;´Д`)