// Uses the max curvature function for quads to estimate // where to chop the conic. If the max curvature is not // found along the curve segment it will return 1 and // dst[0] is the original conic. If it returns 2 the dst[0] // and dst[1] are the two new conics. static int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) { SkScalar t = SkFindQuadMaxCurvature(src); if (t == 0) { if (dst) { dst[0].set(src, weight); } return 1; } else { if (dst) { SkConic conic; conic.set(src, weight); conic.chopAt(t, dst); } return 2; } }
static void chopBothWays(const SkDConic& dConic, double t, const char* name) { SkConic conic; for (int index = 0; index < 3; ++index) { conic.fPts[index] = dConic.fPts[index].asSkPoint(); } conic.fW = dConic.fWeight; SkConic chopped[2]; SkDConic dChopped[2]; conic.chopAt(SkDoubleToScalar(t), chopped); dChopped[0] = dConic.subDivide(0, t); dChopped[1] = dConic.subDivide(t, 1); #if DEBUG_VISUALIZE_CONICS dConic.dump(); #endif chopCompare(chopped, dChopped); #if DEBUG_VISUALIZE_CONICS writePng(conic, chopped, name); #endif }
static void test_conic_eval_tan(skiatest::Reporter* reporter, const SkConic& conic, SkScalar t) { SkVector v0, v1; conic.evalAt(t, nullptr, &v0); v1 = conic.evalTangentAt(t); check_pairs(reporter, 0, t, "conic-tan", v0.fX, v0.fY, v1.fX, v1.fY); }
static void test_conic_eval_pos(skiatest::Reporter* reporter, const SkConic& conic, SkScalar t) { SkPoint p0, p1; conic.evalAt(t, &p0, nullptr); p1 = conic.evalAt(t); check_pairs(reporter, 0, t, "conic-pos", p0.fX, p0.fY, p1.fX, p1.fY); }