blob: 32cfe58ecf81d6e960dd485fed6fa2e00412a2a0 [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
8#ifndef SkPathOpsQuad_DEFINED
9#define SkPathOpsQuad_DEFINED
10
11#include "SkPathOpsPoint.h"
12
caryclark03b03ca2015-04-23 09:13:37 -070013struct SkOpCurve;
14
caryclark@google.com07393ca2013-04-08 11:47:37 +000015struct SkDQuadPair {
16 const SkDQuad& first() const { return (const SkDQuad&) pts[0]; }
17 const SkDQuad& second() const { return (const SkDQuad&) pts[2]; }
18 SkDPoint pts[5];
19};
20
21struct SkDQuad {
caryclark54359292015-03-26 07:52:43 -070022 static const int kPointCount = 3;
23 static const int kPointLast = kPointCount - 1;
24 static const int kMaxIntersections = 4;
25
26 SkDPoint fPts[kPointCount];
27
28 bool collapsed() const {
29 return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual(fPts[2]);
30 }
31
32 bool controlsInside() const {
33 SkDVector v01 = fPts[0] - fPts[1];
34 SkDVector v02 = fPts[0] - fPts[2];
35 SkDVector v12 = fPts[1] - fPts[2];
36 return v02.dot(v01) > 0 && v02.dot(v12) > 0;
37 }
caryclark@google.com07393ca2013-04-08 11:47:37 +000038
caryclark1049f122015-04-20 08:31:59 -070039 void debugInit() {
40 sk_bzero(fPts, sizeof(fPts));
41 }
42
caryclark@google.comcffbcc32013-06-04 17:59:42 +000043 SkDQuad flip() const {
44 SkDQuad result = {{fPts[2], fPts[1], fPts[0]}};
45 return result;
46 }
47
caryclarked0935a2015-10-22 07:23:52 -070048 static bool IsConic() { return false; }
caryclark54359292015-03-26 07:52:43 -070049
caryclark1049f122015-04-20 08:31:59 -070050 const SkDQuad& set(const SkPoint pts[kPointCount]) {
caryclark@google.com07393ca2013-04-08 11:47:37 +000051 fPts[0] = pts[0];
52 fPts[1] = pts[1];
53 fPts[2] = pts[2];
caryclark1049f122015-04-20 08:31:59 -070054 return *this;
caryclark@google.com07393ca2013-04-08 11:47:37 +000055 }
56
caryclark54359292015-03-26 07:52:43 -070057 const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
58 SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
caryclark@google.com07393ca2013-04-08 11:47:37 +000059
60 static int AddValidTs(double s[], int realRoots, double* t);
caryclark@google.comcffbcc32013-06-04 17:59:42 +000061 void align(int endIndex, SkDPoint* dstPt) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +000062 SkDQuadPair chopAt(double t) const;
63 SkDVector dxdyAtT(double t) const;
caryclarkaec25102015-04-29 08:28:30 -070064 static int FindExtrema(const double src[], double tValue[1]);
caryclark0449bcf2016-02-09 13:25:45 -080065
66 /**
67 * Return the number of valid roots (0 < root < 1) for this cubic intersecting the
68 * specified horizontal line.
69 */
70 int horizontalIntersect(double yIntercept, double roots[2]) const;
71
caryclark54359292015-03-26 07:52:43 -070072 bool hullIntersects(const SkDQuad& , bool* isLinear) const;
caryclark1049f122015-04-20 08:31:59 -070073 bool hullIntersects(const SkDConic& , bool* isLinear) const;
74 bool hullIntersects(const SkDCubic& , bool* isLinear) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +000075 bool isLinear(int startIndex, int endIndex) const;
caryclarkaec25102015-04-29 08:28:30 -070076 bool monotonicInX() const;
caryclark@google.com07393ca2013-04-08 11:47:37 +000077 bool monotonicInY() const;
caryclark54359292015-03-26 07:52:43 -070078 void otherPts(int oddMan, const SkDPoint* endPt[2]) const;
caryclark@google.com4fdbb222013-07-23 15:27:41 +000079 SkDPoint ptAtT(double t) const;
caryclark@google.com07393ca2013-04-08 11:47:37 +000080 static int RootsReal(double A, double B, double C, double t[2]);
81 static int RootsValidT(const double A, const double B, const double C, double s[2]);
82 static void SetABC(const double* quad, double* a, double* b, double* c);
83 SkDQuad subDivide(double t1, double t2) const;
caryclark54359292015-03-26 07:52:43 -070084 static SkDQuad SubDivide(const SkPoint a[kPointCount], double t1, double t2) {
caryclark@google.com07393ca2013-04-08 11:47:37 +000085 SkDQuad quad;
86 quad.set(a);
87 return quad.subDivide(t1, t2);
88 }
89 SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const;
caryclark54359292015-03-26 07:52:43 -070090 static SkDPoint SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, const SkDPoint& c,
caryclark@google.com07393ca2013-04-08 11:47:37 +000091 double t1, double t2) {
92 SkDQuad quad;
93 quad.set(pts);
94 return quad.subDivide(a, c, t1, t2);
95 }
caryclark@google.com570863f2013-09-16 15:55:01 +000096
caryclark0449bcf2016-02-09 13:25:45 -080097 /**
98 * Return the number of valid roots (0 < root < 1) for this cubic intersecting the
99 * specified vertical line.
100 */
101 int verticalIntersect(double xIntercept, double roots[2]) const;
102
caryclark624637c2015-05-11 07:21:27 -0700103 SkDCubic debugToCubic() const;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000104 // utilities callable by the user from the debugger when the implementation code is linked in
105 void dump() const;
caryclark54359292015-03-26 07:52:43 -0700106 void dumpID(int id) const;
107 void dumpInner() const;
commit-bot@chromium.org4431e772014-04-14 17:08:59 +0000108
caryclark@google.com07393ca2013-04-08 11:47:37 +0000109private:
110// static double Tangent(const double* quadratic, double t); // uncalled
111};
112
113#endif