Android・・・テキスト描画あれこれ, ascent(), descent()等
Androidのテキスト描画に必要なTipsをメモ。
存在に忘れがちな横方向のAlignや、意外に正解がわかりにくい縦方向のセンター合わせ等。
テキスト描画の原点となるbaselineから上方向の高さがascentで、下方向の高さがdescentとなる。
baselineを割ってdescent領域に入るのは例えば小文字の"j"等だ。
しかし理解しづらいのは、ascentが負の値であることだ。
これは、画面の座標系を思い浮かべてbaselineを(0,0)と考えるとイメージしやすい。
つまり、画面上にはみ出すascentが負、画面内に入るdescentが正、となる。
存在に忘れがちな横方向のAlignや、意外に正解がわかりにくい縦方向のセンター合わせ等。
ascentとdescent
Paint及びFontMetricsで取得可能なascentとdescent。テキスト描画の原点となるbaselineから上方向の高さがascentで、下方向の高さがdescentとなる。
baselineを割ってdescent領域に入るのは例えば小文字の"j"等だ。
しかし理解しづらいのは、ascentが負の値であることだ。
これは、画面の座標系を思い浮かべてbaselineを(0,0)と考えるとイメージしやすい。
つまり、画面上にはみ出すascentが負、画面内に入るdescentが正、となる。
テキスト用Paintの作成
TextPaint tp = new TextPaint(); tp.setColor( Color.WHITE ); // アンチエイリアスON tp.setAntiAlias( true ); // 塗りつぶしのみ。STROKEを入れると太くなる。STROKEだけだと中抜き tp.setStyle( Style.FILL ); // テキストのフォントサイズ。Paintに直接指定する場合、Density等の考慮が必要。 tp.setTextSize( 11f * density );
縦方向にセンター合わせ
@Override protected void onDraw(Canvas canvas) { // 領域の高さ int areaHeight = getHeight(); FontMetrics fm = tp.getFontMetrics(); // フォントの高さを求める float fh = fm.descent - fm.ascent; // センター合わせにしたあと、Baselineの位置を求めるためにdescentを引く float ty = (areaHeight/2f) + (fh/2f) - fm.descent; canvas.drawText( "text", 0, ty, tp ); }
横方向に原点を右端で設定する(右揃えで便利)
@Override protected void onDraw(Canvas canvas) { // 表示領域の右端の座標を求める int right = getWidth() - getPaddingRight(); // 縦方向は上揃え float y = 0 - tp.ascent(); // Paintで原点右端指定を設定 tp.setTextAlign( Align.RIGHT ); // いざ描画 canvas.drawText( "text", right, y, tp ); }
PaintでAlignが設定できることに気が付かないと、左端の座標を求めるためにmeasureTextなんかを使ってしまい、ご苦労なソースになってしまう。これと同様に横方向のセンター合わせも設定することが可能。
コメント
コメントを投稿