目录

使用属性字符串

部分框架或应用具备自研的文字排版能力,在移植时,其文字排版能力会被对接到方舟2D图形服务的文本引擎。为了避免开发者重复开发文本组件,Text组件可以通过ArkUI_NodeAttributeType中的NODE_TEXT_CONTENT_WITH_STYLED_STRING属性,使用格式化字符串对象设置文本内容属性,直接渲染方舟文本引擎生成的文本。

  • 本篇示例仅提供核心接口的调用方法,完整的示例工程请参考StyledStringSample。

以下示例代码基于接入ArkTS页面章节,阐述了如何创建StyledString,并利用ArkUI_NodeType为ARKUI_NODE_TEXT的组件进行渲染显示。

下图展示了 NODE_TEXT_CONTENT_WITH_STYLED_STRING 接口的主要使用流程。

创建StyledString对象

使用OH_ArkUI_StyledString_Create接口创建StyledString对象,需要传入段落样式和字体集合。

// 创建StyledString对象
ArkUI_StyledString *styledString = OH_ArkUI_StyledString_Create(typographyStyle, fontCollection);

通过StyledString设置样式

StyledString支持为文本中的不同部分设置不同的样式,包括段落样式和文本样式。

[h2]设置段落样式

通过如下接口可以设置StyledString的段落样式属性,包括最大行数、对齐方式等。

StyledString需要依赖OH_Drawing_前缀的方舟字体引擎接口进行字体以及段落样式的设置,参考简单文本绘制与显示(C/C++)、复杂文本绘制与显示(C/C++)。涉及字体引擎的接口,需在CMakeLists.txt中添加target_link_libraries(entry PUBLIC libnative_drawing.so),否则链接阶段会报错。

表1 段落样式设置接口

接口 描述
OH_Drawing_CreateFontCollection 创建字体集对象。
OH_Drawing_CreateTypographyStyle 创建段落样式对象。
OH_Drawing_SetTypographyTextAlign 设置文本对齐方式。
OH_Drawing_SetTypographyTextMaxLines 设置文本最大行数。

以下代码示例设置了文字居中,最大行数限制为10。

// 创建字体集合与段落样式,并设置对齐方式和最大行数
OH_Drawing_FontCollection *fontCollection = OH_Drawing_CreateFontCollection();
OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextAlign(typographyStyle, OH_Drawing_TextAlign::TEXT_ALIGN_CENTER);
OH_Drawing_SetTypographyTextMaxLines(typographyStyle, NUM_10);

[h2]设置文本样式

不同内容的文本可以通过StyledString设置不同的文本样式,但必须按照以下三个接口的逻辑调用顺序进行设置,否则将无法生效。

  1. OH_ArkUI_StyledString_PushTextStyle:将文字样式推入栈中。
  2. OH_ArkUI_StyledString_AddText:添加要修改样式的文字内容。
  3. OH_ArkUI_StyledString_PopTextStyle:将文字样式弹出栈。

表2 文本样式设置接口

接口 描述
OH_Drawing_CreateTextStyle 创建文本样式对象。
OH_Drawing_SetTextStyleFontSize 设置字体大小。
OH_Drawing_SetTextStyleColor 设置字体颜色。

使用OH_Drawing_CreateTextStyle创建文本样式。以下示例设置"Hello"字体大小28px,颜色为0xFF707070,显示为灰色;设置"World!"字体大小为28px,颜色为0xFF2787D9,显示为蓝色。

// 第一段文本(灰色"Hello")
OH_Drawing_TextStyle *textStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleFontSize(textStyle, FONT_SIZE);
OH_Drawing_SetTextStyleColor(textStyle, TEXT_COLOR_GRAY);
OH_ArkUI_StyledString_PushTextStyle(styledString, textStyle);
OH_ArkUI_StyledString_AddText(styledString, "Hello");
OH_ArkUI_StyledString_PopTextStyle(styledString);
// 第二段文本(蓝色"World!")
OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleFontSize(worldTextStyle, FONT_SIZE);
OH_Drawing_SetTextStyleColor(worldTextStyle, TEXT_COLOR_BLUE);
OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
OH_ArkUI_StyledString_AddText(styledString, "World!");
OH_ArkUI_StyledString_PopTextStyle(styledString);

添加占位符

占位符功能主要用于图文混排场景,可以在文本中插入指定大小的空白区域,用于挂载Image组件或其他自定义内容。

