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