Socket
Socket
Sign inDemoInstall

svg-pathdata

Package Overview
Dependencies
0
Maintainers
3
Versions
34
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.0.1 to 5.0.0

.idea/codeStyles/codeStyleConfig.xml

5

CHANGELOG.md

@@ -0,1 +1,6 @@

<a name="5.0.0"></a>
# [5.0.0](https://github.com/nfroidure/svg-pathdata/compare/v4.0.0...v5.0.0) (2018-06-02)
<a name="4.0.1"></a>

@@ -2,0 +7,0 @@ ## [4.0.1](https://github.com/nfroidure/svg-pathdata/compare/v4.0.0...v4.0.1) (2017-08-22)

2

lib/mathUtils.d.ts

@@ -22,3 +22,3 @@ import { CommandA, CommandC } from "./SVGPathData";

*/
export declare function intersectionUnitCircleLine(a: number, b: number, c: number): number[][];
export declare function intersectionUnitCircleLine(a: number, b: number, c: number): Array<[number, number]>;
export declare const DEG: number;

@@ -25,0 +25,0 @@ export declare function lerp(a: number, b: number, t: number): number;

@@ -158,2 +158,3 @@ "use strict";

function a2c(arc, x0, y0) {
var _a, _b, _c, _d;
if (!arc.cX) {

@@ -172,8 +173,8 @@ annotateArcCommand(arc, x0, y0);

// x1/y1, x2/y2 and x/y coordinates on the unit circle for phiStart/phiEnd
var _a = [
var _e = [
Math.cos(phiStart * exports.DEG) - f * Math.sin(phiStart * exports.DEG),
Math.sin(phiStart * exports.DEG) + f * Math.cos(phiStart * exports.DEG)
], x1 = _a[0], y1 = _a[1];
var _b = [Math.cos(phiEnd * exports.DEG), Math.sin(phiEnd * exports.DEG)], x = _b[0], y = _b[1];
var _c = [x + f * Math.sin(phiEnd * exports.DEG), y - f * Math.cos(phiEnd * exports.DEG)], x2 = _c[0], y2 = _c[1];
], x1 = _e[0], y1 = _e[1];
var _f = [Math.cos(phiEnd * exports.DEG), Math.sin(phiEnd * exports.DEG)], x = _f[0], y = _f[1];
var _g = [x + f * Math.sin(phiEnd * exports.DEG), y - f * Math.cos(phiEnd * exports.DEG)], x2 = _g[0], y2 = _g[1];
result[i] = { relative: arc.relative, type: SVGPathData_1.SVGPathData.CURVE_TO };

@@ -184,5 +185,5 @@ var transform = function (x, y) {

};
_d = transform(x1, y1), result[i].x1 = _d[0], result[i].y1 = _d[1];
_e = transform(x2, y2), result[i].x2 = _e[0], result[i].y2 = _e[1];
_f = transform(x, y), result[i].x = _f[0], result[i].y = _f[1];
_a = transform(x1, y1), result[i].x1 = _a[0], result[i].y1 = _a[1];
_b = transform(x2, y2), result[i].x2 = _b[0], result[i].y2 = _b[1];
_c = transform(x, y), result[i].x = _c[0], result[i].y = _c[1];
if (arc.relative) {

@@ -196,8 +197,7 @@ result[i].x1 -= prevX;

}
_g = [result[i].x, result[i].y], prevX = _g[0], prevY = _g[1];
_d = [result[i].x, result[i].y], prevX = _d[0], prevY = _d[1];
}
return result;
var _d, _e, _f, _g;
}
exports.a2c = a2c;
//# sourceMappingURL=mathUtils.js.map

@@ -0,1 +1,2 @@

import { TransformableSVG } from "./TransformableSVG";
export declare type CommandM = {

@@ -24,3 +25,2 @@ relative: boolean;

export declare type CommandZ = {
relative: boolean;
type: typeof SVGPathData.CLOSE_PATH;

@@ -77,23 +77,6 @@ };

export declare type TransformFunction = (input: SVGCommand) => SVGCommand | SVGCommand[];
export declare class SVGPathData {
export declare class SVGPathData extends TransformableSVG {
commands: SVGCommand[];
constructor(content: string | SVGCommand[]);
encode(): string;
round(x?: number): this;
toAbs(): this;
toRel(): this;
normalizeHVZ(a?: boolean, b?: boolean, c?: boolean): this;
normalizeST(): this;
qtToC(): this;
aToC(): this;
sanitize(eps?: number): this;
translate(x: number, y?: number): this;
scale(x: number, y?: number): this;
rotate(a: number, x?: number, y?: number): this;
matrix(a: number, b: number, c: number, d: number, e: number, f: number): this;
skewX(a: number): this;
skewY(a: number): this;
xSymmetry(xOffset?: number): this;
ySymmetry(yOffset?: number): this;
annotateArcs(): this;
getBounds(): TransformFunction & {

@@ -107,3 +90,3 @@ minX: number;

static encode(commands: SVGCommand[]): string;
static parse(content: string): SVGCommand[];
static parse(path: string): SVGCommand[];
static readonly CLOSE_PATH: 1;

@@ -122,5 +105,5 @@ static readonly MOVE_TO: 2;

}
import { SVGPathDataEncoder } from "./SVGPathDataEncoder";
import { encodeSVGPath } from "./SVGPathDataEncoder";
import { SVGPathDataParser } from "./SVGPathDataParser";
import { SVGPathDataTransformer } from "./SVGPathDataTransformer";
export { SVGPathDataEncoder, SVGPathDataParser, SVGPathDataTransformer };
export { encodeSVGPath, SVGPathDataParser, SVGPathDataTransformer };
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var SVGPathData = (function () {
var TransformableSVG_1 = require("./TransformableSVG");
var SVGPathData = /** @class */ (function (_super) {
__extends(SVGPathData, _super);
function SVGPathData(content) {
var _this = _super.call(this) || this;
if ("string" === typeof content) {
this.commands = SVGPathData.parse(content);
_this.commands = SVGPathData.parse(content);
}
else {
this.commands = content;
_this.commands = content;
}
return _this;
}

@@ -15,53 +29,2 @@ SVGPathData.prototype.encode = function () {

};
SVGPathData.prototype.round = function (x) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.ROUND(x));
};
SVGPathData.prototype.toAbs = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.TO_ABS());
};
SVGPathData.prototype.toRel = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.TO_REL());
};
SVGPathData.prototype.normalizeHVZ = function (a, b, c) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.NORMALIZE_HVZ(a, b, c));
};
SVGPathData.prototype.normalizeST = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.NORMALIZE_ST());
};
SVGPathData.prototype.qtToC = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.QT_TO_C());
};
SVGPathData.prototype.aToC = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.A_TO_C());
};
SVGPathData.prototype.sanitize = function (eps) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.SANITIZE(eps));
};
SVGPathData.prototype.translate = function (x, y) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.TRANSLATE(x, y));
};
SVGPathData.prototype.scale = function (x, y) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.SCALE(x, y));
};
SVGPathData.prototype.rotate = function (a, x, y) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.ROTATE(a, x, y));
};
SVGPathData.prototype.matrix = function (a, b, c, d, e, f) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.MATRIX(a, b, c, d, e, f));
};
SVGPathData.prototype.skewX = function (a) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.SKEW_X(a));
};
SVGPathData.prototype.skewY = function (a) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.SKEW_Y(a));
};
SVGPathData.prototype.xSymmetry = function (xOffset) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.X_AXIS_SYMMETRY(xOffset));
};
SVGPathData.prototype.ySymmetry = function (yOffset) {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.Y_AXIS_SYMMETRY(yOffset));
};
SVGPathData.prototype.annotateArcs = function () {
return this.transform(SVGPathDataTransformer_1.SVGPathDataTransformer.ANNOTATE_ARCS());
};
SVGPathData.prototype.getBounds = function () {

@@ -77,3 +40,3 @@ var boundsTransform = SVGPathDataTransformer_1.SVGPathDataTransformer.CALCULATE_BOUNDS();

var transformedCommand = transformFunction(command);
if (transformedCommand instanceof Array) {
if (Array.isArray(transformedCommand)) {
newCommands.push.apply(newCommands, transformedCommand);

@@ -89,25 +52,9 @@ }

SVGPathData.encode = function (commands) {
var content = "";
var encoder = new SVGPathDataEncoder_1.SVGPathDataEncoder();
encoder.on("readable", function () {
var str;
while (null !== (str = encoder.read())) {
content += str;
}
});
encoder.write(commands);
encoder.end();
return content;
return SVGPathDataEncoder_1.encodeSVGPath(commands);
};
SVGPathData.parse = function (content) {
SVGPathData.parse = function (path) {
var parser = new SVGPathDataParser_1.SVGPathDataParser();
var commands = [];
var parser = new SVGPathDataParser_1.SVGPathDataParser();
parser.on("readable", function () {
var command;
while (null !== (command = parser.read())) {
commands.push(command);
}
});
parser.write(content);
parser.end();
parser.parse(path, commands);
parser.finish(commands);
return commands;

@@ -130,6 +77,6 @@ };

return SVGPathData;
}());
}(TransformableSVG_1.TransformableSVG));
exports.SVGPathData = SVGPathData;
var SVGPathDataEncoder_1 = require("./SVGPathDataEncoder");
exports.SVGPathDataEncoder = SVGPathDataEncoder_1.SVGPathDataEncoder;
exports.encodeSVGPath = SVGPathDataEncoder_1.encodeSVGPath;
var SVGPathDataParser_1 = require("./SVGPathDataParser");

