gfx/skia/trunk/src/pathops/SkIntersectionHelper.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:f7ba5afce950
1 /*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7 #include "SkOpContour.h"
8 #include "SkPath.h"
9
10 #ifdef SK_DEBUG
11 #include "SkPathOpsPoint.h"
12 #endif
13
14 class SkIntersectionHelper {
15 public:
16 enum SegmentType {
17 kHorizontalLine_Segment = -1,
18 kVerticalLine_Segment = 0,
19 kLine_Segment = SkPath::kLine_Verb,
20 kQuad_Segment = SkPath::kQuad_Verb,
21 kCubic_Segment = SkPath::kCubic_Verb,
22 };
23
24 bool addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool 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.fIndex, 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 SkIntersectionHelper& other, const SkPoint& pt, double newT) {
50 return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT);
51 }
52
53 bool advance() {
54 return ++fIndex < fLast;
55 }
56
57 SkScalar bottom() const {
58 return bounds().fBottom;
59 }
60
61 const SkPathOpsBounds& bounds() const {
62 return fContour->segments()[fIndex].bounds();
63 }
64
65 void init(SkOpContour* contour) {
66 fContour = contour;
67 fIndex = 0;
68 fLast = contour->segments().count();
69 }
70
71 bool isAdjacent(const SkIntersectionHelper& next) {
72 return fContour == next.fContour && fIndex + 1 == next.fIndex;
73 }
74
75 bool isFirstLast(const SkIntersectionHelper& next) {
76 return fContour == next.fContour && fIndex == 0
77 && next.fIndex == fLast - 1;
78 }
79
80 bool isPartial(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt2) const {
81 const SkOpSegment& segment = fContour->segments()[fIndex];
82 double mid = (t1 + t2) / 2;
83 SkDPoint midPtByT = segment.dPtAtT(mid);
84 SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2);
85 return midPtByT.approximatelyPEqual(midPtByAvg);
86 }
87
88 SkScalar left() const {
89 return bounds().fLeft;
90 }
91
92 const SkPoint* pts() const {
93 return fContour->segments()[fIndex].pts();
94 }
95
96 SkScalar right() const {
97 return bounds().fRight;
98 }
99
100 SegmentType segmentType() const {
101 const SkOpSegment& segment = fContour->segments()[fIndex];
102 SegmentType type = (SegmentType) segment.verb();
103 if (type != kLine_Segment) {
104 return type;
105 }
106 if (segment.isHorizontal()) {
107 return kHorizontalLine_Segment;
108 }
109 if (segment.isVertical()) {
110 return kVerticalLine_Segment;
111 }
112 return kLine_Segment;
113 }
114
115 bool startAfter(const SkIntersectionHelper& after) {
116 fIndex = after.fIndex;
117 return advance();
118 }
119
120 SkScalar top() const {
121 return bounds().fTop;
122 }
123
124 SkPath::Verb verb() const {
125 return fContour->segments()[fIndex].verb();
126 }
127
128 SkScalar x() const {
129 return bounds().fLeft;
130 }
131
132 bool xFlipped() const {
133 return x() != pts()[0].fX;
134 }
135
136 SkScalar y() const {
137 return bounds().fTop;
138 }
139
140 bool yFlipped() const {
141 return y() != pts()[0].fY;
142 }
143
144 #ifdef SK_DEBUG
145 void dump() {
146 SkDPoint::dump(pts()[0]);
147 SkDPoint::dump(pts()[1]);
148 if (verb() >= SkPath::kQuad_Verb) {
149 SkDPoint::dump(pts()[2]);
150 }
151 if (verb() >= SkPath::kCubic_Verb) {
152 SkDPoint::dump(pts()[3]);
153 }
154 }
155 #endif
156
157 private:
158 SkOpContour* fContour;
159 int fIndex;
160 int fLast;
161 };

mercurial