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

Transform on clipPath does not work #366

Open
blayzen-w opened this issue Dec 9, 2022 · 2 comments
Open

Transform on clipPath does not work #366

blayzen-w opened this issue Dec 9, 2022 · 2 comments

Comments

@blayzen-w
Copy link

blayzen-w commented Dec 9, 2022

When clipPaths contain a path with a transform, the path is ignored and discarded with the error message Unsupported shape type Group for clipping.

The svg I am testing with is the following:

<svg namespace="http://www.w3.org/XML/1998/namespace" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <defs>
        <clipPath id="clip-1">
            <path transform="scale(0.5, 0.5)" d="M 50, 50 m -50, 0 a 50,50 0 1,0 100,0 a 50,50 0 1,0 -100,0"/>
        </clipPath>
    </defs>
    <g>
        <g clip-path="url(#clip-1)">
            <path d="M25,25h-50v-50h50V25z"/>
        </g>
    </g>
</svg>

I don't believe this was happening with earlier versions so I decided to do some digging and narrowed the problem down.

The error that is displayed starts here, when the detected shape from the node is neither a Path or a Rect despite the svg using a path element.

svglib/svglib/svglib.py

Lines 655 to 656 in 9a43d4f

elif shape:
logging.error("Unsupported shape type %s for clipping", shape.__class__.__name__)

This is caused from the convertShape function where, if there is a transform, then it will add the shape to a group and apply the transform to the group instead of the shape.

svglib/svglib/svglib.py

Lines 895 to 916 in 9a43d4f

class Svg2RlgShapeConverter(SvgShapeConverter):
"""Converter from SVG shapes to RLG (ReportLab Graphics) shapes."""
def convertShape(self, name, node, clipping=None):
method_name = f"convert{name.capitalize()}"
shape = getattr(self, method_name)(node)
if not shape:
return
if name not in ('path', 'polyline', 'text'):
# Only apply style where the convert method did not apply it.
self.applyStyleOnShape(shape, node)
transform = node.getAttribute("transform")
if not (transform or clipping):
return shape
else:
group = Group()
if transform:
self.applyTransformOnGroup(transform, group)
if clipping:
group.add(clipping)
group.add(shape)
return group

I did a quick test and applied the transform directly on the path element and everything seemed to work fine, however I'm not sure if there are any unintended side effects from doing it this way. Is this an intended feature or could I work on a patch to add an optional argument to apply the transformation directly for this use case?

Edit: I doubled checked the output and the transformed path was not placed or transformed correctly so additional work may be needed with this part.

@github-actions
Copy link

github-actions bot commented Dec 9, 2022

Thank you for raising your first issue! Your help to improve svglib is much appreciated!

@claudep
Copy link
Collaborator

claudep commented Dec 9, 2022

I don't remember if the fact to apply transforms only on shapes was a conveniency, or if it was required. Feel free to experiment and suggest changes if they are successful.

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

No branches or pull requests

2 participants