Home | History | Annotate | Download | only in pathops
      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 "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 
     21     bool collapsed() const {
     22         return fPts.collapsed();
     23     }
     24 
     25     bool controlsInside() const {
     26         return fPts.controlsInside();
     27     }
     28 
     29     void debugInit() {
     30         fPts.debugInit();
     31         fWeight = 0;
     32     }
     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     SkOpGlobalState* globalState() const { return fPts.globalState(); }
     44 #endif
     45 
     46     static bool IsConic() { return true; }
     47 
     48     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 
     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     bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
     70         return fPts.hullIntersects(quad, isLinear);
     71     }
     72 
     73     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 
     79     bool isLinear(int startIndex, int endIndex) const {
     80         return fPts.isLinear(startIndex, endIndex);
     81     }
     82 
     83     static int maxIntersections() { return kMaxIntersections; }
     84 
     85     bool monotonicInX() const {
     86         return fPts.monotonicInX();
     87     }
     88 
     89     bool monotonicInY() const {
     90         return fPts.monotonicInY();
     91     }
     92 
     93     void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
     94         fPts.otherPts(oddMan, endPt);
     95     }
     96 
     97     static int pointCount() { return kPointCount; }
     98     static int pointLast() { return kPointLast; }
     99     SkDPoint ptAtT(double t) const;
    100 
    101     static int RootsReal(double A, double B, double C, double t[2]) {
    102         return SkDQuad::RootsReal(A, B, C, t);
    103     }
    104 
    105     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;
    110     void subDivide(double t1, double t2, SkDConic* c) const { *c = this->subDivide(t1, t2); }
    111 
    112     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 
    121     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 
    140     SkTConic() {}
    141 
    142     SkTConic(const SkDConic& c)
    143         : fConic(c) {
    144     }
    145 
    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 
    151     bool collapsed() const override { return fConic.collapsed(); }
    152     bool controlsInside() const override { return fConic.controlsInside(); }
    153     void debugInit() override { return fConic.debugInit(); }
    154 #if DEBUG_T_SECT
    155     void dumpID(int id) const override { return fConic.dumpID(id); }
    156 #endif
    157     SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
    158 #ifdef SK_DEBUG
    159     SkOpGlobalState* globalState() const override { return fConic.globalState(); }
    160 #endif
    161     bool hullIntersects(const SkDQuad& quad, bool* isLinear) const override;
    162 
    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 
    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;
    174     bool IsConic() const override { return true; }
    175     SkTCurve* make(SkArenaAlloc& heap) const override { return heap.make<SkTConic>(); }
    176 
    177     int maxIntersections() const override { return SkDConic::kMaxIntersections; }
    178 
    179     void otherPts(int oddMan, const SkDPoint* endPt[2]) const override {
    180         fConic.otherPts(oddMan, endPt);
    181     }
    182 
    183     int pointCount() const override { return SkDConic::kPointCount; }
    184     int pointLast() const override { return SkDConic::kPointLast; }
    185     SkDPoint ptAtT(double t) const override { return fConic.ptAtT(t); }
    186     void setBounds(SkDRect* ) const override;
    187 
    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