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

Unified Diff: src/core/SkRRect.cpp

Issue 803153003: Fix rrects that are large enough that we lose/gain a bit when we add the radius to a bounds coordin… (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: generalize test for all edges and axes Created 6 years 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 | « src/core/SkPath.cpp ('k') | tests/PathTest.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 d3a571fe9974ccd2cd4e25b1ab36365e4a9ccab8..58e7de7910a1702cfc6e19cf502bfb629676d859 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -97,6 +97,32 @@ void SkRRect::setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad
SkDEBUGCODE(this->validate();)
}
+/*
+ * TODO: clean this guy up and possibly add to SkScalar.h
+ */
+static inline SkScalar SkScalarDecULP(SkScalar value) {
+#if SK_SCALAR_IS_FLOAT
+ return SkBits2Float(SkFloat2Bits(value) - 1);
+#else
+ #error "need impl for doubles"
+#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) {
+ rad = SkScalarDecULP(rad);
+ }
+ return rad;
+}
void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
if (rect.isEmpty()) {
@@ -159,11 +185,27 @@ void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) {
if (scale < SK_Scalar1) {
for (int i = 0; i < 4; ++i) {
- fRadii[i].fX = SkScalarMul(fRadii[i].fX, scale);
- fRadii[i].fY = SkScalarMul(fRadii[i].fY, scale);
+ fRadii[i].fX *= scale;
+ fRadii[i].fY *= scale;
}
}
+ // skbug.com/3239 -- its possible that we can hit the following inconsistency:
+ // rad == bounds.bottom - bounds.top
+ // bounds.bottom - radius < bounds.top
+ // YIKES
+ // 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);
+
// At this point we're either oval, simple, or complex (not empty or rect)
// but we lazily resolve the type to avoid the work if the information
// isn't required.
« no previous file with comments | « src/core/SkPath.cpp ('k') | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698