1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef FloatQuad_h
30#define FloatQuad_h
31
32#include "FloatPoint.h"
33#include "FloatRect.h"
34#include "IntRect.h"
35
36namespace WebCore {
37
38// A FloatQuad is a collection of 4 points, often representing the result of
39// mapping a rectangle through transforms. When initialized from a rect, the
40// points are in clockwise order from top left.
41class FloatQuad {
42 WTF_MAKE_FAST_ALLOCATED;
43public:
44 FloatQuad()
45 {
46 }
47
48 FloatQuad(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3, const FloatPoint& p4)
49 : m_p1(p1)
50 , m_p2(p2)
51 , m_p3(p3)
52 , m_p4(p4)
53 {
54 }
55
56 FloatQuad(const FloatRect& inRect)
57 : m_p1(inRect.location())
58 , m_p2(inRect.maxX(), inRect.y())
59 , m_p3(inRect.maxX(), inRect.maxY())
60 , m_p4(inRect.x(), inRect.maxY())
61 {
62 }
63
64 const FloatPoint& p1() const { return m_p1; }
65 const FloatPoint& p2() const { return m_p2; }
66 const FloatPoint& p3() const { return m_p3; }
67 const FloatPoint& p4() const { return m_p4; }
68
69 void setP1(const FloatPoint& p) { m_p1 = p; }
70 void setP2(const FloatPoint& p) { m_p2 = p; }
71 void setP3(const FloatPoint& p) { m_p3 = p; }
72 void setP4(const FloatPoint& p) { m_p4 = p; }
73
74 // isEmpty tests that the bounding box is empty. This will not identify
75 // "slanted" empty quads.
76 bool isEmpty() const { return boundingBox().isEmpty(); }
77
78 // Tests whether this quad can be losslessly represented by a FloatRect,
79 // that is, if two edges are parallel to the x-axis and the other two
80 // are parallel to the y-axis. If this method returns true, the
81 // corresponding FloatRect can be retrieved with boundingBox().
82 WEBCORE_EXPORT bool isRectilinear() const;
83
84 // Tests whether the given point is inside, or on an edge or corner of this quad.
85 WEBCORE_EXPORT bool containsPoint(const FloatPoint&) const;
86
87 // Tests whether the four corners of other are inside, or coincident with the sides of this quad.
88 // Note that this only works for convex quads, but that includes all quads that originate
89 // from transformed rects.
90 WEBCORE_EXPORT bool containsQuad(const FloatQuad&) const;
91
92 // Tests whether any part of the rectangle intersects with this quad.
93 // This only works for convex quads.
94 bool intersectsRect(const FloatRect&) const;
95
96 // Test whether any part of the circle/ellipse intersects with this quad.
97 // Note that these two functions only work for convex quads.
98 bool intersectsCircle(const FloatPoint& center, float radius) const;
99 bool intersectsEllipse(const FloatPoint& center, const FloatSize& radii) const;
100
101 // The center of the quad. If the quad is the result of a affine-transformed rectangle this is the same as the original center transformed.
102 FloatPoint center() const
103 {
104 return FloatPoint((m_p1.x() + m_p2.x() + m_p3.x() + m_p4.x()) / 4.0,
105 (m_p1.y() + m_p2.y() + m_p3.y() + m_p4.y()) / 4.0);
106 }
107
108 WEBCORE_EXPORT FloatRect boundingBox() const;
109 IntRect enclosingBoundingBox() const
110 {
111 return enclosingIntRect(boundingBox());
112 }
113
114 void move(const FloatSize& offset)
115 {
116 m_p1 += offset;
117 m_p2 += offset;
118 m_p3 += offset;
119 m_p4 += offset;
120 }
121
122 void move(float dx, float dy)
123 {
124 m_p1.move(dx, dy);
125 m_p2.move(dx, dy);
126 m_p3.move(dx, dy);
127 m_p4.move(dx, dy);
128 }
129
130 void scale(float s)
131 {
132 scale(s, s);
133 }
134
135 void scale(float dx, float dy)
136 {
137 m_p1.scale(dx, dy);
138 m_p2.scale(dx, dy);
139 m_p3.scale(dx, dy);
140 m_p4.scale(dx, dy);
141 }
142
143 // Tests whether points are in clock-wise, or counter clock-wise order.
144 // Note that output is undefined when all points are colinear.
145 bool isCounterclockwise() const;
146
147private:
148 FloatPoint m_p1;
149 FloatPoint m_p2;
150 FloatPoint m_p3;
151 FloatPoint m_p4;
152};
153
154inline FloatQuad& operator+=(FloatQuad& a, const FloatSize& b)
155{
156 a.move(b);
157 return a;
158}
159
160inline FloatQuad& operator-=(FloatQuad& a, const FloatSize& b)
161{
162 a.move(-b.width(), -b.height());
163 return a;
164}
165
166inline bool operator==(const FloatQuad& a, const FloatQuad& b)
167{
168 return a.p1() == b.p1() &&
169 a.p2() == b.p2() &&
170 a.p3() == b.p3() &&
171 a.p4() == b.p4();
172}
173
174inline bool operator!=(const FloatQuad& a, const FloatQuad& b)
175{
176 return a.p1() != b.p1() ||
177 a.p2() != b.p2() ||
178 a.p3() != b.p3() ||
179 a.p4() != b.p4();
180}
181
182} // namespace WebCore
183
184
185#endif // FloatQuad_h
186
187