Title: [245293] trunk
Revision
245293
Author
[email protected]
Date
2019-05-14 11:28:11 -0700 (Tue, 14 May 2019)

Log Message

Event region computation should respect transforms
https://bugs.webkit.org/show_bug.cgi?id=197836
<rdar://problem/50762971>

Reviewed by Darin Adler.

Source/WebCore:

* platform/graphics/transforms/AffineTransform.cpp:
(WebCore::AffineTransform::mapRegion const):

Add support for transforming regions. Non-rectlinear results use enclosing rects.

* platform/graphics/transforms/AffineTransform.h:
* rendering/EventRegion.cpp:
(WebCore::EventRegionContext::EventRegionContext):
(WebCore::EventRegionContext::pushTransform):
(WebCore::EventRegionContext::popTransform):
(WebCore::EventRegionContext::unite):
(WebCore::EventRegionContext::contains const):

Add a context object that holds the current transform.

* rendering/EventRegion.h:
(WebCore::EventRegion::makeContext):
* rendering/InlineTextBox.cpp:
(WebCore::InlineTextBox::paint):
* rendering/PaintInfo.h:

Replace the region object with the context.

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paintObject):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerByApplyingTransform):

Apply transforms to regions if needed.

(WebCore::RenderLayer::collectEventRegionForFragments):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateEventRegion):
* rendering/SimpleLineLayoutFunctions.cpp:
(WebCore::SimpleLineLayout::paintFlow):

LayoutTests:

* fast/scrolling/ios/event-region-scale-transform-shared-expected.txt:
* fast/scrolling/ios/event-region-translate-transform-shared-expected.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (245292 => 245293)


--- trunk/LayoutTests/ChangeLog	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/LayoutTests/ChangeLog	2019-05-14 18:28:11 UTC (rev 245293)
@@ -1,3 +1,14 @@
+2019-05-14  Antti Koivisto  <[email protected]>
+
+        Event region computation should respect transforms
+        https://bugs.webkit.org/show_bug.cgi?id=197836
+        <rdar://problem/50762971>
+
+        Reviewed by Darin Adler.
+
+        * fast/scrolling/ios/event-region-scale-transform-shared-expected.txt:
+        * fast/scrolling/ios/event-region-translate-transform-shared-expected.txt:
+
 2019-05-14  Said Abou-Hallawa  <[email protected]>
 
         Unreviewed: fix test failures after r245280.

Modified: trunk/LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt (245292 => 245293)


--- trunk/LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt	2019-05-14 18:28:11 UTC (rev 245293)
@@ -19,8 +19,9 @@
           (bounds 201.00 201.00)
           (drawsContent 1)
           (event region
-            (rect (0,0) width=200 height=200)
-            (rect (200,200) width=100 height=100)
+            (rect (0,0) width=12 height=12)
+            (rect (51,51) width=100 height=100)
+            (rect (151,151) width=50 height=50)
           )
         )
       )

Modified: trunk/LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt (245292 => 245293)


--- trunk/LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt	2019-05-14 18:28:11 UTC (rev 245293)
@@ -19,8 +19,9 @@
           (bounds 451.00 451.00)
           (drawsContent 1)
           (event region
-            (rect (0,0) width=200 height=200)
-            (rect (200,200) width=100 height=100)
+            (rect (0,0) width=12 height=12)
+            (rect (151,151) width=200 height=200)
+            (rect (351,351) width=100 height=100)
           )
         )
       )

Modified: trunk/Source/WebCore/ChangeLog (245292 => 245293)


--- trunk/Source/WebCore/ChangeLog	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/ChangeLog	2019-05-14 18:28:11 UTC (rev 245293)
@@ -1,3 +1,48 @@
+2019-05-14  Antti Koivisto  <[email protected]>
+
+        Event region computation should respect transforms
+        https://bugs.webkit.org/show_bug.cgi?id=197836
+        <rdar://problem/50762971>
+
+        Reviewed by Darin Adler.
+
+        * platform/graphics/transforms/AffineTransform.cpp:
+        (WebCore::AffineTransform::mapRegion const):
+
+        Add support for transforming regions. Non-rectlinear results use enclosing rects.
+
+        * platform/graphics/transforms/AffineTransform.h:
+        * rendering/EventRegion.cpp:
+        (WebCore::EventRegionContext::EventRegionContext):
+        (WebCore::EventRegionContext::pushTransform):
+        (WebCore::EventRegionContext::popTransform):
+        (WebCore::EventRegionContext::unite):
+        (WebCore::EventRegionContext::contains const):
+
+        Add a context object that holds the current transform.
+
+        * rendering/EventRegion.h:
+        (WebCore::EventRegion::makeContext):
+        * rendering/InlineTextBox.cpp:
+        (WebCore::InlineTextBox::paint):
+        * rendering/PaintInfo.h:
+
+        Replace the region object with the context.
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::paintObject):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::paintLayerByApplyingTransform):
+
+        Apply transforms to regions if needed.
+
+        (WebCore::RenderLayer::collectEventRegionForFragments):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateEventRegion):
+        * rendering/SimpleLineLayoutFunctions.cpp:
+        (WebCore::SimpleLineLayout::paintFlow):
+
 2019-05-14  Youenn Fablet  <[email protected]>
 
         Video frame resizing should be using Trim

Modified: trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp (245292 => 245293)


--- trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -31,6 +31,7 @@
 #include "FloatQuad.h"
 #include "FloatRect.h"
 #include "IntRect.h"
+#include "Region.h"
 #include "TransformationMatrix.h"
 #include <wtf/MathExtras.h>
 #include <wtf/Optional.h>
@@ -334,6 +335,21 @@
     return result;
 }
 
+Region AffineTransform::mapRegion(const Region& region) const
+{
+    if (isIdentityOrTranslation()) {
+        Region mappedRegion(region);
+        mappedRegion.translate(roundedIntSize(FloatSize(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5]))));
+        return mappedRegion;
+    }
+
+    Region mappedRegion;
+    for (auto& rect : region.rects())
+        mappedRegion.unite(mapRect(rect));
+
+    return mappedRegion;
+}
+
 void AffineTransform::blend(const AffineTransform& from, double progress)
 {
     DecomposedType srA, srB;

Modified: trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h (245292 => 245293)


--- trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h	2019-05-14 18:28:11 UTC (rev 245293)
@@ -53,6 +53,7 @@
 class IntPoint;
 class IntSize;
 class IntRect;
+class Region;
 class TransformationMatrix;
 
 class AffineTransform {
@@ -89,6 +90,8 @@
     WEBCORE_EXPORT FloatRect mapRect(const FloatRect&) const;
     WEBCORE_EXPORT FloatQuad mapQuad(const FloatQuad&) const;
 
+    WEBCORE_EXPORT Region mapRegion(const Region&) const;
+
     WEBCORE_EXPORT bool isIdentity() const;
 
     double a() const { return m_transform[0]; }

Modified: trunk/Source/WebCore/rendering/EventRegion.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/EventRegion.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/EventRegion.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -30,6 +30,40 @@
 
 namespace WebCore {
 
+EventRegionContext::EventRegionContext(EventRegion& eventRegion)
+    : m_eventRegion(eventRegion)
+{
+}
+
+void EventRegionContext::pushTransform(const AffineTransform& transform)
+{
+    if (m_transformStack.isEmpty())
+        m_transformStack.append(transform);
+    else
+        m_transformStack.append(m_transformStack.last() * transform);
+}
+
+void EventRegionContext::popTransform()
+{
+    m_transformStack.removeLast();
+}
+
+void EventRegionContext::unite(const Region& region, const RenderStyle& style)
+{
+    if (m_transformStack.isEmpty())
+        m_eventRegion.unite(region, style);
+    else
+        m_eventRegion.unite(m_transformStack.last().mapRegion(region), style);
+}
+
+bool EventRegionContext::contains(const IntRect& rect) const
+{
+    if (m_transformStack.isEmpty())
+        return m_eventRegion.contains(rect);
+
+    return m_eventRegion.contains(m_transformStack.last().mapRect(rect));
+}
+
 EventRegion::EventRegion() = default;
 
 bool EventRegion::operator==(const EventRegion& other) const

Modified: trunk/Source/WebCore/rendering/EventRegion.h (245292 => 245293)


--- trunk/Source/WebCore/rendering/EventRegion.h	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/EventRegion.h	2019-05-14 18:28:11 UTC (rev 245293)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "AffineTransform.h"
 #include "Region.h"
 #include "TouchAction.h"
 #include <wtf/OptionSet.h>
@@ -32,12 +33,30 @@
 
 namespace WebCore {
 
+class EventRegion;
 class RenderStyle;
 
+class EventRegionContext {
+public:
+    explicit EventRegionContext(EventRegion&);
+
+    void pushTransform(const AffineTransform&);
+    void popTransform();
+
+    void unite(const Region&, const RenderStyle&);
+    bool contains(const IntRect&) const;
+
+private:
+    EventRegion& m_eventRegion;
+    Vector<AffineTransform> m_transformStack;
+};
+
 class EventRegion {
 public:
     WEBCORE_EXPORT EventRegion();
 
+    EventRegionContext makeContext() { return EventRegionContext(*this); }
+
     bool isEmpty() const { return m_region.isEmpty(); }
 
     WEBCORE_EXPORT bool operator==(const EventRegion&) const;

Modified: trunk/Source/WebCore/rendering/InlineTextBox.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/InlineTextBox.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/InlineTextBox.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -505,7 +505,7 @@
 
     if (paintInfo.phase == PaintPhase::EventRegion) {
         if (visibleToHitTesting())
-            paintInfo.eventRegion->unite(enclosingIntRect(boxRect), renderer().style());
+            paintInfo.eventRegionContext->unite(enclosingIntRect(boxRect), renderer().style());
         return;
     }
 

Modified: trunk/Source/WebCore/rendering/PaintInfo.h (245292 => 245293)


--- trunk/Source/WebCore/rendering/PaintInfo.h	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/PaintInfo.h	2019-05-14 18:28:11 UTC (rev 245293)
@@ -37,7 +37,7 @@
 
 namespace WebCore {
 
-class EventRegion;
+class EventRegionContext;
 class OverlapTestRequestClient;
 class RenderInline;
 class RenderLayer;
@@ -130,7 +130,8 @@
     const RenderLayerModelObject* paintContainer; // the layer object that originates the current painting
     bool requireSecurityOriginAccessForWidgets { false };
     const RenderLayer* m_enclosingSelfPaintingLayer { nullptr };
-    EventRegion* eventRegion { nullptr }; // For PaintPhase::EventRegion.
+    EventRegionContext* eventRegionContext { nullptr }; // For PaintPhase::EventRegion.
+
 private:
     GraphicsContext* m_context;
 };

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -1246,11 +1246,11 @@
 
         if (visibleToHitTesting()) {
             auto borderRegion = approximateAsRegion(style().getRoundedBorderFor(borderRect));
-            paintInfo.eventRegion->unite(borderRegion, style());
+            paintInfo.eventRegionContext->unite(borderRegion, style());
         }
 
         // No need to check descendants if we don't have overflow and the area is already covered.
-        bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegion->contains(enclosingIntRect(borderRect));
+        bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect));
 #if PLATFORM(IOS_FAMILY) && ENABLE(POINTER_EVENTS)
         needsTraverseDescendants = needsTraverseDescendants || document().touchActionElements();
 #endif

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -4600,9 +4600,13 @@
     // Translate the graphics context to the snapping position to avoid off-device-pixel positing.
     transform.translateRight(devicePixelSnappedOffsetForThisLayer.width(), devicePixelSnappedOffsetForThisLayer.height());
     // Apply the transform.
-    AffineTransform oldTransfrom = context.getCTM();
-    context.concatCTM(transform.toAffineTransform());
+    auto oldTransform = context.getCTM();
+    auto affineTransform = transform.toAffineTransform();
+    context.concatCTM(affineTransform);
 
+    if (paintingInfo.eventRegionContext)
+        paintingInfo.eventRegionContext->pushTransform(affineTransform);
+
     // Now do a paint with the root layer shifted to be us.
     LayoutSize adjustedSubpixelOffset = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
     LayerPaintingInfo transformedPaintingInfo(paintingInfo);
@@ -4610,7 +4614,11 @@
     transformedPaintingInfo.paintDirtyRect = LayoutRect(encloseRectToDevicePixels(transform.inverse().valueOr(AffineTransform()).mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor));
     transformedPaintingInfo.subpixelOffset = adjustedSubpixelOffset;
     paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
-    context.setCTM(oldTransfrom);
+
+    if (paintingInfo.eventRegionContext)
+        paintingInfo.eventRegionContext->popTransform();
+
+    context.setCTM(oldTransform);
 }
 
 void RenderLayer::paintList(LayerList layerIterator, GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
@@ -4998,11 +5006,11 @@
 
 void RenderLayer::collectEventRegionForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo)
 {
-    ASSERT(localPaintingInfo.eventRegion);
+    ASSERT(localPaintingInfo.eventRegionContext);
 
     for (const auto& fragment : layerFragments) {
         PaintInfo paintInfo(context, fragment.foregroundRect.rect(), PaintPhase::EventRegion, { });
-        paintInfo.eventRegion = localPaintingInfo.eventRegion;
+        paintInfo.eventRegionContext = localPaintingInfo.eventRegionContext;
         renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
     }
 }

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (245292 => 245293)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2019-05-14 18:28:11 UTC (rev 245293)
@@ -63,7 +63,7 @@
 class CSSFilter;
 class ClipRects;
 class ClipRectsCache;
-class EventRegion;
+class EventRegionContext;
 class HitTestRequest;
 class HitTestResult;
 class HitTestingTransformState;
@@ -941,7 +941,7 @@
         OptionSet<PaintBehavior> paintBehavior;
         bool requireSecurityOriginAccessForWidgets;
         bool clipToDirtyRect { true };
-        EventRegion* eventRegion { nullptr };
+        EventRegionContext* eventRegionContext { nullptr };
     };
 
     // Compute, cache and return clip rects computed with the given layer as the root.

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -1484,7 +1484,8 @@
     RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, compositedBounds(), { }, LayoutSize());
 
     EventRegion eventRegion;
-    paintingInfo.eventRegion = &eventRegion;
+    auto eventRegionContext = eventRegion.makeContext();
+    paintingInfo.eventRegionContext = &eventRegionContext;
 
     auto paintFlags = RenderLayer::paintLayerPaintingCompositingAllPhasesFlags() | RenderLayer::PaintLayerCollectingEventRegion;
     m_owningLayer.paintLayerContents(nullContext, paintingInfo, paintFlags);

Modified: trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp (245292 => 245293)


--- trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp	2019-05-14 18:27:14 UTC (rev 245292)
+++ trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp	2019-05-14 18:28:11 UTC (rev 245293)
@@ -84,7 +84,7 @@
         paintRect.moveBy(-paintOffset);
         for (auto run : layout.runResolver().rangeForRect(paintRect)) {
             FloatRect visualOverflowRect = computeOverflow(flow, run.rect());
-            paintInfo.eventRegion->unite(enclosingIntRect(visualOverflowRect), flow.style());
+            paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), flow.style());
         }
         return;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to