svglib icon indicating copy to clipboard operation
svglib copied to clipboard

Is the preserveAspectRatio attribute taken into account?

Open dannmartens opened this issue 6 years ago • 5 comments

Hi,

I've found that in the generated PDF from an SVG image, the image has lost its original aspect ratio.

For example, a setting of

preserveAspectRatio="xMidYMid meet"

will render the image, :

xMidYMid (the default) - Force uniform scaling.

  • align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
  • align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport.

and

meet (the default) - Scale the graphic such that:

  • aspect ratio is preserved
  • the entire viewBox is visible within the viewport
  • the viewBox is scaled up as much as possible, while still meeting the other criteria

With a native SVG renderer, this works as expected.

With svglib, it seems the image is stretched to fill the available page within margins.

Does svg2rlg take this attribute into account? Or are there perhaps parameters which need to be set properly to preserve aspect ratio with respect to the viewbox?

Thanks, Dann

dannmartens avatar Nov 12 '19 14:11 dannmartens

No, I dont' think we are currently taking this parameter into account.

claudep avatar Nov 12 '19 14:11 claudep

This is the spec explained: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

dannmartens avatar Nov 12 '19 16:11 dannmartens

I‘m not sure we have the resources for adding this now. Or let‘s say I know I don‘t. But we do encourage and accept PRs. And should do it more often.

deeplook avatar Nov 12 '19 21:11 deeplook

It's probably somewhere around here, where the preserveAspectRatio should be taken into account:

    def render(self, svg_node):
        node = NodeTracker(svg_node)
        view_box = self.get_box(node, default_box=True)
        # Knowing the main box is useful for percentage units
        self.attrConverter.set_box(view_box)

        main_group = self.renderSvg(node, outermost=True)
        for xlink in self.waiting_use_nodes.keys():
            logger.debug("Ignoring unavailable object width ID '%s'." % xlink)

        main_group.translate(0 - view_box.x, -view_box.height - view_box.y)

        width, height = self.shape_converter.convert_length_attrs(
            svg_node, "width", "height", defaults=(view_box.width, view_box.height)
        )
        drawing = Drawing(width, height)
        drawing.add(main_group)
        return drawing

Where does the stretching occur? Just by doing drawing.add(main_group)? I mean width and height are the actual page size, the main_group appears to be only translated. Or is it caused by self.attrConverter.set_box(view_box)?

dannmartens avatar Nov 13 '19 10:11 dannmartens

I see preserveAspectRatio is used in tests/samples/others/png_in_svg.svg, but I can't do any testing for now, sorry.

deeplook avatar Nov 14 '19 10:11 deeplook