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 SkPoint& pt, double newT) { 50 return fContour->addSelfT(fIndex, pt, newT); 51 } 52 53 bool advance() { 54 return ++fIndex < fLast; 55 } 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 } 61 62 SkScalar bottom() const { 63 return bounds().fBottom; 64 } 65 66 const SkPathOpsBounds& bounds() const { 67 return fContour->segments()[fIndex].bounds(); 68 } 69 70 void init(SkOpContour* contour) { 71 fContour = contour; 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& pt2) 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 } 92 93 SkScalar left() const { 94 return bounds().fLeft; 95 } 96 97 const SkPoint* pts() const { 98 return fContour->segments()[fIndex].pts(); 99 } 100 101 SkScalar right() const { 102 return bounds().fRight; 103 } 104 105 SegmentType segmentType() const { 106 const SkOpSegment& segment = fContour->segments()[fIndex]; 107 SegmentType type = (SegmentType) segment.verb(); 108 if (type != kLine_Segment) { 109 return type; 110 } 111 if (segment.isHorizontal()) { 112 return kHorizontalLine_Segment; 113 } 114 if (segment.isVertical()) { 115 return kVerticalLine_Segment; 116 } 117 return kLine_Segment; 118 } 119 120 bool startAfter(const SkIntersectionHelper& after) { 121 fIndex = after.fIndex; 122 return advance(); 123 } 124 125 SkScalar top() const { 126 return bounds().fTop; 127 } 128 129 SkPath::Verb verb() const { 130 return fContour->segments()[fIndex].verb(); 131 } 132 133 SkScalar x() const { 134 return bounds().fLeft; 135 } 136 137 bool xFlipped() const { 138 return x() != pts()[0].fX; 139 } 140 141 SkScalar y() const { 142 return bounds().fTop; 143 } 144 145 bool yFlipped() const { 146 return y() != pts()[0].fY; 147 } 148 149 private: 150 // utility callable by the user from the debugger when the implementation code is linked in 151 void dump() const; 152 153 SkOpContour* fContour; 154 int fIndex; 155 int fLast; 156 }; 157