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

SVG rendering #1147

Closed
RubendeBruin opened this issue Apr 12, 2024 · 4 comments · Fixed by #1150
Closed

SVG rendering #1147

RubendeBruin opened this issue Apr 12, 2024 · 4 comments · Fixed by #1150
Labels

Comments

@RubendeBruin
Copy link

RubendeBruin commented Apr 12, 2024

I'm rendering a .svg image (attached). In 2.7.6 this worked fine, in 2.7.7 it broke and in 2.7.8 the result is incorrect.

Version 2.7.6:
Renders OK:
image

Version 2.7.7:
Fails with

  File "C:\python\venvs\work11\Lib\site-packages\fpdf\svg.py", line 870, in handle_defs
    self.build_clipping_path(child_, clip_id)
  File "C:\python\venvs\work11\Lib\site-packages\fpdf\svg.py", line 968, in build_clipping_path
    clipping_path_shape = getattr(ShapeBuilder, shape_tags[shape.tag])(shape, True)
                                                ~~~~~~~~~~^^^^^^^^^^^
KeyError: '{http://www.w3.org/2000/svg}path'

Version fpdf2-2.7.8 (including current master branch): Renders incorrectly
image

Minimal code

from fpdf import FPDF

pdf = FPDF()
pdf.add_page()


fname = f"overflow1.svg"    # this is the .svg below
pdf.image(fname, w=pdf.epw )

pdf.output("report.pdf")

Environment
Please provide the following information: Windows 11, Python 3.11

Reference SVG:
overflow1

@andersonhc
Copy link
Collaborator

I don't know much about SVG but taking a quick look I believe the problem is the clipping path being painted.
Looking how ClippingPath() works setting paint_rule to PathPaintRule.DONT_PAINT at init, I tried doing the same for path and it seems to work.

    def build_clipping_path(self, shape, clip_id):
        if shape.tag in shape_tags:
            shape_builder = getattr(ShapeBuilder, shape_tags[shape.tag])
            clipping_path_shape = shape_builder(shape, True)
        elif shape.tag in xmlns_lookup("svg", "path"):
            clipping_path_shape = PaintedPath()
            apply_styles(clipping_path_shape, shape)
            clipping_path_shape.paint_rule = PathPaintRule.DONT_PAINT  # line added
            svg_path = shape.attrib.get("d")
            if svg_path is not None:
                svg_path_converter(clipping_path_shape, svg_path)
        else:
            LOGGER.warning(
                "Ignoring unsupported <clipPath> child tag: <%s> (contributions are welcome to add support for it)",
                without_ns(shape.tag),
            )
            return
        self.update_xref(clip_id, clipping_path_shape)

@Lucas-C can you please check if it makes sense?

@RubendeBruin
Copy link
Author

hi @andersonhc , thank for looking into this. Do you have a fork/branch that I can check out to have a look?

@andersonhc
Copy link
Collaborator

andersonhc commented Apr 22, 2024

Hey @RubendeBruin

Here is the branch I created:
https://github.com/andersonhc/fpdf2/tree/svg

Is it OK using your file on a unit test?
I will start a PR soon

@RubendeBruin
Copy link
Author

Hi @andersonhc ,
"Is it OK using your file on a unit test?": Yes
FYI: it is the measured waves somewhere in the north-sea.

gmischler pushed a commit that referenced this issue Apr 25, 2024
* Add DONT_PAINT to path clippingPath

* fix missing import

* add test

* add changelog
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants