Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright 2016 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 SkCurveMeasure_DEFINED
      9 #define SkCurveMeasure_DEFINED
     10 
     11 #include "SkPathMeasurePriv.h"
     12 #include "SkPoint.h"
     13 #include "SkNx.h"
     14 
     15 // These are weights and abscissae for gaussian quadrature with weight function
     16 // w(x) = 1
     17 static SkScalar weights8[8] = {0.3626837833783620f, 0.3626837833783620f,
     18                                0.3137066458778873f, 0.3137066458778873f,
     19                                0.2223810344533745f, 0.2223810344533745f,
     20                                0.1012285362903763f, 0.1012285362903763f};
     21 static SkScalar absc8[8] = {-0.1834346424956498f, 0.1834346424956498f,
     22                             -0.5255324099163290f, 0.5255324099163290f,
     23                             -0.7966664774136267f, 0.7966664774136267f,
     24                             -0.9602898564975363f, 0.9602898564975363f};
     25 
     26 static Sk8f weights = Sk8f::Load(weights8);
     27 static Sk8f absc = 0.5f*(Sk8f::Load(absc8) + 1.0f);
     28 
     29 
     30 class ArcLengthIntegrator {
     31 public:
     32     ArcLengthIntegrator() {}
     33     ArcLengthIntegrator(const SkPoint* pts, SkSegType segType);
     34     SkScalar computeLength(SkScalar t);
     35 
     36 private:
     37     SkSegType fSegType;
     38 
     39     // precomputed coefficients for derivatives in Horner form
     40     float xCoeff[3][8];
     41     float yCoeff[3][8];
     42 };
     43 
     44 class SkCurveMeasure {
     45 public:
     46     SkCurveMeasure() {}
     47 
     48     // Almost exactly the same as in SkPath::Iter:
     49     // kLine_SegType  -> 2 points: start end
     50     // kQuad_SegType  -> 3 points: start control end
     51     // kCubic_SegType -> 4 points: start control1 control2 end
     52     // kConic_SegType -> 4 points: start control end (w, w)
     53     //
     54     // i.e. the only difference is that the conic's last point is a point
     55     // consisting of the w value twice
     56     SkCurveMeasure(const SkPoint* pts, SkSegType segType);
     57 
     58     SkScalar getTime(SkScalar targetLength);
     59     void getPosTanTime(SkScalar distance, SkPoint* pos, SkVector* tan, SkScalar* time);
     60     SkScalar getLength();
     61 
     62 private:
     63     const SkScalar kTolerance = 0.0001f;
     64     const int kNewtonIters = 5;
     65     const int kBisectIters = 5;
     66 
     67     SkSegType fSegType;
     68     SkPoint fPts[4];
     69     SkScalar fLength = -1.0f;
     70     ArcLengthIntegrator fIntegrator;
     71 
     72     // for debug purposes
     73     int fIters;
     74 };
     75 
     76 #endif  // SkCurveMeasure_DEFINED
     77