diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkRRect.cpp | 75 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 4 | ||||
-rw-r--r-- | src/utils/SkLua.cpp | 1 | ||||
-rw-r--r-- | src/utils/debugger/SkObjectParser.cpp | 2 |
4 files changed, 79 insertions, 3 deletions
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp index 915ed75327..082646c2a7 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 diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index a5cdc4f703..ff98daf048 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -288,10 +288,10 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma // already have code for rectangles. return kUnimplemented_FilterReturn; + // These three can take advantage of this fast path. case SkRRect::kSimple_Type: - // Fall through. + case SkRRect::kNinePatch_Type: case SkRRect::kComplex_Type: - // These can take advantage of this fast path. break; } diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp index 4b87458923..44f2211b8f 100644 --- a/src/utils/SkLua.cpp +++ b/src/utils/SkLua.cpp @@ -1208,6 +1208,7 @@ static const char* rrect_type(const SkRRect& rr) { case SkRRect::kRect_Type: return "rect"; case SkRRect::kOval_Type: return "oval"; case SkRRect::kSimple_Type: return "simple"; + case SkRRect::kNinePatch_Type: return "nine-patch"; case SkRRect::kComplex_Type: return "complex"; } SkDEBUGFAIL("never get here"); diff --git a/src/utils/debugger/SkObjectParser.cpp b/src/utils/debugger/SkObjectParser.cpp index 028300c5a5..a3b208544e 100644 --- a/src/utils/debugger/SkObjectParser.cpp +++ b/src/utils/debugger/SkObjectParser.cpp @@ -241,6 +241,8 @@ SkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) mRRect->append("oval"); } else if (rrect.isSimple()) { mRRect->append("simple"); + } else if (rrect.isNinePatch()) { + mRRect->append("nine-patch"); } else { SkASSERT(rrect.isComplex()); mRRect->append("complex"); |