Home | History | Annotate | Download | only in pathops
      1 /*
      2  * Copyright 2012 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 SkPathOpsQuad_DEFINED
      9 #define SkPathOpsQuad_DEFINED
     10 
     11 #include "SkPathOpsPoint.h"
     12 
     13 struct SkOpCurve;
     14 
     15 struct SkDQuadPair {
     16     const SkDQuad& first() const { return (const SkDQuad&) pts[0]; }
     17     const SkDQuad& second() const { return (const SkDQuad&) pts[2]; }
     18     SkDPoint pts[5];
     19 };
     20 
     21 struct SkDQuad {
     22     static const int kPointCount = 3;
     23     static const int kPointLast = kPointCount - 1;
     24     static const int kMaxIntersections = 4;
     25 
     26     SkDPoint fPts[kPointCount];
     27 
     28     bool collapsed() const {
     29         return fPts[0].approximatelyEqual(fPts[1]) && fPts[0].approximatelyEqual(fPts[2]);
     30     }
     31 
     32     bool controlsInside() const {
     33         SkDVector v01 = fPts[0] - fPts[1];
     34         SkDVector v02 = fPts[0] - fPts[2];
     35         SkDVector v12 = fPts[1] - fPts[2];
     36         return v02.dot(v01) > 0 && v02.dot(v12) > 0;
     37     }
     38 
     39     void debugInit() {
     40         sk_bzero(fPts, sizeof(fPts));
     41     }
     42 
     43     void debugSet(const SkDPoint* pts);
     44 
     45     SkDQuad flip() const {
     46         SkDQuad result = {{fPts[2], fPts[1], fPts[0]}  SkDEBUGPARAMS(fDebugGlobalState) };
     47         return result;
     48     }
     49 
     50     static bool IsConic() { return false; }
     51 
     52     const SkDQuad& set(const SkPoint pts[kPointCount]
     53             SkDEBUGPARAMS(SkOpGlobalState* state = nullptr)) {
     54         fPts[0] = pts[0];
     55         fPts[1] = pts[1];
     56         fPts[2] = pts[2];
     57         SkDEBUGCODE(fDebugGlobalState = state);
     58         return *this;
     59     }
     60 
     61     const SkDPoint& operator[](int n) const { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
     62     SkDPoint& operator[](int n) { SkASSERT(n >= 0 && n < kPointCount); return fPts[n]; }
     63 
     64     static int AddValidTs(double s[], int realRoots, double* t);
     65     void align(int endIndex, SkDPoint* dstPt) const;
     66     SkDQuadPair chopAt(double t) const;
     67     SkDVector dxdyAtT(double t) const;
     68     static int FindExtrema(const double src[], double tValue[1]);
     69 
     70 #ifdef SK_DEBUG
     71     SkOpGlobalState* globalState() const { return fDebugGlobalState; }
     72 #endif
     73 
     74     /**
     75      *  Return the number of valid roots (0 < root < 1) for this cubic intersecting the
     76      *  specified horizontal line.
     77      */
     78     int horizontalIntersect(double yIntercept, double roots[2]) const;
     79 
     80     bool hullIntersects(const SkDQuad& , bool* isLinear) const;
     81     bool hullIntersects(const SkDConic& , bool* isLinear) const;
     82     bool hullIntersects(const SkDCubic& , bool* isLinear) const;
     83     bool isLinear(int startIndex, int endIndex) const;
     84     bool monotonicInX() const;
     85     bool monotonicInY() const;
     86     void otherPts(int oddMan, const SkDPoint* endPt[2]) const;
     87     SkDPoint ptAtT(double t) const;
     88     static int RootsReal(double A, double B, double C, double t[2]);
     89     static int RootsValidT(const double A, const double B, const double C, double s[2]);
     90     static void SetABC(const double* quad, double* a, double* b, double* c);
     91     SkDQuad subDivide(double t1, double t2) const;
     92     static SkDQuad SubDivide(const SkPoint a[kPointCount], double t1, double t2) {
     93         SkDQuad quad;
     94         quad.set(a);
     95         return quad.subDivide(t1, t2);
     96     }
     97     SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2) const;
     98     static SkDPoint SubDivide(const SkPoint pts[kPointCount], const SkDPoint& a, const SkDPoint& c,
     99                               double t1, double t2) {
    100         SkDQuad quad;
    101         quad.set(pts);
    102         return quad.subDivide(a, c, t1, t2);
    103     }
    104 
    105     /**
    106      *  Return the number of valid roots (0 < root < 1) for this cubic intersecting the
    107      *  specified vertical line.
    108      */
    109     int verticalIntersect(double xIntercept, double roots[2]) const;
    110 
    111     SkDCubic debugToCubic() const;
    112     // utilities callable by the user from the debugger when the implementation code is linked in
    113     void dump() const;
    114     void dumpID(int id) const;
    115     void dumpInner() const;
    116 
    117     SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState);
    118 };
    119 
    120 #endif
    121