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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 | 90 |
91 fRect = rect; | 91 fRect = rect; |
92 fRadii[kUpperLeft_Corner].set(leftRad, topRad); | 92 fRadii[kUpperLeft_Corner].set(leftRad, topRad); |
93 fRadii[kUpperRight_Corner].set(rightRad, topRad); | 93 fRadii[kUpperRight_Corner].set(rightRad, topRad); |
94 fRadii[kLowerRight_Corner].set(rightRad, bottomRad); | 94 fRadii[kLowerRight_Corner].set(rightRad, bottomRad); |
95 fRadii[kLowerLeft_Corner].set(leftRad, bottomRad); | 95 fRadii[kLowerLeft_Corner].set(leftRad, bottomRad); |
96 | 96 |
97 SkDEBUGCODE(this->validate();) | 97 SkDEBUGCODE(this->validate();) |
98 } | 98 } |
99 | 99 |
| 100 /* |
| 101 * TODO: clean this guy up and possibly add to SkScalar.h |
| 102 */ |
| 103 static inline SkScalar SkScalarDecULP(SkScalar value) { |
| 104 #if SK_SCALAR_IS_FLOAT |
| 105 return SkBits2Float(SkFloat2Bits(value) - 1); |
| 106 #else |
| 107 #error "need impl for doubles" |
| 108 #endif |
| 109 } |
| 110 |
| 111 static SkScalar clamp_radius_add(SkScalar rad, SkScalar min, SkScalar max) { |
| 112 SkASSERT(rad <= max - min); |
| 113 if (min + rad > max) { |
| 114 rad = SkScalarDecULP(rad); |
| 115 } |
| 116 return rad; |
| 117 } |
| 118 |
| 119 static SkScalar clamp_radius_sub(SkScalar rad, SkScalar min, SkScalar max) { |
| 120 SkASSERT(rad <= max - min); |
| 121 if (max - rad < min) { |
| 122 rad = SkScalarDecULP(rad); |
| 123 } |
| 124 return rad; |
| 125 } |
100 | 126 |
101 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { | 127 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
102 if (rect.isEmpty()) { | 128 if (rect.isEmpty()) { |
103 this->setEmpty(); | 129 this->setEmpty(); |
104 return; | 130 return; |
105 } | 131 } |
106 | 132 |
107 fRect = rect; | 133 fRect = rect; |
108 memcpy(fRadii, radii, sizeof(fRadii)); | 134 memcpy(fRadii, radii, sizeof(fRadii)); |
109 | 135 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 scale = SkMinScalar(scale, | 178 scale = SkMinScalar(scale, |
153 SkScalarDiv(rect.width(), fRadii[2].fX + fRadii[3].f
X)); | 179 SkScalarDiv(rect.width(), fRadii[2].fX + fRadii[3].f
X)); |
154 } | 180 } |
155 if (fRadii[3].fY + fRadii[0].fY > rect.height()) { | 181 if (fRadii[3].fY + fRadii[0].fY > rect.height()) { |
156 scale = SkMinScalar(scale, | 182 scale = SkMinScalar(scale, |
157 SkScalarDiv(rect.height(), fRadii[3].fY + fRadii[0].
fY)); | 183 SkScalarDiv(rect.height(), fRadii[3].fY + fRadii[0].
fY)); |
158 } | 184 } |
159 | 185 |
160 if (scale < SK_Scalar1) { | 186 if (scale < SK_Scalar1) { |
161 for (int i = 0; i < 4; ++i) { | 187 for (int i = 0; i < 4; ++i) { |
162 fRadii[i].fX = SkScalarMul(fRadii[i].fX, scale); | 188 fRadii[i].fX *= scale; |
163 fRadii[i].fY = SkScalarMul(fRadii[i].fY, scale); | 189 fRadii[i].fY *= scale; |
164 } | 190 } |
165 } | 191 } |
166 | 192 |
| 193 // skbug.com/3239 -- its possible that we can hit the following inconsistenc
y: |
| 194 // rad == bounds.bottom - bounds.top |
| 195 // bounds.bottom - radius < bounds.top |
| 196 // YIKES |
| 197 // We need to detect and "fix" this now, otherwise we can have the following
wackiness: |
| 198 // path.addRRect(rrect); |
| 199 // rrect.rect() != path.getBounds() |
| 200 fRadii[0].fX = clamp_radius_add(fRadii[0].fX, rect.fLeft, rect.fRight); |
| 201 fRadii[0].fY = clamp_radius_add(fRadii[0].fY, rect.fTop, rect.fBottom); |
| 202 fRadii[1].fX = clamp_radius_sub(fRadii[1].fX, rect.fLeft, rect.fRight); |
| 203 fRadii[1].fY = clamp_radius_add(fRadii[1].fY, rect.fTop, rect.fBottom); |
| 204 fRadii[2].fX = clamp_radius_sub(fRadii[2].fX, rect.fLeft, rect.fRight); |
| 205 fRadii[2].fY = clamp_radius_sub(fRadii[2].fY, rect.fTop, rect.fBottom); |
| 206 fRadii[3].fX = clamp_radius_add(fRadii[3].fX, rect.fLeft, rect.fRight); |
| 207 fRadii[3].fY = clamp_radius_sub(fRadii[3].fY, rect.fTop, rect.fBottom); |
| 208 |
167 // At this point we're either oval, simple, or complex (not empty or rect) | 209 // At this point we're either oval, simple, or complex (not empty or rect) |
168 // but we lazily resolve the type to avoid the work if the information | 210 // but we lazily resolve the type to avoid the work if the information |
169 // isn't required. | 211 // isn't required. |
170 fType = (SkRRect::Type) kUnknown_Type; | 212 fType = (SkRRect::Type) kUnknown_Type; |
171 | 213 |
172 SkDEBUGCODE(this->validate();) | 214 SkDEBUGCODE(this->validate();) |
173 } | 215 } |
174 | 216 |
175 // This method determines if a point known to be inside the RRect's bounds is | 217 // This method determines if a point known to be inside the RRect's bounds is |
176 // inside all the corners. | 218 // inside all the corners. |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 SkASSERT(!patchesOfNine); | 565 SkASSERT(!patchesOfNine); |
524 break; | 566 break; |
525 case kUnknown_Type: | 567 case kUnknown_Type: |
526 // no limits on this | 568 // no limits on this |
527 break; | 569 break; |
528 } | 570 } |
529 } | 571 } |
530 #endif // SK_DEBUG | 572 #endif // SK_DEBUG |
531 | 573 |
532 /////////////////////////////////////////////////////////////////////////////// | 574 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |