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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 * We need all combinations of predicates to be true to have a "safe" radius va lue. | 121 * We need all combinations of predicates to be true to have a "safe" radius va lue. |
122 */ | 122 */ |
123 static SkScalar clamp_radius_check_predicates(SkScalar rad, SkScalar min, SkScal ar max) { | 123 static SkScalar clamp_radius_check_predicates(SkScalar rad, SkScalar min, SkScal ar max) { |
124 SkASSERT(min < max); | 124 SkASSERT(min < max); |
125 if (rad > max - min || min + rad > max || max - rad < min) { | 125 if (rad > max - min || min + rad > max || max - rad < min) { |
126 rad = SkScalarDecULP(rad); | 126 rad = SkScalarDecULP(rad); |
127 } | 127 } |
128 return rad; | 128 return rad; |
129 } | 129 } |
130 | 130 |
131 static double compute_min_scale(double rad1, double rad2, double limit, double c urMin) { | |
reed1
2015/03/13 16:41:53
// explicitly use doubles here because ...
robertphillips
2015/03/13 16:46:23
Done.
| |
132 if ((rad1 + rad2) > limit) { | |
133 return SkTMin(curMin, limit / (rad1 + rad2)); | |
134 } | |
135 return curMin; | |
136 } | |
137 | |
131 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { | 138 void SkRRect::setRectRadii(const SkRect& rect, const SkVector radii[4]) { |
132 if (rect.isEmpty() || !rect.isFinite()) { | 139 if (rect.isEmpty() || !rect.isFinite()) { |
133 this->setEmpty(); | 140 this->setEmpty(); |
134 return; | 141 return; |
135 } | 142 } |
136 | 143 |
137 if (!SkScalarsAreFinite(&radii[0].fX, 8)) { | 144 if (!SkScalarsAreFinite(&radii[0].fX, 8)) { |
138 this->setRect(rect); // devolve into a simple rect | 145 this->setRect(rect); // devolve into a simple rect |
139 return; | 146 return; |
140 } | 147 } |
(...skipping 25 matching lines...) Expand all Loading... | |
166 // Proportionally scale down all radii to fit. Find the minimum ratio | 173 // Proportionally scale down all radii to fit. Find the minimum ratio |
167 // of a side and the radii on that side (for all four sides) and use | 174 // of a side and the radii on that side (for all four sides) and use |
168 // that to scale down _all_ the radii. This algorithm is from the | 175 // that to scale down _all_ the radii. This algorithm is from the |
169 // W3 spec (http://www.w3.org/TR/css3-background/) section 5.5 - Overlapping | 176 // W3 spec (http://www.w3.org/TR/css3-background/) section 5.5 - Overlapping |
170 // Curves: | 177 // Curves: |
171 // "Let f = min(Li/Si), where i is one of { top, right, bottom, left }, | 178 // "Let f = min(Li/Si), where i is one of { top, right, bottom, left }, |
172 // Si is the sum of the two corresponding radii of the corners on side i, | 179 // Si is the sum of the two corresponding radii of the corners on side i, |
173 // and Ltop = Lbottom = the width of the box, | 180 // and Ltop = Lbottom = the width of the box, |
174 // and Lleft = Lright = the height of the box. | 181 // and Lleft = Lright = the height of the box. |
175 // If f < 1, then all corner radii are reduced by multiplying them by f." | 182 // If f < 1, then all corner radii are reduced by multiplying them by f." |
176 SkScalar scale = SK_Scalar1; | 183 double scale = 1.0; |
177 | 184 |
178 if (fRadii[0].fX + fRadii[1].fX > rect.width()) { | 185 scale = compute_min_scale(fRadii[0].fX, fRadii[1].fX, rect.width(), scale); |
179 scale = SkMinScalar(scale, | 186 scale = compute_min_scale(fRadii[1].fY, fRadii[2].fY, rect.height(), scale); |
180 SkScalarDiv(rect.width(), fRadii[0].fX + fRadii[1].f X)); | 187 scale = compute_min_scale(fRadii[2].fX, fRadii[3].fX, rect.width(), scale); |
181 } | 188 scale = compute_min_scale(fRadii[3].fY, fRadii[0].fY, rect.height(), scale); |
182 if (fRadii[1].fY + fRadii[2].fY > rect.height()) { | |
183 scale = SkMinScalar(scale, | |
184 SkScalarDiv(rect.height(), fRadii[1].fY + fRadii[2]. fY)); | |
185 } | |
186 if (fRadii[2].fX + fRadii[3].fX > rect.width()) { | |
187 scale = SkMinScalar(scale, | |
188 SkScalarDiv(rect.width(), fRadii[2].fX + fRadii[3].f X)); | |
189 } | |
190 if (fRadii[3].fY + fRadii[0].fY > rect.height()) { | |
191 scale = SkMinScalar(scale, | |
192 SkScalarDiv(rect.height(), fRadii[3].fY + fRadii[0]. fY)); | |
193 } | |
194 | 189 |
195 if (scale < SK_Scalar1) { | 190 if (scale < 1.0) { |
196 for (int i = 0; i < 4; ++i) { | 191 for (int i = 0; i < 4; ++i) { |
197 fRadii[i].fX *= scale; | 192 fRadii[i].fX *= scale; |
198 fRadii[i].fY *= scale; | 193 fRadii[i].fY *= scale; |
199 } | 194 } |
200 } | 195 } |
201 | 196 |
202 // skbug.com/3239 -- its possible that we can hit the following inconsistenc y: | 197 // skbug.com/3239 -- its possible that we can hit the following inconsistenc y: |
203 // rad == bounds.bottom - bounds.top | 198 // rad == bounds.bottom - bounds.top |
204 // bounds.bottom - radius < bounds.top | 199 // bounds.bottom - radius < bounds.top |
205 // YIKES | 200 // YIKES |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 } | 585 } |
591 | 586 |
592 for (int i = 0; i < 4; ++i) { | 587 for (int i = 0; i < 4; ++i) { |
593 validate_radius_check_predicates(fRadii[i].fX, fRect.fLeft, fRect.fRight ); | 588 validate_radius_check_predicates(fRadii[i].fX, fRect.fLeft, fRect.fRight ); |
594 validate_radius_check_predicates(fRadii[i].fY, fRect.fTop, fRect.fBottom ); | 589 validate_radius_check_predicates(fRadii[i].fY, fRect.fTop, fRect.fBottom ); |
595 } | 590 } |
596 } | 591 } |
597 #endif // SK_DEBUG | 592 #endif // SK_DEBUG |
598 | 593 |
599 /////////////////////////////////////////////////////////////////////////////// | 594 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |