Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern inside SVG not influenced by SVG offset inside PDF, unexpected point of origin #212

Open
DarSim2 opened this issue Apr 28, 2022 · 12 comments
Labels
bug difficulty:medium help wanted Help with creating a proper test-case, looking up the spec, or creating a pull request.

Comments

@DarSim2
Copy link

DarSim2 commented Apr 28, 2022

I have a SVG containing a pattern and a rect which is filled with said pattern:

<svg xmlns="https://www.w3.org/2000/svg" version="1.1" xmlns:xlink="https://www.w3.org/1999/xlink" xmlns:svgjs="https://svgjs.dev/svgjs" width="200" height="200">
    <defs>
        <pattern x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse" id="SvgjsPattern1003">
            <rect width="10" height="10" fill="purple" x="0" y="0"></rect>
            <rect width="10" height="10" fill="pink" x="10" y="10"></rect>
        </pattern>
    </defs>
    <rect width="75" height="75" fill="url('#SvgjsPattern1003')"></rect>
</svg>

When I convert to PDF with a x and/or y offset then the pattern doesn't inherit the offset. It doesn't start at (0, 0) of the SVG inside the PDF but apparently the pattern starts at (0, 0) of the PDF.

const pdfDoc = new jsPDF({ orientation: 'l', unit: 'pt', format: 'a4' })
pdfDoc.svg(nested.node, {
                x: 17,
                y: 32,
            })
            .then(() => {
                pdfDoc.save('testStuffPDF')
            })

And when I print the PDF then the printer adds some margins of its own which offsets the pattern again so that the printed element filled with the pattern doesn't look the same as its counterpart on the screen.

I know that the pattern inside a SVG always starts at (0, 0) of the SVG itself.
This is the behavior I would also expect to be seen in the PDF. Pattern should start at the origin of the SVG inside the PDF not the origin of the PDF.

pattern_no_offset.pdf
pattern_with_offset.pdf

@HackbrettXXX
Copy link
Member

Thanks for the bug report. I was able to reproduce it.

@HackbrettXXX HackbrettXXX added bug help wanted Help with creating a proper test-case, looking up the spec, or creating a pull request. difficulty:medium labels Apr 28, 2022
@DarSim2
Copy link
Author

DarSim2 commented Aug 5, 2022

Hi, I just wanted to ask, if there is any development in this matter?

Because this became kind of a pressing matter for me, so I forked svg2pdf and tried to analyze the issue with a collegue.
We didn't manage to find a fix. Our current observations are the following, maybe this will help you:

  1. BoundingBox in pattern.ts is calculated correctly (for the pattern element)
  2. Our guess is that the rendered children of the pattern in their render() call do not take the offset of the pattern parent element into account

@yGuy
Copy link
Member

yGuy commented Aug 5, 2022

Unfortunately, there was no progress, here, so far. We would have removed the "help wanted" tag if we were working on the task. HackbrettXXX is not available at the moment and won't be for the next couple of months, as far as I can tell. I am sorry to say, so we depend on the community to step in.

Is this a problem with the way we interpret the SVG or is this a problem with the way js2pdf writes the PDF? Have you been able to narrow down the issue?

What are the corresponding involved specs for the behavior?

@DanielBretzigheimer
Copy link

I have looked into the issue and I am trying to fix it. In my research, I have found some other issues:

  1. using a unit other than pt will scale the pattern elements wrong
    In the following sample the red rectange has the same size as the blue rectangles in the svg (20 x 20). With unit 'pt' this works correct, but when changed to e.g. 'mm' they scale differently.
    SVG:
    image
    PDF:
    image

  2. adding an offset to the pattern will result in differences between svg and pdf (see here)
    image
    PDF:
    image

I'll find these bugs and create a PR which hopefully resolves all these issues.

DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 11, 2022
DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 11, 2022
DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 11, 2022
DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 12, 2022
DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 12, 2022
@DanielBretzigheimer
Copy link

After further investigation, we found a solution for the scaling problem in units besides pt. We had to apply the context.pdf.internal.scaleFactor to the TilingPattern and the child transform. This worked, but showed the next issue we couldn't solve.

The tiling pattern doesn't start at y = 0 and looks to be offset a little. We speculated that this could be from text baseline or something like that. If you have any idea how this could be fixed, please tell us. We will look further into the issue.

SVG:
image

PDF:
image

DanielBretzigheimer pushed a commit to DanielBretzigheimer/svg2pdf.js that referenced this issue Aug 13, 2022
@DarSim2
Copy link
Author

DarSim2 commented Aug 16, 2022

I tried the fix from @DanielBretzigheimer 's PR, it is working 😄

@DarSim2
Copy link
Author

DarSim2 commented Aug 24, 2022

I found another related problem with the pattern in PDF, it also doesn't consider viewbox values of the svg. It just alsways shows the same part of the pattern as if there was no viewbox on the svg

@Shiuyin
Copy link

Shiuyin commented May 25, 2023

Is there any update to this? Without fixing this issue, it is not possible to use any types of pattern objects in combination with this lib.

@yGuy
Copy link
Member

yGuy commented May 25, 2023

That's not true. For one, there have been improvements (check the commits above) and secondly "not possible to use any type of pattern" is wrong. Many patterns do work. Which one specifically does not work for you? Can you share a repro?

@Shiuyin
Copy link

Shiuyin commented May 26, 2023

Thanks for your answer.

  1. I know the commits above, i helped DanielBretzigheimer working on them, he is a colleague of mine.
  2. These commits have not been merged into the official lib.
  3. These commits still do not adress open issues with patterns as DarSim2 has pointed out (viewbox handling) and we were unable to fix them on our own when we tried.
  4. Example code is in the original issue, just add a viewbox to it.

@yGuy
Copy link
Member

yGuy commented May 27, 2023

OK. So to summarize: there are still cases that don't work for you, but the feature does work for many other patterns. You helped try to solve the issue (thanks!) but you were unsuccessful and need help. That's what the tag at this issue says. So I guess the answer to your question is: no, there aren't any updates, sorry. If you can find someone who can fix it for you, we will be happy to accept a PR. If this is super important to you, you could open a bounty and have someone work on it.

@Shiuyin
Copy link

Shiuyin commented May 31, 2023

Correct. I hope to be able to look into it myself in a few weeks again.

Rootek pushed a commit to Rootek/svg2pdf.js that referenced this issue Jun 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug difficulty:medium help wanted Help with creating a proper test-case, looking up the spec, or creating a pull request.
Projects
None yet
Development

No branches or pull requests

5 participants