UNPKG

svg2ttf

Version:

Converts SVG font to TTF font

130 lines (109 loc) 3.46 kB
'use strict' var _ = require('lodash') var math = require('../math') // Remove points, that looks like straight line function simplify (contours, accuracy) { return _.map(contours, function (contour) { var i, curr, prev, next var p, pPrev, pNext // run from the end, to simplify array elements removal for (i = contour.length - 2; i > 1; i--) { prev = contour[i - 1] next = contour[i + 1] curr = contour[i] // skip point (both oncurve & offcurve), // if [prev,next] is straight line if (prev.onCurve && next.onCurve) { p = new math.Point(curr.x, curr.y) pPrev = new math.Point(prev.x, prev.y) pNext = new math.Point(next.x, next.y) if (math.isInLine(pPrev, p, pNext, accuracy)) { contour.splice(i, 1) } } } return contour }) } // Remove interpolateable oncurve points // Those should be in the middle of nebor offcurve points function interpolate (contours, accuracy) { return _.map(contours, function (contour) { var resContour = [] _.forEach(contour, function (point, idx) { // Never skip first and last points if (idx === 0 || idx === (contour.length - 1)) { resContour.push(point) return } var prev = contour[idx - 1] var next = contour[idx + 1] var p, pPrev, pNext // skip interpolateable oncurve points (if exactly between previous and next offcurves) if (!prev.onCurve && point.onCurve && !next.onCurve) { p = new math.Point(point.x, point.y) pPrev = new math.Point(prev.x, prev.y) pNext = new math.Point(next.x, next.y) if (pPrev.add(pNext).div(2).sub(p).dist() < accuracy) { return } } // keep the rest resContour.push(point) }) return resContour }) } function roundPoints (contours) { return _.map(contours, function (contour) { return _.map(contour, function (point) { return { x: Math.round(point.x), y: Math.round(point.y), onCurve: point.onCurve } }) }) } // Remove closing point if it is the same as first point of contour. // TTF doesn't need this point when drawing contours. function removeClosingReturnPoints (contours) { return _.map(contours, function (contour) { var length = contour.length if (length > 1 && contour[0].x === contour[length - 1].x && contour[0].y === contour[length - 1].y) { contour.splice(length - 1) } return contour }) } function toRelative (contours) { var prevPoint = { x: 0, y: 0 } var resContours = [] var resContour _.forEach(contours, function (contour) { resContour = [] resContours.push(resContour) _.forEach(contour, function (point) { resContour.push({ x: point.x - prevPoint.x, y: point.y - prevPoint.y, onCurve: point.onCurve }) prevPoint = point }) }) return resContours } function identifier (string, littleEndian) { var result = 0 for (var i = 0; i < string.length; i++) { result = result << 8 var index = littleEndian ? string.length - i - 1 : i result += string.charCodeAt(index) } return result } module.exports.interpolate = interpolate module.exports.simplify = simplify module.exports.roundPoints = roundPoints module.exports.removeClosingReturnPoints = removeClosingReturnPoints module.exports.toRelative = toRelative module.exports.identifier = identifier