Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Side by Side Diff: src/core/SkRRect.cpp

Issue 913743002: check for nonfinites in rrects (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: update test for nonfinites Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkScalar.h ('k') | tests/PathTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 ///////////////////////////////////////////////////////////////////////////////
OLDNEW
« no previous file with comments | « include/core/SkScalar.h ('k') | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698