使用OH_ArkUI_StyledString_AddPlaceholder接口在文本中插入占位符。

// 添加占位符
OH_Drawing_PlaceholderSpan placeHolder{.width = PLACEHOLDER_WIDTH, .height = PLACEHOLDER_HEIGHT};
OH_ArkUI_StyledString_AddPlaceholder(styledString, &placeHolder);

布局与绘制

StyledString在设置到Text组件之前,需要先完成布局计算,然后再进行渲染。

文字样式和内容设置完成后,调用字体引擎接口OH_Drawing_TypographyLayout对文本进行布局,传入最大宽度。超过此宽度的文字会自动换行。

OH_Drawing_Typography *typography = OH_ArkUI_StyledString_CreateTypography(styledString);
OH_Drawing_TypographyLayout(typography, LAYOUT_MAX_WIDTH);
// 布局完成后,将StyledString设置给Text组件
ArkUI_AttributeItem styledStringItem = {.object = styledString};
nodeApi->setAttribute(text, NODE_TEXT_CONTENT_WITH_STYLED_STRING, &styledStringItem);

序列化与反序列化

从API version 14开始,StyledString提供了序列化和反序列化功能,支持将字节数据反序列化为描述符,或将描述符转换为HTML格式,便于数据的存储、传输和跨平台使用。

表3 序列化与反序列化接口

接口 描述
OH_ArkUI_StyledString_Descriptor_Create 创建StyledString描述符。
OH_ArkUI_UnmarshallStyledStringDescriptor 反序列化字节数据到描述符。
OH_ArkUI_ConvertToHtml 将描述符转换为HTML格式。
OH_ArkUI_StyledString_Descriptor_Destroy 销毁StyledString描述符。

以下示例展示了如何创建描述符、反序列化字节数据、转换为HTML并进行验证。

static void SerializeAndDeserializeStyledString()
{
    // 准备测试数据
    uint8_t data_bytes[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    size_t dataSize = sizeof(data_bytes) / sizeof(data_bytes[0]);

    // 创建StyledString描述符
    auto desc = OH_ArkUI_StyledString_Descriptor_Create();
    if (desc == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "styledString", "Create Descriptor failed");
        return;
    }

    // 反序列化字节数据
    auto status = OH_ArkUI_UnmarshallStyledStringDescriptor(data_bytes, dataSize, desc);
    OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "styledString", "Unmarshall status: %{public}d", status);

    // 转换为HTML格式
    const char* html = OH_ArkUI_ConvertToHtml(desc);
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "styledString", "html: [%{public}s]", html);
    size_t resultSize = dataSize + 2;
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "styledString", "resultSize: %{public}zu", resultSize);
    uint8_t *buf2 = (uint8_t *)malloc(resultSize * sizeof(uint8_t));

    // 验证反序列化后的数据
    if (buf2 != nullptr) {
        if (resultSize >= dataSize) {
            for (size_t i = 0; i < dataSize; i++) {
                buf2[i] = data_bytes[i];
            }
        } else {
            OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "styledString",
                         "Buf too small: %{public}zu < %{public}zu", resultSize, dataSize);
            free(buf2);
            OH_ArkUI_StyledString_Descriptor_Destroy(desc);
            return;
        }
        bool equal = true;
        for (size_t i = 0; i < dataSize && equal; i++) equal = (data_bytes[i] == buf2[i]);
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "styledString",
            "Before: %{public}zu, After: %{public}zu, Equal: %{public}d", dataSize, resultSize, equal);
        free(buf2);
    }

    // 释放描述符
    OH_ArkUI_StyledString_Descriptor_Destroy(desc);
}

销毁对象

Text组件不对本文涉及的任何对象的生命周期进行管理,需由开发者自行负责。字体引擎接口均配有相应的销毁方法。

OH_Drawing_DestroyTextStyle(OH_Drawing_TextStyle *style):销毁文本样式对象。

OH_Drawing_DestroyTypographyStyle(OH_Drawing_TypographyStyle *style):销毁段落样式对象。

当Text组件仍在界面上显示时,此时释放会导致文字无法绘制。在实际业务场景下需确保Text组件不再使用时才释放。

相关字体引擎销毁的接口请参考OH_Drawing_DestroyTextStyle 和 OH_Drawing_DestroyTypographyStyle。

Text组件提供OH_ArkUI_StyledString_Destroy,用于销毁属性字符串对象。