Title: [246301] trunk/Source/WebCore
Revision
246301
Author
[email protected]
Date
2019-06-10 17:54:11 -0700 (Mon, 10 Jun 2019)

Log Message

Add visualization of touch action regions
https://bugs.webkit.org/show_bug.cgi?id=198718

Reviewed by Antoine Quint.

Add a way to show which elements of the page have touch-action set on them by
painting an overlay with small text that shows the type of action(s).

The event regions are painted into GraphicsLayers at paint time in
RenderLayerBacking by making a pattern image and filling the region rects
with the pattern.

* page/DebugPageOverlays.cpp:
(WebCore::touchEventRegionColors):
* rendering/EventRegion.cpp:
(WebCore::EventRegion::regionForTouchAction const):
* rendering/EventRegion.h:
(WebCore::EventRegion::region const):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateEventRegion):
(WebCore::patternForTouchAction):
(WebCore::RenderLayerBacking::paintContents):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (246300 => 246301)


--- trunk/Source/WebCore/ChangeLog	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/ChangeLog	2019-06-11 00:54:11 UTC (rev 246301)
@@ -1,3 +1,28 @@
+2019-06-10  Simon Fraser  <[email protected]>
+
+        Add visualization of touch action regions
+        https://bugs.webkit.org/show_bug.cgi?id=198718
+
+        Reviewed by Antoine Quint.
+
+        Add a way to show which elements of the page have touch-action set on them by
+        painting an overlay with small text that shows the type of action(s).
+
+        The event regions are painted into GraphicsLayers at paint time in
+        RenderLayerBacking by making a pattern image and filling the region rects
+        with the pattern.
+
+        * page/DebugPageOverlays.cpp:
+        (WebCore::touchEventRegionColors):
+        * rendering/EventRegion.cpp:
+        (WebCore::EventRegion::regionForTouchAction const):
+        * rendering/EventRegion.h:
+        (WebCore::EventRegion::region const):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateEventRegion):
+        (WebCore::patternForTouchAction):
+        (WebCore::RenderLayerBacking::paintContents):
+
 2019-06-10  Basuke Suzuki  <[email protected]>
 
         Web Inspector: DNS names in SymmaryInfo was wrong.

Modified: trunk/Source/WebCore/page/DebugPageOverlays.cpp (246300 => 246301)


--- trunk/Source/WebCore/page/DebugPageOverlays.cpp	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/page/DebugPageOverlays.cpp	2019-06-11 00:54:11 UTC (rev 246301)
@@ -162,7 +162,7 @@
         };
         HashMap<String, Color> map;
         for (auto& entry : entries)
-            map.add(entry.name, Color { entry.r, entry.g, entry.b, 80 });
+            map.add(entry.name, Color { entry.r, entry.g, entry.b, 50 });
         return map;
     }());
     return regionColors;

Modified: trunk/Source/WebCore/rendering/EventRegion.cpp (246300 => 246301)


--- trunk/Source/WebCore/rendering/EventRegion.cpp	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/rendering/EventRegion.cpp	2019-06-11 00:54:11 UTC (rev 246301)
@@ -157,6 +157,15 @@
     }
 }
 
+const Region* EventRegion::regionForTouchAction(TouchAction action) const
+{
+    unsigned actionIndex = toIndex(action);
+    if (actionIndex >= m_touchActionRegions.size())
+        return nullptr;
+
+    return &m_touchActionRegions[actionIndex];
+}
+
 OptionSet<TouchAction> EventRegion::touchActionsForPoint(const IntPoint& point) const
 {
     OptionSet<TouchAction> actions;
@@ -196,7 +205,7 @@
     return ts;
 }
 
-#endif
+#endif // ENABLE(POINTER_EVENTS)
 
 TextStream& operator<<(TextStream& ts, const EventRegion& eventRegion)
 {

Modified: trunk/Source/WebCore/rendering/EventRegion.h (246300 => 246301)


--- trunk/Source/WebCore/rendering/EventRegion.h	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/rendering/EventRegion.h	2019-06-11 00:54:11 UTC (rev 246301)
@@ -67,9 +67,13 @@
     bool contains(const IntPoint& point) const { return m_region.contains(point); }
     bool contains(const IntRect& rect) const { return m_region.contains(rect); }
 
+    const Region& region() const { return m_region; }
+
 #if ENABLE(POINTER_EVENTS)
     bool hasTouchActions() const { return !m_touchActionRegions.isEmpty(); }
     WEBCORE_EXPORT OptionSet<TouchAction> touchActionsForPoint(const IntPoint&) const;
+
+    const Region* regionForTouchAction(TouchAction) const;
 #endif
 
     template<class Encoder> void encode(Encoder&) const;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (246300 => 246301)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2019-06-11 00:54:11 UTC (rev 246301)
@@ -2733,6 +2733,123 @@
     compositor().didPaintBacking(this);
 }
 
+#if ENABLE(POINTER_EVENTS)
+static RefPtr<Pattern> patternForTouchAction(TouchAction touchAction, FloatSize contentOffset, GraphicsContext& destContext)
+{
+    auto toIndex = [](TouchAction touchAction) -> unsigned {
+        switch (touchAction) {
+        case TouchAction::Manipulation:
+            return 1;
+        case TouchAction::PanX:
+            return 2;
+        case TouchAction::PanY:
+            return 3;
+        case TouchAction::PinchZoom:
+            return 4;
+        case TouchAction::None:
+        case TouchAction::Auto:
+            break;
+        }
+        return 0;
+    };
+
+    struct TouchActionAndRGB {
+        TouchAction action;
+        ASCIILiteral name;
+        FloatSize phase;
+    };
+    static const TouchActionAndRGB actionsAndColors[] = {
+        { TouchAction::None, "none"_s, { } },
+        { TouchAction::Manipulation, "manip"_s, { } },
+        { TouchAction::PanX, "pan-x"_s, { } },
+        { TouchAction::PanY, "pan-y"_s, { 0, 9 } },
+        { TouchAction::PinchZoom, "p-z"_s, { 16, 4.5 } },
+    };
+    
+    auto actionIndex = toIndex(touchAction);
+    if (!actionIndex || actionIndex >= ARRAY_SIZE(actionsAndColors))
+        return nullptr;
+
+    const FloatSize tileSize { 32, 18 };
+
+    auto imageBuffer = ImageBuffer::createCompatibleBuffer(tileSize, ColorSpaceSRGB, destContext);
+    if (!imageBuffer)
+        return nullptr;
+
+    const auto& touchActionData = actionsAndColors[actionIndex];
+    {
+        GraphicsContext& imageContext = imageBuffer->context();
+
+        FontCascadeDescription fontDescription;
+        fontDescription.setOneFamily("Helvetica");
+        fontDescription.setSpecifiedSize(10);
+        fontDescription.setComputedSize(10);
+        fontDescription.setWeight(FontSelectionValue(500));
+        FontCascade font(WTFMove(fontDescription), 0, 0);
+        font.update(nullptr);
+
+        TextRun textRun = TextRun(touchActionData.name);
+        imageContext.setFillColor(Color(0, 0, 0, 128));
+
+        constexpr float textGap = 4;
+        constexpr float yOffset = 12;
+        imageContext.drawText(font, textRun, { textGap, yOffset }, 0);
+    }
+
+    auto tileImage = ImageBuffer::sinkIntoImage(WTFMove(imageBuffer));
+    auto fillPattern = Pattern::create(tileImage.releaseNonNull(), true, true);
+    AffineTransform patternOffsetTransform;
+    patternOffsetTransform.translate(contentOffset + touchActionData.phase);
+    patternOffsetTransform.scale(1 / destContext.scaleFactor());
+    fillPattern->setPatternSpaceTransform(patternOffsetTransform);
+
+    return fillPattern;
+}
+#endif // ENABLE(POINTER_EVENTS)
+
+void RenderLayerBacking::paintDebugOverlays(const GraphicsLayer* graphicsLayer, GraphicsContext& context)
+{
+    if (graphicsLayer->eventRegion().isEmpty())
+        return;
+
+    GraphicsContextStateSaver stateSaver(context);
+
+    // The region is offset by contentOffsetInCompositingLayer() so undo that.
+    auto contentOffset = roundedIntSize(contentOffsetInCompositingLayer());
+    context.translate(-contentOffset);
+
+    // The interactive part.
+    auto& eventRegion = graphicsLayer->eventRegion();
+    Color regionColor(0, 0, 0, 5);
+    context.setFillColor(regionColor);
+    for (auto rect : eventRegion.region().rects())
+        context.fillRect(rect);
+
+#if ENABLE(POINTER_EVENTS)
+    const TouchAction touchActionList[] = {
+        TouchAction::None,
+        TouchAction::Manipulation,
+        TouchAction::PanX,
+        TouchAction::PanY,
+        TouchAction::PinchZoom,
+    };
+
+    for (auto action : touchActionList) {
+        auto* actionRegion = graphicsLayer->eventRegion().regionForTouchAction(action);
+        if (!actionRegion)
+            continue;
+
+        auto fillPattern = patternForTouchAction(action, contentOffsetInCompositingLayer(), context);
+        if (!fillPattern)
+            continue;
+
+        context.setFillPattern(fillPattern.releaseNonNull());
+        for (auto rect : actionRegion->rects())
+            context.fillRect(rect);
+    }
+#endif // ENABLE(POINTER_EVENTS)
+}
+
 // Up-call from compositing layer drawing callback.
 void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, OptionSet<GraphicsLayerPaintingPhase> paintingPhase, const FloatRect& clip, GraphicsLayerPaintBehavior layerPaintBehavior)
 {
@@ -2771,6 +2888,10 @@
             behavior.add(PaintBehavior::TileFirstPaint);
 
         paintIntoLayer(graphicsLayer, context, dirtyRect, behavior, paintingPhase);
+
+        if (renderer().settings().visibleDebugOverlayRegions() & NonFastScrollableRegion) // Piggy-back off the setting that shows touch handler regions.
+            paintDebugOverlays(graphicsLayer, context);
+
     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
     } else if (graphicsLayer == layerForVerticalScrollbar()) {

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (246300 => 246301)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.h	2019-06-11 00:45:50 UTC (rev 246300)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h	2019-06-11 00:54:11 UTC (rev 246301)
@@ -384,6 +384,8 @@
     GraphicsLayer* tileCacheFlatteningLayer() const { return m_isFrameLayerWithTiledBacking ? m_childContainmentLayer.get() : nullptr; }
 
     void paintIntoLayer(const GraphicsLayer*, GraphicsContext&, const IntRect& paintDirtyRect, OptionSet<PaintBehavior>, OptionSet<GraphicsLayerPaintingPhase>);
+    
+    void paintDebugOverlays(const GraphicsLayer*, GraphicsContext&);
 
     static CSSPropertyID graphicsLayerToCSSProperty(AnimatedPropertyID);
     static AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to