mapbox/node-fontnik工具使用介绍

作者: 猿基地 | 来源:发表于2016-10-21 21:25 被阅读1545次

    Mapbox GL JS本地化实践文章中,有提到node-fontnik这个工具,用于把otfttf字体转换为Mapbox GL使用的protobuf格式的SDF字体。由于篇幅的问题,在那篇文章中,并没有详细介绍这个工具。但该工具对于字体的生成至关重要,所以还是需要详细说明一下。

    字体加载约定

    此处需要说明一点,Mapbox GL JS加载字体是采用的分段式加载,而不是整个字体库加载。假如是英文国家的字体,一次性加载整个字体库,也不会有多大,但如果是中文字体呢?微软雅黑字体都有10多M,一次性加载肯定会出现加载时间过长的问题。

    具体如何分段加载?根据字符编码范围进行分段,Unicode字符采用2个字节编码,所以字符的编码的范围是[0, 65535],Mapbox GL JS按照每段长度256的方式,平均分为若干段。注意,每一段字体请求的命名方式为start-end.pbf。比如第一段则是0-255.pbf,依次是256-511.pbf512-767.pbf...。

    工具使用

    在了解上面的规则的情况下,就可以利用工具进行转换,需要说明的是,它是一个库,并不是直接可运行可执行程序。不能直接配置待转换的字体,输出转换结果。它只是提供了可供使用的接口,需要自己写代码来实现最后的转换。打开工具页面,里面有个API.md,列出了该工具提供的可用接口。

    使用该库之前,按照readme的说明,在对应环境上安装好。最后编写代码完成最后一步的转换。此处贴出我编写的转换代码:

    var fontnik = require('.');
    var fs = require('fs');
    var path = require('path');
    
    var convert = function(fileName, outputDir) {
        var font = fs.readFileSync(path.resolve(__dirname + "/" + fileName));
        output2pbf(font, 0, 255, outputDir);
    }
    
    function output2pbf(font, start, end, outputDir) {
        if (start > 65535) {
            console.log("done!");
            return;
        }
        fontnik.range({font: font, start: start, end: end}, function(err, res) {
            var outputFilePath = path.resolve(__dirname + "/" + outputDir + start + "-" + end + ".pbf");
            fs.writeFile(outputFilePath, res, function(err){
                if(err) {
                    console.error(err);
                } else {
                    output2pbf(font, end+1, end+1+255, outputDir);
                }
            });
        });
    }
    
    convert("./fonts/NotoSansHans-Regular.otf", "./siyuan-pbf/Noto Sans Hans Regular/");
    convert("./fonts/NotoSansHans-Black.otf", "./siyuan-pbf/Noto Sans Hans Black/");
    convert("./fonts/NotoSansHans-Bold.otf", "./siyuan-pbf/Noto Sans Hans Bold/");
    convert("./fonts/NotoSansHans-DemiLight.otf", "./siyuan-pbf/Noto Sans Hans DemiLight/");
    convert("./fonts/NotoSansHans-Light.otf", "./siyuan-pbf/Noto Sans Hans Light/");
    convert("./fonts/NotoSansHans-Medium.otf", "./siyuan-pbf/Noto Sans Hans Medium/");
    convert("./fonts/NotoSansHans-Thin-Windows.otf", "./siyuan-pbf/Noto Sans Hans Thin Windows/");
    convert("./fonts/Microsoft-YaHei.ttf", "./yahei-pbf/Microsoft YaHei/");
    

    我在代码中转换了开源的思源字体和微软雅黑字体。经验证,转换后的字体均可用。请放心尝试。

    BTW:Mapbox GL JS的字体halo效果不错,有图有真相:

    MapBox Halo Font.png

    Okay,Bye!

    相关文章

      网友评论

      • YvanZhu:需要字体的朋友,可以看这篇博文https://www.cnblogs.com/ATtuing/p/9217029.html
      • 大块板砖:大佬,我执行node xxx.js 之后报错Cannot find module './lib/binding/fontnik.node' 咋整啊,你要不要写个傻瓜式操作文档?我小白,真心不懂啊
      • 悠然望剑:猿大神,我想用MapboxGL开发地图,我从官网上下载了mapbox-gl-js-0.45.0.zip包后,怎样才能离线使用MapboxGL库(由于网的原因,无法访问官网提供的CDN资源)。
        猿基地:@悠然望剑 看另一篇本地化的文章
      • 1e508ef7e28a:虽然字体做了分片,但是一个分片接近200k,初始化加载地图会请求大约40个pbf,一台服务器的带宽不够,后面的请求耗时要2s。
        有没有方法不使用这种字体分片的方式。
      • 1e508ef7e28a:必须顶一下
      • 李晓柒:你好,是在windows环境下实现的吗?我在win下不行
        cebdd8e4a5ef:https://github.com/mapbox/node-fontnik/issues/137这玩意不支持windows;
        对node的版本也有要求;
        在虚拟机centos6.5上也是各种错,放弃了。。。
      • 1c4a1b2bbd23:很安装不上这个工具 可以帮忙转一下常用的 黑体 嘛
      • f02384fbc9d4:英文没问题,CJK文字转了之后应用到系统。页面初始加载光字体文件就20兆多
        有什么好的解决办法吗。我用的是klokantech转好的思源字体。
        大的一P
        猿基地: @beikehanbao23 cjk? 没有自己指定文字路径
        f02384fbc9d4:@猿基地 在web端加载矢量瓦片,文字是中文,需要请求CJK的字体
        猿基地:转换后的字体都是分段的,客户端请求也是根据字来加载对应段的pbf文件,不会一开始就加载20M吧? 你做的是什么应用?
      • 四爷在此:我就说没有这么简单。。编译如此麻烦,还是大叔直接发来的好,哈哈😄
        猿基地:@四爷在此 没有接触过,你要裁剪到嵌入式系统上?
        四爷在此:@猿基地 我今天在用bitbake 编译裁剪版的nodejs ,大叔有没有接触过。。我正在各种谷歌填坑。我发现官方有发布不到10MB 的0.12.x 版本的nodejs,很小。。。
        猿基地:@四爷在此 我开始也以为比较简单,还好,搞出来了。要不然中文就恼火了。
      • Jididiah:顶一下

      本文标题:mapbox/node-fontnik工具使用介绍

      本文链接:https://www.haomeiwen.com/subject/zsucuttx.html