• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/pathops/SkPathOpsQuad.h"
12  
13  struct SkDConic {
14      static const int kPointCount = 3;
15      static const int kPointLast = kPointCount - 1;
16      static const int kMaxIntersections = 4;
17  
18      SkDQuad fPts;
19      SkScalar fWeight;
20  
collapsedSkDConic21      bool collapsed() const {
22          return fPts.collapsed();
23      }
24  
controlsInsideSkDConic25      bool controlsInside() const {
26          return fPts.controlsInside();
27      }
28  
debugInitSkDConic29      void debugInit() {
30          fPts.debugInit();
31          fWeight = 0;
32      }
33  
34      void debugSet(const SkDPoint* pts, SkScalar weight);
35  
flipSkDConic36      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
globalStateSkDConic43      SkOpGlobalState* globalState() const { return fPts.globalState(); }
44  #endif
45  
IsConicSkDConic46      static bool IsConic() { return true; }
47  
setSkDConic48      const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight
49              SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
50          fPts.set(pts  SkDEBUGPARAMS(state));
51          fWeight = weight;
52          return *this;
53      }
54  
55      const SkDPoint& operator[](int n) const { return fPts[n]; }
56      SkDPoint& operator[](int n) { return fPts[n]; }
57  
AddValidTsSkDConic58      static int AddValidTs(double s[], int realRoots, double* t) {
59          return SkDQuad::AddValidTs(s, realRoots, t);
60      }
61  
alignSkDConic62      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  
hullIntersectsSkDConic69      bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
70          return fPts.hullIntersects(quad, isLinear);
71      }
72  
hullIntersectsSkDConic73      bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
74          return fPts.hullIntersects(conic.fPts, isLinear);
75      }
76  
77      bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
78  
isLinearSkDConic79      bool isLinear(int startIndex, int endIndex) const {
80          return fPts.isLinear(startIndex, endIndex);
81      }
82  
maxIntersectionsSkDConic83      static int maxIntersections() { return kMaxIntersections; }
84  
monotonicInXSkDConic85      bool monotonicInX() const {
86          return fPts.monotonicInX();
87      }
88  
monotonicInYSkDConic89      bool monotonicInY() const {
90          return fPts.monotonicInY();
91      }
92  
otherPtsSkDConic93      void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
94          fPts.otherPts(oddMan, endPt);
95      }
96  
pointCountSkDConic97      static int pointCount() { return kPointCount; }
pointLastSkDConic98      static int pointLast() { return kPointLast; }
99      SkDPoint ptAtT(double t) const;
100  
RootsRealSkDConic101      static int RootsReal(double A, double B, double C, double t[2]) {
102          return SkDQuad::RootsReal(A, B, C, t);
103      }
104  
RootsValidTSkDConic105      static int RootsValidT(const double A, const double B, const double C, double s[2]) {
106          return SkDQuad::RootsValidT(A, B, C, s);
107      }
108  
109      SkDConic subDivide(double t1, double t2) const;
subDivideSkDConic110      void subDivide(double t1, double t2, SkDConic* c) const { *c = this->subDivide(t1, t2); }
111  
SubDivideSkDConic112      static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
113          SkDConic conic;
114          conic.set(a, weight);
115          return conic.subDivide(t1, t2);
116      }
117  
118      SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
119              SkScalar* weight) const;
120  
SubDivideSkDConic121      static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
122                                const SkDPoint& a, const SkDPoint& c,
123                                double t1, double t2, SkScalar* newWeight) {
124          SkDConic conic;
125          conic.set(pts, weight);
126          return conic.subDivide(a, c, t1, t2, newWeight);
127      }
128  
129      // utilities callable by the user from the debugger when the implementation code is linked in
130      void dump() const;
131      void dumpID(int id) const;
132      void dumpInner() const;
133  
134  };
135  
136  class SkTConic : public SkTCurve {
137  public:
138      SkDConic fConic;
139  
SkTConic()140      SkTConic() {}
141  
SkTConic(const SkDConic & c)142      SkTConic(const SkDConic& c)
143          : fConic(c) {
144      }
145  
~SkTConic()146      ~SkTConic() override {}
147  
148      const SkDPoint& operator[](int n) const override { return fConic[n]; }
149      SkDPoint& operator[](int n) override { return fConic[n]; }
150  
collapsed()151      bool collapsed() const override { return fConic.collapsed(); }
controlsInside()152      bool controlsInside() const override { return fConic.controlsInside(); }
debugInit()153      void debugInit() override { return fConic.debugInit(); }
154  #if DEBUG_T_SECT
dumpID(int id)155      void dumpID(int id) const override { return fConic.dumpID(id); }
156  #endif
dxdyAtT(double t)157      SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
158  #ifdef SK_DEBUG
globalState()159      SkOpGlobalState* globalState() const override { return fConic.globalState(); }
160  #endif
161      bool hullIntersects(const SkDQuad& quad, bool* isLinear) const override;
162  
hullIntersects(const SkDConic & conic,bool * isLinear)163      bool hullIntersects(const SkDConic& conic, bool* isLinear) const override {
164          return conic.hullIntersects(fConic, isLinear);
165      }
166  
167      bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const override;
168  
hullIntersects(const SkTCurve & curve,bool * isLinear)169      bool hullIntersects(const SkTCurve& curve, bool* isLinear) const override {
170          return curve.hullIntersects(fConic, isLinear);
171      }
172  
173      int intersectRay(SkIntersections* i, const SkDLine& line) const override;
IsConic()174      bool IsConic() const override { return true; }
make(SkArenaAlloc & heap)175      SkTCurve* make(SkArenaAlloc& heap) const override { return heap.make<SkTConic>(); }
176  
maxIntersections()177      int maxIntersections() const override { return SkDConic::kMaxIntersections; }
178  
otherPts(int oddMan,const SkDPoint * endPt[2])179      void otherPts(int oddMan, const SkDPoint* endPt[2]) const override {
180          fConic.otherPts(oddMan, endPt);
181      }
182  
pointCount()183      int pointCount() const override { return SkDConic::kPointCount; }
pointLast()184      int pointLast() const override { return SkDConic::kPointLast; }
ptAtT(double t)185      SkDPoint ptAtT(double t) const override { return fConic.ptAtT(t); }
186      void setBounds(SkDRect* ) const override;
187  
subDivide(double t1,double t2,SkTCurve * curve)188      void subDivide(double t1, double t2, SkTCurve* curve) const override {
189          ((SkTConic*) curve)->fConic = fConic.subDivide(t1, t2);
190      }
191  };
192  
193  #endif
194