static void oneOff(skiatest::Reporter* reporter, const SkDCubic& cubic1, const SkDCubic& cubic2,
        bool coin) {
    SkASSERT(ValidCubic(cubic1));
    SkASSERT(ValidCubic(cubic2));
#if ONE_OFF_DEBUG
    SkDebugf("computed quadratics given\n");
    SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
        cubic1[0].fX, cubic1[0].fY, cubic1[1].fX, cubic1[1].fY,
        cubic1[2].fX, cubic1[2].fY, cubic1[3].fX, cubic1[3].fY);
    SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
        cubic2[0].fX, cubic2[0].fY, cubic2[1].fX, cubic2[1].fY,
        cubic2[2].fX, cubic2[2].fY, cubic2[3].fX, cubic2[3].fY);
#endif
    SkTArray<SkDQuad, true> quads1;
    CubicToQuads(cubic1, cubic1.calcPrecision(), quads1);
#if ONE_OFF_DEBUG
    SkDebugf("computed quadratics set 1\n");
    for (int index = 0; index < quads1.count(); ++index) {
        const SkDQuad& q = quads1[index];
        SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].fX, q[0].fY,
                 q[1].fX, q[1].fY,  q[2].fX, q[2].fY);
    }
#endif
    SkTArray<SkDQuad, true> quads2;
    CubicToQuads(cubic2, cubic2.calcPrecision(), quads2);
#if ONE_OFF_DEBUG
    SkDebugf("computed quadratics set 2\n");
    for (int index = 0; index < quads2.count(); ++index) {
        const SkDQuad& q = quads2[index];
        SkDebugf("  {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].fX, q[0].fY,
                 q[1].fX, q[1].fY,  q[2].fX, q[2].fY);
    }
#endif
    SkIntersections intersections;
    intersections.intersect(cubic1, cubic2);
    REPORTER_ASSERT(reporter, !coin || intersections.used() == 2);
    double tt1, tt2;
    SkDPoint xy1, xy2;
    for (int pt3 = 0; pt3 < intersections.used(); ++pt3) {
        tt1 = intersections[0][pt3];
        xy1 = cubic1.ptAtT(tt1);
        tt2 = intersections[1][pt3];
        xy2 = cubic2.ptAtT(tt2);
        const SkDPoint& iPt = intersections.pt(pt3);
#if ONE_OFF_DEBUG
        SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1.9g\n",
                __FUNCTION__, tt1, xy1.fX, xy1.fY, iPt.fX,
                iPt.fY, xy2.fX, xy2.fY, tt2);
