From 144edbd2c5877b70450834b95f6357120f843ced Mon Sep 17 00:00:00 2001 From: kekee000 Date: Thu, 17 Sep 2020 12:19:00 +0800 Subject: [PATCH] feat: use eslint to lint codes --- .fecsignore => .eslintignore | 0 .eslintrc.js | 39 ++ .fecsrc | 26 - bower.json | 2 +- package.json | 17 +- src/common/DOMParser.js | 2 +- src/common/I18n.js | 6 +- src/common/ajaxFile.js | 16 +- src/common/lang.js | 28 +- src/common/string.js | 11 +- src/graphics/computeBoundingBox.js | 24 +- src/graphics/getArc.js | 80 +-- src/graphics/matrix.js | 4 +- src/graphics/pathAdjust.js | 4 +- src/graphics/pathIterator.js | 19 +- src/graphics/pathRotate.js | 8 +- src/graphics/pathSkew.js | 4 +- src/graphics/pathSkewX.js | 4 +- src/graphics/pathSkewY.js | 6 +- src/graphics/pathUtil.js | 40 +- src/graphics/pathsUtil.js | 18 +- src/main.js | 1 + src/math/bezierCubic2Q2.js | 12 +- src/nodejs/buffer.js | 10 +- src/ttf/enum/nameId.js | 2 +- src/ttf/eot2ttf.js | 28 +- src/ttf/error.js | 4 +- src/ttf/font.js | 12 +- src/ttf/getEmptyttfObject.js | 2 +- src/ttf/otf2ttfobject.js | 6 +- src/ttf/otfreader.js | 28 +- src/ttf/reader.js | 20 +- src/ttf/svg/contoursTransform.js | 73 +-- src/ttf/svg/oval2contour.js | 12 +- src/ttf/svg/parseParams.js | 2 +- src/ttf/svg/parseTransform.js | 4 +- src/ttf/svg/path2contours.js | 77 +-- src/ttf/svg/polygon2contour.js | 4 +- src/ttf/svg/rect2contour.js | 8 +- src/ttf/svg/svgnode2contours.js | 24 +- src/ttf/svg2ttfobject.js | 97 ++-- src/ttf/table/CFF.js | 78 +-- src/ttf/table/GPOS.js | 2 +- src/ttf/table/OS2.js | 38 +- src/ttf/table/cff/cffStandardStrings.js | 4 + src/ttf/table/cff/parseCFFCharset.js | 4 +- src/ttf/table/cff/parseCFFDict.js | 28 +- src/ttf/table/cff/parseCFFEncoding.js | 12 +- src/ttf/table/cff/parseCFFGlyph.js | 684 ++++++++++++------------ src/ttf/table/cmap.js | 2 +- src/ttf/table/cmap/parse.js | 75 +-- src/ttf/table/cmap/sizeof.js | 32 +- src/ttf/table/cmap/write.js | 22 +- src/ttf/table/cvt.js | 2 +- src/ttf/table/directory.js | 12 +- src/ttf/table/fpgm.js | 2 +- src/ttf/table/gasp.js | 2 +- src/ttf/table/glyf.js | 32 +- src/ttf/table/glyf/parse.js | 29 +- src/ttf/table/glyf/sizeof.js | 39 +- src/ttf/table/glyf/write.js | 47 +- src/ttf/table/hmtx.js | 16 +- src/ttf/table/kern.js | 2 +- src/ttf/table/loca.js | 22 +- src/ttf/table/maxp.js | 2 +- src/ttf/table/name.js | 41 +- src/ttf/table/post.js | 38 +- src/ttf/table/prep.js | 2 +- src/ttf/table/struct.js | 4 +- src/ttf/table/table.js | 239 +++++---- src/ttf/ttf.js | 184 +++---- src/ttf/ttf2eot.js | 19 +- src/ttf/ttf2icon.js | 20 +- src/ttf/ttf2svg.js | 12 +- src/ttf/ttf2symbol.js | 24 +- src/ttf/ttf2woff.js | 24 +- src/ttf/ttfreader.js | 34 +- src/ttf/ttftowoff2.js | 7 +- src/ttf/ttfwriter.js | 44 +- src/ttf/util/base642bytes.js | 4 +- src/ttf/util/bytes2base64.js | 4 +- src/ttf/util/checkSum.js | 6 +- src/ttf/util/compound2simpleglyf.js | 4 +- src/ttf/util/contour2svg.js | 26 +- src/ttf/util/contours2svg.js | 4 +- src/ttf/util/glyf2svg.js | 4 +- src/ttf/util/glyfAdjust.js | 9 +- src/ttf/util/optimizettf.js | 20 +- src/ttf/util/otfContours2ttfContours.js | 6 +- src/ttf/util/readWindowsAllCodes.js | 4 +- src/ttf/util/reduceGlyf.js | 2 +- src/ttf/util/string.js | 30 +- src/ttf/util/transformGlyfContours.js | 11 +- src/ttf/util/unicode2xml.js | 2 +- src/ttf/woff2tottf.js | 7 +- src/ttf/woff2ttf.js | 22 +- src/ttf/writer.js | 17 +- 97 files changed, 1422 insertions(+), 1424 deletions(-) rename .fecsignore => .eslintignore (100%) create mode 100644 .eslintrc.js delete mode 100644 .fecsrc diff --git a/.fecsignore b/.eslintignore similarity index 100% rename from .fecsignore rename to .eslintignore diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..1022f81 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,39 @@ +// eslint-disable-next-line import/no-commonjs +module.exports = { + 'env': { + 'browser': true, + 'es2021': true, + 'node': true + }, + 'extends': ['eslint:recommended', 'esnext'], + 'parserOptions': { + 'ecmaVersion': 12, + 'sourceType': 'module' + }, + 'rules': { + 'indent': [ + 'error', + 4 + ], + 'linebreak-style': [ + 'error', + 'unix' + ], + 'quotes': [ + 'error', + 'single' + ], + 'semi': [ + 'error', + 'always' + ], + 'eqeqeq': [ + 'error', + 'always', + { + 'null': 'ignore' + } + ], + 'class-methods-use-this': 0 + } +}; diff --git a/.fecsrc b/.fecsrc deleted file mode 100644 index 9646174..0000000 --- a/.fecsrc +++ /dev/null @@ -1,26 +0,0 @@ -{ - "eslint": { - "env": { - "node": true, - "browser": true - }, - - "rules": { - "no-console": false, - "fecs-max-statements": false, - "max-params": false, - "max-depth": false, - "fecs-camelcase": false, - "fecs-use-computed-property": false, - "fecs-prefer-destructure": false, - "fecs-export-on-declare": false, - "fecs-use-computed-property": false - }, - "globals": { - "ArrayBuffer": true, - "DataView": true, - "Uint8Array": true, - "Int8Array": true - } - } -} diff --git a/bower.json b/bower.json index 8af05ce..e88aba9 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "fonteditor-core", - "version": "0.0.33", + "version": "2.1.2", "homepage": "https://github.com/kekee000/fonteditor-core", "authors": [ "kekee000 ", diff --git a/package.json b/package.json index 0102263..4a837bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fonteditor-core", - "version": "2.1.1", + "version": "2.1.2", "description": "fonts (ttf, woff, woff2, eot, svg, otf) parse, write, transform, glyph adjust.", "keywords": [ "sfnt", @@ -34,12 +34,21 @@ } ], "scripts": { + "precommit": "npm run lint", "publish:npm": "npm run build && npm publish --registry=https://registry.npmjs.org/", "test": "./node_modules/.bin/mocha --require @babel/register test/spec/*.spec.js test/spec/**/*.spec.js", "test:node": "npm run build && ./node_modules/mocha/bin/mocha test/node-spec/**/*.spec.js ", "dev": "webpack-dev-server --open --config ./config/webpack.dev.js", "build": "babel src --out-dir lib", - "lint": "fecs ./src --reporter=baidu --rule" + "lint": "eslint ./src" + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "src/**/*.{jsx,txs,ts,js,vue}": ["eslint"] }, "dependencies": { "xmldom": "~0.1.19" @@ -63,7 +72,11 @@ "babel-plugin-module-resolver": "^3.2.0", "commander": "^3.0.2", "css-loader": "^3.2.0", + "eslint": "^7.9.0", + "eslint-config-esnext": "^4.1.0", "html-webpack-plugin": "^3.2.0", + "husky": "^4.3.0", + "lint-staged": "^10.4.0", "mocha": "^6.2.1", "pako": "^1.0.10", "style-loader": "^1.0.0", diff --git a/src/common/DOMParser.js b/src/common/DOMParser.js index edd5a48..aa4de59 100644 --- a/src/common/DOMParser.js +++ b/src/common/DOMParser.js @@ -3,7 +3,7 @@ * @author mengke01(kekee000@gmail.com) */ -/* eslint-disable no-undef, fecs-no-require */ +/* eslint-disable no-undef */ export default typeof exports !== 'undefined' ? require('xmldom').DOMParser : window.DOMParser; diff --git a/src/common/I18n.js b/src/common/I18n.js index 73af413..2e9b00f 100644 --- a/src/common/I18n.js +++ b/src/common/I18n.js @@ -4,8 +4,8 @@ */ function appendLanguage(store, languageList) { - languageList.forEach(function (item) { - let language = item[0]; + languageList.forEach(item => { + const language = item[0]; store[language] = Object.assign(store[language] || {}, item[1]); }); return store; @@ -65,7 +65,7 @@ export default class I18n { * @return {string} 语言字符串 */ get(path) { - let ref = path.split('.'); + const ref = path.split('.'); let refObject = this.lang; let level; while (refObject != null && (level = ref.shift())) { diff --git a/src/common/ajaxFile.js b/src/common/ajaxFile.js index 9d34445..e203bb8 100644 --- a/src/common/ajaxFile.js +++ b/src/common/ajaxFile.js @@ -15,15 +15,15 @@ * @param {Object=} options.params 参数集合 */ export default function ajaxFile(options) { - let xhr = new XMLHttpRequest(); + const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { - let status = xhr.status; + const status = xhr.status; if (status >= 200 && status < 300 || status === 304) { if (options.onSuccess) { if (options.type === 'binary') { - let buffer = xhr.responseBlob || xhr.response; + const buffer = xhr.responseBlob || xhr.response; options.onSuccess(buffer); } else if (options.type === 'xml') { @@ -38,20 +38,18 @@ export default function ajaxFile(options) { } } - else { - if (options.onError) { - options.onError(xhr, xhr.status); - } + else if (options.onError) { + options.onError(xhr, xhr.status); } } }; - let method = (options.method || 'GET').toUpperCase(); + const method = (options.method || 'GET').toUpperCase(); let params = null; if (options.params) { let str = []; - Object.keys(options.params).forEach(function (key) { + Object.keys(options.params).forEach(key => { str.push(key + '=' + encodeURIComponent(options.params[key])); }); str = str.join('&'); diff --git a/src/common/lang.js b/src/common/lang.js index dcc7465..41ed273 100644 --- a/src/common/lang.js +++ b/src/common/lang.js @@ -25,7 +25,8 @@ export function isDate(obj) { } export function isEmptyObject(object) { - for (let name in object) { + for (const name in object) { + // eslint-disable-next-line no-prototype-builtins if (object.hasOwnProperty(name)) { return false; } @@ -43,7 +44,8 @@ export function isEmptyObject(object) { */ export function curry(fn, ...cargs) { return function (...rargs) { - let args = cargs.concat(rargs); + const args = cargs.concat(rargs); + // eslint-disable-next-line no-invalid-this return fn.apply(this, args); }; } @@ -78,7 +80,7 @@ export function overwrite(thisObj, thatObj, fields) { // 这里`fields`未指定则仅overwrite自身可枚举的字段,指定`fields`则不做限制 fields = fields || Object.keys(thatObj); - fields.forEach(function (field) { + fields.forEach(field => { // 拷贝对象 if ( thisObj[field] && typeof thisObj[field] === 'object' @@ -112,7 +114,7 @@ export function clone(source) { } else if (isObject(source) && 'isPrototypeOf' in source) { cloned = {}; - for (let key of Object.keys(source)) { + for (const key of Object.keys(source)) { cloned[key] = clone(source[key]); } } @@ -130,15 +132,16 @@ export function throttle(func, wait) { let timeout; let result; let previous = 0; - let later = function () { + const later = function () { previous = new Date(); timeout = null; result = func.apply(context, args); }; return function (...args) { - let now = new Date(); - let remaining = wait - (now - previous); + const now = new Date(); + const remaining = wait - (now - previous); + // eslint-disable-next-line no-invalid-this context = this; if (remaining <= 0) { clearTimeout(timeout); @@ -163,15 +166,16 @@ export function debounce(func, wait, immediate) { let result; return function (...args) { - let context = this; - let later = function () { + // eslint-disable-next-line no-invalid-this + const context = this; + const later = function () { timeout = null; if (!immediate) { result = func.apply(context, args); } }; - let callNow = immediate && !timeout; + const callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); @@ -208,8 +212,8 @@ export function equals(thisObj, thatObj, fields) { // 这里`fields`未指定则仅overwrite自身可枚举的字段,指定`fields`则不做限制 fields = fields || (typeof thisObj === 'object' - ? Object.keys(thisObj) - : []); + ? Object.keys(thisObj) + : []); if (!fields.length) { return thisObj === thatObj; diff --git a/src/common/string.js b/src/common/string.js index 757756e..87573ea 100644 --- a/src/common/string.js +++ b/src/common/string.js @@ -13,16 +13,14 @@ export default { */ decodeHTML(source) { - let str = String(source) + const str = String(source) .replace(/"/g, '"') .replace(/</g, '<') .replace(/>/g, '>') .replace(/&/g, '&'); // 处理转义的中文和实体字符 - return str.replace(/&#([\d]+);/g, function ($0, $1) { - return String.fromCodePoint(parseInt($1, 10)); - }); + return str.replace(/&#([\d]+);/g, ($0, $1) => String.fromCodePoint(parseInt($1, 10))); }, /** @@ -47,6 +45,7 @@ export default { * @return {number} 长度 */ getLength(source) { + // eslint-disable-next-line no-control-regex return String(source).replace(/[^\x00-\xff]/g, '11').length; }, @@ -58,8 +57,8 @@ export default { * @return {string} 格式化后字符串 */ format(source, data) { - return source.replace(/\$\{([\w.]+)\}/g, function ($0, $1) { - let ref = $1.split('.'); + return source.replace(/\$\{([\w.]+)\}/g, ($0, $1) => { + const ref = $1.split('.'); let refObject = data; let level; diff --git a/src/graphics/computeBoundingBox.js b/src/graphics/computeBoundingBox.js index e3e0fe6..96ff164 100644 --- a/src/graphics/computeBoundingBox.js +++ b/src/graphics/computeBoundingBox.js @@ -26,7 +26,7 @@ function computeBoundingBox(points) { let bottom = points[0].y; for (let i = 1; i < points.length; i++) { - let p = points[i]; + const p = points[i]; if (p.x < left) { left = p.x; @@ -87,14 +87,14 @@ function computeQuadraticBezierBoundingBox(p0, p1, p2) { t1 = Math.max(Math.min(t1, 1), 0); t2 = Math.max(Math.min(t2, 1), 0); - let ct1 = 1 - t1; - let ct2 = 1 - t2; + const ct1 = 1 - t1; + const ct2 = 1 - t2; - let x1 = ct1 * ct1 * p0.x + 2 * ct1 * t1 * p1.x + t1 * t1 * p2.x; - let y1 = ct1 * ct1 * p0.y + 2 * ct1 * t1 * p1.y + t1 * t1 * p2.y; + const x1 = ct1 * ct1 * p0.x + 2 * ct1 * t1 * p1.x + t1 * t1 * p2.x; + const y1 = ct1 * ct1 * p0.y + 2 * ct1 * t1 * p1.y + t1 * t1 * p2.y; - let x2 = ct2 * ct2 * p0.x + 2 * ct2 * t2 * p1.x + t2 * t2 * p2.x; - let y2 = ct2 * ct2 * p0.y + 2 * ct2 * t2 * p1.y + t2 * t2 * p2.y; + const x2 = ct2 * ct2 * p0.x + 2 * ct2 * t2 * p1.x + t2 * t2 * p2.x; + const y2 = ct2 * ct2 * p0.y + 2 * ct2 * t2 * p1.y + t2 * t2 * p2.y; return computeBoundingBox( [ @@ -121,14 +121,14 @@ function computeQuadraticBezierBoundingBox(p0, p1, p2) { */ function computePathBoundingBox(...args) { - let points = []; - let iterator = function (c, p0, p1, p2) { + const points = []; + const iterator = function (c, p0, p1, p2) { if (c === 'L') { points.push(p0); points.push(p1); } else if (c === 'Q') { - let bound = computeQuadraticBezierBoundingBox(p0, p1, p2); + const bound = computeQuadraticBezierBoundingBox(p0, p1, p2); points.push(bound); points.push({ @@ -139,13 +139,13 @@ function computePathBoundingBox(...args) { }; if (args.length === 1) { - pathIterator(args[0], function (c, p0, p1, p2) { + pathIterator(args[0], (c, p0, p1, p2) => { if (c === 'L') { points.push(p0); points.push(p1); } else if (c === 'Q') { - let bound = computeQuadraticBezierBoundingBox(p0, p1, p2); + const bound = computeQuadraticBezierBoundingBox(p0, p1, p2); points.push(bound); points.push({ diff --git a/src/graphics/getArc.js b/src/graphics/getArc.js index f8f988b..4f5da22 100644 --- a/src/graphics/getArc.js +++ b/src/graphics/getArc.js @@ -15,10 +15,10 @@ const TAU = Math.PI * 2; function vectorAngle(ux, uy, vx, vy) { // Calculate an angle between two vectors - let sign = (ux * vy - uy * vx < 0) ? -1 : 1; - let umag = Math.sqrt(ux * ux + uy * uy); - let vmag = Math.sqrt(ux * ux + uy * uy); - let dot = ux * vx + uy * vy; + const sign = (ux * vy - uy * vx < 0) ? -1 : 1; + const umag = Math.sqrt(ux * ux + uy * uy); + const vmag = Math.sqrt(ux * ux + uy * uy); + const dot = ux * vx + uy * vy; let div = dot / (umag * vmag); if (div > 1 || div < -1) { @@ -35,7 +35,7 @@ function correctRadii(midx, midy, rx, ry) { rx = Math.abs(rx); ry = Math.abs(ry); - let Λ = (midx * midx) / (rx * rx) + (midy * midy) / (ry * ry); + const Λ = (midx * midx) / (rx * rx) + (midy * midy) / (ry * ry); if (Λ > 1) { rx *= Math.sqrt(Λ); ry *= Math.sqrt(Λ); @@ -55,13 +55,13 @@ function getArcCenter(x1, y1, x2, y2, fa, fs, rx, ry, sin_φ, cos_φ) { // points. After that, rotate it to line up ellipse axes with coordinate // axes. // - let x1p = cos_φ * (x1 - x2) / 2 + sin_φ * (y1 - y2) / 2; - let y1p = -sin_φ * (x1 - x2) / 2 + cos_φ * (y1 - y2) / 2; + const x1p = cos_φ * (x1 - x2) / 2 + sin_φ * (y1 - y2) / 2; + const y1p = -sin_φ * (x1 - x2) / 2 + cos_φ * (y1 - y2) / 2; - let rx_sq = rx * rx; - let ry_sq = ry * ry; - let x1p_sq = x1p * x1p; - let y1p_sq = y1p * y1p; + const rx_sq = rx * rx; + const ry_sq = ry * ry; + const x1p_sq = x1p * x1p; + const y1p_sq = y1p * y1p; // Step 2. // @@ -78,27 +78,27 @@ function getArcCenter(x1, y1, x2, y2, fa, fs, rx, ry, sin_φ, cos_φ) { radicant /= (rx_sq * y1p_sq) + (ry_sq * x1p_sq); radicant = Math.sqrt(radicant) * (fa === fs ? -1 : 1); - let cxp = radicant * rx / ry * y1p; - let cyp = radicant * -ry / rx * x1p; + const cxp = radicant * rx / ry * y1p; + const cyp = radicant * -ry / rx * x1p; // Step 3. // // Transform back to get centre coordinates (cx, cy) in the original // coordinate system. // - let cx = cos_φ * cxp - sin_φ * cyp + (x1 + x2) / 2; - let cy = sin_φ * cxp + cos_φ * cyp + (y1 + y2) / 2; + const cx = cos_φ * cxp - sin_φ * cyp + (x1 + x2) / 2; + const cy = sin_φ * cxp + cos_φ * cyp + (y1 + y2) / 2; // Step 4. // // Compute angles (θ1, Δθ). // - let v1x = (x1p - cxp) / rx; - let v1y = (y1p - cyp) / ry; - let v2x = (-x1p - cxp) / rx; - let v2y = (-y1p - cyp) / ry; + const v1x = (x1p - cxp) / rx; + const v1y = (y1p - cyp) / ry; + const v2x = (-x1p - cxp) / rx; + const v2y = (-y1p - cyp) / ry; - let θ1 = vectorAngle(1, 0, v1x, v1y); + const θ1 = vectorAngle(1, 0, v1x, v1y); let Δθ = vectorAngle(v1x, v1y, v2x, v2y); if (fs === 0 && Δθ > 0) { @@ -115,25 +115,25 @@ function approximateUnitArc(θ1, Δθ) { // Approximate one unit arc segment with bézier curves, // see http://math.stackexchange.com/questions/873224/ // calculate-control-points-of-cubic-bezier-curve-approximating-a-part-of-a-circle - let α = 4 / 3 * Math.tan(Δθ / 4); + const α = 4 / 3 * Math.tan(Δθ / 4); - let x1 = Math.cos(θ1); - let y1 = Math.sin(θ1); - let x2 = Math.cos(θ1 + Δθ); - let y2 = Math.sin(θ1 + Δθ); + const x1 = Math.cos(θ1); + const y1 = Math.sin(θ1); + const x2 = Math.cos(θ1 + Δθ); + const y2 = Math.sin(θ1 + Δθ); return [x1, y1, x1 - y1 * α, y1 + x1 * α, x2 + y2 * α, y2 - x2 * α, x2, y2]; } function a2c(x1, y1, x2, y2, fa, fs, rx, ry, φ) { - let sin_φ = Math.sin(φ * TAU / 360); - let cos_φ = Math.cos(φ * TAU / 360); + const sin_φ = Math.sin(φ * TAU / 360); + const cos_φ = Math.cos(φ * TAU / 360); // Make sure radii are valid // - let x1p = cos_φ * (x1 - x2) / 2 + sin_φ * (y1 - y2) / 2; - let y1p = -sin_φ * (x1 - x2) / 2 + cos_φ * (y1 - y2) / 2; + const x1p = cos_φ * (x1 - x2) / 2 + sin_φ * (y1 - y2) / 2; + const y1p = -sin_φ * (x1 - x2) / 2 + cos_φ * (y1 - y2) / 2; if (x1p === 0 && y1p === 0) { // we're asked to draw line to itself @@ -145,22 +145,22 @@ function a2c(x1, y1, x2, y2, fa, fs, rx, ry, φ) { return []; } - let radii = correctRadii(x1p, y1p, rx, ry); + const radii = correctRadii(x1p, y1p, rx, ry); rx = radii[0]; ry = radii[1]; // Get center parameters (cx, cy, θ1, Δθ) // - let cc = getArcCenter(x1, y1, x2, y2, fa, fs, rx, ry, sin_φ, cos_φ); + const cc = getArcCenter(x1, y1, x2, y2, fa, fs, rx, ry, sin_φ, cos_φ); - let result = []; + const result = []; let θ1 = cc[2]; let Δθ = cc[3]; // Split an arc to multiple segments, so each segment // will be less than τ/4 (= 90°) // - let segments = Math.max(Math.ceil(Math.abs(Δθ) / (TAU / 4)), 1); + const segments = Math.max(Math.ceil(Math.abs(Δθ) / (TAU / 4)), 1); Δθ /= segments; for (let i = 0; i < segments; i++) { @@ -171,7 +171,7 @@ function a2c(x1, y1, x2, y2, fa, fs, rx, ry, φ) { // We have a bezier approximation of a unit circle, // now need to transform back to the original ellipse // - return result.map(function (curve) { + return result.map(curve => { for (let i = 0; i < curve.length; i += 2) { let x = curve[i + 0]; let y = curve[i + 1]; @@ -181,8 +181,8 @@ function a2c(x1, y1, x2, y2, fa, fs, rx, ry, φ) { y *= ry; // rotate - let xp = cos_φ * x - sin_φ * y; - let yp = sin_φ * x + cos_φ * y; + const xp = cos_φ * x - sin_φ * y; + const yp = sin_φ * x + cos_φ * y; // translate curve[i + 0] = xp + cc[0]; @@ -206,8 +206,8 @@ function a2c(x1, y1, x2, y2, fa, fs, rx, ry, φ) { * @return {Array} 分割后的路径 */ export default function getArc(rx, ry, angle, largeArc, sweep, p0, p1) { - let result = a2c(p0.x, p0.y, p1.x, p1.y, largeArc, sweep, rx, ry, angle); - let path = []; + const result = a2c(p0.x, p0.y, p1.x, p1.y, largeArc, sweep, rx, ry, angle); + const path = []; if (result.length) { path.push({ @@ -217,8 +217,8 @@ export default function getArc(rx, ry, angle, largeArc, sweep, p0, p1) { }); // 将三次曲线转换成二次曲线 - result.forEach(function (c, index) { - let q2Array = bezierCubic2Q2({ + result.forEach(c => { + const q2Array = bezierCubic2Q2({ x: c[0], y: c[1] }, { diff --git a/src/graphics/matrix.js b/src/graphics/matrix.js index 46cb907..a0533f4 100644 --- a/src/graphics/matrix.js +++ b/src/graphics/matrix.js @@ -41,8 +41,8 @@ export function mul(matrix1 = [1, 0, 0, 1], matrix2 = [1, 0, 0, 1]) { */ export function multiply(...matrixs) { let result = matrixs[0]; - for (let i = 1, matrix; matrix = matrixs[i]; i++) { - result = this.mul(result, matrix); + for (let i = 1, matrix; (matrix = matrixs[i]); i++) { + result = mul(result, matrix); } return result; diff --git a/src/graphics/pathAdjust.js b/src/graphics/pathAdjust.js index 13923a7..4146149 100644 --- a/src/graphics/pathAdjust.js +++ b/src/graphics/pathAdjust.js @@ -17,8 +17,8 @@ export default function pathAdjust(contour, scaleX, scaleY, offsetX, offsetY) { scaleX = scaleX === undefined ? 1 : scaleX; scaleY = scaleY === undefined ? 1 : scaleY; - let x = offsetX || 0; - let y = offsetY || 0; + const x = offsetX || 0; + const y = offsetY || 0; let p; for (let i = 0, l = contour.length; i < l; i++) { p = contour[i]; diff --git a/src/graphics/pathIterator.js b/src/graphics/pathIterator.js index d1fd0d3..6e7bd44 100644 --- a/src/graphics/pathIterator.js +++ b/src/graphics/pathIterator.js @@ -29,17 +29,16 @@ export default function pathIterator(contour, callBack) { if (curPoint.onCurve) { cursorPoint = curPoint; } + else if (prevPoint.onCurve) { + cursorPoint = prevPoint; + } else { - if (prevPoint.onCurve) { - cursorPoint = prevPoint; - } - else { - cursorPoint = { - x: (prevPoint.x + curPoint.x) / 2, - y: (prevPoint.y + curPoint.y) / 2 - }; - } + cursorPoint = { + x: (prevPoint.x + curPoint.x) / 2, + y: (prevPoint.y + curPoint.y) / 2 + }; } + } // 直线 @@ -58,7 +57,7 @@ export default function pathIterator(contour, callBack) { cursorPoint = nextPoint; } else { - let last = { + const last = { x: (curPoint.x + nextPoint.x) / 2, y: (curPoint.y + nextPoint.y) / 2 }; diff --git a/src/graphics/pathRotate.js b/src/graphics/pathRotate.js index c4a07ce..0e69bb4 100644 --- a/src/graphics/pathRotate.js +++ b/src/graphics/pathRotate.js @@ -15,10 +15,10 @@ */ export default function pathRotate(contour, angle, centerX, centerY) { angle = angle === undefined ? 0 : angle; - let x = centerX || 0; - let y = centerY || 0; - let cos = Math.cos(angle); - let sin = Math.sin(angle); + const x = centerX || 0; + const y = centerY || 0; + const cos = Math.cos(angle); + const sin = Math.sin(angle); let px; let py; let p; diff --git a/src/graphics/pathSkew.js b/src/graphics/pathSkew.js index b6f9360..343ce3e 100644 --- a/src/graphics/pathSkew.js +++ b/src/graphics/pathSkew.js @@ -15,8 +15,8 @@ */ export default function pathSkew(contour, angle, offsetX, offsetY) { angle = angle === undefined ? 0 : angle; - let x = offsetX || 0; - let tan = Math.tan(angle); + const x = offsetX || 0; + const tan = Math.tan(angle); let p; let i; let l; diff --git a/src/graphics/pathSkewX.js b/src/graphics/pathSkewX.js index b4661dd..3b91eca 100644 --- a/src/graphics/pathSkewX.js +++ b/src/graphics/pathSkewX.js @@ -14,8 +14,8 @@ import {computePath} from './computeBoundingBox'; */ export default function pathSkewX(contour, angle) { angle = angle === undefined ? 0 : angle; - let y = computePath(contour).y; - let tan = Math.tan(angle); + const y = computePath(contour).y; + const tan = Math.tan(angle); let p; // x 平移 for (let i = 0, l = contour.length; i < l; i++) { diff --git a/src/graphics/pathSkewY.js b/src/graphics/pathSkewY.js index 22621a4..10b915d 100644 --- a/src/graphics/pathSkewY.js +++ b/src/graphics/pathSkewY.js @@ -2,7 +2,7 @@ * @file 按Y轴平移变换, 变换中心为图像中心点 * @author mengke01(kekee000@gmail.com) */ -import computePath from './computeBoundingBox'; +import {computePath} from './computeBoundingBox'; /** * path倾斜变换 @@ -14,8 +14,8 @@ import computePath from './computeBoundingBox'; */ export default function pathSkewY(contour, angle) { angle = angle === undefined ? 0 : angle; - let x = computePath(contour).x; - let tan = Math.tan(angle); + const x = computePath(contour).x; + const tan = Math.tan(angle); let p; // y 平移 for (let i = 0, l = contour.length; i < l; i++) { diff --git a/src/graphics/pathUtil.js b/src/graphics/pathUtil.js index 861fbf2..49e201d 100644 --- a/src/graphics/pathUtil.js +++ b/src/graphics/pathUtil.js @@ -12,9 +12,9 @@ import {getPointHash} from './util'; * @return {Array} 路径 */ export function interpolate(path) { - let newPath = []; + const newPath = []; for (let i = 0, l = path.length; i < l; i++) { - let next = i === l - 1 ? 0 : i + 1; + const next = i === l - 1 ? 0 : i + 1; newPath.push(path[i]); // 插值 if (!path[i].onCurve && !path[next].onCurve) { @@ -37,11 +37,11 @@ export function interpolate(path) { * @return {Array} 路径 */ export function deInterpolate(path) { - let newPath = []; + const newPath = []; for (let i = 0, l = path.length; i < l; i++) { - let next = i === l - 1 ? 0 : i + 1; - let prev = i === 0 ? l - 1 : i - 1; + const next = i === l - 1 ? 0 : i + 1; + const prev = i === 0 ? l - 1 : i - 1; // 插值 if ( !path[prev].onCurve && path[i].onCurve && !path[next].onCurve @@ -75,10 +75,10 @@ export function isClockWise(path) { let zCount = 0; for (let i = 0, l = path.length; i < l; i++) { - let cur = path[i]; - let prev = i === 0 ? path[l - 1] : path[i - 1]; - let next = i === l - 1 ? path[0] : path[i + 1]; - let z = (cur.x - prev.x) * (next.y - cur.y) + const cur = path[i]; + const prev = i === 0 ? path[l - 1] : path[i - 1]; + const next = i === l - 1 ? path[0] : path[i + 1]; + const z = (cur.x - prev.x) * (next.y - cur.y) - (cur.y - prev.y) * (next.x - cur.x); if (z < 0) { @@ -102,9 +102,9 @@ export function isClockWise(path) { */ export function getPathHash(path) { let hash = 0; - let seed = 131; + const seed = 131; - path.forEach(function (p) { + path.forEach(p => { hash = 0x7FFFFFFF & (hash * seed + getPointHash(p) + (p.onCurve ? 1 : 0)); }); @@ -119,10 +119,10 @@ export function getPathHash(path) { * @return {Array} 移除后点集合 */ export function removeOverlapPoints(points) { - let hash = {}; - let ret = []; + const hash = {}; + const ret = []; for (let i = 0, l = points.length; i < l; i++) { - let hashcode = points[i].x * 31 + points[i].y; + const hashcode = points[i].x * 31 + points[i].y; if (!hash[hashcode]) { ret.push(points[i]); hash[hashcode] = 1; @@ -139,9 +139,9 @@ export function removeOverlapPoints(points) { */ export function makeLink(path) { for (let i = 0, l = path.length; i < l; i++) { - let cur = path[i]; - let prev = i === 0 ? path[l - 1] : path[i - 1]; - let next = i === l - 1 ? path[0] : path[i + 1]; + const cur = path[i]; + const prev = i === 0 ? path[l - 1] : path[i - 1]; + const next = i === l - 1 ? path[0] : path[i + 1]; cur.index = i; cur.next = next; cur.prev = prev; @@ -160,7 +160,7 @@ export function makeLink(path) { */ export function scale(path, ratio) { for (let i = 0, l = path.length; i < l; i++) { - let cur = path[i]; + const cur = path[i]; cur.x *= ratio; cur.y *= ratio; } @@ -170,8 +170,8 @@ export function scale(path, ratio) { export function clone(path) { - return path ? path.map(function (p) { - let newP = { + return path ? path.map(p => { + const newP = { x: p.x, y: p.y }; diff --git a/src/graphics/pathsUtil.js b/src/graphics/pathsUtil.js index d82bd1a..c32a0bd 100644 --- a/src/graphics/pathsUtil.js +++ b/src/graphics/pathsUtil.js @@ -16,10 +16,10 @@ import pathRotate from './pathRotate'; * @return {Array} 变换后的路径 */ function mirrorPaths(paths, xScale, yScale) { - let {x, y, width, height} = computePath.apply(null, paths); + const {x, y, width, height} = computePath(...paths); if (xScale === -1) { - paths.forEach(function (p) { + paths.forEach(p => { pathAdjust(p, -1, 1, -x, 0); pathAdjust(p, 1, 1, x + width, 0); p.reverse(); @@ -28,7 +28,7 @@ function mirrorPaths(paths, xScale, yScale) { } if (yScale === -1) { - paths.forEach(function (p) { + paths.forEach(p => { pathAdjust(p, 1, -1, 0, -y); pathAdjust(p, 1, 1, 0, y + height); p.reverse(); @@ -54,12 +54,12 @@ export default { return paths; } - let bound = computePath.apply(null, paths); + const bound = computePath(...paths); - let cx = bound.x + (bound.width) / 2; - let cy = bound.y + (bound.height) / 2; + const cx = bound.x + (bound.width) / 2; + const cy = bound.y + (bound.height) / 2; - paths.forEach(function (p) { + paths.forEach(p => { pathRotate(p, angle, cx, cy); }); @@ -75,8 +75,8 @@ export default { * @return {Array} 变换后的路径 */ move(paths, x, y) { - let bound = computePath.apply(null, paths); - paths.forEach(function (path) { + const bound = computePath(...paths); + paths.forEach(path => { pathAdjust(path, 1, 1, x - bound.x, y - bound.y); }); diff --git a/src/main.js b/src/main.js index a3a5278..c331464 100644 --- a/src/main.js +++ b/src/main.js @@ -47,5 +47,6 @@ const modules = { export default modules; if (typeof exports !== 'undefined') { + // eslint-disable-next-line import/no-commonjs module.exports = modules; } diff --git a/src/math/bezierCubic2Q2.js b/src/math/bezierCubic2Q2.js index 633be77..22dd66f 100644 --- a/src/math/bezierCubic2Q2.js +++ b/src/math/bezierCubic2Q2.js @@ -10,8 +10,8 @@ function toQuad(p1, c1, c2, p2) { // Quad control point is (3*c2 - p2 + 3*c1 - p1)/4 - let x = (3 * c2.x - p2.x + 3 * c1.x - p1.x) / 4; - let y = (3 * c2.y - p2.y + 3 * c1.y - p1.y) / 4; + const x = (3 * c2.x - p2.x + 3 * c1.x - p1.x) / 4; + const y = (3 * c2.y - p2.y + 3 * c1.y - p1.y) / 4; return [ p1, {x, y}, @@ -45,9 +45,8 @@ export default function bezierCubic2Q2(p1, c1, c2, p2) { ]; } - - let mx = p2.x - 3 * c2.x + 3 * c1.x - p1.x; - let my = p2.y - 3 * c2.y + 3 * c1.y - p1.y; + const mx = p2.x - 3 * c2.x + 3 * c1.x - p1.x; + const my = p2.y - 3 * c2.y + 3 * c1.y - p1.y; // control points near if (mx * mx + my * my <= 4) { @@ -58,10 +57,9 @@ export default function bezierCubic2Q2(p1, c1, c2, p2) { // Split to 2 qubic beziers by midpoints // (p2 + 3*c2 + 3*c1 + p1)/8 - let mp = { + const mp = { x: (p2.x + 3 * c2.x + 3 * c1.x + p1.x) / 8, y: (p2.y + 3 * c2.y + 3 * c1.y + p1.y) / 8 - }; return [ diff --git a/src/nodejs/buffer.js b/src/nodejs/buffer.js index f4b2883..75eaa00 100644 --- a/src/nodejs/buffer.js +++ b/src/nodejs/buffer.js @@ -13,8 +13,8 @@ export default { * @return {ArrayBuffer} */ toArrayBuffer(buffer) { - let length = buffer.length; - let view = new DataView(new ArrayBuffer(length), 0, length); + const length = buffer.length; + const view = new DataView(new ArrayBuffer(length), 0, length); for (let i = 0, l = length; i < l; i++) { view.setUint8(i, buffer[i], false); } @@ -32,9 +32,9 @@ export default { return Buffer.from(arrayBuffer); } - let length = arrayBuffer.byteLength; - let view = new DataView(arrayBuffer, 0, length); - let buffer = Buffer.alloc(length); + const length = arrayBuffer.byteLength; + const view = new DataView(arrayBuffer, 0, length); + const buffer = Buffer.alloc(length); for (let i = 0, l = length; i < l; i++) { buffer[i] = view.getUint8(i, false); } diff --git a/src/ttf/enum/nameId.js b/src/ttf/enum/nameId.js index 2aa5dea..37a4235 100644 --- a/src/ttf/enum/nameId.js +++ b/src/ttf/enum/nameId.js @@ -27,7 +27,7 @@ const nameId = { // 反转names const nameIdHash = {}; -Object.keys(nameId).forEach(function (id) { +Object.keys(nameId).forEach(id => { nameIdHash[nameId[id]] = +id; }); diff --git a/src/ttf/eot2ttf.js b/src/ttf/eot2ttf.js index f81c8b9..0f3ee5f 100644 --- a/src/ttf/eot2ttf.js +++ b/src/ttf/eot2ttf.js @@ -15,52 +15,52 @@ import error from './error'; * * @return {ArrayBuffer} ttf格式byte流 */ +// eslint-disable-next-line no-unused-vars export default function eot2ttf(eotBuffer, options = {}) { - // 这里用小尾方式读取 - let eotReader = new Reader(eotBuffer, 0, eotBuffer.byteLength, true); + const eotReader = new Reader(eotBuffer, 0, eotBuffer.byteLength, true); // check magic number - let magicNumber = eotReader.readUint16(34); + const magicNumber = eotReader.readUint16(34); if (magicNumber !== 0x504C) { error.raise(10110); } // check version - let version = eotReader.readUint32(8); + const version = eotReader.readUint32(8); if (version !== 0x20001 && version !== 0x10000 && version !== 0x20002) { error.raise(10110); } - let eotSize = eotBuffer.byteLength || eotBuffer.length; - let fontSize = eotReader.readUint32(4); + const eotSize = eotBuffer.byteLength || eotBuffer.length; + const fontSize = eotReader.readUint32(4); let fontOffset = 82; - let familyNameSize = eotReader.readUint16(fontOffset); + const familyNameSize = eotReader.readUint16(fontOffset); fontOffset += 4 + familyNameSize; - let styleNameSize = eotReader.readUint16(fontOffset); + const styleNameSize = eotReader.readUint16(fontOffset); fontOffset += 4 + styleNameSize; - let versionNameSize = eotReader.readUint16(fontOffset); + const versionNameSize = eotReader.readUint16(fontOffset); fontOffset += 4 + versionNameSize; - let fullNameSize = eotReader.readUint16(fontOffset); + const fullNameSize = eotReader.readUint16(fontOffset); fontOffset += 2 + fullNameSize; // version 0x20001 if (version === 0x20001 || version === 0x20002) { - let rootStringSize = eotReader.readUint16(fontOffset + 2); + const rootStringSize = eotReader.readUint16(fontOffset + 2); fontOffset += 4 + rootStringSize; } // version 0x20002 if (version === 0x20002) { fontOffset += 10; - let signatureSize = eotReader.readUint16(fontOffset); + const signatureSize = eotReader.readUint16(fontOffset); fontOffset += 2 + signatureSize; fontOffset += 4; - let eudcFontSize = eotReader.readUint32(fontOffset); + const eudcFontSize = eotReader.readUint32(fontOffset); fontOffset += 4 + eudcFontSize; } @@ -74,6 +74,6 @@ export default function eot2ttf(eotBuffer, options = {}) { } // not support ArrayBuffer.slice eg. IE10 - let bytes = eotReader.readBytes(fontOffset, fontSize); + const bytes = eotReader.readBytes(fontOffset, fontSize); return new Writer(new ArrayBuffer(fontSize)).writeBytes(bytes).getBuffer(); } diff --git a/src/ttf/error.js b/src/ttf/error.js index c50cf2b..c12066d 100644 --- a/src/ttf/error.js +++ b/src/ttf/error.js @@ -34,13 +34,13 @@ export default { let message = i18n.lang[number]; if (fargs.length > 0) { - let args = typeof fargs[0] === 'object' + const args = typeof fargs[0] === 'object' ? fargs[0] : fargs; message = string.format(message, args); } - let event = new Error(message); + const event = new Error(message); event.number = number; if (data) { event.data = data; diff --git a/src/ttf/font.js b/src/ttf/font.js index 82a126a..ac31436 100644 --- a/src/ttf/font.js +++ b/src/ttf/font.js @@ -265,7 +265,7 @@ export default class Font { * @return {Font} */ optimize(out) { - let result = optimizettf(this.data); + const result = optimizettf(this.data); if (out) { out.result = result; } @@ -278,7 +278,7 @@ export default class Font { * @return {this} */ compound2simple() { - let ttf = new TTF(this.data); + const ttf = new TTF(this.data); ttf.compound2simple(); this.data = ttf.get(); return this; @@ -290,7 +290,7 @@ export default class Font { * @return {this} */ sort() { - let ttf = new TTF(this.data); + const ttf = new TTF(this.data); ttf.sortGlyf(); this.data = ttf.get(); return this; @@ -310,8 +310,8 @@ export default class Font { * @return {Array} glyf字形列表 */ find(condition) { - let ttf = new TTF(this.data); - let indexList = ttf.findGlyf(condition); + const ttf = new TTF(this.data); + const indexList = ttf.findGlyf(condition); return indexList.length ? ttf.getGlyf(indexList) : indexList; } @@ -327,7 +327,7 @@ export default class Font { * @return {Font} */ merge(font, options) { - let ttf = new TTF(this.data); + const ttf = new TTF(this.data); ttf.mergeGlyf(font.get(), options); this.data = ttf.get(); return this; diff --git a/src/ttf/getEmptyttfObject.js b/src/ttf/getEmptyttfObject.js index b3ff2e1..c99c930 100644 --- a/src/ttf/getEmptyttfObject.js +++ b/src/ttf/getEmptyttfObject.js @@ -9,7 +9,7 @@ import config from './data/default'; export default function getEmpty() { - let ttf = clone(emptyttf); + const ttf = clone(emptyttf); Object.assign(ttf.name, config.name); ttf.head.created = ttf.head.modified = Date.now(); return ttf; diff --git a/src/ttf/otf2ttfobject.js b/src/ttf/otf2ttfobject.js index 32461b1..c7c08c7 100644 --- a/src/ttf/otf2ttfobject.js +++ b/src/ttf/otf2ttfobject.js @@ -18,7 +18,7 @@ import {computePathBox} from '../graphics/computeBoundingBox'; export default function otf2ttfobject(otfBuffer, options) { let otfObject; if (otfBuffer instanceof ArrayBuffer) { - let otfReader = new OTFReader(options); + const otfReader = new OTFReader(options); otfObject = otfReader.read(otfBuffer); otfReader.dispose(); } @@ -30,9 +30,9 @@ export default function otf2ttfobject(otfBuffer, options) { } // 转换otf轮廓 - otfObject.glyf.forEach(function (g) { + otfObject.glyf.forEach((g) => { g.contours = otfContours2ttfContours(g.contours); - let box = computePathBox.apply(null, g.contours); + const box = computePathBox(...g.contours); if (box) { g.xMin = box.x; g.xMax = box.x + box.width; diff --git a/src/ttf/otfreader.js b/src/ttf/otfreader.js index 3beddc5..49df929 100644 --- a/src/ttf/otfreader.js +++ b/src/ttf/otfreader.js @@ -3,8 +3,6 @@ * @author mengke01(kekee000@gmail.com) */ -/* eslint-disable fecs-use-computed-property */ - import Directory from './table/directory'; import supportTables from './table/support-otf'; import Reader from './reader'; @@ -23,7 +21,7 @@ export default class OTFReader { this.options = options; } - /** + /** * 初始化 * * @param {ArrayBuffer} buffer buffer对象 @@ -31,8 +29,8 @@ export default class OTFReader { */ readBuffer(buffer) { - let reader = new Reader(buffer, 0, buffer.byteLength, false); - let font = {}; + const reader = new Reader(buffer, 0, buffer.byteLength, false); + const font = {}; // version font.version = reader.readString(0, 4); @@ -66,9 +64,9 @@ export default class OTFReader { font.readOptions = this.options; // 读取支持的表数据 - Object.keys(supportTables).forEach(function (tableName) { + Object.keys(supportTables).forEach((tableName) => { if (font.tables[tableName]) { - let offset = font.tables[tableName].offset; + const offset = font.tables[tableName].offset; font[tableName] = new supportTables[tableName](offset).read(reader, font); } }); @@ -89,12 +87,12 @@ export default class OTFReader { */ resolveGlyf(font) { - let codes = font.cmap; + const codes = font.cmap; let glyf = font.CFF.glyf; - let subsetMap = font.readOptions.subset ? font.subsetMap : null; // 当前ttf的子集列表 + const subsetMap = font.readOptions.subset ? font.subsetMap : null; // 当前ttf的子集列表 // unicode - Object.keys(codes).forEach(function (c) { - let i = codes[c]; + Object.keys(codes).forEach((c) => { + const i = codes[c]; if (subsetMap && !subsetMap[i]) { return; } @@ -105,7 +103,7 @@ export default class OTFReader { }); // leftSideBearing - font.hmtx.forEach(function (item, i) { + font.hmtx.forEach((item, i) => { if (subsetMap && !subsetMap[i]) { return; } @@ -115,8 +113,8 @@ export default class OTFReader { // 设置了subsetMap之后需要选取subset中的字形 if (subsetMap) { - let subGlyf = []; - Object.keys(subsetMap).forEach(function (i) { + const subGlyf = []; + Object.keys(subsetMap).forEach((i) => { subGlyf.push(glyf[+i]); }); glyf = subGlyf; @@ -139,7 +137,7 @@ export default class OTFReader { delete font.subsetMap; // 删除无用的表 - let cff = font.CFF; + const cff = font.CFF; delete cff.glyf; delete cff.charset; delete cff.encoding; diff --git a/src/ttf/reader.js b/src/ttf/reader.js index acb9c3b..5ff4f4f 100644 --- a/src/ttf/reader.js +++ b/src/ttf/reader.js @@ -40,7 +40,7 @@ export default class Reader { */ constructor(buffer, offset, length, littleEndian) { - let bufferLength = buffer.byteLength || buffer.length; + const bufferLength = buffer.byteLength || buffer.length; this.offset = offset || 0; this.length = length || (bufferLength - this.offset); @@ -74,7 +74,7 @@ export default class Reader { return this['read' + type](offset, littleEndian); } - let size = dataType[type]; + const size = dataType[type]; this.offset = offset + size; return this.view['get' + type](offset, littleEndian); } @@ -97,7 +97,7 @@ export default class Reader { error.raise(10001, this.length, offset + length); } - let buffer = []; + const buffer = []; for (let i = 0; i < length; ++i) { buffer.push(this.view.getUint8(offset + i)); } @@ -126,7 +126,7 @@ export default class Reader { let value = ''; for (let i = 0; i < length; ++i) { - let c = this.readUint8(offset + i); + const c = this.readUint8(offset + i); value += String.fromCharCode(c); } @@ -152,7 +152,7 @@ export default class Reader { * @return {number} */ readUint24(offset) { - let [i, j, k] = this.readBytes(offset || this.offset, 3); + const [i, j, k] = this.readBytes(offset || this.offset, 3); return (i << 16) + (j << 8) + k; } @@ -166,7 +166,7 @@ export default class Reader { if (undefined === offset) { offset = this.offset; } - let val = this.readInt32(offset, false) / 65536.0; + const val = this.readInt32(offset, false) / 65536.0; return Math.ceil(val * 100000) / 100000; } @@ -182,9 +182,9 @@ export default class Reader { } // new Date(1970, 1, 1).getTime() - new Date(1904, 1, 1).getTime(); - let delta = -2077545600000; - let time = this.readUint32(offset + 4, false); - let date = new Date(); + const delta = -2077545600000; + const time = this.readUint32(offset + 4, false); + const date = new Date(); date.setTime(time * 1000 + delta); return date; } @@ -218,6 +218,6 @@ export default class Reader { } // 直接支持的数据类型 -Object.keys(dataType).forEach(function (type) { +Object.keys(dataType).forEach((type) => { Reader.prototype['read' + type] = curry(Reader.prototype.read, type); }); diff --git a/src/ttf/svg/contoursTransform.js b/src/ttf/svg/contoursTransform.js index 6706f16..232bfcf 100644 --- a/src/ttf/svg/contoursTransform.js +++ b/src/ttf/svg/contoursTransform.js @@ -25,47 +25,48 @@ export default function contoursTransform(contours, transforms) { let matrix = [1, 0, 0, 1, 0, 0]; for (let i = 0, l = transforms.length; i < l; i++) { - let transform = transforms[i]; - let params = transform.params; + const transform = transforms[i]; + const params = transform.params; + let radian = null; switch (transform.name) { - case 'translate': - matrix = mul(matrix, [1, 0, 0, 1, params[0], params[1]]); - break; - case 'scale': - matrix = mul(matrix, [params[0], 0, 0, params[1], 0, 0]); - break; - case 'matrix': - matrix = mul(matrix, - [params[0], params[1], params[2], params[3], params[4], params[5]]); - break; - case 'rotate': - let radian = params[0] * Math.PI / 180; - if (params.length > 1) { + case 'translate': + matrix = mul(matrix, [1, 0, 0, 1, params[0], params[1]]); + break; + case 'scale': + matrix = mul(matrix, [params[0], 0, 0, params[1], 0, 0]); + break; + case 'matrix': + matrix = mul(matrix, + [params[0], params[1], params[2], params[3], params[4], params[5]]); + break; + case 'rotate': + radian = params[0] * Math.PI / 180; + if (params.length > 1) { - matrix = multiply( - matrix, - [1, 0, 0, 1, -params[1], -params[2]], - [Math.cos(radian), Math.sin(radian), -Math.sin(radian), Math.cos(radian), 0, 0], - [1, 0, 0, 1, params[1], params[2]] - ); - } - else { - matrix = mul( - matrix, [Math.cos(radian), Math.sin(radian), -Math.sin(radian), Math.cos(radian), 0, 0]); - } - break; - case 'skewX': - matrix = mul(matrix, - [1, 0, Math.tan(params[0] * Math.PI / 180), 1, 0, 0]); - break; - case 'skewY': - matrix = mul(matrix, - [1, Math.tan(params[0] * Math.PI / 180), 0, 1, 0, 0]); - break; + matrix = multiply( + matrix, + [1, 0, 0, 1, -params[1], -params[2]], + [Math.cos(radian), Math.sin(radian), -Math.sin(radian), Math.cos(radian), 0, 0], + [1, 0, 0, 1, params[1], params[2]] + ); + } + else { + matrix = mul( + matrix, [Math.cos(radian), Math.sin(radian), -Math.sin(radian), Math.cos(radian), 0, 0]); + } + break; + case 'skewX': + matrix = mul(matrix, + [1, 0, Math.tan(params[0] * Math.PI / 180), 1, 0, 0]); + break; + case 'skewY': + matrix = mul(matrix, + [1, Math.tan(params[0] * Math.PI / 180), 0, 1, 0, 0]); + break; } } - contours.forEach(function (p) { + contours.forEach(p => { pathTransform(p, matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]); }); diff --git a/src/ttf/svg/oval2contour.js b/src/ttf/svg/oval2contour.js index 9a25d55..cec8039 100644 --- a/src/ttf/svg/oval2contour.js +++ b/src/ttf/svg/oval2contour.js @@ -23,12 +23,12 @@ export default function oval2contour(cx, cy, rx, ry) { ry = rx; } - let bound = computePath(circlePath); - let scaleX = (+rx) * 2 / bound.width; - let scaleY = (+ry) * 2 / bound.height; - let centerX = bound.width * scaleX / 2; - let centerY = bound.height * scaleY / 2; - let contour = clone(circlePath); + const bound = computePath(circlePath); + const scaleX = (+rx) * 2 / bound.width; + const scaleY = (+ry) * 2 / bound.height; + const centerX = bound.width * scaleX / 2; + const centerY = bound.height * scaleY / 2; + const contour = clone(circlePath); pathAdjust(contour, scaleX, scaleY); pathAdjust(contour, 1, 1, +cx - centerX, +cy - centerY); diff --git a/src/ttf/svg/parseParams.js b/src/ttf/svg/parseParams.js index 41c5c2f..d101e00 100644 --- a/src/ttf/svg/parseParams.js +++ b/src/ttf/svg/parseParams.js @@ -25,6 +25,6 @@ export default function (str) { if (!str) { return []; } - let matchs = str.match(SEGMENT_REGEX); + const matchs = str.match(SEGMENT_REGEX); return matchs ? matchs.map(getSegment) : []; } diff --git a/src/ttf/svg/parseTransform.js b/src/ttf/svg/parseTransform.js index 89b8c37..11e8fb2 100644 --- a/src/ttf/svg/parseTransform.js +++ b/src/ttf/svg/parseTransform.js @@ -25,10 +25,10 @@ export default function parseTransform(str) { } TRANSFORM_REGEX.lastIndex = 0; - let transforms = []; + const transforms = []; let match; - while (match = TRANSFORM_REGEX.exec(str)) { + while ((match = TRANSFORM_REGEX.exec(str))) { transforms.push({ name: match[1], params: parseParams(match[2]) diff --git a/src/ttf/svg/path2contours.js b/src/ttf/svg/path2contours.js index 6be3dc5..c084fc3 100644 --- a/src/ttf/svg/path2contours.js +++ b/src/ttf/svg/path2contours.js @@ -18,10 +18,10 @@ function cubic2Points(cubicList, contour) { let i; let l; - let q2List = []; + const q2List = []; - cubicList.forEach(function (c) { - let list = bezierCubic2Q2(c[0], c[1], c[2], c[3]); + cubicList.forEach(c => { + const list = bezierCubic2Q2(c[0], c[1], c[2], c[3]); for (i = 0, l = list.length; i < l; i++) { q2List.push(list[i]); } @@ -82,7 +82,7 @@ function cubic2Points(cubicList, contour) { function segments2Contours(segments) { // 解析segments - let contours = []; + const contours = []; let contour = []; let prevX = 0; let prevY = 0; @@ -431,7 +431,7 @@ function segments2Contours(segments) { ey = prevY + ey; } - let path = getArc( + const path = getArc( args[q], args[q + 1], args[q + 2], args[q + 3], args[q + 4], {x: prevX, y: prevY}, @@ -475,49 +475,50 @@ export default function path2contours(path) { path = path.replace(/(\d+)\s*(m|$)/gi, '$1z$2'); // 获取segments - let segments = []; + const segments = []; let cmd; let relative = false; let lastIndex; let args; for (let i = 0, l = path.length; i < l; i++) { - let c = path[i].toUpperCase(); - let r = c !== path[i]; + const c = path[i].toUpperCase(); + const r = c !== path[i]; switch (c) { - case 'M': - /* jshint -W086 */ - if (i === 0) { - cmd = c; - lastIndex = 1; - break; - } - case 'Q': - case 'T': - case 'C': - case 'S': - case 'H': - case 'V': - case 'L': - case 'A': - case 'Z': - if (cmd === 'Z') { - segments.push({cmd: 'Z'}); - } - else { - args = path.slice(lastIndex, i); - segments.push({ - cmd: cmd, - relative: relative, - args: parseParams(args) - }); - } - + case 'M': + /* jshint -W086 */ + if (i === 0) { cmd = c; - relative = r; - lastIndex = i + 1; + lastIndex = 1; break; + } + // eslint-disable-next-line no-fallthrough + case 'Q': + case 'T': + case 'C': + case 'S': + case 'H': + case 'V': + case 'L': + case 'A': + case 'Z': + if (cmd === 'Z') { + segments.push({cmd: 'Z'}); + } + else { + args = path.slice(lastIndex, i); + segments.push({ + cmd, + relative, + args: parseParams(args) + }); + } + + cmd = c; + relative = r; + lastIndex = i + 1; + break; } } diff --git a/src/ttf/svg/polygon2contour.js b/src/ttf/svg/polygon2contour.js index db45918..1882388 100644 --- a/src/ttf/svg/polygon2contour.js +++ b/src/ttf/svg/polygon2contour.js @@ -17,8 +17,8 @@ export default function polygon2contour(points) { return null; } - let contours = []; - let segments = parseParams(points); + const contours = []; + const segments = parseParams(points); for (let i = 0, l = segments.length; i < l; i += 2) { contours.push({ x: segments[i], diff --git a/src/ttf/svg/rect2contour.js b/src/ttf/svg/rect2contour.js index 811b7a1..00a72be 100644 --- a/src/ttf/svg/rect2contour.js +++ b/src/ttf/svg/rect2contour.js @@ -20,13 +20,13 @@ export default function rect2contour(x, y, width, height) { return [ { - x: x, - y: y, + x, + y, onCurve: true }, { x: x + width, - y: y, + y, onCurve: true }, { @@ -35,7 +35,7 @@ export default function rect2contour(x, y, width, height) { onCurve: true }, { - x: x, + x, y: y + height, onCurve: true } diff --git a/src/ttf/svg/svgnode2contours.js b/src/ttf/svg/svgnode2contours.js index c5cf4c9..17614dc 100644 --- a/src/ttf/svg/svgnode2contours.js +++ b/src/ttf/svg/svgnode2contours.js @@ -57,30 +57,30 @@ export default function svgnode2contours(xmlNodes) { let j; let jlength; let segment; // 当前指令 - let parsedSegments = []; // 解析后的指令 + const parsedSegments = []; // 解析后的指令 if (xmlNodes.length) { for (i = 0, length = xmlNodes.length; i < length; i++) { - let node = xmlNodes[i]; - let name = node.tagName; + const node = xmlNodes[i]; + const name = node.tagName; if (support[name]) { - let supportParams = support[name].params; - let params = []; + const supportParams = support[name].params; + const params = []; for (j = 0, jlength = supportParams.length; j < jlength; j++) { params.push(node.getAttribute(supportParams[j])); } segment = { - name: name, - params: params, + name, + params, transform: parseTransform(node.getAttribute('transform')) }; if (node.parentNode) { let curNode = node.parentNode; - let transforms = segment.transform || []; + const transforms = segment.transform || []; let transAttr; - let iterator = function (t) { + const iterator = function (t) { transforms.unshift(t); }; while (curNode !== null && curNode.tagName !== 'svg') { @@ -99,11 +99,11 @@ export default function svgnode2contours(xmlNodes) { } if (parsedSegments.length) { - let result = []; + const result = []; for (i = 0, length = parsedSegments.length; i < length; i++) { segment = parsedSegments[i]; - let parser = support[segment.name]; - let contour = parser.parse.apply(null, segment.params); + const parser = support[segment.name]; + const contour = parser.parse.apply(null, segment.params); if (contour && contour.length) { let contours = parser.contours ? contour : [contour]; diff --git a/src/ttf/svg2ttfobject.js b/src/ttf/svg2ttfobject.js index 57aa742..8924751 100644 --- a/src/ttf/svg2ttfobject.js +++ b/src/ttf/svg2ttfobject.js @@ -23,8 +23,8 @@ import reduceGlyf from './util/reduceGlyf'; function loadXML(xml) { if (DOMParser) { try { - let domParser = new DOMParser(); - let xmlDoc = domParser.parseFromString(xml, 'text/xml'); + const domParser = new DOMParser(); + const xmlDoc = domParser.parseFromString(xml, 'text/xml'); return xmlDoc; } catch (exp) { @@ -42,8 +42,8 @@ function loadXML(xml) { */ function resolveSVG(svg) { // 去除xmlns,防止xmlns导致svg解析错误 - svg = svg.replace(/\s+xmlns(?:\:[\w-]+)?=("|')[^"']*\1/g, ' ') - .replace(/\s][\s\S]+?\/defs>/g, function (text) { + svg = svg.replace(/\s+xmlns(?::[\w-]+)?=("|')[^"']*\1/g, ' ') + .replace(/\s][\s\S]+?\/defs>/g, (text) => { if (text.indexOf('') >= 0) { return text; } @@ -59,7 +59,7 @@ function resolveSVG(svg) { * @return {Object} ttfObject对象 */ function getEmptyTTF() { - let ttf = getEmptyttfObject(); + const ttf = getEmptyttfObject(); ttf.head.unitsPerEm = 0; // 去除unitsPerEm以便于重新计算 ttf.from = 'svgfont'; return ttf; @@ -92,7 +92,7 @@ function getEmptyObject() { * @return {number} */ function getUnitsPerEm(xMin, xMax, yMin, yMax) { - let seed = Math.ceil(Math.min(yMax - yMin, xMax - xMin)); + const seed = Math.ceil(Math.min(yMax - yMin, xMax - xMin)); if (!seed) { return 1024; @@ -110,7 +110,7 @@ function getUnitsPerEm(xMin, xMax, yMin, yMax) { return unitsPerEm; } - unitsPerEm = unitsPerEm << 1; + unitsPerEm <<= 1; } return 1024; @@ -128,7 +128,7 @@ function resolve(ttf) { // 如果是svg格式字体,则去小数 // 由于svg格式导入时候会出现字形重复问题,这里进行优化 if (ttf.from === 'svgfont' && ttf.head.unitsPerEm > 128) { - ttf.glyf.forEach(function (g) { + ttf.glyf.forEach((g) => { if (g.contours) { glyfAdjust(g); reduceGlyf(g); @@ -142,9 +142,9 @@ function resolve(ttf) { let yMin = 16384; let yMax = -16384; - ttf.glyf.forEach(function (g) { + ttf.glyf.forEach((g) => { if (g.contours) { - let bound = computePathBox.apply(null, g.contours); + const bound = computePathBox(...g.contours); if (bound) { xMin = Math.min(xMin, bound.x); xMax = Math.max(xMax, bound.x + bound.width); @@ -154,10 +154,10 @@ function resolve(ttf) { } }); - let unitsPerEm = getUnitsPerEm(xMin, xMax, yMin, yMax); - let scale = 1024 / unitsPerEm; + const unitsPerEm = getUnitsPerEm(xMin, xMax, yMin, yMax); + const scale = 1024 / unitsPerEm; - ttf.glyf.forEach(function (g) { + ttf.glyf.forEach((g) => { glyfAdjust(g, scale, scale); reduceGlyf(g); }); @@ -176,9 +176,9 @@ function resolve(ttf) { */ function parseFont(xmlDoc, ttf) { - let metaNode = xmlDoc.getElementsByTagName('metadata')[0]; - let fontNode = xmlDoc.getElementsByTagName('font')[0]; - let fontFaceNode = xmlDoc.getElementsByTagName('font-face')[0]; + const metaNode = xmlDoc.getElementsByTagName('metadata')[0]; + const fontNode = xmlDoc.getElementsByTagName('font')[0]; + const fontFaceNode = xmlDoc.getElementsByTagName('font-face')[0]; if (metaNode && metaNode.textContent) { ttf.metadata = string.decodeHTML(metaNode.textContent.trim()); @@ -192,17 +192,17 @@ function parseFont(xmlDoc, ttf) { } if (fontFaceNode) { - let OS2 = ttf['OS/2']; + const OS2 = ttf['OS/2']; ttf.name.fontFamily = fontFaceNode.getAttribute('font-family') || ''; OS2.usWeightClass = +(fontFaceNode.getAttribute('font-weight') || 0); ttf.head.unitsPerEm = +(fontFaceNode.getAttribute('units-per-em') || 0); // 解析panose, eg: 2 0 6 3 0 0 0 0 0 0 - let panose = (fontFaceNode.getAttribute('panose-1') || '').split(' '); + const panose = (fontFaceNode.getAttribute('panose-1') || '').split(' '); [ 'bFamilyType', 'bSerifStyle', 'bWeight', 'bProportion', 'bContrast', 'bStrokeVariation', 'bArmStyle', 'bLetterform', 'bMidline', 'bXHeight' - ].forEach(function (name, i) { + ].forEach((name, i) => { OS2[name] = +(panose[i] || 0); }); @@ -211,8 +211,8 @@ function parseFont(xmlDoc, ttf) { OS2.bXHeight = +(fontFaceNode.getAttribute('x-height') || 0); // 解析bounding - let box = (fontFaceNode.getAttribute('bbox') || '').split(' '); - ['xMin', 'yMin', 'xMax', 'yMax'].forEach(function (name, i) { + const box = (fontFaceNode.getAttribute('bbox') || '').split(' '); + ['xMin', 'yMin', 'xMax', 'yMax'].forEach((name, i) => { ttf.head[name] = +(box[i] || ''); }); @@ -220,9 +220,9 @@ function parseFont(xmlDoc, ttf) { ttf.post.underlinePosition = +(fontFaceNode.getAttribute('underline-position') || 0); // unicode range - let unicodeRange = fontFaceNode.getAttribute('unicode-range'); + const unicodeRange = fontFaceNode.getAttribute('unicode-range'); if (unicodeRange) { - unicodeRange.replace(/u\+([0-9A-Z]+)(\-[0-9A-Z]+)?/i, function ($0, a, b) { + unicodeRange.replace(/u\+([0-9A-Z]+)(-[0-9A-Z]+)?/i, ($0, a, b) => { OS2.usFirstCharIndex = Number('0x' + a); OS2.usLastCharIndex = b ? Number('0x' + b.slice(1)) : 0xFFFFFFFF; }); @@ -241,14 +241,14 @@ function parseFont(xmlDoc, ttf) { */ function parseGlyf(xmlDoc, ttf) { - let missingNode = xmlDoc.getElementsByTagName('missing-glyph')[0]; + const missingNode = xmlDoc.getElementsByTagName('missing-glyph')[0]; // 解析glyf let d; let unicode; if (missingNode) { - let missing = { + const missing = { name: '.notdef' }; @@ -268,15 +268,15 @@ function parseGlyf(xmlDoc, ttf) { ttf.glyf.unshift(missing); } - let glyfNodes = xmlDoc.getElementsByTagName('glyph'); + const glyfNodes = xmlDoc.getElementsByTagName('glyph'); if (glyfNodes.length) { for (let i = 0, l = glyfNodes.length; i < l; i++) { - let node = glyfNodes[i]; - let glyf = { + const node = glyfNodes[i]; + const glyf = { name: node.getAttribute('glyph-name') || node.getAttribute('name') || '' }; @@ -285,23 +285,22 @@ function parseGlyf(xmlDoc, ttf) { } if ((unicode = node.getAttribute('unicode'))) { - let nextUnicode = [] - let nextIndex =0; + const nextUnicode = []; let totalCodePoints = 0; - let dupe = false - for(let ui=0; ui < unicode.length; ui++) { - let ucp = unicode.codePointAt(ui) - nextUnicode.push(ucp) - ui = ucp > 0xffff ? ui +1 : ui - totalCodePoints = totalCodePoints + 1; + for (let ui = 0; ui < unicode.length; ui++) { + const ucp = unicode.codePointAt(ui); + nextUnicode.push(ucp); + ui = ucp > 0xffff ? ui + 1 : ui; + totalCodePoints += 1; } - if(totalCodePoints == 1) { //TTF can't handle ligatures - glyf.unicode = nextUnicode + if (totalCodePoints === 1) { + // TTF can't handle ligatures + glyf.unicode = nextUnicode; - if ((d = node.getAttribute('d'))) { - glyf.contours = path2contours(d); - } - ttf.glyf.push(glyf); + if ((d = node.getAttribute('d'))) { + glyf.contours = path2contours(d); + } + ttf.glyf.push(glyf); } } @@ -325,7 +324,7 @@ function parsePath(xmlDoc, ttf) { let contours; let glyf; let node; - let pathNodes = xmlDoc.getElementsByTagName('path'); + const pathNodes = xmlDoc.getElementsByTagName('path'); if (pathNodes.length) { for (let i = 0, l = pathNodes.length; i < l; i++) { @@ -341,9 +340,7 @@ function parsePath(xmlDoc, ttf) { // 其他svg指令组成一个glyf字形 contours = svgnode2contours( - Array.prototype.slice.call(xmlDoc.getElementsByTagName('*')).filter(function (node) { - return node.tagName !== 'path'; - }) + Array.prototype.slice.call(xmlDoc.getElementsByTagName('*')).filter((node) => node.tagName !== 'path') ); if (contours) { glyf = { @@ -387,14 +384,14 @@ function parseXML(xmlDoc, options) { } if (ttf.from === 'svg') { - let glyf = ttf.glyf; + const glyf = ttf.glyf; let i; let l; // 合并导入的字形为单个字形 if (options.combinePath) { - let combined = []; + const combined = []; for (i = 0, l = glyf.length; i < l; i++) { - let contours = glyf[i].contours; + const contours = glyf[i].contours; for (let index = 0, length = contours.length; index < length; index++) { combined.push(contours[index]); } @@ -429,6 +426,6 @@ export default function svg2ttfObject(svg, options = {combinePath: false}) { xmlDoc = loadXML(svg); } - let ttf = parseXML(xmlDoc, options); + const ttf = parseXML(xmlDoc, options); return resolve(ttf); } diff --git a/src/ttf/table/CFF.js b/src/ttf/table/CFF.js index 5af87ef..3433ee2 100644 --- a/src/ttf/table/CFF.js +++ b/src/ttf/table/CFF.js @@ -43,7 +43,7 @@ function getOffset(reader, offSize) { * @return {Object} 头部字段 */ function parseCFFHead(reader) { - let head = {}; + const head = {}; head.startOffset = reader.offset; head.endOffset = head.startOffset + 4; head.formatMajor = reader.readUint8(); @@ -65,14 +65,14 @@ function parseCFFIndex(reader, offset, conversionFn) { if (offset) { reader.seek(offset); } - let start = reader.offset; - let offsets = []; - let objects = []; - let count = reader.readUint16(); + const start = reader.offset; + const offsets = []; + const objects = []; + const count = reader.readUint16(); let i; let l; if (count !== 0) { - let offsetSize = reader.readUint8(); + const offsetSize = reader.readUint8(); for (i = 0, l = count + 1; i < l; i++) { offsets.push(getOffset(reader, offsetSize)); } @@ -87,7 +87,7 @@ function parseCFFIndex(reader, offset, conversionFn) { } return { - objects: objects, + objects, startOffset: start, endOffset: reader.offset }; @@ -117,17 +117,17 @@ export default table.create( { read(reader, font) { - let offset = this.offset; + const offset = this.offset; reader.seek(offset); - let head = parseCFFHead(reader); - let nameIndex = parseCFFIndex(reader, head.endOffset, string.getString); - let topDictIndex = parseCFFIndex(reader, nameIndex.endOffset); - let stringIndex = parseCFFIndex(reader, topDictIndex.endOffset, string.getString); - let globalSubrIndex = parseCFFIndex(reader, stringIndex.endOffset); + const head = parseCFFHead(reader); + const nameIndex = parseCFFIndex(reader, head.endOffset, string.getString); + const topDictIndex = parseCFFIndex(reader, nameIndex.endOffset); + const stringIndex = parseCFFIndex(reader, topDictIndex.endOffset, string.getString); + const globalSubrIndex = parseCFFIndex(reader, stringIndex.endOffset); - let cff = { - head: head + const cff = { + head }; // 全局子glyf数据 @@ -135,8 +135,8 @@ export default table.create( cff.gsubrsBias = calcCFFSubroutineBias(globalSubrIndex.objects); // 顶级字典数据 - let dictReader = new Reader(new Uint8Array(topDictIndex.objects[0]).buffer); - let topDict = parseCFFDict.parseTopDict( + const dictReader = new Reader(new Uint8Array(topDictIndex.objects[0]).buffer); + const topDict = parseCFFDict.parseTopDict( dictReader, 0, dictReader.length, @@ -145,7 +145,7 @@ export default table.create( cff.topDict = topDict; // 私有字典数据 - let privateDictLength = topDict.private[0]; + const privateDictLength = topDict.private[0]; let privateDict = {}; let privateDictOffset; if (privateDictLength) { @@ -166,8 +166,8 @@ export default table.create( // 私有子glyf数据 if (privateDict.subrs) { - let subrOffset = privateDictOffset + privateDict.subrs; - let subrIndex = parseCFFIndex(reader, subrOffset); + const subrOffset = privateDictOffset + privateDict.subrs; + const subrIndex = parseCFFIndex(reader, subrOffset); cff.subrs = subrIndex.objects; cff.subrsBias = calcCFFSubroutineBias(cff.subrs); } @@ -178,20 +178,20 @@ export default table.create( cff.privateDict = privateDict; // 解析glyf数据和名字 - let charStringsIndex = parseCFFIndex(reader, offset + topDict.charStrings); - let nGlyphs = charStringsIndex.objects.length; + const charStringsIndex = parseCFFIndex(reader, offset + topDict.charStrings); + const nGlyphs = charStringsIndex.objects.length; if (topDict.charset < 3) { - /*@author: fr33z00 - See end of chapter 13 (p22) of #5176.CFF.pdf : - Still more optimization is possible by - observing that many fonts adopt one of 3 common charsets. In - these cases the operand to the charset operator in the Top DICT - specifies a predefined charset id, in place of an offset, as shown in table 22*/ - cff.charset = cffStandardStrings; + // @author: fr33z00 + // See end of chapter 13 (p22) of #5176.CFF.pdf : + // Still more optimization is possible by + // observing that many fonts adopt one of 3 common charsets. In + // these cases the operand to the charset operator in the Top DICT + // specifies a predefined charset id, in place of an offset, as shown in table 22 + cff.charset = cffStandardStrings; } else { - cff.charset = parseCFFCharset(reader, offset + topDict.charset, nGlyphs, stringIndex.objects); + cff.charset = parseCFFCharset(reader, offset + topDict.charset, nGlyphs, stringIndex.objects); } // Standard encoding @@ -209,27 +209,27 @@ export default table.create( cff.glyf = []; // only parse subset glyphs - let subset = font.readOptions.subset; + const subset = font.readOptions.subset; if (subset && subset.length > 0) { // subset map - let subsetMap = { + const subsetMap = { 0: true // 设置.notdef }; - let codes = font.cmap; + const codes = font.cmap; // unicode to index - Object.keys(codes).forEach(function (c) { + Object.keys(codes).forEach((c) => { if (subset.indexOf(+c) > -1) { - let i = codes[c]; + const i = codes[c]; subsetMap[i] = true; } }); font.subsetMap = subsetMap; - Object.keys(subsetMap).forEach(function (i) { + Object.keys(subsetMap).forEach((i) => { i = +i; - let glyf = parseCFFGlyph(charStringsIndex.objects[i], cff, i); + const glyf = parseCFFGlyph(charStringsIndex.objects[i], cff, i); glyf.name = cff.charset[i]; cff.glyf[i] = glyf; }); @@ -237,7 +237,7 @@ export default table.create( // parse all else { for (let i = 0, l = nGlyphs; i < l; i++) { - let glyf = parseCFFGlyph(charStringsIndex.objects[i], cff, i); + const glyf = parseCFFGlyph(charStringsIndex.objects[i], cff, i); glyf.name = cff.charset[i]; cff.glyf.push(glyf); } @@ -246,10 +246,12 @@ export default table.create( return cff; }, + // eslint-disable-next-line no-unused-vars write(writer, font) { throw new Error('not support write cff table'); }, + // eslint-disable-next-line no-unused-vars size(font) { throw new Error('not support get cff table size'); } diff --git a/src/ttf/table/GPOS.js b/src/ttf/table/GPOS.js index f684c61..9f7ad4c 100644 --- a/src/ttf/table/GPOS.js +++ b/src/ttf/table/GPOS.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.GPOS.length; + const length = ttf.tables.GPOS.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/OS2.js b/src/ttf/table/OS2.js index e321651..4931daf 100644 --- a/src/ttf/table/OS2.js +++ b/src/ttf/table/OS2.js @@ -82,7 +82,7 @@ export default table.create( { read(reader, ttf) { - let format = reader.readUint16(this.offset); + const format = reader.readUint16(this.offset); let struct = this.struct; // format2 @@ -93,11 +93,11 @@ export default table.create( struct = struct.slice(0, 41); } - let OS2Head = table.create('os2head', struct); - let tbl = new OS2Head(this.offset).read(reader, ttf); + const OS2Head = table.create('os2head', struct); + const tbl = new OS2Head(this.offset).read(reader, ttf); // 补齐其他version的字段 - let os2Fields = { + const os2Fields = { ulCodePageRange1: 1, ulCodePageRange2: 0, sxHeight: 0, @@ -139,7 +139,7 @@ export default table.create( let maxComponentElements = 0; let glyfNotEmpty = 0; // 非空glyf - let hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; + const hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; // 计算instructions和functiondefs if (hinting) { @@ -159,20 +159,20 @@ export default table.create( } - ttf.glyf.forEach(function (glyf, index) { + ttf.glyf.forEach((glyf) => { // 统计control point信息 if (glyf.compound) { let compositeContours = 0; let compositePoints = 0; - glyf.glyfs.forEach(function (g) { - let cglyf = ttf.glyf[g.glyphIndex]; + glyf.glyfs.forEach((g) => { + const cglyf = ttf.glyf[g.glyphIndex]; if (!cglyf) { return; } compositeContours += cglyf.contours ? cglyf.contours.length : 0; if (cglyf.contours && cglyf.contours.length) { - cglyf.contours.forEach(function (contour) { + cglyf.contours.forEach((contour) => { compositePoints += contour.length; }); } @@ -187,7 +187,7 @@ export default table.create( maxContours = Math.max(maxContours, glyf.contours.length); let points = 0; - glyf.contours.forEach(function (contour) { + glyf.contours.forEach((contour) => { points += contour.length; }); maxPoints = Math.max(maxPoints, points); @@ -230,7 +230,7 @@ export default table.create( } if (Array.isArray(unicodes)) { - unicodes.forEach(function (unicode) { + unicodes.forEach((unicode) => { if (unicode !== 0xFFFF) { usFirstCharIndex = Math.min(usFirstCharIndex, unicode); usLastCharIndex = Math.max(usLastCharIndex, unicode); @@ -264,7 +264,7 @@ export default table.create( // head rewrite if (ttf.support.head) { - let {xMin, yMin, xMax, yMax} = ttf.support.head; + const {xMin, yMin, xMax, yMax} = ttf.support.head; if (xMin != null) { ttf.head.xMin = xMin; } @@ -281,7 +281,7 @@ export default table.create( } // hhea rewrite if (ttf.support.hhea) { - let {advanceWidthMax, xMaxExtent, minLeftSideBearing, minRightSideBearing} = ttf.support.hhea; + const {advanceWidthMax, xMaxExtent, minLeftSideBearing, minRightSideBearing} = ttf.support.hhea; if (advanceWidthMax != null) { ttf.hhea.advanceWidthMax = advanceWidthMax; } @@ -300,17 +300,17 @@ export default table.create( ttf.support.maxp = { version: 1.0, numGlyphs: ttf.glyf.length, - maxPoints: maxPoints, - maxContours: maxContours, - maxCompositePoints: maxCompositePoints, - maxCompositeContours: maxCompositeContours, + maxPoints, + maxContours, + maxCompositePoints, + maxCompositeContours, maxZones: ttf.maxp.maxZones || 0, maxTwilightPoints: ttf.maxp.maxTwilightPoints || 0, maxStorage: ttf.maxp.maxStorage || 0, maxFunctionDefs: ttf.maxp.maxFunctionDefs || 0, maxStackElements: ttf.maxp.maxStackElements || 0, - maxSizeOfInstructions: maxSizeOfInstructions, - maxComponentElements: maxComponentElements, + maxSizeOfInstructions, + maxComponentElements, maxComponentDepth: maxComponentElements ? 1 : 0 }; diff --git a/src/ttf/table/cff/cffStandardStrings.js b/src/ttf/table/cff/cffStandardStrings.js index a6d20bd..a76c716 100644 --- a/src/ttf/table/cff/cffStandardStrings.js +++ b/src/ttf/table/cff/cffStandardStrings.js @@ -1,3 +1,7 @@ +/** + * @file cffStandardStrings.js + * @author mengke01(kekee000@gmail.com) + */ const cffStandardStrings = [ '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', diff --git a/src/ttf/table/cff/parseCFFCharset.js b/src/ttf/table/cff/parseCFFCharset.js index c5e47a3..1ff8a6d 100644 --- a/src/ttf/table/cff/parseCFFCharset.js +++ b/src/ttf/table/cff/parseCFFCharset.js @@ -25,9 +25,9 @@ export default function parseCFFCharset(reader, start, nGlyphs, strings) { let count; // The .notdef glyph is not included, so subtract 1. nGlyphs -= 1; - let charset = ['.notdef']; + const charset = ['.notdef']; - let format = reader.readUint8(); + const format = reader.readUint8(); if (format === 0) { for (i = 0; i < nGlyphs; i += 1) { sid = reader.readUint16(); diff --git a/src/ttf/table/cff/parseCFFDict.js b/src/ttf/table/cff/parseCFFDict.js index b64d47e..98f076b 100644 --- a/src/ttf/table/cff/parseCFFDict.js +++ b/src/ttf/table/cff/parseCFFDict.js @@ -149,16 +149,16 @@ const PRIVATE_DICT_META = [ ]; function entriesToObject(entries) { - let hash = {}; + const hash = {}; for (let i = 0, l = entries.length; i < l; i++) { - let key = entries[i][0]; + const key = entries[i][0]; if (undefined !== hash[key]) { console.warn('dict already has key:' + key); continue; } - let values = entries[i][1]; + const values = entries[i][1]; hash[key] = values.length === 1 ? values[0] : values; } @@ -169,13 +169,13 @@ function entriesToObject(entries) { /* eslint-disable no-constant-condition */ function parseFloatOperand(reader) { let s = ''; - let eof = 15; - let lookup = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'E', 'E-', null, '-']; + const eof = 15; + const lookup = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'E', 'E-', null, '-']; while (true) { - let b = reader.readUint8(); - let n1 = b >> 4; - let n2 = b & 15; + const b = reader.readUint8(); + const n1 = b >> 4; + const n2 = b & 15; if (n1 === eof) { break; @@ -252,12 +252,12 @@ function parseOperand(reader, b0) { * @return {Object} 解析后数据 */ function interpretDict(dict, meta, strings) { - let newDict = {}; + const newDict = {}; // Because we also want to include missing values, we start out from the meta list // and lookup values in the dict. for (let i = 0, l = meta.length; i < l; i++) { - let m = meta[i]; + const m = meta[i]; let value = dict[m.op]; if (value === undefined) { value = m.value !== undefined ? m.value : null; @@ -287,9 +287,9 @@ function parseCFFDict(reader, offset, length) { reader.seek(offset); } - let entries = []; + const entries = []; let operands = []; - let lastOffset = reader.offset + (null != length ? length : reader.length); + const lastOffset = reader.offset + (null != length ? length : reader.length); while (reader.offset < lastOffset) { let op = reader.readUint8(); @@ -325,7 +325,7 @@ function parseCFFDict(reader, offset, length) { * @return {Object} 字典数据 */ function parseTopDict(reader, start, length, strings) { - let dict = parseCFFDict(reader, start || 0, length || reader.length); + const dict = parseCFFDict(reader, start || 0, length || reader.length); return interpretDict(dict, TOP_DICT_META, strings); } @@ -339,7 +339,7 @@ function parseTopDict(reader, start, length, strings) { * @return {Object} 字典数据 */ function parsePrivateDict(reader, start, length, strings) { - let dict = parseCFFDict(reader, start || 0, length || reader.length); + const dict = parseCFFDict(reader, start || 0, length || reader.length); return interpretDict(dict, PRIVATE_DICT_META, strings); } diff --git a/src/ttf/table/cff/parseCFFEncoding.js b/src/ttf/table/cff/parseCFFEncoding.js index 97384f2..e714ae2 100644 --- a/src/ttf/table/cff/parseCFFEncoding.js +++ b/src/ttf/table/cff/parseCFFEncoding.js @@ -18,22 +18,22 @@ export default function parseCFFEncoding(reader, start) { let i; let code; - let encoding = {}; - let format = reader.readUint8(); + const encoding = {}; + const format = reader.readUint8(); if (format === 0) { - let nCodes = reader.readUint8(); + const nCodes = reader.readUint8(); for (i = 0; i < nCodes; i += 1) { code = reader.readUint8(); encoding[code] = i; } } else if (format === 1) { - let nRanges = reader.readUint8(); + const nRanges = reader.readUint8(); code = 1; for (i = 0; i < nRanges; i += 1) { - let first = reader.readUint8(); - let nLeft = reader.readUint8(); + const first = reader.readUint8(); + const nLeft = reader.readUint8(); for (let j = first; j <= first + nLeft; j += 1) { encoding[j] = code; code += 1; diff --git a/src/ttf/table/cff/parseCFFGlyph.js b/src/ttf/table/cff/parseCFFGlyph.js index d98ffba..6c6534e 100644 --- a/src/ttf/table/cff/parseCFFGlyph.js +++ b/src/ttf/table/cff/parseCFFGlyph.js @@ -16,10 +16,10 @@ export default function parseCFFCharstring(code, font, index) { let c1y; let c2x; let c2y; - let contours = []; + const contours = []; let contour = []; - let stack = []; - let glyfs = []; + const stack = []; + const glyfs = []; let nStems = 0; let haveWidth = false; let width = font.defaultWidthX; @@ -30,8 +30,8 @@ export default function parseCFFCharstring(code, font, index) { function lineTo(x, y) { contour.push({ onCurve: true, - x: x, - y: y + x, + y }); } @@ -46,8 +46,8 @@ export default function parseCFFCharstring(code, font, index) { }); contour.push({ onCurve: true, - x: x, - y: y + x, + y }); } @@ -62,10 +62,9 @@ export default function parseCFFCharstring(code, font, index) { } function parseStems() { - let hasWidthArg; // The number of stem operators on the stack is always even. // If the value is uneven, that means a width is specified. - hasWidthArg = stack.length % 2 !== 0; + const hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + font.nominalWidthX; } @@ -94,373 +93,386 @@ export default function parseCFFCharstring(code, font, index) { let v = code[i]; i += 1; switch (v) { - case 1: // hstem - parseStems(); - break; - case 3: // vstem - parseStems(); - break; - case 4: // vmoveto - if (stack.length > 1 && !haveWidth) { - width = stack.shift() + font.nominalWidthX; - haveWidth = true; - } + case 1: // hstem + parseStems(); + break; + case 3: // vstem + parseStems(); + break; + case 4: // vmoveto + if (stack.length > 1 && !haveWidth) { + width = stack.shift() + font.nominalWidthX; + haveWidth = true; + } + + y += stack.pop(); + newContour(x, y); + break; + case 5: // rlineto + while (stack.length > 0) { + x += stack.shift(); + y += stack.shift(); + lineTo(x, y); + } - y += stack.pop(); - newContour(x, y); - break; - case 5: // rlineto - while (stack.length > 0) { - x += stack.shift(); - y += stack.shift(); - lineTo(x, y); + break; + case 6: // hlineto + while (stack.length > 0) { + x += stack.shift(); + lineTo(x, y); + if (stack.length === 0) { + break; } - break; - case 6: // hlineto - while (stack.length > 0) { - x += stack.shift(); - lineTo(x, y); - if (stack.length === 0) { - break; - } - - y += stack.shift(); - lineTo(x, y); - } + y += stack.shift(); + lineTo(x, y); + } - break; - case 7: // vlineto - while (stack.length > 0) { - y += stack.shift(); - lineTo(x, y); - if (stack.length === 0) { - break; - } - - x += stack.shift(); - lineTo(x, y); + break; + case 7: // vlineto + while (stack.length > 0) { + y += stack.shift(); + lineTo(x, y); + if (stack.length === 0) { + break; } - break; - case 8: // rrcurveto - while (stack.length > 0) { - c1x = x + stack.shift(); - c1y = y + stack.shift(); - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x + stack.shift(); - y = c2y + stack.shift(); - curveTo(c1x, c1y, c2x, c2y, x, y); - } + x += stack.shift(); + lineTo(x, y); + } + break; + case 8: // rrcurveto + while (stack.length > 0) { + c1x = x + stack.shift(); + c1y = y + stack.shift(); + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y + stack.shift(); + curveTo(c1x, c1y, c2x, c2y, x, y); + } + + break; + case 10: // callsubr + codeIndex = stack.pop() + font.subrsBias; + subrCode = font.subrs[codeIndex]; + if (subrCode) { + parse(subrCode); + } + + break; + case 11: // return + return; + case 12: // flex operators + v = code[i]; + i += 1; + switch (v) { + case 35: // flex + // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |- + c1x = x + stack.shift(); // dx1 + c1y = y + stack.shift(); // dy1 + c2x = c1x + stack.shift(); // dx2 + c2y = c1y + stack.shift(); // dy2 + jpx = c2x + stack.shift(); // dx3 + jpy = c2y + stack.shift(); // dy3 + c3x = jpx + stack.shift(); // dx4 + c3y = jpy + stack.shift(); // dy4 + c4x = c3x + stack.shift(); // dx5 + c4y = c3y + stack.shift(); // dy5 + x = c4x + stack.shift(); // dx6 + y = c4y + stack.shift(); // dy6 + stack.shift(); // flex depth + curveTo(c1x, c1y, c2x, c2y, jpx, jpy); + curveTo(c3x, c3y, c4x, c4y, x, y); break; - case 10: // callsubr - codeIndex = stack.pop() + font.subrsBias; - subrCode = font.subrs[codeIndex]; - if (subrCode) { - parse(subrCode); - } - + case 34: // hflex + // |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |- + c1x = x + stack.shift(); // dx1 + c1y = y; // dy1 + c2x = c1x + stack.shift(); // dx2 + c2y = c1y + stack.shift(); // dy2 + jpx = c2x + stack.shift(); // dx3 + jpy = c2y; // dy3 + c3x = jpx + stack.shift(); // dx4 + c3y = c2y; // dy4 + c4x = c3x + stack.shift(); // dx5 + c4y = y; // dy5 + x = c4x + stack.shift(); // dx6 + curveTo(c1x, c1y, c2x, c2y, jpx, jpy); + curveTo(c3x, c3y, c4x, c4y, x, y); break; - case 11: // return - return; - case 12: // flex operators - v = code[i]; - i += 1; - switch (v) { - case 35: // flex - // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |- - c1x = x + stack.shift(); // dx1 - c1y = y + stack.shift(); // dy1 - c2x = c1x + stack.shift(); // dx2 - c2y = c1y + stack.shift(); // dy2 - jpx = c2x + stack.shift(); // dx3 - jpy = c2y + stack.shift(); // dy3 - c3x = jpx + stack.shift(); // dx4 - c3y = jpy + stack.shift(); // dy4 - c4x = c3x + stack.shift(); // dx5 - c4y = c3y + stack.shift(); // dy5 - x = c4x + stack.shift(); // dx6 - y = c4y + stack.shift(); // dy6 - stack.shift(); // flex depth - curveTo(c1x, c1y, c2x, c2y, jpx, jpy); - curveTo(c3x, c3y, c4x, c4y, x, y); - break; - case 34: // hflex - // |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |- - c1x = x + stack.shift(); // dx1 - c1y = y; // dy1 - c2x = c1x + stack.shift(); // dx2 - c2y = c1y + stack.shift(); // dy2 - jpx = c2x + stack.shift(); // dx3 - jpy = c2y; // dy3 - c3x = jpx + stack.shift(); // dx4 - c3y = c2y; // dy4 - c4x = c3x + stack.shift(); // dx5 - c4y = y; // dy5 - x = c4x + stack.shift(); // dx6 - curveTo(c1x, c1y, c2x, c2y, jpx, jpy); - curveTo(c3x, c3y, c4x, c4y, x, y); - break; - case 36: // hflex1 - // |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |- - c1x = x + stack.shift(); // dx1 - c1y = y + stack.shift(); // dy1 - c2x = c1x + stack.shift(); // dx2 - c2y = c1y + stack.shift(); // dy2 - jpx = c2x + stack.shift(); // dx3 - jpy = c2y; // dy3 - c3x = jpx + stack.shift(); // dx4 - c3y = c2y; // dy4 - c4x = c3x + stack.shift(); // dx5 - c4y = c3y + stack.shift(); // dy5 - x = c4x + stack.shift(); // dx6 - curveTo(c1x, c1y, c2x, c2y, jpx, jpy); - curveTo(c3x, c3y, c4x, c4y, x, y); - break; - case 37: // flex1 - // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |- - c1x = x + stack.shift(); // dx1 - c1y = y + stack.shift(); // dy1 - c2x = c1x + stack.shift(); // dx2 - c2y = c1y + stack.shift(); // dy2 - jpx = c2x + stack.shift(); // dx3 - jpy = c2y + stack.shift(); // dy3 - c3x = jpx + stack.shift(); // dx4 - c3y = jpy + stack.shift(); // dy4 - c4x = c3x + stack.shift(); // dx5 - c4y = c3y + stack.shift(); // dy5 - if (Math.abs(c4x - x) > Math.abs(c4y - y)) { - x = c4x + stack.shift(); - } - else { - y = c4y + stack.shift(); - } - - curveTo(c1x, c1y, c2x, c2y, jpx, jpy); - curveTo(c3x, c3y, c4x, c4y, x, y); - break; - default: - console.warn('Glyph ' + index + ': unknown operator ' + (1200 + v)); - stack.length = 0; - } + case 36: // hflex1 + // |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |- + c1x = x + stack.shift(); // dx1 + c1y = y + stack.shift(); // dy1 + c2x = c1x + stack.shift(); // dx2 + c2y = c1y + stack.shift(); // dy2 + jpx = c2x + stack.shift(); // dx3 + jpy = c2y; // dy3 + c3x = jpx + stack.shift(); // dx4 + c3y = c2y; // dy4 + c4x = c3x + stack.shift(); // dx5 + c4y = c3y + stack.shift(); // dy5 + x = c4x + stack.shift(); // dx6 + curveTo(c1x, c1y, c2x, c2y, jpx, jpy); + curveTo(c3x, c3y, c4x, c4y, x, y); break; - case 14: // endchar - if (stack.length === 1 && !haveWidth) { - width = stack.shift() + font.nominalWidthX; - haveWidth = true; - } - else if (stack.length === 4) { - glyfs[1] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}}; - glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}}; - glyfs[1].transform.f = stack.pop(); - glyfs[1].transform.e = stack.pop(); - } - else if (stack.length === 5) { - if (!haveWidth) { - width = stack.shift() + font.nominalWidthX; - } - haveWidth = true; - glyfs[1] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}}; - glyfs[0] = {glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0}}; - glyfs[1].transform.f = stack.pop(); - glyfs[1].transform.e = stack.pop(); - } - - if (open) { - contours.push(contour); - open = false; + case 37: // flex1 + // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |- + c1x = x + stack.shift(); // dx1 + c1y = y + stack.shift(); // dy1 + c2x = c1x + stack.shift(); // dx2 + c2y = c1y + stack.shift(); // dy2 + jpx = c2x + stack.shift(); // dx3 + jpy = c2y + stack.shift(); // dy3 + c3x = jpx + stack.shift(); // dx4 + c3y = jpy + stack.shift(); // dy4 + c4x = c3x + stack.shift(); // dx5 + c4y = c3y + stack.shift(); // dy5 + if (Math.abs(c4x - x) > Math.abs(c4y - y)) { + x = c4x + stack.shift(); } - - break; - case 18: // hstemhm - parseStems(); - break; - case 19: // hintmask - case 20: // cntrmask - parseStems(); - i += (nStems + 7) >> 3; - break; - case 21: // rmoveto - if (stack.length > 2 && !haveWidth) { - width = stack.shift() + font.nominalWidthX; - haveWidth = true; + else { + y = c4y + stack.shift(); } - y += stack.pop(); - x += stack.pop(); - newContour(x, y); + curveTo(c1x, c1y, c2x, c2y, jpx, jpy); + curveTo(c3x, c3y, c4x, c4y, x, y); break; - case 22: // hmoveto - if (stack.length > 1 && !haveWidth) { + default: + console.warn('Glyph ' + index + ': unknown operator ' + (1200 + v)); + stack.length = 0; + } + break; + case 14: // endchar + if (stack.length === 1 && !haveWidth) { + width = stack.shift() + font.nominalWidthX; + haveWidth = true; + } + else if (stack.length === 4) { + glyfs[1] = { + glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), + transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0} + }; + glyfs[0] = { + glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), + transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0} + }; + glyfs[1].transform.f = stack.pop(); + glyfs[1].transform.e = stack.pop(); + } + else if (stack.length === 5) { + if (!haveWidth) { width = stack.shift() + font.nominalWidthX; - haveWidth = true; } - - x += stack.pop(); - newContour(x, y); - break; - case 23: // vstemhm - parseStems(); - break; - case 24: // rcurveline - while (stack.length > 2) { - c1x = x + stack.shift(); - c1y = y + stack.shift(); - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x + stack.shift(); - y = c2y + stack.shift(); - curveTo(c1x, c1y, c2x, c2y, x, y); - } - + haveWidth = true; + glyfs[1] = { + glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), + transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0} + }; + glyfs[0] = { + glyphIndex: font.charset.indexOf(font.encoding[stack.pop()]), + transform: {a: 1, b: 0, c: 0, d: 1, e: 0, f: 0} + }; + glyfs[1].transform.f = stack.pop(); + glyfs[1].transform.e = stack.pop(); + } + + if (open) { + contours.push(contour); + open = false; + } + + break; + case 18: // hstemhm + parseStems(); + break; + case 19: // hintmask + case 20: // cntrmask + parseStems(); + i += (nStems + 7) >> 3; + break; + case 21: // rmoveto + if (stack.length > 2 && !haveWidth) { + width = stack.shift() + font.nominalWidthX; + haveWidth = true; + } + + y += stack.pop(); + x += stack.pop(); + newContour(x, y); + break; + case 22: // hmoveto + if (stack.length > 1 && !haveWidth) { + width = stack.shift() + font.nominalWidthX; + haveWidth = true; + } + + x += stack.pop(); + newContour(x, y); + break; + case 23: // vstemhm + parseStems(); + break; + case 24: // rcurveline + while (stack.length > 2) { + c1x = x + stack.shift(); + c1y = y + stack.shift(); + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y + stack.shift(); + curveTo(c1x, c1y, c2x, c2y, x, y); + } + + x += stack.shift(); + y += stack.shift(); + lineTo(x, y); + break; + case 25: // rlinecurve + while (stack.length > 6) { x += stack.shift(); y += stack.shift(); lineTo(x, y); - break; - case 25: // rlinecurve - while (stack.length > 6) { - x += stack.shift(); - y += stack.shift(); - lineTo(x, y); - } + } + + c1x = x + stack.shift(); + c1y = y + stack.shift(); + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y + stack.shift(); + curveTo(c1x, c1y, c2x, c2y, x, y); + break; + case 26: // vvcurveto + if (stack.length % 2) { + x += stack.shift(); + } - c1x = x + stack.shift(); + while (stack.length > 0) { + c1x = x; c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); - x = c2x + stack.shift(); + x = c2x; y = c2y + stack.shift(); curveTo(c1x, c1y, c2x, c2y, x, y); - break; - case 26: // vvcurveto - if (stack.length % 2) { - x += stack.shift(); - } + } - while (stack.length > 0) { - c1x = x; - c1y = y + stack.shift(); - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x; - y = c2y + stack.shift(); - curveTo(c1x, c1y, c2x, c2y, x, y); - } + break; + case 27: // hhcurveto + if (stack.length % 2) { + y += stack.shift(); + } - break; - case 27: // hhcurveto - if (stack.length % 2) { - y += stack.shift(); + while (stack.length > 0) { + c1x = x + stack.shift(); + c1y = y; + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y; + curveTo(c1x, c1y, c2x, c2y, x, y); + } + + break; + case 28: // shortint + b1 = code[i]; + b2 = code[i + 1]; + stack.push(((b1 << 24) | (b2 << 16)) >> 16); + i += 2; + break; + case 29: // callgsubr + codeIndex = stack.pop() + font.gsubrsBias; + subrCode = font.gsubrs[codeIndex]; + if (subrCode) { + parse(subrCode); + } + + break; + case 30: // vhcurveto + while (stack.length > 0) { + c1x = x; + c1y = y + stack.shift(); + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y + (stack.length === 1 ? stack.shift() : 0); + curveTo(c1x, c1y, c2x, c2y, x, y); + if (stack.length === 0) { + break; } - while (stack.length > 0) { - c1x = x + stack.shift(); - c1y = y; - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x + stack.shift(); - y = c2y; - curveTo(c1x, c1y, c2x, c2y, x, y); + c1x = x + stack.shift(); + c1y = y; + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + y = c2y + stack.shift(); + x = c2x + (stack.length === 1 ? stack.shift() : 0); + curveTo(c1x, c1y, c2x, c2y, x, y); + } + + break; + case 31: // hvcurveto + while (stack.length > 0) { + c1x = x + stack.shift(); + c1y = y; + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + y = c2y + stack.shift(); + x = c2x + (stack.length === 1 ? stack.shift() : 0); + curveTo(c1x, c1y, c2x, c2y, x, y); + if (stack.length === 0) { + break; } - break; - case 28: // shortint + c1x = x; + c1y = y + stack.shift(); + c2x = c1x + stack.shift(); + c2y = c1y + stack.shift(); + x = c2x + stack.shift(); + y = c2y + (stack.length === 1 ? stack.shift() : 0); + curveTo(c1x, c1y, c2x, c2y, x, y); + } + + break; + default: + if (v < 32) { + console.warn('Glyph ' + index + ': unknown operator ' + v); + } + else if (v < 247) { + stack.push(v - 139); + } + else if (v < 251) { + b1 = code[i]; + i += 1; + stack.push((v - 247) * 256 + b1 + 108); + } + else if (v < 255) { + b1 = code[i]; + i += 1; + stack.push(-(v - 251) * 256 - b1 - 108); + } + else { b1 = code[i]; b2 = code[i + 1]; - stack.push(((b1 << 24) | (b2 << 16)) >> 16); - i += 2; - break; - case 29: // callgsubr - codeIndex = stack.pop() + font.gsubrsBias; - subrCode = font.gsubrs[codeIndex]; - if (subrCode) { - parse(subrCode); - } - - break; - case 30: // vhcurveto - while (stack.length > 0) { - c1x = x; - c1y = y + stack.shift(); - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x + stack.shift(); - y = c2y + (stack.length === 1 ? stack.shift() : 0); - curveTo(c1x, c1y, c2x, c2y, x, y); - if (stack.length === 0) { - break; - } - - c1x = x + stack.shift(); - c1y = y; - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - y = c2y + stack.shift(); - x = c2x + (stack.length === 1 ? stack.shift() : 0); - curveTo(c1x, c1y, c2x, c2y, x, y); - } - - break; - case 31: // hvcurveto - while (stack.length > 0) { - c1x = x + stack.shift(); - c1y = y; - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - y = c2y + stack.shift(); - x = c2x + (stack.length === 1 ? stack.shift() : 0); - curveTo(c1x, c1y, c2x, c2y, x, y); - if (stack.length === 0) { - break; - } - - c1x = x; - c1y = y + stack.shift(); - c2x = c1x + stack.shift(); - c2y = c1y + stack.shift(); - x = c2x + stack.shift(); - y = c2y + (stack.length === 1 ? stack.shift() : 0); - curveTo(c1x, c1y, c2x, c2y, x, y); - } - - break; - default: - if (v < 32) { - console.warn('Glyph ' + index + ': unknown operator ' + v); - } - else if (v < 247) { - stack.push(v - 139); - } - else if (v < 251) { - b1 = code[i]; - i += 1; - stack.push((v - 247) * 256 + b1 + 108); - } - else if (v < 255) { - b1 = code[i]; - i += 1; - stack.push(-(v - 251) * 256 - b1 - 108); - } - else { - b1 = code[i]; - b2 = code[i + 1]; - b3 = code[i + 2]; - b4 = code[i + 3]; - i += 4; - stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536); - } + b3 = code[i + 2]; + b4 = code[i + 3]; + i += 4; + stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536); + } } } } parse(code); - let glyf = { + + const glyf = { // 移除重复的起点和终点 - contours: contours.map(function (contour) { - let last = contour.length - 1; + contours: contours.map(contour => { + const last = contour.length - 1; if (contour[0].x === contour[last].x && contour[0].y === contour[last].y) { contour.splice(last, 1); } diff --git a/src/ttf/table/cmap.js b/src/ttf/table/cmap.js index 9b5c195..b5b2ed3 100644 --- a/src/ttf/table/cmap.js +++ b/src/ttf/table/cmap.js @@ -15,8 +15,8 @@ export default table.create( 'cmap', [], { + write, read: parse, - write: write, size: sizeof } ); diff --git a/src/ttf/table/cmap/parse.js b/src/ttf/table/cmap/parse.js index e8aec01..5a0f513 100644 --- a/src/ttf/table/cmap/parse.js +++ b/src/ttf/table/cmap/parse.js @@ -17,13 +17,13 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { let i; let l; let glyphIdArray; - let startOffset = cmapOffset + subTable.offset; + const startOffset = cmapOffset + subTable.offset; let glyphCount; subTable.format = reader.readUint16(startOffset); // 0~256 紧凑排列 if (subTable.format === 0) { - let format0 = subTable; + const format0 = subTable; // 跳过format字段 format0.length = reader.readUint16(); format0.language = reader.readUint16(); @@ -34,12 +34,12 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { format0.glyphIdArray = glyphIdArray; } else if (subTable.format === 2) { - let format2 = subTable; + const format2 = subTable; // 跳过format字段 format2.length = reader.readUint16(); format2.language = reader.readUint16(); - let subHeadKeys = []; + const subHeadKeys = []; let maxSubHeadKey = 0;// 最大索引 let maxPos = -1; // 最大位置 for (let i = 0, l = 256; i < l; i++) { @@ -50,7 +50,7 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } } - let subHeads = []; + const subHeads = []; for (i = 0; i <= maxSubHeadKey; i++) { subHeads[i] = { firstCode: reader.readUint16(), @@ -61,7 +61,7 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } glyphCount = (startOffset + format2.length - reader.offset) / 2; - let glyphs = []; + const glyphs = []; for (i = 0; i < glyphCount; i++) { glyphs[i] = reader.readUint16(); } @@ -74,7 +74,7 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } // 双字节编码,非紧凑排列 else if (subTable.format === 4) { - let format4 = subTable; + const format4 = subTable; // 跳过format字段 format4.length = reader.readUint16(); format4.language = reader.readUint16(); @@ -83,10 +83,10 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { format4.entrySelector = reader.readUint16(); format4.rangeShift = reader.readUint16(); - let segCount = format4.segCountX2 / 2; + const segCount = format4.segCountX2 / 2; // end code - let endCode = []; + const endCode = []; for (i = 0; i < segCount; ++i) { endCode.push(reader.readUint16()); } @@ -95,14 +95,14 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { format4.reservedPad = reader.readUint16(); // start code - let startCode = []; + const startCode = []; for (i = 0; i < segCount; ++i) { startCode.push(reader.readUint16()); } format4.startCode = startCode; // idDelta - let idDelta = []; + const idDelta = []; for (i = 0; i < segCount; ++i) { idDelta.push(reader.readUint16()); } @@ -112,7 +112,7 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { format4.idRangeOffsetOffset = reader.offset; // idRangeOffset - let idRangeOffset = []; + const idRangeOffset = []; for (i = 0; i < segCount; ++i) { idRangeOffset.push(reader.readUint16()); } @@ -134,7 +134,7 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } else if (subTable.format === 6) { - let format6 = subTable; + const format6 = subTable; format6.length = reader.readUint16(); format6.language = reader.readUint16(); @@ -144,8 +144,8 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { // 记录array offset format6.glyphIdArrayOffset = reader.offset; - let glyphIndexArray = []; - let entryCount = format6.entryCount; + const glyphIndexArray = []; + const entryCount = format6.entryCount; // 读取字符分组 for (i = 0; i < entryCount; ++i) { glyphIndexArray.push(reader.readUint16()); @@ -155,18 +155,18 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } // defines segments for sparse representation in 4-byte character space else if (subTable.format === 12) { - let format12 = subTable; + const format12 = subTable; format12.reserved = reader.readUint16(); format12.length = reader.readUint32(); format12.language = reader.readUint32(); format12.nGroups = reader.readUint32(); - let groups = []; - let nGroups = format12.nGroups; + const groups = []; + const nGroups = format12.nGroups; // 读取字符分组 for (i = 0; i < nGroups; ++i) { - let group = {}; + const group = {}; group.start = reader.readUint32(); group.end = reader.readUint32(); group.startId = reader.readUint32(); @@ -176,20 +176,20 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } // format 14 else if (subTable.format === 14) { - let format14 = subTable; + const format14 = subTable; format14.length = reader.readUint32(); - let numVarSelectorRecords = reader.readUint32(); - let groups = []; + const numVarSelectorRecords = reader.readUint32(); + const groups = []; for (let i = 0; i < numVarSelectorRecords; i++) { - let varSelector = reader.readUint24(); - let defaultUVSOffset = reader.readUint32(); - let nonDefaultUVSOffset = reader.readUint32(); + const varSelector = reader.readUint24(); + const defaultUVSOffset = reader.readUint32(); + const nonDefaultUVSOffset = reader.readUint32(); if (defaultUVSOffset) { - let numUnicodeValueRanges = reader.readUint32(startOffset + defaultUVSOffset); + const numUnicodeValueRanges = reader.readUint32(startOffset + defaultUVSOffset); for (let j = 0; j < numUnicodeValueRanges; j++) { - let startUnicode = reader.readUint24(); - let additionalCount = reader.readUint8(); + const startUnicode = reader.readUint24(); + const additionalCount = reader.readUint8(); groups.push({ start: startUnicode, end: startUnicode + additionalCount, @@ -198,10 +198,10 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { } } if (nonDefaultUVSOffset) { - let numUVSMappings = reader.readUint32(startOffset + nonDefaultUVSOffset); + const numUVSMappings = reader.readUint32(startOffset + nonDefaultUVSOffset); for (let j = 0; j < numUVSMappings; j++) { - let unicode = reader.readUint24(); - let glyphId = reader.readUint16(); + const unicode = reader.readUint24(); + const glyphId = reader.readUint16(); groups.push({ unicode, glyphId, @@ -219,21 +219,22 @@ function readSubTable(reader, ttf, subTable, cmapOffset) { export default function parse(reader, ttf) { - let tcmap = {}; - let cmapOffset = this.offset; + const tcmap = {}; + // eslint-disable-next-line no-invalid-this + const cmapOffset = this.offset; reader.seek(cmapOffset); tcmap.version = reader.readUint16(); // 编码方式 - let numberSubtables = tcmap.numberSubtables = reader.readUint16(); // 表个数 + const numberSubtables = tcmap.numberSubtables = reader.readUint16(); // 表个数 - let subTables = tcmap.tables = []; // 名字表 + const subTables = tcmap.tables = []; // 名字表 let offset = reader.offset; // 使用offset读取,以便于查找 for (let i = 0, l = numberSubtables; i < l; i++) { - let subTable = {}; + const subTable = {}; subTable.platformID = reader.readUint16(offset); subTable.encodingID = reader.readUint16(offset + 2); subTable.offset = reader.readUint32(offset + 4); @@ -244,7 +245,7 @@ export default function parse(reader, ttf) { offset += 8; } - let cmap = readWindowsAllCodes(subTables, ttf); + const cmap = readWindowsAllCodes(subTables, ttf); return cmap; } diff --git a/src/ttf/table/cmap/sizeof.js b/src/ttf/table/cmap/sizeof.js index 77faed5..5146eec 100644 --- a/src/ttf/table/cmap/sizeof.js +++ b/src/ttf/table/cmap/sizeof.js @@ -28,10 +28,10 @@ function encodeDelta(delta) { function getSegments(glyfUnicodes, bound) { let prevGlyph = null; - let result = []; + const result = []; let segment = {}; - glyfUnicodes.forEach(function (glyph) { + glyfUnicodes.forEach((glyph) => { if (bound === undefined || glyph.unicode <= bound) { // 初始化编码头部,这里unicode和graph id 都必须连续 @@ -76,17 +76,15 @@ function getSegments(glyfUnicodes, bound) { * @return {Array} 码表 */ function getFormat0Segment(glyfUnicodes) { - let unicodes = []; - glyfUnicodes.forEach(function (u) { + const unicodes = []; + glyfUnicodes.forEach((u) => { if (u.unicode !== undefined && u.unicode < 256) { unicodes.push([u.unicode, u.id]); } }); // 按编码排序 - unicodes.sort(function (a, b) { - return a[0] - b[0]; - }); + unicodes.sort((a, b) => a[0] - b[0]); return unicodes; } @@ -100,7 +98,7 @@ function getFormat0Segment(glyfUnicodes) { export default function sizeof(ttf) { ttf.support.cmap = {}; let glyfUnicodes = []; - ttf.glyf.forEach(function (glyph, index) { + ttf.glyf.forEach((glyph, index) => { let unicodes = glyph.unicode; @@ -109,9 +107,9 @@ export default function sizeof(ttf) { } if (unicodes && unicodes.length) { - unicodes.forEach(function (unicode) { + unicodes.forEach((unicode) => { glyfUnicodes.push({ - unicode: unicode, + unicode, id: unicode !== 0xFFFF ? index : 0 }); }); @@ -119,13 +117,11 @@ export default function sizeof(ttf) { }); - glyfUnicodes = glyfUnicodes.sort(function (a, b) { - return a.unicode - b.unicode; - }); + glyfUnicodes = glyfUnicodes.sort((a, b) => a.unicode - b.unicode); ttf.support.cmap.unicodes = glyfUnicodes; - let unicodes2Bytes = glyfUnicodes; + const unicodes2Bytes = glyfUnicodes; ttf.support.cmap.format4Segments = getSegments(unicodes2Bytes, 0xFFFF); ttf.support.cmap.format4Size = 24 @@ -135,21 +131,19 @@ export default function sizeof(ttf) { ttf.support.cmap.format0Size = 262; // we need subtable 12 only if found unicodes with > 2 bytes. - let hasGLyphsOver2Bytes = unicodes2Bytes.some(function (glyph) { - return glyph.unicode > 0xFFFF; - }); + const hasGLyphsOver2Bytes = unicodes2Bytes.some((glyph) => glyph.unicode > 0xFFFF); if (hasGLyphsOver2Bytes) { ttf.support.cmap.hasGLyphsOver2Bytes = hasGLyphsOver2Bytes; - let unicodes4Bytes = glyfUnicodes; + const unicodes4Bytes = glyfUnicodes; ttf.support.cmap.format12Segments = getSegments(unicodes4Bytes); ttf.support.cmap.format12Size = 16 + ttf.support.cmap.format12Segments.length * 12; } - let size = 4 + (hasGLyphsOver2Bytes ? 32 : 24) // cmap header + const size = 4 + (hasGLyphsOver2Bytes ? 32 : 24) // cmap header + ttf.support.cmap.format0Size // format 0 + ttf.support.cmap.format4Size // format 4 + (hasGLyphsOver2Bytes ? ttf.support.cmap.format12Size : 0); // format 12 diff --git a/src/ttf/table/cmap/write.js b/src/ttf/table/cmap/write.js index e243fa2..01bff0a 100644 --- a/src/ttf/table/cmap/write.js +++ b/src/ttf/table/cmap/write.js @@ -49,9 +49,9 @@ function writeSubTable4(writer, segments) { writer.writeUint16(24 + segments.length * 8); // length writer.writeUint16(0); // language - let segCount = segments.length + 1; - let maxExponent = Math.floor(Math.log(segCount) / Math.LN2); - let searchRange = 2 * Math.pow(2, maxExponent); + const segCount = segments.length + 1; + const maxExponent = Math.floor(Math.log(segCount) / Math.LN2); + const searchRange = 2 * Math.pow(2, maxExponent); writer.writeUint16(segCount * 2); // segCountX2 writer.writeUint16(searchRange); // searchRange @@ -59,7 +59,7 @@ function writeSubTable4(writer, segments) { writer.writeUint16(2 * segCount - searchRange); // rangeShift // end list - segments.forEach(function (segment) { + segments.forEach((segment) => { writer.writeUint16(segment.end); }); writer.writeUint16(0xFFFF); // end code @@ -67,13 +67,13 @@ function writeSubTable4(writer, segments) { // start list - segments.forEach(function (segment) { + segments.forEach((segment) => { writer.writeUint16(segment.start); }); writer.writeUint16(0xFFFF); // start code // id delta - segments.forEach(function (segment) { + segments.forEach((segment) => { writer.writeUint16(segment.delta); }); writer.writeUint16(1); @@ -102,7 +102,7 @@ function writeSubTable12(writer, segments) { writer.writeUint32(0); // language writer.writeUint32(segments.length); // nGroups - segments.forEach(function (segment) { + segments.forEach((segment) => { writer.writeUint32(segment.start); writer.writeUint32(segment.end); writer.writeUint32(segment.startId); @@ -136,16 +136,16 @@ function writeSubTableHeader(writer, platform, encoding, offset) { * @return {Object} 写入器 */ export default function write(writer, ttf) { - let hasGLyphsOver2Bytes = ttf.support.cmap.hasGLyphsOver2Bytes; + const hasGLyphsOver2Bytes = ttf.support.cmap.hasGLyphsOver2Bytes; // write table header. writer.writeUint16(0); // version writer.writeUint16(hasGLyphsOver2Bytes ? 4 : 3); // count // header size - let subTableOffset = 4 + (hasGLyphsOver2Bytes ? 32 : 24); - let format4Size = ttf.support.cmap.format4Size; - let format0Size = ttf.support.cmap.format0Size; + const subTableOffset = 4 + (hasGLyphsOver2Bytes ? 32 : 24); + const format4Size = ttf.support.cmap.format4Size; + const format0Size = ttf.support.cmap.format0Size; // subtable 4, unicode writeSubTableHeader(writer, 0, 3, subTableOffset); diff --git a/src/ttf/table/cvt.js b/src/ttf/table/cvt.js index 21dc412..e011ae2 100644 --- a/src/ttf/table/cvt.js +++ b/src/ttf/table/cvt.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.cvt.length; + const length = ttf.tables.cvt.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/directory.js b/src/ttf/table/directory.js index 8c029be..9c45fcb 100644 --- a/src/ttf/table/directory.js +++ b/src/ttf/table/directory.js @@ -12,15 +12,15 @@ export default table.create( [], { read(reader, ttf) { - let tables = {}; - let numTables = ttf.numTables; - let offset = this.offset; + const tables = {}; + const numTables = ttf.numTables; + const offset = this.offset; for (let i = offset, l = numTables * 16; i < l; i += 16) { - let name = reader.readString(i, 4).trim(); + const name = reader.readString(i, 4).trim(); tables[name] = { - name: name, + name, checkSum: reader.readUint32(i + 4), offset: reader.readUint32(i + 8), length: reader.readUint32(i + 12) @@ -32,7 +32,7 @@ export default table.create( write(writer, ttf) { - let tables = ttf.support.tables; + const tables = ttf.support.tables; for (let i = 0, l = tables.length; i < l; i++) { writer.writeString((tables[i].name + ' ').slice(0, 4)); writer.writeUint32(tables[i].checkSum); diff --git a/src/ttf/table/fpgm.js b/src/ttf/table/fpgm.js index e3119b6..aab5e68 100644 --- a/src/ttf/table/fpgm.js +++ b/src/ttf/table/fpgm.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.fpgm.length; + const length = ttf.tables.fpgm.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/gasp.js b/src/ttf/table/gasp.js index 3d43094..fa33eb1 100644 --- a/src/ttf/table/gasp.js +++ b/src/ttf/table/gasp.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.gasp.length; + const length = ttf.tables.gasp.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/glyf.js b/src/ttf/table/glyf.js index 90ade0b..0d16a50 100644 --- a/src/ttf/table/glyf.js +++ b/src/ttf/table/glyf.js @@ -17,38 +17,38 @@ export default table.create( { read(reader, ttf) { - let startOffset = this.offset; - let loca = ttf.loca; - let numGlyphs = ttf.maxp.numGlyphs; - let glyphs = []; + const startOffset = this.offset; + const loca = ttf.loca; + const numGlyphs = ttf.maxp.numGlyphs; + const glyphs = []; reader.seek(startOffset); // subset - let subset = ttf.readOptions.subset; + const subset = ttf.readOptions.subset; if (subset && subset.length > 0) { - let subsetMap = { + const subsetMap = { 0: true // 设置.notdef }; subsetMap[0] = true; // subset map - let cmap = ttf.cmap; + const cmap = ttf.cmap; // unicode to index - Object.keys(cmap).forEach(function (c) { + Object.keys(cmap).forEach((c) => { if (subset.indexOf(+c) > -1) { - let i = cmap[c]; + const i = cmap[c]; subsetMap[i] = true; } }); ttf.subsetMap = subsetMap; - let parsedGlyfMap = {}; + const parsedGlyfMap = {}; // 循环解析subset相关的glyf,包括复合字形相关的字形 - let travelsParse = function travels(subsetMap) { - let newSubsetMap = {}; - Object.keys(subsetMap).forEach(function (i) { - let index = +i; + const travelsParse = function travels(subsetMap) { + const newSubsetMap = {}; + Object.keys(subsetMap).forEach((i) => { + const index = +i; parsedGlyfMap[index] = true; // 当前的和下一个一样,或者最后一个无轮廓 if (loca[index] === loca[index + 1]) { @@ -61,7 +61,7 @@ export default table.create( } if (glyphs[index].compound) { - glyphs[index].glyfs.forEach(function (g) { + glyphs[index].glyfs.forEach((g) => { if (!parsedGlyfMap[g.glyphIndex]) { newSubsetMap[g.glyphIndex] = true; } @@ -106,7 +106,7 @@ export default table.create( return glyphs; }, - write: write, + write, size: sizeof } ); diff --git a/src/ttf/table/glyf/parse.js b/src/ttf/table/glyf/parse.js index 1ab6816..6361f2e 100644 --- a/src/ttf/table/glyf/parse.js +++ b/src/ttf/table/glyf/parse.js @@ -5,7 +5,6 @@ import glyFlag from '../../enum/glyFlag'; import componentFlag from '../../enum/componentFlag'; -import error from '../../error'; const MAX_INSTRUCTION_LENGTH = 5000; // 设置instructions阈值防止读取错误 const MAX_NUMBER_OF_COORDINATES = 20000; // 设置坐标最大个数阈值,防止glyf读取错误 @@ -18,10 +17,10 @@ const MAX_NUMBER_OF_COORDINATES = 20000; // 设置坐标最大个数阈值,防 * @return {Object} 解析后的glyf */ function parseSimpleGlyf(reader, glyf) { - let offset = reader.offset; + const offset = reader.offset; // 轮廓点个数 - let numberOfCoordinates = glyf.endPtsOfContours[ + const numberOfCoordinates = glyf.endPtsOfContours[ glyf.endPtsOfContours.length - 1 ] + 1; @@ -34,7 +33,7 @@ function parseSimpleGlyf(reader, glyf) { // 获取flag标志 let i; let length; - let flags = []; + const flags = []; let flag; i = 0; @@ -46,7 +45,7 @@ function parseSimpleGlyf(reader, glyf) { // 标志位3重复flag if ((flag & glyFlag.REPEAT) && i < numberOfCoordinates) { // 重复个数 - let repeat = reader.readUint8(); + const repeat = reader.readUint8(); for (let j = 0; j < repeat; j++) { flags.push(flag); i++; @@ -55,8 +54,8 @@ function parseSimpleGlyf(reader, glyf) { } // 坐标集合 - let coordinates = []; - let xCoordinates = []; + const coordinates = []; + const xCoordinates = []; let prevX = 0; let x; @@ -92,7 +91,7 @@ function parseSimpleGlyf(reader, glyf) { } } - let yCoordinates = []; + const yCoordinates = []; let prevY = 0; let y; @@ -120,8 +119,8 @@ function parseSimpleGlyf(reader, glyf) { // 计算轮廓集合 if (coordinates.length) { - let endPtsOfContours = glyf.endPtsOfContours; - let contours = []; + const endPtsOfContours = glyf.endPtsOfContours; + const contours = []; contours.push(coordinates.slice(0, endPtsOfContours[0] + 1)); for (i = 1, length = endPtsOfContours.length; i < length; i++) { @@ -222,9 +221,9 @@ function parseCompoundGlyf(reader, glyf) { } while (componentFlag.MORE_COMPONENTS & flags); if (componentFlag.WE_HAVE_INSTRUCTIONS & flags) { - let length = reader.readUint16(); + const length = reader.readUint16(); if (length < MAX_INSTRUCTION_LENGTH) { - let instructions = []; + const instructions = []; for (let i = 0; i < length; ++i) { instructions.push(reader.readUint8()); } @@ -254,13 +253,13 @@ export default function parseGlyf(reader, ttf, offset) { reader.seek(offset); } - let glyf = {}; + const glyf = {}; let i; let length; let instructions; // 边界值 - let numberOfContours = reader.readInt16(); + const numberOfContours = reader.readInt16(); glyf.xMin = reader.readInt16(); glyf.yMin = reader.readInt16(); glyf.xMax = reader.readInt16(); @@ -269,7 +268,7 @@ export default function parseGlyf(reader, ttf, offset) { // 读取简单字形 if (numberOfContours >= 0) { // endPtsOfConturs - let endPtsOfContours = []; + const endPtsOfContours = []; if (numberOfContours >= 0) { for (i = 0; i < numberOfContours; i++) { endPtsOfContours.push(reader.readUint16()); diff --git a/src/ttf/table/glyf/sizeof.js b/src/ttf/table/glyf/sizeof.js index 23427d9..d6ea233 100644 --- a/src/ttf/table/glyf/sizeof.js +++ b/src/ttf/table/glyf/sizeof.js @@ -20,11 +20,11 @@ function sizeofSimple(glyf, glyfSupport, hinting) { + (glyf.contours || []).length * 2 + (glyfSupport.flags || []).length; - (glyfSupport.xCoord || []).forEach(function (x) { + (glyfSupport.xCoord || []).forEach((x) => { result += 0 <= x && x <= 0xFF ? 1 : 2; }); - (glyfSupport.yCoord || []).forEach(function (y) { + (glyfSupport.yCoord || []).forEach((y) => { result += 0 <= y && y <= 0xFF ? 1 : 2; }); @@ -38,10 +38,11 @@ function sizeofSimple(glyf, glyfSupport, hinting) { * @param {boolean} hinting 是否保留hints, compound 图元暂时不做hinting * @return {number} size大小 */ +// eslint-disable-next-line no-unused-vars function sizeofCompound(glyf, hinting) { let size = 10; let transform; - glyf.glyfs.forEach(function (g) { + glyf.glyfs.forEach((g) => { transform = g.transform; // flags + glyfIndex size += 4; @@ -59,11 +60,9 @@ function sizeofCompound(glyf, hinting) { if (transform.b || transform.c) { size += 8; } - else { - // scale - if (transform.a !== 1 || transform.d !== 1) { - size += transform.a === transform.d ? 2 : 4; - } + // scale + else if (transform.a !== 1 || transform.d !== 1) { + size += transform.a === transform.d ? 2 : 4; } }); @@ -84,11 +83,11 @@ function getFlags(glyf, glyfSupport) { return glyfSupport; } - let flags = []; - let xCoord = []; - let yCoord = []; + const flags = []; + const xCoord = []; + const yCoord = []; - let contours = glyf.contours; + const contours = glyf.contours; let contour; let prev; let first = true; @@ -98,7 +97,7 @@ function getFlags(glyf, glyfSupport) { for (let i = 0, l = contour.length; i < l; i++) { - let point = contour[i]; + const point = contour[i]; if (first) { xCoord.push(point.x); yCoord.push(point.y); @@ -114,15 +113,15 @@ function getFlags(glyf, glyfSupport) { } // compress - let flagsC = []; - let xCoordC = []; - let yCoordC = []; + const flagsC = []; + const xCoordC = []; + const yCoordC = []; let x; let y; let prevFlag; let repeatPoint = -1; - flags.forEach(function (flag, index) { + flags.forEach((flag, index) => { x = xCoord[index]; y = yCoord[index]; @@ -221,12 +220,12 @@ function getFlags(glyf, glyfSupport) { export default function sizeof(ttf) { ttf.support.glyf = []; let tableSize = 0; - let hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; - ttf.glyf.forEach(function (glyf) { + const hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; + ttf.glyf.forEach((glyf) => { let glyfSupport = {}; glyfSupport = glyf.compound ? glyfSupport : getFlags(glyf, glyfSupport); - let glyfSize = glyf.compound + const glyfSize = glyf.compound ? sizeofCompound(glyf, hinting) : sizeofSimple(glyf, glyfSupport, hinting); let size = glyfSize; diff --git a/src/ttf/table/glyf/write.js b/src/ttf/table/glyf/write.js index 1f140c6..7d3c8b8 100644 --- a/src/ttf/table/glyf/write.js +++ b/src/ttf/table/glyf/write.js @@ -14,8 +14,8 @@ import componentFlag from '../../enum/componentFlag'; */ export default function write(writer, ttf) { - let hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; - ttf.glyf.forEach(function (glyf, index) { + const hinting = ttf.writeOptions ? ttf.writeOptions.hinting : false; + ttf.glyf.forEach((glyf, index) => { // header writer.writeInt16(glyf.compound ? -1 : (glyf.contours || []).length); @@ -32,11 +32,10 @@ export default function write(writer, ttf) { if (glyf.compound) { for (i = 0, l = glyf.glyfs.length; i < l; i++) { - let g = glyf.glyfs[i]; + const g = glyf.glyfs[i]; - flags = g.points ? 0 : - (componentFlag.ARGS_ARE_XY_VALUES - + componentFlag.ROUND_XY_TO_GRID); // xy values + flags = g.points + ? 0 : (componentFlag.ARGS_ARE_XY_VALUES + componentFlag.ROUND_XY_TO_GRID); // xy values // more components if (i < l - 1) { @@ -49,13 +48,13 @@ export default function write(writer, ttf) { // overlap compound flags += g.overlapCompound ? componentFlag.OVERLAP_COMPOUND : 0; - let transform = g.transform; - let a = transform.a; - let b = transform.b; - let c = transform.c; - let d = transform.d; - let e = g.points ? g.points[0] : transform.e; - let f = g.points ? g.points[1] : transform.f; + const transform = g.transform; + const a = transform.a; + const b = transform.b; + const c = transform.c; + const d = transform.d; + const e = g.points ? g.points[0] : transform.e; + const f = g.points ? g.points[1] : transform.f; // xy values or points // int 8 放不下,则用int16放 @@ -66,13 +65,11 @@ export default function write(writer, ttf) { if (b || c) { flags += componentFlag.WE_HAVE_A_TWO_BY_TWO; } - else { - if ((a !== 1 || d !== 1) && a === d) { - flags += componentFlag.WE_HAVE_A_SCALE; - } - else if (a !== 1 || d !== 1) { - flags += componentFlag.WE_HAVE_AN_X_AND_Y_SCALE; - } + else if ((a !== 1 || d !== 1) && a === d) { + flags += componentFlag.WE_HAVE_A_SCALE; + } + else if (a !== 1 || d !== 1) { + flags += componentFlag.WE_HAVE_AN_X_AND_Y_SCALE; } writer.writeUint16(flags); @@ -107,14 +104,14 @@ export default function write(writer, ttf) { else { let endPtsOfContours = -1; - (glyf.contours || []).forEach(function (contour) { + (glyf.contours || []).forEach((contour) => { endPtsOfContours += contour.length; writer.writeUint16(endPtsOfContours); }); // instruction if (hinting && glyf.instructions) { - let instructions = glyf.instructions; + const instructions = glyf.instructions; writer.writeUint16(instructions.length); for (i = 0, l = instructions.length; i < l; i++) { writer.writeUint8(instructions[i]); @@ -131,7 +128,7 @@ export default function write(writer, ttf) { writer.writeUint8(flags[i]); } - let xCoord = ttf.support.glyf[index].xCoord || []; + const xCoord = ttf.support.glyf[index].xCoord || []; for (i = 0, l = xCoord.length; i < l; i++) { if (0 <= xCoord[i] && xCoord[i] <= 0xFF) { writer.writeUint8(xCoord[i]); @@ -141,7 +138,7 @@ export default function write(writer, ttf) { } } - let yCoord = ttf.support.glyf[index].yCoord || []; + const yCoord = ttf.support.glyf[index].yCoord || []; for (i = 0, l = yCoord.length; i < l; i++) { if (0 <= yCoord[i] && yCoord[i] <= 0xFF) { writer.writeUint8(yCoord[i]); @@ -153,7 +150,7 @@ export default function write(writer, ttf) { } // 4字节对齐 - let glyfSize = ttf.support.glyf[index].glyfSize; + const glyfSize = ttf.support.glyf[index].glyfSize; if (glyfSize % 4) { writer.writeEmpty(4 - glyfSize % 4); diff --git a/src/ttf/table/hmtx.js b/src/ttf/table/hmtx.js index 10a5992..2846cfb 100644 --- a/src/ttf/table/hmtx.js +++ b/src/ttf/table/hmtx.js @@ -13,11 +13,11 @@ export default table.create( { read(reader, ttf) { - let offset = this.offset; + const offset = this.offset; reader.seek(offset); - let numOfLongHorMetrics = ttf.hhea.numOfLongHorMetrics; - let hMetrics = []; + const numOfLongHorMetrics = ttf.hhea.numOfLongHorMetrics; + const hMetrics = []; let i; let hMetric; for (i = 0; i < numOfLongHorMetrics; ++i) { @@ -28,8 +28,8 @@ export default table.create( } // 最后一个宽度 - let advanceWidth = hMetrics[numOfLongHorMetrics - 1].advanceWidth; - let numOfLast = ttf.maxp.numGlyphs - numOfLongHorMetrics; + const advanceWidth = hMetrics[numOfLongHorMetrics - 1].advanceWidth; + const numOfLast = ttf.maxp.numGlyphs - numOfLongHorMetrics; // 获取后续的hmetrics for (i = 0; i < numOfLast; ++i) { @@ -45,14 +45,14 @@ export default table.create( write(writer, ttf) { let i; - let numOfLongHorMetrics = ttf.hhea.numOfLongHorMetrics; + const numOfLongHorMetrics = ttf.hhea.numOfLongHorMetrics; for (i = 0; i < numOfLongHorMetrics; ++i) { writer.writeUint16(ttf.glyf[i].advanceWidth); writer.writeInt16(ttf.glyf[i].leftSideBearing); } // 最后一个宽度 - let numOfLast = ttf.glyf.length - numOfLongHorMetrics; + const numOfLast = ttf.glyf.length - numOfLongHorMetrics; for (i = 0; i < numOfLast; ++i) { writer.writeInt16(ttf.glyf[numOfLongHorMetrics + i].leftSideBearing); @@ -66,7 +66,7 @@ export default table.create( // 计算同最后一个advanceWidth相等的元素个数 let numOfLast = 0; // 最后一个advanceWidth - let advanceWidth = ttf.glyf[ttf.glyf.length - 1].advanceWidth; + const advanceWidth = ttf.glyf[ttf.glyf.length - 1].advanceWidth; for (let i = ttf.glyf.length - 2; i >= 0; i--) { if (advanceWidth === ttf.glyf[i].advanceWidth) { diff --git a/src/ttf/table/kern.js b/src/ttf/table/kern.js index f1ae03b..67bc49a 100644 --- a/src/ttf/table/kern.js +++ b/src/ttf/table/kern.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.kern.length; + const length = ttf.tables.kern.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/loca.js b/src/ttf/table/loca.js index f9a94ea..46f2858 100644 --- a/src/ttf/table/loca.js +++ b/src/ttf/table/loca.js @@ -13,16 +13,16 @@ export default table.create( read(reader, ttf) { let offset = this.offset; - let indexToLocFormat = ttf.head.indexToLocFormat; + const indexToLocFormat = ttf.head.indexToLocFormat; // indexToLocFormat有2字节和4字节的区别 - let type = struct.names[(indexToLocFormat === 0) ? struct.Uint16 : struct.Uint32]; - let size = (indexToLocFormat === 0) ? 2 : 4; // 字节大小 - let sizeRatio = (indexToLocFormat === 0) ? 2 : 1; // 真实地址偏移 - let wordOffset = []; + const type = struct.names[(indexToLocFormat === 0) ? struct.Uint16 : struct.Uint32]; + const size = (indexToLocFormat === 0) ? 2 : 4; // 字节大小 + const sizeRatio = (indexToLocFormat === 0) ? 2 : 1; // 真实地址偏移 + const wordOffset = []; reader.seek(offset); - let numGlyphs = ttf.maxp.numGlyphs; + const numGlyphs = ttf.maxp.numGlyphs; for (let i = 0; i < numGlyphs; ++i) { wordOffset.push(reader.read(type, offset, false) * sizeRatio); offset += size; @@ -32,11 +32,11 @@ export default table.create( }, write(writer, ttf) { - let glyfSupport = ttf.support.glyf; + const glyfSupport = ttf.support.glyf; let offset = ttf.support.glyf.offset || 0; - let indexToLocFormat = ttf.head.indexToLocFormat; - let sizeRatio = (indexToLocFormat === 0) ? 0.5 : 1; - let numGlyphs = ttf.glyf.length; + const indexToLocFormat = ttf.head.indexToLocFormat; + const sizeRatio = (indexToLocFormat === 0) ? 0.5 : 1; + const numGlyphs = ttf.glyf.length; for (let i = 0; i < numGlyphs; ++i) { if (indexToLocFormat) { @@ -60,7 +60,7 @@ export default table.create( }, size(ttf) { - let locaCount = ttf.glyf.length + 1; + const locaCount = ttf.glyf.length + 1; return ttf.head.indexToLocFormat ? locaCount * 4 : locaCount * 2; } } diff --git a/src/ttf/table/maxp.js b/src/ttf/table/maxp.js index 42504d4..87df1d7 100644 --- a/src/ttf/table/maxp.js +++ b/src/ttf/table/maxp.js @@ -32,7 +32,7 @@ export default table.create( return writer; }, - size(ttf) { + size() { return 32; } } diff --git a/src/ttf/table/name.js b/src/ttf/table/name.js index 7e14608..7a18d57 100644 --- a/src/ttf/table/name.js +++ b/src/ttf/table/name.js @@ -18,13 +18,13 @@ export default table.create( let offset = this.offset; reader.seek(offset); - let nameTbl = {}; + const nameTbl = {}; nameTbl.format = reader.readUint16(); nameTbl.count = reader.readUint16(); nameTbl.stringOffset = reader.readUint16(); - let nameRecordTbl = []; - let count = nameTbl.count; + const nameRecordTbl = []; + const count = nameTbl.count; let i; let nameRecord; @@ -39,7 +39,7 @@ export default table.create( nameRecordTbl.push(nameRecord); } - offset = offset + nameTbl.stringOffset; + offset += nameTbl.stringOffset; // 读取字符名字 for (i = 0; i < count; ++i) { @@ -47,7 +47,7 @@ export default table.create( nameRecord.name = reader.readBytes(offset + nameRecord.offset, nameRecord.length); } - let names = {}; + const names = {}; // mac 下的english name let platform = platformTbl.Macintosh; @@ -55,11 +55,9 @@ export default table.create( let language = 0; // 如果有windows 下的 english,则用windows下的 name - if (nameRecordTbl.some(function (record) { - return record.platform === platformTbl.Microsoft + if (nameRecordTbl.some((record) => record.platform === platformTbl.Microsoft && record.encoding === win.UCS2 - && record.language === 1033; - })) { + && record.language === 1033)) { platform = platformTbl.Microsoft; encoding = win.UCS2; language = 1033; @@ -81,7 +79,7 @@ export default table.create( }, write(writer, ttf) { - let nameRecordTbl = ttf.support.name; + const nameRecordTbl = ttf.support.name; writer.writeUint16(0); // format writer.writeUint16(nameRecordTbl.length); // count @@ -89,7 +87,7 @@ export default table.create( // write name tbl header let offset = 0; - nameRecordTbl.forEach(function (nameRecord) { + nameRecordTbl.forEach((nameRecord) => { writer.writeUint16(nameRecord.platform); writer.writeUint16(nameRecord.encoding); writer.writeUint16(nameRecord.language); @@ -100,7 +98,7 @@ export default table.create( }); // write name tbl strings - nameRecordTbl.forEach(function (nameRecord) { + nameRecordTbl.forEach((nameRecord) => { writer.writeBytes(nameRecord.name); }); @@ -108,18 +106,18 @@ export default table.create( }, size(ttf) { - let names = ttf.name; + const names = ttf.name; let nameRecordTbl = []; // 写入name信息 // 这里为了简化书写,仅支持英文编码字符, // 中文编码字符将被转化成url encode let size = 6; - Object.keys(names).forEach(function (name) { - let id = nameIdTbl.names[name]; + Object.keys(names).forEach((name) => { + const id = nameIdTbl.names[name]; - let utf8Bytes = string.toUTF8Bytes(names[name]); - let usc2Bytes = string.toUCS2Bytes(names[name]); + const utf8Bytes = string.toUTF8Bytes(names[name]); + const usc2Bytes = string.toUCS2Bytes(names[name]); if (undefined !== id) { // mac @@ -145,15 +143,16 @@ export default table.create( } }); - let namingOrder = ['platform', 'encoding', 'language', 'nameId']; - nameRecordTbl = nameRecordTbl.sort(function (a, b) { + const namingOrder = ['platform', 'encoding', 'language', 'nameId']; + nameRecordTbl = nameRecordTbl.sort((a, b) => { let l = 0; - namingOrder.some(function (name) { - let o = a[name] - b[name]; + namingOrder.some(name => { + const o = a[name] - b[name]; if (o) { l = o; return true; } + return false; }); return l; }); diff --git a/src/ttf/table/post.js b/src/ttf/table/post.js index db098b7..ad4d26d 100644 --- a/src/ttf/table/post.js +++ b/src/ttf/table/post.js @@ -31,22 +31,22 @@ export default table.create( { read(reader, ttf) { - let format = reader.readFixed(this.offset); + const format = reader.readFixed(this.offset); // 读取表头 - let tbl = new Posthead(this.offset).read(reader, ttf); + const tbl = new Posthead(this.offset).read(reader, ttf); // format2 if (format === 2) { - let numberOfGlyphs = reader.readUint16(); - let glyphNameIndex = []; + const numberOfGlyphs = reader.readUint16(); + const glyphNameIndex = []; for (let i = 0; i < numberOfGlyphs; ++i) { glyphNameIndex.push(reader.readUint16()); } - let pascalStringOffset = reader.offset; - let pascalStringLength = ttf.tables.post.length - (pascalStringOffset - this.offset); - let pascalStringBytes = reader.readBytes(reader.offset, pascalStringLength); + const pascalStringOffset = reader.offset; + const pascalStringLength = ttf.tables.post.length - (pascalStringOffset - this.offset); + const pascalStringBytes = reader.readBytes(reader.offset, pascalStringLength); tbl.nameIndex = glyphNameIndex; // 设置glyf名字索引 tbl.names = string.getPascalString(pascalStringBytes); // glyf名字数组 @@ -62,7 +62,7 @@ export default table.create( write(writer, ttf) { - let post = ttf.post || { + const post = ttf.post || { format: 3 }; @@ -79,16 +79,16 @@ export default table.create( // version 3 不设置post信息 if (post.format === 2) { - let numberOfGlyphs = ttf.glyf.length; + const numberOfGlyphs = ttf.glyf.length; writer.writeUint16(numberOfGlyphs); // numberOfGlyphs // write glyphNameIndex - let nameIndex = ttf.support.post.nameIndex; + const nameIndex = ttf.support.post.nameIndex; for (let i = 0, l = nameIndex.length; i < l; i++) { writer.writeUint16(nameIndex[i]); } // write names - ttf.support.post.names.forEach(function (name) { + ttf.support.post.names.forEach((name) => { writer.writeBytes(name); }); } @@ -96,7 +96,7 @@ export default table.create( size(ttf) { - let numberOfGlyphs = ttf.glyf.length; + const numberOfGlyphs = ttf.glyf.length; ttf.post = ttf.post || {}; ttf.post.format = ttf.post.format || 3; ttf.post.maxMemType1 = numberOfGlyphs; @@ -108,8 +108,8 @@ export default table.create( // version 2 let size = 34 + numberOfGlyphs * 2; // header + numberOfGlyphs + numberOfGlyphs * 2 - let glyphNames = []; - let nameIndexArr = []; + const glyphNames = []; + const nameIndexArr = []; let nameIndex = 0; // 获取 name的大小 @@ -119,15 +119,15 @@ export default table.create( nameIndexArr.push(0); } else { - let glyf = ttf.glyf[i]; - let unicode = glyf.unicode ? glyf.unicode[0] : 0; - let unicodeNameIndex = unicodeName[unicode]; + const glyf = ttf.glyf[i]; + const unicode = glyf.unicode ? glyf.unicode[0] : 0; + const unicodeNameIndex = unicodeName[unicode]; if (undefined !== unicodeNameIndex) { nameIndexArr.push(unicodeNameIndex); } else { // 这里需要注意,"" 有可能是"\3" length不为0,但是是空字符串 - let name = glyf.name; + const name = glyf.name; if (!name || name.charCodeAt(0) < 32) { nameIndexArr.push(258 + nameIndex++); glyphNames.push([0]); @@ -135,7 +135,7 @@ export default table.create( } else { nameIndexArr.push(258 + nameIndex++); - let bytes = string.toPascalStringBytes(name); // pascal string bytes + const bytes = string.toPascalStringBytes(name); // pascal string bytes glyphNames.push(bytes); size += bytes.length; } diff --git a/src/ttf/table/prep.js b/src/ttf/table/prep.js index 57c9ef4..b4dc9e2 100644 --- a/src/ttf/table/prep.js +++ b/src/ttf/table/prep.js @@ -13,7 +13,7 @@ export default table.create( { read(reader, ttf) { - let length = ttf.tables.prep.length; + const length = ttf.tables.prep.length; return reader.readBytes(this.offset, length); }, diff --git a/src/ttf/table/struct.js b/src/ttf/table/struct.js index af44e52..4d46b51 100644 --- a/src/ttf/table/struct.js +++ b/src/ttf/table/struct.js @@ -28,8 +28,8 @@ const struct = { }; // 反转名字查找 -let names = {}; -Object.keys(struct).forEach(function (key) { +const names = {}; +Object.keys(struct).forEach((key) => { names[struct[key]] = key; }); diff --git a/src/ttf/table/table.js b/src/ttf/table/table.js index dbdda96..cc284f9 100644 --- a/src/ttf/table/table.js +++ b/src/ttf/table/table.js @@ -5,7 +5,7 @@ import struct from './struct'; import error from '../error'; - +/* eslint-disable no-invalid-this */ /** * 读取表结构 * @@ -14,51 +14,51 @@ import error from '../error'; */ function read(reader) { - let offset = this.offset; + const offset = this.offset; if (undefined !== offset) { reader.seek(offset); } - let me = this; - - this.struct.forEach(function (item) { - let name = item[0]; - let type = item[1]; + const me = this; + this.struct.forEach((item) => { + const name = item[0]; + const type = item[1]; + let typeName = null; switch (type) { - case struct.Int8: - case struct.Uint8: - case struct.Int16: - case struct.Uint16: - case struct.Int32: - case struct.Uint32: - let typeName = struct.names[type]; - me[name] = reader.read(typeName); - break; - - case struct.Fixed: - me[name] = reader.readFixed(); - break; - - case struct.LongDateTime: - me[name] = reader.readLongDateTime(); - break; - - case struct.Bytes: - me[name] = reader.readBytes(reader.offset, item[2] || 0); - break; - - case struct.Char: - me[name] = reader.readChar(); - break; - - case struct.String: - me[name] = reader.readString(reader.offset, item[2] || 0); - break; - - default: - error.raise(10003, name, type); + case struct.Int8: + case struct.Uint8: + case struct.Int16: + case struct.Uint16: + case struct.Int32: + case struct.Uint32: + typeName = struct.names[type]; + me[name] = reader.read(typeName); + break; + + case struct.Fixed: + me[name] = reader.readFixed(); + break; + + case struct.LongDateTime: + me[name] = reader.readLongDateTime(); + break; + + case struct.Bytes: + me[name] = reader.readBytes(reader.offset, item[2] || 0); + break; + + case struct.Char: + me[name] = reader.readChar(); + break; + + case struct.String: + me[name] = reader.readString(reader.offset, item[2] || 0); + break; + + default: + error.raise(10003, name, type); } }); @@ -74,49 +74,49 @@ function read(reader) { * @return {Writer} 返回writer对象 */ function write(writer, ttf) { - let table = ttf[this.name]; + const table = ttf[this.name]; if (!table) { error.raise(10203, this.name); } - this.struct.forEach(function (item) { - let name = item[0]; - let type = item[1]; - + this.struct.forEach((item) => { + const name = item[0]; + const type = item[1]; + let typeName = null; switch (type) { - case struct.Int8: - case struct.Uint8: - case struct.Int16: - case struct.Uint16: - case struct.Int32: - case struct.Uint32: - let typeName = struct.names[type]; - writer.write(typeName, table[name]); - break; - - case struct.Fixed: - writer.writeFixed(table[name]); - break; - - case struct.LongDateTime: - writer.writeLongDateTime(table[name]); - break; - - case struct.Bytes: - writer.writeBytes(table[name], item[2] || 0); - break; - - case struct.Char: - writer.writeChar(table[name]); - break; - - case struct.String: - writer.writeString(table[name], item[2] || 0); - break; - - default: - error.raise(10003, name, type); + case struct.Int8: + case struct.Uint8: + case struct.Int16: + case struct.Uint16: + case struct.Int32: + case struct.Uint32: + typeName = struct.names[type]; + writer.write(typeName, table[name]); + break; + + case struct.Fixed: + writer.writeFixed(table[name]); + break; + + case struct.LongDateTime: + writer.writeLongDateTime(table[name]); + break; + + case struct.Bytes: + writer.writeBytes(table[name], item[2] || 0); + break; + + case struct.Char: + writer.writeChar(table[name]); + break; + + case struct.String: + writer.writeString(table[name], item[2] || 0); + break; + + default: + error.raise(10003, name, type); } }); @@ -132,43 +132,43 @@ function write(writer, ttf) { function size() { let sz = 0; - this.struct.forEach(function (item) { - let type = item[1]; + this.struct.forEach((item) => { + const type = item[1]; switch (type) { - case struct.Int8: - case struct.Uint8: - sz += 1; - break; - - case struct.Int16: - case struct.Uint16: - sz += 2; - break; - - case struct.Int32: - case struct.Uint32: - case struct.Fixed: - sz += 4; - break; - - case struct.LongDateTime: - sz += 8; - break; - - case struct.Bytes: - sz += item[2] || 0; - break; - - case struct.Char: - sz += 1; - break; - - case struct.String: - sz += item[2] || 0; - break; - - default: - error.raise(10003, name, type); + case struct.Int8: + case struct.Uint8: + sz += 1; + break; + + case struct.Int16: + case struct.Uint16: + sz += 2; + break; + + case struct.Int32: + case struct.Uint32: + case struct.Fixed: + sz += 4; + break; + + case struct.LongDateTime: + sz += 8; + break; + + case struct.Bytes: + sz += item[2] || 0; + break; + + case struct.Char: + sz += 1; + break; + + case struct.String: + sz += item[2] || 0; + break; + + default: + error.raise(10003, name, type); } }); @@ -181,10 +181,9 @@ function size() { * @return {*} 当前对象的值 */ function valueOf() { - let val = {}; - let me = this; - - this.struct.forEach(function (item) { + const val = {}; + const me = this; + this.struct.forEach(item => { val[item[0]] = me[item[0]]; }); @@ -192,10 +191,10 @@ function valueOf() { } export default { - read: read, - write: write, - size: size, - valueOf: valueOf, + read, + write, + size, + valueOf, /** * 创建一个表结构 diff --git a/src/ttf/ttf.js b/src/ttf/ttf.js index e764b7c..c4a18f2 100644 --- a/src/ttf/ttf.js +++ b/src/ttf/ttf.js @@ -24,16 +24,16 @@ import config from './data/default'; */ function adjustToEmBox(glyfList, ascent, descent, ajdustToEmPadding) { - glyfList.forEach(function (g) { + glyfList.forEach((g) => { if (g.contours && g.contours.length) { - let rightSideBearing = g.advanceWidth - g.xMax; - let bound = computePath.apply(null, g.contours); - let scale = (ascent - descent - ajdustToEmPadding) / bound.height; - let center = (ascent + descent) / 2; - let yOffset = center - (bound.y + bound.height / 2) * scale; + const rightSideBearing = g.advanceWidth - g.xMax; + const bound = computePath(...g.contours); + const scale = (ascent - descent - ajdustToEmPadding) / bound.height; + const center = (ascent + descent) / 2; + const yOffset = center - (bound.y + bound.height / 2) * scale; - g.contours.forEach(function (contour) { + g.contours.forEach((contour) => { if (scale !== 1) { pathAdjust(contour, scale, scale); } @@ -42,7 +42,7 @@ function adjustToEmBox(glyfList, ascent, descent, ajdustToEmPadding) { pathCeil(contour); }); - let box = computePathBox.apply(null, g.contours); + const box = computePathBox(...g.contours); g.xMin = box.x; g.xMax = box.x + box.width; @@ -77,7 +77,7 @@ function adjustPos(glyfList, leftSideBearing, rightSideBearing, verticalAlign) { if (null != leftSideBearing) { changed = true; - glyfList.forEach(function (g) { + glyfList.forEach((g) => { if (g.leftSideBearing !== leftSideBearing) { glyfAdjust(g, 1, 1, leftSideBearing - g.leftSideBearing); } @@ -88,7 +88,7 @@ function adjustPos(glyfList, leftSideBearing, rightSideBearing, verticalAlign) { if (null != rightSideBearing) { changed = true; - glyfList.forEach(function (g) { + glyfList.forEach((g) => { g.advanceWidth = g.xMax + rightSideBearing; }); } @@ -97,10 +97,10 @@ function adjustPos(glyfList, leftSideBearing, rightSideBearing, verticalAlign) { if (null != verticalAlign) { changed = true; - glyfList.forEach(function (g) { + glyfList.forEach(g => { if (g.contours && g.contours.length) { - let bound = computePath.apply(this, g.contours); - let offset = verticalAlign - bound.y; + const bound = computePath(...g.contours); + const offset = verticalAlign - bound.y; glyfAdjust(g, 1, 1, 0, offset); } }); @@ -125,22 +125,22 @@ function adjustPos(glyfList, leftSideBearing, rightSideBearing, verticalAlign) { */ function merge(ttf, imported, options = {scale: true}) { - let list = imported.glyf.filter(function (g, index) { + const list = imported.glyf.filter((g) => // 简单轮廓 - return g.contours && g.contours.length + g.contours && g.contours.length // 非预定义字形 - && g.name !== '.notdef' && g.name !== '.null' && g.name !== 'nonmarkingreturn'; - }); + && g.name !== '.notdef' && g.name !== '.null' && g.name !== 'nonmarkingreturn' + ); // 调整字形以适应边界 if (options.adjustGlyf) { - let ascent = ttf.hhea.ascent; - let descent = ttf.hhea.descent; - let ajdustToEmPadding = 16; + const ascent = ttf.hhea.ascent; + const descent = ttf.hhea.descent; + const ajdustToEmPadding = 16; adjustPos(list, 16, 16); adjustToEmBox(list, ascent, descent, ajdustToEmPadding); - list.forEach(function (g) { + list.forEach((g) => { ttf.glyf.push(g); }); } @@ -154,7 +154,7 @@ function merge(ttf, imported, options = {scale: true}) { scale = ttf.head.unitsPerEm / imported.head.unitsPerEm; } - list.forEach(function (g) { + list.forEach((g) => { glyfAdjust(g, scale, scale); ttf.glyf.push(g); }); @@ -192,8 +192,8 @@ export default class TTF { * @return {?number} 返回glyf索引号 */ getGlyfIndexByCode(c) { - let charCode = typeof c === 'number' ? c : c.codePointAt(0); - let glyfIndex = this.ttf.cmap[charCode] || -1; + const charCode = typeof c === 'number' ? c : c.codePointAt(0); + const glyfIndex = this.ttf.cmap[charCode] || -1; return glyfIndex; } @@ -205,8 +205,8 @@ export default class TTF { * @return {?Object} 返回glyf对象 */ getGlyfByIndex(glyfIndex) { - let glyfList = this.ttf.glyf; - let glyf = glyfList[glyfIndex]; + const glyfList = this.ttf.glyf; + const glyf = glyfList[glyfIndex]; return glyf; } @@ -218,7 +218,7 @@ export default class TTF { * @return {?Object} 返回glyf对象 */ getGlyfByCode(c) { - let glyfIndex = this.getGlyfIndexByCode(c); + const glyfIndex = this.getGlyfIndexByCode(c); return this.getGlyfByIndex(glyfIndex); } @@ -283,7 +283,7 @@ export default class TTF { * @return {Array} 添加的glyf */ mergeGlyf(imported, options) { - let list = merge(this.ttf, imported, options); + const list = merge(this.ttf, imported, options); return list; } @@ -295,8 +295,8 @@ export default class TTF { * @return {Array} 删除的glyf */ removeGlyf(indexList) { - let glyf = this.ttf.glyf; - let removed = []; + const glyf = this.ttf.glyf; + const removed = []; for (let i = glyf.length - 1; i >= 0; i--) { if (indexList.indexOf(i) >= 0) { removed.push(glyf[i]); @@ -316,16 +316,14 @@ export default class TTF { * @return {Array} 改变的glyf */ setUnicode(unicode, indexList, isGenerateName) { - let glyf = this.ttf.glyf; + const glyf = this.ttf.glyf; let list = []; if (indexList && indexList.length) { - let first = indexList.indexOf(0); + const first = indexList.indexOf(0); if (first >= 0) { indexList.splice(first, 1); } - list = indexList.map(function (item) { - return glyf[item]; - }); + list = indexList.map((item) => glyf[item]); } else { list = glyf.slice(1); @@ -333,17 +331,15 @@ export default class TTF { // 需要选出 unicode >32 的glyf if (list.length > 1) { - let less32 = function (u) { + const less32 = function (u) { return u < 33; }; - list = list.filter(function (g) { - return !g.unicode || !g.unicode.some(less32); - }); + list = list.filter((g) => !g.unicode || !g.unicode.some(less32)); } if (list.length) { unicode = Number('0x' + unicode.slice(1)); - list.forEach(function (g) { + list.forEach((g) => { // 空格有可能会放入 nonmarkingreturn 因此不做编码 if (unicode === 0xA0 || unicode === 0x3000) { unicode++; @@ -368,31 +364,27 @@ export default class TTF { * @return {Array} 改变的glyf */ genGlyfName(indexList) { - let glyf = this.ttf.glyf; + const glyf = this.ttf.glyf; let list = []; if (indexList && indexList.length) { - list = indexList.map(function (item) { - return glyf[item]; - }); + list = indexList.map((item) => glyf[item]); } else { list = glyf; } if (list.length) { - let first = this.ttf.glyf[0]; + const first = this.ttf.glyf[0]; - list.forEach(function (g) { + list.forEach((g) => { if (g === first) { g.name = '.notdef'; } + else if (g.unicode && g.unicode.length) { + g.name = string.getUnicodeName(g.unicode[0]); + } else { - if (g.unicode && g.unicode.length) { - g.name = string.getUnicodeName(g.unicode[0]); - } - else { - g.name = '.notdef'; - } + g.name = '.notdef'; } }); } @@ -407,12 +399,10 @@ export default class TTF { * @return {Array} 改变的glyf */ clearGlyfName(indexList) { - let glyf = this.ttf.glyf; + const glyf = this.ttf.glyf; let list = []; if (indexList && indexList.length) { - list = indexList.map(function (item) { - return glyf[item]; - }); + list = indexList.map((item) => glyf[item]); } else { list = glyf; @@ -420,7 +410,7 @@ export default class TTF { if (list.length) { - list.forEach(function (g) { + list.forEach((g) => { delete g.name; }); } @@ -436,11 +426,11 @@ export default class TTF { * @return {Array} 改变的glyf */ appendGlyf(glyfList, indexList) { - let glyf = this.ttf.glyf; - let result = glyfList.slice(0); + const glyf = this.ttf.glyf; + const result = glyfList.slice(0); if (indexList && indexList.length) { - let l = Math.min(glyfList.length, indexList.length); + const l = Math.min(glyfList.length, indexList.length); for (let i = 0; i < l; i++) { glyf[indexList[i]] = glyfList[i]; } @@ -467,7 +457,7 @@ export default class TTF { */ adjustGlyfPos(indexList, setting) { - let glyfList = this.getGlyf(indexList); + const glyfList = this.getGlyf(indexList); return adjustPos( glyfList, setting.leftSideBearing, @@ -491,18 +481,18 @@ export default class TTF { */ adjustGlyf(indexList, setting) { - let glyfList = this.getGlyf(indexList); + const glyfList = this.getGlyf(indexList); let changed = false; if (setting.reverse || setting.mirror) { changed = true; - glyfList.forEach(function (g) { + glyfList.forEach((g) => { if (g.contours && g.contours.length) { - let offsetX = g.xMax + g.xMin; - let offsetY = g.yMax + g.yMin; - g.contours.forEach(function (contour) { + const offsetX = g.xMax + g.xMin; + const offsetY = g.yMax + g.yMin; + g.contours.forEach((contour) => { pathAdjust(contour, setting.mirror ? -1 : 1, setting.reverse ? -1 : 1); pathAdjust(contour, 1, 1, setting.mirror ? offsetX : 0, setting.reverse ? offsetY : 0); }); @@ -515,8 +505,8 @@ export default class TTF { changed = true; - let scale = setting.scale; - glyfList.forEach(function (g) { + const scale = setting.scale; + glyfList.forEach((g) => { if (g.contours && g.contours.length) { glyfAdjust(g, scale, scale); } @@ -526,9 +516,9 @@ export default class TTF { else if (setting.ajdustToEmBox) { changed = true; - let ascent = this.ttf.hhea.ascent; - let descent = this.ttf.hhea.descent; - let ajdustToEmPadding = 2 * (setting.ajdustToEmPadding || 0); + const ascent = this.ttf.hhea.ascent; + const descent = this.ttf.hhea.descent; + const ajdustToEmPadding = 2 * (setting.ajdustToEmPadding || 0); adjustToEmBox(glyfList, ascent, descent, ajdustToEmPadding); } @@ -543,11 +533,9 @@ export default class TTF { * @return {Array} glyflist */ getGlyf(indexList) { - let glyf = this.ttf.glyf; + const glyf = this.ttf.glyf; if (indexList && indexList.length) { - return indexList.map(function (item) { - return glyf[item]; - }); + return indexList.map((item) => glyf[item]); } return glyf; @@ -573,20 +561,20 @@ export default class TTF { } - let filters = []; + const filters = []; // 按unicode数组查找 if (condition.unicode) { - let unicodeList = Array.isArray(condition.unicode) ? condition.unicode : [condition.unicode]; - let unicodeHash = {}; - unicodeList.forEach(function (unicode) { + const unicodeList = Array.isArray(condition.unicode) ? condition.unicode : [condition.unicode]; + const unicodeHash = {}; + unicodeList.forEach((unicode) => { if (typeof unicode === 'string') { unicode = Number('0x' + unicode.slice(1)); } unicodeHash[unicode] = true; }); - filters.push(function (glyf) { + filters.push((glyf) => { if (!glyf.unicode || !glyf.unicode.length) { return false; } @@ -601,10 +589,8 @@ export default class TTF { // 按名字查找 if (condition.name) { - let name = condition.name; - filters.push(function (glyf) { - return glyf.name && glyf.name.indexOf(name) === 0; - }); + const name = condition.name; + filters.push((glyf) => glyf.name && glyf.name.indexOf(name) === 0); } // 按筛选函数查找 @@ -612,8 +598,8 @@ export default class TTF { filters.push(condition.filter); } - let indexList = []; - this.ttf.glyf.forEach(function (glyf, index) { + const indexList = []; + this.ttf.glyf.forEach((glyf, index) => { for (let filterIndex = 0, filter; (filter = filters[filterIndex++]);) { if (true === filter(glyf)) { indexList.push(index); @@ -660,19 +646,17 @@ export default class TTF { * @return {Array} 设置的glyf列表 */ sortGlyf() { - let glyf = this.ttf.glyf; + const glyf = this.ttf.glyf; if (glyf.length > 1) { // 如果存在复合字形则退出 - if (glyf.some(function (a) { - return a.compound; - })) { + if (glyf.some((a) => a.compound)) { return -2; } - let notdef = glyf.shift(); + const notdef = glyf.shift(); // 按代码点排序, 首先将空字形排到最后,然后按照unicode第一个编码进行排序 - glyf.sort(function (a, b) { + glyf.sort((a, b) => { if ((!a.unicode || !a.unicode.length) && (!b.unicode || !b.unicode.length)) { return 0; } @@ -799,11 +783,11 @@ export default class TTF { calcMetrics() { let ascent = -16384; let descent = 16384; - let uX = 0x78; - let uH = 0x48; + const uX = 0x78; + const uH = 0x48; let sxHeight; let sCapHeight; - this.ttf.glyf.forEach(function (g) { + this.ttf.glyf.forEach((g) => { if (g.yMax > ascent) { ascent = g.yMax; @@ -829,8 +813,8 @@ export default class TTF { return { // 此处非必须自动设置 - ascent: ascent, - descent: descent, + ascent, + descent, sTypoAscender: ascent, sTypoDescender: descent, @@ -860,7 +844,7 @@ export default class TTF { */ compound2simple(indexList) { - let ttf = this.ttf; + const ttf = this.ttf; if (ttf.maxp && !ttf.maxp.maxComponentElements) { return []; } @@ -877,9 +861,9 @@ export default class TTF { } } - let list = []; + const list = []; for (i = 0, l = indexList.length; i < l; ++i) { - let glyfIndex = indexList[i]; + const glyfIndex = indexList[i]; if (ttf.glyf[glyfIndex] && ttf.glyf[glyfIndex].compound) { compound2simpleglyf(glyfIndex, ttf, true); list.push(ttf.glyf[glyfIndex]); diff --git a/src/ttf/ttf2eot.js b/src/ttf/ttf2eot.js index 1e6fe82..f023323 100644 --- a/src/ttf/ttf2eot.js +++ b/src/ttf/ttf2eot.js @@ -43,11 +43,12 @@ const EotHead = table.create( * @param {Object} options 选项 * @return {ArrayBuffer} eot格式byte流 */ +// eslint-disable-next-line no-unused-vars export default function ttf2eot(ttfBuffer, options = {}) { // 构造eot头部 - let eotHead = new EotHead(); - let eotHeaderSize = eotHead.size(); - let eot = {}; + const eotHead = new EotHead(); + const eotHeaderSize = eotHead.size(); + const eot = {}; eot.head = eotHead.read(new Reader(new ArrayBuffer(eotHeaderSize))); // set fields @@ -58,9 +59,9 @@ export default function ttf2eot(ttfBuffer, options = {}) { eot.head.MagicNumber = 0x504C; eot.head.Padding1 = 0; - let ttfReader = new Reader(ttfBuffer); + const ttfReader = new Reader(ttfBuffer); // 读取ttf表个数 - let numTables = ttfReader.readUint16(4); + const numTables = ttfReader.readUint16(4); if (numTables <= 0 || numTables > 100) { error.raise(10101); @@ -72,14 +73,14 @@ export default function ttf2eot(ttfBuffer, options = {}) { let tblReaded = 0; for (let i = 0; i < numTables && tblReaded !== 0x7; ++i) { - let tableEntry = { + const tableEntry = { tag: ttfReader.readString(ttfReader.offset, 4), checkSum: ttfReader.readUint32(), offset: ttfReader.readUint32(), length: ttfReader.readUint32() }; - let entryOffset = ttfReader.offset; + const entryOffset = ttfReader.offset; if (tableEntry.tag === 'head') { eot.head.CheckSumAdjustment = ttfReader.readUint32(tableEntry.offset + 8); @@ -97,7 +98,7 @@ export default function ttf2eot(ttfBuffer, options = {}) { // 设置名字信息 else if (tableEntry.tag === 'name') { - let names = new NameTbl(tableEntry.offset).read(ttfReader); + const names = new NameTbl(tableEntry.offset).read(ttfReader); eot.FamilyName = string.toUCS2Bytes(names.fontFamily || ''); eot.FamilyNameSize = eot.FamilyName.length; @@ -127,7 +128,7 @@ export default function ttf2eot(ttfBuffer, options = {}) { + eot.head.FontDataSize; // 这里用小尾方式写入 - let eotWriter = new Writer(new ArrayBuffer(eot.head.EOTSize), 0, eot.head.EOTSize, true); + const eotWriter = new Writer(new ArrayBuffer(eot.head.EOTSize), 0, eot.head.EOTSize, true); // write head eotHead.write(eotWriter, eot); diff --git a/src/ttf/ttf2icon.js b/src/ttf/ttf2icon.js index f8f00c0..baf7568 100644 --- a/src/ttf/ttf2icon.js +++ b/src/ttf/ttf2icon.js @@ -15,9 +15,7 @@ import {getSymbolId} from './ttf2symbol'; * @return {string} unicode string */ function listUnicode(unicode) { - return unicode.map(function (u) { - return '\\' + u.toString(16); - }).join(','); + return unicode.map((u) => '\\' + u.toString(16)).join(','); } /** @@ -31,17 +29,15 @@ function listUnicode(unicode) { */ function ttfobject2icon(ttf, options = {}) { - let glyfList = []; + const glyfList = []; // glyf 信息 - let filtered = ttf.glyf.filter(function (g) { - return g.name !== '.notdef' + const filtered = ttf.glyf.filter((g) => g.name !== '.notdef' && g.name !== '.null' && g.name !== 'nonmarkingreturn' - && g.unicode && g.unicode.length; - }); + && g.unicode && g.unicode.length); - filtered.forEach(function (g, i) { + filtered.forEach((g, i) => { glyfList.push({ code: '&#x' + g.unicode[0].toString(16) + ';', codeName: listUnicode(g.unicode), @@ -53,7 +49,7 @@ function ttfobject2icon(ttf, options = {}) { return { fontFamily: ttf.name.fontFamily || config.name.fontFamily, iconPrefix: options.iconPrefix || 'icon', - glyfList: glyfList + glyfList }; } @@ -71,8 +67,8 @@ function ttfobject2icon(ttf, options = {}) { export default function ttf2icon(ttfBuffer, options = {}) { // 读取ttf二进制流 if (ttfBuffer instanceof ArrayBuffer) { - let reader = new TTFReader(); - let ttfObject = reader.read(ttfBuffer); + const reader = new TTFReader(); + const ttfObject = reader.read(ttfBuffer); reader.dispose(); return ttfobject2icon(ttfObject, options); diff --git a/src/ttf/ttf2svg.js b/src/ttf/ttf2svg.js index d0eb96d..01f7103 100644 --- a/src/ttf/ttf2svg.js +++ b/src/ttf/ttf2svg.js @@ -46,10 +46,10 @@ const GLYPH_TPL = '' */ function ttfobject2svg(ttf, options) { - let OS2 = ttf['OS/2']; + const OS2 = ttf['OS/2']; // 用来填充xml的数据 - let xmlObject = { + const xmlObject = { id: ttf.name.uniqueSubFamily || SVG_FONT_ID, metadata: string.encodeHTML(options.metadata || ''), advanceWidth: ttf.hhea.advanceWidthMax, @@ -80,11 +80,11 @@ function ttfobject2svg(ttf, options) { // glyf 信息 let glyphList = ''; for (let i = 1, l = ttf.glyf.length; i < l; i++) { - let glyf = ttf.glyf[i]; + const glyf = ttf.glyf[i]; // 筛选简单字形,并且有轮廓,有编码 if (!glyf.compound && glyf.contours && glyf.unicode && glyf.unicode.length) { - let glyfObject = { + const glyfObject = { name: utilString.escape(glyf.name), unicode: unicode2xml(glyf.unicode), d: contours2svg(glyf.contours) @@ -111,8 +111,8 @@ export default function ttf2svg(ttfBuffer, options = {}) { // 读取ttf二进制流 if (ttfBuffer instanceof ArrayBuffer) { - let reader = new TTFReader(); - let ttfObject = reader.read(ttfBuffer); + const reader = new TTFReader(); + const ttfObject = reader.read(ttfBuffer); reader.dispose(); return ttfobject2svg(ttfObject, options); diff --git a/src/ttf/ttf2symbol.js b/src/ttf/ttf2symbol.js index bced71f..31b7a5b 100644 --- a/src/ttf/ttf2symbol.js +++ b/src/ttf/ttf2symbol.js @@ -52,21 +52,21 @@ export function getSymbolId(glyf, index) { * @param {Object} options.metadata 字体相关的信息 * @return {string} svg字符串 */ -function ttfobject2symbol(ttf, options) { - - let xmlObject = {}; - let unitsPerEm = ttf.head.unitsPerEm; - let descent = ttf.hhea.descent; +// eslint-disable-next-line no-unused-vars +function ttfobject2symbol(ttf, options = {}) { + const xmlObject = {}; + const unitsPerEm = ttf.head.unitsPerEm; + const descent = ttf.hhea.descent; // glyf 信息 let symbolList = ''; for (let i = 1, l = ttf.glyf.length; i < l; i++) { - let glyf = ttf.glyf[i]; + const glyf = ttf.glyf[i]; // 筛选简单字形,并且有轮廓,有编码 if (!glyf.compound && glyf.contours) { - let contours = pathsUtil.flip(glyf.contours); - let glyfObject = { - descent: descent, - unitsPerEm: unitsPerEm, + const contours = pathsUtil.flip(glyf.contours); + const glyfObject = { + descent, + unitsPerEm, id: getSymbolId(glyf, i), d: contours2svg(contours) }; @@ -91,8 +91,8 @@ export default function ttf2symbol(ttfBuffer, options = {}) { // 读取ttf二进制流 if (ttfBuffer instanceof ArrayBuffer) { - let reader = new TTFReader(); - let ttfObject = reader.read(ttfBuffer); + const reader = new TTFReader(); + const ttfObject = reader.read(ttfBuffer); reader.dispose(); return ttfobject2symbol(ttfObject, options); diff --git a/src/ttf/ttf2woff.js b/src/ttf/ttf2woff.js index 7fe1531..66fae3e 100644 --- a/src/ttf/ttf2woff.js +++ b/src/ttf/ttf2woff.js @@ -66,9 +66,9 @@ function metadata2xml(metadata) { if (metadata.credit) { xml += ''; - let credits = metadata.credit instanceof Array ? metadata.credit : [metadata.credit]; + const credits = metadata.credit instanceof Array ? metadata.credit : [metadata.credit]; - credits.forEach(function (credit) { + credits.forEach((credit) => { xml += ''; @@ -125,7 +125,7 @@ function metadata2xml(metadata) { export default function ttf2woff(ttfBuffer, options = {}) { // woff 头部结构 - let woffHeader = { + const woffHeader = { signature: 0x774F4646, // for woff flavor: 0x10000, // for ttf length: 0, @@ -141,9 +141,9 @@ export default function ttf2woff(ttfBuffer, options = {}) { privLength: 0 }; - let ttfReader = new Reader(ttfBuffer); + const ttfReader = new Reader(ttfBuffer); let tableEntries = []; - let numTables = ttfReader.readUint16(4); // 读取ttf表个数 + const numTables = ttfReader.readUint16(4); // 读取ttf表个数 let tableEntry; let deflatedData; let i; @@ -165,7 +165,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { length: ttfReader.readUint32() }; - let entryOffset = ttfReader.offset; + const entryOffset = ttfReader.offset; if (tableEntry.tag === 'head') { // 读取font revision @@ -174,7 +174,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { } // ttf 表数据 - let sfntData = ttfReader.readBytes(tableEntry.offset, tableEntry.length); + const sfntData = ttfReader.readBytes(tableEntry.offset, tableEntry.length); // 对数据进行压缩 if (options.deflate) { @@ -203,9 +203,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { } // 对table进行排序 - tableEntries = tableEntries.sort(function (a, b) { - return a.tag === b.tag ? 0 : a.tag < b.tag ? -1 : 1; - }); + tableEntries = tableEntries.sort((a, b) => a.tag === b.tag ? 0 : a.tag < b.tag ? -1 : 1); // 计算offset和 woff size let woffSize = 44 + 20 * numTables; // header size + table entries @@ -214,7 +212,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { for (i = 0, l = tableEntries.length; i < l; ++i) { tableEntry = tableEntries[i]; tableEntry.offset = woffSize; - // 4字节对齐 + // 4字节对齐 woffSize += tableEntry.compLength + (tableEntry.compLength % 4 ? 4 - tableEntry.compLength % 4 : 0); ttfSize += tableEntry.length + (tableEntry.length % 4 ? 4 - tableEntry.length % 4 : 0); } @@ -222,7 +220,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { // 计算metaData let metadata = null; if (options.metadata) { - let xml = utilString.toUTF8Bytes(metadata2xml(options.metadata)); + const xml = utilString.toUTF8Bytes(metadata2xml(options.metadata)); if (options.deflate) { deflatedData = options.deflate(xml); @@ -249,7 +247,7 @@ export default function ttf2woff(ttfBuffer, options = {}) { woffHeader.totalSfntSize = ttfSize; // 写woff数据 - let woffWriter = new Writer(new ArrayBuffer(woffSize)); + const woffWriter = new Writer(new ArrayBuffer(woffSize)); // 写woff头部 woffWriter.writeUint32(woffHeader.signature); diff --git a/src/ttf/ttfreader.js b/src/ttf/ttfreader.js index 8b23f87..5d6df06 100644 --- a/src/ttf/ttfreader.js +++ b/src/ttf/ttfreader.js @@ -39,9 +39,9 @@ export default class TTFReader { */ readBuffer(buffer) { - let reader = new Reader(buffer, 0, buffer.byteLength, false); + const reader = new Reader(buffer, 0, buffer.byteLength, false); - let ttf = {}; + const ttf = {}; // version ttf.version = reader.readFixed(0); @@ -75,10 +75,10 @@ export default class TTFReader { ttf.readOptions = this.options; // 读取支持的表数据 - Object.keys(supportTables).forEach(function (tableName) { + Object.keys(supportTables).forEach((tableName) => { if (ttf.tables[tableName]) { - let offset = ttf.tables[tableName].offset; + const offset = ttf.tables[tableName].offset; ttf[tableName] = new supportTables[tableName](offset).read(reader, ttf); } }); @@ -98,13 +98,13 @@ export default class TTFReader { * @param {Object} ttf ttf对象 */ resolveGlyf(ttf) { - let codes = ttf.cmap; - let glyf = ttf.glyf; - let subsetMap = ttf.readOptions.subset ? ttf.subsetMap : null; // 当前ttf的子集列表 + const codes = ttf.cmap; + const glyf = ttf.glyf; + const subsetMap = ttf.readOptions.subset ? ttf.subsetMap : null; // 当前ttf的子集列表 // unicode - Object.keys(codes).forEach(function (c) { - let i = codes[c]; + Object.keys(codes).forEach((c) => { + const i = codes[c]; if (subsetMap && !subsetMap[i]) { return; } @@ -115,7 +115,7 @@ export default class TTFReader { }); // advanceWidth - ttf.hmtx.forEach(function (item, i) { + ttf.hmtx.forEach((item, i) => { if (subsetMap && !subsetMap[i]) { return; } @@ -125,9 +125,9 @@ export default class TTFReader { // format = 2 的post表会携带glyf name信息 if (ttf.post && 2 === ttf.post.format) { - let nameIndex = ttf.post.nameIndex; - let names = ttf.post.names; - nameIndex.forEach(function (nameIndex, i) { + const nameIndex = ttf.post.nameIndex; + const names = ttf.post.names; + nameIndex.forEach((nameIndex, i) => { if (subsetMap && !subsetMap[i]) { return; } @@ -143,8 +143,8 @@ export default class TTFReader { // 设置了subsetMap之后需要选取subset中的字形 // 并且对复合字形转换成简单字形 if (subsetMap) { - let subGlyf = []; - Object.keys(subsetMap).forEach(function (i) { + const subGlyf = []; + Object.keys(subsetMap).forEach((i) => { i = +i; if (glyf[i].compound) { compound2simpleglyf(i, ttf, true); @@ -182,14 +182,14 @@ export default class TTFReader { delete ttf.prep; delete ttf.GPOS; delete ttf.kern; - ttf.glyf.forEach(function (glyf) { + ttf.glyf.forEach((glyf) => { delete glyf.instructions; }); } // 复合字形转简单字形 if (this.options.compound2simple && ttf.maxp.maxComponentElements) { - ttf.glyf.forEach(function (glyf, index) { + ttf.glyf.forEach((glyf, index) => { if (glyf.compound) { compound2simpleglyf(index, ttf, true); } diff --git a/src/ttf/ttftowoff2.js b/src/ttf/ttftowoff2.js index 12211ec..799a923 100644 --- a/src/ttf/ttftowoff2.js +++ b/src/ttf/ttftowoff2.js @@ -12,12 +12,13 @@ import woff2 from '../../woff2/index'; * * @return {Promise.} woff格式byte流 */ +// eslint-disable-next-line no-unused-vars export default function ttftowoff2(ttfBuffer, options = {}) { if (!woff2.isInited()) { throw new Error('use woff2.init() to init woff2 module!'); } - let result = woff2.encode(ttfBuffer); + const result = woff2.encode(ttfBuffer); return result.buffer; } @@ -31,8 +32,8 @@ export default function ttftowoff2(ttfBuffer, options = {}) { * @return {Promise.} woff格式byte流 */ export function ttftowoff2async(ttfBuffer, options = {}) { - return woff2.init(options.wasmUrl).then(function () { - let result = woff2.encode(ttfBuffer); + return woff2.init(options.wasmUrl).then(() => { + const result = woff2.encode(ttfBuffer); return result.buffer; }); } diff --git a/src/ttf/ttfwriter.js b/src/ttf/ttfwriter.js index 68a34ed..54702a7 100644 --- a/src/ttf/ttfwriter.js +++ b/src/ttf/ttfwriter.js @@ -65,14 +65,14 @@ export default class TTFWriter { ttf.head.modified = ttf.head.created; } - let checkUnicodeRepeat = {}; // 检查是否有重复代码点 + const checkUnicodeRepeat = {}; // 检查是否有重复代码点 // 将glyf的代码点按小到大排序 - ttf.glyf.forEach(function (glyf, index) { + ttf.glyf.forEach((glyf, index) => { if (glyf.unicode) { glyf.unicode = glyf.unicode.sort(); - glyf.unicode.forEach(function (u) { + glyf.unicode.forEach((u) => { if (checkUnicodeRepeat[u]) { error.raise({ number: 10200, @@ -105,10 +105,10 @@ export default class TTFWriter { // 构造tables ttf.support.tables = []; - ttf.writeOptions.tables.forEach(function (tableName) { - let offset = ttfSize; - let TableClass = supportTables[tableName]; - let tableSize = new TableClass().size(ttf); // 原始的表大小 + ttf.writeOptions.tables.forEach((tableName) => { + const offset = ttfSize; + const TableClass = supportTables[tableName]; + const tableSize = new TableClass().size(ttf); // 原始的表大小 let size = tableSize; // 对齐后的表大小 if (tableName === 'head') { @@ -123,15 +123,15 @@ export default class TTFWriter { ttf.support.tables.push({ name: tableName, checkSum: 0, - offset: offset, + offset, length: tableSize, - size: size + size }); ttfSize += size; }); - let writer = new Writer(new ArrayBuffer(ttfSize)); + const writer = new Writer(new ArrayBuffer(ttfSize)); // 写头部 writer.writeFixed(ttf.version); @@ -141,14 +141,14 @@ export default class TTFWriter { writer.writeUint16(ttf.rangeShift); // 写表偏移 - !new Directory().write(writer, ttf); + new Directory().write(writer, ttf); // 写支持的表数据 - ttf.support.tables.forEach(function (table) { + ttf.support.tables.forEach((table) => { - let tableStart = writer.offset; - let TableClass = supportTables[table.name]; - !new TableClass().write(writer, ttf); + const tableStart = writer.offset; + const TableClass = supportTables[table.name]; + new TableClass().write(writer, ttf); if (table.length % 4) { // 对齐字节 @@ -161,19 +161,19 @@ export default class TTFWriter { }); // 重新写入每个表校验和 - ttf.support.tables.forEach(function (table, index) { - let offset = 12 + index * 16 + 4; + ttf.support.tables.forEach((table, index) => { + const offset = 12 + index * 16 + 4; writer.writeUint32(table.checkSum, offset); }); // 写入总校验和 - let ttfCheckSum = (0xB1B0AFBA - checkSum(writer.getBuffer()) + 0x100000000) % 0x100000000; + const ttfCheckSum = (0xB1B0AFBA - checkSum(writer.getBuffer()) + 0x100000000) % 0x100000000; writer.writeUint32(ttfCheckSum, ttfHeadOffset + 8); delete ttf.writeOptions; delete ttf.support; - let buffer = writer.getBuffer(); + const buffer = writer.getBuffer(); writer.dispose(); return buffer; @@ -195,11 +195,11 @@ export default class TTFWriter { } - let tables = SUPPORT_TABLES.slice(0); + const tables = SUPPORT_TABLES.slice(0); ttf.writeOptions = {}; // hinting tables direct copy if (this.options.hinting) { - ['cvt', 'fpgm', 'prep', 'gasp', 'GPOS', 'kern'].forEach(function (table) { + ['cvt', 'fpgm', 'prep', 'gasp', 'GPOS', 'kern'].forEach((table) => { if (ttf[table]) { tables.push(table); } @@ -219,7 +219,7 @@ export default class TTFWriter { write(ttf) { this.prepareDump(ttf); this.resolveTTF(ttf); - let buffer = this.dump(ttf); + const buffer = this.dump(ttf); return buffer; } diff --git a/src/ttf/util/base642bytes.js b/src/ttf/util/base642bytes.js index 41de9ae..8720903 100644 --- a/src/ttf/util/base642bytes.js +++ b/src/ttf/util/base642bytes.js @@ -10,8 +10,8 @@ * @return {Array} 数组 */ export default function base642bytes(base64) { - let str = atob(base64); - let result = []; + const str = atob(base64); + const result = []; for (let i = 0, l = str.length; i < l; i++) { result.push(str[i].charCodeAt(0)); } diff --git a/src/ttf/util/bytes2base64.js b/src/ttf/util/bytes2base64.js index 48b76aa..32bfa0c 100644 --- a/src/ttf/util/bytes2base64.js +++ b/src/ttf/util/bytes2base64.js @@ -3,8 +3,6 @@ * @author mengke01(kekee000@gmail.com) */ -/* globals btoa */ - /** * 二进制byte流转base64编码 * @@ -18,7 +16,7 @@ export default function bytes2base64(buffer) { // ArrayBuffer if (buffer instanceof ArrayBuffer) { length = buffer.byteLength; - let view = new DataView(buffer, 0, length); + const view = new DataView(buffer, 0, length); for (i = 0; i < length; i++) { str += String.fromCharCode(view.getUint8(i, false)); } diff --git a/src/ttf/util/checkSum.js b/src/ttf/util/checkSum.js index e92037e..a2ce0c1 100644 --- a/src/ttf/util/checkSum.js +++ b/src/ttf/util/checkSum.js @@ -10,8 +10,8 @@ function checkSumArrayBuffer(buffer, offset = 0, length) { throw new Error('check sum out of bound'); } - let nLongs = Math.floor(length / 4); - let view = new DataView(buffer, offset, length); + const nLongs = Math.floor(length / 4); + const view = new DataView(buffer, offset, length); let sum = 0; let i = 0; @@ -38,7 +38,7 @@ function checkSumArray(buffer, offset = 0, length) { throw new Error('check sum out of bound'); } - let nLongs = Math.floor(length / 4); + const nLongs = Math.floor(length / 4); let sum = 0; let i = 0; diff --git a/src/ttf/util/compound2simpleglyf.js b/src/ttf/util/compound2simpleglyf.js index fc1266f..1b7bd07 100644 --- a/src/ttf/util/compound2simpleglyf.js +++ b/src/ttf/util/compound2simpleglyf.js @@ -34,11 +34,11 @@ export default function compound2simpleglyf(glyf, ttf, recrusive) { return glyf; } - let contoursList = {}; + const contoursList = {}; transformGlyfContours(glyf, ttf, contoursList, glyfIndex); if (recrusive) { - Object.keys(contoursList).forEach(function (index) { + Object.keys(contoursList).forEach((index) => { compound2simple(ttf.glyf[index], contoursList[index]); }); } diff --git a/src/ttf/util/contour2svg.js b/src/ttf/util/contour2svg.js index b538a09..deed2a2 100644 --- a/src/ttf/util/contour2svg.js +++ b/src/ttf/util/contour2svg.js @@ -15,10 +15,10 @@ export default function contour2svg(contour, precision = 2) { return ''; } - let ceil = function (number) { + const ceil = function (number) { return +(number).toFixed(precision); }; - let pathArr = []; + const pathArr = []; let curPoint; let prevPoint; let nextPoint; @@ -36,17 +36,15 @@ export default function contour2svg(contour, precision = 2) { y = curPoint.y; pathArr.push('M' + ceil(x) + ' ' + ceil(y)); } + else if (prevPoint.onCurve) { + x = prevPoint.x; + y = prevPoint.y; + pathArr.push('M' + ceil(x) + ' ' + ceil(y)); + } else { - if (prevPoint.onCurve) { - x = prevPoint.x; - y = prevPoint.y; - pathArr.push('M' + ceil(x) + ' ' + ceil(y)); - } - else { - x = (prevPoint.x + curPoint.x) / 2; - y = (prevPoint.y + curPoint.y) / 2; - pathArr.push('M' + ceil(x) + ' ' + ceil(y)); - } + x = (prevPoint.x + curPoint.x) / 2; + y = (prevPoint.y + curPoint.y) / 2; + pathArr.push('M' + ceil(x) + ' ' + ceil(y)); } } @@ -67,8 +65,8 @@ export default function contour2svg(contour, precision = 2) { y = nextPoint.y; } else { - let x1 = (curPoint.x + nextPoint.x) / 2; - let y1 = (curPoint.y + nextPoint.y) / 2; + const x1 = (curPoint.x + nextPoint.x) / 2; + const y1 = (curPoint.y + nextPoint.y) / 2; pathArr.push('q' + ceil(curPoint.x - x) + ' ' + ceil(curPoint.y - y) + ' ' + ceil(x1 - x) diff --git a/src/ttf/util/contours2svg.js b/src/ttf/util/contours2svg.js index c9266b1..7797c1b 100644 --- a/src/ttf/util/contours2svg.js +++ b/src/ttf/util/contours2svg.js @@ -18,7 +18,5 @@ export default function contours2svg(contours, precision) { return ''; } - return contours.map(function (contour) { - return contour2svg(contour, precision); - }).join(''); + return contours.map((contour) => contour2svg(contour, precision)).join(''); } diff --git a/src/ttf/util/glyf2svg.js b/src/ttf/util/glyf2svg.js index 039f4a8..4984ef0 100644 --- a/src/ttf/util/glyf2svg.js +++ b/src/ttf/util/glyf2svg.js @@ -23,7 +23,7 @@ export default function glyf2svg(glyf, ttf) { return ''; } - let pathArray = []; + const pathArray = []; if (!glyf.compound) { if (glyf.contours && glyf.contours.length) { @@ -32,7 +32,7 @@ export default function glyf2svg(glyf, ttf) { } else { - let contours = transformGlyfContours(glyf, ttf); + const contours = transformGlyfContours(glyf, ttf); if (contours && contours.length) { pathArray.push(contours2svg(contours)); } diff --git a/src/ttf/util/glyfAdjust.js b/src/ttf/util/glyfAdjust.js index 37d5115..6b19eab 100644 --- a/src/ttf/util/glyfAdjust.js +++ b/src/ttf/util/glyfAdjust.js @@ -24,26 +24,26 @@ export default function glyfAdjust(g, scaleX = 1, scaleY = 1, offsetX = 0, offse if (g.contours && g.contours.length) { if (scaleX !== 1 || scaleY !== 1) { - g.contours.forEach(function (contour) { + g.contours.forEach((contour) => { pathAdjust(contour, scaleX, scaleY); }); } if (offsetX !== 0 || offsetY !== 0) { - g.contours.forEach(function (contour) { + g.contours.forEach((contour) => { pathAdjust(contour, 1, 1, offsetX, offsetY); }); } if (false !== useCeil) { - g.contours.forEach(function (contour) { + g.contours.forEach((contour) => { pathCeil(contour); }); } } // 重新计算xmin,xmax,ymin,ymax - let advanceWidth = g.advanceWidth; + const advanceWidth = g.advanceWidth; if ( undefined === g.xMin || undefined === g.yMax @@ -53,6 +53,7 @@ export default function glyfAdjust(g, scaleX = 1, scaleY = 1, offsetX = 0, offse // 有的字形没有形状,需要特殊处理一下 let bound; if (g.contours && g.contours.length) { + // eslint-disable-next-line no-invalid-this bound = computePathBox.apply(this, g.contours); } else { diff --git a/src/ttf/util/optimizettf.js b/src/ttf/util/optimizettf.js index b14c200..34d984a 100644 --- a/src/ttf/util/optimizettf.js +++ b/src/ttf/util/optimizettf.js @@ -14,17 +14,15 @@ import pathCeil from '../../graphics/pathCeil'; */ export default function optimizettf(ttf) { - let checkUnicodeRepeat = {}; // 检查是否有重复代码点 - let repeatList = []; + const checkUnicodeRepeat = {}; // 检查是否有重复代码点 + const repeatList = []; - ttf.glyf.forEach(function (glyf, index) { + ttf.glyf.forEach((glyf, index) => { if (glyf.unicode) { glyf.unicode = glyf.unicode.sort(); // 将glyf的代码点按小到大排序 - glyf.unicode.sort(function (a, b) { - return a - b; - }).forEach(function (u) { + glyf.unicode.sort((a, b) => a - b).forEach((u) => { if (checkUnicodeRepeat[u]) { repeatList.push(index); } @@ -37,7 +35,7 @@ export default function optimizettf(ttf) { if (!glyf.compound && glyf.contours) { // 整数化 - glyf.contours.forEach(function (contour) { + glyf.contours.forEach((contour) => { pathCeil(contour); }); // 缩减glyf @@ -54,12 +52,8 @@ export default function optimizettf(ttf) { }); // 过滤无轮廓字体,如果存在复合字形不进行过滤 - if (!ttf.glyf.some(function (a) { - return a.compound; - })) { - ttf.glyf = ttf.glyf.filter(function (glyf, index) { - return index === 0 || glyf.contours && glyf.contours.length; - }); + if (!ttf.glyf.some((a) => a.compound)) { + ttf.glyf = ttf.glyf.filter((glyf, index) => index === 0 || glyf.contours && glyf.contours.length); } if (!repeatList.length) { diff --git a/src/ttf/util/otfContours2ttfContours.js b/src/ttf/util/otfContours2ttfContours.js index 8e925c0..36fce44 100644 --- a/src/ttf/util/otfContours2ttfContours.js +++ b/src/ttf/util/otfContours2ttfContours.js @@ -13,7 +13,7 @@ import pathCeil from '../../graphics/pathCeil'; * @return {Array} ttf轮廓 */ function transformContour(otfContour) { - let contour = []; + const contour = []; let prevPoint; let curPoint; let nextPoint; @@ -31,7 +31,7 @@ function transformContour(otfContour) { else { nextPoint = otfContour[i + 1]; nextNextPoint = i === l - 2 ? otfContour[0] : otfContour[i + 2]; - let bezierArray = bezierCubic2Q2(prevPoint, curPoint, nextPoint, nextNextPoint); + const bezierArray = bezierCubic2Q2(prevPoint, curPoint, nextPoint, nextNextPoint); bezierArray[0][2].onCurve = true; contour.push(bezierArray[0][1]); contour.push(bezierArray[0][2]); @@ -62,7 +62,7 @@ export default function otfContours2ttfContours(otfContours) { if (!otfContours || !otfContours.length) { return otfContours; } - let contours = []; + const contours = []; for (let i = 0, l = otfContours.length; i < l; i++) { // 这里可能由于转换错误导致空轮廓,需要去除 diff --git a/src/ttf/util/readWindowsAllCodes.js b/src/ttf/util/readWindowsAllCodes.js index 8d1c190..121a76e 100644 --- a/src/ttf/util/readWindowsAllCodes.js +++ b/src/ttf/util/readWindowsAllCodes.js @@ -1,3 +1,5 @@ +/* eslint-disable */ + /** * @file 读取windows支持的字符集 * @author mengke01(kekee000@gmail.com) @@ -6,8 +8,6 @@ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cmap.html */ -/* eslint-disable fecs-valid-map-set */ - /** * 读取ttf中windows字符表的字符 * diff --git a/src/ttf/util/reduceGlyf.js b/src/ttf/util/reduceGlyf.js index 1d3bb3f..9701cf3 100644 --- a/src/ttf/util/reduceGlyf.js +++ b/src/ttf/util/reduceGlyf.js @@ -13,7 +13,7 @@ import reducePath from '../../graphics/reducePath'; */ export default function reduceGlyf(glyf) { - let contours = glyf.contours; + const contours = glyf.contours; let contour; for (let j = contours.length - 1; j >= 0; j--) { contour = reducePath(contours[j]); diff --git a/src/ttf/util/string.js b/src/ttf/util/string.js index a2c8893..d1a8ffc 100644 --- a/src/ttf/util/string.js +++ b/src/ttf/util/string.js @@ -34,7 +34,7 @@ function stringify(str) { export default { - stringify: stringify, + stringify, /** * 将双字节编码字符转换成`\uxxxx`形式 @@ -46,9 +46,7 @@ export default { if (!str) { return str; } - return String(str).replace(/[\uff-\uffff]/g, function (c) { - return escape(c).replace('%', '\\'); - }); + return String(str).replace(/[\uff-\uffff]/g, c => escape(c).replace('%', '\\')); }, /** @@ -72,7 +70,7 @@ export default { * @return {string} 名字 */ getUnicodeName(unicode) { - let unicodeNameIndex = unicodeName[unicode]; + const unicodeNameIndex = unicodeName[unicode]; if (undefined !== unicodeNameIndex) { return postName[unicodeNameIndex]; } @@ -88,17 +86,17 @@ export default { */ toUTF8Bytes(str) { str = stringify(str); - let byteArray = []; + const byteArray = []; for (let i = 0, l = str.length; i < l; i++) { if (str.charCodeAt(i) <= 0x7F) { byteArray.push(str.charCodeAt(i)); } else { - let codePoint = str.codePointAt(i) - if(codePoint > 0xffff) { - i = i + 1; + const codePoint = str.codePointAt(i); + if (codePoint > 0xffff) { + i++; } - let h = encodeURIComponent(String.fromCodePoint(codePoint)).slice(1).split('%'); + const h = encodeURIComponent(String.fromCodePoint(codePoint)).slice(1).split('%'); for (let j = 0; j < h.length; j++) { byteArray.push(parseInt(h[j], 16)); } @@ -115,7 +113,7 @@ export default { */ toUCS2Bytes(str) { str = stringify(str); - let byteArray = []; + const byteArray = []; for (let i = 0, l = str.length, ch; i < l; i++) { ch = str.charCodeAt(i); @@ -134,12 +132,12 @@ export default { * @return {Array.} byteArray byte数组 */ toPascalStringBytes(str) { - let bytes = []; - let length = str ? (str.length < 256 ? str.length : 255) : 0; + const bytes = []; + const length = str ? (str.length < 256 ? str.length : 255) : 0; bytes.push(length); for (let i = 0, l = str.length; i < l; i++) { - let c = str.charCodeAt(i); + const c = str.charCodeAt(i); // non-ASCII characters are substituted with '*' bytes.push(c < 128 ? c : 42); } @@ -188,9 +186,9 @@ export default { * @return {Array.} 读取后的字符串数组 */ getPascalString(byteArray) { - let strArray = []; + const strArray = []; let i = 0; - let l = byteArray.length; + const l = byteArray.length; while (i < l) { let strLength = byteArray[i++]; diff --git a/src/ttf/util/transformGlyfContours.js b/src/ttf/util/transformGlyfContours.js index 6ebe67c..943ed5f 100644 --- a/src/ttf/util/transformGlyfContours.js +++ b/src/ttf/util/transformGlyfContours.js @@ -23,9 +23,9 @@ export default function transformGlyfContours(glyf, ttf, contoursList = {}, glyf return glyf; } - let compoundContours = []; - glyf.glyfs.forEach(function (g) { - let glyph = ttf.glyf[g.glyphIndex]; + const compoundContours = []; + glyf.glyfs.forEach(g => { + const glyph = ttf.glyf[g.glyphIndex]; if (!glyph || glyph === glyf) { return; @@ -37,8 +37,8 @@ export default function transformGlyfContours(glyf, ttf, contoursList = {}, glyf } // 这里需要进行matrix变换,需要复制一份 - let contours = clone(glyph.compound ? (contoursList[g.glyphIndex] || []) : glyph.contours); - let transform = g.transform; + const contours = clone(glyph.compound ? (contoursList[g.glyphIndex] || []) : glyph.contours); + const transform = g.transform; for (let i = 0, l = contours.length; i < l; i++) { pathTransform( contours[i], @@ -53,6 +53,7 @@ export default function transformGlyfContours(glyf, ttf, contoursList = {}, glyf } }); + // eslint-disable-next-line eqeqeq if (null != glyfIndex) { contoursList[glyfIndex] = compoundContours; } diff --git a/src/ttf/util/unicode2xml.js b/src/ttf/util/unicode2xml.js index b019329..8c5596e 100644 --- a/src/ttf/util/unicode2xml.js +++ b/src/ttf/util/unicode2xml.js @@ -14,7 +14,7 @@ export default function unicode2xml(unicodeList) { if (typeof unicodeList === 'number') { unicodeList = [unicodeList]; } - return unicodeList.map(function (u) { + return unicodeList.map(u => { if (u < 0x20) { return ''; } diff --git a/src/ttf/woff2tottf.js b/src/ttf/woff2tottf.js index ff16c74..efc1044 100644 --- a/src/ttf/woff2tottf.js +++ b/src/ttf/woff2tottf.js @@ -13,11 +13,12 @@ import woff2 from '../../woff2/index'; * * @return {ArrayBuffer} woff格式byte流 */ +// eslint-disable-next-line no-unused-vars export default function woff2tottf(woff2Buffer, options = {}) { if (!woff2.isInited()) { throw new Error('use woff2.init() to init woff2 module!'); } - let result = woff2.decode(woff2Buffer); + const result = woff2.decode(woff2Buffer); return result.buffer; } @@ -30,8 +31,8 @@ export default function woff2tottf(woff2Buffer, options = {}) { * @return {Promise.} woff格式byte流 */ export function woff2tottfasync(woff2Buffer, options = {}) { - return woff2.init(options.wasmUrl).then(function () { - let result = woff2.decode(woff2Buffer); + return woff2.init(options.wasmUrl).then(() => { + const result = woff2.decode(woff2Buffer); return result.buffer; }); } diff --git a/src/ttf/woff2ttf.js b/src/ttf/woff2ttf.js index 797bebc..5e9e9f8 100644 --- a/src/ttf/woff2ttf.js +++ b/src/ttf/woff2ttf.js @@ -17,18 +17,18 @@ import error from './error'; * @return {ArrayBuffer} ttf格式byte流 */ export default function woff2ttf(woffBuffer, options = {}) { - let reader = new Reader(woffBuffer); - let signature = reader.readUint32(0); - let flavor = reader.readUint32(4); + const reader = new Reader(woffBuffer); + const signature = reader.readUint32(0); + const flavor = reader.readUint32(4); if (signature !== 0x774F4646 || (flavor !== 0x10000 && flavor !== 0x4f54544f)) { reader.dispose(); error.raise(10102); } - let numTables = reader.readUint16(12); - let ttfSize = reader.readUint32(16); - let tableEntries = []; + const numTables = reader.readUint16(12); + const ttfSize = reader.readUint32(16); + const tableEntries = []; let tableEntry; let i; let l; @@ -45,7 +45,7 @@ export default function woff2ttf(woffBuffer, options = {}) { }; // ttf 表数据 - let deflateData = reader.readBytes(tableEntry.offset, tableEntry.compLength); + const deflateData = reader.readBytes(tableEntry.offset, tableEntry.compLength); // 需要解压 if (deflateData.length < tableEntry.length) { @@ -65,11 +65,11 @@ export default function woff2ttf(woffBuffer, options = {}) { } - let writer = new Writer(new ArrayBuffer(ttfSize)); + const writer = new Writer(new ArrayBuffer(ttfSize)); // 写头部 - let entrySelector = Math.floor(Math.log(numTables) / Math.LN2); - let searchRange = Math.pow(2, entrySelector) * 16; - let rangeShift = numTables * 16 - searchRange; + const entrySelector = Math.floor(Math.log(numTables) / Math.LN2); + const searchRange = Math.pow(2, entrySelector) * 16; + const rangeShift = numTables * 16 - searchRange; writer.writeUint32(flavor); writer.writeUint16(numTables); diff --git a/src/ttf/writer.js b/src/ttf/writer.js index 902ae0c..6b438a4 100644 --- a/src/ttf/writer.js +++ b/src/ttf/writer.js @@ -35,7 +35,7 @@ const dataType = { */ class Writer { constructor(buffer, offset, length, littleEndian) { - let bufferLength = buffer.byteLength || buffer.length; + const bufferLength = buffer.byteLength || buffer.length; this.offset = offset || 0; this.length = length || (bufferLength - this.offset); this.littleEndian = littleEndian || false; @@ -69,7 +69,7 @@ class Writer { return this['write' + type](value, offset, littleEndian); } - let size = dataType[type]; + const size = dataType[type]; this.offset = offset + size; this.view['set' + type](offset, value, littleEndian); return this; @@ -100,9 +100,9 @@ class Writer { error.raise(10002, this.length, offset + length); } - let littleEndian = this.littleEndian; + const littleEndian = this.littleEndian; if (value instanceof ArrayBuffer) { - let view = new DataView(value, 0, length); + const view = new DataView(value, 0, length); for (i = 0; i < length; ++i) { this.view.setUint8(offset + i, view.getUint8(i, littleEndian), littleEndian); } @@ -135,7 +135,7 @@ class Writer { offset = this.offset; } - let littleEndian = this.littleEndian; + const littleEndian = this.littleEndian; for (let i = 0; i < length; ++i) { this.view.setUint8(offset + i, 0, littleEndian); } @@ -160,6 +160,7 @@ class Writer { offset = this.offset; } + // eslint-disable-next-line no-control-regex length = length || str.replace(/[^\x00-\xff]/g, '11').length; if (length < 0 || offset + length > this.length) { @@ -227,7 +228,7 @@ class Writer { } // new Date(1970, 1, 1).getTime() - new Date(1904, 1, 1).getTime(); - let delta = -2077545600000; + const delta = -2077545600000; if (typeof value === 'undefined') { value = delta; @@ -242,7 +243,7 @@ class Writer { value = Date.parse(value); } - let time = Math.round((value - delta) / 1000); + const time = Math.round((value - delta) / 1000); this.writeUint32(0, offset); this.writeUint32(time, offset + 4); @@ -298,7 +299,7 @@ class Writer { } // 直接支持的数据类型 -Object.keys(dataType).forEach(function (type) { +Object.keys(dataType).forEach(type => { Writer.prototype['write' + type] = curry(Writer.prototype.write, type); });