Viewport abstraction ==================== https://gitlab.gnome.org/GNOME/librsvg/-/issues/298 is about unifying several concepts into a Viewport abstraction. This chapter attempts to explain that. SVG has the concept of `establishing a new viewport `_, in particular for the elements ```` and ````. The viewport is set up like this: - Apply the element's ``transform``. - Compute a transform / coordinate system from the element's size+position (``x``, ``y``, ``width``, ``height``), the ``preserveAspectRatio`` and ``viewBox`` attributes. - Set up a clipping rectangle if the element's ``overflow`` property says so. However, that mechanism is general enough that it can also be made to work when rendering the elements ````, ````, and ````. They have their own way of specifying a size (e.g. the marker-specific ``markerWidth`` and ``markerHeight`` attributes), but they also need to compute a new transform, set up clipping, etc. The original code for librsvg reimplemented the mechanism above independently for each of ````, ````, etc., by doing direct calls to Cairo to set up a transform and a clipping rectangle. Unfortunately, during the initial port to Rust we did not identify this pattern to gather the various implementations and abstract them in a single place. Gradual refactoring led to all calls to Cairo happening in ``drawing_ctx.rs``, instead of all over the code. Still, the various versions still exist, with slightly different mechanisms for each. What I'd like to do ------------------- The idea in #298 is to consolidate all the parameters needed for a viewport, as mentioned above, into a single place. Now that the structs for a :doc:`render_tree` are starting to take hold, I think we can do these: - Move the ``Viewport`` struct from ``drawing_ctx.rs`` into ``layout.rs``. - Add the necessary fields from the previous section (element's transform, perhaps moved from the ``StackingCtx``), the viewport size, ``preserveAspectRatio``, and ``overflow``. - (Look at the Firefox source code a bit before doing that; they have nice code for it.) - One by one, migrate each part of librsvg that requires it to using the new ``Viewport`` abstraction with everything in it. We can probably start with ```` and `` / ``; markers and patterns may need a little extra untangling.