Title: [248604] trunk
Revision
248604
Author
an...@apple.com
Date
2019-08-13 12:26:22 -0700 (Tue, 13 Aug 2019)

Log Message

Source/WebCore:
Event region collection should take clipping into account
https://bugs.webkit.org/show_bug.cgi?id=200668
<rdar://problem/53826561>

Reviewed by Simon Fraser.

Test: pointerevents/ios/touch-action-region-clip-and-transform.html

* rendering/EventRegion.cpp:
(WebCore::EventRegionContext::pushClip):
(WebCore::EventRegionContext::popClip):

Maintain clip rect stack.

(WebCore::EventRegionContext::unite):

Apply both transforms and clipping.

* rendering/EventRegion.h:
* rendering/RenderBlock.cpp:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::pushContentsClip):
(WebCore::RenderBox::popContentsClip):

Update clip for non-self-painting layers.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::restoreClip):

Update clip for self-painting layers.

LayoutTests:
Event regions collection should take clipping into account
https://bugs.webkit.org/show_bug.cgi?id=200668
<rdar://problem/53826561>

Reviewed by Simon Fraser.

* pointerevents/ios/touch-action-region-clip-and-transform-expected.txt: Added.
* pointerevents/ios/touch-action-region-clip-and-transform.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (248603 => 248604)


--- trunk/LayoutTests/ChangeLog	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/LayoutTests/ChangeLog	2019-08-13 19:26:22 UTC (rev 248604)
@@ -1,3 +1,14 @@
+2019-08-13  Antti Koivisto  <an...@apple.com>
+
+        Event regions collection should take clipping into account
+        https://bugs.webkit.org/show_bug.cgi?id=200668
+        <rdar://problem/53826561>
+
+        Reviewed by Simon Fraser.
+
+        * pointerevents/ios/touch-action-region-clip-and-transform-expected.txt: Added.
+        * pointerevents/ios/touch-action-region-clip-and-transform.html: Added.
+
 2019-08-13  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: Styles: show @supports CSS groupings

Added: trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt (0 => 248604)


--- trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform-expected.txt	2019-08-13 19:26:22 UTC (rev 248604)
@@ -0,0 +1,101 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 2408.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 2408.00)
+      (contentsOpaque 1)
+      (event region
+        (rect (0,0) width=800 height=2408)
+      )
+      (children 6
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 350.00 350.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=200)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 408.00)
+          (bounds 350.00 350.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=200)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 808.00)
+          (bounds 350.00 350.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=200)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 1208.00)
+          (bounds 350.00 350.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=150)
+            (rect (0,150) width=350 height=50)
+            (rect (150,200) width=200 height=150)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 1608.00)
+          (bounds 350.00 350.00)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=150)
+            (rect (0,150) width=350 height=50)
+            (rect (150,200) width=200 height=150)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 8.00 2008.00)
+          (bounds 200.00 200.00)
+          (contentsOpaque 1)
+          (drawsContent 1)
+          (event region
+            (rect (0,0) width=200 height=150)
+            (rect (0,150) width=350 height=50)
+            (rect (150,200) width=200 height=150)
+            (touch-action
+              (none              
+                (rect (150,150) width=50 height=50)
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html (0 => 248604)


--- trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html	                        (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/touch-action-region-clip-and-transform.html	2019-08-13 19:26:22 UTC (rev 248604)
@@ -0,0 +1,52 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<style>
+.root { position:relative; width:200px; height:200px; will-change:transform; background:green; margin-bottom:200px; }
+.container { width:200px; height:200px; background:red; }
+.larger { width:300px; height:300px; }
+.relative { position:relative }
+.none { width:100px; height:100px; background:blue; touch-action: none; }
+.clip { overflow:hidden; }
+.transform { transform:translate(150px, 150px); }
+.negtransform { transform:translate(-50px, -50px); }
+</style>
+<body>
+<div class="root">
+    <div class="container clip">
+        <div class="none transform"></div>
+    </div>
+</div>
+<div class="root">
+    <div class="container relative clip">
+        <div class="none transform"></div>
+    </div>
+</div>
+<div class="root">
+    <div class="container relative clip">
+        <div class="none transform relative"></div>
+    </div>
+</div>
+<div class="root">
+    <div class="container clip transform">
+        <div class="none negtransform"></div>
+    </div>
+</div>
+<div class="root">
+    <div class="container relative clip transform">
+        <div class="none negtransform"></div>
+    </div>
+</div>
+<div class="root clip">
+    <div class="container relative clip transform">
+        <div class="none negtransform"></div>
+    </div>
+</div>
+<pre id="results"></pre>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals)
+    results.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION);
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (248603 => 248604)


--- trunk/Source/WebCore/ChangeLog	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/ChangeLog	2019-08-13 19:26:22 UTC (rev 248604)
@@ -1,3 +1,37 @@
+2019-08-13  Antti Koivisto  <an...@apple.com>
+
+        Event region collection should take clipping into account
+        https://bugs.webkit.org/show_bug.cgi?id=200668
+        <rdar://problem/53826561>
+
+        Reviewed by Simon Fraser.
+
+        Test: pointerevents/ios/touch-action-region-clip-and-transform.html
+
+        * rendering/EventRegion.cpp:
+        (WebCore::EventRegionContext::pushClip):
+        (WebCore::EventRegionContext::popClip):
+
+        Maintain clip rect stack.
+
+        (WebCore::EventRegionContext::unite):
+
+        Apply both transforms and clipping.
+
+        * rendering/EventRegion.h:
+        * rendering/RenderBlock.cpp:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::pushContentsClip):
+        (WebCore::RenderBox::popContentsClip):
+
+        Update clip for non-self-painting layers.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::clipToRect):
+        (WebCore::RenderLayer::restoreClip):
+
+        Update clip for self-painting layers.
+
 2019-08-13  Devin Rousso  <drou...@apple.com>
 
         Web Inspector: Styles: show @supports CSS groupings

