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
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.
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 ***** */
49 // this order is important!
52 eCornerBottomRight
= 2,
53 eCornerBottomLeft
= 3,
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; \
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);
76 struct THEBES_API 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
) {
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
) {
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
) {
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
) {
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
) {
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.
171 // Snap the rectangle edges to integer coordinates, such that the
172 // original rectangle contains the resulting rectangle.
175 // Snap the rectangle edges to integer coordinates, such that the
176 // resulting rectangle contains the original rectangle.
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 {
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();
192 NS_ERROR("Invalid corner!");
195 return gfxPoint(0.0, 0.0);
198 gfxPoint
CCWCorner(mozilla::css::Side side
) const {
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();
205 NS_ERROR("Invalid side!");
208 return gfxPoint(0.0, 0.0);
211 gfxPoint
CWCorner(mozilla::css::Side side
) const {
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();
218 NS_ERROR("Invalid side!");
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.
230 void Scale(gfxFloat k
) {
231 NS_ASSERTION(k
>= 0.0, "Invalid (negative) scale factor");
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");
247 void ScaleInverse(gfxFloat k
) {
248 NS_ASSERTION(k
> 0.0, "Invalid (negative) scale factor");
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 {
284 gfxSize
& operator[] (mozilla::css::Corner 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 */