UNPKG

fonteditor-core

Version:

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

165 lines (160 loc) 4.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.computePath = exports.computeBounding = void 0; exports.computePathBox = computePathBox; exports.quadraticBezier = void 0; var _pathIterator = _interopRequireDefault(require("./pathIterator")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @file 计算曲线包围盒 * @author mengke01(kekee000@gmail.com) * * modify from: * zrender * https://github.com/ecomfe/zrender/blob/master/src/tool/computeBoundingBox.js */ /** * 计算包围盒 * * @param {Array} points 点集 * @return {Object} bounding box */ function computeBoundingBox(points) { if (points.length === 0) { return false; } var left = points[0].x; var right = points[0].x; var top = points[0].y; var bottom = points[0].y; for (var i = 1; i < points.length; i++) { var p = points[i]; if (p.x < left) { left = p.x; } if (p.x > right) { right = p.x; } if (p.y < top) { top = p.y; } if (p.y > bottom) { bottom = p.y; } } return { x: left, y: top, width: right - left, height: bottom - top }; } /** * 计算二阶贝塞尔曲线的包围盒 * http://pissang.net/blog/?p=91 * * @param {Object} p0 p0 * @param {Object} p1 p1 * @param {Object} p2 p2 * @return {Object} bound对象 */ function computeQuadraticBezierBoundingBox(p0, p1, p2) { // Find extremities, where derivative in x dim or y dim is zero var tmp = p0.x + p2.x - 2 * p1.x; // p1 is center of p0 and p2 in x dim var t1; if (tmp === 0) { t1 = 0.5; } else { t1 = (p0.x - p1.x) / tmp; } tmp = p0.y + p2.y - 2 * p1.y; // p1 is center of p0 and p2 in y dim var t2; if (tmp === 0) { t2 = 0.5; } else { t2 = (p0.y - p1.y) / tmp; } t1 = Math.max(Math.min(t1, 1), 0); t2 = Math.max(Math.min(t2, 1), 0); var ct1 = 1 - t1; var ct2 = 1 - t2; var x1 = ct1 * ct1 * p0.x + 2 * ct1 * t1 * p1.x + t1 * t1 * p2.x; var y1 = ct1 * ct1 * p0.y + 2 * ct1 * t1 * p1.y + t1 * t1 * p2.y; var x2 = ct2 * ct2 * p0.x + 2 * ct2 * t2 * p1.x + t2 * t2 * p2.x; var y2 = ct2 * ct2 * p0.y + 2 * ct2 * t2 * p1.y + t2 * t2 * p2.y; return computeBoundingBox([p0, p2, { x: x1, y: y1 }, { x: x2, y: y2 }]); } /** * 计算曲线包围盒 * * @private * @param {...Array} args 坐标点集, 支持多个path * @return {Object} {x, y, width, height} */ function computePathBoundingBox() { var points = []; var iterator = function iterator(c, p0, p1, p2) { if (c === 'L') { points.push(p0); points.push(p1); } else if (c === 'Q') { var bound = computeQuadraticBezierBoundingBox(p0, p1, p2); points.push(bound); points.push({ x: bound.x + bound.width, y: bound.y + bound.height }); } }; if (arguments.length === 1) { (0, _pathIterator.default)(arguments.length <= 0 ? undefined : arguments[0], function (c, p0, p1, p2) { if (c === 'L') { points.push(p0); points.push(p1); } else if (c === 'Q') { var bound = computeQuadraticBezierBoundingBox(p0, p1, p2); points.push(bound); points.push({ x: bound.x + bound.width, y: bound.y + bound.height }); } }); } else { for (var i = 0, l = arguments.length; i < l; i++) { (0, _pathIterator.default)(i < 0 || arguments.length <= i ? undefined : arguments[i], iterator); } } return computeBoundingBox(points); } /** * 计算曲线点边界 * * @private * @param {...Array} args path对象, 支持多个path * @return {Object} {x, y, width, height} */ function computePathBox() { var points = []; if (arguments.length === 1) { points = arguments.length <= 0 ? undefined : arguments[0]; } else { for (var i = 0, l = arguments.length; i < l; i++) { Array.prototype.splice.apply(points, [points.length, 0].concat(i < 0 || arguments.length <= i ? undefined : arguments[i])); } } return computeBoundingBox(points); } var computeBounding = exports.computeBounding = computeBoundingBox; var quadraticBezier = exports.quadraticBezier = computeQuadraticBezierBoundingBox; var computePath = exports.computePath = computePathBoundingBox;