summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/HitTestResult.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-07-30 11:37:48 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-07-30 11:38:52 +0200
commit89e2486a48b739f8d771d69ede5a6a1b244a10fc (patch)
tree503b1a7812cf97d93704c32437eb5f62dc1a1ff9 /Source/WebCore/rendering/HitTestResult.cpp
parent625f028249cb37c55bbbd153f3902afd0b0756d9 (diff)
downloadqtwebkit-89e2486a48b739f8d771d69ede5a6a1b244a10fc.tar.gz
Imported WebKit commit 0282df8ca7c11d8c8a66ea18543695c69f545a27 (http://svn.webkit.org/repository/webkit/trunk@124002)
New snapshot with prospective Mountain Lion build fix
Diffstat (limited to 'Source/WebCore/rendering/HitTestResult.cpp')
-rw-r--r--Source/WebCore/rendering/HitTestResult.cpp90
1 files changed, 72 insertions, 18 deletions
diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp
index 541f5d0af..0f6e4b916 100644
--- a/Source/WebCore/rendering/HitTestResult.cpp
+++ b/Source/WebCore/rendering/HitTestResult.cpp
@@ -49,28 +49,76 @@ namespace WebCore {
using namespace HTMLNames;
HitTestPoint::HitTestPoint()
- : m_isRectBased(false)
+ : m_region(0)
+ , m_isRectBased(false)
+ , m_isRectilinear(true)
{
}
HitTestPoint::HitTestPoint(const LayoutPoint& point)
: m_point(point)
, m_boundingBox(rectForPoint(point, 0, 0, 0, 0))
+ , m_transformedPoint(point)
+ , m_transformedRect(m_boundingBox)
+ , m_region(0)
+ , m_isRectBased(false)
+ , m_isRectilinear(true)
+{
+}
+
+HitTestPoint::HitTestPoint(const FloatPoint& point)
+ : m_point(roundedLayoutPoint(point))
+ , m_boundingBox(rectForPoint(m_point, 0, 0, 0, 0))
+ , m_transformedPoint(point)
+ , m_transformedRect(m_boundingBox)
+ , m_region(0)
, m_isRectBased(false)
+ , m_isRectilinear(true)
{
}
+HitTestPoint::HitTestPoint(const FloatPoint& point, const FloatQuad& quad)
+ : m_transformedPoint(point)
+ , m_transformedRect(quad)
+ , m_region(0)
+ , m_isRectBased(true)
+{
+ m_point = roundedLayoutPoint(point);
+ m_boundingBox = enclosingIntRect(quad.boundingBox());
+ m_isRectilinear = quad.isRectilinear();
+}
+
HitTestPoint::HitTestPoint(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
: m_point(centerPoint)
, m_boundingBox(rectForPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding))
+ , m_transformedPoint(centerPoint)
+ , m_region(0)
, m_isRectBased(topPadding || rightPadding || bottomPadding || leftPadding)
+ , m_isRectilinear(true)
+{
+ m_transformedRect = FloatQuad(m_boundingBox);
+}
+
+HitTestPoint::HitTestPoint(const HitTestPoint& other, const LayoutSize& offset, RenderRegion* region)
+ : m_point(other.m_point)
+ , m_boundingBox(other.m_boundingBox)
+ , m_transformedPoint(other.m_transformedPoint)
+ , m_transformedRect(other.m_transformedRect)
+ , m_region(region)
+ , m_isRectBased(other.m_isRectBased)
+ , m_isRectilinear(other.m_isRectilinear)
{
+ move(offset);
}
HitTestPoint::HitTestPoint(const HitTestPoint& other)
: m_point(other.m_point)
, m_boundingBox(other.m_boundingBox)
+ , m_transformedPoint(other.m_transformedPoint)
+ , m_transformedRect(other.m_transformedRect)
+ , m_region(other.m_region)
, m_isRectBased(other.m_isRectBased)
+ , m_isRectilinear(other.m_isRectilinear)
{
}
@@ -82,40 +130,53 @@ HitTestPoint& HitTestPoint::operator=(const HitTestPoint& other)
{
m_point = other.m_point;
m_boundingBox = other.m_boundingBox;
+ m_transformedPoint = other.m_transformedPoint;
+ m_transformedRect = other.m_transformedRect;
+ m_region = other.m_region;
m_isRectBased = other.m_isRectBased;
+ m_isRectilinear = other.m_isRectilinear;
return *this;
}
-void HitTestPoint::setPoint(const LayoutPoint& point)
+void HitTestPoint::move(const LayoutSize& offset)
{
- m_boundingBox.move(roundedIntPoint(point) - roundedIntPoint(m_point));
- m_point = point;
+ m_point.move(offset);
+ m_transformedPoint.move(offset);
+ m_transformedRect.move(offset);
+ m_boundingBox = enclosingIntRect(m_transformedRect.boundingBox());
}
template<typename RectType>
-bool hitTestPointIntersects(const HitTestPoint& hitTestPoint, const RectType& rect)
+bool HitTestPoint::intersectsRect(const RectType& rect) const
{
// FIXME: When the hit test is not rect based we should use rect.contains(m_point).
// That does change some corner case tests though.
- // First check if rect even intersects our bounding rect.
- if (!rect.intersects(hitTestPoint.boundingBox()))
+ // First check if rect even intersects our bounding box.
+ if (!rect.intersects(m_boundingBox))
return false;
- // FIXME: Implement quad based intersection test to handle transformed hit test rectangles.
- return true;
+ // If the transformed rect is rectilinear the bounding box intersection was accurate.
+ if (m_isRectilinear)
+ return true;
+
+ // If rect fully contains our bounding box, we are also sure of an intersection.
+ if (rect.contains(m_boundingBox))
+ return true;
+ // Otherwise we need to do a slower quad based intersection test.
+ return m_transformedRect.intersectsRect(rect);
}
bool HitTestPoint::intersects(const LayoutRect& rect) const
{
- return hitTestPointIntersects(*this, rect);
+ return intersectsRect(rect);
}
bool HitTestPoint::intersects(const FloatRect& rect) const
{
- return hitTestPointIntersects(*this, rect);
+ return intersectsRect(rect);
}
IntRect HitTestPoint::rectForPoint(const LayoutPoint& point, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
@@ -134,14 +195,12 @@ IntRect HitTestPoint::rectForPoint(const LayoutPoint& point, unsigned topPadding
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)
{
}
@@ -149,7 +208,6 @@ HitTestResult::HitTestResult(const LayoutPoint& centerPoint, unsigned topPadding
: HitTestPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding)
, m_isOverWidget(false)
, m_shadowContentFilterPolicy(allowShadowContent)
- , m_region(0)
{
}
@@ -157,7 +215,6 @@ HitTestResult::HitTestResult(const HitTestPoint& other, ShadowContentFilterPolic
: HitTestPoint(other)
, m_isOverWidget(false)
, m_shadowContentFilterPolicy(allowShadowContent)
- , m_region(0)
{
}
@@ -170,7 +227,6 @@ HitTestResult::HitTestResult(const HitTestResult& other)
, m_scrollbar(other.scrollbar())
, m_isOverWidget(other.isOverWidget())
, m_shadowContentFilterPolicy(other.shadowContentFilterPolicy())
- , m_region(other.region())
{
// Only copy the NodeSet in case of rect hit test.
m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
@@ -194,8 +250,6 @@ HitTestResult& HitTestResult::operator=(const HitTestResult& other)
m_rectBasedTestResult = adoptPtr(other.m_rectBasedTestResult ? new NodeSet(*other.m_rectBasedTestResult) : 0);
m_shadowContentFilterPolicy = other.shadowContentFilterPolicy();
- m_region = other.m_region;
-
return *this;
}