227 lines
4.7 KiB
JavaScript
227 lines
4.7 KiB
JavaScript
/**
|
|
* @file svgs2ttf
|
|
* @author junmer
|
|
*/
|
|
|
|
/* eslint-env node */
|
|
|
|
var isSvg = require('is-svg');
|
|
var through = require('through2');
|
|
var path = require('path');
|
|
var replaceExt = require('replace-ext');
|
|
var ab2b = require('b3b').ab2b;
|
|
var _ = require('lodash');
|
|
var bufferToVinyl = require('buffer-to-vinyl');
|
|
var TTFWriter = require('fonteditor-core').TTFWriter;
|
|
var TTF = require('fonteditor-core').TTF;
|
|
var svg2ttfobject = require('fonteditor-core').svg2ttfobject;
|
|
var getEmptyttfObject = require('fonteditor-core/ttf/getEmptyttfObject');
|
|
|
|
/**
|
|
* SvgFont
|
|
*
|
|
* @constructor
|
|
* @param {string} name filename
|
|
* @param {Object} opts opts
|
|
*/
|
|
function SvgFont(name, opts) {
|
|
|
|
this.opts = _.extend(
|
|
{
|
|
adjust: {
|
|
leftSideBearing: 0,
|
|
rightSideBearing: 0,
|
|
ajdustToEmBox: true,
|
|
ajdustToEmPadding: 0
|
|
},
|
|
name: {
|
|
fontFamily: name,
|
|
fontSubFamily: name,
|
|
uniqueSubFamily: name,
|
|
postScriptName: name
|
|
}
|
|
},
|
|
opts
|
|
);
|
|
|
|
// empty ttfobj
|
|
var ttfobj = getEmptyttfObject();
|
|
|
|
// for save name
|
|
ttfobj.post.format = 2;
|
|
|
|
// new TTF
|
|
this.ttf = new TTF(ttfobj);
|
|
|
|
// set name
|
|
this.ttf.setName(this.opts.name);
|
|
|
|
// unicode start
|
|
this.startCode = opts.startCode || 0xe001;
|
|
|
|
}
|
|
|
|
/**
|
|
* add svg
|
|
*
|
|
* @param {string} name svg basename
|
|
* @param {buffer} contents svg contents
|
|
*/
|
|
SvgFont.prototype.add = function (name, contents) {
|
|
|
|
var ttfObj = svg2ttfobject(
|
|
contents.toString('utf-8'),
|
|
{
|
|
combinePath: true
|
|
}
|
|
);
|
|
|
|
var glyf = ttfObj.glyf[0];
|
|
|
|
glyf.name = path.basename(name, '.svg');
|
|
|
|
if (!Array.isArray(glyf.unicode)) {
|
|
glyf.unicode = [this.startCode++];
|
|
}
|
|
|
|
this.ttf.addGlyf(glyf);
|
|
|
|
};
|
|
|
|
/**
|
|
* compile ttf contents
|
|
*
|
|
*/
|
|
SvgFont.prototype.compile = function () {
|
|
|
|
if (this.opts.adjust) {
|
|
this.ttf.adjustGlyfPos(null, this.opts.adjust);
|
|
this.ttf.adjustGlyf(null, this.opts.adjust);
|
|
}
|
|
|
|
this.contents = ab2b(
|
|
new TTFWriter(
|
|
this.opts
|
|
)
|
|
.write(
|
|
this.ttf.ttf
|
|
)
|
|
);
|
|
|
|
};
|
|
|
|
|
|
/**
|
|
* svgs2ttf fontmin plugin
|
|
*
|
|
* @param {string} file filename
|
|
* @param {Object} opts opts
|
|
* @param {string} opts.fontName font name
|
|
* @return {Object} stream.Transform instance
|
|
* @api public
|
|
*/
|
|
module.exports = function (file, opts) {
|
|
|
|
if (!file) {
|
|
throw new Error('Missing file option for fontmin-svg2ttf');
|
|
}
|
|
|
|
opts = _.extend({hinting: true}, opts);
|
|
|
|
var firstFile;
|
|
var fileName;
|
|
var svgFont;
|
|
|
|
if (typeof file === 'string') {
|
|
|
|
// fix file ext
|
|
file = replaceExt(file, '.ttf');
|
|
|
|
// set file name
|
|
fileName = file;
|
|
}
|
|
else if (typeof file.path === 'string') {
|
|
fileName = path.basename(file.path);
|
|
firstFile = bufferToVinyl.file(null, fileName);
|
|
}
|
|
else {
|
|
throw new Error('Missing path in file options for fontmin-svg2ttf');
|
|
}
|
|
|
|
|
|
function bufferContents(file, enc, cb) {
|
|
|
|
// ignore empty files
|
|
if (file.isNull()) {
|
|
cb();
|
|
return;
|
|
}
|
|
|
|
// check stream
|
|
if (file.isStream()) {
|
|
this.emit('error', new Error('Streaming not supported'));
|
|
cb();
|
|
return;
|
|
}
|
|
|
|
// check svg
|
|
if (!isSvg(file.contents)) {
|
|
cb();
|
|
return;
|
|
}
|
|
|
|
// set first file if not already set
|
|
if (!firstFile) {
|
|
firstFile = file;
|
|
}
|
|
|
|
// construct SvgFont instance
|
|
if (!svgFont) {
|
|
var fontName = opts.fontName || path.basename(fileName, '.ttf');
|
|
svgFont = new SvgFont(fontName, opts);
|
|
}
|
|
|
|
// add file to SvgFont instance
|
|
svgFont.add(file.relative, file.contents);
|
|
|
|
cb();
|
|
}
|
|
|
|
|
|
function endStream(cb) {
|
|
// no files passed in, no file goes out
|
|
if (!firstFile || !svgFont) {
|
|
cb();
|
|
return;
|
|
}
|
|
|
|
var joinedFile;
|
|
|
|
// if file opt was a file path
|
|
// clone everything from the first file
|
|
if (typeof file === 'string') {
|
|
joinedFile = firstFile.clone({
|
|
contents: false
|
|
});
|
|
|
|
joinedFile.path = path.join(firstFile.base, file);
|
|
}
|
|
else {
|
|
joinedFile = firstFile;
|
|
}
|
|
|
|
// complie svgfont
|
|
svgFont.compile();
|
|
|
|
// set contents
|
|
joinedFile.contents = svgFont.contents;
|
|
joinedFile.ttfObject = svgFont.ttf.ttf;
|
|
|
|
this.push(joinedFile);
|
|
cb();
|
|
}
|
|
|
|
return through.obj(bufferContents, endStream);
|
|
|
|
};
|