Hot For Coding

WebGL解决中文字体载入的问题

WebGL

从写代码开始,中文导致的问题不计其数,本次也不例外。

WebGL里要显示中文有两种方式:

  • 2D效果 新建一个Canvas写上中文,然后再添加到WebGL里,优点是不用额外加载特定字体,网页能用什么字体它就能用什么字体,而且只要使用普通DOM API刷新内容,WebGL里render后就能渲染最新。使用DOM方便调试维护。缺点是这种方式还是2D的方式,没有完全发挥3D的效果。
  • 3D效果 每一个字体都是一个3D模型,优点是完全发挥3D效果可以配合3D实现原理能做出很炫的效果,缺点是这种方式需要额外准备字体模型库,然后还要载入页面中。

这还要分两种情况:

  • 静态展示型,这就好办,你需要多少个字就提前做好引入,没有任何问题。
  • 动态展示型,展示的字体根据动态数据随时变换,这种情况就要额外处理了,这也是本文讨论的解决方案。

一个中文字体有通常常用的也有五六千个字,有不少网站可以让你把ttf字体转为WebGL里能用的path,但这个过程还是非常痛苦的,转一次耗时非常长,重要的是还不一定能用,可能有bug。测试几个字体文件后,居然发现只有隶书能用,整个字体文件三十多兆

full

图片超过1M都觉得大了,不要说这个31M的字体文件在网速多快的情况下如何秒下,这是根本不可能的,只能需要另外一种方法来解决。打开lisu_regular.typeface.js文件,内容大部分都是每一个字的path,于是我认为可以把头尾摘出来,然后在需要哪个字体的时候预先向服务器端请求字体路径再描绘3D。

摘除字体path后的lisu_regular.typeface.js

if (_typeface_js && _typeface_js.loadFace) _typeface_js.loadFace({
  "glyphs":{},
  "cssFontWeight":"normal",
  "ascender":1194,
  "underlinePosition":-59,
  "cssFontStyle":"normal",
  "boundingBox":{"yMin":-255,"xMin":54.25,"yMax":1194,"xMax":1378.046875},
  "resolution":1000,
  "original_font_information":{
    "postscript_name":"LiSu",
    "version_string":"Version 3.01",
    "vendor_url":"",
    "full_font_name":"LiSu",
    "font_family_name":"LiSu",
    "copyright":"(C) Copyright Stone Co., 1996",
    "description":"",
    "trademark":"Trademark of Stone Co., Beijing",
    "designer":"",
    "designer_url":"",
    "unique_font_identifier":"LiSu",
    "license_url":"",
    "license_description":"",
    "manufacturer_name":"",
    "font_sub_family_name":"Regular"
  },
  "descender":-196,
  "familyName":"LiSu",
  "lineHeight":1584,
  "underlineThickness":13
});

摘除后的lisu_regular.typeface.js只有1k大小,与之前的31M相比是不是舒服了很多,大家看看glyphs默认是一个字体path都没有的,我们向服务器端请求载入几个字体看看

full

我们把请求的数据改写_typeface_,于是_typeface_里就有了这几个字的path

full

然后再做一些优化,比如要向服务器端请求字体path之前,先把重复的字给去掉,再把glyphs已存在的字给去掉就ok了

分享

TITLE: WebGL解决中文字体载入的问题

LINK: https://www.qttc.net/458-webgl-chinese-font.html

NOTE: 原创内容,转载请注明出自琼台博客