blob: 4e7d8d1fe5041a60dc63c0e5513d50b55cc27ce3 [file]
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkTypes.h"
#include "include/private/SkDebug.h"
#include "src/pathops/SkIntersections.h"
#include "src/pathops/SkPathOpsCubic.h"
#include "src/pathops/SkPathOpsPoint.h"
#include "src/pathops/SkPathOpsQuad.h"
#include "src/pathops/SkReduceOrder.h"
#include "tests/PathOpsTestCommon.h"
#include "tests/Test.h"
#include <array>
struct quadCubic {
CubicPts cubic;
QuadPts quad;
};
static constexpr auto quadCubicTests = std::to_array<quadCubic>({
quadCubic{{{{945.08099365234375, 747.1619873046875},
{982.5679931640625, 747.1619873046875},
{1013.6290283203125, 719.656005859375},
{1019.1910400390625, 683.72601318359375}}},
{{{945, 747},
{976.0660400390625, 747},
{998.03302001953125, 725.03302001953125}}}},
quadCubic{{{{778, 14089},
{778, 14091.208984375},
{776.20916748046875, 14093},
{774, 14093}}},
{{{778, 14089},
{777.99957275390625, 14090.65625},
{776.82843017578125, 14091.828125}}}},
quadCubic{{{{1020.08099, 672.161987},
{1020.08002, 630.73999},
{986.502014, 597.161987},
{945.080994, 597.161987}}},
{{{1020, 672}, {1020, 640.93396}, {998.03302, 618.96698}}}},
quadCubic{{{{778, 14089},
{778, 14091.208984375},
{776.20916748046875, 14093},
{774, 14093}}},
{{{778, 14089},
{777.99957275390625, 14090.65625},
{776.82843017578125, 14091.828125}}}},
quadCubic{{{{1110, 817}, {1110.55225f, 817}, {1111, 817.447693f}, {1111, 818}}},
{{{1110.70715f, 817.292908f}, {1110.41406f, 817.000122f}, {1110, 817}}}},
quadCubic{{{{1110, 817}, {1110.55225f, 817}, {1111, 817.447693f}, {1111, 818}}},
{{{1111, 818}, {1110.99988f, 817.585876f}, {1110.70715f, 817.292908f}}}},
quadCubic{{{{55, 207},
{52.238574981689453, 207},
{50, 204.76142883300781},
{50, 202}}},
{{{55, 207},
{52.929431915283203, 206.99949645996094},
{51.464466094970703, 205.53553771972656}}}},
quadCubic{{{{49, 47},
{49, 74.614250183105469},
{26.614250183105469, 97},
{-1, 97}}},
{{{-8.659739592076221e-015, 96.991401672363281},
{20.065492630004883, 96.645187377929688},
{34.355339050292969, 82.355339050292969}}}},
quadCubic{{{{10, 234}, {10, 229.58172607421875}, {13.581720352172852, 226}, {18, 226}}},
{{{18, 226},
{14.686291694641113, 226},
{12.342399597167969, 228.3424072265625}}}},
quadCubic{{{{10, 234}, {10, 229.58172607421875}, {13.581720352172852, 226}, {18, 226}}},
{{{12.342399597167969, 228.3424072265625},
{10, 230.68629455566406},
{10, 234}}}},
});
static const int quadCubicTests_count = (int) std::size(quadCubicTests);
static void cubicQuadIntersection(skiatest::Reporter* reporter, int index) {
int iIndex = static_cast<int>(index);
const CubicPts& c = quadCubicTests[index].cubic;
SkDCubic cubic;
cubic.debugSet(c.fPts);
SkASSERT(ValidCubic(cubic));
const QuadPts& q = quadCubicTests[index].quad;
SkDQuad quad;
quad.debugSet(q.fPts);
SkASSERT(ValidQuad(quad));
SkReduceOrder reduce1;
SkReduceOrder reduce2;
int order1 = reduce1.reduce(cubic, SkReduceOrder::kNo_Quadratics);
int order2 = reduce2.reduce(quad);
if (order1 != 4) {
SkDebugf("[%d] cubic order=%d\n", iIndex, order1);
REPORTER_ASSERT(reporter, 0);
}
if (order2 != 3) {
SkDebugf("[%d] quad order=%d\n", iIndex, order2);
REPORTER_ASSERT(reporter, 0);
}
SkIntersections i;
int roots = i.intersect(cubic, quad);
for (int pt = 0; pt < roots; ++pt) {
double tt1 = i[0][pt];
SkDPoint xy1 = cubic.ptAtT(tt1);
double tt2 = i[1][pt];
SkDPoint xy2 = quad.ptAtT(tt2);
if (!xy1.approximatelyEqual(xy2)) {
SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n",
__FUNCTION__, iIndex, pt, tt1, xy1.fX, xy1.fY, tt2, xy2.fX, xy2.fY);
}
REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2));
}
reporter->bumpTestCount();
}
DEF_TEST(PathOpsCubicQuadIntersection, reporter) {
for (int index = 0; index < quadCubicTests_count; ++index) {
cubicQuadIntersection(reporter, index);
reporter->bumpTestCount();
}
}
DEF_TEST(PathOpsCubicQuadIntersectionOneOff, reporter) {
cubicQuadIntersection(reporter, 0);
}