207 lines
4.5 KiB
JavaScript
207 lines
4.5 KiB
JavaScript
/**
|
|
* @file css
|
|
* @author junmer
|
|
*/
|
|
|
|
/* eslint-env node */
|
|
var _ = require('lodash');
|
|
var fs = require('fs');
|
|
var path = require('path');
|
|
var isTtf = require('is-ttf');
|
|
var through = require('through2');
|
|
var replaceExt = require('replace-ext');
|
|
var b2a = require('b3b').b2a;
|
|
|
|
/**
|
|
* tpl
|
|
*
|
|
* @type {string}
|
|
*/
|
|
var tpl = fs.readFileSync(
|
|
path.resolve(__dirname, '../lib/font-face.tpl')
|
|
).toString('utf-8');
|
|
|
|
/**
|
|
* renderCss
|
|
*
|
|
* @type {function}
|
|
*/
|
|
var renderCss = _.template(tpl);
|
|
|
|
|
|
/**
|
|
* listUnicode
|
|
*
|
|
* @param {Array} unicode unicode
|
|
* @return {string} unicode string
|
|
*/
|
|
function listUnicode(unicode) {
|
|
return unicode.map(function (u) {
|
|
return '\\' + u.toString(16);
|
|
}).join(',');
|
|
}
|
|
|
|
/**
|
|
* get glyf list from ttf obj
|
|
*
|
|
* @param {ttfObject} ttf ttfObject
|
|
* @return {Object} icon obj
|
|
*/
|
|
function getGlyfList(ttf) {
|
|
|
|
var glyfList = [];
|
|
|
|
// exclude empty glyf
|
|
var filtered = ttf.glyf.filter(function (g) {
|
|
return g.name !== '.notdef'
|
|
&& g.name !== '.null'
|
|
&& g.name !== 'nonmarkingreturn'
|
|
&& g.unicode && g.unicode.length;
|
|
});
|
|
|
|
// format glyf info
|
|
filtered.forEach(function (g) {
|
|
glyfList.push({
|
|
code: '&#x' + g.unicode[0].toString(16) + ';',
|
|
codeName: listUnicode(g.unicode),
|
|
name: g.name || 'uni' + g.unicode[0].toString(16)
|
|
});
|
|
});
|
|
|
|
return {
|
|
glyfList: glyfList
|
|
};
|
|
|
|
}
|
|
|
|
/**
|
|
* get font family name
|
|
*
|
|
* @param {Object} fontInfo font info object
|
|
* @param {ttfObject} ttf ttfObject
|
|
* @param {Object} opts opts
|
|
* @return {string} font family name
|
|
*/
|
|
function getFontFamily(fontInfo, ttf, opts) {
|
|
var fontFamily = opts.fontFamily;
|
|
// Call transform function
|
|
if (typeof fontFamily === 'function') {
|
|
fontFamily = fontFamily(_.cloneDeep(fontInfo), ttf);
|
|
}
|
|
return fontFamily || ttf.name.fontFamily || fontInfo.fontFile;
|
|
}
|
|
|
|
/**
|
|
* Transform font family name
|
|
* @callback FontFamilyTransform
|
|
* @param {Object} font info object
|
|
* @param {ttfObject} ttf ttfObject
|
|
* @return {string} font family name
|
|
*/
|
|
// function(fontInfo, ttfObject) { return "Font Name"; }
|
|
|
|
/**
|
|
* css fontmin plugin
|
|
*
|
|
* @param {Object} opts opts
|
|
* @param {boolean=} opts.glyph generate class for each glyph. default = false
|
|
* @param {boolean=} opts.base64 inject base64
|
|
* @param {string=} opts.iconPrefix icon prefix
|
|
* @param {(string|FontFamilyTransform)=} opts.fontFamily fontFamily
|
|
* @return {Object} stream.Transform instance
|
|
* @api public
|
|
*/
|
|
module.exports = function (opts) {
|
|
opts = opts || {};
|
|
|
|
return through.ctor({
|
|
objectMode: true
|
|
}, function (file, enc, cb) {
|
|
|
|
// check null
|
|
if (file.isNull()) {
|
|
cb(null, file);
|
|
return;
|
|
}
|
|
|
|
// check stream
|
|
if (file.isStream()) {
|
|
cb(new Error('Streaming is not supported'));
|
|
return;
|
|
}
|
|
|
|
// check ttf
|
|
if (!isTtf(file.contents)) {
|
|
cb(null, file);
|
|
return;
|
|
}
|
|
|
|
// clone
|
|
this.push(file.clone(false));
|
|
|
|
file.path = replaceExt(file.path, '.css');
|
|
var fontFile = path.basename(file.path, '.css');
|
|
|
|
// font data
|
|
var fontInfo = {
|
|
fontFile: fontFile,
|
|
fontPath: '',
|
|
base64: '',
|
|
glyph: false,
|
|
iconPrefix: 'icon',
|
|
local: false
|
|
};
|
|
|
|
// opts
|
|
_.extend(fontInfo, opts);
|
|
|
|
// ttf obj
|
|
var ttfObject = file.ttfObject || {
|
|
name: {}
|
|
};
|
|
|
|
// glyph
|
|
if (opts.glyph && ttfObject.glyf) {
|
|
_.extend(
|
|
fontInfo,
|
|
getGlyfList(ttfObject)
|
|
);
|
|
}
|
|
|
|
// font family
|
|
fontInfo.fontFamily = getFontFamily(fontInfo, ttfObject, opts);
|
|
|
|
// rewrite font family as filename
|
|
if (opts.asFileName) {
|
|
fontInfo.fontFamily = fontFile;
|
|
}
|
|
|
|
// base64
|
|
if (opts.base64) {
|
|
fontInfo.base64 = ''
|
|
+ 'data:application/x-font-ttf;charset=utf-8;base64,'
|
|
+ b2a(file.contents);
|
|
}
|
|
|
|
// local
|
|
if (fontInfo.local === true) {
|
|
fontInfo.local = fontInfo.fontFamily;
|
|
}
|
|
|
|
// render
|
|
var output = _.attempt(function (data) {
|
|
return Buffer.from(renderCss(data));
|
|
}, fontInfo);
|
|
|
|
if (_.isError(output)) {
|
|
cb(output, file);
|
|
}
|
|
else {
|
|
file.contents = output;
|
|
cb(null, file);
|
|
}
|
|
|
|
});
|
|
|
|
};
|