|
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef GFX_RECT_H |
|
7 #define GFX_RECT_H |
|
8 |
|
9 #include "gfxTypes.h" |
|
10 #include "gfxPoint.h" |
|
11 #include "nsDebug.h" |
|
12 #include "nsRect.h" |
|
13 #include "mozilla/gfx/BaseMargin.h" |
|
14 #include "mozilla/gfx/BaseRect.h" |
|
15 #include "mozilla/Assertions.h" |
|
16 |
|
17 struct gfxMargin : public mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> { |
|
18 typedef mozilla::gfx::BaseMargin<gfxFloat, gfxMargin> Super; |
|
19 |
|
20 // Constructors |
|
21 gfxMargin() : Super() {} |
|
22 gfxMargin(const gfxMargin& aMargin) : Super(aMargin) {} |
|
23 gfxMargin(gfxFloat aTop, gfxFloat aRight, gfxFloat aBottom, gfxFloat aLeft) |
|
24 : Super(aTop, aRight, aBottom, aLeft) {} |
|
25 }; |
|
26 |
|
27 namespace mozilla { |
|
28 namespace css { |
|
29 enum Corner { |
|
30 // this order is important! |
|
31 eCornerTopLeft = 0, |
|
32 eCornerTopRight = 1, |
|
33 eCornerBottomRight = 2, |
|
34 eCornerBottomLeft = 3, |
|
35 eNumCorners = 4 |
|
36 }; |
|
37 } |
|
38 } |
|
39 #define NS_CORNER_TOP_LEFT mozilla::css::eCornerTopLeft |
|
40 #define NS_CORNER_TOP_RIGHT mozilla::css::eCornerTopRight |
|
41 #define NS_CORNER_BOTTOM_RIGHT mozilla::css::eCornerBottomRight |
|
42 #define NS_CORNER_BOTTOM_LEFT mozilla::css::eCornerBottomLeft |
|
43 #define NS_NUM_CORNERS mozilla::css::eNumCorners |
|
44 |
|
45 #define NS_FOR_CSS_CORNERS(var_) \ |
|
46 for (mozilla::css::Corner var_ = NS_CORNER_TOP_LEFT; \ |
|
47 var_ <= NS_CORNER_BOTTOM_LEFT; \ |
|
48 var_++) |
|
49 |
|
50 static inline mozilla::css::Corner operator++(mozilla::css::Corner& corner, int) { |
|
51 NS_PRECONDITION(corner >= NS_CORNER_TOP_LEFT && |
|
52 corner < NS_NUM_CORNERS, "Out of range corner"); |
|
53 corner = mozilla::css::Corner(corner + 1); |
|
54 return corner; |
|
55 } |
|
56 |
|
57 struct gfxRect : |
|
58 public mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> { |
|
59 typedef mozilla::gfx::BaseRect<gfxFloat, gfxRect, gfxPoint, gfxSize, gfxMargin> Super; |
|
60 |
|
61 gfxRect() : Super() {} |
|
62 gfxRect(const gfxPoint& aPos, const gfxSize& aSize) : |
|
63 Super(aPos, aSize) {} |
|
64 gfxRect(gfxFloat aX, gfxFloat aY, gfxFloat aWidth, gfxFloat aHeight) : |
|
65 Super(aX, aY, aWidth, aHeight) {} |
|
66 gfxRect(const nsIntRect& aRect) : |
|
67 Super(aRect.x, aRect.y, aRect.width, aRect.height) {} |
|
68 |
|
69 /** |
|
70 * Return true if all components of this rect are within |
|
71 * aEpsilon of integer coordinates, defined as |
|
72 * |round(coord) - coord| <= |aEpsilon| |
|
73 * for x,y,width,height. |
|
74 */ |
|
75 bool WithinEpsilonOfIntegerPixels(gfxFloat aEpsilon) const; |
|
76 |
|
77 gfxPoint AtCorner(mozilla::css::Corner corner) const { |
|
78 switch (corner) { |
|
79 case NS_CORNER_TOP_LEFT: return TopLeft(); |
|
80 case NS_CORNER_TOP_RIGHT: return TopRight(); |
|
81 case NS_CORNER_BOTTOM_RIGHT: return BottomRight(); |
|
82 case NS_CORNER_BOTTOM_LEFT: return BottomLeft(); |
|
83 default: |
|
84 NS_ERROR("Invalid corner!"); |
|
85 break; |
|
86 } |
|
87 return gfxPoint(0.0, 0.0); |
|
88 } |
|
89 |
|
90 gfxPoint CCWCorner(mozilla::css::Side side) const { |
|
91 switch (side) { |
|
92 case NS_SIDE_TOP: return TopLeft(); |
|
93 case NS_SIDE_RIGHT: return TopRight(); |
|
94 case NS_SIDE_BOTTOM: return BottomRight(); |
|
95 case NS_SIDE_LEFT: return BottomLeft(); |
|
96 } |
|
97 MOZ_CRASH("Incomplete switch"); |
|
98 } |
|
99 |
|
100 gfxPoint CWCorner(mozilla::css::Side side) const { |
|
101 switch (side) { |
|
102 case NS_SIDE_TOP: return TopRight(); |
|
103 case NS_SIDE_RIGHT: return BottomRight(); |
|
104 case NS_SIDE_BOTTOM: return BottomLeft(); |
|
105 case NS_SIDE_LEFT: return TopLeft(); |
|
106 } |
|
107 MOZ_CRASH("Incomplete switch"); |
|
108 } |
|
109 |
|
110 /* Conditions this border to Cairo's max coordinate space. |
|
111 * The caller can check IsEmpty() after Condition() -- if it's TRUE, |
|
112 * the caller can possibly avoid doing any extra rendering. |
|
113 */ |
|
114 void Condition(); |
|
115 |
|
116 void Scale(gfxFloat k) { |
|
117 NS_ASSERTION(k >= 0.0, "Invalid (negative) scale factor"); |
|
118 x *= k; |
|
119 y *= k; |
|
120 width *= k; |
|
121 height *= k; |
|
122 } |
|
123 |
|
124 void Scale(gfxFloat sx, gfxFloat sy) { |
|
125 NS_ASSERTION(sx >= 0.0, "Invalid (negative) scale factor"); |
|
126 NS_ASSERTION(sy >= 0.0, "Invalid (negative) scale factor"); |
|
127 x *= sx; |
|
128 y *= sy; |
|
129 width *= sx; |
|
130 height *= sy; |
|
131 } |
|
132 |
|
133 void ScaleInverse(gfxFloat k) { |
|
134 NS_ASSERTION(k > 0.0, "Invalid (negative) scale factor"); |
|
135 x /= k; |
|
136 y /= k; |
|
137 width /= k; |
|
138 height /= k; |
|
139 } |
|
140 }; |
|
141 |
|
142 struct gfxCornerSizes { |
|
143 gfxSize sizes[NS_NUM_CORNERS]; |
|
144 |
|
145 gfxCornerSizes () { } |
|
146 |
|
147 gfxCornerSizes (gfxFloat v) { |
|
148 for (int i = 0; i < NS_NUM_CORNERS; i++) |
|
149 sizes[i].SizeTo(v, v); |
|
150 } |
|
151 |
|
152 gfxCornerSizes (gfxFloat tl, gfxFloat tr, gfxFloat br, gfxFloat bl) { |
|
153 sizes[NS_CORNER_TOP_LEFT].SizeTo(tl, tl); |
|
154 sizes[NS_CORNER_TOP_RIGHT].SizeTo(tr, tr); |
|
155 sizes[NS_CORNER_BOTTOM_RIGHT].SizeTo(br, br); |
|
156 sizes[NS_CORNER_BOTTOM_LEFT].SizeTo(bl, bl); |
|
157 } |
|
158 |
|
159 gfxCornerSizes (const gfxSize& tl, const gfxSize& tr, const gfxSize& br, const gfxSize& bl) { |
|
160 sizes[NS_CORNER_TOP_LEFT] = tl; |
|
161 sizes[NS_CORNER_TOP_RIGHT] = tr; |
|
162 sizes[NS_CORNER_BOTTOM_RIGHT] = br; |
|
163 sizes[NS_CORNER_BOTTOM_LEFT] = bl; |
|
164 } |
|
165 |
|
166 const gfxSize& operator[] (mozilla::css::Corner index) const { |
|
167 return sizes[index]; |
|
168 } |
|
169 |
|
170 gfxSize& operator[] (mozilla::css::Corner index) { |
|
171 return sizes[index]; |
|
172 } |
|
173 |
|
174 void Scale(gfxFloat aXScale, gfxFloat aYScale) |
|
175 { |
|
176 for (int i = 0; i < NS_NUM_CORNERS; i++) |
|
177 sizes[i].Scale(aXScale, aYScale); |
|
178 } |
|
179 |
|
180 const gfxSize TopLeft() const { return sizes[NS_CORNER_TOP_LEFT]; } |
|
181 gfxSize& TopLeft() { return sizes[NS_CORNER_TOP_LEFT]; } |
|
182 |
|
183 const gfxSize TopRight() const { return sizes[NS_CORNER_TOP_RIGHT]; } |
|
184 gfxSize& TopRight() { return sizes[NS_CORNER_TOP_RIGHT]; } |
|
185 |
|
186 const gfxSize BottomLeft() const { return sizes[NS_CORNER_BOTTOM_LEFT]; } |
|
187 gfxSize& BottomLeft() { return sizes[NS_CORNER_BOTTOM_LEFT]; } |
|
188 |
|
189 const gfxSize BottomRight() const { return sizes[NS_CORNER_BOTTOM_RIGHT]; } |
|
190 gfxSize& BottomRight() { return sizes[NS_CORNER_BOTTOM_RIGHT]; } |
|
191 }; |
|
192 #endif /* GFX_RECT_H */ |