blob: e85fca76458e0bb4391782a4b8ac10c5d0878730 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com097a3512010-07-13 18:35:14 +00008#include "Test.h"
9#include "SkRegion.h"
10#include "SkRandom.h"
11
reed@google.com8a0d8ff2012-04-30 16:28:04 +000012static void test_empties(skiatest::Reporter* reporter) {
13 SkRegion valid(SkIRect::MakeWH(10, 10));
14 SkRegion empty, empty2;
15
16 REPORTER_ASSERT(reporter, empty.isEmpty());
17 REPORTER_ASSERT(reporter, !valid.isEmpty());
18
19 // test intersects
20 REPORTER_ASSERT(reporter, !empty.intersects(empty2));
21 REPORTER_ASSERT(reporter, !valid.intersects(empty));
22
23 // test contains
24 REPORTER_ASSERT(reporter, !empty.contains(empty2));
25 REPORTER_ASSERT(reporter, !valid.contains(empty));
26 REPORTER_ASSERT(reporter, !empty.contains(valid));
27}
28
mike@reedtribe.org67c31842012-04-28 20:09:19 +000029enum {
30 W = 256,
31 H = 256
32};
33
34static SkIRect randRect(SkRandom& rand) {
35 int x = rand.nextU() % W;
36 int y = rand.nextU() % H;
37 int w = rand.nextU() % W;
38 int h = rand.nextU() % H;
39 return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
40}
41
42static void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
43 rgn->setEmpty();
44 for (int i = 0; i < n; ++i) {
45 rgn->op(randRect(rand), SkRegion::kUnion_Op);
46 }
47}
48
49static bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
50 SkRegion tmp;
51 tmp.op(outer, inner, SkRegion::kUnion_Op);
52 return outer == tmp;
53}
54
55static bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
56 SkRegion tmp;
57 return tmp.op(outer, inner, SkRegion::kIntersect_Op);
58}
59
60static void contains_proc(skiatest::Reporter* reporter,
61 const SkRegion& a, const SkRegion& b) {
62 bool c0 = a.contains(b);
63 bool c1 = slow_contains(a, b);
64 REPORTER_ASSERT(reporter, c0 == c1);
65}
66
67static void intersects_proc(skiatest::Reporter* reporter,
68 const SkRegion& a, const SkRegion& b) {
69 bool c0 = a.intersects(b);
70 bool c1 = slow_intersects(a, b);
71 REPORTER_ASSERT(reporter, c0 == c1);
72}
73
74static void test_proc(skiatest::Reporter* reporter,
75 void (*proc)(skiatest::Reporter*,
76 const SkRegion& a, const SkRegion&)) {
77 SkRandom rand;
78 for (int i = 0; i < 10000; ++i) {
79 SkRegion outer;
80 randRgn(rand, &outer, 8);
81 SkRegion inner;
82 randRgn(rand, &inner, 2);
83 proc(reporter, outer, inner);
84 }
85}
86
reed@android.com097a3512010-07-13 18:35:14 +000087static void rand_rect(SkIRect* rect, SkRandom& rand) {
88 int bits = 6;
89 int shift = 32 - bits;
90 rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
91 rand.nextU() >> shift, rand.nextU() >> shift);
92 rect->sort();
93}
94
95static bool test_rects(const SkIRect rect[], int count) {
96 SkRegion rgn0, rgn1;
97
98 for (int i = 0; i < count; i++) {
99 rgn0.op(rect[i], SkRegion::kUnion_Op);
100 }
101 rgn1.setRects(rect, count);
102
103 if (rgn0 != rgn1) {
104 SkDebugf("\n");
105 for (int i = 0; i < count; i++) {
106 SkDebugf(" { %d, %d, %d, %d },\n",
107 rect[i].fLeft, rect[i].fTop,
108 rect[i].fRight, rect[i].fBottom);
109 }
110 SkDebugf("\n");
111 return false;
112 }
113 return true;
114}
115
116static void TestRegion(skiatest::Reporter* reporter) {
117 const SkIRect r2[] = {
118 { 0, 0, 1, 1 },
119 { 2, 2, 3, 3 },
120 };
121 REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
122
123 const SkIRect rects[] = {
124 { 0, 0, 1, 2 },
125 { 2, 1, 3, 3 },
126 { 4, 0, 5, 1 },
127 { 6, 0, 7, 4 },
128 };
129 REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
130
131 SkRandom rand;
132 for (int i = 0; i < 1000; i++) {
133 SkRegion rgn0, rgn1;
134
135 const int N = 8;
136 SkIRect rect[N];
137 for (int j = 0; j < N; j++) {
138 rand_rect(&rect[j], rand);
139 }
140 REPORTER_ASSERT(reporter, test_rects(rect, N));
141 }
mike@reedtribe.org67c31842012-04-28 20:09:19 +0000142
143 test_proc(reporter, contains_proc);
144 test_proc(reporter, intersects_proc);
reed@google.com8a0d8ff2012-04-30 16:28:04 +0000145 test_empties(reporter);
reed@android.com097a3512010-07-13 18:35:14 +0000146}
147
148#include "TestClassDef.h"
149DEFINE_TESTCLASS("Region", RegionTestClass, TestRegion)