| 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 |