1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.org
895e3c058ef633782f7549e9e1c2727d60dbc8ee5Hal Canary#include "SkAutoMalloc.h"
9c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed#include "SkPath.h"
10097a3513535ad854c1b049c32c080ec875ab1411reed@android.com#include "SkRandom.h"
118f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "SkRegion.h"
128f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h"
13097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
145a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.orgstatic void Union(SkRegion* rgn, const SkIRect& rect) {
155a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    rgn->op(rect, SkRegion::kUnion_Op);
165a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org}
175a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org
185a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org#define TEST_NO_INTERSECT(rgn, rect)    REPORTER_ASSERT(reporter, !rgn.intersects(rect))
195a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org#define TEST_INTERSECT(rgn, rect)       REPORTER_ASSERT(reporter, rgn.intersects(rect))
20796a1753d96eb0c76e742c8288617d758ddf33dfmike@reedtribe.org#define TEST_NO_CONTAINS(rgn, rect)     REPORTER_ASSERT(reporter, !rgn.contains(rect))
215a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org
225a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org// inspired by http://code.google.com/p/skia/issues/detail?id=958
235a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org//
245a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.orgstatic void test_fromchrome(skiatest::Reporter* reporter) {
255a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    SkRegion r;
265a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&r, SkIRect::MakeXYWH(0, 0, 1, 1));
275a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_NO_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 0, 0));
285a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 2, 2));
295a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 0, 2, 2));
305a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
315a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 2, 2));
325a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 3, 3));
3372b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
345a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&r, SkIRect::MakeXYWH(0, 0, 3, 3));
355a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&r, SkIRect::MakeXYWH(10, 0, 3, 3));
365a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&r, SkIRect::MakeXYWH(0, 10, 13, 3));
375a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, -1, 2, 2));
385a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 2, 2));
395a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 2, 2, 2));
405a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(-1, 2, 2, 2));
4172b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
425a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(9, -1, 2, 2));
435a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(12, -1, 2, 2));
445a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(12, 2, 2, 2));
455a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(9, 2, 2, 2));
4672b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
475a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, -1, 13, 5));
485a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(1, -1, 11, 5));
495a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 9, 5));
505a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, -1, 8, 5));
515a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(3, -1, 8, 5));
5272b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
535a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 1));
545a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(1, 1, 11, 1));
555a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 9, 1));
565a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(2, 1, 8, 1));
575a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(3, 1, 8, 1));
5872b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
595a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 0, 13, 13));
605a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 1, 13, 11));
615a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 9));
625a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_INTERSECT(r, SkIRect::MakeXYWH(0, 2, 13, 8));
6372b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
6472b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
655a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    // These test SkRegion::contains(Rect) and SkRegion::contains(Region)
6672b2e6fff3f54c6aa80a98eab4c73f02a8cd450dskia.committer@gmail.com
675a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    SkRegion container;
685a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&container, SkIRect::MakeXYWH(0, 0, 40, 20));
695a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    Union(&container, SkIRect::MakeXYWH(30, 20, 10, 20));
705a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(0, 0, 10, 39));
715a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    TEST_NO_CONTAINS(container, SkIRect::MakeXYWH(29, 0, 10, 39));
72bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com
73bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com    {
74bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com        SkRegion rgn;
75bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com        Union(&rgn, SkIRect::MakeXYWH(0, 0, 10, 10));
76bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com        Union(&rgn, SkIRect::MakeLTRB(5, 10, 20, 20));
77bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com        TEST_INTERSECT(rgn, SkIRect::MakeXYWH(15, 0, 5, 11));
78bb094b947bb53374f5ad3df1b0cc71f41d43d9bfreed@google.com    }
795a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org}
805a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org
818a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.comstatic void test_empties(skiatest::Reporter* reporter) {
828a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    SkRegion valid(SkIRect::MakeWH(10, 10));
838a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    SkRegion empty, empty2;
848a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com
858a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, empty.isEmpty());
868a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !valid.isEmpty());
878a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com
888a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    // test intersects
898a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !empty.intersects(empty2));
908a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !valid.intersects(empty));
918a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com
928a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    // test contains
938a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !empty.contains(empty2));
948a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !valid.contains(empty));
958a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    REPORTER_ASSERT(reporter, !empty.contains(valid));
96c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed
97c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    SkPath emptyPath;
98c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    emptyPath.moveTo(1, 5);
99c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    emptyPath.close();
100c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    SkRegion openClip;
101c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    openClip.setRect(-16000, -16000, 16000, 16000);
102c1b11f1db69bea8d64ebf656ae92ea9ec6dbb40freed    empty.setPath(emptyPath, openClip);  // should not assert
1038a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com}
1048a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com
10567c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgenum {
10667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    W = 256,
10767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    H = 256
10867c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org};
10967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
110e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic SkIRect randRect(SkRandom& rand) {
11167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    int x = rand.nextU() % W;
11267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    int y = rand.nextU() % H;
11367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    int w = rand.nextU() % W;
11467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    int h = rand.nextU() % H;
11567c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    return SkIRect::MakeXYWH(x, y, w >> 1, h >> 1);
11667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
11767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
118e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic void randRgn(SkRandom& rand, SkRegion* rgn, int n) {
11967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    rgn->setEmpty();
12067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    for (int i = 0; i < n; ++i) {
12167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        rgn->op(randRect(rand), SkRegion::kUnion_Op);
12267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    }
12367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
12467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
12567c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgstatic bool slow_contains(const SkRegion& outer, const SkRegion& inner) {
12667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    SkRegion tmp;
12767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    tmp.op(outer, inner, SkRegion::kUnion_Op);
12867c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    return outer == tmp;
12967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
13067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
1317ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.comstatic bool slow_contains(const SkRegion& outer, const SkIRect& r) {
1327ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    SkRegion tmp;
1337ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    tmp.op(outer, SkRegion(r), SkRegion::kUnion_Op);
1347ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    return outer == tmp;
1357ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com}
1367ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com
13767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgstatic bool slow_intersects(const SkRegion& outer, const SkRegion& inner) {
13867c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    SkRegion tmp;
13967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    return tmp.op(outer, inner, SkRegion::kIntersect_Op);
14067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
14167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
1427ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.comstatic void test_contains_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
1437ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    SkRegion::Iterator iter(rgn);
1447ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    while (!iter.done()) {
1457ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com        SkIRect r = iter.rect();
1467ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com        REPORTER_ASSERT(reporter, rgn.contains(r));
1477ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com        r.inset(-1, -1);
1487ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com        REPORTER_ASSERT(reporter, !rgn.contains(r));
1497ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com        iter.next();
1507ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    }
1517ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com}
1527ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com
15367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgstatic void contains_proc(skiatest::Reporter* reporter,
15467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org                          const SkRegion& a, const SkRegion& b) {
1557ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    // test rgn
15667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    bool c0 = a.contains(b);
15767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    bool c1 = slow_contains(a, b);
15867c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    REPORTER_ASSERT(reporter, c0 == c1);
1597ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com
1607ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    // test rect
1617ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    SkIRect r = a.getBounds();
1627ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    r.inset(r.width()/4, r.height()/4);
1637ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    c0 = a.contains(r);
1647ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    c1 = slow_contains(a, r);
1657ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    REPORTER_ASSERT(reporter, c0 == c1);
1667ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com
1677ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    test_contains_iter(reporter, a);
1687ab71baf65eb7c5ee5b0025953baa5395c0fc5d4reed@google.com    test_contains_iter(reporter, b);
16967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
17067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
171684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.comstatic void test_intersects_iter(skiatest::Reporter* reporter, const SkRegion& rgn) {
172684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com    SkRegion::Iterator iter(rgn);
173684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com    while (!iter.done()) {
174684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com        SkIRect r = iter.rect();
175684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com        REPORTER_ASSERT(reporter, rgn.intersects(r));
176684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com        r.inset(-1, -1);
177684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com        REPORTER_ASSERT(reporter, rgn.intersects(r));
178684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com        iter.next();
179684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com    }
180684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com}
181684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com
18267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgstatic void intersects_proc(skiatest::Reporter* reporter,
18367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org                          const SkRegion& a, const SkRegion& b) {
18467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    bool c0 = a.intersects(b);
18567c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    bool c1 = slow_intersects(a, b);
18667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    REPORTER_ASSERT(reporter, c0 == c1);
187684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com
188684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com    test_intersects_iter(reporter, a);
189684119d126942d7a68e7b0d8de4aad18c28f1744reed@google.com    test_intersects_iter(reporter, b);
19067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
19167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
19267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.orgstatic void test_proc(skiatest::Reporter* reporter,
19367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org                      void (*proc)(skiatest::Reporter*,
19467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org                                   const SkRegion& a, const SkRegion&)) {
195e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
19667c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    for (int i = 0; i < 10000; ++i) {
19767c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        SkRegion outer;
19867c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        randRgn(rand, &outer, 8);
19967c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        SkRegion inner;
20067c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        randRgn(rand, &inner, 2);
20167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org        proc(reporter, outer, inner);
20267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    }
20367c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org}
20467c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org
205e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgstatic void rand_rect(SkIRect* rect, SkRandom& rand) {
206097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    int bits = 6;
207097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    int shift = 32 - bits;
208097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    rect->set(rand.nextU() >> shift, rand.nextU() >> shift,
209097a3513535ad854c1b049c32c080ec875ab1411reed@android.com              rand.nextU() >> shift, rand.nextU() >> shift);
210097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    rect->sort();
211097a3513535ad854c1b049c32c080ec875ab1411reed@android.com}
212097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
213097a3513535ad854c1b049c32c080ec875ab1411reed@android.comstatic bool test_rects(const SkIRect rect[], int count) {
214097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    SkRegion rgn0, rgn1;
215097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
216097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    for (int i = 0; i < count; i++) {
217097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        rgn0.op(rect[i], SkRegion::kUnion_Op);
218097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    }
219097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    rgn1.setRects(rect, count);
220097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
221097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    if (rgn0 != rgn1) {
222097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        SkDebugf("\n");
223097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        for (int i = 0; i < count; i++) {
224097a3513535ad854c1b049c32c080ec875ab1411reed@android.com            SkDebugf(" { %d, %d, %d, %d },\n",
225097a3513535ad854c1b049c32c080ec875ab1411reed@android.com                     rect[i].fLeft, rect[i].fTop,
226097a3513535ad854c1b049c32c080ec875ab1411reed@android.com                     rect[i].fRight, rect[i].fBottom);
227097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        }
228097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        SkDebugf("\n");
229097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        return false;
230097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    }
231097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    return true;
232097a3513535ad854c1b049c32c080ec875ab1411reed@android.com}
233097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
234e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Region, reporter) {
235097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    const SkIRect r2[] = {
236097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 0, 0, 1, 1 },
237097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 2, 2, 3, 3 },
238097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    };
239097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    REPORTER_ASSERT(reporter, test_rects(r2, SK_ARRAY_COUNT(r2)));
240d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
241097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    const SkIRect rects[] = {
242097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 0, 0, 1, 2 },
243097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 2, 1, 3, 3 },
244097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 4, 0, 5, 1 },
245097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        { 6, 0, 7, 4 },
246097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    };
247097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    REPORTER_ASSERT(reporter, test_rects(rects, SK_ARRAY_COUNT(rects)));
248097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
249e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.org    SkRandom rand;
250097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    for (int i = 0; i < 1000; i++) {
251097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        SkRegion rgn0, rgn1;
252097a3513535ad854c1b049c32c080ec875ab1411reed@android.com
253097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        const int N = 8;
254097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        SkIRect rect[N];
255097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        for (int j = 0; j < N; j++) {
256097a3513535ad854c1b049c32c080ec875ab1411reed@android.com            rand_rect(&rect[j], rand);
257097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        }
258097a3513535ad854c1b049c32c080ec875ab1411reed@android.com        REPORTER_ASSERT(reporter, test_rects(rect, N));
259097a3513535ad854c1b049c32c080ec875ab1411reed@android.com    }
260d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
26167c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    test_proc(reporter, contains_proc);
26267c3184a67c66e2e6f3d24ba6bccf1f3b32a5b7bmike@reedtribe.org    test_proc(reporter, intersects_proc);
2638a0d8ff854a034ff742341a2eb4bf68ba6ea1b9creed@google.com    test_empties(reporter);
2645a7ae4f5e5de3be99210dd9df89794f52c7c6d6emike@reedtribe.org    test_fromchrome(reporter);
265097a3513535ad854c1b049c32c080ec875ab1411reed@android.com}
266d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo
267d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo// Test that writeToMemory reports the same number of bytes whether there was a
268d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo// buffer to write to or not.
269d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggostatic void test_write(const SkRegion& region, skiatest::Reporter* r) {
27096fcdcc219d2a0d3579719b84b28bede76efba64halcanary    const size_t bytesNeeded = region.writeToMemory(nullptr);
271d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    SkAutoMalloc storage(bytesNeeded);
272d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    const size_t bytesWritten = region.writeToMemory(storage.get());
273d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, bytesWritten == bytesNeeded);
274251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary
275251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    // Also check that the bytes are meaningful.
276251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    SkRegion copy;
277251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    REPORTER_ASSERT(r, copy.readFromMemory(storage.get(), bytesNeeded));
278251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    REPORTER_ASSERT(r, region == copy);
279d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo}
280d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo
281d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggoDEF_TEST(Region_writeToMemory, r) {
282d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    // Test an empty region.
283d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    SkRegion region;
284d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, region.isEmpty());
285d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    test_write(region, r);
286d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo
287d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    // Test a rectangular region
288d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    bool nonEmpty = region.setRect(0, 0, 50, 50);
289d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, nonEmpty);
290d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, region.isRect());
291d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    test_write(region, r);
292d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo
293d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    // Test a complex region
294d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    nonEmpty = region.op(50, 50, 100, 100, SkRegion::kUnion_Op);
295d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, nonEmpty);
296d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    REPORTER_ASSERT(r, region.isComplex());
297d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo    test_write(region, r);
29858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary
29958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    SkRegion complexRegion;
30058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 1, 1));
30158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(0, 0, 3, 3));
30258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(10, 0, 3, 3));
30358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(0, 10, 13, 3));
30458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    test_write(complexRegion, r);
30558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary
30658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(10, 20, 3, 3));
30758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    Union(&complexRegion, SkIRect::MakeXYWH(0,  20, 3, 3));
30858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    test_write(complexRegion, r);
309d49f48ddf70cb1afcf13b7654457de8a85c12ad2scroggo}
310251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary
311251bf3e089b7422980e39bff38623c5b726c2ee4Hal CanaryDEF_TEST(Region_readFromMemory_bad, r) {
312251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    // These assume what our binary format is: conceivably we could change it
313251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    // and might need to remove or change some of these tests.
314251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary    SkRegion region;
315251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary
31658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
31758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // invalid boundary rectangle
31858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[5] = {0, 4, 4, 8, 2};
31958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
32058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
32158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    // Region Layout, Serialized Format:
32258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    //    COUNT LEFT TOP RIGHT BOTTOM Y_SPAN_COUNT TOTAL_INTERVAL_COUNT
32358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    //    Top ( Bottom Span_Interval_Count ( Left Right )* Sentinel )+ Sentinel
32458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
32558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // Example of valid data
32658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
32758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, 2147483647};
32858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 != region.readFromMemory(data, sizeof(data)));
32958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
33058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
33158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // Short count
33258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {8, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
33358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, 2147483647};
33458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
33558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
33658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
33758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // bounds don't match
33858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 11, 1, 2, 0, 10, 2, 0, 4, 6, 10,
33958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, 2147483647};
34058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
34158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
34258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
34358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        //  bad yspan count
34458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 10, 2, 2, 0, 10, 2, 0, 4, 6, 10,
34558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, 2147483647};
34658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
34758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
34858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
34958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // bad int count
35058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 10, 1, 3, 0, 10, 2, 0, 4, 6, 10,
35158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, 2147483647};
35258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
35358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
35458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
35558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // bad final sentinal
35658a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
35758a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          2147483647, -1};
35858a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
35958a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
36058a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    {
36158a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        // bad row sentinal
36258a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        int32_t data[] = {9, 0, 0, 10, 10, 1, 2, 0, 10, 2, 0, 4, 6, 10,
36358a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary                          -1, 2147483647};
36458a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary        REPORTER_ASSERT(r, 0 == region.readFromMemory(data, sizeof(data)));
36558a1ea8d54f78e1ef45240f1f1e46e537a9356f0Hal Canary    }
366251bf3e089b7422980e39bff38623c5b726c2ee4Hal Canary}
367