11049f1246e7be4ccb68001361efceb8933e6f81ccaryclark/*
21049f1246e7be4ccb68001361efceb8933e6f81ccaryclark * Copyright 2015 Google Inc.
31049f1246e7be4ccb68001361efceb8933e6f81ccaryclark *
41049f1246e7be4ccb68001361efceb8933e6f81ccaryclark * Use of this source code is governed by a BSD-style license that can be
51049f1246e7be4ccb68001361efceb8933e6f81ccaryclark * found in the LICENSE file.
61049f1246e7be4ccb68001361efceb8933e6f81ccaryclark */
71049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
81049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#ifndef SkPathOpsConic_DEFINED
91049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#define SkPathOpsConic_DEFINED
101049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#include "SkPathOpsPoint.h"
121049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#include "SkPathOpsQuad.h"
131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
141049f1246e7be4ccb68001361efceb8933e6f81ccaryclarkstruct SkDConic {
151049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static const int kPointCount = 3;
161049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static const int kPointLast = kPointCount - 1;
171049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static const int kMaxIntersections = 4;
181049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
191049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDQuad fPts;
201049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkScalar fWeight;
211049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
221049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool collapsed() const {
231049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.collapsed();
241049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
251049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
261049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool controlsInside() const {
271049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.controlsInside();
281049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
291049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
301049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void debugInit() {
311049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        fPts.debugInit();
321049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
331049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
341049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDConic flip() const {
351049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDConic result = {{{fPts[2], fPts[1], fPts[0]}}, fWeight};
361049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return result;
371049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
381049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
392880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    static bool IsConic() { return true; }
401049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
411049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    const SkDConic& set(const SkPoint pts[kPointCount], SkScalar weight) {
421049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        fPts.set(pts);
431049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        fWeight = weight;
441049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return *this;
451049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
461049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
471049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    const SkDPoint& operator[](int n) const { return fPts[n]; }
481049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDPoint& operator[](int n) { return fPts[n]; }
491049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
501049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static int AddValidTs(double s[], int realRoots, double* t) {
511049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return SkDQuad::AddValidTs(s, realRoots, t);
521049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
531049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
541049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void align(int endIndex, SkDPoint* dstPt) const {
551049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        fPts.align(endIndex, dstPt);
561049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
571049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
581049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDVector dxdyAtT(double t) const;
591049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static int FindExtrema(const double src[], SkScalar weight, double tValue[1]);
601049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
611049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool hullIntersects(const SkDQuad& quad, bool* isLinear) const {
621049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.hullIntersects(quad, isLinear);
631049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
641049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
651049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool hullIntersects(const SkDConic& conic, bool* isLinear) const {
661049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.hullIntersects(conic.fPts, isLinear);
671049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
681049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
691049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool hullIntersects(const SkDCubic& cubic, bool* isLinear) const;
701049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
711049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool isLinear(int startIndex, int endIndex) const {
721049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.isLinear(startIndex, endIndex);
731049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
741049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
75aec251012542e971100e218bf463adbfb5d21d20caryclark    bool monotonicInX() const {
76aec251012542e971100e218bf463adbfb5d21d20caryclark        return fPts.monotonicInX();
77aec251012542e971100e218bf463adbfb5d21d20caryclark    }
78aec251012542e971100e218bf463adbfb5d21d20caryclark
791049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    bool monotonicInY() const {
801049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return fPts.monotonicInY();
811049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
821049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
831049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void otherPts(int oddMan, const SkDPoint* endPt[2]) const {
841049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        fPts.otherPts(oddMan, endPt);
851049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
861049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
871049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDPoint ptAtT(double t) const;
881049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
891049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static int RootsReal(double A, double B, double C, double t[2]) {
901049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return SkDQuad::RootsReal(A, B, C, t);
911049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
921049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
931049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static int RootsValidT(const double A, const double B, const double C, double s[2]) {
941049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return SkDQuad::RootsValidT(A, B, C, s);
951049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
961049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
971049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDConic subDivide(double t1, double t2) const;
981049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
991049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static SkDConic SubDivide(const SkPoint a[kPointCount], SkScalar weight, double t1, double t2) {
1001049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDConic conic;
1011049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        conic.set(a, weight);
1021049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return conic.subDivide(t1, t2);
1031049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
1041049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1051049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    SkDPoint subDivide(const SkDPoint& a, const SkDPoint& c, double t1, double t2,
1061049f1246e7be4ccb68001361efceb8933e6f81ccaryclark            SkScalar* weight) const;
1071049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1081049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    static SkDPoint SubDivide(const SkPoint pts[kPointCount], SkScalar weight,
1091049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                              const SkDPoint& a, const SkDPoint& c,
1101049f1246e7be4ccb68001361efceb8933e6f81ccaryclark                              double t1, double t2, SkScalar* newWeight) {
1111049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        SkDConic conic;
1121049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        conic.set(pts, weight);
1131049f1246e7be4ccb68001361efceb8933e6f81ccaryclark        return conic.subDivide(a, c, t1, t2, newWeight);
1141049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    }
1151049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1161049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    // utilities callable by the user from the debugger when the implementation code is linked in
1171049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void dump() const;
1181049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void dumpID(int id) const;
1191049f1246e7be4ccb68001361efceb8933e6f81ccaryclark    void dumpInner() const;
1201049f1246e7be4ccb68001361efceb8933e6f81ccaryclark};
1211049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1221049f1246e7be4ccb68001361efceb8933e6f81ccaryclark
1231049f1246e7be4ccb68001361efceb8933e6f81ccaryclark#endif
124