// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "libvideostitch/config.hpp" #include <cassert> namespace VideoStitch { namespace Core { /** * @brief A simple Rectangle class. */ struct VS_EXPORT Rect { static Rect fromInclusiveTopLeftBottomRight(int64_t top, int64_t left, int64_t bottom, int64_t right) { return Rect{top, left, bottom, right}; } Rect() : top_(0), left_(0), bottom_(-1), right_(-1) {} /** * Copy contructor. */ Rect(const Rect& o) : top_(o.top_), left_(o.left_), bottom_(o.bottom_), right_(o.right_) {} /** * Returns the top coordinate of the rectangle. */ int64_t top() const { return top_; } /** * Returns the left coordinate of the rectangle. */ int64_t left() const { return left_; } /** * Returns the bottom coordinate of the rectangle. */ int64_t bottom() const { return bottom_; } /** * Returns the right coordinate of the rectangle. */ int64_t right() const { return right_; } /** * Set the top coordinate of the rectangle. */ void setTop(int64_t top) { top_ = top; } /** * Set the left coordinate of the rectangle. */ void setLeft(int64_t left) { left_ = left; } /** * Set the bottom coordinate of the rectangle. */ void setBottom(int64_t bottom) { bottom_ = bottom; } /** * Set the right coordinate of the rectangle. */ void setRight(int64_t right) { right_ = right; } /** * Returns the width of the rectangle. */ int64_t getWidth() const { assert(right_ >= left_); return right_ - left_ + 1; } /** * Returns the height of the rectangle. */ int64_t getHeight() const { assert(bottom_ >= top_); return bottom_ - top_ + 1; } /** * Returns true if the rectangle is empty vertically. */ bool verticallyEmpty() const { return top_ > bottom_; } /** * Returns true if the rectangle is empty horizontally. */ bool horizontallyEmpty() const { return left_ > right_; } /** * Returns true if the rectangle is empty (area <= 0). */ bool empty() const { return horizontallyEmpty() || verticallyEmpty(); } /** * Returns the area of the rectangle. */ int64_t getArea() const { return empty() ? 0 : getWidth() * getHeight(); } /** * Move left and top so that they are aligned on a multiple of the given dimensions. * They can only decrease. Right and bottom are not touched. */ void growToAlignTo(int x, int y); /** * Move right and bottom so that the width and height are divisible by the given dimensions. * They can only increase. Top and left are not touched. */ void growToMultipleSizeOf(int x, int y); /** * Fill iRect and uRect with the intersection and union of the two rectangles a and b. */ static void getInterAndUnion(const Rect& a, const Rect& b, Rect& iRect, Rect& uRect, unsigned wrapWidth); /** * Returns true if rectangles are the same. */ bool operator==(const Rect& o) const { return empty() == o.empty() || (top_ == o.top_ && left_ == o.left_ && bottom_ == o.bottom_ && right_ == o.right_); } Rect& operator=(const Rect& o) { top_ = o.top_; bottom_ = o.bottom_; right_ = o.right_; left_ = o.left_; return *this; } /** * Returns true if *this is inside o. An empty rectangle is inside all rectangles. */ bool isInside(const Rect& o) const { if (empty()) { return true; } else if (o.empty()) { return false; } else { return (top_ >= o.top_ && left_ >= o.left_ && bottom_ <= o.bottom_ && right_ <= o.right_); } } /** * Returns true if point is contained in *this */ bool contains(int x, int y) const { return left_ <= x && x <= right_ && top_ <= y && y <= bottom_; } private: /** * Constructor. Values are inclusive. */ Rect(int64_t top, int64_t left, int64_t bottom, int64_t right) : top_(top), left_(left), bottom_(bottom), right_(right) {} int64_t top_; int64_t left_; int64_t bottom_; int64_t right_; }; } // namespace Core } // namespace VideoStitch