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なんかを使ってしまい、ご苦労なソースになってしまう。これと同様に横方向のセンター合わせも設定することが可能。
コメント
コメントを投稿