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 ***** */
40 #include "nsIDeviceContext.h"
43 PRBool
nsRect::Contains(nscoord aX
, nscoord aY
) const
45 return (PRBool
) ((aX
>= x
) && (aY
>= y
) &&
46 (aX
< XMost()) && (aY
< YMost()));
49 //Also Returns true if aRect is Empty
50 PRBool
nsRect::Contains(const nsRect
&aRect
) const
52 return aRect
.IsEmpty() ||
53 ((PRBool
) ((aRect
.x
>= x
) && (aRect
.y
>= y
) &&
54 (aRect
.XMost() <= XMost()) && (aRect
.YMost() <= YMost())));
57 // Intersection. Returns TRUE if the receiver overlaps aRect and
59 PRBool
nsRect::Intersects(const nsRect
&aRect
) const
61 return (PRBool
) ((x
< aRect
.XMost()) && (y
< aRect
.YMost()) &&
62 (aRect
.x
< XMost()) && (aRect
.y
< YMost()));
65 // Computes the area in which aRect1 and aRect2 overlap and fills 'this' with
66 // the result. Returns FALSE if the rectangles don't intersect.
67 PRBool
nsRect::IntersectRect(const nsRect
&aRect1
, const nsRect
&aRect2
)
69 nscoord xmost1
= aRect1
.XMost();
70 nscoord ymost1
= aRect1
.YMost();
71 nscoord xmost2
= aRect2
.XMost();
72 nscoord ymost2
= aRect2
.YMost();
75 x
= PR_MAX(aRect1
.x
, aRect2
.x
);
76 y
= PR_MAX(aRect1
.y
, aRect2
.y
);
78 // Compute the destination width
79 temp
= PR_MIN(xmost1
, xmost2
);
86 // Compute the destination height
87 temp
= PR_MIN(ymost1
, ymost2
);
97 // Computes the smallest rectangle that contains both aRect1 and aRect2 and
98 // fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are
99 // empty and TRUE otherwise
100 PRBool
nsRect::UnionRect(const nsRect
&aRect1
, const nsRect
&aRect2
)
102 PRBool result
= PR_TRUE
;
105 if (aRect1
.IsEmpty()) {
106 if (aRect2
.IsEmpty()) {
107 // Both rectangles are empty which is an error
111 // aRect1 is empty so set the result to aRect2
114 } else if (aRect2
.IsEmpty()) {
115 // aRect2 is empty so set the result to aRect1
118 UnionRectIncludeEmpty(aRect1
, aRect2
);
124 void nsRect::UnionRectIncludeEmpty(const nsRect
&aRect1
, const nsRect
&aRect2
)
126 nscoord xmost1
= aRect1
.XMost();
127 nscoord xmost2
= aRect2
.XMost();
128 nscoord ymost1
= aRect1
.YMost();
129 nscoord ymost2
= aRect2
.YMost();
131 // Compute the origin
132 x
= PR_MIN(aRect1
.x
, aRect2
.x
);
133 y
= PR_MIN(aRect1
.y
, aRect2
.y
);
136 width
= PR_MAX(xmost1
, xmost2
) - x
;
137 height
= PR_MAX(ymost1
, ymost2
) - y
;
140 // Inflate the rect by the specified width and height
141 void nsRect::Inflate(nscoord aDx
, nscoord aDy
)
149 // Inflate the rect by the specified margin
150 void nsRect::Inflate(const nsMargin
&aMargin
)
154 width
+= aMargin
.left
+ aMargin
.right
;
155 height
+= aMargin
.top
+ aMargin
.bottom
;
158 // Deflate the rect by the specified width and height
159 void nsRect::Deflate(nscoord aDx
, nscoord aDy
)
163 width
= PR_MAX(0, width
- 2 * aDx
);
164 height
= PR_MAX(0, height
- 2 * aDy
);
167 // Deflate the rect by the specified margin
168 void nsRect::Deflate(const nsMargin
&aMargin
)
172 width
= PR_MAX(0, width
- aMargin
.LeftRight());
173 height
= PR_MAX(0, height
- aMargin
.TopBottom());
176 // scale the rect but round to smallest containing rect
177 nsRect
& nsRect::ScaleRoundOut(float aScale
)
179 nscoord right
= NSToCoordCeil(float(XMost()) * aScale
);
180 nscoord bottom
= NSToCoordCeil(float(YMost()) * aScale
);
181 x
= NSToCoordFloor(float(x
) * aScale
);
182 y
= NSToCoordFloor(float(y
) * aScale
);
184 height
= (bottom
- y
);
188 nsRect
& nsRect::ScaleRoundOutInverse(float aScale
)
190 nscoord right
= NSToCoordCeil(float(XMost()) / aScale
);
191 nscoord bottom
= NSToCoordCeil(float(YMost()) / aScale
);
192 x
= NSToCoordFloor(float(x
) / aScale
);
193 y
= NSToCoordFloor(float(y
) / aScale
);
195 height
= (bottom
- y
);
199 // scale the rect but round to largest contained rect
200 nsRect
& nsRect::ScaleRoundIn(float aScale
)
202 nscoord right
= NSToCoordFloor(float(XMost()) * aScale
);
203 nscoord bottom
= NSToCoordFloor(float(YMost()) * aScale
);
204 x
= NSToCoordCeil(float(x
) * aScale
);
205 y
= NSToCoordCeil(float(y
) * aScale
);
207 height
= (bottom
- y
);
211 nsRect
& nsRect::ScaleRoundPreservingCentersInverse(float aScale
)
213 nscoord right
= NSToCoordRound(float(XMost()) / aScale
);
214 nscoord bottom
= NSToCoordRound(float(YMost()) / aScale
);
215 x
= NSToCoordRound(float(x
) / aScale
);
216 y
= NSToCoordRound(float(y
) / aScale
);
218 height
= (bottom
- y
);
225 FILE* operator<<(FILE* out
, const nsRect
& rect
)
229 // Output the coordinates in fractional pixels so they're easier to read
230 tmp
.AppendLiteral("{");
231 tmp
.AppendFloat(NSAppUnitsToFloatPixels(rect
.x
,
232 nsIDeviceContext::AppUnitsPerCSSPixel()));
233 tmp
.AppendLiteral(", ");
234 tmp
.AppendFloat(NSAppUnitsToFloatPixels(rect
.y
,
235 nsIDeviceContext::AppUnitsPerCSSPixel()));
236 tmp
.AppendLiteral(", ");
237 tmp
.AppendFloat(NSAppUnitsToFloatPixels(rect
.width
,
238 nsIDeviceContext::AppUnitsPerCSSPixel()));
239 tmp
.AppendLiteral(", ");
240 tmp
.AppendFloat(NSAppUnitsToFloatPixels(rect
.height
,
241 nsIDeviceContext::AppUnitsPerCSSPixel()));
242 tmp
.AppendLiteral("}");
243 fputs(NS_LossyConvertUTF16toASCII(tmp
).get(), out
);
247 #ifdef NS_COORD_IS_FLOAT
248 // Computes the area in which aRect1 and aRect2 overlap and fills 'this' with
249 // the result. Returns FALSE if the rectangles don't intersect.
250 PRBool
nsIntRect::IntersectRect(const nsIntRect
&aRect1
, const nsIntRect
&aRect2
)
252 PRInt32 xmost1
= aRect1
.XMost();
253 PRInt32 ymost1
= aRect1
.YMost();
254 PRInt32 xmost2
= aRect2
.XMost();
255 PRInt32 ymost2
= aRect2
.YMost();
258 x
= PR_MAX(aRect1
.x
, aRect2
.x
);
259 y
= PR_MAX(aRect1
.y
, aRect2
.y
);
261 // Compute the destination width
262 temp
= PR_MIN(xmost1
, xmost2
);
269 // Compute the destination height
270 temp
= PR_MIN(ymost1
, ymost2
);
280 // Computes the smallest rectangle that contains both aRect1 and aRect2 and
281 // fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are
282 // empty and TRUE otherwise
283 PRBool
nsIntRect::UnionRect(const nsIntRect
&aRect1
, const nsIntRect
&aRect2
)
285 PRBool result
= PR_TRUE
;
288 if (aRect1
.IsEmpty()) {
289 if (aRect2
.IsEmpty()) {
290 // Both rectangles are empty which is an error
294 // aRect1 is empty so set the result to aRect2
297 } else if (aRect2
.IsEmpty()) {
298 // aRect2 is empty so set the result to aRect1
301 PRInt32 xmost1
= aRect1
.XMost();
302 PRInt32 xmost2
= aRect2
.XMost();
303 PRInt32 ymost1
= aRect1
.YMost();
304 PRInt32 ymost2
= aRect2
.YMost();
306 // Compute the origin
307 x
= PR_MIN(aRect1
.x
, aRect2
.x
);
308 y
= PR_MIN(aRect1
.y
, aRect2
.y
);
311 width
= PR_MAX(xmost1
, xmost2
) - x
;
312 height
= PR_MAX(ymost1
, ymost2
) - y
;