blob: 1dc425061352f43188d88abea5a6d84512b7827b [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
caryclark65f55312014-11-13 06:58:52 -080053 int sectorEnd() const {
54 return fSectorEnd;
55 }
56
57 int sectorStart() const {
58 return fSectorStart;
59 }
60
caryclark@google.comcffbcc32013-06-04 17:59:42 +000061 void set(const SkOpSegment* segment, int start, int end);
caryclark@google.comad65a3e2013-04-15 19:13:59 +000062
caryclark@google.com570863f2013-09-16 15:55:01 +000063 void setLastMarked(SkOpSpan* marked) {
64 fLastMarked = marked;
65 }
66
caryclark@google.com07393ca2013-04-08 11:47:37 +000067 SkOpSegment* segment() const {
68 return const_cast<SkOpSegment*>(fSegment);
69 }
70
71 int sign() const {
72 return SkSign32(fStart - fEnd);
73 }
74
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000075 bool small() const;
76
caryclark@google.com07393ca2013-04-08 11:47:37 +000077 int start() const {
78 return fStart;
79 }
80
caryclark@google.comcffbcc32013-06-04 17:59:42 +000081 bool unorderable() const {
82 return fUnorderable;
83 }
84
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000085 // available to testing only
86#if DEBUG_SORT
87 void debugLoop() const; // called by code during run
caryclark@google.com570863f2013-09-16 15:55:01 +000088#endif
commit-bot@chromium.org4431e772014-04-14 17:08:59 +000089#if DEBUG_ANGLE
90 void debugSameAs(const SkOpAngle* compare) const;
91#endif
92 void dump() const;
caryclarkdac1d172014-06-17 05:15:38 -070093 void dumpLoop() const;
94 void dumpTo(const SkOpSegment* fromSeg, const SkOpAngle* ) const;
caryclark@google.comcffbcc32013-06-04 17:59:42 +000095
caryclark@google.com570863f2013-09-16 15:55:01 +000096#if DEBUG_ANGLE
caryclarkdac1d172014-06-17 05:15:38 -070097 int debugID() const { return fID; }
98
caryclark@google.comcffbcc32013-06-04 17:59:42 +000099 void setID(int id) {
100 fID = id;
101 }
caryclarkdac1d172014-06-17 05:15:38 -0700102#else
103 int debugID() const { return 0; }
caryclark@google.com07393ca2013-04-08 11:47:37 +0000104#endif
caryclarkdac1d172014-06-17 05:15:38 -0700105
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000106#if DEBUG_VALIDATE
107 void debugValidateLoop() const;
108#endif
caryclark@google.com07393ca2013-04-08 11:47:37 +0000109
110private:
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000111 bool after(const SkOpAngle* test) const;
112 int allOnOneSide(const SkOpAngle& test) const;
113 bool calcSlop(double x, double y, double rx, double ry, bool* result) const;
114 bool checkCrossesZero() const;
115 bool checkParallel(const SkOpAngle& ) const;
116 bool computeSector();
117 int convexHullOverlaps(const SkOpAngle& ) const;
118 double distEndRatio(double dist) const;
119 int findSector(SkPath::Verb verb, double x, double y) const;
120 bool endsIntersect(const SkOpAngle& ) const;
121 double midT() const;
122 bool oppositePlanes(const SkOpAngle& rh) const;
123 bool orderable(const SkOpAngle& rh) const; // false == this < rh ; true == this > rh
commit-bot@chromium.org8cb1daa2014-04-25 12:59:11 +0000124 bool overlap(const SkOpAngle& test) const;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000125 void setCurveHullSweep();
126 void setSector();
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000127 void setSpans();
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000128 bool tangentsDiverge(const SkOpAngle& rh, double s0xt0) const;
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000129
caryclark@google.com570863f2013-09-16 15:55:01 +0000130 SkDCubic fCurvePart; // the curve from start to end
caryclark@google.com07393ca2013-04-08 11:47:37 +0000131 double fSide;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000132 SkLineParameters fTangentHalf; // used only to sort a pair of lines or line-like sections
caryclark@google.com07393ca2013-04-08 11:47:37 +0000133 const SkOpSegment* fSegment;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000134 SkOpAngle* fNext;
caryclark@google.com570863f2013-09-16 15:55:01 +0000135 SkOpSpan* fLastMarked;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000136 SkDVector fSweep[2];
caryclark@google.com07393ca2013-04-08 11:47:37 +0000137 int fStart;
138 int fEnd;
caryclarkdac1d172014-06-17 05:15:38 -0700139 int fComputedEnd;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000140 int fSectorMask;
commit-bot@chromium.org86084632014-04-14 18:33:03 +0000141 int8_t fSectorStart; // in 32nds of a circle
142 int8_t fSectorEnd;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000143 bool fIsCurve;
144 bool fStop; // set if ordered angle is greater than the previous
145 mutable bool fUnorderable; // this is editable by orderable()
146 bool fUnorderedSweep; // set when a cubic's first control point between the sweep vectors
147 bool fComputeSector;
148 bool fComputedSector;
149
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000150#if DEBUG_ANGLE
151 int fID;
152#endif
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000153#if DEBUG_VALIDATE
154 void debugValidateNext() const; // in debug builds, verify that angle loop is uncorrupted
155#else
156 void debugValidateNext() const {}
157#endif
caryclarkdac1d172014-06-17 05:15:38 -0700158 void dumpOne(bool showFunc) const; // available to testing only
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000159 void dumpPartials() const; // utility to be called by user from debugger
160 friend class PathOpsAngleTester;
caryclark@google.com07393ca2013-04-08 11:47:37 +0000161};
162
caryclarkdac1d172014-06-17 05:15:38 -0700163class SkOpAngleSet {
164public:
165 SkOpAngleSet();
166 ~SkOpAngleSet();
167 SkOpAngle& push_back();
168 void reset();
169private:
170 void dump() const; // utility to be called by user from debugger
caryclark5e27e0e2014-08-12 07:46:33 -0700171 SkChunkAlloc* fAngles;
caryclarkdac1d172014-06-17 05:15:38 -0700172#if DEBUG_ANGLE
173 int fCount;
174#endif
caryclarkdac1d172014-06-17 05:15:38 -0700175};
176
caryclark@google.com07393ca2013-04-08 11:47:37 +0000177#endif