Draw Center Text(FontMetrics解析)
本文首發在我的個人部落格ghui.me歡迎指教
使用canvas.drawText
方法可以直接在canvas上畫text,通常情況下需要文字在水平與垂直方向上均居中顯示,水平居中很容易實現。假設我們需要在rectF
所標識的區域中實現這樣的效果,
程式碼如下:
Paint.Align align = paint.getTextAlign();
float x;
float y;
//x
if (align == Paint.Align.LEFT) {
x = rectF.centerX() - paint.measureText(text) / 2;
} else if (align == Paint.Align.CENTER) {
x = rectF.centerX();
} else {
x = rectF.centerX() + paint.measureText(text) / 2;
}
Paint物件可以設定繪製文字開始的錨點,如果align
為LEFT
則代表 canvas.drawText(String text,float x,float y,Paint paint)
中x,y
為文字最左邊的點,
依次類推:若為CENTER
則相當於直接設定文字在水平方向上的中點,為RIGHT
則相當於設定文字最右邊的點。
總之,通過上面的程式碼可以完美實現文字在水平方向上居中顯示,下面看一下如何實現在垂直方向上居中顯示。
通常情況下會有下面這樣的程式碼:
int textSize = paint.getTextSize();
y = rectF.centerY() + textSize/2f;
上面的程式碼基本上可以實現垂直居中,但如果你仔細觀察會發現文字略微有點靠下,似乎是沒有居中。實際上文字應該算是居中了,但在視覺上它的確沒有居中,要想搞明白其中的原因,需要了解一下Paint.FontMetrics
類,原始碼如下:
public static class FontMetrics {
/**
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
通俗的講
- top是一行文字的上邊界
- ascent是文字可視區域的上邊界
- descent是文字可視區域的下邊界
- bottom是一行文字的下邊界
- leading是行與行之間的間距(通常為0,bottom與descent及top與ascent之間的間距足夠間隔行行)
為了更好的理解上面的概念請看下面的圖:
現在回過頭來看一下為什麼上面我們垂直居中的程式碼有問題,從上面的圖中可以發現:文字的可視區域在ascent與descent之間,而我們上面的程式碼實際上是將top
與bottom
之間的部分居中了,並沒有將可視區域居中,實際上通過log可以發現top
與ascent
之間的間距大概是bottom
與descent
之間間距的5倍,這也就解釋了為什麼上面的程式碼在垂直方向上
略微偏下了,原因找到了,解決方法也自然有了.
為了達到文字在視覺上的垂直居中效果,我們需要將文字的可視區域在垂直方面上的中點與rectF的centerY重合,
,就需要計算出可視區域在垂直方向上的中點與baseline之間的間距deltaY
,使baseline的y值=rectF.centerY + deltaY。這樣就能保證文字的可視區域的中點位於rectF的中點了,達到了視覺上的垂直居中。整體程式碼如下:
public static void drawCenterText(String text, RectF rectF, Canvas canvas, Paint paint) {
Paint.Align align = paint.getTextAlign();
float x;
float y;
//x
if (align == Paint.Align.LEFT) {
x = rectF.centerX() - paint.measureText(text) / 2;
} else if (align == Paint.Align.CENTER) {
x = rectF.centerX();
} else {
x = rectF.centerX() + paint.measureText(text) / 2;
}
//y
Paint.FontMetrics metrics = paint.getFontMetrics();
float acent = Math.abs(metrics.ascent);
float descent = Math.abs(metrics.descent);
y = rectF.centerY() + (acent - descent) / 2f;
canvas.drawText(text, x, y, paint);
}
抽成了一個方法,可以直接拿來用,這裡需要注意一點drawText垂直方向上是基於baseline畫的,baseline之上的ascent
及top
均為負值,之下的descent
及bottom
為正值,baseline的y值為0;
個人微信公眾號已開通:CoderGhui ,歡迎關注!
相關文章
- text-align:center和margin:0 auto居中的區別
- Android View 繪製流程(Draw) 完全解析AndroidView
- text-align:center與margin:0px auto的區別
- Direct3D Draw函式 非同步呼叫原理解析3D函式非同步
- WPF draw graph
- View draw流程分析View
- mozilla css developer centerCSSDeveloper
- draw.io使用教程
- draw call 的優化優化
- SAP Profit Center Accounting
- Unity SRP 02 Draw CallsUnity
- DEVICE DRAW VERTEX BUFFER TOO SMALLdev
- flutter佈局-3-centerFlutter
- Difference between business area and profit center
- Java GUI之FlowLayout.CENTERJavaGUI
- INCS 775 – Data Center Security
- 2006-12-06 | XML解析時過濾#textXML
- 遊戲的Draw Calls是什麼遊戲
- wpf draw ellipse via mouse click
- draw.io 使用自定義字型自定義字型
- How to draw a simple relation graph in PythonPython
- jenkins - ssh Server Groups CenterJenkinsServer
- Java測試框架Automation CenterJava框架
- win10怎麼禁用聯想solution center win10禁用聯想solution center如何設定Win10
- 探究 Text Kit 和 Core Text 的前世今生 (Text Kit 篇)
- css position:absolute align center bottomCSS
- text/html和text/plain的區別HTMLAI
- One simple way to draw canvas, wxml2canvasCanvasXML
- Unity2D之draw call優化Unity優化
- android view draw原始碼過程分析AndroidView原始碼
- WPF C# create canvas and draw ellipse in canvasC#Canvas
- jQuery text()jQuery
- jQuery :textjQuery
- Text Representation
- win10 action center怎麼關閉通知_win10系統action center關閉通知如何操作Win10
- Error: User gpmon is not allowed to login Command CenterError
- Mercury Quality Center 9.00 CN下載地址
- 如何將 Google Auto Draw 移植到小程式上Go