Chromium Code Reviews| Index: src/core/SkRRect.cpp |
| diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp |
| index d3dce98ad5f103ddade09c219c4e09a117d2f884..788bf1d9a693c98084249ed08ad9ed9e32a9801a 100644 |
| --- a/src/core/SkRRect.cpp |
| +++ b/src/core/SkRRect.cpp |
| @@ -117,17 +117,12 @@ static inline SkScalar SkScalarDecULP(SkScalar value) { |
| #endif |
| } |
| -static SkScalar clamp_radius_add(SkScalar rad, SkScalar min, SkScalar max) { |
| - SkASSERT(rad <= max - min); |
| - if (min + rad > max) { |
| - rad = SkScalarDecULP(rad); |
| - } |
| - return rad; |
| -} |
| - |
| -static SkScalar clamp_radius_sub(SkScalar rad, SkScalar min, SkScalar max) { |
| - SkASSERT(rad <= max - min); |
| - if (max - rad < min) { |
| + /** |
|
robertphillips
2015/02/13 22:31:03
missing spaces here ?
|
| + * We need all combinations of predicates to be true to have a "safe" radius value. |
| + */ |
| +static SkScalar clamp_radius_check_predicates(SkScalar rad, SkScalar min, SkScalar max) { |
| + SkASSERT(min < max); |
| + if (rad > max - min || min + rad > max || max - rad < min) { |
| rad = SkScalarDecULP(rad); |
| } |
| return rad; |
| @@ -211,15 +206,10 @@ void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
| // We need to detect and "fix" this now, otherwise we can have the following wackiness: |
| // path.addRRect(rrect); |
| // rrect.rect() != path.getBounds() |
| - fRadii[0].fX = clamp_radius_add(fRadii[0].fX, rect.fLeft, rect.fRight); |
| - fRadii[0].fY = clamp_radius_add(fRadii[0].fY, rect.fTop, rect.fBottom); |
| - fRadii[1].fX = clamp_radius_sub(fRadii[1].fX, rect.fLeft, rect.fRight); |
| - fRadii[1].fY = clamp_radius_add(fRadii[1].fY, rect.fTop, rect.fBottom); |
| - fRadii[2].fX = clamp_radius_sub(fRadii[2].fX, rect.fLeft, rect.fRight); |
| - fRadii[2].fY = clamp_radius_sub(fRadii[2].fY, rect.fTop, rect.fBottom); |
| - fRadii[3].fX = clamp_radius_add(fRadii[3].fX, rect.fLeft, rect.fRight); |
| - fRadii[3].fY = clamp_radius_sub(fRadii[3].fY, rect.fTop, rect.fBottom); |
| - |
| + for (int i = 0; i < 4; ++i) { |
| + fRadii[i].fX = clamp_radius_check_predicates(fRadii[i].fX, rect.fLeft, rect.fRight); |
| + fRadii[i].fY = clamp_radius_check_predicates(fRadii[i].fY, rect.fTop, rect.fBottom); |
| + } |
| // At this point we're either oval, simple, or complex (not empty or rect). |
| this->computeType(); |
| @@ -397,6 +387,13 @@ bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { |
| return false; |
| } |
| + // The matrix may have scaled us to zero (or due to float madness, we now have collapsed |
|
robertphillips
2015/02/13 22:31:03
',' -> ')' ?
|
| + // some dimension of the rect, so we need to check for that. |
| + if (newRect.isEmpty()) { |
| + dst->setEmpty(); |
| + return true; |
| + } |
| + |
| // At this point, this is guaranteed to succeed, so we can modify dst. |
| dst->fRect = newRect; |
| @@ -528,6 +525,16 @@ void SkRRect::dump(bool asHex) const { |
| /////////////////////////////////////////////////////////////////////////////// |
| #ifdef SK_DEBUG |
| +/** |
| + * We need all combinations of predicates to be true to have a "safe" radius value. |
| + */ |
| +static void validate_radius_check_predicates(SkScalar rad, SkScalar min, SkScalar max) { |
| + SkASSERT(min <= max); |
| + SkASSERT(rad <= max - min); |
| + SkASSERT(min + rad <= max); |
| + SkASSERT(max - rad >= min); |
| +} |
| + |
| void SkRRect::validate() const { |
| bool allRadiiZero = (0 == fRadii[0].fX && 0 == fRadii[0].fY); |
| bool allCornersSquare = (0 == fRadii[0].fX || 0 == fRadii[0].fY); |
| @@ -581,6 +588,11 @@ void SkRRect::validate() const { |
| SkASSERT(!patchesOfNine); |
| break; |
| } |
| + |
| + for (int i = 0; i < 4; ++i) { |
| + validate_radius_check_predicates(fRadii[i].fX, fRect.fLeft, fRect.fRight); |
| + validate_radius_check_predicates(fRadii[i].fY, fRect.fTop, fRect.fBottom); |
| + } |
| } |
| #endif // SK_DEBUG |