目录

Using Styled Strings

Some frameworks or applications have their own text layout capabilities, which are integrated into the ArkGraphics2D text engine during porting. To avoid the need for redeveloping text components, the Text component provides the NODE_TEXT_CONTENT_WITH_STYLED_STRING API, which can directly render text generated by the Ark text engine.

The following describes how to create a font engine text and render the text using a Text component based on integration with ArkTS pages.

For APIs involving the font engine, add target_link_libraries(entry PUBLIC libnative_drawing.so) to CMakeLists.txt; otherwise, a linking error will occur.

The following figure shows the main process for using the NODE_TEXT_CONTENT_WITH_STYLED_STRING API.

Creating a Text Component

Since text styles are set through font engine APIs, there is no need to configure style attributes such as text color and font size when creating a Text component. However, universal attributes such as width and height still need to be set. If they are unspecified, the component automatically adapts to the text content dimensions.

ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
    OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
if (nodeApi == nullptr) {
    return;
}
// ···
// Create a Text component.
ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT);
ArkUI_NumberValue textWidth[] = {{.f32 = 300}};
ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1};
nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem);
ArkUI_NumberValue textHeight[] = {{.f32 = 100}};
ArkUI_AttributeItem textHeightItem = {.value = textHeight, .size = 1};
nodeApi->setAttribute(text, NODE_HEIGHT, &textHeightItem);

Setting Paragraph and Text Styles

Adding a Placeholder

Placeholders reserve blank areas of specified sizes. While no text is drawn in these areas, they participate in layout measurement and affect text typesetting.

Line height is determined by the larger value between text height and placeholder height.

This example inserts a placeholder between "Hello" and "World!":

OH_Drawing_TextStyle *textStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleFontSize(textStyle, NUM_28);
OH_Drawing_SetTextStyleColor(textStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70));
// Apply style sequence: push -> add -> pop.
OH_ArkUI_StyledString_PushTextStyle(styledString, textStyle);
OH_ArkUI_StyledString_AddText(styledString, "Hello");
OH_ArkUI_StyledString_PopTextStyle(styledString);
// Add a placeholder. No text is rendered in this area, but it reserves space for other components. You can mount Image components at placeholder positions to achieve mixed text and image layouts.
OH_Drawing_PlaceholderSpan placeHolder{.width = 100, .height = 100};
OH_ArkUI_StyledString_AddPlaceholder(styledString, &placeHolder);
// Apply different styles.
OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleFontSize(worldTextStyle, NUM_28);
OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27, 0x87, 0xD9));
OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
OH_ArkUI_StyledString_AddText(styledString, "World!");
OH_ArkUI_StyledString_PopTextStyle(styledString);

Implementing Text Layout and Drawing

Destroying an Object

The Text component does not manage the lifecycle of any objects involved in this process. You are responsible for this.

**OH_Drawing_DestroyTextStyle(OH_Drawing_TextStyle *style)**: destroys the text style object.

**OH_Drawing_DestroyTypographyStyle(OH_Drawing_TypographyStyle *style)**: destroys the paragraph style object.

Releasing objects while the Text component is still displayed will cause rendering failures. Ensure that the Text component is no longer in use before releasing resources.

For details about the font engine cleanup APIs, see OH_Drawing_DestroyTextStyle and OH_Drawing_DestroyTypographyStyle.

The Text component provides OH_ArkUI_StyledString_Destroy to destroy styled string objects.

Sample

This section demonstrates core API usage only. For the complete sample project, see StyledStringSample.

#include "manager.h"
#include <sstream>
#include <arkui/native_interface.h>
#include <arkui/styled_string.h>
// ···
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_text_declaration.h>

