Diff
Modified: trunk/Source/WebCore/ChangeLog (289605 => 289606)
--- trunk/Source/WebCore/ChangeLog 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/ChangeLog 2022-02-11 08:04:03 UTC (rev 289606)
@@ -1,3 +1,57 @@
+2022-02-11 Nikolas Zimmermann <[email protected]>
+
+ [LBSE] Begin stub implementation of transform support for SVG layers
+ https://bugs.webkit.org/show_bug.cgi?id=236185
+
+ Reviewed by Rob Buis.
+
+ RenderLayer / RenderLayerBacking use RenderStyle::applyTransform()
+ to compute a TransformationMatrix from the CSS Transform properties.
+
+ To hook in SVG transform support, which goes beyond pure CSS properties
+ that influence the "effective transform" for a certain SVG element,
+ RenderStyle is not the right place to place the applyTransform()
+ implementation for SVG specific requirements.
+
+ Therefore introduce a virtual RenderLayerModelObject::applyTransform()
+ function, that is implemented in RenderBox / RenderSVGModelObject.
+ In this patch RenderSVGModelObject::applyTransform() stays a stub
+ and RenderBox::applyTransform() simply forwards to RenderStyle,
+ preserving the current behavior.
+
+ This allows SVG to add additional transformations to the transformation
+ stack, which is useful to implement 'viewBox' support among other things.
+
+ Covered by existing tests, no change in behaviour.
+
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::applyTransform const):
+ * rendering/RenderBox.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::applyTransform const):
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::updateTransform):
+ (WebCore::RenderLayer::currentTransform const):
+ (WebCore::RenderLayer::perspectiveTransform const):
+ (WebCore::RenderLayer::perspectiveOrigin const):
+ * rendering/RenderLayer.h:
+ (WebCore::RenderLayer::rendererBorderBoxRect const):
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateTransform):
+ (WebCore::RenderLayerBacking::updateChildrenTransformAndAnchorPoint):
+ (WebCore::RenderLayerBacking::updateGeometry):
+ (WebCore::RenderLayerBacking::startAnimation):
+ (WebCore::RenderLayerBacking::transformMatrixForProperty const):
+ (WebCore::rendererBorderBoxRect): Deleted.
+ * rendering/RenderLayerModelObject.h:
+ * rendering/svg/RenderSVGModelObject.cpp:
+ (WebCore::RenderSVGModelObject::applyTransform const):
+ * rendering/svg/RenderSVGModelObject.h:
+ * rendering/svg/RenderSVGRoot.cpp:
+ (WebCore::RenderSVGRoot::applyTransform const):
+ * rendering/svg/RenderSVGRoot.h:
+
2022-02-10 Simon Fraser <[email protected]>
Separate out setVolatile() from setNonVolatile() on IOSurface-backed buffers
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -669,6 +669,11 @@
layer()->updateTransform();
}
+void RenderBox::applyTransform(TransformationMatrix& t, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
+{
+ style().applyTransform(t, boundingBox, options);
+}
+
LayoutUnit RenderBox::constrainLogicalWidthInFragmentByMinMax(LayoutUnit logicalWidth, LayoutUnit availableWidth, RenderBlock& cb, RenderFragmentContainer* fragment, AllowIntrinsic allowIntrinsic) const
{
const RenderStyle& styleToUse = style();
Modified: trunk/Source/WebCore/rendering/RenderBox.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderBox.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderBox.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -219,6 +219,7 @@
void addOverflowFromChild(const RenderBox* child, const LayoutSize& delta);
void updateLayerTransform();
+ void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const override;
LayoutSize contentSize() const { return { contentWidth(), contentHeight() }; }
LayoutUnit contentWidth() const { return std::max(0_lu, paddingBoxWidth() - paddingLeft() - paddingRight()); }
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -2721,4 +2721,11 @@
}
}
+void RenderBoxModelObject::applyTransform(TransformationMatrix&, const FloatRect&, OptionSet<RenderStyle::TransformOperationOption>) const
+{
+ // applyTransform() is only used through RenderLayer*, which only invokes this for RenderBox derived renderers, thus not for
+ // RenderInline/RenderLineBreak - the other two renderers that inherit from RenderBoxModelObject.
+ ASSERT_NOT_REACHED();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -62,6 +62,7 @@
class ImageBuffer;
class RenderTextFragment;
class StickyPositionViewportConstraints;
+class TransformationMatrix;
namespace InlineIterator {
class InlineBoxIterator;
@@ -248,6 +249,8 @@
virtual bool hasOverridingContainingBlockContentWidth() const { return false; }
virtual bool hasOverridingContainingBlockContentHeight() const { return false; }
+ void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const override;
+
protected:
RenderBoxModelObject(Element&, RenderStyle&&, BaseTypeFlags);
RenderBoxModelObject(Document&, RenderStyle&&, BaseTypeFlags);
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2006-2020 Apple Inc. All rights reserved.
* Copyright (C) 2019 Adobe. All rights reserved.
- * Copyright (c) 2020 Igalia S.L.
+ * Copyright (c) 2020, 2021, 2022 Igalia S.L.
*
* Portions are Copyright (C) 1998 Netscape Communications Corporation.
*
@@ -1330,9 +1330,14 @@
}
if (hasTransform) {
- auto& renderBox = downcast<RenderBox>(renderer());
m_transform->makeIdentity();
- renderBox.style().applyTransform(*m_transform, snapRectToDevicePixels(renderBox.referenceBox(transformBoxToCSSBoxType(renderBox.style().transformBox())), renderBox.document().deviceScaleFactor()));
+
+ // FIXME: [LBSE] Upstream reference box computation for RenderSVGModelObject derived renderers
+ FloatRect referenceBox;
+ if (is<RenderBox>(renderer()))
+ referenceBox = snapRectToDevicePixels(downcast<RenderBox>(renderer()).referenceBox(transformBoxToCSSBoxType(renderer().style().transformBox())), renderer().document().deviceScaleFactor());
+
+ renderer().applyTransform(*m_transform, referenceBox);
makeMatrixRenderable(*m_transform, canRender3DTransforms());
}
@@ -1348,6 +1353,7 @@
if (!m_transform)
return { };
+ // FIXME: [LBSE] Upstream transform support for RenderSVGModelObject derived renderers
if (!is<RenderBox>(renderer()))
return { };
@@ -1787,6 +1793,7 @@
TransformationMatrix RenderLayer::perspectiveTransform(const LayoutRect& layerRect) const
{
+ // FIXME: [LBSE] Upstream transform support for RenderSVGModelObject derived renderers
if (!is<RenderBox>(renderer()))
return { };
@@ -1821,9 +1828,7 @@
{
if (!renderer().hasTransformRelatedProperty())
return { };
-
- auto borderBox = downcast<RenderBox>(renderer()).borderBoxRect();
- return floatPointForLengthPoint(renderer().style().perspectiveOrigin(), borderBox.size());
+ return floatPointForLengthPoint(renderer().style().perspectiveOrigin(), rendererBorderBoxRect().size());
}
static inline bool isContainerForPositioned(RenderLayer& layer, PositionType position, bool establishesTopLayer)
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -981,9 +981,22 @@
if (is<RenderSVGModelObject>(renderer()))
return downcast<RenderSVGModelObject>(renderer()).layoutLocation();
#endif
+
return LayoutPoint();
}
+ LayoutRect rendererBorderBoxRect() const
+ {
+ if (is<RenderBox>(renderer()))
+ return downcast<RenderBox>(renderer()).borderBoxRect();
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (is<RenderSVGModelObject>(renderer()))
+ return downcast<RenderSVGModelObject>(renderer()).borderBoxRectEquivalent();
+#endif
+
+ return LayoutRect();
+ }
+
bool setupFontSubpixelQuantization(GraphicsContext&, bool& didQuantizeFonts);
std::pair<Path, WindRule> computeClipPath(const LayoutSize& offsetFromRoot, const LayoutRect& rootRelativeBoundsForNonBoxes) const;
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -604,20 +604,6 @@
GraphicsLayer::unparentAndClear(m_graphicsLayer);
}
-static LayoutRect rendererBorderBoxRect(const RenderLayerModelObject& renderer)
-{
- if (is<RenderBox>(renderer))
- return downcast<RenderBox>(renderer).borderBoxRect();
-
-#if ENABLE(LAYER_BASED_SVG_ENGINE)
- if (is<RenderSVGModelObject>(renderer))
- return downcast<RenderSVGModelObject>(renderer).borderBoxRectEquivalent();
-#endif
-
- ASSERT_NOT_REACHED();
- return LayoutRect();
-}
-
static LayoutRect scrollContainerLayerBox(const RenderBox& renderBox)
{
return renderBox.paddingBoxRect();
@@ -651,14 +637,13 @@
m_graphicsLayer->setOpacity(compositingOpacity(style.opacity()));
}
-void RenderLayerBacking::updateTransform(const RenderStyle& style)
+void RenderLayerBacking::updateTransform(const RenderStyle&)
{
// 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()) {
- auto& renderBox = downcast<RenderBox>(renderer());
- style.applyTransform(t, snapRectToDevicePixels(renderBox.borderBoxRect(), deviceScaleFactor()), RenderStyle::individualTransformOperations);
+ renderer().applyTransform(t, snapRectToDevicePixels(m_owningLayer.rendererBorderBoxRect(), deviceScaleFactor()), RenderStyle::individualTransformOperations);
makeMatrixRenderable(t, compositor().canRender3DTransforms());
}
@@ -683,7 +668,7 @@
}
const auto deviceScaleFactor = this->deviceScaleFactor();
- auto borderBoxRect = rendererBorderBoxRect(renderer());
+ auto borderBoxRect = m_owningLayer.rendererBorderBoxRect();
auto transformOrigin = computeTransformOriginForPainting(borderBoxRect);
auto layerOffset = roundPointToDevicePixels(toLayoutPoint(offsetFromParentGraphicsLayer), deviceScaleFactor);
auto anchor = FloatPoint3D {
@@ -1396,7 +1381,7 @@
auto computeMasksToBoundsRect = [&] {
if ((renderer().style().clipPath() || renderer().style().hasBorderRadius()) && !m_childClippingMaskLayer) {
- auto contentsClippingRect = FloatRoundedRect(renderer().style().getRoundedInnerBorderFor(rendererBorderBoxRect(renderer())));
+ auto contentsClippingRect = FloatRoundedRect(renderer().style().getRoundedInnerBorderFor(m_owningLayer.rendererBorderBoxRect()));
contentsClippingRect.move(LayoutSize(-clipLayer->offsetFromRenderer()));
return contentsClippingRect;
}
@@ -3748,16 +3733,16 @@
bool didAnimate = false;
- if (hasRotate && m_graphicsLayer->addAnimation(rotateVector, snappedIntRect(rendererBorderBoxRect(renderer())).size(), &animation, keyframes.animationName(), timeOffset))
+ if (hasRotate && m_graphicsLayer->addAnimation(rotateVector, snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size(), &animation, keyframes.animationName(), timeOffset))
didAnimate = true;
- if (hasScale && m_graphicsLayer->addAnimation(scaleVector, snappedIntRect(rendererBorderBoxRect(renderer())).size(), &animation, keyframes.animationName(), timeOffset))
+ if (hasScale && m_graphicsLayer->addAnimation(scaleVector, snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size(), &animation, keyframes.animationName(), timeOffset))
didAnimate = true;
- if (hasTranslate && m_graphicsLayer->addAnimation(translateVector, snappedIntRect(rendererBorderBoxRect(renderer())).size(), &animation, keyframes.animationName(), timeOffset))
+ if (hasTranslate && m_graphicsLayer->addAnimation(translateVector, snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size(), &animation, keyframes.animationName(), timeOffset))
didAnimate = true;
- if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(rendererBorderBoxRect(renderer())).size(), &animation, keyframes.animationName(), timeOffset))
+ if (hasTransform && m_graphicsLayer->addAnimation(transformVector, snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size(), &animation, keyframes.animationName(), timeOffset))
didAnimate = true;
if (hasOpacity && m_graphicsLayer->addAnimation(opacityVector, IntSize { }, &animation, keyframes.animationName(), timeOffset))
@@ -3992,7 +3977,7 @@
auto applyTransformOperation = [&](TransformOperation* operation) {
if (operation)
- operation->apply(matrix, snappedIntRect(rendererBorderBoxRect(renderer())).size());
+ operation->apply(matrix, snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size());
};
if (property == AnimatedPropertyTranslate)
@@ -4002,7 +3987,7 @@
else if (property == AnimatedPropertyRotate)
applyTransformOperation(renderer().style().rotate());
else if (property == AnimatedPropertyTransform)
- renderer().style().transform().apply(snappedIntRect(rendererBorderBoxRect(renderer())).size(), matrix);
+ renderer().style().transform().apply(snappedIntRect(m_owningLayer.rendererBorderBoxRect()).size(), matrix);
else
ASSERT_NOT_REACHED();
Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/RenderLayerModelObject.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -77,6 +77,8 @@
void mapLocalToSVGContainer(const RenderLayerModelObject* ancestorContainer, TransformState&, OptionSet<MapCoordinatesMode>, bool* wasFixed) const;
#endif
+ virtual void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const = 0;
+
protected:
RenderLayerModelObject(Element&, RenderStyle&&, BaseTypeFlags);
RenderLayerModelObject(Document&, RenderStyle&&, BaseTypeFlags);
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -276,10 +276,9 @@
return rect.contains(ctm.mapRect(renderer->repaintRectInLocalCoordinates()));
}
-void RenderSVGModelObject::applyTransform(TransformationMatrix& transform, const RenderStyle& style, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
+void RenderSVGModelObject::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
{
UNUSED_PARAM(transform);
- UNUSED_PARAM(style);
UNUSED_PARAM(boundingBox);
UNUSED_PARAM(options);
// FIXME: [LBSE] Upstream SVGRenderSupport changes
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGModelObject.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -58,8 +58,7 @@
inline SVGElement& element() const;
- // FIXME: [LBSE] Mark final, add applyTransform to RenderLayerModelObject
- void applyTransform(TransformationMatrix&, const RenderStyle&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption>) const;
+ void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const override;
// Mimic the RenderBox accessors - by sharing the same terminology the painting / hit testing / layout logic is
// similar to read compared to non-SVG renderers such as RenderBox & friends.
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp (289605 => 289606)
--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp 2022-02-11 08:04:03 UTC (rev 289606)
@@ -608,12 +608,10 @@
return clipRect;
}
-void RenderSVGRoot::applyTransform(TransformationMatrix& transform, const RenderStyle& style, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
+void RenderSVGRoot::applyTransform(TransformationMatrix& transform, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> options) const
{
- UNUSED_PARAM(transform);
- UNUSED_PARAM(style);
- UNUSED_PARAM(boundingBox);
- UNUSED_PARAM(options);
+ RenderReplaced::applyTransform(transform, boundingBox, options);
+
// FIXME: [LBSE] Upstream SVGRenderSupport changes
// SVGRenderSupport::applyTransform(*this, transform, style, boundingBox, std::nullopt, std::nullopt, options);
}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h (289605 => 289606)
--- trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h 2022-02-11 06:55:20 UTC (rev 289605)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGRoot.h 2022-02-11 08:04:03 UTC (rev 289606)
@@ -66,8 +66,7 @@
bool shouldApplyViewportClip() const;
- // FIXME: [LBSE] Mark final, add applyTransform to RenderLayerModelObject
- void applyTransform(TransformationMatrix&, const RenderStyle&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption>) const;
+ void applyTransform(TransformationMatrix&, const FloatRect& boundingBox, OptionSet<RenderStyle::TransformOperationOption> = RenderStyle::allTransformOperations) const final;
FloatRect objectBoundingBox() const final { return m_objectBoundingBox; }
FloatRect strokeBoundingBox() const final { return m_strokeBoundingBox; }