32 const double adjust =
sqrt(3.) / 36;
43 double dx = c[3].fX - 3 * (c[2].fX - c[1].fX) - c[0].fX;
44 double dy = c[3].fY - 3 * (c[2].fY - c[1].fY) - c[0].fY;
45 double dist =
sqrt(
dx *
dx + dy * dy);
46 double tDiv3 = precision / (adjust * dist);
47 double t = std::cbrt(tDiv3);
70 for (
double index = 0; index <
parts; ++index) {
72 if (newT > 0 && newT < 1) {
85 int inflections =
cubic->findInflections(inflectT);
87 if (!
cubic->endsAreExtremaInXOrY()) {
88 inflections +=
cubic->findMaxCurvature(&inflectT[inflections]);
91 SkTQSort<double>(inflectT, inflectT + inflections);
95 memmove(inflectT, &inflectT[1],
sizeof(inflectT[0]) * --inflections);
99 while (
next < inflections) {
105 memmove(&inflectT[
start], &inflectT[
next],
sizeof(inflectT[0]) * (--inflections -
start));
112 if (inflections == 1) {
113 pair =
cubic->chopAt(inflectT[0]);
127 if (inflections == 1) {
128 pair =
cubic->chopAt(inflectT[0]);
129 addTs(pair.
first(), precision, 0, inflectT[0], ts);
130 addTs(pair.
second(), precision, inflectT[0], 1, ts);
133 if (inflections > 1) {
135 addTs(part, precision, 0, inflectT[0], ts);
136 int last = inflections - 1;
137 for (
int idx = 0; idx < last; ++idx) {
138 part =
cubic->subDivide(inflectT[idx], inflectT[idx + 1]);
139 addTs(part, precision, inflectT[idx], inflectT[idx + 1], ts);
141 part =
cubic->subDivide(inflectT[last], 1);
142 addTs(part, precision, inflectT[last], 1, ts);
157 for (
int i1 = 0; i1 <= ts.
size(); ++i1) {
158 const double tEnd = i1 < ts.
size() ? ts[i1] : 1;
163 if (quad[1].fX <
bounds.fLeft) {
164 quad[1].fX =
bounds.fLeft;
165 }
else if (quad[1].fX >
bounds.fRight) {
166 quad[1].fX =
bounds.fRight;
168 if (quad[1].fY <
bounds.fTop) {
170 }
else if (quad[1].fY >
bounds.fBottom) {
171 quad[1].fY =
bounds.fBottom;
185 quadPath->
moveTo(pts[0].fX, pts[0].fY);
188 quadPath->
lineTo(pts[1].fX, pts[1].fY);
191 quadPath->
quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
197 for (
int index = 0; index < quads.
size(); ++index) {
199 quads[index][1].asSkPoint(),
200 quads[index][2].asSkPoint()
202 quadPath->
quadTo(qPts[0].fX, qPts[0].fY, qPts[1].fX, qPts[1].fY);
221 simplePath->
moveTo(pts[0].fX, pts[0].fY);
224 simplePath->
lineTo(pts[1].fX, pts[1].fY);
227 simplePath->
quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
232 int inflections =
cubic.findInflections(tInflects);
233 if (inflections > 1 && tInflects[0] > tInflects[1]) {
235 swap(tInflects[0], tInflects[1]);
238 for (
int index = 0; index <= inflections; ++index) {
239 double hi = index < inflections ? tInflects[index] : 1;
242 cPts[0] = part[1].asSkPoint();
243 cPts[1] = part[2].asSkPoint();
244 cPts[2] = part[3].asSkPoint();
245 simplePath->
cubicTo(cPts[0].fX, cPts[0].fY, cPts[1].fX, cPts[1].fY,
246 cPts[2].fX, cPts[2].fY);
287 for (
int index = 0; index < 4; ++index) {
296 for (
int index = 0; index < 2; ++index) {
312 for (
int index = 0; index <
count; ++index) {
324 for (
int index = 0; index < 3; ++index) {
static float next(float f)
void CubicPathToQuads(const SkPath &cubicPath, SkPath *quadPath)
static bool add_simple_ts(const SkDCubic &cubic, double precision, TArray< double, true > *ts)
void CubicPathToSimple(const SkPath &cubicPath, SkPath *simplePath)
bool ValidCubic(const SkDCubic &cubic)
void CubicToQuads(const SkDCubic &cubic, double precision, TArray< SkDQuad, true > &quads)
bool ValidVector(const SkDVector &v)
bool ValidConic(const SkDConic &conic)
bool ValidPoints(const SkPoint *pts, int count)
static void addTs(const SkDCubic &cubic, double precision, double start, double end, TArray< double, true > *ts)
static void toQuadraticTs(const SkDCubic *cubic, double precision, TArray< double, true > *ts)
bool ValidPoint(const SkDPoint &pt)
bool ValidBounds(const SkPathOpsBounds &bounds)
bool ValidLine(const SkDLine &line)
static double calc_t_div(const SkDCubic &cubic, double precision, double start)
bool ValidQuad(const SkDQuad &quad)
#define SkDEBUGFAIL(message)
static constexpr bool SkIsNaN(T x)
static bool SkDoubleIsNaN(double x)
bool approximately_less_than_zero(double x)
bool approximately_equal(double x, double y)
bool approximately_greater_than_one(double x)
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
void swap(sk_sp< T > &a, sk_sp< T > &b)
SkPath & moveTo(SkScalar x, SkScalar y)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Optional< SkRect > bounds
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
static const int kPointCount
int reduce(const SkDCubic &cubic, Quadratics)