Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / HitTestLocation.cpp
1 /*
2  * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  *
20 */
21
22 #include "config.h"
23 #include "core/rendering/HitTestLocation.h"
24
25 namespace WebCore {
26
27 HitTestLocation::HitTestLocation()
28     : m_isRectBased(false)
29     , m_isRectilinear(true)
30 {
31 }
32
33 HitTestLocation::HitTestLocation(const LayoutPoint& point)
34     : m_point(point)
35     , m_boundingBox(rectForPoint(point, 0, 0, 0, 0))
36     , m_transformedPoint(point)
37     , m_transformedRect(m_boundingBox)
38     , m_isRectBased(false)
39     , m_isRectilinear(true)
40 {
41 }
42
43 HitTestLocation::HitTestLocation(const FloatPoint& point)
44     : m_point(flooredLayoutPoint(point))
45     , m_boundingBox(rectForPoint(m_point, 0, 0, 0, 0))
46     , m_transformedPoint(point)
47     , m_transformedRect(m_boundingBox)
48     , m_isRectBased(false)
49     , m_isRectilinear(true)
50 {
51 }
52
53 HitTestLocation::HitTestLocation(const FloatPoint& point, const FloatQuad& quad)
54     : m_transformedPoint(point)
55     , m_transformedRect(quad)
56     , m_isRectBased(true)
57 {
58     m_point = flooredLayoutPoint(point);
59     m_boundingBox = enclosingIntRect(quad.boundingBox());
60     m_isRectilinear = quad.isRectilinear();
61 }
62
63 HitTestLocation::HitTestLocation(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
64     : m_point(centerPoint)
65     , m_boundingBox(rectForPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding))
66     , m_transformedPoint(centerPoint)
67     , m_isRectBased(topPadding || rightPadding || bottomPadding || leftPadding)
68     , m_isRectilinear(true)
69 {
70     m_transformedRect = FloatQuad(m_boundingBox);
71 }
72
73 HitTestLocation::HitTestLocation(const HitTestLocation& other, const LayoutSize& offset)
74     : m_point(other.m_point)
75     , m_boundingBox(other.m_boundingBox)
76     , m_transformedPoint(other.m_transformedPoint)
77     , m_transformedRect(other.m_transformedRect)
78     , m_isRectBased(other.m_isRectBased)
79     , m_isRectilinear(other.m_isRectilinear)
80 {
81     move(offset);
82 }
83
84 HitTestLocation::HitTestLocation(const HitTestLocation& other)
85     : m_point(other.m_point)
86     , m_boundingBox(other.m_boundingBox)
87     , m_transformedPoint(other.m_transformedPoint)
88     , m_transformedRect(other.m_transformedRect)
89     , m_isRectBased(other.m_isRectBased)
90     , m_isRectilinear(other.m_isRectilinear)
91 {
92 }
93
94 HitTestLocation::~HitTestLocation()
95 {
96 }
97
98 HitTestLocation& HitTestLocation::operator=(const HitTestLocation& other)
99 {
100     m_point = other.m_point;
101     m_boundingBox = other.m_boundingBox;
102     m_transformedPoint = other.m_transformedPoint;
103     m_transformedRect = other.m_transformedRect;
104     m_isRectBased = other.m_isRectBased;
105     m_isRectilinear = other.m_isRectilinear;
106
107     return *this;
108 }
109
110 void HitTestLocation::move(const LayoutSize& offset)
111 {
112     m_point.move(offset);
113     m_transformedPoint.move(offset);
114     m_transformedRect.move(offset);
115     m_boundingBox = enclosingIntRect(m_transformedRect.boundingBox());
116 }
117
118 template<typename RectType>
119 bool HitTestLocation::intersectsRect(const RectType& rect) const
120 {
121     // FIXME: When the hit test is not rect based we should use rect.contains(m_point).
122     // That does change some corner case tests though.
123
124     // First check if rect even intersects our bounding box.
125     if (!rect.intersects(m_boundingBox))
126         return false;
127
128     // If the transformed rect is rectilinear the bounding box intersection was accurate.
129     if (m_isRectilinear)
130         return true;
131
132     // If rect fully contains our bounding box, we are also sure of an intersection.
133     if (rect.contains(m_boundingBox))
134         return true;
135
136     // Otherwise we need to do a slower quad based intersection test.
137     return m_transformedRect.intersectsRect(rect);
138 }
139
140 bool HitTestLocation::intersects(const LayoutRect& rect) const
141 {
142     return intersectsRect(rect);
143 }
144
145 bool HitTestLocation::intersects(const FloatRect& rect) const
146 {
147     return intersectsRect(rect);
148 }
149
150 bool HitTestLocation::intersects(const RoundedRect& rect) const
151 {
152     return rect.intersectsQuad(m_transformedRect);
153 }
154
155 IntRect HitTestLocation::rectForPoint(const LayoutPoint& point, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding)
156 {
157     IntPoint actualPoint(flooredIntPoint(point));
158     actualPoint -= IntSize(leftPadding, topPadding);
159
160     IntSize actualPadding(leftPadding + rightPadding, topPadding + bottomPadding);
161     // As IntRect is left inclusive and right exclusive (seeing IntRect::contains(x, y)), adding "1".
162     // FIXME: Remove this once non-rect based hit-detection stops using IntRect:intersects.
163     actualPadding += IntSize(1, 1);
164
165     return IntRect(actualPoint, actualPadding);
166 }
167
168 } // namespace WebCore