#endif
       REPORTER_ASSERT(reporter, xy1.approximatelyEqual(iPt));
       REPORTER_ASSERT(reporter, xy2.approximatelyEqual(iPt));
       REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2));
    }
    reporter->bumpTestCount();
}
static void selfOneOff(skiatest::Reporter* reporter, int index) {
    const SkDCubic& cubic = selfSet[index];
#if ONE_OFF_DEBUG
    int idx2;
    double max[3];
    int ts = cubic.findMaxCurvature(max);
    for (idx2 = 0; idx2 < ts; ++idx2) {
        SkDebugf("%s max[%d]=%1.9g (%1.9g, %1.9g)\n", __FUNCTION__, idx2,
                max[idx2], cubic.ptAtT(max[idx2]).fX, cubic.ptAtT(max[idx2]).fY);
    }
    SkTArray<double, true> ts1;
    SkTArray<SkDQuad, true> quads1;
    cubic.toQuadraticTs(cubic.calcPrecision(), &ts1);
    for (idx2 = 0; idx2 < ts1.count(); ++idx2) {
        SkDebugf("%s t[%d]=%1.9g\n", __FUNCTION__, idx2, ts1[idx2]);
    }
    CubicToQuads(cubic, cubic.calcPrecision(), quads1);
    for (idx2 = 0; idx2 < quads1.count(); ++idx2) {
        const SkDQuad& q = quads1[idx2];
        SkDebugf("  {{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}},\n",
                q[0].fX, q[0].fY,  q[1].fX, q[1].fY,  q[2].fX, q[2].fY);
    }
    SkDebugf("\n");
#endif
    SkIntersections i;
    int result = i.intersect(cubic);
    REPORTER_ASSERT(reporter, result == 1);
    REPORTER_ASSERT(reporter, i.used() == 1);
    REPORTER_ASSERT(reporter, !approximately_equal(i[0][0], i[1][0]));
    SkDPoint pt1 = cubic.ptAtT(i[0][0]);
    SkDPoint pt2 = cubic.ptAtT(i[1][0]);
    REPORTER_ASSERT(reporter, pt1.approximatelyEqual(pt2));
    reporter->bumpTestCount();
}
Exemple #3
0
static void test(skiatest::Reporter* reporter, const SkDCubic* cubics, const char* name,
                 int firstTest, size_t testCount) {
    for (size_t index = firstTest; index < testCount; ++index) {
        const SkDCubic& cubic = cubics[index];
        double precision = cubic.calcPrecision();
        SkTDArray<SkDQuad> quads;
        CubicToQuads(cubic, precision, quads);
        if (quads.count() != 1) {
            SkDebugf("%s [%d] cubic to quadratics failed count=%d\n", name, static_cast<int>(index),
                     quads.count());
        }
        REPORTER_ASSERT(reporter, quads.count() == 1);
    }
}
Exemple #4
0
static void oneOff(skiatest::Reporter* reporter, size_t x) {
    const SkDCubic& cubic = locals[x];
    const SkPoint skcubic[4] = {
        {static_cast<float>(cubic[0].fX), static_cast<float>(cubic[0].fY)},
        {static_cast<float>(cubic[1].fX), static_cast<float>(cubic[1].fY)},
        {static_cast<float>(cubic[2].fX), static_cast<float>(cubic[2].fY)},
        {static_cast<float>(cubic[3].fX), static_cast<float>(cubic[3].fY)}
    };
    SkScalar skinflect[2];
    int skin = SkFindCubicInflections(skcubic, skinflect);
    if (false) SkDebugf("%s %d %1.9g\n", __FUNCTION__, skin, skinflect[0]);
    SkTDArray<SkDQuad> quads;
    double precision = cubic.calcPrecision();
    CubicToQuads(cubic, precision, quads);
    if (false) SkDebugf("%s quads=%d\n", __FUNCTION__, quads.count());
}
Exemple #5
0
static void testC(skiatest::Reporter* reporter, const SkDCubic* cubics, const char* name,
                  int firstTest, size_t testCount) {
    // test if computed line end points are valid
    for (size_t index = firstTest; index < testCount; ++index) {
        const SkDCubic& cubic = cubics[index];
        double precision = cubic.calcPrecision();
        SkTDArray<SkDQuad> quads;
        CubicToQuads(cubic, precision, quads);
        if (!AlmostEqualUlps(cubic[0].fX, quads[0][0].fX)
                || !AlmostEqualUlps(cubic[0].fY, quads[0][0].fY)) {
            SkDebugf("[%d] unmatched start\n", static_cast<int>(index));
            REPORTER_ASSERT(reporter, 0);
        }
        int last = quads.count() - 1;
        if (!AlmostEqualUlps(cubic[3].fX, quads[last][2].fX)
                || !AlmostEqualUlps(cubic[3].fY, quads[last][2].fY)) {
            SkDebugf("[%d] unmatched end\n", static_cast<int>(index));
            REPORTER_ASSERT(reporter, 0);
        }
    }
}
void CubicPathToQuads(const SkPath& cubicPath, SkPath* quadPath) {
    quadPath->reset();
    SkDCubic cubic;
    SkTArray<SkDQuad, true> quads;
    SkPath::RawIter iter(cubicPath);
    uint8_t verb;
    SkPoint pts[4];
    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
        switch (verb) {
            case SkPath::kMove_Verb:
                quadPath->moveTo(pts[0].fX, pts[0].fY);
                continue;
            case SkPath::kLine_Verb:
                quadPath->lineTo(pts[1].fX, pts[1].fY);
                break;
            case SkPath::kQuad_Verb:
                quadPath->quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
                break;
            case SkPath::kCubic_Verb:
                quads.reset();
                cubic.set(pts);
                CubicToQuads(cubic, cubic.calcPrecision(), quads);
                for (int index = 0; index < quads.count(); ++index) {
                    SkPoint qPts[2] = {
                        quads[index][1].asSkPoint(),
                        quads[index][2].asSkPoint()
                    };
                    quadPath->quadTo(qPts[0].fX, qPts[0].fY, qPts[1].fX, qPts[1].fY);
                }
                break;
            case SkPath::kClose_Verb:
                 quadPath->close();
                break;
            default:
                SkDEBUGFAIL("bad verb");
                return;
        }
    }
}