RESOLVED FIXED Bug 239717
[LBSE] Fix origin of transformations in SVG
https://bugs.webkit.org/show_bug.cgi?id=239717
Summary [LBSE] Fix origin of transformations in SVG
Nikolas Zimmermann
Reported 2022-04-25 06:46:44 PDT
Ticket 237711 laid the groundwork for SVG transforms in LBSE, however there are still issues: - SVG transforms specified alone on SVG elements, w/o any additional style/perspective related property such as transform-box / transform-origin / ... does not trigger layer creation (StyleAdjuster needs to consult SVG transforms as well, as special case, to determine if the animatedLocalTransform() is non-identity). This was missing. - Switching on/off transforms for a SVG element, was not tracking updates to both 'HasSVGTransform' / 'HasTransformRelatedProperty' flags correctly, fix that. And finally an important change with respect to LBSE downstream. In previous approach, the role of 'offsetFromAncestor' was changed for SVG, in e.g. paintLayerByApplyingTransform(). It did not measure the offsetFromAncestor in the same coordinate space as CSS. CSS layout does not consider transformations, everything is laid out as it's untransformed, and transforms are merely a painting effect. This is true for SVG on shape-level, but not for containers, since SVG containers are the union of the bounds of the children, mapped through the child transformations. When SVGContainerLayout positions container children relative to itself, to "mimic" nested absolute positioned CSS boxes, it subtracts the container objectBoundingBox() location from the locations of the children. That is easy to implement, one doesn't need new geometry but can rely on objectBoundingBox(). However this makes SVG container 'internal boundaries' dependent on the transformations of the children. Therefore one needs to relayout the whole tree upwards, if the transformation changes in a non-accelerated way (SVGTransformList manipulation, SVG DOM, SMIL <animateTransform>, ...). Furthermore one needs to adapt RenderLayer to change the transformation style from "M * T" to "T * M", where T is the translation due to offsetFromAncestor() and M the user-defined transformation matrix. This works fine, but there is a less-intrusive approach: Compute a new geometry 'objectBoundingBoxWithoutTransformations' that is the same as objectBoundingBox(), but does not map contains children through their transformations. Change SVGContainerLayout to subtract that location instead of objectBoundingBox() location. This way the boundaries stay independent of the transformation. Hit-testing / painting via layers, still does respect the transformations, if present. This slightly changed approach, is way less confusing in the end, since the "M * T" logic (first translate to offsetFromAncestor, then apply transformation matrix, can stay as-is). Patch for this approach will follow, that fixes most transform tests in LBSE, that are testable at present.
Attachments
Patch, v1 (44.99 KB, patch)
2022-04-25 06:55 PDT, Nikolas Zimmermann
no flags
Patch, v2 (45.32 KB, patch)
2022-04-25 15:29 PDT, Nikolas Zimmermann
no flags
Patch, v3 (48.15 KB, patch)
2022-04-25 16:33 PDT, Nikolas Zimmermann
ews-feeder: commit-queue-
Patch, v4 (48.19 KB, patch)
2022-04-25 16:53 PDT, Nikolas Zimmermann
no flags
Patch for landing (48.14 KB, patch)
2022-04-27 02:59 PDT, Nikolas Zimmermann
no flags
Nikolas Zimmermann
Comment 1 2022-04-25 06:55:18 PDT
Created attachment 458267 [details] Patch, v1
Rob Buis
Comment 2 2022-04-25 12:18:16 PDT
Comment on attachment 458267 [details] Patch, v1 View in context: https://bugs.webkit.org/attachment.cgi?id=458267&action=review > Source/WebCore/rendering/RenderLayer.cpp:3549 > +#endif I think a lambda is nicer here. > Source/WebCore/style/StyleAdjuster.cpp:374 > +#endif I think a lambda is nicer here.
Rob Buis
Comment 3 2022-04-25 13:27:43 PDT
Comment on attachment 458267 [details] Patch, v1 View in context: https://bugs.webkit.org/attachment.cgi?id=458267&action=review > Source/WebCore/rendering/RenderElement.cpp:2437 > + if (isSVGLayerAwareRenderer() && !isSVGRoot() && document().settings().layerBasedSVGEngineEnabled()) It seems a bit more logical to do the isSVGRoot check last.
Nikolas Zimmermann
Comment 4 2022-04-25 15:29:36 PDT
Created attachment 458305 [details] Patch, v2
Nikolas Zimmermann
Comment 5 2022-04-25 15:35:19 PDT
(In reply to Rob Buis from comment #2) > > Source/WebCore/rendering/RenderLayer.cpp:3549 > > +#endif > > I think a lambda is nicer here. Good idea, fixed. > > Source/WebCore/style/StyleAdjuster.cpp:374 > > +#endif > > I think a lambda is nicer here. Fixed as well. (In reply to Rob Buis from comment #3) > > Source/WebCore/rendering/RenderElement.cpp:2437 > > + if (isSVGLayerAwareRenderer() && !isSVGRoot() && document().settings().layerBasedSVGEngineEnabled()) > > It seems a bit more logical to do the isSVGRoot check last. Hmm, I disagree. isSVGLayerAwareRenderer() contains an explicit '||.isSVGRoot()' condition, so it returns true for RenderSVGRoot. I really meant to check here: "all layer aware renderers, except RenderSVGRoot" (--> "isSVGLayerAwareRenderer() && !isSVGRoot()"). Note, that if 'isSVGRoot()' evaluates to true, that means LBSE must be enabled, otherwise we'd see a LegacyRenderSVGRoot, not a RenderSVGRoot. You could argue about testing: "if (document().settings().layerBasedSVGEngineEnabled() && isSVGLayerAwareRenderer() && !isSVGRoot())" though ;-) I left it as-is, if you're ok with it.
Nikolas Zimmermann
Comment 6 2022-04-25 16:33:30 PDT
Created attachment 458310 [details] Patch, v3
Nikolas Zimmermann
Comment 7 2022-04-25 16:53:29 PDT
Created attachment 458314 [details] Patch, v4
Rob Buis
Comment 8 2022-04-26 07:17:40 PDT
Comment on attachment 458314 [details] Patch, v4 View in context: https://bugs.webkit.org/attachment.cgi?id=458314&action=review > Source/WebCore/rendering/RenderObject.h:377 > + // Their laid out in such a way that transformations do NOT affect layout, as in HTML/CSS world, but take affect during Their -> They are
Nikolas Zimmermann
Comment 9 2022-04-27 02:59:18 PDT
Created attachment 458434 [details] Patch for landing
EWS
Comment 10 2022-04-27 04:15:53 PDT
Committed r293504 (250035@main): <https://commits.webkit.org/250035@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 458434 [details].
Radar WebKit Bug Importer
Comment 11 2022-04-27 04:16:21 PDT
Note You need to log in before you can comment on or make changes to this bug.