2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef SkPathOpsConic_DEFINED
9 #define SkPathOpsConic_DEFINED
11 #include "src/pathops/SkPathOpsQuad.h"
14 static const int kPointCount = 3;
15 static const int kPointLast = kPointCount - 1;
16 static const int kMaxIntersections = 4;
21 bool collapsed() const {
22 return fPts.collapsed();
25 bool controlsInside() const {
26 return fPts.controlsInside();
34 void debugSet(const SkDPoint* pts, SkScalar weight);
36 SkDConic flip() const {
37 SkDConic result = {{{fPts[2], fPts[1], fPts[0]}
38 SkDEBUGPARAMS(fPts.fDebugGlobalState) }, fWeight};
43 SkOpGlobalState* globalState() const { return fPts.globalState(); }
46 static bool IsConic() { return true; }
48 const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight
49 SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
50 fPts.set(pts SkDEBUGPARAMS(state));
55 const SkDPoint& operator[](int n) const { return fPts[n]; }
56 SkDPoint& operator[](int n) { return fPts[n]; }
58 static int AddValidTs(double s[], int realRoots, double* t) {
59 return SkDQuad::AddValidTs(s, realRoots, t);
62 void align(int endIndex, SkDPoint* dstPt) const {
63 fPts.align(endIndex, dstPt);
66 SkDVector dxdyAtT(double t) const;
67 static int FindExtrema(const double src[], SkScalar weight, double tValue[1]);
69 bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
70 return fPts.hullIntersects(quad, isLinear);
73 bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
74 return fPts.hullIntersects(conic.fPts, isLinear);
77 bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
79 bool isLinear(int startIndex, int endIndex) const {
80 return fPts.isLinear(startIndex, endIndex);
83 static int maxIntersections() { return kMaxIntersections; }
85 bool monotonicInX() const {
86 return fPts.monotonicInX();
89 bool monotonicInY() const {
90 return fPts.monotonicInY();
93 void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
94 fPts.otherPts(oddMan, endPt);
97 static int pointCount() { return kPointCount; }
98 static int pointLast() { return kPointLast; }
99 SkDPoint ptAtT(double t) const;
101 static int RootsReal(double A, double B, double C, double t[2]) {
102 return SkDQuad::RootsReal(A, B, C, t);
105 static int RootsValidT(const double A, const double B, const double C, double s[2]) {
106 return SkDQuad::RootsValidT(A, B, C, s);
109 SkDConic subDivide(double t1, double t2) const;
110 void subDivide(double t1, double t2, SkDConic* c) const { *c = this->subDivide(t1, t2); }
112 static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
114 conic.set(a, weight);
115 return conic.subDivide(t1, t2);
118 SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
119 SkScalar* weight) const;
121 static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
122 const SkDPoint& a, const SkDPoint& c,
123 double t1, double t2, SkScalar* newWeight) {
125 conic.set(pts, weight);
126 return conic.subDivide(a, c, t1, t2, newWeight);
129 // utilities callable by the user from the debugger when the implementation code is linked in
131 void dumpID(int id) const;
132 void dumpInner() const;
136 class SkTConic : public SkTCurve {
142 SkTConic(const SkDConic& c)
146 ~SkTConic() override {}
148 const SkDPoint& operator[](int n) const override { return fConic[n]; }
149 SkDPoint& operator[](int n) override { return fConic[n]; }
151 bool collapsed() const override { return fConic.collapsed(); }
152 bool controlsInside() const override { return fConic.controlsInside(); }
153 void debugInit() override { return fConic.debugInit(); }
155 void dumpID(int id) const override { return fConic.dumpID(id); }
157 SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
159 SkOpGlobalState* globalState() const override { return fConic.globalState(); }
161 bool hullIntersects(const SkDQuad& quad, bool* isLinear) const override;
163 bool hullIntersects(const SkDConic& conic, bool* isLinear) const override {
164 return conic.hullIntersects(fConic, isLinear);
167 bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const override;
169 bool hullIntersects(const SkTCurve& curve, bool* isLinear) const override {
170 return curve.hullIntersects(fConic, isLinear);
173 int intersectRay(SkIntersections* i, const SkDLine& line) const override;
174 bool IsConic() const override { return true; }
175 SkTCurve* make(SkArenaAlloc& heap) const override { return heap.make<SkTConic>(); }
177 int maxIntersections() const override { return SkDConic::kMaxIntersections; }
179 void otherPts(int oddMan, const SkDPoint* endPt[2]) const override {
180 fConic.otherPts(oddMan, endPt);
183 int pointCount() const override { return SkDConic::kPointCount; }
184 int pointLast() const override { return SkDConic::kPointLast; }
185 SkDPoint ptAtT(double t) const override { return fConic.ptAtT(t); }
186 void setBounds(SkDRect* ) const override;
188 void subDivide(double t1, double t2, SkTCurve* curve) const override {
189 ((SkTConic*) curve)->fConic = fConic.subDivide(t1, t2);