1/* 2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. 3 * Copyright (C) 2005 Nokia. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#ifndef FloatRect_h 28#define FloatRect_h 29 30#include "FloatPoint.h" 31#include <wtf/Vector.h> 32 33#if USE(CG) 34typedef struct CGRect CGRect; 35#endif 36 37#if PLATFORM(MAC) 38#ifdef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES 39typedef struct CGRect NSRect; 40#else 41typedef struct _NSRect NSRect; 42#endif 43#endif 44 45#if PLATFORM(QT) 46QT_BEGIN_NAMESPACE 47class QRectF; 48QT_END_NAMESPACE 49#endif 50 51#if PLATFORM(BLACKBERRY) 52namespace BlackBerry { 53namespace Platform { 54class FloatRect; 55} 56} 57#endif 58 59#if USE(CAIRO) 60typedef struct _cairo_rectangle cairo_rectangle_t; 61#endif 62 63namespace WebCore { 64 65class LayoutRect; 66class IntRect; 67class IntPoint; 68 69class FloatRect { 70public: 71 enum ContainsMode { 72 InsideOrOnStroke, 73 InsideButNotOnStroke 74 }; 75 76 FloatRect() { } 77 FloatRect(const FloatPoint& location, const FloatSize& size) 78 : m_location(location), m_size(size) { } 79 FloatRect(float x, float y, float width, float height) 80 : m_location(FloatPoint(x, y)), m_size(FloatSize(width, height)) { } 81 FloatRect(const IntRect&); 82 FloatRect(const LayoutRect&); 83 84 static FloatRect narrowPrecision(double x, double y, double width, double height); 85 86 FloatPoint location() const { return m_location; } 87 FloatSize size() const { return m_size; } 88 89 void setLocation(const FloatPoint& location) { m_location = location; } 90 void setSize(const FloatSize& size) { m_size = size; } 91 92 float x() const { return m_location.x(); } 93 float y() const { return m_location.y(); } 94 float maxX() const { return x() + width(); } 95 float maxY() const { return y() + height(); } 96 float width() const { return m_size.width(); } 97 float height() const { return m_size.height(); } 98 99 void setX(float x) { m_location.setX(x); } 100 void setY(float y) { m_location.setY(y); } 101 void setWidth(float width) { m_size.setWidth(width); } 102 void setHeight(float height) { m_size.setHeight(height); } 103 104 bool isEmpty() const { return m_size.isEmpty(); } 105 bool isZero() const { return m_size.isZero(); } 106 bool isExpressibleAsIntRect() const; 107 108 FloatPoint center() const { return FloatPoint(x() + width() / 2, y() + height() / 2); } 109 110 void move(const FloatSize& delta) { m_location += delta; } 111 void moveBy(const FloatPoint& delta) { m_location.move(delta.x(), delta.y()); } 112 void move(float dx, float dy) { m_location.move(dx, dy); } 113 114 void expand(const FloatSize& size) { m_size += size; } 115 void expand(float dw, float dh) { m_size.expand(dw, dh); } 116 void contract(const FloatSize& size) { m_size -= size; } 117 void contract(float dw, float dh) { m_size.expand(-dw, -dh); } 118 119 void shiftXEdgeTo(float edge) 120 { 121 float delta = edge - x(); 122 setX(edge); 123 setWidth(std::max(0.0f, width() - delta)); 124 } 125 void shiftMaxXEdgeTo(float edge) 126 { 127 float delta = edge - maxX(); 128 setWidth(std::max(0.0f, width() + delta)); 129 } 130 void shiftYEdgeTo(float edge) 131 { 132 float delta = edge - y(); 133 setY(edge); 134 setHeight(std::max(0.0f, height() - delta)); 135 } 136 void shiftMaxYEdgeTo(float edge) 137 { 138 float delta = edge - maxY(); 139 setHeight(std::max(0.0f, height() + delta)); 140 } 141 142 FloatPoint minXMinYCorner() const { return m_location; } // typically topLeft 143 FloatPoint maxXMinYCorner() const { return FloatPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight 144 FloatPoint minXMaxYCorner() const { return FloatPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft 145 FloatPoint maxXMaxYCorner() const { return FloatPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight 146 147 bool intersects(const FloatRect&) const; 148 bool contains(const FloatRect&) const; 149 bool contains(const FloatPoint&, ContainsMode = InsideOrOnStroke) const; 150 151 void intersect(const FloatRect&); 152 void unite(const FloatRect&); 153 void uniteEvenIfEmpty(const FloatRect&); 154 void uniteIfNonZero(const FloatRect&); 155 void extend(const FloatPoint&); 156 157 // Note, this doesn't match what IntRect::contains(IntPoint&) does; the int version 158 // is really checking for containment of 1x1 rect, but that doesn't make sense with floats. 159 bool contains(float px, float py) const 160 { return px >= x() && px <= maxX() && py >= y() && py <= maxY(); } 161 162 void inflateX(float dx) { 163 m_location.setX(m_location.x() - dx); 164 m_size.setWidth(m_size.width() + dx + dx); 165 } 166 void inflateY(float dy) { 167 m_location.setY(m_location.y() - dy); 168 m_size.setHeight(m_size.height() + dy + dy); 169 } 170 void inflate(float d) { inflateX(d); inflateY(d); } 171 void scale(float s) { scale(s, s); } 172 void scale(float sx, float sy); 173 174 FloatRect transposedRect() const { return FloatRect(m_location.transposedPoint(), m_size.transposedSize()); } 175 176 // Re-initializes this rectangle to fit the sets of passed points. 177 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1); 178 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2); 179 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3); 180 181#if PLATFORM(BLACKBERRY) 182 FloatRect(const BlackBerry::Platform::FloatRect&); 183 operator BlackBerry::Platform::FloatRect() const; 184 FloatRect normalized() const; 185#endif 186 187#if USE(CG) 188 FloatRect(const CGRect&); 189 operator CGRect() const; 190#endif 191 192#if PLATFORM(MAC) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) 193 FloatRect(const NSRect&); 194 operator NSRect() const; 195#endif 196 197#if PLATFORM(QT) 198 FloatRect(const QRectF&); 199 operator QRectF() const; 200 FloatRect normalized() const; 201#endif 202 203#if USE(CAIRO) 204 FloatRect(const cairo_rectangle_t&); 205 operator cairo_rectangle_t() const; 206#endif 207 208private: 209 FloatPoint m_location; 210 FloatSize m_size; 211 212 void setLocationAndSizeFromEdges(float left, float top, float right, float bottom) 213 { 214 m_location.set(left, top); 215 m_size.setWidth(right - left); 216 m_size.setHeight(bottom - top); 217 } 218}; 219 220inline FloatRect intersection(const FloatRect& a, const FloatRect& b) 221{ 222 FloatRect c = a; 223 c.intersect(b); 224 return c; 225} 226 227inline FloatRect unionRect(const FloatRect& a, const FloatRect& b) 228{ 229 FloatRect c = a; 230 c.unite(b); 231 return c; 232} 233 234FloatRect unionRect(const Vector<FloatRect>&); 235 236inline FloatRect& operator+=(FloatRect& a, const FloatRect& b) 237{ 238 a.move(b.x(), b.y()); 239 a.setWidth(a.width() + b.width()); 240 a.setHeight(a.height() + b.height()); 241 return a; 242} 243 244inline FloatRect operator+(const FloatRect& a, const FloatRect& b) 245{ 246 FloatRect c = a; 247 c += b; 248 return c; 249} 250 251inline bool operator==(const FloatRect& a, const FloatRect& b) 252{ 253 return a.location() == b.location() && a.size() == b.size(); 254} 255 256inline bool operator!=(const FloatRect& a, const FloatRect& b) 257{ 258 return a.location() != b.location() || a.size() != b.size(); 259} 260 261IntRect enclosingIntRect(const FloatRect&); 262 263// Returns a valid IntRect contained within the given FloatRect. 264IntRect enclosedIntRect(const FloatRect&); 265 266IntRect roundedIntRect(const FloatRect&); 267 268// Map rect r from srcRect to an equivalent rect in destRect. 269FloatRect mapRect(const FloatRect& r, const FloatRect& srcRect, const FloatRect& destRect); 270 271} 272 273#endif 274