2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
7 #ifndef SkIntersections_DEFINE
8 #define SkIntersections_DEFINE
10 #include "SkPathOpsCubic.h"
11 #include "SkPathOpsLine.h"
12 #include "SkPathOpsPoint.h"
13 #include "SkPathOpsQuad.h"
15 class SkIntersections {
23 sk_bzero(fPt, sizeof(fPt));
24 sk_bzero(fT, sizeof(fT));
25 sk_bzero(fIsCoincident, sizeof(fIsCoincident));
27 fMax = 0; // require that the caller set the max
32 explicit TArray(const double ts[9]) : fTArray(ts) {}
33 double operator[](int n) const {
36 const double* fTArray;
38 TArray operator[](int n) const { return TArray(fT[n]); }
40 void set(const SkIntersections& i) {
41 memcpy(fPt, i.fPt, sizeof(fPt));
42 memcpy(fT, i.fT, sizeof(fT));
43 memcpy(fIsCoincident, i.fIsCoincident, sizeof(fIsCoincident));
47 SkDEBUGCODE(fDepth = i.fDepth);
50 void allowNear(bool nearAllowed) {
51 fAllowNear = nearAllowed;
54 int cubic(const SkPoint a[4]) {
57 fMax = 1; // self intersect
58 return intersect(cubic);
61 int cubicCubic(const SkPoint a[4], const SkPoint b[4]) {
67 return intersect(aCubic, bCubic);
70 int cubicHorizontal(const SkPoint a[4], SkScalar left, SkScalar right, SkScalar y,
75 return horizontal(cubic, left, right, y, flipped);
78 int cubicVertical(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
82 return vertical(cubic, top, bottom, x, flipped);
85 int cubicLine(const SkPoint a[4], const SkPoint b[2]) {
91 return intersect(cubic, line);
94 int cubicQuad(const SkPoint a[4], const SkPoint b[3]) {
100 return intersect(cubic, quad);
103 bool hasT(double t) const {
104 SkASSERT(t == 0 || t == 1);
105 return fUsed > 0 && (t == 0 ? fT[0][0] == 0 : fT[0][fUsed - 1] == 1);
108 int insertSwap(double one, double two, const SkDPoint& pt) {
110 return insert(two, one, pt);
112 return insert(one, two, pt);
116 bool isCoincident(int index) {
117 return (fIsCoincident[0] & 1 << index) != 0;
120 int lineHorizontal(const SkPoint a[2], SkScalar left, SkScalar right, SkScalar y,
125 return horizontal(line, left, right, y, flipped);
128 int lineVertical(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
132 return vertical(line, top, bottom, x, flipped);
135 int lineLine(const SkPoint a[2], const SkPoint b[2]) {
136 SkDLine aLine, bLine;
140 return intersect(aLine, bLine);
143 const SkDPoint& pt(int index) const {
147 int quadHorizontal(const SkPoint a[3], SkScalar left, SkScalar right, SkScalar y,
152 return horizontal(quad, left, right, y, flipped);
155 int quadVertical(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped) {
159 return vertical(quad, top, bottom, x, flipped);
162 int quadLine(const SkPoint a[3], const SkPoint b[2]) {
168 return intersect(quad, line);
171 int quadQuad(const SkPoint a[3], const SkPoint b[3]) {
177 return intersect(aQuad, bQuad);
180 // leaves flip, swap, max alone
186 void setMax(int max) {
196 bool swapped() const {
205 SkASSERT(--fDepth >= 0);
209 SkASSERT(++fDepth < 16);
212 void append(const SkIntersections& );
213 static double Axial(const SkDQuad& , const SkDPoint& , bool vertical);
214 void cleanUpCoincidence();
215 int coincidentUsed() const;
216 int cubicRay(const SkPoint pts[4], const SkDLine& line);
218 int horizontal(const SkDLine&, double y);
219 int horizontal(const SkDLine&, double left, double right, double y, bool flipped);
220 int horizontal(const SkDQuad&, double left, double right, double y, bool flipped);
221 int horizontal(const SkDQuad&, double left, double right, double y, double tRange[2]);
222 int horizontal(const SkDCubic&, double y, double tRange[3]);
223 int horizontal(const SkDCubic&, double left, double right, double y, bool flipped);
224 int horizontal(const SkDCubic&, double left, double right, double y, double tRange[3]);
225 // FIXME : does not respect swap
226 int insert(double one, double two, const SkDPoint& pt);
227 void insertNear(double one, double two, const SkDPoint& pt);
228 // start if index == 0 : end if index == 1
229 void insertCoincident(double one, double two, const SkDPoint& pt);
230 int intersect(const SkDLine&, const SkDLine&);
231 int intersect(const SkDQuad&, const SkDLine&);
232 int intersect(const SkDQuad&, const SkDQuad&);
233 int intersect(const SkDCubic&); // return true if cubic self-intersects
234 int intersect(const SkDCubic&, const SkDLine&);
235 int intersect(const SkDCubic&, const SkDQuad&);
236 int intersect(const SkDCubic&, const SkDCubic&);
237 int intersectRay(const SkDLine&, const SkDLine&);
238 int intersectRay(const SkDQuad&, const SkDLine&);
239 int intersectRay(const SkDCubic&, const SkDLine&);
240 static SkDPoint Line(const SkDLine&, const SkDLine&);
241 int lineRay(const SkPoint pts[2], const SkDLine& line);
242 void offset(int base, double start, double end);
243 void quickRemoveOne(int index, int replace);
244 int quadRay(const SkPoint pts[3], const SkDLine& line);
245 void removeOne(int index);
246 static bool Test(const SkDLine& , const SkDLine&);
247 int vertical(const SkDLine&, double x);
248 int vertical(const SkDLine&, double top, double bottom, double x, bool flipped);
249 int vertical(const SkDQuad&, double top, double bottom, double x, bool flipped);
250 int vertical(const SkDCubic&, double top, double bottom, double x, bool flipped);
251 int verticalCubic(const SkPoint a[4], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
252 int verticalLine(const SkPoint a[2], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
253 int verticalQuad(const SkPoint a[3], SkScalar top, SkScalar bottom, SkScalar x, bool flipped);
264 bool cubicCheckCoincidence(const SkDCubic& c1, const SkDCubic& c2);
265 bool cubicExactEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2);
266 void cubicNearEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cubic2, const SkDRect& );
267 void cleanUpParallelLines(bool parallel);
268 void computePoints(const SkDLine& line, int used);
269 // used by addCoincident to remove ordinary intersections in range
270 // void remove(double one, double two, const SkDPoint& startPt, const SkDPoint& endPt);
272 SkDPoint fPt[9]; // FIXME: since scans store points as SkPoint, this should also
274 uint16_t fIsCoincident[2]; // bit set for each curve's coincident T
284 extern int (SkIntersections::*CurveRay[])(const SkPoint[], const SkDLine& );
285 extern int (SkIntersections::*CurveVertical[])(const SkPoint[], SkScalar top, SkScalar bottom,
286 SkScalar x, bool flipped);