blob: 23470d7884e016d12ad9e10f60f2e44f734dd2c2 [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
99 bool isCoincident(int index) {
100 return (fIsCoincident[0] & 1 << index) != 0;
101 }
102
103 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
104 bool flipped) {
105 SkDLine line;
106 line.set(a);
107 return horizontal(line, left, right, y, flipped);
108 }
109
110 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
111 SkDLine line;
112 line.set(a);
113 return vertical(line, top, bottom, x, flipped);
114 }
115
116 int lineLine(const SkPoint a[2], const SkPoint b[2]) {
117 SkDLine aLine, bLine;
118 aLine.set(a);
119 bLine.set(b);
120 return intersect(aLine, bLine);
121 }
122
123 const SkDPoint& pt(int index) const {
124 return fPt[index];
125 }
126
127 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
128 bool flipped) {
129 SkDQuad quad;
130 quad.set(a);
131 return horizontal(quad, left, right, y, flipped);
132 }
133
134 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
135 SkDQuad quad;
136 quad.set(a);
137 return vertical(quad, top, bottom, x, flipped);
138 }
139
140 int quadLine(const SkPoint a[3], const SkPoint b[2]) {
141 SkDQuad quad;
142 quad.set(a);
143 SkDLine line;
144 line.set(b);
145 return intersect(quad, line);
146 }
147
148 int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
149 SkDQuad aQuad;
150 aQuad.set(a);
151 SkDQuad bQuad;
152 bQuad.set(b);
153 return intersect(aQuad, bQuad);
154 }
155
156 int quadRay(const SkPoint pts[3], const SkDLine& line);
157 void removeOne(int index);
158
159 // leaves flip, swap alone
160 void reset() {
161 fUsed = 0;
162 }
163
164 void swap() {
165 fSwap ^= true;
166 }
167
168 void swapPts();
169
170 bool swapped() const {
171 return fSwap;
172 }
173
174 int used() const {
175 return fUsed;
176 }
177
178 void downDepth() {
179 SkASSERT(--fDepth >= 0);
180 }
181
182 void upDepth() {
183 SkASSERT(++fDepth < 16);
184 }
185
186 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
187 int coincidentUsed() const;
188 int cubicRay(const SkPoint pts[4], const SkDLine& line);
189 void flip();
190 int horizontal(const SkDLine&, double y);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000191 int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
192 int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
193 int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
194 int horizontal(const SkDCubic&, double y, double tRange[3]);
195 int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
196 int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
197 // FIXME : does not respect swap
198 int insert(double one, double two, const SkDPoint& pt);
199 // start if index == 0 : end if index == 1
200 void insertCoincident(double one, double two, const SkDPoint& pt);
201 void insertCoincidentPair(double s1, double e1, double s2, double e2,
202 const SkDPoint& startPt, const SkDPoint& endPt);
203 int intersect(const SkDLine&, const SkDLine&);
204 int intersect(const SkDQuad&, const SkDLine&);
205 int intersect(const SkDQuad&, const SkDQuad&);
206 int intersect(const SkDCubic&); // return true if cubic self-intersects
207 int intersect(const SkDCubic&, const SkDLine&);
208 int intersect(const SkDCubic&, const SkDQuad&);
209 int intersect(const SkDCubic&, const SkDCubic&);
caryclark@google.comcffbcc32013-06-04 17:59:42 +0000210 int intersectRay(const SkDLine&, const SkDLine&);
211 int intersectRay(const SkDQuad&, const SkDLine&);
212 int intersectRay(const SkDCubic&, const SkDLine&);
213 static SkDPoint Line(const SkDLine&, const SkDLine&);
caryclark@google.com07393ca2013-04-08 11:47:37 +0000214 void offset(int base, double start, double end);
215 void quickRemoveOne(int index, int replace);
216 static bool Test(const SkDLine& , const SkDLine&);
217 int vertical(const SkDLine&, double x);
218 int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
219 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
220 int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
221 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
222 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
223 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
224
225 int depth() const {
226#ifdef SK_DEBUG
227 return fDepth;
228#else
229 return 0;
230#endif
231 }
232
233private:
234 int computePoints(const SkDLine& line, int used);
235 // used by addCoincident to remove ordinary intersections in range
236 void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
237
238 SkDPoint fPt[9];
239 double fT[2][9];
240 uint16_t fIsCoincident[2]; // bit arrays, one bit set for each coincident T
241 unsigned char fUsed;
242 bool fSwap;
243#ifdef SK_DEBUG
244 int fDepth;
245#endif
246};
247
248extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
249extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
250 SkScalar x, bool flipped);
251
252#endif