在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.pbf
,512-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.pngOkay,Bye!
网友评论
有没有方法不使用这种字体分片的方式。
对node的版本也有要求;
在虚拟机centos6.5上也是各种错,放弃了。。。
有什么好的解决办法吗。我用的是klokantech转好的思源字体。
大的一P