@@ -136,0 +83,0 @@ exports.SVGPathDataParser = SVGPathDataParser_1.SVGPathDataParser;

@@ -1,7 +0,2 @@

/// <reference types="node" />
import { Transform } from "stream";
import { SVGCommand } from "./SVGPathData";
export declare class SVGPathDataEncoder extends Transform {
constructor();
_transform(commands: SVGCommand | SVGCommand[], encoding: string, done: () => void): void;
}
export declare function encodeSVGPath(commands: SVGCommand | SVGCommand[]): string;
"use strict";
// Encode SVG PathData
// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var stream_1 = require("stream");
var SVGPathData_1 = require("./SVGPathData");
// Private consts : Char groups
var WSP = " ";
var SVGPathDataEncoder = (function (_super) {
__extends(SVGPathDataEncoder, _super);
function SVGPathDataEncoder() {
return _super.call(this, { objectMode: true, writableObjectMode: true, readableObjectMode: false }) || this;
function encodeSVGPath(commands) {
var str = "";
if (!Array.isArray(commands)) {
commands = [commands];
}
// Read method
SVGPathDataEncoder.prototype._transform = function (commands, encoding, done) {
var str = "";
var i;
var j;
if (!Array.isArray(commands)) {
commands = [commands];
for (var i = 0; i < commands.length; i++) {
var command = commands[i];
if (command.type === SVGPathData_1.SVGPathData.CLOSE_PATH) {
str += "z";
}
for (i = 0, j = commands.length; i < j; i++) {
var command = commands[i];
if (command.type === SVGPathData_1.SVGPathData.CLOSE_PATH) {
str += "z";
}
else if (command.type === SVGPathData_1.SVGPathData.HORIZ_LINE_TO) {
str += (command.relative ? "h" : "H") +
command.x;
}
else if (command.type === SVGPathData_1.SVGPathData.VERT_LINE_TO) {
str += (command.relative ? "v" : "V") +
command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.MOVE_TO) {
str += (command.relative ? "m" : "M") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.LINE_TO) {
str += (command.relative ? "l" : "L") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.CURVE_TO) {
str += (command.relative ? "c" : "C") +
command.x1 + WSP + command.y1 +
WSP + command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.SMOOTH_CURVE_TO) {
str += (command.relative ? "s" : "S") +
command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.QUAD_TO) {
str += (command.relative ? "q" : "Q") +
command.x1 + WSP + command.y1 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.SMOOTH_QUAD_TO) {
str += (command.relative ? "t" : "T") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.ARC) {
str += (command.relative ? "a" : "A") +
command.rX + WSP + command.rY +
WSP + command.xRot +
WSP + (+command.lArcFlag) + WSP + (+command.sweepFlag) +
WSP + command.x + WSP + command.y;
}
else {
// Unknown command
this.emit("error", new Error("Unexpected command type \"" + command.type + "\" at index " + i + "."));
}
else if (command.type === SVGPathData_1.SVGPathData.HORIZ_LINE_TO) {
str += (command.relative ? "h" : "H") +
command.x;
}
this.push(new Buffer(str, "utf8"));
done();
};
return SVGPathDataEncoder;
}(stream_1.Transform));
exports.SVGPathDataEncoder = SVGPathDataEncoder;
else if (command.type === SVGPathData_1.SVGPathData.VERT_LINE_TO) {
str += (command.relative ? "v" : "V") +
command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.MOVE_TO) {
str += (command.relative ? "m" : "M") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.LINE_TO) {
str += (command.relative ? "l" : "L") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.CURVE_TO) {
str += (command.relative ? "c" : "C") +
command.x1 + WSP + command.y1 +
WSP + command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.SMOOTH_CURVE_TO) {
str += (command.relative ? "s" : "S") +
command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.QUAD_TO) {
str += (command.relative ? "q" : "Q") +
command.x1 + WSP + command.y1 +
WSP + command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.SMOOTH_QUAD_TO) {
str += (command.relative ? "t" : "T") +
command.x + WSP + command.y;
}
else if (command.type === SVGPathData_1.SVGPathData.ARC) {
str += (command.relative ? "a" : "A") +
command.rX + WSP + command.rY +
WSP + command.xRot +
WSP + (+command.lArcFlag) + WSP + (+command.sweepFlag) +
WSP + command.x + WSP + command.y;
}
else {
// Unknown command
throw new Error("Unexpected command type \"" + command.type + "\" at index " + i + ".");
}
}
return str;
}
exports.encodeSVGPath = encodeSVGPath;
//# sourceMappingURL=SVGPathDataEncoder.js.map

@@ -1,10 +0,14 @@

/// <reference types="node" />
import { Transform } from "stream";
export declare class SVGPathDataParser extends Transform {
import { SVGCommand, TransformFunction } from "./SVGPathData";
import { TransformableSVG } from "./TransformableSVG";
export declare class SVGPathDataParser extends TransformableSVG {
curCommand: any;
state: number;
curNumber: any;
curNumber: string;
constructor();
_flush(callback: () => void): void;
_transform(chunk: Buffer, encoding: string, callback: () => void): void;
finish(commands?: SVGCommand[]): SVGCommand[];
parse(str: string, commands?: SVGCommand[]): SVGCommand[];
/**
* Return a wrapper around this parser which applies the transformation on parsed commands.
*/
transform(transform: TransformFunction): this;
static readonly STATE_WSP: number;

@@ -11,0 +15,0 @@ static readonly STATE_WSPS: number;

@@ -15,4 +15,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
var stream_1 = require("stream");
var SVGPathData_1 = require("./SVGPathData");
var TransformableSVG_1 = require("./TransformableSVG");
// Private consts : Char groups

@@ -27,33 +27,49 @@ var WSP = [" ", "\t", "\r", "\n"];

var COMMANDS = [
"m", "M", "z", "Z", "l", "L", "h", "H", "v", "V", "c", "C",
"s", "S", "q", "Q", "t", "T", "a", "A",
"m",
"M",
"z",
"Z",
"l",
"L",
"h",
"H",
"v",
"V",
"c",
"C",
"s",
"S",
"q",
"Q",
"t",
"T",
"a",
"A",
];
var SVGPathDataParser = (function (_super) {
var SVGPathDataParser = /** @class */ (function (_super) {
__extends(SVGPathDataParser, _super);
function SVGPathDataParser() {
var _this = _super.call(this, { objectMode: true, readableObjectMode: true, writableObjectMode: false }) || this;
// Parsing vars
var _this = _super.call(this) || this;
_this.curCommand = undefined;
_this.state = SVGPathDataParser.STATE_COMMAS_WSPS;
_this.curNumber = "";
_this.curCommand = null;
return _this;
}
SVGPathDataParser.prototype._flush = function (callback) {
this._transform(new Buffer(" "), "utf-8", function () { return undefined; });
SVGPathDataParser.prototype.finish = function (commands) {
if (commands === void 0) { commands = []; }
var result = this.parse(" ", commands);
// Adding residual command
if (null !== this.curCommand) {
if (undefined !== this.curCommand) {
if (this.curCommand.invalid) {
this.emit("error", new SyntaxError("Unterminated command at the path end."));
throw new SyntaxError("Unterminated command at the path end.");
}
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
this.state ^= this.state & SVGPathDataParser.STATE_COMMANDS_MASK;
}
callback();
return result;
};
SVGPathDataParser.prototype._transform = function (chunk, encoding, callback) {
var str = chunk.toString("buffer" !== encoding ? encoding : "utf8");
var i;
var j;
for (i = 0, j = str.length; i < j; i++) {
SVGPathDataParser.prototype.parse = function (str, commands) {
if (commands === void 0) { commands = []; }
for (var i = 0; i < str.length; i++) {
// White spaces parsing

@@ -92,4 +108,5 @@ if (this.state & SVGPathDataParser.STATE_WSP ||

SVGPathDataParser.STATE_NUMBER) {
this.state |= SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
this.state |=
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
if (-1 !== SIGNS.indexOf(str[i])) {

@@ -123,4 +140,5 @@ this.curNumber += str[i];

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
this.state |=
SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
continue;

@@ -131,4 +149,5 @@ // if got e/E, reading the exponent

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;
this.state |=
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;
continue;

@@ -145,4 +164,5 @@ }

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;
this.state |=
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;
continue;

@@ -163,4 +183,4 @@ }

if (this.state & SVGPathDataParser.STATE_HORIZ_LINE_TO) {
if (null === this.curCommand) {
this.push({
if (undefined === this.curCommand) {
commands.push({
type: SVGPathData_1.SVGPathData.HORIZ_LINE_TO,

@@ -174,4 +194,4 @@ relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),

delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -182,4 +202,4 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

else if (this.state & SVGPathDataParser.STATE_VERT_LINE_TO) {
if (null === this.curCommand) {
this.push({
if (undefined === this.curCommand) {
commands.push({
type: SVGPathData_1.SVGPathData.VERT_LINE_TO,

@@ -193,4 +213,4 @@ relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),

delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -203,8 +223,9 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

this.state & SVGPathDataParser.STATE_SMOOTH_QUAD_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {
type: (this.state & SVGPathDataParser.STATE_MOVE_TO ?
SVGPathData_1.SVGPathData.MOVE_TO :
(this.state & SVGPathDataParser.STATE_LINE_TO ?
SVGPathData_1.SVGPathData.LINE_TO : SVGPathData_1.SVGPathData.SMOOTH_QUAD_TO)),
type: this.state & SVGPathDataParser.STATE_MOVE_TO
? SVGPathData_1.SVGPathData.MOVE_TO
: this.state & SVGPathDataParser.STATE_LINE_TO
? SVGPathData_1.SVGPathData.LINE_TO
: SVGPathData_1.SVGPathData.SMOOTH_QUAD_TO,
relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),

@@ -214,3 +235,3 @@ x: Number(this.curNumber),

}
else if ("undefined" === typeof this.curCommand.x) {
else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);

@@ -221,4 +242,4 @@ }

this.curCommand.y = Number(this.curNumber);
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
// Switch to line to state

@@ -234,3 +255,3 @@ if (this.state & SVGPathDataParser.STATE_MOVE_TO) {

else if (this.state & SVGPathDataParser.STATE_CURVE_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -243,22 +264,22 @@ type: SVGPathData_1.SVGPathData.CURVE_TO,

}
else if ("undefined" === typeof this.curCommand.x1) {
else if (undefined === this.curCommand.x1) {
this.curCommand.x1 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y1) {
else if (undefined === this.curCommand.y1) {
this.curCommand.y1 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.x2) {
else if (undefined === this.curCommand.x2) {
this.curCommand.x2 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y2) {
else if (undefined === this.curCommand.y2) {
this.curCommand.y2 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.x) {
else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y) {
else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -269,3 +290,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

else if (this.state & SVGPathDataParser.STATE_SMOOTH_CURVE_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -278,16 +299,16 @@ type: SVGPathData_1.SVGPathData.SMOOTH_CURVE_TO,

}
else if ("undefined" === typeof this.curCommand.x2) {
else if (undefined === this.curCommand.x2) {
this.curCommand.x2 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y2) {
else if (undefined === this.curCommand.y2) {
this.curCommand.y2 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.x) {
else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y) {
else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -298,3 +319,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

else if (this.state & SVGPathDataParser.STATE_QUAD_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -307,16 +328,16 @@ type: SVGPathData_1.SVGPathData.QUAD_TO,

}
else if ("undefined" === typeof this.curCommand.x1) {
else if (undefined === this.curCommand.x1) {
this.curCommand.x1 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y1) {
else if (undefined === this.curCommand.y1) {
this.curCommand.y1 = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.x) {
else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y) {
else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -327,3 +348,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

else if (this.state & SVGPathDataParser.STATE_ARC) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -336,37 +357,37 @@ type: SVGPathData_1.SVGPathData.ARC,

}
else if ("undefined" === typeof this.curCommand.rX) {
else if (undefined === this.curCommand.rX) {
if (0 > Number(this.curNumber)) {
this.emit("error", new SyntaxError("Expected positive number, got \"" + this.curNumber + "\" at index \"" + i + "\""));
throw new SyntaxError("Expected positive number, got \"" + this.curNumber + "\" at index \"" + i + "\"");
}
this.curCommand.rX = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.rY) {
else if (undefined === this.curCommand.rY) {
if (0 > Number(this.curNumber)) {
this.emit("error", new SyntaxError("Expected positive number, got \"" + this.curNumber + "\" at index \"" + i + "\""));
throw new SyntaxError("Expected positive number, got \"" + this.curNumber + "\" at index \"" + i + "\"");
}
this.curCommand.rY = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.xRot) {
else if (undefined === this.curCommand.xRot) {
this.curCommand.xRot = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.lArcFlag) {
else if (undefined === this.curCommand.lArcFlag) {
if (-1 === FLAGS.indexOf(this.curNumber)) {
this.emit("error", new SyntaxError("Expected a flag, got \"" + this.curNumber + "\" at index \"" + i + "\""));
throw new SyntaxError("Expected a flag, got \"" + this.curNumber + "\" at index \"" + i + "\"");
}
this.curCommand.lArcFlag = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.sweepFlag) {
else if (undefined === this.curCommand.sweepFlag) {
if ("0" !== this.curNumber && "1" !== this.curNumber) {
this.emit("error", new SyntaxError("Expected a flag, got \"" + this.curNumber + "\" at index \"" + i + "\""));
throw new SyntaxError("Expected a flag, got \"" + this.curNumber + "\" at index \"" + i + "\"");
}
this.curCommand.sweepFlag = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.x) {
else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
}
else if ("undefined" === typeof this.curCommand.y) {
else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -383,4 +404,5 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

this.curNumber = str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
this.state |=
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
continue;

@@ -391,4 +413,5 @@ }

this.curNumber = str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
this.state |=
SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;
continue;

@@ -400,8 +423,8 @@ }

// Adding residual command
if (null !== this.curCommand) {
if (undefined !== this.curCommand) {
if (this.curCommand.invalid) {
this.emit("error", new SyntaxError("Unterminated command at index " + i + "."));
throw new SyntaxError("Unterminated command at index " + i + ".");
}
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
this.state ^= this.state & SVGPathDataParser.STATE_COMMANDS_MASK;

@@ -421,3 +444,3 @@ }

if ("z" === str[i].toLowerCase()) {
this.push({
commands.push({
type: SVGPathData_1.SVGPathData.CLOSE_PATH,

@@ -511,10 +534,35 @@ });

else {
this.emit("error", new SyntaxError("Unexpected character \"" + str[i] + "\" at index " + i + "."));
throw new SyntaxError("Unexpected character \"" + str[i] + "\" at index " + i + ".");
}
// White spaces can follow a command
this.state |= SVGPathDataParser.STATE_COMMAS_WSPS |
SVGPathDataParser.STATE_NUMBER;
this.state |=
SVGPathDataParser.STATE_COMMAS_WSPS | SVGPathDataParser.STATE_NUMBER;
}
callback();
return commands;
};
/**
* Return a wrapper around this parser which applies the transformation on parsed commands.
*/
SVGPathDataParser.prototype.transform = function (transform) {
var result = Object.create(this, {
parse: {
value: function (chunk, commands) {
if (commands === void 0) { commands = []; }
var parsedCommands = Object.getPrototypeOf(this).parse.call(this, chunk);
for (var _i = 0, parsedCommands_1 = parsedCommands; _i < parsedCommands_1.length; _i++) {
var c = parsedCommands_1[_i];
var cT = transform(c);
if (Array.isArray(cT)) {
commands.push.apply(commands, cT);
}
else {
commands.push(cT);
}
}
return commands;
},
},
});
return result;
};
// Parsing states

@@ -525,4 +573,6 @@ SVGPathDataParser.STATE_WSP = 1;

SVGPathDataParser.STATE_COMMAS = 8;
SVGPathDataParser.STATE_COMMAS_WSPS = SVGPathDataParser.STATE_WSP | SVGPathDataParser.STATE_WSPS |
SVGPathDataParser.STATE_COMMA | SVGPathDataParser.STATE_COMMAS;
SVGPathDataParser.STATE_COMMAS_WSPS = SVGPathDataParser.STATE_WSP |
SVGPathDataParser.STATE_WSPS |
SVGPathDataParser.STATE_COMMA |
SVGPathDataParser.STATE_COMMAS;
SVGPathDataParser.STATE_NUMBER = 16;

@@ -535,4 +585,6 @@ SVGPathDataParser.STATE_NUMBER_DIGITS = 32;

SVGPathDataParser.STATE_NUMBER_MASK = SVGPathDataParser.STATE_NUMBER |
SVGPathDataParser.STATE_NUMBER_DIGITS | SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_EXP | SVGPathDataParser.STATE_NUMBER_FLOAT;
SVGPathDataParser.STATE_NUMBER_DIGITS |
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_FLOAT;
SVGPathDataParser.STATE_RELATIVE = 1024;

@@ -549,10 +601,15 @@ SVGPathDataParser.STATE_CLOSE_PATH = 2048; // Close path command (z/Z)

SVGPathDataParser.STATE_ARC = 1048576; // Elliptic arc command (a/A)
SVGPathDataParser.STATE_COMMANDS_MASK = SVGPathDataParser.STATE_CLOSE_PATH | SVGPathDataParser.STATE_MOVE_TO |
SVGPathDataParser.STATE_LINE_TO | SVGPathDataParser.STATE_HORIZ_LINE_TO |
SVGPathDataParser.STATE_VERT_LINE_TO | SVGPathDataParser.STATE_CURVE_TO |
SVGPathDataParser.STATE_SMOOTH_CURVE_TO | SVGPathDataParser.STATE_QUAD_TO |
SVGPathDataParser.STATE_SMOOTH_QUAD_TO | SVGPathDataParser.STATE_ARC;
SVGPathDataParser.STATE_COMMANDS_MASK = SVGPathDataParser.STATE_CLOSE_PATH |
SVGPathDataParser.STATE_MOVE_TO |
SVGPathDataParser.STATE_LINE_TO |
SVGPathDataParser.STATE_HORIZ_LINE_TO |
SVGPathDataParser.STATE_VERT_LINE_TO |
SVGPathDataParser.STATE_CURVE_TO |
SVGPathDataParser.STATE_SMOOTH_CURVE_TO |
SVGPathDataParser.STATE_QUAD_TO |
SVGPathDataParser.STATE_SMOOTH_QUAD_TO |
SVGPathDataParser.STATE_ARC;
return SVGPathDataParser;
}(stream_1.Transform));
}(TransformableSVG_1.TransformableSVG));
exports.SVGPathDataParser = SVGPathDataParser;
//# sourceMappingURL=SVGPathDataParser.js.map

@@ -1,9 +0,2 @@

/// <reference types="node" />
import { Transform } from "stream";
import { SVGCommand, TransformFunction } from "./SVGPathData";
export declare class SVGPathDataTransformer extends Transform {
private _transformer;
constructor(transformFunction: TransformFunction);
_transform(commands: SVGCommand | SVGCommand[], encoding: string, done: () => void): void;
}
export declare namespace SVGPathDataTransformer {

@@ -10,0 +3,0 @@ function ROUND(roundVal?: number): (command: any) => any;

"use strict";
// Transform SVG PathData
// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var stream_1 = require("stream");
var mathUtils_js_1 = require("./mathUtils.js");
var SVGPathData_1 = require("./SVGPathData");
var SVGPathDataTransformer = (function (_super) {
__extends(SVGPathDataTransformer, _super);
function SVGPathDataTransformer(transformFunction) {
var _this = _super.call(this, { objectMode: true }) || this;
// Transform function needed
if ("function" !== typeof transformFunction) {
throw new Error("Please provide a transform callback to receive commands.");
}
_this._transformer = transformFunction;
return _this;
}
SVGPathDataTransformer.prototype._transform = function (commands, encoding, done) {
if (!(commands instanceof Array)) {
commands = [commands];
}
for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++) {
var command = commands_1[_i];
this.push(this._transformer(command));
}
done();
};
return SVGPathDataTransformer;
}(stream_1.Transform));
exports.SVGPathDataTransformer = SVGPathDataTransformer;
var SVGPathDataTransformer;
(function (SVGPathDataTransformer) {

@@ -656,3 +622,2 @@ // Predefined transforming functions

})(SVGPathDataTransformer = exports.SVGPathDataTransformer || (exports.SVGPathDataTransformer = {}));
exports.SVGPathDataTransformer = SVGPathDataTransformer;
//# sourceMappingURL=SVGPathDataTransformer.js.map
{
"name": "svg-pathdata",
"version": "4.0.1",
"version": "5.0.0",
"description": "Manipulate SVG path data (path[d] attribute content) simply and efficiently.",

@@ -45,5 +45,5 @@ "main": "lib/SVGPathData.js",

"devDependencies": {
"@types/node": "^8.0.24",
"@types/node": "^10.3.0",
"browserify": "^14.4.0",
"chai": "^4.1.1",
"chai": "^4.1.2",
"chai-stats": "^0.3.0",

@@ -55,9 +55,9 @@ "commitizen": "^2.9.6",

"eslint": "^4.5.0",
"eslint-config-simplifield": "^6.0.0",
"eslint-config-simplifield": "7.1.0",
"istanbul": "0.4.5",
"mocha": "3.2.0",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "1.3.0",
"rimraf": "^2.4.4",
"tslint": "^5.6.0",
"typescript": "^2.4.2"
"typescript": "^2.9.1"
},

@@ -64,0 +64,0 @@ "config": {

@@ -56,24 +56,21 @@ # svg-pathdata

## Reading streamed PathData
## Reading PathData in chunks
```js
const parser = new SVGPathDataParser();
parser.on('data', console.log);
parser.write(' ');
parser.write('M 10');
parser.write(' 10');
// {type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 }
parser.parse(' '); // returns []
parser.parse('M 10'); // returns []
parser.parse(' 10'); // returns [{type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 }]
parser.write('H 60');
// {type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 }
parser.write('H 60'); // returns [{type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 }]
parser.write('V');
parser.write('60');
// {type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 }
parser.write('V'); // returns []
parser.write('60'); // returns [{type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 }]
parser.write('L 10 60 \n Z');
// {type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 }
// {type: SVGPathData.CLOSE_PATH }
// returns [
// {type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 },
// {type: SVGPathData.CLOSE_PATH }]
parser.end();
parser.finish(); // tell parser there is no more data: will throw if there are unfinished commands.
```

@@ -89,40 +86,24 @@

Z`);
// returns "M10 10H60V60L10 60Z"
console.log(pathData.encode());
// "M10 10H60V60L10 60Z"
```
encodeSVGPath({ type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 });
// returns "M10 10"
encodeSVGPath({ type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 });
// returns "H60"
## Streaming PathData out
```js
const encoder = new SVGPathDataEncoder();
encoder.setEncoding('utf8');
encodeSVGPath([
{ type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 },
{ type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 },
{ type: SVGPathData.CLOSE_PATH}])
// returns "V60L10 60Z"
encode.on('data', console.log(str));
encoder.write({ type: SVGPathData.MOVE_TO, relative: false, x: 10, y: 10 });
// "M10 10"
encoder.write({ type: SVGPathData.HORIZ_LINE_TO, relative: false, x: 60 });
// "H60"
encoder.write({ type: SVGPathData.VERT_LINE_TO, relative: false, y: 60 });
// "V60"
encoder.write({ type: SVGPathData.LINE_TO, relative: false, x: 10, y: 60 });
// "L10 60"
encoder.write({ type: SVGPathData.CLOSE_PATH});
// "Z"
encoder.end();
```
## Transforming PathData
This library was made to live decoding/transform/encoding SVG PathData. Here is
This library can perform transformations on SVG paths. Here is
[an example of that kind of use](https://github.com/nfroidure/svgicons2svgfont/blob/aa6df0211419e9d61c417c63bcc353f0cb2ea0c8/src/index.js#L192).
### The synchronous way
### Transforming entire paths
```js
console.log(
new SVGPathData (`

@@ -135,18 +116,12 @@ m 10,10

.toAbs()
.encode()
);
// "M10,10 H70 V70 L80,130 Z"
.encode();
// return s"M10,10 H70 V70 L80,130 Z"
```
### The streaming/asynchronous way
### Transforming partial data
Here, we take SVGPathData from stdin and output it transformed to stdout.
```js
// stdin to parser
process.stdin.pipe(new SVGPathDataParser())
// parser to transformer to absolute
.pipe(new SVGPathDataTransformer(SVGPathData.Transformer.TO_ABS()))
// transformer to encoder
.pipe(new SVGPathDataEncoder())
// encoder to stdout
.pipe(process.stdout);
const transformingParser = new SVGPathDataParser().toAbs().scale(2, 2);
transformingParser.parse('m 0 0') // returns [{ type: SVGPathData.MOVE_TO, relative: false, x: 0, y: 0 }]
transformingParser.parse('l 2 3') // returns [{ type: SVGPathData.LINE_TO, relative: false, x: 4, y: 6 }]
```

@@ -156,5 +131,7 @@

You can find all supported transformations in
[src/SVGPathDataTransformer.js](https://github.com/nfroidure/SVGPathData/blob/master/src/SVGPathDataTransformer.js#L47).
Additionally, you can create your own using this format:
[src/SVGPathDataTransformer.ts](https://github.com/nfroidure/SVGPathData/blob/master/src/SVGPathDataTransformer.ts#L47).
Additionally, you can create your own by writing a function with the following signature:
```js
type TransformFunction = (command: SVGCommand) => SVGCommand | SVGCommand[];
function SET_X_TO(xValue = 10) {

@@ -172,7 +149,4 @@ return function(command) {

// Streaming usage
process.stdin.pipe(new SVGPathDataParser())
.pipe(new SVGPathDataTransformer(SET_X_TO(25)))
.pipe(new SVGPathDataEncoder())
.pipe(process.stdout);
// Chunk usage
new SVGPathDataParser().transform(SET_X_TO(25));
```

@@ -179,0 +153,0 @@

@@ -80,3 +80,3 @@ import {CommandA, CommandC, SVGPathData} from "./SVGPathData";

*/
export function intersectionUnitCircleLine(a: number, b: number, c: number) {
export function intersectionUnitCircleLine(a: number, b: number, c: number): Array<[number, number]> {
assertNumbers(a, b, c);

@@ -83,0 +83,0 @@ // cf. pqFormula

@@ -0,1 +1,2 @@

import {TransformableSVG} from "./TransformableSVG";
export type CommandM = { relative: boolean, type: typeof SVGPathData.MOVE_TO, x: number, y: number };

@@ -5,5 +6,11 @@ export type CommandL = { relative: boolean, type: typeof SVGPathData.LINE_TO, x: number, y: number };

export type CommandV = { relative: boolean, type: typeof SVGPathData.VERT_LINE_TO, y: number };
export type CommandZ = { relative: boolean, type: typeof SVGPathData.CLOSE_PATH };
export type CommandQ =
{ relative: boolean, type: typeof SVGPathData.QUAD_TO, x1: number, y1: number, x: number, y: number };
export type CommandZ = { type: typeof SVGPathData.CLOSE_PATH };
export type CommandQ = {
relative: boolean;
type: typeof SVGPathData.QUAD_TO;
x1: number;
y1: number;
x: number;
y: number;
};
export type CommandT = { relative: boolean, type: typeof SVGPathData.SMOOTH_QUAD_TO, x: number, y: number };

@@ -16,4 +23,10 @@ export type CommandC = {

x: number, y: number };
export type CommandS =
{ relative: boolean, type: typeof SVGPathData.SMOOTH_CURVE_TO, x2: number, y2: number, x: number, y: number };
export type CommandS = {
relative: boolean;
type: typeof SVGPathData.SMOOTH_CURVE_TO;
x2: number;
y2: number;
x: number;
y: number;
};
export type CommandA = {

@@ -31,5 +44,6 @@ relative: boolean,

export class SVGPathData {
export class SVGPathData extends TransformableSVG {
commands: SVGCommand[];
constructor(content: string | SVGCommand[]) {
super();
if ("string" === typeof content) {

@@ -46,70 +60,2 @@ this.commands = SVGPathData.parse(content);

round(x?: number) {
return this.transform(SVGPathDataTransformer.ROUND(x));
}
toAbs() {
return this.transform(SVGPathDataTransformer.TO_ABS());
}
toRel() {
return this.transform(SVGPathDataTransformer.TO_REL());
}
normalizeHVZ(a?: boolean, b?: boolean, c?: boolean) {
return this.transform(SVGPathDataTransformer.NORMALIZE_HVZ(a, b, c));
}
normalizeST() {
return this.transform(SVGPathDataTransformer.NORMALIZE_ST());
}
qtToC() {
return this.transform(SVGPathDataTransformer.QT_TO_C());
}
aToC() {
return this.transform(SVGPathDataTransformer.A_TO_C());
}
sanitize(eps?: number) {
return this.transform(SVGPathDataTransformer.SANITIZE(eps));
}
translate(x: number, y?: number) {
return this.transform(SVGPathDataTransformer.TRANSLATE(x, y));
}
scale(x: number, y?: number) {
return this.transform(SVGPathDataTransformer.SCALE(x, y));
}
rotate(a: number, x?: number, y?: number) {
return this.transform(SVGPathDataTransformer.ROTATE(a, x, y));
}
matrix(a: number, b: number, c: number, d: number, e: number, f: number) {
return this.transform(SVGPathDataTransformer.MATRIX(a, b, c, d, e, f));
}
skewX(a: number) {
return this.transform(SVGPathDataTransformer.SKEW_X(a));
}
skewY(a: number) {
return this.transform(SVGPathDataTransformer.SKEW_Y(a));
}
xSymmetry(xOffset?: number) {
return this.transform(SVGPathDataTransformer.X_AXIS_SYMMETRY(xOffset));
}
ySymmetry(yOffset?: number) {
return this.transform(SVGPathDataTransformer.Y_AXIS_SYMMETRY(yOffset));
}
annotateArcs() {
return this.transform(SVGPathDataTransformer.ANNOTATE_ARCS());
}
getBounds() {

@@ -122,3 +68,5 @@ const boundsTransform = SVGPathDataTransformer.CALCULATE_BOUNDS();

transform(transformFunction: (input: SVGCommand) => SVGCommand | SVGCommand[]) {
transform(
transformFunction: (input: SVGCommand) => SVGCommand | SVGCommand[],
) {
const newCommands = [];

@@ -129,3 +77,3 @@

if (transformedCommand instanceof Array) {
if (Array.isArray(transformedCommand)) {
newCommands.push(...transformedCommand);

@@ -141,30 +89,10 @@ } else {

static encode(commands: SVGCommand[]) {
let content = "";
const encoder = new SVGPathDataEncoder();
encoder.on("readable", () => {
let str;
while (null !== (str = encoder.read())) {
content += str;
return encodeSVGPath(commands);
}
});
encoder.write(commands);
encoder.end();
return content;
}
static parse(content: string) {
static parse(path: string) {
const parser = new SVGPathDataParser();
const commands: SVGCommand[] = [];
const parser = new SVGPathDataParser();
parser.on("readable", () => {
let command;
while (null !== (command = parser.read())) {
commands.push(command);
}
});
parser.write(content);
parser.end();
parser.parse(path, commands);
parser.finish(commands);
return commands;

@@ -189,5 +117,5 @@ }

import {SVGPathDataEncoder} from "./SVGPathDataEncoder";
import { encodeSVGPath } from "./SVGPathDataEncoder";
import {SVGPathDataParser} from "./SVGPathDataParser";
import {SVGPathDataTransformer} from "./SVGPathDataTransformer";
export { SVGPathDataEncoder, SVGPathDataParser, SVGPathDataTransformer } ;
export { encodeSVGPath, SVGPathDataParser, SVGPathDataTransformer };
// Encode SVG PathData
// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
import { Transform } from "stream";
import {SVGCommand, SVGPathData} from "./SVGPathData";

@@ -10,63 +9,54 @@

export class SVGPathDataEncoder extends Transform {
constructor() {
super({objectMode: true, writableObjectMode: true, readableObjectMode: false});
export function encodeSVGPath(commands: SVGCommand | SVGCommand[]) {
let str = "";
if (!Array.isArray(commands)) {
commands = [commands];
}
// Read method
_transform(commands: SVGCommand | SVGCommand[], encoding: string, done: () => void) {
let str = "";
let i;
let j;
if (!Array.isArray(commands)) {
commands = [commands];
for (let i = 0; i < commands.length; i++) {
const command = commands[i];
if (command.type === SVGPathData.CLOSE_PATH) {
str += "z";
} else if (command.type === SVGPathData.HORIZ_LINE_TO) {
str += (command.relative ? "h" : "H") +
command.x;
} else if (command.type === SVGPathData.VERT_LINE_TO) {
str += (command.relative ? "v" : "V") +
command.y;
} else if (command.type === SVGPathData.MOVE_TO) {
str += (command.relative ? "m" : "M") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.LINE_TO) {
str += (command.relative ? "l" : "L") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.CURVE_TO) {
str += (command.relative ? "c" : "C") +
command.x1 + WSP + command.y1 +
WSP + command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.SMOOTH_CURVE_TO) {
str += (command.relative ? "s" : "S") +
command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.QUAD_TO) {
str += (command.relative ? "q" : "Q") +
command.x1 + WSP + command.y1 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.SMOOTH_QUAD_TO) {
str += (command.relative ? "t" : "T") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.ARC) {
str += (command.relative ? "a" : "A") +
command.rX + WSP + command.rY +
WSP + command.xRot +
WSP + (+command.lArcFlag) + WSP + (+command.sweepFlag) +
WSP + command.x + WSP + command.y;
} else {
// Unknown command
throw new Error(
`Unexpected command type "${ (command as any).type}" at index ${i}.`);
}
for (i = 0, j = commands.length; i < j; i++) {
const command = commands[i];
if (command.type === SVGPathData.CLOSE_PATH) {
str += "z";
} else if (command.type === SVGPathData.HORIZ_LINE_TO) {
str += (command.relative ? "h" : "H") +
command.x;
} else if (command.type === SVGPathData.VERT_LINE_TO) {
str += (command.relative ? "v" : "V") +
command.y;
} else if (command.type === SVGPathData.MOVE_TO) {
str += (command.relative ? "m" : "M") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.LINE_TO) {
str += (command.relative ? "l" : "L") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.CURVE_TO) {
str += (command.relative ? "c" : "C") +
command.x1 + WSP + command.y1 +
WSP + command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.SMOOTH_CURVE_TO) {
str += (command.relative ? "s" : "S") +
command.x2 + WSP + command.y2 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.QUAD_TO) {
str += (command.relative ? "q" : "Q") +
command.x1 + WSP + command.y1 +
WSP + command.x + WSP + command.y;
} else if (command.type === SVGPathData.SMOOTH_QUAD_TO) {
str += (command.relative ? "t" : "T") +
command.x + WSP + command.y;
} else if (command.type === SVGPathData.ARC) {
str += (command.relative ? "a" : "A") +
command.rX + WSP + command.rY +
WSP + command.xRot +
WSP + (+command.lArcFlag) + WSP + (+command.sweepFlag) +
WSP + command.x + WSP + command.y;
} else {
// Unknown command
this.emit("error", new Error(
`Unexpected command type "${ (command as any).type}" at index ${i}.`));
}
}
this.push(new Buffer(str, "utf8"));
done();
}
return str;
}

@@ -5,3 +5,4 @@ // Parse SVG PathData

import { Transform } from "stream";
import { SVGPathData } from "./SVGPathData";
import { SVGCommand, SVGPathData, TransformFunction } from "./SVGPathData";
import { TransformableSVG } from "./TransformableSVG";

@@ -17,42 +18,54 @@ // Private consts : Char groups

const COMMANDS = [
"m", "M", "z", "Z", "l", "L", "h", "H", "v", "V", "c", "C",
"s", "S", "q", "Q", "t", "T", "a", "A",
"m",
"M",
"z",
"Z",
"l",
"L",
"h",
"H",
"v",
"V",
"c",
"C",
"s",
"S",
"q",
"Q",
"t",
"T",
"a",
"A",
];
export class SVGPathDataParser extends Transform {
curCommand: any;
state: number;
curNumber: any;
export class SVGPathDataParser extends TransformableSVG {
curCommand: any = undefined;
state: number = SVGPathDataParser.STATE_COMMAS_WSPS;
curNumber: string = "";
constructor() {
super({ objectMode: true, readableObjectMode: true, writableObjectMode: false });
super();
}
// Parsing vars
this.state = SVGPathDataParser.STATE_COMMAS_WSPS;
this.curNumber = "";
this.curCommand = null;
}
_flush(callback: () => void) {
this._transform(new Buffer(" "), "utf-8", () => undefined);
finish(commands: SVGCommand[] = []) {
const result = this.parse(" ", commands);
// Adding residual command
if (null !== this.curCommand) {
if (undefined !== this.curCommand) {
if (this.curCommand.invalid) {
this.emit("error",
new SyntaxError("Unterminated command at the path end."));
throw new SyntaxError("Unterminated command at the path end.");
}
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
this.state ^= this.state & SVGPathDataParser.STATE_COMMANDS_MASK;
}
callback();
return result;
}
_transform(chunk: Buffer, encoding: string, callback: () => void) {
const str = chunk.toString("buffer" !== encoding ? encoding : "utf8");
let i;
let j;
for (i = 0, j = str.length; i < j; i++) {
parse(str: string, commands: SVGCommand[] = []) {
for (let i = 0; i < str.length; i++) {
// White spaces parsing
if (this.state & SVGPathDataParser.STATE_WSP ||
this.state & SVGPathDataParser.STATE_WSPS) {
if (
this.state & SVGPathDataParser.STATE_WSP ||
this.state & SVGPathDataParser.STATE_WSPS
) {
if (-1 !== WSP.indexOf(str[i])) {

@@ -69,4 +82,6 @@ this.state ^= this.state & SVGPathDataParser.STATE_WSP;

// Commas parsing
if (this.state & SVGPathDataParser.STATE_COMMA ||
this.state & SVGPathDataParser.STATE_COMMAS) {
if (
this.state & SVGPathDataParser.STATE_COMMA ||
this.state & SVGPathDataParser.STATE_COMMAS
) {
if (-1 !== COMMA.indexOf(str[i])) {

@@ -85,5 +100,8 @@ this.state ^= this.state & SVGPathDataParser.STATE_COMMA;

// Reading the sign
if ((this.state & SVGPathDataParser.STATE_NUMBER_MASK) ===
SVGPathDataParser.STATE_NUMBER) {
this.state |= SVGPathDataParser.STATE_NUMBER_INT |
if (
(this.state & SVGPathDataParser.STATE_NUMBER_MASK) ===
SVGPathDataParser.STATE_NUMBER
) {
this.state |=
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;

@@ -118,3 +136,4 @@ if (-1 !== SIGNS.indexOf(str[i])) {

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_FLOAT |
this.state |=
SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;

@@ -125,3 +144,4 @@ continue;

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_EXP |
this.state |=
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;

@@ -139,3 +159,4 @@ continue;

this.curNumber += str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_EXP |
this.state |=
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_EXPSIGN;

@@ -157,4 +178,4 @@ continue;

if (this.state & SVGPathDataParser.STATE_HORIZ_LINE_TO) {
if (null === this.curCommand) {
this.push({
if (undefined === this.curCommand) {
commands.push({
type: SVGPathData.HORIZ_LINE_TO,

@@ -167,4 +188,4 @@ relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),

delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -174,4 +195,4 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

} else if (this.state & SVGPathDataParser.STATE_VERT_LINE_TO) {
if (null === this.curCommand) {
this.push({
if (undefined === this.curCommand) {
commands.push({
type: SVGPathData.VERT_LINE_TO,

@@ -184,22 +205,24 @@ relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),

delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}
this.state |= SVGPathDataParser.STATE_NUMBER;
// Move to / line to / smooth quadratic curve to commands (x, y)
} else if (this.state & SVGPathDataParser.STATE_MOVE_TO ||
} else if (
this.state & SVGPathDataParser.STATE_MOVE_TO ||
this.state & SVGPathDataParser.STATE_LINE_TO ||
this.state & SVGPathDataParser.STATE_SMOOTH_QUAD_TO) {
if (null === this.curCommand) {
this.state & SVGPathDataParser.STATE_SMOOTH_QUAD_TO
) {
if (undefined === this.curCommand) {
this.curCommand = {
type: (this.state & SVGPathDataParser.STATE_MOVE_TO ?
SVGPathData.MOVE_TO :
(this.state & SVGPathDataParser.STATE_LINE_TO ?
SVGPathData.LINE_TO : SVGPathData.SMOOTH_QUAD_TO
)
),
type:
this.state & SVGPathDataParser.STATE_MOVE_TO
? SVGPathData.MOVE_TO
: this.state & SVGPathDataParser.STATE_LINE_TO
? SVGPathData.LINE_TO
: SVGPathData.SMOOTH_QUAD_TO,
relative: !!(this.state & SVGPathDataParser.STATE_RELATIVE),
x: Number(this.curNumber),
};
} else if ("undefined" === typeof this.curCommand.x) {
} else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);

@@ -209,4 +232,4 @@ } else {

this.curCommand.y = Number(this.curNumber);
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
// Switch to line to state

@@ -221,3 +244,3 @@ if (this.state & SVGPathDataParser.STATE_MOVE_TO) {

} else if (this.state & SVGPathDataParser.STATE_CURVE_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -229,17 +252,17 @@ type: SVGPathData.CURVE_TO,

};
} else if ("undefined" === typeof this.curCommand.x1) {
} else if (undefined === this.curCommand.x1) {
this.curCommand.x1 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y1) {
} else if (undefined === this.curCommand.y1) {
this.curCommand.y1 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.x2) {
} else if (undefined === this.curCommand.x2) {
this.curCommand.x2 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y2) {
} else if (undefined === this.curCommand.y2) {
this.curCommand.y2 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.x) {
} else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y) {
} else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -249,3 +272,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

} else if (this.state & SVGPathDataParser.STATE_SMOOTH_CURVE_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -257,13 +280,13 @@ type: SVGPathData.SMOOTH_CURVE_TO,

};
} else if ("undefined" === typeof this.curCommand.x2) {
} else if (undefined === this.curCommand.x2) {
this.curCommand.x2 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y2) {
} else if (undefined === this.curCommand.y2) {
this.curCommand.y2 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.x) {
} else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y) {
} else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -273,3 +296,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

} else if (this.state & SVGPathDataParser.STATE_QUAD_TO) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -281,13 +304,13 @@ type: SVGPathData.QUAD_TO,

};
} else if ("undefined" === typeof this.curCommand.x1) {
} else if (undefined === this.curCommand.x1) {
this.curCommand.x1 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y1) {
} else if (undefined === this.curCommand.y1) {
this.curCommand.y1 = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.x) {
} else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y) {
} else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -297,3 +320,3 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

} else if (this.state & SVGPathDataParser.STATE_ARC) {
if (null === this.curCommand) {
if (undefined === this.curCommand) {
this.curCommand = {

@@ -305,35 +328,43 @@ type: SVGPathData.ARC,

};
} else if ("undefined" === typeof this.curCommand.rX) {
} else if (undefined === this.curCommand.rX) {
if (0 > Number(this.curNumber)) {
this.emit("error", new SyntaxError(
`Expected positive number, got "${this.curNumber}" at index "${i}"`));
throw new SyntaxError(
`Expected positive number, got "${
this.curNumber
}" at index "${i}"`,
);
}
this.curCommand.rX = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.rY) {
} else if (undefined === this.curCommand.rY) {
if (0 > Number(this.curNumber)) {
this.emit("error", new SyntaxError(
`Expected positive number, got "${this.curNumber}" at index "${i}"`));
throw new SyntaxError(
`Expected positive number, got "${
this.curNumber
}" at index "${i}"`,
);
}
this.curCommand.rY = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.xRot) {
} else if (undefined === this.curCommand.xRot) {
this.curCommand.xRot = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.lArcFlag) {
} else if (undefined === this.curCommand.lArcFlag) {
if (-1 === FLAGS.indexOf(this.curNumber)) {
this.emit("error", new SyntaxError(
`Expected a flag, got "${this.curNumber}" at index "${i}"`));
throw new SyntaxError(
`Expected a flag, got "${this.curNumber}" at index "${i}"`,
);
}
this.curCommand.lArcFlag = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.sweepFlag) {
} else if (undefined === this.curCommand.sweepFlag) {
if ("0" !== this.curNumber && "1" !== this.curNumber) {
this.emit("error", new SyntaxError(
`Expected a flag, got "${this.curNumber}" at index "${i}"`));
throw new SyntaxError(
`Expected a flag, got "${this.curNumber}" at index "${i}"`,
);
}
this.curCommand.sweepFlag = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.x) {
} else if (undefined === this.curCommand.x) {
this.curCommand.x = Number(this.curNumber);
} else if ("undefined" === typeof this.curCommand.y) {
} else if (undefined === this.curCommand.y) {
this.curCommand.y = Number(this.curNumber);
delete this.curCommand.invalid;
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
}

@@ -350,3 +381,4 @@ this.state |= SVGPathDataParser.STATE_NUMBER;

this.curNumber = str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_INT |
this.state |=
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_DIGITS;

@@ -358,3 +390,4 @@ continue;

this.curNumber = str[i];
this.state |= SVGPathDataParser.STATE_NUMBER_FLOAT |
this.state |=
SVGPathDataParser.STATE_NUMBER_FLOAT |
SVGPathDataParser.STATE_NUMBER_DIGITS;

@@ -367,9 +400,8 @@ continue;

// Adding residual command
if (null !== this.curCommand) {
if (undefined !== this.curCommand) {
if (this.curCommand.invalid) {
this.emit("error",
new SyntaxError(`Unterminated command at index ${i}.`));
throw new SyntaxError(`Unterminated command at index ${i}.`);
}
this.push(this.curCommand);
this.curCommand = null;
commands.push(this.curCommand);
this.curCommand = undefined;
this.state ^= this.state & SVGPathDataParser.STATE_COMMANDS_MASK;

@@ -388,3 +420,3 @@ }

if ("z" === str[i].toLowerCase()) {
this.push({
commands.push({
type: SVGPathData.CLOSE_PATH,

@@ -468,12 +500,36 @@ });

} else {
this.emit("error", new SyntaxError(`Unexpected character "${str[i]
}" at index ${i}.`));
throw new SyntaxError(
`Unexpected character "${str[i]}" at index ${i}.`,
);
}
// White spaces can follow a command
this.state |= SVGPathDataParser.STATE_COMMAS_WSPS |
SVGPathDataParser.STATE_NUMBER;
this.state |=
SVGPathDataParser.STATE_COMMAS_WSPS | SVGPathDataParser.STATE_NUMBER;
}
callback();
return commands;
}
/**
* Return a wrapper around this parser which applies the transformation on parsed commands.
*/
transform(transform: TransformFunction) {
const result = Object.create(this, {
parse: {
value(chunk: string, commands: SVGCommand[] = []) {
const parsedCommands = Object.getPrototypeOf(this).parse.call(this, chunk);
for (const c of parsedCommands) {
const cT = transform(c);
if (Array.isArray(cT)) {
commands.push(...cT);
} else {
commands.push(cT);
}
}
return commands;
},
},
});
return result as this;
}
// Parsing states

@@ -484,5 +540,6 @@ static readonly STATE_WSP = 1;

static readonly STATE_COMMAS = 8;
static readonly STATE_COMMAS_WSPS =
SVGPathDataParser.STATE_WSP | SVGPathDataParser.STATE_WSPS |
SVGPathDataParser.STATE_COMMA | SVGPathDataParser.STATE_COMMAS;
static readonly STATE_COMMAS_WSPS = SVGPathDataParser.STATE_WSP |
SVGPathDataParser.STATE_WSPS |
SVGPathDataParser.STATE_COMMA |
SVGPathDataParser.STATE_COMMAS;
static readonly STATE_NUMBER = 16;

@@ -495,4 +552,6 @@ static readonly STATE_NUMBER_DIGITS = 32;

static readonly STATE_NUMBER_MASK = SVGPathDataParser.STATE_NUMBER |
SVGPathDataParser.STATE_NUMBER_DIGITS | SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_EXP | SVGPathDataParser.STATE_NUMBER_FLOAT;
SVGPathDataParser.STATE_NUMBER_DIGITS |
SVGPathDataParser.STATE_NUMBER_INT |
SVGPathDataParser.STATE_NUMBER_EXP |
SVGPathDataParser.STATE_NUMBER_FLOAT;
static readonly STATE_RELATIVE = 1024;

@@ -509,8 +568,12 @@ static readonly STATE_CLOSE_PATH = 2048; // Close path command (z/Z)

static readonly STATE_ARC = 1048576; // Elliptic arc command (a/A)
static readonly STATE_COMMANDS_MASK =
SVGPathDataParser.STATE_CLOSE_PATH | SVGPathDataParser.STATE_MOVE_TO |
SVGPathDataParser.STATE_LINE_TO | SVGPathDataParser.STATE_HORIZ_LINE_TO |
SVGPathDataParser.STATE_VERT_LINE_TO | SVGPathDataParser.STATE_CURVE_TO |
SVGPathDataParser.STATE_SMOOTH_CURVE_TO | SVGPathDataParser.STATE_QUAD_TO |
SVGPathDataParser.STATE_SMOOTH_QUAD_TO | SVGPathDataParser.STATE_ARC;
static readonly STATE_COMMANDS_MASK = SVGPathDataParser.STATE_CLOSE_PATH |
SVGPathDataParser.STATE_MOVE_TO |
SVGPathDataParser.STATE_LINE_TO |
SVGPathDataParser.STATE_HORIZ_LINE_TO |
SVGPathDataParser.STATE_VERT_LINE_TO |
SVGPathDataParser.STATE_CURVE_TO |
SVGPathDataParser.STATE_SMOOTH_CURVE_TO |
SVGPathDataParser.STATE_QUAD_TO |
SVGPathDataParser.STATE_SMOOTH_QUAD_TO |
SVGPathDataParser.STATE_ARC;
}
// Transform SVG PathData
// http://www.w3.org/TR/SVG/paths.html#PathDataBNF
import { Transform } from "stream";
import { a2c, annotateArcCommand, arcAt, assertNumbers, bezierAt, bezierRoot,

@@ -9,26 +8,2 @@ intersectionUnitCircleLine } from "./mathUtils.js";

export class SVGPathDataTransformer extends Transform {
private _transformer: TransformFunction;
constructor(transformFunction: TransformFunction) {
super({ objectMode: true });
// Transform function needed
if ("function" !== typeof transformFunction) {
throw new Error("Please provide a transform callback to receive commands.");
}
this._transformer = transformFunction;
}
_transform(commands: SVGCommand | SVGCommand[], encoding: string, done: () => void) {
if (!(commands instanceof Array)) {
commands = [commands];
}
for (const command of commands) {
this.push(this._transformer(command));
}
done();
}
}
export namespace SVGPathDataTransformer {

@@ -35,0 +10,0 @@ // Predefined transforming functions

@@ -197,16 +197,16 @@ /* eslint-disable no-new */

// eslint-disable-next-line complexity
// eslint-disable-next-line complexity
function assertDeepCloseTo(x, y, delta) {
if('number' === typeof x && 'number' === typeof y) {
if ('number' === typeof x && 'number' === typeof y) {
assert.closeTo(x, y, delta);
} else if('object' === typeof x && 'object' === typeof y) {
} else if ('object' === typeof x && 'object' === typeof y) {
const keys = Object.getOwnPropertyNames(x);
assert.sameMembers(keys, Object.getOwnPropertyNames(y));
for(let i = 0; i < keys.length; i++) {
for (let i = 0; i < keys.length; i++) {
assertDeepCloseTo(x[keys[i]], y[keys[i]], delta);
}
} else if(x instanceof Array && y instanceof Array) {
} else if (x instanceof Array && y instanceof Array) {
assert.equal(x.length, y.length, 'arrays have different lengths');
for(let i = 0; i < x.length; i++) {
for (let i = 0; i < x.length; i++) {
assertDeepCloseTo(x[i], y[i], delta);

@@ -213,0 +213,0 @@ }

@@ -5,8 +5,8 @@ /* eslint max-len:0 */

const assert = require('chai').assert;
const { SVGPathDataEncoder } = require('..');
const { encodeSVGPath, SVGPathDataEncoder } = require('..');
describe('SVGPathDataEncoder', () => {
it('should still work when the new operator is forgotten', () => {
assert.doesNotThrow(() => {
it('should not work when the command is forgotten', () => {
assert.throws(() => {
new SVGPathDataEncoder();

@@ -18,5 +18,3 @@ });

assert.throws(() => {
const encoder = new SVGPathDataEncoder();
encoder.write({
encodeSVGPath({
type: 'plop',

@@ -23,0 +21,0 @@ x: 0,

@@ -15,3 +15,3 @@ /* eslint max-len:0 */

it('should work with single complexer coordinate', () => {
it('should not work with single complexer coordinate', () => {
assert.throw(() => {

@@ -18,0 +18,0 @@ new SVGPathData('m-10e-5');

@@ -5,18 +5,8 @@ /* eslint max-len:0 */

const assert = require('chai').assert;
const { SVGPathDataParser } = require('..');
const { SVGPathData } = require('..');
describe('SVGPathDataParser', () => {
it('should still work when the new operator is forgotten', () => {
assert.doesNotThrow(() => {
new SVGPathDataParser();
});
});
it('should fail when a bad command is given', () => {
assert.throws(() => {
const parser = new SVGPathDataParser();
parser.write('b80,20');
parser.end();
SVGPathData.parse('b80,20');
}, 'Unexpected character "b" at index 0.');

@@ -23,0 +13,0 @@ });

@@ -6,29 +6,15 @@ /* eslint-disable new-cap */

const assert = require('chai').assert;
const { SVGPathData, SVGPathDataTransformer } = require('..');
const { SVGPathData, SVGPathDataParser } = require('..');
describe('SVGPathDataTransformer', () => {
it('should fail with bad args', () => {
assert.throws(() => {
new SVGPathDataTransformer();
}, 'Please provide a transform callback to receive commands.');
});
it('should be possible to transform the parser', () => {
const parser = new SVGPathDataParser().toAbs();
it('should work in streaming mode', () => {
const encoder = new SVGPathDataTransformer(SVGPathDataTransformer.SCALE(1, 1));
encoder.write({
type: SVGPathData.MOVE_TO,
relative: false,
x: 0,
y: 0,
}, {
type: SVGPathData.LINE_TO,
relative: true,
x: 10,
y: 10,
});
encoder.end();
assert.equal(SVGPathData.encode(parser.parse('m 0')), '');
assert.equal(SVGPathData.encode(parser.parse(' 0 l')), 'M0 0');
assert.equal(SVGPathData.encode(parser.parse('2 3')), '');
assert.equal(SVGPathData.encode(parser.finish()), 'L2 3');
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc