Bug 574778 - Fix win widget's ConstrainPosition so that it supports full screen windo...
[mozilla-central.git] / gfx / thebes / gfxRect.h
blob166a884f3d5d46530889d6781563d0a7403fcaf2
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Oracle Corporation code.
17 * The Initial Developer of the Original Code is Oracle Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Stuart Parmenter <pavlov@pavlov.net>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef GFX_RECT_H
39 #define GFX_RECT_H
41 #include "gfxTypes.h"
42 #include "gfxPoint.h"
43 #include "gfxCore.h"
44 #include "nsDebug.h"
46 namespace mozilla {
47 namespace css {
48 enum Corner {
49 // this order is important!
50 eCornerTopLeft = 0,
51 eCornerTopRight = 1,
52 eCornerBottomRight = 2,
53 eCornerBottomLeft = 3,
54 eNumCorners = 4
58 #define NS_CORNER_TOP_LEFT mozilla::css::eCornerTopLeft
59 #define NS_CORNER_TOP_RIGHT mozilla::css::eCornerTopRight
60 #define NS_CORNER_BOTTOM_RIGHT mozilla::css::eCornerBottomRight
61 #define NS_CORNER_BOTTOM_LEFT mozilla::css::eCornerBottomLeft
62 #define NS_NUM_CORNERS mozilla::css::eNumCorners
64 #define NS_FOR_CSS_CORNERS(var_) \
65 for (mozilla::css::Corner var_ = NS_CORNER_TOP_LEFT; \
66 var_ <= NS_CORNER_BOTTOM_LEFT; \
67 var_++)
69 static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int) {
70 NS_PRECONDITION(corner >= NS_CORNER_TOP_LEFT &&
71 corner < NS_NUM_CORNERS, "Out of range corner");
72 corner = mozilla::css::Corner(corner + 1);
73 return corner;
76 struct THEBES_API gfxRect {
77 // pt? point?
78 gfxPoint pos;
79 gfxSize size;
81 gfxRect() {}
82 gfxRect(const gfxRect& s) : pos(s.pos), size(s.size) {}
83 gfxRect(const gfxPoint& _pos, const gfxSize& _size) : pos(_pos), size(_size) {}
84 gfxRect(gfxFloat _x, gfxFloat _y, gfxFloat _width, gfxFloat _height) :
85 pos(_x, _y), size(_width, _height) {}
87 int operator==(const gfxRect& s) const {
88 return (pos == s.pos) && (size == s.size);
90 int operator!=(const gfxRect& s) const {
91 return (pos != s.pos) || (size != s.size);
94 const gfxRect& MoveBy(const gfxPoint& aPt) {
95 pos = pos + aPt;
96 return *this;
98 gfxRect operator+(const gfxPoint& aPt) const {
99 return gfxRect(pos + aPt, size);
101 gfxRect operator-(const gfxPoint& aPt) const {
102 return gfxRect(pos - aPt, size);
105 gfxFloat Width() const { return size.width; }
106 gfxFloat Height() const { return size.height; }
107 gfxFloat X() const { return pos.x; }
108 gfxFloat Y() const { return pos.y; }
109 gfxFloat XMost() const { return pos.x + size.width; }
110 gfxFloat YMost() const { return pos.y + size.height; }
112 PRBool IsEmpty() const { return size.width <= 0 || size.height <= 0; }
113 gfxRect Intersect(const gfxRect& aRect) const;
114 gfxRect Union(const gfxRect& aRect) const;
115 PRBool Contains(const gfxRect& aRect) const;
116 PRBool Contains(const gfxPoint& aPoint) const;
117 // XXX figure out what methods (intersect, union, etc) we use and add them.
119 gfxPoint TopLeft() { return pos; }
120 gfxPoint BottomRight() { return gfxPoint(XMost(), YMost()); }
122 void Inset(gfxFloat k) {
123 pos.x += k;
124 pos.y += k;
125 size.width = PR_MAX(0.0, size.width - k * 2.0);
126 size.height = PR_MAX(0.0, size.height - k * 2.0);
129 void Inset(gfxFloat top, gfxFloat right, gfxFloat bottom, gfxFloat left) {
130 pos.x += left;
131 pos.y += top;
132 size.width = PR_MAX(0.0, size.width - (right+left));
133 size.height = PR_MAX(0.0, size.height - (bottom+top));
136 void Inset(const gfxFloat *sides) {
137 Inset(sides[0], sides[1], sides[2], sides[3]);
140 void Outset(gfxFloat k) {
141 pos.x -= k;
142 pos.y -= k;
143 size.width = PR_MAX(0.0, size.width + k * 2.0);
144 size.height = PR_MAX(0.0, size.height + k * 2.0);
147 void Outset(gfxFloat top, gfxFloat right, gfxFloat bottom, gfxFloat left) {
148 pos.x -= left;
149 pos.y -= top;
150 size.width = PR_MAX(0.0, size.width + (right+left));
151 size.height = PR_MAX(0.0, size.height + (bottom+top));
154 void Outset(const gfxFloat *sides) {
155 Outset(sides[0], sides[1], sides[2], sides[3]);
158 // Round the rectangle edges to integer coordinates, such that the rounded
159 // rectangle has the same set of pixel centers as the original rectangle.
160 // Edges at offset 0.5 round up.
161 // Suitable for most places where integral device coordinates
162 // are needed, but note that any translation should be applied first to
163 // avoid pixel rounding errors.
164 // Note that this is *not* rounding to nearest integer if the values are negative.
165 // They are always rounding as floor(n + 0.5).
166 // See https://bugzilla.mozilla.org/show_bug.cgi?id=410748#c14
167 // If you need similar method which is using NS_round(), you should create
168 // new |RoundAwayFromZero()| method.
169 void Round();
171 // Snap the rectangle edges to integer coordinates, such that the
172 // original rectangle contains the resulting rectangle.
173 void RoundIn();
175 // Snap the rectangle edges to integer coordinates, such that the
176 // resulting rectangle contains the original rectangle.
177 void RoundOut();
179 // grabbing specific points
180 gfxPoint TopLeft() const { return gfxPoint(pos); }
181 gfxPoint TopRight() const { return pos + gfxSize(size.width, 0.0); }
182 gfxPoint BottomLeft() const { return pos + gfxSize(0.0, size.height); }
183 gfxPoint BottomRight() const { return pos + size; }
185 gfxPoint AtCorner(mozilla::css::Corner corner) const {
186 switch (corner) {
187 case NS_CORNER_TOP_LEFT: return TopLeft();
188 case NS_CORNER_TOP_RIGHT: return TopRight();
189 case NS_CORNER_BOTTOM_RIGHT: return BottomRight();
190 case NS_CORNER_BOTTOM_LEFT: return BottomLeft();
191 default:
192 NS_ERROR("Invalid corner!");
193 break;
195 return gfxPoint(0.0, 0.0);
198 gfxPoint CCWCorner(mozilla::css::Side side) const {
199 switch (side) {
200 case NS_SIDE_TOP: return TopLeft();
201 case NS_SIDE_RIGHT: return TopRight();
202 case NS_SIDE_BOTTOM: return BottomRight();
203 case NS_SIDE_LEFT: return BottomLeft();
204 default:
205 NS_ERROR("Invalid side!");
206 break;
208 return gfxPoint(0.0, 0.0);
211 gfxPoint CWCorner(mozilla::css::Side side) const {
212 switch (side) {
213 case NS_SIDE_TOP: return TopRight();
214 case NS_SIDE_RIGHT: return BottomRight();
215 case NS_SIDE_BOTTOM: return BottomLeft();
216 case NS_SIDE_LEFT: return TopLeft();
217 default:
218 NS_ERROR("Invalid side!");
219 break;
221 return gfxPoint(0.0, 0.0);
224 /* Conditions this border to Cairo's max coordinate space.
225 * The caller can check IsEmpty() after Condition() -- if it's TRUE,
226 * the caller can possibly avoid doing any extra rendering.
228 void Condition();
230 void Scale(gfxFloat k) {
231 NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor");
232 pos.x *= k;
233 pos.y *= k;
234 size.width *= k;
235 size.height *= k;
238 void Scale(gfxFloat sx, gfxFloat sy) {
239 NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor");
240 NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor");
241 pos.x *= sx;
242 pos.y *= sy;
243 size.width *= sx;
244 size.height *= sy;
247 void ScaleInverse(gfxFloat k) {
248 NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor");
249 pos.x /= k;
250 pos.y /= k;
251 size.width /= k;
252 size.height /= k;
256 struct THEBES_API gfxCornerSizes {
257 gfxSize sizes[NS_NUM_CORNERS];
259 gfxCornerSizes () { }
261 gfxCornerSizes (gfxFloat v) {
262 for (int i = 0; i < NS_NUM_CORNERS; i++)
263 sizes[i].SizeTo(v, v);
266 gfxCornerSizes (gfxFloat tl, gfxFloat tr, gfxFloat br, gfxFloat bl) {
267 sizes[NS_CORNER_TOP_LEFT].SizeTo(tl, tl);
268 sizes[NS_CORNER_TOP_RIGHT].SizeTo(tr, tr);
269 sizes[NS_CORNER_BOTTOM_RIGHT].SizeTo(br, br);
270 sizes[NS_CORNER_BOTTOM_LEFT].SizeTo(bl, bl);
273 gfxCornerSizes (const gfxSize& tl, const gfxSize& tr, const gfxSize& br, const gfxSize& bl) {
274 sizes[NS_CORNER_TOP_LEFT] = tl;
275 sizes[NS_CORNER_TOP_RIGHT] = tr;
276 sizes[NS_CORNER_BOTTOM_RIGHT] = br;
277 sizes[NS_CORNER_BOTTOM_LEFT] = bl;
280 const gfxSize& operator[] (mozilla::css::Corner index) const {
281 return sizes[index];
284 gfxSize& operator[] (mozilla::css::Corner index) {
285 return sizes[index];
288 const gfxSize TopLeft() const { return sizes[NS_CORNER_TOP_LEFT]; }
289 gfxSize& TopLeft() { return sizes[NS_CORNER_TOP_LEFT]; }
291 const gfxSize TopRight() const { return sizes[NS_CORNER_TOP_RIGHT]; }
292 gfxSize& TopRight() { return sizes[NS_CORNER_TOP_RIGHT]; }
294 const gfxSize BottomLeft() const { return sizes[NS_CORNER_BOTTOM_LEFT]; }
295 gfxSize& BottomLeft() { return sizes[NS_CORNER_BOTTOM_LEFT]; }
297 const gfxSize BottomRight() const { return sizes[NS_CORNER_BOTTOM_RIGHT]; }
298 gfxSize& BottomRight() { return sizes[NS_CORNER_BOTTOM_RIGHT]; }
300 #endif /* GFX_RECT_H */