我有一个用例,需要在画布元素上渲染大量(〜50,000个字形)清晰,可伸缩的文本字符串.到目前为止,我尝试过的最佳解决方案包括对在画布元素上绘制的文本进行三角剖分(文本是使用fillText方法绘制的),通过WebGL将矩阵统一和代表该字符串的三角形的Float32Array上载到GPU.使用这种方法,我能够以约30fps的速度渲染100,000个字形.字形在非常高的缩放级别下会变得块状,但这对于我的用例来说很好.
但是,此方法的开销约为每个字符串250毫秒,因为我先将字符串绘制到内存中的canvas元素,读取像素数据,将位图图像转换为矢量,然后对矢量数据进行三角剖分.在网上搜索解决方案时,我遇到了两个有趣的开源项目:
> OpenType.js:https://opentype.js.org/
>耳塞:https://github.com/mapbox/earcut
因此,现在我想重新编写我的初始概念证明,以使用OpenType和Earcut. OpenType用于将曲线数据输入到Earcut中,而Earcut用于对该数据进行三角测量并返回一个表示每个三角形的点的数组.
我的问题是,我不知道如何获取OpenType提供的数据并将其转换为Earcut接受的格式.有人可以为此提供协助吗?
更多信息:
这个*问题有很多有用的信息,但是缺少一些实现细节:Better Quality Text in WebGL.我想我要实现的是第一个答案中描述的“作为几何图形的字体”方法.
解决方法:
您可以使用Font.getPath创建路径.路径包含可通过path.commands访问的移动到,直线到,曲线到,四边形和关闭指令.当然,您首先需要将贝塞尔曲线指令转换成小段.
拥有一组闭合路径后,您需要确定哪些是孔.内部轮廓线的方向与外部轮廓线的方向相反,您可以将它们分配给包含它们的最小外部轮廓线.一旦有了<外部轮廓和一组孔>的组,您应该能够将其输入到快捷库中.
这是一个简单的实现,假设没有交叉点.对我来说,它对大多数字体都非常有效,除了极少数具有相交路径的“奇特”字体.
这是一个工作示例:https://jsbin.com/gecakub/edit?html,js,output
除了为每个字符串创建网格之外,您还可以为单个字符创建网格,然后使用库中的字距调整数据自行放置网格.
编辑:此解决方案仅适用于TTF字体,尽管可以通过忽略路径方向并使用更好的“路径A在路径B内”检查来轻松调整CCF(.otf),除非字体具有相交的路径.