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 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 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 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|  |  | 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 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 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-->