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

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

Issue 1541523002: check in direct quad length measure (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years 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 | « no previous file | 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 /* 2 /*
3 * Copyright 2008 The Android Open Source Project 3 * Copyright 2008 The Android Open Source Project
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 8
9 9
10 #include "SkPathMeasure.h" 10 #include "SkPathMeasure.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 static bool cubic_too_curvy(const SkPoint pts[4]) { 83 static bool cubic_too_curvy(const SkPoint pts[4]) {
84 return cheap_dist_exceeds_limit(pts[1], 84 return cheap_dist_exceeds_limit(pts[1],
85 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1/3), 85 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1/3),
86 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1/3)) 86 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1/3))
87 || 87 ||
88 cheap_dist_exceeds_limit(pts[2], 88 cheap_dist_exceeds_limit(pts[2],
89 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1*2/3), 89 SkScalarInterp(pts[0].fX, pts[3].fX, SK_Scalar1*2/3),
90 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1*2/3)); 90 SkScalarInterp(pts[0].fY, pts[3].fY, SK_Scalar1*2/3));
91 } 91 }
92 92
93 /* from http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/ */
94 static SkScalar compute_quad_len(const SkPoint pts[3]) {
95 SkPoint a,b;
96 a.fX = pts[0].fX - 2 * pts[1].fX + pts[2].fX;
97 a.fY = pts[0].fY - 2 * pts[1].fY + pts[2].fY;
98 b.fX = 2 * (pts[1].fX - pts[0].fX);
99 b.fY = 2 * (pts[1].fY - pts[0].fY);
100 SkScalar A = 4 * (a.fX * a.fX + a.fY * a.fY);
101 SkScalar B = 4 * (a.fX * b.fX + a.fY * b.fY);
102 SkScalar C = b.fX * b.fX + b.fY * b.fY;
103
104 SkScalar Sabc = 2 * SkScalarSqrt(A + B + C);
105 SkScalar A_2 = SkScalarSqrt(A);
106 SkScalar A_32 = 2 * A * A_2;
107 SkScalar C_2 = 2 * SkScalarSqrt(C);
108 SkScalar BA = B / A_2;
109
110 return (A_32 * Sabc + A_2 * B * (Sabc - C_2) +
111 (4 * C * A - B * B) * SkScalarLog((2 * A_2 + BA + Sabc) / (BA + C_2) )) / (4 * A_32);
112 }
113
114
93 SkScalar SkPathMeasure::compute_quad_segs(const SkPoint pts[3], 115 SkScalar SkPathMeasure::compute_quad_segs(const SkPoint pts[3],
94 SkScalar distance, int mint, int maxt, int ptIndex) { 116 SkScalar distance, int mint, int maxt, int ptIndex) {
95 if (tspan_big_enough(maxt - mint) && quad_too_curvy(pts)) { 117 if (tspan_big_enough(maxt - mint) && quad_too_curvy(pts)) {
96 SkPoint tmp[5]; 118 SkPoint tmp[5];
97 int halft = (mint + maxt) >> 1; 119 int halft = (mint + maxt) >> 1;
98 120
99 SkChopQuadAtHalf(pts, tmp); 121 SkChopQuadAtHalf(pts, tmp);
100 distance = this->compute_quad_segs(tmp, distance, mint, halft, ptIndex); 122 distance = this->compute_quad_segs(tmp, distance, mint, halft, ptIndex);
101 distance = this->compute_quad_segs(&tmp[2], distance, halft, maxt, ptInd ex); 123 distance = this->compute_quad_segs(&tmp[2], distance, halft, maxt, ptInd ex);
102 } else { 124 } else {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 seg->fPtIndex = ptIndex; 224 seg->fPtIndex = ptIndex;
203 seg->fType = kLine_SegType; 225 seg->fType = kLine_SegType;
204 seg->fTValue = kMaxTValue; 226 seg->fTValue = kMaxTValue;
205 fPts.append(1, pts + 1); 227 fPts.append(1, pts + 1);
206 ptIndex++; 228 ptIndex++;
207 } 229 }
208 } break; 230 } break;
209 231
210 case SkPath::kQuad_Verb: { 232 case SkPath::kQuad_Verb: {
211 SkScalar prevD = distance; 233 SkScalar prevD = distance;
212 distance = this->compute_quad_segs(pts, distance, 0, kMaxTValue, ptIndex); 234 if (false) {
235 SkScalar length = compute_quad_len(pts);
236 if (length) {
237 distance += length;
238 Segment* seg = fSegments.append();
239 seg->fDistance = distance;
240 seg->fPtIndex = ptIndex;
241 seg->fType = kQuad_SegType;
242 seg->fTValue = kMaxTValue;
243 }
244 } else {
245 distance = this->compute_quad_segs(pts, distance, 0, kMaxTVa lue, ptIndex);
246 }
213 if (distance > prevD) { 247 if (distance > prevD) {
214 fPts.append(2, pts + 1); 248 fPts.append(2, pts + 1);
215 ptIndex += 2; 249 ptIndex += 2;
216 } 250 }
217 } break; 251 } break;
218 252
219 case SkPath::kConic_Verb: { 253 case SkPath::kConic_Verb: {
220 const SkConic conic(pts, fIter.conicWeight()); 254 const SkConic conic(pts, fIter.conicWeight());
221 SkScalar prevD = distance; 255 SkScalar prevD = distance;
222 distance = this->compute_conic_segs(conic, distance, 0, kMaxTVal ue, ptIndex); 256 distance = this->compute_conic_segs(conic, distance, 0, kMaxTVal ue, ptIndex);
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 667
634 for (int i = 0; i < fSegments.count(); i++) { 668 for (int i = 0; i < fSegments.count(); i++) {
635 const Segment* seg = &fSegments[i]; 669 const Segment* seg = &fSegments[i];
636 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n", 670 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n",
637 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(), 671 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(),
638 seg->fType); 672 seg->fType);
639 } 673 }
640 } 674 }
641 675
642 #endif 676 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698