• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Text组件的文本绘制与显示
2<!--Kit: ArkUI-->
3<!--Subsystem: ArkUI-->
4<!--Owner: @hddgzw-->
5<!--Designer: @pssea-->
6<!--Tester: @jiaoaozihao-->
7<!--Adviser: @HelloCrease-->
8部分框架或应用具备自研的文字排版能力,在移植时,这些能力会被对接到[方舟2D图形服务的文本引擎](../graphics/complex-text-c.md)。为了避免开发者重复开发文本组件,Text组件提供了接口[NODE_TEXT_CONTENT_WITH_STYLED_STRING](../../application-dev/reference/apis-arkui/capi-native-node-h.md#arkui_nodeattributetype),可以直接渲染方舟文本引擎生成的文本。
9
10以下场景基于[接入ArkTS页面章节](../ui/ndk-access-the-arkts-page.md),阐述了如何创建字体引擎文本,并利用Text组件进行渲染显示。
11
12> **说明:**
13>
14> 涉及字体引擎的接口,需在CMakeLists.txt中添加`target_link_libraries(entry PUBLIC libnative_drawing.so)`,否则链接阶段会报错。
15
16下图展示了 `NODE_TEXT_CONTENT_WITH_STYLED_STRING` 接口的主要使用流程。
17
18![ndk_text_style_string_activity](figures/native_styledString_activity.png)
19
20## 创建Text组件
21
22创建文本组件时,无需配置文字颜色、字体大小等样式属性,因为这些属性通过字体引擎接口设置。但仍需设置基础的通用属性,如宽度和高度。如果不指定,组件自动适应文本的宽度和高度。
23```c++
24ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
25    OH_ArkUI_QueryMod32uleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
26if (nodeApi == nullptr) {
27    return;
28}
29ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT);
30// 设置宽度
31ArkUI_NumberValue textWidth[] = {{.f32 = 300}};
32ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1};
33nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem);
34// 设置高度
35ArkUI_NumberValue textHeight[] = {{.f32 = 100}};
36ArkUI_AttributeItem textHeightItem = {.value = textHeight, .size = 1};
37nodeApi->setAttribute(text, NODE_HEIGHT, &textHeightItem);
38```
39## 设置段落与文本样式
40
41- 设置段落样式
42
43    段落样式定义了一段文字的整体属性,例如最大显示行数、文字方向等。以下代码示例设置了文字居中,最大行数限制为10。
44
45    > **说明:**
46    >
47    > `OH_Drawing_`前缀的接口由方舟字体引擎提供,参考[简单文本绘制与显示(C/C++)](../graphics/simple-text-c.md)、[复杂文本绘制与显示(C/C++)](../graphics/complex-text-c.md)。
48    ```c++
49    OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle();
50    OH_Drawing_SetTypographyTextAlign(typographyStyle, OH_Drawing_TextAlign::TEXT_ALIGN_CENTER);
51    OH_Drawing_SetTypographyTextMaxLines(typographyStyle, 10);
52    ```
53- 设置文本样式
54
55    不同内容的文本可以设置不同的文本样式,但必须按照以下三个接口的逻辑调用顺序进行设置,否则将无法生效。
56
57    1. [OH_ArkUI_StyledString_PushTextStyle](../reference/apis-arkui/capi-styled-string-h.md#oh_arkui_styledstring_pushtextstyle):将文字样式推入栈中。
58    2. [OH_ArkUI_StyledString_AddText](../reference/apis-arkui/capi-styled-string-h.md#oh_arkui_styledstring_addtext):添加要修改样式的文字内容。
59    3. [OH_ArkUI_StyledString_PopTextStyle](../reference/apis-arkui/capi-styled-string-h.md#oh_arkui_styledstring_poptextstyle):将文字样式弹出栈。
60
61    > **说明:**
62    >
63    > `OH_ArkUI_StyledString_`前缀的接口由Text组件提供。
64    >
65    > `OH_Drawing_`前缀的接口由方舟字体引擎提供,参考[简单文本绘制与显示(C/C++)](../graphics/simple-text-c.md)、[复杂文本绘制与显示(C/C++)](../graphics/complex-text-c.md)。
66
67    [OH_Drawing_CreateTextStyle](../reference/apis-arkgraphics2d/capi-drawing-text-typography-h.md#oh_drawing_createtextstyle)创建文本样式。设置“Hello”字体大小28px,颜色为0xFF707070。设置“World!”字体大小为28px,颜色为0xFF2787D9。
68    ```c++
69    ArkUI_StyledString *styledString = OH_ArkUI_StyledString_Create(typographyStyle,OH_Drawing_CreateFontCollection());
70
71    OH_Drawing_TextStyle *helloStyle = OH_Drawing_CreateTextStyle();
72    // 设置字体大小
73    OH_Drawing_SetTextStyleFontSize(helloStyle, 28);
74    // 设置颜色
75    OH_Drawing_SetTextStyleColor(helloStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70));
76    OH_ArkUI_StyledString_PushTextStyle(styledString, helloStyle);
77    OH_ArkUI_StyledString_AddText(styledString, "Hello");
78    OH_ArkUI_StyledString_PopTextStyle(styledString);
79
80    OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
81    OH_Drawing_SetTextStyleFontSize(worldTextStyle, 28);
82    OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27,0x87, 0xD9));
83    OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
84    OH_ArkUI_StyledString_AddText(styledString, "World!");
85    OH_ArkUI_StyledString_PopTextStyle(styledString);
86    ```
87## 添加占位
88占位保留指定大小的空白区域,此区域不绘制文字,但参与布局测量,影响文字排版。
89行高是文字高度与占位高度中的较大值。
90
91以下示例展示在`Hello`与`World!`中间插入占位。
92```c++
93OH_Drawing_TextStyle *helloStyle = OH_Drawing_CreateTextStyle();
94OH_Drawing_SetTextStyleFontSize(helloStyle, 28);
95OH_Drawing_SetTextStyleColor(helloStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70));
96OH_ArkUI_StyledString_PushTextStyle(styledString, helloStyle);
97OH_ArkUI_StyledString_AddText(styledString, "Hello");
98OH_ArkUI_StyledString_PopTextStyle(styledString);
99
100// 设置占位宽和高
101OH_Drawing_PlaceholderSpan placeHolder{
102    .width = 100,
103    .height = 100,
104};
105OH_ArkUI_StyledString_AddPlaceholder(styledString, placeHolder);
106
107OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
108OH_Drawing_SetTextStyleFontSize(worldTextStyle, 28);
109OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27,0x87, 0xD9));
110OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
111OH_ArkUI_StyledString_AddText(styledString, "World!");
112OH_ArkUI_StyledString_PopTextStyle(styledString);
113```
114## 文本布局与绘制
115- 文本布局
116
117  文字样式和内容设置完成后,调用字体引擎接口[OH_Drawing_TypographyLayout](../reference/apis-arkgraphics2d/capi-drawing-text-typography-h.md#oh_drawing_typographylayout)对文本进行布局,传入最大宽度。超过此宽度的文字会自动换行。
118
119    > **说明:**
120    >
121    > 未经过布局的文本无法显示。
122
123    ```c++
124    OH_Drawing_Typography *typography = OH_ArkUI_StyledString_CreateTypography(styledString);
125    OH_Drawing_TypographyLayout(typography, 400);
126    ```
127
128- 文本绘制
129
130    文本绘制由字体引擎与图形交互完成,无需额外设置。Text组件会在ArkUI渲染机制下,在组件触发绘制时调用字体引擎绘制接口。此处仅需将已创建的StyledString对象传递给已创建的Text组件。
131    ```c++
132    ArkUI_AttributeItem styledStringItem = {.object = styledString};
133    nodeApi->setAttribute(text, NODE_TEXT_CONTENT_WITH_STYLED_STRING, &styledStringItem);
134    ```
135
136## 销毁对象
137
138Text组件不对本文涉及的任何对象的生命周期进行管理,需由开发者自行负责。字体引擎接口均配有相应的销毁方法。
139
140上述涉及的字体引擎接口都有对应的销毁方法。
141
142`OH_Drawing_DestroyTextStyle(OH_Drawing_TextStyle *style)`:销毁文本样式对象。
143
144`OH_Drawing_DestroyTypographyStyle(OH_Drawing_TypographyStyle *style)`:销毁段落样式对象。
145
146当Text组件仍在界面上显示时,此时释放会导致文字无法绘制。在实际业务场景下需确保Text组件不再使用时才释放。
147
148相关字体引擎销毁的接口请参考[OH_Drawing_DestroyTextStyle](../reference/apis-arkgraphics2d/capi-drawing-text-typography-h.md#oh_drawing_destroytextstyle) 和 [OH_Drawing_DestroyTypographyStyle](../reference/apis-arkgraphics2d/capi-drawing-text-typography-h.md#oh_drawing_destroytypographystyle)。
149
150Text组件提供[OH_ArkUI_StyledString_Destroy](../reference/apis-arkui/capi-styled-string-h.md#oh_arkui_styledstring_destroy),用于销毁属性字符串对象。
151
152## 完整示例
153本篇示例仅提供核心接口的调用方法,完整的示例工程请参考<!--RP1-->[StyledStringNDK](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/ArkUISample/StyledStringNDK)<!--RP1End-->。
154
155```c++
156#include <arkui/native_interface.h>
157#include <arkui/styled_string.h>
158#include <native_drawing/drawing_font_collection.h>
159#include <native_drawing/drawing_text_declaration.h>
160
161void CreateNativeNode() {
162    ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
163        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
164    if (nodeApi == nullptr) {
165        return;
166    }
167    // 创建一个Column容器组件
168    ArkUI_NodeHandle column = nodeApi->createNode(ARKUI_NODE_COLUMN);
169    ArkUI_NumberValue colWidth[] = {{.f32 = 300}};
170    ArkUI_AttributeItem widthItem = {.value = colWidth, .size = 1};
171    nodeApi->setAttribute(column, NODE_WIDTH, &widthItem);
172    // 创建Text组件
173    ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT);
174    ArkUI_NumberValue textWidth[] = {{.f32 = 300}};
175    ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1};
176    nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem);
177
178    ArkUI_NumberValue textHeight[] = {{.f32 = 100}};
179    ArkUI_AttributeItem textHeightItem = {.value = textHeight, .size = 1};
180    nodeApi->setAttribute(text, NODE_HEIGHT, &textHeightItem);
181
182    ArkUI_NumberValue borderWidth[] = {{.f32 = 1}};
183    ArkUI_AttributeItem borderWidthItem = {.value = borderWidth, .size = 1};
184    nodeApi->setAttribute(text, NODE_BORDER_WIDTH, &borderWidthItem);
185
186    // typographyStyle表示段落样式。
187    OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle();
188    // 文字居中显示
189    OH_Drawing_SetTypographyTextAlign(typographyStyle, OH_Drawing_TextAlign::TEXT_ALIGN_CENTER);
190    OH_Drawing_SetTypographyTextMaxLines(typographyStyle, 10);
191    ArkUI_StyledString *styledString = OH_ArkUI_StyledString_Create(typographyStyle, OH_Drawing_CreateFontCollection());
192    // 创建文本样式,设置字体和颜色。
193    OH_Drawing_TextStyle *textStyle = OH_Drawing_CreateTextStyle();
194    OH_Drawing_SetTextStyleFontSize(textStyle, 28);
195    OH_Drawing_SetTextStyleColor(textStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70));
196    // 文本样式的设置有顺序。
197    OH_ArkUI_StyledString_PushTextStyle(styledString, textStyle);
198    OH_ArkUI_StyledString_AddText(styledString, "Hello");
199    OH_ArkUI_StyledString_PopTextStyle(styledString);
200    // 在Hello和World中间插入100x100的占位。
201    OH_Drawing_PlaceholderSpan placeHolder{
202        .width = 100,
203        .height = 100,
204    };
205    OH_ArkUI_StyledString_AddPlaceholder(styledString, &placeHolder);
206    OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
207    OH_Drawing_SetTextStyleFontSize(worldTextStyle, 28);
208    OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27, 0x87, 0xD9));
209    OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
210    OH_ArkUI_StyledString_AddText(styledString, "World!");
211    OH_ArkUI_StyledString_PopTextStyle(styledString);
212    OH_Drawing_Typography *typography = OH_ArkUI_StyledString_CreateTypography(styledString);
213    OH_Drawing_TypographyLayout(typography, 400);
214    ArkUI_AttributeItem styledStringItem = {.object = styledString};
215    nodeApi->setAttribute(text, NODE_TEXT_CONTENT_WITH_STYLED_STRING, &styledStringItem);
216
217    OH_ArkUI_StyledString_Destroy(styledString);
218    // Text作为Column子组件
219    nodeApi->addChild(column, text);
220    // Column作为XComponent子组件
221    OH_NativeXComponent_AttachNativeRootNode(xComponent, column);
222}
223```
224
225![ndk_text_styled_string](figures/ndk_text_styled_string.png)