UNPKG

fonteditor-core

Version:

fonts (ttf, woff, woff2, eot, svg, otf) parse, write, transform, glyph adjust.

222 lines (209 loc) 5.83 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = sizeof; var _glyFlag = _interopRequireDefault(require("../../enum/glyFlag")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @file 获取glyf的大小,同时对glyf写入进行预处理 * @author mengke01(kekee000@gmail.com) */ /** * 获取glyf的大小 * * @param {Object} glyf glyf对象 * @param {Object} glyfSupport glyf相关统计 * @param {boolean} hinting 是否保留hints * @param {boolean} writeZeroContoursGlyfData 是否写空轮廓 glyph * @return {number} size大小 */ function sizeofSimple(glyf, glyfSupport, hinting, writeZeroContoursGlyfData) { if (!writeZeroContoursGlyfData && (!glyf.contours || !glyf.contours.length)) { return 0; } // fixed header + endPtsOfContours var result = 12 + (glyf.contours || []).length * 2 + (glyfSupport.flags || []).length; (glyfSupport.xCoord || []).forEach(function (x) { result += 0 <= x && x <= 0xFF ? 1 : 2; }); (glyfSupport.yCoord || []).forEach(function (y) { result += 0 <= y && y <= 0xFF ? 1 : 2; }); return result + (hinting && glyf.instructions ? glyf.instructions.length : 0); } /** * 复合图元size * * @param {Object} glyf glyf对象 * @param {boolean} hinting 是否保留hints, compound 图元暂时不做hinting * @return {number} size大小 */ // eslint-disable-next-line no-unused-vars function sizeofCompound(glyf, hinting) { var size = 10; var transform; glyf.glyfs.forEach(function (g) { transform = g.transform; // flags + glyfIndex size += 4; // a, b, c, d, e // xy values or points if (transform.e < 0 || transform.e > 0x7F || transform.f < 0 || transform.f > 0x7F) { size += 4; } else { size += 2; } // 01 , 10 if (transform.b || transform.c) { size += 8; } // scale else if (transform.a !== 1 || transform.d !== 1) { size += transform.a === transform.d ? 2 : 4; } }); return size; } /** * 获取flags * * @param {Object} glyf glyf对象 * @param {Object} glyfSupport glyf相关统计 * @return {Array} */ function getFlags(glyf, glyfSupport) { if (!glyf.contours || 0 === glyf.contours.length) { return glyfSupport; } var flags = []; var xCoord = []; var yCoord = []; var contours = glyf.contours; var contour; var prev; var first = true; for (var j = 0, cl = contours.length; j < cl; j++) { contour = contours[j]; for (var i = 0, l = contour.length; i < l; i++) { var point = contour[i]; if (first) { xCoord.push(point.x); yCoord.push(point.y); first = false; } else { xCoord.push(point.x - prev.x); yCoord.push(point.y - prev.y); } flags.push(point.onCurve ? _glyFlag.default.ONCURVE : 0); prev = point; } } // compress var flagsC = []; var xCoordC = []; var yCoordC = []; var x; var y; var prevFlag; var repeatPoint = -1; flags.forEach(function (flag, index) { x = xCoord[index]; y = yCoord[index]; // 第一个 if (index === 0) { if (-0xFF <= x && x <= 0xFF) { flag += _glyFlag.default.XSHORT; if (x >= 0) { flag += _glyFlag.default.XSAME; } x = Math.abs(x); } if (-0xFF <= y && y <= 0xFF) { flag += _glyFlag.default.YSHORT; if (y >= 0) { flag += _glyFlag.default.YSAME; } y = Math.abs(y); } flagsC.push(prevFlag = flag); xCoordC.push(x); yCoordC.push(y); } // 后续 else { if (x === 0) { flag += _glyFlag.default.XSAME; } else { if (-0xFF <= x && x <= 0xFF) { flag += _glyFlag.default.XSHORT; if (x > 0) { flag += _glyFlag.default.XSAME; } x = Math.abs(x); } xCoordC.push(x); } if (y === 0) { flag += _glyFlag.default.YSAME; } else { if (-0xFF <= y && y <= 0xFF) { flag += _glyFlag.default.YSHORT; if (y > 0) { flag += _glyFlag.default.YSAME; } y = Math.abs(y); } yCoordC.push(y); } // repeat if (flag === prevFlag) { // 记录重复个数 if (-1 === repeatPoint) { repeatPoint = flagsC.length - 1; flagsC[repeatPoint] |= _glyFlag.default.REPEAT; flagsC.push(1); } else { ++flagsC[repeatPoint + 1]; } } else { repeatPoint = -1; flagsC.push(prevFlag = flag); } } }); glyfSupport.flags = flagsC; glyfSupport.xCoord = xCoordC; glyfSupport.yCoord = yCoordC; return glyfSupport; } /** * 对glyf数据进行预处理,获取大小 * * @param {Object} ttf ttf对象 * @return {number} 大小 */ function sizeof(ttf) { ttf.support.glyf = []; var tableSize = 0; var hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; var writeZeroContoursGlyfData = ttf.writeOptions ? ttf.writeOptions.writeZeroContoursGlyfData : false; ttf.glyf.forEach(function (glyf) { var glyfSupport = {}; glyfSupport = glyf.compound ? glyfSupport : getFlags(glyf, glyfSupport); var glyfSize = glyf.compound ? sizeofCompound(glyf, hinting) : sizeofSimple(glyf, glyfSupport, hinting, writeZeroContoursGlyfData); var size = glyfSize; // 4字节对齐 if (size % 4) { size += 4 - size % 4; } glyfSupport.glyfSize = glyfSize; glyfSupport.size = size; ttf.support.glyf.push(glyfSupport); tableSize += size; }); ttf.support.glyf.tableSize = tableSize; // 写header的indexToLocFormat ttf.head.indexToLocFormat = tableSize > 65536 ? 1 : 0; return ttf.support.glyf.tableSize; }