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 "SkPathOpsPoint.h"
12 #include "SkPathOpsQuad.h"
13 
14 struct 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 
collapsedSkDConic22     bool collapsed() const {
23         return fPts.collapsed();
24     }
25 
controlsInsideSkDConic26     bool controlsInside() const {
27         return fPts.controlsInside();
28     }
29 
debugInitSkDConic30     void debugInit() {
31         fPts.debugInit();
32     }
33 
flipSkDConic34     SkDConic flip() const {
35         SkDConic result = {{{fPts[2], fPts[1], fPts[0]}}, fWeight};
36         return result;
37     }
38 
IsConicSkDConic39     static bool IsConic() { return true; }
40 
setSkDConic41     const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight) {
42         fPts.set(pts);
43         fWeight = weight;
44         return *this;
45     }
46 
47     const SkDPoint& operator[](int n) const { return fPts[n]; }
48     SkDPoint& operator[](int n) { return fPts[n]; }
49 
AddValidTsSkDConic50     static int AddValidTs(double s[], int realRoots, double* t) {
51         return SkDQuad::AddValidTs(s, realRoots, t);
52     }
53 
alignSkDConic54     void align(int endIndex, SkDPoint* dstPt) const {
55         fPts.align(endIndex, dstPt);
56     }
57 
58     SkDVector dxdyAtT(double t) const;
59     static int FindExtrema(const double src[], SkScalar weight, double tValue[1]);
60 
hullIntersectsSkDConic61     bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
62         return fPts.hullIntersects(quad, isLinear);
63     }
64 
hullIntersectsSkDConic65     bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
66         return fPts.hullIntersects(conic.fPts, isLinear);
67     }
68 
69     bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
70 
isLinearSkDConic71     bool isLinear(int startIndex, int endIndex) const {
72         return fPts.isLinear(startIndex, endIndex);
73     }
74 
monotonicInXSkDConic75     bool monotonicInX() const {
76         return fPts.monotonicInX();
77     }
78 
monotonicInYSkDConic79     bool monotonicInY() const {
80         return fPts.monotonicInY();
81     }
82 
otherPtsSkDConic83     void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
84         fPts.otherPts(oddMan, endPt);
85     }
86 
87     SkDPoint ptAtT(double t) const;
88 
RootsRealSkDConic89     static int RootsReal(double A, double B, double C, double t[2]) {
90         return SkDQuad::RootsReal(A, B, C, t);
91     }
92 
RootsValidTSkDConic93     static int RootsValidT(const double A, const double B, const double C, double s[2]) {
94         return SkDQuad::RootsValidT(A, B, C, s);
95     }
96 
97     SkDConic subDivide(double t1, double t2) const;
98 
SubDivideSkDConic99     static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
100         SkDConic conic;
101         conic.set(a, weight);
102         return conic.subDivide(t1, t2);
103     }
104 
105     SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
106             SkScalar* weight) const;
107 
SubDivideSkDConic108     static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
109                               const SkDPoint& a, const SkDPoint& c,
110                               double t1, double t2, SkScalar* newWeight) {
111         SkDConic conic;
112         conic.set(pts, weight);
113         return conic.subDivide(a, c, t1, t2, newWeight);
114     }
115 
116     // utilities callable by the user from the debugger when the implementation code is linked in
117     void dump() const;
118     void dumpID(int id) const;
119     void dumpInner() const;
120 };
121 
122 
123 #endif
124