1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "Test.h"
9#include "SkPathMeasure.h"
10
11static void TestPathMeasure(skiatest::Reporter* reporter) {
12    SkPath  path;
13
14    path.moveTo(0, 0);
15    path.lineTo(SK_Scalar1, 0);
16    path.lineTo(SK_Scalar1, SK_Scalar1);
17    path.lineTo(0, SK_Scalar1);
18
19    SkPathMeasure   meas(path, true);
20    SkScalar        length = meas.getLength();
21    SkASSERT(length == SK_Scalar1*4);
22
23    path.reset();
24    path.moveTo(0, 0);
25    path.lineTo(SK_Scalar1*3, SK_Scalar1*4);
26    meas.setPath(&path, false);
27    length = meas.getLength();
28    REPORTER_ASSERT(reporter, length == SK_Scalar1*5);
29
30    path.reset();
31    path.addCircle(0, 0, SK_Scalar1);
32    meas.setPath(&path, true);
33    length = meas.getLength();
34//    SkDebugf("circle arc-length = %g\n", length);
35
36    for (int i = 0; i < 8; i++) {
37        SkScalar    d = length * i / 8;
38        SkPoint     p;
39        SkVector    v;
40        meas.getPosTan(d, &p, &v);
41#if 0
42        SkDebugf("circle arc-length=%g, pos[%g %g] tan[%g %g]\n",
43                 d, p.fX, p.fY, v.fX, v.fY);
44#endif
45    }
46
47    // Test the behavior following a close not followed by a move.
48    path.reset();
49    path.lineTo(SK_Scalar1, 0);
50    path.lineTo(SK_Scalar1, SK_Scalar1);
51    path.lineTo(0, SK_Scalar1);
52    path.close();
53    path.lineTo(-SK_Scalar1, 0);
54    meas.setPath(&path, false);
55    length = meas.getLength();
56    REPORTER_ASSERT(reporter, length == SK_Scalar1 * 4);
57    meas.nextContour();
58    length = meas.getLength();
59    REPORTER_ASSERT(reporter, length == SK_Scalar1);
60    SkPoint position;
61    SkVector tangent;
62    REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
63    REPORTER_ASSERT(reporter,
64        SkScalarNearlyEqual(position.fX, -SK_ScalarHalf, SK_Scalar1 * 0.0001));
65    REPORTER_ASSERT(reporter, position.fY == 0);
66    REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
67    REPORTER_ASSERT(reporter, tangent.fY == 0);
68
69    // Test degenerate paths
70    path.reset();
71    path.moveTo(0, 0);
72    path.lineTo(0, 0);
73    path.lineTo(SK_Scalar1, 0);
74    path.quadTo(SK_Scalar1, 0, SK_Scalar1, 0);
75    path.quadTo(SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1 * 2);
76    path.cubicTo(SK_Scalar1, SK_Scalar1 * 2,
77                 SK_Scalar1, SK_Scalar1 * 2,
78                 SK_Scalar1, SK_Scalar1 * 2);
79    path.cubicTo(SK_Scalar1*2, SK_Scalar1 * 2,
80                 SK_Scalar1*3, SK_Scalar1 * 2,
81                 SK_Scalar1*4, SK_Scalar1 * 2);
82    meas.setPath(&path, false);
83    length = meas.getLength();
84    REPORTER_ASSERT(reporter, length == SK_Scalar1 * 6);
85    REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
86    REPORTER_ASSERT(reporter,
87        SkScalarNearlyEqual(position.fX, SK_ScalarHalf, SK_Scalar1 * 0.0001));
88    REPORTER_ASSERT(reporter, position.fY == 0);
89    REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
90    REPORTER_ASSERT(reporter, tangent.fY == 0);
91    REPORTER_ASSERT(reporter, meas.getPosTan(SK_Scalar1 * 2.5f, &position, &tangent));
92    REPORTER_ASSERT(reporter,
93        SkScalarNearlyEqual(position.fX, SK_Scalar1, SK_Scalar1 * 0.0001));
94    REPORTER_ASSERT(reporter,
95        SkScalarNearlyEqual(position.fY, SK_Scalar1 * 1.5f));
96    REPORTER_ASSERT(reporter, tangent.fX == 0);
97    REPORTER_ASSERT(reporter, tangent.fY == SK_Scalar1);
98    REPORTER_ASSERT(reporter, meas.getPosTan(SK_Scalar1 * 4.5f, &position, &tangent));
99    REPORTER_ASSERT(reporter,
100        SkScalarNearlyEqual(position.fX, SK_Scalar1 * 2.5f, SK_Scalar1 * 0.0001));
101    REPORTER_ASSERT(reporter,
102        SkScalarNearlyEqual(position.fY, SK_Scalar1 * 2.0f, SK_Scalar1 * 0.0001));
103    REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
104    REPORTER_ASSERT(reporter, tangent.fY == 0);
105
106    path.reset();
107    path.moveTo(0, 0);
108    path.lineTo(SK_Scalar1, 0);
109    path.moveTo(SK_Scalar1, SK_Scalar1);
110    path.moveTo(SK_Scalar1 * 2, SK_Scalar1 * 2);
111    path.lineTo(SK_Scalar1, SK_Scalar1 * 2);
112    meas.setPath(&path, false);
113    length = meas.getLength();
114    REPORTER_ASSERT(reporter, length == SK_Scalar1);
115    REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
116    REPORTER_ASSERT(reporter,
117        SkScalarNearlyEqual(position.fX, SK_ScalarHalf, SK_Scalar1 * 0.0001));
118    REPORTER_ASSERT(reporter, position.fY == 0);
119    REPORTER_ASSERT(reporter, tangent.fX == SK_Scalar1);
120    REPORTER_ASSERT(reporter, tangent.fY == 0);
121    meas.nextContour();
122    length = meas.getLength();
123    REPORTER_ASSERT(reporter, length == SK_Scalar1);
124    REPORTER_ASSERT(reporter, meas.getPosTan(SK_ScalarHalf, &position, &tangent));
125    REPORTER_ASSERT(reporter,
126        SkScalarNearlyEqual(position.fX, SK_Scalar1 * 1.5f, SK_Scalar1 * 0.0001));
127    REPORTER_ASSERT(reporter,
128        SkScalarNearlyEqual(position.fY, SK_Scalar1 * 2.0f, SK_Scalar1 * 0.0001));
129    REPORTER_ASSERT(reporter, tangent.fX == -SK_Scalar1);
130    REPORTER_ASSERT(reporter, tangent.fY == 0);
131}
132
133#include "TestClassDef.h"
134DEFINE_TESTCLASS("PathMeasure", PathMeasureTestClass, TestPathMeasure)
135