• mapbox/node-fontnik工具使用介绍


    在Mapbox GL JS本地化实践文章中,有提到node-fontnik这个工具,用于把otf和ttf字体转换为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的说明,在对应环境上安装好。最后编写代码完成最后一步的转换。此处贴出我编写的转换代码my_test.js :

    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);
                }
            });
        });
    }
    // 下面是需要转换的字体,和转换后pbf存放路径
    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/");

    convert("./fonts/open-sans/OpenSans-Regular.ttf", "./lgl/open sans regular/");

    convert("./fonts/Alegreya/Alegreya-Black.ttf", "./lgl/Alegreya-Black/");
    convert("./fonts/Alegreya/Alegreya-BlackItalic.ttf", "./lgl/Alegreya-BlackItalic/");
    convert("./fonts/Alegreya/Alegreya-Bold.ttf", "./lgl/Alegreya-Bold/");
    convert("./fonts/Alegreya/Alegreya-BoldItalic.ttf", "./lgl/Alegreya-BoldItalic/");
    convert("./fonts/Alegreya/Alegreya-ExtraBold.ttf", "./lgl/Alegreya-ExtraBold/");
    convert("./fonts/Alegreya/Alegreya-ExtraBoldItalic.ttf", "./lgl/Alegreya-ExtraBoldItalic/");
    convert("./fonts/Alegreya/Alegreya-Italic.ttf", "./lgl/Alegreya-Italic/");
    convert("./fonts/Alegreya/Alegreya-Medium.ttf", "./lgl/Alegreya-Medium/");
    convert("./fonts/Alegreya/Alegreya-MediumItalic.ttf", "./lgl/Alegreya-MediumItalic/");
    convert("./fonts/Alegreya/Alegreya-Regular.ttf", "./lgl/Alegreya-Regular/");

    convert("./fonts/Cairo/Cairo-Black.ttf", "./lgl/Cairo-Black/");
    convert("./fonts/Cairo/Cairo-Bold.ttf", "./lgl/Cairo-Bold/");
    convert("./fonts/Cairo/Cairo-ExtraLight.ttf", "./lgl/Cairo-ExtraLight/");
    convert("./fonts/Cairo/Cairo-Light.ttf", "./lgl/Cairo-Light/");
    convert("./fonts/Cairo/Cairo-Regular.ttf", "./lgl/Cairo-Regular/");
    convert("./fonts/Cairo/Cairo-SemiBold.ttf", "./lgl/Cairo-SemiBold/");

    convert("./fonts/Lato/Lato-Black.ttf", "./lgl/Lato-Black/");
    convert("./fonts/Lato/Lato-BlackItalic.ttf", "./lgl/Lato-BlackItalic/");
    convert("./fonts/Lato/Lato-Bold.ttf", "./lgl/Lato-Bold/");
    convert("./fonts/Lato/Lato-BoldItalic.ttf", "./lgl/Lato-BoldItalic/");
    convert("./fonts/Lato/Lato-Hairline.ttf", "./lgl/Lato-Hairline/");
    convert("./fonts/Lato/Lato-HairlineItalic.ttf", "./lgl/Lato-HairlineItalic/");
    convert("./fonts/Lato/Lato-Italic.ttf", "./lgl/Lato-Italic/");
    convert("./fonts/Lato/Lato-Light.ttf", "./lgl/Lato-Light/");
    convert("./fonts/Lato/Lato-LightItalic.ttf", "./lgl/Lato-LightItalic/");
    convert("./fonts/Lato/Lato-Regular.ttf", "./lgl/Lato-Regular/");

    convert("./fonts/Lora/Lora-Bold.ttf", "./lgl/Lora-Bold/");
    convert("./fonts/Lora/Lora-BoldItalic.ttf", "./lgl/Lora-BoldItalic/");
    convert("./fonts/Lora/Lora-Italic.ttf", "./lgl/Lora-Italic/");
    convert("./fonts/Lora/Lora-Regular.ttf", "./lgl/Lora-Regular/");

    convert("./fonts/Montserrat/Montserrat-Black.ttf", "./lgl/Montserrat-Black/");
    convert("./fonts/Montserrat/Montserrat-BlackItalic.ttf", "./lgl/Montserrat-BlackItalic/");
    convert("./fonts/Montserrat/Montserrat-Bold.ttf", "./lgl/Montserrat-Bold/");
    convert("./fonts/Montserrat/Montserrat-BoldItalic.ttf", "./lgl/Montserrat-BoldItalic/");
    convert("./fonts/Montserrat/Montserrat-ExtraBold.ttf", "./lgl/Montserrat-ExtraBold/");
    convert("./fonts/Montserrat/Montserrat-ExtraBoldItalic.ttf", "./lgl/Montserrat-ExtraBoldItalic/");
    convert("./fonts/Montserrat/Montserrat-ExtraLight.ttf", "./lgl/Montserrat-ExtraLight/");
    convert("./fonts/Montserrat/Montserrat-ExtraLightItalic.ttf", "./lgl/Montserrat-ExtraLightItalic/");
    convert("./fonts/Montserrat/Montserrat-Italic.ttf", "./lgl/Montserrat-Italic/");
    convert("./fonts/Montserrat/Montserrat-Light.ttf", "./lgl/Montserrat-Light/");
    convert("./fonts/Montserrat/Montserrat-LightItalic.ttf", "./lgl/Montserrat-LightItalic/");
    convert("./fonts/Montserrat/Montserrat-Medium.ttf", "./lgl/Montserrat-Medium/");
    convert("./fonts/Montserrat/Montserrat-MediumItalic.ttf", "./lgl/Montserrat-MediumItalic/");
    convert("./fonts/Montserrat/Montserrat-Regular.ttf", "./lgl/Montserrat-Regular/");
    convert("./fonts/Montserrat/Montserrat-SemiBold.ttf", "./lgl/Montserrat-SemiBold/");
    convert("./fonts/Montserrat/Montserrat-SemiBoldItalic.ttf", "./lgl/Montserrat-SemiBoldItalic/");
    convert("./fonts/Montserrat/Montserrat-Thin.ttf", "./lgl/Montserrat-Thin/");
    convert("./fonts/Montserrat/Montserrat-ThinItalic.ttf", "./lgl/Montserrat-ThinItalic/");

    convert("./fonts/Noto_Sans/NotoSans-Bold.ttf", "./lgl/NotoSans-Bold/");
    convert("./fonts/Noto_Sans/NotoSans-BoldItalic.ttf", "./lgl/NotoSans-BoldItalic/");
    convert("./fonts/Noto_Sans/NotoSans-Italic.ttf", "./lgl/NotoSans-Italic/");
    convert("./fonts/Noto_Sans/NotoSans-Regular.ttf", "./lgl/NotoSans-Regular/");

    convert("./fonts/Open_Sans/OpenSans-Bold.ttf", "./lgl/OpenSans-Bold/");
    convert("./fonts/Open_Sans/OpenSans-BoldItalic.ttf", "./lgl/OpenSans-BoldItalic/");
    convert("./fonts/Open_Sans/OpenSans-ExtraBold.ttf", "./lgl/OpenSans-ExtraBold/");
    convert("./fonts/Open_Sans/OpenSans-ExtraBoldItalic.ttf", "./lgl/OpenSans-ExtraBoldItalic/");
    convert("./fonts/Open_Sans/OpenSans-Italic.ttf", "./lgl/OpenSans-Italic/");
    convert("./fonts/Open_Sans/OpenSans-Light.ttf", "./lgl/OpenSans-Light/");
    convert("./fonts/Open_Sans/OpenSans-LightItalic.ttf", "./lgl/OpenSans-LightItalic/");
    convert("./fonts/Open_Sans/OpenSans-Regular.ttf", "./lgl/OpenSans-Regular/");
    convert("./fonts/Open_Sans/OpenSans-SemiBold.ttf", "./lgl/OpenSans-SemiBold/");
    convert("./fonts/Open_Sans/OpenSans-SemiBoldItalic.ttf", "./lgl/OpenSans-SemiBoldItalic/");


    convert("./fonts/Oxygen/Oxygen-Bold.ttf", "./lgl/Oxygen-Bold/");
    convert("./fonts/Oxygen/Oxygen-Light.ttf", "./lgl/Oxygen-Light/");
    convert("./fonts/Oxygen/Oxygen-Regular.ttf", "./lgl/Oxygen-Regular/");

    convert("./fonts/Palanquin_Dark/PalanquinDark-Bold.ttf", "./lgl/PalanquinDark-Bold/");
    convert("./fonts/Palanquin_Dark/PalanquinDark-Medium.ttf", "./lgl/PalanquinDark-Medium/");
    convert("./fonts/Palanquin_Dark/PalanquinDark-Regular.ttf", "./lgl/PalanquinDark-Regular/");
    convert("./fonts/Palanquin_Dark/PalanquinDark-SemiBold.ttf", "./lgl/PalanquinDark-SemiBold/");

    convert("./fonts/Roboto/Roboto-Black.ttf", "./lgl/Roboto-Black/");
    convert("./fonts/Roboto/Roboto-BlackItalic.ttf", "./lgl/Roboto-BlackItalic/");
    convert("./fonts/Roboto/Roboto-Bold.ttf", "./lgl/Roboto-Bold/");
    convert("./fonts/Roboto/Roboto-BoldItalic.ttf", "./lgl/Roboto-BoldItalic/");
    convert("./fonts/Roboto/Roboto-Italic.ttf", "./lgl/Roboto-Italic/");
    convert("./fonts/Roboto/Roboto-Light.ttf", "./lgl/Roboto-Light/");
    convert("./fonts/Roboto/Roboto-LightItalic.ttf", "./lgl/Roboto-LightItalic/");
    convert("./fonts/Roboto/Roboto-Medium.ttf", "./lgl/Roboto-Medium/");
    convert("./fonts/Roboto/Roboto-MediumItalic.ttf", "./lgl/Roboto-MediumItalic/");
    convert("./fonts/Roboto/Roboto-Regular.ttf", "./lgl/Roboto-Regular/");
    convert("./fonts/Roboto/Roboto-Thin.ttf", "./lgl/Roboto-Thin/");
    convert("./fonts/Roboto/Roboto-ThinItalic.ttf", "./lgl/Roboto-ThinItalic/");

    convert("./fonts/Teko/Teko-Bold.ttf", "./lgl/Teko-Bold/");
    convert("./fonts/Teko/Teko-Light.ttf", "./lgl/Teko-Light/");
    convert("./fonts/Teko/Teko-Medium.ttf", "./lgl/Teko-Medium/");
    convert("./fonts/Teko/Teko-Regular.ttf", "./lgl/Teko-Regular/");
    convert("./fonts/Teko/Teko-SemiBold.ttf", "./lgl/Teko-SemiBold/");

    convert("./fonts/Ubuntu/Ubuntu-Bold.ttf", "./lgl/Ubuntu-Bold/");
    convert("./fonts/Ubuntu/Ubuntu-BoldItalic.ttf", "./lgl/Ubuntu-BoldItalic/");
    convert("./fonts/Ubuntu/Ubuntu-Italic.ttf", "./lgl/Ubuntu-Italic/");
    convert("./fonts/Ubuntu/Ubuntu-Light.ttf", "./lgl/Ubuntu-Light/");
    convert("./fonts/Ubuntu/Ubuntu-LightItalic.ttf", "./lgl/Ubuntu-LightItalic/");
    convert("./fonts/Ubuntu/Ubuntu-Medium.ttf", "./lgl/Ubuntu-Medium/");
    convert("./fonts/Ubuntu/Ubuntu-MediumItalic.ttf", "./lgl/Ubuntu-MediumItalic/");
    convert("./fonts/Ubuntu/Ubuntu-Regular.ttf", "./lgl/Ubuntu-Regular/");



    convert("./fonts/Rubik/Rubik-Black.ttf", "./lgl/Rubik-Black/");
    convert("./fonts/Rubik/Rubik-BlackItalic.ttf", "./lgl/Rubik-BlackItalic/");
    convert("./fonts/Rubik/Rubik-Bold.ttf", "./lgl/Rubik-Bold/");
    convert("./fonts/Rubik/Rubik-BoldItalic.ttf", "./lgl/Rubik-BoldItalic/");
    convert("./fonts/Rubik/Rubik-Italic.ttf", "./lgl/Rubik-Italic/");
    convert("./fonts/Rubik/Rubik-Light.ttf", "./lgl/Rubik-Light/");
    convert("./fonts/Rubik/Rubik-LightItalic.ttf", "./lgl/Rubik-LightItalic/");
    convert("./fonts/Rubik/Rubik-Medium.ttf", "./lgl/Rubik-Medium/");
    convert("./fonts/Rubik/Rubik-MediumItalic.ttf", "./lgl/Rubik-MediumItalic/");
    convert("./fonts/Rubik/Rubik-Regular.ttf", "./lgl/Rubik-Regular/");


    convert("./fonts/Nunito/Nunito-Black.ttf", "./lgl/Nunito-Black/");
    convert("./fonts/Nunito/Nunito-BlackItalic.ttf", "./lgl/Nunito-BlackItalic/");
    convert("./fonts/Nunito/Nunito-Bold.ttf", "./lgl/Nunito-Bold/");
    convert("./fonts/Nunito/Nunito-BoldItalic.ttf", "./lgl/Nunito-BoldItalic/");
    convert("./fonts/Nunito/Nunito-ExtraBold.ttf", "./lgl/Nunito-ExtraBold/");
    convert("./fonts/Nunito/Nunito-ExtraBoldItalic.ttf", "./lgl/Nunito-ExtraBoldItalic/");
    convert("./fonts/Nunito/Nunito-ExtraLight.ttf", "./lgl/Nunito-ExtraLight/");
    convert("./fonts/Nunito/Nunito-ExtraLightItalic.ttf", "./lgl/Nunito-ExtraLightItalic/");
    convert("./fonts/Nunito/Nunito-Italic.ttf", "./lgl/Nunito-Italic/");
    convert("./fonts/Nunito/Nunito-Light.ttf", "./lgl/Nunito-Light/");
    convert("./fonts/Nunito/Nunito-LightItalic.ttf", "./lgl/Nunito-LightItalic/");
    convert("./fonts/Nunito/Nunito-Regular.ttf", "./lgl/Nunito-Regular/");
    convert("./fonts/Nunito/Nunito-SemiBold.ttf", "./lgl/Nunito-SemiBold/");8

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

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

    以上my_test.js 必须放置于  /root/mapbox_tools/node-fontnik0目录下

    运行

    node my_test.js

    /spritezero(雪碧图本地化实践)


  • 相关阅读:
    在Java中使用 break/continue 语句来控制多重嵌套循环的跳转
    Android系统架构基本模式解析
    添加蓝牙通讯功能
    wince串口蓝牙
    Android各层推荐开发书籍及参考资料
    CDEFINES的用法
    蓝牙地址的规则
    WinCE中sources文件中targetlibs与sourcelibs的作用与区别
    Java初学者不得不知的概念,JDK,JRE,JVM的区别?
    WINCE的内存配置config.bib文件的解析
  • 原文地址:https://www.cnblogs.com/lishanyang/p/15458841.html
Copyright © 2020-2023  润新知