blob: c0bb61fef0f09c335f2744edc51eb35ad0826d54 [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 SkIntersections_DEFINE
8#define SkIntersections_DEFINE
9
10#include "SkPathOpsCubic.h"
11#include "SkPathOpsLine.h"
12#include "SkPathOpsPoint.h"
13#include "SkPathOpsQuad.h"
14
15class SkIntersections {
16public:
17 SkIntersections()
18 : fSwap(0)
19#ifdef SK_DEBUG
20 , fDepth(0)
21#endif
22 {
23 sk_bzero(fPt, sizeof(fPt));
24 sk_bzero(fT, sizeof(fT));
25 sk_bzero(fIsCoincident, sizeof(fIsCoincident));
26 reset();
27 }
28
29 class TArray {
30 public:
31 explicit TArray(const double ts[9]) : fTArray(ts) {}
32 double operator[](int n) const {
33 return fTArray[n];
34 }
35 const double* fTArray;
36 };
37 TArray operator[](int n) const { return TArray(fT[n]); }
38
caryclark@google.comb3f09212013-04-17 15:49:16 +000039 void set(const SkIntersections& i) {
40 memcpy(fPt, i.fPt, sizeof(fPt));
41 memcpy(fT, i.fT, sizeof(fT));
42 memcpy(fIsCoincident, i.fIsCoincident, sizeof(fIsCoincident));
43 fUsed = i.fUsed;
44 fSwap = i.fSwap;
45 SkDEBUGCODE(fDepth = i.fDepth);
46 }
47
caryclark@google.com07393ca2013-04-08 11:47:37 +000048 int cubic(const SkPoint a[4]) {
49 SkDCubic cubic;
50 cubic.set(a);
51 return intersect(cubic);
52 }
53
54 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
55 SkDCubic aCubic;
56 aCubic.set(a);
57 SkDCubic bCubic;
58 bCubic.set(b);
59 return intersect(aCubic, bCubic);
60 }
61
62 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
63 bool flipped) {
64 SkDCubic cubic;
65 cubic.set(a);
66 return horizontal(cubic, left, right, y, flipped);
67 }
68
69 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
70 SkDCubic cubic;
71 cubic.set(a);
72 return vertical(cubic, top, bottom, x, flipped);
73 }
74
75 int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
76 SkDCubic cubic;
77 cubic.set(a);
78 SkDLine line;
79 line.set(b);
80 return intersect(cubic, line);
81 }
82
83 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
84 SkDCubic cubic;
85 cubic.set(a);
86 SkDQuad quad;
87 quad.set(b);
88 return intersect(cubic, quad);
89 }
90
91 int insertSwap(double one, double two, const SkDPoint& pt) {
92 if (fSwap) {
93 return insert(two, one, pt);
94 } else {
95 return insert(one, two, pt);
96 }
97 }
98
caryclark@google.com07e97fc2013-07-08 17:17:02 +000099 int insertSwap(double one, double two, double x, double y) {
100 if (fSwap) {
101 return insert(two, one, x, y);
102 } else {
103 return insert(one, two, x, y);
104 }
105 }
106
caryclark@google.com07393ca2013-04-08 11:47:37 +0000107 bool isCoincident(int index) {
108 return (fIsCoincident[0] & 1 << index) != 0;
109 }
110
111 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
112 bool flipped) {
113 SkDLine line;
114 line.set(a);
115 return horizontal(line, left, right, y, flipped);
116 }
117
118 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
119 SkDLine line;
120 line.set(a);
121 return vertical(line, top, bottom, x, flipped);
122 }
123
124 int lineLine(const SkPoint a[2], const SkPoint b[2]) {
125 SkDLine aLine, bLine;
126 aLine.set(a);
127 bLine.set(b);
128 return intersect(aLine, bLine);
129 }
130
131 const SkDPoint& pt(int index) const {
132 return fPt[index];
133 }
134
135 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
136 bool flipped) {
137 SkDQuad quad;
138 quad.set(a);
139 return horizontal(quad, left, right, y, flipped);
140 }
141
142 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
143 SkDQuad quad;
144 quad.set(a);
145 return vertical(quad, top, bottom, x, flipped);
146 }
147
148 int quadLine(const SkPoint a[3], const SkPoint b[2]) {
149 SkDQuad quad;
150 quad.set(a);
151 SkDLine line;
152 line.set(b);
153 return intersect(quad, line);
154 }
155
156 int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
157 SkDQuad aQuad;
158 aQuad.set(a);
159 SkDQuad bQuad;
160 bQuad.set(b);
161 return intersect(aQuad, bQuad);
162 }
163
164 int quadRay(const SkPoint pts[3], const SkDLine& line);
165 void removeOne(int index);
166
167 // leaves flip, swap alone
168 void reset() {
169 fUsed = 0;
170 }
171
172 void swap() {
173 fSwap ^= true;
174 }
175
176 void swapPts();
177
178 bool swapped() const {
179 return fSwap;
180 }
181
182 int used() const {
183 return fUsed;
184 }
185
186 void downDepth() {
187 SkASSERT(--fDepth >= 0);
188 }
189
190 void upDepth() {
191 SkASSERT(++fDepth < 16);
192 }
193
194 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
195 int coincidentUsed() const;
196 int cubicRay(const SkPoint pts[4], const SkDLine& line);
197 void flip();
198 int horizontal(const SkDLine&, double y);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000199 int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
200 int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
201 int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
202 int horizontal(const SkDCubic&, double y, double tRange[3]);
203 int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
204 int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
205 // FIXME : does not respect swap
206 int insert(double one, double two, const SkDPoint& pt);
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000207 int insert(double one, double two, double x, double y);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000208 // start if index == 0 : end if index == 1
209 void insertCoincident(double one, double two, const SkDPoint& pt);
210 void insertCoincidentPair(double s1, double e1, double s2, double e2,
211 const SkDPoint& startPt, const SkDPoint& endPt);
212 int intersect(const SkDLine&, const SkDLine&);
213 int intersect(const SkDQuad&, const SkDLine&);
214 int intersect(const SkDQuad&, const SkDQuad&);
215 int intersect(const SkDCubic&); // return true if cubic self-intersects
216 int intersect(const SkDCubic&, const SkDLine&);
217 int intersect(const SkDCubic&, const SkDQuad&);
218 int intersect(const SkDCubic&, const SkDCubic&);
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000219 int intersectRay(const SkDLine&, const SkDLine&);
220 int intersectRay(const SkDQuad&, const SkDLine&);
221 int intersectRay(const SkDCubic&, const SkDLine&);
222 static SkDPoint Line(const SkDLine&, const SkDLine&);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000223 void offset(int base, double start, double end);
224 void quickRemoveOne(int index, int replace);
225 static bool Test(const SkDLine& , const SkDLine&);
226 int vertical(const SkDLine&, double x);
227 int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
228 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
229 int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
230 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
231 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
232 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
233
234 int depth() const {
235#ifdef SK_DEBUG
236 return fDepth;
237#else
238 return 0;
239#endif
240 }
241
242private:
243 int computePoints(const SkDLine& line, int used);
244 // used by addCoincident to remove ordinary intersections in range
caryclark@google.com07e97fc2013-07-08 17:17:02 +0000245 // void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000246
247 SkDPoint fPt[9];
248 double fT[2][9];
249 uint16_t fIsCoincident[2]; // bit arrays, one bit set for each coincident T
250 unsigned char fUsed;
251 bool fSwap;
252#ifdef SK_DEBUG
253 int fDepth;
254#endif
255};
256
257extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
258extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
259 SkScalar x, bool flipped);
260
261#endif