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 |