ClipCubicTest.cpp revision 5546ef2dd9edad601383b85907f677118f857332
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
10#include "SkCanvas.h"
11#include "SkPaint.h"
12#include "SkCubicClipper.h"
13#include "SkGeometry.h"
14
15// Currently the supersampler blitter uses int16_t for its index into an array
16// the width of the clip. Test that we don't crash/assert if we try to draw
17// with a device/clip that is larger.
18static void test_giantClip() {
19    SkBitmap bm;
20    bm.setConfig(SkBitmap::kARGB_8888_Config, 64919, 1);
21    bm.allocPixels();
22    SkCanvas canvas(bm);
23    canvas.clear(0);
24
25    SkPath path;
26    path.moveTo(0, 0); path.lineTo(1, 0); path.lineTo(33, 1);
27    SkPaint paint;
28    paint.setAntiAlias(true);
29    canvas.drawPath(path, paint);
30}
31
32static void PrintCurve(const char *name, const SkPoint crv[4]) {
33    printf("%s: %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g, %.10g\n",
34            name,
35            (float)crv[0].fX, (float)crv[0].fY,
36            (float)crv[1].fX, (float)crv[1].fY,
37            (float)crv[2].fX, (float)crv[2].fY,
38            (float)crv[3].fX, (float)crv[3].fY);
39
40}
41
42
43static bool CurvesAreEqual(const SkPoint c0[4],
44                           const SkPoint c1[4],
45                           float tol) {
46    for (int i = 0; i < 4; i++) {
47        if (SkScalarAbs(c0[i].fX - c1[i].fX) > SkFloatToScalar(tol) ||
48            SkScalarAbs(c0[i].fY - c1[i].fY) > SkFloatToScalar(tol)
49        ) {
50            PrintCurve("c0", c0);
51            PrintCurve("c1", c1);
52            return false;
53        }
54    }
55    return true;
56}
57
58
59static SkPoint* SetCurve(float x0, float y0,
60                         float x1, float y1,
61                         float x2, float y2,
62                         float x3, float y3,
63                         SkPoint crv[4]) {
64    crv[0].fX = SkFloatToScalar(x0);   crv[0].fY = SkFloatToScalar(y0);
65    crv[1].fX = SkFloatToScalar(x1);   crv[1].fY = SkFloatToScalar(y1);
66    crv[2].fX = SkFloatToScalar(x2);   crv[2].fY = SkFloatToScalar(y2);
67    crv[3].fX = SkFloatToScalar(x3);   crv[3].fY = SkFloatToScalar(y3);
68    return crv;
69}
70
71
72static void TestCubicClipping(skiatest::Reporter* reporter) {
73    static SkPoint crv[4] = {
74        { SkIntToScalar(0), SkIntToScalar(0)  },
75        { SkIntToScalar(2), SkIntToScalar(3)  },
76        { SkIntToScalar(1), SkIntToScalar(10) },
77        { SkIntToScalar(4), SkIntToScalar(12) }
78    };
79
80    SkCubicClipper clipper;
81    SkPoint clipped[4], shouldbe[4];
82    SkIRect clipRect;
83    bool success;
84    const float tol = SkFloatToScalar(1e-4);
85
86    // Test no clip, with plenty of room.
87    clipRect.set(-2, -2, 6, 14);
88    clipper.setClip(clipRect);
89    success = clipper.clipCubic(crv, clipped);
90    REPORTER_ASSERT(reporter, success == true);
91    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
92        0, 0, 2, 3, 1, 10, 4, 12, shouldbe), tol));
93
94    // Test no clip, touching first point.
95    clipRect.set(-2, 0, 6, 14);
96    clipper.setClip(clipRect);
97    success = clipper.clipCubic(crv, clipped);
98    REPORTER_ASSERT(reporter, success == true);
99    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
100        0, 0, 2, 3, 1, 10, 4, 12, shouldbe), tol));
101
102    // Test no clip, touching last point.
103    clipRect.set(-2, -2, 6, 12);
104    clipper.setClip(clipRect);
105    success = clipper.clipCubic(crv, clipped);
106    REPORTER_ASSERT(reporter, success == true);
107    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
108        0, 0, 2, 3, 1, 10, 4, 12, shouldbe), tol));
109
110    // Test all clip.
111    clipRect.set(-2, 14, 6, 20);
112    clipper.setClip(clipRect);
113    success = clipper.clipCubic(crv, clipped);
114    REPORTER_ASSERT(reporter, success == false);
115
116    // Test clip at 1.
117    clipRect.set(-2, 1, 6, 14);
118    clipper.setClip(clipRect);
119    success = clipper.clipCubic(crv, clipped);
120    REPORTER_ASSERT(reporter, success == true);
121    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
122        0.5126125216, 1,
123        1.841195941,  4.337081432,
124        1.297019958,  10.19801331,
125        4,            12,
126        shouldbe), tol));
127
128    // Test clip at 2.
129    clipRect.set(-2, 2, 6, 14);
130    clipper.setClip(clipRect);
131    success = clipper.clipCubic(crv, clipped);
132    REPORTER_ASSERT(reporter, success == true);
133    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
134        00.8412352204, 2,
135        1.767683744,   5.400758266,
136        1.55052948,    10.36701965,
137        4,             12,
138        shouldbe), tol));
139
140    // Test clip at 11.
141    clipRect.set(-2, -2, 6, 11);
142    clipper.setClip(clipRect);
143    success = clipper.clipCubic(crv, clipped);
144    REPORTER_ASSERT(reporter, success == true);
145    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
146        0,           0,
147        1.742904663, 2.614356995,
148        1.207521796, 8.266430855,
149        3.026495695, 11,
150        shouldbe), tol));
151
152    // Test clip at 10.
153    clipRect.set(-2, -2, 6, 10);
154    clipper.setClip(clipRect);
155    success = clipper.clipCubic(crv, clipped);
156    REPORTER_ASSERT(reporter, success == true);
157    REPORTER_ASSERT(reporter, CurvesAreEqual(clipped, SetCurve(
158        0,           0,
159        1.551193237, 2.326789856,
160        1.297736168, 7.059780121,
161        2.505550385, 10,
162        shouldbe), tol));
163
164    test_giantClip();
165}
166
167
168
169
170#include "TestClassDef.h"
171DEFINE_TESTCLASS("CubicClipper", CubicClippingTestClass, TestCubicClipping)
172