Modified: trunk/Source/WebCore/rendering/EventRegion.cpp (248603 => 248604)


--- trunk/Source/WebCore/rendering/EventRegion.cpp	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/EventRegion.cpp	2019-08-13 19:26:22 UTC (rev 248604)
@@ -45,15 +45,45 @@
 
 void EventRegionContext::popTransform()
 {
+    if (m_transformStack.isEmpty()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
     m_transformStack.removeLast();
 }
 
+void EventRegionContext::pushClip(const IntRect& clipRect)
+{
+    auto transformedClip = m_transformStack.isEmpty() ? clipRect : m_transformStack.last().mapRect(clipRect);
+
+    if (m_clipStack.isEmpty())
+        m_clipStack.append(transformedClip);
+    else
+        m_clipStack.append(intersection(m_clipStack.last(), transformedClip));
+}
+
+void EventRegionContext::popClip()
+{
+    if (m_clipStack.isEmpty()) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    m_clipStack.removeLast();
+}
+
 void EventRegionContext::unite(const Region& region, const RenderStyle& style)
 {
-    if (m_transformStack.isEmpty())
+    if (m_transformStack.isEmpty() && m_clipStack.isEmpty()) {
         m_eventRegion.unite(region, style);
-    else
-        m_eventRegion.unite(m_transformStack.last().mapRegion(region), style);
+        return;
+    }
+
+    auto transformedAndClippedRegion = m_transformStack.isEmpty() ? region : m_transformStack.last().mapRegion(region);
+
+    if (!m_clipStack.isEmpty())
+        transformedAndClippedRegion.intersect(m_clipStack.last());
+
+    m_eventRegion.unite(transformedAndClippedRegion, style);
 }
 
 bool EventRegionContext::contains(const IntRect& rect) const

Modified: trunk/Source/WebCore/rendering/EventRegion.h (248603 => 248604)


--- trunk/Source/WebCore/rendering/EventRegion.h	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/EventRegion.h	2019-08-13 19:26:22 UTC (rev 248604)
@@ -43,6 +43,9 @@
     void pushTransform(const AffineTransform&);
     void popTransform();
 
+    void pushClip(const IntRect&);
+    void popClip();
+
     void unite(const Region&, const RenderStyle&);
     bool contains(const IntRect&) const;
 
@@ -49,6 +52,7 @@
 private:
     EventRegion& m_eventRegion;
     Vector<AffineTransform> m_transformStack;
+    Vector<IntRect> m_clipStack;
 };
 
 class EventRegion {

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (248603 => 248604)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2019-08-13 19:26:22 UTC (rev 248604)
@@ -1804,6 +1804,10 @@
     if (style().hasBorderRadius())
         paintInfo.context().clipRoundedRect(style().getRoundedInnerBorderFor(LayoutRect(accumulatedOffset, size())).pixelSnappedRoundedRectForPainting(deviceScaleFactor));
     paintInfo.context().clip(clipRect);
+
+    if (paintInfo.phase == PaintPhase::EventRegion)
+        paintInfo.eventRegionContext->pushClip(enclosingIntRect(clipRect));
+
     return true;
 }
 
@@ -1811,6 +1815,9 @@
 {
     ASSERT(hasControlClip() || (hasOverflowClip() && !layer()->isSelfPaintingLayer()));
 
+    if (paintInfo.phase == PaintPhase::EventRegion)
+        paintInfo.eventRegionContext->popClip();
+
     paintInfo.context().restore();
     if (originalPhase == PaintPhase::Outline) {
         paintInfo.phase = PaintPhase::SelfOutline;

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (248603 => 248604)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-08-13 18:54:32 UTC (rev 248603)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-08-13 19:26:22 UTC (rev 248604)
@@ -4010,7 +4010,11 @@
     if (needsClipping) {
         LayoutRect adjustedClipRect = clipRect.rect();
         adjustedClipRect.move(paintingInfo.subpixelOffset);
-        context.clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
+        auto snappedClipRect = snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor);
+        context.clip(snappedClipRect);
+
+        if (paintingInfo.eventRegionContext)
+            paintingInfo.eventRegionContext->pushClip(enclosingIntRect(snappedClipRect));
     }
 
     if (clipRect.affectedByRadius()) {
@@ -4036,8 +4040,12 @@
 
 void RenderLayer::restoreClip(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const ClipRect& clipRect)
 {
-    if ((!clipRect.isInfinite() && clipRect.rect() != paintingInfo.paintDirtyRect) || clipRect.affectedByRadius())
+    if ((!clipRect.isInfinite() && clipRect.rect() != paintingInfo.paintDirtyRect) || clipRect.affectedByRadius()) {
         context.restore();
+
+        if (paintingInfo.eventRegionContext)
+            paintingInfo.eventRegionContext->popClip();
+    }
 }
 
 static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to