鸿蒙开发-想精确控制字重?TypefaceArguments字体参数设置
文章摘要: TypefaceArguments是HarmonyOS绘图模块中用于精确控制字体变体的工具,支持从100(极细)到900(极粗)的连续字重调节。相比Font类的enableEmbolden模拟加粗,它直接调用字体文件内置的不同字重设计,实现更专业的排版效果。开发者可通过两种方式使用:在加载字体时通过makeFromFileWithArguments指定参数,或基于现有字体用makeFr
想精确控制字体的字重?TypefaceArguments 让你配置字体变体
你有没有注意过,很多字体其实不只是"粗体"和"细体"两种选择?像一些现代字体(比如 HarmonyOS Sans)支持连续的字重变化——从极细(Thin,100)到极粗(Black,900),中间有很多档位。在 HarmonyOS 的 drawing 模块里,TypefaceArguments 就是用来配置这些字体变体参数的。
TypefaceArguments 是什么?
下面是使用 TypefaceArguments 配置字重的完整流程:
简单说,TypefaceArguments 就是一个"字体属性配置器"。它让你能够指定字体的可变维度参数,比如字重(weight)。
你可能会问:Font 类不是有 enableEmbolden 来加粗吗?有什么区别?
区别在于:enableEmbolden 是"软件模拟加粗",它不管字体文件本身的设计,只是把笔画加粗。而 TypefaceArguments 是"使用字体文件本身的设计",如果字体文件支持多种字重,你可以精确地选择用哪一种。
打个比方:enableEmbolden 就像用粗笔写字,字的骨架还是原来的;TypefaceArguments 就像换了一套专门设计的粗体字模,每个笔画都是精心设计的。
创建 TypefaceArguments
创建一个 TypefaceArguments 对象很简单:
import { drawing } from '@kit.ArkGraphics2D';
let typeFaceArgument = new drawing.TypefaceArguments();
创建出来的是一个空的配置对象,你需要用 addVariation 方法来添加具体的参数。
添加字体变体:addVariation
addVariation 方法用来设置字体的可变维度参数:
import { drawing } from '@kit.ArkGraphics2D';
let typeFaceArgument = new drawing.TypefaceArguments();
typeFaceArgument.addVariation('wght', 10);
这里有两个参数:
axis:维度标签
目前支持的标签是 'wght',代表字重(weight)。这个标签来自 OpenType 字体规范里的可变字体(Variable Fonts)技术。
具体是否支持这个标签,取决于你加载的字体文件。不是所有字体都支持可变字重,你需要查看字体文件的具体支持情况。
value:参数值
对于字重(wght),常用的值有:
| 值 | 名称 | 说明 |
|---|---|---|
| 100 | Thin / Hairline | 极细 |
| 200 | Extra Light / Ultra Light | 超细 |
| 300 | Light | 细 |
| 400 | Normal / Regular | 常规 |
| 500 | Medium | 中等 |
| 600 | Semi Bold / Demi Bold | 半粗 |
| 700 | Bold | 粗 |
| 800 | Extra Bold / Ultra Bold | 超粗 |
| 900 | Black / Heavy | 极粗 |
注意:这个值必须在字体文件支持的范围内。如果传的值小于字体支持的最小值,会自动使用最小值;如果大于最大值,会自动使用最大值。
怎么使用 TypefaceArguments?
下面是两种使用方式的对比:
TypefaceArguments 通常配合 Typeface 的方法来使用。有两种方式:
方式一:加载字体时指定参数
import { RenderNode } from '@kit.ArkUI';
import { drawing } from '@kit.ArkGraphics2D';
class TextRenderNode extends RenderNode {
async draw(context: DrawContext) {
const canvas = context.canvas;
let font = new drawing.Font();
let str = "/system/fonts/HarmonyOS_Sans_Italic.ttf";
let typeFaceArgument = new drawing.TypefaceArguments();
const myTypeFace = drawing.Typeface.makeFromFileWithArguments(str, typeFaceArgument);
font.setTypeface(myTypeFace);
const textBlob = drawing.TextBlob.makeFromString("Hello World", font, drawing.TextEncoding.TEXT_ENCODING_UTF8);
canvas.drawTextBlob(textBlob, 60, 100);
}
}
用 Typeface.makeFromFileWithArguments 或 Typeface.makeFromRawFileWithArguments 在加载字体文件的同时指定参数。
方式二:基于现有字体创建变体
import { RenderNode } from '@kit.ArkUI';
import { drawing } from '@kit.ArkGraphics2D';
class TextRenderNode extends RenderNode {
async draw(context: DrawContext) {
const canvas = context.canvas;
let typeArguments = new drawing.TypefaceArguments();
typeArguments.addVariation("wght", 100);
const myTypeFace = drawing.Typeface.makeFromFile("/system/fonts/HarmonyOS_Sans_SC.ttf");
const typeFace1 = myTypeFace.makeFromCurrent(typeArguments);
let font = new drawing.Font();
font.setTypeface(typeFace1);
const textBlob = drawing.TextBlob.makeFromString("Hello World", font, drawing.TextEncoding.TEXT_ENCODING_UTF8);
canvas.drawTextBlob(textBlob, 60, 100);
}
}
这段代码先加载了 HarmonyOS_Sans_SC.ttf,然后用 makeFromCurrent 基于它创建了一个字重为 100(极细)的变体。
实际应用场景
场景一:标题和正文使用不同字重
做文章阅读 APP 时,标题用粗字重,正文用常规字重:
// 加载字体
let typeface = drawing.Typeface.makeFromFile("/system/fonts/HarmonyOS_Sans_SC.ttf");
// 标题:字重 700(粗体)
let titleArgs = new drawing.TypefaceArguments();
titleArgs.addVariation("wght", 700);
let titleTypeface = typeface.makeFromCurrent(titleArgs);
let titleFont = new drawing.Font();
titleFont.setTypeface(titleTypeface);
titleFont.setSize(28);
// 正文:字重 400(常规)
let bodyArgs = new drawing.TypefaceArguments();
bodyArgs.addVariation("wght", 400);
let bodyTypeface = typeface.makeFromCurrent(bodyArgs);
let bodyFont = new drawing.Font();
bodyFont.setTypeface(bodyTypeface);
bodyFont.setSize(16);
场景二:渐变字重效果
想做一个字重从细到粗的渐变效果?你可以创建多个不同字重的 Typeface:
let baseTypeface = drawing.Typeface.makeFromFile("/system/fonts/HarmonyOS_Sans_SC.ttf");
let weights = [100, 200, 300, 400, 500, 600, 700, 800, 900];
let fonts: drawing.Font[] = [];
for (let w of weights) {
let args = new drawing.TypefaceArguments();
args.addVariation("wght", w);
let tf = baseTypeface.makeFromCurrent(args);
let f = new drawing.Font();
f.setTypeface(tf);
f.setSize(24);
fonts.push(f);
}
// 然后用这些不同字重的 font 逐个绘制文字,形成渐变效果
场景三:根据用户偏好调整字重
有些用户喜欢看粗一点的文字,有些喜欢细一点的。你可以让用户在设置里选择字重偏好:
function createFontWithWeight(weight: number): drawing.Font {
let baseTypeface = drawing.Typeface.makeFromFile("/system/fonts/HarmonyOS_Sans_SC.ttf");
let args = new drawing.TypefaceArguments();
args.addVariation("wght", weight);
let tf = baseTypeface.makeFromCurrent(args);
let font = new drawing.Font();
font.setTypeface(tf);
font.setSize(16);
return font;
}
// 用户选择的字重(100-900)
let userPreferredWeight = 500;
let font = createFontWithWeight(userPreferredWeight);
场景四:数据可视化中的文字标注
在做图表时,不同重要级别的标注可能需要不同的字重:
let baseTypeface = drawing.Typeface.makeFromFile("/system/fonts/HarmonyOS_Sans_SC.ttf");
// 图表标题:字重 700
let titleArgs = new drawing.TypefaceArguments();
titleArgs.addVariation("wght", 700);
let titleTypeface = baseTypeface.makeFromCurrent(titleArgs);
// 坐标轴标签:字重 400
let labelArgs = new drawing.TypefaceArguments();
labelArgs.addVariation("wght", 400);
let labelTypeface = baseTypeface.makeFromCurrent(labelArgs);
// 辅助说明:字重 300
let captionArgs = new drawing.TypefaceArguments();
captionArgs.addVariation("wght", 300);
let captionTypeface = baseTypeface.makeFromCurrent(captionArgs);
注意事项
-
API 版本:TypefaceArguments 从 API version 20 开始支持。
-
字体文件必须支持可变字重:不是所有字体都支持
wght标签。你需要确认你使用的字体文件是否是可变字体(Variable Font)。如果字体不支持,设置的字重参数不会生效。 -
值的范围:传入的值必须在字体文件支持的范围内。超出范围的值会被自动截断到最小或最大值。
-
性能考虑:每次调用
makeFromCurrent都会创建一个新的 Typeface 对象。如果你需要频繁切换字重,建议把常用的字重变体缓存起来。 -
物理像素:和其他 drawing 对象一样,使用物理像素单位。
-
线程安全:单线程模型,需要自己管理线程安全。
小结
TypefaceArguments 是一个专门用来配置字体变体参数的工具类。目前它主要支持设置字重(wght),让你能够精确控制文字的粗细程度。
和 Font 的 enableEmbolden 不同,TypefaceArguments 使用的是字体文件本身的设计,效果更自然、更专业。如果你的 APP 需要精细的字重控制,TypefaceArguments 是更好的选择。
记住它是从 API version 20 开始支持的,而且需要字体文件本身支持可变字重才能生效。
更多推荐


所有评论(0)