| Index: src/pathops/SkPathOpsCubicSect.h
|
| diff --git a/src/pathops/SkPathOpsCubicSect.h b/src/pathops/SkPathOpsCubicSect.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d7634449b6ce2031d4bbf66bba083f4c6c253381
|
| --- /dev/null
|
| +++ b/src/pathops/SkPathOpsCubicSect.h
|
| @@ -0,0 +1,175 @@
|
| +/*
|
| + * Copyright 2014 Google Inc.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +#ifndef SkCubicSpan_DEFINE
|
| +#define SkCubicSpan_DEFINE
|
| +
|
| +#include "SkChunkAlloc.h"
|
| +#include "SkPathOpsRect.h"
|
| +#include "SkPathOpsCubic.h"
|
| +#include "SkTArray.h"
|
| +
|
| +class SkIntersections;
|
| +
|
| +class SkCubicCoincident {
|
| +public:
|
| + bool isCoincident() const {
|
| + return fCoincident;
|
| + }
|
| +
|
| + void init() {
|
| + fCoincident = false;
|
| + SkDEBUGCODE(fPerpPt.fX = fPerpPt.fY = SK_ScalarNaN);
|
| + SkDEBUGCODE(fPerpT = SK_ScalarNaN);
|
| + }
|
| +
|
| + void markCoincident() {
|
| + if (!fCoincident) {
|
| + fPerpT = -1;
|
| + }
|
| + fCoincident = true;
|
| + }
|
| +
|
| + const SkDPoint& perpPt() const {
|
| + return fPerpPt;
|
| + }
|
| +
|
| + double perpT() const {
|
| + return fPerpT;
|
| + }
|
| +
|
| + void setPerp(const SkDCubic& cubic1, double t, const SkDPoint& qPt, const SkDCubic& cubic2);
|
| +
|
| +private:
|
| + SkDPoint fPerpPt;
|
| + double fPerpT; // perpendicular intersection on opposite Cubic
|
| + bool fCoincident;
|
| +};
|
| +
|
| +class SkCubicSect; // used only by debug id
|
| +
|
| +class SkCubicSpan {
|
| +public:
|
| + void init(const SkDCubic& Cubic);
|
| + void initBounds(const SkDCubic& Cubic);
|
| +
|
| + bool contains(double t) const {
|
| + return !! const_cast<SkCubicSpan*>(this)->innerFind(t);
|
| + }
|
| +
|
| + bool contains(const SkCubicSpan* span) const;
|
| +
|
| + SkCubicSpan* find(double t) {
|
| + SkCubicSpan* result = innerFind(t);
|
| + SkASSERT(result);
|
| + return result;
|
| + }
|
| +
|
| + bool intersects(const SkCubicSpan* span) const;
|
| +
|
| + const SkCubicSpan* next() const {
|
| + return fNext;
|
| + }
|
| +
|
| + void reset() {
|
| + fBounded.reset();
|
| + }
|
| +
|
| + bool split(SkCubicSpan* work) {
|
| + return splitAt(work, (work->fStartT + work->fEndT) * 0.5);
|
| + }
|
| +
|
| + bool splitAt(SkCubicSpan* work, double t);
|
| + bool tightBoundsIntersects(const SkCubicSpan* span) const;
|
| +
|
| + // implementation is for testing only
|
| + void dump() const;
|
| +
|
| +private:
|
| + bool hullIntersects(const SkDCubic& ) const;
|
| + SkCubicSpan* innerFind(double t);
|
| + bool linearIntersects(const SkDCubic& ) const;
|
| +
|
| + // implementation is for testing only
|
| +#if DEBUG_BINARY_CUBIC
|
| + int debugID(const SkCubicSect* ) const { return fDebugID; }
|
| +#else
|
| + int debugID(const SkCubicSect* ) const;
|
| +#endif
|
| + void dump(const SkCubicSect* ) const;
|
| + void dumpID(const SkCubicSect* ) const;
|
| +
|
| +#if DEBUG_BINARY_CUBIC
|
| + void validate() const;
|
| +#endif
|
| +
|
| + SkDCubic fPart;
|
| + SkCubicCoincident fCoinStart;
|
| + SkCubicCoincident fCoinEnd;
|
| + SkSTArray<4, SkCubicSpan*, true> fBounded;
|
| + SkCubicSpan* fPrev;
|
| + SkCubicSpan* fNext;
|
| + SkDRect fBounds;
|
| + double fStartT;
|
| + double fEndT;
|
| + double fBoundsMax;
|
| + bool fCollapsed;
|
| + bool fHasPerp;
|
| + mutable bool fIsLinear;
|
| +#if DEBUG_BINARY_CUBIC
|
| + int fDebugID;
|
| + bool fDebugDeleted;
|
| +#endif
|
| + friend class SkCubicSect;
|
| +};
|
| +
|
| +class SkCubicSect {
|
| +public:
|
| + SkCubicSect(const SkDCubic& Cubic PATH_OPS_DEBUG_PARAMS(int id));
|
| + static void BinarySearch(SkCubicSect* sect1, SkCubicSect* sect2, SkIntersections* intersections);
|
| +
|
| + // for testing only
|
| + void dumpCubics() const;
|
| +private:
|
| + SkCubicSpan* addOne();
|
| + bool binarySearchCoin(const SkCubicSect& , double tStart, double tStep, double* t,
|
| + double* oppT);
|
| + SkCubicSpan* boundsMax() const;
|
| + void coincidentCheck(SkCubicSect* sect2);
|
| + bool intersects(const SkCubicSpan* span, const SkCubicSect* opp, const SkCubicSpan* oppSpan) const;
|
| + void onCurveCheck(SkCubicSect* sect2, SkCubicSpan* first, SkCubicSpan* last);
|
| + void recoverCollapsed();
|
| + void removeSpan(SkCubicSpan* span);
|
| + void removeOne(const SkCubicSpan* test, SkCubicSpan* span);
|
| + void removeSpans(SkCubicSpan* span, SkCubicSect* opp);
|
| + void setPerp(const SkDCubic& opp, SkCubicSpan* first, SkCubicSpan* last);
|
| + void trim(SkCubicSpan* span, SkCubicSect* opp);
|
| +
|
| + // for testing only
|
| + void dump() const;
|
| + void dumpBoth(const SkCubicSect& opp) const;
|
| + void dumpBoth(const SkCubicSect* opp) const;
|
| +
|
| +#if DEBUG_BINARY_CUBIC
|
| + int debugID() const { return fDebugID; }
|
| + void validate() const;
|
| +#else
|
| + int debugID() const { return 0; }
|
| +#endif
|
| + const SkDCubic& fCubic;
|
| + SkChunkAlloc fHeap;
|
| + SkCubicSpan* fHead;
|
| + SkCubicSpan* fDeleted;
|
| + int fActiveCount;
|
| +#if DEBUG_BINARY_CUBIC
|
| + int fDebugID;
|
| + int fDebugCount;
|
| + int fDebugAllocatedCount;
|
| +#endif
|
| + friend class SkCubicSpan; // only used by debug id
|
| +};
|
| +
|
| +#endif
|
|
|