UNPKG

fonteditor-core

Version:

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

170 lines (162 loc) 3.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.clone = clone; exports.deInterpolate = deInterpolate; exports.getPathHash = getPathHash; exports.interpolate = interpolate; exports.isClockWise = isClockWise; exports.makeLink = makeLink; exports.removeOverlapPoints = removeOverlapPoints; exports.scale = scale; var _util = require("./util"); /** * @file 路径相关的函数集合 * @author mengke01(kekee000@gmail.com) */ /** * 对路径进行插值,补全省略的点 * * @param {Array} path 路径 * @return {Array} 路径 */ function interpolate(path) { var newPath = []; for (var i = 0, l = path.length; i < l; i++) { var next = i === l - 1 ? 0 : i + 1; newPath.push(path[i]); // 插值 if (!path[i].onCurve && !path[next].onCurve) { newPath.push({ x: (path[i].x + path[next].x) / 2, y: (path[i].y + path[next].y) / 2, onCurve: true }); } } return newPath; } /** * 去除路径中的插值点 * * @param {Array} path 路径 * @return {Array} 路径 */ function deInterpolate(path) { var newPath = []; for (var i = 0, l = path.length; i < l; i++) { var next = i === l - 1 ? 0 : i + 1; var prev = i === 0 ? l - 1 : i - 1; // 插值 if (!path[prev].onCurve && path[i].onCurve && !path[next].onCurve && Math.abs(2 * path[i].x - path[prev].x - path[next].x) < 0.001 && Math.abs(2 * path[i].y - path[prev].y - path[next].y) < 0.001) { continue; } newPath.push(path[i]); } return newPath; } /** * 判断路径的方向是否顺时针 * * see: * http://debian.fmi.uni-sofia.bg/~sergei/cgsr/docs/clockwise.htm * * @param {Array} path 路径 * @return {number} 0 无方向 1 clockwise, -1 counter clockwise */ function isClockWise(path) { if (path.length < 3) { return 0; } var zCount = 0; for (var i = 0, l = path.length; i < l; i++) { var cur = path[i]; var prev = i === 0 ? path[l - 1] : path[i - 1]; var next = i === l - 1 ? path[0] : path[i + 1]; var z = (cur.x - prev.x) * (next.y - cur.y) - (cur.y - prev.y) * (next.x - cur.x); if (z < 0) { zCount--; } else if (z > 0) { zCount++; } } return zCount === 0 ? 0 : zCount < 0 ? 1 : -1; } /** * 获取路径哈希 * * @param {Array} path 路径数组 * @return {number} 哈希值 */ function getPathHash(path) { var hash = 0; var seed = 131; path.forEach(function (p) { hash = 0x7FFFFFFF & hash * seed + (0, _util.getPointHash)(p) + (p.onCurve ? 1 : 0); }); return hash; } /** * 移除重复点 * * @param {Array} points 点集合 * @return {Array} 移除后点集合 */ function removeOverlapPoints(points) { var hash = {}; var ret = []; for (var i = 0, l = points.length; i < l; i++) { var hashcode = points[i].x * 31 + points[i].y; if (!hash[hashcode]) { ret.push(points[i]); hash[hashcode] = 1; } } return ret; } /** * 对path进行双向链表连接 * * @param {Array} path 轮廓数组 * @return {Array} path */ function makeLink(path) { for (var i = 0, l = path.length; i < l; i++) { var cur = path[i]; var prev = i === 0 ? path[l - 1] : path[i - 1]; var next = i === l - 1 ? path[0] : path[i + 1]; cur.index = i; cur.next = next; cur.prev = prev; } return path; } /** * 对path进行缩放 * * @param {Array} path 轮廓数组 * @param {number} ratio 缩放大小 * * @return {Array} path */ function scale(path, ratio) { for (var i = 0, l = path.length; i < l; i++) { var cur = path[i]; cur.x *= ratio; cur.y *= ratio; } return path; } function clone(path) { return path ? path.map(function (p) { var newP = { x: p.x, y: p.y }; if (p.onCurve) { newP.onCurve = true; } return newP; }) : path; }