1#include "Test.h"
2#include "SkClipStack.h"
3#include "SkPath.h"
4#include "SkRect.h"
5
6static void test_assign_and_comparison(skiatest::Reporter* reporter) {
7    SkClipStack s;
8
9    // Build up a clip stack with a path, an empty clip, and a rect.
10    s.save();
11    SkPath p;
12    p.moveTo(5, 6);
13    p.lineTo(7, 8);
14    p.lineTo(5, 9);
15    p.close();
16    s.clipDevPath(p);
17
18    s.save();
19    SkRect r = SkRect::MakeLTRB(1, 2, 3, 4);
20    s.clipDevRect(r);
21    r = SkRect::MakeLTRB(10, 11, 12, 13);
22    s.clipDevRect(r);
23
24    s.save();
25    r = SkRect::MakeLTRB(14, 15, 16, 17);
26    s.clipDevRect(r, SkRegion::kUnion_Op);
27
28    // Test that assignment works.
29    SkClipStack copy = s;
30    REPORTER_ASSERT(reporter, s == copy);
31
32    // Test that different save levels triggers not equal.
33    s.restore();
34    REPORTER_ASSERT(reporter, s != copy);
35
36    // Test that an equal, but not copied version is equal.
37    s.save();
38    r = SkRect::MakeLTRB(14, 15, 16, 17);
39    s.clipDevRect(r, SkRegion::kUnion_Op);
40    REPORTER_ASSERT(reporter, s == copy);
41
42    // Test that a different op on one level triggers not equal.
43    s.restore();
44    s.save();
45    r = SkRect::MakeLTRB(14, 15, 16, 17);
46    s.clipDevRect(r);
47    REPORTER_ASSERT(reporter, s != copy);
48
49    // Test that different state (clip type) triggers not equal.
50    s.restore();
51    s.save();
52    SkPath rp;
53    rp.addRect(r);
54    s.clipDevPath(rp, SkRegion::kUnion_Op);
55    REPORTER_ASSERT(reporter, s != copy);
56
57    // Test that different rects triggers not equal.
58    s.restore();
59    s.save();
60    r = SkRect::MakeLTRB(24, 25, 26, 27);
61    s.clipDevRect(r, SkRegion::kUnion_Op);
62    REPORTER_ASSERT(reporter, s != copy);
63
64    // Sanity check
65    s.restore();
66    copy.restore();
67    REPORTER_ASSERT(reporter, s == copy);
68    s.restore();
69    copy.restore();
70    REPORTER_ASSERT(reporter, s == copy);
71
72    // Test that different paths triggers not equal.
73    s.restore();
74    s.save();
75    p.addRect(r);
76    s.clipDevPath(p);
77    REPORTER_ASSERT(reporter, s != copy);
78}
79
80static void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack,
81                         int count) {
82    REPORTER_ASSERT(reporter, count == stack.getSaveCount());
83
84    SkClipStack::B2FIter iter(stack);
85    int counter = 0;
86    while (iter.next()) {
87        counter += 1;
88    }
89    REPORTER_ASSERT(reporter, count == counter);
90}
91
92static void TestClipStack(skiatest::Reporter* reporter) {
93    SkClipStack stack;
94
95    assert_count(reporter, stack, 0);
96
97    static const SkIRect gRects[] = {
98        { 0, 0, 100, 100 },
99        { 25, 25, 125, 125 },
100        { 0, 0, 1000, 1000 },
101        { 0, 0, 75, 75 }
102    };
103    for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) {
104        stack.clipDevRect(gRects[i]);
105    }
106
107    // all of the above rects should have been intersected, leaving only 1 rect
108    SkClipStack::B2FIter iter(stack);
109    const SkClipStack::B2FIter::Clip* clip = iter.next();
110    SkRect answer;
111    answer.iset(25, 25, 75, 75);
112
113    REPORTER_ASSERT(reporter, clip);
114    REPORTER_ASSERT(reporter, clip->fRect);
115    REPORTER_ASSERT(reporter, !clip->fPath);
116    REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == clip->fOp);
117    REPORTER_ASSERT(reporter, *clip->fRect == answer);
118    // now check that we only had one in our iterator
119    REPORTER_ASSERT(reporter, !iter.next());
120
121    stack.reset();
122    assert_count(reporter, stack, 0);
123
124    test_assign_and_comparison(reporter);
125}
126
127#include "TestClassDef.h"
128DEFINE_TESTCLASS("ClipStack", TestClipStackClass, TestClipStack)
129