• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 字块绘制(C/C++)
2
3<!--Kit: ArkGraphics 2D-->
4<!--Subsystem: Graphics-->
5<!--Owner: @hangmengxin-->
6<!--Designer: @wangyanglan-->
7<!--Tester: @nobuggers-->
8<!--Adviser: @ge-yafang-->
9
10## 场景介绍
11
12字块(TextBlob)是指文本的集合。无论是单个的文字还是大块的文本,都可以通过字块来绘制。
13
14除了基本的字块绘制之外,还可以给文字添加各种绘制效果。常见的字块绘制场景包括[文字描边](#文字描边)、[文字渐变](#文字渐变)等,更多效果请见[绘制效果](drawing-effect-overview.md)。
15
16本节不涉及文本测量和布局排版相关内容,如需在开发中处理此类文本绘制需求,可参考[文本开发概述](text-overview.md),该文档系统讲解了排版策略与相关使用指导。
17
18## 基本字块绘制
19
20使用OH_Drawing_CanvasDrawTextBlob()接口绘制字块,接口接受4个参数,分别为:画布Canvas对象、字块对象、文字基线左端点的x坐标和y坐标。
21
22画布Canvas对象具体可见[画布的获取与绘制结果的显示(C/C++)](canvas-get-result-draw-c.md)。
23
24字块对象可以通过多种方式创建得到,详细的字块创建方式请参考[drawing_text_blob.h](../reference/apis-arkgraphics2d/capi-drawing-text-blob-h.md)。
25
26此处以使用OH_Drawing_TextBlobCreateFromString()接口创建字块为例,接口接受3个参数,分别为:
27
28- 需要显示的文本字符串内容。
29
30- 指向OH_Drawing_Font字体对象的指针。OH_Drawing_Font用于设置和获取字体的各种属性,如字体大小、文本样式、字体对齐方式、字体渲染方式、字体描边方式等,详细的API介绍请参考[draw_font](../reference/apis-arkgraphics2d/capi-drawing-font-h.md)。
31
32- 文本编码方式。
33
34简单示例和示意图如下所示:
35
36```c++
37// 创建字体对象
38OH_Drawing_Font *font = OH_Drawing_FontCreate();
39// 设置字体大小
40OH_Drawing_FontSetTextSize(font, 100);
41// 需要绘制的文字
42const char *str = "Hello world";
43// 创建字块对象
44OH_Drawing_TextBlob *textBlob =
45    OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8);
46// 绘制字块
47OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, 200, 800);
48// 释放字块对象
49OH_Drawing_TextBlobDestroy(textBlob);
50// 释放字体对象
51OH_Drawing_FontDestroy(font);
52```
53
54![Screenshot_20241225164926098](figures/Screenshot_20241225164926098.jpg)
55
56## 文字描边
57
58基于基本的字块绘制,还可以通过画笔实现文字描边效果,描边效果的更多介绍请参考[描边效果](basic-drawing-effect-c.md#描边效果)。
59
60文字描边的简要示例和示意图如下:
61
62```c++
63// 创建画笔
64OH_Drawing_Pen *pen = OH_Drawing_PenCreate();
65// 设置抗锯齿
66OH_Drawing_PenSetAntiAlias(pen, true);
67// 设置描边颜色
68OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
69// 设置描边线宽
70OH_Drawing_PenSetWidth(pen, 3);
71// 设置画笔描边效果
72OH_Drawing_CanvasAttachPen(canvas, pen);
73// 创建字型对象
74OH_Drawing_Font *font = OH_Drawing_FontCreate();
75// 设置字体大小
76OH_Drawing_FontSetTextSize(font, 150);
77const char *str = "Hello world";
78// 创建字块对象
79OH_Drawing_TextBlob *textBlob =
80    OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8);
81// 绘制字块
82OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, 200, 800);
83// 去除描边效果
84OH_Drawing_CanvasDetachPen(canvas);
85// 销毁各类对象
86OH_Drawing_TextBlobDestroy(textBlob);
87OH_Drawing_FontDestroy(font);
88OH_Drawing_PenDestroy(pen);
89```
90
91![Screenshot_20241225171259621](figures/Screenshot_20241225171259621.jpg)
92
93## 文字渐变
94
95基于基本字块绘制,还可以通过着色器实现文字渐变的效果,着色器的更多介绍请参考[着色器效果](complex-drawing-effect-c.md#着色器效果)。
96
97以下为文字添加了线性渐变着色器效果的简要示例和示意图:
98
99```c++
100// 开始点
101OH_Drawing_Point *startPt = OH_Drawing_PointCreate(100, 100);
102// 结束点
103OH_Drawing_Point *endPt = OH_Drawing_PointCreate(900, 900);
104// 颜色数组
105uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF};
106// 相对位置数组
107float pos[] = {0.0f, 0.5f, 1.0f};
108// 创建线性渐变着色器效果
109OH_Drawing_ShaderEffect *colorShaderEffect =
110    OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP);
111// 创建画刷对象
112OH_Drawing_Brush *brush = OH_Drawing_BrushCreate();
113// 基于画刷设置着色器效果
114OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect);
115// 设置画刷填充效果
116OH_Drawing_CanvasAttachBrush(canvas, brush);
117// 创建字型对象
118OH_Drawing_Font *font = OH_Drawing_FontCreate();
119// 设置字体大小
120OH_Drawing_FontSetTextSize(font, 150);
121const char *str = "Hello world";
122// 创建字块对象
123OH_Drawing_TextBlob *textBlob =
124    OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8);
125// 绘制字块
126OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, 200, 800);
127// 取消填充效果
128OH_Drawing_CanvasDetachBrush(canvas);
129// 销毁各类对象
130OH_Drawing_TextBlobDestroy(textBlob);
131OH_Drawing_FontDestroy(font);
132OH_Drawing_BrushDestroy(brush);
133```
134
135![Screenshot_20241225173900576](figures/Screenshot_20241225173900576.jpg)
136
137## 主题字体
138
139主题字体,特指系统**主题应用**中能使用的字体,属于一种特殊的自定义字体。如需涉及文本测量和布局排版相关内容,可参考[使用主题字体(C/C++)](theme-font-c.md)。
140
141设置跟随主题字体的示例代码和效果图如下:
142
143```c++
144// 创建字型对象
145OH_Drawing_Font *font = OH_Drawing_FontCreate();
146// 设置文字大小
147OH_Drawing_FontSetTextSize(font, 100);
148// 设置跟随主题字体
149OH_Drawing_FontSetThemeFontFollowed(font, true);
150// 需要绘制的文字
151const char *str = "Hello World";
152// 创建字块对象
153OH_Drawing_TextBlob *textBlob =
154    OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8);
155// 绘制字块
156OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, 200, 800);
157// 释放字块对象
158OH_Drawing_TextBlobDestroy(textBlob);
159// 释放字型对象
160OH_Drawing_FontDestroy(font);
161```
162
163| 未跟随主题字体的效果图 | 跟随主题字体的效果图(不同主题字体显示效果不同,此处仅示意) |
164| -------- | -------- |
165| ![Snapshot_setThemeFontFollowed_sys](figures/Snapshot_setThemeFontFollowed_sys.jpg) | ![Snapshot_setThemeFontFollowed](figures/Snapshot_setThemeFontFollowed.jpg) |
166
167> **说明**
168>
169> 需要在应用入口文件(默认工程中为EntryAbility.ets)中重写onConfigurationUpdate函数,以响应切换主题字体的操作,确保切换后页面能够及时刷新并生效。具体实现可参考[使用主题字体(C/C++)](theme-font-c.md)。
170
171## 单字绘制
172
173单字绘制是图形渲染中针对文本渲染的一种精细化控制技术。相比字块绘制,其核心优势在于能够利用字体退化机制,在当前字体无法显示某字符时,自动退化到使用系统字体绘制字符,提升对特殊字符的兼容性,避免字符缺失。同时,单字绘制支持逐字符配置字体特征(如连字、替代字形),满足复杂排版需求,增强用户体验。详细API说明请见[drawing_canvas.h](../reference/apis-arkgraphics2d/capi-drawing-canvas-h.md#oh_drawing_canvasdrawsinglecharacter)。
174
175基础场景:绘制无字体特征的字符
176对于无需字体特征的常规文本渲染场景,可以使用OH_Drawing_CanvasDrawSingleCharacter绘制单个字符,使用OH_Drawing_FontMeasureSingleCharacter测量单个字符的宽度,示例代码和效果图如下:
177
178```c++
179// 创建字型对象
180OH_Drawing_Font *font = OH_Drawing_FontCreate();
181// 设置文字大小
182OH_Drawing_FontSetTextSize(font, 100);
183float startX = 100;
184float startY = 100;
185const char* str = "Hello";
186for (int i = 0; i < 5; ++i) {
187    // 单字绘制
188    OH_Drawing_CanvasDrawSingleCharacter(canvas, &str[i], font, startX, startY);
189    float textWidth = 0.f;
190    // 测量单个字符的宽度
191    OH_Drawing_FontMeasureSingleCharacter(font, &str[i], &textWidth);
192    startX += textWidth;
193}
194// 释放字型对象
195OH_Drawing_FontDestroy(font);
196```
197
198![Snapshot_drawSingleCharacter](figures/Snapshot_drawSingleCharacter.jpg)
199
200进阶场景:绘制带字体特征的字符
201对于需要字体特征的文本渲染场景,可以使用OH_Drawing_CanvasDrawSingleCharacterWithFeatures绘制单个字符,使用OH_Drawing_FontMeasureSingleCharacterWithFeatures测量单个字符的宽度,示例代码和效果图如下:
202
203```c++
204// 创建字型对象
205OH_Drawing_Font *font = OH_Drawing_FontCreate();
206// 设置文字大小
207OH_Drawing_FontSetTextSize(font, 100);
208// 创建字体特征对象
209OH_Drawing_FontFeatures* features = OH_Drawing_FontFeaturesCreate();
210OH_Drawing_FontFeaturesAddFeature(features, "frac", 1);
211float startX = 100;
212float startY = 100;
213const char* str = "a2+b2";
214for (int i = 0; i < 5; ++i) {
215    // 单字绘制
216    OH_Drawing_CanvasDrawSingleCharacterWithFeatures(canvas, &str[i], font, startX, startY, features);
217    float textWidth = 0.f;
218    // 测量单个字符的宽度
219    OH_Drawing_FontMeasureSingleCharacterWithFeatures(font, &str[i], features, &textWidth);
220    startX += textWidth;
221}
222// 释放字体特征对象
223OH_Drawing_FontFeaturesDestroy(features);
224// 释放字型对象
225OH_Drawing_FontDestroy(font);
226```
227
228![Snapshot_drawSingleCharacter](figures/Snapshot_drawSingleCharacterWithFeatures.png)
229
230> **说明**
231>
232> 如果 `OH_Drawing_CanvasDrawSingleCharacterWithFeatures` 与 `OH_Drawing_FontMeasureSingleCharacter` 混合使用,或者 `OH_Drawing_CanvasDrawSingleCharacter` 与 `OH_Drawing_FontMeasureSingleCharacterWithFeatures` 混合使用,字体绘制可能会重叠。
233
234<!--RP1-->
235## 相关实例
236
237针对Drawing(C/C++)的开发,有以下相关实例可供参考:
238
239- [NDKGraphicsDraw (API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/Drawing/NDKGraphicsDraw)
240<!--RP1End-->