Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

svg2pdf.js

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svg2pdf.js - npm Package Compare versions

Comparing version 0.9.0 to 0.10.0

.npmignore

5

package.json
{
"name": "svg2pdf.js",
"version": "0.9.0",
"version": "0.10.0",
"description": "A javascript-only SVG to PDF conversion utility that runs in the browser leveraging jsPDF",

@@ -25,5 +25,4 @@ "main": "svg2pdf.js",

"dependencies": {
"jspdf": "git+https://github.com/yWorks/jsPDF.git#1.1.345",
"jquery": ">=2.1.4"
"jspdf": "git+https://github.com/yWorks/jsPDF.git#1.1.350"
}
}

30

README.md

@@ -5,6 +5,34 @@ # svg2pdf.js

## Installation
If you have cloned this repository via
```bash
git clone https://github.com/yWorks/svg2pdf.js.git
```
run
```bash
bower install
```
or
```bash
npm install
```
to install all dependencies.
If you're only interested in the complete package, run
```bash
bower install svg2pdf.js
```
or
```bash
npm install svg2pdf.js
```
## Usage

@@ -31,5 +59,3 @@ ```javascript

* [jsPDF](https://github.com/yWorks/jsPDF) (yWorks fork version!)
* [jQuery](https://jquery.org/)
## License

@@ -36,0 +62,0 @@

@@ -35,3 +35,3 @@ /*

*/
var svgElementToPdf = (function () {
var svgElementToPdf = (function (global) {

@@ -115,2 +115,21 @@ var _pdf; // jsPDF pdf-document

var nodeIs = function (node, tagsString) {
return tagsString.indexOf(node.tagName.toLowerCase()) >= 0;
};
var forEachChild = function (node, fn) {
// copy list of children, as the original might be modified
var children = [];
for (var i = 0; i < node.children.length; i++) {
children.push(node.children[i]);
}
for (i = 0; i < children.length; i++) {
fn(i, children[i]);
}
};
var getAngle = function (from, to) {
return Math.atan2(to[1] - from[1], to[0] - from[0]);
};
// mirrors p1 at p2

@@ -185,8 +204,8 @@ var mirrorPoint = function (p1, p2) {

var nodeTransform = _pdf.unitMatrix;
if (node.is("svg,g")) {
x = parseFloat(node.attr("x")) || 0;
y = parseFloat(node.attr("y")) || 0;
if (nodeIs(node, "svg,g")) {
x = parseFloat(node.getAttribute("x")) || 0;
y = parseFloat(node.getAttribute("y")) || 0;
// jquery doesn't like camelCase notation...
viewBox = node.get(0).getAttribute("viewBox");
viewBox = node.getAttribute("viewBox");
if (viewBox) {

@@ -196,4 +215,4 @@ bounds = parseFloats(viewBox);

viewBoxHeight = bounds[3] - bounds[1];
width = parseFloat(node.attr("width")) || viewBoxWidth;
height = parseFloat(node.attr("height")) || viewBoxHeight;
width = parseFloat(node.getAttribute("width")) || viewBoxWidth;
height = parseFloat(node.getAttribute("height")) || viewBoxHeight;
nodeTransform = new _pdf.Matrix(width / viewBoxWidth, 0, 0, height / viewBoxHeight, x - bounds[0], y - bounds[1]);

@@ -203,7 +222,7 @@ } else {

}
} else if (node.is("marker")) {
x = -parseFloat(node.get(0).getAttribute("refX")) || 0;
y = -parseFloat(node.get(0).getAttribute("refY")) || 0;
} else if (nodeIs(node, "marker")) {
x = -parseFloat(node.getAttribute("refX")) || 0;
y = -parseFloat(node.getAttribute("refY")) || 0;
viewBox = node.get(0).getAttribute("viewBox");
viewBox = node.getAttribute("viewBox");
if (viewBox) {

@@ -213,7 +232,7 @@ bounds = parseFloats(viewBox);

viewBoxHeight = bounds[3] - bounds[1];
width = parseFloat(node.get(0).getAttribute("markerWidth")) || viewBoxWidth;
height = parseFloat(node.get(0).getAttribute("markerHeight")) || viewBoxHeight;
width = parseFloat(node.getAttribute("markerWidth")) || viewBoxWidth;
height = parseFloat(node.getAttribute("markerHeight")) || viewBoxHeight;
var s = new _pdf.Matrix(width / viewBoxWidth, 0, 0, height / viewBoxHeight, 0, 0);
var t = new _pdf.Matrix(1, 0, 0, 1, x - bounds[0], y - bounds[1]);
var t = new _pdf.Matrix(1, 0, 0, 1, x, y);
nodeTransform = _pdf.matrixMult(t, s);

@@ -225,3 +244,3 @@ } else {

var transformString = node.attr("transform");
var transformString = node.getAttribute("transform");
if (!transformString)

@@ -326,6 +345,7 @@ return nodeTransform;

var getUntransformedBBox = function (node) {
var i, minX, minY, maxX, maxY, viewBox, vb;
var i, minX, minY, maxX, maxY, viewBox, vb, boundingBox;
var pf = parseFloat;
if (node.is("polygon")) {
var points = parsePointsString(node.attr("points"));
if (nodeIs(node, "polygon")) {
var points = parsePointsString(node.getAttribute("points"));
minX = Number.POSITIVE_INFINITY;

@@ -342,3 +362,3 @@ minY = Number.POSITIVE_INFINITY;

}
return [
boundingBox = [
minX,

@@ -349,6 +369,4 @@ minY,

];
}
if (node.is("path")) {
var list = getPathSegList(node.get(0));
} else if (nodeIs(node, "path")) {
var list = getPathSegList(node);
minX = Number.POSITIVE_INFINITY;

@@ -359,3 +377,3 @@ minY = Number.POSITIVE_INFINITY;

var x = 0, y = 0;
var prevX, prevY;
var prevX, prevY, newX, newY;
var p2, p3, to;

@@ -367,12 +385,16 @@ for (i = 0; i < list.numberOfItems; i++) {

case "H":
x = seg.x;
newX = seg.x;
newY = y;
break;
case "h":
x = seg.x + x;
newX = seg.x + x;
newY = y;
break;
case "V":
y = seg.y;
newX = x;
newY = seg.y;
break;
case "v":
y = seg.y + y;
newX = x;
newY = seg.y + y;
break;

@@ -435,2 +457,5 @@ case "C":

y = seg.y + y;
} else if ("zZ".indexOf(cmd) < 0) {
x = newX;
y = newY;
}

@@ -449,3 +474,3 @@ if ("CSQTcsqt".indexOf(cmd) >= 0) {

}
return [
boundingBox = [
minX,

@@ -456,7 +481,4 @@ minY,

];
}
var pf = parseFloat;
if (node.is("svg")) {
viewBox = node.get(0).getAttribute("viewBox");
} else if (nodeIs(node, "svg")) {
viewBox = node.getAttribute("viewBox");
if (viewBox) {

@@ -466,10 +488,9 @@ vb = parseFloats(viewBox);

return [
pf(node.attr("x")) || (vb && vb[0]) || 0,
pf(node.attr("y")) || (vb && vb[1]) || 0,
pf(node.attr("width")) || (vb && vb[2]) || 0,
pf(node.attr("height")) || (vb && vb[3]) || 0
pf(node.getAttribute("x")) || (vb && vb[0]) || 0,
pf(node.getAttribute("y")) || (vb && vb[1]) || 0,
pf(node.getAttribute("width")) || (vb && vb[2]) || 0,
pf(node.getAttribute("height")) || (vb && vb[3]) || 0
];
}
if (node.is("marker")) {
viewBox = node.get(0).getAttribute("viewBox");
} else if (nodeIs(node, "marker")) {
viewBox = node.getAttribute("viewBox");
if (viewBox) {

@@ -481,18 +502,34 @@ vb = parseFloats(viewBox);

(vb && vb[1]) || 0,
(vb && vb[2]) || pf(node.attr("marker-width")) || 0,
(vb && vb[3]) || pf(node.attr("marker-height")) || 0
(vb && vb[2]) || pf(node.getAttribute("marker-width")) || 0,
(vb && vb[3]) || pf(node.getAttribute("marker-height")) || 0
];
} else {
// TODO: check if there are other possible coordinate attributes
var x1 = pf(node.getAttribute("x1")) || pf(node.getAttribute("x")) || pf((node.getAttribute("cx")) - pf(node.getAttribute("r"))) || 0;
var x2 = pf(node.getAttribute("x2")) || (x1 + pf(node.getAttribute("width"))) || (pf(node.getAttribute("cx")) + pf(node.getAttribute("r"))) || 0;
var y1 = pf(node.getAttribute("y1")) || pf(node.getAttribute("y")) || (pf(node.getAttribute("cy")) - pf(node.getAttribute("r"))) || 0;
var y2 = pf(node.getAttribute("y2")) || (y1 + pf(node.getAttribute("height"))) || (pf(node.getAttribute("cy")) + pf(node.getAttribute("r"))) || 0;
boundingBox = [
Math.min(x1, x2),
Math.min(y1, y2),
Math.max(x1, x2) - Math.min(x1, x2),
Math.max(y1, y2) - Math.min(y1, y2)
];
}
// TODO: check if there are other possible coordinate attributes
var x1 = pf(node.attr("x1")) || pf(node.attr("x")) || pf((node.attr("cx")) - pf(node.attr("r"))) || 0;
var x2 = pf(node.attr("x2")) || (x1 + pf(node.attr("width"))) || (pf(node.attr("cx")) + pf(node.attr("r"))) || 0;
var y1 = pf(node.attr("y1")) || pf(node.attr("y")) || (pf(node.attr("cy")) - pf(node.attr("r"))) || 0;
var y2 = pf(node.attr("y2")) || (y1 + pf(node.attr("height"))) || (pf(node.attr("cy")) + pf(node.attr("r"))) || 0;
return [
Math.min(x1, x2),
Math.min(y1, y2),
Math.max(x1, x2) - Math.min(x1, x2),
Math.max(y1, y2) - Math.min(y1, y2)
];
if (!nodeIs(node, "marker,svg,g")) {
// add line-width
var lineWidth = getAttribute(node, "stroke-width") || 1;
var miterLimit = getAttribute(node, "stroke-miterlimit");
// miterLength / lineWidth = 1 / sin(phi / 2)
miterLimit && (lineWidth *= 0.5 / (Math.sin(Math.PI / 12)));
return [
boundingBox[0] - lineWidth,
boundingBox[1] - lineWidth,
boundingBox[2] + 2 * lineWidth,
boundingBox[3] + 2 * lineWidth
];
}
return boundingBox;
};

@@ -521,4 +558,4 @@

// draws a polygon
var polygon = function (n, tfMatrix, colorMode, gradient, gradientMatrix) {
var points = parsePointsString(n.attr("points"));
var polygon = function (node, tfMatrix, colorMode, gradient, gradientMatrix) {
var points = parsePointsString(node.getAttribute("points"));
var lines = [{op: "m", c: multVecMatrix(points[0], tfMatrix)}];

@@ -535,5 +572,5 @@ for (var i = 1; i < points.length; i++) {

// draws an image (converts it to jpeg first, as jsPDF doesn't support png or other formats)
var image = function (n) {
var image = function (node) {
// convert image to jpeg
var imageUrl = n.attr("xlink:href") || n.attr("href");
var imageUrl = node.getAttribute("xlink:href") || node.getAttribute("href");
var image = new Image();

@@ -543,4 +580,4 @@ image.src = imageUrl;

var canvas = document.createElement("canvas");
var width = parseFloat(n.attr("width")),
height = parseFloat(n.attr("height"));
var width = parseFloat(node.getAttribute("width")),
height = parseFloat(node.getAttribute("height"));
canvas.width = width;

@@ -564,4 +601,7 @@ canvas.height = height;

// draws a path
var path = function (n, node, tfMatrix, svgIdPrefix, colorMode, gradient, gradientMatrix) {
var path = function (node, tfMatrix, svgIdPrefix, colorMode, gradient, gradientMatrix) {
var list = getPathSegList(node);
var markerEnd = node.getAttribute("marker-end"),
markerStart = node.getAttribute("marker-start"),
markerMid = node.getAttribute("marker-mid");

@@ -571,8 +611,17 @@ var getLinesFromPath = function (pathSegList, tfMatrix) {

var x0 = x, y0 = y;
var prevX, prevY;
var from, to, p2, p3;
var prevX, prevY, newX, newY;
var to, p, p2, p3;
var lines = [];
var markers = [];
var op;
var prevAngle = 0, curAngle;
var addMarker = function (angle, anchor, type) {
var cos = Math.cos(angle);
var sin = Math.sin(angle);
var tf;
tf = new _pdf.Matrix(cos, sin, -sin, cos, anchor[0], anchor[1]);
markers.push({type: type, tf: _pdf.matrixMult(tf, tfMatrix)});
};
for (var i = 0; i < list.numberOfItems; i++) {

@@ -605,3 +654,4 @@ var seg = list.getItem(i);

op = "l";
x = seg.x;
newX = seg.x;
newY = y;
break;

@@ -611,3 +661,4 @@ case "h":

op = "l";
x = seg.x + x;
newX = seg.x + x;
newY = y;
break;

@@ -617,3 +668,4 @@ case "V":

op = "l";
y = seg.y;
newX = x;
newY = seg.y;
break;

@@ -623,3 +675,4 @@ case "v":

op = "l";
y = seg.y + y;
newX = x;
newY = seg.y + y;
break;

@@ -679,4 +732,24 @@ case "C":

var hasStartMarker = markerStart
&& (i === 1
|| ("mM".indexOf(cmd) < 0 && "mM".indexOf(list.getItem(i - 1).pathSegTypeAsLetter) >= 0));
var hasEndMarker = markerEnd
&& (i === list.numberOfItems - 1
|| ("mM".indexOf(cmd) < 0 && "mM".indexOf(list.getItem(i + 1).pathSegTypeAsLetter) >= 0));
var hasMidMarker = markerMid
&& i > 0
&& !(i === 1 && "mM".indexOf(list.getItem(i - 1).pathSegTypeAsLetter) >= 0);
if ("sScCqQtT".indexOf(cmd) >= 0) {
from = p3;
hasStartMarker && addMarker(getAngle([x, y], p2), [x, y], "start");
hasEndMarker && addMarker(getAngle(p3, to), to, "end");
if (hasMidMarker) {
curAngle = getAngle([x, y], p2);
curAngle = "mM".indexOf(list.getItem(i - 1).pathSegTypeAsLetter) >= 0 ?
curAngle : .5 * (prevAngle + curAngle);
addMarker(curAngle, [x, y], "mid");
}
prevAngle = getAngle(p3, to);
prevX = x;

@@ -695,3 +768,13 @@ prevY = y;

} else if ("lLhHvVmM".indexOf(cmd) >= 0) {
from = [x, y];
curAngle = getAngle([x, y], to);
hasStartMarker && addMarker(curAngle, [x, y], "start");
hasEndMarker && addMarker(curAngle, to, "end");
if (hasMidMarker) {
var angle = "mM".indexOf(cmd) >= 0 ?
prevAngle : "mM".indexOf(list.getItem(i - 1).pathSegTypeAsLetter) >= 0 ?
curAngle : .5 * (prevAngle + curAngle);
addMarker(angle, [x, y], "mid");
}
prevAngle = curAngle;
p = multVecMatrix(to, tfMatrix);

@@ -701,9 +784,2 @@ lines.push({op: op, c: p});

if (i === list.numberOfItems - 1
|| ("mM".indexOf(cmd) < 0 && "mM".indexOf(list.getItem(i + 1).pathSegTypeAsLetter) >= 0)) {
var a = Math.atan2(to[1] - from[1], to[0] - from[0]);
var tf = new _pdf.Matrix(Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), to[0], to[1]);
markers.push({type: "end", tf: _pdf.matrixMult(tf, tfMatrix)});
}
if ("MLCSQT".indexOf(cmd) >= 0) {

@@ -715,2 +791,5 @@ x = seg.x;

y = seg.y + y;
} else if ("zZ".indexOf(cmd) < 0) {
x = newX;
y = newY;
}

@@ -723,4 +802,3 @@ }

var markerEnd = n.attr("marker-end");
if (markerEnd) {
if (markerEnd || markerStart || markerMid) {
for (var i = 0; i < lines.markers.length; i++) {

@@ -730,4 +808,11 @@ var marker = lines.markers[i];

switch (marker.type) {
case "start":
markerElement = svgIdPrefix.get() + /url\(#(\w+)\)/.exec(markerStart)[1];
break;
case "end":
markerElement = svgIdPrefix.get() + /url\(#(\w+)\)/.exec(markerEnd)[1];
break;
case "mid":
markerElement = svgIdPrefix.get() + /url\(#(\w+)\)/.exec(markerMid)[1];
break;
}

@@ -745,4 +830,4 @@ _pdf.doFormObject(markerElement, marker.tf);

// to the pdf document. This highly reduces the file size and computation time.
var use = function (n, tfMatrix, svgIdPrefix) {
var url = (n.attr("href") || n.attr("xlink:href"));
var use = function (node, tfMatrix, svgIdPrefix) {
var url = (node.getAttribute("href") || node.getAttribute("xlink:href"));
// just in case someone has the idea to use empty use-tags, wtf???

@@ -752,14 +837,11 @@ if (!url)

// get the size of the referenced form object (to apply the correct saling)
// get the size of the referenced form object (to apply the correct scaling)
var formObject = _pdf.getFormObject(svgIdPrefix.get() + url.substring(1));
// scale and position it right
var x = n.attr("x") || 0;
var y = n.attr("y") || 0;
var width = n.attr("width") || formObject.width;
var height = n.attr("height") || formObject.height;
var t = _pdf.unitMatrix;
if (width > 0 && height > 0) {
t = new _pdf.Matrix(width / formObject.width, 0, 0, height / formObject.height, x, y);
}
var x = node.getAttribute("x") || 0;
var y = node.getAttribute("y") || 0;
var width = node.getAttribute("width") || formObject.width;
var height = node.getAttribute("height") || formObject.height;
var t = new _pdf.Matrix(width / formObject.width || 0, 0, 0, height / formObject.height || 0, x, y);
t = _pdf.matrixMult(t, tfMatrix);

@@ -770,5 +852,5 @@ _pdf.doFormObject(svgIdPrefix.get() + url.substring(1), t);

// draws a line
var line = function (n, tfMatrix) {
var p1 = multVecMatrix([parseFloat(n.attr('x1')), parseFloat(n.attr('y1'))], tfMatrix);
var p2 = multVecMatrix([parseFloat(n.attr('x2')), parseFloat(n.attr('y2'))], tfMatrix);
var line = function (node, tfMatrix) {
var p1 = multVecMatrix([parseFloat(node.getAttribute('x1')), parseFloat(node.getAttribute('y1'))], tfMatrix);
var p2 = multVecMatrix([parseFloat(node.getAttribute('x2')), parseFloat(node.getAttribute('y2'))], tfMatrix);
_pdf.line(p1[0], p1[1], p2[0], p2[1]);

@@ -778,10 +860,10 @@ };

// draws a rect
var rect = function (n, colorMode, gradient, gradientMatrix) {
var rect = function (node, colorMode, gradient, gradientMatrix) {
_pdf.roundedRect(
parseFloat(n.attr('x')) || 0,
parseFloat(n.attr('y')) || 0,
parseFloat(n.attr('width')),
parseFloat(n.attr('height')),
parseFloat(n.attr('rx')) || 0,
parseFloat(n.attr('ry')) || 0,
parseFloat(node.getAttribute('x')) || 0,
parseFloat(node.getAttribute('y')) || 0,
parseFloat(node.getAttribute('width')),
parseFloat(node.getAttribute('height')),
parseFloat(node.getAttribute('rx')) || 0,
parseFloat(node.getAttribute('ry')) || 0,
colorMode,

@@ -794,8 +876,8 @@ gradient,

// draws an ellipse
var ellipse = function (n, colorMode, gradient, gradientMatrix) {
var ellipse = function (node, colorMode, gradient, gradientMatrix) {
_pdf.ellipse(
parseFloat(n.attr('cx')) || 0,
parseFloat(n.attr('cy')) || 0,
parseFloat(n.attr('rx')),
parseFloat(n.attr('ry')),
parseFloat(node.getAttribute('cx')) || 0,
parseFloat(node.getAttribute('cy')) || 0,
parseFloat(node.getAttribute('rx')),
parseFloat(node.getAttribute('ry')),
colorMode,

@@ -808,7 +890,7 @@ gradient,

// draws a circle
var circle = function (n, colorMode, gradient, gradientMatrix) {
var radius = parseFloat(n.attr('r')) || 0;
var circle = function (node, colorMode, gradient, gradientMatrix) {
var radius = parseFloat(node.getAttribute('r')) || 0;
_pdf.ellipse(
parseFloat(n.attr('cx')) || 0,
parseFloat(n.attr('cy')) || 0,
parseFloat(node.getAttribute('cx')) || 0,
parseFloat(node.getAttribute('cy')) || 0,
radius,

@@ -823,16 +905,6 @@ radius,

// draws a text element and its tspan children
var text = function (n, node, tfMatrix, hasFillColor, fillRGB) {
var text = function (node, tfMatrix, hasFillColor, fillRGB) {
var fontFamily = getAttribute(node, "font-family");
if (fontFamily) {
switch (fontFamily.toLowerCase()) {
case 'serif':
_pdf.setFont('times');
break;
case 'monospace':
_pdf.setFont('courier');
break;
default:
_pdf.setFont('helvetica');
break;
}
_pdf.setFont(fontFamily);
}

@@ -896,7 +968,7 @@

tfMatrix.a, tfMatrix.b, tfMatrix.c, tfMatrix.d,
tfMatrix.e + (parseFloat(n.attr('x')) || 0),
tfMatrix.f + (parseFloat(n.attr('y')) || 0)
tfMatrix.e + (parseFloat(node.getAttribute('x')) || 0),
tfMatrix.f + (parseFloat(node.getAttribute('y')) || 0)
);
x = (parseFloat(n.attr("dx")) || 0) * pdfFontSize;
y = (parseFloat(n.attr("dy")) || 0) * pdfFontSize;
x = (parseFloat(node.getAttribute("dx")) || 0) * pdfFontSize;
y = (parseFloat(node.getAttribute("dy")) || 0) * pdfFontSize;
_pdf.setFontSize(pdfFontSize);

@@ -909,3 +981,3 @@

y,
removeNewlinesAndTrim(n.text()),
removeNewlinesAndTrim(node.textContent),
void 0,

@@ -916,11 +988,9 @@ m

// otherwise loop over tspans and position each relative to the previous one
n.children().each(function (i, tSpan) {
forEachChild(node, function (i, tSpan) {
var xOffset = getTextOffset(textAnchor, tSpan.getComputedTextLength());
var s = $(tSpan);
x += (parseFloat(s.attr("dx")) || 0) * pdfFontSize;
y += (parseFloat(s.attr("dy")) || 0) * pdfFontSize;
y += (parseFloat(tSpan.getAttribute("dy")) || 0) * pdfFontSize;
_pdf.text(
x - xOffset,
y,
removeNewlinesAndTrim(s.text()),
removeNewlinesAndTrim(tSpan.textContent),
void 0,

@@ -936,4 +1006,4 @@ m

// As defs elements are allowed to appear after they are referenced, we search for them at first
var findAndRenderDefs = function (n, tfMatrix, defs, svgIdPrefix, withinDefs) {
n.children().each(function (i, child) {
var findAndRenderDefs = function (node, tfMatrix, defs, svgIdPrefix, withinDefs) {
forEachChild(node, function (i, child) {
if (child.tagName.toLowerCase() === "defs") {

@@ -948,13 +1018,13 @@ renderNode(child, tfMatrix, defs, svgIdPrefix, withinDefs);

// processes a svg node
var svg = function (n, tfMatrix, defs, svgIdPrefix, withinDefs) {
var svg = function (node, tfMatrix, defs, svgIdPrefix, withinDefs) {
// create a new prefix and clone the defs, as defs within the svg should not be visible outside
var newSvgIdPrefix = svgIdPrefix.nextChild();
var newDefs = cloneDefs(defs);
findAndRenderDefs(n, tfMatrix, newDefs, newSvgIdPrefix, withinDefs);
renderChildren(n, tfMatrix, newDefs, newSvgIdPrefix, withinDefs);
findAndRenderDefs(node, tfMatrix, newDefs, newSvgIdPrefix, withinDefs);
renderChildren(node, tfMatrix, newDefs, newSvgIdPrefix, withinDefs);
};
// renders all children of a node
var renderChildren = function (n, tfMatrix, defs, svgIdPrefix, withinDefs) {
n.children().each(function (i, node) {
var renderChildren = function (node, tfMatrix, defs, svgIdPrefix, withinDefs) {
forEachChild(node, function (i, node) {
renderNode(node, tfMatrix, defs, svgIdPrefix, withinDefs);

@@ -967,3 +1037,3 @@ });

// transforms are applied on use
var putGradient = function (n, node, type, coords, defs, svgIdPrefix) {
var putGradient = function (node, type, coords, defs, svgIdPrefix) {
var colors = [];

@@ -973,9 +1043,8 @@ var opacitySum = 0;

var gState;
n.children().each(function (i, element) {
forEachChild(node, function (i, element) {
// since opacity gradients are hard to realize, avarage the opacity over the control points
if (element.tagName.toLowerCase() === "stop") {
var e = $(element);
var color = new RGBColor(getAttribute(element, "stop-color"));
colors.push({
offset: parseFloat(e.attr("offset")),
offset: parseFloat(element.getAttribute("offset")),
color: [color.r, color.g, color.b]

@@ -996,3 +1065,3 @@ });

var pattern = new _pdf.Pattern(type, coords, colors, gState);
var id = svgIdPrefix.get() + n.attr("id");
var id = svgIdPrefix.get() + node.getAttribute("id");
_pdf.addPattern(id, pattern);

@@ -1012,6 +1081,2 @@ defs[id] = node;

var renderNode = function (node, contextTransform, defs, svgIdPrefix, withinDefs) {
var n = $(node); // jquery node for comfort
var tfMatrix,

@@ -1031,8 +1096,8 @@ hasFillColor = false,

// of the top-level page
var targetIsFormObject = withinDefs && "lineargradient,radialgradient".indexOf(node.tagName.toLowerCase()) < 0;
var targetIsFormObject = withinDefs && !nodeIs(node, "lineargradient,radialgradient");
if (targetIsFormObject) {
// the transformations directly at the node are written to the pdf form object transformation matrix
tfMatrix = computeNodeTransform(n);
bBox = getUntransformedBBox(n);
tfMatrix = computeNodeTransform(node);
bBox = getUntransformedBBox(node);

@@ -1046,3 +1111,3 @@ _pdf.beginFormObject(bBox[0], bBox[1], bBox[2], bBox[3], tfMatrix);

} else {
tfMatrix = _pdf.matrixMult(computeNodeTransform(n), contextTransform);
tfMatrix = _pdf.matrixMult(computeNodeTransform(node), contextTransform);
_pdf.saveGraphicsState();

@@ -1056,4 +1121,4 @@ }

// fill mode
if (n.is('g,path,rect,text,ellipse,line,circle,polygon')) {
var fillColor = n.attr('fill');
if (nodeIs(node, "g,path,rect,text,ellipse,line,circle,polygon")) {
var fillColor = node.getAttribute("fill");
if (fillColor) {

@@ -1065,3 +1130,3 @@ var url = /url\(#(\w+)\)/.exec(fillColor);

var fill = getFromDefs(gradient, defs);
if ("lineargradient,radialgradient".indexOf(fill.tagName.toLowerCase()) >= 0) {
if (nodeIs(fill, "lineargradient,radialgradient")) {

@@ -1074,6 +1139,6 @@ // matrix to convert between gradient space and user space

|| fill.getAttribute("gradientUnits").toLowerCase() === "objectboundingbox") {
bBox = getUntransformedBBox(n);
bBox = getUntransformedBBox(node);
gradientUnitsMatrix = new _pdf.Matrix(bBox[2], 0, 0, bBox[3], bBox[0], bBox[1]);
var nodeTransform = computeNodeTransform(n);
var nodeTransform = computeNodeTransform(node);
gradientUnitsMatrix = _pdf.matrixMult(gradientUnitsMatrix, nodeTransform);

@@ -1105,3 +1170,3 @@ }

// opacity is realized via a pdf graphics state
var opacity = n.attr("opacity") || n.attr("fill-opacity");
var opacity = node.getAttribute("opacity") || node.getAttribute("fill-opacity");
if (opacity) {

@@ -1114,3 +1179,3 @@ _pdf.setGState(new _pdf.GState({opacity: parseFloat(opacity)}));

if (n.is('g,path,rect,ellipse,line,circle,polygon')) {
if (nodeIs(node, "g,path,rect,ellipse,line,circle,polygon")) {
// text has no fill color, so apply it not until here

@@ -1122,6 +1187,6 @@ if (hasFillColor) {

// stroke mode
var strokeColor = n.attr('stroke');
var strokeColor = node.getAttribute('stroke');
if (strokeColor) {
if (node.hasAttribute("stroke-width")) {
_pdf.setLineWidth(Math.abs(parseFloat(n.attr('stroke-width'))));
_pdf.setLineWidth(Math.abs(parseFloat(node.getAttribute('stroke-width'))));
}

@@ -1134,13 +1199,16 @@ var strokeRGB = new RGBColor(strokeColor);

if (node.hasAttribute("stroke-linecap")) {
_pdf.setLineCap(n.attr("stroke-linecap"));
_pdf.setLineCap(node.getAttribute("stroke-linecap"));
}
if (node.hasAttribute("stroke-linejoin")) {
_pdf.setLineJoin(n.attr("stroke-linejoin"));
_pdf.setLineJoin(node.getAttribute("stroke-linejoin"));
}
if (node.hasAttribute("stroke-dasharray")) {
_pdf.setLineDashPattern(
parseFloats(n.attr("stroke-dasharray")),
parseInt(n.attr("stroke-dashoffset")) || 0
parseFloats(node.getAttribute("stroke-dasharray")),
parseInt(node.getAttribute("stroke-dashoffset")) || 0
);
}
if (node.hasAttribute("stroke-miterlimit")) {
_pdf.setLineMiterLimit(parseFloat(node.getAttribute("stroke-miterlimit")));
}
}

@@ -1152,21 +1220,21 @@ }

case 'svg':
svg(n, tfMatrix, defs, svgIdPrefix, withinDefs);
svg(node, tfMatrix, defs, svgIdPrefix, withinDefs);
break;
case 'g':
findAndRenderDefs(n, tfMatrix, defs, svgIdPrefix, withinDefs);
findAndRenderDefs(node, tfMatrix, defs, svgIdPrefix, withinDefs);
case 'a':
case "marker":
renderChildren(n, tfMatrix, defs, svgIdPrefix, withinDefs);
renderChildren(node, tfMatrix, defs, svgIdPrefix, withinDefs);
break;
case 'defs':
renderChildren(n, tfMatrix, defs, svgIdPrefix, true);
renderChildren(node, tfMatrix, defs, svgIdPrefix, true);
break;
case 'use':
use(n, tfMatrix, svgIdPrefix);
use(node, tfMatrix, svgIdPrefix);
break;
case 'line':
line(n, tfMatrix);
line(node, tfMatrix);
break;

@@ -1176,3 +1244,3 @@

_pdf.setCurrentTransformationMatrix(tfMatrix);
rect(n, colorMode, gradient, gradientMatrix);
rect(node, colorMode, gradient, gradientMatrix);
break;

@@ -1182,3 +1250,3 @@

_pdf.setCurrentTransformationMatrix(tfMatrix);
ellipse(n, colorMode, gradient, gradientMatrix);
ellipse(node, colorMode, gradient, gradientMatrix);
break;

@@ -1188,14 +1256,14 @@

_pdf.setCurrentTransformationMatrix(tfMatrix);
circle(n, colorMode, gradient, gradientMatrix);
circle(node, colorMode, gradient, gradientMatrix);
break;
case 'text':
text(n, node, tfMatrix, hasFillColor, fillRGB);
text(node, tfMatrix, hasFillColor, fillRGB);
break;
case 'path':
path(n, node, tfMatrix, svgIdPrefix, colorMode, gradient, gradientMatrix);
path(node, tfMatrix, svgIdPrefix, colorMode, gradient, gradientMatrix);
break;
case 'polygon':
polygon(n, tfMatrix, colorMode, gradient, gradientMatrix);
polygon(node, tfMatrix, colorMode, gradient, gradientMatrix);
break;

@@ -1205,19 +1273,23 @@

_pdf.setCurrentTransformationMatrix(tfMatrix);
image(n);
image(node);
break;
case "lineargradient":
putGradient(n, node, "axial", [n.attr("x1"), n.attr("y1"), n.attr("x2"), n.attr("y2")], defs, svgIdPrefix);
putGradient(node, "axial", [
node.getAttribute("x1"),
node.getAttribute("y1"),
node.getAttribute("x2"),
node.getAttribute("y2")
], defs, svgIdPrefix);
break;
case "radialgradient":
var coords = [
n.attr("fx") || n.attr("cx"),
n.attr("fy") || n.attr("cy"),
putGradient(node, "radial", [
node.getAttribute("fx") || node.getAttribute("cx"),
node.getAttribute("fy") || node.getAttribute("cy"),
0,
n.attr("cx") || 0,
n.attr("cy") || 0,
n.attr("r") || 0
];
putGradient(n, node, "radial", coords, defs, svgIdPrefix);
node.getAttribute("cx") || 0,
node.getAttribute("cy") || 0,
node.getAttribute("r") || 0
], defs, svgIdPrefix);
break;

@@ -1228,3 +1300,3 @@ }

if (targetIsFormObject) {
_pdf.endFormObject(svgIdPrefix.get() + n.attr("id"));
_pdf.endFormObject(svgIdPrefix.get() + node.getAttribute("id"));
} else {

@@ -1236,3 +1308,3 @@ _pdf.restoreGraphicsState();

// the actual svgToPdf function (see above)
return function (element, pdf, options) {
var svg2pdf = function (element, pdf, options) {
_pdf = pdf;

@@ -1254,2 +1326,13 @@

};
})();
if (typeof define === 'function' && define.amd) {
define("svg2pdf", function () {
return svg2pdf;
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = svg2pdf;
} else {
global.svg2pdf = svg2pdf;
}
return svg2pdf;
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this));
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc