diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-30 11:37:48 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-07-30 11:38:52 +0200 |
commit | 89e2486a48b739f8d771d69ede5a6a1b244a10fc (patch) | |
tree | 503b1a7812cf97d93704c32437eb5f62dc1a1ff9 /Source/WebCore/rendering/HitTestResult.cpp | |
parent | 625f028249cb37c55bbbd153f3902afd0b0756d9 (diff) | |
download | qtwebkit-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.cpp | 90 |
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; } |