Index: src/core/SkRRect.cpp |
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp |
index 915ed75327f590c567ec18a5e9e0d92f64b76ee4..082646c2a76594c4a33e47fa7b759ef3308634c1 100644 |
--- a/src/core/SkRRect.cpp |
+++ b/src/core/SkRRect.cpp |
@@ -43,6 +43,61 @@ void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { |
SkDEBUGCODE(this->validate();) |
} |
+void SkRRect::setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad, |
+ SkScalar rightRad, SkScalar bottomRad) { |
+ if (rect.isEmpty()) { |
+ this->setEmpty(); |
+ return; |
+ } |
+ |
+ leftRad = SkMaxScalar(leftRad, 0); |
+ topRad = SkMaxScalar(topRad, 0); |
+ rightRad = SkMaxScalar(rightRad, 0); |
+ bottomRad = SkMaxScalar(bottomRad, 0); |
+ |
+ SkScalar scale = SK_Scalar1; |
+ if (leftRad + rightRad > rect.width()) { |
+ scale = SkScalarDiv(rect.width(), leftRad + rightRad); |
+ } |
+ if (topRad + bottomRad > rect.height()) { |
+ scale = SkMinScalar(scale, SkScalarDiv(rect.width(), leftRad + rightRad)); |
+ } |
+ |
+ if (scale < SK_Scalar1) { |
+ leftRad = SkScalarMul(leftRad, scale); |
+ topRad = SkScalarMul(topRad, scale); |
+ rightRad = SkScalarMul(rightRad, scale); |
+ bottomRad = SkScalarMul(bottomRad, scale); |
+ } |
+ |
+ if (leftRad == rightRad && topRad == bottomRad) { |
+ if (leftRad >= SkScalarHalf(rect.width()) && topRad >= SkScalarHalf(rect.height())) { |
+ fType = kOval_Type; |
+ } else if (0 == leftRad || 0 == topRad) { |
+ // If the left and (by equality check above) right radii are zero then it is a rect. |
+ // Same goes for top/bottom. |
+ fType = kRect_Type; |
+ leftRad = 0; |
+ topRad = 0; |
+ rightRad = 0; |
+ bottomRad = 0; |
+ } else { |
+ fType = kSimple_Type; |
+ } |
+ } else { |
+ fType = kNinePatch_Type; |
+ } |
+ |
+ fRect = rect; |
+ fRadii[kUpperLeft_Corner].set(leftRad, topRad); |
+ fRadii[kUpperRight_Corner].set(rightRad, topRad); |
+ fRadii[kLowerRight_Corner].set(rightRad, bottomRad); |
+ fRadii[kLowerLeft_Corner].set(leftRad, bottomRad); |
+ |
+ SkDEBUGCODE(this->validate();) |
+} |
+ |
+ |
void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
if (rect.isEmpty()) { |
this->setEmpty(); |
@@ -200,6 +255,13 @@ bool SkRRect::contains(const SkRect& rect) const { |
this->checkCornerContainment(rect.fLeft, rect.fBottom); |
} |
+static bool radii_are_nine_patch(const SkVector radii[4]) { |
+ return radii[SkRRect::kUpperLeft_Corner].fX == radii[SkRRect::kLowerLeft_Corner].fX && |
+ radii[SkRRect::kUpperLeft_Corner].fY == radii[SkRRect::kUpperRight_Corner].fY && |
+ radii[SkRRect::kUpperRight_Corner].fX == radii[SkRRect::kLowerRight_Corner].fX && |
+ radii[SkRRect::kLowerLeft_Corner].fY == radii[SkRRect::kLowerRight_Corner].fY; |
+} |
+ |
// There is a simplified version of this method in setRectXY |
void SkRRect::computeType() const { |
SkDEBUGCODE(this->validate();) |
@@ -238,7 +300,11 @@ void SkRRect::computeType() const { |
return; |
} |
- fType = kComplex_Type; |
+ if (radii_are_nine_patch(fRadii)) { |
+ fType = kNinePatch_Type; |
+ } else { |
+ fType = kComplex_Type; |
+ } |
} |
static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { |
@@ -391,6 +457,7 @@ void SkRRect::validate() const { |
allCornersSquare = false; |
} |
} |
+ bool patchesOfNine = radii_are_nine_patch(fRadii); |
switch (fType) { |
case kEmpty_Type: |
@@ -417,9 +484,15 @@ void SkRRect::validate() const { |
SkASSERT(!fRect.isEmpty()); |
SkASSERT(!allRadiiZero && allRadiiSame && !allCornersSquare); |
break; |
+ case kNinePatch_Type: |
+ SkASSERT(!fRect.isEmpty()); |
+ SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
+ SkASSERT(patchesOfNine); |
+ break; |
case kComplex_Type: |
SkASSERT(!fRect.isEmpty()); |
SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
+ SkASSERT(!patchesOfNine); |
break; |
case kUnknown_Type: |
// no limits on this |