diff options
author | Cary Clark <caryclark@skia.org> | 2017-10-30 11:48:35 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-30 16:30:49 +0000 |
commit | cc309eb9b18a707dfb94d89866a474bebf7f2777 (patch) | |
tree | 5c12476cae12568a01efd93f0fa89698f56ae02a /include/core/SkRect.h | |
parent | d2b8af11520ae26e6e6afca636dfcb87036d600d (diff) |
generated include refresh
The latest, minor changes on includes already
generated, plus four new ones.
TBR=reed@google.com
Bug: skia:6898
Change-Id: If06ae9b9aaa3a0a9fae570aa7a6698ff340c43b8
Reviewed-on: https://skia-review.googlesource.com/62862
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'include/core/SkRect.h')
-rw-r--r-- | include/core/SkRect.h | 1272 |
1 files changed, 1019 insertions, 253 deletions
diff --git a/include/core/SkRect.h b/include/core/SkRect.h index 12afddd9ce..e4ff612883 100644 --- a/include/core/SkRect.h +++ b/include/core/SkRect.h @@ -15,120 +15,278 @@ struct SkRect; /** \struct SkIRect - - SkIRect holds four 32 bit integer coordinates for a rectangle + SkIRect holds four 32 bit integer coordinates describing the upper and + lower bounds of a rectangle. SkIRect may be created from outer bounds or + from position, width, and height. SkIRect describes an area; if its right + is less than or equal to its left, or if its bottom is less than or equal to + its top, it is considered empty. */ struct SK_API SkIRect { + + /** May contain any value. The smaller of the horizontal values when sorted. + When equal to or greater than fRight, SkIRect is empty. + */ int32_t fLeft; + + /** May contain any value. The smaller of the horizontal values when sorted. + When equal to or greater than fBottom, SkIRect is empty. + */ int32_t fTop; + + /** May contain any value. The larger of the vertical values when sorted. + When equal to or less than fLeft, SkIRect is empty. + */ int32_t fRight; + + /** May contain any value. The larger of the vertical values when sorted. + When equal to or less than fTop, SkIRect is empty. + */ int32_t fBottom; + /** Returns constructed SkIRect set to (0, 0, 0, 0). + Many other rectangles are empty; if left is equal to or greater than right, + or if top is equal to or greater than bottom. Setting all members to zero + is a convenience, but does not designate a special empty rectangle. + + @return bounds (0, 0, 0, 0) + */ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeEmpty() { return SkIRect{0, 0, 0, 0}; } + /** Returns constructed SkIRect setting left and top to most negative value, and + setting right and bottom to most positive value. + + @return bounds (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) + */ static SkIRect SK_WARN_UNUSED_RESULT MakeLargest() { SkIRect r; r.setLargest(); return r; } + /** Returns constructed SkIRect set to (0, 0, w, h). Does not validate input; w or h + may be negative. + + @param w width of constructed SkRect + @param h height of constructed SkRect + @return bounds (0, 0, w, h) + */ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeWH(int32_t w, int32_t h) { return SkIRect{0, 0, w, h}; } + /** Returns constructed SkIRect set to (0, 0, size.width(), size.height()). + Does not validate input; size.width() or size.height() may be negative. + + @param size values for SkRect width and height + @return bounds (0, 0, size.width(), size.height()) + */ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeSize(const SkISize& size) { return SkIRect{0, 0, size.fWidth, size.fHeight}; } + /** Returns constructed SkIRect set to (l, t, r, b). Does not sort input; SkRect may + result in fLeft greater than fRight, or fTop greater than fBottom. + + @param l integer stored in fLeft + @param t integer stored in fTop + @param r integer stored in fRight + @param b integer stored in fBottom + @return bounds (l, t, r, b) + */ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b) { return SkIRect{l, t, r, b}; } + /** Returns constructed SkIRect set to: (x, y, x + w, y + h). Does not validate input; + w or h may be negative. + + @param x stored in fLeft + @param y stored in fTop + @param w added to x and stored in fRight + @param h added to y and stored in fBottom + @return bounds at (x, y) with width w and height h + */ static constexpr SkIRect SK_WARN_UNUSED_RESULT MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h) { return SkIRect{x, y, x + w, y + h}; } + /** Returns left edge of SkIRect, if sorted. + Call sort() to reverse fLeft and fRight if needed. + + @return fLeft + */ int left() const { return fLeft; } + + /** Returns top edge of SkIRect, if sorted. Call isEmpty() to see if SkIRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fTop + */ int top() const { return fTop; } + + /** Returns right edge of SkIRect, if sorted. + Call sort() to reverse fLeft and fRight if needed. + + @return fRight + */ int right() const { return fRight; } + + /** Returns bottom edge of SkIRect, if sorted. Call isEmpty() to see if SkIRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fBottom + */ int bottom() const { return fBottom; } - /** return the left edge of the rect */ + /** Returns left edge of SkIRect, if sorted. Call isEmpty() to see if SkIRect may be invalid, + and sort() to reverse fLeft and fRight if needed. + + @return fLeft + */ int x() const { return fLeft; } - /** return the top edge of the rect */ + + /** Returns top edge of SkIRect, if sorted. Call isEmpty() to see if SkIRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fTop + */ int y() const { return fTop; } - /** - * Returns the rectangle's width. This does not check for a valid rect - * (i.e. left <= right) so the result may be negative. - */ + + /** Returns span on the x-axis. This does not check if SkIRect is sorted, or if + result fits in 32-bit signed integer; result may be negative. + + @return fRight minus fLeft + */ int width() const { return fRight - fLeft; } - /** - * Returns the rectangle's height. This does not check for a valid rect - * (i.e. top <= bottom) so the result may be negative. - */ + /** Returns span on the y-axis. This does not check if SkIRect is sorted, or if + result fits in 32-bit signed integer; result may be negative. + + @return fBottom minus fTop + */ int height() const { return fBottom - fTop; } + /** Returns spans on the x-axis and y-axis. This does not check if SkIRect is sorted, + or if result fits in 32-bit signed integer; result may be negative. + + @return SkISize (width, height) + */ SkISize size() const { return SkISize::Make(this->width(), this->height()); } - /** - * Since the center of an integer rect may fall on a factional value, this - * method is defined to return (right + left) >> 1. - * - * This is a specific "truncation" of the average, which is different than - * (right + left) / 2 when the sum is negative. - */ + /** Returns average of left edge and right edge. Result does not change if SkRect + is sorted. Result may be incorrect if SkRect is far from the origin. + + Result is rounded down. + + @return midpoint in x + */ int centerX() const { return (fRight + fLeft) >> 1; } - /** - * Since the center of an integer rect may fall on a factional value, this - * method is defined to return (bottom + top) >> 1 - * - * This is a specific "truncation" of the average, which is different than - * (bottom + top) / 2 when the sum is negative. - */ + /** Returns average of top edge and bottom edge. Result does not change if SkRect + is sorted. Result may be incorrect if SkRect is far from the origin. + + Result is rounded down. + + @return midpoint in y + */ int centerY() const { return (fBottom + fTop) >> 1; } - /** - * Return true if the rectangle's width or height are <= 0 - */ + /** Returns true if fLeft is equal to or greater than fRight, or if fTop is equal + to or greater than fBottom. Call sort() to reverse rectangles with negative + width() or height(). + + @return true if width() or height() are zero or negative + */ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } + /** Returns true if SkIRect encloses largest possible area. + + @return true if equal to (SK_MinS32, SK_MinS32, SK_MaxS32, SK_MaxS32) + */ bool isLargest() const { return SK_MinS32 == fLeft && SK_MinS32 == fTop && SK_MaxS32 == fRight && SK_MaxS32 == fBottom; } + /** Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are + identical to corresponding members in b. + + @param a SkIRect to compare + @param b SkIRect to compare + @return true if members are equal + */ friend bool operator==(const SkIRect& a, const SkIRect& b) { return !memcmp(&a, &b, sizeof(a)); } + /** Returns true if any member in a: fLeft, fTop, fRight, and fBottom; is not + identical to the corresponding member in b. + + @param a SkIRect to compare + @param b SkIRect to compare + @return true if members are not equal + */ friend bool operator!=(const SkIRect& a, const SkIRect& b) { return !(a == b); } + /** Returns true if all members: fLeft, fTop, fRight, and fBottom; values are + equal to or larger than -32768 and equal to or smaller than 32767. + + @return true if members fit in 16-bit word + */ bool is16Bit() const { return SkTFitsIn<int16_t>(fLeft) && SkTFitsIn<int16_t>(fTop) && SkTFitsIn<int16_t>(fRight) && SkTFitsIn<int16_t>(fBottom); } - /** Set the rectangle to (0,0,0,0) + /** Sets SkIRect to (0, 0, 0, 0). + + Many other rectangles are empty; if left is equal to or greater than right, + or if top is equal to or greater than bottom. Setting all members to zero + is a convenience, but does not designate a special empty rectangle. */ void setEmpty() { memset(this, 0, sizeof(*this)); } + /** Sets SkIRect to (left, top, right, bottom). + left and right are not sorted; left is not necessarily less than right. + top and bottom are not sorted; top is not necessarily less than bottom. + + @param left assigned to fLeft + @param top assigned to fTop + @param right assigned to fRight + @param bottom assigned to fBottom + */ void set(int32_t left, int32_t top, int32_t right, int32_t bottom) { fLeft = left; fTop = top; fRight = right; fBottom = bottom; } - // alias for set(l, t, r, b) + + /** Sets SkIRect to (left, top, right, bottom). + left and right are not sorted; left is not necessarily less than right. + top and bottom are not sorted; top is not necessarily less than bottom. + + @param left stored in fLeft + @param top stored in fTop + @param right stored in fRight + @param bottom stored in fBottom + */ void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) { this->set(left, top, right, bottom); } + /** Sets SkIRect to: (x, y, x + width, y + height). Does not validate input; + width or height may be negative. + + @param x stored in fLeft + @param y stored in fTop + @param width added to x and stored in fRight + @param height added to y and stored in fBottom + */ void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) { fLeft = x; fTop = y; @@ -136,46 +294,77 @@ struct SK_API SkIRect { fBottom = y + height; } - /** - * Make the largest representable rectangle - */ + /** Sets rectangle left and top to most negative value, and sets + right and bottom to most positive value. + */ void setLargest() { fLeft = fTop = SK_MinS32; fRight = fBottom = SK_MaxS32; } - /** - * Make the largest representable rectangle, but inverted (e.g. fLeft will - * be max 32bit and right will be min 32bit). - */ + /** Sets rectangle left and top to most positive value, and sets + right and bottom to most negative value. This is used internally to + flag that a condition is met, but otherwise has no special purpose. + */ void setLargestInverted() { fLeft = fTop = SK_MaxS32; fRight = fBottom = SK_MinS32; } - /** - * Return a new IRect, built as an offset of this rect. - */ + /** Returns SkIRect offset by (dx, dy). + + If dx is negative, SkIRect returned is moved to the left. + If dx is positive, SkIRect returned is moved to the right. + If dy is negative, SkIRect returned is moved upward. + If dy is positive, SkIRect returned is moved downward. + + @param dx offset added to fLeft and fRight + @param dy offset added to fTop and fBottom + @return SkRect offset in x or y, with original width and height + */ SkIRect makeOffset(int32_t dx, int32_t dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); } - /** - * Return a new IRect, built as an inset of this rect. - */ + /** Returns SkIRect, inset by (dx, dy). + + If dx is negative, SkIRect returned is wider. + If dx is positive, SkIRect returned is narrower. + If dy is negative, SkIRect returned is taller. + If dy is positive, SkIRect returned is shorter. + + @param dx offset added to fLeft and subtracted from fRight + @param dy offset added to fTop and subtracted from fBottom + @return SkRect inset symmetrically left and right, top and bottom + */ SkIRect makeInset(int32_t dx, int32_t dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); } - /** - * Return a new Rect, built as an outset of this rect. - */ + /** Returns SkIRect, outset by (dx, dy). + + If dx is negative, SkIRect returned is narrower. + If dx is positive, SkIRect returned is wider. + If dy is negative, SkIRect returned is shorter. + If dy is positive, SkIRect returned is taller. + + @param dx offset subtracted to fLeft and added from fRight + @param dy offset subtracted to fTop and added from fBottom + @return SkRect outset symmetrically left and right, top and bottom + */ SkIRect makeOutset(int32_t dx, int32_t dy) const { return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); } - /** Offset set the rectangle by adding dx to its left and right, - and adding dy to its top and bottom. + /** Offsets SkIRect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom. + + If dx is negative, moves SkIRect returned to the left. + If dx is positive, moves SkIRect returned to the right. + If dy is negative, moves SkIRect returned upward. + If dy is positive, moves SkIRect returned downward. + + @param dx offset added to fLeft and fRight + @param dy offset added to fTop and fBottom */ void offset(int32_t dx, int32_t dy) { fLeft += dx; @@ -184,13 +373,26 @@ struct SK_API SkIRect { fBottom += dy; } + /** Offsets SkIRect by adding delta.fX to fLeft, fRight; and by adding delta.fY to + fTop, fBottom. + + If delta.fX is negative, moves SkIRect returned to the left. + If delta.fX is positive, moves SkIRect returned to the right. + If delta.fY is negative, moves SkIRect returned upward. + If delta.fY is positive, moves SkIRect returned downward. + + @param delta offset added to SkIRect + */ void offset(const SkIPoint& delta) { this->offset(delta.fX, delta.fY); } - /** - * Offset this rect such its new x() and y() will equal newX and newY. - */ + /** Offsets SkIRect so that fLeft equals newX, and fTop equals newY. width and height + are unchanged. + + @param newX stored in fLeft, preserving width() + @param newY stored in fTop, preserving height() + */ void offsetTo(int32_t newX, int32_t newY) { fRight += newX - fLeft; fBottom += newY - fTop; @@ -198,9 +400,15 @@ struct SK_API SkIRect { fTop = newY; } - /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards, - making the rectangle narrower. If dx is negative, then the sides are moved outwards, - making the rectangle wider. The same holds true for dy and the top and bottom. + /** Insets SkIRect by (dx,dy). + + If dx is positive, makes SkIRect narrower. + If dx is negative, makes SkIRect wider. + If dy is positive, makes SkIRect shorter. + If dy is negative, makes SkIRect taller. + + @param dx offset added to fLeft and subtracted from fRight + @param dy offset added to fTop and subtracted from fBottom */ void inset(int32_t dx, int32_t dy) { fLeft += dx; @@ -209,29 +417,60 @@ struct SK_API SkIRect { fBottom -= dy; } - /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are - moved outwards, making the rectangle wider. If dx is negative, then the - sides are moved inwards, making the rectangle narrower. The same holds - true for dy and the top and bottom. + /** Outsets SkIRect by (dx, dy). + + If dx is positive, makes SkRect wider. + If dx is negative, makes SkRect narrower. + If dy is positive, makes SkRect taller. + If dy is negative, makes SkRect shorter. + + @param dx subtracted to fLeft and added from fRight + @param dy subtracted to fTop and added from fBottom */ void outset(int32_t dx, int32_t dy) { this->inset(-dx, -dy); } + /** Constructs SkIRect (l, t, r, b) and returns true if constructed SkIRect does not + intersect SkIRect. Does not check to see if construction or SkIRect is empty. + + Is implemented with short circuit logic so that true can be returned after + a single compare. + + @param l x minimum of constructed SkRect + @param t y minimum of constructed SkRect + @param r x maximum of constructed SkRect + @param b y maximum of constructed SkRect + @return true if construction and SkIRect have no area in common + */ bool quickReject(int l, int t, int r, int b) const { return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b; } - /** Returns true if (x,y) is inside the rectangle and the rectangle is not - empty. The left and top are considered to be inside, while the right - and bottom are not. Thus for the rectangle (0, 0, 5, 10), the - points (0,0) and (0,9) are inside, while (-1,0) and (5,9) are not. + /** Returns true if: fLeft <= x < fRight && fTop <= y < fBottom. + Returns false if SkRect is empty. + + Considers input to describe constructed SkIRect: (x, y, x + 1, y + 1) and + returns true if constructed area is completely enclosed by SkIRect area. + + @param x test SkPoint x-coordinate + @param y test SkPoint y-coordinate + @return true if (x, y) is inside SkIRect */ bool contains(int32_t x, int32_t y) const { return (unsigned)(x - fLeft) < (unsigned)(fRight - fLeft) && (unsigned)(y - fTop) < (unsigned)(fBottom - fTop); } - /** Returns true if the 4 specified sides of a rectangle are inside or equal to this rectangle. - If either rectangle is empty, contains() returns false. + /** Constructs SkRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Returns true if SkRect contains construction. + Returns false if SkRect is empty or construction is empty. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect + @return true if all sides of SkIRect are outside construction */ bool contains(int32_t left, int32_t top, int32_t right, int32_t bottom) const { return left < right && top < bottom && !this->isEmpty() && // check for empties @@ -239,7 +478,13 @@ struct SK_API SkIRect { fRight >= right && fBottom >= bottom; } - /** Returns true if the specified rectangle r is inside or equal to this rectangle. + /** Returns true if SkRect contains r. + Returns false if SkRect is empty or r is empty. + + SkRect contains r when SkRect area completely includes r area. + + @param r SkIRect contained + @return true if all sides of SkIRect are outside r */ bool contains(const SkIRect& r) const { return !r.isEmpty() && !this->isEmpty() && // check for empties @@ -247,15 +492,29 @@ struct SK_API SkIRect { fRight >= r.fRight && fBottom >= r.fBottom; } - /** Returns true if the specified rectangle r is inside or equal to this rectangle. + /** Returns true if SkRect contains r. + Returns false if SkRect is empty or r is empty. + + SkRect contains r when SkRect area completely includes r area. + + @param r SkRect contained + @return true if all sides of SkIRect are outside r */ bool contains(const SkRect& r) const; - /** Return true if this rectangle contains the specified rectangle. - For speed, this method does not check if either this or the specified - rectangles are empty, and if either is, its return value is undefined. - In the debugging build however, we assert that both this and the - specified rectangles are non-empty. + /** Constructs SkIRect from (left, top, right, bottom). Does not sort + construction. + + Returns true if SkRect contains construction. + Asserts if SkIRect is empty or construction is empty, and if SK_DEBUG is defined. + + Return is undefined if SkRect is empty or construction is empty. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect + @return true if all sides of SkIRect are outside construction */ bool containsNoEmptyCheck(int32_t left, int32_t top, int32_t right, int32_t bottom) const { @@ -266,21 +525,38 @@ struct SK_API SkIRect { fRight >= right && fBottom >= bottom; } + /** Returns true if SkRect contains construction. + Asserts if SkIRect is empty or construction is empty, and if SK_DEBUG is defined. + + Return is undefined if SkRect is empty or construction is empty. + + @param r SkRect contained + @return true if all sides of SkIRect are outside r + */ bool containsNoEmptyCheck(const SkIRect& r) const { return containsNoEmptyCheck(r.fLeft, r.fTop, r.fRight, r.fBottom); } - /** If r intersects this rectangle, return true and set this rectangle to that - intersection, otherwise return false and do not change this rectangle. - If either rectangle is empty, do nothing and return false. + /** Returns true if SkIRect intersects r, and sets SkIRect to intersection. + Returns false if SkIRect does not intersect r, and leaves SkIRect unchanged. + + Returns false if either r or SkIRect is empty, leaving SkIRect unchanged. + + @param r limit of result + @return true if r and SkRect have area in common */ bool intersect(const SkIRect& r) { return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); } - /** If rectangles a and b intersect, return true and set this rectangle to - that intersection, otherwise return false and do not change this - rectangle. If either rectangle is empty, do nothing and return false. + /** Returns true if a intersects b, and sets SkIRect to intersection. + Returns false if a does not intersect b, and leaves SkIRect unchanged. + + Returns false if either a or b is empty, leaving SkIRect unchanged. + + @param a SkIRect to intersect + @param b SkIRect to intersect + @return true if a and b have area in common */ bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b) { @@ -296,11 +572,14 @@ struct SK_API SkIRect { return false; } - /** If rectangles a and b intersect, return true and set this rectangle to - that intersection, otherwise return false and do not change this - rectangle. For speed, no check to see if a or b are empty is performed. - If either is, then the return result is undefined. In the debug build, - we assert that both rectangles are non-empty. + /** Returns true if a intersects b, and sets SkIRect to intersection. + Returns false if a does not intersect b, and leaves SkIRect unchanged. + + Asserts if either a or b is empty, and if SK_DEBUG is defined. + + @param a SkIRect to intersect + @param b SkIRect to intersect + @return true if a and b have area in common */ bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { SkASSERT(!a.isEmpty() && !b.isEmpty()); @@ -316,10 +595,19 @@ struct SK_API SkIRect { return false; } - /** If the rectangle specified by left,top,right,bottom intersects this rectangle, - return true and set this rectangle to that intersection, - otherwise return false and do not change this rectangle. - If either rectangle is empty, do nothing and return false. + /** Constructs SkIRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Returns true if SkIRect intersects construction, and sets SkIRect to intersection. + Returns false if SkIRect does not intersect construction, and leaves SkIRect unchanged. + + Returns false if either construction or SkIRect is empty, leaving SkIRect unchanged. + + @param left x minimum of constructed SkIRect + @param top y minimum of constructed SkIRect + @param right x maximum of constructed SkIRect + @param bottom y maximum of constructed SkIRect + @return true if construction and SkIRect have area in common */ bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) { if (left < right && top < bottom && !this->isEmpty() && @@ -333,17 +621,26 @@ struct SK_API SkIRect { return false; } - /** Returns true if a and b are not empty, and they intersect - */ + /** Returns true if a intersects b. + Returns false if either a or b is empty, or do not intersect. + + @param a SkIRect to intersect + @param b SkIRect to intersect + @return true if a and b have area in common + */ static bool Intersects(const SkIRect& a, const SkIRect& b) { return !a.isEmpty() && !b.isEmpty() && // check for empties a.fLeft < b.fRight && b.fLeft < a.fRight && a.fTop < b.fBottom && b.fTop < a.fBottom; } - /** - * Returns true if a and b intersect. debug-asserts that neither are empty. - */ + /** Returns true if a intersects b. + Asserts if either a or b is empty, and if SK_DEBUG is defined. + + @param a SkIRect to intersect + @param b SkIRect to intersect + @return true if a and b have area in common + */ static bool IntersectsNoEmptyCheck(const SkIRect& a, const SkIRect& b) { SkASSERT(!a.isEmpty()); SkASSERT(!b.isEmpty()); @@ -351,24 +648,34 @@ struct SK_API SkIRect { a.fTop < b.fBottom && b.fTop < a.fBottom; } - /** Update this rectangle to enclose itself and the specified rectangle. - If this rectangle is empty, just set it to the specified rectangle. If the specified - rectangle is empty, do nothing. + /** Constructs SkRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Sets SkRect to the union of itself and the construction. + + Has no effect if construction is empty. Otherwise, if SkRect is empty, sets + SkRect to construction. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect */ void join(int32_t left, int32_t top, int32_t right, int32_t bottom); - /** Update this rectangle to enclose itself and the specified rectangle. - If this rectangle is empty, just set it to the specified rectangle. If the specified - rectangle is empty, do nothing. + /** Sets SkRect to the union of itself and r. + + Has no effect if r is empty. Otherwise, if SkRect is empty, sets SkRect to r. + + @param r expansion SkRect */ void join(const SkIRect& r) { this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); } - /** Swap top/bottom or left/right if there are flipped. - This can be called if the edges are computed separately, - and may have crossed over each other. - When this returns, left <= right && top <= bottom + /** Swaps fLeft and fRight if fLeft is greater than fRight; and swaps + fTop and fBottom if fTop is greater than fBottom. Result may be empty, + and width() and height() will be zero or positive. */ void sort() { if (fLeft > fRight) { @@ -379,14 +686,21 @@ struct SK_API SkIRect { } } - /** - * Return a new Rect that is the sorted version of this rect (left <= right, top <= bottom). - */ + /** Returns SkRect with fLeft and fRight swapped if fLeft is greater than fRight; and + with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty; + and width() and height() will be zero or positive. + + @return sorted SkIRect + */ SkIRect makeSorted() const { return MakeLTRB(SkMin32(fLeft, fRight), SkMin32(fTop, fBottom), SkMax32(fLeft, fRight), SkMax32(fTop, fBottom)); } + /** Returns a reference to immutable empty SkIRect, set to (0, 0, 0, 0). + + @return global SkIRect set to all zeroes + */ static const SkIRect& SK_WARN_UNUSED_RESULT EmptyIRect() { static const SkIRect gEmpty = { 0, 0, 0, 0 }; return gEmpty; @@ -394,24 +708,66 @@ struct SK_API SkIRect { }; /** \struct SkRect + SkRect holds four SkScalar coordinates describing the upper and + lower bounds of a rectangle. SkRect may be created from outer bounds or + from position, width, and height. SkRect describes an area; if its right + is less than or equal to its left, or if its bottom is less than or equal to + its top, it is considered empty. */ struct SK_API SkRect { - SkScalar fLeft; - SkScalar fTop; - SkScalar fRight; - SkScalar fBottom; + /** May contain any value, including infinities and NaN. The smaller of the + horizontal values when sorted. When equal to or greater than fRight, SkRect is empty. + */ + SkScalar fLeft; + + /** May contain any value, including infinities and NaN. The smaller of the + vertical values when sorted. When equal to or greater than fBottom, SkRect is empty. + */ + SkScalar fTop; + + /** May contain any value, including infinities and NaN. The larger of the + horizontal values when sorted. When equal to or less than fLeft, SkRect is empty. + */ + SkScalar fRight; + + /** May contain any value, including infinities and NaN. The larger of the + vertical values when sorted. When equal to or less than fTop, SkRect is empty. + */ + SkScalar fBottom; + + /** Returns constructed SkRect set to (0, 0, 0, 0). + Many other rectangles are empty; if left is equal to or greater than right, + or if top is equal to or greater than bottom. Setting all members to zero + is a convenience, but does not designate a special empty rectangle. + + @return bounds (0, 0, 0, 0) + */ static constexpr SkRect SK_WARN_UNUSED_RESULT MakeEmpty() { return SkRect{0, 0, 0, 0}; } + /** Returns constructed SkRect setting left and top to most negative finite value, and + setting right and bottom to most positive finite value. + + @return bounds (SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax) + */ static SkRect SK_WARN_UNUSED_RESULT MakeLargest() { SkRect r; r.setLargest(); return r; } - // The largest SkRect for which round() is well-defined. + /** Returns constructed SkRect that can be represented exactly with SkIRect. The left + and top are set to the most negative integer value that fits in a 32-bit float, + and the right and bottom are set to the most positive finite value that fits in + a 32-bit float. + + These are the largest values for which round() is well defined. + + @return bounds (SK_MinS32FitsInFloat, SK_MinS32FitsInFloat, + SK_MaxS32FitsInFloat, SK_MaxS32FitsInFloat) + */ static SkRect SK_WARN_UNUSED_RESULT MakeLargestS32() { const SkRect r = MakeLTRB(SK_MinS32FitsInFloat, SK_MinS32FitsInFloat, SK_MaxS32FitsInFloat, SK_MaxS32FitsInFloat); @@ -419,29 +775,78 @@ struct SK_API SkRect { return r; } + /** Returns constructed SkRect set to SkScalar values (0, 0, w, h). Does not + validate input; w or h may be negative. + + Passing integer values may generate a compiler warning since SkRect cannot + represent 32-bit integers exactly. Use SkIRect for an exact integer rectangle. + + @param w SkScalar width of constructed SkRect + @param h SkScalar height of constructed SkRect + @return bounds (0, 0, w, h) + */ static constexpr SkRect SK_WARN_UNUSED_RESULT MakeWH(SkScalar w, SkScalar h) { return SkRect{0, 0, w, h}; } + /** Returns constructed SkRect set to integer values (0, 0, w, h). Does not validate + input; w or h may be negative. + + Use to avoid a compiler warning that input may lose precision when stored. + Use SkIRect for an exact integer rectangle. + + @param w integer width of constructed SkRect + @param h integer height of constructed SkRect + @return bounds (0, 0, w, h) + */ static SkRect SK_WARN_UNUSED_RESULT MakeIWH(int w, int h) { SkRect r; r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h)); return r; } + /** Returns constructed SkRect set to (0, 0, size.width(), size.height()). Does not + validate input; size.width() or size.height() may be negative. + + @param size SkScalar values for SkRect width and height + @return bounds (0, 0, size.width(), size.height()) + */ static constexpr SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { return SkRect{0, 0, size.fWidth, size.fHeight}; } + /** Returns constructed SkRect set to (l, t, r, b). Does not sort input; SkRect may + result in fLeft greater than fRight, or fTop greater than fBottom. + + @param l SkScalar stored in fLeft + @param t SkScalar stored in fTop + @param r SkScalar stored in fRight + @param b SkScalar stored in fBottom + @return bounds (l, t, r, b) + */ static constexpr SkRect SK_WARN_UNUSED_RESULT MakeLTRB(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { return SkRect {l, t, r, b}; } + /** Returns constructed SkRect set to (x, y, x + w, y + h). Does not validate input; + w or h may be negative. + + @param x stored in fLeft + @param y stored in fTop + @param w added to x and stored in fRight + @param h added to y and stored in fBottom + @return bounds at (x, y) with width w and height h + */ static constexpr SkRect SK_WARN_UNUSED_RESULT MakeXYWH(SkScalar x, SkScalar y, SkScalar w, SkScalar h) { return SkRect {x, y, x + w, y + h}; } + /** Deprecated. + + @param irect integer rect + @return irect as SkRect + */ SK_ATTR_DEPRECATED("use Make()") static SkRect SK_WARN_UNUSED_RESULT MakeFromIRect(const SkIRect& irect) { SkRect r; @@ -452,10 +857,23 @@ struct SK_API SkRect { return r; } + /** Returns constructed SkIRect set to (0, 0, size.width(), size.height()). + Does not validate input; size.width() or size.height() may be negative. + + @param size integer values for SkRect width and height + @return bounds (0, 0, size.width(), size.height()) + */ static SkRect Make(const SkISize& size) { return MakeIWH(size.width(), size.height()); } + /** Returns constructed SkIRect set to irect, promoting integers to scalar. + Does not validate input; fLeft may be greater than fRight, fTop may be greater + than fBottom. + + @param irect integer unsorted bounds + @return irect members converted to SkScalar + */ static SkRect SK_WARN_UNUSED_RESULT Make(const SkIRect& irect) { SkRect r; r.set(SkIntToScalar(irect.fLeft), @@ -465,25 +883,36 @@ struct SK_API SkRect { return r; } - /** - * Return true if the rectangle's width or height are <= 0 - */ + /** Returns true if fLeft is equal to or greater than fRight, or if fTop is equal + to or greater than fBottom. Call sort() to reverse rectangles with negative + width() or height(). + + @return true if width() or height() are zero or negative + */ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; } - /** - * Return true if the rectangle's width and height are >= 0 - */ + /** Returns true if fLeft is equal to or less than fRight, or if fTop is equal + to or less than fBottom. Call sort() to reverse rectangles with negative + width() or height(). + + @return true if width() or height() are zero or positive + */ bool isSorted() const { return fLeft <= fRight && fTop <= fBottom; } + /** Returns true if SkRect encloses largest possible area. + + @return true if equal to (SK_ScalarMin, SK_ScalarMin, SK_ScalarMax, SK_ScalarMax) + */ bool isLargest() const { return SK_ScalarMin == fLeft && SK_ScalarMin == fTop && SK_ScalarMax == fRight && SK_ScalarMax == fBottom; } - /** - * Returns true iff all values in the rect are finite. If any are - * infinite or NaN then this returns false. - */ + /** Returns true if all values in the rectangle are finite: SK_ScalarMin or larger, + and SK_ScalarMax or smaller. + + @return true if no member is infinite or NaN + */ bool isFinite() const { float accum = 0; accum *= fLeft; @@ -499,34 +928,125 @@ struct SK_API SkRect { return !SkScalarIsNaN(accum); } + /** Returns left edge of SkRect, if sorted. Call isSorted() to see if SkRect is valid. + Call sort() to reverse fLeft and fRight if needed. + + @return fLeft + */ SkScalar x() const { return fLeft; } + + /** Returns top edge of SkRect, if sorted. Call isEmpty() to see if SkRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fTop + */ SkScalar y() const { return fTop; } + + /** Returns left edge of SkRect, if sorted. Call isSorted() to see if SkRect is valid. + Call sort() to reverse fLeft and fRight if needed. + + @return fLeft + */ SkScalar left() const { return fLeft; } + + /** Returns top edge of SkRect, if sorted. Call isEmpty() to see if SkRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fTop + */ SkScalar top() const { return fTop; } + + /** Returns right edge of SkRect, if sorted. Call isSorted() to see if SkRect is valid. + Call sort() to reverse fLeft and fRight if needed. + + @return fRight + */ SkScalar right() const { return fRight; } + + /** Returns bottom edge of SkRect, if sorted. Call isEmpty() to see if SkRect may be invalid, + and sort() to reverse fTop and fBottom if needed. + + @return fBottom + */ SkScalar bottom() const { return fBottom; } + + /** Returns span on the x-axis. This does not check if SkRect is sorted, or if + result fits in 32-bit float; result may be negative or infinity. + + @return fRight minus fLeft + */ SkScalar width() const { return fRight - fLeft; } + + /** Returns span on the y-axis. This does not check if SkIRect is sorted, or if + result fits in 32-bit float; result may be negative or infinity. + + @return fBottom minus fTop + */ SkScalar height() const { return fBottom - fTop; } + + /** Returns average of left edge and right edge. Result does not change if SkRect + is sorted. Result may overflow to infinity if SkRect is far from the origin. + + @return midpoint in x + */ SkScalar centerX() const { return SkScalarHalf(fLeft + fRight); } + + /** Returns average of top edge and bottom edge. Result does not change if SkRect + is sorted. Result may overflow to infinity if SkRect is far from the origin. + + @return midpoint in y + */ SkScalar centerY() const { return SkScalarHalf(fTop + fBottom); } + /** Returns true if all members in a: fLeft, fTop, fRight, and fBottom; are + equal to the corresponding members in b. + + a and b are not equal if either contain NaN. a and b are equal if members + contain zeroes width different signs. + + @param a SkRect to compare + @param b SkRect to compare + @return true if members are equal + */ friend bool operator==(const SkRect& a, const SkRect& b) { return SkScalarsEqual((const SkScalar*)&a, (const SkScalar*)&b, 4); } + /** Returns true if any in a: fLeft, fTop, fRight, and fBottom; does not + equal the corresponding members in b. + + a and b are not equal if either contain NaN. a and b are equal if members + contain zeroes width different signs. + + @param a SkRect to compare + @param b SkRect to compare + @return true if members are not equal + */ friend bool operator!=(const SkRect& a, const SkRect& b) { return !SkScalarsEqual((const SkScalar*)&a, (const SkScalar*)&b, 4); } - /** return the 4 points that enclose the rectangle (top-left, top-right, bottom-right, - bottom-left). TODO: Consider adding param to control whether quad is CW or CCW. - */ + /** Returns four points in quad that enclose SkRect ordered as: top-left, top-right, + bottom-right, bottom-left. + Consider adding param to control whether quad is CW or CCW. + + @param quad storage for corners of SkRect + */ void toQuad(SkPoint quad[4]) const; - /** Set this rectangle to the empty rectangle (0,0,0,0) + /** Sets SkRect to (0, 0, 0, 0). + + Many other rectangles are empty; if left is equal to or greater than right, + or if top is equal to or greater than bottom. Setting all members to zero + is a convenience, but does not designate a special empty rectangle. */ void setEmpty() { *this = MakeEmpty(); } + /** Sets SkRect to src, promoting src members from integer to scalar. + Very large values in src may lose precision. + + @param src integer SkRect + */ void set(const SkIRect& src) { fLeft = SkIntToScalar(src.fLeft); fTop = SkIntToScalar(src.fTop); @@ -534,20 +1054,45 @@ struct SK_API SkRect { fBottom = SkIntToScalar(src.fBottom); } + /** Sets SkRect to (left, top, right, bottom). + left and right are not sorted; left is not necessarily less than right. + top and bottom are not sorted; top is not necessarily less than bottom. + + @param left stored in fLeft + @param top stored in fTop + @param right stored in fRight + @param bottom stored in fBottom + */ void set(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { fLeft = left; fTop = top; fRight = right; fBottom = bottom; } - // alias for set(l, t, r, b) + + /** Sets SkRect to (left, top, right, bottom). + left and right are not sorted; left is not necessarily less than right. + top and bottom are not sorted; top is not necessarily less than bottom. + + @param left stored in fLeft + @param top stored in fTop + @param right stored in fRight + @param bottom stored in fBottom + */ void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) { this->set(left, top, right, bottom); } - /** Initialize the rect with the 4 specified integers. The routine handles - converting them to scalars (by calling SkIntToScalar) - */ + /** Sets SkRect to (left, top, right, bottom). + All parameters are promoted from integer to scalar. + left and right are not sorted; left is not necessarily less than right. + top and bottom are not sorted; top is not necessarily less than bottom. + + @param left promoted to SkScalar and stored in fLeft + @param top promoted to SkScalar and stored in fTop + @param right promoted to SkScalar and stored in fRight + @param bottom promoted to SkScalar and stored in fBottom + */ void iset(int left, int top, int right, int bottom) { fLeft = SkIntToScalar(left); fTop = SkIntToScalar(top); @@ -555,19 +1100,27 @@ struct SK_API SkRect { fBottom = SkIntToScalar(bottom); } - /** - * Set this rectangle to be left/top at 0,0, and have the specified width - * and height (automatically converted to SkScalar). - */ + /** Sets SkRect to (0, 0, width, height). + width and height may be zero or negative. width and height are promoted from + integer to SkScalar, large values may lose precision. + + @param width promoted to SkScalar and stored in fRight + @param height promoted to SkScalar and stored in fBottom + */ void isetWH(int width, int height) { fLeft = fTop = 0; fRight = SkIntToScalar(width); fBottom = SkIntToScalar(height); } - /** Set this rectangle to be the bounds of the array of points. - If the array is empty (count == 0), then set this rectangle - to the empty rectangle (0,0,0,0) + /** Sets to bounds of SkPoint array with count entries. If count is zero or smaller, + or if SkPoint array contains an infinity or NaN, sets SkRect to (0, 0, 0, 0). + + Result is either empty or sorted: fLeft is less than or equal to fRight, and + fTop is less than or equal to fBottom. + + @param pts SkPoint array + @param count entries in array */ void set(const SkPoint pts[], int count) { // set() had been checking for non-finite values, so keep that behavior @@ -576,18 +1129,38 @@ struct SK_API SkRect { (void)this->setBoundsCheck(pts, count); } - // alias for set(pts, count) + /** Sets to bounds of SkPoint array with count entries. If count is zero or smaller, + or if SkPoint array contains an infinity or NaN, sets to (0, 0, 0, 0). + + Result is either empty or sorted: fLeft is less than or equal to fRight, and + fTop is less than or equal to fBottom. + + @param pts SkPoint array + @param count entries in array + */ void setBounds(const SkPoint pts[], int count) { (void)this->setBoundsCheck(pts, count); } - /** - * Compute the bounds of the array of points, and set this rect to that - * bounds and return true... unless a non-finite value is encountered, - * in which case this rect is set to empty and false is returned. - */ + /** Sets to bounds of SkPoint array with count entries. Returns false if count is + zero or smaller, or if SkPoint array contains an infinity or NaN; in these cases + sets SkRect to (0, 0, 0, 0). + + Result is either empty or sorted: fLeft is less than or equal to fRight, and + fTop is less than or equal to fBottom. + + @param pts SkPoint array + @param count entries in array + @return true if all SkPoint values are finite + */ bool setBoundsCheck(const SkPoint pts[], int count); + /** Sets bounds to the smallest SkRect enclosing points p0 and p1. The result is + sorted and may be empty. Does not check to see if values are finite. + + @param p0 corner to include + @param p1 corner to include + */ void set(const SkPoint& p0, const SkPoint& p1) { fLeft = SkMinScalar(p0.fX, p1.fX); fRight = SkMaxScalar(p0.fX, p1.fX); @@ -595,6 +1168,14 @@ struct SK_API SkRect { fBottom = SkMaxScalar(p0.fY, p1.fY); } + /** Sets SkRect to (x, y, x + width, y + height). Does not validate input; + width or height may be negative. + + @param x stored in fLeft + @param y stored in fTop + @param width added to x and stored in fRight + @param height added to y and stored in fBottom + */ void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) { fLeft = x; fTop = y; @@ -602,6 +1183,12 @@ struct SK_API SkRect { fBottom = y + height; } + /** Sets SkRect to (0, 0, width, height). Does not validate input; + width or height may be negative. + + @param width stored in fRight + @param height stored in fBottom + */ void setWH(SkScalar width, SkScalar height) { fLeft = 0; fTop = 0; @@ -609,46 +1196,78 @@ struct SK_API SkRect { fBottom = height; } - /** - * Make the largest representable rectangle - */ + /** Sets rectangle left and top to most negative finite value, and sets + right and bottom to most positive finite value. + */ void setLargest() { fLeft = fTop = SK_ScalarMin; fRight = fBottom = SK_ScalarMax; } - /** - * Make the largest representable rectangle, but inverted (e.g. fLeft will - * be max and right will be min). - */ + /** Sets rectangle left and top to most positive finite value, and sets + right and bottom to most negative finite value. + + Use to initial SkRect before one or more calls to growToInclude(). + */ void setLargestInverted() { fLeft = fTop = SK_ScalarMax; fRight = fBottom = SK_ScalarMin; } - /** - * Return a new Rect, built as an offset of this rect. - */ + /** Returns SkRect offset by (dx, dy). + + If dx is negative, SkRect returned is moved to the left. + If dx is positive, SkRect returned is moved to the right. + If dy is negative, SkRect returned is moved upward. + If dy is positive, SkRect returned is moved downward. + + @param dx added to fLeft and fRight + @param dy added to fTop and fBottom + @return SkRect offset in x or y, with original width and height + */ SkRect makeOffset(SkScalar dx, SkScalar dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); } - /** - * Return a new Rect, built as an inset of this rect. - */ + /** Returns SkRect, inset by (dx, dy). + + If dx is negative, SkRect returned is wider. + If dx is positive, SkRect returned is narrower. + If dy is negative, SkRect returned is taller. + If dy is positive, SkRect returned is shorter. + + @param dx added to fLeft and subtracted from fRight + @param dy added to fTop and subtracted from fBottom + @return SkRect inset symmetrically left and right, top and bottom + */ SkRect makeInset(SkScalar dx, SkScalar dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); } - /** - * Return a new Rect, built as an outset of this rect. - */ + /** Returns SkRect, outset by (dx, dy). + + If dx is negative, SkRect returned is narrower. + If dx is positive, SkRect returned is wider. + If dy is negative, SkRect returned is shorter. + If dy is positive, SkRect returned is taller. + + @param dx subtracted to fLeft and added from fRight + @param dy subtracted to fTop and added from fBottom + @return SkRect outset symmetrically left and right, top and bottom + */ SkRect makeOutset(SkScalar dx, SkScalar dy) const { return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); } - /** Offset set the rectangle by adding dx to its left and right, - and adding dy to its top and bottom. + /** Offsets SkRect by adding dx to fLeft, fRight; and by adding dy to fTop, fBottom. + + If dx is negative, moves SkRect to the left. + If dx is positive, moves SkRect to the right. + If dy is negative, moves SkRect upward. + If dy is positive, moves SkRect downward. + + @param dx offset added to fLeft and fRight + @param dy offset added to fTop and fBottom */ void offset(SkScalar dx, SkScalar dy) { fLeft += dx; @@ -657,13 +1276,26 @@ struct SK_API SkRect { fBottom += dy; } + /** Offsets SkRect by adding delta.fX to fLeft, fRight; and by adding delta.fY to + fTop, fBottom. + + If delta.fX is negative, moves SkRect to the left. + If delta.fX is positive, moves SkRect to the right. + If delta.fY is negative, moves SkRect upward. + If delta.fY is positive, moves SkRect downward. + + @param delta added to SkRect + */ void offset(const SkPoint& delta) { this->offset(delta.fX, delta.fY); } - /** - * Offset this rect such its new x() and y() will equal newX and newY. - */ + /** Offsets SkRect so that fLeft equals newX, and fTop equals newY. width and height + are unchanged. + + @param newX stored in fLeft, preserving width() + @param newY stored in fTop, preserving height() + */ void offsetTo(SkScalar newX, SkScalar newY) { fRight += newX - fLeft; fBottom += newY - fTop; @@ -671,10 +1303,15 @@ struct SK_API SkRect { fTop = newY; } - /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are - moved inwards, making the rectangle narrower. If dx is negative, then - the sides are moved outwards, making the rectangle wider. The same holds - true for dy and the top and bottom. + /** Insets SkRect by (dx, dy). + + If dx is positive, makes SkRect narrower. + If dx is negative, makes SkRect wider. + If dy is positive, makes SkRect shorter. + If dy is negative, makes SkRect taller. + + @param dx added to fLeft and subtracted from fRight + @param dy added to fTop and subtracted from fBottom */ void inset(SkScalar dx, SkScalar dy) { fLeft += dx; @@ -683,31 +1320,53 @@ struct SK_API SkRect { fBottom -= dy; } - /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are - moved outwards, making the rectangle wider. If dx is negative, then the - sides are moved inwards, making the rectangle narrower. The same holds - true for dy and the top and bottom. + /** Outsets SkRect by (dx, dy). + + If dx is positive, makes SkRect wider. + If dx is negative, makes SkRect narrower. + If dy is positive, makes SkRect taller. + If dy is negative, makes SkRect shorter. + + @param dx subtracted to fLeft and added from fRight + @param dy subtracted to fTop and added from fBottom */ void outset(SkScalar dx, SkScalar dy) { this->inset(-dx, -dy); } - /** If this rectangle intersects r, return true and set this rectangle to that - intersection, otherwise return false and do not change this rectangle. - If either rectangle is empty, do nothing and return false. + /** Returns true if SkRect intersects r, and sets SkRect to intersection. + Returns false if SkRect does not intersect r, and leaves SkRect unchanged. + + Returns false if either r or SkRect is empty, leaving SkRect unchanged. + + @param r limit of result + @return true if r and SkRect have area in common */ bool intersect(const SkRect& r); - /** If this rectangle intersects the rectangle specified by left, top, right, bottom, - return true and set this rectangle to that intersection, otherwise return false - and do not change this rectangle. - If either rectangle is empty, do nothing and return false. + /** Constructs SkRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Returns true if SkRect intersects construction, and sets SkRect to intersection. + Returns false if SkRect does not intersect construction, and leaves SkRect unchanged. + + Returns false if either construction or SkRect is empty, leaving SkRect unchanged. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect + @return true if construction and SkRect have area in common */ bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); - /** - * If rectangles a and b intersect, return true and set this rectangle to - * that intersection, otherwise return false and do not change this - * rectangle. If either rectangle is empty, do nothing and return false. - */ + /** Returns true if a intersects b, and sets SkRect to intersection. + Returns false if a does not intersect b, and leaves SkRect unchanged. + + Returns false if either a or b is empty, leaving SkRect unchanged. + + @param a SkRect to intersect + @param b SkRect to intersect + @return true if a and b have area in common + */ bool SK_WARN_UNUSED_RESULT intersect(const SkRect& a, const SkRect& b); @@ -722,42 +1381,81 @@ private: } public: - /** - * Return true if this rectangle is not empty, and the specified sides of - * a rectangle are not empty, and they intersect. - */ + + /** Constructs SkRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Returns true if SkRect intersects construction. + Returns false if either construction or SkRect is empty, or do not intersect. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect + @return true if construction and SkRect have area in common + */ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom); } + /** Returns true if SkRect intersects r. + Returns false if either r or SkRect is empty, or do not intersect. + + @param r SkRect to intersect + @return true if r and SkRect have area in common + */ bool intersects(const SkRect& r) const { return Intersects(fLeft, fTop, fRight, fBottom, r.fLeft, r.fTop, r.fRight, r.fBottom); } - /** - * Return true if rectangles a and b are not empty and intersect. - */ + /** Returns true if a intersects b. + Returns false if either a or b is empty, or do not intersect. + + @param a SkRect to intersect + @param b SkRect to intersect + @return true if a and b have area in common + */ static bool Intersects(const SkRect& a, const SkRect& b) { return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, b.fLeft, b.fTop, b.fRight, b.fBottom); } - /** - * Update this rectangle to enclose itself and the specified rectangle. - * If this rectangle is empty, just set it to the specified rectangle. - * If the specified rectangle is empty, do nothing. - */ + /** Constructs SkRect to intersect from (left, top, right, bottom). Does not sort + construction. + + Sets SkRect to the union of itself and the construction. + + Has no effect if construction is empty. Otherwise, if SkRect is empty, sets + SkRect to construction. + + @param left x minimum of constructed SkRect + @param top y minimum of constructed SkRect + @param right x maximum of constructed SkRect + @param bottom y maximum of constructed SkRect + */ void join(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); - /** Update this rectangle to enclose itself and the specified rectangle. - If this rectangle is empty, just set it to the specified rectangle. If the specified - rectangle is empty, do nothing. + /** Sets SkRect to the union of itself and r. + + Has no effect if r is empty. Otherwise, if SkRect is empty, sets + SkRect to r. + + @param r expansion SkRect */ void join(const SkRect& r) { this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); } + /** Sets SkRect to the union of itself and r. + + Asserts if r is empty and SK_DEBUG is defined. + If SkRect is empty, sets SkRect to r. + + May produce incorrect results if r is empty. + + @param r expansion SkRect + */ void joinNonEmptyArg(const SkRect& r) { SkASSERT(!r.isEmpty()); // if we are empty, just assign @@ -768,10 +1466,12 @@ public: } } - /** - * Joins the rectangle with another without checking if either are empty (may produce unexpected - * results if either rect is inverted). - */ + /** Sets SkRect to the union of itself and the construction. + + May produce incorrect results if SkRect or r is empty. + + @param r expansion SkRect + */ void joinPossiblyEmptyRect(const SkRect& r) { fLeft = SkMinScalar(fLeft, r.left()); fTop = SkMinScalar(fTop, r.top()); @@ -779,15 +1479,14 @@ public: fBottom = SkMaxScalar(fBottom, r.bottom()); } - /** - * Grow the rect to include the specified (x,y). After this call, the - * following will be true: fLeft <= x <= fRight && fTop <= y <= fBottom. - * - * This is close, but not quite the same contract as contains(), since - * contains() treats the left and top different from the right and bottom. - * contains(x,y) -> fLeft <= x < fRight && fTop <= y < fBottom. Also note - * that contains(x,y) always returns false if the rect is empty. - */ + /** Grows SkRect to include (pt.fX, pt.fY), modifying it so that: + fLeft <= pt.fX <= fRight && fTop <= pt.fY <= fBottom. + + If SkRect is initialized with setLargestInverted(), then SkRect will contain bounds of + points after one or more calls. In this case, SkRect is empty after first call. + + @param pt SkPoint to include + */ void growToInclude(SkPoint pt) { fLeft = SkMinScalar(pt.fX, fLeft); fRight = SkMaxScalar(pt.fX, fRight); @@ -795,12 +1494,33 @@ public: fBottom = SkMaxScalar(pt.fY, fBottom); } - /** Bulk version of growToInclude */ + /** For each of count SkPoint in pts, grows SkRect to include (pt.fX, pt.fY), modifying + it so that: fLeft <= pt.fX <= fRight && fTop <= pt.fY <= fBottom. + + If SkRect is initialized with setLargestInverted(), then SkRect will contain bounds of + points after one or more calls. In this case, SkRect is empty after first call. + + @param pts SkPoint array + @param count number of points in array + */ void growToInclude(const SkPoint pts[], int count) { this->growToInclude(pts, sizeof(SkPoint), count); } - /** Bulk version of growToInclude with stride. */ + /** For each of count SkPoint in pts, grows SkRect to include (pt.fX, pt.fY), modifying + it so that: fLeft <= pt.fX <= fRight && fTop <= pt.fY <= fBottom. + + SkPoint may be followed with other data in each array element. stride is number + of bytes in element; the interval to skip to advance from one SkPoint to + the next. + + If SkRect is initialized with setLargestInverted(), then SkRect will contain bounds of + points after one or more calls. In this case, SkRect is empty after first call. + + @param pts array of elements beginning with SkPoint + @param stride size of pts elements in 32-bit words; zero or greater + @param count number of elements in array + */ void growToInclude(const SkPoint pts[], size_t stride, int count) { SkASSERT(count >= 0); SkASSERT(stride >= sizeof(SkPoint)); @@ -810,10 +1530,14 @@ public: } } - /** - * Return true if this rectangle contains r, and if both rectangles are - * not empty. - */ + /** Returns true if SkRect contains r. + Returns false if SkRect is empty or r is empty. + + SkRect contains r when SkRect area completely includes r area. + + @param r SkRect contained + @return true if all sides of SkRect are outside r + */ bool contains(const SkRect& r) const { // todo: can we eliminate the this->isEmpty check? return !r.isEmpty() && !this->isEmpty() && @@ -821,9 +1545,14 @@ public: fRight >= r.fRight && fBottom >= r.fBottom; } - /** - * Returns true if the specified rectangle r is inside or equal to this rectangle. - */ + /** Returns true if SkRect contains r. + Returns false if SkRect is empty or r is empty. + + SkRect contains r when SkRect area completely includes r area. + + @param r SkIRect contained + @return true if all sides of SkRect are outside r + */ bool contains(const SkIRect& r) const { // todo: can we eliminate the this->isEmpty check? return !r.isEmpty() && !this->isEmpty() && @@ -831,32 +1560,36 @@ public: fRight >= SkIntToScalar(r.fRight) && fBottom >= SkIntToScalar(r.fBottom); } - /** - * Set the dst rectangle by rounding this rectangle's coordinates to their - * nearest integer values using SkScalarRoundToInt. - */ + /** Sets SkIRect by adding 0.5 and discarding the fractional portion of SkRect + members, using (SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), + SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)). + + @param dst storage for SkIRect + */ void round(SkIRect* dst) const { SkASSERT(dst); dst->set(SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)); } - /** - * Set the dst rectangle by rounding "out" this rectangle, choosing the - * SkScalarFloor of top and left, and the SkScalarCeil of right and bottom. - */ + /** Sets SkIRect by discarding the fractional portion of fLeft and fTop; and + rounding up fRight and fbottom, using (SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), + SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)). + + @param dst storage for SkIRect + */ void roundOut(SkIRect* dst) const { SkASSERT(dst); dst->set(SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)); } - /** - * Set the dst rectangle by rounding "out" this rectangle, choosing the - * SkScalarFloorToScalar of top and left, and the SkScalarCeilToScalar of right and bottom. - * - * It is safe for this == dst - */ + /** Sets SkRect by discarding the fractional portion of fLeft and fTop; and + rounding up fRight and fbottom, using (SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), + SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)). + + @param dst storage for SkRect + */ void roundOut(SkRect* dst) const { dst->set(SkScalarFloorToScalar(fLeft), SkScalarFloorToScalar(fTop), @@ -864,38 +1597,47 @@ public: SkScalarCeilToScalar(fBottom)); } - /** - * Set the dst rectangle by rounding "in" this rectangle, choosing the - * ceil of top and left, and the floor of right and bottom. This does *not* - * call sort(), so it is possible that the resulting rect is inverted... - * e.g. left >= right or top >= bottom. Call isEmpty() to detect that. - */ + /** Sets SkRect by rounding up fLeft and fTop; and + discarding the fractional portion of fRight and fbottom, using + (SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop), + SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)). + + @param dst storage for SkIRect + */ void roundIn(SkIRect* dst) const { SkASSERT(dst); dst->set(SkScalarCeilToInt(fLeft), SkScalarCeilToInt(fTop), SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); } - //! Returns the result of calling round(&dst) + /** Returns SkIRect by adding 0.5 and discarding the fractional portion of SkRect + members, using (SkScalarRoundToInt(fLeft), SkScalarRoundToInt(fTop), + SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom)). + + @return rounded SkIRect + */ SkIRect round() const { SkIRect ir; this->round(&ir); return ir; } - //! Returns the result of calling roundOut(&dst) + /** Sets SkIRect by discarding the fractional portion of fLeft and fTop; and + rounding up fRight and fbottom, using (SkScalarFloorToInt(fLeft), SkScalarFloorToInt(fTop), + SkScalarCeilToInt(fRight), SkScalarCeilToInt(fBottom)). + + @return rounded SkIRect + */ SkIRect roundOut() const { SkIRect ir; this->roundOut(&ir); return ir; } - /** - * Swap top/bottom or left/right if there are flipped (i.e. if width() - * or height() would have returned a negative value.) This should be called - * if the edges are computed separately, and may have crossed over each - * other. When this returns, left <= right && top <= bottom - */ + /** Swaps fLeft and fRight if fLeft is greater than fRight; and swaps + fTop and fBottom if fTop is greater than fBottom. Result may be empty; + and width() and height() will be zero or positive. + */ void sort() { if (fLeft > fRight) { SkTSwap<SkScalar>(fLeft, fRight); @@ -906,21 +1648,45 @@ public: } } - /** - * Return a new Rect that is the sorted version of this rect (left <= right, top <= bottom). - */ + /** Returns SkRect with fLeft and fRight swapped if fLeft is greater than fRight; and + with fTop and fBottom swapped if fTop is greater than fBottom. Result may be empty; + and width() and height() will be zero or positive. + + @return sorted SkRect + */ SkRect makeSorted() const { return MakeLTRB(SkMinScalar(fLeft, fRight), SkMinScalar(fTop, fBottom), SkMaxScalar(fLeft, fRight), SkMaxScalar(fTop, fBottom)); } - /** - * cast-safe way to treat the rect as an array of (4) SkScalars. - */ + /** Returns pointer to first scalar in SkRect, to treat it as an array with four + entries. + + @return pointer to fLeft + */ const SkScalar* asScalars() const { return &fLeft; } + /** Writes text representation of SkRect to standard output. Set asHex to true to + generate exact binary representations of floating point numbers. + + @param asHex true if SkScalar values are written as hexadecimal + */ void dump(bool asHex) const; + + /** Writes text representation of SkRect to standard output. The representation may be + directly compiled as C++ code. Floating point values are written + with limited precision; it may not be possible to reconstruct original SkRect + from output. + */ void dump() const { this->dump(false); } + + /** Writes text representation of SkRect to standard output. The representation may be + directly compiled as C++ code. Floating point values are written + in hexadecimal to preserve their exact bit pattern. The output reconstructs the + original SkRect. + + Use instead of dump() when submitting + */ void dumpHex() const { this->dump(true); } }; |