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) {
126 return return_check_zero((
int)(r -
roots));
152 if ((t == 0 &&
src[0] ==
src[1]) || (t == 1 &&
src[1] ==
src[2])) {
166 return to_vector(
T +
T);
172 return v0 + (v1 - v0) * t;
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)) {
315 if (is_not_monotonic(
a,
b, c)) {
350 SkScalar numer = -(Ax * Bx + Ay * By);
359 if (numer >= denom) {
369 if (t > 0 && t < 1) {
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);
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;
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);
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);
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));
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)) {
642 auto C_x =
fma(kM[0],
src[0].fX,
645 auto C_y =
fma(kM[0],
src[0].fY,
648 auto coeffs = C_x * bisector.
x() + C_y * bisector.
y();
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];
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]) {
850 double q = 3*
D2 + copysign(
sqrt(3*discr),
D2);
854 }
else if (discr < 0) {
856 double q =
D2 + copysign(
sqrt(-discr),
D2);
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 },
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);
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) {
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;
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};
1189 double coefficients[8] = {
src[0].fX,
src[0].fY,
src[1].fX,
src[1].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,
1207 double solution = 0;
1209 double cubicPair[14];
1211 for (
int i = 0;
i < 7;
i ++) {
1257 coeff[0] =
w * P20 - P20;
1258 coeff[1] = P20 - 2 * wP10;
1287 dst[0].set(
src[0].fX * 1,
src[0].fY * 1, 1);
1289 dst[2].set(
src[2].fX * 1,
src[2].fY * 1, 1);
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);
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;
1454 dst[0].fPts[1] = p1;
1455 dst[0].fPts[2] = p2;
1456 dst[1].fPts[0] = p2;
1457 dst[1].fPts[1] = p3;
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));
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);
1704bool SkConic::findMaxCurvature(
SkScalar* t)
const {
1711 if (!
matrix.hasPerspective()) {
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);
1812 matrix.postConcat(*userMatrix);
1814 for (
int i = 0;
i < conicCount; ++
i) {
#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 constexpr bool SkIsNaN(T 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])
static skvx::float2 times_2(const skvx::float2 &value)
@ kCW_SkRotationDirection
@ kCCW_SkRotationDirection
static skvx::float2 from_point(const SkPoint &point)
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)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
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
static float max(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
const CatchEntryMove ab[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets dir
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SINT T dot(const Vec< N, T > &a, const Vec< N, T > &b)
SIN Vec< N, float > fma(const Vec< N, float > &x, const Vec< N, float > &y, const Vec< N, float > &z)
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
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
std::shared_ptr< const fml::Mapping > data