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

Side by Side Diff: src/utils/SkCurveMeasure.cpp

Issue 2243313002: Implement Conics in SkCurveMeasure (Closed) Base URL: https://skia.googlesource.com/skia.git@cubic_fix
Patch Set: Created 4 years, 4 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
« src/utils/SkCurveMeasure.h ('K') | « src/utils/SkCurveMeasure.h ('k') | no next file » | 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 2016 Google Inc. 2 * Copyright 2016 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 "SkCurveMeasure.h" 8 #include "SkCurveMeasure.h"
9 #include "SkGeometry.h" 9 #include "SkGeometry.h"
10 10
11 // for abs 11 // for abs
12 #include <cmath> 12 #include <cmath>
13 13
14 #define UNIMPLEMENTED SkDEBUGF(("%s:%d unimplemented\n", __FILE__, __LINE__)) 14 #define UNIMPLEMENTED SkDEBUGF(("%s:%d unimplemented\n", __FILE__, __LINE__))
caryclark 2016/08/15 19:13:04 Make this an assert.
Harry Stern 2016/08/15 20:55:16 Done, depends on https://codereview.chromium.org/2
15 15
16 /// Used inside SkCurveMeasure::getTime's Newton's iteration 16 /// Used inside SkCurveMeasure::getTime's Newton's iteration
17 static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType, 17 static inline SkPoint evaluate(const SkPoint pts[4], SkSegType segType,
18 SkScalar t) { 18 SkScalar t) {
19 SkPoint pos; 19 SkPoint pos;
20 switch (segType) { 20 switch (segType) {
21 case kQuad_SegType: 21 case kQuad_SegType:
22 pos = SkEvalQuadAt(pts, t); 22 pos = SkEvalQuadAt(pts, t);
23 break; 23 break;
24 case kLine_SegType: 24 case kLine_SegType:
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 default: 62 default:
63 UNIMPLEMENTED; 63 UNIMPLEMENTED;
64 } 64 }
65 65
66 return tan; 66 return tan;
67 } 67 }
68 /// Used in ArcLengthIntegrator::computeLength 68 /// Used in ArcLengthIntegrator::computeLength
69 static inline Sk8f evaluateDerivativeLength(const Sk8f& ts, 69 static inline Sk8f evaluateDerivativeLength(const Sk8f& ts,
70 const Sk8f (&xCoeff)[3], 70 const Sk8f (&xCoeff)[3],
71 const Sk8f (&yCoeff)[3], 71 const Sk8f (&yCoeff)[3],
72 const SkScalar w,
72 const SkSegType segType) { 73 const SkSegType segType) {
73 Sk8f x; 74 Sk8f x;
74 Sk8f y; 75 Sk8f y;
75 switch (segType) { 76 switch (segType) {
76 case kQuad_SegType: 77 case kQuad_SegType:
77 x = xCoeff[0]*ts + xCoeff[1]; 78 x = xCoeff[0]*ts + xCoeff[1];
78 y = yCoeff[0]*ts + yCoeff[1]; 79 y = yCoeff[0]*ts + yCoeff[1];
79 break; 80 break;
80 case kCubic_SegType: 81 case kCubic_SegType:
81 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2]; 82 x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2];
82 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2]; 83 y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2];
83 break; 84 break;
84 case kConic_SegType: 85 case kConic_SegType: {
85 UNIMPLEMENTED; 86 Sk8f xnum = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2];
87 Sk8f ynum = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2];
88
89 Sk8f denom = ts*(-4 + 4*w + ts*(8 - 12*w + 4*w*w + ts*(-8 + 16*w -
90 8*w*w + ts*(4 - 8*w + 4*w*w)))) + 1;
caryclark 2016/08/15 19:13:04 Where did this come from? That is, please document
Harry Stern 2016/08/15 20:55:16 I took out those terms. I honestly didn't notice t
Harry Stern 2016/08/17 02:48:46 Also, I have added the mathematica commands used t
91
92 x = xnum / denom;
93 y = ynum / denom;
caryclark 2016/08/15 19:13:04 Is there a unit test for this?
Harry Stern 2016/08/15 20:55:16 It's on my todo by tomorrow.
94 }
86 break; 95 break;
87 default: 96 default:
88 UNIMPLEMENTED; 97 UNIMPLEMENTED;
89 } 98 }
90 99
91 x = x * x; 100 x = x * x;
92 y = y * y; 101 y = y * y;
93 102
94 return (x + y).sqrt(); 103 return (x + y).sqrt();
95 } 104 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 // precompute coefficients for derivative 136 // precompute coefficients for derivative
128 xCoeff[0] = Sk8f(3.0f*(-Ax + 3.0f*(Bx - Cx) + Dx)); 137 xCoeff[0] = Sk8f(3.0f*(-Ax + 3.0f*(Bx - Cx) + Dx));
129 xCoeff[1] = Sk8f(3.0f*(2.0f*(Ax - 2.0f*Bx + Cx))); 138 xCoeff[1] = Sk8f(3.0f*(2.0f*(Ax - 2.0f*Bx + Cx)));
130 xCoeff[2] = Sk8f(3.0f*(-Ax + Bx)); 139 xCoeff[2] = Sk8f(3.0f*(-Ax + Bx));
131 140
132 yCoeff[0] = Sk8f(3.0f*(-Ay + 3.0f*(By - Cy) + Dy)); 141 yCoeff[0] = Sk8f(3.0f*(-Ay + 3.0f*(By - Cy) + Dy));
133 yCoeff[1] = Sk8f(3.0f*(2.0f*(Ay - 2.0f*By + Cy))); 142 yCoeff[1] = Sk8f(3.0f*(2.0f*(Ay - 2.0f*By + Cy)));
134 yCoeff[2] = Sk8f(3.0f*(-Ay + By)); 143 yCoeff[2] = Sk8f(3.0f*(-Ay + By));
135 } 144 }
136 break; 145 break;
137 case kConic_SegType: 146 case kConic_SegType: {
138 UNIMPLEMENTED; 147 float Ax = pts[0].x();
148 float Bx = pts[1].x();
149 float Cx = pts[2].x();
150 float Ay = pts[0].y();
151 float By = pts[1].y();
152 float Cy = pts[2].y();
153
154 fConicW = pts[3].x();
Harry Stern 2016/08/15 18:01:21 fConicW gets set here
155
156 SkScalar w = fConicW;
157
158 // precompute coefficients for derivative
159 xCoeff[0] = Sk8f(2*(Ax - Cx - Ax*w + Cx*w));
160 xCoeff[1] = Sk8f(-2*(Ax + Cx + 2*(Ax*w - Bx*w)));
161 xCoeff[2] = Sk8f(-2*(Ax*w + Bx*w));
162
163 yCoeff[0] = Sk8f(2*(Ay - Cy - Ay*w + Cy*w));
164 yCoeff[1] = Sk8f(-2*(Ay + Cy + 2*(Ay*w - By*w)));
165 yCoeff[2] = Sk8f(-2*(Ay*w + By*w));
166 }
139 break; 167 break;
140 default: 168 default:
141 UNIMPLEMENTED; 169 UNIMPLEMENTED;
142 } 170 }
143 } 171 }
144 172
145 // We use Gaussian quadrature 173 // We use Gaussian quadrature
146 // (https://en.wikipedia.org/wiki/Gaussian_quadrature) 174 // (https://en.wikipedia.org/wiki/Gaussian_quadrature)
147 // to approximate the arc length integral here, because it is amenable to SIMD. 175 // to approximate the arc length integral here, because it is amenable to SIMD.
148 SkScalar ArcLengthIntegrator::computeLength(SkScalar t) { 176 SkScalar ArcLengthIntegrator::computeLength(SkScalar t) {
149 SkScalar length = 0.0f; 177 SkScalar length = 0.0f;
150 178
151 Sk8f lengths = evaluateDerivativeLength(absc*t, xCoeff, yCoeff, fSegType); 179 Sk8f lengths = evaluateDerivativeLength(absc*t, xCoeff, yCoeff, fConicW, fSe gType);
152 lengths = weights*lengths; 180 lengths = weights*lengths;
153 // is it faster or more accurate to sum and then multiply or vice versa? 181 // is it faster or more accurate to sum and then multiply or vice versa?
154 lengths = lengths*(t*0.5f); 182 lengths = lengths*(t*0.5f);
155 183
156 // Why does SkNx index with ints? does negative index mean something? 184 // Why does SkNx index with ints? does negative index mean something?
157 for (int i = 0; i < 8; i++) { 185 for (int i = 0; i < 8; i++) {
158 length += lengths[i]; 186 length += lengths[i];
159 } 187 }
160 return length; 188 return length;
161 } 189 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 if (time) { 329 if (time) {
302 *time = t; 330 *time = t;
303 } 331 }
304 if (pos) { 332 if (pos) {
305 *pos = evaluate(fPts, fSegType, t); 333 *pos = evaluate(fPts, fSegType, t);
306 } 334 }
307 if (tan) { 335 if (tan) {
308 *tan = evaluateDerivative(fPts, fSegType, t); 336 *tan = evaluateDerivative(fPts, fSegType, t);
309 } 337 }
310 } 338 }
OLDNEW
« src/utils/SkCurveMeasure.h ('K') | « src/utils/SkCurveMeasure.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698