使用主题字体（C/C++）
=============

#### 场景介绍

主题字体，特指系统**主题应用**中能使用的字体，属于一种特殊的自定义字体。可以通过相关接口调用使能主题应用中的主题字体。

#### 实现机制

**图1** 主题字体的切换和使用

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/a1/v3/uO0F4aR2Qe2BHW5Dsm73eQ/zh-cn_image_0000002625188317.jpg?HW-CC-KV=V1&HW-CC-Date=20260612T073536Z&HW-CC-Expire=86400&HW-CC-Sign=257210D71320CCAE409A83B0C36E22C6BFF0A41B389882A031A0BB0F63EC0B8E)

针对主题字的切换使用，应用方应确保订阅主题字变更事件，当接收字体变更事件后，由应用方主动调用页面刷新才能实现主题字的切换，否则主题字只能在重启应用后才生效；主题字的绘制需要使用OH\_Drawing\_GetFontCollectionGlobalInstance来获取全局字体集对象，仅该接口返回的对象拥有主题字体信息。

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/39/v3/fZjDDk36SnWxE1i97Vrx3w/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073536Z&HW-CC-Expire=86400&HW-CC-Sign=809EB622908729FB4D1CBE9B1B13DDA74446F447F9831CEF14BB282C9A5A8557)

由OH\_Drawing\_CreateSharedFontCollection创建的字体集对象不包含主题字信息，无法用于绘制主题字。

#### 接口说明

注册使用主题字体的常用接口如下表所示，详细接口说明请参考[Drawing](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-drawing)。

| 接口名 | 描述 |
| :-- | :-- |
| OH\_Drawing\_FontCollection\* OH\_Drawing\_GetFontCollectionGlobalInstance(void) | 获取全局的字体集对象OH\_Drawing\_FontCollection。 |
| [onConfigurationUpdate()](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-app-ability-ability#abilityonconfigurationupdate) | 
系统配置更新时调用。

主题应用当前仅提供ArkTS接口发布变更事件，需要应用自行处理进行跨语言调用。

 |

#### 开发步骤

1.  请确保在设备系统**主题应用**中，能成功应用一项主题字体。
    
2.  在应用入口文件（默认工程中为EntryAbility.ets）中重写onConfigurationUpdate函数，以响应fontId变更，适配主题字体的切换和页面刷新，重写方式可参考[主题字变更事件](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/theme-font-arkts#开发步骤)。
    
    系统配置信息（即示例中的newConfig）变化时，会自动触发onConfigurationUpdate函数。应用可从系统发送的配置信息获取fontId，通过判断是否与应用本地保存的fontId一致来识别主题字的切换。若不一致则刷新本地fontId，并调用C++代码刷新排版结果。从ArkTS到C++的调用通路需应用根据实际情况选取调用方式，本示例不作推荐。跨语言调用可参考[Node-API简介](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/napi-introduction)。
    
3.  导入C++侧依赖，本步骤及之后均为主题字体在C++侧的使用
    
    在工程的src/main/cpp/CMakeLists.txt文件中添加以下lib。
    
    libnative\_drawing.so
    
    导入头文件。
    
    #include <native\_drawing/drawing\_font\_collection.h>
    #include <native\_drawing/drawing\_text\_typography.h>
    #include <native\_drawing/drawing\_register\_font.h>
    
4.  创建字体管理器。
    
    ![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/5b/v3/VKjQRcGFQi6duG4-6Fz2aw/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073536Z&HW-CC-Expire=86400&HW-CC-Sign=C05962E81972E6D81C81043C2CF92C2647040FAAEDB860347246E3B9A02CD976)
    
    注册主题字体作用于字体管理集全局对象，故必须使用OH\_Drawing\_GetFontCollectionGlobalInstance获取全局字体集对象进行绘制。如若使用OH\_Drawing\_CreateSharedFontCollection或OH\_Drawing\_CreateFontCollection创建字体集对象，无法使用主题字体。OH\_Drawing\_GetFontCollectionGlobalInstance获取的全局字体集不允许释放，释放会造成字体绘制紊乱问题。
    
    OH\_Drawing\_FontCollection \*fontCollection = OH\_Drawing\_GetFontCollectionGlobalInstance();
    
5.  OH\_Drawing\_SetTextStyleFontFamilies()接口可以用来指定字体家族名，从而实现使用指定字体。但使用主题字体，不需要使用OH\_Drawing\_SetTextStyleFontFamilies()接口指定字体，否则行为变更为优先使用指定字体，而不是主题字体。
    
    OH\_Drawing\_TextStyle \*myTextStyle = OH\_Drawing\_CreateTextStyle();
    // const char\* myFontFamilies\[\] = {"otherFontFamilyName"};
    // 注意不要使用此接口来指定字体
    // OH\_Drawing\_SetTextStyleFontFamilies(textStyle, 1, myFontFamilies);
    
6.  设置段落文本内容为"Hello World. \\nThis is the theme font."，此时该段落文本将应用主题字体。
    
    // 设置其他文本样式
    OH\_Drawing\_SetTextStyleColor(myTextStyle, OH\_Drawing\_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
    // 设置字体大小为100.0
    OH\_Drawing\_SetTextStyleFontSize(myTextStyle, 100.0);
    // 创建一个段落样式对象，以设置排版风格
    OH\_Drawing\_TypographyStyle \*typographyStyle = OH\_Drawing\_CreateTypographyStyle();
    OH\_Drawing\_SetTypographyTextAlign(typographyStyle, TEXT\_ALIGN\_LEFT); // 设置段落样式为左对齐
    // 创建一个段落生成器
    OH\_Drawing\_TypographyCreate \*handler = OH\_Drawing\_CreateTypographyHandler(typographyStyle, fontCollection);
    // 在段落生成器中设置文本样式
    OH\_Drawing\_TypographyHandlerPushTextStyle(handler, myTextStyle);
    // 在段落生成器中设置文本内容
    const char \*text = "Hello World. \\nThis is the theme font.";
    OH\_Drawing\_TypographyHandlerAddText(handler, text);
    // 通过段落生成器生成段落
    OH\_Drawing\_Typography \*typography = OH\_Drawing\_CreateTypography(handler);
    

#### 效果展示

以下展示了在系统**主题应用**中切换使用不同主题字体后，对应的文字渲染效果。

不同主题字体显示效果不同，此处仅示意。

**图2** 主题字体1的效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/ef/v3/bStSmK4iSE24w7MWwJb0DQ/zh-cn_image_0000002594828874.png?HW-CC-KV=V1&HW-CC-Date=20260612T073536Z&HW-CC-Expire=86400&HW-CC-Sign=42A87DBED019EC712F1A1A1ED45AD511E3DAA2B412ECA8A044BCBBFAA6BC7AFF)

**图3** 主题字体2的效果

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/96/v3/ADmizDORRweMsAE5O5OpyQ/zh-cn_image_0000002625188321.png?HW-CC-KV=V1&HW-CC-Date=20260612T073536Z&HW-CC-Expire=86400&HW-CC-Sign=8017C9BAA22B22678F3AF1620C1E2B3F71F171960E5A6E55D81C11BA6E166CC1)