/work/obj-fuzz/dist/include/mozilla/gfx/RectAbsolute.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef MOZILLA_GFX_RECT_ABSOLUTE_H_ |
8 | | #define MOZILLA_GFX_RECT_ABSOLUTE_H_ |
9 | | |
10 | | #include <algorithm> |
11 | | #include <cstdint> |
12 | | |
13 | | #include "mozilla/Attributes.h" |
14 | | #include "Rect.h" |
15 | | #include "Types.h" |
16 | | |
17 | | namespace mozilla { |
18 | | |
19 | | template <typename> struct IsPixel; |
20 | | |
21 | | namespace gfx { |
22 | | |
23 | | /** |
24 | | * A RectAbsolute is similar to a Rect (see BaseRect.h), but represented as |
25 | | * (x1, y1, x2, y2) instead of (x, y, width, height). |
26 | | * |
27 | | * Unless otherwise indicated, methods on this class correspond |
28 | | * to methods on BaseRect. |
29 | | * |
30 | | * The API is currently very bare-bones; it may be extended as needed. |
31 | | * |
32 | | * Do not use this class directly. Subclass it, pass that subclass as the |
33 | | * Sub parameter, and only use that subclass. |
34 | | */ |
35 | | template <class T, class Sub, class Rect> |
36 | | struct BaseRectAbsolute { |
37 | | protected: |
38 | | T left, top, right, bottom; |
39 | | |
40 | | public: |
41 | 0 | BaseRectAbsolute() : left(0), top(0), right(0), bottom(0) {} Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::BaseRectAbsolute() Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::BaseRectAbsolute() Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::BaseRectAbsolute() |
42 | | BaseRectAbsolute(T aLeft, T aTop, T aRight, T aBottom) : |
43 | 0 | left(aLeft), top(aTop), right(aRight), bottom(aBottom) {} Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::BaseRectAbsolute(int, int, int, int) Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::BaseRectAbsolute(int, int, int, int) Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::BaseRectAbsolute(float, float, float, float) |
44 | | |
45 | 0 | MOZ_ALWAYS_INLINE T X() const { return left; } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::X() const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::X() const |
46 | 0 | MOZ_ALWAYS_INLINE T Y() const { return top; } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::Y() const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::Y() const |
47 | 0 | MOZ_ALWAYS_INLINE T Width() const { return right - left; } |
48 | 0 | MOZ_ALWAYS_INLINE T Height() const { return bottom - top; } |
49 | 0 | MOZ_ALWAYS_INLINE T XMost() const { return right; } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::XMost() const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::XMost() const |
50 | 0 | MOZ_ALWAYS_INLINE T YMost() const { return bottom; } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::YMost() const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::YMost() const |
51 | 0 | MOZ_ALWAYS_INLINE const T& Left() const { return left; } |
52 | 0 | MOZ_ALWAYS_INLINE const T& Right() const { return right; } |
53 | 0 | MOZ_ALWAYS_INLINE const T& Top() const { return top; } |
54 | 0 | MOZ_ALWAYS_INLINE const T& Bottom() const { return bottom; } |
55 | | MOZ_ALWAYS_INLINE T& Left() { return left; } |
56 | | MOZ_ALWAYS_INLINE T& Right() { return right; } |
57 | | MOZ_ALWAYS_INLINE T& Top() { return top; } |
58 | | MOZ_ALWAYS_INLINE T& Bottom() { return bottom; } |
59 | 0 | T Area() const { return Width() * Height(); } |
60 | | |
61 | | void Inflate(T aD) { Inflate(aD, aD); } |
62 | | void Inflate(T aDx, T aDy) |
63 | | { |
64 | | left -= aDx; |
65 | | top -= aDy; |
66 | | right += aDx; |
67 | | bottom += aDy; |
68 | | } |
69 | | |
70 | | MOZ_ALWAYS_INLINE void SetBox(T aLeft, T aTop, T aRight, T aBottom) |
71 | 0 | { |
72 | 0 | left = aLeft; top = aTop; right = aRight; bottom = aBottom; |
73 | 0 | } |
74 | | void SetLeftEdge(T aLeft) |
75 | 0 | { |
76 | 0 | left = aLeft; |
77 | 0 | } |
78 | | void SetRightEdge(T aRight) |
79 | 0 | { |
80 | 0 | right = aRight; |
81 | 0 | } |
82 | | void SetTopEdge(T aTop) |
83 | 0 | { |
84 | 0 | top = aTop; |
85 | 0 | } |
86 | | void SetBottomEdge(T aBottom) |
87 | 0 | { |
88 | 0 | bottom = aBottom; |
89 | 0 | } |
90 | | |
91 | | static Sub FromRect(const Rect& aRect) |
92 | 0 | { |
93 | 0 | if (aRect.Overflows()) { |
94 | 0 | return Sub(); |
95 | 0 | } |
96 | 0 | return Sub(aRect.x, aRect.y, aRect.XMost(), aRect.YMost()); |
97 | 0 | } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::FromRect(nsRect const&) Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::FromRect(mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const&) |
98 | | |
99 | | MOZ_MUST_USE Sub Intersect(const Sub& aOther) const |
100 | 0 | { |
101 | 0 | Sub result; |
102 | 0 | result.left = std::max<T>(left, aOther.left); |
103 | 0 | result.top = std::max<T>(top, aOther.top); |
104 | 0 | result.right = std::min<T>(right, aOther.right); |
105 | 0 | result.bottom = std::min<T>(bottom, aOther.bottom); |
106 | 0 | if (result.right < result.left || result.bottom < result.top) { |
107 | 0 | result.SizeTo(0, 0); |
108 | 0 | } |
109 | 0 | return result; |
110 | 0 | } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::Intersect(nsRectAbsolute const&) const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::Intersect(mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits> const&) const |
111 | | |
112 | 0 | bool IsEmpty() const { |
113 | 0 | return right <= left || bottom <= top; |
114 | 0 | } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::IsEmpty() const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::IsEmpty() const |
115 | | |
116 | | bool IsEqualEdges(const Sub& aOther) const |
117 | 0 | { |
118 | 0 | return left == aOther.left && top == aOther.top && |
119 | 0 | right == aOther.right && bottom == aOther.bottom; |
120 | 0 | } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::IsEqualEdges(nsRectAbsolute const&) const Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<float, mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel>, mozilla::gfx::RectTyped<mozilla::LayerPixel, float> >::IsEqualEdges(mozilla::gfx::RectAbsoluteTyped<mozilla::LayerPixel> const&) const |
121 | | |
122 | | bool IsEqualInterior(const Sub& aRect) const |
123 | 0 | { |
124 | 0 | return IsEqualEdges(aRect) || (IsEmpty() && aRect.IsEmpty()); |
125 | 0 | } |
126 | | |
127 | | MOZ_ALWAYS_INLINE void MoveBy(T aDx, T aDy) { left += aDx; right += aDx; top += aDy; bottom += aDy; } |
128 | | MOZ_ALWAYS_INLINE void MoveBy(const Point& aPoint) { left += aPoint.x; right += aPoint.x; top += aPoint.y; bottom += aPoint.y; } |
129 | 0 | MOZ_ALWAYS_INLINE void SizeTo(T aWidth, T aHeight) { right = left + aWidth; bottom = top + aHeight; } Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, nsRectAbsolute, nsRect>::SizeTo(int, int) Unexecuted instantiation: mozilla::gfx::BaseRectAbsolute<int, mozilla::gfx::IntRectAbsoluteTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> >::SizeTo(int, int) |
130 | | |
131 | | bool Contains(const Sub& aRect) const |
132 | 0 | { |
133 | 0 | return aRect.IsEmpty() || |
134 | 0 | (left <= aRect.left && aRect.right <= right && |
135 | 0 | top <= aRect.top && aRect.bottom <= bottom); |
136 | 0 | } |
137 | | bool Contains(T aX, T aY) const |
138 | 0 | { |
139 | 0 | return (left <= aX && aX < right && |
140 | 0 | top <= aY && aY < bottom); |
141 | 0 | } |
142 | | |
143 | | bool Intersects(const Sub& aRect) const |
144 | 0 | { |
145 | 0 | return !IsEmpty() && !aRect.IsEmpty() && |
146 | 0 | left < aRect.right && aRect.left < right && |
147 | 0 | top < aRect.bottom && aRect.top < bottom; |
148 | 0 | } |
149 | | |
150 | 0 | void SetEmpty() { |
151 | 0 | left = right = top = bottom = 0; |
152 | 0 | } |
153 | | |
154 | | // Returns the smallest rectangle that contains both the area of both |
155 | | // this and aRect2. |
156 | | // Thus, empty input rectangles are ignored. |
157 | | // If both rectangles are empty, returns this. |
158 | | // WARNING! This is not safe against overflow, prefer using SafeUnion instead |
159 | | // when dealing with int-based rects. |
160 | | MOZ_MUST_USE Sub Union(const Sub& aRect) const |
161 | 0 | { |
162 | 0 | if (IsEmpty()) { |
163 | 0 | return aRect; |
164 | 0 | } else if (aRect.IsEmpty()) { |
165 | 0 | return *static_cast<const Sub*>(this); |
166 | 0 | } else { |
167 | 0 | return UnionEdges(aRect); |
168 | 0 | } |
169 | 0 | } |
170 | | // Returns the smallest rectangle that contains both the points (including |
171 | | // edges) of both aRect1 and aRect2. |
172 | | // Thus, empty input rectangles are allowed to affect the result. |
173 | | // WARNING! This is not safe against overflow, prefer using SafeUnionEdges |
174 | | // instead when dealing with int-based rects. |
175 | | MOZ_MUST_USE Sub UnionEdges(const Sub& aRect) const |
176 | 0 | { |
177 | 0 | Sub result; |
178 | 0 | result.left = std::min(left, aRect.left); |
179 | 0 | result.top = std::min(top, aRect.top); |
180 | 0 | result.right = std::max(XMost(), aRect.XMost()); |
181 | 0 | result.bottom = std::max(YMost(), aRect.YMost()); |
182 | 0 | return result; |
183 | 0 | } |
184 | | |
185 | | // Scale 'this' by aScale without doing any rounding. |
186 | | void Scale(T aScale) { Scale(aScale, aScale); } |
187 | | // Scale 'this' by aXScale and aYScale, without doing any rounding. |
188 | | void Scale(T aXScale, T aYScale) |
189 | | { |
190 | | right = XMost() * aXScale; |
191 | | bottom = YMost() * aYScale; |
192 | | left = left * aXScale; |
193 | | top = top * aYScale; |
194 | | } |
195 | | // Scale 'this' by aScale, converting coordinates to integers so that the result is |
196 | | // the smallest integer-coordinate rectangle containing the unrounded result. |
197 | | // Note: this can turn an empty rectangle into a non-empty rectangle |
198 | | void ScaleRoundOut(double aScale) { ScaleRoundOut(aScale, aScale); } |
199 | | // Scale 'this' by aXScale and aYScale, converting coordinates to integers so |
200 | | // that the result is the smallest integer-coordinate rectangle containing the |
201 | | // unrounded result. |
202 | | // Note: this can turn an empty rectangle into a non-empty rectangle |
203 | | void ScaleRoundOut(double aXScale, double aYScale) |
204 | 0 | { |
205 | 0 | right = static_cast<T>(ceil(double(XMost()) * aXScale)); |
206 | 0 | bottom = static_cast<T>(ceil(double(YMost()) * aYScale)); |
207 | 0 | left = static_cast<T>(floor(double(left) * aXScale)); |
208 | 0 | top = static_cast<T>(floor(double(top) * aYScale)); |
209 | 0 | } |
210 | | // Scale 'this' by aScale, converting coordinates to integers so that the result is |
211 | | // the largest integer-coordinate rectangle contained by the unrounded result. |
212 | | void ScaleRoundIn(double aScale) { ScaleRoundIn(aScale, aScale); } |
213 | | // Scale 'this' by aXScale and aYScale, converting coordinates to integers so |
214 | | // that the result is the largest integer-coordinate rectangle contained by the |
215 | | // unrounded result. |
216 | | void ScaleRoundIn(double aXScale, double aYScale) |
217 | | { |
218 | | right = static_cast<T>(floor(double(XMost()) * aXScale)); |
219 | | bottom = static_cast<T>(floor(double(YMost()) * aYScale)); |
220 | | left = static_cast<T>(ceil(double(left) * aXScale)); |
221 | | top = static_cast<T>(ceil(double(top) * aYScale)); |
222 | | } |
223 | | // Scale 'this' by 1/aScale, converting coordinates to integers so that the result is |
224 | | // the smallest integer-coordinate rectangle containing the unrounded result. |
225 | | // Note: this can turn an empty rectangle into a non-empty rectangle |
226 | | void ScaleInverseRoundOut(double aScale) { ScaleInverseRoundOut(aScale, aScale); } |
227 | | // Scale 'this' by 1/aXScale and 1/aYScale, converting coordinates to integers so |
228 | | // that the result is the smallest integer-coordinate rectangle containing the |
229 | | // unrounded result. |
230 | | // Note: this can turn an empty rectangle into a non-empty rectangle |
231 | | void ScaleInverseRoundOut(double aXScale, double aYScale) |
232 | 0 | { |
233 | 0 | right = static_cast<T>(ceil(double(XMost()) / aXScale)); |
234 | 0 | bottom = static_cast<T>(ceil(double(YMost()) / aYScale)); |
235 | 0 | left = static_cast<T>(floor(double(left) / aXScale)); |
236 | 0 | top = static_cast<T>(floor(double(top) / aYScale)); |
237 | 0 | } |
238 | | // Scale 'this' by 1/aScale, converting coordinates to integers so that the result is |
239 | | // the largest integer-coordinate rectangle contained by the unrounded result. |
240 | | void ScaleInverseRoundIn(double aScale) { ScaleInverseRoundIn(aScale, aScale); } |
241 | | // Scale 'this' by 1/aXScale and 1/aYScale, converting coordinates to integers so |
242 | | // that the result is the largest integer-coordinate rectangle contained by the |
243 | | // unrounded result. |
244 | | void ScaleInverseRoundIn(double aXScale, double aYScale) |
245 | | { |
246 | | right = static_cast<T>(floor(double(XMost()) / aXScale)); |
247 | | bottom = static_cast<T>(floor(double(YMost()) / aYScale)); |
248 | | left = static_cast<T>(ceil(double(left) / aXScale)); |
249 | | top = static_cast<T>(ceil(double(top) / aYScale)); |
250 | | } |
251 | | |
252 | | }; |
253 | | |
254 | | template <class Units> |
255 | | struct IntRectAbsoluteTyped : |
256 | | public BaseRectAbsolute<int32_t, IntRectAbsoluteTyped<Units>, IntRectTyped<Units>>, |
257 | | public Units { |
258 | | static_assert(IsPixel<Units>::value, |
259 | | "'units' must be a coordinate system tag"); |
260 | | typedef BaseRectAbsolute<int32_t, IntRectAbsoluteTyped<Units>, IntRectTyped<Units>> Super; |
261 | | typedef IntParam<int32_t> ToInt; |
262 | | |
263 | 0 | IntRectAbsoluteTyped() : Super() {} |
264 | | IntRectAbsoluteTyped(ToInt aLeft, ToInt aTop, ToInt aRight, ToInt aBottom) : |
265 | 0 | Super(aLeft.value, aTop.value, aRight.value, aBottom.value) {} |
266 | | }; |
267 | | |
268 | | template <class Units> |
269 | | struct RectAbsoluteTyped : |
270 | | public BaseRectAbsolute<Float, RectAbsoluteTyped<Units>, RectTyped<Units>>, |
271 | | public Units { |
272 | | static_assert(IsPixel<Units>::value, |
273 | | "'units' must be a coordinate system tag"); |
274 | | typedef BaseRectAbsolute<Float, RectAbsoluteTyped<Units>, RectTyped<Units>> Super; |
275 | | |
276 | 0 | RectAbsoluteTyped() : Super() {} |
277 | | RectAbsoluteTyped(Float aLeft, Float aTop, Float aRight, Float aBottom) : |
278 | 0 | Super(aLeft, aTop, aRight, aBottom) {} |
279 | | }; |
280 | | |
281 | | typedef IntRectAbsoluteTyped<UnknownUnits> IntRectAbsolute; |
282 | | |
283 | | } |
284 | | } |
285 | | |
286 | | #endif /* MOZILLA_GFX_RECT_ABSOLUTE_H_ */ |