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

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

Issue 2221203002: Move seg_to to a new header, define SkSegType enum there (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rename addSegmentToPath to SkPathMeasure_segTo 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
« no previous file with comments | « include/core/SkPathMeasure.h ('k') | src/core/SkPathMeasurePriv.h » ('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 2008 The Android Open Source Project 2 * Copyright 2008 The Android Open Source Project
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 8
9 #include "SkPathMeasure.h" 9 #include "SkPathMeasure.h"
10 #include "SkPathMeasurePriv.h"
10 #include "SkGeometry.h" 11 #include "SkGeometry.h"
11 #include "SkPath.h" 12 #include "SkPath.h"
12 #include "SkTSearch.h" 13 #include "SkTSearch.h"
13 14
14 // these must be 0,1,2,3 since they are in our 2-bit field
15 enum {
16 kLine_SegType,
17 kQuad_SegType,
18 kCubic_SegType,
19 kConic_SegType,
20 };
21
22 #define kMaxTValue 0x3FFFFFFF 15 #define kMaxTValue 0x3FFFFFFF
23 16
24 static inline SkScalar tValue2Scalar(int t) { 17 static inline SkScalar tValue2Scalar(int t) {
25 SkASSERT((unsigned)t <= kMaxTValue); 18 SkASSERT((unsigned)t <= kMaxTValue);
26 const SkScalar kMaxTReciprocal = 1.0f / kMaxTValue; 19 const SkScalar kMaxTReciprocal = 1.0f / kMaxTValue;
27 return t * kMaxTReciprocal; 20 return t * kMaxTReciprocal;
28 } 21 }
29 22
30 SkScalar SkPathMeasure::Segment::getScalarT() const { 23 SkScalar SkPathMeasure::Segment::getScalarT() const {
31 return tValue2Scalar(fTValue); 24 return tValue2Scalar(fTValue);
32 } 25 }
33 26
34 const SkPathMeasure::Segment* SkPathMeasure::NextSegment(const Segment* seg) { 27 const SkPathMeasure::Segment* SkPathMeasure::NextSegment(const Segment* seg) {
35 unsigned ptIndex = seg->fPtIndex; 28 unsigned ptIndex = seg->fPtIndex;
36 29
37 do { 30 do {
38 ++seg; 31 ++seg;
39 } while (seg->fPtIndex == ptIndex); 32 } while (seg->fPtIndex == ptIndex);
40 return seg; 33 return seg;
41 } 34 }
42 35
36 void SkPathMeasure_segTo(const SkPoint pts[], unsigned segType,
37 SkScalar startT, SkScalar stopT, SkPath* dst) {
38 SkASSERT(startT >= 0 && startT <= SK_Scalar1);
39 SkASSERT(stopT >= 0 && stopT <= SK_Scalar1);
40 SkASSERT(startT <= stopT);
41
42 if (startT == stopT) {
43 /* if the dash as a zero-length on segment, add a corresponding zero-len gth line.
44 The stroke code will add end caps to zero length lines as appropriate */
45 SkPoint lastPt;
46 SkAssertResult(dst->getLastPt(&lastPt));
47 dst->lineTo(lastPt);
48 return;
49 }
50
51 SkPoint tmp0[7], tmp1[7];
52
53 switch (segType) {
54 case kLine_SegType:
55 if (SK_Scalar1 == stopT) {
56 dst->lineTo(pts[1]);
57 } else {
58 dst->lineTo(SkScalarInterp(pts[0].fX, pts[1].fX, stopT),
59 SkScalarInterp(pts[0].fY, pts[1].fY, stopT));
60 }
61 break;
62 case kQuad_SegType:
63 if (0 == startT) {
64 if (SK_Scalar1 == stopT) {
65 dst->quadTo(pts[1], pts[2]);
66 } else {
67 SkChopQuadAt(pts, tmp0, stopT);
68 dst->quadTo(tmp0[1], tmp0[2]);
69 }
70 } else {
71 SkChopQuadAt(pts, tmp0, startT);
72 if (SK_Scalar1 == stopT) {
73 dst->quadTo(tmp0[3], tmp0[4]);
74 } else {
75 SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT) );
76 dst->quadTo(tmp1[1], tmp1[2]);
77 }
78 }
79 break;
80 case kConic_SegType: {
81 SkConic conic(pts[0], pts[2], pts[3], pts[1].fX);
82
83 if (0 == startT) {
84 if (SK_Scalar1 == stopT) {
85 dst->conicTo(conic.fPts[1], conic.fPts[2], conic.fW);
86 } else {
87 SkConic tmp[2];
88 conic.chopAt(stopT, tmp);
89 dst->conicTo(tmp[0].fPts[1], tmp[0].fPts[2], tmp[0].fW);
90 }
91 } else {
92 if (SK_Scalar1 == stopT) {
93 SkConic tmp1[2];
94 conic.chopAt(startT, tmp1);
95 dst->conicTo(tmp1[1].fPts[1], tmp1[1].fPts[2], tmp1[1].fW);
96 } else {
97 SkConic tmp;
98 conic.chopAt(startT, stopT, &tmp);
99 dst->conicTo(tmp.fPts[1], tmp.fPts[2], tmp.fW);
100 }
101 }
102 } break;
103 case kCubic_SegType:
104 if (0 == startT) {
105 if (SK_Scalar1 == stopT) {
106 dst->cubicTo(pts[1], pts[2], pts[3]);
107 } else {
108 SkChopCubicAt(pts, tmp0, stopT);
109 dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]);
110 }
111 } else {
112 SkChopCubicAt(pts, tmp0, startT);
113 if (SK_Scalar1 == stopT) {
114 dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]);
115 } else {
116 SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT ));
117 dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]);
118 }
119 }
120 break;
121 default:
122 SkDEBUGFAIL("unknown segType");
123 sk_throw();
124 }
125 }
126
43 /////////////////////////////////////////////////////////////////////////////// 127 ///////////////////////////////////////////////////////////////////////////////
44 128
45 static inline int tspan_big_enough(int tspan) { 129 static inline int tspan_big_enough(int tspan) {
46 SkASSERT((unsigned)tspan <= kMaxTValue); 130 SkASSERT((unsigned)tspan <= kMaxTValue);
47 return tspan >> 10; 131 return tspan >> 10;
48 } 132 }
49 133
50 // can't use tangents, since we need [0..1..................2] to be seen 134 // can't use tangents, since we need [0..1..................2] to be seen
51 // as definitely not a line (it is when drawn, but not parametrically) 135 // as definitely not a line (it is when drawn, but not parametrically)
52 // so we compare midpoints 136 // so we compare midpoints
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 422
339 distance = seg->fDistance; 423 distance = seg->fDistance;
340 ptIndex = seg->fPtIndex; 424 ptIndex = seg->fPtIndex;
341 seg += 1; 425 seg += 1;
342 } 426 }
343 // SkDebugf("\n"); 427 // SkDebugf("\n");
344 } 428 }
345 #endif 429 #endif
346 } 430 }
347 431
348 static void compute_pos_tan(const SkPoint pts[], int segType, 432 static void compute_pos_tan(const SkPoint pts[], unsigned segType,
349 SkScalar t, SkPoint* pos, SkVector* tangent) { 433 SkScalar t, SkPoint* pos, SkVector* tangent) {
350 switch (segType) { 434 switch (segType) {
351 case kLine_SegType: 435 case kLine_SegType:
352 if (pos) { 436 if (pos) {
353 pos->set(SkScalarInterp(pts[0].fX, pts[1].fX, t), 437 pos->set(SkScalarInterp(pts[0].fX, pts[1].fX, t),
354 SkScalarInterp(pts[0].fY, pts[1].fY, t)); 438 SkScalarInterp(pts[0].fY, pts[1].fY, t));
355 } 439 }
356 if (tangent) { 440 if (tangent) {
357 tangent->setNormalize(pts[1].fX - pts[0].fX, pts[1].fY - pts[0]. fY); 441 tangent->setNormalize(pts[1].fX - pts[0].fX, pts[1].fY - pts[0]. fY);
358 } 442 }
(...skipping 14 matching lines...) Expand all
373 SkEvalCubicAt(pts, t, pos, tangent, nullptr); 457 SkEvalCubicAt(pts, t, pos, tangent, nullptr);
374 if (tangent) { 458 if (tangent) {
375 tangent->normalize(); 459 tangent->normalize();
376 } 460 }
377 break; 461 break;
378 default: 462 default:
379 SkDEBUGFAIL("unknown segType"); 463 SkDEBUGFAIL("unknown segType");
380 } 464 }
381 } 465 }
382 466
383 static void seg_to(const SkPoint pts[], int segType,
384 SkScalar startT, SkScalar stopT, SkPath* dst) {
385 SkASSERT(startT >= 0 && startT <= SK_Scalar1);
386 SkASSERT(stopT >= 0 && stopT <= SK_Scalar1);
387 SkASSERT(startT <= stopT);
388
389 if (startT == stopT) {
390 /* if the dash as a zero-length on segment, add a corresponding zero-len gth line.
391 The stroke code will add end caps to zero length lines as appropriate */
392 SkPoint lastPt;
393 SkAssertResult(dst->getLastPt(&lastPt));
394 dst->lineTo(lastPt);
395 return;
396 }
397
398 SkPoint tmp0[7], tmp1[7];
399
400 switch (segType) {
401 case kLine_SegType:
402 if (SK_Scalar1 == stopT) {
403 dst->lineTo(pts[1]);
404 } else {
405 dst->lineTo(SkScalarInterp(pts[0].fX, pts[1].fX, stopT),
406 SkScalarInterp(pts[0].fY, pts[1].fY, stopT));
407 }
408 break;
409 case kQuad_SegType:
410 if (0 == startT) {
411 if (SK_Scalar1 == stopT) {
412 dst->quadTo(pts[1], pts[2]);
413 } else {
414 SkChopQuadAt(pts, tmp0, stopT);
415 dst->quadTo(tmp0[1], tmp0[2]);
416 }
417 } else {
418 SkChopQuadAt(pts, tmp0, startT);
419 if (SK_Scalar1 == stopT) {
420 dst->quadTo(tmp0[3], tmp0[4]);
421 } else {
422 SkChopQuadAt(&tmp0[2], tmp1, (stopT - startT) / (1 - startT) );
423 dst->quadTo(tmp1[1], tmp1[2]);
424 }
425 }
426 break;
427 case kConic_SegType: {
428 SkConic conic(pts[0], pts[2], pts[3], pts[1].fX);
429
430 if (0 == startT) {
431 if (SK_Scalar1 == stopT) {
432 dst->conicTo(conic.fPts[1], conic.fPts[2], conic.fW);
433 } else {
434 SkConic tmp[2];
435 conic.chopAt(stopT, tmp);
436 dst->conicTo(tmp[0].fPts[1], tmp[0].fPts[2], tmp[0].fW);
437 }
438 } else {
439 if (SK_Scalar1 == stopT) {
440 SkConic tmp1[2];
441 conic.chopAt(startT, tmp1);
442 dst->conicTo(tmp1[1].fPts[1], tmp1[1].fPts[2], tmp1[1].fW);
443 } else {
444 SkConic tmp;
445 conic.chopAt(startT, stopT, &tmp);
446 dst->conicTo(tmp.fPts[1], tmp.fPts[2], tmp.fW);
447 }
448 }
449 } break;
450 case kCubic_SegType:
451 if (0 == startT) {
452 if (SK_Scalar1 == stopT) {
453 dst->cubicTo(pts[1], pts[2], pts[3]);
454 } else {
455 SkChopCubicAt(pts, tmp0, stopT);
456 dst->cubicTo(tmp0[1], tmp0[2], tmp0[3]);
457 }
458 } else {
459 SkChopCubicAt(pts, tmp0, startT);
460 if (SK_Scalar1 == stopT) {
461 dst->cubicTo(tmp0[4], tmp0[5], tmp0[6]);
462 } else {
463 SkChopCubicAt(&tmp0[3], tmp1, (stopT - startT) / (1 - startT ));
464 dst->cubicTo(tmp1[1], tmp1[2], tmp1[3]);
465 }
466 }
467 break;
468 default:
469 SkDEBUGFAIL("unknown segType");
470 sk_throw();
471 }
472 }
473 467
474 //////////////////////////////////////////////////////////////////////////////// 468 ////////////////////////////////////////////////////////////////////////////////
475 //////////////////////////////////////////////////////////////////////////////// 469 ////////////////////////////////////////////////////////////////////////////////
476 470
477 SkPathMeasure::SkPathMeasure() { 471 SkPathMeasure::SkPathMeasure() {
478 fPath = nullptr; 472 fPath = nullptr;
479 fTolerance = CHEAP_DIST_LIMIT; 473 fTolerance = CHEAP_DIST_LIMIT;
480 fLength = -1; // signal we need to compute it 474 fLength = -1; // signal we need to compute it
481 fForceClosed = false; 475 fForceClosed = false;
482 fFirstPtIndex = -1; 476 fFirstPtIndex = -1;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 const Segment* seg = this->distanceToSegment(startD, &startT); 654 const Segment* seg = this->distanceToSegment(startD, &startT);
661 const Segment* stopSeg = this->distanceToSegment(stopD, &stopT); 655 const Segment* stopSeg = this->distanceToSegment(stopD, &stopT);
662 SkASSERT(seg <= stopSeg); 656 SkASSERT(seg <= stopSeg);
663 657
664 if (startWithMoveTo) { 658 if (startWithMoveTo) {
665 compute_pos_tan(&fPts[seg->fPtIndex], seg->fType, startT, &p, nullptr); 659 compute_pos_tan(&fPts[seg->fPtIndex], seg->fType, startT, &p, nullptr);
666 dst->moveTo(p); 660 dst->moveTo(p);
667 } 661 }
668 662
669 if (seg->fPtIndex == stopSeg->fPtIndex) { 663 if (seg->fPtIndex == stopSeg->fPtIndex) {
670 seg_to(&fPts[seg->fPtIndex], seg->fType, startT, stopT, dst); 664 SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, startT, stopT, dst );
671 } else { 665 } else {
672 do { 666 do {
673 seg_to(&fPts[seg->fPtIndex], seg->fType, startT, SK_Scalar1, dst); 667 SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, startT, SK_Sca lar1, dst);
674 seg = SkPathMeasure::NextSegment(seg); 668 seg = SkPathMeasure::NextSegment(seg);
675 startT = 0; 669 startT = 0;
676 } while (seg->fPtIndex < stopSeg->fPtIndex); 670 } while (seg->fPtIndex < stopSeg->fPtIndex);
677 seg_to(&fPts[seg->fPtIndex], seg->fType, 0, stopT, dst); 671 SkPathMeasure_segTo(&fPts[seg->fPtIndex], seg->fType, 0, stopT, dst);
678 } 672 }
679 return true; 673 return true;
680 } 674 }
681 675
682 bool SkPathMeasure::isClosed() { 676 bool SkPathMeasure::isClosed() {
683 (void)this->getLength(); 677 (void)this->getLength();
684 return fIsClosed; 678 return fIsClosed;
685 } 679 }
686 680
687 /** Move to the next contour in the path. Return true if one exists, or false if 681 /** Move to the next contour in the path. Return true if one exists, or false if
(...skipping 14 matching lines...) Expand all
702 696
703 for (int i = 0; i < fSegments.count(); i++) { 697 for (int i = 0; i < fSegments.count(); i++) {
704 const Segment* seg = &fSegments[i]; 698 const Segment* seg = &fSegments[i];
705 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n", 699 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n",
706 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(), 700 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(),
707 seg->fType); 701 seg->fType);
708 } 702 }
709 } 703 }
710 704
711 #endif 705 #endif
OLDNEW
« no previous file with comments | « include/core/SkPathMeasure.h ('k') | src/core/SkPathMeasurePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698