1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/pathops/SkIntersectionHelper.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,161 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 +#include "SkOpContour.h" 1.11 +#include "SkPath.h" 1.12 + 1.13 +#ifdef SK_DEBUG 1.14 +#include "SkPathOpsPoint.h" 1.15 +#endif 1.16 + 1.17 +class SkIntersectionHelper { 1.18 +public: 1.19 + enum SegmentType { 1.20 + kHorizontalLine_Segment = -1, 1.21 + kVerticalLine_Segment = 0, 1.22 + kLine_Segment = SkPath::kLine_Verb, 1.23 + kQuad_Segment = SkPath::kQuad_Verb, 1.24 + kCubic_Segment = SkPath::kCubic_Verb, 1.25 + }; 1.26 + 1.27 + bool addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) { 1.28 + return fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap); 1.29 + } 1.30 + 1.31 + // FIXME: does it make sense to write otherIndex now if we're going to 1.32 + // fix it up later? 1.33 + void addOtherT(int index, double otherT, int otherIndex) { 1.34 + fContour->addOtherT(fIndex, index, otherT, otherIndex); 1.35 + } 1.36 + 1.37 + bool addPartialCoincident(SkIntersectionHelper& other, const SkIntersections& ts, int index, 1.38 + bool swap) { 1.39 + return fContour->addPartialCoincident(fIndex, other.fContour, other.fIndex, ts, index, 1.40 + swap); 1.41 + } 1.42 + 1.43 + // Avoid collapsing t values that are close to the same since 1.44 + // we walk ts to describe consecutive intersections. Since a pair of ts can 1.45 + // be nearly equal, any problems caused by this should be taken care 1.46 + // of later. 1.47 + // On the edge or out of range values are negative; add 2 to get end 1.48 + int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) { 1.49 + return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT); 1.50 + } 1.51 + 1.52 + int addSelfT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) { 1.53 + return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT); 1.54 + } 1.55 + 1.56 + bool advance() { 1.57 + return ++fIndex < fLast; 1.58 + } 1.59 + 1.60 + SkScalar bottom() const { 1.61 + return bounds().fBottom; 1.62 + } 1.63 + 1.64 + const SkPathOpsBounds& bounds() const { 1.65 + return fContour->segments()[fIndex].bounds(); 1.66 + } 1.67 + 1.68 + void init(SkOpContour* contour) { 1.69 + fContour = contour; 1.70 + fIndex = 0; 1.71 + fLast = contour->segments().count(); 1.72 + } 1.73 + 1.74 + bool isAdjacent(const SkIntersectionHelper& next) { 1.75 + return fContour == next.fContour && fIndex + 1 == next.fIndex; 1.76 + } 1.77 + 1.78 + bool isFirstLast(const SkIntersectionHelper& next) { 1.79 + return fContour == next.fContour && fIndex == 0 1.80 + && next.fIndex == fLast - 1; 1.81 + } 1.82 + 1.83 + bool isPartial(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt2) const { 1.84 + const SkOpSegment& segment = fContour->segments()[fIndex]; 1.85 + double mid = (t1 + t2) / 2; 1.86 + SkDPoint midPtByT = segment.dPtAtT(mid); 1.87 + SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2); 1.88 + return midPtByT.approximatelyPEqual(midPtByAvg); 1.89 + } 1.90 + 1.91 + SkScalar left() const { 1.92 + return bounds().fLeft; 1.93 + } 1.94 + 1.95 + const SkPoint* pts() const { 1.96 + return fContour->segments()[fIndex].pts(); 1.97 + } 1.98 + 1.99 + SkScalar right() const { 1.100 + return bounds().fRight; 1.101 + } 1.102 + 1.103 + SegmentType segmentType() const { 1.104 + const SkOpSegment& segment = fContour->segments()[fIndex]; 1.105 + SegmentType type = (SegmentType) segment.verb(); 1.106 + if (type != kLine_Segment) { 1.107 + return type; 1.108 + } 1.109 + if (segment.isHorizontal()) { 1.110 + return kHorizontalLine_Segment; 1.111 + } 1.112 + if (segment.isVertical()) { 1.113 + return kVerticalLine_Segment; 1.114 + } 1.115 + return kLine_Segment; 1.116 + } 1.117 + 1.118 + bool startAfter(const SkIntersectionHelper& after) { 1.119 + fIndex = after.fIndex; 1.120 + return advance(); 1.121 + } 1.122 + 1.123 + SkScalar top() const { 1.124 + return bounds().fTop; 1.125 + } 1.126 + 1.127 + SkPath::Verb verb() const { 1.128 + return fContour->segments()[fIndex].verb(); 1.129 + } 1.130 + 1.131 + SkScalar x() const { 1.132 + return bounds().fLeft; 1.133 + } 1.134 + 1.135 + bool xFlipped() const { 1.136 + return x() != pts()[0].fX; 1.137 + } 1.138 + 1.139 + SkScalar y() const { 1.140 + return bounds().fTop; 1.141 + } 1.142 + 1.143 + bool yFlipped() const { 1.144 + return y() != pts()[0].fY; 1.145 + } 1.146 + 1.147 +#ifdef SK_DEBUG 1.148 + void dump() { 1.149 + SkDPoint::dump(pts()[0]); 1.150 + SkDPoint::dump(pts()[1]); 1.151 + if (verb() >= SkPath::kQuad_Verb) { 1.152 + SkDPoint::dump(pts()[2]); 1.153 + } 1.154 + if (verb() >= SkPath::kCubic_Verb) { 1.155 + SkDPoint::dump(pts()[3]); 1.156 + } 1.157 + } 1.158 +#endif 1.159 + 1.160 +private: 1.161 + SkOpContour* fContour; 1.162 + int fIndex; 1.163 + int fLast; 1.164 +};