Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1.  Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  * 2.  Redistributions in binary form must reproduce the above copyright
     10  *     notice, this list of conditions and the following disclaimer in the
     11  *     documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 #include "config.h"
     26 
     27 #include "core/platform/graphics/Region.h"
     28 
     29 #include <gtest/gtest.h>
     30 
     31 using namespace WebCore;
     32 
     33 namespace {
     34 
     35 #define TEST_INSIDE_RECT(r, x, y, w, h)                      \
     36     EXPECT_TRUE(r.contains(IntPoint(x, y)));                 \
     37     EXPECT_TRUE(r.contains(IntPoint(x + w - 1, y)));         \
     38     EXPECT_TRUE(r.contains(IntPoint(x, y + h - 1)));         \
     39     EXPECT_TRUE(r.contains(IntPoint(x + w - 1, y + h - 1))); \
     40     EXPECT_TRUE(r.contains(IntPoint(x, y + h / 2)));         \
     41     EXPECT_TRUE(r.contains(IntPoint(x + w - 1, y + h / 2))); \
     42     EXPECT_TRUE(r.contains(IntPoint(x + w / 2, y)));         \
     43     EXPECT_TRUE(r.contains(IntPoint(x + w / 2, y + h - 1))); \
     44     EXPECT_TRUE(r.contains(IntPoint(x + w / 2, y + h / 2))); \
     45 
     46 #define TEST_LEFT_OF_RECT(r, x, y, w, h)                     \
     47     EXPECT_FALSE(r.contains(IntPoint(x - 1, y)));            \
     48     EXPECT_FALSE(r.contains(IntPoint(x - 1, y + h - 1)));    \
     49 
     50 #define TEST_RIGHT_OF_RECT(r, x, y, w, h)                 \
     51     EXPECT_FALSE(r.contains(IntPoint(x + w, y)));         \
     52     EXPECT_FALSE(r.contains(IntPoint(x + w, y + h - 1))); \
     53 
     54 #define TEST_TOP_OF_RECT(r, x, y, w, h)                   \
     55     EXPECT_FALSE(r.contains(IntPoint(x, y - 1)));         \
     56     EXPECT_FALSE(r.contains(IntPoint(x + w - 1, y - 1))); \
     57 
     58 #define TEST_BOTTOM_OF_RECT(r, x, y, w, h)                \
     59     EXPECT_FALSE(r.contains(IntPoint(x, y + h)));         \
     60     EXPECT_FALSE(r.contains(IntPoint(x + w - 1, y + h))); \
     61 
     62 TEST(RegionTest, containsPoint)
     63 {
     64     Region r;
     65 
     66     EXPECT_FALSE(r.contains(IntPoint(0, 0)));
     67 
     68     r.unite(IntRect(35, 35, 1, 1));
     69     TEST_INSIDE_RECT(r, 35, 35, 1, 1);
     70     TEST_LEFT_OF_RECT(r, 35, 35, 1, 1);
     71     TEST_RIGHT_OF_RECT(r, 35, 35, 1, 1);
     72     TEST_TOP_OF_RECT(r, 35, 35, 1, 1);
     73     TEST_BOTTOM_OF_RECT(r, 35, 35, 1, 1);
     74 
     75     r.unite(IntRect(30, 30, 10, 10));
     76     TEST_INSIDE_RECT(r, 30, 30, 10, 10);
     77     TEST_LEFT_OF_RECT(r, 30, 30, 10, 10);
     78     TEST_RIGHT_OF_RECT(r, 30, 30, 10, 10);
     79     TEST_TOP_OF_RECT(r, 30, 30, 10, 10);
     80     TEST_BOTTOM_OF_RECT(r, 30, 30, 10, 10);
     81 
     82     r.unite(IntRect(31, 40, 10, 10));
     83     EXPECT_FALSE(r.contains(IntPoint(30, 40)));
     84     EXPECT_TRUE(r.contains(IntPoint(31, 40)));
     85     EXPECT_FALSE(r.contains(IntPoint(40, 39)));
     86     EXPECT_TRUE(r.contains(IntPoint(40, 40)));
     87 
     88     TEST_INSIDE_RECT(r, 30, 30, 10, 10);
     89     TEST_LEFT_OF_RECT(r, 30, 30, 10, 10);
     90     TEST_RIGHT_OF_RECT(r, 30, 30, 10, 10);
     91     TEST_TOP_OF_RECT(r, 30, 30, 10, 10);
     92     TEST_INSIDE_RECT(r, 31, 40, 10, 10);
     93     TEST_LEFT_OF_RECT(r, 31, 40, 10, 10);
     94     TEST_RIGHT_OF_RECT(r, 31, 40, 10, 10);
     95     TEST_BOTTOM_OF_RECT(r, 31, 40, 10, 10);
     96 
     97     r.unite(IntRect(42, 40, 10, 10));
     98 
     99     TEST_INSIDE_RECT(r, 42, 40, 10, 10);
    100     TEST_LEFT_OF_RECT(r, 42, 40, 10, 10);
    101     TEST_RIGHT_OF_RECT(r, 42, 40, 10, 10);
    102     TEST_TOP_OF_RECT(r, 42, 40, 10, 10);
    103     TEST_BOTTOM_OF_RECT(r, 42, 40, 10, 10);
    104 
    105     TEST_INSIDE_RECT(r, 30, 30, 10, 10);
    106     TEST_LEFT_OF_RECT(r, 30, 30, 10, 10);
    107     TEST_RIGHT_OF_RECT(r, 30, 30, 10, 10);
    108     TEST_TOP_OF_RECT(r, 30, 30, 10, 10);
    109     TEST_INSIDE_RECT(r, 31, 40, 10, 10);
    110     TEST_LEFT_OF_RECT(r, 31, 40, 10, 10);
    111     TEST_RIGHT_OF_RECT(r, 31, 40, 10, 10);
    112     TEST_BOTTOM_OF_RECT(r, 31, 40, 10, 10);
    113 }
    114 
    115 TEST(RegionTest, emptySpan)
    116 {
    117     Region r;
    118     r.unite(IntRect(5, 0, 10, 10));
    119     r.unite(IntRect(0, 5, 10, 10));
    120     r.subtract(IntRect(7, 7, 10, 0));
    121 
    122     Vector<IntRect> rects = r.rects();
    123     for (size_t i = 0; i < rects.size(); ++i)
    124         EXPECT_FALSE(rects[i].isEmpty());
    125 }
    126 
    127 #define TEST_NO_INTERSECT(a, b)      \
    128 {                                    \
    129     Region ar = a;                   \
    130     Region br = b;                   \
    131     EXPECT_FALSE(ar.intersects(br)); \
    132     EXPECT_FALSE(br.intersects(ar)); \
    133 }
    134 
    135 #define TEST_INTERSECT(a, b)        \
    136 {                                   \
    137     Region ar = a;                  \
    138     Region br = b;                  \
    139     EXPECT_TRUE(ar.intersects(br)); \
    140     EXPECT_TRUE(br.intersects(ar)); \
    141 }
    142 
    143 TEST(RegionTest, intersectsRegion)
    144 {
    145     Region r;
    146 
    147     TEST_NO_INTERSECT(IntRect(), IntRect());
    148     TEST_NO_INTERSECT(IntRect(), IntRect(0, 0, 1, 1));
    149     TEST_NO_INTERSECT(IntRect(), IntRect(1, 1, 1, 1));
    150 
    151     r.unite(IntRect(0, 0, 1, 1));
    152     TEST_NO_INTERSECT(r, IntRect());
    153     TEST_INTERSECT(r, IntRect(0, 0, 1, 1));
    154     TEST_INTERSECT(r, IntRect(0, 0, 2, 2));
    155     TEST_INTERSECT(r, IntRect(-1, 0, 2, 2));
    156     TEST_INTERSECT(r, IntRect(-1, -1, 2, 2));
    157     TEST_INTERSECT(r, IntRect(0, -1, 2, 2));
    158     TEST_INTERSECT(r, IntRect(-1, -1, 3, 3));
    159 
    160     r.unite(IntRect(0, 0, 3, 3));
    161     r.unite(IntRect(10, 0, 3, 3));
    162     r.unite(IntRect(0, 10, 13, 3));
    163     TEST_NO_INTERSECT(r, IntRect());
    164     TEST_INTERSECT(r, IntRect(1, 1, 1, 1));
    165     TEST_INTERSECT(r, IntRect(0, 0, 2, 2));
    166     TEST_INTERSECT(r, IntRect(1, 0, 2, 2));
    167     TEST_INTERSECT(r, IntRect(1, 1, 2, 2));
    168     TEST_INTERSECT(r, IntRect(0, 1, 2, 2));
    169     TEST_INTERSECT(r, IntRect(0, 0, 3, 3));
    170     TEST_INTERSECT(r, IntRect(-1, -1, 2, 2));
    171     TEST_INTERSECT(r, IntRect(2, -1, 2, 2));
    172     TEST_INTERSECT(r, IntRect(2, 2, 2, 2));
    173     TEST_INTERSECT(r, IntRect(-1, 2, 2, 2));
    174 
    175     TEST_INTERSECT(r, IntRect(11, 1, 1, 1));
    176     TEST_INTERSECT(r, IntRect(10, 0, 2, 2));
    177     TEST_INTERSECT(r, IntRect(11, 0, 2, 2));
    178     TEST_INTERSECT(r, IntRect(11, 1, 2, 2));
    179     TEST_INTERSECT(r, IntRect(10, 1, 2, 2));
    180     TEST_INTERSECT(r, IntRect(10, 0, 3, 3));
    181     TEST_INTERSECT(r, IntRect(9, -1, 2, 2));
    182     TEST_INTERSECT(r, IntRect(12, -1, 2, 2));
    183     TEST_INTERSECT(r, IntRect(12, 2, 2, 2));
    184     TEST_INTERSECT(r, IntRect(9, 2, 2, 2));
    185 
    186     TEST_INTERSECT(r, IntRect(0, -1, 13, 5));
    187     TEST_INTERSECT(r, IntRect(1, -1, 11, 5));
    188     TEST_INTERSECT(r, IntRect(2, -1, 9, 5));
    189     TEST_INTERSECT(r, IntRect(2, -1, 8, 5));
    190     TEST_INTERSECT(r, IntRect(3, -1, 8, 5));
    191     TEST_NO_INTERSECT(r, IntRect(3, -1, 7, 5));
    192 
    193     TEST_INTERSECT(r, IntRect(0, 1, 13, 1));
    194     TEST_INTERSECT(r, IntRect(1, 1, 11, 1));
    195     TEST_INTERSECT(r, IntRect(2, 1, 9, 1));
    196     TEST_INTERSECT(r, IntRect(2, 1, 8, 1));
    197     TEST_INTERSECT(r, IntRect(3, 1, 8, 1));
    198     TEST_NO_INTERSECT(r, IntRect(3, 1, 7, 1));
    199 
    200     TEST_INTERSECT(r, IntRect(0, 0, 13, 13));
    201     TEST_INTERSECT(r, IntRect(0, 1, 13, 11));
    202     TEST_INTERSECT(r, IntRect(0, 2, 13, 9));
    203     TEST_INTERSECT(r, IntRect(0, 2, 13, 8));
    204     TEST_INTERSECT(r, IntRect(0, 3, 13, 8));
    205     TEST_NO_INTERSECT(r, IntRect(0, 3, 13, 7));
    206 }
    207 
    208 TEST(RegionTest, ReadPastFullSpanVectorInIntersectsTest)
    209 {
    210     Region r;
    211 
    212     // This region has enough spans to fill its allocated Vector exactly.
    213     r.unite(IntRect(400, 300, 1, 800));
    214     r.unite(IntRect(785, 585, 1, 1));
    215     r.unite(IntRect(787, 585, 1, 1));
    216     r.unite(IntRect(0, 587, 16, 162));
    217     r.unite(IntRect(26, 590, 300, 150));
    218     r.unite(IntRect(196, 750, 1, 1));
    219     r.unite(IntRect(0, 766, 1, 1));
    220     r.unite(IntRect(0, 782, 1, 1));
    221     r.unite(IntRect(745, 798, 1, 1));
    222     r.unite(IntRect(795, 882, 10, 585));
    223     r.unite(IntRect(100, 1499, 586, 1));
    224     r.unite(IntRect(100, 1500, 585, 784));
    225     // This query rect goes past the bottom of the Region, causing the
    226     // test to reach the last span and try go past it. It should not read
    227     // memory off the end of the span Vector.
    228     TEST_NO_INTERSECT(r, IntRect(0, 2184, 1, 150));
    229 }
    230 
    231 #define TEST_NO_CONTAINS(a, b)     \
    232 {                                  \
    233     Region ar = a;                 \
    234     Region br = b;                 \
    235     EXPECT_FALSE(ar.contains(br)); \
    236 }
    237 
    238 #define TEST_CONTAINS(a, b)       \
    239 {                                 \
    240     Region ar = a;                \
    241     Region br = b;                \
    242     EXPECT_TRUE(ar.contains(br)); \
    243 }
    244 
    245 TEST(RegionTest, containsRegion)
    246 {
    247     TEST_CONTAINS(IntRect(), IntRect());
    248     TEST_NO_CONTAINS(IntRect(), IntRect(0, 0, 1, 1));
    249     TEST_NO_CONTAINS(IntRect(), IntRect(1, 1, 1, 1));
    250 
    251     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(11, 10, 1, 1));
    252     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(10, 11, 1, 1));
    253     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(9, 10, 1, 1));
    254     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(10, 9, 1, 1));
    255     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(9, 9, 2, 2));
    256     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(10, 9, 2, 2));
    257     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(9, 10, 2, 2));
    258     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(10, 10, 2, 2));
    259     TEST_NO_CONTAINS(IntRect(10, 10, 1, 1), IntRect(9, 9, 3, 3));
    260 
    261     Region hLines;
    262     for (int i = 10; i < 20; i += 2)
    263         hLines.unite(IntRect(i, 10, 1, 10));
    264 
    265     TEST_CONTAINS(IntRect(10, 10, 9, 10), hLines);
    266     TEST_NO_CONTAINS(IntRect(10, 10, 9, 9), hLines);
    267     TEST_NO_CONTAINS(IntRect(10, 11, 9, 9), hLines);
    268     TEST_NO_CONTAINS(IntRect(10, 10, 8, 10), hLines);
    269     TEST_NO_CONTAINS(IntRect(11, 10, 8, 10), hLines);
    270 
    271     Region vLines;
    272     for (int i = 10; i < 20; i += 2)
    273         vLines.unite(IntRect(10, i, 10, 1));
    274 
    275     TEST_CONTAINS(IntRect(10, 10, 10, 9), vLines);
    276     TEST_NO_CONTAINS(IntRect(10, 10, 9, 9), vLines);
    277     TEST_NO_CONTAINS(IntRect(11, 10, 9, 9), vLines);
    278     TEST_NO_CONTAINS(IntRect(10, 10, 10, 8), vLines);
    279     TEST_NO_CONTAINS(IntRect(10, 11, 10, 8), vLines);
    280 
    281     Region grid;
    282     for (int i = 10; i < 20; i += 2)
    283         for (int j = 10; j < 20; j += 2)
    284             grid.unite(IntRect(i, j, 1, 1));
    285 
    286     TEST_CONTAINS(IntRect(10, 10, 9, 9), grid);
    287     TEST_NO_CONTAINS(IntRect(10, 10, 9, 8), grid);
    288     TEST_NO_CONTAINS(IntRect(10, 11, 9, 8), grid);
    289     TEST_NO_CONTAINS(IntRect(10, 10, 8, 9), grid);
    290     TEST_NO_CONTAINS(IntRect(11, 10, 8, 9), grid);
    291 
    292     TEST_CONTAINS(hLines, hLines);
    293     TEST_CONTAINS(vLines, vLines);
    294     TEST_NO_CONTAINS(vLines, hLines);
    295     TEST_NO_CONTAINS(hLines, vLines);
    296     TEST_CONTAINS(grid, grid);
    297     TEST_CONTAINS(hLines, grid);
    298     TEST_CONTAINS(vLines, grid);
    299     TEST_NO_CONTAINS(grid, hLines);
    300     TEST_NO_CONTAINS(grid, vLines);
    301 
    302     for (int i = 10; i < 20; i += 2)
    303         TEST_CONTAINS(hLines, IntRect(i, 10, 1, 10));
    304 
    305     for (int i = 10; i < 20; i += 2)
    306         TEST_CONTAINS(vLines, IntRect(10, i, 10, 1));
    307 
    308     for (int i = 10; i < 20; i += 2)
    309         for (int j = 10; j < 20; j += 2)
    310             TEST_CONTAINS(grid, IntRect(i, j, 1, 1));
    311 
    312     Region container;
    313     container.unite(IntRect(0, 0, 40, 20));
    314     container.unite(IntRect(0, 20, 41, 20));
    315     TEST_CONTAINS(container, IntRect(5, 5, 30, 30));
    316 
    317     container = Region();
    318     container.unite(IntRect(0, 0, 10, 10));
    319     container.unite(IntRect(0, 30, 10, 10));
    320     container.unite(IntRect(30, 30, 10, 10));
    321     container.unite(IntRect(30, 0, 10, 10));
    322     TEST_NO_CONTAINS(container, IntRect(5, 5, 30, 30));
    323 
    324     container = Region();
    325     container.unite(IntRect(0, 0, 10, 10));
    326     container.unite(IntRect(0, 30, 10, 10));
    327     container.unite(IntRect(30, 0, 10, 40));
    328     TEST_NO_CONTAINS(container, IntRect(5, 5, 30, 30));
    329 
    330     container = Region();
    331     container.unite(IntRect(30, 0, 10, 10));
    332     container.unite(IntRect(30, 30, 10, 10));
    333     container.unite(IntRect(0, 0, 10, 40));
    334     TEST_NO_CONTAINS(container, IntRect(5, 5, 30, 30));
    335 
    336     container = Region();
    337     container.unite(IntRect(0, 0, 10, 40));
    338     container.unite(IntRect(30, 0, 10, 40));
    339     TEST_NO_CONTAINS(container, IntRect(5, 5, 30, 30));
    340 
    341     container = Region();
    342     container.unite(IntRect(0, 0, 40, 40));
    343     TEST_NO_CONTAINS(container, IntRect(10, -1, 20, 10));
    344 
    345     container = Region();
    346     container.unite(IntRect(0, 0, 40, 40));
    347     TEST_NO_CONTAINS(container, IntRect(10, 31, 20, 10));
    348 
    349     container = Region();
    350     container.unite(IntRect(0, 0, 40, 20));
    351     container.unite(IntRect(0, 20, 41, 20));
    352     TEST_NO_CONTAINS(container, IntRect(-1, 10, 10, 20));
    353 
    354     container = Region();
    355     container.unite(IntRect(0, 0, 40, 20));
    356     container.unite(IntRect(0, 20, 41, 20));
    357     TEST_NO_CONTAINS(container, IntRect(31, 10, 10, 20));
    358 
    359     container = Region();
    360     container.unite(IntRect(0, 0, 40, 40));
    361     container.subtract(IntRect(0, 20, 60, 0));
    362     TEST_NO_CONTAINS(container, IntRect(31, 10, 10, 20));
    363 }
    364 
    365 TEST(RegionTest, unite)
    366 {
    367     Region r;
    368     Region r2;
    369 
    370     // A rect uniting a contained rect does not change the region.
    371     r2 = r = IntRect(0, 0, 50, 50);
    372     r2.unite(IntRect(20, 20, 10, 10));
    373     EXPECT_EQ(r, r2);
    374 
    375     // A rect uniting a containing rect gives back the containing rect.
    376     r = IntRect(0, 0, 50, 50);
    377     r.unite(IntRect(0, 0, 100, 100));
    378     EXPECT_EQ(Region(IntRect(0, 0, 100, 100)), r);
    379 
    380     // A complex region uniting a contained rect does not change the region.
    381     r = IntRect(0, 0, 50, 50);
    382     r.unite(IntRect(100, 0, 50, 50));
    383     r2 = r;
    384     r2.unite(IntRect(20, 20, 10, 10));
    385     EXPECT_EQ(r, r2);
    386 
    387     // A complex region uniting a containing rect gives back the containing rect.
    388     r = IntRect(0, 0, 50, 50);
    389     r.unite(IntRect(100, 0, 50, 50));
    390     r. unite(IntRect(0, 0, 500, 500));
    391     EXPECT_EQ(Region(IntRect(0, 0, 500, 500)), r);
    392 }
    393 
    394 } // namespace
    395