1# Using the Text Module for Text Display
2
3## When to Use
4
5The @ohos.graphics.text module provides APIs for creating complex text paragraphs, with various text styles, paragraph styles, and line break rules, and converting the information into layout data that can be efficiently rendered on the screen.
6
7## Available APIs
8
9The table below lists the common APIs provided by the @ohos.graphics.text module. For details about all the APIs, see [@ohos.graphics.text](../reference/apis-arkgraphics2d/js-apis-graphics-text.md).
10
11| API| Description|
12| -------- | -------- |
13| pushStyle(textStyle: TextStyle): void | Pushes a text style.|
14| addText(text: string): void | Inserts a text string into the paragraph being built.|
15| addPlaceholder(placeholderSpan: PlaceholderSpan): void | Inserts a placeholder into the paragraph being built.|
16| build(): Paragraph | Creates a paragraph object that can be used for subsequent typography and rendering.|
17| paint(canvas: drawing.Canvas, x: number, y: number): void | Paints the text on the canvas with the coordinate point (x, y) as the upper left corner.|
18
19## How to Develop
20
21When using the text engine to draw and display the text, you need to use the font manager, paragraph style, and paragraph builder of the @ohos.graphics.text module to create a text paragraph and display the text on the application.
22
23The following walks you through on how to draw and display a paragraph.
24### Adding Dependencies
25
26**Importing Dependency Files**
27```js
28import { NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI'
29import { UIContext } from '@kit.ArkUI'
30import { drawing } from '@kit.ArkGraphics2D'
31import { text } from '@kit.ArkGraphics2D'
32import { image } from '@kit.ImageKit'
33import { common2D } from '@kit.ArkGraphics2D'
34```
35
36Now you can use the APIs for text drawing.
37
38### Text Drawing
39
40The following steps describe how to create a paragraph object and display the paragraph text using the APIs of the @ohos.graphics.text module.
41
421. **Create a child class of RenderNode.**
43
44    Create the child class **MyRenderNode** and define drawing functions in it. Steps 2 and 3 describe the implementation of the draw functions. **RenderNode** contains operations on the tree structure and drawing attributes.
45
46    ```js
47    // Create a MyRenderNode class and draw the text.
48    class MyRenderNode extends RenderNode {
49
50        async draw(context: DrawContext) {
51            // ...
52        }
53    }
54    ```
55
562. **Create a canvas and set the pen and brush styles.**
57
58    Use **Pen** to create a pen object, and set the attributes such as anti-aliasing, color, and thickness. The pen is used to outline a shape.
59
60    Use **Brush** to create a brush object, and set the brush color. The brush is used to fill in a shape.
61
62    Use **attachPen** and **attachBrush** in **canvas** to attach the pen and brush to the canvas.
63
64    ```js
65    // Create a canvas object.
66    const canvas = context.canvas
67    // Create a pen object and set the anti-aliasing, color, and thickness attributes.
68    let pen = new drawing.Pen()
69    let pen_color : common2D.Color = { alpha: 0xFF, red: 0xFF, green: 0x00, blue: 0x00 }
70    pen.setColor(pen_color)
71
72    // Attach the pen to the canvas.
73    canvas.attachPen(pen)
74
75    // Create a brush object and set the color.
76    let brush = new drawing.Brush()
77    let brush_color : common2D.Color = { alpha: 0xFF, red: 0x00, green: 0xFF, blue: 0x00 }
78    brush.setColor(brush_color)
79
80    // Attach the brush to the canvas.
81    canvas.attachBrush(brush)
82    ```
83
843. **Draw the text.**
85
86    Use **TextStyle** to create a text style object named **myTextStyle**, and set the text color. Use **ParagraphStyle** to create a paragraph style object named **myParagraphStyle**, and set attributes such as the text style. Use **FontCollection** to create a font manager named **fontCollection**. Use **ParagraphBuilder** to create a paragraph builder named **ParagraphGraphBuilder**, with **myParagraphStyle** and **fontCollection** as input parameters. Call the APIs to push the text style and add the text. Call **build()** to generate a paragraph object named **paragraph**, and call **paint** to paint the paragraph on the screen.
87
88    ```js
89    // Set attributes such as the font color, weight, and size.
90    let myTextStyle: text.TextStyle = {
91        color: { alpha: 255, red: 255, green: 0, blue: 0 },
92    };
93    // Set the word break type, text break strategy, text direction, and alignment mode.
94    let myParagraphStyle: text.ParagraphStyle = {
95        textStyle: myTextStyle,
96        align: 3,
97        // Word break type: wordBreak:text.WordBreak.NORMAL
98    };
99    let fontCollection = new text.FontCollection();
100    let ParagraphGraphBuilder = new text.ParagraphBuilder(myParagraphStyle, fontCollection);
101    // Push the text style.
102    ParagraphGraphBuilder.pushStyle(myTextStyle);
103    // Add the text.
104    ParagraphGraphBuilder.addText("0123456789");
105    // Build a paragraph.
106    let paragraph = ParagraphGraphBuilder.build();
107    // Layout
108    paragraph.layoutSync(600);
109    // Draw the text.
110    paragraph.paint(canvas, 0, 0);
111    ```
112
1134. **Create a MyRenderNode object.**
114
115    Steps 1 to 3 build the **MyRenderNode** class and define the main drawing functions in it. Next, create a **MyRenderNode** object and set its pixel format.
116
117    ```js
118    // Create a MyRenderNode object.
119    const textNode = new MyRenderNode()
120    // Define the pixel format of MyRenderNode.
121    textNode.frame = { x: 100, y: 100, width: 200, height: 800 }
122    textNode.pivot = { x: 0.2, y: 0.8 }
123    textNode.scale = { x: 1, y: 1 }
124    ```
125
1265. **Create a child class of NodeController.**
127
128    Create the child class **MyNodeController**, and define the functions for creating FrameNode in it. **NodeController** defines the controller of a node container and controls the nodes in the lifecycle of the container. FrameNode defines the basic type of a node and contains a RenderNode.
129
130    ```js
131    class MyNodeController extends NodeController {
132        private rootNode: FrameNode | null = null;
133
134        makeNode(uiContext: UIContext): FrameNode {
135            this.rootNode = new FrameNode(uiContext)
136            if (this.rootNode == null) {
137                return this.rootNode
138            }
139            const renderNode = this.rootNode.getRenderNode()
140            if (renderNode != null) {
141                renderNode.frame = { x: 0, y: 0, width: 10, height: 500 }
142                renderNode.pivot = { x: 50, y: 50 }
143            }
144            return this.rootNode
145        }
146    }
147    ```
148
1496. **Define an interface for adding a node.**
150
151    Define an interface for adding a RenderNode in the **MyNodeController** class created in step 5.
152
153    ```js
154    addNode(node: RenderNode): void {
155        if (this.rootNode == null) {
156            return
157        }
158        const renderNode = this.rootNode.getRenderNode()
159        if (renderNode != null) {
160            renderNode.appendChild(node)
161        }
162    }
163    ```
164
1657. **Define an interface for deleting a node.**
166
167    Define an interface for deleting a RenderNode in the **MyNodeController** class created in step 5.
168
169    ```js
170    clearNodes(): void {
171        if (this.rootNode == null) {
172            return
173        }
174        const renderNode = this.rootNode.getRenderNode()
175        if (renderNode != null) {
176            renderNode.clearChildren()
177        }
178    }
179    ```
180
1818. **Draw the graphics and text blob.**
182
183    Create a **MyNodeController** instance and save it to the NodeContainer, add a **Button** component, and call the defined interfaces.
184
185    ```js
186    @Entry
187    @Component
188    struct RenderTest {
189        private myNodeController: MyNodeController = new MyNodeController()
190        build() {
191            Column() {
192                Row() {
193                    NodeContainer(this.myNodeController)
194                        .height('100%')
195                    Button("Draw Text")
196                        .margin({ bottom: 200, right: 12 })
197                        .onClick(() => {
198                            this.myNodeController.clearNodes()
199                            this.myNodeController.addNode(textNode)
200                        })
201                }
202                .width('100%')
203                .justifyContent(FlexAlign.Center)
204                .shadow(ShadowStyle.OUTER_DEFAULT_SM)
205                .alignItems(VerticalAlign.Bottom)
206                .layoutWeight(1)
207            }
208        }
209    }
210    ```
211
212    The following figure shows the drawing and display effect.
213
214    | Home page                                | Drawn text (WordBreak not set)                 | Drawn text (WordBreak set)              |
215    | ------------------------------------ | ---------------------------------------- | ------------------------------------ |
216    | ![main](./figures/JStextMainPage.jpg) | ![Draw Path](figures/JStextText.jpg)    | ![Draw Path](figures/JStextText2.jpg) |
217