1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2012 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkFloatingPoint.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsCubic.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "src/pathops/SkPathOpsPoint.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "tests/PathOpsTestCommon.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
13*c8dee2aaSAndroid Build Coastguard Worker
14*c8dee2aaSAndroid Build Coastguard Worker #include <string>
15*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
16*c8dee2aaSAndroid Build Coastguard Worker
17*c8dee2aaSAndroid Build Coastguard Worker static const CubicPts hullTests[] = {
18*c8dee2aaSAndroid Build Coastguard Worker {{{2.6250000819563866, 2.3750000223517418}, {2.833333432674408, 2.3333333432674408}, {3.1111112236976624, 2.3333333134651184}, {3.4074075222015381, 2.3333332538604736}}},
19*c8dee2aaSAndroid Build Coastguard Worker };
20*c8dee2aaSAndroid Build Coastguard Worker
21*c8dee2aaSAndroid Build Coastguard Worker static const size_t hullTests_count = std::size(hullTests);
22*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(PathOpsCubicHull,reporter)23*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(PathOpsCubicHull, reporter) {
24*c8dee2aaSAndroid Build Coastguard Worker for (size_t index = 0; index < hullTests_count; ++index) {
25*c8dee2aaSAndroid Build Coastguard Worker const CubicPts& c = hullTests[index];
26*c8dee2aaSAndroid Build Coastguard Worker SkDCubic cubic;
27*c8dee2aaSAndroid Build Coastguard Worker cubic.debugSet(c.fPts);
28*c8dee2aaSAndroid Build Coastguard Worker char order[4];
29*c8dee2aaSAndroid Build Coastguard Worker cubic.convexHull(order);
30*c8dee2aaSAndroid Build Coastguard Worker }
31*c8dee2aaSAndroid Build Coastguard Worker }
32*c8dee2aaSAndroid Build Coastguard Worker
nearly_equal(double expected,double actual)33*c8dee2aaSAndroid Build Coastguard Worker static bool nearly_equal(double expected, double actual) {
34*c8dee2aaSAndroid Build Coastguard Worker if (sk_double_nearly_zero(expected)) {
35*c8dee2aaSAndroid Build Coastguard Worker return sk_double_nearly_zero(actual);
36*c8dee2aaSAndroid Build Coastguard Worker }
37*c8dee2aaSAndroid Build Coastguard Worker return sk_doubles_nearly_equal_ulps(expected, actual, 64);
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker
testConvertToPolynomial(skiatest::Reporter * reporter,const std::string & name,SkSpan<const SkDPoint> curveInputs,bool yValues,double expectedA,double expectedB,double expectedC,double expectedD)40*c8dee2aaSAndroid Build Coastguard Worker static void testConvertToPolynomial(skiatest::Reporter* reporter, const std::string& name,
41*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const SkDPoint> curveInputs, bool yValues,
42*c8dee2aaSAndroid Build Coastguard Worker double expectedA, double expectedB,
43*c8dee2aaSAndroid Build Coastguard Worker double expectedC, double expectedD) {
44*c8dee2aaSAndroid Build Coastguard Worker skiatest::ReporterContext subtest(reporter, name);
45*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, curveInputs.size() == 4,
46*c8dee2aaSAndroid Build Coastguard Worker "Invalid test case. Need 4 points (start, control, control, end)");
47*c8dee2aaSAndroid Build Coastguard Worker
48*c8dee2aaSAndroid Build Coastguard Worker const double* input = &curveInputs[0].fX;
49*c8dee2aaSAndroid Build Coastguard Worker if (yValues) {
50*c8dee2aaSAndroid Build Coastguard Worker input = &curveInputs[0].fY;
51*c8dee2aaSAndroid Build Coastguard Worker }
52*c8dee2aaSAndroid Build Coastguard Worker double A, B, C, D;
53*c8dee2aaSAndroid Build Coastguard Worker SkDCubic::Coefficients(input, &A, &B, &C, &D);
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, nearly_equal(expectedA, A), "%f != %f", expectedA, A);
56*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, nearly_equal(expectedB, B), "%f != %f", expectedB, B);
57*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, nearly_equal(expectedC, C), "%f != %f", expectedC, C);
58*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, nearly_equal(expectedD, D), "%f != %f", expectedD, D);
59*c8dee2aaSAndroid Build Coastguard Worker }
60*c8dee2aaSAndroid Build Coastguard Worker
DEF_TEST(SkDCubicPolynomialCoefficients,reporter)61*c8dee2aaSAndroid Build Coastguard Worker DEF_TEST(SkDCubicPolynomialCoefficients, reporter) {
62*c8dee2aaSAndroid Build Coastguard Worker testConvertToPolynomial(reporter, "Arbitrary control points X direction",
63*c8dee2aaSAndroid Build Coastguard Worker {{1, 2}, {-3, 4}, {5, -6}, {7, 8}}, false, /*=yValues*/
64*c8dee2aaSAndroid Build Coastguard Worker -18, 36, -12, 1
65*c8dee2aaSAndroid Build Coastguard Worker );
66*c8dee2aaSAndroid Build Coastguard Worker testConvertToPolynomial(reporter, "Arbitrary control points Y direction",
67*c8dee2aaSAndroid Build Coastguard Worker {{1, 2}, {-3, 4}, {5, -6}, {7, 8}}, true, /*=yValues*/
68*c8dee2aaSAndroid Build Coastguard Worker 36, -36, 6, 2
69*c8dee2aaSAndroid Build Coastguard Worker );
70*c8dee2aaSAndroid Build Coastguard Worker }
71