linebender / resvg

An SVG rendering library.
Mozilla Public License 2.0
2.79k stars 225 forks source link

Bounding box inconsistencies - different values between 0.28 and 0.44 #831

Open tmbb opened 1 week ago

tmbb commented 1 week ago

I have noticed some wierd things about measurements returned resvg --query-all. The units are not obvious, and measurements have changed from v0.42 onwards.

Let's sayy we call resvg --query-all on the following SVG file using versions v0.34 to v0.44:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="30pt" height="20pt" viewBox="0 0 30 20">
    <rect id="rect-1" x="15pt" y="15pt" width="1pt" height="1pt" fill="black"/>
</svg>

We get the following (I used an Elixir project to download the 10 versiona and set things up, the important part are the measurements returned by each version):

2) test query dimensions (ResvgTestMinimal)
     test/resvg_test_minimal_test.exs:92
     ** (RuntimeError) A number of outputs was returned by the different resvg versions.
     The versions grouped by output are the following:

     ===== v0.42.0, v0.43.0, v0.44.0 ========

     rect-1,260.417,260.417,17.361,17.361

     ===== v0.34.0, v0.35.0, v0.36.0, v0.37.0, v0.38.0, v0.39.0, v0.40.0, v0.41.0 ========

     rect-1,62.5,62.5,4.167,4.167

I can't find these differences documented anywhere. Is any of these the expected value? Which units should these numbers be? What changes in v0.42? I actualy found about this when using resvg to get some text measurements, where there seems to be further "weirdness", but even the 1pt-side rectangle has left me a bit stumped...

Thanks for any help.

LaurenzV commented 1 week ago

I can't really reproduce it, I just tried your example with main (v0.44) and those are the values I'm getting:

rect-1,26.667,26.667,1.778,1.778

those are the values before v0.42:

20,20,1.333,1.333

I'm pretty sure the reason for the change in behavior is that usvg now also flattens the viewBox, meaning that the bounding box includes the transforms that is applied to account for the view box. If I remove the viewBox, I get the same values as before.

Which units should these numbers be?

I believe they should be in pixels.

RazrFalcon commented 1 week ago

Yes, this is the correct output now. There we some changes to what --query-all reports.

Here is a post-processed SVG:

<svg width="40" height="26.666666" xmlns="http://www.w3.org/2000/svg">
    <defs/>
    <g transform="matrix(1.3333333 0 0 1.3333333 0.00000191 0.00000095)">
        <path id="rect-1" fill="#000000" stroke="none" d="M 20 20 L 21.333334 20 L 21.333334 21.333334 L 20 21.333334 Z"/>
    </g>
</svg>

As you can see, viewBox transform was flattened and will be applied to the rect.

Remember that width="30pt" height="20pt" != viewBox="0 0 30 20". viewBox uses pixels, not points.

tmbb commented 1 week ago

Thanks, I'll have to dive deeper into measurement units in SVGz which is a very confusing topic.