Closed FHoffmannSopra closed 3 years ago
From this information alone I cannot reproduce the issue. I can guess that the exception might originate from here: https://github.com/MrRio/jsPDF/blob/d8bb3b39efcd129994f7a3b01b632164144ec43e/src/modules/annotations.js#L84-L88
However, this would mean that adding pages is completely broken in jsPDF, which it isn't. Do you call any other jsPDF methods besides the svg() call (e.g. link() or textWithLink())?
In order to help you we need to be able to reproduce the issue. Could you share a small example with two SVGs that cause the exception and the code that produces the PDF?
I can give you the library specific code and two example Svg's for now. I hope it helps
/** renders multiPage Pdf
* @param {Array} _canvasObjects all svgCanvasObjects that should be rendered on pdf
* @param {String} _fileName name of output file
* @memberof PdfController
*/
function _renderMultiPagePdf(_canvasObjects, _fileName) {
const canvas = _canvasObjects[0];
_canvasObjects.shift();
const width = canvas.width + 2*canvas.padding.horizontal;
const height = canvas.height + 2*canvas.padding.vertical;
const svgElement = document.getElementById(canvas.id);
let doc;
if (width > height) {doc = new jsPDF("1", "pt", [width, height]);} else {doc = new jsPDF("0", "pt", [width, height]);}
doc
.svg(svgElement, {
x: 0 + canvas.padding.horizontal,
y: 0 + canvas.padding.vertical,
width: width,
height: height,
})
.then(() => {
const start = async () => {
await renderAllPagesBesidesFirst(_canvasObjects, doc);
doc.save(`${_fileName}`);
const div = document.getElementById("pdfExportWrapper");
while (div.firstChild) {
div.removeChild(div.firstChild);
}
};
start();
});
/** renders all remaining pages
* @param {Array} _array remaining pages
* @param {*} _doc jsPdf document
*/
async function renderAllPagesBesidesFirst(_array, _doc) {
for (let index = 0; index < _array.length; index++) {
const canvas = _array[index];
const width = canvas.width + 2*canvas.padding.horizontal;
const height = canvas.height + 2*canvas.padding.vertical;
const svgElement = document.getElementById(canvas.id);
if (width > height) {
_doc.addPage([width, height, "1"]);
} else {
_doc.addPage([width, height], "0");
}
await _doc
.svg(svgElement, {
x: 0 + canvas.padding.horizontal,
y: 0 + canvas.padding.vertical,
width: width,
height: height,
});
}
}
}
Thanks for sharing your code with us. When I run it with the two SVGs, I get a different error:
Uncaught (in promise) TypeError: Cannot read property 'offset' of undefined
That's the same bug you reported in #165. However, I could not reproduce your exception.
Thanks for your research first of all. You are absolutely right I am fixing the gradients without stops dynamically and forgot to also send that workaround.
Back to the topic of this thread:
I did analyze my Svg's in detail and detected that the def
-Block is quite messy (around 2000 lines of code).
I tried to localize this, which also include a huge amount of href
-Statements and it turned out that a specific part of the Svg causes the majority of statements in there.
I guess that is caused by copy and pasting things in InkScape multiple times (maybe 50 times or sth like that).
When I removed that specific parts and transfered the rest to a clean file, I could not reproduce the error.
So I encourage everyone that detects such cross page errors to clean up their Svg files, in case their def
-Block seems too heavy for the things they have drawn.
I will let you know if I can detect what exactly crashes the library.
Hey guys,
After more research I found a case for which I could isolate the error better. I also fixed the gradients for you, so testing should be possible now.
The two svgs I will attach are just multiple gradient colored lines. They differ in these aspects:
1) pathObjects.svg
<path/>
object2) useObjects.svg
<use/>
objectjsPdf PubSub Error
appears, but only when drawn to two different pagesThanks for your help Frederic
- but not appearing on the PDF, which is most likely caused by another problem or an unsupported feature
I tested also with non gradient colored lines, the lines are rendered correctly
Thanks for narrowing it down. The lines don't appear in the PDF because gradients are not supported on strokes.
I could also reproduce the PubSub error now. There are two bugs, one in jsPDF and one in svg2pdf:
var endFormObject = function(key) {
// only add it if it is not already present (the keys provided by the user must be unique!)
if (renderTargetMap[key]) return;
// save the created xObject
var newXObject = new RenderTarget();
var xObjectId = "Xo" + (Object.keys(renderTargets).length + 1).toString(10);
newXObject.id = xObjectId;
renderTargetMap[key] = xObjectId;
renderTargets[xObjectId] = newXObject;
events.publish("addFormObject", newXObject);
// restore state from stack
renderTargetStack.pop().restore();
};
The early exit leaves jsPDF in a bad state, resulting in the exception when writing the pages. The early exit is missing the renderTargetStack.pop().restore();
line. I've created an issue for that: https://github.com/MrRio/jsPDF/issues/3127
We are running into this case, because we render the same SVG twice, resulting in the path with id path853
drawn twice. The second time will not be written to PDF because of above early exit and there is already an form object with the given id. While in this particular case this actually benefits the file size, in general we should write all form objects from different SVGs even if they have the same id. I suggest we prefix the ids passed to jsPDF. Either keep a counter for the current svg2pdf invocation or generate a hash from the SVG. We can probably just extend this function:
Hey guys,
I tried to render the same SVG image in my pdf with the svg2pdf tool on two different pages in the document.
For most of the Svg-files I have that works perfectly.
But for some Svg's I get the following behavior:
Unfortunately I could not isolate the problem better, except for the fact that when I remove all
xlink:href
attributes it works fine. Sincexlink:href
is deprecated in the Svg-standard, I did also tryhref
instead, but got no positive effects. Not to usehref
is not an option for me.I have seen that the error is thrown by the jsPdf library, but I am not sure if its a problem with the preprocessing of svg2pdf or indeed a problem with jsPdf.
If I can provide more information just let me know.
The Svg's are created with InkScape.
I am using svg2pdf 2.0.0 and jsPdf 2.0.0.
Thanks for your help Frederic