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), nullptr, nullptr);
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] = WINPR_C_ARRAY_INIT;
76 char buffer2[64] = WINPR_C_ARRAY_INIT;
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 = nullptr;
105 HGDI_BITMAP bmp = nullptr;
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, nullptr, nullptr);
116 if (!bmp)
117 return -1;
118 gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
119 if (!gdi_SetNullClipRgn(hdc))
120 return -1;
121
122 struct testcase_t
123 {
124 const GDI_RGN* clip;
125 const GDI_RGN* in;
126 const GDI_RGN* expect;
127 };
128
129 const GDI_RGN rgn0x0_1024x768 = { 0, 0, 0, 1024, 768, FALSE };
130 const GDI_RGN rgn20x20_100x100 = { 0, 20, 20, 100, 100, FALSE };
131 const GDI_RGN rgn100x300_250x100 = { 0, 100, 300, 250, 100, FALSE };
132 const GDI_RGN rgn100x300_300x100 = { 0, 100, 300, 300, 100, FALSE };
133 const GDI_RGN rgn300x20_100x100 = { 0, 300, 20, 100, 100, FALSE };
134 const GDI_RGN rgn300x100_300x300 = { 0, 300, 100, 300, 300, FALSE };
135 const GDI_RGN rgn300x300_50x100 = { 0, 300, 300, 50, 100, FALSE };
136 const GDI_RGN rgn300x300_100x100 = { 0, 300, 300, 100, 100, FALSE };
137 const GDI_RGN rgn300x300_300x100 = { 0, 300, 300, 300, 100, FALSE };
138 const GDI_RGN rgn300x300_300x200 = { 0, 300, 300, 100, 200, FALSE };
139 const GDI_RGN rgn300x420_100x100 = { 0, 300, 420, 100, 100, FALSE };
140 const GDI_RGN rgn350x300_50x100 = { 0, 350, 300, 50, 100, FALSE };
141 const GDI_RGN rgn350x300_200x100 = { 0, 350, 300, 200, 100, FALSE };
142 const GDI_RGN rgn420x420_100x100 = { 0, 420, 420, 100, 100, FALSE };
143
144 const struct testcase_t testcases[] = {
145 /* null clipping region */
146 { nullptr, &rgn20x20_100x100, &rgn20x20_100x100 },
147 /* region all inside clipping region */
148 { &rgn0x0_1024x768, &rgn20x20_100x100, &rgn20x20_100x100 },
149 /* region all outside clipping region, on the left */
150 { &rgn300x300_100x100, &rgn20x20_100x100, nullptr },
151 /* region all outside clipping region, on the right */
152 { &rgn300x300_100x100, &rgn420x420_100x100, nullptr },
153 /* region all outside clipping region, on top */
154 { &rgn300x300_100x100, &rgn300x20_100x100, nullptr },
155 /* region all outside clipping region, at the bottom */
156 { &rgn300x300_100x100, &rgn300x420_100x100, nullptr },
157 /* left outside, right = clip, top = clip, bottom = clip */
158 { &rgn300x300_100x100, &rgn100x300_300x100, &rgn300x300_100x100 },
159 /* left outside, right inside, top = clip, bottom = clip */
160 { &rgn300x300_100x100, &rgn100x300_250x100, &rgn300x300_50x100 },
161 /* left = clip, right outside, top = clip, bottom = clip */
162 { &rgn300x300_100x100, &rgn300x300_300x100, &rgn300x300_100x100 },
163 /* left inside, right outside, top = clip, bottom = clip */
164 { &rgn300x300_100x100, &rgn350x300_200x100, &rgn350x300_50x100 },
165 /* top outside, bottom = clip, left = clip, right = clip */
166 { &rgn300x300_100x100, &rgn300x100_300x300, &rgn300x300_100x100 },
167 /* top = clip, bottom outside, left = clip, right = clip */
168 { &rgn300x300_100x100, &rgn300x300_300x200, &rgn300x300_100x100 },
169 /* top = clip, bottom = clip, top = clip, bottom = clip */
170 { &rgn300x300_100x100, &rgn300x300_100x100, &rgn300x300_100x100 }
171 };
172
173 for (size_t x = 0; x < ARRAYSIZE(testcases); x++)
174 {
175 const struct testcase_t* cur = &testcases[x];
176 if (!test_gdi_coords(x, hdc, cur->clip, cur->in, cur->expect))
177 goto fail;
178 }
179
180 rc = 0;
181fail:
182 gdi_DeleteObject((HGDIOBJECT)bmp);
183 gdi_DeleteDC(hdc);
184 return rc;
185}
186
187static int test_gdi_InvalidateRegion(void)
188{
189 int rc = -1;
190 HGDI_DC hdc = nullptr;
191 HGDI_RGN rgn1 = nullptr;
192 HGDI_RGN rgn2 = nullptr;
193 HGDI_RGN invalid = nullptr;
194 HGDI_BITMAP bmp = nullptr;
195 const UINT32 format = PIXEL_FORMAT_XRGB32;
196
197 if (!(hdc = gdi_GetDC()))
198 {
199 printf("failed to get gdi device context\n");
200 return -1;
201 }
202
203 hdc->format = format;
204 bmp = gdi_CreateBitmapEx(1024, 768, PIXEL_FORMAT_XRGB32, 0, nullptr, nullptr);
205 if (!bmp)
206 goto fail;
207 gdi_SelectObject(hdc, (HGDIOBJECT)bmp);
208 if (!gdi_SetNullClipRgn(hdc))
209 goto fail;
210 hdc->hwnd = (HGDI_WND)calloc(1, sizeof(GDI_WND));
211 if (!hdc->hwnd)
212 goto fail;
213 hdc->hwnd->invalid = gdi_CreateRectRgn(0, 0, 0, 0);
214 if (!hdc->hwnd->invalid)
215 goto fail;
216 hdc->hwnd->invalid->null = TRUE;
217 invalid = hdc->hwnd->invalid;
218 hdc->hwnd->count = 16;
219 hdc->hwnd->cinvalid = (HGDI_RGN)calloc(hdc->hwnd->count, sizeof(GDI_RGN));
220 rgn1 = gdi_CreateRectRgn(0, 0, 0, 0);
221 rgn2 = gdi_CreateRectRgn(0, 0, 0, 0);
222 rgn1->null = TRUE;
223 rgn2->null = TRUE;
224 /* no previous invalid region */
225 invalid->null = TRUE;
226 if (!gdi_SetRgn(rgn1, 300, 300, 100, 100))
227 goto fail;
228 if (!gdi_SetRgn(rgn2, 300, 300, 100, 100))
229 goto fail;
230 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
231 goto fail;
232
233 if (!gdi_EqualRgn(invalid, rgn2))
234 goto fail;
235
236 /* region same as invalid region */
237 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
238 goto fail;
239 if (!gdi_SetRgn(rgn1, 300, 300, 100, 100))
240 goto fail;
241 if (!gdi_SetRgn(rgn2, 300, 300, 100, 100))
242 goto fail;
243 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
244 goto fail;
245
246 if (!gdi_EqualRgn(invalid, rgn2))
247 goto fail;
248
249 /* left outside */
250 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
251 goto fail;
252 if (!gdi_SetRgn(rgn1, 100, 300, 300, 100))
253 goto fail;
254 if (!gdi_SetRgn(rgn2, 100, 300, 300, 100))
255 goto fail;
256 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
257 goto fail;
258
259 if (!gdi_EqualRgn(invalid, rgn2))
260 goto fail;
261
262 /* right outside */
263 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
264 goto fail;
265 if (!gdi_SetRgn(rgn1, 300, 300, 300, 100))
266 goto fail;
267 if (!gdi_SetRgn(rgn2, 300, 300, 300, 100))
268 goto fail;
269 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
270 goto fail;
271
272 if (!gdi_EqualRgn(invalid, rgn2))
273 goto fail;
274
275 /* top outside */
276 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
277 goto fail;
278 if (!gdi_SetRgn(rgn1, 300, 100, 100, 300))
279 goto fail;
280 if (!gdi_SetRgn(rgn2, 300, 100, 100, 300))
281 goto fail;
282 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
283 goto fail;
284
285 if (!gdi_EqualRgn(invalid, rgn2))
286 goto fail;
287
288 /* bottom outside */
289 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
290 goto fail;
291 if (!gdi_SetRgn(rgn1, 300, 300, 100, 300))
292 goto fail;
293 if (!gdi_SetRgn(rgn2, 300, 300, 100, 300))
294 goto fail;
295 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
296 goto fail;
297
298 if (!gdi_EqualRgn(invalid, rgn2))
299 goto fail;
300
301 /* left outside, right outside */
302 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
303 goto fail;
304 if (!gdi_SetRgn(rgn1, 100, 300, 600, 300))
305 goto fail;
306 if (!gdi_SetRgn(rgn2, 100, 300, 600, 300))
307 goto fail;
308 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
309 goto fail;
310
311 if (!gdi_EqualRgn(invalid, rgn2))
312 goto fail;
313
314 /* top outside, bottom outside */
315 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
316 goto fail;
317 if (!gdi_SetRgn(rgn1, 300, 100, 100, 500))
318 goto fail;
319 if (!gdi_SetRgn(rgn2, 300, 100, 100, 500))
320 goto fail;
321 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
322 goto fail;
323
324 if (!gdi_EqualRgn(invalid, rgn2))
325 goto fail;
326
327 /* all outside, left */
328 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
329 goto fail;
330 if (!gdi_SetRgn(rgn1, 100, 300, 100, 100))
331 goto fail;
332 if (!gdi_SetRgn(rgn2, 100, 300, 300, 100))
333 goto fail;
334 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
335 goto fail;
336
337 if (!gdi_EqualRgn(invalid, rgn2))
338 goto fail;
339
340 /* all outside, right */
341 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
342 goto fail;
343 if (!gdi_SetRgn(rgn1, 700, 300, 100, 100))
344 goto fail;
345 if (!gdi_SetRgn(rgn2, 300, 300, 500, 100))
346 goto fail;
347 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
348 goto fail;
349
350 if (!gdi_EqualRgn(invalid, rgn2))
351 goto fail;
352
353 /* all outside, top */
354 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
355 goto fail;
356 if (!gdi_SetRgn(rgn1, 300, 100, 100, 100))
357 goto fail;
358 if (!gdi_SetRgn(rgn2, 300, 100, 100, 300))
359 goto fail;
360 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
361 goto fail;
362
363 if (!gdi_EqualRgn(invalid, rgn2))
364 goto fail;
365
366 /* all outside, bottom */
367 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
368 goto fail;
369 if (!gdi_SetRgn(rgn1, 300, 500, 100, 100))
370 goto fail;
371 if (!gdi_SetRgn(rgn2, 300, 300, 100, 300))
372 goto fail;
373 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
374 goto fail;
375
376 if (!gdi_EqualRgn(invalid, rgn2))
377 goto fail;
378
379 /* all outside */
380 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
381 goto fail;
382 if (!gdi_SetRgn(rgn1, 100, 100, 600, 600))
383 goto fail;
384 if (!gdi_SetRgn(rgn2, 100, 100, 600, 600))
385 goto fail;
386 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
387 goto fail;
388
389 if (!gdi_EqualRgn(invalid, rgn2))
390 goto fail;
391
392 /* everything */
393 if (!gdi_SetRgn(invalid, 300, 300, 100, 100))
394 goto fail;
395 if (!gdi_SetRgn(rgn1, 0, 0, 1024, 768))
396 goto fail;
397 if (!gdi_SetRgn(rgn2, 0, 0, 1024, 768))
398 goto fail;
399 if (!gdi_InvalidateRegion(hdc, rgn1->x, rgn1->y, rgn1->w, rgn1->h))
400 goto fail;
401
402 if (!gdi_EqualRgn(invalid, rgn2))
403 goto fail;
404
405 rc = 0;
406fail:
407 gdi_DeleteObject((HGDIOBJECT)rgn1);
408 gdi_DeleteObject((HGDIOBJECT)rgn2);
409 gdi_DeleteObject((HGDIOBJECT)bmp);
410 gdi_DeleteDC(hdc);
411 return rc;
412}
413
414int TestGdiClip(int argc, char* argv[])
415{
416 WINPR_UNUSED(argc);
417 WINPR_UNUSED(argv);
418 (void)fprintf(stderr, "test_gdi_ClipCoords()\n");
419
420 if (test_gdi_ClipCoords() < 0)
421 return -1;
422
423 (void)fprintf(stderr, "test_gdi_InvalidateRegion()\n");
424
425 if (test_gdi_InvalidateRegion() < 0)
426 return -1;
427
428 return 0;
429}