Index: src/core/SkRRect.cpp |
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp |
index 75af106b7b6eaf81183ce1b977afa27231577aa3..ec4d686530fd2786b0548ebc6daf3c55729b0f2f 100644 |
--- a/src/core/SkRRect.cpp |
+++ b/src/core/SkRRect.cpp |
@@ -6,6 +6,7 @@ |
*/ |
#include "SkRRect.h" |
+#include "SkMatrix.h" |
/////////////////////////////////////////////////////////////////////////////// |
@@ -254,6 +255,85 @@ void SkRRect::computeType() const { |
fType = kComplex_Type; |
} |
+static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { |
+ const SkMatrix::TypeMask m = (SkMatrix::TypeMask) (SkMatrix::kAffine_Mask |
+ | SkMatrix::kPerspective_Mask); |
+ return (matrix.getType() & m) == 0; |
+} |
+ |
+bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { |
+ if (NULL == dst) { |
+ dst = const_cast<SkRRect*>(this); |
+ } |
+ |
+ if (matrix.isIdentity()) { |
+ *dst = *this; |
+ return true; |
+ } |
+ |
+ if (!matrix_only_scale_and_translate(matrix)) { |
+ return false; |
+ } |
+ |
+ SkRect newRect; |
+ if (!matrix.mapRect(&newRect, fRect)) { |
+ return false; |
+ } |
+ |
+ dst->fRect = newRect; |
+ |
+ // Now scale each corner |
+ SkScalar xScale = matrix.getScaleX(); |
+ if (xScale < 0) { |
+ xScale = -xScale; |
+ // Each x radius will swap with its horizontal opposite. |
+ const SkScalar upperLeftXRadius = this->radii(kUpperLeft_Corner).fX; |
+ const SkScalar upperRightXRadius = this->radii(kUpperRight_Corner).fX; |
+ dst->fRadii[(int) kUpperRight_Corner].fX = SkScalarMul(xScale, upperLeftXRadius); |
+ dst->fRadii[(int) kUpperLeft_Corner].fX = SkScalarMul(xScale, upperRightXRadius); |
+ |
+ const SkScalar lowerLeftXRadius = this->radii(kLowerLeft_Corner).fX; |
+ const SkScalar lowerRightXRadius = this->radii(kLowerRight_Corner).fX; |
+ dst->fRadii[(int) kLowerRight_Corner].fX = SkScalarMul(xScale, lowerLeftXRadius); |
+ dst->fRadii[(int) kLowerLeft_Corner].fX = SkScalarMul(xScale, lowerRightXRadius); |
+ } else { |
+ dst->fRadii[(int) kUpperLeft_Corner].fX = SkScalarMul(xScale, |
+ this->radii(kUpperLeft_Corner).fX); |
+ dst->fRadii[(int) kUpperRight_Corner].fX = SkScalarMul(xScale, |
+ this->radii(kUpperRight_Corner).fX); |
+ dst->fRadii[(int) kLowerRight_Corner].fX = SkScalarMul(xScale, |
+ this->radii(kLowerRight_Corner).fX); |
+ dst->fRadii[(int) kLowerLeft_Corner].fX = SkScalarMul(xScale, |
+ this->radii(kLowerLeft_Corner).fX); |
+ } |
+ |
+ SkScalar yScale = matrix.getScaleY(); |
+ if (yScale < 0) { |
+ yScale = -yScale; |
+ // Each y radius will swap with its vertical opposite. |
+ const SkScalar upperLeftYRadius = this->radii(kUpperLeft_Corner).fY; |
+ const SkScalar lowerLeftYRadius = this->radii(kLowerLeft_Corner).fY; |
+ dst->fRadii[(int) kLowerLeft_Corner].fY = SkScalarMul(yScale, upperLeftYRadius); |
+ dst->fRadii[(int) kUpperLeft_Corner].fY = SkScalarMul(yScale, lowerLeftYRadius); |
+ |
+ const SkScalar upperRightYRadius = this->radii(kUpperRight_Corner).fY; |
+ const SkScalar lowerRightYRadius = this->radii(kLowerRight_Corner).fY; |
+ dst->fRadii[(int) kLowerRight_Corner].fY = SkScalarMul(yScale, upperRightYRadius); |
+ dst->fRadii[(int) kUpperRight_Corner].fY = SkScalarMul(yScale, lowerRightYRadius); |
+ } else { |
+ dst->fRadii[(int) kUpperLeft_Corner].fY = SkScalarMul(yScale, |
+ this->radii(kUpperLeft_Corner).fY); |
+ dst->fRadii[(int) kUpperRight_Corner].fY = SkScalarMul(yScale, |
+ this->radii(kUpperRight_Corner).fY); |
+ dst->fRadii[(int) kLowerRight_Corner].fY = SkScalarMul(yScale, |
+ this->radii(kLowerRight_Corner).fY); |
+ dst->fRadii[(int) kLowerLeft_Corner].fY = SkScalarMul(yScale, |
+ this->radii(kLowerLeft_Corner).fY); |
+ } |
+ |
+ return true; |
+} |
+ |
/////////////////////////////////////////////////////////////////////////////// |
void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const { |