Error: Offset is outside the bounds of the DataView ——以NotoSansCJK为例

in 未分类 with 0 comment

Error: Offset is outside the bounds of the DataView

前端界面中时常需要加载一些字体文件。而中文的字体文件相对很大,因此在网速过低的情况下(服务端或客户端),字体文件的加载就十分漫长,进而导致页面的渲染出现异常。

因此我们需要对加载的字体库进行有效的裁剪,从而使前端界面的渲染速度得到提高。

常用的字体裁剪工具有 Font-Spider。它能够自动索引html中包含的字体(font-face),并将html中出现的字符从字体文件中提取出来生成较小的裁剪后的文件。

但是对于 NotoSansCJK 字体而言,在裁剪过程中会产生 Error: Offset is outside the bounds of the DataView。通过查看调用栈信息,我们发现这是由于 Font-Spider 在调用 Fontmin 的 Otf2ttf 时产生了报错。因此考虑将 NotoSansCJK 字体转换为 ttf 尝试是否能够解决问题。

我直接安装了 fontmin,并尝试直接调用 otf2ttf 接口,不出所料依然产生了上述的报错。经过搜索我决定采用其他工具来实现 otf2ttf 的转换。https://github.com/adobe-type-tools/afdko/ 我找到了 Adobe 的 afdko(Adobe Font Development Kit for OpenType)来实现这个功能。

安装好后,运行 otf2ttf,等待片刻,NotoSansCJK 文件已经被转换为 ttf 格式的了。接着我再次使用 Font-Spider 结果仍然产生了报错。产生报错的调用栈信息显示依然是由于依赖 fontmin 导致。

这时候猜测是不是由于 NotoSansCJK 中某个字形,或者是因为 NotoSansCJK 中字形数目太多导致。

了解到 NotoSansCJK 中的 CJK 是分别代表中日韩三国的文字,此外由于包含多国的汉字字形,在应用该字体库的时候,汉字可能采用的其他语言的风格而导致显示不太统一。因为该字体是开源字体,所以我到 GitHub 上下载了只包含了简中的字体,NotoSansSC 但是使用字体转换后同样的还是产生了该类型的报错。

再次查询发现了 FontPruner 这个工具,这个工具同样适用于字体的裁剪,因此我打算使用这个工具进行尝试。文章中给出的repo 并不是原 repo。但是原 repo 已经五年没有更新,而这个 repo 也长达四年没有更新。最后我采用了https://github.com/cmd2001/FontPruner-python3 这个 repo 来实现,这个 repo 是在上述 repo 基础上构建的。

按照 repo 的说明我成功的裁剪出了字体,但是当我应用到项目中时,我发现前端的字体并没有发生任何改变,还是采用的默认字体,这让我感到很疑惑。查看了一下控制台谷歌浏览器报了个加载错误(忘了具体是什么了)。

查询后,我猜测应该是fontPruner导出的字体不能被浏览器正确解码识别,于是我考虑使用 Fontmin/Font-spider 对字体文件再进一次编解码,这次程序并没有发生报错,同时生成的字体也能在前端界正确加载了。

总结一下,我认为应该是 fontmin 的依赖 fonteditor-core 的 bug 导致的该问题。

下面介绍几项字体裁剪的思路:

1.直接采用 Font-spider 裁剪。

2.可能发生变化的文本、js 生成的文本采用 fontmin 手动裁剪。

3.发生报错后采用上述的方法裁剪。

需要注意的是,裁剪后的字体库可能发生行间距字间距的变化,可能需要手动调整。

Responses

captcha
请输入验证码