You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Skia中加载TrueType/OpenType集合并使用其中的指定字体样式?

解决方案

前置检查

  • 先确认你的SkiaSharp版本 ≥ 2.80.0,低于该版本存在ttcIndex参数不生效的已知bug,升级到稳定版即可修复
  • 加载用的流必须支持定位(Stream.CanSeek == true),如果是不可定位的网络流/非内存流,先拷贝到MemoryStream中再操作

具体实现步骤

1. 预处理流(仅不可定位流需要)

// 替换为你实际的字体集合流
Stream rawCollectionStream = GetFontCollectionStream();
MemoryStream seekableStream = new MemoryStream();
rawCollectionStream.CopyTo(seekableStream);
seekableStream.Position = 0;

2. 获取集合内字体总数量

调用带out int count参数的SKTypeface.FromStream重载,即可读取TTC/OTC文件内包含的字体总数:

int fontCount = 0;
// 临时Typeface用完即可释放
using (var _ = SKTypeface.FromStream(seekableStream, ttcIndex: 0, out fontCount))
{
    // 无操作,仅用于获取总数量
}
seekableStream.Position = 0; // 必须重置流位置到起始点

3. 循环加载所有字体

按索引遍历加载所有Typeface,注意每次加载完成后都要重置流位置:

List<SKTypeface> collectionTypefaces = new List<SKTypeface>();
for (int i = 0; i < fontCount; i++)
{
    var typeface = SKTypeface.FromStream(seekableStream, ttcIndex: i);
    if (typeface != null)
    {
        collectionTypefaces.Add(typeface);
    }
    // 重置流位置,避免下一次读取失败
    seekableStream.Position = 0;
}

常见问题说明

非零ttcIndex返回null的90%以上场景都是未重置流位置导致的,每次调用FromStream方法后,流的读取指针会移动到末尾,后续调用如果不重置位置就会读取不到有效数据,直接返回null。
加载完成后你可以通过SKTypeface.FamilyName、SKTypeface.FontWeight、SKTypeface.FontSlant等属性筛选所需的字体样式,正常用于Skia文本渲染即可。

内容的提问来源于stack exchange,提问作者John Carruthers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 00:39:03