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