• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ArcLengthIntegrator()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:
SkCurveMeasure()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