linebender / resvg

An SVG rendering library.
Apache License 2.0
2.84k stars 229 forks source link

viewbox values get rounded to nearest int #810

Open RiedleroD opened 2 months ago

RiedleroD commented 2 months ago

Not much to explain here, the issue is quite simple. I hope the fix will be simple too 🀞🏻 I've attached some renders of a test image. I tested in resvg 0.41 and 0.43

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1.5 1.5">
    <rect fill="green" width="1.7" height="1.7"/>
    <rect fill="blue" width="1.5" height="1.5"/>
    <rect fill="red" width="1.2" height="1.2"/>
</svg>
Impl Image viewbox size command
Your Browser test - -
rsvg test_rsvg 1.5x1.5 rsvg-convert test.svg -w 100 -o test_rsvg.png
inkscape test_inkscape 1.5x1.5 inkscape "/home/riedler/Downloads/test.svg" --export-filename="test_inkscape.png" -w 100
resvg test_resvg 2x2 resvg test.svg -w 100 test_resvg.png

note that this is less of an issue when rounded up, but quite a big issue when rounded down, since some SVGs are perfectly cut to their contents. I feel that a suitable hotfix would be always rounding up, and cutting the resulting bitmap image to the proper size afterwards.

I didn't test whether aspect ratio is preserved e.g. when viewBox="0 0 1.5 2", but I assume that's also an issue.

RazrFalcon commented 2 months ago

Not sure if the SVG spec specifies this behavior to begin with. Will see what we can do about it.

RiedleroD commented 2 months ago

I would say so, considering what they say here: https://www.w3.org/TR/SVG11/types.html#Precision

edit: equivalent SVG 2 spec: https://www.w3.org/TR/SVG2/types.html#Precision

RazrFalcon commented 2 months ago

Yes, I'm familiar with it, but it doesn't describe that case in particular. Once again, I will look into it eventually.

jermy commented 1 week ago

Just to quickly comment - this is a specific issue with the resvg binary, and shouldn't be an issue if you use the the C or Rust API directly.

It's easy enough to change to support floating point sizes returned for the SVG, but for consistent behaviour will require a small modification to tiny-skia to support scale_by, scale_to_width and scale_to_height against the Size type (which currently only exist on it uses IntSize).

I've got those patches - let me know if it's worth doing a couple of respective PRs for this.