// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef PPAPI_CPP_RECT_H_ #define PPAPI_CPP_RECT_H_ #include "ppapi/c/pp_rect.h" #include "ppapi/cpp/point.h" #include "ppapi/cpp/size.h" /// @file /// This file defines the APIs for creating a 2 dimensional rectangle. namespace pp { /// A 2 dimensional rectangle. A rectangle is represented by x and y (which /// identifies the upper-left corner of the rectangle), width, and height. class Rect { public: /// The default constructor. Creates a <code>Rect</code> in the upper-left /// at 0,0 with height and width of 0. Rect() { rect_.point.x = 0; rect_.point.y = 0; rect_.size.width = 0; rect_.size.height = 0; } /// A constructor accepting a reference to a <code>PP_Rect and</code> /// converting the <code>PP_Rect</code> to a <code>Rect</code>. This is an /// implicit conversion constructor. /// /// @param[in] rect A <code>PP_Rect</code>. Rect(const PP_Rect& rect) { // Implicit. set_x(rect.point.x); set_y(rect.point.y); set_width(rect.size.width); set_height(rect.size.height); } /// A constructor accepting two int32_t values for width and height and /// converting them to a <code>Rect</code> in the upper-left starting /// coordinate of 0,0. /// /// @param[in] w An int32_t value representing a width. /// @param[in] h An int32_t value representing a height. Rect(int32_t w, int32_t h) { set_x(0); set_y(0); set_width(w); set_height(h); } /// A constructor accepting four int32_t values for width, height, x, and y. /// /// @param[in] x An int32_t value representing a horizontal coordinate /// of a point, starting with 0 as the left-most coordinate. /// @param[in] y An int32_t value representing a vertical coordinate /// of a point, starting with 0 as the top-most coordinate. /// @param[in] w An int32_t value representing a width. /// @param[in] h An int32_t value representing a height. Rect(int32_t x, int32_t y, int32_t w, int32_t h) { set_x(x); set_y(y); set_width(w); set_height(h); } /// A constructor accepting a pointer to a Size and converting the /// <code>Size</code> to a <code>Rect</code> in the upper-left starting /// coordinate of 0,0. /// /// @param[in] s A pointer to a <code>Size</code>. explicit Rect(const Size& s) { set_x(0); set_y(0); set_size(s); } /// A constructor accepting a pointer to a <code>Point</code> representing /// the origin of the rectangle and a pointer to a <code>Size</code> /// representing the height and width. /// /// @param[in] origin A pointer to a <code>Point</code> representing the /// upper-left starting coordinate. /// @param[in] size A pointer to a <code>Size</code> representing the height /// and width. Rect(const Point& origin, const Size& size) { set_point(origin); set_size(size); } /// Destructor. ~Rect() { } /// PP_Rect() allows implicit conversion of a <code>Rect</code> to a /// <code>PP_Rect</code>. /// /// @return A <code>Point</code>. operator PP_Rect() const { return rect_; } /// Getter function for returning the internal <code>PP_Rect</code> struct. /// /// @return A const reference to the internal <code>PP_Rect</code> struct. const PP_Rect& pp_rect() const { return rect_; } /// Getter function for returning the internal <code>PP_Rect</code> struct. /// /// @return A mutable reference to the <code>PP_Rect</code> struct. PP_Rect& pp_rect() { return rect_; } /// Getter function for returning the value of x. /// /// @return The value of x for this <code>Point</code>. int32_t x() const { return rect_.point.x; } /// Setter function for setting the value of x. /// /// @param[in] in_x A new x value. void set_x(int32_t in_x) { rect_.point.x = in_x; } /// Getter function for returning the value of y. /// /// @return The value of y for this <code>Point</code>. int32_t y() const { return rect_.point.y; } /// Setter function for setting the value of y. /// /// @param[in] in_y A new y value. void set_y(int32_t in_y) { rect_.point.y = in_y; } /// Getter function for returning the value of width. /// /// @return The value of width for this <code>Rect</code>. int32_t width() const { return rect_.size.width; } /// Setter function for setting the value of width. /// /// @param[in] w A new width value. void set_width(int32_t w) { if (w < 0) { PP_DCHECK(w >= 0); w = 0; } rect_.size.width = w; } /// Getter function for returning the value of height. /// /// @return The value of height for this <code>Rect</code>. int32_t height() const { return rect_.size.height; } /// Setter function for setting the value of height. /// /// @param[in] h A new width height. void set_height(int32_t h) { if (h < 0) { PP_DCHECK(h >= 0); h = 0; } rect_.size.height = h; } /// Getter function for returning the <code>Point</code>. /// /// @return A <code>Point</code>. Point point() const { return Point(rect_.point); } /// Setter function for setting the value of the <code>Point</code>. /// /// @param[in] origin A <code>Point</code> representing the upper-left /// starting coordinate. void set_point(const Point& origin) { rect_.point = origin; } /// Getter function for returning the <code>Size</code>. /// /// @return The size of the rectangle. Size size() const { return Size(rect_.size); } /// Setter function for setting the <code>Size</code>. /// /// @param[in] s A pointer to a <code>Size</code> representing the height /// and width. void set_size(const Size& s) { rect_.size.width = s.width(); rect_.size.height = s.height(); } /// Getter function to get the upper-bound for the x-coordinates of the /// rectangle. Note that this coordinate value is one past the highest x /// value of pixels in the rectangle. This loop will access all the pixels /// in a horizontal line in the rectangle: /// <code>for (int32_t x = rect.x(); x < rect.right(); ++x) {}</code> /// /// @return The value of x + width for this point. int32_t right() const { return x() + width(); } /// Getter function to get the upper-bound for the y-coordinates of the /// rectangle. Note that this coordinate value is one past the highest xy /// value of pixels in the rectangle. This loop will access all the pixels /// in a horizontal line in the rectangle: /// <code>for (int32_t y = rect.y(); y < rect.bottom(); ++y) {}</code> /// /// @return The value of y + height for this point. int32_t bottom() const { return y() + height(); } /// Setter function for setting the value of the <code>Rect</code>. /// /// @param[in] x A new x value. /// @param[in] y A new y value. /// @param[in] w A new width value. /// @param[in] h A new height value. void SetRect(int32_t x, int32_t y, int32_t w, int32_t h) { set_x(x); set_y(y); set_width(w); set_height(h); } /// Setter function for setting the value of the <code>Rect</code>. /// /// @param[in] rect A pointer to a <code>PP_Rect</code>. void SetRect(const PP_Rect& rect) { rect_ = rect; } /// Inset() shrinks the rectangle by a horizontal and vertical /// distance on all sides. /// /// @param[in] horizontal An int32_t value representing a horizontal /// shrinking distance. /// @param[in] vertical An int32_t value representing a vertical /// shrinking distance. void Inset(int32_t horizontal, int32_t vertical) { Inset(horizontal, vertical, horizontal, vertical); } /// Inset() shrinks the rectangle by the specified amount on each /// side. /// /// @param[in] left An int32_t value representing a left /// shrinking distance. /// @param[in] top An int32_t value representing a top /// shrinking distance. /// @param[in] right An int32_t value representing a right /// shrinking distance. /// @param[in] bottom An int32_t value representing a bottom /// shrinking distance. void Inset(int32_t left, int32_t top, int32_t right, int32_t bottom); /// Offset() moves the rectangle by a horizontal and vertical distance. /// /// @param[in] horizontal An int32_t value representing a horizontal /// move distance. /// @param[in] vertical An int32_t value representing a vertical /// move distance. void Offset(int32_t horizontal, int32_t vertical); /// Offset() moves the rectangle by a horizontal and vertical distance. /// /// @param[in] point A pointer to a <code>Point</code> representing the /// horizontal and vertical move distances. void Offset(const Point& point) { Offset(point.x(), point.y()); } /// IsEmpty() determines if the area of a rectangle is zero. Returns true if /// the area of the rectangle is zero. /// /// @return true if the area of the rectangle is zero. bool IsEmpty() const { return rect_.size.width == 0 && rect_.size.height == 0; } /// Contains() determines if the point identified by point_x and point_y /// falls inside this rectangle. The point (x, y) is inside the rectangle, /// but the point (x + width, y + height) is not. /// /// @param[in] point_x An int32_t value representing a x value. /// @param[in] point_y An int32_t value representing a y value. /// /// @return true if the point_x and point_y fall inside the rectangle. bool Contains(int32_t point_x, int32_t point_y) const; /// Contains() determines if the specified point is contained by this /// rectangle. /// /// @param[in] point A pointer to a Point representing a 2D coordinate. /// /// @return true if the point_x and point_y fall inside the rectangle. bool Contains(const Point& point) const { return Contains(point.x(), point.y()); } /// Contains() determines if this rectangle contains the specified rectangle. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return true if the rectangle fall inside this rectangle. bool Contains(const Rect& rect) const; /// Intersects() determines if this rectangle intersects the specified /// rectangle. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return true if the rectangle intersects this rectangle. bool Intersects(const Rect& rect) const; /// Intersect() computes the intersection of this rectangle with the given /// rectangle. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return A <code>Rect</code> representing the intersection. Rect Intersect(const Rect& rect) const; /// Union() computes the union of this rectangle with the given rectangle. /// The union is the smallest rectangle containing both rectangles. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return A <code>Rect</code> representing the union. Rect Union(const Rect& rect) const; /// Subtract() computes the rectangle resulting from subtracting /// <code>rect</code> from this Rect. If <code>rect</code>does not intersect /// completely in either the x or y direction, then <code>*this</code> is /// returned. If <code>rect</code> contains <code>this</code>, then an empty /// <code>Rect</code> is returned. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return A <code>Rect</code> representing the subtraction. Rect Subtract(const Rect& rect) const; /// AdjustToFit() fits as much of the receiving rectangle within /// the supplied rectangle as possible, returning the result. For example, /// if the receiver had a x-location of 2 and a width of 4, and the supplied /// rectangle had an x-location of 0 with a width of 5, the returned /// rectangle would have an x-location of 1 with a width of 4. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return A <code>Rect</code> representing the difference between this /// rectangle and the receiving rectangle. Rect AdjustToFit(const Rect& rect) const; /// CenterPoint() determines the center of this rectangle. /// /// @return A <code>Point</code> representing the center of this rectangle. Point CenterPoint() const; /// SharesEdgeWith() determines if this rectangle shares an entire edge /// (same width or same height) with the given rectangle, and the /// rectangles do not overlap. /// /// @param[in] rect A pointer to a <code>Rect</code>. /// /// @return true if this rectangle and supplied rectangle share an edge. bool SharesEdgeWith(const Rect& rect) const; private: PP_Rect rect_; }; } // namespace pp /// This function determines whether the x, y, width, and height values of two /// rectangles and are equal. /// /// @param[in] lhs The <code>Rect</code> on the left-hand side of the equation. /// @param[in] rhs The <code>Rect</code> on the right-hand side of the equation. /// /// @return true if they are equal, false if unequal. inline bool operator==(const pp::Rect& lhs, const pp::Rect& rhs) { return lhs.x() == rhs.x() && lhs.y() == rhs.y() && lhs.width() == rhs.width() && lhs.height() == rhs.height(); } /// This function determines whether two Rects are not equal. /// /// @param[in] lhs The <code>Rect</code> on the left-hand side of the equation. /// @param[in] rhs The <code>Rect</code> on the right-hand side of the /// equation. /// /// @return true if the given Rects are equal, otherwise false. inline bool operator!=(const pp::Rect& lhs, const pp::Rect& rhs) { return !(lhs == rhs); } #endif