跳到主要内容

字体(Fonts)

运行时换字体(Swapping Fonts at Runtime)

字体可以在运行时动态加载与替换。这使你可以为不同语言/地区提供不同字库,从而实现内容本地化,而无需把所有字体都内嵌进导出的 .riv 文件(避免文件体积显著增长)。

更多资源加载细节见:


回退字体(Fallback Fonts)

在渲染文本时,当前字体不一定包含所有字形(glyph / 字符)。这种情况常见于:

  • 使用的自定义字体不覆盖所有语言或 Unicode 范围
  • 内嵌字体是“子集字体”(subset),导致缺字
  • 用户生成/动态文本包含预期之外的字符

为避免出现“缺字 / 不可见 / 方块”等问题,一些平台支持 回退字体(fallback fonts):当主字体无法渲染某个字形时,会自动尝试回退字体(通常是系统字体,Unicode 覆盖更广)。

备注

Web 不支持系统回退字体。

出于安全原因,浏览器不允许 Canvas 访问本地系统文件(包括系统字体)。因此在 Web 上,Rive 只能使用你显式提供给运行时的字体资源。

备注

在 iOS 与 Android 上,为回退字体指定的字号(size)通常会被忽略;平台会选择最匹配文本样式与动画效果的系统字体。


React Native:加载与设置回退字体

完整示例参考:

加载回退字体

回退字体来源可以是:

  • 打包在 App 内的原生资源(bundled native asset)
  • 远程 URL
  • 通过名称指定的系统字体
import { RiveFonts } from '@rive-app/react-native';

// Bundled native font
const bundled = await RiveFonts.loadFont('kanit_regular.ttf');

// Remote font
const remote = await RiveFonts.loadFont({
uri: 'https://raw.githubusercontent.com/google/fonts/main/ofl/kanit/Kanit-Regular.ttf',
});

// System font by name
const system = await RiveFonts.loadFont({ name: 'Thonburi' });

设置回退字体

在挂载 Rive 视图之前调用 RiveFonts.setFallbackFonts()

await RiveFonts.setFallbackFonts({
default: [
bundled,
remote,
RiveFonts.systemFallback(),
],
});

清除回退字体配置

如需移除之前的配置,可调用:

await RiveFonts.clearFallbackFonts();

当你的 App 需要在重新创建 RiveView 之前“彻底重置字体配置”时,这会很有用。


Apple:静态列表与回调式回退

v6.1 起,在 iOS 与 macOS 上可使用多种回退字体方案。Apple Runtime 提供了一些 helper,用于按请求的字体样式选择系统字体;同时也可以直接使用 UIFont / NSFont

备注

如果没有注册任何回退字体,系统会使用一个“常规字重/字宽”的默认系统字体。

// 在应用生命周期的早期,调用类似下方的代码:
RiveFont.fallbackFonts = [
RiveFallbackFontDescriptor(), // 使用默认系统字体
RiveFallbackFontDescriptor(design: .default, weight: .bold, width: .expanded), // 使用粗体、加宽的系统字体
UIFont(name: "...", size: 20)!
]

// 也可以在运行时按 style 提供不同字体

v6.4 起,你还可以使用更动态的“回调式 API”:根据缺失字符所在 text run 的样式(style)返回不同字体。

// 与 fallbackFonts 类似,你可以使用 Rive helper types
// 或原生 UIFont/NSFont types
RiveFont.fallbackFontsCallback = { style in
switch style.weight {
case .thin: return [
RiveFallbackFontDescriptor(weight: .thin),
UIFont.systemFont(ofSize: 20, weight: .thin)
]
case .bold: return [
RiveFallbackFontDescriptor(weight: .bold),
UIFont.systemFont(ofSize: 20, weight: .bold)
]
default: return [
RiveFallbackFontDescriptor(),
UIFont.systemFont(ofSize: 20)
]
}
}

// 也可以使用 rawWeight 返回不同字体
RiveFont.fallbackFontsCallback = { style in
switch style.rawWeight {
case 100: return [
RiveFallbackFontDescriptor(weight: .thin),
UIFont.systemFont(ofSize: 20, weight: .thin)
]
case 700: return [
RiveFallbackFontDescriptor(weight: .bold),
UIFont.systemFont(ofSize: 20, weight: .bold)
]
default: return [
RiveFallbackFontDescriptor(),
UIFont.systemFont(ofSize: 20)
]
}
}