namespace NativeNode::Manager {
constexpr int32_t NUM_10 = 10;
constexpr int32_t NUM_28 = 28;
constexpr int32_t NUM_400 = 400;
// ···
void NodeManager::CreateNativeNode()
{
    // ···
    ArkUI_NativeNodeAPI_1 *nodeApi = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
        OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
    if (nodeApi == nullptr) {
        return;
    }
    // Create a Column container component.
    ArkUI_NodeHandle column = nodeApi->createNode(ARKUI_NODE_COLUMN);
    ArkUI_NumberValue colWidth[] = {{.f32 = 300}};
    ArkUI_AttributeItem widthItem = {.value = colWidth, .size = 1};
    nodeApi->setAttribute(column, NODE_WIDTH, &widthItem);
    // Create a Text component.
    ArkUI_NodeHandle text = nodeApi->createNode(ARKUI_NODE_TEXT);
    ArkUI_NumberValue textWidth[] = {{.f32 = 300}};
    ArkUI_AttributeItem textWidthItem = {.value = textWidth, .size = 1};
    nodeApi->setAttribute(text, NODE_WIDTH, &textWidthItem);
    ArkUI_NumberValue textHeight[] = {{.f32 = 100}};
    ArkUI_AttributeItem textHeightItem = {.value = textHeight, .size = 1};
    nodeApi->setAttribute(text, NODE_HEIGHT, &textHeightItem);
    ArkUI_NumberValue borderWidth[] = {{.f32 = 1}};
    ArkUI_AttributeItem borderWidthItem = {.value = borderWidth, .size = 1};
    nodeApi->setAttribute(text, NODE_BORDER_WIDTH, &borderWidthItem);
    
    // OH_Drawing_ prefixed APIs are provided by the font engine. typographyStyle represents paragraph style configuration.
    OH_Drawing_TypographyStyle *typographyStyle = OH_Drawing_CreateTypographyStyle();
    OH_Drawing_SetTypographyTextAlign(typographyStyle, OH_Drawing_TextAlign::TEXT_ALIGN_CENTER);
    OH_Drawing_SetTypographyTextMaxLines(typographyStyle, NUM_10);
    // Create an ArkUI_StyledString object.
    ArkUI_StyledString *styledString = OH_ArkUI_StyledString_Create(typographyStyle, OH_Drawing_CreateFontCollection());
    // Create a text style and set the font and color.
    OH_Drawing_TextStyle *textStyle = OH_Drawing_CreateTextStyle();
    OH_Drawing_SetTextStyleFontSize(textStyle, NUM_28);
    OH_Drawing_SetTextStyleColor(textStyle, OH_Drawing_ColorSetArgb(0xFF, 0x70, 0x70, 0x70));
    // Apply style sequence: push -> add -> pop.
    OH_ArkUI_StyledString_PushTextStyle(styledString, textStyle);
    OH_ArkUI_StyledString_AddText(styledString, "Hello");
    OH_ArkUI_StyledString_PopTextStyle(styledString);
    // Add a placeholder. No text is rendered in this area, but it reserves space for other components. You can mount Image components at placeholder positions to achieve mixed text and image layouts.
    OH_Drawing_PlaceholderSpan placeHolder{.width = 100, .height = 100};
    OH_ArkUI_StyledString_AddPlaceholder(styledString, &placeHolder);
    // Apply different styles.
    OH_Drawing_TextStyle *worldTextStyle = OH_Drawing_CreateTextStyle();
    OH_Drawing_SetTextStyleFontSize(worldTextStyle, NUM_28);
    OH_Drawing_SetTextStyleColor(worldTextStyle, OH_Drawing_ColorSetArgb(0xFF, 0x27, 0x87, 0xD9));
    OH_ArkUI_StyledString_PushTextStyle(styledString, worldTextStyle);
    OH_ArkUI_StyledString_AddText(styledString, "World!");
    OH_ArkUI_StyledString_PopTextStyle(styledString);
    // Create Typography of the font engine based on the StyledString object. The Typography object contains the configured text and its style.
    OH_Drawing_Typography *typography = OH_ArkUI_StyledString_CreateTypography(styledString);
    // Call the font engine layout method. The width must match the width of the Text component.
    // Layout width = Text component width - (Left padding + Right padding)
    OH_Drawing_TypographyLayout(typography, NUM_400);
    ArkUI_AttributeItem styledStringItem = {.object = styledString};
    // After the layout is complete, pass the object to the Text component through NODE_TEXT_CONTENT_WITH_STYLED_STRING.
    nodeApi->setAttribute(text, NODE_TEXT_CONTENT_WITH_STYLED_STRING, &styledStringItem);

    // Release resources. The application can determine when to release resources.
    OH_ArkUI_StyledString_Destroy(styledString);
    // Add Text as a child component of Column.
    nodeApi->addChild(column, text);
    // Add Column as a child component of XComponent.
    OH_NativeXComponent_AttachNativeRootNode(xComponent_, column);
}
} // namespace NativeNode::Manager