字体(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)
}
}
}
该方法返回 FontBytes(ByteArray)列表。Runtime 会按 FIFO(先进先出)顺序尝试使用列表中的字体匹配字符。
另外,你也可以通过 Rive.setFallbackFont() 设置回退字体,并用 Fonts.FontOpts 指定偏好;这些字体会在尝试完 FontFallbackStrategy.getFont() 的结果之后再进行尝试。
2) Fonts.FontOpts(字体选项)
用于定义选择回退字体时的字体特征。
familyName:字体族名(例如"Roboto"、"NotoSansThai-Regular.ttf"),默认nulllang:可选语言标记,默认nullweight:字重(Fonts.Weight),默认Weight.NORMALstyle:样式(Fonts.Font.STYLE_NORMAL或Fonts.Font.STYLE_ITALIC),默认STYLE_NORMAL
默认示例:
val defaultFontOpts = Fonts.FontOpts.DEFAULT