⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 245293 in webkit


Ignore:
Timestamp:
May 14, 2019, 11:28:11 AM (7 years ago)
Author:
Antti Koivisto
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:
Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245292 r245293  
     12019-05-14  Antti Koivisto  <antti@apple.com>
     2
     3        Event region computation should respect transforms
     4        https://bugs.webkit.org/show_bug.cgi?id=197836
     5        <rdar://problem/50762971>
     6
     7        Reviewed by Darin Adler.
     8
     9        * fast/scrolling/ios/event-region-scale-transform-shared-expected.txt:
     10        * fast/scrolling/ios/event-region-translate-transform-shared-expected.txt:
     11
    1122019-05-14  Said Abou-Hallawa  <sabouhallawa@apple.com>
    213
  • trunk/LayoutTests/fast/scrolling/ios/event-region-scale-transform-shared-expected.txt

    r245242 r245293  
    2020          (drawsContent 1)
    2121          (event region
    22             (rect (0,0) width=200 height=200)
    23             (rect (200,200) width=100 height=100)
     22            (rect (0,0) width=12 height=12)
     23            (rect (51,51) width=100 height=100)
     24            (rect (151,151) width=50 height=50)
    2425          )
    2526        )
  • trunk/LayoutTests/fast/scrolling/ios/event-region-translate-transform-shared-expected.txt

    r245242 r245293  
    2020          (drawsContent 1)
    2121          (event region
    22             (rect (0,0) width=200 height=200)
    23             (rect (200,200) width=100 height=100)
     22            (rect (0,0) width=12 height=12)
     23            (rect (151,151) width=200 height=200)
     24            (rect (351,351) width=100 height=100)
    2425          )
    2526        )
  • trunk/Source/WebCore/ChangeLog

    r245289 r245293  
     12019-05-14  Antti Koivisto  <antti@apple.com>
     2
     3        Event region computation should respect transforms
     4        https://bugs.webkit.org/show_bug.cgi?id=197836
     5        <rdar://problem/50762971>
     6
     7        Reviewed by Darin Adler.
     8
     9        * platform/graphics/transforms/AffineTransform.cpp:
     10        (WebCore::AffineTransform::mapRegion const):
     11
     12        Add support for transforming regions. Non-rectlinear results use enclosing rects.
     13
     14        * platform/graphics/transforms/AffineTransform.h:
     15        * rendering/EventRegion.cpp:
     16        (WebCore::EventRegionContext::EventRegionContext):
     17        (WebCore::EventRegionContext::pushTransform):
     18        (WebCore::EventRegionContext::popTransform):
     19        (WebCore::EventRegionContext::unite):
     20        (WebCore::EventRegionContext::contains const):
     21
     22        Add a context object that holds the current transform.
     23
     24        * rendering/EventRegion.h:
     25        (WebCore::EventRegion::makeContext):
     26        * rendering/InlineTextBox.cpp:
     27        (WebCore::InlineTextBox::paint):
     28        * rendering/PaintInfo.h:
     29
     30        Replace the region object with the context.
     31
     32        * rendering/RenderBlock.cpp:
     33        (WebCore::RenderBlock::paintObject):
     34        * rendering/RenderLayer.cpp:
     35        (WebCore::RenderLayer::paintLayerByApplyingTransform):
     36
     37        Apply transforms to regions if needed.
     38
     39        (WebCore::RenderLayer::collectEventRegionForFragments):
     40        * rendering/RenderLayer.h:
     41        * rendering/RenderLayerBacking.cpp:
     42        (WebCore::RenderLayerBacking::updateEventRegion):
     43        * rendering/SimpleLineLayoutFunctions.cpp:
     44        (WebCore::SimpleLineLayout::paintFlow):
     45
    1462019-05-14  Youenn Fablet  <youenn@apple.com>
    247
  • trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.cpp

    r242776 r245293  
    3232#include "FloatRect.h"
    3333#include "IntRect.h"
     34#include "Region.h"
    3435#include "TransformationMatrix.h"
    3536#include <wtf/MathExtras.h>
     
    333334    result.setP4(mapPoint(q.p4()));
    334335    return result;
     336}
     337
     338Region AffineTransform::mapRegion(const Region& region) const
     339{
     340    if (isIdentityOrTranslation()) {
     341        Region mappedRegion(region);
     342        mappedRegion.translate(roundedIntSize(FloatSize(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5]))));
     343        return mappedRegion;
     344    }
     345
     346    Region mappedRegion;
     347    for (auto& rect : region.rects())
     348        mappedRegion.unite(mapRect(rect));
     349
     350    return mappedRegion;
    335351}
    336352
  • trunk/Source/WebCore/platform/graphics/transforms/AffineTransform.h

    r242776 r245293  
    5454class IntSize;
    5555class IntRect;
     56class Region;
    5657class TransformationMatrix;
    5758
     
    8990    WEBCORE_EXPORT FloatRect mapRect(const FloatRect&) const;
    9091    WEBCORE_EXPORT FloatQuad mapQuad(const FloatQuad&) const;
     92
     93    WEBCORE_EXPORT Region mapRegion(const Region&) const;
    9194
    9295    WEBCORE_EXPORT bool isIdentity() const;
  • trunk/Source/WebCore/rendering/EventRegion.cpp

    r244037 r245293  
    3131namespace WebCore {
    3232
     33EventRegionContext::EventRegionContext(EventRegion& eventRegion)
     34    : m_eventRegion(eventRegion)
     35{
     36}
     37
     38void EventRegionContext::pushTransform(const AffineTransform& transform)
     39{
     40    if (m_transformStack.isEmpty())
     41        m_transformStack.append(transform);
     42    else
     43        m_transformStack.append(m_transformStack.last() * transform);
     44}
     45
     46void EventRegionContext::popTransform()
     47{
     48    m_transformStack.removeLast();
     49}
     50
     51void EventRegionContext::unite(const Region& region, const RenderStyle& style)
     52{
     53    if (m_transformStack.isEmpty())
     54        m_eventRegion.unite(region, style);
     55    else
     56        m_eventRegion.unite(m_transformStack.last().mapRegion(region), style);
     57}
     58
     59bool EventRegionContext::contains(const IntRect& rect) const
     60{
     61    if (m_transformStack.isEmpty())
     62        return m_eventRegion.contains(rect);
     63
     64    return m_eventRegion.contains(m_transformStack.last().mapRect(rect));
     65}
     66
    3367EventRegion::EventRegion() = default;
    3468
  • trunk/Source/WebCore/rendering/EventRegion.h

    r243962 r245293  
    2626#pragma once
    2727
     28#include "AffineTransform.h"
    2829#include "Region.h"
    2930#include "TouchAction.h"
     
    3334namespace WebCore {
    3435
     36class EventRegion;
    3537class RenderStyle;
     38
     39class EventRegionContext {
     40public:
     41    explicit EventRegionContext(EventRegion&);
     42
     43    void pushTransform(const AffineTransform&);
     44    void popTransform();
     45
     46    void unite(const Region&, const RenderStyle&);
     47    bool contains(const IntRect&) const;
     48
     49private:
     50    EventRegion& m_eventRegion;
     51    Vector<AffineTransform> m_transformStack;
     52};
    3653
    3754class EventRegion {
    3855public:
    3956    WEBCORE_EXPORT EventRegion();
     57
     58    EventRegionContext makeContext() { return EventRegionContext(*this); }
    4059
    4160    bool isEmpty() const { return m_region.isEmpty(); }
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r243962 r245293  
    506506    if (paintInfo.phase == PaintPhase::EventRegion) {
    507507        if (visibleToHitTesting())
    508             paintInfo.eventRegion->unite(enclosingIntRect(boxRect), renderer().style());
     508            paintInfo.eventRegionContext->unite(enclosingIntRect(boxRect), renderer().style());
    509509        return;
    510510    }
  • trunk/Source/WebCore/rendering/PaintInfo.h

    r243962 r245293  
    3838namespace WebCore {
    3939
    40 class EventRegion;
     40class EventRegionContext;
    4141class OverlapTestRequestClient;
    4242class RenderInline;
     
    131131    bool requireSecurityOriginAccessForWidgets { false };
    132132    const RenderLayer* m_enclosingSelfPaintingLayer { nullptr };
    133     EventRegion* eventRegion { nullptr }; // For PaintPhase::EventRegion.
     133    EventRegionContext* eventRegionContext { nullptr }; // For PaintPhase::EventRegion.
     134
    134135private:
    135136    GraphicsContext* m_context;
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r243962 r245293  
    12471247        if (visibleToHitTesting()) {
    12481248            auto borderRegion = approximateAsRegion(style().getRoundedBorderFor(borderRect));
    1249             paintInfo.eventRegion->unite(borderRegion, style());
     1249            paintInfo.eventRegionContext->unite(borderRegion, style());
    12501250        }
    12511251
    12521252        // No need to check descendants if we don't have overflow and the area is already covered.
    1253         bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegion->contains(enclosingIntRect(borderRect));
     1253        bool needsTraverseDescendants = hasVisualOverflow() || !paintInfo.eventRegionContext->contains(enclosingIntRect(borderRect));
    12541254#if PLATFORM(IOS_FAMILY) && ENABLE(POINTER_EVENTS)
    12551255        needsTraverseDescendants = needsTraverseDescendants || document().touchActionElements();
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r245219 r245293  
    46014601    transform.translateRight(devicePixelSnappedOffsetForThisLayer.width(), devicePixelSnappedOffsetForThisLayer.height());
    46024602    // Apply the transform.
    4603     AffineTransform oldTransfrom = context.getCTM();
    4604     context.concatCTM(transform.toAffineTransform());
     4603    auto oldTransform = context.getCTM();
     4604    auto affineTransform = transform.toAffineTransform();
     4605    context.concatCTM(affineTransform);
     4606
     4607    if (paintingInfo.eventRegionContext)
     4608        paintingInfo.eventRegionContext->pushTransform(affineTransform);
    46054609
    46064610    // Now do a paint with the root layer shifted to be us.
     
    46114615    transformedPaintingInfo.subpixelOffset = adjustedSubpixelOffset;
    46124616    paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
    4613     context.setCTM(oldTransfrom);
     4617
     4618    if (paintingInfo.eventRegionContext)
     4619        paintingInfo.eventRegionContext->popTransform();
     4620
     4621    context.setCTM(oldTransform);
    46144622}
    46154623
     
    49995007void RenderLayer::collectEventRegionForFragments(const LayerFragments& layerFragments, GraphicsContext& context, const LayerPaintingInfo& localPaintingInfo)
    50005008{
    5001     ASSERT(localPaintingInfo.eventRegion);
     5009    ASSERT(localPaintingInfo.eventRegionContext);
    50025010
    50035011    for (const auto& fragment : layerFragments) {
    50045012        PaintInfo paintInfo(context, fragment.foregroundRect.rect(), PaintPhase::EventRegion, { });
    5005         paintInfo.eventRegion = localPaintingInfo.eventRegion;
     5013        paintInfo.eventRegionContext = localPaintingInfo.eventRegionContext;
    50065014        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
    50075015    }
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r245219 r245293  
    6464class ClipRects;
    6565class ClipRectsCache;
    66 class EventRegion;
     66class EventRegionContext;
    6767class HitTestRequest;
    6868class HitTestResult;
     
    942942        bool requireSecurityOriginAccessForWidgets;
    943943        bool clipToDirtyRect { true };
    944         EventRegion* eventRegion { nullptr };
     944        EventRegionContext* eventRegionContext { nullptr };
    945945    };
    946946
  • trunk/Source/WebCore/rendering/RenderLayerBacking.cpp

    r245242 r245293  
    14851485
    14861486    EventRegion eventRegion;
    1487     paintingInfo.eventRegion = &eventRegion;
     1487    auto eventRegionContext = eventRegion.makeContext();
     1488    paintingInfo.eventRegionContext = &eventRegionContext;
    14881489
    14891490    auto paintFlags = RenderLayer::paintLayerPaintingCompositingAllPhasesFlags() | RenderLayer::PaintLayerCollectingEventRegion;
  • trunk/Source/WebCore/rendering/SimpleLineLayoutFunctions.cpp

    r243962 r245293  
    8585        for (auto run : layout.runResolver().rangeForRect(paintRect)) {
    8686            FloatRect visualOverflowRect = computeOverflow(flow, run.rect());
    87             paintInfo.eventRegion->unite(enclosingIntRect(visualOverflowRect), flow.style());
     87            paintInfo.eventRegionContext->unite(enclosingIntRect(visualOverflowRect), flow.style());
    8888        }
    8989        return;
Note: See TracChangeset for help on using the changeset viewer.