Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Unified Diff: src/core/SkRRect.cpp

Issue 921163003: fix more tricky-float cases in SkRRect validate (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/RoundRectTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « no previous file | tests/RoundRectTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698