Decide whether the legacy sizing logic makes sense
#633 (closed) is about documenting the legacy sizing logic, which is in get_svg_size
. The logic is this:
- Can the size of the SVG be obtained "trivially" from the IntrinsicDimensions? I.e. does
<svg>
havewidth
andheight
that are non-percent lengths (in which case, just normalize and return them), or does it haveviewBox
(in which case, just return the vbox size in pixels). - If
width
/height
are percentages, multiply them by theviewBox
size if it exists. This is quirky and doesn't make much sense unless those attributes are both100%
. - Otherwise, (no
width/height/viewBox
), actually go ahead and measure all the objects in the document to find out their extents. This is moderately expensive in theory, fast in practice, and the legacy API expects it anyway.
In the legacy API, rsvg_handle_render_cairo
and render_cairo_sub
, plus get_dimensions
, all make use of that logic because they do not take in a viewport into which the SVG should be rendered. They operate from a mindset of "I'll render the SVG at its natural size (whatever that size is), and you can control the size with a Cairo transform". The new API is more web-like, where an SVG is rendered into a given viewport because surprise surprise it is actually scalable!
This logic is not easy to replicate outside of rsvg_internals for the following reasons. If a calling application just requests the IntrinsicDimensions
, it cannot fully resolve that natural size in pixels because:
- If the
width/height
are inem
orex
units, it means that they are relative to thefont-size
for the<svg>
element once the CSS cascade is done. However, there is no API to get that font-size; this knowledge is exclusive to the library. - The quirky part described above is completely arbitrary. A web browser, if it finds percentage units in
width
orheight
, will multiply them by the size of the given viewport... which the legacy API doesn't have. However, most SVGs in the wild which use percentage lengths just usewidth="100%" height="100%"
, and just picking up theviewBox
size in that case makes sense, because it produces the desired aspect ratio. - Computing the extent of elements is doable in the way
get_geometry_sub
does it, by passing a unit rectangle as the viewport togeometry_for_layer
.
(This is the reason why tests/src/reference.rs has a funny image_size
function and also duplicates some of the length normalization logic.)
I have some points of anxiety:
- Should we have a public
get_natural_size
in the Rust API which does exactly the above, and can be used to implement the legacy C API in terms of the public Rust API instead of having special hooks into rsvg_internals? - As part of removing old cruft, but this is a behavior change, should we ignore percent lengths for
width
/height
and just return theviewBox
size if it exists? I posted about this in social media; let's see if the lazyweb yields results. - Should we document that
get_natural_size
may returnNone
if there is no natural size because there is nowidth/height/viewBox
, and the caller needs to actually do the expensiveget_geometry_for_layer
? Is that just bureaucratic and should the function do it automatically instead? - Should it be called
get_legacy_size
instead...