// 你也可以在运行时按 style 提供不同字体

Android:FontFallbackStrategy 与系统字体检索

v9.12.0 起,Android 上可以使用多种方式配置回退字体。

备注

如果没有注册任何回退字体,会使用默认系统字体("sans-serif")+ 常规字重(400,NORMAL)+ 正常样式(NORMAL)。

Fonts 类提供了一些 API 用于:检索系统字体、定义字体偏好(font options),以及按特征查找回退字体。

1) 设置回退策略(Fallback Strategy)

在 v9.12.0 中,Runtime 提供了 FontFallbackStrategy 接口,用于按字重(weight)匹配回退字体。

接口包含一个方法:

fun getFont(weight: Fonts.Weight): List<FontBytes>

实现后,将实例设置为当前策略(FontFallbackStrategy.stylePicker)。示例:

class FontFallback : AppCompatActivity(), FontFallbackStrategy {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set the fallback strategy
FontFallbackStrategy.stylePicker = this
}

override fun getFont(weight: Fonts.Weight): List<FontBytes> {
val desiredWeight = weight.weight
val fonts = listOf(
Fonts.FontOpts(
familyName = "sans-serif",
weight = Fonts.Weight(weight = desiredWeight) // Find a matching weight font
),
// Non-Latin Unicode fallback
Fonts.FontOpts("NotoSansThai-Regular.ttf")
)
return fonts.mapNotNull {
// Filter out fonts that cannot be found on the system
FontHelper.getFallbackFontBytes(it)
}
}
}

该方法返回 FontBytesByteArray)列表。Runtime 会按 FIFO(先进先出)顺序尝试使用列表中的字体匹配字符。

另外,你也可以通过 Rive.setFallbackFont() 设置回退字体,并用 Fonts.FontOpts 指定偏好;这些字体会在尝试完 FontFallbackStrategy.getFont() 的结果之后再进行尝试。

2) Fonts.FontOpts(字体选项)

用于定义选择回退字体时的字体特征。

  • familyName:字体族名(例如 "Roboto""NotoSansThai-Regular.ttf"),默认 null
  • lang:可选语言标记,默认 null
  • weight:字重(Fonts.Weight),默认 Weight.NORMAL
  • style:样式(Fonts.Font.STYLE_NORMALFonts.Font.STYLE_ITALIC),默认 STYLE_NORMAL

默认示例:

val defaultFontOpts = Fonts.FontOpts.DEFAULT

3) 根据条件检索回退字体

使用 FontHelper.getFallbackFont() 可以按指定选项找到合适的回退字体;如果找不到则返回 null

val fontOpts = Fonts.FontOpts(familyName = "Roboto", weight = Fonts.Weight.BOLD)
val fallbackFont = FontHelper.getFallbackFont(fontOpts)

4) 获取字体文件与字节

  • FontHelper.getFontFile(font: Fonts.Font):获取指定字体对应的文件
  • FontHelper.getFontBytes(font: Fonts.Font):读取字体文件并返回其字节
val fontFile = FontHelper.getFontFile(fallbackFont)
val fontBytes = FontHelper.getFontBytes(fallbackFont)

5) Fonts.Weight(字重)

表示字重(0~1000)。

  • Fonts.Weight.NORMAL(400)
  • Fonts.Weight.BOLD(700)
val normalWeight = Fonts.Weight.NORMAL
val customWeight = Fonts.Weight.fromInt(500)

6) Fonts.Style(样式)

表示字体样式:normalitalic

  • Fonts.Font.STYLE_NORMAL
  • Fonts.Font.STYLE_ITALIC
val normalStyle = Fonts.Font.STYLE_NORMAL
val italicStyle = Fonts.Font.STYLE_ITALIC

7) 获取系统字体列表

  • FontHelper.getSystemFonts():返回可用系统字体族的 map。
val systemFonts = FontHelper.getSystemFonts()

与 Feature Support 的关系

你可以在“特性支持矩阵”中查看 Fallback Fonts 在各运行时的支持情况与最低版本: