svg2pdf.js icon indicating copy to clipboard operation
svg2pdf.js copied to clipboard

Provide `href` attribute support in `a` elements

Open linev opened this issue 1 year ago • 2 comments

This PR provide possible solution for #312

To be able use jsPDF.link() method, one need to have valid bounding box for all child nodes of a element.

Seems to be, existing implementation of getBoundingBoxByChildren function is not correct. First commit excludes dummy box (all 0) from consideration. Also transformation attributes from child nodes are taken into account - for now only translations.

While text node is most probable candidate to be used inside a element - one have to provide reasonable bounding box implementation for it. In the PR second method is just workaround to avoid re-implementation of rendering again to just get bounding box. Provided solution works only for plain text without tspan elements inside.

Last commit implements GroupA class which extends normal Group rendering and creates link in the PDF document. Here some internals of jsPDF context are used - maybe better solution can be provided.

linev avatar Oct 01 '24 11:10 linev

Thanks!

At the very least we should build upon the fix for the getBoundingBoxByChildren function - however implementing it properly with the transformation should not be too difficult, either, so I guess this should be done, too, because even though translations are common, scales are probably at least as common and this seems to fail. Is this function never used in other contexts? I wonder how it could be that broken....

That said, it would be very helpful, if you could come up with a few test cases, ideally some that show the various problematic combinations with transforms etc. so that we have test cases, even if they fail.

yGuy avatar Oct 01 '24 11:10 yGuy

If I am right - I cannot use Point class from jsPDF and therefore Matrix.applyToPoint() method is not available.

I add commit which directly applies x/y axis scales from the matrix.

As primary example one can use SVG from developer.mozilla.org. Also here is SVG with some transform attributes:

canvas

linev avatar Oct 01 '24 12:10 linev

I rebase PR, introducing Anchor class instead of GroupA.

I did not try to use multVecMatrix while it is not trivial for the box computation. One need to translate all 4 corners of the boundary box separately to get correct positions - but then it is not that one really can use afterwards.

I add test/specs/anchor/ with several <a> elements. Test also shows thatsvg2pdf.js does not support dominant-baseline attribute. This can be fixed by separate PR.

linev avatar Oct 28 '24 12:10 linev

I would love some test cases with links on elements other than text and maybe some rotated elements after rotation is considered in the bounding box.

But one need to implement bounding box for such elements.

linev avatar Oct 31 '24 11:10 linev

I tried to implement bounding box using multVecMatrix function. And add test with rotated text inside anchor.

Not sure that method works properly - see produced pdf in the anchor-rotation test. In the SVG I used text like:

<text dy="0.2em" transform="rotate(180) translate(40)" font-size="20">rotate(180)</text>

Here three different transformations are applied - rotation, translate X, translate Y. Not sure that such transformation properly can be described by single matrix - especially if one swap order like transform="translate(40) rotate(180)"

linev avatar Oct 31 '24 12:10 linev

You're right. The bounding boxes of the rotated elements are not correct. The multVecMatrix function should theoretically be correct. At quick glance I couldn't figure out what the issue is. Maybe you can step-debug a bit? Or draw the boxes into the PDF for debugging?

HackbrettXXX avatar Nov 05 '24 14:11 HackbrettXXX

Can we split this?

One PR is creation of URL link for <a> elements.

Second is proper calculation of bounding box in case of rotated <text> elements.

And maybe third is testing if bounding box for all other elements like <rect> or <path> gives reasonable results.

linev avatar Nov 05 '24 14:11 linev

Yes, sure.

HackbrettXXX avatar Nov 06 '24 09:11 HackbrettXXX

Yes, sure.

Then I removing last two commits and will create another PR - once this is finalized

linev avatar Nov 06 '24 09:11 linev

Yes, I did it

linev avatar Nov 07 '24 15:11 linev

Any news here?

linev avatar Feb 05 '25 15:02 linev

Hey, sorry for the delay. I'm currently quite busy with other stuff, but I will review it as soon as I get to it.

HackbrettXXX avatar Feb 06 '25 08:02 HackbrettXXX