blob: 3d1c415598ce8cf24fced10af9cb3cadc935dc3f [file] [log] [blame]
hstern0446a3c2016-08-08 12:28:13 -07001/*
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
hstern23d97762016-08-09 09:38:30 -070011#include "SkPathMeasurePriv.h"
hstern0446a3c2016-08-08 12:28:13 -070012#include "SkPoint.h"
13#include "SkNx.h"
14
15// These are weights and abscissae for gaussian quadrature with weight function
16// w(x) = 1
17static SkScalar weights8[8] = {0.3626837833783620f, 0.3626837833783620f,
18 0.3137066458778873f, 0.3137066458778873f,
19 0.2223810344533745f, 0.2223810344533745f,
20 0.1012285362903763f, 0.1012285362903763f};
21static SkScalar absc8[8] = {-0.1834346424956498f, 0.1834346424956498f,
22 -0.5255324099163290f, 0.5255324099163290f,
23 -0.7966664774136267f, 0.7966664774136267f,
24 -0.9602898564975363f, 0.9602898564975363f};
25
26static Sk8f weights = Sk8f::Load(weights8);
27static Sk8f absc = 0.5f*(Sk8f::Load(absc8) + 1.0f);
28
29
hstern0446a3c2016-08-08 12:28:13 -070030class ArcLengthIntegrator {
31public:
32 ArcLengthIntegrator() {}
33 ArcLengthIntegrator(const SkPoint* pts, SkSegType segType);
34 SkScalar computeLength(SkScalar t);
35
36private:
37 SkSegType fSegType;
38
39 // precomputed coefficients for derivatives in Horner form
Mike Klein1e764642016-10-14 17:09:03 -040040 float xCoeff[3][8];
41 float yCoeff[3][8];
hstern0446a3c2016-08-08 12:28:13 -070042};
43
44class SkCurveMeasure {
45public:
46 SkCurveMeasure() {}
hstern5a4b18c2016-08-10 16:31:10 -070047
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
hstern0446a3c2016-08-08 12:28:13 -070056 SkCurveMeasure(const SkPoint* pts, SkSegType segType);
57
58 SkScalar getTime(SkScalar targetLength);
hstern80ac5912016-08-10 07:45:31 -070059 void getPosTanTime(SkScalar distance, SkPoint* pos, SkVector* tan, SkScalar* time);
hstern0446a3c2016-08-08 12:28:13 -070060 SkScalar getLength();
61
62private:
hstern0446a3c2016-08-08 12:28:13 -070063 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