| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkRRect.h" | 8 #include "SkRRect.h" |
| 9 #include "SkMatrix.h" |
| 9 | 10 |
| 10 /////////////////////////////////////////////////////////////////////////////// | 11 /////////////////////////////////////////////////////////////////////////////// |
| 11 | 12 |
| 12 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { | 13 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { |
| 13 if (rect.isEmpty()) { | 14 if (rect.isEmpty()) { |
| 14 this->setEmpty(); | 15 this->setEmpty(); |
| 15 return; | 16 return; |
| 16 } | 17 } |
| 17 | 18 |
| 18 if (xRad <= 0 || yRad <= 0) { | 19 if (xRad <= 0 || yRad <= 0) { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 247 fType = kOval_Type; | 248 fType = kOval_Type; |
| 248 } else { | 249 } else { |
| 249 fType = kSimple_Type; | 250 fType = kSimple_Type; |
| 250 } | 251 } |
| 251 return; | 252 return; |
| 252 } | 253 } |
| 253 | 254 |
| 254 fType = kComplex_Type; | 255 fType = kComplex_Type; |
| 255 } | 256 } |
| 256 | 257 |
| 258 static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { |
| 259 const SkMatrix::TypeMask m = (SkMatrix::TypeMask) (SkMatrix::kAffine_Mask |
| 260 | SkMatrix::kPerspective_Mask); |
| 261 return (matrix.getType() & m) == 0; |
| 262 } |
| 263 |
| 264 bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { |
| 265 if (NULL == dst) { |
| 266 return false; |
| 267 } |
| 268 |
| 269 // Assert that the caller is not trying to do this in place, which |
| 270 // would violate const-ness. Do not return false though, so that |
| 271 // if they know what they're doing and want to violate it they can. |
| 272 SkASSERT(dst != this); |
| 273 |
| 274 if (matrix.isIdentity()) { |
| 275 *dst = *this; |
| 276 return true; |
| 277 } |
| 278 |
| 279 if (!matrix_only_scale_and_translate(matrix)) { |
| 280 return false; |
| 281 } |
| 282 |
| 283 SkRect newRect; |
| 284 if (!matrix.mapRect(&newRect, fRect)) { |
| 285 return false; |
| 286 } |
| 287 |
| 288 // At this point, this is guaranteed to succeed, so we can modify dst. |
| 289 dst->fRect = newRect; |
| 290 |
| 291 // Now scale each corner |
| 292 SkScalar xScale = matrix.getScaleX(); |
| 293 const bool flipX = xScale < 0; |
| 294 if (flipX) { |
| 295 xScale = -xScale; |
| 296 } |
| 297 SkScalar yScale = matrix.getScaleY(); |
| 298 const bool flipY = yScale < 0; |
| 299 if (flipY) { |
| 300 yScale = -yScale; |
| 301 } |
| 302 |
| 303 // Scale the radii without respecting the flip. |
| 304 for (int i = 0; i < 4; ++i) { |
| 305 dst->fRadii[i].fX = SkScalarMul(fRadii[i].fX, xScale); |
| 306 dst->fRadii[i].fY = SkScalarMul(fRadii[i].fY, yScale); |
| 307 } |
| 308 |
| 309 // Now swap as necessary. |
| 310 if (flipX) { |
| 311 if (flipY) { |
| 312 // Swap with opposite corners |
| 313 SkTSwap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerRight_Corn
er]); |
| 314 SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerLeft_Corn
er]); |
| 315 } else { |
| 316 // Only swap in x |
| 317 SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kUpperLeft_Corn
er]); |
| 318 SkTSwap(dst->fRadii[kLowerRight_Corner], dst->fRadii[kLowerLeft_Corn
er]); |
| 319 } |
| 320 } else if (flipY) { |
| 321 // Only swap in y |
| 322 SkTSwap(dst->fRadii[kUpperLeft_Corner], dst->fRadii[kLowerLeft_Corner]); |
| 323 SkTSwap(dst->fRadii[kUpperRight_Corner], dst->fRadii[kLowerRight_Corner]
); |
| 324 } |
| 325 |
| 326 // Since the only transforms that were allowed are scale and translate, the
type |
| 327 // remains unchanged. |
| 328 dst->fType = fType; |
| 329 |
| 330 SkDEBUGCODE(dst->validate();) |
| 331 |
| 332 return true; |
| 333 } |
| 334 |
| 257 /////////////////////////////////////////////////////////////////////////////// | 335 /////////////////////////////////////////////////////////////////////////////// |
| 258 | 336 |
| 259 void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const { | 337 void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const { |
| 260 SkRect r = fRect; | 338 SkRect r = fRect; |
| 261 | 339 |
| 262 r.inset(dx, dy); | 340 r.inset(dx, dy); |
| 263 if (r.isEmpty()) { | 341 if (r.isEmpty()) { |
| 264 dst->setEmpty(); | 342 dst->setEmpty(); |
| 265 return; | 343 return; |
| 266 } | 344 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); | 430 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
| 353 break; | 431 break; |
| 354 case kUnknown_Type: | 432 case kUnknown_Type: |
| 355 // no limits on this | 433 // no limits on this |
| 356 break; | 434 break; |
| 357 } | 435 } |
| 358 } | 436 } |
| 359 #endif // SK_DEBUG | 437 #endif // SK_DEBUG |
| 360 | 438 |
| 361 /////////////////////////////////////////////////////////////////////////////// | 439 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |