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