Title: [287832] trunk/Source/WebCore
Revision
287832
Author
[email protected]
Date
2022-01-10 01:47:29 -0800 (Mon, 10 Jan 2022)

Log Message

[LBSE] Begin layer-aware RenderSVGShape implementation
https://bugs.webkit.org/show_bug.cgi?id=234954

Reviewed by Rob Buis.

Begin implementing RenderSVGShape, based on the downstream version in the
LBSE branch. Many parts are 1:1 copies from LegacyRenderSVGShape, although
the core methods for layout / paint / hit-testing looks quite different in
RenderSVGShape -- the code is mostly adapted from layer-aware CSS renderers
such as RenderBox / RenderBlock taking SVG specifics into account.

This patch hooks in RenderSVGShape in all places that used to handle
LegacyRenderSVGShape, e.g. in AccessibilityRenderObject. However no
renderer inherits from RenderSVGShape yet -- a follow-up patch will
introduce RenderSVGRect.

Covered by existing tests, no change in behaviour.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* accessibility/AccessibilityRenderObject.cpp:
(WebCore::AccessibilityRenderObject::supportsPath const):
(WebCore::AccessibilityRenderObject::elementPath const):
* rendering/RenderTreeAsText.cpp:
(WebCore::write):
* rendering/svg/RenderSVGResource.cpp:
(WebCore::RenderSVGResource::fillAndStrokePathOrShape const):
* rendering/svg/RenderSVGResource.h:
(WebCore::RenderSVGResource::postApplyResource):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::postApplyResource):
* rendering/svg/RenderSVGResourceFilter.h:
* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::RenderSVGResourceGradient::postApplyResource):
* rendering/svg/RenderSVGResourceGradient.h:
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::postApplyResource):
* rendering/svg/RenderSVGResourcePattern.h:
* rendering/svg/RenderSVGResourceSolidColor.cpp:
(WebCore::RenderSVGResourceSolidColor::postApplyResource):
* rendering/svg/RenderSVGResourceSolidColor.h:
* rendering/svg/RenderSVGShape.cpp: Added.
(WebCore::RenderSVGShape::RenderSVGShape):
(WebCore::RenderSVGShape::updateShapeFromElement):
(WebCore::RenderSVGShape::isEmpty const):
(WebCore::RenderSVGShape::fillShape const):
(WebCore::RenderSVGShape::strokeShape const):
(WebCore::RenderSVGShape::shapeDependentStrokeContains):
(WebCore::RenderSVGShape::shapeDependentFillContains const):
(WebCore::RenderSVGShape::fillContains):
(WebCore::RenderSVGShape::strokeContains):
(WebCore::RenderSVGShape::layout):
(WebCore::RenderSVGShape::nonScalingStrokePath const):
(WebCore::RenderSVGShape::setupNonScalingStrokeContext):
(WebCore::RenderSVGShape::nonScalingStrokeTransform const):
(WebCore::RenderSVGShape::shouldGenerateMarkerPositions const):
(WebCore::RenderSVGShape::fillShape):
(WebCore::RenderSVGShape::strokeShape):
(WebCore::RenderSVGShape::fillStrokeMarkers):
(WebCore::RenderSVGShape::paint):
(WebCore::RenderSVGShape::isPointInFill):
(WebCore::RenderSVGShape::isPointInStroke):
(WebCore::RenderSVGShape::getTotalLength const):
(WebCore::RenderSVGShape::getPointAtLength const):
(WebCore::RenderSVGShape::nodeAtPoint):
(WebCore::markerForType):
(WebCore::RenderSVGShape::computeMarkerBoundingBox const):
(WebCore::RenderSVGShape::calculateObjectBoundingBox const):
(WebCore::RenderSVGShape::calculateStrokeBoundingBox const):
(WebCore::RenderSVGShape::strokeWidth const):
(WebCore::RenderSVGShape::hasSmoothStroke const):
(WebCore::RenderSVGShape::drawMarkers):
(WebCore::RenderSVGShape::createPath const):
(WebCore::RenderSVGShape::processMarkerPositions):
(WebCore::RenderSVGShape::styleWillChange):
* rendering/svg/RenderSVGShape.h: Added.
(WebCore::RenderSVGShape::setNeedsShapeUpdate):
(WebCore::RenderSVGShape::hasPath const):
(WebCore::RenderSVGShape::path const):
(WebCore::RenderSVGShape::clearPath):
(WebCore::RenderSVGShape::hasNonScalingStroke const):
* rendering/svg/RenderSVGShapeInlines.h: Added.
(WebCore::RenderSVGShape::graphicsElement const):
* rendering/svg/SVGRenderSupport.cpp:
* rendering/svg/SVGRenderTreeAsText.cpp:
(WebCore::writeSVGPaintingResource):
(WebCore::writeSVGFillPaintingResource):
(WebCore::writeSVGStrokePaintingResource):
(WebCore::writeStyle):
(WebCore::writeSVGGraphicsElement):
(WebCore::operator<<):
(WebCore::write):
* rendering/svg/SVGRenderTreeAsText.h:
* svg/SVGAnimateMotionElement.cpp:
* svg/SVGGeometryElement.cpp:
(WebCore::SVGGeometryElement::getTotalLength const):
(WebCore::SVGGeometryElement::getPointAtLength const):
(WebCore::SVGGeometryElement::isPointInFill):
(WebCore::SVGGeometryElement::isPointInStroke):
* svg/SVGLineElement.cpp:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (287831 => 287832)


--- trunk/Source/WebCore/ChangeLog	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/ChangeLog	2022-01-10 09:47:29 UTC (rev 287832)
@@ -1,3 +1,106 @@
+2022-01-10  Nikolas Zimmermann  <[email protected]>
+
+        [LBSE] Begin layer-aware RenderSVGShape implementation
+        https://bugs.webkit.org/show_bug.cgi?id=234954
+
+        Reviewed by Rob Buis.
+
+        Begin implementing RenderSVGShape, based on the downstream version in the
+        LBSE branch. Many parts are 1:1 copies from LegacyRenderSVGShape, although
+        the core methods for layout / paint / hit-testing looks quite different in
+        RenderSVGShape -- the code is mostly adapted from layer-aware CSS renderers
+        such as RenderBox / RenderBlock taking SVG specifics into account.
+
+        This patch hooks in RenderSVGShape in all places that used to handle
+        LegacyRenderSVGShape, e.g. in AccessibilityRenderObject. However no
+        renderer inherits from RenderSVGShape yet -- a follow-up patch will
+        introduce RenderSVGRect.
+
+        Covered by existing tests, no change in behaviour.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * accessibility/AccessibilityRenderObject.cpp:
+        (WebCore::AccessibilityRenderObject::supportsPath const):
+        (WebCore::AccessibilityRenderObject::elementPath const):
+        * rendering/RenderTreeAsText.cpp:
+        (WebCore::write):
+        * rendering/svg/RenderSVGResource.cpp:
+        (WebCore::RenderSVGResource::fillAndStrokePathOrShape const):
+        * rendering/svg/RenderSVGResource.h:
+        (WebCore::RenderSVGResource::postApplyResource):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::postApplyResource):
+        * rendering/svg/RenderSVGResourceFilter.h:
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::RenderSVGResourceGradient::postApplyResource):
+        * rendering/svg/RenderSVGResourceGradient.h:
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::postApplyResource):
+        * rendering/svg/RenderSVGResourcePattern.h:
+        * rendering/svg/RenderSVGResourceSolidColor.cpp:
+        (WebCore::RenderSVGResourceSolidColor::postApplyResource):
+        * rendering/svg/RenderSVGResourceSolidColor.h:
+        * rendering/svg/RenderSVGShape.cpp: Added.
+        (WebCore::RenderSVGShape::RenderSVGShape):
+        (WebCore::RenderSVGShape::updateShapeFromElement):
+        (WebCore::RenderSVGShape::isEmpty const):
+        (WebCore::RenderSVGShape::fillShape const):
+        (WebCore::RenderSVGShape::strokeShape const):
+        (WebCore::RenderSVGShape::shapeDependentStrokeContains):
+        (WebCore::RenderSVGShape::shapeDependentFillContains const):
+        (WebCore::RenderSVGShape::fillContains):
+        (WebCore::RenderSVGShape::strokeContains):
+        (WebCore::RenderSVGShape::layout):
+        (WebCore::RenderSVGShape::nonScalingStrokePath const):
+        (WebCore::RenderSVGShape::setupNonScalingStrokeContext):
+        (WebCore::RenderSVGShape::nonScalingStrokeTransform const):
+        (WebCore::RenderSVGShape::shouldGenerateMarkerPositions const):
+        (WebCore::RenderSVGShape::fillShape):
+        (WebCore::RenderSVGShape::strokeShape):
+        (WebCore::RenderSVGShape::fillStrokeMarkers):
+        (WebCore::RenderSVGShape::paint):
+        (WebCore::RenderSVGShape::isPointInFill):
+        (WebCore::RenderSVGShape::isPointInStroke):
+        (WebCore::RenderSVGShape::getTotalLength const):
+        (WebCore::RenderSVGShape::getPointAtLength const):
+        (WebCore::RenderSVGShape::nodeAtPoint):
+        (WebCore::markerForType):
+        (WebCore::RenderSVGShape::computeMarkerBoundingBox const):
+        (WebCore::RenderSVGShape::calculateObjectBoundingBox const):
+        (WebCore::RenderSVGShape::calculateStrokeBoundingBox const):
+        (WebCore::RenderSVGShape::strokeWidth const):
+        (WebCore::RenderSVGShape::hasSmoothStroke const):
+        (WebCore::RenderSVGShape::drawMarkers):
+        (WebCore::RenderSVGShape::createPath const):
+        (WebCore::RenderSVGShape::processMarkerPositions):
+        (WebCore::RenderSVGShape::styleWillChange):
+        * rendering/svg/RenderSVGShape.h: Added.
+        (WebCore::RenderSVGShape::setNeedsShapeUpdate):
+        (WebCore::RenderSVGShape::hasPath const):
+        (WebCore::RenderSVGShape::path const):
+        (WebCore::RenderSVGShape::clearPath):
+        (WebCore::RenderSVGShape::hasNonScalingStroke const):
+        * rendering/svg/RenderSVGShapeInlines.h: Added.
+        (WebCore::RenderSVGShape::graphicsElement const):
+        * rendering/svg/SVGRenderSupport.cpp:
+        * rendering/svg/SVGRenderTreeAsText.cpp:
+        (WebCore::writeSVGPaintingResource):
+        (WebCore::writeSVGFillPaintingResource):
+        (WebCore::writeSVGStrokePaintingResource):
+        (WebCore::writeStyle):
+        (WebCore::writeSVGGraphicsElement):
+        (WebCore::operator<<):
+        (WebCore::write):
+        * rendering/svg/SVGRenderTreeAsText.h:
+        * svg/SVGAnimateMotionElement.cpp:
+        * svg/SVGGeometryElement.cpp:
+        (WebCore::SVGGeometryElement::getTotalLength const):
+        (WebCore::SVGGeometryElement::getPointAtLength const):
+        (WebCore::SVGGeometryElement::isPointInFill):
+        (WebCore::SVGGeometryElement::isPointInStroke):
+        * svg/SVGLineElement.cpp:
+
 2022-01-09  Sam Weinig  <[email protected]>
 
         Remove support for Direct2D / FTW

Modified: trunk/Source/WebCore/Sources.txt (287831 => 287832)


--- trunk/Source/WebCore/Sources.txt	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/Sources.txt	2022-01-10 09:47:29 UTC (rev 287832)
@@ -2494,6 +2494,7 @@
 rendering/svg/RenderSVGResourceRadialGradient.cpp
 rendering/svg/RenderSVGResourceSolidColor.cpp
 rendering/svg/RenderSVGRoot.cpp
+rendering/svg/RenderSVGShape.cpp
 rendering/svg/RenderSVGTSpan.cpp
 rendering/svg/RenderSVGText.cpp
 rendering/svg/RenderSVGTextPath.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (287831 => 287832)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2022-01-10 09:47:29 UTC (rev 287832)
@@ -3273,6 +3273,7 @@
 		A104F24414C71F7A009E2C23 /* CachedSVGDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = A104F24214C71F7A009E2C23 /* CachedSVGDocument.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A10BB5851484E3A700B2E87A /* LegacyRenderSVGRect.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5831484E3A700B2E87A /* LegacyRenderSVGRect.h */; };
 		A10BB58B1484E3B300B2E87A /* LegacyRenderSVGShape.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5891484E3B300B2E87A /* LegacyRenderSVGShape.h */; };
+		A10BB58B1484E3B300C3F77B /* RenderSVGShape.h in Headers */ = {isa = PBXBuildFile; fileRef = A10BB5891484E3B300C3F77B /* RenderSVGShape.h */; };
 		A10DBF4718F92317000D70C6 /* LegacyPreviewLoaderClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A10DBF4618F92317000D70C6 /* LegacyPreviewLoaderClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A10DC76B14747BAB005E2471 /* StyleGridData.h in Headers */ = {isa = PBXBuildFile; fileRef = A10DC76914747BAB005E2471 /* StyleGridData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A10F7C73273100D0008FA9AF /* ModalContainerObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = A10F7C7027310073008FA9AF /* ModalContainerObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4632,6 +4633,7 @@
 		CDF747F3270F76CF008FEEEC /* RenderSVGResourceLinearGradientInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747F2270F76CF008FEEEC /* RenderSVGResourceLinearGradientInlines.h */; };
 		CDF747F5270F83B1008FEEEC /* RenderSVGGradientStopInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747F4270F83B1008FEEEC /* RenderSVGGradientStopInlines.h */; };
 		CDF747F7270F86A4008FEEEC /* LegacyRenderSVGShapeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747F6270F86A4008FEEEC /* LegacyRenderSVGShapeInlines.h */; };
+		CDF747F7270F83B4107DEEEC /* RenderSVGShapeInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747F6270F83B4107DEEEC /* RenderSVGShapeInlines.h */; };
 		CDF747F9270F87CB008FEEEC /* RenderSVGResourceRadialGradientInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747F8270F87CB008FEEEC /* RenderSVGResourceRadialGradientInlines.h */; };
 		CDF747FB270F891A008FEEEC /* RenderSVGResourceMaskerInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF747FA270F891A008FEEEC /* RenderSVGResourceMaskerInlines.h */; };
 		CDF7483F18FEBCEC0006ECC0 /* GridPositionsResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = CDF7483D18FEBCEC0006ECC0 /* GridPositionsResolver.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -13379,7 +13381,9 @@
 		A10BB5821484E3A700B2E87A /* LegacyRenderSVGRect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyRenderSVGRect.cpp; sourceTree = "<group>"; };
 		A10BB5831484E3A700B2E87A /* LegacyRenderSVGRect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGRect.h; sourceTree = "<group>"; };
 		A10BB5881484E3B300B2E87A /* LegacyRenderSVGShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyRenderSVGShape.cpp; sourceTree = "<group>"; };
+		A10CC5881473E3B300B2A8BF /* RenderSVGShape.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGShape.cpp; sourceTree = "<group>"; };
 		A10BB5891484E3B300B2E87A /* LegacyRenderSVGShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGShape.h; sourceTree = "<group>"; };
+		A10BB5891484E3B300C3F77B /* RenderSVGShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGShape.h; sourceTree = "<group>"; };
 		A10D6E942144C99800FDD14D /* JSPaymentResponseCustom.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSPaymentResponseCustom.cpp; sourceTree = "<group>"; };
 		A10DBF4618F92317000D70C6 /* LegacyPreviewLoaderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyPreviewLoaderClient.h; sourceTree = "<group>"; };
 		A10DC76814747BAB005E2471 /* StyleGridData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleGridData.cpp; sourceTree = "<group>"; };
@@ -16280,6 +16284,7 @@
 		CDF747F2270F76CF008FEEEC /* RenderSVGResourceLinearGradientInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceLinearGradientInlines.h; sourceTree = "<group>"; };
 		CDF747F4270F83B1008FEEEC /* RenderSVGGradientStopInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderSVGGradientStopInlines.h; sourceTree = "<group>"; };
 		CDF747F6270F86A4008FEEEC /* LegacyRenderSVGShapeInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGShapeInlines.h; sourceTree = "<group>"; };
+		CDF747F6270F83B4107DEEEC /* RenderSVGShapeInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderSVGShapeInlines.h; sourceTree = "<group>"; };
 		CDF747F8270F87CB008FEEEC /* RenderSVGResourceRadialGradientInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceRadialGradientInlines.h; sourceTree = "<group>"; };
 		CDF747FA270F891A008FEEEC /* RenderSVGResourceMaskerInlines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceMaskerInlines.h; sourceTree = "<group>"; };
 		CDF7483C18FEBCEC0006ECC0 /* GridPositionsResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GridPositionsResolver.cpp; sourceTree = "<group>"; };
@@ -18972,6 +18977,9 @@
 				436708A412D9CA4B00044234 /* RenderSVGResourceSolidColor.h */,
 				436708A512D9CA5C00044234 /* RenderSVGRoot.cpp */,
 				436708A612D9DB4B00044234 /* RenderSVGRoot.h */,
+				A10CC5881473E3B300B2A8BF /* RenderSVGShape.cpp */,
+				A10BB5891484E3B300C3F77B /* RenderSVGShape.h */,
+				CDF747F6270F83B4107DEEEC /* RenderSVGShapeInlines.h */,
 				0854B0061255E4E600B9CDD0 /* RenderSVGText.cpp */,
 				0854B0071255E4E600B9CDD0 /* RenderSVGText.h */,
 				0854B0081255E4E600B9CDD0 /* RenderSVGTextPath.cpp */,
@@ -36750,6 +36758,8 @@
 				CDF747F9270F87CB008FEEEC /* RenderSVGResourceRadialGradientInlines.h in Headers */,
 				436708E312D9CA4B00044234 /* RenderSVGResourceSolidColor.h in Headers */,
 				436708E512D9DB4B00044234 /* RenderSVGRoot.h in Headers */,
+				A10BB58B1484E3B300C3F77B /* RenderSVGShape.h in Headers */,
+				CDF747F7270F83B4107DEEEC /* RenderSVGShapeInlines.h in Headers */,
 				0854B0191255E4E600B9CDD0 /* RenderSVGText.h in Headers */,
 				0854B01B1255E4E600B9CDD0 /* RenderSVGTextPath.h in Headers */,
 				436708E912D9CA4B00044234 /* RenderSVGTransformableContainer.h in Headers */,

Modified: trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp (287831 => 287832)


--- trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -96,6 +96,7 @@
 #include "RenderMathMLBlock.h"
 #include "RenderMenuList.h"
 #include "RenderSVGRoot.h"
+#include "RenderSVGShape.h"
 #include "RenderTableCell.h"
 #include "RenderText.h"
 #include "RenderTextControl.h"
@@ -910,7 +911,7 @@
 
 bool AccessibilityRenderObject::supportsPath() const
 {
-    return is<RenderText>(renderer()) || is<LegacyRenderSVGShape>(renderer());
+    return is<RenderText>(renderer()) || (renderer() && renderer()->isSVGShapeOrLegacySVGShape());
 }
 
 Path AccessibilityRenderObject::elementPath() const
@@ -960,15 +961,24 @@
         if (auto svgRoot = ancestorsOfType<LegacyRenderSVGRoot>(*m_renderer).first()) {
             LayoutPoint parentOffset = axObjectCache()->getOrCreate(&*svgRoot)->elementRect().location();
             path.transform(AffineTransform().translate(parentOffset.x(), parentOffset.y()));
+        }
+
+        return path;
+    }
+
 #if ENABLE(LAYER_BASED_SVG_ENGINE)
-        } else if (auto svgRoot = ancestorsOfType<RenderSVGRoot>(*m_renderer).first()) {
+    if (is<RenderSVGShape>(renderer()) && downcast<RenderSVGShape>(*m_renderer).hasPath()) {
+        Path path = downcast<RenderSVGShape>(*m_renderer).path();
+
+        // The SVG path is in terms of the parent's bounding box. The path needs to be offset to frame coordinates.
+        if (auto svgRoot = ancestorsOfType<RenderSVGRoot>(*m_renderer).first()) {
             LayoutPoint parentOffset = axObjectCache()->getOrCreate(&*svgRoot)->elementRect().location();
             path.transform(AffineTransform().translate(parentOffset.x(), parentOffset.y()));
-#endif
         }
 
         return path;
     }
+#endif
 
     return Path();
 }

Modified: trunk/Source/WebCore/rendering/RenderTreeAsText.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/RenderTreeAsText.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -39,6 +39,7 @@
 #include "InlineIteratorTextBox.h"
 #include "LegacyInlineTextBox.h"
 #include "LegacyRenderSVGRoot.h"
+#include "LegacyRenderSVGShape.h"
 #include "Logging.h"
 #include "PrintContext.h"
 #include "PseudoElement.h"
@@ -64,6 +65,7 @@
 #include "RenderSVGPath.h"
 #include "RenderSVGResourceContainer.h"
 #include "RenderSVGRoot.h"
+#include "RenderSVGShape.h"
 #include "RenderSVGText.h"
 #include "RenderTableCell.h"
 #include "RenderView.h"
@@ -558,6 +560,12 @@
         ts << "\n";
     };
 
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    if (is<RenderSVGShape>(o)) {
+        write(ts, downcast<RenderSVGShape>(o), behavior);
+        return;
+    }
+#endif
     if (is<LegacyRenderSVGShape>(o)) {
         write(ts, downcast<LegacyRenderSVGShape>(o), behavior);
         return;

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResource.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResource.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResource.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -26,11 +26,13 @@
 #include "Frame.h"
 #include "FrameView.h"
 #include "LegacyRenderSVGRoot.h"
+#include "LegacyRenderSVGShape.h"
 #include "RenderSVGResourceClipper.h"
 #include "RenderSVGResourceFilter.h"
 #include "RenderSVGResourceMasker.h"
 #include "RenderSVGResourceSolidColor.h"
 #include "RenderSVGRoot.h"
+#include "RenderSVGShape.h"
 #include "RenderView.h"
 #include "SVGResourceElementClient.h"
 #include "SVGResources.h"
@@ -243,4 +245,39 @@
     }
 }
 
+void RenderSVGResource::fillAndStrokePathOrShape(GraphicsContext& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const RenderElement* shape) const
+{
+    if (shape) {
+        ASSERT(shape->isSVGShapeOrLegacySVGShape());
+
+        if (resourceMode.contains(RenderSVGResourceMode::ApplyToFill)) {
+            if (is<LegacyRenderSVGShape>(shape))
+                downcast<LegacyRenderSVGShape>(shape)->fillShape(context);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+            else if (is<RenderSVGShape>(shape))
+                downcast<RenderSVGShape>(shape)->fillShape(context);
+#endif
+        }
+
+        if (resourceMode.contains(RenderSVGResourceMode::ApplyToStroke)) {
+            if (is<LegacyRenderSVGShape>(shape))
+                downcast<LegacyRenderSVGShape>(shape)->strokeShape(context);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+            else if (is<RenderSVGShape>(shape))
+                downcast<RenderSVGShape>(shape)->strokeShape(context);
+#endif
+        }
+
+        return;
+    }
+
+    if (!path)
+        return;
+
+    if (resourceMode.contains(RenderSVGResourceMode::ApplyToFill))
+        context.fillPath(*path);
+    if (resourceMode.contains(RenderSVGResourceMode::ApplyToStroke))
+        context.strokePath(*path);
 }
+
+}

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResource.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResource.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResource.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -19,8 +19,8 @@
 
 #pragma once
 
-#include "LegacyRenderSVGShape.h"
 #include "RenderStyleConstants.h"
+#include <wtf/OptionSet.h>
 #include <wtf/TypeCasts.h>
 
 namespace WebCore {
@@ -47,9 +47,10 @@
 class FloatRect;
 class GraphicsContext;
 class Path;
+class RenderElement;
 class RenderObject;
+class RenderSVGResourceSolidColor;
 class RenderStyle;
-class RenderSVGResourceSolidColor;
 
 class RenderSVGResource {
 public:
@@ -60,7 +61,7 @@
     virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) = 0;
 
     virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>) = 0;
-    virtual void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const LegacyRenderSVGShape*) { }
+    virtual void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement* /* shape */) { }
     virtual FloatRect resourceBoundingBox(const RenderObject&) = 0;
 
     virtual RenderSVGResourceType resourceType() const = 0;
@@ -71,6 +72,9 @@
     static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
 
     static void markForLayoutAndParentResourceInvalidation(RenderObject&, bool needsLayout = true);
+
+protected:
+    void fillAndStrokePathOrShape(GraphicsContext&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement* shape) const;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -172,7 +172,7 @@
     return true;
 }
 
-void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path*, const LegacyRenderSVGShape*)
+void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path*, const RenderElement*)
 {
     ASSERT(context);
     ASSERT_UNUSED(resourceMode, !resourceMode);

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -69,7 +69,7 @@
     void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
 
     bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>) override;
-    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const LegacyRenderSVGShape*) override;
+    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement*) override;
 
     FloatRect resourceBoundingBox(const RenderObject&) override;
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -179,7 +179,7 @@
     return true;
 }
 
-void RenderSVGResourceGradient::postApplyResource(RenderElement& renderer, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const LegacyRenderSVGShape* shape)
+void RenderSVGResourceGradient::postApplyResource(RenderElement& renderer, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const RenderElement* shape)
 {
     ASSERT(context);
     ASSERT(!resourceMode.isEmpty());
@@ -207,20 +207,8 @@
 #else
         UNUSED_PARAM(renderer);
 #endif
-    } else {
-        if (resourceMode.contains(RenderSVGResourceMode::ApplyToFill)) {
-            if (path)
-                context->fillPath(*path);
-            else if (shape)
-                shape->fillShape(*context);
-        }
-        if (resourceMode.contains(RenderSVGResourceMode::ApplyToStroke)) {
-            if (path)
-                context->strokePath(*path);
-            else if (shape)
-                shape->strokeShape(*context);
-        }
-    }
+    } else
+        fillAndStrokePathOrShape(*context, resourceMode, path, shape);
 
     context->restore();
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -40,7 +40,7 @@
     void removeClientFromCache(RenderElement&, bool markForInvalidation = true) final;
 
     bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>) final;
-    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const LegacyRenderSVGShape*) final;
+    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement*) final;
     FloatRect resourceBoundingBox(const RenderObject&) final { return FloatRect(); }
 
 protected:

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -201,24 +201,11 @@
     return true;
 }
 
