1 /*
2  * Unit test suite for paths
3  *
4  * Copyright 2007 Laurent Vromman
5  * Copyright 2007 Misha Koshelev
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 
29 #include "wine/test.h"
30 
31 #include "winuser.h"
32 #include "winerror.h"
33 
34 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
35 
test_path_state(void)36 static void test_path_state(void)
37 {
38     BYTE buffer[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
39     BITMAPINFO *bi = (BITMAPINFO *)buffer;
40     HDC hdc;
41     HRGN rgn;
42     HBITMAP orig, dib;
43     void *bits;
44     BOOL ret;
45 
46     hdc = CreateCompatibleDC( 0 );
47     memset( buffer, 0, sizeof(buffer) );
48     bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
49     bi->bmiHeader.biHeight = 256;
50     bi->bmiHeader.biWidth = 256;
51     bi->bmiHeader.biBitCount = 32;
52     bi->bmiHeader.biPlanes = 1;
53     bi->bmiHeader.biCompression = BI_RGB;
54     dib = CreateDIBSection( 0, bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0 );
55     orig = SelectObject( hdc, dib );
56 
57     BeginPath( hdc );
58     LineTo( hdc, 100, 100 );
59     ret = WidenPath( hdc );
60     ok( !ret, "WidenPath succeeded\n" );
61 
62     /* selecting another bitmap doesn't affect the path */
63     SelectObject( hdc, orig );
64     ret = WidenPath( hdc );
65     ok( !ret, "WidenPath succeeded\n" );
66 
67     SelectObject( hdc, dib );
68     ret = WidenPath( hdc );
69     ok( !ret, "WidenPath succeeded\n" );
70 
71     ret = EndPath( hdc );
72     ok( ret, "EndPath failed error %u\n", GetLastError() );
73     ret = WidenPath( hdc );
74     ok( ret, "WidenPath failed error %u\n", GetLastError() );
75 
76     SelectObject( hdc, orig );
77     ret = WidenPath( hdc );
78     ok( ret, "WidenPath failed error %u\n", GetLastError() );
79 
80     BeginPath( hdc );
81     LineTo( hdc, 100, 100 );
82     ret = WidenPath( hdc );
83     ok( !ret, "WidenPath succeeded\n" );
84     SaveDC( hdc );
85     SelectObject( hdc, dib );
86     ret = EndPath( hdc );
87     ok( ret, "EndPath failed error %u\n", GetLastError() );
88     ret = WidenPath( hdc );
89     ok( ret, "WidenPath failed error %u\n", GetLastError() );
90 
91     /* path should be open again after RestoreDC */
92     RestoreDC( hdc, -1  );
93     ret = WidenPath( hdc );
94     ok( !ret, "WidenPath succeeded\n" );
95     ret = EndPath( hdc );
96     ok( ret, "EndPath failed error %u\n", GetLastError() );
97 
98     SaveDC( hdc );
99     BeginPath( hdc );
100     RestoreDC( hdc, -1  );
101     ret = WidenPath( hdc );
102     ok( ret, "WidenPath failed error %u\n", GetLastError() );
103 
104     /* test all functions with no path at all */
105     AbortPath( hdc );
106     SetLastError( 0xdeadbeef );
107     ret = WidenPath( hdc );
108     ok( !ret, "WidenPath succeeded\n" );
109     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
110         "wrong error %u\n", GetLastError() );
111 
112     SetLastError( 0xdeadbeef );
113     ret = FlattenPath( hdc );
114     ok( !ret, "FlattenPath succeeded\n" );
115     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
116         "wrong error %u\n", GetLastError() );
117 
118     SetLastError( 0xdeadbeef );
119     ret = StrokePath( hdc );
120     ok( !ret, "StrokePath succeeded\n" );
121     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
122         "wrong error %u\n", GetLastError() );
123 
124     SetLastError( 0xdeadbeef );
125     ret = FillPath( hdc );
126     ok( !ret, "FillPath succeeded\n" );
127     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
128         "wrong error %u\n", GetLastError() );
129 
130     SetLastError( 0xdeadbeef );
131     ret = StrokeAndFillPath( hdc );
132     ok( !ret, "StrokeAndFillPath succeeded\n" );
133     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
134         "wrong error %u\n", GetLastError() );
135 
136     SetLastError( 0xdeadbeef );
137     ret = SelectClipPath( hdc, RGN_OR );
138     ok( !ret, "SelectClipPath succeeded\n" );
139     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
140         "wrong error %u\n", GetLastError() );
141 
142     SetLastError( 0xdeadbeef );
143     rgn = PathToRegion( hdc );
144     ok( !rgn, "PathToRegion succeeded\n" );
145     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
146         "wrong error %u\n", GetLastError() );
147 
148     SetLastError( 0xdeadbeef );
149     ret = EndPath( hdc );
150     ok( !ret, "SelectClipPath succeeded\n" );
151     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
152         "wrong error %u\n", GetLastError() );
153 
154     SetLastError( 0xdeadbeef );
155     ret = CloseFigure( hdc );
156     ok( !ret, "CloseFigure succeeded\n" );
157     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
158         "wrong error %u\n", GetLastError() );
159 
160     /* test all functions with an open path */
161     AbortPath( hdc );
162     BeginPath( hdc );
163     SetLastError( 0xdeadbeef );
164     ret = WidenPath( hdc );
165     ok( !ret, "WidenPath succeeded\n" );
166     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
167         "wrong error %u\n", GetLastError() );
168 
169     AbortPath( hdc );
170     BeginPath( hdc );
171     SetLastError( 0xdeadbeef );
172     ret = FlattenPath( hdc );
173     ok( !ret, "FlattenPath succeeded\n" );
174     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
175         "wrong error %u\n", GetLastError() );
176 
177     AbortPath( hdc );
178     BeginPath( hdc );
179     SetLastError( 0xdeadbeef );
180     ret = StrokePath( hdc );
181     ok( !ret, "StrokePath succeeded\n" );
182     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
183         "wrong error %u\n", GetLastError() );
184 
185     AbortPath( hdc );
186     BeginPath( hdc );
187     SetLastError( 0xdeadbeef );
188     ret = FillPath( hdc );
189     ok( !ret, "FillPath succeeded\n" );
190     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
191         "wrong error %u\n", GetLastError() );
192 
193     AbortPath( hdc );
194     BeginPath( hdc );
195     SetLastError( 0xdeadbeef );
196     ret = StrokeAndFillPath( hdc );
197     ok( !ret, "StrokeAndFillPath succeeded\n" );
198     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
199         "wrong error %u\n", GetLastError() );
200 
201     AbortPath( hdc );
202     BeginPath( hdc );
203     Rectangle( hdc, 1, 1, 10, 10 );  /* region needs some contents */
204     SetLastError( 0xdeadbeef );
205     ret = SelectClipPath( hdc, RGN_OR );
206     ok( !ret, "SelectClipPath succeeded\n" );
207     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
208         "wrong error %u\n", GetLastError() );
209 
210     AbortPath( hdc );
211     BeginPath( hdc );
212     Rectangle( hdc, 1, 1, 10, 10 );  /* region needs some contents */
213     SetLastError( 0xdeadbeef );
214     rgn = PathToRegion( hdc );
215     ok( !rgn, "PathToRegion succeeded\n" );
216     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
217         "wrong error %u\n", GetLastError() );
218 
219     AbortPath( hdc );
220     BeginPath( hdc );
221     ret = CloseFigure( hdc );
222     ok( ret, "CloseFigure failed\n" );
223 
224     /* test all functions with a closed path */
225     AbortPath( hdc );
226     BeginPath( hdc );
227     EndPath( hdc );
228     ret = WidenPath( hdc );
229     ok( ret, "WidenPath failed\n" );
230     ok( GetPath( hdc, NULL, NULL, 0 ) != -1, "path deleted\n" );
231 
232     AbortPath( hdc );
233     BeginPath( hdc );
234     EndPath( hdc );
235     ret = FlattenPath( hdc );
236     ok( ret, "FlattenPath failed\n" );
237     ok( GetPath( hdc, NULL, NULL, 0 ) != -1, "path deleted\n" );
238 
239     AbortPath( hdc );
240     BeginPath( hdc );
241     EndPath( hdc );
242     ret = StrokePath( hdc );
243     ok( ret, "StrokePath failed\n" );
244     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
245 
246     BeginPath( hdc );
247     EndPath( hdc );
248     ret = FillPath( hdc );
249     ok( ret, "FillPath failed\n" );
250     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
251 
252     BeginPath( hdc );
253     EndPath( hdc );
254     ret = StrokeAndFillPath( hdc );
255     ok( ret, "StrokeAndFillPath failed\n" );
256     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
257 
258     BeginPath( hdc );
259     Rectangle( hdc, 1, 1, 10, 10 );  /* region needs some contents */
260     EndPath( hdc );
261     ret = SelectClipPath( hdc, RGN_OR );
262     ok( ret, "SelectClipPath failed\n" );
263     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
264 
265     BeginPath( hdc );
266     EndPath( hdc );
267     SetLastError( 0xdeadbeef );
268     ret = SelectClipPath( hdc, RGN_OR );
269     ok( !ret, "SelectClipPath succeeded on empty path\n" );
270     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
271     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
272 
273     BeginPath( hdc );
274     Rectangle( hdc, 1, 1, 10, 10 );  /* region needs some contents */
275     EndPath( hdc );
276     rgn = PathToRegion( hdc );
277     ok( rgn != 0, "PathToRegion failed\n" );
278     DeleteObject( rgn );
279     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
280 
281     BeginPath( hdc );
282     EndPath( hdc );
283     SetLastError( 0xdeadbeef );
284     rgn = PathToRegion( hdc );
285     ok( !rgn, "PathToRegion succeeded on empty path\n" );
286     ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
287     DeleteObject( rgn );
288     ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
289 
290     BeginPath( hdc );
291     EndPath( hdc );
292     SetLastError( 0xdeadbeef );
293     ret = CloseFigure( hdc );
294     ok( !ret, "CloseFigure succeeded\n" );
295     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
296         "wrong error %u\n", GetLastError() );
297 
298     AbortPath( hdc );
299     BeginPath( hdc );
300     EndPath( hdc );
301     SetLastError( 0xdeadbeef );
302     ret = EndPath( hdc );
303     ok( !ret, "EndPath succeeded\n" );
304     ok( GetLastError() == ERROR_CAN_NOT_COMPLETE || broken(GetLastError() == 0xdeadbeef),
305         "wrong error %u\n", GetLastError() );
306 
307     DeleteDC( hdc );
308     DeleteObject( dib );
309 }
310 
test_widenpath(void)311 static void test_widenpath(void)
312 {
313     HDC hdc = GetDC(0);
314     HPEN greenPen, narrowPen;
315     POINT pnt[6];
316     INT nSize;
317     BOOL ret;
318 
319     /* Create a pen to be used in WidenPath */
320     greenPen = CreatePen(PS_SOLID, 10, RGB(0,0,0));
321     SelectObject(hdc, greenPen);
322 
323     /* Prepare a path */
324     pnt[0].x = 100;
325     pnt[0].y = 0;
326     pnt[1].x = 200;
327     pnt[1].y = 0;
328     pnt[2].x = 300;
329     pnt[2].y = 100;
330     pnt[3].x = 300;
331     pnt[3].y = 200;
332     pnt[4].x = 200;
333     pnt[4].y = 300;
334     pnt[5].x = 100;
335     pnt[5].y = 300;
336 
337     /* Set a polyline path */
338     BeginPath(hdc);
339     Polyline(hdc, pnt, 6);
340     EndPath(hdc);
341 
342     /* Widen the polyline path */
343     ok(WidenPath(hdc), "WidenPath fails while widening a poyline path.\n");
344 
345     /* Test if WidenPath seems to have done his job */
346     nSize = GetPath(hdc, NULL, NULL, 0);
347     ok(nSize != -1, "GetPath fails after calling WidenPath.\n");
348     ok(nSize > 6, "Path number of points is too low. Should be more than 6 but is %d\n", nSize);
349 
350     AbortPath(hdc);
351 
352     /* Test WidenPath with an open path (last error only set on Win2k and later) */
353     SetLastError(0xdeadbeef);
354     BeginPath(hdc);
355     ret = WidenPath(hdc);
356     ok(ret == FALSE && (GetLastError() == ERROR_CAN_NOT_COMPLETE || GetLastError() == 0xdeadbeef),
357        "WidenPath fails while widening an open path. Return value is %d, should be %d. Error is %u\n", ret, FALSE, GetLastError());
358 
359     AbortPath(hdc);
360 
361     /* Test when the pen width is equal to 1. The path should change too */
362     narrowPen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
363     SelectObject(hdc, narrowPen);
364     BeginPath(hdc);
365     Polyline(hdc, pnt, 6);
366     EndPath(hdc);
367     ret = WidenPath(hdc);
368     ok(ret == TRUE, "WidenPath failed: %d\n", GetLastError());
369     nSize = GetPath(hdc, NULL, NULL, 0);
370     ok(nSize > 6, "WidenPath should compute a widened path with a 1px wide pen. Path length is %d, should be more than 6\n", nSize);
371 
372     ReleaseDC(0, hdc);
373     return;
374 }
375 
376 /*
377  * Tests for GDI drawing functions in paths
378  */
379 
380 typedef struct
381 {
382     int x, y;
383     BYTE type;
384 } path_test_t;
385 
386 /* Helper function to verify that the current path in the given DC matches the expected path.
387  *
388  * We use a "smart" matching algorithm that allows us to detect partial improvements
389  * in conformance. Specifically, two running indices are kept, one through the actual
390  * path and one through the expected path. The actual path index increases unless there is
391  * no match and the todo field of the appropriate path_test_t element is 2. Similarly,
392  * if the wine_entries_preceding field of the appropriate path_test_t element is non-zero,
393  * the expected path index does not increase for that many elements as long as there
394  * is no match. This allows us to todo_wine extra path elements that are present only
395  * on wine but not on native and vice versa.
396  *
397  * Note that if expected_size is zero and the WINETEST_DEBUG environment variable is
398  * greater than 2, the trace() output is a C path_test_t array structure, useful for making
399  * new tests that use this function.
400  */
ok_path(HDC hdc,const char * path_name,const path_test_t * expected,int expected_size)401 static void ok_path(HDC hdc, const char *path_name, const path_test_t *expected, int expected_size)
402 {
403     static const char *type_string[8] = { "Unknown (0)", "PT_CLOSEFIGURE", "PT_LINETO",
404                                           "PT_LINETO | PT_CLOSEFIGURE", "PT_BEZIERTO",
405                                           "PT_BEZIERTO | PT_CLOSEFIGURE", "PT_MOVETO", "PT_MOVETO | PT_CLOSEFIGURE"};
406     POINT *pnt;
407     BYTE *types;
408     int size, idx;
409 
410     /* Get the path */
411     assert(hdc != 0);
412     size = GetPath(hdc, NULL, NULL, 0);
413     ok(size > 0, "GetPath returned size %d, last error %d\n", size, GetLastError());
414     if (size <= 0) return;
415 
416     pnt = HeapAlloc(GetProcessHeap(), 0, size*sizeof(POINT));
417     assert(pnt != 0);
418     types = HeapAlloc(GetProcessHeap(), 0, size*sizeof(BYTE));
419     assert(types != 0);
420     size = GetPath(hdc, pnt, types, size);
421     assert(size > 0);
422 
423     ros_skip_flaky
424     ok( size == expected_size, "%s: Path size %d does not match expected size %d\n",
425         path_name, size, expected_size);
426 
427     for (idx = 0; idx < min( size, expected_size ); idx++)
428     {
429         /* We allow a few pixels fudge in matching X and Y coordinates to account for imprecision in
430          * floating point to integer conversion */
431         static const int fudge = 2;
432 
433         ros_skip_flaky
434         ok( types[idx] == expected[idx].type, "%s: Expected #%d: %s (%d,%d) but got %s (%d,%d)\n",
435             path_name, idx, type_string[expected[idx].type], expected[idx].x, expected[idx].y,
436             type_string[types[idx]], pnt[idx].x, pnt[idx].y);
437 
438         if (types[idx] == expected[idx].type)
439             ros_skip_flaky
440             ok( (pnt[idx].x >= expected[idx].x - fudge && pnt[idx].x <= expected[idx].x + fudge) &&
441                 (pnt[idx].y >= expected[idx].y - fudge && pnt[idx].y <= expected[idx].y + fudge),
442                 "%s: Expected #%d: %s  position (%d,%d) but got (%d,%d)\n", path_name, idx,
443                 type_string[expected[idx].type], expected[idx].x, expected[idx].y, pnt[idx].x, pnt[idx].y);
444     }
445 
446     if (winetest_debug > 2)
447     {
448         printf("static const path_test_t %s[] =\n{\n", path_name);
449         for (idx = 0; idx < size; idx++)
450             printf("    {%d, %d, %s}, /* %d */\n", pnt[idx].x, pnt[idx].y, type_string[types[idx]], idx);
451         printf("};\n" );
452     }
453 
454     HeapFree(GetProcessHeap(), 0, types);
455     HeapFree(GetProcessHeap(), 0, pnt);
456 }
457 
458 static const path_test_t arcto_path[] =
459 {
460     {0, 0, PT_MOVETO}, /* 0 */
461     {229, 215, PT_LINETO}, /* 1 */
462     {248, 205, PT_BEZIERTO}, /* 2 */
463     {273, 200, PT_BEZIERTO}, /* 3 */
464     {300, 200, PT_BEZIERTO}, /* 4 */
465     {355, 200, PT_BEZIERTO}, /* 5 */
466     {399, 222, PT_BEZIERTO}, /* 6 */
467     {399, 250, PT_BEZIERTO}, /* 7 */
468     {399, 263, PT_BEZIERTO}, /* 8 */
469     {389, 275, PT_BEZIERTO}, /* 9 */
470     {370, 285, PT_BEZIERTO}, /* 10 */
471     {363, 277, PT_LINETO}, /* 11 */
472     {380, 270, PT_BEZIERTO}, /* 12 */
473     {389, 260, PT_BEZIERTO}, /* 13 */
474     {389, 250, PT_BEZIERTO}, /* 14 */
475     {389, 228, PT_BEZIERTO}, /* 15 */
476     {349, 210, PT_BEZIERTO}, /* 16 */
477     {300, 210, PT_BEZIERTO}, /* 17 */
478     {276, 210, PT_BEZIERTO}, /* 18 */
479     {253, 214, PT_BEZIERTO}, /* 19 */
480     {236, 222, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 20 */
481 };
482 
test_arcto(void)483 static void test_arcto(void)
484 {
485     HDC hdc = GetDC(0);
486 
487     BeginPath(hdc);
488     SetArcDirection(hdc, AD_CLOCKWISE);
489     if (!ArcTo(hdc, 200, 200, 400, 300, 200, 200, 400, 300) &&
490         GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
491     {
492         /* ArcTo is only available on Win2k and later */
493         win_skip("ArcTo is not available\n");
494         goto done;
495     }
496     SetArcDirection(hdc, AD_COUNTERCLOCKWISE);
497     ArcTo(hdc, 210, 210, 390, 290, 390, 290, 210, 210);
498     CloseFigure(hdc);
499     EndPath(hdc);
500 
501     ok_path(hdc, "arcto_path", arcto_path, sizeof(arcto_path)/sizeof(path_test_t));
502 done:
503     ReleaseDC(0, hdc);
504 }
505 
506 static const path_test_t anglearc_path[] =
507 {
508     {0, 0, PT_MOVETO}, /* 0 */
509     {371, 229, PT_LINETO}, /* 1 */
510     {352, 211, PT_BEZIERTO}, /* 2 */
511     {327, 200, PT_BEZIERTO}, /* 3 */
512     {300, 200, PT_BEZIERTO}, /* 4 */
513     {245, 200, PT_BEZIERTO}, /* 5 */
514     {200, 245, PT_BEZIERTO}, /* 6 */
515     {200, 300, PT_BEZIERTO}, /* 7 */
516     {200, 300, PT_BEZIERTO}, /* 8 */
517     {200, 300, PT_BEZIERTO}, /* 9 */
518     {200, 300, PT_BEZIERTO}, /* 10 */
519     {231, 260, PT_LINETO}, /* 11 */
520     {245, 235, PT_BEZIERTO}, /* 12 */
521     {271, 220, PT_BEZIERTO}, /* 13 */
522     {300, 220, PT_BEZIERTO}, /* 14 */
523     {344, 220, PT_BEZIERTO}, /* 15 */
524     {380, 256, PT_BEZIERTO}, /* 16 */
525     {380, 300, PT_BEZIERTO}, /* 17 */
526     {380, 314, PT_BEZIERTO}, /* 18 */
527     {376, 328, PT_BEZIERTO}, /* 19 */
528     {369, 340, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 20 */
529 };
530 
test_anglearc(void)531 static void test_anglearc(void)
532 {
533     HDC hdc = GetDC(0);
534     BeginPath(hdc);
535     if (!AngleArc(hdc, 300, 300, 100, 45.0, 135.0) &&
536         GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
537     {
538         /* AngleArc is only available on Win2k and later */
539         win_skip("AngleArc is not available\n");
540         goto done;
541     }
542     AngleArc(hdc, 300, 300, 80, 150.0, -180.0);
543     CloseFigure(hdc);
544     EndPath(hdc);
545 
546     ok_path(hdc, "anglearc_path", anglearc_path, sizeof(anglearc_path)/sizeof(path_test_t));
547 done:
548     ReleaseDC(0, hdc);
549 }
550 
551 static const path_test_t polydraw_path[] =
552 {
553     {-20, -20, PT_MOVETO}, /* 0 */
554     {10, 10, PT_LINETO}, /* 1 */
555     {10, 15, PT_LINETO | PT_CLOSEFIGURE}, /* 2 */
556     {-20, -20, PT_MOVETO}, /* 3 */
557     {-10, -10, PT_LINETO}, /* 4 */
558     {100, 100, PT_MOVETO}, /* 5 */
559     {95, 95, PT_LINETO}, /* 6 */
560     {10, 10, PT_LINETO}, /* 7 */
561     {10, 15, PT_LINETO | PT_CLOSEFIGURE}, /* 8 */
562     {100, 100, PT_MOVETO}, /* 9 */
563     {15, 15, PT_LINETO}, /* 10 */
564     {25, 25, PT_MOVETO}, /* 11 */
565     {25, 30, PT_LINETO}, /* 12 */
566     {100, 100, PT_MOVETO}, /* 13 */
567     {30, 30, PT_BEZIERTO}, /* 14 */
568     {30, 35, PT_BEZIERTO}, /* 15 */
569     {35, 35, PT_BEZIERTO}, /* 16 */
570     {35, 40, PT_LINETO}, /* 17 */
571     {40, 40, PT_MOVETO}, /* 18 */
572     {40, 45, PT_LINETO}, /* 19 */
573     {35, 40, PT_MOVETO}, /* 20 */
574     {45, 50, PT_LINETO}, /* 21 */
575     {35, 40, PT_MOVETO}, /* 22 */
576     {50, 55, PT_LINETO}, /* 23 */
577     {45, 50, PT_LINETO}, /* 24 */
578     {35, 40, PT_MOVETO}, /* 25 */
579     {60, 60, PT_LINETO}, /* 26 */
580     {60, 65, PT_MOVETO}, /* 27 */
581     {65, 65, PT_LINETO}, /* 28 */
582     {75, 75, PT_MOVETO}, /* 29 */
583     {80, 80, PT_LINETO | PT_CLOSEFIGURE}, /* 30 */
584 };
585 
586 static POINT polydraw_pts[] = {
587     {10, 10}, {10, 15},
588     {15, 15}, {15, 20}, {20, 20}, {20, 25},
589     {25, 25}, {25, 30},
590     {30, 30}, {30, 35}, {35, 35}, {35, 40},
591     {40, 40}, {40, 45}, {45, 45},
592     {45, 50}, {50, 50},
593     {50, 55}, {45, 50}, {55, 60},
594     {60, 60}, {60, 65}, {65, 65},
595     {70, 70}, {75, 70}, {75, 75}, {80, 80}};
596 
597 static BYTE polydraw_tps[] =
598     {PT_LINETO, PT_CLOSEFIGURE | PT_LINETO, /* 2 */
599      PT_LINETO, PT_BEZIERTO, PT_LINETO, PT_LINETO, /* 6 */
600      PT_MOVETO, PT_LINETO, /* 8 */
601      PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO, /* 12 */
602      PT_MOVETO, PT_LINETO, PT_CLOSEFIGURE, /* 15 */
603      PT_LINETO, PT_MOVETO | PT_CLOSEFIGURE, /* 17 */
604      PT_LINETO, PT_LINETO, PT_MOVETO | PT_CLOSEFIGURE, /* 20 */
605      PT_LINETO, PT_MOVETO | PT_LINETO, PT_LINETO,  /* 23 */
606      PT_MOVETO, PT_MOVETO, PT_MOVETO, PT_LINETO | PT_CLOSEFIGURE}; /* 27 */
607 
test_polydraw(void)608 static void test_polydraw(void)
609 {
610     BOOL retb;
611     POINT pos;
612     HDC hdc = GetDC(0);
613 
614     MoveToEx( hdc, -20, -20, NULL );
615 
616     BeginPath(hdc);
617     GetCurrentPositionEx( hdc, &pos );
618     ok( pos.x == -20 && pos.y == -20, "wrong pos %d,%d\n", pos.x, pos.y );
619 
620     /* closefigure with no previous moveto */
621     if (!(retb = PolyDraw(hdc, polydraw_pts, polydraw_tps, 2)) &&
622         GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
623     {
624         /* PolyDraw is only available on Win2k and later */
625         win_skip("PolyDraw is not available\n");
626         goto done;
627     }
628     expect(TRUE, retb);
629     GetCurrentPositionEx( hdc, &pos );
630     ok( pos.x == 10 && pos.y == 15, "wrong pos %d,%d\n", pos.x, pos.y );
631     LineTo(hdc, -10, -10);
632     GetCurrentPositionEx( hdc, &pos );
633     ok( pos.x == -10 && pos.y == -10, "wrong pos %d,%d\n", pos.x, pos.y );
634 
635     MoveToEx(hdc, 100, 100, NULL);
636     GetCurrentPositionEx( hdc, &pos );
637     ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
638     LineTo(hdc, 95, 95);
639     GetCurrentPositionEx( hdc, &pos );
640     ok( pos.x == 95 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
641     /* closefigure with previous moveto */
642     retb = PolyDraw(hdc, polydraw_pts, polydraw_tps, 2);
643     expect(TRUE, retb);
644     GetCurrentPositionEx( hdc, &pos );
645     ok( pos.x == 10 && pos.y == 15, "wrong pos %d,%d\n", pos.x, pos.y );
646     /* bad bezier points */
647     retb = PolyDraw(hdc, &(polydraw_pts[2]), &(polydraw_tps[2]), 4);
648     expect(FALSE, retb);
649     GetCurrentPositionEx( hdc, &pos );
650     ok( pos.x == 10 && pos.y == 15, "wrong pos %d,%d\n", pos.x, pos.y );
651     retb = PolyDraw(hdc, &(polydraw_pts[6]), &(polydraw_tps[6]), 4);
652     expect(FALSE, retb);
653     GetCurrentPositionEx( hdc, &pos );
654     ok( pos.x == 10 && pos.y == 15, "wrong pos %d,%d\n", pos.x, pos.y );
655     /* good bezier points */
656     retb = PolyDraw(hdc, &(polydraw_pts[8]), &(polydraw_tps[8]), 4);
657     expect(TRUE, retb);
658     GetCurrentPositionEx( hdc, &pos );
659     ok( pos.x == 35 && pos.y == 40, "wrong pos %d,%d\n", pos.x, pos.y );
660     /* does lineto or bezierto take precedence? */
661     retb = PolyDraw(hdc, &(polydraw_pts[12]), &(polydraw_tps[12]), 4);
662     expect(FALSE, retb);
663     GetCurrentPositionEx( hdc, &pos );
664     ok( pos.x == 35 && pos.y == 40, "wrong pos %d,%d\n", pos.x, pos.y );
665     /* bad point type, has already moved cursor position */
666     retb = PolyDraw(hdc, &(polydraw_pts[15]), &(polydraw_tps[15]), 4);
667     expect(FALSE, retb);
668     GetCurrentPositionEx( hdc, &pos );
669     ok( pos.x == 35 && pos.y == 40, "wrong pos %d,%d\n", pos.x, pos.y );
670     /* bad point type, cursor position is moved, but back to its original spot */
671     retb = PolyDraw(hdc, &(polydraw_pts[17]), &(polydraw_tps[17]), 4);
672     expect(FALSE, retb);
673     GetCurrentPositionEx( hdc, &pos );
674     ok( pos.x == 35 && pos.y == 40, "wrong pos %d,%d\n", pos.x, pos.y );
675     /* does lineto or moveto take precedence? */
676     retb = PolyDraw(hdc, &(polydraw_pts[20]), &(polydraw_tps[20]), 3);
677     expect(TRUE, retb);
678     GetCurrentPositionEx( hdc, &pos );
679     ok( pos.x == 65 && pos.y == 65, "wrong pos %d,%d\n", pos.x, pos.y );
680     /* consecutive movetos */
681     retb = PolyDraw(hdc, &(polydraw_pts[23]), &(polydraw_tps[23]), 4);
682     expect(TRUE, retb);
683     GetCurrentPositionEx( hdc, &pos );
684     ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
685 
686     EndPath(hdc);
687     ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t));
688     GetCurrentPositionEx( hdc, &pos );
689     ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
690 done:
691     ReleaseDC(0, hdc);
692 }
693 
test_closefigure(void)694 static void test_closefigure(void) {
695     int nSize, nSizeWitness;
696     POINT pos;
697     HDC hdc = GetDC(0);
698 
699     MoveToEx( hdc, 100, 100, NULL );
700     GetCurrentPositionEx( hdc, &pos );
701     ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
702 
703     BeginPath(hdc);
704     GetCurrentPositionEx( hdc, &pos );
705     ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
706     MoveToEx(hdc, 95, 95, NULL);
707     GetCurrentPositionEx( hdc, &pos );
708     ok( pos.x == 95 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
709     LineTo(hdc, 95,  0);
710     GetCurrentPositionEx( hdc, &pos );
711     ok( pos.x == 95 && pos.y == 0, "wrong pos %d,%d\n", pos.x, pos.y );
712     LineTo(hdc,  0, 95);
713     GetCurrentPositionEx( hdc, &pos );
714     ok( pos.x == 0 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
715 
716     CloseFigure(hdc);
717     GetCurrentPositionEx( hdc, &pos );
718     ok( pos.x == 0 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
719     EndPath(hdc);
720     GetCurrentPositionEx( hdc, &pos );
721     ok( pos.x == 0 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
722     nSize = GetPath(hdc, NULL, NULL, 0);
723 
724     AbortPath(hdc);
725 
726     BeginPath(hdc);
727     MoveToEx(hdc, 95, 95, NULL);
728     LineTo(hdc, 95,  0);
729     LineTo(hdc,  0, 95);
730 
731     EndPath(hdc);
732     nSizeWitness = GetPath(hdc, NULL, NULL, 0);
733 
734     /* This test shows CloseFigure does not have to add a point at the end of the path */
735     ok(nSize == nSizeWitness, "Wrong number of points, no point should be added by CloseFigure\n");
736 
737     ReleaseDC(0, hdc);
738 }
739 
linedda_callback(INT x,INT y,LPARAM lparam)740 static void WINAPI linedda_callback(INT x, INT y, LPARAM lparam)
741 {
742     POINT **pt = (POINT**)lparam;
743     ok((*pt)->x == x && (*pt)->y == y, "point mismatch expect(%d,%d) got(%d,%d)\n",
744        (*pt)->x, (*pt)->y, x, y);
745 
746     (*pt)++;
747     return;
748 }
749 
test_linedda(void)750 static void test_linedda(void)
751 {
752     const POINT *pt;
753     static const POINT array_10_20_20_40[] = {{10,20},{10,21},{11,22},{11,23},
754                                               {12,24},{12,25},{13,26},{13,27},
755                                               {14,28},{14,29},{15,30},{15,31},
756                                               {16,32},{16,33},{17,34},{17,35},
757                                               {18,36},{18,37},{19,38},{19,39},
758                                               {-1,-1}};
759     static const POINT array_10_20_20_43[] = {{10,20},{10,21},{11,22},{11,23},
760                                               {12,24},{12,25},{13,26},{13,27},
761                                               {13,28},{14,29},{14,30},{15,31},
762                                               {15,32},{16,33},{16,34},{17,35},
763                                               {17,36},{17,37},{18,38},{18,39},
764                                               {19,40},{19,41},{20,42},{-1,-1}};
765 
766     static const POINT array_10_20_10_20[] = {{-1,-1}};
767     static const POINT array_10_20_11_27[] = {{10,20},{10,21},{10,22},{10,23},
768                                               {11,24},{11,25},{11,26},{-1,-1}};
769 
770     static const POINT array_20_43_10_20[] = {{20,43},{20,42},{19,41},{19,40},
771                                               {18,39},{18,38},{17,37},{17,36},
772                                               {17,35},{16,34},{16,33},{15,32},
773                                               {15,31},{14,30},{14,29},{13,28},
774                                               {13,27},{13,26},{12,25},{12,24},
775                                               {11,23},{11,22},{10,21},{-1,-1}};
776 
777     static const POINT array_20_20_10_43[] = {{20,20},{20,21},{19,22},{19,23},
778                                               {18,24},{18,25},{17,26},{17,27},
779                                               {17,28},{16,29},{16,30},{15,31},
780                                               {15,32},{14,33},{14,34},{13,35},
781                                               {13,36},{13,37},{12,38},{12,39},
782                                               {11,40},{11,41},{10,42},{-1,-1}};
783 
784     static const POINT array_20_20_43_10[] = {{20,20},{21,20},{22,19},{23,19},
785                                               {24,18},{25,18},{26,17},{27,17},
786                                               {28,17},{29,16},{30,16},{31,15},
787                                               {32,15},{33,14},{34,14},{35,13},
788                                               {36,13},{37,13},{38,12},{39,12},
789                                               {40,11},{41,11},{42,10},{-1,-1}};
790 
791 
792     pt = array_10_20_20_40;
793     LineDDA(10, 20, 20, 40, linedda_callback, (LPARAM)&pt);
794     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
795 
796     pt = array_10_20_20_43;
797     LineDDA(10, 20, 20, 43, linedda_callback, (LPARAM)&pt);
798     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
799 
800     pt = array_10_20_10_20;
801     LineDDA(10, 20, 10, 20, linedda_callback, (LPARAM)&pt);
802     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
803 
804     pt = array_10_20_11_27;
805     LineDDA(10, 20, 11, 27, linedda_callback, (LPARAM)&pt);
806     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
807 
808     pt = array_20_43_10_20;
809     LineDDA(20, 43, 10, 20, linedda_callback, (LPARAM)&pt);
810     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
811 
812     pt = array_20_20_10_43;
813     LineDDA(20, 20, 10, 43, linedda_callback, (LPARAM)&pt);
814     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
815 
816     pt = array_20_20_43_10;
817     LineDDA(20, 20, 43, 10, linedda_callback, (LPARAM)&pt);
818     ok(pt->x == -1 && pt->y == -1, "didn't find terminator\n");
819 }
820 
821 static const path_test_t rectangle_path[] =
822 {
823     {39, 20, PT_MOVETO}, /* 0 */
824     {20, 20, PT_LINETO}, /* 1 */
825     {20, 39, PT_LINETO}, /* 2 */
826     {39, 39, PT_LINETO | PT_CLOSEFIGURE}, /* 3 */
827     {54, 35, PT_MOVETO}, /* 4 */
828     {30, 35, PT_LINETO}, /* 5 */
829     {30, 49, PT_LINETO}, /* 6 */
830     {54, 49, PT_LINETO | PT_CLOSEFIGURE}, /* 7 */
831     {59, 45, PT_MOVETO}, /* 8 */
832     {35, 45, PT_LINETO}, /* 9 */
833     {35, 59, PT_LINETO}, /* 10 */
834     {59, 59, PT_LINETO | PT_CLOSEFIGURE}, /* 11 */
835     {80, 80, PT_MOVETO}, /* 12 */
836     {80, 80, PT_LINETO}, /* 13 */
837     {80, 80, PT_LINETO}, /* 14 */
838     {80, 80, PT_LINETO | PT_CLOSEFIGURE}, /* 15 */
839     {39, 39, PT_MOVETO}, /* 16 */
840     {20, 39, PT_LINETO}, /* 17 */
841     {20, 20, PT_LINETO}, /* 18 */
842     {39, 20, PT_LINETO | PT_CLOSEFIGURE}, /* 19 */
843     {54, 49, PT_MOVETO}, /* 20 */
844     {30, 49, PT_LINETO}, /* 21 */
845     {30, 35, PT_LINETO}, /* 22 */
846     {54, 35, PT_LINETO | PT_CLOSEFIGURE}, /* 23 */
847     {59, 59, PT_MOVETO}, /* 24 */
848     {35, 59, PT_LINETO}, /* 25 */
849     {35, 45, PT_LINETO}, /* 26 */
850     {59, 45, PT_LINETO | PT_CLOSEFIGURE}, /* 27 */
851     {80, 80, PT_MOVETO}, /* 28 */
852     {80, 80, PT_LINETO}, /* 29 */
853     {80, 80, PT_LINETO}, /* 30 */
854     {80, 80, PT_LINETO | PT_CLOSEFIGURE}, /* 31 */
855     {-41, 40, PT_MOVETO}, /* 32 */
856     {-80, 40, PT_LINETO}, /* 33 */
857     {-80, 79, PT_LINETO}, /* 34 */
858     {-41, 79, PT_LINETO | PT_CLOSEFIGURE}, /* 35 */
859     {-61, 70, PT_MOVETO}, /* 36 */
860     {-110, 70, PT_LINETO}, /* 37 */
861     {-110, 99, PT_LINETO}, /* 38 */
862     {-61, 99, PT_LINETO | PT_CLOSEFIGURE}, /* 39 */
863     {119, -120, PT_MOVETO}, /* 40 */
864     {60, -120, PT_LINETO}, /* 41 */
865     {60, -61, PT_LINETO}, /* 42 */
866     {119, -61, PT_LINETO | PT_CLOSEFIGURE}, /* 43 */
867     {164, -150, PT_MOVETO}, /* 44 */
868     {90, -150, PT_LINETO}, /* 45 */
869     {90, -106, PT_LINETO}, /* 46 */
870     {164, -106, PT_LINETO | PT_CLOSEFIGURE}, /* 47 */
871     {-4, -6, PT_MOVETO}, /* 48 */
872     {-6, -6, PT_LINETO}, /* 49 */
873     {-6, -4, PT_LINETO}, /* 50 */
874     {-4, -4, PT_LINETO | PT_CLOSEFIGURE}, /* 51 */
875     {40, 20, PT_MOVETO}, /* 52 */
876     {20, 20, PT_LINETO}, /* 53 */
877     {20, 40, PT_LINETO}, /* 54 */
878     {40, 40, PT_LINETO | PT_CLOSEFIGURE}, /* 55 */
879     {55, 35, PT_MOVETO}, /* 56 */
880     {30, 35, PT_LINETO}, /* 57 */
881     {30, 50, PT_LINETO}, /* 58 */
882     {55, 50, PT_LINETO | PT_CLOSEFIGURE}, /* 59 */
883     {60, 45, PT_MOVETO}, /* 60 */
884     {35, 45, PT_LINETO}, /* 61 */
885     {35, 60, PT_LINETO}, /* 62 */
886     {60, 60, PT_LINETO | PT_CLOSEFIGURE}, /* 63 */
887     {70, 70, PT_MOVETO}, /* 64 */
888     {50, 70, PT_LINETO}, /* 65 */
889     {50, 70, PT_LINETO}, /* 66 */
890     {70, 70, PT_LINETO | PT_CLOSEFIGURE}, /* 67 */
891     {75, 75, PT_MOVETO}, /* 68 */
892     {75, 75, PT_LINETO}, /* 69 */
893     {75, 85, PT_LINETO}, /* 70 */
894     {75, 85, PT_LINETO | PT_CLOSEFIGURE}, /* 71 */
895     {81, 80, PT_MOVETO}, /* 72 */
896     {80, 80, PT_LINETO}, /* 73 */
897     {80, 81, PT_LINETO}, /* 74 */
898     {81, 81, PT_LINETO | PT_CLOSEFIGURE}, /* 75 */
899     {40, 40, PT_MOVETO}, /* 76 */
900     {20, 40, PT_LINETO}, /* 77 */
901     {20, 20, PT_LINETO}, /* 78 */
902     {40, 20, PT_LINETO | PT_CLOSEFIGURE}, /* 79 */
903     {55, 50, PT_MOVETO}, /* 80 */
904     {30, 50, PT_LINETO}, /* 81 */
905     {30, 35, PT_LINETO}, /* 82 */
906     {55, 35, PT_LINETO | PT_CLOSEFIGURE}, /* 83 */
907     {60, 60, PT_MOVETO}, /* 84 */
908     {35, 60, PT_LINETO}, /* 85 */
909     {35, 45, PT_LINETO}, /* 86 */
910     {60, 45, PT_LINETO | PT_CLOSEFIGURE}, /* 87 */
911     {70, 70, PT_MOVETO}, /* 88 */
912     {50, 70, PT_LINETO}, /* 89 */
913     {50, 70, PT_LINETO}, /* 90 */
914     {70, 70, PT_LINETO | PT_CLOSEFIGURE}, /* 91 */
915     {75, 85, PT_MOVETO}, /* 92 */
916     {75, 85, PT_LINETO}, /* 93 */
917     {75, 75, PT_LINETO}, /* 94 */
918     {75, 75, PT_LINETO | PT_CLOSEFIGURE}, /* 95 */
919     {81, 81, PT_MOVETO}, /* 96 */
920     {80, 81, PT_LINETO}, /* 97 */
921     {80, 80, PT_LINETO}, /* 98 */
922     {81, 80, PT_LINETO | PT_CLOSEFIGURE}, /* 99 */
923 };
924 
test_rectangle(void)925 static void test_rectangle(void)
926 {
927     HDC hdc = GetDC( 0 );
928 
929     BeginPath( hdc );
930     Rectangle( hdc, 20, 20, 40, 40 );
931     Rectangle( hdc, 30, 50, 55, 35 );
932     Rectangle( hdc, 60, 60, 35, 45 );
933     Rectangle( hdc, 70, 70, 50, 70 );
934     Rectangle( hdc, 75, 75, 75, 85 );
935     Rectangle( hdc, 80, 80, 81, 81 );
936     SetArcDirection( hdc, AD_CLOCKWISE );
937     Rectangle( hdc, 20, 20, 40, 40 );
938     Rectangle( hdc, 30, 50, 55, 35 );
939     Rectangle( hdc, 60, 60, 35, 45 );
940     Rectangle( hdc, 70, 70, 50, 70 );
941     Rectangle( hdc, 75, 75, 75, 85 );
942     Rectangle( hdc, 80, 80, 81, 81 );
943     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
944     SetMapMode( hdc, MM_ANISOTROPIC );
945     SetViewportExtEx( hdc, -2, 2, NULL );
946     Rectangle( hdc, 20, 20, 40, 40 );
947     Rectangle( hdc, 30, 50, 55, 35 );
948     SetViewportExtEx( hdc, 3, -3, NULL );
949     Rectangle( hdc, 20, 20, 40, 40 );
950     Rectangle( hdc, 30, 50, 55, 35 );
951     SetWindowExtEx( hdc, -20, 20, NULL );
952     Rectangle( hdc, 20, 20, 40, 40 );
953     Rectangle( hdc, 24, 22, 21, 20 );
954     SetMapMode( hdc, MM_TEXT );
955     SetGraphicsMode( hdc, GM_ADVANCED );
956     Rectangle( hdc, 20, 20, 40, 40 );
957     Rectangle( hdc, 30, 50, 55, 35 );
958     Rectangle( hdc, 60, 60, 35, 45 );
959     Rectangle( hdc, 70, 70, 50, 70 );
960     Rectangle( hdc, 75, 75, 75, 85 );
961     Rectangle( hdc, 80, 80, 81, 81 );
962     SetArcDirection( hdc, AD_CLOCKWISE );
963     Rectangle( hdc, 20, 20, 40, 40 );
964     Rectangle( hdc, 30, 50, 55, 35 );
965     Rectangle( hdc, 60, 60, 35, 45 );
966     Rectangle( hdc, 70, 70, 50, 70 );
967     Rectangle( hdc, 75, 75, 75, 85 );
968     Rectangle( hdc, 80, 80, 81, 81 );
969     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
970     EndPath( hdc );
971     SetMapMode( hdc, MM_TEXT );
972     ok_path( hdc, "rectangle_path", rectangle_path, sizeof(rectangle_path)/sizeof(path_test_t) );
973     ReleaseDC( 0, hdc );
974 }
975 
976 static const path_test_t roundrect_path[] =
977 {
978     {39, 25, PT_MOVETO}, /* 0 */
979     {39, 22, PT_BEZIERTO}, /* 1 */
980     {37, 20, PT_BEZIERTO}, /* 2 */
981     {34, 20, PT_BEZIERTO}, /* 3 */
982     {25, 20, PT_LINETO}, /* 4 */
983     {22, 20, PT_BEZIERTO}, /* 5 */
984     {20, 22, PT_BEZIERTO}, /* 6 */
985     {20, 25, PT_BEZIERTO}, /* 7 */
986     {20, 34, PT_LINETO}, /* 8 */
987     {20, 37, PT_BEZIERTO}, /* 9 */
988     {22, 39, PT_BEZIERTO}, /* 10 */
989     {25, 39, PT_BEZIERTO}, /* 11 */
990     {34, 39, PT_LINETO}, /* 12 */
991     {37, 39, PT_BEZIERTO}, /* 13 */
992     {39, 37, PT_BEZIERTO}, /* 14 */
993     {39, 34, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 15 */
994     {54, 42, PT_MOVETO}, /* 16 */
995     {54, 38, PT_BEZIERTO}, /* 17 */
996     {49, 35, PT_BEZIERTO}, /* 18 */
997     {42, 35, PT_BEZIERTO}, /* 19 */
998     {42, 35, PT_LINETO}, /* 20 */
999     {35, 35, PT_BEZIERTO}, /* 21 */
1000     {30, 38, PT_BEZIERTO}, /* 22 */
1001     {30, 42, PT_BEZIERTO}, /* 23 */
1002     {30, 42, PT_LINETO}, /* 24 */
1003     {30, 46, PT_BEZIERTO}, /* 25 */
1004     {35, 49, PT_BEZIERTO}, /* 26 */
1005     {42, 49, PT_BEZIERTO}, /* 27 */
1006     {42, 49, PT_LINETO}, /* 28 */
1007     {49, 49, PT_BEZIERTO}, /* 29 */
1008     {54, 46, PT_BEZIERTO}, /* 30 */
1009     {54, 42, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 31 */
1010     {59, 46, PT_MOVETO}, /* 32 */
1011     {59, 45, PT_BEZIERTO}, /* 33 */
1012     {58, 45, PT_BEZIERTO}, /* 34 */
1013     {57, 45, PT_BEZIERTO}, /* 35 */
1014     {37, 45, PT_LINETO}, /* 36 */
1015     {36, 45, PT_BEZIERTO}, /* 37 */
1016     {35, 45, PT_BEZIERTO}, /* 38 */
1017     {35, 46, PT_BEZIERTO}, /* 39 */
1018     {35, 58, PT_LINETO}, /* 40 */
1019     {35, 59, PT_BEZIERTO}, /* 41 */
1020     {36, 59, PT_BEZIERTO}, /* 42 */
1021     {37, 59, PT_BEZIERTO}, /* 43 */
1022     {57, 59, PT_LINETO}, /* 44 */
1023     {58, 59, PT_BEZIERTO}, /* 45 */
1024     {59, 59, PT_BEZIERTO}, /* 46 */
1025     {59, 58, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 47 */
1026     {80, 80, PT_MOVETO}, /* 48 */
1027     {80, 80, PT_BEZIERTO}, /* 49 */
1028     {80, 80, PT_BEZIERTO}, /* 50 */
1029     {80, 80, PT_BEZIERTO}, /* 51 */
1030     {80, 80, PT_LINETO}, /* 52 */
1031     {80, 80, PT_BEZIERTO}, /* 53 */
1032     {80, 80, PT_BEZIERTO}, /* 54 */
1033     {80, 80, PT_BEZIERTO}, /* 55 */
1034     {80, 80, PT_LINETO}, /* 56 */
1035     {80, 80, PT_BEZIERTO}, /* 57 */
1036     {80, 80, PT_BEZIERTO}, /* 58 */
1037     {80, 80, PT_BEZIERTO}, /* 59 */
1038     {80, 80, PT_LINETO}, /* 60 */
1039     {80, 80, PT_BEZIERTO}, /* 61 */
1040     {80, 80, PT_BEZIERTO}, /* 62 */
1041     {80, 80, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 63 */
1042     {94, 85, PT_MOVETO}, /* 64 */
1043     {90, 85, PT_LINETO}, /* 65 */
1044     {90, 89, PT_LINETO}, /* 66 */
1045     {94, 89, PT_LINETO | PT_CLOSEFIGURE}, /* 67 */
1046     {39, 34, PT_MOVETO}, /* 68 */
1047     {39, 37, PT_BEZIERTO}, /* 69 */
1048     {37, 39, PT_BEZIERTO}, /* 70 */
1049     {34, 39, PT_BEZIERTO}, /* 71 */
1050     {25, 39, PT_LINETO}, /* 72 */
1051     {22, 39, PT_BEZIERTO}, /* 73 */
1052     {20, 37, PT_BEZIERTO}, /* 74 */
1053     {20, 34, PT_BEZIERTO}, /* 75 */
1054     {20, 25, PT_LINETO}, /* 76 */
1055     {20, 22, PT_BEZIERTO}, /* 77 */
1056     {22, 20, PT_BEZIERTO}, /* 78 */
1057     {25, 20, PT_BEZIERTO}, /* 79 */
1058     {34, 20, PT_LINETO}, /* 80 */
1059     {37, 20, PT_BEZIERTO}, /* 81 */
1060     {39, 22, PT_BEZIERTO}, /* 82 */
1061     {39, 25, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 83 */
1062     {54, 42, PT_MOVETO}, /* 84 */
1063     {54, 46, PT_BEZIERTO}, /* 85 */
1064     {49, 49, PT_BEZIERTO}, /* 86 */
1065     {42, 49, PT_BEZIERTO}, /* 87 */
1066     {42, 49, PT_LINETO}, /* 88 */
1067     {35, 49, PT_BEZIERTO}, /* 89 */
1068     {30, 46, PT_BEZIERTO}, /* 90 */
1069     {30, 42, PT_BEZIERTO}, /* 91 */
1070     {30, 42, PT_LINETO}, /* 92 */
1071     {30, 38, PT_BEZIERTO}, /* 93 */
1072     {35, 35, PT_BEZIERTO}, /* 94 */
1073     {42, 35, PT_BEZIERTO}, /* 95 */
1074     {42, 35, PT_LINETO}, /* 96 */
1075     {49, 35, PT_BEZIERTO}, /* 97 */
1076     {54, 38, PT_BEZIERTO}, /* 98 */
1077     {54, 42, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 99 */
1078     {-41, 52, PT_MOVETO}, /* 100 */
1079     {-41, 45, PT_BEZIERTO}, /* 101 */
1080     {-47, 40, PT_BEZIERTO}, /* 102 */
1081     {-56, 40, PT_BEZIERTO}, /* 103 */
1082     {-65, 40, PT_LINETO}, /* 104 */
1083     {-73, 40, PT_BEZIERTO}, /* 105 */
1084     {-80, 45, PT_BEZIERTO}, /* 106 */
1085     {-80, 52, PT_BEZIERTO}, /* 107 */
1086     {-80, 67, PT_LINETO}, /* 108 */
1087     {-80, 74, PT_BEZIERTO}, /* 109 */
1088     {-73, 79, PT_BEZIERTO}, /* 110 */
1089     {-65, 79, PT_BEZIERTO}, /* 111 */
1090     {-56, 79, PT_LINETO}, /* 112 */
1091     {-47, 79, PT_BEZIERTO}, /* 113 */
1092     {-41, 74, PT_BEZIERTO}, /* 114 */
1093     {-41, 67, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 115 */
1094     {-61, 79, PT_MOVETO}, /* 116 */
1095     {-61, 74, PT_BEZIERTO}, /* 117 */
1096     {-64, 70, PT_BEZIERTO}, /* 118 */
1097     {-68, 70, PT_BEZIERTO}, /* 119 */
1098     {-103, 70, PT_LINETO}, /* 120 */
1099     {-107, 70, PT_BEZIERTO}, /* 121 */
1100     {-110, 74, PT_BEZIERTO}, /* 122 */
1101     {-110, 79, PT_BEZIERTO}, /* 123 */
1102     {-110, 90, PT_LINETO}, /* 124 */
1103     {-110, 95, PT_BEZIERTO}, /* 125 */
1104     {-107, 99, PT_BEZIERTO}, /* 126 */
1105     {-103, 99, PT_BEZIERTO}, /* 127 */
1106     {-68, 99, PT_LINETO}, /* 128 */
1107     {-64, 99, PT_BEZIERTO}, /* 129 */
1108     {-61, 95, PT_BEZIERTO}, /* 130 */
1109     {-61, 90, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 131 */
1110     {119, -102, PT_MOVETO}, /* 132 */
1111     {119, -112, PT_BEZIERTO}, /* 133 */
1112     {109, -120, PT_BEZIERTO}, /* 134 */
1113     {97, -120, PT_BEZIERTO}, /* 135 */
1114     {82, -120, PT_LINETO}, /* 136 */
1115     {70, -120, PT_BEZIERTO}, /* 137 */
1116     {60, -112, PT_BEZIERTO}, /* 138 */
1117     {60, -102, PT_BEZIERTO}, /* 139 */
1118     {60, -79, PT_LINETO}, /* 140 */
1119     {60, -69, PT_BEZIERTO}, /* 141 */
1120     {70, -61, PT_BEZIERTO}, /* 142 */
1121     {82, -61, PT_BEZIERTO}, /* 143 */
1122     {97, -61, PT_LINETO}, /* 144 */
1123     {109, -61, PT_BEZIERTO}, /* 145 */
1124     {119, -69, PT_BEZIERTO}, /* 146 */
1125     {119, -79, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 147 */
1126     {164, -144, PT_MOVETO}, /* 148 */
1127     {164, -147, PT_BEZIERTO}, /* 149 */
1128     {162, -150, PT_BEZIERTO}, /* 150 */
1129     {160, -150, PT_BEZIERTO}, /* 151 */
1130     {94, -150, PT_LINETO}, /* 152 */
1131     {92, -150, PT_BEZIERTO}, /* 153 */
1132     {90, -147, PT_BEZIERTO}, /* 154 */
1133     {90, -144, PT_BEZIERTO}, /* 155 */
1134     {90, -112, PT_LINETO}, /* 156 */
1135     {90, -109, PT_BEZIERTO}, /* 157 */
1136     {92, -106, PT_BEZIERTO}, /* 158 */
1137     {94, -106, PT_BEZIERTO}, /* 159 */
1138     {160, -106, PT_LINETO}, /* 160 */
1139     {162, -106, PT_BEZIERTO}, /* 161 */
1140     {164, -109, PT_BEZIERTO}, /* 162 */
1141     {164, -112, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 163 */
1142     {-4, -6, PT_MOVETO}, /* 164 */
1143     {-4, -6, PT_BEZIERTO}, /* 165 */
1144     {-4, -6, PT_BEZIERTO}, /* 166 */
1145     {-4, -6, PT_BEZIERTO}, /* 167 */
1146     {-6, -6, PT_LINETO}, /* 168 */
1147     {-6, -6, PT_BEZIERTO}, /* 169 */
1148     {-6, -6, PT_BEZIERTO}, /* 170 */
1149     {-6, -6, PT_BEZIERTO}, /* 171 */
1150     {-6, -4, PT_LINETO}, /* 172 */
1151     {-6, -4, PT_BEZIERTO}, /* 173 */
1152     {-6, -4, PT_BEZIERTO}, /* 174 */
1153     {-6, -4, PT_BEZIERTO}, /* 175 */
1154     {-4, -4, PT_LINETO}, /* 176 */
1155     {-4, -4, PT_BEZIERTO}, /* 177 */
1156     {-4, -4, PT_BEZIERTO}, /* 178 */
1157     {-4, -4, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 179 */
1158     {40, 25, PT_MOVETO}, /* 180 */
1159     {40, 22, PT_BEZIERTO}, /* 181 */
1160     {38, 20, PT_BEZIERTO}, /* 182 */
1161     {35, 20, PT_BEZIERTO}, /* 183 */
1162     {25, 20, PT_LINETO}, /* 184 */
1163     {22, 20, PT_BEZIERTO}, /* 185 */
1164     {20, 22, PT_BEZIERTO}, /* 186 */
1165     {20, 25, PT_BEZIERTO}, /* 187 */
1166     {20, 35, PT_LINETO}, /* 188 */
1167     {20, 38, PT_BEZIERTO}, /* 189 */
1168     {22, 40, PT_BEZIERTO}, /* 190 */
1169     {25, 40, PT_BEZIERTO}, /* 191 */
1170     {35, 40, PT_LINETO}, /* 192 */
1171     {38, 40, PT_BEZIERTO}, /* 193 */
1172     {40, 38, PT_BEZIERTO}, /* 194 */
1173     {40, 35, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 195 */
1174     {55, 43, PT_MOVETO}, /* 196 */
1175     {55, 38, PT_BEZIERTO}, /* 197 */
1176     {49, 35, PT_BEZIERTO}, /* 198 */
1177     {43, 35, PT_BEZIERTO}, /* 199 */
1178     {43, 35, PT_LINETO}, /* 200 */
1179     {36, 35, PT_BEZIERTO}, /* 201 */
1180     {30, 38, PT_BEZIERTO}, /* 202 */
1181     {30, 43, PT_BEZIERTO}, /* 203 */
1182     {30, 43, PT_LINETO}, /* 204 */
1183     {30, 47, PT_BEZIERTO}, /* 205 */
1184     {36, 50, PT_BEZIERTO}, /* 206 */
1185     {43, 50, PT_BEZIERTO}, /* 207 */
1186     {43, 50, PT_LINETO}, /* 208 */
1187     {49, 50, PT_BEZIERTO}, /* 209 */
1188     {55, 47, PT_BEZIERTO}, /* 210 */
1189     {55, 43, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 211 */
1190     {60, 46, PT_MOVETO}, /* 212 */
1191     {60, 46, PT_BEZIERTO}, /* 213 */
1192     {59, 45, PT_BEZIERTO}, /* 214 */
1193     {58, 45, PT_BEZIERTO}, /* 215 */
1194     {38, 45, PT_LINETO}, /* 216 */
1195     {36, 45, PT_BEZIERTO}, /* 217 */
1196     {35, 46, PT_BEZIERTO}, /* 218 */
1197     {35, 46, PT_BEZIERTO}, /* 219 */
1198     {35, 59, PT_LINETO}, /* 220 */
1199     {35, 60, PT_BEZIERTO}, /* 221 */
1200     {36, 60, PT_BEZIERTO}, /* 222 */
1201     {38, 60, PT_BEZIERTO}, /* 223 */
1202     {58, 60, PT_LINETO}, /* 224 */
1203     {59, 60, PT_BEZIERTO}, /* 225 */
1204     {60, 60, PT_BEZIERTO}, /* 226 */
1205     {60, 59, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 227 */
1206     {70, 70, PT_MOVETO}, /* 228 */
1207     {70, 70, PT_BEZIERTO}, /* 229 */
1208     {70, 70, PT_BEZIERTO}, /* 230 */
1209     {70, 70, PT_BEZIERTO}, /* 231 */
1210     {50, 70, PT_LINETO}, /* 232 */
1211     {50, 70, PT_BEZIERTO}, /* 233 */
1212     {50, 70, PT_BEZIERTO}, /* 234 */
1213     {50, 70, PT_BEZIERTO}, /* 235 */
1214     {50, 70, PT_LINETO}, /* 236 */
1215     {50, 70, PT_BEZIERTO}, /* 237 */
1216     {50, 70, PT_BEZIERTO}, /* 238 */
1217     {50, 70, PT_BEZIERTO}, /* 239 */
1218     {70, 70, PT_LINETO}, /* 240 */
1219     {70, 70, PT_BEZIERTO}, /* 241 */
1220     {70, 70, PT_BEZIERTO}, /* 242 */
1221     {70, 70, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 243 */
1222     {75, 75, PT_MOVETO}, /* 244 */
1223     {75, 75, PT_BEZIERTO}, /* 245 */
1224     {75, 75, PT_BEZIERTO}, /* 246 */
1225     {75, 75, PT_BEZIERTO}, /* 247 */
1226     {75, 75, PT_LINETO}, /* 248 */
1227     {75, 75, PT_BEZIERTO}, /* 249 */
1228     {75, 75, PT_BEZIERTO}, /* 250 */
1229     {75, 75, PT_BEZIERTO}, /* 251 */
1230     {75, 85, PT_LINETO}, /* 252 */
1231     {75, 85, PT_BEZIERTO}, /* 253 */
1232     {75, 85, PT_BEZIERTO}, /* 254 */
1233     {75, 85, PT_BEZIERTO}, /* 255 */
1234     {75, 85, PT_LINETO}, /* 256 */
1235     {75, 85, PT_BEZIERTO}, /* 257 */
1236     {75, 85, PT_BEZIERTO}, /* 258 */
1237     {75, 85, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 259 */
1238     {81, 81, PT_MOVETO}, /* 260 */
1239     {81, 80, PT_BEZIERTO}, /* 261 */
1240     {81, 80, PT_BEZIERTO}, /* 262 */
1241     {81, 80, PT_BEZIERTO}, /* 263 */
1242     {81, 80, PT_LINETO}, /* 264 */
1243     {80, 80, PT_BEZIERTO}, /* 265 */
1244     {80, 80, PT_BEZIERTO}, /* 266 */
1245     {80, 81, PT_BEZIERTO}, /* 267 */
1246     {80, 81, PT_LINETO}, /* 268 */
1247     {80, 81, PT_BEZIERTO}, /* 269 */
1248     {80, 81, PT_BEZIERTO}, /* 270 */
1249     {81, 81, PT_BEZIERTO}, /* 271 */
1250     {81, 81, PT_LINETO}, /* 272 */
1251     {81, 81, PT_BEZIERTO}, /* 273 */
1252     {81, 81, PT_BEZIERTO}, /* 274 */
1253     {81, 81, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 275 */
1254     {95, 85, PT_MOVETO}, /* 276 */
1255     {90, 85, PT_LINETO}, /* 277 */
1256     {90, 90, PT_LINETO}, /* 278 */
1257     {95, 90, PT_LINETO | PT_CLOSEFIGURE}, /* 279 */
1258     {40, 35, PT_MOVETO}, /* 280 */
1259     {40, 38, PT_BEZIERTO}, /* 281 */
1260     {38, 40, PT_BEZIERTO}, /* 282 */
1261     {35, 40, PT_BEZIERTO}, /* 283 */
1262     {25, 40, PT_LINETO}, /* 284 */
1263     {22, 40, PT_BEZIERTO}, /* 285 */
1264     {20, 38, PT_BEZIERTO}, /* 286 */
1265     {20, 35, PT_BEZIERTO}, /* 287 */
1266     {20, 25, PT_LINETO}, /* 288 */
1267     {20, 22, PT_BEZIERTO}, /* 289 */
1268     {22, 20, PT_BEZIERTO}, /* 290 */
1269     {25, 20, PT_BEZIERTO}, /* 291 */
1270     {35, 20, PT_LINETO}, /* 292 */
1271     {38, 20, PT_BEZIERTO}, /* 293 */
1272     {40, 22, PT_BEZIERTO}, /* 294 */
1273     {40, 25, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 295 */
1274     {55, 43, PT_MOVETO}, /* 296 */
1275     {55, 47, PT_BEZIERTO}, /* 297 */
1276     {49, 50, PT_BEZIERTO}, /* 298 */
1277     {43, 50, PT_BEZIERTO}, /* 299 */
1278     {43, 50, PT_LINETO}, /* 300 */
1279     {36, 50, PT_BEZIERTO}, /* 301 */
1280     {30, 47, PT_BEZIERTO}, /* 302 */
1281     {30, 43, PT_BEZIERTO}, /* 303 */
1282     {30, 43, PT_LINETO}, /* 304 */
1283     {30, 38, PT_BEZIERTO}, /* 305 */
1284     {36, 35, PT_BEZIERTO}, /* 306 */
1285     {43, 35, PT_BEZIERTO}, /* 307 */
1286     {43, 35, PT_LINETO}, /* 308 */
1287     {49, 35, PT_BEZIERTO}, /* 309 */
1288     {55, 38, PT_BEZIERTO}, /* 310 */
1289     {55, 43, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 311 */
1290 };
1291 
test_roundrect(void)1292 static void test_roundrect(void)
1293 {
1294     HDC hdc = GetDC( 0 );
1295 
1296     BeginPath( hdc );
1297     RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1298     RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
1299     RoundRect( hdc, 60, 60, 35, 45, 5, 2 );
1300     RoundRect( hdc, 70, 70, 50, 70, 3, 5 );
1301     RoundRect( hdc, 75, 75, 75, 85, 6, 4 );
1302     RoundRect( hdc, 80, 80, 81, 81, 8, 9 );
1303     RoundRect( hdc, 90, 90, 95, 85, 0, 7 );
1304     SetArcDirection( hdc, AD_CLOCKWISE );
1305     RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1306     RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
1307     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
1308     SetMapMode( hdc, MM_ANISOTROPIC );
1309     SetViewportExtEx( hdc, -2, 2, NULL );
1310     RoundRect( hdc, 20, 20, 40, 40, 15, 12 );
1311     RoundRect( hdc, 30, 50, 55, 35, 7, 9 );
1312     SetViewportExtEx( hdc, 3, -3, NULL );
1313     RoundRect( hdc, 20, 20, 40, 40, 15, 12 );
1314     RoundRect( hdc, 30, 50, 55, 35, 3, 4 );
1315     SetWindowExtEx( hdc, -20, 20, NULL );
1316     RoundRect( hdc, 20, 20, 40, 40, 2, 1 );
1317     RoundRect( hdc, 24, 22, 21, 20, 4, 4 );
1318     SetMapMode( hdc, MM_TEXT );
1319     SetGraphicsMode( hdc, GM_ADVANCED );
1320     RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1321     RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
1322     RoundRect( hdc, 60, 60, 35, 45, 5, 2 );
1323     RoundRect( hdc, 70, 70, 50, 70, 3, 5 );
1324     RoundRect( hdc, 75, 75, 75, 85, 6, 4 );
1325     RoundRect( hdc, 80, 80, 81, 81, 8, 9 );
1326     RoundRect( hdc, 90, 90, 95, 85, 0, 7 );
1327     SetArcDirection( hdc, AD_CLOCKWISE );
1328     RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1329     RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
1330     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
1331     EndPath( hdc );
1332     SetMapMode( hdc, MM_TEXT );
1333     ok_path( hdc, "roundrect_path", roundrect_path, sizeof(roundrect_path)/sizeof(path_test_t) );
1334     ReleaseDC( 0, hdc );
1335 }
1336 
1337 static const path_test_t ellipse_path[] =
1338 {
1339     {39, 30, PT_MOVETO}, /* 0 */
1340     {39, 24, PT_BEZIERTO}, /* 1 */
1341     {35, 20, PT_BEZIERTO}, /* 2 */
1342     {30, 20, PT_BEZIERTO}, /* 3 */
1343     {24, 20, PT_BEZIERTO}, /* 4 */
1344     {20, 24, PT_BEZIERTO}, /* 5 */
1345     {20, 30, PT_BEZIERTO}, /* 6 */
1346     {20, 35, PT_BEZIERTO}, /* 7 */
1347     {24, 39, PT_BEZIERTO}, /* 8 */
1348     {30, 39, PT_BEZIERTO}, /* 9 */
1349     {35, 39, PT_BEZIERTO}, /* 10 */
1350     {39, 35, PT_BEZIERTO}, /* 11 */
1351     {39, 30, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 12 */
1352     {54, 42, PT_MOVETO}, /* 13 */
1353     {54, 38, PT_BEZIERTO}, /* 14 */
1354     {49, 35, PT_BEZIERTO}, /* 15 */
1355     {42, 35, PT_BEZIERTO}, /* 16 */
1356     {35, 35, PT_BEZIERTO}, /* 17 */
1357     {30, 38, PT_BEZIERTO}, /* 18 */
1358     {30, 42, PT_BEZIERTO}, /* 19 */
1359     {30, 46, PT_BEZIERTO}, /* 20 */
1360     {35, 49, PT_BEZIERTO}, /* 21 */
1361     {42, 49, PT_BEZIERTO}, /* 22 */
1362     {49, 49, PT_BEZIERTO}, /* 23 */
1363     {54, 46, PT_BEZIERTO}, /* 24 */
1364     {54, 42, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 25 */
1365     {59, 52, PT_MOVETO}, /* 26 */
1366     {59, 48, PT_BEZIERTO}, /* 27 */
1367     {54, 45, PT_BEZIERTO}, /* 28 */
1368     {47, 45, PT_BEZIERTO}, /* 29 */
1369     {40, 45, PT_BEZIERTO}, /* 30 */
1370     {35, 48, PT_BEZIERTO}, /* 31 */
1371     {35, 52, PT_BEZIERTO}, /* 32 */
1372     {35, 56, PT_BEZIERTO}, /* 33 */
1373     {40, 59, PT_BEZIERTO}, /* 34 */
1374     {47, 59, PT_BEZIERTO}, /* 35 */
1375     {54, 59, PT_BEZIERTO}, /* 36 */
1376     {59, 56, PT_BEZIERTO}, /* 37 */
1377     {59, 52, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 38 */
1378     {80, 80, PT_MOVETO}, /* 39 */
1379     {80, 80, PT_BEZIERTO}, /* 40 */
1380     {80, 80, PT_BEZIERTO}, /* 41 */
1381     {80, 80, PT_BEZIERTO}, /* 42 */
1382     {80, 80, PT_BEZIERTO}, /* 43 */
1383     {80, 80, PT_BEZIERTO}, /* 44 */
1384     {80, 80, PT_BEZIERTO}, /* 45 */
1385     {80, 80, PT_BEZIERTO}, /* 46 */
1386     {80, 80, PT_BEZIERTO}, /* 47 */
1387     {80, 80, PT_BEZIERTO}, /* 48 */
1388     {80, 80, PT_BEZIERTO}, /* 49 */
1389     {80, 80, PT_BEZIERTO}, /* 50 */
1390     {80, 80, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 51 */
1391     {39, 30, PT_MOVETO}, /* 52 */
1392     {39, 35, PT_BEZIERTO}, /* 53 */
1393     {35, 39, PT_BEZIERTO}, /* 54 */
1394     {30, 39, PT_BEZIERTO}, /* 55 */
1395     {24, 39, PT_BEZIERTO}, /* 56 */
1396     {20, 35, PT_BEZIERTO}, /* 57 */
1397     {20, 30, PT_BEZIERTO}, /* 58 */
1398     {20, 24, PT_BEZIERTO}, /* 59 */
1399     {24, 20, PT_BEZIERTO}, /* 60 */
1400     {30, 20, PT_BEZIERTO}, /* 61 */
1401     {35, 20, PT_BEZIERTO}, /* 62 */
1402     {39, 24, PT_BEZIERTO}, /* 63 */
1403     {39, 30, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 64 */
1404     {54, 42, PT_MOVETO}, /* 65 */
1405     {54, 46, PT_BEZIERTO}, /* 66 */
1406     {49, 49, PT_BEZIERTO}, /* 67 */
1407     {42, 49, PT_BEZIERTO}, /* 68 */
1408     {35, 49, PT_BEZIERTO}, /* 69 */
1409     {30, 46, PT_BEZIERTO}, /* 70 */
1410     {30, 42, PT_BEZIERTO}, /* 71 */
1411     {30, 38, PT_BEZIERTO}, /* 72 */
1412     {35, 35, PT_BEZIERTO}, /* 73 */
1413     {42, 35, PT_BEZIERTO}, /* 74 */
1414     {49, 35, PT_BEZIERTO}, /* 75 */
1415     {54, 38, PT_BEZIERTO}, /* 76 */
1416     {54, 42, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 77 */
1417     {59, 52, PT_MOVETO}, /* 78 */
1418     {59, 56, PT_BEZIERTO}, /* 79 */
1419     {54, 59, PT_BEZIERTO}, /* 80 */
1420     {47, 59, PT_BEZIERTO}, /* 81 */
1421     {40, 59, PT_BEZIERTO}, /* 82 */
1422     {35, 56, PT_BEZIERTO}, /* 83 */
1423     {35, 52, PT_BEZIERTO}, /* 84 */
1424     {35, 48, PT_BEZIERTO}, /* 85 */
1425     {40, 45, PT_BEZIERTO}, /* 86 */
1426     {47, 45, PT_BEZIERTO}, /* 87 */
1427     {54, 45, PT_BEZIERTO}, /* 88 */
1428     {59, 48, PT_BEZIERTO}, /* 89 */
1429     {59, 52, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 90 */
1430     {80, 80, PT_MOVETO}, /* 91 */
1431     {80, 80, PT_BEZIERTO}, /* 92 */
1432     {80, 80, PT_BEZIERTO}, /* 93 */
1433     {80, 80, PT_BEZIERTO}, /* 94 */
1434     {80, 80, PT_BEZIERTO}, /* 95 */
1435     {80, 80, PT_BEZIERTO}, /* 96 */
1436     {80, 80, PT_BEZIERTO}, /* 97 */
1437     {80, 80, PT_BEZIERTO}, /* 98 */
1438     {80, 80, PT_BEZIERTO}, /* 99 */
1439     {80, 80, PT_BEZIERTO}, /* 100 */
1440     {80, 80, PT_BEZIERTO}, /* 101 */
1441     {80, 80, PT_BEZIERTO}, /* 102 */
1442     {80, 80, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 103 */
1443     {-41, 60, PT_MOVETO}, /* 104 */
1444     {-41, 49, PT_BEZIERTO}, /* 105 */
1445     {-50, 40, PT_BEZIERTO}, /* 106 */
1446     {-60, 40, PT_BEZIERTO}, /* 107 */
1447     {-71, 40, PT_BEZIERTO}, /* 108 */
1448     {-80, 49, PT_BEZIERTO}, /* 109 */
1449     {-80, 60, PT_BEZIERTO}, /* 110 */
1450     {-80, 70, PT_BEZIERTO}, /* 111 */
1451     {-71, 79, PT_BEZIERTO}, /* 112 */
1452     {-60, 79, PT_BEZIERTO}, /* 113 */
1453     {-50, 79, PT_BEZIERTO}, /* 114 */
1454     {-41, 70, PT_BEZIERTO}, /* 115 */
1455     {-41, 60, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 116 */
1456     {-61, 85, PT_MOVETO}, /* 117 */
1457     {-61, 77, PT_BEZIERTO}, /* 118 */
1458     {-72, 70, PT_BEZIERTO}, /* 119 */
1459     {-85, 70, PT_BEZIERTO}, /* 120 */
1460     {-99, 70, PT_BEZIERTO}, /* 121 */
1461     {-110, 77, PT_BEZIERTO}, /* 122 */
1462     {-110, 85, PT_BEZIERTO}, /* 123 */
1463     {-110, 93, PT_BEZIERTO}, /* 124 */
1464     {-99, 99, PT_BEZIERTO}, /* 125 */
1465     {-85, 99, PT_BEZIERTO}, /* 126 */
1466     {-72, 99, PT_BEZIERTO}, /* 127 */
1467     {-61, 93, PT_BEZIERTO}, /* 128 */
1468     {-61, 85, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 129 */
1469     {119, -90, PT_MOVETO}, /* 130 */
1470     {119, -107, PT_BEZIERTO}, /* 131 */
1471     {106, -120, PT_BEZIERTO}, /* 132 */
1472     {90, -120, PT_BEZIERTO}, /* 133 */
1473     {73, -120, PT_BEZIERTO}, /* 134 */
1474     {60, -107, PT_BEZIERTO}, /* 135 */
1475     {60, -90, PT_BEZIERTO}, /* 136 */
1476     {60, -74, PT_BEZIERTO}, /* 137 */
1477     {73, -61, PT_BEZIERTO}, /* 138 */
1478     {90, -61, PT_BEZIERTO}, /* 139 */
1479     {106, -61, PT_BEZIERTO}, /* 140 */
1480     {119, -74, PT_BEZIERTO}, /* 141 */
1481     {119, -90, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 142 */
1482     {164, -128, PT_MOVETO}, /* 143 */
1483     {164, -140, PT_BEZIERTO}, /* 144 */
1484     {147, -150, PT_BEZIERTO}, /* 145 */
1485     {127, -150, PT_BEZIERTO}, /* 146 */
1486     {107, -150, PT_BEZIERTO}, /* 147 */
1487     {90, -140, PT_BEZIERTO}, /* 148 */
1488     {90, -128, PT_BEZIERTO}, /* 149 */
1489     {90, -116, PT_BEZIERTO}, /* 150 */
1490     {107, -106, PT_BEZIERTO}, /* 151 */
1491     {127, -106, PT_BEZIERTO}, /* 152 */
1492     {147, -106, PT_BEZIERTO}, /* 153 */
1493     {164, -116, PT_BEZIERTO}, /* 154 */
1494     {164, -128, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 155 */
1495     {-4, -5, PT_MOVETO}, /* 156 */
1496     {-4, -5, PT_BEZIERTO}, /* 157 */
1497     {-4, -6, PT_BEZIERTO}, /* 158 */
1498     {-5, -6, PT_BEZIERTO}, /* 159 */
1499     {-6, -6, PT_BEZIERTO}, /* 160 */
1500     {-6, -5, PT_BEZIERTO}, /* 161 */
1501     {-6, -5, PT_BEZIERTO}, /* 162 */
1502     {-6, -4, PT_BEZIERTO}, /* 163 */
1503     {-6, -4, PT_BEZIERTO}, /* 164 */
1504     {-5, -4, PT_BEZIERTO}, /* 165 */
1505     {-4, -4, PT_BEZIERTO}, /* 166 */
1506     {-4, -4, PT_BEZIERTO}, /* 167 */
1507     {-4, -5, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 168 */
1508     {40, 30, PT_MOVETO}, /* 169 */
1509     {40, 25, PT_BEZIERTO}, /* 170 */
1510     {36, 20, PT_BEZIERTO}, /* 171 */
1511     {30, 20, PT_BEZIERTO}, /* 172 */
1512     {24, 20, PT_BEZIERTO}, /* 173 */
1513     {20, 25, PT_BEZIERTO}, /* 174 */
1514     {20, 30, PT_BEZIERTO}, /* 175 */
1515     {20, 36, PT_BEZIERTO}, /* 176 */
1516     {24, 40, PT_BEZIERTO}, /* 177 */
1517     {30, 40, PT_BEZIERTO}, /* 178 */
1518     {36, 40, PT_BEZIERTO}, /* 179 */
1519     {40, 36, PT_BEZIERTO}, /* 180 */
1520     {40, 30, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 181 */
1521     {55, 43, PT_MOVETO}, /* 182 */
1522     {55, 38, PT_BEZIERTO}, /* 183 */
1523     {49, 35, PT_BEZIERTO}, /* 184 */
1524     {43, 35, PT_BEZIERTO}, /* 185 */
1525     {36, 35, PT_BEZIERTO}, /* 186 */
1526     {30, 38, PT_BEZIERTO}, /* 187 */
1527     {30, 43, PT_BEZIERTO}, /* 188 */
1528     {30, 47, PT_BEZIERTO}, /* 189 */
1529     {36, 50, PT_BEZIERTO}, /* 190 */
1530     {43, 50, PT_BEZIERTO}, /* 191 */
1531     {49, 50, PT_BEZIERTO}, /* 192 */
1532     {55, 47, PT_BEZIERTO}, /* 193 */
1533     {55, 43, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 194 */
1534     {60, 53, PT_MOVETO}, /* 195 */
1535     {60, 48, PT_BEZIERTO}, /* 196 */
1536     {54, 45, PT_BEZIERTO}, /* 197 */
1537     {48, 45, PT_BEZIERTO}, /* 198 */
1538     {41, 45, PT_BEZIERTO}, /* 199 */
1539     {35, 48, PT_BEZIERTO}, /* 200 */
1540     {35, 53, PT_BEZIERTO}, /* 201 */
1541     {35, 57, PT_BEZIERTO}, /* 202 */
1542     {41, 60, PT_BEZIERTO}, /* 203 */
1543     {48, 60, PT_BEZIERTO}, /* 204 */
1544     {54, 60, PT_BEZIERTO}, /* 205 */
1545     {60, 57, PT_BEZIERTO}, /* 206 */
1546     {60, 53, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 207 */
1547     {70, 70, PT_MOVETO}, /* 208 */
1548     {70, 70, PT_BEZIERTO}, /* 209 */
1549     {66, 70, PT_BEZIERTO}, /* 210 */
1550     {60, 70, PT_BEZIERTO}, /* 211 */
1551     {54, 70, PT_BEZIERTO}, /* 212 */
1552     {50, 70, PT_BEZIERTO}, /* 213 */
1553     {50, 70, PT_BEZIERTO}, /* 214 */
1554     {50, 70, PT_BEZIERTO}, /* 215 */
1555     {54, 70, PT_BEZIERTO}, /* 216 */
1556     {60, 70, PT_BEZIERTO}, /* 217 */
1557     {66, 70, PT_BEZIERTO}, /* 218 */
1558     {70, 70, PT_BEZIERTO}, /* 219 */
1559     {70, 70, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 220 */
1560     {75, 80, PT_MOVETO}, /* 221 */
1561     {75, 77, PT_BEZIERTO}, /* 222 */
1562     {75, 75, PT_BEZIERTO}, /* 223 */
1563     {75, 75, PT_BEZIERTO}, /* 224 */
1564     {75, 75, PT_BEZIERTO}, /* 225 */
1565     {75, 77, PT_BEZIERTO}, /* 226 */
1566     {75, 80, PT_BEZIERTO}, /* 227 */
1567     {75, 83, PT_BEZIERTO}, /* 228 */
1568     {75, 85, PT_BEZIERTO}, /* 229 */
1569     {75, 85, PT_BEZIERTO}, /* 230 */
1570     {75, 85, PT_BEZIERTO}, /* 231 */
1571     {75, 83, PT_BEZIERTO}, /* 232 */
1572     {75, 80, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 233 */
1573     {81, 81, PT_MOVETO}, /* 234 */
1574     {81, 80, PT_BEZIERTO}, /* 235 */
1575     {81, 80, PT_BEZIERTO}, /* 236 */
1576     {81, 80, PT_BEZIERTO}, /* 237 */
1577     {80, 80, PT_BEZIERTO}, /* 238 */
1578     {80, 80, PT_BEZIERTO}, /* 239 */
1579     {80, 81, PT_BEZIERTO}, /* 240 */
1580     {80, 81, PT_BEZIERTO}, /* 241 */
1581     {80, 81, PT_BEZIERTO}, /* 242 */
1582     {81, 81, PT_BEZIERTO}, /* 243 */
1583     {81, 81, PT_BEZIERTO}, /* 244 */
1584     {81, 81, PT_BEZIERTO}, /* 245 */
1585     {81, 81, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 246 */
1586     {40, 30, PT_MOVETO}, /* 247 */
1587     {40, 36, PT_BEZIERTO}, /* 248 */
1588     {36, 40, PT_BEZIERTO}, /* 249 */
1589     {30, 40, PT_BEZIERTO}, /* 250 */
1590     {24, 40, PT_BEZIERTO}, /* 251 */
1591     {20, 36, PT_BEZIERTO}, /* 252 */
1592     {20, 30, PT_BEZIERTO}, /* 253 */
1593     {20, 24, PT_BEZIERTO}, /* 254 */
1594     {24, 20, PT_BEZIERTO}, /* 255 */
1595     {30, 20, PT_BEZIERTO}, /* 256 */
1596     {36, 20, PT_BEZIERTO}, /* 257 */
1597     {40, 24, PT_BEZIERTO}, /* 258 */
1598     {40, 30, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 259 */
1599     {55, 43, PT_MOVETO}, /* 260 */
1600     {55, 47, PT_BEZIERTO}, /* 261 */
1601     {49, 50, PT_BEZIERTO}, /* 262 */
1602     {43, 50, PT_BEZIERTO}, /* 263 */
1603     {36, 50, PT_BEZIERTO}, /* 264 */
1604     {30, 47, PT_BEZIERTO}, /* 265 */
1605     {30, 43, PT_BEZIERTO}, /* 266 */
1606     {30, 38, PT_BEZIERTO}, /* 267 */
1607     {36, 35, PT_BEZIERTO}, /* 268 */
1608     {43, 35, PT_BEZIERTO}, /* 269 */
1609     {49, 35, PT_BEZIERTO}, /* 270 */
1610     {55, 38, PT_BEZIERTO}, /* 271 */
1611     {55, 43, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 272 */
1612     {60, 53, PT_MOVETO}, /* 273 */
1613     {60, 57, PT_BEZIERTO}, /* 274 */
1614     {54, 60, PT_BEZIERTO}, /* 275 */
1615     {48, 60, PT_BEZIERTO}, /* 276 */
1616     {41, 60, PT_BEZIERTO}, /* 277 */
1617     {35, 57, PT_BEZIERTO}, /* 278 */
1618     {35, 53, PT_BEZIERTO}, /* 279 */
1619     {35, 48, PT_BEZIERTO}, /* 280 */
1620     {41, 45, PT_BEZIERTO}, /* 281 */
1621     {48, 45, PT_BEZIERTO}, /* 282 */
1622     {54, 45, PT_BEZIERTO}, /* 283 */
1623     {60, 48, PT_BEZIERTO}, /* 284 */
1624     {60, 53, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 285 */
1625     {70, 70, PT_MOVETO}, /* 286 */
1626     {70, 70, PT_BEZIERTO}, /* 287 */
1627     {66, 70, PT_BEZIERTO}, /* 288 */
1628     {60, 70, PT_BEZIERTO}, /* 289 */
1629     {54, 70, PT_BEZIERTO}, /* 290 */
1630     {50, 70, PT_BEZIERTO}, /* 291 */
1631     {50, 70, PT_BEZIERTO}, /* 292 */
1632     {50, 70, PT_BEZIERTO}, /* 293 */
1633     {54, 70, PT_BEZIERTO}, /* 294 */
1634     {60, 70, PT_BEZIERTO}, /* 295 */
1635     {66, 70, PT_BEZIERTO}, /* 296 */
1636     {70, 70, PT_BEZIERTO}, /* 297 */
1637     {70, 70, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 298 */
1638     {75, 80, PT_MOVETO}, /* 299 */
1639     {75, 83, PT_BEZIERTO}, /* 300 */
1640     {75, 85, PT_BEZIERTO}, /* 301 */
1641     {75, 85, PT_BEZIERTO}, /* 302 */
1642     {75, 85, PT_BEZIERTO}, /* 303 */
1643     {75, 83, PT_BEZIERTO}, /* 304 */
1644     {75, 80, PT_BEZIERTO}, /* 305 */
1645     {75, 77, PT_BEZIERTO}, /* 306 */
1646     {75, 75, PT_BEZIERTO}, /* 307 */
1647     {75, 75, PT_BEZIERTO}, /* 308 */
1648     {75, 75, PT_BEZIERTO}, /* 309 */
1649     {75, 77, PT_BEZIERTO}, /* 310 */
1650     {75, 80, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 311 */
1651     {81, 81, PT_MOVETO}, /* 312 */
1652     {81, 81, PT_BEZIERTO}, /* 313 */
1653     {81, 81, PT_BEZIERTO}, /* 314 */
1654     {81, 81, PT_BEZIERTO}, /* 315 */
1655     {80, 81, PT_BEZIERTO}, /* 316 */
1656     {80, 81, PT_BEZIERTO}, /* 317 */
1657     {80, 81, PT_BEZIERTO}, /* 318 */
1658     {80, 80, PT_BEZIERTO}, /* 319 */
1659     {80, 80, PT_BEZIERTO}, /* 320 */
1660     {81, 80, PT_BEZIERTO}, /* 321 */
1661     {81, 80, PT_BEZIERTO}, /* 322 */
1662     {81, 80, PT_BEZIERTO}, /* 323 */
1663     {81, 81, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 324 */
1664 };
1665 
test_ellipse(void)1666 static void test_ellipse(void)
1667 {
1668     HDC hdc = GetDC( 0 );
1669 
1670     BeginPath( hdc );
1671     Ellipse( hdc, 20, 20, 40, 40 );
1672     Ellipse( hdc, 30, 50, 55, 35 );
1673     Ellipse( hdc, 60, 60, 35, 45 );
1674     Ellipse( hdc, 70, 70, 50, 70 );
1675     Ellipse( hdc, 75, 75, 75, 85 );
1676     Ellipse( hdc, 80, 80, 81, 81 );
1677     SetArcDirection( hdc, AD_CLOCKWISE );
1678     Ellipse( hdc, 20, 20, 40, 40 );
1679     Ellipse( hdc, 30, 50, 55, 35 );
1680     Ellipse( hdc, 60, 60, 35, 45 );
1681     Ellipse( hdc, 70, 70, 50, 70 );
1682     Ellipse( hdc, 75, 75, 75, 85 );
1683     Ellipse( hdc, 80, 80, 81, 81 );
1684     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
1685     SetMapMode( hdc, MM_ANISOTROPIC );
1686     SetViewportExtEx( hdc, -2, 2, NULL );
1687     Ellipse( hdc, 20, 20, 40, 40 );
1688     Ellipse( hdc, 30, 50, 55, 35 );
1689     SetViewportExtEx( hdc, 3, -3, NULL );
1690     Ellipse( hdc, 20, 20, 40, 40 );
1691     Ellipse( hdc, 30, 50, 55, 35 );
1692     SetWindowExtEx( hdc, -20, 20, NULL );
1693     Ellipse( hdc, 20, 20, 40, 40 );
1694     Ellipse( hdc, 24, 22, 21, 20 );
1695     SetMapMode( hdc, MM_TEXT );
1696     SetGraphicsMode( hdc, GM_ADVANCED );
1697     Ellipse( hdc, 20, 20, 40, 40 );
1698     Ellipse( hdc, 30, 50, 55, 35 );
1699     Ellipse( hdc, 60, 60, 35, 45 );
1700     Ellipse( hdc, 70, 70, 50, 70 );
1701     Ellipse( hdc, 75, 75, 75, 85 );
1702     Ellipse( hdc, 80, 80, 81, 81 );
1703     SetArcDirection( hdc, AD_CLOCKWISE );
1704     Ellipse( hdc, 20, 20, 40, 40 );
1705     Ellipse( hdc, 30, 50, 55, 35 );
1706     Ellipse( hdc, 60, 60, 35, 45 );
1707     Ellipse( hdc, 70, 70, 50, 70 );
1708     Ellipse( hdc, 75, 75, 75, 85 );
1709     Ellipse( hdc, 80, 80, 81, 81 );
1710     SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
1711     EndPath( hdc );
1712     SetMapMode( hdc, MM_TEXT );
1713     ok_path( hdc, "ellipse_path", ellipse_path, sizeof(ellipse_path)/sizeof(path_test_t) );
1714 }
1715 
1716 static const path_test_t all_funcs_path[] =
1717 {
1718     {0, 0, PT_MOVETO}, /* 0 */
1719     {50, 150, PT_LINETO}, /* 1 */
1720     {50, 50, PT_MOVETO}, /* 2 */
1721     {150, 150, PT_LINETO}, /* 3 */
1722     {150, 50, PT_LINETO}, /* 4 */
1723     {50, 50, PT_LINETO}, /* 5 */
1724     {37, 13, PT_LINETO}, /* 6 */
1725     {24, 13, PT_BEZIERTO}, /* 7 */
1726     {14, 23, PT_BEZIERTO}, /* 8 */
1727     {14, 36, PT_BEZIERTO}, /* 9 */
1728     {14, 49, PT_BEZIERTO}, /* 10 */
1729     {24, 59, PT_BEZIERTO}, /* 11 */
1730     {37, 59, PT_BEZIERTO}, /* 12 */
1731     {37, 59, PT_BEZIERTO}, /* 13 */
1732     {37, 59, PT_BEZIERTO}, /* 14 */
1733     {37, 59, PT_BEZIERTO}, /* 15 */
1734     {10, 10, PT_MOVETO}, /* 16 */
1735     {20, 10, PT_LINETO}, /* 17 */
1736     {10, 20, PT_LINETO}, /* 18 */
1737     {20, 20, PT_LINETO}, /* 19 */
1738     {36, 27, PT_MOVETO}, /* 20 */
1739     {37, 26, PT_BEZIERTO}, /* 21 */
1740     {38, 25, PT_BEZIERTO}, /* 22 */
1741     {38, 25, PT_BEZIERTO}, /* 23 */
1742     {38, 23, PT_BEZIERTO}, /* 24 */
1743     {34, 21, PT_BEZIERTO}, /* 25 */
1744     {30, 21, PT_BEZIERTO}, /* 26 */
1745     {27, 21, PT_BEZIERTO}, /* 27 */
1746     {25, 21, PT_BEZIERTO}, /* 28 */
1747     {24, 22, PT_BEZIERTO}, /* 29 */
1748     {37, 59, PT_MOVETO}, /* 30 */
1749     {10, 10, PT_LINETO}, /* 31 */
1750     {20, 10, PT_LINETO}, /* 32 */
1751     {10, 20, PT_LINETO}, /* 33 */
1752     {20, 20, PT_LINETO}, /* 34 */
1753     {34, 26, PT_LINETO}, /* 35 */
1754     {35, 25, PT_BEZIERTO}, /* 36 */
1755     {36, 25, PT_BEZIERTO}, /* 37 */
1756     {36, 25, PT_BEZIERTO}, /* 38 */
1757     {36, 24, PT_BEZIERTO}, /* 39 */
1758     {33, 23, PT_BEZIERTO}, /* 40 */
1759     {30, 23, PT_BEZIERTO}, /* 41 */
1760     {28, 23, PT_BEZIERTO}, /* 42 */
1761     {26, 23, PT_BEZIERTO}, /* 43 */
1762     {25, 23, PT_BEZIERTO}, /* 44 */
1763     {10, 10, PT_MOVETO}, /* 45 */
1764     {20, 10, PT_LINETO}, /* 46 */
1765     {10, 20, PT_LINETO}, /* 47 */
1766     {20, 20, PT_LINETO}, /* 48 */
1767     {30, 30, PT_MOVETO}, /* 49 */
1768     {40, 20, PT_LINETO}, /* 50 */
1769     {20, 30, PT_LINETO}, /* 51 */
1770     {30, 40, PT_LINETO}, /* 52 */
1771     {10, 50, PT_LINETO}, /* 53 */
1772     {45, 45, PT_MOVETO}, /* 54 */
1773     {45, 45, PT_BEZIERTO}, /* 55 */
1774     {44, 46, PT_BEZIERTO}, /* 56 */
1775     {43, 47, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 57 */
1776     {10, 10, PT_MOVETO}, /* 58 */
1777     {20, 10, PT_LINETO}, /* 59 */
1778     {10, 20, PT_BEZIERTO}, /* 60 */
1779     {20, 20, PT_BEZIERTO}, /* 61 */
1780     {30, 30, PT_BEZIERTO}, /* 62 */
1781     {40, 20, PT_LINETO}, /* 63 */
1782     {20, 30, PT_LINETO | PT_CLOSEFIGURE}, /* 64 */
1783     {30, 40, PT_MOVETO}, /* 65 */
1784     {10, 50, PT_LINETO}, /* 66 */
1785     {55, 55, PT_MOVETO}, /* 67 */
1786     {54, 55, PT_BEZIERTO}, /* 68 */
1787     {54, 56, PT_BEZIERTO}, /* 69 */
1788     {54, 56, PT_BEZIERTO}, /* 70 */
1789     {58, 61, PT_LINETO | PT_CLOSEFIGURE}, /* 71 */
1790     {10, 10, PT_MOVETO}, /* 72 */
1791     {20, 10, PT_LINETO}, /* 73 */
1792     {10, 20, PT_LINETO}, /* 74 */
1793     {20, 20, PT_LINETO}, /* 75 */
1794     {30, 30, PT_LINETO}, /* 76 */
1795     {40, 20, PT_LINETO}, /* 77 */
1796     {20, 30, PT_LINETO}, /* 78 */
1797     {30, 40, PT_LINETO}, /* 79 */
1798     {10, 50, PT_LINETO | PT_CLOSEFIGURE}, /* 80 */
1799     {43, 49, PT_MOVETO}, /* 81 */
1800     {43, 40, PT_BEZIERTO}, /* 82 */
1801     {38, 33, PT_BEZIERTO}, /* 83 */
1802     {33, 33, PT_BEZIERTO}, /* 84 */
1803     {27, 33, PT_BEZIERTO}, /* 85 */
1804     {22, 40, PT_BEZIERTO}, /* 86 */
1805     {22, 49, PT_BEZIERTO}, /* 87 */
1806     {22, 58, PT_BEZIERTO}, /* 88 */
1807     {27, 65, PT_BEZIERTO}, /* 89 */
1808     {33, 65, PT_BEZIERTO}, /* 90 */
1809     {38, 65, PT_BEZIERTO}, /* 91 */
1810     {43, 58, PT_BEZIERTO}, /* 92 */
1811     {43, 49, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 93 */
1812     {79, 70, PT_MOVETO}, /* 94 */
1813     {60, 70, PT_LINETO}, /* 95 */
1814     {60, 89, PT_LINETO}, /* 96 */
1815     {79, 89, PT_LINETO | PT_CLOSEFIGURE}, /* 97 */
1816     {199, 122, PT_MOVETO}, /* 98 */
1817     {199, 110, PT_BEZIERTO}, /* 99 */
1818     {191, 100, PT_BEZIERTO}, /* 100 */
1819     {182, 100, PT_BEZIERTO}, /* 101 */
1820     {117, 100, PT_LINETO}, /* 102 */
1821     {108, 100, PT_BEZIERTO}, /* 103 */
1822     {100, 110, PT_BEZIERTO}, /* 104 */
1823     {100, 122, PT_BEZIERTO}, /* 105 */
1824     {100, 177, PT_LINETO}, /* 106 */
1825     {100, 189, PT_BEZIERTO}, /* 107 */
1826     {108, 199, PT_BEZIERTO}, /* 108 */
1827     {117, 199, PT_BEZIERTO}, /* 109 */
1828     {182, 199, PT_LINETO}, /* 110 */
1829     {191, 199, PT_BEZIERTO}, /* 111 */
1830     {199, 189, PT_BEZIERTO}, /* 112 */
1831     {199, 177, PT_BEZIERTO | PT_CLOSEFIGURE}, /* 113 */
1832     {10, 10, PT_MOVETO}, /* 114 */
1833     {20, 10, PT_BEZIERTO}, /* 115 */
1834     {10, 20, PT_BEZIERTO}, /* 116 */
1835     {20, 20, PT_BEZIERTO}, /* 117 */
1836     {30, 30, PT_BEZIERTO}, /* 118 */
1837     {40, 20, PT_BEZIERTO}, /* 119 */
1838     {20, 30, PT_BEZIERTO}, /* 120 */
1839     {10, 10, PT_MOVETO}, /* 121 */
1840     {20, 10, PT_LINETO}, /* 122 */
1841     {10, 20, PT_LINETO}, /* 123 */
1842     {20, 20, PT_LINETO | PT_CLOSEFIGURE}, /* 124 */
1843     {30, 30, PT_MOVETO}, /* 125 */
1844     {40, 20, PT_LINETO}, /* 126 */
1845     {20, 30, PT_LINETO}, /* 127 */
1846     {30, 40, PT_LINETO}, /* 128 */
1847     {10, 50, PT_LINETO | PT_CLOSEFIGURE}, /* 129 */
1848     {10, 50, PT_MOVETO}, /* 130 */
1849     {10, 10, PT_BEZIERTO}, /* 131 */
1850     {20, 10, PT_BEZIERTO}, /* 132 */
1851     {10, 20, PT_BEZIERTO}, /* 133 */
1852     {20, 20, PT_BEZIERTO}, /* 134 */
1853     {30, 30, PT_BEZIERTO}, /* 135 */
1854     {40, 20, PT_BEZIERTO}, /* 136 */
1855     {20, 30, PT_BEZIERTO}, /* 137 */
1856     {30, 40, PT_BEZIERTO}, /* 138 */
1857     {10, 50, PT_BEZIERTO}, /* 139 */
1858     {150, 150, PT_LINETO}, /* 140 */
1859 };
1860 
1861 /* run once through all functions that support paths */
test_all_functions(void)1862 static void test_all_functions(void)
1863 {
1864     POINT pts[9] = {{10, 10}, {20, 10}, {10, 20}, {20, 20}, {30, 30}, {40, 20},
1865                     {20, 30}, {30, 40}, {10, 50}};
1866     DWORD counts[5] = {4, 5, 0, 1, 2};
1867     BYTE types[9] = { PT_MOVETO, PT_LINETO, PT_BEZIERTO, PT_BEZIERTO, PT_BEZIERTO, PT_LINETO,
1868                       PT_LINETO | PT_CLOSEFIGURE, PT_MOVETO, PT_LINETO };
1869     HDC hdc = GetDC( 0 );
1870 
1871     BeginPath( hdc );
1872     LineTo( hdc, 50, 150 );
1873     MoveToEx( hdc, 50, 50, NULL );
1874     LineTo( hdc, 150, 150 );
1875     LineTo( hdc, 150, 50 );
1876     LineTo( hdc, 50, 50 );
1877     AngleArc( hdc, 37, 36, 23, 90, 180 );
1878     Polyline( hdc, pts, 4 );
1879     Arc( hdc, 21, 21, 39, 29, 39, 29, 21, 21 );
1880     PolylineTo( hdc, pts, 4 );
1881     ArcTo( hdc, 23, 23, 37, 27, 37, 27, 23, 23 );
1882     PolyPolyline( hdc, pts, counts, 2 );
1883     Chord( hdc, 42, 43, 57, 66, 39, 29, 21, 21 );
1884     PolyDraw( hdc, pts, types, 9 );
1885     Pie( hdc, 52, 54, 65, 68, 39, 29, 21, 21 );
1886     Polygon( hdc, pts, 9 );
1887     Ellipse( hdc, 22, 33, 44, 66 );
1888     Rectangle( hdc, 60, 70, 80, 90 );
1889     RoundRect( hdc, 100, 100, 200, 200, 35, 45 );
1890     PolyBezier( hdc, pts, 7 );
1891     PolyPolygon( hdc, pts, (int *)counts, 2 );
1892     PolyBezierTo( hdc, pts, 9 );
1893     LineTo( hdc, 150, 150 );
1894     /* FIXME: ExtTextOut */
1895     EndPath( hdc );
1896     ok_path( hdc, "all_funcs_path", all_funcs_path, sizeof(all_funcs_path)/sizeof(path_test_t) );
1897     ReleaseDC( 0, hdc );
1898 }
1899 
START_TEST(path)1900 START_TEST(path)
1901 {
1902     test_path_state();
1903     test_widenpath();
1904     test_arcto();
1905     test_anglearc();
1906     test_polydraw();
1907     test_closefigure();
1908     test_linedda();
1909     test_rectangle();
1910     test_roundrect();
1911     test_ellipse();
1912     test_all_functions();
1913 }
1914