49 return ab == 0 || bc < 0;
62 if (denom == 0 || numer == 0 || numer >= denom) {
80int return_check_zero(
int value) {
105 double dr = (double)
B *
B - 4 * (
double)
A *
C;
107 return return_check_zero(0);
112 return return_check_zero(0);
118 if (r - roots == 2) {
119 if (roots[0] > roots[1]) {
121 swap(roots[0], roots[1]);
122 }
else if (roots[0] == roots[1]) {
126 return return_check_zero((
int)(r - roots));
145 return to_point(SkQuadCoeff(src).eval(t));
152 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[1] == src[2])) {
153 return src[2] - src[0];
166 return to_vector(
T +
T);
172 return v0 + (v1 - v0) * t;
200 cosTheta = std::max(std::min(1.f, cosTheta), -1.f);
201 return acosf(cosTheta);
205 std::array<SkVector, 2> v;
209 }
else if (
a.cross(
b) >= 0) {
213 v[0].set(-
a.fY, +
a.fX);
214 v[1].set(+
b.fY, -
b.fX);
219 v[0].set(+
a.fY, -
a.fX);
220 v[1].set(-
b.fY, +
b.fX);
225 auto invLengths = 1.0f / sqrt(x0_x1 * x0_x1 + y0_y1 * y0_y1);
228 return SkPoint{x0_x1[0] + x0_x1[1], y0_y1[0] + y0_y1[1]};
253 if (!(
T > 0 &&
T < 1)) {
273 coords[2] = coords[6] = coords[4];
287 if (is_not_monotonic(
a,
b, c)) {
298 dst[0].set(src[0].fX,
a);
299 dst[1].set(src[1].fX,
b);
300 dst[2].set(src[2].fX, c);
315 if (is_not_monotonic(
a,
b, c)) {
326 dst[0].set(
a, src[0].fY);
327 dst[1].set(
b, src[1].fY);
328 dst[2].set(c, src[2].fY);
345 SkScalar Ax = src[1].fX - src[0].fX;
346 SkScalar Ay = src[1].fY - src[0].fY;
347 SkScalar Bx = src[0].fX - src[1].fX - src[1].fX + src[2].fX;
348 SkScalar By = src[0].fY - src[1].fY - src[1].fY + src[2].fY;
350 SkScalar numer = -(Ax * Bx + Ay * By);
359 if (numer >= denom) {
369 if (t > 0 && t < 1) {
373 memcpy(dst, src, 3 *
sizeof(
SkPoint));
401 coeff.fA = P3 + 3 * (P1 - P2) - P0;
404 return to_vector(coeff.eval(t));
412 float2 A = P3 + 3 * (P1 - P2) - P0;
415 return to_vector(
A * t +
B);
424 *loc =
to_point(SkCubicCoeff(src).eval(t));
430 if ((t == 0 && src[0] == src[1]) || (t == 1 && src[2] == src[3])) {
432 *tangent = src[2] - src[0];
434 *tangent = src[3] - src[1];
436 if (!tangent->
fX && !tangent->
fY) {
437 *tangent = src[3] - src[0];
467template<
int N,
typename T>
470 return (
b -
a)*t +
a;
477 memcpy(dst, src,
sizeof(
SkPoint) * 4);
478 dst[4] = dst[5] = dst[6] = src[3];
482 float2 p0 = sk_bit_cast<float2>(src[0]);
483 float2 p1 = sk_bit_cast<float2>(src[1]);
484 float2 p2 = sk_bit_cast<float2>(src[2]);
485 float2 p3 = sk_bit_cast<float2>(src[3]);
495 dst[0] = sk_bit_cast<SkPoint>(p0);
496 dst[1] = sk_bit_cast<SkPoint>(
ab);
497 dst[2] = sk_bit_cast<SkPoint>(abc);
498 dst[3] = sk_bit_cast<SkPoint>(abcd);
499 dst[4] = sk_bit_cast<SkPoint>(bcd);
500 dst[5] = sk_bit_cast<SkPoint>(cd);
501 dst[6] = sk_bit_cast<SkPoint>(p3);
505 SkASSERT(0 <= t0 && t0 <= t1 && t1 <= 1);
509 dst[7] = dst[8] = dst[9] = src[3];
515 p00.
lo = p00.
hi = sk_bit_cast<float2>(src[0]);
516 p11.
lo = p11.
hi = sk_bit_cast<float2>(src[1]);
517 p22.
lo = p22.
hi = sk_bit_cast<float2>(src[2]);
518 p33.
lo = p33.
hi = sk_bit_cast<float2>(src[3]);
530 dst[0] = sk_bit_cast<SkPoint>(p00.
lo);
531 dst[1] = sk_bit_cast<SkPoint>(
ab.lo);
532 dst[2] = sk_bit_cast<SkPoint>(abc.
lo);
533 dst[3] = sk_bit_cast<SkPoint>(abcd.
lo);
534 middle.
store(dst + 4);
535 dst[6] = sk_bit_cast<SkPoint>(abcd.
hi);
536 dst[7] = sk_bit_cast<SkPoint>(bcd.
hi);
537 dst[8] = sk_bit_cast<SkPoint>(cd.
hi);
538 dst[9] = sk_bit_cast<SkPoint>(p33.
hi);
542 const SkScalar tValues[],
int tCount) {
543 SkASSERT(std::all_of(tValues, tValues + tCount, [](
SkScalar t) {
return t >= 0 && t <= 1; }));
544 SkASSERT(std::is_sorted(tValues, tValues + tCount));
548 memcpy(dst, src, 4*
sizeof(
SkPoint));
551 for (; i < tCount - 1; i += 2) {
555 float lastT = tValues[i - 1];
564 float t = tValues[i];
566 float lastT = tValues[i - 1];
604 float q = -.5f * (
b + copysignf(sqrtf(discr),
b));
606 float _5qa = -.5f*q*
a;
609 if (!(
T > 0 &&
T < 1)) {
626 SkVector tan0 = (src[0] == src[1]) ? src[2] - src[0] : src[1] - src[0];
627 SkVector tan1 = (src[2] == src[3]) ? src[3] - src[1] : src[3] - src[2];
642 auto C_x =
fma(kM[0], src[0].fX,
643 fma(kM[1], src[1].fX,
645 auto C_y =
fma(kM[0], src[0].fY,
646 fma(kM[1], src[1].fY,
648 auto coeffs = C_x * bisector.
x() + C_y * bisector.
y();
652 float a=coeffs[0],
b=coeffs[1], c=coeffs[2];
653 float discr =
b*
b - 4*
a*c;
664 coeffs = C_x * tan0.
x() + C_y * tan0.
y();
677 if (!(
T > 0 &&
T < 1)) {
687 coords[4] = coords[8] = coords[6];
704 if (dst && roots > 0) {
720 if (dst && roots > 0) {
742 SkScalar Ax = src[1].fX - src[0].fX;
743 SkScalar Ay = src[1].fY - src[0].fY;
744 SkScalar Bx = src[2].fX - 2 * src[1].fX + src[0].fX;
745 SkScalar By = src[2].fY - 2 * src[1].fY + src[0].fY;
746 SkScalar Cx = src[3].fX + 3 * (src[1].fX - src[2].fX) - src[0].fX;
747 SkScalar Cy = src[3].fY + 3 * (src[1].fY - src[2].fY) - src[0].fY;
761 memcpy(dst, src, 4 *
sizeof(
SkPoint));
772 const double xComp = (double) p0.
fX * ((
double) p1.
fY - (double) p2.
fY);
773 const double yComp = (double) p0.
fY * ((
double) p2.
fX - (double) p1.
fX);
774 const double wComp = (double) p1.
fX * (
double) p2.
fY - (double) p1.
fY * (
double) p2.
fX;
775 return (xComp + yComp + wComp);
784 memcpy(&bits, &n,
sizeof(
double));
785 bits = ((1023llu*2 << 52) + ((1llu << 52) - 1)) - bits;
786 bits &= (0x7ffllu) << 52;
787 memcpy(&n, &bits,
sizeof(
double));
792 double* t,
double*
s) {
798 t[1] = -copysign(t1, t1 * s1);
802 if (copysign(
s[1],
s[0]) * t[0] > -fabs(
s[0]) * t[1]) {
823 double D1 = D2 - A2 + A1;
827 double Dmax = std::max(std::max(fabs(D1), fabs(D2)), fabs(D3));
847 double discr = 3*D2*D2 - 4*D1*D3;
850 double q = 3*D2 + copysign(sqrt(3*discr), D2);
854 }
else if (discr < 0) {
856 double q = D2 + copysign(sqrt(-discr), D2);
882 for (
int i =
count - 1; i > 0; --i)
883 for (
int j = i; j > 0; --j)
884 if (array[j] < array[j-1])
887 array[j] = array[j-1];
897 for (
int n =
count; n > 1; --n) {
898 if (array[0] == array[1]) {
899 for (
int i = 1; i < n; ++i) {
900 array[i - 1] = array[i];
912#define TEST_COLLAPS_ENTRY(array) array, std::size(array)
914static void test_collaps_duplicates() {
916 if (gOnce) {
return; }
921 const SkScalar src3[] = { 0, 0, 0 };
922 const SkScalar src4[] = { 0, 0, 1 };
923 const SkScalar src5[] = { 0, 1, 1 };
924 const SkScalar src6[] = { 0, 1, 2 };
930 { TEST_COLLAPS_ENTRY(src0), 1 },
931 { TEST_COLLAPS_ENTRY(src1), 1 },
932 { TEST_COLLAPS_ENTRY(src2), 2 },
933 { TEST_COLLAPS_ENTRY(src3), 1 },
934 { TEST_COLLAPS_ENTRY(src4), 2 },
935 { TEST_COLLAPS_ENTRY(src5), 2 },
936 { TEST_COLLAPS_ENTRY(src6), 3 },
938 for (
size_t i = 0; i < std::size(data); ++i) {
940 memcpy(dst, data[i].fData, data[i].fCount *
sizeof(dst[0]));
943 for (
int j = 1; j <
count; ++j) {
977 R = (2*
a*
a*
a - 9*
a*
b + 27*c) / 54;
1005 tValues[0] =
SkTPin(
A - adiv3, 0.0f, 1.0f);
1023 SkScalar b = src[4] - 2 * src[2] + src[0];
1024 SkScalar c = src[6] + 3 * (src[2] - src[4]) - src[0];
1027 coeff[1] = 3 *
b * c;
1028 coeff[2] = 2 *
b *
b + c *
a;
1050 for (i = 0; i < 4; i++) {
1051 coeffX[i] += coeffY[i];
1064 if (tValues ==
nullptr) {
1065 tValues = t_storage;
1073 for (
int i = 0; i < rootCount; ++i) {
1074 if (0 < roots[i] && roots[i] < 1) {
1075 tValues[
count++] = roots[i];
1081 memcpy(dst, src, 4 *
sizeof(
SkPoint));
1099 SkPoint origin = src[lineIndex];
1100 SkVector line = src[lineIndex + 1] - origin;
1102 for (
int index = 0; index < 2; ++index) {
1103 SkVector testLine = src[testIndex + index] - origin;
1104 crosses[index] = line.cross(testLine);
1106 return crosses[0] * crosses[1] >= 0;
1117 if (src[0] == src[1]) {
1120 if (src[2] == src[3]) {
1132 for (
int index = 0; index < roots; ++index) {
1133 SkScalar testT = maxCurvature[index];
1134 if (0 >= testT || testT >= 1) {
1143 if (dPtMagnitude < precision) {
1153 return std::fabs(
x) < 0.00001;
1157 double axisIntercept,
double* solution) {
1160 double roots[3] = {0, 0, 0};
1166 for (
int i = 0; i <
count; i++) {
1168 *solution = roots[i];
1179 for (
int i = 0; i <
count; i++) {
1181 *solution = roots[i];
1189 double coefficients[8] = {src[0].fX, src[0].fY, src[1].fX, src[1].fY,
1190 src[2].fX, src[2].fY, src[3].fX, src[3].fY};
1191 double solution = 0;
1193 double cubicPair[14];
1195 for (
int i = 0; i < 7; i ++) {
1205 double coefficients[8] = {src[0].fX, src[0].fY, src[1].fX, src[1].fY,
1206 src[2].fX, src[2].fY, src[3].fX, src[3].fY};
1207 double solution = 0;
1209 double cubicPair[14];
1211 for (
int i = 0; i < 7; i ++) {
1254 const SkScalar P20 = src[4] - src[0];
1255 const SkScalar P10 = src[2] - src[0];
1257 coeff[0] =
w * P20 - P20;
1258 coeff[1] = P20 - 2 * wP10;
1268 SkASSERT(0 == roots || 1 == roots);
1287 dst[0].set(src[0].fX * 1, src[0].fY * 1, 1);
1288 dst[1].set(src[1].fX *
w, src[1].fY *
w,
w);
1289 dst[2].set(src[2].fX * 1, src[2].fY * 1, 1);
1293 return {src.fX / src.fZ, src.fY / src.fZ};
1306 dst[0].fPts[0] =
fPts[0];
1308 dst[0].fPts[2] =
project_down(tmp2[1]); dst[1].fPts[0] = dst[0].fPts[2];
1310 dst[1].fPts[2] =
fPts[2];
1321 dst[0].fW = tmp2[0].
fZ / root;
1322 dst[1].fW = tmp2[2].
fZ / root;
1329 if (0 == t1 || 1 == t2) {
1330 if (0 == t1 && 1 == t2) {
1335 if (this->
chopAt(t1 ? t1 : t2, pair)) {
1341 SkConicCoeff coeff(*
this);
1343 float2 aXY = coeff.fNumer.eval(tt1);
1344 float2 aZZ = coeff.fDenom.eval(tt1);
1345 float2 midTT((t1 + t2) / 2);
1346 float2 dXY = coeff.fNumer.eval(midTT);
1347 float2 dZZ = coeff.fDenom.eval(midTT);
1349 float2 cXY = coeff.fNumer.eval(tt2);
1350 float2 cZZ = coeff.fDenom.eval(tt2);
1353 dst->fPts[0] =
to_point(aXY / aZZ);
1354 dst->fPts[1] =
to_point(bXY / bZZ);
1355 dst->fPts[2] =
to_point(cXY / cZZ);
1356 float2 ww = bZZ / sqrt(aZZ * cZZ);
1361 return to_point(SkConicCoeff(*this).eval(t));
1383 return to_vector(SkQuadCoeff(
A,
B,
C).eval(t));
1401#if defined(SK_SUPPORT_LEGACY_CONIC_CHOP)
1416 double w_2 = w_d * 2;
1417 double scale_half = 1 / (1 + w_d) * 0.5;
1423 dst[0].fPts[2] =
dst[1].fPts[0] = mPt;
1427 dst[0].fW =
dst[1].fW = newW;
1453 dst[0].fPts[0] =
fPts[0];
1454 dst[0].fPts[1] = p1;
1455 dst[0].fPts[2] = p2;
1456 dst[1].fPts[0] = p2;
1457 dst[1].fPts[1] = p3;
1458 dst[1].fPts[2] =
fPts[2];
1469#define AS_QUAD_ERROR_SETUP \
1470 SkScalar a = fW - 1; \
1471 SkScalar k = a / (4 * (2 + a)); \
1472 SkScalar x = k * (fPts[0].fX - 2 * fPts[1].fX + fPts[2].fX); \
1473 SkScalar y = k * (fPts[0].fY - 2 * fPts[1].fY + fPts[2].fY);
1482 return (
x *
x +
y *
y) <= tol * tol;
1486#define kMaxConicToQuadPOW2 5
1515 if (altPow2 != pow2) {
1516 SkDebugf(
"pow2 %d altPow2 %d fbits %g err %g tol %g\n", pow2, altPow2, fpow2, err, tol);
1526 return (
a -
b) * (c -
b) <= 0;
1533 memcpy(pts, &src.fPts[1], 2 *
sizeof(
SkPoint));
1538 const SkScalar startY = src.fPts[0].fY;
1540 if (
between(startY, src.fPts[1].fY, endY)) {
1544 if (!
between(startY, midY, endY)) {
1547 dst[0].fPts[2].fY = dst[1].fPts[0].fY = closerY;
1552 dst[0].fPts[1].fY = startY;
1557 dst[1].fPts[1].fY = endY;
1580 pts[1] = pts[2] = pts[3] = dst[0].fPts[1];
1581 pts[4] = dst[1].fPts[2];
1584 goto commonFinitePtCheck;
1589 const int quadCount = 1 << pow2;
1590 const int ptCount = 2 * quadCount + 1;
1595 for (
int i = 1; i < ptCount - 1; ++i) {
1633 float a = bisector.
dot(
A);
1634 float b = bisector.
dot(
B);
1635 float c = bisector.
dot(
C);
1650 if (!this->
chopAt(t, dst)) {
1657 dst[0].fPts[1].fX =
value;
1658 dst[1].fPts[0].fX =
value;
1659 dst[1].fPts[1].fX =
value;
1668 if (!this->
chopAt(t, dst)) {
1675 dst[0].fPts[1].fY =
value;
1676 dst[1].fPts[0].fY =
value;
1677 dst[1].fPts[1].fY =
value;
1696 bounds->setBounds(pts,
count);
1700 bounds->setBounds(
fPts, 3);
1704bool SkConic::findMaxCurvature(
SkScalar* t)
const {
1711 if (!matrix.hasPerspective()) {
1719 matrix.mapHomogeneousPoints(dst, src, 3);
1723 double w0 = dst[0].fZ;
1724 double w1 = dst[1].fZ;
1725 double w2 = dst[2].fZ;
1759 }
else if (0 ==
x) {
1761 quadrant =
y > 0 ? 1 : 3;
1766 if ((
x < 0) != (
y < 0)) {
1771 const SkPoint quadrantPts[] = {
1772 { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, { -1, 0 }, { -1, -1 }, { 0, -1 }, { 1, -1 }
1776 int conicCount = quadrant;
1777 for (
int i = 0; i < conicCount; ++i) {
1778 dst[i].set(&quadrantPts[i * 2], quadrantWeight);
1783 const SkPoint& lastQ = quadrantPts[quadrant * 2];
1800 dst[conicCount].set(lastQ, offCurve, finalP, cosThetaOver2);
1807 matrix.setSinCos(uStart.
fY, uStart.
fX);
1812 matrix.postConcat(*userMatrix);
1814 for (
int i = 0; i < conicCount; ++i) {
1815 matrix.mapPoints(dst[i].
fPts, 3);
#define SkASSERTF(cond, fmt,...)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static constexpr float sk_double_to_float(double x)
static bool SkIsFinite(T x, Pack... values)
static constexpr double sk_ieee_double_divide(double numer, double denom)
static constexpr float sk_ieee_float_divide(float numer, float denom)
static SkScalar subdivide_w_value(SkScalar w)
static skvx::Vec< N, T > unchecked_mix(const skvx::Vec< N, T > &a, const skvx::Vec< N, T > &b, const skvx::Vec< N, T > &t)
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t)
float SkFindQuadMidTangent(const SkPoint src[3])
static SkPoint project_down(const SkPoint3 &src)
int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5])
SkVector SkFindBisector(SkVector a, SkVector b)
static int collaps_duplicates(SkScalar array[], int count)
int SkChopCubicAtYExtrema(const SkPoint src[4], SkPoint dst[10])
static bool first_axis_intersection(const double coefficients[8], bool yDirection, double axisIntercept, double *solution)
static float solve_quadratic_equation_for_midtangent(float a, float b, float c, float discr)
void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7])
int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10])
float SkMeasureNonInflectCubicRotation(const SkPoint pts[4])
static void flatten_double_cubic_extrema(SkScalar coords[14])
static bool conic_find_extrema(const SkScalar src[], SkScalar w, SkScalar *t)
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t)
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2])
void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5])
SkScalar SkFindCubicCusp(const SkPoint src[4])
void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4])
static void conic_deriv_coeff(const SkScalar src[], SkScalar w, SkScalar coeff[3])
SkScalar SkFindQuadMaxCurvature(const SkPoint src[3])
static SkScalar SkScalarCubeRoot(SkScalar x)
int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar tValues[2])
static SkVector eval_cubic_2ndDerivative(const SkPoint src[4], SkScalar t)
static float2 interp(const float2 &v0, const float2 &v1, const float2 &t)
float SkMeasureAngleBetweenVectors(SkVector a, SkVector b)
SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t)
static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4])
static void ratquad_mapTo3D(const SkPoint src[3], SkScalar w, SkPoint3 dst[3])
SkCubicType SkClassifyCubic(const SkPoint P[4], double t[2], double s[2], double d[4])
static skvx::float4 fma(const skvx::float4 &f, float m, const skvx::float4 &a)
static double calc_dot_cross_cubic(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2)
#define kMaxConicToQuadPOW2
int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3])
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint *pt, SkVector *tangent)
#define AS_QUAD_ERROR_SETUP
bool SkChopMonoCubicAtY(const SkPoint src[4], SkScalar y, SkPoint dst[7])
int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10])
int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1])
float SkFindCubicMidTangent(const SkPoint src[4])
int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tValues[3])
static double previous_inverse_pow2(double n)
int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2])
static SkVector eval_cubic_derivative(const SkPoint src[4], SkScalar t)
static bool between(SkScalar a, SkScalar b, SkScalar c)
static void p3d_interp(const SkScalar src[7], SkScalar dst[7], SkScalar t)
static SkPoint * subdivide(const SkConic &src, SkPoint pts[], int level)
static SkScalar calc_cubic_precision(const SkPoint src[4])
static bool close_enough_to_zero(double x)
bool SkChopMonoCubicAtX(const SkPoint src[4], SkScalar x, SkPoint dst[7])
static bool on_same_side(const SkPoint src[4], int testIndex, int lineIndex)
void bubble_sort(T array[], int count)
static void write_cubic_inflection_roots(double t0, double s0, double t1, double s1, double *t, double *s)
static int solve_cubic_poly(const SkScalar coeff[4], SkScalar tValues[3])
static void flatten_double_quad_extrema(SkScalar coords[14])
int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5])
int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5])
SkVector SkFindBisector(SkVector, SkVector)
static skvx::float2 times_2(const skvx::float2 &value)
@ kCW_SkRotationDirection
@ kCCW_SkRotationDirection
static skvx::float2 from_point(const SkPoint &point)
static SkPoint to_point(const skvx::float2 &x)
static int valid_unit_divide(double numer, double denom, double *ratio)
void swap(sk_sp< T > &a, sk_sp< T > &b)
#define SkScalarInvert(x)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkDoubleToScalar(x)
#define SkScalarCeilToInt(x)
#define SK_ScalarNearlyZero
#define SkScalarCos(radians)
static SkScalar SkScalarInterp(SkScalar A, SkScalar B, SkScalar t)
#define SK_ScalarRoot2Over2
#define SkScalarPow(b, e)
#define SkScalarACos(val)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
static constexpr bool SkToBool(const T &x)
static std::array< double, 4 > ConvertToPolynomial(const double curve[8], bool yValues)
static void Subdivide(const double curve[8], double t, double twoCurves[14])
static int BinarySearchRootsValidT(double A, double B, double C, double D, double solution[3])
static double EvalAt(double A, double B, double C, double D, double t)
static int RootsValidT(double A, double B, double C, double D, double solution[3])
static SkScalar LengthSqd(const SkPoint &pt)
static bool AreFinite(const SkPoint array[], int count)
static bool EqualsWithinTolerance(const SkPoint &p1, const SkPoint &p2)
static SkScalar DistanceToSqd(const SkPoint &pt, const SkPoint &a)
static SkPoint to_point(SkIPoint p)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
const uint8_t uint32_t uint32_t GError ** error
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
SIN Vec< N, float > fma(const Vec< N, float > &x, const Vec< N, float > &y, const Vec< N, float > &z)
SINT Vec< N, T > pin(const Vec< N, T > &x, const Vec< N, T > &lo, const Vec< N, T > &hi)
bool findXExtrema(SkScalar *t) const
int SK_SPI chopIntoQuadsPOW2(SkPoint pts[], int pow2) const
SkVector evalTangentAt(SkScalar t) const
bool chopAtYExtrema(SkConic dst[2]) const
void computeTightBounds(SkRect *bounds) const
int SK_SPI computeQuadPOW2(SkScalar tol) const
static SkScalar TransformW(const SkPoint[3], SkScalar w, const SkMatrix &)
void computeAsQuadError(SkVector *err) const
bool findYExtrema(SkScalar *t) const
bool chopAtXExtrema(SkConic dst[2]) const
float findMidTangent() const
void evalAt(SkScalar t, SkPoint *pos, SkVector *tangent=nullptr) const
bool chopAt(SkScalar t, SkConic dst[2]) const
bool asQuadTol(SkScalar tol) const
void chop(SkConic dst[2]) const
static int BuildUnitArc(const SkVector &start, const SkVector &stop, SkRotationDirection, const SkMatrix *, SkConic conics[kMaxConicsForArc])
void computeFastBounds(SkRect *bounds) const
static float CrossProduct(const SkVector &a, const SkVector &b)
bool setLength(float length)
static float DotProduct(const SkVector &a, const SkVector &b)
float dot(const SkVector &vec) const
void set(float x, float y)
constexpr float y() const
constexpr float x() const
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
SKVX_ALWAYS_INLINE void store(void *ptr) const