1# 自定义字体的注册和使用(ArkTS) 2 3## 场景介绍 4 5自定义字体是指开发者根据应用需求创建或选择的字体,通常用于实现特定的文字风格或满足独特的设计要求。当应用需要使用特定的文本样式和字符集时,可以注册并使用自定义字体进行文本渲染。 6 7## 实现流程 8 9**自定义字体的注册**是指将字体文件(如ttf、otf文件等)从应用资源注册到系统中,使得应用能够使用这些字体进行文本渲染。注册过程通常指将字体文件通过字体管理接口注册到系统字体库中,以便在应用中进行调用。 10 11**自定义字体的使用**是指在应用中显式指定使用已注册的自定义字体进行文本渲染。开发者可以根据需要选择特定的文本样式(如常规、粗体、斜体等),并将其应用到UI元素、文本控件或其他文本展示区域,以确保符合设计要求并提供一致的视觉效果。 12 13 14## 接口说明 15 16自定义字体注册和使用的常用接口如下表所示,详细接口说明请见[@ohos.graphics.text (文本模块)](../reference/apis-arkgraphics2d/js-apis-graphics-text.md)。 17 18| 接口 | 描述 | 19| -------- | -------- | 20| loadFontSync(name: string, path: string \| Resource): void | 同步接口,将路径对应的文件,以name作为使用的别名,注册自定义字体。<br/>**说明:**<br/>需保证使用自定义字体时,自定义字体已完成注册,非性能严格要求场景下,建议使用同步接口。 | 21| loadFont(name: string, path: string \| Resource): Promise<void> | 使用指定的别名和文件路径注册对应字体,使用Promise异步回调。此接口从API version 14开始支持。 | 22 23## 开发步骤 24 251. 导入依赖的相关模块。 26 27 ```ts 28 import { NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI' 29 import { UIContext } from '@kit.ArkUI' 30 import { text } from '@kit.ArkGraphics2D' 31 ``` 32 332. 注册自定义字体。有以下两种方式: 34 35 ```ts 36 // 注册自定义字体 37 let fontCollection = text.FontCollection.getGlobalInstance() 38 // 方式一:/system/fonts/myFontFile.ttf文件仅为示例路径,应用根据自身实际填写文件路径 39 fontCollection.loadFontSync('myFamilyName0', 'file:///system/fonts/myFontFile.ttf') 40 41 // 方式二:确保已经将自定义字体myFontFile.ttf文件放在本应用工程的entry/src/main/resources/rawfile目录 42 fontCollection.loadFontSync('myFamilyName1',$rawfile('myFontFile.ttf')) 43 ``` 44 453. 使用自定义字体。 46 47 ```ts 48 // 填写注册自定义字体时传入的字体家族名 49 let myFontFamily: Array<string> = ["myFamilyName0"] 50 // 设置文本样式 51 let myTextStyle: text.TextStyle = { 52 color: { alpha: 255, red: 255, green: 0, blue: 0 }, 53 fontSize: 100, 54 // 在文本样式中加入可使用的自定义字体 55 fontFamilies: myFontFamily 56 }; 57 ``` 58 594. 创建段落样式,并使用字体管理器实例构造段落生成器PargraphBuilder实例。 60 61 ```ts 62 // 创建一个段落样式对象,以设置排版风格 63 let myParagraphStyle: text.ParagraphStyle = {textStyle: myTextStyle} 64 // 创建一个段落生成器 65 let paragraphBuilder: text.ParagraphBuilder = new text.ParagraphBuilder(myParagraphStyle, fontCollection); 66 ``` 67 685. 生成段落。 69 70 ```ts 71 // 在段落生成器中设置文本样式 72 ParagraphGraphBuilder.pushStyle(myTextStyle); 73 // 在段落生成器中设置文本内容 74 ParagraphGraphBuilder.addText("测试自定义字体"); 75 // 通过段落生成器生成段落 76 let paragraph = ParagraphGraphBuilder.build(); 77 ``` 78 79## 完整示例 80 81这里以使用自定义注册字体方式一为例绘制“Custom font test”文本,并提供如下完整示例。 82 83请保证自定义字体文件已放置到设备正确的路径下。 84 85```ts 86// Index.ets 87import { NodeController, FrameNode, RenderNode, DrawContext } from '@kit.ArkUI' 88import { UIContext } from '@kit.ArkUI' 89import { text } from '@kit.ArkGraphics2D' 90class MyRenderNode extends RenderNode { 91 async draw(context: DrawContext) { 92 // 创建画布canvas对象 93 const canvas = context.canvas 94 // 获取全局字体集实例 95 let fontCollection = text.FontCollection.getGlobalInstance() //获取Arkui全局FC 96 // 注册自定义字体 97 fontCollection.loadFontSync('myFamilyName', 'file:///system/fonts/myFontFile .ttf') 98 // 使用自定义字体 99 let myFontFamily: Array<string> = ["myFamilyName"] // 如果已经注册自定义字体,填入自定义字体的字体家族名 100 // 设置文本样式 101 let myTextStyle: text.TextStyle = { 102 color: { alpha: 255, red: 255, green: 0, blue: 0 }, 103 fontSize: 100, 104 // 在文本样式中加入可使用的自定义字体 105 fontFamilies: myFontFamily 106 }; 107 // 创建一个段落样式对象,以设置排版风格 108 let myParagraphStyle: text.ParagraphStyle = { 109 textStyle: myTextStyle, 110 align: 3, 111 wordBreak:text.WordBreak.NORMAL 112 }; 113 // 创建一个段落生成器 114 let ParagraphGraphBuilder = new text.ParagraphBuilder(myParagraphStyle, fontCollection) 115 // 在段落生成器中设置文本样式 116 ParagraphGraphBuilder.pushStyle(myTextStyle); 117 // 在段落生成器中设置文本内容 118 ParagraphGraphBuilder.addText("Custom font test"); 119 // 通过段落生成器生成段落 120 let paragraph = ParagraphGraphBuilder.build(); 121 // 布局 122 paragraph.layoutSync(1000); 123 paragraph.paint(canvas, 0, 800); 124 } 125} 126// 创建一个MyRenderNode对象 127function getNewRenderNode() { 128 const textNodeTest = new MyRenderNode(); 129 textNodeTest.frame = { x: 0, y: 0, width: 500, height: 500 } 130 textNodeTest.pivot = { x: 0.5, y: 0.5 } 131 textNodeTest.scale = { x: 1, y: 1 } 132 return textNodeTest; 133} 134const textNode = new MyRenderNode(); 135// 定义newNode的像素格式 136textNode.frame = { x: 0, y: 0, width: 500, height: 500 } 137textNode.pivot = { x: 0.5, y: 0.5 } 138textNode.scale = { x: 1, y: 1 } 139class MyNodeController extends NodeController { 140 private rootNode: FrameNode | null = null; 141 makeNode(uiContext: UIContext): FrameNode { 142 this.rootNode = new FrameNode(uiContext) 143 if (this.rootNode == null) { 144 return this.rootNode 145 } 146 const renderNode = this.rootNode.getRenderNode() 147 if (renderNode != null) { 148 renderNode.frame = { x: 0, y: 0, width: 300, height: 50 } 149 renderNode.pivot = { x: 0, y: 0 } 150 } 151 return this.rootNode 152 } 153 addNode(node: RenderNode): void { 154 if (this.rootNode == null) { 155 return 156 } 157 const renderNode = this.rootNode.getRenderNode() 158 if (renderNode != null) { 159 renderNode.appendChild(node) 160 } 161 } 162 clearNodes(): void { 163 if (this.rootNode == null) { 164 return 165 } 166 const renderNode = this.rootNode.getRenderNode() 167 if (renderNode != null) { 168 renderNode.clearChildren() 169 } 170 } 171} 172 173@Entry 174@Component 175struct RenderTest { 176 private myNodeController: MyNodeController = new MyNodeController() 177 build() { 178 Column() { 179 Row() { 180 NodeContainer(this.myNodeController) 181 .height('100%') 182 } 183 .height('90%') 184 .backgroundColor(Color.White) 185 Row(){ 186 Button("Draw Text") 187 .fontSize('16fp') 188 .fontWeight(500) 189 .margin({ bottom: 24, right: 12 }) 190 .onClick(() => { 191 this.myNodeController.clearNodes() 192 this.myNodeController.addNode(getNewRenderNode()) 193 }) 194 .width('50%') 195 .height(40) 196 .shadow(ShadowStyle.OUTER_DEFAULT_LG) 197 } 198 .width('100%') 199 .justifyContent(FlexAlign.Center) 200 .shadow(ShadowStyle.OUTER_DEFAULT_SM) 201 .alignItems(VerticalAlign.Bottom) 202 .layoutWeight(1) 203 } 204 } 205} 206``` 207 208## 效果展示 209 210 211