diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/pathops/SkIntersectionHelper.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/pathops/SkIntersectionHelper.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,161 @@ +/* + * 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" + +#ifdef SK_DEBUG +#include "SkPathOpsPoint.h" +#endif + +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, + }; + + bool addCoincident(SkIntersectionHelper& other, const SkIntersections& ts, bool swap) { + return 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); + } + + bool addPartialCoincident(SkIntersectionHelper& other, const SkIntersections& ts, int index, + bool swap) { + return fContour->addPartialCoincident(fIndex, other.fContour, other.fIndex, ts, index, + swap); + } + + // 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); + } + + 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; + } + + bool isPartial(double t1, double t2, const SkDPoint& pt1, const SkDPoint& pt2) const { + const SkOpSegment& segment = fContour->segments()[fIndex]; + double mid = (t1 + t2) / 2; + SkDPoint midPtByT = segment.dPtAtT(mid); + SkDPoint midPtByAvg = SkDPoint::Mid(pt1, pt2); + return midPtByT.approximatelyPEqual(midPtByAvg); + } + + SkScalar left() const { + return bounds().fLeft; + } + + const SkPoint* pts() const { + return fContour->segments()[fIndex].pts(); + } + + SkScalar right() const { + return bounds().fRight; + } + + 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; + } + +#ifdef SK_DEBUG + void dump() { + SkDPoint::dump(pts()[0]); + SkDPoint::dump(pts()[1]); + if (verb() >= SkPath::kQuad_Verb) { + SkDPoint::dump(pts()[2]); + } + if (verb() >= SkPath::kCubic_Verb) { + SkDPoint::dump(pts()[3]); + } + } +#endif + +private: + SkOpContour* fContour; + int fIndex; + int fLast; +};