Diff
Modified: trunk/LayoutTests/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt (294614 => 294615)
--- trunk/LayoutTests/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt 2022-05-21 23:16:37 UTC (rev 294615)
@@ -24,9 +24,10 @@
(GraphicsLayer
(offsetFromRenderer width=1 height=1)
(position 1.00 1.00)
+ (anchor 0.51 0.50)
(bounds 583.00 578.00)
(backingStoreAttached 1)
- (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [-307.50 -290.00 1.00 -1.00] [0.00 0.00 0.00 1.00])
+ (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [-300.00 -290.00 1.00 -1.00] [0.00 0.00 0.00 1.00])
(children 1
(GraphicsLayer
(position 0.00 -400.00)
Modified: trunk/LayoutTests/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt (294614 => 294615)
--- trunk/LayoutTests/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt 2022-05-21 23:16:37 UTC (rev 294615)
@@ -29,8 +29,9 @@
(children 2
(GraphicsLayer
(bounds origin 0.00 900.00)
+ (anchor 0.51 0.50)
(bounds 585.00 500.00)
- (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [2.93 2.50 1.00 -0.01] [0.00 0.00 0.00 1.00])
+ (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [3.00 2.50 1.00 -0.01] [0.00 0.00 0.00 1.00])
(visible rect 0.00, 900.00 585.00 x 500.00)
(coverage rect 0.00, 900.00 585.00 x 500.00)
(intersects coverage rect 1)
Modified: trunk/LayoutTests/platform/glib/TestExpectations (294614 => 294615)
--- trunk/LayoutTests/platform/glib/TestExpectations 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/glib/TestExpectations 2022-05-21 23:16:37 UTC (rev 294615)
@@ -663,9 +663,6 @@
webkit.org/b/230277 imported/w3c/web-platform-tests/css/css-transforms/dynamic-fixed-pos-cb-change.html [ ImageOnlyFailure ]
webkit.org/b/230277 imported/w3c/web-platform-tests/css/css-transforms/perspective-transforms-equivalence.html [ ImageOnlyFailure ]
-# 'transform-box' support is broken for composited elements.
-webkit.org/b/237553 imported/w3c/web-platform-tests/css/css-transforms/animation/transform-box-will-change-transform-layer.html [ ImageOnlyFailure ]
-
webkit.org/b/237502 fast/dom/Range/getClientRects.html [ Failure ]
webkit.org/b/237502 fast/multicol/newmulticol/hide-box-vertical-lr.html [ ImageOnlyFailure ]
webkit.org/b/237502 imported/blink/fast/multicol/vertical-lr/float-big-line.html [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/platform/ios/TestExpectations (294614 => 294615)
--- trunk/LayoutTests/platform/ios/TestExpectations 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2022-05-21 23:16:37 UTC (rev 294615)
@@ -3023,9 +3023,6 @@
webkit.org/b/202958 css3/filters/svg-blur-filter-clipped.html [ ImageOnlyFailure ]
-# 'transform-box' support is broken for composited elements.
-webkit.org/b/237553 imported/w3c/web-platform-tests/css/css-transforms/animation/transform-box-will-change-transform-layer.html [ ImageOnlyFailure ]
-
webkit.org/b/203305 imported/w3c/web-platform-tests/css/css-transitions/properties-value-001.html [ Pass Failure ]
webkit.org/b/203305 [ Debug ] imported/w3c/web-platform-tests/css/css-transitions/properties-value-inherit-001.html [ Pass Failure ]
webkit.org/b/203356 [ Debug ] imported/w3c/web-platform-tests/css/css-transitions/properties-value-003.html [ Pass Failure ]
Modified: trunk/LayoutTests/platform/ios-wk2/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt (294614 => 294615)
--- trunk/LayoutTests/platform/ios-wk2/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/ios-wk2/compositing/tiling/coverage-adjustment-secondary-quad-mapping-expected.txt 2022-05-21 23:16:37 UTC (rev 294615)
@@ -23,9 +23,10 @@
(GraphicsLayer
(offsetFromRenderer width=1 height=1)
(position 1.00 1.00)
+ (anchor 0.51 0.50)
(bounds 583.00 578.00)
(backingStoreAttached 1)
- (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [-307.50 -290.00 1.00 -1.00] [0.00 0.00 0.00 1.00])
+ (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [-300.00 -290.00 1.00 -1.00] [0.00 0.00 0.00 1.00])
(children 1
(GraphicsLayer
(position 0.00 -400.00)
Modified: trunk/LayoutTests/platform/mac/TestExpectations (294614 => 294615)
--- trunk/LayoutTests/platform/mac/TestExpectations 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2022-05-21 23:16:37 UTC (rev 294615)
@@ -2197,9 +2197,6 @@
webkit.org/b/230327 imported/w3c/web-platform-tests/css/css-transforms/crashtests/transform-marquee-resize-div-image-001.html [ Pass Failure ]
-# 'transform-box' support is broken for composited elements.
-webkit.org/b/237553 imported/w3c/web-platform-tests/css/css-transforms/animation/transform-box-will-change-transform-layer.html [ ImageOnlyFailure ]
-
# rdar://83591040
[ Monterey+ ] editing/mac/dictionary-lookup/dictionary-lookup-input.html [ Crash ]
[ Monterey+ ] editing/mac/dictionary-lookup/dictionary-lookup-inside-selection.html [ Crash ]
Modified: trunk/LayoutTests/platform/mac-wk1/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt (294614 => 294615)
--- trunk/LayoutTests/platform/mac-wk1/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/mac-wk1/compositing/tiling/perspective-on-scroller-tile-coverage-expected.txt 2022-05-21 23:16:37 UTC (rev 294615)
@@ -24,8 +24,9 @@
(contentsScale 1.00)
(children 1
(GraphicsLayer
+ (anchor 0.51 0.50)
(bounds 585.00 500.00)
- (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [2.93 2.50 1.00 -0.01] [0.00 0.00 0.00 1.00])
+ (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [3.00 2.50 1.00 -0.01] [0.00 0.00 0.00 1.00])
(visible rect 0.00, 0.00 585.00 x 500.00)
(coverage rect 0.00, 0.00 585.00 x 500.00)
(intersects coverage rect 1)
Modified: trunk/LayoutTests/platform/win/TestExpectations (294614 => 294615)
--- trunk/LayoutTests/platform/win/TestExpectations 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/LayoutTests/platform/win/TestExpectations 2022-05-21 23:16:37 UTC (rev 294615)
@@ -953,9 +953,6 @@
webkit.org/b/149245 imported/w3c/web-platform-tests/css/css-multicol/multicol-span-all-block-sibling-003.xht [ Skip ]
webkit.org/b/149245 imported/w3c/web-platform-tests/css/css-multicol/multicol-span-all-margin-nested-firstchild-001.xht [ Skip ]
-# 'transform-box' support is broken for composited elements.
-webkit.org/b/237553 imported/w3c/web-platform-tests/css/css-transforms/animation/transform-box-will-change-transform-layer.html [ ImageOnlyFailure ]
-
# TODO EXIF-resolution is not supported
imported/w3c/web-platform-tests/density-size-correction/ [ Skip ]
Modified: trunk/Source/WebCore/animation/KeyframeEffect.cpp (294614 => 294615)
--- trunk/Source/WebCore/animation/KeyframeEffect.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/animation/KeyframeEffect.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -1992,7 +1992,7 @@
bool applyTransformOrigin = containsRotation(style.transform().operations()) || style.transform().affectedByTransformOrigin();
if (applyTransformOrigin) {
- transformOrigin = rendererBox.location() + floatPointForLengthPoint(style.transformOriginXY(), rendererBox.size());
+ transformOrigin = style.computeTransformOrigin(rendererBox).xy();
// Ignore transformOriginZ because we'll bail if we encounter any 3D transforms.
floatBounds.moveBy(-transformOrigin);
}
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -1800,35 +1800,55 @@
return positionOrOffsetChanged;
}
-TransformationMatrix RenderLayer::perspectiveTransform(const LayoutRect& layerRect) const
+TransformationMatrix RenderLayer::perspectiveTransform() const
{
- // FIXME: [LBSE] Upstream transform support for RenderSVGModelObject derived renderers
- if (!is<RenderBox>(renderer()))
+ if (!renderer().hasTransformRelatedProperty())
return { };
- auto& renderBox = downcast<RenderBox>(renderer());
- if (!renderBox.hasTransformRelatedProperty())
- return { };
-
- const auto& style = renderBox.style();
+ const auto& style = renderer().style();
if (!style.hasPerspective())
return { };
- auto referenceBoxRect = snapRectToDevicePixelsIfNeeded(renderer().transformReferenceBoxRect(style), renderer());
- auto snappedLayerRect = snapRectToDevicePixelsIfNeeded(layerRect, renderer());
+ auto transformReferenceBoxRect = snapRectToDevicePixelsIfNeeded(renderer().transformReferenceBoxRect(style), renderer());
+ auto perspectiveOrigin = style.computePerspectiveOrigin(transformReferenceBoxRect);
- auto perspectiveOrigin = referenceBoxRect.location() - toFloatSize(snappedLayerRect.location()) + floatPointForLengthPoint(style.perspectiveOrigin(), referenceBoxRect.size());
+ // In the regular case of a non-clipped, non-scrolled GraphicsLayer, all transformations
+ // (via CSS 'transform' / 'perspective') are applied with respect to a predefined anchor point,
+ // which depends on the chosen CSS 'transform-box' / 'transform-origin' properties.
+ //
+ // A transformation given by the CSS 'transform' property is applied, by translating
+ // to the 'transform origin', applying the transformation, and translating back.
+ // When an element specifies a CSS 'perspective' property, the perspective transformation matrix
+ // that's computed here is propagated to the GraphicsLayer by calling setChildrenTransform().
+ //
+ // However the GraphicsLayer platform implementations (e.g. CA on macOS) apply the children transform,
+ // defined on the parent, with respect to the anchor point of the parent, when rendering child elements.
+ // This is wrong, as the perspective transformation (applied to a child of the element defining the
+ // 3d effect), must be independant of the chosen transform-origin (the parents transform origin
+ // must not affect its children).
+ //
+ // To circumvent this, explicitely remove the transform-origin dependency in the perspective matrix.
+ auto transformOrigin = transformOriginPixelSnappedIfNeeded();
- // A perspective origin of 0,0 makes the vanishing point in the center of the element.
- // We want it to be in the top-left, so subtract half the height and width.
- perspectiveOrigin -= snappedLayerRect.size() / 2.0f;
+ TransformationMatrix transform;
+ style.unapplyTransformOrigin(transform, transformOrigin);
+ style.applyPerspective(transform, renderer(), perspectiveOrigin);
+ style.applyTransformOrigin(transform, transformOrigin);
+ return transform;
+}
- TransformationMatrix t;
- t.translate(perspectiveOrigin.x(), perspectiveOrigin.y());
- t.applyPerspective(style.usedPerspective(renderer()));
- t.translate(-perspectiveOrigin.x(), -perspectiveOrigin.y());
+FloatPoint3D RenderLayer::transformOriginPixelSnappedIfNeeded() const
+{
+ if (!renderer().hasTransformRelatedProperty())
+ return { };
- return t;
+ const auto& style = renderer().style();
+ auto referenceBoxRect = renderer().transformReferenceBoxRect(style);
+
+ auto origin = style.computeTransformOrigin(referenceBoxRect);
+ if (rendererNeedsPixelSnapping(renderer()))
+ origin.setXY(roundPointToDevicePixels(LayoutPoint(origin.xy()), renderer().document().deviceScaleFactor()));
+ return origin;
}
FloatPoint RenderLayer::perspectiveOrigin() const
@@ -1835,8 +1855,7 @@
{
if (!renderer().hasTransformRelatedProperty())
return { };
- // FIXME: This uses the wrong, transform-box unaware, geometry.
- return floatPointForLengthPoint(renderer().style().perspectiveOrigin(), rendererBorderBoxRect().size());
+ return floatPointForLengthPoint(renderer().style().perspectiveOrigin(), renderer().transformReferenceBoxRect(renderer().style()).size());
}
static inline bool isContainerForPositioned(RenderLayer& layer, PositionType position, bool establishesTopLayer)
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2022-05-21 23:16:37 UTC (rev 294615)
@@ -739,11 +739,12 @@
TransformationMatrix currentTransform(OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const;
TransformationMatrix renderableTransform(OptionSet<PaintBehavior>) const;
- // Get the perspective transform, which is applied to transformed sublayers.
- // Returns true if the layer has a -webkit-perspective.
+ // Get the children transform (to apply a perspective on children), which is applied to transformed sublayers, but not this layer.
+ // Returns true if the layer has a perspective.
// Note that this transform has the perspective-origin baked in.
- TransformationMatrix perspectiveTransform(const LayoutRect& layerRect) const;
+ TransformationMatrix perspectiveTransform() const;
FloatPoint perspectiveOrigin() const;
+ FloatPoint3D transformOriginPixelSnappedIfNeeded() const;
bool preserves3D() const { return renderer().style().preserves3D(); }
bool has3DTransform() const { return m_transform && !m_transform->isAffine(); }
bool hasTransformedAncestor() const { return m_hasTransformedAncestor; }
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -635,16 +635,11 @@
m_graphicsLayer->setOpacity(compositingOpacity(style.opacity()));
}
-void RenderLayerBacking::updateTransform(const RenderStyle&)
+void RenderLayerBacking::updateTransform(const RenderStyle& style)
{
- // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
- // baked into it, and we don't want that.
TransformationMatrix t;
- if (m_owningLayer.hasTransform()) {
- // FIXME: This uses the wrong, transform-box unaware, geometry.
- renderer().applyTransform(t, renderer().style(), snapRectToDevicePixels(m_owningLayer.rendererBorderBoxRect(), deviceScaleFactor()), RenderStyle::individualTransformOperations);
- makeMatrixRenderable(t, compositor().canRender3DTransforms());
- }
+ if (m_owningLayer.hasTransform())
+ m_owningLayer.updateTransformFromStyle(t, style, RenderStyle::individualTransformOperations);
if (m_contentsContainmentLayer) {
m_contentsContainmentLayer->setTransform(t);
@@ -655,12 +650,18 @@
void RenderLayerBacking::updateChildrenTransformAndAnchorPoint(const LayoutRect& primaryGraphicsLayerRect, LayoutSize offsetFromParentGraphicsLayer)
{
+ auto defaultAnchorPoint = FloatPoint3D { 0.5, 0.5, 0 };
if (!renderer().hasTransformRelatedProperty()) {
- auto defaultAnchorPoint = FloatPoint3D { 0.5, 0.5, 0 };
m_graphicsLayer->setAnchorPoint(defaultAnchorPoint);
if (m_contentsContainmentLayer)
m_contentsContainmentLayer->setAnchorPoint(defaultAnchorPoint);
+ if (m_childContainmentLayer)
+ m_childContainmentLayer->setAnchorPoint(defaultAnchorPoint);
+
+ if (m_scrollContainerLayer)
+ m_scrollContainerLayer->setAnchorPoint(defaultAnchorPoint);
+
if (m_scrolledContentsLayer)
m_scrolledContentsLayer->setPreserves3D(false);
return;
@@ -667,8 +668,7 @@
}
const auto deviceScaleFactor = this->deviceScaleFactor();
- auto borderBoxRect = m_owningLayer.rendererBorderBoxRect();
- auto transformOrigin = computeTransformOriginForPainting(borderBoxRect);
+ auto transformOrigin = m_owningLayer.transformOriginPixelSnappedIfNeeded();
auto layerOffset = roundPointToDevicePixels(toLayoutPoint(offsetFromParentGraphicsLayer), deviceScaleFactor);
auto anchor = FloatPoint3D {
primaryGraphicsLayerRect.width() ? ((layerOffset.x() - primaryGraphicsLayerRect.x()) + transformOrigin.x()) / primaryGraphicsLayerRect.width() : 0.5f,
@@ -683,11 +683,14 @@
auto removeChildrenTransformFromLayers = [&](GraphicsLayer* layerToIgnore = nullptr) {
auto* clippingLayer = this->clippingLayer();
- if (clippingLayer && clippingLayer != layerToIgnore)
+ if (clippingLayer && clippingLayer != layerToIgnore) {
clippingLayer->setChildrenTransform({ });
-
+ clippingLayer->setAnchorPoint(defaultAnchorPoint);
+ }
+
if (m_scrollContainerLayer && m_scrollContainerLayer != layerToIgnore) {
m_scrollContainerLayer->setChildrenTransform({ });
+ m_scrollContainerLayer->setAnchorPoint(defaultAnchorPoint);
m_scrolledContentsLayer->setPreserves3D(false);
}
@@ -700,7 +703,7 @@
return;
}
- auto layerForChildrenTransform = [&] {
+ auto layerForChildrenTransform = [&]() -> std::tuple<GraphicsLayer*, FloatRect> {
if (m_scrollContainerLayer) {
ASSERT(is<RenderBox>(renderer())); // Scroll container layers are only created for RenderBox derived renderers.
return std::make_tuple(m_scrollContainerLayer.get(), scrollContainerLayerBox(downcast<RenderBox>(renderer())));
@@ -708,19 +711,26 @@
if (auto* layer = clippingLayer())
return std::make_tuple(layer, clippingLayerBox(renderer()));
- return std::make_tuple(m_graphicsLayer.get(), borderBoxRect);
+ return std::make_tuple(m_graphicsLayer.get(), renderer().transformReferenceBoxRect());
};
- auto [layerForPerspective, perspectiveRelativeBox] = layerForChildrenTransform();
- // FIXME: perspectiveRelativeBox isn't quite right here. This needs work: webkit.org/b/211787.
- auto perspectiveTransform = owningLayer().perspectiveTransform(perspectiveRelativeBox);
-
- // If we have scrolling layers, we need the children transform on m_scrollContainerLayer to
- // affect children of m_scrolledContentsLayer, so set setPreserves3D(true).
- if (layerForPerspective == m_scrollContainerLayer)
- m_scrolledContentsLayer->setPreserves3D(true);
-
- layerForPerspective->setChildrenTransform(perspectiveTransform);
+ auto [layerForPerspective, layerForPerspectiveRect] = layerForChildrenTransform();
+ if (layerForPerspective != m_graphicsLayer) {
+ // If we have scrolling layers, we need the children transform on m_scrollContainerLayer to
+ // affect children of m_scrolledContentsLayer, so set setPreserves3D(true).
+ if (layerForPerspective == m_scrollContainerLayer)
+ m_scrolledContentsLayer->setPreserves3D(true);
+
+ auto perspectiveAnchorPoint = FloatPoint3D {
+ layerForPerspectiveRect.width() ? (transformOrigin.x() - layerForPerspectiveRect.x()) / layerForPerspectiveRect.width() : 0.5f,
+ layerForPerspectiveRect.height() ? (transformOrigin.y() - layerForPerspectiveRect.y()) / layerForPerspectiveRect.height() : 0.5f,
+ transformOrigin.z()
+ };
+
+ layerForPerspective->setAnchorPoint(perspectiveAnchorPoint);
+ }
+
+ layerForPerspective->setChildrenTransform(m_owningLayer.perspectiveTransform());
removeChildrenTransformFromLayers(layerForPerspective);
}
@@ -2980,17 +2990,6 @@
image->startAnimation();
}
-FloatPoint3D RenderLayerBacking::computeTransformOriginForPainting(const LayoutRect& borderBox) const
-{
- const RenderStyle& style = renderer().style();
-
- FloatPoint3D origin;
- origin.setXY(roundPointToDevicePixels(pointForLengthPoint(style.transformOriginXY(), borderBox.size()), deviceScaleFactor()));
- origin.setZ(style.transformOriginZ());
-
- return origin;
-}
-
// Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
LayoutSize RenderLayerBacking::contentOffsetInCompositingLayer() const
{
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.h 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h 2022-05-21 23:16:37 UTC (rev 294615)
@@ -331,9 +331,6 @@
void setBackgroundLayerPaintsFixedRootBackground(bool);
LayoutSize contentOffsetInCompositingLayer() const;
- // Result is transform origin in device pixels.
- FloatPoint3D computeTransformOriginForPainting(const LayoutRect& borderBox) const;
-
LayoutSize offsetRelativeToRendererOriginForDescendantLayers() const;
void ensureClippingStackLayers(LayerAncestorClippingStack&);
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -1654,6 +1654,7 @@
|| oldStyle.translate() != newStyle.translate()
|| oldStyle.scale() != newStyle.scale()
|| oldStyle.rotate() != newStyle.rotate()
+ || oldStyle.transformBox() != newStyle.transformBox()
|| oldStyle.transformOriginX() != newStyle.transformOriginX()
|| oldStyle.transformOriginY() != newStyle.transformOriginY()
|| oldStyle.transformOriginZ() != newStyle.transformOriginZ()
Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp (294614 => 294615)
--- trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -347,8 +347,10 @@
FloatPoint3D originTranslate;
if (options.contains(RenderStyle::TransformOperationOption::TransformOrigin) && affectedByTransformOrigin)
- originTranslate = style.applyTransformOrigin(transform, boundingBox);
+ originTranslate = style.computeTransformOrigin(boundingBox);
+ style.applyTransformOrigin(transform, originTranslate);
+
// CSS transforms take precedence over SVG transforms.
if (hasCSSTransform)
style.applyCSSTransform(transform, boundingBox, options);
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (294614 => 294615)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -1491,22 +1491,43 @@
return false;
}
-FloatPoint3D RenderStyle::applyTransformOrigin(TransformationMatrix& transform, const FloatRect& boundingBox) const
+FloatPoint RenderStyle::computePerspectiveOrigin(const FloatRect& boundingBox) const
{
- // https://www.w3.org/TR/css-transforms-2/#ctm
- // 2. Translate by the computed X, Y, and Z values of transform-origin.
+ return boundingBox.location() + floatPointForLengthPoint(perspectiveOrigin(), boundingBox.size());
+}
+
+void RenderStyle::applyPerspective(TransformationMatrix& transform, const RenderObject& renderer, const FloatPoint& originTranslate) const
+{
+ // https://www.w3.org/TR/css-transforms-2/#perspective
+ // The perspective matrix is computed as follows:
+ // 1. Start with the identity matrix.
+
+ // 2. Translate by the computed X and Y values of perspective-origin
+ transform.translate(originTranslate.x(), originTranslate.y());
+
+ // 3. Multiply by the matrix that would be obtained from the perspective() transform function, where the length is provided by the value of the perspective property
+ transform.applyPerspective(usedPerspective(renderer));
+
+ // 4. Translate by the negated computed X and Y values of perspective-origin
+ transform.translate(-originTranslate.x(), -originTranslate.y());
+}
+
+FloatPoint3D RenderStyle::computeTransformOrigin(const FloatRect& boundingBox) const
+{
FloatPoint3D originTranslate;
originTranslate.setXY(boundingBox.location() + floatPointForLengthPoint(transformOriginXY(), boundingBox.size()));
originTranslate.setZ(transformOriginZ());
+ return originTranslate;
+}
+
+void RenderStyle::applyTransformOrigin(TransformationMatrix& transform, const FloatPoint3D& originTranslate) const
+{
if (!originTranslate.isZero())
transform.translate3d(originTranslate.x(), originTranslate.y(), originTranslate.z());
- return originTranslate;
}
void RenderStyle::unapplyTransformOrigin(TransformationMatrix& transform, const FloatPoint3D& originTranslate) const
{
- // https://www.w3.org/TR/css-transforms-2/#ctm
- // 8. Translate by the negated computed X, Y and Z values of transform-origin.
if (!originTranslate.isZero())
transform.translate3d(-originTranslate.x(), -originTranslate.y(), -originTranslate.z());
}
@@ -1518,7 +1539,8 @@
return;
}
- auto originTranslate = applyTransformOrigin(transform, boundingBox);
+ auto originTranslate = computeTransformOrigin(boundingBox);
+ applyTransformOrigin(transform, originTranslate);
applyCSSTransform(transform, boundingBox, options);
unapplyTransformOrigin(transform, originTranslate);
}
@@ -1604,7 +1626,7 @@
if (!offsetPath())
return;
- auto transformOrigin = floatPointForLengthPoint(transformOriginXY(), boundingBox.size()) + boundingBox.location();
+ auto transformOrigin = computeTransformOrigin(boundingBox).xy();
auto anchor = transformOrigin;
if (!offsetAnchor().x().isAuto())
anchor = floatPointForLengthPoint(offsetAnchor(), boundingBox.size()) + boundingBox.location();
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (294614 => 294615)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-21 23:16:37 UTC (rev 294615)
@@ -714,8 +714,14 @@
static constexpr OptionSet<TransformOperationOption> individualTransformOperations = { TransformOperationOption::Translate, TransformOperationOption::Rotate, TransformOperationOption::Scale, TransformOperationOption::Offset };
bool affectedByTransformOrigin() const;
- FloatPoint3D applyTransformOrigin(TransformationMatrix&, const FloatRect& boundingBox) const;
+
+ FloatPoint computePerspectiveOrigin(const FloatRect& boundingBox) const;
+ void applyPerspective(TransformationMatrix&, const RenderObject&, const FloatPoint& originTranslate) const;
+
+ FloatPoint3D computeTransformOrigin(const FloatRect& boundingBox) const;
+ void applyTransformOrigin(TransformationMatrix&, const FloatPoint3D& originTranslate) const;
void unapplyTransformOrigin(TransformationMatrix&, const FloatPoint3D& originTranslate) const;
+
// applyTransform calls applyTransformOrigin(), then applyCSSTransform(), followed by unapplyTransformOrigin().
void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
void applyCSSTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<TransformOperationOption> = allTransformOperations) const;
Modified: trunk/Source/WebCore/svg/SVGGraphicsElement.cpp (294614 => 294615)
--- trunk/Source/WebCore/svg/SVGGraphicsElement.cpp 2022-05-21 19:26:27 UTC (rev 294614)
+++ trunk/Source/WebCore/svg/SVGGraphicsElement.cpp 2022-05-21 23:16:37 UTC (rev 294615)
@@ -107,8 +107,7 @@
// If we didn't have the CSS "transform" property set, we must account for the "transform" attribute.
if (!hasSpecifiedTransform && style) {
- auto boundingBox = renderer()->transformReferenceBoxRect();
- auto t = floatPointForLengthPoint(style->transformOriginXY(), boundingBox.size()) + boundingBox.location();
+ auto t = style->computeTransformOrigin(renderer()->transformReferenceBoxRect()).xy();
matrix.translate(t);
matrix *= transform().concatenate();
matrix.translate(-t.x(), -t.y());