From eb44cd6215f8a46f51ed4d68f508f8c4c87afb2c Mon Sep 17 00:00:00 2001 From: Shaunak Kishore Date: Mon, 7 Sep 2015 00:10:22 -0400 Subject: [PATCH] Make split_and_orient_path robust to edge cases --- lib/glyphs.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/glyphs.js b/lib/glyphs.js index e5a21c27..22268ac8 100644 --- a/lib/glyphs.js +++ b/lib/glyphs.js @@ -17,13 +17,24 @@ Glyphs.get_svg_path = function(glyph) { // Error out if the condition does not hold. function assert(condition, message) { - if (!condition) throw new Error(message); + if (!condition) { + console.error(message); + throw new Error; + } } function clone(point) { return [point[0], point[1]]; } +function equal(point1, point2) { + return point1[0] === point2[0] && point1[1] === point2[1]; +} + +function valid(point) { + return point[0] !== undefined && point[1] !== undefined; +} + // Takes a non-empty list of SVG commands that may contain multiple contours. // Returns a list of lists of path segment objects that each form one contour. // Each path segment has three keys: start, end, and control. @@ -35,6 +46,7 @@ function split_path(path) { var result = [[]]; var start = [path[0].x, path[0].y]; var current = clone(start); + assert(valid(current)); for (var i = 1; i < path.length; i++) { var command = path[i]; @@ -45,16 +57,27 @@ function split_path(path) { assert(i === path.length - 1, 'Path ended early!'); return result; } - var start = {x: command.x, y: command.y}; - var current = {x: start_point.x, y: start_point.y}; + var start = [command.x, command.y]; + var current = clone(start); + assert(valid(current)); continue; } - assert(command.type === 'Q', 'Got unexpected TTF command: ' + command.type); + assert(command.type === 'Q' || command.type === 'L', + 'Got unexpected TTF command: ' + command.type); var segment = { 'start': clone(current), 'end': [command.x, command.y], 'control': [command.x1, command.y1], }; + assert(valid(segment.end)); + if (equal(segment.start, segment.end)) { + continue; + } + if (!valid(segment.control) || + equal(segment.start, segment.control) || + equal(segment.end, segment.control)) { + delete segment.control; + } result[result.length - 1].push(segment); current = clone(segment.end); }