1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or 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 ***** */
48 #include "nsTraceRefcnt.h"
50 struct NS_GFX nsRect
{
52 nscoord width
, height
;
55 nsRect() : x(0), y(0), width(0), height(0) {
56 MOZ_COUNT_CTOR(nsRect
);
58 nsRect(const nsRect
& aRect
) {
59 MOZ_COUNT_CTOR(nsRect
);
62 nsRect(const nsPoint
& aOrigin
, const nsSize
&aSize
) {
63 MOZ_COUNT_CTOR(nsRect
);
64 x
= aOrigin
.x
; y
= aOrigin
.y
;
65 width
= aSize
.width
; height
= aSize
.height
;
67 nsRect(nscoord aX
, nscoord aY
, nscoord aWidth
, nscoord aHeight
) {
68 MOZ_COUNT_CTOR(nsRect
);
69 x
= aX
; y
= aY
; width
= aWidth
; height
= aHeight
;
70 VERIFY_COORD(x
); VERIFY_COORD(y
); VERIFY_COORD(width
); VERIFY_COORD(height
);
73 #ifdef NS_BUILD_REFCNT_LOGGING
75 MOZ_COUNT_DTOR(nsRect
);
79 // Emptiness. An empty rect is one that has no area, i.e. its height or width
81 PRBool
IsEmpty() const {
82 return (PRBool
) ((height
<= 0) || (width
<= 0));
84 void Empty() {width
= height
= 0;}
87 PRBool
Contains(const nsRect
& aRect
) const;
88 PRBool
Contains(nscoord aX
, nscoord aY
) const;
89 PRBool
Contains(const nsPoint
& aPoint
) const {return Contains(aPoint
.x
, aPoint
.y
);}
91 // Intersection. Returns TRUE if the receiver overlaps aRect and
93 PRBool
Intersects(const nsRect
& aRect
) const;
95 // Computes the area in which aRect1 and aRect2 overlap, and fills 'this' with
96 // the result. Returns FALSE if the rectangles don't intersect, and sets 'this'
97 // rect to be an empty rect.
99 // 'this' can be the same object as either aRect1 or aRect2
100 PRBool
IntersectRect(const nsRect
& aRect1
, const nsRect
& aRect2
);
102 // Computes the smallest rectangle that contains both aRect1 and aRect2 and
103 // fills 'this' with the result, ignoring empty input rectangles.
104 // Returns FALSE and sets 'this' rect to be an empty rect if both aRect1
105 // and aRect2 are empty.
107 // 'this' can be the same object as either aRect1 or aRect2
108 PRBool
UnionRect(const nsRect
& aRect1
, const nsRect
& aRect2
);
110 // Computes the smallest rectangle that contains both aRect1 and aRect2,
111 // where empty input rectangles are allowed to affect the result; the
112 // top-left of an empty input rectangle will be inside or on the edge of
115 // 'this' can be the same object as either aRect1 or aRect2
116 void UnionRectIncludeEmpty(const nsRect
& aRect1
, const nsRect
& aRect2
);
119 void SetRect(nscoord aX
, nscoord aY
, nscoord aWidth
, nscoord aHeight
) {
120 x
= aX
; y
= aY
; width
= aWidth
; height
= aHeight
;
122 void SetRect(const nsPoint
& aPt
, const nsSize
& aSize
) {
123 SetRect(aPt
.x
, aPt
.y
, aSize
.width
, aSize
.height
);
125 void MoveTo(nscoord aX
, nscoord aY
) {x
= aX
; y
= aY
;}
126 void MoveTo(const nsPoint
& aPoint
) {x
= aPoint
.x
; y
= aPoint
.y
;}
127 void MoveBy(nscoord aDx
, nscoord aDy
) {x
+= aDx
; y
+= aDy
;}
128 void MoveBy(const nsPoint
& aPoint
) {x
+= aPoint
.x
; y
+= aPoint
.y
;}
129 void SizeTo(nscoord aWidth
, nscoord aHeight
) {width
= aWidth
; height
= aHeight
;}
130 void SizeTo(const nsSize
& aSize
) {SizeTo(aSize
.width
, aSize
.height
);}
131 void SizeBy(nscoord aDeltaWidth
, nscoord aDeltaHeight
) {width
+= aDeltaWidth
;
132 height
+= aDeltaHeight
;}
134 // Inflate the rect by the specified width/height or margin
135 void Inflate(nscoord aDx
, nscoord aDy
);
136 void Inflate(const nsSize
& aSize
) {Inflate(aSize
.width
, aSize
.height
);}
137 void Inflate(const nsMargin
& aMargin
);
139 // Deflate the rect by the specified width/height or margin
140 void Deflate(nscoord aDx
, nscoord aDy
);
141 void Deflate(const nsSize
& aSize
) {Deflate(aSize
.width
, aSize
.height
);}
142 void Deflate(const nsMargin
& aMargin
);
144 // Overloaded operators. Note that '=' isn't defined so we'll get the
145 // compiler generated default assignment operator.
146 PRBool
operator==(const nsRect
& aRect
) const {
147 return (PRBool
) ((IsEmpty() && aRect
.IsEmpty()) ||
148 ((x
== aRect
.x
) && (y
== aRect
.y
) &&
149 (width
== aRect
.width
) && (height
== aRect
.height
)));
151 PRBool
operator!=(const nsRect
& aRect
) const {
152 return (PRBool
) !operator==(aRect
);
155 // Useful when we care about the exact x/y/width/height values being
156 // equal (i.e. we care about differences in empty rectangles)
157 PRBool
IsExactEqual(const nsRect
& aRect
) const {
158 return x
== aRect
.x
&& y
== aRect
.y
&&
159 width
== aRect
.width
&& height
== aRect
.height
;
162 nsRect
operator+(const nsPoint
& aPoint
) const {
163 return nsRect(x
+ aPoint
.x
, y
+ aPoint
.y
, width
, height
);
165 nsRect
operator-(const nsPoint
& aPoint
) const {
166 return nsRect(x
- aPoint
.x
, y
- aPoint
.y
, width
, height
);
168 nsRect
& operator+=(const nsPoint
& aPoint
) {x
+= aPoint
.x
; y
+= aPoint
.y
; return *this;}
169 nsRect
& operator-=(const nsPoint
& aPoint
) {x
-= aPoint
.x
; y
-= aPoint
.y
; return *this;}
171 nsRect
& operator*=(const float aScale
) {x
= NSToCoordRound(x
* aScale
);
172 y
= NSToCoordRound(y
* aScale
);
173 width
= NSToCoordRound(width
* aScale
);
174 height
= NSToCoordRound(height
* aScale
);
177 // Scale by aScale, converting coordinates to integers so that the result
178 // is the smallest integer-coordinate rectangle containing the unrounded result
179 nsRect
& ScaleRoundOut(float aScale
);
180 // Scale by the inverse of aScale, converting coordinates to integers so that the result
181 // is the smallest integer-coordinate rectangle containing the unrounded result.
182 // More accurate than ScaleRoundOut(1.0/aScale).
183 nsRect
& ScaleRoundOutInverse(float aScale
);
184 // Scale by aScale, converting coordinates to integers so that the result
185 // is the larges integer-coordinate rectangle contained in the unrounded result
186 nsRect
& ScaleRoundIn(float aScale
);
187 // Scale by the inverse of aScale, converting coordinates to integers so that
188 // the result contains the same pixel centers as the unrounded result
189 nsRect
& ScaleRoundPreservingCentersInverse(float aScale
);
191 // Helpers for accessing the vertices
192 nsPoint
TopLeft() const { return nsPoint(x
, y
); }
193 nsPoint
TopRight() const { return nsPoint(XMost(), y
); }
194 nsPoint
BottomLeft() const { return nsPoint(x
, YMost()); }
195 nsPoint
BottomRight() const { return nsPoint(XMost(), YMost()); }
197 nsSize
Size() const { return nsSize(width
, height
); }
199 // Helper methods for computing the extents
200 nscoord
XMost() const {return x
+ width
;}
201 nscoord
YMost() const {return y
+ height
;}
204 #ifdef NS_COORD_IS_FLOAT
205 struct NS_GFX nsIntRect
{
207 PRInt32 width
, height
;
210 nsIntRect() : x(0), y(0), width(0), height(0) {}
211 nsIntRect(const nsIntRect
& aRect
) {*this = aRect
;}
212 nsIntRect(PRInt32 aX
, PRInt32 aY
, PRInt32 aWidth
, PRInt32 aHeight
) {
213 x
= aX
; y
= aY
; width
= aWidth
; height
= aHeight
;
216 // Emptiness. An empty rect is one that has no area, i.e. its height or width
218 PRBool
IsEmpty() const {
219 return (PRBool
) ((height
<= 0) || (width
<= 0));
222 void SetRect(PRInt32 aX
, PRInt32 aY
, PRInt32 aWidth
, PRInt32 aHeight
) {
223 x
= aX
; y
= aY
; width
= aWidth
; height
= aHeight
;
226 // Computes the area in which aRect1 and aRect2 overlap, and fills 'this' with
227 // the result. Returns FALSE if the rectangles don't intersect, and sets 'this'
228 // rect to be an empty rect.
230 // 'this' can be the same object as either aRect1 or aRect2
231 PRBool
IntersectRect(const nsIntRect
& aRect1
, const nsIntRect
& aRect2
);
233 // Computes the smallest rectangle that contains both aRect1 and aRect2 and
234 // fills 'this' with the result. Returns FALSE and sets 'this' rect to be an
235 // empty rect if both aRect1 and aRect2 are empty
237 // 'this' can be the same object as either aRect1 or aRect2
238 PRBool
UnionRect(const nsIntRect
& aRect1
, const nsIntRect
& aRect2
);
240 // Helper methods for computing the extents
241 PRInt32
XMost() const {return x
+ width
;}
242 PRInt32
YMost() const {return y
+ height
;}
245 typedef nsRect nsIntRect
;
250 extern NS_GFX
FILE* operator<<(FILE* out
, const nsRect
& rect
);
253 #endif /* NSRECT_H */