blob: af246b760ebfa2cd22b7462efd70cfe02bb3e902 [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +00001/*
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
10class SkIntersectionHelper {
11public:
12 enum SegmentType {
13 kHorizontalLine_Segment = -1,
14 kVerticalLine_Segment = 0,
15 kLine_Segment = SkPath::kLine_Verb,
16 kQuad_Segment = SkPath::kQuad_Verb,
17 kCubic_Segment = SkPath::kCubic_Verb,
18 };
19
20 void addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) {
21 fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap);
22 }
23
24 // FIXME: does it make sense to write otherIndex now if we're going to
25 // fix it up later?
26 void addOtherT(int index, double otherT, int otherIndex) {
27 fContour->addOtherT(fIndex, index, otherT, otherIndex);
28 }
29
caryclark@google.com570863f2013-09-16 15:55:01 +000030 void addPartialCoincident(SkIntersectionHelper& other, const SkIntersections& ts, int index,
31 bool swap) {
32 fContour->addPartialCoincident(fIndex, other.fContour, other.fIndex, ts, index, swap);
33 }
34
caryclark@google.com07393ca2013-04-08 11:47:37 +000035 // Avoid collapsing t values that are close to the same since
36 // we walk ts to describe consecutive intersections. Since a pair of ts can
37 // be nearly equal, any problems caused by this should be taken care
38 // of later.
39 // On the edge or out of range values are negative; add 2 to get end
caryclark@google.com570863f2013-09-16 15:55:01 +000040 int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT, bool isNear) {
41 return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT, isNear);
caryclark@google.com07393ca2013-04-08 11:47:37 +000042 }
43
44 int addSelfT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) {
45 return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT);
46 }
47
caryclark@google.com07393ca2013-04-08 11:47:37 +000048 bool advance() {
49 return ++fIndex < fLast;
50 }
51
52 SkScalar bottom() const {
53 return bounds().fBottom;
54 }
55
56 const SkPathOpsBounds& bounds() const {
57 return fContour->segments()[fIndex].bounds();
58 }
59
60 void init(SkOpContour* contour) {
61 fContour = contour;
62 fIndex = 0;
63 fLast = contour->segments().count();
64 }
65
66 bool isAdjacent(const SkIntersectionHelper& next) {
67 return fContour == next.fContour && fIndex + 1 == next.fIndex;
68 }
69
70 bool isFirstLast(const SkIntersectionHelper& next) {
71 return fContour == next.fContour && fIndex == 0
72 && next.fIndex == fLast - 1;
73 }
74
caryclark@google.com570863f2013-09-16 15:55:01 +000075 bool isNear(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt2) const {
76 const SkOpSegment& segment = fContour->segments()[fIndex];
77 double mid = (t1 + t2) / 2;
78 SkDPoint midPtByT = segment.dPtAtT(mid);
79 SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2);
80 return midPtByT.approximatelyEqualHalf(midPtByAvg);
81 }
82
caryclark@google.com07393ca2013-04-08 11:47:37 +000083 SkScalar left() const {
84 return bounds().fLeft;
85 }
86
87 const SkPoint* pts() const {
88 return fContour->segments()[fIndex].pts();
89 }
90
91 SkScalar right() const {
92 return bounds().fRight;
93 }
94
95 SegmentType segmentType() const {
96 const SkOpSegment& segment = fContour->segments()[fIndex];
97 SegmentType type = (SegmentType) segment.verb();
98 if (type != kLine_Segment) {
99 return type;
100 }
101 if (segment.isHorizontal()) {
102 return kHorizontalLine_Segment;
103 }
104 if (segment.isVertical()) {
105 return kVerticalLine_Segment;
106 }
107 return kLine_Segment;
108 }
109
110 bool startAfter(const SkIntersectionHelper& after) {
111 fIndex = after.fIndex;
112 return advance();
113 }
114
115 SkScalar top() const {
116 return bounds().fTop;
117 }
118
119 SkPath::Verb verb() const {
120 return fContour->segments()[fIndex].verb();
121 }
122
123 SkScalar x() const {
124 return bounds().fLeft;
125 }
126
127 bool xFlipped() const {
128 return x() != pts()[0].fX;
129 }
130
131 SkScalar y() const {
132 return bounds().fTop;
133 }
134
135 bool yFlipped() const {
136 return y() != pts()[0].fY;
137 }
138
139private:
140 SkOpContour* fContour;
141 int fIndex;
142 int fLast;
143};