關於自定義View的drawText字型測量

小小9575發表於2018-11-13

當我們在Canvas上drawText的時候會發現和所寫的文字大小和我們給Paint所設定的不一樣,導致我們無法精準的對齊高度,下面我們來
看一下問題出在了哪裡。首先上圖
中文

英文


首先getFontMetrics()我們可以獲得文字的實際佔用位置的各個高度基線(以500xp的文字為例),各個屬性不解釋,直接看圖就能看出來。
Paint.FontMetrics fontMetrics = normalPaint.getFontMetrics();
float top = fontMetrics.top;
float ascent = fontMetrics.ascent;
float leading = fontMetrics.leading;
float descent = fontMetrics.descent;
float bottom = fontMetrics.bottom;
通過列印的結果可以發現各個基線和字元的種類沒有關係,類似小學拼音作業本的四線三格,你的寫中文英文都行反正線就在那,不會動,除非
你要寫大字了,字號變了,當然得換個基線

英文字元
onDraw: ================================TextSize=500.0
onDraw: ==============FontMetrics============top=-528.0762
onDraw: ==============FontMetrics=========ascent=-463.8672
onDraw: ==============FontMetrics========leading=0.0
onDraw: ==============FontMetrics========descent=122.07031
onDraw: ==============FontMetrics=========bottom=135.49805
中文字元
onDraw: ================================TextSize=500.0
onDraw: ==============FontMetrics============top=-528.0762
onDraw: ==============FontMetrics=========ascent=-463.8672
onDraw: ==============FontMetrics========leading=0.0
onDraw: ==============FontMetrics========descent=122.07031
onDraw: ==============FontMetrics=========bottom=135.49805

然後是通過Rect()直接拿文字的高度
Rect txtRec = new Rect();
txtRec.height();
normalPaint.getTextBounds("Hj",0,"Hj".length(),txtRec);
float leftX = x + txtRec.left;
float topY = y +txtRec.bottom-txtRec.height();
float rightX = x+txtRec.right;
float bottomY = y + txtRec.bottom;
通過log可以發現中英文的字元在高度上是有區別,不同的英文字母也是有去別的,因為通過rect拿到的是當前文字實際的高度,中文是方塊字,所以
佔用的寬高基本一致,而英文有的佔用1、2行如R,有的佔用2行如a有的佔用1、2、3行如j,符號就更不用說了。所以drawText的高度對齊都是
通過某條基線對齊的,也就是上面的leading,不是文字top也不是bottom

英文字元
onDraw: ===============TextBounds=======txtRec.bottom=110
onDraw: ===============TextBounds==========txtRec.top=-383
onDraw: ===============TextBounds=========txtRec.left=39
onDraw: ===============TextBounds========txtRec.right=450
中文字元
onDraw: ===============TextBounds=======txtRec.bottom=47
onDraw: ===============TextBounds==========txtRec.top=-391
onDraw: ===============TextBounds=========txtRec.left=39
onDraw: ===============TextBounds========txtRec.right=461

如果上面的這些內容都瞭解了,那麼高度對齊或者通過文字實際頂部/底部對齊就不困難了

相關文章