Technology︰为中文字体档瘦身
中文字体档案动辄有数十 MB 大小,下载需要一点时间。因此通常都会以图片代替文字。用图片代替文字的短处是无法把文字拷贝、只有单一尺寸、修改起来麻烦...等。究竟有没有其他方法?
预计阅读时间︰5 分钟
在开发网页的过程中,尤其是希望用到特别的中文字体时,由于中文字体档案动辄有数十 MB 大小,下载需要一点时间。因此通常都会以图片代替文字。用图片代替文字的短处是无法把文字拷贝、只有单一尺寸、修改起来麻烦…等。究竟有没有其他方法?
内容大纲
准备
程式
解说
准备
如果能把用不著的文字从字体档中删除,档案体积将会缩小,变成适合在网页中加载。在 Node.js 中有一个名为「
fontmin
」的模组可以满足到这个需求。在 Terminal 输入:
npm install fontmin gulp-rename fs
它会安装程式所需要的模组。
程式
//----------------------------------------------------------------------------------------
// Font File Minifier
//----------------------------------------------------------------------------------------
// Written by : Alvin LAU
// Copyright Fimmick Limited, 2019. All rights reserved.
//----------------------------------------------------------------------------------------
// Require modules
var _GULPRENAME = require("gulp-rename");
var _FONTMIN = require("fontmin");
var _FS = require("fs");
//----------------------------------------------------------------------------------------
// Global variables
var _now = new Date();
var year = _now.getFullYear().toString();
var month = _now.getMonth().toString();
var date = _now.getDate().toString();
var hours = _now.getHours().toString();
var minutes = _now.getMinutes().toString();
var seconds = _now.getSeconds().toString();
month = (month.length === 2) ? month : "0"+month;
date = (date.length === 2) ? date : "0"+date;
hours = (hours.length === 2) ? hours : "0"+hours;
minutes = (minutes.length === 2) ? minutes : "0"+minutes;
seconds = (seconds.length === 2) ? seconds : "0"+seconds;
//========================================================================================
// Program start
console.log("n##----------------------------------------------------------");
console.log("## Font File Minifier");
console.log("## Written by Alvin LAU");
console.log("## Copyright Fimmick Limited, 2019. All rights reserved.");
console.log("##----------------------------------------------------------n");
//----------------------------------------------------------------------------------------
// Reading parameters
var argu = process.argv.slice(2);
var inputFontFilename = "NotoSansTC-Medium.ttf";
var arguGlyphs = "";
for (var i=0; i<argu.length; i++) {
switch (argu[i]) {
case "-f":
case "--font": {
inputFontFilename = argu[i+1];
} break;
case "-g":
case "--glyphs": {
arguGlyphs = argu[i+1];
} break;
}
}
if (arguGlyphs == "") {
// No glyphs provided, show instruction
console.log("Usage:");
console.log(" node fontminifier.js -g -f n");
console.log("Options:");
console.log(" --glyphs");
console.log(" -g = Characters that you want to keep in font file.n");
console.log(" --font");
console.log(" -f = Font source filename in TTF format with extensionn");
console.log("Example:");
console.log(" node fontminifier.js -g 0123456789 -f Arial.ttfn");
process.exit(1);
}
//----------------------------------------------------------------------------------------
// Main process
console.log("Input font file: "+inputFontFilename);
console.log("Glyphs to be keep: "+arguGlyphs);
// Font file name
var fontFilename = inputFontFilename.split(".");
var outputFilename = fontFilename[0]+"_"+year+month+date+hours+minutes+seconds+".ttf";
// Set the files to be optimized
var fontPath = "./"+inputFontFilename;
// Set the destination folder to where your files will be written
var outputPath = "./";
// Check if font file is exists.
if (_FS.existsSync(fontPath) == false) {
// If do not exists then will stop the process
console.error("### Font file not found...n");
process.exit(1);
}
// Set up by fontmin
var fontmin = new _FONTMIN()
.use(_GULPRENAME(outputFilename))
.src(fontPath)
.dest(outputPath);
if (arguGlyphs != "") {
console.log("nProcessing...");
fontmin.use(_FONTMIN.glyph({
text: arguGlyphs,
hinting: false
}));
}
// Start minifying font with the given settings.
fontmin.run(function(err, files) {
if (err) {
console.error("### Something went wrong...n");
throw err;
}
console.log("Minify done: "+outputPath+outputFilename+"n");
process.exit(0);
});
解说
让我们来了解程式的运作。
// Require modules
var _GULPRENAME = require("gulp-rename");
var _FONTMIN = require("fontmin");
var _FS = require("fs");
程式最开端是载入三个需要的模组。「gulp-rename」是用于更改档案名称;「fontmin」是字体瘦身的核心;「fs」主
要是档案相关的处理。
// Global variables
var _now = new Date();
var year = _now.getFullYear().toString();
var month = _now.getMonth().toString();
var date = _now.getDate().toString();
var hours = _now.getHours().toString();
var minutes = _now.getMinutes().toString();
var seconds = _now.getSeconds().toString();
month = (month.length === 2) ? month : "0"+month;
date = (date.length === 2) ? date : "0"+date;
hours = (hours.length === 2) ? hours : "0"+hours;
minutes = (minutes.length === 2) ? minutes : "0"+minutes;
seconds = (seconds.length === 2) ? seconds : "0"+seconds;
向系统取得当刻的时间,并把数值分别设定在对应的变量中。
var argu = process.argv.slice(2);
var inputFontFilename = "NotoSansTC-Medium.ttf";
var arguGlyphs = "";
for (var i=0; i<argu.length; i++) {
switch (argu[i]) {
case "-f":
case "--font": {
inputFontFilename = argu[i+1];
} break;
case "-g":
case "--glyphs": {
arguGlyphs = argu[i+1];
} break;
}
}
if (arguGlyphs == "") {
// No glyphs provided, show instruction
console.log("Usage:");
console.log(" node fontminifier.js -g -f n");
console.log("Options:");
console.log(" --glyphs");
console.log(" -g = Characters that you want to keep in font file.n");
console.log(" --font");
console.log(" -f = Font source filename in TTF format with extensionn");
console.log("Example:");
console.log(" node fontminifier.js -g 0123456789 -f Arial.ttfn");
process.exit(1);
}
这段是读取参数,如果是「-f」或「–font」就把数值储存在「inputFontFilename」;如果是「-g」或「–glyphs」就把数值储存在「arguGlyphs」。当没有指定字体档名时,会使用预设的「NotoSansTC-Medium.ttf」字体档案。
由于这是一个瘦身程式,如果没有指定保留哪些字元时,运作便会变得没有意义,因此程式会停止执行。也有可能是用户不清楚使用方法,所以同时会显示使用说明。
// Main process
console.log("Input font file: "+inputFontFilename);
console.log("Glyphs to be keep: "+arguGlyphs);
// Font file name
var fontFilename = inputFontFilename.split(".");
var outputFilename = fontFilename[0]+"_"+year+month+date+hours+minutes+seconds+".ttf";
// Set the files to be optimized
var fontPath = "./"+inputFontFilename;
// Set the destination folder to where your files will be written
var outputPath = "./";
// Check if font file is exists.
if (_FS.existsSync(fontPath) == false) {
// If do not exists then will stop the process
console.error("### Font file not found...n");
process.exit(1);
}
接下来是依照参数数值去准备好输入路径、输出路径、路径档名。同时也会检查指定的字体档案是否存在。没有字体档案会甚么也做不来,这时就需要显示错误讯息。
// Set up by fontmin
var fontmin = new _FONTMIN()
.use(_GULPRENAME(outputFilename))
.src(fontPath)
.dest(outputPath);
if (arguGlyphs != "") {
console.log("nProcessing...");
fontmin.use(_FONTMIN.glyph({
text: arguGlyphs,
hinting: false
}));
}
一切就绪,现在要建立核心模组,并把准备好的数值通知模组。
// Start minifying font with the given settings.
fontmin.run(function(err, files) {
if (err) {
console.error("### Something went wrong...n");
throw err;
}
console.log("Minify done: "+outputPath+outputFilename+"n");
process.exit(0);
});
最后就是执行瘦身动作。如果当中出现错误时,就显示错误讯息。成功的话则显示输出档名。要执行程式,在「Terminal」输入:
node fontminifier.js -g 0123456789 -f phosphate.ttf
「-g」参数后面的是要保留的文字。「-f」参数后面的是输入的字体档案名称;程式会在档案名称后加入当刻时间,作为
输出的字体档案名称。留意:程式只支援 TTF 格式,TTC, OTF,…等是不支持。这段指令的意思是读取
「phosphate.ttf」字体档,只保留「0123456789」字符,其他的都删除掉。完成后会有一个类似
「phosphate_YYYYMMDDHHIISS.ttf」的档案出现;它就是瘦身后的字体档案。
About FIMMICK
FIMMICK is an AI business transformation agency deploying 4,000+ AI agents for 500+ brands across 8 Asian markets. Our platform automates marketing, sales, content, reporting, and customer engagement. Founded 2008, HQ Hong Kong. Starting at $980/month.
Get Started
Book a free industry benchmark or schedule a 30-minute AI workshop for your leadership team at fimmick.com/contact.