#include "src/core/SkGeometry.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPoint3.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkTPin.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkBezierCurves.h"
#include "src/base/SkCubics.h"
#include "src/base/SkUtils.h"
#include "src/base/SkVx.h"
#include "src/core/SkPointPriv.h"
#include <algorithm>
#include <array>
#include <cmath>
#include <cstddef>
#include <cstdint>
namespace {
float2;
float4;
SkVector to_vector(const float2& x) { … }
int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { … }
int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) { … }
int return_check_zero(int value) { … }
}
int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) { … }
void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tangent) { … }
SkPoint SkEvalQuadAt(const SkPoint src[3], SkScalar t) { … }
SkVector SkEvalQuadTangentAt(const SkPoint src[3], SkScalar t) { … }
static inline float2 interp(const float2& v0,
const float2& v1,
const float2& t) { … }
void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { … }
void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { … }
float SkMeasureAngleBetweenVectors(SkVector a, SkVector b) { … }
SkVector SkFindBisector(SkVector a, SkVector b) { … }
float SkFindQuadMidTangent(const SkPoint src[3]) { … }
int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) { … }
static inline void flatten_double_quad_extrema(SkScalar coords[14]) { … }
int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]) { … }
int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]) { … }
SkScalar SkFindQuadMaxCurvature(const SkPoint src[3]) { … }
int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]) { … }
void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]) { … }
static SkVector eval_cubic_derivative(const SkPoint src[4], SkScalar t) { … }
static SkVector eval_cubic_2ndDerivative(const SkPoint src[4], SkScalar t) { … }
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc,
SkVector* tangent, SkVector* curvature) { … }
int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d,
SkScalar tValues[2]) { … }
template<int N, typename T>
inline 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 SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) { … }
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[10], float t0, float t1) { … }
void SkChopCubicAt(const SkPoint src[4], SkPoint dst[],
const SkScalar tValues[], int tCount) { … }
void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) { … }
float SkMeasureNonInflectCubicRotation(const SkPoint pts[4]) { … }
static skvx::float4 fma(const skvx::float4& f, float m, const skvx::float4& a) { … }
static float solve_quadratic_equation_for_midtangent(float a, float b, float c, float discr) { … }
static float solve_quadratic_equation_for_midtangent(float a, float b, float c) { … }
float SkFindCubicMidTangent(const SkPoint src[4]) { … }
static void flatten_double_cubic_extrema(SkScalar coords[14]) { … }
int SkChopCubicAtYExtrema(const SkPoint src[4], SkPoint dst[10]) { … }
int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10]) { … }
int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[2]) { … }
int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10]) { … }
static double calc_dot_cross_cubic(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2) { … }
inline static double previous_inverse_pow2(double n) { … }
inline static void write_cubic_inflection_roots(double t0, double s0, double t1, double s1,
double* t, double* s) { … }
SkCubicType SkClassifyCubic(const SkPoint P[4], double t[2], double s[2], double d[4]) { … }
template <typename T> void bubble_sort(T array[], int count) { … }
static int collaps_duplicates(SkScalar array[], int count) { … }
#ifdef SK_DEBUG
#define TEST_COLLAPS_ENTRY(array) …
static void test_collaps_duplicates() { … }
#endif
static SkScalar SkScalarCubeRoot(SkScalar x) { … }
static int solve_cubic_poly(const SkScalar coeff[4], SkScalar tValues[3]) { … }
static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) { … }
int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]) { … }
int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13],
SkScalar tValues[3]) { … }
static SkScalar calc_cubic_precision(const SkPoint src[4]) { … }
static bool on_same_side(const SkPoint src[4], int testIndex, int lineIndex) { … }
SkScalar SkFindCubicCusp(const SkPoint src[4]) { … }
static bool close_enough_to_zero(double x) { … }
static bool first_axis_intersection(const double coefficients[8], bool yDirection,
double axisIntercept, double* solution) { … }
bool SkChopMonoCubicAtY(const SkPoint src[4], SkScalar y, SkPoint dst[7]) { … }
bool SkChopMonoCubicAtX(const SkPoint src[4], SkScalar x, SkPoint dst[7]) { … }
static void conic_deriv_coeff(const SkScalar src[],
SkScalar w,
SkScalar coeff[3]) { … }
static bool conic_find_extrema(const SkScalar src[], SkScalar w, SkScalar* t) { … }
static void p3d_interp(const SkScalar src[7], SkScalar dst[7], SkScalar t) { … }
static void ratquad_mapTo3D(const SkPoint src[3], SkScalar w, SkPoint3 dst[3]) { … }
static SkPoint project_down(const SkPoint3& src) { … }
bool SkConic::chopAt(SkScalar t, SkConic dst[2]) const { … }
void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const { … }
SkPoint SkConic::evalAt(SkScalar t) const { … }
SkVector SkConic::evalTangentAt(SkScalar t) const { … }
void SkConic::evalAt(SkScalar t, SkPoint* pt, SkVector* tangent) const { … }
static SkScalar subdivide_w_value(SkScalar w) { … }
#if defined(SK_SUPPORT_LEGACY_CONIC_CHOP)
void SkConic::chop(SkConic * SK_RESTRICT dst) const { … }
#else
void SkConic::chop(SkConic * SK_RESTRICT dst) const {
const float scale = SkScalarInvert(SK_Scalar1 + fW);
float2 t0 = from_point(fPts[0]) * scale;
float2 t1 = from_point(fPts[1]) * (fW * scale);
float2 t2 = from_point(fPts[2]) * scale;
const SkPoint p1 = to_point(t0 + t1);
const SkPoint p3 = to_point(t1 + t2);
const SkPoint p2 = to_point(0.5f * t0 + t1 + 0.5f * t2);
SkASSERT(p1.isFinite() && p2.isFinite() && p3.isFinite());
dst[0].fPts[0] = fPts[0];
dst[0].fPts[1] = p1;
dst[0].fPts[2] = p2;
dst[1].fPts[0] = p2;
dst[1].fPts[1] = p3;
dst[1].fPts[2] = fPts[2];
dst[0].fW = dst[1].fW = subdivide_w_value(fW);
}
#endif
#define AS_QUAD_ERROR_SETUP …
void SkConic::computeAsQuadError(SkVector* err) const { … }
bool SkConic::asQuadTol(SkScalar tol) const { … }
#define kMaxConicToQuadPOW2 …
int SkConic::computeQuadPOW2(SkScalar tol) const { … }
static bool between(SkScalar a, SkScalar b, SkScalar c) { … }
static SkPoint* subdivide(const SkConic& src, SkPoint pts[], int level) { … }
int SkConic::chopIntoQuadsPOW2(SkPoint pts[], int pow2) const { … }
float SkConic::findMidTangent() const { … }
bool SkConic::findXExtrema(SkScalar* t) const { … }
bool SkConic::findYExtrema(SkScalar* t) const { … }
bool SkConic::chopAtXExtrema(SkConic dst[2]) const { … }
bool SkConic::chopAtYExtrema(SkConic dst[2]) const { … }
void SkConic::computeTightBounds(SkRect* bounds) const { … }
void SkConic::computeFastBounds(SkRect* bounds) const { … }
#if 0
bool SkConic::findMaxCurvature(SkScalar* t) const {
return false;
}
#endif
SkScalar SkConic::TransformW(const SkPoint pts[3], SkScalar w, const SkMatrix& matrix) { … }
int SkConic::BuildUnitArc(const SkVector& uStart, const SkVector& uStop, SkRotationDirection dir,
const SkMatrix* userMatrix, SkConic dst[kMaxConicsForArc]) { … }