getScreenCTM returns different answers from other browsers, in the presence of padding-left or padding-top and a rotation transform
Categories
(Core :: SVG, defect)
Tracking
()
People
(Reporter: dholbert, Unassigned)
References
(Blocks 1 open bug)
Details
Attachments
(5 files)
STR:
- Load attached testcase.
- Look at the red dot.
- (for more details) look at the text that displays the CTM and the transformed point's coordinates.
EXPECTED RESULTS:
- The textual display of the CTM should show
100, 100
as the last two components. - The textual display of the transformed point should show
50, 50
- Visually, the red dot should be inside the lime square.
ACTUAL RESULTS:
- The textual display of the CTM shows
124, 100
as the last two components. (offset by 24 from what we expect) - The textual display of the transformed point shows
74, 50
(offset by 24 from what we expect) - Visually, the red dot is offset 24px to the left from its expected position in the lime square.
Reporter | ||
Comment 1•6 months ago
|
||
This testcase uses padding-top
and shows the same breakage described above, except in the vertical axis (the red dot ends up being drawn 24px higher than expected, and the coordinate/CTM have their vertical components off by 24px as well).
Reporter | ||
Comment 2•6 months ago
•
|
||
Chrome gives EXPECTED RESULTS here.
(WebKit (epiphany) doesn't quite get EXPECTED RESULTS; they show a different bug from us. They report the CTM as 1, 0, 0, 1, 100, 100
with positive 1
instead of negative 1
in the 1st and 4th components, so they end up drawing the red dot offscreen (at point -50, -50
in SVG coordinates).)
Comment 3•6 months ago
|
||
Why is 100, 100 as the last two components correct? What happened to the padding?
Comment 4•6 months ago
|
||
The padding on the left becomes padding on the right once rotated and therefore has no effect, right?
Reporter | ||
Comment 5•6 months ago
•
|
||
(In reply to Robert Longson [:longsonr] from comment #4)
The padding on the left becomes padding on the right once rotated and therefore has no effect, right?
I think that's basically right, yeah. You can mess with the testcase to add arbitrary amounts of padding-left
, without impacting the rendering of the SVG (the blue circle). That's because -- with the default transform-origin
and transform-box
, combined with the 180deg rotation -- we rotate about the center of the SVG's border-box. So the padding ends up on the right side in the final visualization, and the visible SVG content always ends up in the same spot, perfectly flush with the left side of the viewport.
Since the SVG content always ends up in the same spot in this testcase (regardless of the amount of padding-left), that means getScreenCTM
should also always produce the same matrix, with 100 100
at the end (regardless of padding-left), in order to reliably produce a transform that can interconvert between the outer coordinate space to the SVG-internal coordinate space.
Reporter | ||
Comment 6•6 months ago
|
||
Here's another testcase with a different transform-origin
so that the rotation does actually move the SVG such that the padding does impact the CTM.
Chrome still seems correct to me here (representing the offset , and Firefox seems incorrect.
In particular:
- The padding on the left side shifts over the
100%,100%
transform-origin by exactly the size of the padding-left amount. - When we rotate around that
100%,100%
point, the content ends up all on the other side of the transform-origin, so the content is still shifted by exactly the size of the padding-left amount. - The padding ends up being drawn on the right side, where it doesn't directly impact the geometry anymore, but the impact that it had via (1) + (2) does still make it effectively a horizontal translation in the CTM by precisely the amount of the padding.
Reporter | ||
Updated•6 months ago
|
Reporter | ||
Comment 7•6 months ago
|
||
If I modify testcase 1 to use transform-box: content-box
(so that we rotate the content-box about its center, with the 12px padding-left essentially being an external offset), then we're consistent with Chrome, and it seems clearly correct for the 12px to be reflected as an offset in the CTM (since it shows up in the actual visual positioning).
Given that we double-apply the padding in testcase 1 and 2 (with 12px of padding yielding final values that are off by 24px), I wonder if we're trying to cancel out the padding but we're doing addition instead of subtraction, or something to that effect?
Reporter | ||
Updated•6 months ago
|
Comment 8•6 months ago
|
||
We ignored padding for years and then implemented a naive version that doesn't deal with transforms: https://searchfox.org/mozilla-central/rev/cfcb29f7705d0601ef151dea87c534637c7da936/dom/svg/SVGContentUtils.cpp#533 that's better than nothing but it only looks at the top and left padding. If you apply a 180 degree rotation it should look at the bottom and right padding instead for instance.
Reporter | ||
Comment 9•6 months ago
•
|
||
(In reply to Robert Longson [:longsonr] from comment #8)
If you apply a 180 degree rotation it should look at the bottom and right padding instead for instance.
We actually already get the answer correct if you use padding-right
, though, FWIW -- here's a version of testcase 1 modified to use padding-right
.
(Visually, the padding-right: 12px
ends up being an offset from the left edge of the page, due to the 180 degree rotation; and we represent that correctly as a +12px offset in our CTM, as shown by the correspondence between the green box and red dot here, and by our agreement with Chrome on this testcase.)
Not sure if we get this right just due to luck (and/or things working out "just right" under default transform-origin/transform-box values), vs. because we properly/intentionally account for the padding-right somewhere.
Description
•