1 /*
2  * Copyright © 2020 Benjamin Otte
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  *
17  * Authors: Benjamin Otte <otte@gnome.org>
18  */
19 
20 #include "config.h"
21 
22 #include <gtk/gtk.h>
23 
24 static void
test_contains_rect(void)25 test_contains_rect (void)
26 {
27   static double points[] = { -5, 0, 5, 10, 15, 85, 90, 95, 100, 105 };
28 #define LAST (G_N_ELEMENTS(points) - 1)
29   GskRoundedRect rounded;
30   guint x1, x2, y1, y2;
31 
32   gsk_rounded_rect_init_from_rect (&rounded, &GRAPHENE_RECT_INIT (0, 0, 100, 100), 10);
33 
34   for (x1 = 0; x1 < G_N_ELEMENTS (points); x1++)
35     for (x2 = x1 + 1; x2 < G_N_ELEMENTS (points); x2++)
36       for (y1 = 0; y1 < G_N_ELEMENTS (points); y1++)
37         for (y2 = y1 + 1; y2 < G_N_ELEMENTS (points); y2++)
38           {
39             graphene_rect_t rect;
40             gboolean inside;
41 
42             /* check all points are in the bounding box */
43             inside = x1 > 0 && y1 > 0 && x2 < LAST && y2 < LAST;
44             /* now check all the corners */
45             inside &= x1 > 2 || y1 > 2 || (x1 == 2 && y1 == 2);
46             inside &= x2 < LAST - 2 || y1 > 2 || (x2 == LAST - 2 && y1 == 2);
47             inside &= x2 < LAST - 2 || y2 < LAST - 2 || (x2 == LAST - 2 && y2 == LAST - 2);
48             inside &= x1 > 2 || y2 < LAST - 2 || (x1 == 2 && y2 == LAST - 2);
49 
50             graphene_rect_init (&rect, points[x1], points[y1], points[x2] - points[x1], points[y2] - points[y1]);
51             if (inside)
52               g_assert_true (gsk_rounded_rect_contains_rect (&rounded, &rect));
53             else
54               g_assert_false (gsk_rounded_rect_contains_rect (&rounded, &rect));
55           }
56 #undef LAST
57 }
58 
59 static void
test_intersects_rect(void)60 test_intersects_rect (void)
61 {
62   static double points[] = { -1, 0, 1, 99, 100, 101 };
63 #define ALL_THE_POINTS (G_N_ELEMENTS(points))
64 #define HALF_THE_POINTS (ALL_THE_POINTS / 2)
65   GskRoundedRect rounded;
66   guint x1, x2, y1, y2;
67 
68   gsk_rounded_rect_init_from_rect (&rounded, &GRAPHENE_RECT_INIT (0, 0, 100, 100), 10);
69 
70   for (x1 = 0; x1 < ALL_THE_POINTS; x1++)
71     for (x2 = x1 + 1; x2 < ALL_THE_POINTS; x2++)
72       for (y1 = 0; y1 < ALL_THE_POINTS; y1++)
73         for (y2 = y1 + 1; y2 < ALL_THE_POINTS; y2++)
74           {
75             graphene_rect_t rect;
76             gboolean should_contain_x, should_contain_y;
77 
78             graphene_rect_init (&rect, points[x1], points[y1], points[x2] - points[x1], points[y2] - points[y1]);
79             should_contain_x = x1 < HALF_THE_POINTS && x2 >= HALF_THE_POINTS && y2 > 1 && y1 < ALL_THE_POINTS - 2;
80             should_contain_y = y1 < HALF_THE_POINTS && y2 >= HALF_THE_POINTS && x2 > 1 && x1 < ALL_THE_POINTS - 2;
81             if (should_contain_x || should_contain_y)
82               g_assert_true (gsk_rounded_rect_intersects_rect (&rounded, &rect));
83             else
84               g_assert_false (gsk_rounded_rect_intersects_rect (&rounded, &rect));
85           }
86 #undef ALL_THE_POINTS
87 #undef HALF_THE_POINTS
88 }
89 
90 static void
test_contains_point(void)91 test_contains_point (void)
92 {
93   GskRoundedRect rect;
94 
95   gsk_rounded_rect_init (&rect,
96                          &GRAPHENE_RECT_INIT (0, 0, 100, 100),
97                          &GRAPHENE_SIZE_INIT (0, 0),
98                          &GRAPHENE_SIZE_INIT (10, 10),
99                          &GRAPHENE_SIZE_INIT (10, 20),
100                          &GRAPHENE_SIZE_INIT (20, 10));
101 
102   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (50, 50)));
103   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (0, 0)));
104   g_assert_false (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (100, 0)));
105   g_assert_false (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (100, 100)));
106   g_assert_false (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (0, 100)));
107   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (0, 50)));
108   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (50, 0)));
109   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (50, 100)));
110   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (100, 50)));
111 
112   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (95, 5)));
113   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (95, 90)));
114   g_assert_true (gsk_rounded_rect_contains_point (&rect, &GRAPHENE_POINT_INIT (10, 95)));
115 }
116 
117 int
main(int argc,char * argv[])118 main (int   argc,
119       char *argv[])
120 {
121   gtk_test_init (&argc, &argv, NULL);
122 
123   g_test_add_func ("/rounded-rect/contains-rect", test_contains_rect);
124   g_test_add_func ("/rounded-rect/intersects-rect", test_intersects_rect);
125   g_test_add_func ("/rounded-rect/contains-point", test_contains_point);
126 
127   return g_test_run ();
128 }
129