Title: [233835] trunk
Revision
233835
Author
k...@webkit.org
Date
2018-07-14 02:19:46 -0700 (Sat, 14 Jul 2018)

Log Message

[css-masking] Fully support -webkit-clip-path on SVG elements
https://bugs.webkit.org/show_bug.cgi?id=185829

Reviewed by Simon Fraser.

Source/WebCore:

-webkit-clip-path contributes to SVG elements with boxes, shapes and now with
element references to <clipPath> elements as well. Make sure that all types
contribute to hit-testing of the SVG element as well as they should.

Tests: svg/clip-path/webkit-clip-path-after-expected.svg
       svg/clip-path/webkit-clip-path-after.svg
       svg/clip-path/webkit-clip-path-before-expected.svg
       svg/clip-path/webkit-clip-path-before.svg
       svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html
       svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html
       svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html
       svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html

* rendering/svg/SVGRenderSupport.cpp: Share code as much as possible.
(WebCore::clipPathReferenceBox):
(WebCore::isPointInCSSClippingArea): Take -webkit-clip-path into account.
(WebCore::SVGRenderSupport::clipContextToCSSClippingArea):
(WebCore::SVGRenderSupport::pointInClippingArea):
* rendering/svg/SVGRenderSupport.h:
* rendering/svg/SVGRenderingContext.cpp: Clip to -webkit-clip-path boxes, shapes and references.
(WebCore::SVGRenderingContext::prepareToRenderSVGContent):
* rendering/svg/SVGResources.cpp: Add -webkit-clip-path references to cached resources. Mimic SVG clip-path.
(WebCore::SVGResources::buildCachedResources):

LayoutTests:

Test -webkit-clip-path element references on SVG elements. Make sure, -webkit-clip-path
contributes to hit testing for element references and basic shapes.

* svg/clip-path/webkit-clip-path-after-expected.svg: Added.
* svg/clip-path/webkit-clip-path-after.svg: Added.
* svg/clip-path/webkit-clip-path-before-expected.svg: Added.
* svg/clip-path/webkit-clip-path-before.svg: Added.
* svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting-expected.txt: Added.
* svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html: Added.
* svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting-expected.txt: Added.
* svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html: Added.
* svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting-expected.txt: Added.
* svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html: Added.
* svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting-expected.txt: Added.
* svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (233834 => 233835)


--- trunk/LayoutTests/ChangeLog	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/LayoutTests/ChangeLog	2018-07-14 09:19:46 UTC (rev 233835)
@@ -1,3 +1,26 @@
+2018-07-14  Dirk Schulze  <k...@webkit.org>
+
+        [css-masking] Fully support -webkit-clip-path on SVG elements
+        https://bugs.webkit.org/show_bug.cgi?id=185829
+
+        Reviewed by Simon Fraser.
+
+        Test -webkit-clip-path element references on SVG elements. Make sure, -webkit-clip-path
+        contributes to hit testing for element references and basic shapes.
+
+        * svg/clip-path/webkit-clip-path-after-expected.svg: Added.
+        * svg/clip-path/webkit-clip-path-after.svg: Added.
+        * svg/clip-path/webkit-clip-path-before-expected.svg: Added.
+        * svg/clip-path/webkit-clip-path-before.svg: Added.
+        * svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting-expected.txt: Added.
+        * svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html: Added.
+        * svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting-expected.txt: Added.
+        * svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html: Added.
+        * svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting-expected.txt: Added.
+        * svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html: Added.
+        * svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting-expected.txt: Added.
+        * svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html: Added.
+
 2018-07-13  Ryan Haddad  <ryanhad...@apple.com>
 
         Add TestExpectations and baselines for iOS 12

Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (233834 => 233835)


--- trunk/LayoutTests/platform/ios-wk2/TestExpectations	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations	2018-07-14 09:19:46 UTC (rev 233835)
@@ -251,6 +251,10 @@
 svg/dynamic-updates/SVGAElement-svgdom-target-prop.html
 svg/dynamic-updates/SVGClipPath-influences-hitTesting.html
 svg/dynamic-updates/SVGClipPathElement-css-transform-influences-hitTesting.html
+svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html
+svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html
+svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html
+svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html
 svg/dynamic-updates/SVGClipPathElement-transform-influences-hitTesting.html
 svg/custom/linking-a-03-b-all.svg
 

Added: trunk/LayoutTests/svg/clip-path/webkit-clip-path-after-expected.svg (0 => 233835)


--- trunk/LayoutTests/svg/clip-path/webkit-clip-path-after-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/webkit-clip-path-after-expected.svg	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<circle cx="100" cy="100" r="100" fill="green"/>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/clip-path/webkit-clip-path-after.svg (0 => 233835)


--- trunk/LayoutTests/svg/clip-path/webkit-clip-path-after.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/webkit-clip-path-after.svg	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: url(#clip1)"/>
+<clipPath id="clip1">
+  <circle cx="100" cy="100" r="100"/>
+</clipPath>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/clip-path/webkit-clip-path-before-expected.svg (0 => 233835)


--- trunk/LayoutTests/svg/clip-path/webkit-clip-path-before-expected.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/webkit-clip-path-before-expected.svg	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<circle cx="100" cy="100" r="100" fill="green"/>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/clip-path/webkit-clip-path-before.svg (0 => 233835)


--- trunk/LayoutTests/svg/clip-path/webkit-clip-path-before.svg	                        (rev 0)
+++ trunk/LayoutTests/svg/clip-path/webkit-clip-path-before.svg	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg">
+<clipPath id="clip1">
+  <circle cx="100" cy="100" r="100"/>
+</clipPath>
+<rect width="200" height="200" fill="green" style="-webkit-clip-path: url(#clip1)"/>
+</svg>
\ No newline at end of file

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting-expected.txt (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting-expected.txt	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,12 @@
+SVG 1.1 dynamic update tests
+
+Tests hitTesting on clipped Elements. Clipped areas shouldn't throw a hit.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Hit thrown on not clipped area of rect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runRepaintTest()">
+<h1>SVG 1.1 dynamic update tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+// [Name] SVGClipPathElement-svgdom-clipPathUnits-prop.js
+// [Expected rendering result] green circle - and a series of PASS messages
+
+description("Tests hitTesting on clipped Elements. Clipped areas shouldn't throw a hit.")
+createSVGTestCase();
+
+var defsElement = createSVGElement("defs");
+rootSVGElement.appendChild(defsElement);
+
+var clipPathElement = createSVGElement("clipPath");
+clipPathElement.setAttribute("id", "clipper");
+
+var clipRectElement = createSVGElement("rect");
+clipRectElement.setAttribute("width", "50");
+clipRectElement.setAttribute("height", "100");
+clipPathElement.appendChild(clipRectElement);
+
+defsElement.appendChild(clipPathElement);
+
+var backgroundRect = createSVGElement("rect");
+backgroundRect.setAttribute("width", "100");
+backgroundRect.setAttribute("height", "100");
+backgroundRect.setAttribute("fill", "green");
+backgroundRect.setAttribute("onclick", "testPassed('Hit thrown on not clipped area of rect.'); completeTest()");
+rootSVGElement.appendChild(backgroundRect);
+
+var foregroundRect = createSVGElement("rect");
+foregroundRect.setAttribute("width", "100");
+foregroundRect.setAttribute("height", "100");
+foregroundRect.setAttribute("fill", "green");
+foregroundRect.setAttribute("style", "-webkit-clip-path: url(#clipper)");
+foregroundRect.setAttribute("onclick", "testFailed('Clipped are of rect throw a hit'); completeTest();");
+rootSVGElement.appendChild(foregroundRect);
+
+// Two rects are drawn. One in the background and one in the foreground. The rect
+// in the foreground gets clipped, so on hittesting, the background rect should
+// throw a hit.
+function repaintTest() {
+    clickAt(75, 50);
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting-expected.txt (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting-expected.txt	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,12 @@
+SVG 1.1 dynamic update tests
+
+Tests hitTesting on clipped Elements. Clipped areas shouldn't throw a hit.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Hit thrown on not clipped area of rect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runRepaintTest()">
+<h1>SVG 1.1 dynamic update tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+// [Name] SVGClipPathElement-svgdom-clipPathUnits-prop.js
+// [Expected rendering result] green circle - and a series of PASS messages
+
+description("Tests hitTesting on clipped Elements. Clipped areas shouldn't throw a hit.")
+createSVGTestCase();
+
+var backgroundRect = createSVGElement("rect");
+backgroundRect.setAttribute("width", "100");
+backgroundRect.setAttribute("height", "100");
+backgroundRect.setAttribute("fill", "green");
+backgroundRect.setAttribute("onclick", "testPassed('Hit thrown on not clipped area of rect.'); completeTest()");
+rootSVGElement.appendChild(backgroundRect);
+
+var foregroundRect = createSVGElement("rect");
+foregroundRect.setAttribute("width", "100");
+foregroundRect.setAttribute("height", "100");
+foregroundRect.setAttribute("fill", "green");
+foregroundRect.setAttribute("style", "-webkit-clip-path: path('M0,0L50,0L50,100L0,100z')");
+foregroundRect.setAttribute("onclick", "testFailed('Clipped are of rect throw a hit'); completeTest();");
+rootSVGElement.appendChild(foregroundRect);
+
+// Two rects are drawn. One in the background and one in the foreground. The rect
+// in the foreground gets clipped, so on hittesting, the background rect should
+// throw a hit.
+function repaintTest() {
+    clickAt(75, 50);
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting-expected.txt (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting-expected.txt	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,12 @@
+SVG 1.1 dynamic update tests
+
+Tests hitTesting on clipped Elements. Clip-path gets CSS transformed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Hit thrown on not clipped area of rect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runRepaintTest()">
+<h1>SVG 1.1 dynamic update tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+// [Name] SVGClipPathElement-transform-influences-hitTesting.js
+// [Expected rendering result] green circle - and a series of PASS messages
+
+description("Tests hitTesting on clipped Elements. Clip-path gets CSS transformed.")
+createSVGTestCase();
+
+var defsElement = createSVGElement("defs");
+rootSVGElement.appendChild(defsElement);
+
+var clipPathElement = createSVGElement("clipPath");
+clipPathElement.setAttribute("id", "clipper");
+
+var clipRectElement = createSVGElement("rect");
+clipRectElement.setAttribute("width", "5");
+clipRectElement.setAttribute("height", "5");
+clipRectElement.setAttribute("style", "-webkit-transform: scale(20)");
+clipPathElement.appendChild(clipRectElement);
+
+defsElement.appendChild(clipPathElement);
+
+var foregroundRect = createSVGElement("rect");
+foregroundRect.setAttribute("width", "100");
+foregroundRect.setAttribute("height", "100");
+foregroundRect.setAttribute("fill", "green");
+foregroundRect.setAttribute("style", "-webkit-clip-path: url(#clipper)");
+foregroundRect.setAttribute("onclick", "testPassed('Hit thrown on not clipped area of rect.'); completeTest();");
+rootSVGElement.appendChild(foregroundRect);
+
+// The clipPath gets scaled by 20. This should influence the hit testing,
+// since the area of the clipped content is affected as well. 
+function repaintTest() {
+    clickAt(75, 50);
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting-expected.txt (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting-expected.txt	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,12 @@
+SVG 1.1 dynamic update tests
+
+Tests hitTesting on clipped Elements. Clip-path gets transformed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Hit thrown on not clipped area of rect.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html (0 => 233835)


--- trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html	                        (rev 0)
+++ trunk/LayoutTests/svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html	2018-07-14 09:19:46 UTC (rev 233835)
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body _onload_="runRepaintTest()">
+<h1>SVG 1.1 dynamic update tests</h1>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+// [Name] SVGClipPathElement-transform-influences-hitTesting.js
+// [Expected rendering result] green circle - and a series of PASS messages
+
+description("Tests hitTesting on clipped Elements. Clip-path gets transformed.")
+createSVGTestCase();
+
+var defsElement = createSVGElement("defs");
+rootSVGElement.appendChild(defsElement);
+
+var clipPathElement = createSVGElement("clipPath");
+clipPathElement.setAttribute("id", "clipper");
+
+var clipRectElement = createSVGElement("rect");
+clipRectElement.setAttribute("width", "5");
+clipRectElement.setAttribute("height", "5");
+clipRectElement.setAttribute("transform", "scale(20)");
+clipPathElement.appendChild(clipRectElement);
+
+defsElement.appendChild(clipPathElement);
+
+var foregroundRect = createSVGElement("rect");
+foregroundRect.setAttribute("width", "100");
+foregroundRect.setAttribute("height", "100");
+foregroundRect.setAttribute("fill", "green");
+foregroundRect.setAttribute("style", "-webkit-clip-path: url(#clipper)");
+foregroundRect.setAttribute("onclick", "testPassed('Hit thrown on not clipped area of rect.'); completeTest();");
+rootSVGElement.appendChild(foregroundRect);
+
+// The clipPath gets scaled by 20. This should influence the hit testing,
+// since the area of the clipped content is affected as well. 
+function repaintTest() {
+    clickAt(75, 50);
+}
+
+var successfullyParsed = true;
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (233834 => 233835)


--- trunk/Source/WebCore/ChangeLog	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/Source/WebCore/ChangeLog	2018-07-14 09:19:46 UTC (rev 233835)
@@ -1,3 +1,34 @@
+2018-07-14  Dirk Schulze  <k...@webkit.org>
+
+        [css-masking] Fully support -webkit-clip-path on SVG elements
+        https://bugs.webkit.org/show_bug.cgi?id=185829
+
+        Reviewed by Simon Fraser.
+
+        -webkit-clip-path contributes to SVG elements with boxes, shapes and now with
+        element references to <clipPath> elements as well. Make sure that all types
+        contribute to hit-testing of the SVG element as well as they should.
+
+        Tests: svg/clip-path/webkit-clip-path-after-expected.svg
+               svg/clip-path/webkit-clip-path-after.svg
+               svg/clip-path/webkit-clip-path-before-expected.svg
+               svg/clip-path/webkit-clip-path-before.svg
+               svg/dynamic-updates/SVGClipPath-prefixed-influences-hitTesting.html
+               svg/dynamic-updates/SVGClipPath-prefixed-path-influences-hitTesting.html
+               svg/dynamic-updates/SVGClipPathElement-prefixed-css-transform-influences-hitTesting.html
+               svg/dynamic-updates/SVGClipPathElement-prefixed-transform-influences-hitTesting.html
+
+        * rendering/svg/SVGRenderSupport.cpp: Share code as much as possible.
+        (WebCore::clipPathReferenceBox):
+        (WebCore::isPointInCSSClippingArea): Take -webkit-clip-path into account.
+        (WebCore::SVGRenderSupport::clipContextToCSSClippingArea):
+        (WebCore::SVGRenderSupport::pointInClippingArea):
+        * rendering/svg/SVGRenderSupport.h:
+        * rendering/svg/SVGRenderingContext.cpp: Clip to -webkit-clip-path boxes, shapes and references.
+        (WebCore::SVGRenderingContext::prepareToRenderSVGContent):
+        * rendering/svg/SVGResources.cpp: Add -webkit-clip-path references to cached resources. Mimic SVG clip-path.
+        (WebCore::SVGResources::buildCachedResources):
+
 2018-07-13  Simon Fraser  <simon.fra...@apple.com>
 
         Avoid fetching visitedDependentColor() so many times in editing code

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp (233834 => 233835)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp	2018-07-14 09:19:46 UTC (rev 233835)
@@ -5,6 +5,7 @@
  * Copyright (C) 2009 Google, Inc.  All rights reserved.
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2018 Adobe Systems Incorporated. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -404,8 +405,76 @@
     return true;
 }
 
+inline FloatRect clipPathReferenceBox(const RenderElement& renderer, CSSBoxType boxType)
+{
+    FloatRect referenceBox;
+    switch (boxType) {
+    case CSSBoxType::BorderBox:
+    case CSSBoxType::MarginBox:
+    case CSSBoxType::StrokeBox:
+        // FIXME: strokeBoundingBox() takes dasharray into account but shouldn't.
+        referenceBox = renderer.strokeBoundingBox();
+        break;
+    case CSSBoxType::ViewBox:
+        if (renderer.element()) {
+            FloatSize viewportSize;
+            SVGLengthContext(downcast<SVGElement>(renderer.element())).determineViewport(viewportSize);
+            referenceBox.setSize(viewportSize);
+            break;
+        }
+        FALLTHROUGH;
+    case CSSBoxType::ContentBox:
+    case CSSBoxType::FillBox:
+    case CSSBoxType::PaddingBox:
+    case CSSBoxType::BoxMissing:
+        referenceBox = renderer.objectBoundingBox();
+        break;
+    }
+    return referenceBox;
+}
+
+inline bool isPointInCSSClippingArea(const RenderElement& renderer, const FloatPoint& point)
+{
+    ClipPathOperation* clipPathOperation = renderer.style().clipPath();
+    if (is<ShapeClipPathOperation>(clipPathOperation)) {
+        auto& clipPath = downcast<ShapeClipPathOperation>(*clipPathOperation);
+        FloatRect referenceBox = clipPathReferenceBox(renderer, clipPath.referenceBox());
+        if (!referenceBox.contains(point))
+            return false;
+        return clipPath.pathForReferenceRect(referenceBox).contains(point, clipPath.windRule());
+    }
+    if (is<BoxClipPathOperation>(clipPathOperation)) {
+        auto& clipPath = downcast<BoxClipPathOperation>(*clipPathOperation);
+        FloatRect referenceBox = clipPathReferenceBox(renderer, clipPath.referenceBox());
+        if (!referenceBox.contains(point))
+            return false;
+        return clipPath.pathForReferenceRect(FloatRoundedRect {referenceBox}).contains(point);
+    }
+
+    return true;
+}
+
+void SVGRenderSupport::clipContextToCSSClippingArea(GraphicsContext& context, const RenderElement& renderer)
+{
+    ClipPathOperation* clipPathOperation = renderer.style().clipPath();
+    if (is<ShapeClipPathOperation>(clipPathOperation)) {
+        auto& clipPath = downcast<ShapeClipPathOperation>(*clipPathOperation);
+        FloatRect referenceBox = clipPathReferenceBox(renderer, clipPath.referenceBox());
+        context.clipPath(clipPath.pathForReferenceRect(referenceBox), clipPath.windRule());
+    }
+    if (is<BoxClipPathOperation>(clipPathOperation)) {
+        auto& clipPath = downcast<BoxClipPathOperation>(*clipPathOperation);
+        FloatRect referenceBox = clipPathReferenceBox(renderer, clipPath.referenceBox());
+        context.clipPath(clipPath.pathForReferenceRect(FloatRoundedRect {referenceBox}));
+    }
+}
+
 bool SVGRenderSupport::pointInClippingArea(const RenderElement& renderer, const FloatPoint& point)
 {
+    ClipPathOperation* clipPathOperation = renderer.style().clipPath();
+    if (is<ShapeClipPathOperation>(clipPathOperation) || is<BoxClipPathOperation>(clipPathOperation))
+        return isPointInCSSClippingArea(renderer, point);
+
     // We just take clippers into account to determine if a point is on the node. The Specification may
     // change later and we also need to check maskers.
     auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h (233834 => 233835)


--- trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderSupport.h	2018-07-14 09:19:46 UTC (rev 233835)
@@ -80,6 +80,8 @@
     // Determines if any ancestor's transform has changed.
     static bool transformToRootChanged(RenderElement*);
 
+    static void clipContextToCSSClippingArea(GraphicsContext&, const RenderElement& renderer);
+
     // Helper functions to keep track of whether a renderer has an SVG shadow applied.
     static bool rendererHasSVGShadow(const RenderObject&);
     static void setRendererHasSVGShadow(RenderObject&, bool hasShadow);

Modified: trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp (233834 => 233835)


--- trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/Source/WebCore/rendering/svg/SVGRenderingContext.cpp	2018-07-14 09:19:46 UTC (rev 233835)
@@ -5,6 +5,7 @@
  * Copyright (C) 2009 Google, Inc.  All rights reserved.
  * Copyright (C) 2009 Dirk Schulze <k...@webkit.org>
  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
+ * Copyright (C) 2018 Adobe Systems Incorporated. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -134,23 +135,9 @@
     }
 
     ClipPathOperation* clipPathOperation = style.clipPath();
-    if (is<ShapeClipPathOperation>(clipPathOperation)) {
-        auto& clipPath = downcast<ShapeClipPathOperation>(*clipPathOperation);
-        FloatRect referenceBox;
-        if (clipPath.referenceBox() == CSSBoxType::StrokeBox || clipPath.referenceBox() == CSSBoxType::MarginBox
-            || clipPath.referenceBox() == CSSBoxType::BorderBox)
-        {
-            // FIXME: strokeBoundingBox() takes dasharray into account but shouldn't.
-            referenceBox = renderer.strokeBoundingBox();
-        } else if (clipPath.referenceBox() == CSSBoxType::ViewBox && renderer.element()) {
-            FloatSize viewportSize;
-            SVGLengthContext(downcast<SVGElement>(renderer.element())).determineViewport(viewportSize);
-            referenceBox.setWidth(viewportSize.width());
-            referenceBox.setHeight(viewportSize.height());
-        } else
-            referenceBox = renderer.objectBoundingBox();
-        m_paintInfo->context().clipPath(clipPath.pathForReferenceRect(referenceBox), clipPath.windRule());
-    }
+    bool hasCSSClipping = is<ShapeClipPathOperation>(clipPathOperation) || is<BoxClipPathOperation>(clipPathOperation);
+    if (hasCSSClipping)
+        SVGRenderSupport::clipContextToCSSClippingArea(m_paintInfo->context(), renderer);
 
     auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*m_renderer);
     if (!resources) {
@@ -172,7 +159,7 @@
     }
 
     RenderSVGResourceClipper* clipper = resources->clipper();
-    if (!clipPathOperation && clipper) {
+    if (!hasCSSClipping && clipper) {
         GraphicsContext* contextPtr = &m_paintInfo->context();
         bool result = clipper->applyResource(*m_renderer, style, contextPtr, RenderSVGResourceMode::ApplyToDefault);
         m_paintInfo->setContext(*contextPtr);

Modified: trunk/Source/WebCore/rendering/svg/SVGResources.cpp (233834 => 233835)


--- trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2018-07-14 06:48:09 UTC (rev 233834)
+++ trunk/Source/WebCore/rendering/svg/SVGResources.cpp	2018-07-14 09:19:46 UTC (rev 233835)
@@ -20,6 +20,7 @@
 #include "config.h"
 #include "SVGResources.h"
 
+#include "ClipPathOperation.h"
 #include "FilterOperation.h"
 #include "RenderSVGResourceClipper.h"
 #include "RenderSVGResourceFilter.h"
@@ -220,6 +221,15 @@
                 foundResources = true;
             else
                 registerPendingResource(extensions, id, element);
+        } else if (is<ReferenceClipPathOperation>(style.clipPath())) {
+            // FIXME: -webkit-clip-path should support external resources
+            // https://bugs.webkit.org/show_bug.cgi?id=127032
+            auto& clipPath = downcast<ReferenceClipPathOperation>(*style.clipPath());
+            AtomicString id(clipPath.fragment());
+            if (setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id)))
+                foundResources = true;
+            else
+                registerPendingResource(extensions, id, element);
         }
 
         if (style.hasFilter()) {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to