xref: /aosp_15_r20/external/skia/src/pathops/SkPathOpsConic.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
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 "include/core/SkPoint.h"
12 #include "include/core/SkScalar.h"
13 #include "include/private/base/SkDebug.h"
14 #include "src/base/SkArenaAlloc.h"
15 #include "src/pathops/SkPathOpsDebug.h"
16 #include "src/pathops/SkPathOpsPoint.h"
17 #include "src/pathops/SkPathOpsQuad.h"
18 #include "src/pathops/SkPathOpsTCurve.h"
19 
20 class SkIntersections;
21 class SkOpGlobalState;
22 struct SkDCubic;
23 struct SkDLine;
24 struct SkDRect;
25 
26 struct SkDConic {
27     static const int kPointCount = 3;
28     static const int kPointLast = kPointCount - 1;
29     static const int kMaxIntersections = 4;
30 
31     SkDQuad fPts;
32     SkScalar fWeight;
33 
collapsedSkDConic34     bool collapsed() const {
35         return fPts.collapsed();
36     }
37 
controlsInsideSkDConic38     bool controlsInside() const {
39         return fPts.controlsInside();
40     }
41 
debugInitSkDConic42     void debugInit() {
43         fPts.debugInit();
44         fWeight = 0;
45     }
46 
47     void debugSet(const SkDPoint* pts, SkScalar weight);
48 
flipSkDConic49     SkDConic flip() const {
50         SkDConic result = {{{fPts[2], fPts[1], fPts[0]}
51                 SkDEBUGPARAMS(fPts.fDebugGlobalState) }, fWeight};
52         return result;
53     }
54 
55 #ifdef SK_DEBUG
globalStateSkDConic56     SkOpGlobalState* globalState() const { return fPts.globalState(); }
57 #endif
58 
IsConicSkDConic59     static bool IsConic() { return true; }
60 
setSkDConic61     const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight
62             SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
63         fPts.set(pts  SkDEBUGPARAMS(state));
64         fWeight = weight;
65         return *this;
66     }
67 
68     const SkDPoint& operator[](int n) const { return fPts[n]; }
69     SkDPoint& operator[](int n) { return fPts[n]; }
70 
AddValidTsSkDConic71     static int AddValidTs(double s[], int realRoots, double* t) {
72         return SkDQuad::AddValidTs(s, realRoots, t);
73     }
74 
alignSkDConic75     void align(int endIndex, SkDPoint* dstPt) const {
76         fPts.align(endIndex, dstPt);
77     }
78 
79     SkDVector dxdyAtT(double t) const;
80     static int FindExtrema(const double src[], SkScalar weight, double tValue[1]);
81 
hullIntersectsSkDConic82     bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
83         return fPts.hullIntersects(quad, isLinear);
84     }
85 
hullIntersectsSkDConic86     bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
87         return fPts.hullIntersects(conic.fPts, isLinear);
88     }
89 
90     bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
91 
isLinearSkDConic92     bool isLinear(int startIndex, int endIndex) const {
93         return fPts.isLinear(startIndex, endIndex);
94     }
95 
maxIntersectionsSkDConic96     static int maxIntersections() { return kMaxIntersections; }
97 
monotonicInXSkDConic98     bool monotonicInX() const {
99         return fPts.monotonicInX();
100     }
101 
monotonicInYSkDConic102     bool monotonicInY() const {
103         return fPts.monotonicInY();
104     }
105 
otherPtsSkDConic106     void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
107         fPts.otherPts(oddMan, endPt);
108     }
109 
pointCountSkDConic110     static int pointCount() { return kPointCount; }
pointLastSkDConic111     static int pointLast() { return kPointLast; }
112     SkDPoint ptAtT(double t) const;
113 
RootsRealSkDConic114     static int RootsReal(double A, double B, double C, double t[2]) {
115         return SkDQuad::RootsReal(A, B, C, t);
116     }
117 
RootsValidTSkDConic118     static int RootsValidT(const double A, const double B, const double C, double s[2]) {
119         return SkDQuad::RootsValidT(A, B, C, s);
120     }
121 
122     SkDConic subDivide(double t1, double t2) const;
subDivideSkDConic123     void subDivide(double t1, double t2, SkDConic* c) const { *c = this->subDivide(t1, t2); }
124 
SubDivideSkDConic125     static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
126         SkDConic conic;
127         conic.set(a, weight);
128         return conic.subDivide(t1, t2);
129     }
130 
131     SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
132             SkScalar* weight) const;
133 
SubDivideSkDConic134     static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
135                               const SkDPoint& a, const SkDPoint& c,
136                               double t1, double t2, SkScalar* newWeight) {
137         SkDConic conic;
138         conic.set(pts, weight);
139         return conic.subDivide(a, c, t1, t2, newWeight);
140     }
141 
142     // utilities callable by the user from the debugger when the implementation code is linked in
143     void dump() const;
144     void dumpID(int id) const;
145     void dumpInner() const;
146 
147 };
148 
149 class SkTConic : public SkTCurve {
150 public:
151     SkDConic fConic;
152 
SkTConic()153     SkTConic() {}
154 
SkTConic(const SkDConic & c)155     SkTConic(const SkDConic& c)
156         : fConic(c) {
157     }
158 
~SkTConic()159     ~SkTConic() override {}
160 
161     const SkDPoint& operator[](int n) const override { return fConic[n]; }
162     SkDPoint& operator[](int n) override { return fConic[n]; }
163 
collapsed()164     bool collapsed() const override { return fConic.collapsed(); }
controlsInside()165     bool controlsInside() const override { return fConic.controlsInside(); }
debugInit()166     void debugInit() override { return fConic.debugInit(); }
167 #if DEBUG_T_SECT
dumpID(int id)168     void dumpID(int id) const override { return fConic.dumpID(id); }
169 #endif
dxdyAtT(double t)170     SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
171 #ifdef SK_DEBUG
globalState()172     SkOpGlobalState* globalState() const override { return fConic.globalState(); }
173 #endif
174     bool hullIntersects(const SkDQuad& quad, bool* isLinear) const override;
175 
hullIntersects(const SkDConic & conic,bool * isLinear)176     bool hullIntersects(const SkDConic& conic, bool* isLinear) const override {
177         return conic.hullIntersects(fConic, isLinear);
178     }
179 
180     bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const override;
181 
hullIntersects(const SkTCurve & curve,bool * isLinear)182     bool hullIntersects(const SkTCurve& curve, bool* isLinear) const override {
183         return curve.hullIntersects(fConic, isLinear);
184     }
185 
186     int intersectRay(SkIntersections* i, const SkDLine& line) const override;
IsConic()187     bool IsConic() const override { return true; }
make(SkArenaAlloc & heap)188     SkTCurve* make(SkArenaAlloc& heap) const override { return heap.make<SkTConic>(); }
189 
maxIntersections()190     int maxIntersections() const override { return SkDConic::kMaxIntersections; }
191 
otherPts(int oddMan,const SkDPoint * endPt[2])192     void otherPts(int oddMan, const SkDPoint* endPt[2]) const override {
193         fConic.otherPts(oddMan, endPt);
194     }
195 
pointCount()196     int pointCount() const override { return SkDConic::kPointCount; }
pointLast()197     int pointLast() const override { return SkDConic::kPointLast; }
ptAtT(double t)198     SkDPoint ptAtT(double t) const override { return fConic.ptAtT(t); }
199     void setBounds(SkDRect* ) const override;
200 
subDivide(double t1,double t2,SkTCurve * curve)201     void subDivide(double t1, double t2, SkTCurve* curve) const override {
202         ((SkTConic*) curve)->fConic = fConic.subDivide(t1, t2);
203     }
204 };
205 
206 #endif
207