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 |