| OLD | NEW | 
|---|
| 1 | 1 | 
| 2 /* | 2 /* | 
| 3  * Copyright 2011 Google Inc. | 3  * Copyright 2011 Google Inc. | 
| 4  * | 4  * | 
| 5  * Use of this source code is governed by a BSD-style license that can be | 5  * Use of this source code is governed by a BSD-style license that can be | 
| 6  * found in the LICENSE file. | 6  * found in the LICENSE file. | 
| 7  */ | 7  */ | 
| 8 #include "SkLineClipper.h" | 8 #include "SkLineClipper.h" | 
| 9 | 9 | 
| 10 template <typename T> T pin_unsorted(T value, T limit0, T limit1) { | 10 template <typename T> T pin_unsorted(T value, T limit0, T limit1) { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 21     } | 21     } | 
| 22     return value; | 22     return value; | 
| 23 } | 23 } | 
| 24 | 24 | 
| 25 // return X coordinate of intersection with horizontal line at Y | 25 // return X coordinate of intersection with horizontal line at Y | 
| 26 static SkScalar sect_with_horizontal(const SkPoint src[2], SkScalar Y) { | 26 static SkScalar sect_with_horizontal(const SkPoint src[2], SkScalar Y) { | 
| 27     SkScalar dy = src[1].fY - src[0].fY; | 27     SkScalar dy = src[1].fY - src[0].fY; | 
| 28     if (SkScalarNearlyZero(dy)) { | 28     if (SkScalarNearlyZero(dy)) { | 
| 29         return SkScalarAve(src[0].fX, src[1].fX); | 29         return SkScalarAve(src[0].fX, src[1].fX); | 
| 30     } else { | 30     } else { | 
| 31 #ifdef SK_SCALAR_IS_FLOAT |  | 
| 32         // need the extra precision so we don't compute a value that exceeds | 31         // need the extra precision so we don't compute a value that exceeds | 
| 33         // our original limits | 32         // our original limits | 
| 34         double X0 = src[0].fX; | 33         double X0 = src[0].fX; | 
| 35         double Y0 = src[0].fY; | 34         double Y0 = src[0].fY; | 
| 36         double X1 = src[1].fX; | 35         double X1 = src[1].fX; | 
| 37         double Y1 = src[1].fY; | 36         double Y1 = src[1].fY; | 
| 38         double result = X0 + ((double)Y - Y0) * (X1 - X0) / (Y1 - Y0); | 37         double result = X0 + ((double)Y - Y0) * (X1 - X0) / (Y1 - Y0); | 
| 39 | 38 | 
| 40         // The computed X value might still exceed [X0..X1] due to quantum flux | 39         // The computed X value might still exceed [X0..X1] due to quantum flux | 
| 41         // when the doubles were added and subtracted, so we have to pin the | 40         // when the doubles were added and subtracted, so we have to pin the | 
| 42         // answer :( | 41         // answer :( | 
| 43         return (float)pin_unsorted(result, X0, X1); | 42         return (float)pin_unsorted(result, X0, X1); | 
| 44 #else |  | 
| 45         return src[0].fX + SkScalarMulDiv(Y - src[0].fY, src[1].fX - src[0].fX, |  | 
| 46                                           dy); |  | 
| 47 #endif |  | 
| 48     } | 43     } | 
| 49 } | 44 } | 
| 50 | 45 | 
| 51 // return Y coordinate of intersection with vertical line at X | 46 // return Y coordinate of intersection with vertical line at X | 
| 52 static SkScalar sect_with_vertical(const SkPoint src[2], SkScalar X) { | 47 static SkScalar sect_with_vertical(const SkPoint src[2], SkScalar X) { | 
| 53     SkScalar dx = src[1].fX - src[0].fX; | 48     SkScalar dx = src[1].fX - src[0].fX; | 
| 54     if (SkScalarNearlyZero(dx)) { | 49     if (SkScalarNearlyZero(dx)) { | 
| 55         return SkScalarAve(src[0].fY, src[1].fY); | 50         return SkScalarAve(src[0].fY, src[1].fY); | 
| 56     } else { | 51     } else { | 
| 57 #ifdef SK_SCALAR_IS_FLOAT |  | 
| 58         // need the extra precision so we don't compute a value that exceeds | 52         // need the extra precision so we don't compute a value that exceeds | 
| 59         // our original limits | 53         // our original limits | 
| 60         double X0 = src[0].fX; | 54         double X0 = src[0].fX; | 
| 61         double Y0 = src[0].fY; | 55         double Y0 = src[0].fY; | 
| 62         double X1 = src[1].fX; | 56         double X1 = src[1].fX; | 
| 63         double Y1 = src[1].fY; | 57         double Y1 = src[1].fY; | 
| 64         double result = Y0 + ((double)X - X0) * (Y1 - Y0) / (X1 - X0); | 58         double result = Y0 + ((double)X - X0) * (Y1 - Y0) / (X1 - X0); | 
| 65         return (float)result; | 59         return (float)result; | 
| 66 #else |  | 
| 67         return src[0].fY + SkScalarMulDiv(X - src[0].fX, src[1].fY - src[0].fY, |  | 
| 68                                           dx); |  | 
| 69 #endif |  | 
| 70     } | 60     } | 
| 71 } | 61 } | 
| 72 | 62 | 
| 73 /////////////////////////////////////////////////////////////////////////////// | 63 /////////////////////////////////////////////////////////////////////////////// | 
| 74 | 64 | 
| 75 static inline bool nestedLT(SkScalar a, SkScalar b, SkScalar dim) { | 65 static inline bool nestedLT(SkScalar a, SkScalar b, SkScalar dim) { | 
| 76     return a <= b && (a < b || dim > 0); | 66     return a <= b && (a < b || dim > 0); | 
| 77 } | 67 } | 
| 78 | 68 | 
| 79 // returns true if outer contains inner, even if inner is empty. | 69 // returns true if outer contains inner, even if inner is empty. | 
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 160 static bool is_between_unsorted(SkScalar value, | 150 static bool is_between_unsorted(SkScalar value, | 
| 161                                 SkScalar limit0, SkScalar limit1) { | 151                                 SkScalar limit0, SkScalar limit1) { | 
| 162     if (limit0 < limit1) { | 152     if (limit0 < limit1) { | 
| 163         return limit0 <= value && value <= limit1; | 153         return limit0 <= value && value <= limit1; | 
| 164     } else { | 154     } else { | 
| 165         return limit1 <= value && value <= limit0; | 155         return limit1 <= value && value <= limit0; | 
| 166     } | 156     } | 
| 167 } | 157 } | 
| 168 #endif | 158 #endif | 
| 169 | 159 | 
| 170 #ifdef SK_SCALAR_IS_FLOAT |  | 
| 171 #ifdef SK_DEBUG | 160 #ifdef SK_DEBUG | 
| 172 // This is an example of why we need to pin the result computed in | 161 // This is an example of why we need to pin the result computed in | 
| 173 // sect_with_horizontal. If we didn't explicitly pin, is_between_unsorted would | 162 // sect_with_horizontal. If we didn't explicitly pin, is_between_unsorted would | 
| 174 // fail. | 163 // fail. | 
| 175 // | 164 // | 
| 176 static void sect_with_horizontal_test_for_pin_results() { | 165 static void sect_with_horizontal_test_for_pin_results() { | 
| 177     const SkPoint pts[] = { | 166     const SkPoint pts[] = { | 
| 178         { -540000,    -720000 }, | 167         { -540000,    -720000 }, | 
| 179         { -9.10000017e-05f, 9.99999996e-13f } | 168         { -9.10000017e-05f, 9.99999996e-13f } | 
| 180     }; | 169     }; | 
| 181     float x = sect_with_horizontal(pts, 0); | 170     float x = sect_with_horizontal(pts, 0); | 
| 182     SkASSERT(is_between_unsorted(x, pts[0].fX, pts[1].fX)); | 171     SkASSERT(is_between_unsorted(x, pts[0].fX, pts[1].fX)); | 
| 183 } | 172 } | 
| 184 #endif | 173 #endif | 
| 185 #endif |  | 
| 186 | 174 | 
| 187 int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, | 175 int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, | 
| 188                             SkPoint lines[]) { | 176                             SkPoint lines[]) { | 
| 189 #ifdef SK_SCALAR_IS_FLOAT |  | 
| 190 #ifdef SK_DEBUG | 177 #ifdef SK_DEBUG | 
| 191     { | 178     { | 
| 192         static bool gOnce; | 179         static bool gOnce; | 
| 193         if (!gOnce) { | 180         if (!gOnce) { | 
| 194             sect_with_horizontal_test_for_pin_results(); | 181             sect_with_horizontal_test_for_pin_results(); | 
| 195             gOnce = true; | 182             gOnce = true; | 
| 196         } | 183         } | 
| 197     } | 184     } | 
| 198 #endif | 185 #endif | 
| 199 #endif |  | 
| 200 | 186 | 
| 201     int index0, index1; | 187     int index0, index1; | 
| 202 | 188 | 
| 203     if (pts[0].fY < pts[1].fY) { | 189     if (pts[0].fY < pts[1].fY) { | 
| 204         index0 = 0; | 190         index0 = 0; | 
| 205         index1 = 1; | 191         index1 = 1; | 
| 206     } else { | 192     } else { | 
| 207         index0 = 1; | 193         index0 = 1; | 
| 208         index1 = 0; | 194         index1 = 0; | 
| 209     } | 195     } | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 288     if (reverse) { | 274     if (reverse) { | 
| 289         // copy the pts in reverse order to maintain winding order | 275         // copy the pts in reverse order to maintain winding order | 
| 290         for (int i = 0; i <= lineCount; i++) { | 276         for (int i = 0; i <= lineCount; i++) { | 
| 291             lines[lineCount - i] = result[i]; | 277             lines[lineCount - i] = result[i]; | 
| 292         } | 278         } | 
| 293     } else { | 279     } else { | 
| 294         memcpy(lines, result, (lineCount + 1) * sizeof(SkPoint)); | 280         memcpy(lines, result, (lineCount + 1) * sizeof(SkPoint)); | 
| 295     } | 281     } | 
| 296     return lineCount; | 282     return lineCount; | 
| 297 } | 283 } | 
| OLD | NEW | 
|---|