Line data Source code
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 :
22 0 : bool collapsed() const {
23 0 : return fPts.collapsed();
24 : }
25 :
26 0 : bool controlsInside() const {
27 0 : return fPts.controlsInside();
28 : }
29 :
30 0 : void debugInit() {
31 0 : fPts.debugInit();
32 0 : }
33 :
34 : void debugSet(const SkDPoint* pts, SkScalar weight);
35 :
36 : SkDConic flip() const {
37 : SkDConic result = {{{fPts[2], fPts[1], fPts[0]}
38 : SkDEBUGPARAMS(fPts.fDebugGlobalState) }, fWeight};
39 : return result;
40 : }
41 :
42 : #ifdef SK_DEBUG
43 0 : SkOpGlobalState* globalState() const { return fPts.globalState(); }
44 : #endif
45 :
46 0 : static bool IsConic() { return true; }
47 :
48 0 : const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight
49 : SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
50 0 : fPts.set(pts SkDEBUGPARAMS(state));
51 0 : fWeight = weight;
52 0 : return *this;
53 : }
54 :
55 0 : const SkDPoint& operator[](int n) const { return fPts[n]; }
56 0 : 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 0 : bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
70 0 : return fPts.hullIntersects(quad, isLinear);
71 : }
72 :
73 0 : bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
74 0 : 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 :
83 0 : bool monotonicInX() const {
84 0 : return fPts.monotonicInX();
85 : }
86 :
87 0 : bool monotonicInY() const {
88 0 : return fPts.monotonicInY();
89 : }
90 :
91 0 : void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
92 0 : fPts.otherPts(oddMan, endPt);
93 0 : }
94 :
95 : SkDPoint ptAtT(double t) const;
96 :
97 : static int RootsReal(double A, double B, double C, double t[2]) {
98 : return SkDQuad::RootsReal(A, B, C, t);
99 : }
100 :
101 : static int RootsValidT(const double A, const double B, const double C, double s[2]) {
102 : return SkDQuad::RootsValidT(A, B, C, s);
103 : }
104 :
105 : SkDConic subDivide(double t1, double t2) const;
106 :
107 : static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
108 : SkDConic conic;
109 : conic.set(a, weight);
110 : return conic.subDivide(t1, t2);
111 : }
112 :
113 : SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
114 : SkScalar* weight) const;
115 :
116 0 : static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
117 : const SkDPoint& a, const SkDPoint& c,
118 : double t1, double t2, SkScalar* newWeight) {
119 : SkDConic conic;
120 0 : conic.set(pts, weight);
121 0 : return conic.subDivide(a, c, t1, t2, newWeight);
122 : }
123 :
124 : // utilities callable by the user from the debugger when the implementation code is linked in
125 : void dump() const;
126 : void dumpID(int id) const;
127 : void dumpInner() const;
128 :
129 : };
130 :
131 :
132 : #endif
|