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 |
11 /////////////////////////////////////////////////////////////////////////////// | 11 /////////////////////////////////////////////////////////////////////////////// |
12 | 12 |
13 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { | 13 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { |
14 if (rect.isEmpty()) { | 14 if (rect.isEmpty() || !rect.isFinite()) { |
15 this->setEmpty(); | 15 this->setEmpty(); |
16 return; | 16 return; |
17 } | 17 } |
18 | 18 |
| 19 if (!SkScalarsAreFinite(xRad, yRad)) { |
| 20 xRad = yRad = 0; // devolve into a simple rect |
| 21 } |
19 if (xRad <= 0 || yRad <= 0) { | 22 if (xRad <= 0 || yRad <= 0) { |
20 // all corners are square in this case | 23 // all corners are square in this case |
21 this->setRect(rect); | 24 this->setRect(rect); |
22 return; | 25 return; |
23 } | 26 } |
24 | 27 |
25 if (rect.width() < xRad+xRad || rect.height() < yRad+yRad) { | 28 if (rect.width() < xRad+xRad || rect.height() < yRad+yRad) { |
26 SkScalar scale = SkMinScalar(SkScalarDiv(rect.width(), xRad + xRad), | 29 SkScalar scale = SkMinScalar(SkScalarDiv(rect.width(), xRad + xRad), |
27 SkScalarDiv(rect.height(), yRad + yRad)); | 30 SkScalarDiv(rect.height(), yRad + yRad)); |
28 SkASSERT(scale < SK_Scalar1); | 31 SkASSERT(scale < SK_Scalar1); |
29 xRad = SkScalarMul(xRad, scale); | 32 xRad = SkScalarMul(xRad, scale); |
30 yRad = SkScalarMul(yRad, scale); | 33 yRad = SkScalarMul(yRad, scale); |
31 } | 34 } |
32 | 35 |
33 fRect = rect; | 36 fRect = rect; |
34 for (int i = 0; i < 4; ++i) { | 37 for (int i = 0; i < 4; ++i) { |
35 fRadii[i].set(xRad, yRad); | 38 fRadii[i].set(xRad, yRad); |
36 } | 39 } |
37 fType = kSimple_Type; | 40 fType = kSimple_Type; |
38 if (xRad >= SkScalarHalf(fRect.width()) && yRad >= SkScalarHalf(fRect.height
())) { | 41 if (xRad >= SkScalarHalf(fRect.width()) && yRad >= SkScalarHalf(fRect.height
())) { |
39 fType = kOval_Type; | 42 fType = kOval_Type; |
40 // TODO: assert that all the x&y radii are already W/2 & H/2 | 43 // TODO: assert that all the x&y radii are already W/2 & H/2 |
41 } | 44 } |
42 | 45 |
43 SkDEBUGCODE(this->validate();) | 46 SkDEBUGCODE(this->validate();) |
44 } | 47 } |
45 | 48 |
46 void SkRRect::setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad
, | 49 void SkRRect::setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad
, |
47 SkScalar rightRad, SkScalar bottomRad) { | 50 SkScalar rightRad, SkScalar bottomRad) { |
48 if (rect.isEmpty()) { | 51 if (rect.isEmpty() || !rect.isFinite()) { |
49 this->setEmpty(); | 52 this->setEmpty(); |
50 return; | 53 return; |
51 } | 54 } |
52 | 55 |
| 56 const SkScalar array[4] = { leftRad, topRad, rightRad, bottomRad }; |
| 57 if (!SkScalarsAreFinite(array, 4)) { |
| 58 this->setRect(rect); // devolve into a simple rect |
| 59 return; |
| 60 } |
| 61 |
53 leftRad = SkMaxScalar(leftRad, 0); | 62 leftRad = SkMaxScalar(leftRad, 0); |
54 topRad = SkMaxScalar(topRad, 0); | 63 topRad = SkMaxScalar(topRad, 0); |
55 rightRad = SkMaxScalar(rightRad, 0); | 64 rightRad = SkMaxScalar(rightRad, 0); |
56 bottomRad = SkMaxScalar(bottomRad, 0); | 65 bottomRad = SkMaxScalar(bottomRad, 0); |
57 | 66 |
58 SkScalar scale = SK_Scalar1; | 67 SkScalar scale = SK_Scalar1; |
59 if (leftRad + rightRad > rect.width()) { | 68 if (leftRad + rightRad > rect.width()) { |
60 scale = SkScalarDiv(rect.width(), leftRad + rightRad); | 69 scale = SkScalarDiv(rect.width(), leftRad + rightRad); |
61 } | 70 } |
62 if (topRad + bottomRad > rect.height()) { | 71 if (topRad + bottomRad > rect.height()) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 | 127 |
119 static SkScalar clamp_radius_sub(SkScalar rad, SkScalar min, SkScalar max) { | 128 static SkScalar clamp_radius_sub(SkScalar rad, SkScalar min, SkScalar max) { |
120 SkASSERT(rad <= max - min); | 129 SkASSERT(rad <= max - min); |
121 if (max - rad < min) { | 130 if (max - rad < min) { |
122 rad = SkScalarDecULP(rad); | 131 rad = SkScalarDecULP(rad); |
123 } | 132 } |
124 return rad; | 133 return rad; |
125 } | 134 } |
126 | 135 |
127 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { | 136 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
128 if (rect.isEmpty()) { | 137 if (rect.isEmpty() || !rect.isFinite()) { |
129 this->setEmpty(); | 138 this->setEmpty(); |
130 return; | 139 return; |
131 } | 140 } |
132 | 141 |
| 142 if (!SkScalarsAreFinite(&radii[0].fX, 8)) { |
| 143 this->setRect(rect); // devolve into a simple rect |
| 144 return; |
| 145 } |
| 146 |
133 fRect = rect; | 147 fRect = rect; |
134 memcpy(fRadii, radii, sizeof(fRadii)); | 148 memcpy(fRadii, radii, sizeof(fRadii)); |
135 | 149 |
136 bool allCornersSquare = true; | 150 bool allCornersSquare = true; |
137 | 151 |
138 // Clamp negative radii to zero | 152 // Clamp negative radii to zero |
139 for (int i = 0; i < 4; ++i) { | 153 for (int i = 0; i < 4; ++i) { |
140 if (fRadii[i].fX <= 0 || fRadii[i].fY <= 0) { | 154 if (fRadii[i].fX <= 0 || fRadii[i].fY <= 0) { |
141 // In this case we are being a little fast & loose. Since one of | 155 // In this case we are being a little fast & loose. Since one of |
142 // the radii is 0 the corner is square. However, the other radii | 156 // the radii is 0 the corner is square. However, the other radii |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 case kComplex_Type: | 578 case kComplex_Type: |
565 SkASSERT(!fRect.isEmpty()); | 579 SkASSERT(!fRect.isEmpty()); |
566 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); | 580 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
567 SkASSERT(!patchesOfNine); | 581 SkASSERT(!patchesOfNine); |
568 break; | 582 break; |
569 } | 583 } |
570 } | 584 } |
571 #endif // SK_DEBUG | 585 #endif // SK_DEBUG |
572 | 586 |
573 /////////////////////////////////////////////////////////////////////////////// | 587 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |