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 ,歡迎關注!
相關文章
- WPF draw graph
- INCS 775 – Data Center Security
- draw.io使用教程
- Unity SRP 02 Draw CallsUnity
- flutter佈局-3-centerFlutter
- How to draw a simple relation graph in PythonPython
- wpf draw ellipse via mouse click
- UIKit Inside: frame bounds position anchorPoint centerUIIDE
- Error: User gpmon is not allowed to login Command CenterError
- draw.io 使用自定義字型自定義字型
- text
- HSSFCellStyle 報錯 標紅 ALIGN_CENTER
- Error: User gpmon is not allowed to login Command Center.Error
- win10怎麼禁用聯想solution center win10禁用聯想solution center如何設定Win10
- WPF C# create canvas and draw ellipse in canvasC#Canvas
- 遊戲的Draw Calls是什麼遊戲
- win10 action center怎麼關閉通知_win10系統action center關閉通知如何操作Win10
- text/html和text/plain的區別HTMLAI
- [react-control-center tutorial 1] 啟動ccReact
- Flutter 佈局(二)- Padding、Align、Center詳解Flutterpadding
- Text Representation
- Unity2D之draw call優化Unity優化
- One simple way to draw canvas, wxml2canvasCanvasXML
- corel draw2019如何裝在win10系統_win10安裝corel draw2019教程繪圖Win10繪圖
- CSS 文字裝飾 text-decoration & text-emphasisCSS
- WPF mouse down on canvas and draw shapes which render with random colorsCanvasrandom
- 向量插圖設計繪製Canvas X DrawCanvas
- Canvas X Draw for mac(技術插圖軟體)CanvasMac
- Canvas X Draw for mac技術插圖軟體CanvasMac
- 如何將 Google Auto Draw 移植到小程式上Go
- text1
- text-to-motion
- ORACLE TEXT(轉)Oracle
- DAN Text Classification
- 網際網路資料中心(Internet Data Center,IDC)
- draw.io 放大字號快捷鍵 ctrl+shift+]
- 快速繪畫應用:Growly Draw for mac 免費版Mac
- 使用draw.io捕獲領域故事 - Darko Kantic
- draw.io 是更值得擁有的流程圖工具流程圖