文本测量(C/C++)
场景介绍
文本测量指的是在图形绘制中,对文本的尺寸和布局进行评估,计算文本在给定字体和样式下占用的空间(例如宽度、高度和其他相关信息)的过程。文本测量用于文本排版、布局、渲染以及调整文本显示的位置和大小等场景,便于更精准地控制与调整界面的布局和呈现,以达到设计预期。
当前主要支持以下方面的文本测量能力:
- 文本宽度:测量给定文本在特定字体、大小和样式下的水平长度。
- 文本高度:测量给定文本的垂直高度,通常涉及字体的上升线、下降线等。
- 行间距:测量多行文本之间的垂直距离,通常与字体的行距相关。
- 字符间距:测量单个字符之间的水平距离,通常与字形和字体设计有关。
接口说明
文本测量中常用接口如下表所示,详细接口说明参考drawing_text_typography.h。
| 接口名 | 描述 |
|---|---|
| double OH_Drawing_TypographyGetLongestLine(OH_Drawing_Typography*) | 获取最长行的宽度,建议实际使用时将返回值向上取整。 |
| double OH_Drawing_TypographyGetLongestLineWithIndent(OH_Drawing_Typography*) | 获取最长行的宽度(该宽度包含当前行缩进的宽度),建议实际使用时将返回值向上取整。 |
| size_t OH_Drawing_TypographyGetLineCount (OH_Drawing_Typography* ) | 获取文本行数。 |
| OH_Drawing_LineMetrics* OH_Drawing_TypographyGetLineMetrics (OH_Drawing_Typography* ) | 获取段落行的度量信息。包含行的高度、宽度、起始坐标等信息。 |
| double OH_Drawing_TextStyleGetLetterSpacing (OH_Drawing_TextStyle *) | 获取文本的字符间距。 |
开发步骤
-
在工程的src/main/cpp/CMakeLists.txt文件中添加以下lib。
libnative_drawing.so -
导入依赖的相关头文件。
#include <native_drawing/drawing_font_collection.h>#include <native_drawing/drawing_text_typography.h>#include <native_drawing/drawing_text_declaration.h> -
创建段落生成器ParagraphBuilder,并设置段落样式。
// 创建文本样式,并设置字体大小为50OH_Drawing_SetTextStyleColor(myTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));OH_Drawing_SetTextStyleFontSize(myTextStyle, 50.0);// 创建一个段落样式对象,以设置排版风格OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle();// 设置段落样式的对齐方式为左对齐OH_Drawing_SetTypographyTextAlign(typographyStyle, TEXT_ALIGN_LEFT);// 创建一个段落生成器OH_Drawing_TypographyCreate *handler = OH_Drawing_CreateTypographyHandler(typographyStyle, fontCollection);// 在段落生成器中设置文本样式OH_Drawing_TypographyHandlerPushTextStyle(handler, myTextStyle);// 在段落生成器中添加文本内容const char *text = "排版测量的文字度量信息";OH_Drawing_TypographyHandlerAddText(handler, text);// 通过段落生成器生成段落OH_Drawing_Typography *typography = OH_Drawing_CreateTypography(handler); -
调用排版接口并设置段落排版宽度,对段落进行塑型排版。
// 对段落进行塑形排版,设置排版宽度为maxWidthOH_Drawing_TypographyLayout(typography, maxWidth); -
调用段落测量信息获取接口,获取指定数据。
// case1: 获取排版后最长行行宽double longestLine = OH_Drawing_TypographyGetLongestLine(typography);DRAWING_LOGI("第%{public}d行 longestLine: %{public}f", longestLine);// case2:获取排版后段落行数size_t lineCnt = OH_Drawing_TypographyGetLineCount(typography);DRAWING_LOGI("lineCnt: %{public}zu", lineCnt);// case3:获取段落每行的度量信息OH_Drawing_LineMetrics *lineMetrics = OH_Drawing_TypographyGetLineMetrics(typography);int lineMetricsSize = OH_Drawing_LineMetricsGetSize(lineMetrics);for (int i = 0; i < lineMetricsSize; ++i) {// lineMetrics为经过排版测量的文字度量信息double curLineAscender = -lineMetrics[i].ascender;double curLineWidth = lineMetrics[i].width;DRAWING_LOGI("第%{public}d行 lineMetrics ascender: %{public}f", i + 1, curLineAscender);DRAWING_LOGI("第%{public}d行 lineMetrics width: %{public}f", i + 1, curLineWidth);}// case4:获取段落最长行宽度与带缩进最长行行宽double longestLineWithIndent = OH_Drawing_TypographyGetLongestLineWithIndent(typography);DRAWING_LOGI("longestLineWithIndent: %{public}f", longestLineWithIndent);OH_Drawing_Font_Metrics fontMetrics;// 获取文本字体属性bool result = OH_Drawing_TextStyleGetFontMetrics(typography, myTextStyle, &fontMetrics);DRAWING_LOGI("result: %{public}zu, fontMetrics ascent: %{public}f" , result, fontMetrics.ascent);// 获取排版对象的指定行位置信息,该接口需要在OH_Drawing_TypographyLayout接口调用之后调用OH_Drawing_LineMetrics lineMetric;OH_Drawing_TypographyGetLineMetricsAt(typography, 0, &lineMetric);DRAWING_LOGI("第1行 lineMetrics ascender: %{public}f", -lineMetric.ascender);