blob: 098c4701287861f79f0881a20e78635396d90973 [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +00001/*
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#ifndef SkOpAngle_DEFINED
8#define SkOpAngle_DEFINED
9
caryclarkdac1d172014-06-17 05:15:38 -070010#include "SkChunkAlloc.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000011#include "SkLineParameters.h"
caryclark@google.comcffbcc32013-06-04 17:59:42 +000012
13class SkOpSegment;
caryclark@google.com570863f2013-09-16 15:55:01 +000014struct SkOpSpan;
caryclark@google.com07393ca2013-04-08 11:47:37 +000015
16// sorting angles
17// given angles of {dx dy ddx ddy dddx dddy} sort them
18class SkOpAngle {
19public:
caryclark@google.comd892bd82013-06-17 14:10:36 +000020 enum { kStackBasedCount = 8 }; // FIXME: determine what this should be
caryclark@google.com570863f2013-09-16 15:55:01 +000021 enum IncludeType {
22 kUnaryWinding,
23 kUnaryXor,
24 kBinarySingle,
25 kBinaryOpp,
26 };
caryclark@google.comd892bd82013-06-17 14:10:36 +000027
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +000028
caryclark@google.com07393ca2013-04-08 11:47:37 +000029 int end() const {
30 return fEnd;
31 }
32
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000033 const SkOpAngle* findFirst() const;
caryclark@google.com07393ca2013-04-08 11:47:37 +000034
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000035 bool inLoop() const {
36 return !!fNext;
caryclark@google.com570863f2013-09-16 15:55:01 +000037 }
38
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000039 void insert(SkOpAngle* );
40 bool isHorizontal() const;
41 SkOpSpan* lastMarked() const;
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +000042 bool loopContains(const SkOpAngle& ) const;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000043 int loopCount() const;
44 void markStops();
45 bool merge(SkOpAngle* );
46
47 SkOpAngle* next() const {
48 return fNext;
49 }
50
51 SkOpAngle* previous() const;
52
caryclark@google.comcffbcc32013-06-04 17:59:42 +000053 void set(const SkOpSegment* segment, int start, int end);
caryclark@google.comad65a3e2013-04-15 19:13:59 +000054
caryclark@google.com570863f2013-09-16 15:55:01 +000055 void setLastMarked(SkOpSpan* marked) {
56 fLastMarked = marked;
57 }
58
caryclark@google.com07393ca2013-04-08 11:47:37 +000059 SkOpSegment* segment() const {
60 return const_cast<SkOpSegment*>(fSegment);
61 }
62
63 int sign() const {
64 return SkSign32(fStart - fEnd);
65 }
66
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000067 bool small() const;
68
caryclark@google.com07393ca2013-04-08 11:47:37 +000069 int start() const {
70 return fStart;
71 }
72
caryclark@google.comcffbcc32013-06-04 17:59:42 +000073 bool unorderable() const {
74 return fUnorderable;
75 }
76
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000077 // available to testing only
78#if DEBUG_SORT
79 void debugLoop() const; // called by code during run
caryclark@google.com570863f2013-09-16 15:55:01 +000080#endif
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000081#if DEBUG_ANGLE
82 void debugSameAs(const SkOpAngle* compare) const;
83#endif
84 void dump() const;
caryclarkdac1d172014-06-17 05:15:38 -070085 void dumpLoop() const;
86 void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;
caryclark@google.comcffbcc32013-06-04 17:59:42 +000087
caryclark@google.com570863f2013-09-16 15:55:01 +000088#if DEBUG_ANGLE
caryclarkdac1d172014-06-17 05:15:38 -070089 int debugID() const { return fID; }
90
caryclark@google.comcffbcc32013-06-04 17:59:42 +000091 void setID(int id) {
92 fID = id;
93 }
caryclarkdac1d172014-06-17 05:15:38 -070094#else
95 int debugID() const { return 0; }
caryclark@google.com07393ca2013-04-08 11:47:37 +000096#endif
caryclarkdac1d172014-06-17 05:15:38 -070097
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000098#if DEBUG_VALIDATE
99 void debugValidateLoop() const;
100#endif
caryclark@google.com07393ca2013-04-08 11:47:37 +0000101
102private:
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000103 bool after(const SkOpAngle* test) const;
104 int allOnOneSide(const SkOpAngle& test) const;
105 bool calcSlop(double x, double y, double rx, double ry, bool* result) const;
106 bool checkCrossesZero() const;
107 bool checkParallel(const SkOpAngle& ) const;
108 bool computeSector();
109 int convexHullOverlaps(const SkOpAngle& ) const;
110 double distEndRatio(double dist) const;
111 int findSector(SkPath::Verb verb, double x, double y) const;
112 bool endsIntersect(const SkOpAngle& ) const;
113 double midT() const;
114 bool oppositePlanes(const SkOpAngle& rh) const;
115 bool orderable(const SkOpAngle& rh) const; // false == this < rh ; true == this > rh
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000116 bool overlap(const SkOpAngle& test) const;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000117 void setCurveHullSweep();
118 void setSector();
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000119 void setSpans();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000120 bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const;
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000121
caryclark@google.com570863f2013-09-16 15:55:01 +0000122 SkDCubic fCurvePart; // the curve from start to end
caryclark@google.com07393ca2013-04-08 11:47:37 +0000123 double fSide;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000124 SkLineParameters fTangentHalf; // used only to sort a pair of lines or line-like sections
caryclark@google.com07393ca2013-04-08 11:47:37 +0000125 const SkOpSegment* fSegment;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000126 SkOpAngle* fNext;
caryclark@google.com570863f2013-09-16 15:55:01 +0000127 SkOpSpan* fLastMarked;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000128 SkDVector fSweep[2];
caryclark@google.com07393ca2013-04-08 11:47:37 +0000129 int fStart;
130 int fEnd;
caryclarkdac1d172014-06-17 05:15:38 -0700131 int fComputedEnd;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000132 int fSectorMask;
commit-bot@chromium.org86084632014-04-14 18:33:03 +0000133 int8_t fSectorStart; // in 32nds of a circle
134 int8_t fSectorEnd;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000135 bool fIsCurve;
136 bool fStop; // set if ordered angle is greater than the previous
137 mutable bool fUnorderable; // this is editable by orderable()
138 bool fUnorderedSweep; // set when a cubic's first control point between the sweep vectors
139 bool fComputeSector;
140 bool fComputedSector;
141
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000142#if DEBUG_ANGLE
143 int fID;
144#endif
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000145#if DEBUG_VALIDATE
146 void debugValidateNext() const; // in debug builds, verify that angle loop is uncorrupted
147#else
148 void debugValidateNext() const {}
149#endif
caryclarkdac1d172014-06-17 05:15:38 -0700150 void dumpOne(bool showFunc) const; // available to testing only
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000151 void dumpPartials() const; // utility to be called by user from debugger
152 friend class PathOpsAngleTester;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000153};
154
caryclarkdac1d172014-06-17 05:15:38 -0700155class SkOpAngleSet {
156public:
157 SkOpAngleSet();
158 ~SkOpAngleSet();
159 SkOpAngle& push_back();
160 void reset();
161private:
162 void dump() const; // utility to be called by user from debugger
caryclark5e27e0e2014-08-12 07:46:33 -0700163 SkChunkAlloc* fAngles;
caryclarkdac1d172014-06-17 05:15:38 -0700164#if DEBUG_ANGLE
165 int fCount;
166#endif
caryclarkdac1d172014-06-17 05:15:38 -0700167};
168
caryclark@google.com07393ca2013-04-08 11:47:37 +0000169#endif