| Index: src/core/SkRRect.cpp
|
| diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
|
| index 75af106b7b6eaf81183ce1b977afa27231577aa3..33b781f52934dc84fe81cbdc91b0b8111db1af3c 100644
|
| --- a/src/core/SkRRect.cpp
|
| +++ b/src/core/SkRRect.cpp
|
| @@ -6,6 +6,7 @@
|
| */
|
|
|
| #include "SkRRect.h"
|
| +#include "SkMatrix.h"
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| @@ -254,6 +255,83 @@ 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) {
|
| + return false;
|
| + }
|
| +
|
| + // Assert that the caller is not trying to do this in place, which
|
| + // would violate const-ness. Do not return false though, so that
|
| + // if they know what they're doing and want to violate it they can.
|
| + SkASSERT(dst != 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;
|
| + }
|
| +
|
| + // At this point, this is guaranteed to succeed, so we can modify dst.
|
| + dst->fRect = newRect;
|
| +
|
| + // Now scale each corner
|
| + SkScalar xScale = matrix.getScaleX();
|
| + const bool flipX = xScale < 0;
|
| + if (flipX) {
|
| + xScale = -xScale;
|
| + }
|
| + SkScalar yScale = matrix.getScaleY();
|
| + const bool flipY = yScale < 0;
|
| + if (flipY) {
|
| + yScale = -yScale;
|
| + }
|
| +
|
| + // Scale the radii without respecting the flip.
|
| + for (int i = 0; i < 4; ++i) {
|
| + dst->fRadii[i].fX = SkScalarMul(fRadii[i].fX, xScale);
|
| + dst->fRadii[i].fY = SkScalarMul(fRadii[i].fY, yScale);
|
| + }
|
| +
|
| + // Now swap as necessary.
|
| + if (flipX) {
|
| + if (flipY) {
|
| + // Swap with opposite corners
|
| + SkTSwap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerRight_Corner]);
|
| + SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerLeft_Corner]);
|
| + } else {
|
| + // Only swap in x
|
| + SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kUpperLeft_Corner]);
|
| + SkTSwap(dst->fRadii[kLowerRight_Corner], dst->fRadii[kLowerLeft_Corner]);
|
| + }
|
| + } else if (flipY) {
|
| + // Only swap in y
|
| + SkTSwap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerLeft_Corner]);
|
| + SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerRight_Corner]);
|
| + }
|
| +
|
| + // Since the only transforms that were allowed are scale and translate, the type
|
| + // remains unchanged.
|
| + dst->fType = fType;
|
| +
|
| + SkDEBUGCODE(dst->validate();)
|
| +
|
| + return true;
|
| +}
|
| +
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const {
|
|
|