Support translate transforms with non-pixel units
With @madds-h's !576 (merged) librsvg now supports the transform
CSS property from SVG2/CSS3. However, it doesn't yet support translate/translateX/translateY
with parameters in units other than pixels - translate(1cm, 1cm)
intentionally yields a parse error.
This is because the code historically did not need to convert transforms into user space coordinates. With SVG2, it needs to do that to fully support transforms with non-pixel units.
Pasting from a conversation with @madds-h about how to implement this:
If you look for values.transform()
, it gets used in places like shapes.rs when creating a StackingContext
, which needs the matrix.
values
is a ComputedValues
, and already contains the matrix-ified transform. It gets matrix-ified in the last lines of properties.rs:to_computed_values()
- either copied from the attribute, or by calling to_transform
on the property.
Where values.transform()
gets used is practically always in the rendering functions, i.e. impl Draw for Foo
or similar. Those functions generally need to normalize length values into user space coordinates, by calling Length.to_user()
.
I think that:
-
ComputedValues should store a TransformProperty to be normalized later, not a Transform.
-
TransformProperty::to_transform should take a NormalizeParams like Length::to_user, and do its thing but first normalizing the lengths in Translate, TranslateX, TranslateY.
-
Modify callers of values.transform() to assume they obtain an unnormalized TransformProperty, and then they call .to_transform(¶ms) by hand to get a Transform matrix for (1), it's probably easiest if the last lines of to_computed_values get changed to just store a TransformProperty in ComputedValues, instead of doing to_transform there. If there's a transform attribute, it can be converted to a TransformProperty with a Matrix.