diff options
author | Brian Salomon <bsalomon@google.com> | 2017-12-15 11:31:05 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-19 21:10:36 +0000 |
commit | 0a241ce808511ceb1c72d6f2473b01b455ac5101 (patch) | |
tree | c137018f24c515dde2d85d4eb6d3f0b7ed0081a7 /include/core/SkRRect.h | |
parent | ab10c8258d7588bb9c353a8ecc1944747a4fac62 (diff) |
Don't canonicalize empty SkRRects. They stroke differently.
Make insetting greater than width or height collapse to a point/line.
SkPath::addRRect() doesn't ignore an empty SkRRect.
Change-Id: I933a3419a6d75be534f1d8328faa715772045f67
Reviewed-on: https://skia-review.googlesource.com/85680
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'include/core/SkRRect.h')
-rw-r--r-- | include/core/SkRRect.h | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/include/core/SkRRect.h b/include/core/SkRRect.h index 06edab9245..798dd47f13 100644 --- a/include/core/SkRRect.h +++ b/include/core/SkRRect.h @@ -48,7 +48,9 @@ class SkWBuffer; */ class SK_API SkRRect { public: - SkRRect() { this->setEmpty(); } + /** Default initialized to a rrect at the origin with zero width and height. */ + SkRRect() = default; + SkRRect(const SkRRect&) = default; SkRRect& operator=(const SkRRect&) = default; @@ -57,7 +59,7 @@ public: * by type(). The subtypes become progressively less restrictive. */ enum Type { - // !< The RR is empty + // !< The RR has zero width and/or zero height. All radii are zero. kEmpty_Type, //!< The RR is actually a (non-empty) rect (i.e., at least one radius @@ -120,25 +122,15 @@ public: SkScalar height() const { return fRect.height(); } /** - * Set this RR to the empty rectangle (0,0,0,0) with 0 x & y radii. + * Same as default initialized - zero width and height at the origin. */ - void setEmpty() { - fRect.setEmpty(); - memset(fRadii, 0, sizeof(fRadii)); - fType = kEmpty_Type; - - SkASSERT(this->isValid()); - } + void setEmpty() { *this = SkRRect(); } /** * Set this RR to match the supplied rect. All radii will be 0. */ void setRect(const SkRect& rect) { - fRect = rect; - fRect.sort(); - - if (fRect.isEmpty() || !fRect.isFinite()) { - this->setEmpty(); + if (!this->initializeRect(rect)) { return; } @@ -148,11 +140,8 @@ public: SkASSERT(this->isValid()); } - static SkRRect MakeEmpty() { - SkRRect rr; - rr.setEmpty(); - return rr; - } + /** Makes an empty rrect at the origin with zero width and height. */ + static SkRRect MakeEmpty() { return SkRRect(); } static SkRRect MakeRect(const SkRect& r) { SkRRect rr; @@ -177,11 +166,7 @@ public: * width and all y radii will equal half the height. */ void setOval(const SkRect& oval) { - fRect = oval; - fRect.sort(); - - if (fRect.isEmpty() || !fRect.isFinite()) { - this->setEmpty(); + if (!this->initializeRect(oval)) { return; } @@ -247,6 +232,12 @@ public: * otherwise we grow/shrink the radii by the amount of the inset. If a * given radius becomes negative, it is pinned to 0. * + * If the inset amount is larger than the width/height then the rrect collapses to + * a degenerate line or point. + * + * If the inset is sufficiently negative to cause the bounds to become infinite then + * the result is a default initialized rrect. + * * It is valid for dst == this. */ void inset(SkScalar dx, SkScalar dy, SkRRect* dst) const; @@ -337,18 +328,23 @@ private: , fRadii{radii[0], radii[1], radii[2], radii[3]} , fType(type) {} - SkRect fRect; - // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] - SkVector fRadii[4]; - // use an explicitly sized type so we're sure the class is dense (no uninitialized bytes) - int32_t fType; - // TODO: add padding so we can use memcpy for flattening and not copy - // uninitialized data + /** + * Initializes fRect. If the passed in rect is not finite or empty the rrect will be fully + * initialized and false is returned. Otherwise, just fRect is initialized and true is returned. + */ + bool initializeRect(const SkRect&); void computeType(); bool checkCornerContainment(SkScalar x, SkScalar y) const; void scaleRadii(); + SkRect fRect = SkRect::MakeEmpty(); + // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] + SkVector fRadii[4] = {{0, 0}, {0, 0}, {0,0}, {0,0}}; + // use an explicitly sized type so we're sure the class is dense (no uninitialized bytes) + int32_t fType = kEmpty_Type; + // TODO: add padding so we can use memcpy for flattening and not copy uninitialized data + // to access fRadii directly friend class SkPath; }; |