-void RenderSVGResourcePattern::postApplyResource(RenderElement&, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const LegacyRenderSVGShape* shape)
+void RenderSVGResourcePattern::postApplyResource(RenderElement&, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const RenderElement* shape)
 {
     ASSERT(context);
     ASSERT(!resourceMode.isEmpty());
-
-    if (resourceMode.contains(RenderSVGResourceMode::ApplyToFill)) {
-        if (path)
-            context->fillPath(*path);
-        else if (shape)
-            shape->fillShape(*context);
-    }
-    if (resourceMode.contains(RenderSVGResourceMode::ApplyToStroke)) {
-        if (path)
-            context->strokePath(*path);
-        else if (shape)
-            shape->strokeShape(*context);
-    }
-
+    fillAndStrokePathOrShape(*context, resourceMode, path, shape);
     context->restore();
 }
 

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -48,7 +48,7 @@
     void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
 
     bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>) override;
-    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const LegacyRenderSVGShape*) override;
+    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement*) override;
     FloatRect resourceBoundingBox(const RenderObject&) override { return FloatRect(); }
 
     RenderSVGResourceType resourceType() const override { return PatternResourceType; }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -23,8 +23,10 @@
 #include "Frame.h"
 #include "FrameView.h"
 #include "GraphicsContext.h"
+#include "RenderElement.h"
 #include "RenderStyle.h"
 #include "RenderView.h"
+#include "SVGRenderSupport.h"
 
 namespace WebCore {
 
@@ -67,23 +69,11 @@
     return true;
 }
 
-void RenderSVGResourceSolidColor::postApplyResource(RenderElement&, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const LegacyRenderSVGShape* shape)
+void RenderSVGResourceSolidColor::postApplyResource(RenderElement&, GraphicsContext*& context, OptionSet<RenderSVGResourceMode> resourceMode, const Path* path, const RenderElement* shape)
 {
     ASSERT(context);
     ASSERT(!resourceMode.isEmpty());
-
-    if (resourceMode.contains(RenderSVGResourceMode::ApplyToFill)) {
-        if (path)
-            context->fillPath(*path);
-        else if (shape)
-            shape->fillShape(*context);
-    }
-    if (resourceMode.contains(RenderSVGResourceMode::ApplyToStroke)) {
-        if (path)
-            context->strokePath(*path);
-        else if (shape)
-            shape->strokeShape(*context);
-    }
+    fillAndStrokePathOrShape(*context, resourceMode, path, shape);
 }
 
 }

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -20,10 +20,13 @@
 #pragma once
 
 #include "Color.h"
+#include "FloatRect.h"
 #include "RenderSVGResource.h"
 
 namespace WebCore {
 
+class RenderObject;
+
 class RenderSVGResourceSolidColor final : public RenderSVGResource {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -34,7 +37,7 @@
     void removeClientFromCache(RenderElement&, bool = true) override { }
 
     bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>) override;
-    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const LegacyRenderSVGShape*) override;
+    void postApplyResource(RenderElement&, GraphicsContext*&, OptionSet<RenderSVGResourceMode>, const Path*, const RenderElement*) override;
     FloatRect resourceBoundingBox(const RenderObject&) override { return FloatRect(); }
 
     RenderSVGResourceType resourceType() const override { return SolidColorResourceType; }

