blob: 88a234f59d5bd4c82bddf85f0853e8858cd49535 [file] [log] [blame]
caryclark1049f122015-04-20 08:31:59 -07001/*
2 * Copyright 2015 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 SkPathOpsConic_DEFINED
9#define SkPathOpsConic_DEFINED
10
11#include "SkPathOpsPoint.h"
12#include "SkPathOpsQuad.h"
13
14struct SkDConic {
15 static const int kPointCount = 3;
16 static const int kPointLast = kPointCount - 1;
17 static const int kMaxIntersections = 4;
18
19 SkDQuad fPts;
20 SkScalar fWeight;
21
22 bool collapsed() const {
23 return fPts.collapsed();
24 }
25
26 bool controlsInside() const {
27 return fPts.controlsInside();
28 }
29
30 void debugInit() {
31 fPts.debugInit();
32 }
33
caryclarka35ab3e2016-10-20 08:32:18 -070034 void debugSet(const SkDPoint* pts, SkScalar weight);
35
caryclark1049f122015-04-20 08:31:59 -070036 SkDConic flip() const {
caryclarka35ab3e2016-10-20 08:32:18 -070037 SkDConic result = {{{fPts[2], fPts[1], fPts[0]}
38 SkDEBUGPARAMS(fPts.fDebugGlobalState) }, fWeight};
caryclark1049f122015-04-20 08:31:59 -070039 return result;
40 }
41
caryclarka35ab3e2016-10-20 08:32:18 -070042#ifdef SK_DEBUG
43 SkOpGlobalState* globalState() const { return fPts.globalState(); }
44#endif
45
caryclarked0935a2015-10-22 07:23:52 -070046 static bool IsConic() { return true; }
caryclark1049f122015-04-20 08:31:59 -070047
caryclarka35ab3e2016-10-20 08:32:18 -070048 const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight
49 SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
50 fPts.set(pts SkDEBUGPARAMS(state));
caryclark1049f122015-04-20 08:31:59 -070051 fWeight = weight;
52 return *this;
53 }
54
55 const SkDPoint& operator[](int n) const { return fPts[n]; }
56 SkDPoint& operator[](int n) { return fPts[n]; }
57
58 static int AddValidTs(double s[], int realRoots, double* t) {
59 return SkDQuad::AddValidTs(s, realRoots, t);
60 }
61
62 void align(int endIndex, SkDPoint* dstPt) const {
63 fPts.align(endIndex, dstPt);
64 }
65
66 SkDVector dxdyAtT(double t) const;
67 static int FindExtrema(const double src[], SkScalar weight, double tValue[1]);
68
69 bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
70 return fPts.hullIntersects(quad, isLinear);
71 }
72
73 bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
74 return fPts.hullIntersects(conic.fPts, isLinear);
75 }
76
77 bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
78
79 bool isLinear(int startIndex, int endIndex) const {
80 return fPts.isLinear(startIndex, endIndex);
81 }
82
Cary Clark0a671982018-10-11 12:16:49 -040083 static int maxIntersections() { return kMaxIntersections; }
84
caryclarkaec25102015-04-29 08:28:30 -070085 bool monotonicInX() const {
86 return fPts.monotonicInX();
87 }
88
caryclark1049f122015-04-20 08:31:59 -070089 bool monotonicInY() const {
90 return fPts.monotonicInY();
91 }
92
93 void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
94 fPts.otherPts(oddMan, endPt);
95 }
96
Cary Clark0a671982018-10-11 12:16:49 -040097 static int pointCount() { return kPointCount; }
98 static int pointLast() { return kPointLast; }
caryclark1049f122015-04-20 08:31:59 -070099 SkDPoint ptAtT(double t) const;
100
101 static int RootsReal(double A, double B, double C, double t[2]) {
102 return SkDQuad::RootsReal(A, B, C, t);
103 }
104
105 static int RootsValidT(const double A, const double B, const double C, double s[2]) {
106 return SkDQuad::RootsValidT(A, B, C, s);
107 }
108
109 SkDConic subDivide(double t1, double t2) const;
Cary Clark0a671982018-10-11 12:16:49 -0400110 void subDivide(double t1, double t2, SkDConic* c) const { *c = this->subDivide(t1, t2); }
caryclark1049f122015-04-20 08:31:59 -0700111
112 static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
113 SkDConic conic;
114 conic.set(a, weight);
115 return conic.subDivide(t1, t2);
116 }
117
118 SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
119 SkScalar* weight) const;
120
121 static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
122 const SkDPoint& a, const SkDPoint& c,
123 double t1, double t2, SkScalar* newWeight) {
124 SkDConic conic;
125 conic.set(pts, weight);
126 return conic.subDivide(a, c, t1, t2, newWeight);
127 }
128
caryclark1049f122015-04-20 08:31:59 -0700129 // utilities callable by the user from the debugger when the implementation code is linked in
130 void dump() const;
131 void dumpID(int id) const;
132 void dumpInner() const;
caryclarka35ab3e2016-10-20 08:32:18 -0700133
caryclark1049f122015-04-20 08:31:59 -0700134};
135
Cary Clark0a671982018-10-11 12:16:49 -0400136#if PATH_OP_COMPILE_FOR_SIZE
caryclark1049f122015-04-20 08:31:59 -0700137
Cary Clark0a671982018-10-11 12:16:49 -0400138#include "SkArenaAlloc.h"
139#include "SkPathOpsTCurve.h"
140
141class SkTConic : public SkTCurve {
142public:
143 SkDConic fConic;
144
145 SkTConic() {}
146
147 SkTConic(const SkDConic& c)
148 : fConic(c) {
149 }
150
151 ~SkTConic() override {}
152
153 const SkDPoint& operator[](int n) const override { return fConic[n]; }
154 SkDPoint& operator[](int n) override { return fConic[n]; }
155
156 bool collapsed() const override { return fConic.collapsed(); }
157 bool controlsInside() const override { return fConic.controlsInside(); }
158 void debugInit() override { return fConic.debugInit(); }
159 SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
160#ifdef SK_DEBUG
161 SkOpGlobalState* globalState() const override { return fConic.globalState(); }
162#endif
163 bool hullIntersects(const SkDQuad& quad, bool* isLinear) const override;
164
165 bool hullIntersects(const SkDConic& conic, bool* isLinear) const override {
166 return conic.hullIntersects(fConic, isLinear);
167 }
168
169 bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const override;
170
171 bool hullIntersects(const SkTCurve& curve, bool* isLinear) const override {
172 return curve.hullIntersects(fConic, isLinear);
173 }
174
175 int intersectRay(SkIntersections* i, const SkDLine& line) const override;
176 bool IsConic() const override { return true; }
177 SkTCurve* make(SkArenaAlloc& heap) const override { return heap.make<SkTConic>(); }
178
179 int maxIntersections() const override { return SkDConic::kMaxIntersections; }
180
181 void otherPts(int oddMan, const SkDPoint* endPt[2]) const override {
182 fConic.otherPts(oddMan, endPt);
183 }
184
185 int pointCount() const override { return SkDConic::kPointCount; }
186 int pointLast() const override { return SkDConic::kPointLast; }
187 SkDPoint ptAtT(double t) const override { return fConic.ptAtT(t); }
188 void setBounds(SkDRect* ) const override;
189
190 void subDivide(double t1, double t2, SkTCurve* curve) const override {
191 ((SkTConic*) curve)->fConic = fConic.subDivide(t1, t2);
192 }
193};
194
195#endif // PATH_OP_COMPILE_FOR_SIZE
caryclark1049f122015-04-20 08:31:59 -0700196#endif