Index: src/pathops/SkIntersectionHelper.h |
=================================================================== |
--- src/pathops/SkIntersectionHelper.h (revision 0) |
+++ src/pathops/SkIntersectionHelper.h (revision 0) |
@@ -0,0 +1,139 @@ |
+/* |
+ * Copyright 2012 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+#include "SkOpContour.h" |
+#include "SkPath.h" |
+ |
+class SkIntersectionHelper { |
+public: |
+ enum SegmentType { |
+ kHorizontalLine_Segment = -1, |
+ kVerticalLine_Segment = 0, |
+ kLine_Segment = SkPath::kLine_Verb, |
+ kQuad_Segment = SkPath::kQuad_Verb, |
+ kCubic_Segment = SkPath::kCubic_Verb, |
+ }; |
+ |
+ void addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) { |
+ fContour->addCoincident(fIndex, other.fContour, other.fIndex, ts, swap); |
+ } |
+ |
+ // FIXME: does it make sense to write otherIndex now if we're going to |
+ // fix it up later? |
+ void addOtherT(int index, double otherT, int otherIndex) { |
+ fContour->addOtherT(fIndex, index, otherT, otherIndex); |
+ } |
+ |
+ // Avoid collapsing t values that are close to the same since |
+ // we walk ts to describe consecutive intersections. Since a pair of ts can |
+ // be nearly equal, any problems caused by this should be taken care |
+ // of later. |
+ // On the edge or out of range values are negative; add 2 to get end |
+ int addT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) { |
+ return fContour->addT(fIndex, other.fContour, other.fIndex, pt, newT); |
+ } |
+ |
+ int addSelfT(const SkIntersectionHelper& other, const SkPoint& pt, double newT) { |
+ return fContour->addSelfT(fIndex, other.fContour, other.fIndex, pt, newT); |
+ } |
+ |
+ int addUnsortableT(const SkIntersectionHelper& other, bool start, const SkPoint& pt, |
+ double newT) { |
+ return fContour->addUnsortableT(fIndex, other.fContour, other.fIndex, start, pt, newT); |
+ } |
+ |
+ bool advance() { |
+ return ++fIndex < fLast; |
+ } |
+ |
+ SkScalar bottom() const { |
+ return bounds().fBottom; |
+ } |
+ |
+ const SkPathOpsBounds& bounds() const { |
+ return fContour->segments()[fIndex].bounds(); |
+ } |
+ |
+ void init(SkOpContour* contour) { |
+ fContour = contour; |
+ fIndex = 0; |
+ fLast = contour->segments().count(); |
+ } |
+ |
+ bool isAdjacent(const SkIntersectionHelper& next) { |
+ return fContour == next.fContour && fIndex + 1 == next.fIndex; |
+ } |
+ |
+ bool isFirstLast(const SkIntersectionHelper& next) { |
+ return fContour == next.fContour && fIndex == 0 |
+ && next.fIndex == fLast - 1; |
+ } |
+ |
+ SkScalar left() const { |
+ return bounds().fLeft; |
+ } |
+ |
+ const SkPoint* pts() const { |
+ return fContour->segments()[fIndex].pts(); |
+ } |
+ |
+ SkScalar right() const { |
+ return bounds().fRight; |
+ } |
+ |
+ ptrdiff_t segmentIndex() const { |
+ return fIndex; |
+ } |
+ |
+ SegmentType segmentType() const { |
+ const SkOpSegment& segment = fContour->segments()[fIndex]; |
+ SegmentType type = (SegmentType) segment.verb(); |
+ if (type != kLine_Segment) { |
+ return type; |
+ } |
+ if (segment.isHorizontal()) { |
+ return kHorizontalLine_Segment; |
+ } |
+ if (segment.isVertical()) { |
+ return kVerticalLine_Segment; |
+ } |
+ return kLine_Segment; |
+ } |
+ |
+ bool startAfter(const SkIntersectionHelper& after) { |
+ fIndex = after.fIndex; |
+ return advance(); |
+ } |
+ |
+ SkScalar top() const { |
+ return bounds().fTop; |
+ } |
+ |
+ SkPath::Verb verb() const { |
+ return fContour->segments()[fIndex].verb(); |
+ } |
+ |
+ SkScalar x() const { |
+ return bounds().fLeft; |
+ } |
+ |
+ bool xFlipped() const { |
+ return x() != pts()[0].fX; |
+ } |
+ |
+ SkScalar y() const { |
+ return bounds().fTop; |
+ } |
+ |
+ bool yFlipped() const { |
+ return y() != pts()[0].fY; |
+ } |
+ |
+private: |
+ SkOpContour* fContour; |
+ int fIndex; |
+ int fLast; |
+}; |