Added: trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp (0 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	                        (rev 0)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <[email protected]>
+ * Copyright (C) 2004, 2005, 2008 Rob Buis <[email protected]>
+ * Copyright (C) 2005, 2007 Eric Seidel <[email protected]>
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2009 Dirk Schulze <[email protected]>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2009 Jeff Schiller <[email protected]>
+ * Copyright (C) 2011 Renata Hodovan <[email protected]>
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2018 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2020, 2021, 2022 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "RenderSVGShape.h"
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "GraphicsContext.h"
+#include "HitTestRequest.h"
+#include "HitTestResult.h"
+#include "LayoutRepainter.h"
+#include "PointerEventsHitRules.h"
+#include "RenderSVGResourceMarker.h"
+#include "RenderSVGResourceSolidColor.h"
+#include "RenderSVGShapeInlines.h"
+#include "SVGPathData.h"
+#include "SVGRenderingContext.h"
+#include "SVGResources.h"
+#include "SVGResourcesCache.h"
+#include "SVGURIReference.h"
+#include <wtf/IsoMallocInlines.h>
+#include <wtf/StackStats.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(RenderSVGShape);
+
+RenderSVGShape::RenderSVGShape(SVGGraphicsElement& element, RenderStyle&& style)
+    : RenderSVGModelObject(element, WTFMove(style))
+{
+}
+
+RenderSVGShape::~RenderSVGShape() = default;
+
+void RenderSVGShape::updateShapeFromElement()
+{
+    m_path = createPath();
+    processMarkerPositions();
+
+    m_fillBoundingBox = calculateObjectBoundingBox();
+    m_strokeBoundingBox = calculateStrokeBoundingBox();
+}
+
+bool RenderSVGShape::isEmpty() const
+{
+    // This function should never be called before assigning a new Path to m_path.
+    // But this bug can happen if this renderer was created and its layout was not
+    // done before painting. Assert this did not happen but do not crash.
+    ASSERT(hasPath());
+    return !hasPath() || path().isEmpty();
+}
+
+void RenderSVGShape::fillShape(GraphicsContext& context) const
+{
+    context.fillPath(path());
+}
+
+void RenderSVGShape::strokeShape(GraphicsContext& context) const
+{
+    ASSERT(m_path);
+    Path* usePath = m_path.get();
+
+    if (hasNonScalingStroke())
+        usePath = nonScalingStrokePath(usePath, nonScalingStrokeTransform());
+
+    context.strokePath(*usePath);
+}
+
+bool RenderSVGShape::shapeDependentStrokeContains(const FloatPoint& point, PointCoordinateSpace pointCoordinateSpace)
+{
+    ASSERT(m_path);
+
+    if (hasNonScalingStroke() && pointCoordinateSpace != LocalCoordinateSpace) {
+        AffineTransform nonScalingTransform = nonScalingStrokeTransform();
+        Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTransform);
+        return usePath->strokeContains(nonScalingTransform.mapPoint(point), [this] (GraphicsContext& context) {
+            SVGRenderSupport::applyStrokeStyleToContext(context, style(), *this);
+        });
+    }
+
+    return m_path->strokeContains(point, [this] (GraphicsContext& context) {
+        SVGRenderSupport::applyStrokeStyleToContext(context, style(), *this);
+    });
+}
+
+bool RenderSVGShape::shapeDependentFillContains(const FloatPoint& point, const WindRule fillRule) const
+{
+    return path().contains(point, fillRule);
+}
+
+bool RenderSVGShape::fillContains(const FloatPoint& point, bool requiresFill, const WindRule fillRule)
+{
+    if (m_fillBoundingBox.isEmpty() || !m_fillBoundingBox.contains(point))
+        return false;
+
+    Color fallbackColor;
+    if (requiresFill && !RenderSVGResource::fillPaintingResource(*this, style(), fallbackColor))
+        return false;
+
+    return shapeDependentFillContains(point, fillRule);
+}
+
+bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke)
+{
+    if (strokeBoundingBox().isEmpty() || !strokeBoundingBox().contains(point))
+        return false;
+
+    Color fallbackColor;
+    if (requiresStroke && !RenderSVGResource::strokePaintingResource(*this, style(), fallbackColor))
+        return false;
+
+    return shapeDependentStrokeContains(point);
+}
+
+void RenderSVGShape::layout()
+{
+    StackStats::LayoutCheckPoint layoutCheckPoint;
+
+    LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
+    if (m_needsShapeUpdate) {
+        // FIXME: [LBSE] Upstream SVGLengthContext changes
+        // graphicsElement().updateLengthContext();
+        updateShapeFromElement();
+
+        m_needsShapeUpdate = false;
+        setLayoutRect(enclosingLayoutRect(m_fillBoundingBox));
+    }
+
+    // FIXME: [LBSE] Upstream SVGLayerTransformUpdater
+    // SVGRenderSupport::updateLayerTransform(*this);
+
+    // Invalidate all resources of this client if our layout changed.
+    if (everHadLayout() && selfNeedsLayout())
+        SVGResourcesCache::clientLayoutChanged(*this);
+
+    repainter.repaintAfterLayout();
+    clearNeedsLayout();
+}
+
+Path* RenderSVGShape::nonScalingStrokePath(const Path* path, const AffineTransform& strokeTransform) const
+{
+    static NeverDestroyed<Path> tempPath;
+
+    tempPath.get() = *path;
+    tempPath.get().transform(strokeTransform);
+
+    return &tempPath.get();
+}
+
+bool RenderSVGShape::setupNonScalingStrokeContext(AffineTransform& strokeTransform, GraphicsContextStateSaver& stateSaver)
+{
+    std::optional<AffineTransform> inverse = strokeTransform.inverse();
+    if (!inverse)
+        return false;
+
+    stateSaver.save();
+    stateSaver.context()->concatCTM(inverse.value());
+    return true;
+}
+
+AffineTransform RenderSVGShape::nonScalingStrokeTransform() const
+{
+    return graphicsElement().getScreenCTM(SVGLocatable::DisallowStyleUpdate);
+}
+
+bool RenderSVGShape::shouldGenerateMarkerPositions() const
+{
+    if (!style().svgStyle().hasMarkers())
+        return false;
+
+    if (!graphicsElement().supportsMarkers())
+        return false;
+
+    auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+    if (!resources)
+        return false;
+
+    return resources->markerStart() || resources->markerMid() || resources->markerEnd();
+}
+
+void RenderSVGShape::fillShape(const RenderStyle& style, GraphicsContext& originalContext)
+{
+    GraphicsContext* context = &originalContext;
+    Color fallbackColor;
+    if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(*this, style, fallbackColor)) {
+        if (fillPaintingResource->applyResource(*this, style, context, RenderSVGResourceMode::ApplyToFill))
+            fillPaintingResource->postApplyResource(*this, context, RenderSVGResourceMode::ApplyToFill, nullptr, this);
+        else if (fallbackColor.isValid()) {
+            RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
+            fallbackResource->setColor(fallbackColor);
+            if (fallbackResource->applyResource(*this, style, context, RenderSVGResourceMode::ApplyToFill))
+                fallbackResource->postApplyResource(*this, context, RenderSVGResourceMode::ApplyToFill, nullptr, this);
+        }
+    }
+}
+
+void RenderSVGShape::strokeShape(const RenderStyle& style, GraphicsContext& originalContext)
+{
+    GraphicsContext* context = &originalContext;
+    Color fallbackColor;
+    if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(*this, style, fallbackColor)) {
+        if (strokePaintingResource->applyResource(*this, style, context, RenderSVGResourceMode::ApplyToStroke))
+            strokePaintingResource->postApplyResource(*this, context, RenderSVGResourceMode::ApplyToStroke, nullptr, this);
+        else if (fallbackColor.isValid()) {
+            RenderSVGResourceSolidColor* fallbackResource = RenderSVGResource::sharedSolidPaintingResource();
+            fallbackResource->setColor(fallbackColor);
+            if (fallbackResource->applyResource(*this, style, context, RenderSVGResourceMode::ApplyToStroke))
+                fallbackResource->postApplyResource(*this, context, RenderSVGResourceMode::ApplyToStroke, nullptr, this);
+        }
+    }
+}
+
+void RenderSVGShape::strokeShape(GraphicsContext& context)
+{
+    if (!style().hasVisibleStroke())
+        return;
+
+    GraphicsContextStateSaver stateSaver(context, false);
+    if (hasNonScalingStroke()) {
+        AffineTransform nonScalingTransform = nonScalingStrokeTransform();
+        if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver))
+            return;
+    }
+    strokeShape(style(), context);
+}
+
+void RenderSVGShape::fillStrokeMarkers(PaintInfo& childPaintInfo)
+{
+    auto paintOrder = RenderStyle::paintTypesForPaintOrder(style().paintOrder());
+    for (unsigned i = 0; i < paintOrder.size(); ++i) {
+        switch (paintOrder.at(i)) {
+        case PaintType::Fill:
+            fillShape(style(), childPaintInfo.context());
+            break;
+        case PaintType::Stroke:
+            strokeShape(childPaintInfo.context());
+            break;
+        case PaintType::Markers:
+            if (!m_markerPositions.isEmpty())
+                drawMarkers(childPaintInfo);
+            break;
+        }
+    }
+}
+
+void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+    if (paintInfo.context().paintingDisabled())
+        return;
+
+    // FIXME: [LBSE] Upstream SVGRenderSupport changes
+    // if (!SVGRenderSupport::shouldPaintHiddenRenderer(*this))
+    //    return;
+
+    if (!shouldPaintSVGRenderer(paintInfo) || isEmpty())
+        return;
+
+    if (paintInfo.phase == PaintPhase::ClippingMask) {
+        // FIXME: [LBSE] Upstream SVGRenderSupport changes
+        // SVGRenderSupport::paintSVGClippingMask(*this, paintInfo);
+        return;
+    }
+
+    auto adjustedPaintOffset = paintOffset + layoutLocation();
+    if (paintInfo.phase == PaintPhase::Mask) {
+        // FIXME: [LBSE] Upstream SVGRenderSupport changes
+        // SVGRenderSupport::paintSVGMask(*this, paintInfo, adjustedPaintOffset);
+        return;
+    }
+
+    auto visualOverflowRect = visualOverflowRectEquivalent();
+    visualOverflowRect.moveBy(adjustedPaintOffset);
+    if (!visualOverflowRect.intersects(paintInfo.rect))
+        return;
+
+    if (paintInfo.phase == PaintPhase::Outline || paintInfo.phase == PaintPhase::SelfOutline) {
+        // FIXME: [LBSE] Upstream outline painting
+        // paintSVGOutline(paintInfo, adjustedPaintOffset);
+        return;
+    }
+
+    GraphicsContextStateSaver stateSaver(paintInfo.context());
+
+    auto coordinateSystemOriginTranslation = adjustedPaintOffset - flooredLayoutPoint(objectBoundingBox().location());
+    paintInfo.context().translate(coordinateSystemOriginTranslation.width(), coordinateSystemOriginTranslation.height());
+
+    if (style().svgStyle().shapeRendering() == ShapeRendering::CrispEdges)
+        paintInfo.context().setShouldAntialias(false);
+
+    fillStrokeMarkers(paintInfo);
+}
+
+bool RenderSVGShape::isPointInFill(const FloatPoint& point)
+{
+    return shapeDependentFillContains(point, style().svgStyle().fillRule());
+}
+
+bool RenderSVGShape::isPointInStroke(const FloatPoint& point)
+{
+    if (!style().svgStyle().hasStroke())
+        return false;
+
+    return shapeDependentStrokeContains(point, LocalCoordinateSpace);
+}
+
+float RenderSVGShape::getTotalLength() const
+{
+    return hasPath() ? path().length() : createPath()->length();
+}
+
+FloatPoint RenderSVGShape::getPointAtLength(float distance) const
+{
+    return hasPath() ? path().pointAtLength(distance) : createPath()->pointAtLength(distance);
+}
+
+bool RenderSVGShape::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
+{
+    if (hitTestAction != HitTestForeground)
+        return false;
+
+    auto adjustedLocation = accumulatedOffset + layoutLocation();
+
+    auto localPoint = locationInContainer.point();
+    auto boundingBoxTopLeftCorner = flooredLayoutPoint(objectBoundingBox().minXMinYCorner());
+    auto coordinateSystemOriginTranslation = boundingBoxTopLeftCorner - adjustedLocation;
+    localPoint.move(coordinateSystemOriginTranslation);
+
+    if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
+        return false;
+
+    SVGHitTestCycleDetectionScope hitTestScope(*this);
+
+    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_PATH_HITTESTING, request, style().pointerEvents());
+    bool isVisible = (style().visibility() == Visibility::Visible);
+    if (isVisible || !hitRules.requireVisible) {
+        const SVGRenderStyle& svgStyle = style().svgStyle();
+        WindRule fillRule = svgStyle.fillRule();
+        if (request.svgClipContent())
+            fillRule = svgStyle.clipRule();
+
+        if (hitRules.canHitStroke && (svgStyle.hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke)) {
+            updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
+            if (result.addNodeToListBasedTestResult(nodeForHitTest(), request, locationInContainer, m_strokeBoundingBox) == HitTestProgress::Stop)
+                return true;
+            return false;
+        }
+
+        if ((hitRules.canHitFill && (svgStyle.hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))
+            || (hitRules.canHitBoundingBox && m_fillBoundingBox.contains(localPoint))) {
+            updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
+            if (result.addNodeToListBasedTestResult(nodeForHitTest(), request, locationInContainer, m_fillBoundingBox) == HitTestProgress::Stop)
+                return true;
+            return false;
+        }
+    }
+
+    return false;
+}
+
+static inline RenderSVGResourceMarker* markerForType(SVGMarkerType type, RenderSVGResourceMarker* markerStart, RenderSVGResourceMarker* markerMid, RenderSVGResourceMarker* markerEnd)
+{
+    switch (type) {
+    case StartMarker:
+        return markerStart;
+    case MidMarker:
+        return markerMid;
+    case EndMarker:
+        return markerEnd;
+    }
+
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+FloatRect RenderSVGShape::computeMarkerBoundingBox() const
+{
+    if (m_markerPositions.isEmpty())
+        return FloatRect();
+
+    auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+    ASSERT(resources);
+
+    auto* markerStart = resources->markerStart();
+    auto* markerMid = resources->markerMid();
+    auto* markerEnd = resources->markerEnd();
+    if (!markerStart && !markerMid && !markerEnd)
+        return FloatRect();
+
+    FloatRect boundaries;
+    unsigned size = m_markerPositions.size();
+    for (unsigned i = 0; i < size; ++i) {
+        if (RenderSVGResourceMarker* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd))
+            boundaries.unite(marker->markerBoundaries(marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth())));
+    }
+    return boundaries;
+}
+
+FloatRect RenderSVGShape::calculateObjectBoundingBox() const
+{
+    return path().boundingRect();
+}
+
+FloatRect RenderSVGShape::calculateStrokeBoundingBox() const
+{
+    ASSERT(m_path);
+    FloatRect strokeBoundingBox = m_fillBoundingBox;
+
+    if (style().svgStyle().hasStroke()) {
+        if (hasNonScalingStroke()) {
+            AffineTransform nonScalingTransform = nonScalingStrokeTransform();
+            if (std::optional<AffineTransform> inverse = nonScalingTransform.inverse()) {
+                Path* usePath = nonScalingStrokePath(m_path.get(), nonScalingTransform);
+                FloatRect strokeBoundingRect = usePath->strokeBoundingRect(Function<void(GraphicsContext&)> { [this] (GraphicsContext& context) {
+                    SVGRenderSupport::applyStrokeStyleToContext(context, style(), *this);
+                } });
+                strokeBoundingRect = inverse.value().mapRect(strokeBoundingRect);
+                strokeBoundingBox.unite(strokeBoundingRect);
+            }
+        } else {
+            strokeBoundingBox.unite(path().strokeBoundingRect(Function<void(GraphicsContext&)> { [this] (GraphicsContext& context) {
+                SVGRenderSupport::applyStrokeStyleToContext(context, style(), *this);
+            } }));
+        }
+    }
+
+    return strokeBoundingBox;
+}
+
+float RenderSVGShape::strokeWidth() const
+{
+    SVGLengthContext lengthContext(&graphicsElement());
+    return lengthContext.valueForLength(style().strokeWidth());
+}
+
+bool RenderSVGShape::hasSmoothStroke() const
+{
+    const SVGRenderStyle& svgStyle = style().svgStyle();
+    return svgStyle.strokeDashArray().isEmpty()
+        && style().strokeMiterLimit() == style().initialStrokeMiterLimit()
+        && style().joinStyle() == style().initialJoinStyle()
+        && style().capStyle() == style().initialCapStyle();
+}
+
+void RenderSVGShape::drawMarkers(PaintInfo&)
+{
+    ASSERT(!m_markerPositions.isEmpty());
+
+    auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+    if (!resources)
+        return;
+
+    auto* markerStart = resources->markerStart();
+    auto* markerMid = resources->markerMid();
+    auto* markerEnd = resources->markerEnd();
+    if (!markerStart && !markerMid && !markerEnd)
+        return;
+
+    float strokeWidth = this->strokeWidth();
+    unsigned size = m_markerPositions.size();
+    for (unsigned i = 0; i < size; ++i) {
+        if (auto* marker = markerForType(m_markerPositions[i].type, markerStart, markerMid, markerEnd)) {
+            UNUSED_PARAM(marker);
+            UNUSED_PARAM(strokeWidth);
+
+            // FIXME: [LBSE] Upstream RenderLayer changes
+            // ASSERT(marker->hasLayer());
+            // GraphicsContextStateSaver stateSaver(paintInfo.context());
+            // auto contentTransform = marker->markerTransformation(m_markerPositions[i].origin, m_markerPositions[i].angle, strokeWidth);
+            // marker->layer()->paintSVGResourceLayer(paintInfo.context(), LayoutRect::infiniteRect(), contentTransform);
+        }
+    }
+}
+
+std::unique_ptr<Path> RenderSVGShape::createPath() const
+{
+    return makeUnique<Path>(pathFromGraphicsElement(&graphicsElement()));
+}
+
+void RenderSVGShape::processMarkerPositions()
+{
+    m_markerPositions.clear();
+
+    if (!shouldGenerateMarkerPositions())
+        return;
+
+    ASSERT(m_path);
+
+    SVGMarkerData markerData(m_markerPositions, SVGResourcesCache::cachedResourcesForRenderer(*this)->markerReverseStart());
+    m_path->apply([&markerData](const PathElement& pathElement) {
+        SVGMarkerData::updateFromPathElement(markerData, pathElement);
+    });
+    markerData.pathIsDone();
+}
+
+void RenderSVGShape::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
+{
+    auto* oldStyle = hasInitializedStyle() ? &style() : nullptr;
+    if (oldStyle) {
+        if (diff == StyleDifference::Layout)
+            setNeedsShapeUpdate();
+    }
+
+    RenderSVGModelObject::styleWillChange(diff, newStyle);
+}
+
+}
+
+#endif // ENABLE(LAYER_BASED_SVG_ENGINE)

