36 static constexpr uint32_t kMaxChopsPerCurve = 10;
38 return 1 << std::min(chopCount, kMaxChopsPerCurve);
43 const SkRect& pathBounds) {
51 for (
int i = 0; i < 4; ++i) {
63 srcTol = std::max(pathBounds.
width(), pathBounds.
height());
65 srcTol = devTol / stretch;
83 uint32_t pointsLeft) {
114 uint32_t pointsLeft) {
115 if (pointsLeft < 2 ||
150 double x0 = qPts[0].
fX;
151 double y0 = qPts[0].
fY;
152 double x1 = qPts[1].
fX;
153 double y1 = qPts[1].
fY;
154 double x2 = qPts[2].
fX;
155 double y2 = qPts[2].
fY;
158 double a2 = x1*y2-x2*y1;
159 double a5 = x2*y0-x0*y2;
160 double a8 = x0*y1-x1*y0;
161 double det = a2 + a5 + a8;
182 SkVector lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge];
194 fM[5] = -lineVec.
dot(qPts[maxEdge]);
198 fM[0] = 0; fM[1] = 0; fM[2] = 100.f;
199 fM[3] = 0; fM[4] = 0; fM[5] = 100.f;
202 double scale = 1.0/det;
205 double a3, a4, a6, a7;
214 fM[0] = (float)((0.5*a3 + a6)*
scale);
215 fM[1] = (float)((0.5*a4 + a7)*
scale);
216 fM[2] = (float)((0.5*a5 + a8)*
scale);
217 fM[3] = (float)(a6*
scale);
218 fM[4] = (float)(a7*
scale);
219 fM[5] = (float)(a8*
scale);
231 klm[0] = p[2].fY - p[0].fY;
232 klm[1] = p[0].fX - p[2].fX;
233 klm[2] = p[2].fX * p[0].fY - p[0].fX * p[2].fY;
235 klm[3] = w2 * (p[1].fY - p[0].fY);
236 klm[4] = w2 * (p[0].fX - p[1].fX);
237 klm[5] = w2 * (p[1].fX * p[0].fY - p[0].fX * p[1].fY);
239 klm[6] = w2 * (p[2].fY - p[1].fY);
240 klm[7] = w2 * (p[1].fX - p[2].fX);
241 klm[8] = w2 * (p[2].fX * p[1].fY - p[1].fX * p[2].fY);
245 for (
int i = 0; i < 9; ++i) {
250 for (
int i = 0; i < 9; ++i) {
265bool is_point_within_cubic_tangents(
const SkPoint&
a,
299void convert_noninflect_cubic_to_quads(
const SkPoint p[4],
303 bool preserveFirstTangent =
true,
304 bool preserveLastTangent =
true) {
325 static const int kMaxSubdivs = 10;
327 ab.scale(kLengthScale);
328 dc.
scale(kLengthScale);
335 if (dSqd < toleranceSqd) {
337 if (preserveFirstTangent == preserveLastTangent) {
343 newC = (c0 + c1) * 0.5f;
344 }
else if (preserveFirstTangent) {
358 convert_noninflect_cubic_to_quads(
359 choppedPts + 0, toleranceSqd, quads, sublevel + 1, preserveFirstTangent,
false);
360 convert_noninflect_cubic_to_quads(
361 choppedPts + 3, toleranceSqd, quads, sublevel + 1,
false, preserveLastTangent);
364void convert_noninflect_cubic_to_quads_with_constraint(
const SkPoint p[4],
409 if (detABSqd * invDALengthSqd < toleranceSqd &&
410 detDCSqd * invDALengthSqd < toleranceSqd) {
440 static const int kMaxSubdivs = 10;
442 ab.scale(kLengthScale);
443 dc.scale(kLengthScale);
450 if (dSqd < toleranceSqd) {
451 SkPoint cAvg = (c0 + c1) * 0.5f;
454 if (!is_point_within_cubic_tangents(p[0],
ab, dc, p[3], dir, cAvg)) {
460 cAvg.
fX =
ab.fY * z1 - z0 * dc.fY;
461 cAvg.
fY = z0 * dc.fX -
ab.fX * z1;
466 if (sublevel <= kMaxSubdivs) {
474 subdivide = 2 * d0d1 + d0Sqd + d1Sqd > toleranceSqd;
487 convert_noninflect_cubic_to_quads_with_constraint(
488 choppedPts + 0, toleranceSqd, dir, quads, sublevel + 1);
489 convert_noninflect_cubic_to_quads_with_constraint(
490 choppedPts + 3, toleranceSqd, dir, quads, sublevel + 1);
508 for (
int i = 0; i <
count; ++i) {
509 SkPoint* cubic = chopped + 3*i;
510 convert_noninflect_cubic_to_quads(cubic, tolSqd, quads);
529 for (
int i = 0; i <
count; ++i) {
530 SkPoint* cubic = chopped + 3*i;
531 convert_noninflect_cubic_to_quads_with_constraint(cubic, tolSqd, dir, quads);
static float tolerance_to_wangs_precision(float srcTol)
uint32_t max_bezier_vertices(uint32_t chopCount)
static const SkScalar kMinCurveTol
static const int points[]
static bool isFinite(const SkRect &r)
static bool SkIsFinite(T x, Pack... values)
static constexpr float sk_ieee_float_divide(float numer, float denom)
void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7])
int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10])
static SkPoint * subdivide(const SkConic &src, SkPoint pts[], int level)
#define SkScalarInvert(x)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
#define SkScalarAve(a, b)
#define SK_ScalarNearlyZero
static SkScalar SkScalarSquare(SkScalar x)
void set(const SkPoint controlPts[3])
SkScalar mapRadius(SkScalar radius) const
SkMatrix & postConcat(const SkMatrix &other)
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
SkScalar getMaxScale() const
static SkPoint MakeOrthog(const SkPoint &vec, Side side=kLeft_Side)
static SkScalar LengthSqd(const SkPoint &pt)
static SkScalar DistanceToLineSegmentBetweenSqd(const SkPoint &pt, const SkPoint &a, const SkPoint &b)
static SkScalar DistanceToSqd(const SkPoint &pt, const SkPoint &a)
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
void convertCubicToQuads(const SkPoint p[4], SkScalar tolScale, skia_private::TArray< SkPoint, true > *quads)
uint32_t generateCubicPoints(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2, const SkPoint &p3, SkScalar tolSqd, SkPoint **points, uint32_t pointsLeft)
uint32_t quadraticPointCount(const SkPoint points[], SkScalar tol)
uint32_t cubicPointCount(const SkPoint points[], SkScalar tol)
SkScalar scaleToleranceToSrc(SkScalar devTol, const SkMatrix &viewM, const SkRect &pathBounds)
void convertCubicToQuadsConstrainToTangents(const SkPoint p[4], SkScalar tolScale, SkPathFirstDirection dir, skia_private::TArray< SkPoint, true > *quads)
void getConicKLM(const SkPoint p[3], const SkScalar weight, SkMatrix *klm)
static const int kMaxPointsPerCurve
uint32_t generateQuadraticPoints(const SkPoint &p0, const SkPoint &p1, const SkPoint &p2, SkScalar tolSqd, SkPoint **points, uint32_t pointsLeft)
static float DotProduct(const SkVector &a, const SkVector &b)
float dot(const SkVector &vec) const
float cross(const SkVector &vec) const
void scale(float scale, SkPoint *dst) const
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
constexpr float height() const
constexpr float width() const
SkScalar fTop
smaller y-axis bounds