Chromium Code Reviews| 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 #include "SkMatrix.h" |
| 10 | 10 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 } | 36 } |
| 37 fType = kSimple_Type; | 37 fType = kSimple_Type; |
| 38 if (xRad >= SkScalarHalf(fRect.width()) && yRad >= SkScalarHalf(fRect.height ())) { | 38 if (xRad >= SkScalarHalf(fRect.width()) && yRad >= SkScalarHalf(fRect.height ())) { |
| 39 fType = kOval_Type; | 39 fType = kOval_Type; |
| 40 // TODO: assert that all the x&y radii are already W/2 & H/2 | 40 // TODO: assert that all the x&y radii are already W/2 & H/2 |
| 41 } | 41 } |
| 42 | 42 |
| 43 SkDEBUGCODE(this->validate();) | 43 SkDEBUGCODE(this->validate();) |
| 44 } | 44 } |
| 45 | 45 |
| 46 void SkRRect::setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad , | |
| 47 SkScalar rightRad, SkScalar bottomRad) { | |
| 48 if (rect.isEmpty()) { | |
| 49 this->setEmpty(); | |
| 50 return; | |
| 51 } | |
| 52 | |
| 53 leftRad = SkMaxScalar(leftRad, 0); | |
| 54 topRad = SkMaxScalar(topRad, 0); | |
| 55 rightRad = SkMaxScalar(rightRad, 0); | |
| 56 bottomRad = SkMaxScalar(bottomRad, 0); | |
| 57 | |
|
robertphillips
2014/03/14 16:22:59
I think we need to scale the x & y radii separatel
bsalomon
2014/03/14 16:30:20
We don't in the other setters (which I just stole
robertphillips
2014/03/14 16:52:07
Sigh - that is correct (http://www.w3.org/TR/2010/
| |
| 58 SkScalar scale = SK_Scalar1; | |
| 59 if (leftRad + rightRad > rect.width()) { | |
| 60 scale = SkScalarDiv(rect.width(), leftRad + rightRad); | |
| 61 } | |
| 62 if (topRad + bottomRad > rect.height()) { | |
| 63 scale = SkMinScalar(scale, SkScalarDiv(rect.width(), leftRad + rightRad) ); | |
| 64 } | |
| 65 | |
| 66 if (scale < SK_Scalar1) { | |
| 67 leftRad = SkScalarMul(leftRad, scale); | |
| 68 topRad = SkScalarMul(topRad, scale); | |
| 69 rightRad = SkScalarMul(rightRad, scale); | |
| 70 bottomRad = SkScalarMul(bottomRad, scale); | |
| 71 } | |
| 72 | |
| 73 if (leftRad == rightRad && topRad == bottomRad) { | |
| 74 if (leftRad >= SkScalarHalf(rect.width()) && topRad >= SkScalarHalf(rect .height())) { | |
| 75 fType = kOval_Type; | |
|
robertphillips
2014/03/14 16:22:59
don't we also need "&& 0 == topRad"?
bsalomon
2014/03/14 16:30:20
I don't think so... if the top radius is 0 then so
robertphillips
2014/03/14 16:52:07
You're right - probably both a comment and jamming
| |
| 76 } else if (0 == leftRad) { | |
| 77 fType = kRect_Type; | |
| 78 } else { | |
| 79 fType = kSimple_Type; | |
| 80 } | |
| 81 } else { | |
| 82 fType = kNinePatch_Type; | |
| 83 } | |
| 84 | |
| 85 fRect = rect; | |
| 86 fRadii[kUpperLeft_Corner].set(leftRad, topRad); | |
| 87 fRadii[kUpperRight_Corner].set(rightRad, topRad); | |
| 88 fRadii[kLowerRight_Corner].set(rightRad, bottomRad); | |
| 89 fRadii[kLowerLeft_Corner].set(leftRad, bottomRad); | |
| 90 | |
| 91 SkDEBUGCODE(this->validate();) | |
| 92 } | |
| 93 | |
| 94 | |
| 46 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { | 95 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
| 47 if (rect.isEmpty()) { | 96 if (rect.isEmpty()) { |
| 48 this->setEmpty(); | 97 this->setEmpty(); |
| 49 return; | 98 return; |
| 50 } | 99 } |
| 51 | 100 |
| 52 fRect = rect; | 101 fRect = rect; |
| 53 memcpy(fRadii, radii, sizeof(fRadii)); | 102 memcpy(fRadii, radii, sizeof(fRadii)); |
| 54 | 103 |
| 55 bool allCornersSquare = true; | 104 bool allCornersSquare = true; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 if (allRadiiEqual) { | 280 if (allRadiiEqual) { |
| 232 if (fRadii[0].fX >= SkScalarHalf(fRect.width()) && | 281 if (fRadii[0].fX >= SkScalarHalf(fRect.width()) && |
| 233 fRadii[0].fY >= SkScalarHalf(fRect.height())) { | 282 fRadii[0].fY >= SkScalarHalf(fRect.height())) { |
| 234 fType = kOval_Type; | 283 fType = kOval_Type; |
| 235 } else { | 284 } else { |
| 236 fType = kSimple_Type; | 285 fType = kSimple_Type; |
| 237 } | 286 } |
| 238 return; | 287 return; |
| 239 } | 288 } |
| 240 | 289 |
| 241 fType = kComplex_Type; | 290 if (fRadii[kUpperLeft_Corner].fX == fRadii[kLowerLeft_Corner].fX && |
| 291 fRadii[kUpperLeft_Corner].fY == fRadii[kUpperRight_Corner].fY && | |
| 292 fRadii[kUpperRight_Corner].fX == fRadii[kLowerRight_Corner].fX && | |
| 293 fRadii[kLowerLeft_Corner].fY == fRadii[kLowerRight_Corner].fY) { | |
| 294 fType = kNinePatch_Type; | |
| 295 } else { | |
| 296 fType = kComplex_Type; | |
| 297 } | |
| 242 } | 298 } |
| 243 | 299 |
| 244 static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { | 300 static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { |
| 245 const SkMatrix::TypeMask m = (SkMatrix::TypeMask) (SkMatrix::kAffine_Mask | 301 const SkMatrix::TypeMask m = (SkMatrix::TypeMask) (SkMatrix::kAffine_Mask |
| 246 | SkMatrix::kPerspective_Mask); | 302 | SkMatrix::kPerspective_Mask); |
| 247 return (matrix.getType() & m) == 0; | 303 return (matrix.getType() & m) == 0; |
| 248 } | 304 } |
| 249 | 305 |
| 250 bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { | 306 bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { |
| 251 if (NULL == dst) { | 307 if (NULL == dst) { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 383 allRadiiZero = false; | 439 allRadiiZero = false; |
| 384 } | 440 } |
| 385 | 441 |
| 386 if (fRadii[i].fX != fRadii[i-1].fX || fRadii[i].fY != fRadii[i-1].fY) { | 442 if (fRadii[i].fX != fRadii[i-1].fX || fRadii[i].fY != fRadii[i-1].fY) { |
| 387 allRadiiSame = false; | 443 allRadiiSame = false; |
| 388 } | 444 } |
| 389 | 445 |
| 390 if (0 != fRadii[i].fX && 0 != fRadii[i].fY) { | 446 if (0 != fRadii[i].fX && 0 != fRadii[i].fY) { |
| 391 allCornersSquare = false; | 447 allCornersSquare = false; |
| 392 } | 448 } |
| 393 } | 449 } |
|
robertphillips
2014/03/14 16:22:59
maybe a radii_make_nine_patch predicate to share c
bsalomon
2014/03/14 16:30:20
I'm not sure what you mean.
robertphillips
2014/03/14 16:52:07
Add a helper function?
bsalomon
2014/03/14 17:15:31
gotcha! will do. I thought you meant incorporating
| |
| 450 bool patchesOfNine = fRadii[kUpperLeft_Corner].fX == fRadii[kLowerLeft_Corne r].fX && | |
| 451 fRadii[kUpperLeft_Corner].fY == fRadii[kUpperRight_Corn er].fY && | |
| 452 fRadii[kUpperRight_Corner].fX == fRadii[kLowerRight_Cor ner].fX && | |
| 453 fRadii[kLowerLeft_Corner].fY == fRadii[kLowerRight_Corn er].fY; | |
| 394 | 454 |
| 395 switch (fType) { | 455 switch (fType) { |
| 396 case kEmpty_Type: | 456 case kEmpty_Type: |
| 397 SkASSERT(fRect.isEmpty()); | 457 SkASSERT(fRect.isEmpty()); |
| 398 SkASSERT(allRadiiZero && allRadiiSame && allCornersSquare); | 458 SkASSERT(allRadiiZero && allRadiiSame && allCornersSquare); |
| 399 | 459 |
| 400 SkASSERT(0 == fRect.fLeft && 0 == fRect.fTop && | 460 SkASSERT(0 == fRect.fLeft && 0 == fRect.fTop && |
| 401 0 == fRect.fRight && 0 == fRect.fBottom); | 461 0 == fRect.fRight && 0 == fRect.fBottom); |
| 402 break; | 462 break; |
| 403 case kRect_Type: | 463 case kRect_Type: |
| 404 SkASSERT(!fRect.isEmpty()); | 464 SkASSERT(!fRect.isEmpty()); |
| 405 SkASSERT(allRadiiZero && allRadiiSame && allCornersSquare); | 465 SkASSERT(allRadiiZero && allRadiiSame && allCornersSquare); |
| 406 break; | 466 break; |
| 407 case kOval_Type: | 467 case kOval_Type: |
| 408 SkASSERT(!fRect.isEmpty()); | 468 SkASSERT(!fRect.isEmpty()); |
| 409 SkASSERT(!allRadiiZero && allRadiiSame && !allCornersSquare); | 469 SkASSERT(!allRadiiZero && allRadiiSame && !allCornersSquare); |
| 410 | 470 |
| 411 for (int i = 0; i < 4; ++i) { | 471 for (int i = 0; i < 4; ++i) { |
| 412 SkASSERT(SkScalarNearlyEqual(fRadii[i].fX, SkScalarHalf(fRect.wi dth()))); | 472 SkASSERT(SkScalarNearlyEqual(fRadii[i].fX, SkScalarHalf(fRect.wi dth()))); |
| 413 SkASSERT(SkScalarNearlyEqual(fRadii[i].fY, SkScalarHalf(fRect.he ight()))); | 473 SkASSERT(SkScalarNearlyEqual(fRadii[i].fY, SkScalarHalf(fRect.he ight()))); |
| 414 } | 474 } |
| 415 break; | 475 break; |
| 416 case kSimple_Type: | 476 case kSimple_Type: |
| 417 SkASSERT(!fRect.isEmpty()); | 477 SkASSERT(!fRect.isEmpty()); |
| 418 SkASSERT(!allRadiiZero && allRadiiSame && !allCornersSquare); | 478 SkASSERT(!allRadiiZero && allRadiiSame && !allCornersSquare); |
| 419 break; | 479 break; |
| 480 case kNinePatch_Type: | |
| 481 SkASSERT(!fRect.isEmpty()); | |
| 482 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); | |
| 483 SkASSERT(patchesOfNine); | |
| 484 break; | |
| 420 case kComplex_Type: | 485 case kComplex_Type: |
| 421 SkASSERT(!fRect.isEmpty()); | 486 SkASSERT(!fRect.isEmpty()); |
| 422 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); | 487 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
| 488 SkASSERT(!patchesOfNine); | |
| 423 break; | 489 break; |
| 424 case kUnknown_Type: | 490 case kUnknown_Type: |
| 425 // no limits on this | 491 // no limits on this |
| 426 break; | 492 break; |
| 427 } | 493 } |
| 428 } | 494 } |
| 429 #endif // SK_DEBUG | 495 #endif // SK_DEBUG |
| 430 | 496 |
| 431 /////////////////////////////////////////////////////////////////////////////// | 497 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |