1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PPAPI_CPP_RECT_H_
6#define PPAPI_CPP_RECT_H_
7
8#include "ppapi/c/pp_rect.h"
9#include "ppapi/cpp/point.h"
10#include "ppapi/cpp/size.h"
11
12/// @file
13/// This file defines the APIs for creating a 2 dimensional rectangle.
14
15namespace pp {
16
17/// A 2 dimensional rectangle. A rectangle is represented by x and y (which
18/// identifies the upper-left corner of the rectangle), width, and height.
19class Rect {
20 public:
21
22  /// The default constructor. Creates a <code>Rect</code> in the upper-left
23  /// at 0,0 with height and width of 0.
24  Rect() {
25    rect_.point.x = 0;
26    rect_.point.y = 0;
27    rect_.size.width = 0;
28    rect_.size.height = 0;
29  }
30
31  /// A constructor accepting a reference to a <code>PP_Rect and</code>
32  /// converting the <code>PP_Rect</code> to a <code>Rect</code>. This is an
33  /// implicit conversion constructor.
34  ///
35  /// @param[in] rect A <code>PP_Rect</code>.
36  Rect(const PP_Rect& rect) {  // Implicit.
37    set_x(rect.point.x);
38    set_y(rect.point.y);
39    set_width(rect.size.width);
40    set_height(rect.size.height);
41  }
42
43  /// A constructor accepting two int32_t values for width and height and
44  /// converting them to a <code>Rect</code> in the upper-left starting
45  /// coordinate of 0,0.
46  ///
47  /// @param[in] w An int32_t value representing a width.
48  /// @param[in] h An int32_t value representing a height.
49  Rect(int32_t w, int32_t h) {
50    set_x(0);
51    set_y(0);
52    set_width(w);
53    set_height(h);
54  }
55
56  /// A constructor accepting four int32_t values for width, height, x, and y.
57  ///
58  /// @param[in] x An int32_t value representing a horizontal coordinate
59  /// of a point, starting with 0 as the left-most coordinate.
60  /// @param[in] y An int32_t value representing a vertical coordinate
61  /// of a point, starting with 0 as the top-most coordinate.
62  /// @param[in] w An int32_t value representing a width.
63  /// @param[in] h An int32_t value representing a height.
64  Rect(int32_t x, int32_t y, int32_t w, int32_t h) {
65    set_x(x);
66    set_y(y);
67    set_width(w);
68    set_height(h);
69  }
70
71  /// A constructor accepting a pointer to a Size and converting the
72  /// <code>Size</code> to a <code>Rect</code> in the upper-left starting
73  /// coordinate of 0,0.
74  ///
75  /// @param[in] s A pointer to a <code>Size</code>.
76  explicit Rect(const Size& s) {
77    set_x(0);
78    set_y(0);
79    set_size(s);
80  }
81
82  /// A constructor accepting a pointer to a <code>Point</code> representing
83  /// the origin of the rectangle and a pointer to a <code>Size</code>
84  /// representing the height and width.
85  ///
86  /// @param[in] origin A pointer to a <code>Point</code> representing the
87  /// upper-left starting coordinate.
88  /// @param[in] size A pointer to a <code>Size</code> representing the height
89  /// and width.
90  Rect(const Point& origin, const Size& size) {
91    set_point(origin);
92    set_size(size);
93  }
94
95  /// Destructor.
96  ~Rect() {
97  }
98
99  /// PP_Rect() allows implicit conversion of a <code>Rect</code> to a
100  /// <code>PP_Rect</code>.
101  ///
102  /// @return A <code>Point</code>.
103  operator PP_Rect() const {
104    return rect_;
105  }
106
107  /// Getter function for returning the internal <code>PP_Rect</code> struct.
108  ///
109  /// @return A const reference to the internal <code>PP_Rect</code> struct.
110  const PP_Rect& pp_rect() const {
111    return rect_;
112  }
113
114  /// Getter function for returning the internal <code>PP_Rect</code> struct.
115  ///
116  /// @return A mutable reference to the <code>PP_Rect</code> struct.
117  PP_Rect& pp_rect() {
118    return rect_;
119  }
120
121
122  /// Getter function for returning the value of x.
123  ///
124  /// @return The value of x for this <code>Point</code>.
125  int32_t x() const {
126    return rect_.point.x;
127  }
128
129  /// Setter function for setting the value of x.
130  ///
131  /// @param[in] in_x A new x value.
132  void set_x(int32_t in_x) {
133    rect_.point.x = in_x;
134  }
135
136  /// Getter function for returning the value of y.
137  ///
138  /// @return The value of y for this <code>Point</code>.
139  int32_t y() const {
140    return rect_.point.y;
141  }
142
143  /// Setter function for setting the value of y.
144  ///
145  /// @param[in] in_y A new y value.
146  void set_y(int32_t in_y) {
147    rect_.point.y = in_y;
148  }
149
150  /// Getter function for returning the value of width.
151  ///
152  /// @return The value of width for this <code>Rect</code>.
153  int32_t width() const {
154    return rect_.size.width;
155  }
156
157  /// Setter function for setting the value of width.
158  ///
159  /// @param[in] w A new width value.
160  void set_width(int32_t w) {
161    if (w < 0) {
162      PP_DCHECK(w >= 0);
163      w = 0;
164    }
165    rect_.size.width = w;
166  }
167
168  /// Getter function for returning the value of height.
169  ///
170  /// @return The value of height for this <code>Rect</code>.
171  int32_t height() const {
172    return rect_.size.height;
173  }
174
175  /// Setter function for setting the value of height.
176  ///
177  /// @param[in] h A new width height.
178  void set_height(int32_t h) {
179    if (h < 0) {
180      PP_DCHECK(h >= 0);
181      h = 0;
182    }
183    rect_.size.height = h;
184  }
185
186  /// Getter function for returning the <code>Point</code>.
187  ///
188  /// @return A <code>Point</code>.
189  Point point() const {
190    return Point(rect_.point);
191  }
192
193  /// Setter function for setting the value of the <code>Point</code>.
194  ///
195  /// @param[in] origin A <code>Point</code> representing the upper-left
196  /// starting coordinate.
197  void set_point(const Point& origin) {
198    rect_.point = origin;
199  }
200
201  /// Getter function for returning the <code>Size</code>.
202  ///
203  /// @return The size of the rectangle.
204  Size size() const {
205    return Size(rect_.size);
206  }
207
208  /// Setter function for setting the <code>Size</code>.
209  ///
210  /// @param[in] s A pointer to a <code>Size</code> representing the height
211  /// and width.
212  void set_size(const Size& s) {
213    rect_.size.width = s.width();
214    rect_.size.height = s.height();
215  }
216
217  /// Getter function to get the upper-bound for the x-coordinates of the
218  /// rectangle.  Note that this coordinate value is one past the highest x
219  /// value of pixels in the rectangle.  This loop will access all the pixels
220  /// in a horizontal line in the rectangle:
221  /// <code>for (int32_t x = rect.x(); x < rect.right(); ++x) {}</code>
222  ///
223  /// @return The value of x + width for this point.
224  int32_t right() const {
225    return x() + width();
226  }
227
228  /// Getter function to get the upper-bound for the y-coordinates of the
229  /// rectangle.  Note that this coordinate value is one past the highest xy
230  /// value of pixels in the rectangle.  This loop will access all the pixels
231  /// in a horizontal line in the rectangle:
232  /// <code>for (int32_t y = rect.y(); y < rect.bottom(); ++y) {}</code>
233  ///
234  /// @return The value of y + height for this point.
235  int32_t bottom() const {
236    return y() + height();
237  }
238
239  /// Setter function for setting the value of the <code>Rect</code>.
240  ///
241  /// @param[in] x A new x value.
242  /// @param[in] y A new y value.
243  /// @param[in] w A new width value.
244  /// @param[in] h A new height value.
245  void SetRect(int32_t x, int32_t y, int32_t w, int32_t h) {
246    set_x(x);
247    set_y(y);
248    set_width(w);
249    set_height(h);
250  }
251
252  /// Setter function for setting the value of the <code>Rect</code>.
253  ///
254  /// @param[in] rect A pointer to a <code>PP_Rect</code>.
255  void SetRect(const PP_Rect& rect) {
256    rect_ = rect;
257  }
258
259  /// Inset() shrinks the rectangle by a horizontal and vertical
260  /// distance on all sides.
261  ///
262  /// @param[in] horizontal An int32_t value representing a horizontal
263  /// shrinking distance.
264  /// @param[in] vertical An int32_t value representing a vertical
265  /// shrinking distance.
266  void Inset(int32_t horizontal, int32_t vertical) {
267    Inset(horizontal, vertical, horizontal, vertical);
268  }
269
270  /// Inset() shrinks the rectangle by the specified amount on each
271  /// side.
272  ///
273  /// @param[in] left An int32_t value representing a left
274  /// shrinking distance.
275  /// @param[in] top An int32_t value representing a top
276  /// shrinking distance.
277  /// @param[in] right An int32_t value representing a right
278  /// shrinking distance.
279  /// @param[in] bottom An int32_t value representing a bottom
280  /// shrinking distance.
281  void Inset(int32_t left, int32_t top, int32_t right, int32_t bottom);
282
283  /// Offset() moves the rectangle by a horizontal and vertical distance.
284  ///
285  /// @param[in] horizontal An int32_t value representing a horizontal
286  /// move distance.
287  /// @param[in] vertical An int32_t value representing a vertical
288  /// move distance.
289  void Offset(int32_t horizontal, int32_t vertical);
290
291  /// Offset() moves the rectangle by a horizontal and vertical distance.
292  ///
293  /// @param[in] point A pointer to a <code>Point</code> representing the
294  /// horizontal and vertical move distances.
295  void Offset(const Point& point) {
296    Offset(point.x(), point.y());
297  }
298
299  /// IsEmpty() determines if the area of a rectangle is zero. Returns true if
300  /// the area of the rectangle is zero.
301  ///
302  /// @return true if the area of the rectangle is zero.
303  bool IsEmpty() const {
304    return rect_.size.width == 0 && rect_.size.height == 0;
305  }
306
307  /// Contains() determines if the point identified by point_x and point_y
308  /// falls inside this rectangle. The point (x, y) is inside the rectangle,
309  /// but the point (x + width, y + height) is not.
310  ///
311  /// @param[in] point_x An int32_t value representing a x value.
312  /// @param[in] point_y An int32_t value representing a y value.
313  ///
314  /// @return true if the point_x and point_y fall inside the rectangle.
315  bool Contains(int32_t point_x, int32_t point_y) const;
316
317  /// Contains() determines if the specified point is contained by this
318  /// rectangle.
319  ///
320  /// @param[in] point A pointer to a Point representing a 2D coordinate.
321  ///
322  /// @return true if the point_x and point_y fall inside the rectangle.
323  bool Contains(const Point& point) const {
324    return Contains(point.x(), point.y());
325  }
326
327  /// Contains() determines if this rectangle contains the specified rectangle.
328  ///
329  /// @param[in] rect A pointer to a <code>Rect</code>.
330  ///
331  /// @return true if the rectangle fall inside this rectangle.
332  bool Contains(const Rect& rect) const;
333
334  /// Intersects() determines if this rectangle intersects the specified
335  /// rectangle.
336  ///
337  /// @param[in] rect A pointer to a <code>Rect</code>.
338  ///
339  /// @return true if the rectangle intersects  this rectangle.
340  bool Intersects(const Rect& rect) const;
341
342  /// Intersect() computes the intersection of this rectangle with the given
343  /// rectangle.
344  ///
345  /// @param[in] rect A pointer to a <code>Rect</code>.
346  ///
347  /// @return A <code>Rect</code> representing the intersection.
348  Rect Intersect(const Rect& rect) const;
349
350  /// Union() computes the union of this rectangle with the given rectangle.
351  /// The union is the smallest rectangle containing both rectangles.
352  ///
353  /// @param[in] rect A pointer to a <code>Rect</code>.
354  ///
355  /// @return A <code>Rect</code> representing the union.
356  Rect Union(const Rect& rect) const;
357
358  /// Subtract() computes the rectangle resulting from subtracting
359  /// <code>rect</code> from this Rect.  If <code>rect</code>does not intersect
360  /// completely in either the x or y direction, then <code>*this</code> is
361  /// returned. If <code>rect</code> contains <code>this</code>, then an empty
362  /// <code>Rect</code> is returned.
363  ///
364  /// @param[in] rect A pointer to a <code>Rect</code>.
365  ///
366  /// @return A <code>Rect</code> representing the subtraction.
367  Rect Subtract(const Rect& rect) const;
368
369  /// AdjustToFit() fits as much of the receiving rectangle within
370  /// the supplied rectangle as possible, returning the result. For example,
371  /// if the receiver had a x-location of 2 and a width of 4, and the supplied
372  /// rectangle had an x-location of 0 with a width of 5, the returned
373  /// rectangle would have an x-location of 1 with a width of 4.
374  ///
375  /// @param[in] rect A pointer to a <code>Rect</code>.
376  ///
377  /// @return A <code>Rect</code> representing the difference between this
378  /// rectangle and the receiving rectangle.
379  Rect AdjustToFit(const Rect& rect) const;
380
381  /// CenterPoint() determines the center of this rectangle.
382  ///
383  /// @return A <code>Point</code> representing the center of this rectangle.
384  Point CenterPoint() const;
385
386  /// SharesEdgeWith() determines if this rectangle shares an entire edge
387  /// (same width or same height) with the given rectangle, and the
388  /// rectangles do not overlap.
389  ///
390  /// @param[in] rect A pointer to a <code>Rect</code>.
391  ///
392  /// @return true if this rectangle and supplied rectangle share an edge.
393  bool SharesEdgeWith(const Rect& rect) const;
394
395 private:
396  PP_Rect rect_;
397};
398
399}  // namespace pp
400
401/// This function determines whether the x, y, width, and height values of two
402/// rectangles and are equal.
403///
404/// @param[in] lhs The <code>Rect</code> on the left-hand side of the equation.
405/// @param[in] rhs The <code>Rect</code> on the right-hand side of the equation.
406///
407/// @return true if they are equal, false if unequal.
408inline bool operator==(const pp::Rect& lhs, const pp::Rect& rhs) {
409  return lhs.x() == rhs.x() &&
410         lhs.y() == rhs.y() &&
411         lhs.width() == rhs.width() &&
412         lhs.height() == rhs.height();
413}
414
415/// This function determines whether two Rects are not equal.
416///
417/// @param[in] lhs The <code>Rect</code> on the left-hand side of the equation.
418/// @param[in] rhs The <code>Rect</code> on the right-hand side of the
419/// equation.
420///
421/// @return true if the given Rects are equal, otherwise false.
422inline bool operator!=(const pp::Rect& lhs, const pp::Rect& rhs) {
423  return !(lhs == rhs);
424}
425
426#endif
427
428