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

Unified Diff: src/core/SkRRect.cpp

Issue 52703003: Add SkRRect::transform. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix negative scaling bug and add a test. Created 7 years, 2 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
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 {
« no previous file with comments | « include/core/SkRRect.h ('k') | tests/RoundRectTest.cpp » ('j') | tests/RoundRectTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698