Coverage Report

Created: 2018-09-25 14:53

/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_ */