blob: c2f05fe936f41710ef1072e7e483d66b5468fe59 [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
39 int cubic(const SkPoint a[4]) {
40 SkDCubic cubic;
41 cubic.set(a);
42 return intersect(cubic);
43 }
44
45 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
46 SkDCubic aCubic;
47 aCubic.set(a);
48 SkDCubic bCubic;
49 bCubic.set(b);
50 return intersect(aCubic, bCubic);
51 }
52
53 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
54 bool flipped) {
55 SkDCubic cubic;
56 cubic.set(a);
57 return horizontal(cubic, left, right, y, flipped);
58 }
59
60 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
61 SkDCubic cubic;
62 cubic.set(a);
63 return vertical(cubic, top, bottom, x, flipped);
64 }
65
66 int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
67 SkDCubic cubic;
68 cubic.set(a);
69 SkDLine line;
70 line.set(b);
71 return intersect(cubic, line);
72 }
73
74 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
75 SkDCubic cubic;
76 cubic.set(a);
77 SkDQuad quad;
78 quad.set(b);
79 return intersect(cubic, quad);
80 }
81
82 int insertSwap(double one, double two, const SkDPoint& pt) {
83 if (fSwap) {
84 return insert(two, one, pt);
85 } else {
86 return insert(one, two, pt);
87 }
88 }
89
90 bool isCoincident(int index) {
91 return (fIsCoincident[0] & 1 << index) != 0;
92 }
93
94 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
95 bool flipped) {
96 SkDLine line;
97 line.set(a);
98 return horizontal(line, left, right, y, flipped);
99 }
100
101 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
102 SkDLine line;
103 line.set(a);
104 return vertical(line, top, bottom, x, flipped);
105 }
106
107 int lineLine(const SkPoint a[2], const SkPoint b[2]) {
108 SkDLine aLine, bLine;
109 aLine.set(a);
110 bLine.set(b);
111 return intersect(aLine, bLine);
112 }
113
114 const SkDPoint& pt(int index) const {
115 return fPt[index];
116 }
117
118 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
119 bool flipped) {
120 SkDQuad quad;
121 quad.set(a);
122 return horizontal(quad, left, right, y, flipped);
123 }
124
125 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
126 SkDQuad quad;
127 quad.set(a);
128 return vertical(quad, top, bottom, x, flipped);
129 }
130
131 int quadLine(const SkPoint a[3], const SkPoint b[2]) {
132 SkDQuad quad;
133 quad.set(a);
134 SkDLine line;
135 line.set(b);
136 return intersect(quad, line);
137 }
138
139 int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
140 SkDQuad aQuad;
141 aQuad.set(a);
142 SkDQuad bQuad;
143 bQuad.set(b);
144 return intersect(aQuad, bQuad);
145 }
146
147 int quadRay(const SkPoint pts[3], const SkDLine& line);
148 void removeOne(int index);
149
150 // leaves flip, swap alone
151 void reset() {
152 fUsed = 0;
153 }
154
155 void swap() {
156 fSwap ^= true;
157 }
158
159 void swapPts();
160
161 bool swapped() const {
162 return fSwap;
163 }
164
165 int used() const {
166 return fUsed;
167 }
168
169 void downDepth() {
170 SkASSERT(--fDepth >= 0);
171 }
172
173 void upDepth() {
174 SkASSERT(++fDepth < 16);
175 }
176
177 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
178 int coincidentUsed() const;
179 int cubicRay(const SkPoint pts[4], const SkDLine& line);
180 void flip();
181 int horizontal(const SkDLine&, double y);
182 int horizontal(const SkDLine&, double left, double right, double y);
183 int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
184 int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
185 int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
186 int horizontal(const SkDCubic&, double y, double tRange[3]);
187 int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
188 int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
189 // FIXME : does not respect swap
190 int insert(double one, double two, const SkDPoint& pt);
191 // start if index == 0 : end if index == 1
192 void insertCoincident(double one, double two, const SkDPoint& pt);
193 void insertCoincidentPair(double s1, double e1, double s2, double e2,
194 const SkDPoint& startPt, const SkDPoint& endPt);
195 int intersect(const SkDLine&, const SkDLine&);
196 int intersect(const SkDQuad&, const SkDLine&);
197 int intersect(const SkDQuad&, const SkDQuad&);
198 int intersect(const SkDCubic&); // return true if cubic self-intersects
199 int intersect(const SkDCubic&, const SkDLine&);
200 int intersect(const SkDCubic&, const SkDQuad&);
201 int intersect(const SkDCubic&, const SkDCubic&);
202 int intersectRay(const SkDCubic& , const SkDLine&);
203 int intersectRay(const SkDQuad& , const SkDLine&);
204 static SkDPoint Line(const SkDLine& , const SkDLine&);
205 void offset(int base, double start, double end);
206 void quickRemoveOne(int index, int replace);
207 static bool Test(const SkDLine& , const SkDLine&);
208 int vertical(const SkDLine&, double x);
209 int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
210 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
211 int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
212 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
213 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
214 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
215
216 int depth() const {
217#ifdef SK_DEBUG
218 return fDepth;
219#else
220 return 0;
221#endif
222 }
223
224private:
225 int computePoints(const SkDLine& line, int used);
226 // used by addCoincident to remove ordinary intersections in range
227 void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
228
229 SkDPoint fPt[9];
230 double fT[2][9];
231 uint16_t fIsCoincident[2]; // bit arrays, one bit set for each coincident T
232 unsigned char fUsed;
233 bool fSwap;
234#ifdef SK_DEBUG
235 int fDepth;
236#endif
237};
238
239extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
240extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
241 SkScalar x, bool flipped);
242
243#endif