FreeRDP
Loading...
Searching...
No Matches
TestGdiClip.c
1
2#include <freerdp/gdi/gdi.h>
3
4#include <freerdp/gdi/dc.h>
5#include <freerdp/gdi/pen.h>
6#include <freerdp/gdi/region.h>
7#include <freerdp/gdi/bitmap.h>
8
9#include <winpr/crt.h>
10
11#include "line.h"
12#include "brush.h"
13#include "clipping.h"
14
15static bool test_gdi_coords(size_t testNr, HGDI_DC hdc, const GDI_RGN* clip, const GDI_RGN* input,
16 const GDI_RGN* expect)
17{
18 bool rc = false;
19
20 WINPR_ASSERT(hdc);
21 WINPR_ASSERT(input);
22
23 HGDI_RGN rgn1 = gdi_CreateRectRgn(0, 0, 0, 0);
24 HGDI_RGN rgn2 = gdi_CreateRectRgn(0, 0, 0, 0);
25 if (!rgn1 || !rgn2)
26 {
27 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_CreateRectRgn failed: rgn1=%p, rgn2=%p\n",
28 __func__, testNr, rgn1, rgn2);
29 goto fail;
30 }
31
32 if (!clip)
33 {
34 if (!gdi_SetNullClipRgn(hdc))
35 {
36 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetNullClipRgn failed\n", __func__, testNr);
37 goto fail;
38 }
39 }
40 else if (!gdi_SetClipRgn(hdc, clip->x, clip->y, clip->w, clip->h))
41 {
42 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetClipRgn failed\n", __func__, testNr);
43 goto fail;
44 }
45
46 if (!gdi_SetRgn(rgn1, input->x, input->y, input->w, input->h))
47 {
48 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetRgn (rgn1) failed\n", __func__, testNr);
49 goto fail;
50 }
51
52 if (expect)
53 {
54 if (!gdi_SetRgn(rgn2, expect->x, expect->y, expect->w, expect->h))
55 {
56 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_SetRgn (rgn2) failed\n", __func__, testNr);
57 goto fail;
58 }
59 }
60
61 const BOOL draw =
62 gdi_ClipCoords(hdc, &(rgn1->x), &(rgn1->y), &(rgn1->w), &(rgn1->h), NULL, NULL);
63 if (expect)
64 {
65 if (!draw)
66 {
67 (void)fprintf(stderr,
68 "[%s:%" PRIuz "] gdi_ClipCoords failed: expected TRUE, got FALSE\n",
69 __func__, testNr);
70 goto fail;
71 }
72
73 if (!gdi_EqualRgn(rgn1, rgn2))
74 {
75 char buffer1[64] = { 0 };
76 char buffer2[64] = { 0 };
77 (void)fprintf(stderr, "[%s:%" PRIuz "] gdi_EqualRgn failed: expected %s, got %s\n",
78 __func__, testNr, buffer1, buffer2);
79 goto fail;
80 }
81 }
82 else
83 {
84 if (draw)
85 {
86 (void)fprintf(stderr,
87 "[%s:%" PRIuz "] gdi_ClipCoords failed: expected FALSE, got TRUE\n",
88 __func__, testNr);
89 goto fail;
90 }
91 }
92
93 rc = true;
94
95fail:
96 gdi_DeleteObject((HGDIOBJECT)rgn1);
97 gdi_DeleteObject((HGDIOBJECT)rgn2);
98 return rc;
99}
100
101static int test_gdi_ClipCoords(void)
102{
103 int rc = -1;
104 HGDI_DC hdc = NULL;
105 HGDI_BITMAP bmp = NULL;
106 const UINT32 format = PIXEL_FORMAT_ARGB32;
107
108 if (!(hdc = gdi_GetDC()))
109 {
110 printf("failed to get gdi device context\n");
111 return -1;
112 }
113
114 hdc->format = format;
115 bmp = gdi_CreateBitmapEx(1024, 768, PIXEL_FORMAT_XRGB32, 0, NULL, NULL);
116 gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
117 gdi_SetNullClipRgn(hdc);
118
119 struct testcase_t
120 {
121 const GDI_RGN* clip;
122 const GDI_RGN* in;
123 const GDI_RGN* expect;
124 };
125
126 const GDI_RGN rgn0x0_1024x768 = { 0, 0, 0, 1024, 768, FALSE };
127 const GDI_RGN rgn20x20_100x100 = { 0, 20, 20, 100, 100, FALSE };
128 const GDI_RGN rgn100x300_250x100 = { 0, 100, 300, 250, 100, FALSE };
129 const GDI_RGN rgn100x300_300x100 = { 0, 100, 300, 300, 100, FALSE };
130 const GDI_RGN rgn300x20_100x100 = { 0, 300, 20, 100, 100, FALSE };
131 const GDI_RGN rgn300x100_300x300 = { 0, 300, 100, 300, 300, FALSE };
132 const GDI_RGN rgn300x300_50x100 = { 0, 300, 300, 50, 100, FALSE };
133 const GDI_RGN rgn300x300_100x100 = { 0, 300, 300, 100, 100, FALSE };
134 const GDI_RGN rgn300x300_300x100 = { 0, 300, 300, 300, 100, FALSE };
135 const GDI_RGN rgn300x300_300x200 = { 0, 300, 300, 100, 200, FALSE };
136 const GDI_RGN rgn300x420_100x100 = { 0, 300, 420, 100, 100, FALSE };
137 const GDI_RGN rgn350x300_50x100 = { 0, 350, 300, 50, 100, FALSE };
138 const GDI_RGN rgn350x300_200x100 = { 0, 350, 300, 200, 100, FALSE };
139 const GDI_RGN rgn420x420_100x100 = { 0, 420, 420, 100, 100, FALSE };
140
141 const struct testcase_t testcases[] = {
142 /* null clipping region */
143 { NULL, &rgn20x20_100x100, &rgn20x20_100x100 },
144 /* region all inside clipping region */
145 { &rgn0x0_1024x768, &rgn20x20_100x100, &rgn20x20_100x100 },
146 /* region all outside clipping region, on the left */
147 { &rgn300x300_100x100, &rgn20x20_100x100, NULL },
148 /* region all outside clipping region, on the right */
149 { &rgn300x300_100x100, &rgn420x420_100x100, NULL },
150 /* region all outside clipping region, on top */
151 { &rgn300x300_100x100, &rgn300x20_100x100, NULL },
152 /* region all outside clipping region, at the bottom */
153 { &rgn300x300_100x100, &rgn300x420_100x100, NULL },
154 /* left outside, right = clip, top = clip, bottom = clip */
155 { &rgn300x300_100x100, &rgn100x300_300x100, &rgn300x300_100x100 },
156 /* left outside, right inside, top = clip, bottom = clip */
157 { &rgn300x300_100x100, &rgn100x300_250x100, &rgn300x300_50x100 },
158 /* left = clip, right outside, top = clip, bottom = clip */
159 { &rgn300x300_100x100, &rgn300x300_300x100, &rgn300x300_100x100 },
160 /* left inside, right outside, top = clip, bottom = clip */
161 { &rgn300x300_100x100, &rgn350x300_200x100, &rgn350x300_50x100 },
162 /* top outside, bottom = clip, left = clip, right = clip */
163 { &rgn300x300_100x100, &rgn300x100_300x300, &rgn300x300_100x100 },
164 /* top = clip, bottom outside, left = clip, right = clip */
165 { &rgn300x300_100x100, &rgn300x300_300x200, &rgn300x300_100x100 },
166 /* top = clip, bottom = clip, top = clip, bottom = clip */
167 { &rgn300x300_100x100, &rgn300x300_100x100, &rgn300x300_100x100 }
168 };
169
170 for (size_t x = 0; x < ARRAYSIZE(testcases); x++)
171 {
172 const struct testcase_t* cur = &testcases[x];
173 if (!test_gdi_coords(x, hdc, cur->clip, cur->in, cur->expect))
174 goto fail;
175 }
176
177 rc = 0;
178fail:
179 gdi_DeleteObject((HGDIOBJECT)bmp);
180 gdi_DeleteDC(hdc);
181 return rc;
182}
183
184static int test_gdi_InvalidateRegion(void)
185{
186 int rc = -1;
187 HGDI_DC hdc = NULL;
188 HGDI_RGN rgn1 = NULL;
189 HGDI_RGN rgn2 = NULL;
190 HGDI_RGN invalid = NULL;
191 HGDI_BITMAP bmp = NULL;
192 const UINT32 format = PIXEL_FORMAT_XRGB32;
193
194 if (!(hdc = gdi_GetDC()))
195 {
196 printf("failed to get gdi device context\n");
197 return -1;
198 }
199
200 hdc->format = format;
201 bmp = gdi_CreateBitmapEx(1024, 768, PIXEL_FORMAT_XRGB32, 0, NULL, NULL);
202 gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
203 gdi_SetNullClipRgn(hdc);
204 hdc->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND));
205 hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);
206 hdc->hwnd->invalid->null = TRUE;
207 invalid = hdc->hwnd->invalid;
208 hdc->hwnd->count = 16;
209 hdc->hwnd->cinvalid = (HGDI_RGN)calloc(hdc->hwnd->count, sizeof(GDI_RGN));
210 rgn1 = gdi_CreateRectRgn(0, 0, 0, 0);
211 rgn2 = gdi_CreateRectRgn(0, 0, 0, 0);
212 rgn1->null = TRUE;
213 rgn2->null = TRUE;
214 /* no previous invalid region */
215 invalid->null = TRUE;
216 gdi_SetRgn(rgn1, 300, 300, 100, 100);
217 gdi_SetRgn(rgn2, 300, 300, 100, 100);
218 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
219
220 if (!gdi_EqualRgn(invalid, rgn2))
221 goto fail;
222
223 /* region same as invalid region */
224 gdi_SetRgn(invalid, 300, 300, 100, 100);
225 gdi_SetRgn(rgn1, 300, 300, 100, 100);
226 gdi_SetRgn(rgn2, 300, 300, 100, 100);
227 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
228
229 if (!gdi_EqualRgn(invalid, rgn2))
230 goto fail;
231
232 /* left outside */
233 gdi_SetRgn(invalid, 300, 300, 100, 100);
234 gdi_SetRgn(rgn1, 100, 300, 300, 100);
235 gdi_SetRgn(rgn2, 100, 300, 300, 100);
236 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
237
238 if (!gdi_EqualRgn(invalid, rgn2))
239 goto fail;
240
241 /* right outside */
242 gdi_SetRgn(invalid, 300, 300, 100, 100);
243 gdi_SetRgn(rgn1, 300, 300, 300, 100);
244 gdi_SetRgn(rgn2, 300, 300, 300, 100);
245 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
246
247 if (!gdi_EqualRgn(invalid, rgn2))
248 goto fail;
249
250 /* top outside */
251 gdi_SetRgn(invalid, 300, 300, 100, 100);
252 gdi_SetRgn(rgn1, 300, 100, 100, 300);
253 gdi_SetRgn(rgn2, 300, 100, 100, 300);
254 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
255
256 if (!gdi_EqualRgn(invalid, rgn2))
257 goto fail;
258
259 /* bottom outside */
260 gdi_SetRgn(invalid, 300, 300, 100, 100);
261 gdi_SetRgn(rgn1, 300, 300, 100, 300);
262 gdi_SetRgn(rgn2, 300, 300, 100, 300);
263 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
264
265 if (!gdi_EqualRgn(invalid, rgn2))
266 goto fail;
267
268 /* left outside, right outside */
269 gdi_SetRgn(invalid, 300, 300, 100, 100);
270 gdi_SetRgn(rgn1, 100, 300, 600, 300);
271 gdi_SetRgn(rgn2, 100, 300, 600, 300);
272 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
273
274 if (!gdi_EqualRgn(invalid, rgn2))
275 goto fail;
276
277 /* top outside, bottom outside */
278 gdi_SetRgn(invalid, 300, 300, 100, 100);
279 gdi_SetRgn(rgn1, 300, 100, 100, 500);
280 gdi_SetRgn(rgn2, 300, 100, 100, 500);
281 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
282
283 if (!gdi_EqualRgn(invalid, rgn2))
284 goto fail;
285
286 /* all outside, left */
287 gdi_SetRgn(invalid, 300, 300, 100, 100);
288 gdi_SetRgn(rgn1, 100, 300, 100, 100);
289 gdi_SetRgn(rgn2, 100, 300, 300, 100);
290 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
291
292 if (!gdi_EqualRgn(invalid, rgn2))
293 goto fail;
294
295 /* all outside, right */
296 gdi_SetRgn(invalid, 300, 300, 100, 100);
297 gdi_SetRgn(rgn1, 700, 300, 100, 100);
298 gdi_SetRgn(rgn2, 300, 300, 500, 100);
299 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
300
301 if (!gdi_EqualRgn(invalid, rgn2))
302 goto fail;
303
304 /* all outside, top */
305 gdi_SetRgn(invalid, 300, 300, 100, 100);
306 gdi_SetRgn(rgn1, 300, 100, 100, 100);
307 gdi_SetRgn(rgn2, 300, 100, 100, 300);
308 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
309
310 if (!gdi_EqualRgn(invalid, rgn2))
311 goto fail;
312
313 /* all outside, bottom */
314 gdi_SetRgn(invalid, 300, 300, 100, 100);
315 gdi_SetRgn(rgn1, 300, 500, 100, 100);
316 gdi_SetRgn(rgn2, 300, 300, 100, 300);
317 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
318
319 if (!gdi_EqualRgn(invalid, rgn2))
320 goto fail;
321
322 /* all outside */
323 gdi_SetRgn(invalid, 300, 300, 100, 100);
324 gdi_SetRgn(rgn1, 100, 100, 600, 600);
325 gdi_SetRgn(rgn2, 100, 100, 600, 600);
326 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
327
328 if (!gdi_EqualRgn(invalid, rgn2))
329 goto fail;
330
331 /* everything */
332 gdi_SetRgn(invalid, 300, 300, 100, 100);
333 gdi_SetRgn(rgn1, 0, 0, 1024, 768);
334 gdi_SetRgn(rgn2, 0, 0, 1024, 768);
335 gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h);
336
337 if (!gdi_EqualRgn(invalid, rgn2))
338 goto fail;
339
340 rc = 0;
341fail:
342 gdi_DeleteObject((HGDIOBJECT)rgn1);
343 gdi_DeleteObject((HGDIOBJECT)rgn2);
344 gdi_DeleteObject((HGDIOBJECT)bmp);
345 gdi_DeleteDC(hdc);
346 return rc;
347}
348
349int TestGdiClip(int argc, char* argv[])
350{
351 WINPR_UNUSED(argc);
352 WINPR_UNUSED(argv);
353 (void)fprintf(stderr, "test_gdi_ClipCoords()\n");
354
355 if (test_gdi_ClipCoords() < 0)
356 return -1;
357
358 (void)fprintf(stderr, "test_gdi_InvalidateRegion()\n");
359
360 if (test_gdi_InvalidateRegion() < 0)
361 return -1;
362
363 return 0;
364}