Added: trunk/Source/WebCore/rendering/svg/RenderSVGShape.h (0 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShape.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShape.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <[email protected]>
+ * Copyright (C) 2004, 2005 Rob Buis <[email protected]>
+ * Copyright (C) 2005 Eric Seidel <[email protected]>
+ * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2009 Google, Inc.
+ * Copyright (C) 2011 Renata Hodovan <[email protected]>
+ * Copyright (C) 2011 University of Szeged
+ * Copyright (C) 2020, 2021, 2022 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+#include "AffineTransform.h"
+#include "FloatRect.h"
+#include "RenderSVGModelObject.h"
+// FIXME: [LBSE] Upstream SVGBoundingBoxComputation
+// #include "SVGBoundingBoxComputation.h"
+#include "SVGGraphicsElement.h"
+#include "SVGMarkerData.h"
+#include <memory>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FloatPoint;
+class GraphicsContextStateSaver;
+class RenderSVGContainer;
+class RenderSVGPath;
+class RenderSVGResource;
+class SVGGraphicsElement;
+
+class RenderSVGShape : public RenderSVGModelObject {
+    WTF_MAKE_ISO_ALLOCATED(RenderSVGShape);
+public:
+    enum PointCoordinateSpace {
+        GlobalCoordinateSpace,
+        LocalCoordinateSpace
+    };
+    RenderSVGShape(SVGGraphicsElement&, RenderStyle&&);
+    virtual ~RenderSVGShape();
+
+    inline SVGGraphicsElement& graphicsElement() const;
+
+    void setNeedsShapeUpdate() { m_needsShapeUpdate = true; }
+
+    virtual void fillShape(GraphicsContext&) const;
+    virtual void strokeShape(GraphicsContext&) const;
+    virtual bool isRenderingDisabled() const = 0;
+
+    bool isPointInFill(const FloatPoint&);
+    bool isPointInStroke(const FloatPoint&);
+
+    float getTotalLength() const;
+    FloatPoint getPointAtLength(float distance) const;
+
+    bool hasPath() const { return m_path.get(); }
+    Path& path() const
+    {
+        ASSERT(m_path);
+        return *m_path;
+    }
+    void clearPath() { m_path = nullptr; }
+
+    FloatRect objectBoundingBox() const final { return m_fillBoundingBox; }
+    FloatRect strokeBoundingBox() const final { return m_strokeBoundingBox; }
+
+    FloatRect repaintRectInLocalCoordinates() const final
+    {
+        // FIXME: [LBSE] Upstream SVGBoundingBoxComputation
+        // return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this); }
+        return FloatRect();
+    }
+
+    FloatRect computeMarkerBoundingBox() const;
+
+protected:
+    void element() const = delete;
+
+    virtual void updateShapeFromElement();
+    virtual bool isEmpty() const;
+    virtual bool shapeDependentStrokeContains(const FloatPoint&, PointCoordinateSpace = GlobalCoordinateSpace);
+    virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
+    float strokeWidth() const;
+    bool hasSmoothStroke() const;
+
+    bool hasNonScalingStroke() const { return style().svgStyle().vectorEffect() == VectorEffect::NonScalingStroke; }
+    AffineTransform nonScalingStrokeTransform() const;
+    Path* nonScalingStrokePath(const Path*, const AffineTransform&) const;
+
+    FloatRect m_fillBoundingBox;
+    FloatRect m_strokeBoundingBox;
+
+private:
+    // Hit-detection separated for the fill and the stroke
+    bool fillContains(const FloatPoint&, bool requiresFill = true, const WindRule fillRule = WindRule::NonZero);
+    bool strokeContains(const FloatPoint&, bool requiresStroke = true);
+
+    bool isSVGShape() const final { return true; }
+    bool canHaveChildren() const final { return false; }
+    const char* renderName() const override { return "RenderSVGShape"; }
+
+    void layout() final;
+    void paint(PaintInfo&, const LayoutPoint&) final;
+
+    bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
+
+    FloatRect calculateObjectBoundingBox() const;
+    FloatRect calculateStrokeBoundingBox() const;
+
+    bool setupNonScalingStrokeContext(AffineTransform&, GraphicsContextStateSaver&);
+
+    bool shouldGenerateMarkerPositions() const;
+    
+    std::unique_ptr<Path> createPath() const;
+    void processMarkerPositions();
+
+    void fillShape(const RenderStyle&, GraphicsContext&);
+    void strokeShape(const RenderStyle&, GraphicsContext&);
+    void strokeShape(GraphicsContext&);
+    void fillStrokeMarkers(PaintInfo&);
+    void drawMarkers(PaintInfo&);
+
+    void styleWillChange(StyleDifference, const RenderStyle& newStyle) override;
+
+private:
+    bool m_needsShapeUpdate { true };
+
+    std::unique_ptr<Path> m_path;
+    Vector<MarkerPosition> m_markerPositions;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGShape, isSVGShape())
+
+#endif // ENABLE(LAYER_BASED_SVG_ENGINE)

Added: trunk/Source/WebCore/rendering/svg/RenderSVGShapeInlines.h (0 => 287832)


--- trunk/Source/WebCore/rendering/svg/RenderSVGShapeInlines.h	                        (rev 0)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGShapeInlines.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+#include "RenderSVGShape.h"
+#include "SVGGraphicsElement.h"
+
+namespace WebCore {
+
+inline SVGGraphicsElement& RenderSVGShape::graphicsElement() const
+{
+    return downcast<SVGGraphicsElement>(RenderSVGModelObject::element());
+}
+
+} // namespace WebCore
+
+#endif // LAYER_BASED_SVG_ENGINE

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -29,6 +29,7 @@
 
 #include "ElementAncestorIterator.h"
 #include "LegacyRenderSVGRoot.h"
+#include "LegacyRenderSVGShape.h"
 #include "NodeRenderStyle.h"
 #include "RenderChildIterator.h"
 #include "RenderElement.h"

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -49,6 +49,7 @@
 #include "RenderSVGResourceRadialGradientInlines.h"
 #include "RenderSVGResourceSolidColor.h"
 #include "RenderSVGRoot.h"
+#include "RenderSVGShapeInlines.h"
 #include "RenderSVGText.h"
 #include "SVGCircleElement.h"
 #include "SVGElementTypeHelpers.h"
@@ -151,27 +152,73 @@
     return ts;
 }
 
