xref: /aosp_15_r20/external/skia/tests/PathOpsDCubicTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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