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 "platform/geometry/FloatPoint.h" 31#include "third_party/skia/include/core/SkRect.h" 32#include "wtf/Vector.h" 33 34#if OS(MACOSX) 35typedef struct CGRect CGRect; 36 37#ifdef __OBJC__ 38#import <Foundation/Foundation.h> 39#endif 40#endif 41 42namespace blink { 43 44class LayoutRect; 45class IntRect; 46 47class PLATFORM_EXPORT FloatRect { 48public: 49 enum ContainsMode { 50 InsideOrOnStroke, 51 InsideButNotOnStroke 52 }; 53 54 FloatRect() { } 55 FloatRect(const FloatPoint& location, const FloatSize& size) 56 : m_location(location), m_size(size) { } 57 FloatRect(float x, float y, float width, float height) 58 : m_location(FloatPoint(x, y)), m_size(FloatSize(width, height)) { } 59 FloatRect(const IntRect&); 60 FloatRect(const LayoutRect&); 61 FloatRect(const SkRect&); 62 63 static FloatRect narrowPrecision(double x, double y, double width, double height); 64 65 FloatPoint location() const { return m_location; } 66 FloatSize size() const { return m_size; } 67 68 void setLocation(const FloatPoint& location) { m_location = location; } 69 void setSize(const FloatSize& size) { m_size = size; } 70 71 float x() const { return m_location.x(); } 72 float y() const { return m_location.y(); } 73 float maxX() const { return x() + width(); } 74 float maxY() const { return y() + height(); } 75 float width() const { return m_size.width(); } 76 float height() const { return m_size.height(); } 77 78 void setX(float x) { m_location.setX(x); } 79 void setY(float y) { m_location.setY(y); } 80 void setWidth(float width) { m_size.setWidth(width); } 81 void setHeight(float height) { m_size.setHeight(height); } 82 83 bool isEmpty() const { return m_size.isEmpty(); } 84 bool isZero() const { return m_size.isZero(); } 85 bool isExpressibleAsIntRect() const; 86 87 FloatPoint center() const { return FloatPoint(x() + width() / 2, y() + height() / 2); } 88 89 void move(const FloatSize& delta) { m_location += delta; } 90 void moveBy(const FloatPoint& delta) { m_location.move(delta.x(), delta.y()); } 91 void move(float dx, float dy) { m_location.move(dx, dy); } 92 93 void expand(const FloatSize& size) { m_size += size; } 94 void expand(float dw, float dh) { m_size.expand(dw, dh); } 95 void contract(const FloatSize& size) { m_size -= size; } 96 void contract(float dw, float dh) { m_size.expand(-dw, -dh); } 97 98 void shiftXEdgeTo(float edge) 99 { 100 float delta = edge - x(); 101 setX(edge); 102 setWidth(std::max(0.0f, width() - delta)); 103 } 104 void shiftMaxXEdgeTo(float edge) 105 { 106 float delta = edge - maxX(); 107 setWidth(std::max(0.0f, width() + delta)); 108 } 109 void shiftYEdgeTo(float edge) 110 { 111 float delta = edge - y(); 112 setY(edge); 113 setHeight(std::max(0.0f, height() - delta)); 114 } 115 void shiftMaxYEdgeTo(float edge) 116 { 117 float delta = edge - maxY(); 118 setHeight(std::max(0.0f, height() + delta)); 119 } 120 121 FloatPoint minXMinYCorner() const { return m_location; } // typically topLeft 122 FloatPoint maxXMinYCorner() const { return FloatPoint(m_location.x() + m_size.width(), m_location.y()); } // typically topRight 123 FloatPoint minXMaxYCorner() const { return FloatPoint(m_location.x(), m_location.y() + m_size.height()); } // typically bottomLeft 124 FloatPoint maxXMaxYCorner() const { return FloatPoint(m_location.x() + m_size.width(), m_location.y() + m_size.height()); } // typically bottomRight 125 126 bool intersects(const FloatRect&) const; 127 bool contains(const FloatRect&) const; 128 bool contains(const FloatPoint&, ContainsMode = InsideOrOnStroke) const; 129 130 void intersect(const FloatRect&); 131 void unite(const FloatRect&); 132 void uniteEvenIfEmpty(const FloatRect&); 133 void uniteIfNonZero(const FloatRect&); 134 void extend(const FloatPoint&); 135 136 // Note, this doesn't match what IntRect::contains(IntPoint&) does; the int version 137 // is really checking for containment of 1x1 rect, but that doesn't make sense with floats. 138 bool contains(float px, float py) const 139 { 140 return px >= x() && px <= maxX() && py >= y() && py <= maxY(); 141 } 142 143 void inflateX(float dx) 144 { 145 m_location.setX(m_location.x() - dx); 146 m_size.setWidth(m_size.width() + dx + dx); 147 } 148 void inflateY(float dy) 149 { 150 m_location.setY(m_location.y() - dy); 151 m_size.setHeight(m_size.height() + dy + dy); 152 } 153 void inflate(float d) { inflateX(d); inflateY(d); } 154 void scale(float s) { scale(s, s); } 155 void scale(float sx, float sy); 156 157 FloatRect transposedRect() const { return FloatRect(m_location.transposedPoint(), m_size.transposedSize()); } 158 159 // Re-initializes this rectangle to fit the sets of passed points. 160 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1); 161 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2); 162 void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3); 163 164#if OS(MACOSX) 165 FloatRect(const CGRect&); 166 operator CGRect() const; 167#if defined(__OBJC__) && !defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) 168 FloatRect(const NSRect&); 169 operator NSRect() const; 170#endif 171#endif 172 173 operator SkRect() const { return SkRect::MakeXYWH(x(), y(), width(), height()); } 174 175private: 176 FloatPoint m_location; 177 FloatSize m_size; 178 179 void setLocationAndSizeFromEdges(float left, float top, float right, float bottom) 180 { 181 m_location.set(left, top); 182 m_size.setWidth(right - left); 183 m_size.setHeight(bottom - top); 184 } 185}; 186 187inline FloatRect intersection(const FloatRect& a, const FloatRect& b) 188{ 189 FloatRect c = a; 190 c.intersect(b); 191 return c; 192} 193 194inline FloatRect unionRect(const FloatRect& a, const FloatRect& b) 195{ 196 FloatRect c = a; 197 c.unite(b); 198 return c; 199} 200 201FloatRect unionRect(const Vector<FloatRect>&); 202 203inline FloatRect& operator+=(FloatRect& a, const FloatRect& b) 204{ 205 a.move(b.x(), b.y()); 206 a.setWidth(a.width() + b.width()); 207 a.setHeight(a.height() + b.height()); 208 return a; 209} 210 211inline FloatRect operator+(const FloatRect& a, const FloatRect& b) 212{ 213 FloatRect c = a; 214 c += b; 215 return c; 216} 217 218inline bool operator==(const FloatRect& a, const FloatRect& b) 219{ 220 return a.location() == b.location() && a.size() == b.size(); 221} 222 223inline bool operator!=(const FloatRect& a, const FloatRect& b) 224{ 225 return a.location() != b.location() || a.size() != b.size(); 226} 227 228PLATFORM_EXPORT IntRect enclosingIntRect(const FloatRect&); 229 230// Returns a valid IntRect contained within the given FloatRect. 231PLATFORM_EXPORT IntRect enclosedIntRect(const FloatRect&); 232 233PLATFORM_EXPORT IntRect roundedIntRect(const FloatRect&); 234 235// Map supplied rect from srcRect to an equivalent rect in destRect. 236PLATFORM_EXPORT FloatRect mapRect(const FloatRect&, const FloatRect& srcRect, const FloatRect& destRect); 237 238} 239 240#endif 241