-static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource)
+static void writeSVGPaintingResource(TextStream& ts, const RenderSVGResource& resource)
 {
-    if (resource->resourceType() == SolidColorResourceType) {
-        ts << "[type=SOLID] [color=" << static_cast<RenderSVGResourceSolidColor*>(resource)->color() << "]";
+    auto resourceType = resource.resourceType();
+    if (resourceType == SolidColorResourceType) {
+        ts << "[type=SOLID] [color=" << downcast<RenderSVGResourceSolidColor>(resource).color() << "]";
         return;
     }
 
-    // All other resources derive from RenderSVGResourceContainer
-    RenderSVGResourceContainer* container = static_cast<RenderSVGResourceContainer*>(resource);
-    SVGElement& element = container->element();
-
-    if (resource->resourceType() == PatternResourceType)
+    if (resourceType == PatternResourceType)
         ts << "[type=PATTERN]";
-    else if (resource->resourceType() == LinearGradientResourceType)
+    else if (resourceType == LinearGradientResourceType)
         ts << "[type=LINEAR-GRADIENT]";
-    else if (resource->resourceType() == RadialGradientResourceType)
+    else if (resourceType == RadialGradientResourceType)
         ts << "[type=RADIAL-GRADIENT]";
 
-    ts << " [id=\"" << element.getIdAttribute() << "\"]";
+    // All other resources derive from RenderSVGResourceContainer
+    const auto& container = static_cast<const RenderSVGResourceContainer&>(resource);
+    ts << " [id=\"" << container.element().getIdAttribute() << "\"]";
 }
 
+static void writeSVGFillPaintingResource(TextStream& ts, const RenderElement& renderer, const RenderSVGResource& fillPaintingResource)
+{
+    TextStreamSeparator s(" ");
+    ts << " [fill={" << s;
+    writeSVGPaintingResource(ts, fillPaintingResource);
+
+    const auto& svgStyle = renderer.style().svgStyle();
+    writeIfNotDefault(ts, "opacity", svgStyle.fillOpacity(), 1.0f);
+    writeIfNotDefault(ts, "fill rule", svgStyle.fillRule(), WindRule::NonZero);
+    ts << "}]";
+}
+
+static void writeSVGStrokePaintingResource(TextStream& ts, const RenderElement& renderer, const RenderSVGResource& strokePaintingResource, const SVGGraphicsElement& shape)
+{
+    TextStreamSeparator s(" ");
+    ts << " [stroke={" << s;
+    writeSVGPaintingResource(ts, strokePaintingResource);
+
+    const auto& style = renderer.style();
+    const auto& svgStyle = style.svgStyle();
+
+    SVGLengthContext lengthContext(&shape);
+    double dashOffset = lengthContext.valueForLength(svgStyle.strokeDashOffset());
+    double strokeWidth = lengthContext.valueForLength(style.strokeWidth());
+    const auto& dashes = svgStyle.strokeDashArray();
+
+    DashArray dashArray;
+    for (auto& length : dashes)
+        dashArray.append(length.value(lengthContext));
+
+    writeIfNotDefault(ts, "opacity", svgStyle.strokeOpacity(), 1.0f);
+    writeIfNotDefault(ts, "stroke width", strokeWidth, 1.0);
+    writeIfNotDefault(ts, "miter limit", style.strokeMiterLimit(), 4.0f);
+    writeIfNotDefault(ts, "line cap", style.capStyle(), LineCap::Butt);
+    writeIfNotDefault(ts, "line join", style.joinStyle(), LineJoin::Miter);
+    writeIfNotDefault(ts, "dash offset", dashOffset, 0.0);
+    if (!dashArray.isEmpty())
+        writeNameValuePair(ts, "dash array", dashArray);
+
+    if (is<SVGGeometryElement>(shape)) {
+        double pathLength = downcast<SVGGeometryElement>(shape).pathLength();
+        writeIfNotDefault(ts, "path length", pathLength, 0.0);
+    }
+
+    ts << "}]";
+}
+
 static void writeStyle(TextStream& ts, const RenderElement& renderer)
 {
     const RenderStyle& style = renderer.style();
@@ -181,52 +228,34 @@
         writeNameValuePair(ts, "transform", renderer.localTransform());
     writeIfNotDefault(ts, "image rendering", style.imageRendering(), RenderStyle::initialImageRendering());
     writeIfNotDefault(ts, "opacity", style.opacity(), RenderStyle::initialOpacity());
+
     if (is<LegacyRenderSVGShape>(renderer)) {
         const auto& shape = downcast<LegacyRenderSVGShape>(renderer);
 
         Color fallbackColor;
-        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<LegacyRenderSVGShape&>(shape), shape.style(), fallbackColor)) {
-            TextStreamSeparator s(" ");
-            ts << " [stroke={" << s;
-            writeSVGPaintingResource(ts, strokePaintingResource);
+        if (auto* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<LegacyRenderSVGShape&>(shape), shape.style(), fallbackColor))
+            writeSVGStrokePaintingResource(ts, renderer, *strokePaintingResource, shape.graphicsElement());
 
-            SVGLengthContext lengthContext(&shape.graphicsElement());
-            double dashOffset = lengthContext.valueForLength(svgStyle.strokeDashOffset());
-            double strokeWidth = lengthContext.valueForLength(style.strokeWidth());
-            const auto& dashes = svgStyle.strokeDashArray();
+        if (auto* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<LegacyRenderSVGShape&>(shape), shape.style(), fallbackColor))
+            writeSVGFillPaintingResource(ts, renderer, *fillPaintingResource);
 
-            DashArray dashArray;
-            for (auto& length : dashes)
-                dashArray.append(length.value(lengthContext));
+        writeIfNotDefault(ts, "clip rule", svgStyle.clipRule(), WindRule::NonZero);
+    }
 
-            writeIfNotDefault(ts, "opacity", svgStyle.strokeOpacity(), 1.0f);
-            writeIfNotDefault(ts, "stroke width", strokeWidth, 1.0);
-            writeIfNotDefault(ts, "miter limit", style.strokeMiterLimit(), 4.0f);
-            writeIfNotDefault(ts, "line cap", style.capStyle(), LineCap::Butt);
-            writeIfNotDefault(ts, "line join", style.joinStyle(), LineJoin::Miter);
-            writeIfNotDefault(ts, "dash offset", dashOffset, 0.0);
-            if (!dashArray.isEmpty())
-                writeNameValuePair(ts, "dash array", dashArray);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    else if (is<LegacyRenderSVGShape>(renderer)) {
+        const auto& shape = downcast<RenderSVGShape>(renderer);
 
-            if (is<SVGGeometryElement>(shape.graphicsElement())) {
-                double pathLength = downcast<SVGGeometryElement>(shape.graphicsElement()).pathLength();
-                writeIfNotDefault(ts, "path length", pathLength, 0.0);
-            }
+        Color fallbackColor;
+        if (auto* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape&>(shape), shape.style(), fallbackColor))
+            writeSVGStrokePaintingResource(ts, renderer, *strokePaintingResource, shape.graphicsElement());
 
-            ts << "}]";
-        }
+        if (auto* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape&>(shape), shape.style(), fallbackColor))
+            writeSVGFillPaintingResource(ts, renderer, *fillPaintingResource);
 
