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
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
34    SkDConic flip() const {
35        SkDConic result = {{{fPts[2], fPts[1], fPts[0]}}, fWeight};
36        return result;
37    }
38
39    static bool IsCubic() { return false; }
40
41    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
50    static int AddValidTs(double s[], int realRoots, double* t) {
51        return SkDQuad::AddValidTs(s, realRoots, t);
52    }
53
54    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
61    bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
62        return fPts.hullIntersects(quad, isLinear);
63    }
64
65    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
71    bool isLinear(int startIndex, int endIndex) const {
72        return fPts.isLinear(startIndex, endIndex);
73    }
74
75    bool monotonicInX() const {
76        return fPts.monotonicInX();
77    }
78
79    bool monotonicInY() const {
80        return fPts.monotonicInY();
81    }
82
83    void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
84        fPts.otherPts(oddMan, endPt);
85    }
86
87    SkDPoint ptAtT(double t) const;
88
89    static int RootsReal(double A, double B, double C, double t[2]) {
90        return SkDQuad::RootsReal(A, B, C, t);
91    }
92
93    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
99    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
108    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