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