-        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<LegacyRenderSVGShape&>(shape), shape.style(), fallbackColor)) {
-            TextStreamSeparator s(" ");
-            ts << " [fill={" << s;
-            writeSVGPaintingResource(ts, fillPaintingResource);
-
-            writeIfNotDefault(ts, "opacity", svgStyle.fillOpacity(), 1.0f);
-            writeIfNotDefault(ts, "fill rule", svgStyle.fillRule(), WindRule::NonZero);
-            ts << "}]";
-        }
         writeIfNotDefault(ts, "clip rule", svgStyle.clipRule(), WindRule::NonZero);
     }
+#endif
 
     writeIfNotEmpty(ts, "start marker", svgStyle.markerStartResource());
     writeIfNotEmpty(ts, "middle marker", svgStyle.markerMidResource());
@@ -250,11 +279,8 @@
     return ts;
 }
 
-static TextStream& operator<<(TextStream& ts, const LegacyRenderSVGShape& shape)
+static void writeSVGGraphicsElement(TextStream& ts, SVGGraphicsElement& svgElement)
 {
-    writePositionAndStyle(ts, shape);
-
-    SVGGraphicsElement& svgElement = shape.graphicsElement();
     SVGLengthContext lengthContext(&svgElement);
 
     if (is<SVGRectElement>(svgElement)) {
@@ -291,9 +317,24 @@
         writeNameAndQuotedValue(ts, "data", pathString);
     } else
         ASSERT_NOT_REACHED();
+}
+
+static TextStream& operator<<(TextStream& ts, const LegacyRenderSVGShape& shape)
+{
+    writePositionAndStyle(ts, shape);
+    writeSVGGraphicsElement(ts, shape.graphicsElement());
     return ts;
 }
 
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
+{
+    writePositionAndStyle(ts, shape);
+    writeSVGGraphicsElement(ts, shape.graphicsElement());
+    return ts;
+}
+#endif
+
 static void writeRenderSVGTextBox(TextStream& ts, const RenderSVGText& text)
 {
     auto* box = downcast<SVGRootInlineBox>(text.firstRootBox());
@@ -551,6 +592,15 @@
     writeResources(ts, image, behavior);
 }
 
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+void write(TextStream& ts, const RenderSVGShape& shape, OptionSet<RenderAsTextFlag> behavior)
+{
+    writeStandardPrefix(ts, shape, behavior);
+    ts << shape << "\n";
+    writeResources(ts, shape, behavior);
+}
+#endif
+
 void write(TextStream& ts, const LegacyRenderSVGShape& shape, OptionSet<RenderAsTextFlag> behavior)
 {
     writeStandardPrefix(ts, shape, behavior);

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h (287831 => 287832)


--- trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h	2022-01-10 09:47:29 UTC (rev 287832)
@@ -45,15 +45,17 @@
 class RenderSVGInlineText;
 class RenderSVGResourceContainer;
 class RenderSVGRoot;
+class RenderSVGShape;
 class RenderSVGText;
 class SVGUnitTypes;
 
 // functions used by the main RenderTreeAsText code
 void write(WTF::TextStream&, const LegacyRenderSVGRoot&, OptionSet<RenderAsTextFlag>);
+void write(WTF::TextStream&, const LegacyRenderSVGShape&, OptionSet<RenderAsTextFlag>);
 #if ENABLE(LAYER_BASED_SVG_ENGINE)
 void write(WTF::TextStream&, const RenderSVGRoot&, OptionSet<RenderAsTextFlag>);
+void write(WTF::TextStream&, const RenderSVGShape&, OptionSet<RenderAsTextFlag>);
 #endif
-void write(WTF::TextStream&, const LegacyRenderSVGShape&, OptionSet<RenderAsTextFlag>);
 void writeSVGGradientStop(WTF::TextStream&, const RenderSVGGradientStop&, OptionSet<RenderAsTextFlag>);
 void writeSVGResourceContainer(WTF::TextStream&, const RenderSVGResourceContainer&, OptionSet<RenderAsTextFlag>);
 void writeSVGContainer(WTF::TextStream&, const RenderSVGContainer&, OptionSet<RenderAsTextFlag>);

Modified: trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp (287831 => 287832)


--- trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/svg/SVGAnimateMotionElement.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -25,6 +25,7 @@
 #include "AffineTransform.h"
 #include "ElementIterator.h"
 #include "PathTraversalState.h"
+#include "RenderElement.h"
 #include "RenderSVGResource.h"
 #include "SVGElementTypeHelpers.h"
 #include "SVGImageElement.h"

Modified: trunk/Source/WebCore/svg/SVGGeometryElement.cpp (287831 => 287832)


--- trunk/Source/WebCore/svg/SVGGeometryElement.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/svg/SVGGeometryElement.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -26,6 +26,7 @@
 #include "DOMPoint.h"
 #include "LegacyRenderSVGShape.h"
 #include "RenderSVGResource.h"
+#include "RenderSVGShape.h"
 #include "SVGDocumentExtensions.h"
 #include "SVGPathUtilities.h"
 #include "SVGPoint.h"
@@ -48,11 +49,20 @@
 {
     document().updateLayoutIgnorePendingStylesheets();
 
-    auto* renderer = downcast<LegacyRenderSVGShape>(this->renderer());
+    auto* renderer = this->renderer();
     if (!renderer)
         return 0;
 
-    return renderer->getTotalLength();
+    if (is<LegacyRenderSVGShape>(renderer))
+        return downcast<LegacyRenderSVGShape>(renderer)->getTotalLength();
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    if (is<RenderSVGShape>(renderer))
+        return downcast<RenderSVGShape>(renderer)->getTotalLength();
+#endif
+
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 ExceptionOr<Ref<SVGPoint>> SVGGeometryElement::getPointAtLength(float distance) const
@@ -59,17 +69,26 @@
 {
     document().updateLayoutIgnorePendingStylesheets();
 
-    auto* renderer = downcast<LegacyRenderSVGShape>(this->renderer());
-    
+    auto* renderer = this->renderer();
+
     // Spec: If current element is a non-rendered element, throw an InvalidStateError.
     if (!renderer)
         return Exception { InvalidStateError };
-    
+
     // Spec: Clamp distance to [0, length].
     distance = clampTo<float>(distance, 0, getTotalLength());
 
     // Spec: Return a newly created, detached SVGPoint object.
-    return SVGPoint::create(renderer->getPointAtLength(distance));
+    if (is<LegacyRenderSVGShape>(renderer))
+        return SVGPoint::create(downcast<LegacyRenderSVGShape>(renderer)->getPointAtLength(distance));
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    if (is<RenderSVGShape>(renderer))
+        return SVGPoint::create(downcast<RenderSVGShape>(renderer)->getPointAtLength(distance));
+#endif
+
+    ASSERT_NOT_REACHED();
+    return Exception { InvalidStateError };
 }
 
 bool SVGGeometryElement::isPointInFill(DOMPointInit&& pointInit)
@@ -76,12 +95,21 @@
 {
     document().updateLayoutIgnorePendingStylesheets();
 
-    auto* renderer = downcast<LegacyRenderSVGShape>(this->renderer());
+    auto* renderer = this->renderer();
     if (!renderer)
         return false;
 
     FloatPoint point {static_cast<float>(pointInit.x), static_cast<float>(pointInit.y)};
-    return renderer->isPointInFill(point);
+    if (is<LegacyRenderSVGShape>(renderer))
+        return downcast<LegacyRenderSVGShape>(renderer)->isPointInFill(point);
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    if (is<RenderSVGShape>(renderer))
+        return downcast<RenderSVGShape>(renderer)->isPointInFill(point);
+#endif
+
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
 bool SVGGeometryElement::isPointInStroke(DOMPointInit&& pointInit)
@@ -88,12 +116,21 @@
 {
     document().updateLayoutIgnorePendingStylesheets();
 
-    auto* renderer = downcast<LegacyRenderSVGShape>(this->renderer());
+    auto* renderer = this->renderer();
     if (!renderer)
         return false;
 
     FloatPoint point {static_cast<float>(pointInit.x), static_cast<float>(pointInit.y)};
-    return renderer->isPointInStroke(point);
+    if (is<LegacyRenderSVGShape>(renderer))
+        return downcast<LegacyRenderSVGShape>(renderer)->isPointInStroke(point);
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+    if (is<RenderSVGShape>(renderer))
+        return downcast<RenderSVGShape>(renderer)->isPointInStroke(point);
+#endif
+
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
 void SVGGeometryElement::parseAttribute(const QualifiedName& name, const AtomString& value)

Modified: trunk/Source/WebCore/svg/SVGLineElement.cpp (287831 => 287832)


--- trunk/Source/WebCore/svg/SVGLineElement.cpp	2022-01-10 08:45:56 UTC (rev 287831)
+++ trunk/Source/WebCore/svg/SVGLineElement.cpp	2022-01-10 09:47:29 UTC (rev 287832)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "SVGLineElement.h"
 
+#include "LegacyRenderSVGShape.h"
 #include "RenderSVGResource.h"
 #include "SVGLengthValue.h"
 #include <wtf/IsoMallocInlines.h>
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to