OLD | NEW |
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 #include "SkOpContour.h" | 7 #include "SkOpContour.h" |
| 8 #include "SkOpSegment.h" |
8 #include "SkPath.h" | 9 #include "SkPath.h" |
9 | 10 |
10 #ifdef SK_DEBUG | 11 #ifdef SK_DEBUG |
11 #include "SkPathOpsPoint.h" | 12 #include "SkPathOpsPoint.h" |
12 #endif | 13 #endif |
13 | 14 |
14 class SkIntersectionHelper { | 15 class SkIntersectionHelper { |
15 public: | 16 public: |
16 enum SegmentType { | 17 enum SegmentType { |
17 kHorizontalLine_Segment = -1, | 18 kHorizontalLine_Segment = -1, |
18 kVerticalLine_Segment = 0, | 19 kVerticalLine_Segment = 0, |
19 kLine_Segment = SkPath::kLine_Verb, | 20 kLine_Segment = SkPath::kLine_Verb, |
20 kQuad_Segment = SkPath::kQuad_Verb, | 21 kQuad_Segment = SkPath::kQuad_Verb, |
21 kCubic_Segment = SkPath::kCubic_Verb, | 22 kCubic_Segment = SkPath::kCubic_Verb, |
22 }; | 23 }; |
23 | 24 |
24 bool addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, b
ool swap) { | |
25 return fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts,
swap); | |
26 } | |
27 | |
28 // FIXME: does it make sense to write otherIndex now if we're going to | |
29 // fix it up later? | |
30 void addOtherT(int index, double otherT, int otherIndex) { | |
31 fContour->addOtherT(fIndex, index, otherT, otherIndex); | |
32 } | |
33 | |
34 bool addPartialCoincident(SkIntersectionHelper& other, const SkIntersections
& ts, int index, | |
35 bool swap) { | |
36 return fContour->addPartialCoincident(fIndex, other.fContour, other.fInd
ex, ts, index, | |
37 swap); | |
38 } | |
39 | |
40 // Avoid collapsing t values that are close to the same since | |
41 // we walk ts to describe consecutive intersections. Since a pair of ts can | |
42 // be nearly equal, any problems caused by this should be taken care | |
43 // of later. | |
44 // On the edge or out of range values are negative; add 2 to get end | |
45 int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT)
{ | |
46 return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT); | |
47 } | |
48 | |
49 int addSelfT(const SkPoint& pt, double newT) { | |
50 return fContour->addSelfT(fIndex, pt, newT); | |
51 } | |
52 | |
53 bool advance() { | 25 bool advance() { |
54 return ++fIndex < fLast; | 26 fSegment = fSegment->next(); |
55 } | 27 return fSegment != NULL; |
56 | |
57 void alignTPt(SkIntersectionHelper& other, bool swap, int index, | |
58 SkIntersections* ts, SkPoint* point) { | |
59 fContour->alignTPt(fIndex, other.fContour, other.fIndex, swap, index, ts
, point); | |
60 } | 28 } |
61 | 29 |
62 SkScalar bottom() const { | 30 SkScalar bottom() const { |
63 return bounds().fBottom; | 31 return bounds().fBottom; |
64 } | 32 } |
65 | 33 |
66 const SkPathOpsBounds& bounds() const { | 34 const SkPathOpsBounds& bounds() const { |
67 return fContour->segments()[fIndex].bounds(); | 35 return fSegment->bounds(); |
| 36 } |
| 37 |
| 38 SkOpContour* contour() const { |
| 39 return fSegment->contour(); |
68 } | 40 } |
69 | 41 |
70 void init(SkOpContour* contour) { | 42 void init(SkOpContour* contour) { |
71 fContour = contour; | 43 fSegment = contour->first(); |
72 fIndex = 0; | |
73 fLast = contour->segments().count(); | |
74 } | |
75 | |
76 bool isAdjacent(const SkIntersectionHelper& next) { | |
77 return fContour == next.fContour && fIndex + 1 == next.fIndex; | |
78 } | |
79 | |
80 bool isFirstLast(const SkIntersectionHelper& next) { | |
81 return fContour == next.fContour && fIndex == 0 | |
82 && next.fIndex == fLast - 1; | |
83 } | |
84 | |
85 bool isPartial(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt
2) const { | |
86 const SkOpSegment& segment = fContour->segments()[fIndex]; | |
87 double mid = (t1 + t2) / 2; | |
88 SkDPoint midPtByT = segment.dPtAtT(mid); | |
89 SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2); | |
90 return midPtByT.approximatelyPEqual(midPtByAvg); | |
91 } | 44 } |
92 | 45 |
93 SkScalar left() const { | 46 SkScalar left() const { |
94 return bounds().fLeft; | 47 return bounds().fLeft; |
95 } | 48 } |
96 | 49 |
97 const SkPoint* pts() const { | 50 const SkPoint* pts() const { |
98 return fContour->segments()[fIndex].pts(); | 51 return fSegment->pts(); |
99 } | 52 } |
100 | 53 |
101 SkScalar right() const { | 54 SkScalar right() const { |
102 return bounds().fRight; | 55 return bounds().fRight; |
103 } | 56 } |
104 | 57 |
| 58 SkOpSegment* segment() const { |
| 59 return fSegment; |
| 60 } |
| 61 |
105 SegmentType segmentType() const { | 62 SegmentType segmentType() const { |
106 const SkOpSegment& segment = fContour->segments()[fIndex]; | 63 SegmentType type = (SegmentType) fSegment->verb(); |
107 SegmentType type = (SegmentType) segment.verb(); | |
108 if (type != kLine_Segment) { | 64 if (type != kLine_Segment) { |
109 return type; | 65 return type; |
110 } | 66 } |
111 if (segment.isHorizontal()) { | 67 if (fSegment->isHorizontal()) { |
112 return kHorizontalLine_Segment; | 68 return kHorizontalLine_Segment; |
113 } | 69 } |
114 if (segment.isVertical()) { | 70 if (fSegment->isVertical()) { |
115 return kVerticalLine_Segment; | 71 return kVerticalLine_Segment; |
116 } | 72 } |
117 return kLine_Segment; | 73 return kLine_Segment; |
118 } | 74 } |
119 | 75 |
120 bool startAfter(const SkIntersectionHelper& after) { | 76 bool startAfter(const SkIntersectionHelper& after) { |
121 fIndex = after.fIndex; | 77 fSegment = after.fSegment->next(); |
122 return advance(); | 78 return fSegment != NULL; |
123 } | 79 } |
124 | 80 |
125 SkScalar top() const { | 81 SkScalar top() const { |
126 return bounds().fTop; | 82 return bounds().fTop; |
127 } | 83 } |
128 | 84 |
129 SkPath::Verb verb() const { | |
130 return fContour->segments()[fIndex].verb(); | |
131 } | |
132 | |
133 SkScalar x() const { | 85 SkScalar x() const { |
134 return bounds().fLeft; | 86 return bounds().fLeft; |
135 } | 87 } |
136 | 88 |
137 bool xFlipped() const { | 89 bool xFlipped() const { |
138 return x() != pts()[0].fX; | 90 return x() != pts()[0].fX; |
139 } | 91 } |
140 | 92 |
141 SkScalar y() const { | 93 SkScalar y() const { |
142 return bounds().fTop; | 94 return bounds().fTop; |
143 } | 95 } |
144 | 96 |
145 bool yFlipped() const { | 97 bool yFlipped() const { |
146 return y() != pts()[0].fY; | 98 return y() != pts()[0].fY; |
147 } | 99 } |
148 | 100 |
149 private: | 101 private: |
150 // utility callable by the user from the debugger when the implementation co
de is linked in | 102 SkOpSegment* fSegment; |
151 void dump() const; | |
152 | |
153 SkOpContour* fContour; | |
154 int fIndex; | |
155 int fLast; | |
156 }; | 103 }; |
OLD | NEW |