Title: [117091] trunk/Source/WebCore
Revision
117091
Author
[email protected]
Date
2012-05-15 10:41:34 -0700 (Tue, 15 May 2012)

Log Message

Factor HitTestPoint out of HitTestResult.
https://bugs.webkit.org/show_bug.cgi?id=85965

Patch by Allan Sandfeld Jensen <[email protected]> on 2012-05-15
Reviewed by Simon Fraser.

In preparation for handling transformations on area-based hit-testing,
we need to factor test-point and test-area out of HitTestResult so that
it can be transformed independently.

To maintain the current API as closely as possible HitTestResult now
inherit from HitTestPoint, representing the original untransformed
hitTestPoint.

No change in functionality. No new tests.

* rendering/HitTestResult.cpp:
(WebCore::HitTestPoint::HitTestPoint):
(WebCore::HitTestPoint::~HitTestPoint):
(WebCore::HitTestPoint::operator=):
(WebCore::HitTestPoint::rectForPoint):
(WebCore::HitTestResult::HitTestResult):
(WebCore::HitTestResult::operator=):
(WebCore::HitTestResult::isSelected):
(WebCore::HitTestResult::spellingToolTip):
(WebCore::HitTestResult::replacedString):
* rendering/HitTestResult.h:
(HitTestPoint):
(WebCore::HitTestPoint::point):
(WebCore::HitTestPoint::roundedPoint):
(WebCore::HitTestPoint::setPoint):
(WebCore::HitTestPoint::isRectBasedTest):
(WebCore::HitTestPoint::topPadding):
(WebCore::HitTestPoint::rightPadding):
(WebCore::HitTestPoint::bottomPadding):
(WebCore::HitTestPoint::leftPadding):
(HitTestResult):
(WebCore::HitTestResult::hitTestPoint):
(WebCore::HitTestPoint::rectForPoint):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::hitTestLayer):
(WebCore::RenderLayer::hitTestList):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117090 => 117091)


--- trunk/Source/WebCore/ChangeLog	2012-05-15 17:34:45 UTC (rev 117090)
+++ trunk/Source/WebCore/ChangeLog	2012-05-15 17:41:34 UTC (rev 117091)
@@ -1,3 +1,47 @@
+2012-05-15  Allan Sandfeld Jensen  <[email protected]>
+
+        Factor HitTestPoint out of HitTestResult.
+        https://bugs.webkit.org/show_bug.cgi?id=85965
+
+        Reviewed by Simon Fraser.
+
+        In preparation for handling transformations on area-based hit-testing, 
+        we need to factor test-point and test-area out of HitTestResult so that
+        it can be transformed independently.
+
+        To maintain the current API as closely as possible HitTestResult now
+        inherit from HitTestPoint, representing the original untransformed
+        hitTestPoint.
+
+        No change in functionality. No new tests. 
+
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestPoint::HitTestPoint):
+        (WebCore::HitTestPoint::~HitTestPoint):
+        (WebCore::HitTestPoint::operator=):
+        (WebCore::HitTestPoint::rectForPoint):
+        (WebCore::HitTestResult::HitTestResult):
+        (WebCore::HitTestResult::operator=):
+        (WebCore::HitTestResult::isSelected):
+        (WebCore::HitTestResult::spellingToolTip):
+        (WebCore::HitTestResult::replacedString):
+        * rendering/HitTestResult.h:
+        (HitTestPoint):
+        (WebCore::HitTestPoint::point):
+        (WebCore::HitTestPoint::roundedPoint):
+        (WebCore::HitTestPoint::setPoint):
+        (WebCore::HitTestPoint::isRectBasedTest):
+        (WebCore::HitTestPoint::topPadding):
+        (WebCore::HitTestPoint::rightPadding):
+        (WebCore::HitTestPoint::bottomPadding):
+        (WebCore::HitTestPoint::leftPadding):
+        (HitTestResult):
+        (WebCore::HitTestResult::hitTestPoint):
+        (WebCore::HitTestPoint::rectForPoint):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::hitTestLayer):
+        (WebCore::RenderLayer::hitTestList):
+
 2012-05-15  Rob Buis  <[email protected]>
 
         Refactor SVG parts of Node::addEventListener/removeEventListener

Modified: trunk/Source/WebCore/rendering/HitTestResult.cpp (117090 => 117091)


--- trunk/Source/WebCore/rendering/HitTestResult.cpp	2012-05-15 17:34:45 UTC (rev 117090)
+++ trunk/Source/WebCore/rendering/HitTestResult.cpp	2012-05-15 17:41:34 UTC (rev 117091)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -47,53 +48,109 @@
 
 using namespace HTMLNames;
 
-HitTestResult::HitTestResult()
-    : m_isOverWidget(false)
-    , m_isRectBased(false)
-    , m_topPadding(0)
+HitTestPoint::HitTestPoint()
+    : m_topPadding(0)
     , m_rightPadding(0)
     , m_bottomPadding(0)
     , m_leftPadding(0)
-    , m_shadowContentFilterPolicy(DoNotAllowShadowContent)
-    , m_region(0)
+    , m_isRectBased(false)
 {
 }
 
-HitTestResult::HitTestResult(const LayoutPoint& point)
+HitTestPoint::HitTestPoint(const LayoutPoint& point)
     : m_point(point)
-    , m_isOverWidget(false)
-    , m_isRectBased(false)
     , m_topPadding(0)
     , m_rightPadding(0)
     , m_bottomPadding(0)
     , m_leftPadding(0)
-    , m_shadowContentFilterPolicy(DoNotAllowShadowContent)
-    , m_region(0)
+    , m_isRectBased(false)
 {
 }
 
-HitTestResult::HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, ShadowContentFilterPolicy allowShadowContent)
+HitTestPoint::HitTestPoint(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
     : m_point(centerPoint)
-    , m_isOverWidget(false)
     , m_topPadding(topPadding)
     , m_rightPadding(rightPadding)
     , m_bottomPadding(bottomPadding)
     , m_leftPadding(leftPadding)
-    , m_shadowContentFilterPolicy(allowShadowContent)
-    , m_region(0)
 {
     // If all padding values passed in are zero then it is not a rect based hit test.
     m_isRectBased = topPadding || rightPadding || bottomPadding || leftPadding;
+}
 
-    // Make sure all padding values are clamped to zero if it is not a rect hit test.
-    if (!m_isRectBased)
-        m_topPadding = m_rightPadding = m_bottomPadding = m_leftPadding = 0;
+HitTestPoint::HitTestPoint(const HitTestPoint& other)
+    : m_point(other.m_point)
+    , m_topPadding(other.m_topPadding)
+    , m_rightPadding(other.m_rightPadding)
+    , m_bottomPadding(other.m_bottomPadding)
+    , m_leftPadding(other.m_leftPadding)
+    , m_isRectBased(other.m_isRectBased)
+{
 }
 
+HitTestPoint::~HitTestPoint()
+{
+}
+
+HitTestPoint& HitTestPoint::operator=(const HitTestPoint& other)
+{
+    m_point = other.m_point;
+    m_topPadding = other.m_topPadding;
+    m_rightPadding = other.m_rightPadding;
+    m_bottomPadding = other.m_bottomPadding;
+    m_leftPadding = other.m_leftPadding;
+    m_isRectBased = other.m_isRectBased;
+
+    return *this;
+}
+
+IntRect HitTestPoint::rectForPoint(const LayoutPoint& point, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
+{
+    IntPoint actualPoint(roundedIntPoint(point));
+    actualPoint -= IntSize(leftPadding, topPadding);
+
+    IntSize actualPadding(leftPadding + rightPadding, topPadding + bottomPadding);
+    // As IntRect is left inclusive and right exclusive (seeing IntRect::contains(x, y)), adding "1".
+    // FIXME: Remove this once non-rect based hit-detection stops using IntRect:intersects.
+    actualPadding += IntSize(1, 1);
+
+    return IntRect(actualPoint, actualPadding);
+}
+
+HitTestResult::HitTestResult() : HitTestPoint()
+    , m_isOverWidget(false)
+    , m_shadowContentFilterPolicy(DoNotAllowShadowContent)
+    , m_region(0)
+{
+}
+
+HitTestResult::HitTestResult(const LayoutPoint& point) : HitTestPoint(point)
+    , m_isOverWidget(false)
+    , m_shadowContentFilterPolicy(DoNotAllowShadowContent)
+    , m_region(0)
+{
+}
+
+HitTestResult::HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, ShadowContentFilterPolicy allowShadowContent)
+    : HitTestPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding)
+    , m_isOverWidget(false)
+    , m_shadowContentFilterPolicy(allowShadowContent)
+    , m_region(0)
+{
+}
+
+HitTestResult::HitTestResult(const HitTestPoint& other, ShadowContentFilterPolicy allowShadowContent)
+    : HitTestPoint(other)
+    , m_isOverWidget(false)
+    , m_shadowContentFilterPolicy(allowShadowContent)
+    , m_region(0)
+{
+}
+
 HitTestResult::HitTestResult(const HitTestResult& other)
-    : m_innerNode(other.innerNode())
+    : HitTestPoint(other)
+    , m_innerNode(other.innerNode())
     , m_innerNonSharedNode(other.innerNonSharedNode())
-    , m_point(other.point())
     , m_localPoint(other.localPoint())
     , m_innerURLElement(other.URLElement())
     , m_scrollbar(other.scrollbar())
@@ -101,16 +158,7 @@
     , m_shadowContentFilterPolicy(other.shadowContentFilterPolicy())
     , m_region(other.region())
 {
-    // Only copy the padding and NodeSet in case of rect hit test.
-    // Copying the later is rather expensive.
-    if ((m_isRectBased = other.isRectBasedTest())) {
-        m_topPadding = other.m_topPadding;
-        m_rightPadding = other.m_rightPadding;
-        m_bottomPadding = other.m_bottomPadding;
-        m_leftPadding = other.m_leftPadding;
-    } else
-        m_topPadding = m_rightPadding = m_bottomPadding = m_leftPadding = 0;
-
+    // Only copy the NodeSet in case of rect hit test.
     m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
 }
 
@@ -120,25 +168,17 @@
 
 HitTestResult& HitTestResult::operator=(const HitTestResult& other)
 {
+    HitTestPoint::operator=(other);
     m_innerNode = other.innerNode();
     m_innerNonSharedNode = other.innerNonSharedNode();
-    m_point = other.point();
     m_localPoint = other.localPoint();
     m_innerURLElement = other.URLElement();
     m_scrollbar = other.scrollbar();
     m_isOverWidget = other.isOverWidget();
-    // Only copy the padding and NodeSet in case of rect hit test.
-    // Copying the later is rather expensive.
-    if ((m_isRectBased = other.isRectBasedTest())) {
-        m_topPadding = other.m_topPadding;
-        m_rightPadding = other.m_rightPadding;
-        m_bottomPadding = other.m_bottomPadding;
-        m_leftPadding = other.m_leftPadding;
-    } else
-        m_topPadding = m_rightPadding = m_bottomPadding = m_leftPadding = 0;
 
+    // Only copy the NodeSet in case of rect hit test.
     m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
-    m_shadowContentFilterPolicy = other.shadowContentFilterPolicy();
+    m_shadowContentFilterPolicy  = other.shadowContentFilterPolicy();
 
     m_region = other.m_region;
 
@@ -198,7 +238,7 @@
     if (!frame)
         return false;
 
-    return frame->selection()->contains(m_point);
+    return frame->selection()->contains(point());
 }
 
 String HitTestResult::spellingToolTip(TextDirection& dir) const
@@ -209,7 +249,7 @@
     if (!m_innerNonSharedNode)
         return String();
     
-    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(m_point, DocumentMarker::Grammar);
+    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(point(), DocumentMarker::Grammar);
     if (!marker)
         return String();
 
@@ -225,7 +265,7 @@
     if (!m_innerNonSharedNode)
         return String();
     
-    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(m_point, DocumentMarker::Replacement);
+    DocumentMarker* marker = m_innerNonSharedNode->document()->markers()->markerContainingPoint(point(), DocumentMarker::Replacement);
     if (!marker)
         return String();
     
@@ -652,18 +692,6 @@
     }
 }
 
-IntRect HitTestResult::rectForPoint(const LayoutPoint& point, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
-{
-    IntPoint actualPoint(roundedIntPoint(point));
-    actualPoint -= IntSize(leftPadding, topPadding);
-
-    IntSize actualPadding(leftPadding + rightPadding, topPadding + bottomPadding);
-    // As IntRect is left inclusive and right exclusive (seeing IntRect::contains(x, y)), adding "1".
-    actualPadding += IntSize(1, 1);
-
-    return IntRect(actualPoint, actualPadding);
-}
-
 const HitTestResult::NodeSet& HitTestResult::rectBasedTestResult() const
 {
     if (!m_rectBasedTestResult)

Modified: trunk/Source/WebCore/rendering/HitTestResult.h (117090 => 117091)


--- trunk/Source/WebCore/rendering/HitTestResult.h	2012-05-15 17:34:45 UTC (rev 117090)
+++ trunk/Source/WebCore/rendering/HitTestResult.h	2012-05-15 17:41:34 UTC (rev 117091)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -22,6 +23,7 @@
 #define HitTestResult_h
 
 #include "FloatRect.h"
+#include "HitTestRequest.h"
 #include "LayoutTypes.h"
 #include "TextDirection.h"
 #include <wtf/Forward.h>
@@ -44,22 +46,56 @@
 
 enum ShadowContentFilterPolicy { DoNotAllowShadowContent, AllowShadowContent };
 
-class HitTestResult {
+class HitTestPoint {
 public:
+
+    HitTestPoint();
+    HitTestPoint(const LayoutPoint&);
+    // Pass non-negative padding values to perform a rect-based hit test.
+    HitTestPoint(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
+    HitTestPoint(const HitTestPoint&);
+    ~HitTestPoint();
+    HitTestPoint& operator=(const HitTestPoint&);
+
+    LayoutPoint point() const { return m_point; }
+    IntPoint roundedPoint() const { return roundedIntPoint(m_point); }
+
+    void setPoint(const LayoutPoint& p) { m_point = p; }
+
+    // Rect-based hit test related methods.
+    bool isRectBasedTest() const { return m_isRectBased; }
+    IntRect rectForPoint(const LayoutPoint&) const;
+    static IntRect rectForPoint(const LayoutPoint&, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
+    int topPadding() const { return m_topPadding; }
+    int rightPadding() const { return m_rightPadding; }
+    int bottomPadding() const { return m_bottomPadding; }
+    int leftPadding() const { return m_leftPadding; }
+
+private:
+    LayoutPoint m_point;
+
+    int m_topPadding;
+    int m_rightPadding;
+    int m_bottomPadding;
+    int m_leftPadding;
+    bool m_isRectBased;
+};
+
+class HitTestResult : public HitTestPoint {
+public:
     typedef ListHashSet<RefPtr<Node> > NodeSet;
 
     HitTestResult();
     HitTestResult(const LayoutPoint&);
     // Pass non-negative padding values to perform a rect-based hit test.
     HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, ShadowContentFilterPolicy);
+    HitTestResult(const HitTestPoint&, ShadowContentFilterPolicy);
     HitTestResult(const HitTestResult&);
     ~HitTestResult();
     HitTestResult& operator=(const HitTestResult&);
 
     Node* innerNode() const { return m_innerNode.get(); }
     Node* innerNonSharedNode() const { return m_innerNonSharedNode.get(); }
-    LayoutPoint point() const { return m_point; }
-    IntPoint roundedPoint() const { return roundedIntPoint(m_point); }
     LayoutPoint localPoint() const { return m_localPoint; }
     Element* URLElement() const { return m_innerURLElement.get(); }
     Scrollbar* scrollbar() const { return m_scrollbar.get(); }
@@ -70,11 +106,11 @@
 
     void setToNonShadowAncestor();
 
+    const HitTestPoint& hitTestPoint() const { return *this; }
     ShadowContentFilterPolicy shadowContentFilterPolicy() const { return m_shadowContentFilterPolicy; }
 
     void setInnerNode(Node*);
     void setInnerNonSharedNode(Node*);
-    void setPoint(const LayoutPoint& p) { m_point = p; }
     void setLocalPoint(const LayoutPoint& p) { m_localPoint = p; }
     void setURLElement(Element*);
     void setScrollbar(Scrollbar*);
@@ -110,15 +146,6 @@
     bool mediaMuted() const;
     void toggleMediaMuteState() const;
 
-    // Rect-based hit test related methods.
-    bool isRectBasedTest() const { return m_isRectBased; }
-    IntRect rectForPoint(const LayoutPoint&) const;
-    static IntRect rectForPoint(const LayoutPoint&, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding);
-    int topPadding() const { return m_topPadding; }
-    int rightPadding() const { return m_rightPadding; }
-    int bottomPadding() const { return m_bottomPadding; }
-    int leftPadding() const { return m_leftPadding; }
-
     // Returns true if it is rect-based hit test and needs to continue until the rect is fully
     // enclosed by the boundaries of a node.
     bool addNodeToRectBasedTestResult(Node*, const LayoutPoint& pointInContainer, const IntRect& = IntRect());
@@ -139,19 +166,14 @@
 
     RefPtr<Node> m_innerNode;
     RefPtr<Node> m_innerNonSharedNode;
-    LayoutPoint m_point;
     LayoutPoint m_localPoint; // A point in the local coordinate space of m_innerNonSharedNode's renderer. Allows us to efficiently
                               // determine where inside the renderer we hit on subsequent operations.
     RefPtr<Element> m_innerURLElement;
     RefPtr<Scrollbar> m_scrollbar;
     bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example).
-    bool m_isRectBased;
-    int m_topPadding;
-    int m_rightPadding;
-    int m_bottomPadding;
-    int m_leftPadding;
+
     ShadowContentFilterPolicy m_shadowContentFilterPolicy;
-    
+
     RenderRegion* m_region; // The region we're inside.
 
     mutable OwnPtr<NodeSet> m_rectBasedTestResult;
@@ -162,7 +184,7 @@
 // y = p.y() - topPadding
 // width = leftPadding + rightPadding + 1
 // height = topPadding + bottomPadding + 1
-inline IntRect HitTestResult::rectForPoint(const LayoutPoint& point) const
+inline IntRect HitTestPoint::rectForPoint(const LayoutPoint& point) const
 {
     return rectForPoint(point, m_topPadding, m_rightPadding, m_bottomPadding, m_leftPadding);
 }

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (117090 => 117091)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-05-15 17:34:45 UTC (rev 117090)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-05-15 17:41:34 UTC (rev 117091)
@@ -3573,7 +3573,7 @@
     // Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
     if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
         // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
-        HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding(), result.shadowContentFilterPolicy());
+        HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
             if (result.isRectBasedTest())
@@ -3602,7 +3602,7 @@
         return candidateLayer;
 
     if (bgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
-        HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding(), result.shadowContentFilterPolicy());
+        HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
         if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
             isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
             if (result.isRectBasedTest())
@@ -3658,7 +3658,7 @@
     for (int i = list->size() - 1; i >= 0; --i) {
         RenderLayer* childLayer = list->at(i);
         RenderLayer* hitLayer = 0;
-        HitTestResult tempResult(result.point(), result.topPadding(), result.rightPadding(), result.bottomPadding(), result.leftPadding(), result.shadowContentFilterPolicy());
+        HitTestResult tempResult(result.hitTestPoint(), result.shadowContentFilterPolicy());
         if (childLayer->isPaginated())
             hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestPoint, transformState, zOffsetForDescendants);
         else
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to