ReactOS  0.4.14-dev-599-g2d4d3f5
path.c
Go to the documentation of this file.
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 
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;
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 );
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 );
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 );
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 );
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 );
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 );
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 );
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 
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;
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  */
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 
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 
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)
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 
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 
483 static void test_arcto(void)
484 {
485  HDC hdc = GetDC(0);
486 
487  BeginPath(hdc);
489  if (!ArcTo(hdc, 200, 200, 400, 300, 200, 200, 400, 300) &&
491  {
492  /* ArcTo is only available on Win2k and later */
493  win_skip("ArcTo is not available\n");
494  goto done;
495  }
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 
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) &&
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 */
600  PT_MOVETO, PT_LINETO, /* 8 */
603  PT_LINETO, PT_MOVETO | PT_CLOSEFIGURE, /* 17 */
605  PT_LINETO, PT_MOVETO | PT_LINETO, PT_LINETO, /* 23 */
607 
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);
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)) &&
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);
630  ok( pos.x == 10 && pos.y == 15, "wrong pos %d,%d\n", pos.x, pos.y );
631  LineTo(hdc, -10, -10);
633  ok( pos.x == -10 && pos.y == -10, "wrong pos %d,%d\n", pos.x, pos.y );
634 
635  MoveToEx(hdc, 100, 100, NULL);
637  ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
638  LineTo(hdc, 95, 95);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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));
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 
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 );
701  ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
702 
703  BeginPath(hdc);
705  ok( pos.x == 100 && pos.y == 100, "wrong pos %d,%d\n", pos.x, pos.y );
706  MoveToEx(hdc, 95, 95, NULL);
708  ok( pos.x == 95 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
709  LineTo(hdc, 95, 0);
711  ok( pos.x == 95 && pos.y == 0, "wrong pos %d,%d\n", pos.x, pos.y );
712  LineTo(hdc, 0, 95);
714  ok( pos.x == 0 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
715 
716  CloseFigure(hdc);
718  ok( pos.x == 0 && pos.y == 95, "wrong pos %d,%d\n", pos.x, pos.y );
719  EndPath(hdc);
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 
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 
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 
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 );
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 );
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 );
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 );
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 );
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 
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 );
1305  RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1306  RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
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 );
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 );
1328  RoundRect( hdc, 20, 20, 40, 40, 10, 10 );
1329  RoundRect( hdc, 30, 50, 55, 35, -30, -30 );
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 
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 );
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 );
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 );
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 );
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 );
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 */
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};
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 
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();
1913 }
BOOL WINAPI PolyDraw(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_reads_(cpt) const BYTE *aj, _In_ int cpt)
BOOL WINAPI GetCurrentPositionEx(_In_ HDC, _Out_ LPPOINT)
Definition: coord.c:241
#define TRUE
Definition: types.h:120
BOOL WINAPI SelectClipPath(HDC hdc, int iMode)
Definition: path.c:191
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
static const path_test_t anglearc_path[]
Definition: path.c:506
BOOL WINAPI SetWindowExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1475
START_TEST(path)
Definition: path.c:1900
long y
Definition: polytest.cpp:48
static void test_polydraw(void)
Definition: path.c:608
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
static const path_test_t all_funcs_path[]
Definition: path.c:1716
long x
Definition: polytest.cpp:48
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
static void test_widenpath(void)
Definition: path.c:311
#define pt(x, y)
Definition: drawing.c:79
BOOL WINAPI StrokeAndFillPath(HDC hdc)
Definition: path.c:153
static const path_test_t arcto_path[]
Definition: path.c:458
static void test_ellipse(void)
Definition: path.c:1666
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2031
static const path_test_t polydraw_path[]
Definition: path.c:551
static HDC
Definition: imagelist.c:92
GLsizei GLenum GLenum * types
Definition: glext.h:7753
BOOL WINAPI CloseFigure(HDC hdc)
Definition: path.c:43
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
BOOL WINAPI Chord(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xRadial1, _In_ INT yRadial1, _In_ INT xRadial2, _In_ INT yRadial2)
Definition: arc.c:119
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
static const path_test_t ellipse_path[]
Definition: path.c:1337
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static void test_closefigure(void)
Definition: path.c:694
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
BOOL WINAPI PolylineTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:354
static void test_rectangle(void)
Definition: path.c:925
#define expect(expected, got)
Definition: path.c:34
static void ok_path(HDC hdc, const char *path_name, const path_test_t *expected, int expected_size)
Definition: path.c:401
static void test_linedda(void)
Definition: path.c:750
BYTE type
Definition: path.c:383
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
int winetest_debug
int32_t INT
Definition: typedefs.h:56
DWORD ret
Definition: path.c:47
#define AD_COUNTERCLOCKWISE
Definition: wingdi.h:666
BOOL WINAPI BeginPath(HDC hdc)
Definition: path.c:31
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
#define PS_SOLID
Definition: wingdi.h:585
static const path_test_t roundrect_path[]
Definition: path.c:976
static BYTE polydraw_tps[]
Definition: path.c:597
BOOL WINAPI PolyBezierTo(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:281
BOOL WINAPI RoundRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
unsigned int BOOL
Definition: ntddk_ex.h:94
int WINAPI SetMapMode(_In_ HDC, _In_ int)
BOOL WINAPI Arc(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xStartArc, _In_ INT yStartArc, _In_ INT xEndArc, _In_ INT yEndArc)
Definition: arc.c:5
#define ERROR_CAN_NOT_COMPLETE
Definition: winerror.h:582
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
DWORD biCompression
Definition: amvideo.idl:35
unsigned int idx
Definition: utils.c:41
static void test_roundrect(void)
Definition: path.c:1292
smooth NULL
Definition: ftsmooth.c:416
#define RGN_OR
Definition: wingdi.h:358
LONG_PTR LPARAM
Definition: windef.h:208
#define AD_CLOCKWISE
Definition: wingdi.h:667
static void test_all_functions(void)
Definition: path.c:1862
int WINAPI SetArcDirection(_In_ HDC, _In_ int)
BOOL WINAPI PolyPolygon(_In_ HDC hdc, _In_ const POINT *apt, _In_reads_(csz) const INT *asz, _In_ int csz)
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
Definition: cmds.c:130
BOOL WINAPI Pie(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int, _In_ int)
BOOL WINAPI WidenPath(HDC hdc)
Definition: path.c:179
INT WINAPI GetPath(HDC hdc, LPPOINT pptlBuf, LPBYTE pjTypes, INT cptBuf)
Definition: path.c:95
static char * path_name(DOS_FILE *file)
Definition: check.c:208
HRGN WINAPI PathToRegion(HDC hdc)
Definition: path.c:120
#define RGB(r, g, b)
Definition: wingdi.h:2939
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI FillPath(HDC hdc)
Definition: path.c:69
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
BOOL WINAPI StrokePath(HDC hdc)
Definition: path.c:166
HDC hdc
Definition: main.c:9
#define MM_ANISOTROPIC
Definition: wingdi.h:866
BOOL WINAPI LineDDA(_In_ int, _In_ int, _In_ int, _In_ int, _In_ LINEDDAPROC, _In_opt_ LPARAM)
unsigned char BYTE
Definition: mem.h:68
BOOL WINAPI PolyPolyline(_In_ HDC hdc, _In_ const POINT *apt, _In_reads_(csz) const DWORD *asz, _In_ DWORD csz)
#define broken(x)
Definition: _sntprintf.h:21
BOOL WINAPI EndPath(HDC hdc)
Definition: path.c:56
static POINT polydraw_pts[]
Definition: path.c:586
static void test_anglearc(void)
Definition: path.c:531
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI Ellipse(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define ros_skip_flaky
Definition: test.h:167
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:197
#define ok(value,...)
Definition: atltest.h:57
#define min(a, b)
Definition: monoChain.cc:55
int WINAPI SaveDC(_In_ HDC)
static const BYTE dib[]
Definition: ole2.c:201
static void test_arcto(void)
Definition: path.c:483
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
BOOL WINAPI PolyBezier(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ DWORD cpt)
Definition: painting.c:263
static void WINAPI linedda_callback(INT x, INT y, LPARAM lparam)
Definition: path.c:740
BOOL WINAPI FlattenPath(HDC hdc)
Definition: path.c:82
#define MM_TEXT
Definition: wingdi.h:872
#define PT_CLOSEFIGURE
Definition: wingdi.h:886
#define PT_LINETO
Definition: wingdi.h:884
BOOL WINAPI Polyline(_In_ HDC hdc, _In_reads_(cpt) const POINT *apt, _In_ int cpt)
#define PT_MOVETO
Definition: wingdi.h:883
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:92
static HBITMAP
Definition: button.c:44
BOOL WINAPI SetViewportExtEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPSIZE)
Definition: coord.c:465
#define PT_BEZIERTO
Definition: wingdi.h:885
static void test_path_state(void)
Definition: path.c:36
#define DIB_RGB_COLORS
Definition: wingdi.h:366
int y
Definition: path.c:382
#define memset(x, y, z)
Definition: compat.h:39
int WINAPI SetGraphicsMode(_In_ HDC, _In_ int)
Definition: dc.c:1202
BOOL WINAPI RestoreDC(_In_ HDC, _In_ int)
#define win_skip
Definition: test.h:150
#define BI_RGB
Definition: precomp.h:34
#define HeapFree(x, y, z)
Definition: compat.h:402
static const path_test_t rectangle_path[]
Definition: path.c:821
BOOL WINAPI AngleArc(_In_ HDC hdc, _In_ INT x, _In_ INT y, _In_ DWORD dwRadius, _In_ FLOAT eStartAngle, _In_ FLOAT eSweepAngle)
Definition: arc.c:49
BOOL WINAPI AbortPath(HDC hdc)
Definition: path.c:18
BOOL expected
Definition: store.c:2063
#define printf
Definition: config.h:203
struct tagBITMAPINFO BITMAPINFO
#define GM_ADVANCED
Definition: wingdi.h:864
BOOL WINAPI ArcTo(_In_ HDC hdc, _In_ INT xLeft, _In_ INT yTop, _In_ INT xRight, _In_ INT yBottom, _In_ INT xRadial1, _In_ INT yRadial1, _In_ INT xRadial2, _In_ INT yRadial2)
Definition: arc.c:79