gdiplus: Add LineCapRoundAnchor path widening.
[wine.git] / dlls / gdiplus / tests / graphicspath.c
blob6acfddd53ef51d046ce7048adc3becff6cdca33a
1 /*
2 * Unit test suite for paths
4 * Copyright (C) 2007 Google (Evan Stade)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "objbase.h"
22 #include "gdiplus.h"
23 #include "wine/test.h"
24 #include <math.h>
26 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
27 #define expectf(expected, got) ok(fabs(expected - got) < 2.0, "Expected %.2f, got %.2f\n", expected, got)
28 #define POINT_TYPE_MAX_LEN (75)
30 static void stringify_point_type(PathPointType type, char * name)
32 *name = '\0';
34 switch(type & PathPointTypePathTypeMask){
35 case PathPointTypeStart:
36 strcat(name, "PathPointTypeStart");
37 break;
38 case PathPointTypeLine:
39 strcat(name, "PathPointTypeLine");
40 break;
41 case PathPointTypeBezier:
42 strcat(name, "PathPointTypeBezier");
43 break;
44 default:
45 strcat(name, "Unknown type");
46 return;
49 type &= ~PathPointTypePathTypeMask;
50 if(type & ~((PathPointTypePathMarker | PathPointTypeCloseSubpath))){
51 *name = '\0';
52 strcat(name, "Unknown type");
53 return;
56 if(type & PathPointTypePathMarker)
57 strcat(name, " | PathPointTypePathMarker");
58 if(type & PathPointTypeCloseSubpath)
59 strcat(name, " | PathPointTypeCloseSubpath");
62 /* this helper structure and function modeled after gdi path.c test */
63 typedef struct
65 REAL X, Y;
66 BYTE type;
68 /* How many extra entries before this one only on wine
69 * but not on native? */
70 int wine_only_entries_preceding;
72 /* 0 - This entry matches on wine.
73 * 1 - This entry corresponds to a single entry on wine that does not match the native entry.
74 * 2 - This entry is currently skipped on wine but present on native. */
75 int todo;
76 } path_test_t;
78 static void ok_path(GpPath* path, const path_test_t *expected, INT expected_size, BOOL todo_size)
80 BYTE * types;
81 INT size, idx = 0, eidx = 0, numskip;
82 GpPointF * points;
83 char ename[POINT_TYPE_MAX_LEN], name[POINT_TYPE_MAX_LEN];
85 if(GdipGetPointCount(path, &size) != Ok){
86 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
87 return;
90 todo_wine_if (todo_size)
91 ok(size == expected_size, "Path size %d does not match expected size %d\n",
92 size, expected_size);
94 points = HeapAlloc(GetProcessHeap(), 0, size * sizeof(GpPointF));
95 types = HeapAlloc(GetProcessHeap(), 0, size);
97 if(GdipGetPathPoints(path, points, size) != Ok || GdipGetPathTypes(path, types, size) != Ok){
98 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
99 goto end;
102 numskip = expected_size ? expected[eidx].wine_only_entries_preceding : 0;
103 while (idx < size && eidx < expected_size){
104 /* We allow a few pixels fudge in matching X and Y coordinates to account for imprecision in
105 * floating point to integer conversion */
106 BOOL match = (types[idx] == expected[eidx].type) &&
107 fabs(points[idx].X - expected[eidx].X) <= 2.0 &&
108 fabs(points[idx].Y - expected[eidx].Y) <= 2.0;
110 stringify_point_type(expected[eidx].type, ename);
111 stringify_point_type(types[idx], name);
113 todo_wine_if (expected[eidx].todo || numskip)
114 ok(match, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx,
115 ename, expected[eidx].X, expected[eidx].Y,
116 name, points[idx].X, points[idx].Y);
118 if (match || expected[eidx].todo != 2)
119 idx++;
120 if (match || !numskip--)
121 numskip = expected[++eidx].wine_only_entries_preceding;
124 end:
125 HeapFree(GetProcessHeap(), 0, types);
126 HeapFree(GetProcessHeap(), 0, points);
129 static void test_constructor_destructor(void)
131 GpStatus status;
132 GpPath* path = NULL;
134 status = GdipCreatePath(FillModeAlternate, &path);
135 expect(Ok, status);
136 ok(path != NULL, "Expected path to be initialized\n");
138 status = GdipDeletePath(NULL);
139 expect(InvalidParameter, status);
141 status = GdipDeletePath(path);
142 expect(Ok, status);
145 static void test_getpathdata(void)
147 GpPath *path;
148 GpPathData data;
149 GpStatus status;
150 INT count;
152 status = GdipCreatePath(FillModeAlternate, &path);
153 expect(Ok, status);
154 status = GdipAddPathLine(path, 5.0, 5.0, 100.0, 50.0);
155 expect(Ok, status);
157 status = GdipGetPointCount(path, &count);
158 expect(Ok, status);
159 expect(2, count);
161 data.Count = count;
162 data.Types = GdipAlloc(sizeof(BYTE) * count);
163 data.Points = GdipAlloc(sizeof(PointF) * count);
165 status = GdipGetPathData(path, &data);
166 expect(Ok, status);
167 expect((data.Points[0].X == 5.0) && (data.Points[0].Y == 5.0) &&
168 (data.Points[1].X == 100.0) && (data.Points[1].Y == 50.0), TRUE);
169 expect((data.Types[0] == PathPointTypeStart) && (data.Types[1] == PathPointTypeLine), TRUE);
171 GdipFree(data.Points);
172 GdipFree(data.Types);
173 GdipDeletePath(path);
176 static path_test_t line2_path[] = {
177 {0.0, 50.0, PathPointTypeStart, 0, 0}, /*0*/
178 {5.0, 45.0, PathPointTypeLine, 0, 0}, /*1*/
179 {0.0, 40.0, PathPointTypeLine, 0, 0}, /*2*/
180 {15.0, 35.0, PathPointTypeLine, 0, 0}, /*3*/
181 {0.0, 30.0, PathPointTypeLine, 0, 0}, /*4*/
182 {25.0, 25.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*5*/
183 {0.0, 20.0, PathPointTypeStart, 0, 0}, /*6*/
184 {35.0, 15.0, PathPointTypeLine, 0, 0}, /*7*/
185 {0.0, 10.0, PathPointTypeLine, 0, 0} /*8*/
188 static void test_line2(void)
190 GpStatus status;
191 GpPath* path;
192 int i;
193 GpPointF line2_points[9];
195 for(i = 0; i < 9; i ++){
196 line2_points[i].X = i * 5.0 * (REAL)(i % 2);
197 line2_points[i].Y = 50.0 - i * 5.0;
200 GdipCreatePath(FillModeAlternate, &path);
201 status = GdipAddPathLine2(path, line2_points, 3);
202 expect(Ok, status);
203 status = GdipAddPathLine2(path, &(line2_points[3]), 3);
204 expect(Ok, status);
205 status = GdipClosePathFigure(path);
206 expect(Ok, status);
207 status = GdipAddPathLine2(path, &(line2_points[6]), 3);
208 expect(Ok, status);
210 ok_path(path, line2_path, ARRAY_SIZE(line2_path), FALSE);
212 GdipDeletePath(path);
215 static path_test_t arc_path[] = {
216 {600.0, 450.0, PathPointTypeStart, 0, 0}, /*0*/
217 {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*1*/
218 {488.1, 800.0, PathPointTypeBezier, 0, 0}, /*2*/
219 {350.0, 800.0, PathPointTypeBezier, 0, 0}, /*3*/
220 {600.0, 450.0, PathPointTypeLine, 0, 0}, /*4*/
221 {600.0, 643.3, PathPointTypeBezier, 0, 0}, /*5*/
222 {488.1, 800.0, PathPointTypeBezier, 0, 0}, /*6*/
223 {350.0, 800.0, PathPointTypeBezier, 0, 0}, /*7*/
224 {329.8, 800.0, PathPointTypeBezier, 0, 0}, /*8*/
225 {309.7, 796.6, PathPointTypeBezier, 0, 0}, /*9*/
226 {290.1, 789.8, PathPointTypeBezier, 0, 0}, /*10*/
227 {409.9, 110.2, PathPointTypeLine, 0, 0}, /*11*/
228 {544.0, 156.5, PathPointTypeBezier, 0, 0}, /*12*/
229 {625.8, 346.2, PathPointTypeBezier, 0, 0}, /*13*/
230 {592.7, 533.9, PathPointTypeBezier, 0, 0}, /*14*/
231 {592.5, 535.3, PathPointTypeBezier, 0, 0}, /*15*/
232 {592.2, 536.7, PathPointTypeBezier, 0, 0}, /*16*/
233 {592.0, 538.1, PathPointTypeBezier, 0, 0}, /*17*/
234 {409.9, 789.8, PathPointTypeLine, 0, 0}, /*18*/
235 {544.0, 743.5, PathPointTypeBezier, 0, 0}, /*19*/
236 {625.8, 553.8, PathPointTypeBezier, 0, 0}, /*20*/
237 {592.7, 366.1, PathPointTypeBezier, 0, 0}, /*21*/
238 {592.5, 364.7, PathPointTypeBezier, 0, 0}, /*22*/
239 {592.2, 363.3, PathPointTypeBezier, 0, 0}, /*23*/
240 {592.0, 361.9, PathPointTypeBezier, 0, 0}, /*24*/
241 {540.4, 676.9, PathPointTypeLine, 0, 0}, /*25*/
242 {629.9, 529.7, PathPointTypeBezier, 0, 0}, /*26*/
243 {617.2, 308.8, PathPointTypeBezier, 0, 0}, /*27*/
244 {512.1, 183.5, PathPointTypeBezier, 0, 0}, /*28*/
245 {406.9, 58.2, PathPointTypeBezier, 0, 0}, /*29*/
246 {249.1, 75.9, PathPointTypeBezier, 0, 0}, /*30*/
247 {159.6, 223.1, PathPointTypeBezier, 0, 0}, /*31*/
248 {70.1, 370.3, PathPointTypeBezier, 0, 0}, /*32*/
249 {82.8, 591.2, PathPointTypeBezier, 0, 0}, /*33*/
250 {187.9, 716.5, PathPointTypeBezier, 0, 0}, /*34*/
251 {293.1, 841.8, PathPointTypeBezier, 0, 0}, /*35*/
252 {450.9, 824.1, PathPointTypeBezier, 0, 0}, /*36*/
253 {540.4, 676.9, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 1} /*37*/
256 static void test_arc(void)
258 GpStatus status;
259 GpPath* path;
261 GdipCreatePath(FillModeAlternate, &path);
262 /* Exactly 90 degrees */
263 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
264 expect(Ok, status);
265 /* Over 90 degrees */
266 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
267 expect(Ok, status);
268 /* Negative start angle */
269 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
270 expect(Ok, status);
271 /* Negative sweep angle */
272 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 80.0, -100.0);
273 expect(Ok, status);
274 /* More than a full revolution */
275 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 50.0, -400.0);
276 expect(Ok, status);
277 /* 0 sweep angle */
278 status = GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 50.0, 0.0);
279 expect(Ok, status);
281 ok_path(path, arc_path, ARRAY_SIZE(arc_path), FALSE);
283 GdipDeletePath(path);
286 static void test_worldbounds(void)
288 GpStatus status;
289 GpPath *path;
290 GpPen *pen;
291 GpMatrix *matrix;
292 GpRectF bounds;
293 GpPointF line2_points[10];
294 int i;
296 for(i = 0; i < 10; i ++){
297 line2_points[i].X = 200.0 + i * 50.0 * (i % 2);
298 line2_points[i].Y = 200.0 + i * 50.0 * !(i % 2);
300 GdipCreatePen1((ARGB)0xdeadbeef, 20.0, UnitWorld, &pen);
301 GdipSetPenEndCap(pen, LineCapSquareAnchor);
302 GdipCreateMatrix2(1.5, 0.0, 1.0, 1.2, 10.4, 10.2, &matrix);
304 GdipCreatePath(FillModeAlternate, &path);
305 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
306 GdipAddPathLine2(path, &(line2_points[0]), 10);
307 status = GdipGetPathWorldBounds(path, &bounds, NULL, NULL);
308 expect(Ok, status);
309 GdipDeletePath(path);
311 expectf(200.0, bounds.X);
312 expectf(200.0, bounds.Y);
313 expectf(450.0, bounds.Width);
314 expectf(600.0, bounds.Height);
316 GdipCreatePath(FillModeAlternate, &path);
317 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
318 GdipAddPathLine2(path, &(line2_points[0]), 10);
319 status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL);
320 expect(Ok, status);
321 GdipDeletePath(path);
323 expectf(510.4, bounds.X);
324 expectf(250.2, bounds.Y);
325 expectf(1275.0, bounds.Width);
326 expectf(720.0, bounds.Height);
328 GdipCreatePath(FillModeAlternate, &path);
329 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
330 GdipAddPathLine2(path, &(line2_points[0]), 10);
331 status = GdipGetPathWorldBounds(path, &bounds, NULL, pen);
332 expect(Ok, status);
333 GdipDeletePath(path);
335 expectf(100.0, bounds.X);
336 expectf(100.0, bounds.Y);
337 expectf(650.0, bounds.Width);
338 expectf(800.0, bounds.Height);
340 GdipCreatePath(FillModeAlternate, &path);
341 GdipAddPathLine2(path, &(line2_points[0]), 2);
342 status = GdipGetPathWorldBounds(path, &bounds, NULL, pen);
343 expect(Ok, status);
344 GdipDeletePath(path);
346 expectf(156.0, bounds.X);
347 expectf(156.0, bounds.Y);
348 expectf(138.0, bounds.Width);
349 expectf(88.0, bounds.Height);
351 line2_points[2].X = 2 * line2_points[1].X - line2_points[0].X;
352 line2_points[2].Y = 2 * line2_points[1].Y - line2_points[0].Y;
354 GdipCreatePath(FillModeAlternate, &path);
355 GdipAddPathLine2(path, &(line2_points[0]), 3);
356 status = GdipGetPathWorldBounds(path, &bounds, NULL, pen);
357 expect(Ok, status);
358 GdipDeletePath(path);
360 expectf(100.0, bounds.X);
361 expectf(100.0, bounds.Y);
362 expectf(300.0, bounds.Width);
363 expectf(200.0, bounds.Height);
365 GdipCreatePath(FillModeAlternate, &path);
366 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 45.0, 20.0);
367 status = GdipGetPathWorldBounds(path, &bounds, NULL, pen);
368 expect(Ok, status);
369 GdipDeletePath(path);
371 expectf(386.7, bounds.X);
372 expectf(553.4, bounds.Y);
373 expectf(266.8, bounds.Width);
374 expectf(289.6, bounds.Height);
376 GdipCreatePath(FillModeAlternate, &path);
377 status = GdipGetPathWorldBounds(path, &bounds, matrix, pen);
378 expect(Ok, status);
379 GdipDeletePath(path);
381 expectf(0.0, bounds.X);
382 expectf(0.0, bounds.Y);
383 expectf(0.0, bounds.Width);
384 expectf(0.0, bounds.Height);
386 GdipCreatePath(FillModeAlternate, &path);
387 GdipAddPathLine2(path, &(line2_points[0]), 2);
388 status = GdipGetPathWorldBounds(path, &bounds, matrix, pen);
389 expect(Ok, status);
390 GdipDeletePath(path);
392 todo_wine{
393 expectf(427.9, bounds.X);
394 expectf(167.7, bounds.Y);
395 expectf(239.9, bounds.Width);
396 expectf(164.9, bounds.Height);
399 GdipDeleteMatrix(matrix);
400 GdipCreateMatrix2(0.9, -0.5, -0.5, -1.2, 10.4, 10.2, &matrix);
401 GdipCreatePath(FillModeAlternate, &path);
402 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
403 GdipAddPathLine2(path, &(line2_points[0]), 10);
404 status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL);
405 expect(Ok, status);
406 GdipDeletePath(path);
407 GdipDeleteMatrix(matrix);
409 expectf(-209.6, bounds.X);
410 expectf(-1274.8, bounds.Y);
411 expectf(705.0, bounds.Width);
412 expectf(945.0, bounds.Height);
414 GdipDeletePen(pen);
417 static path_test_t pathpath_path[] = {
418 {600.00, 450.00, PathPointTypeStart, 0, 0}, /*0*/
419 {600.00, 643.30, PathPointTypeBezier, 0, 0}, /*1*/
420 {488.07, 800.00, PathPointTypeBezier, 0, 0}, /*2*/
421 {350.00, 800.00, PathPointTypeBezier, 0, 0}, /*3*/
422 {319.61, 797.40, PathPointTypeStart, 0, 0}, /*4*/
423 {182.56, 773.90, PathPointTypeBezier, 0, 0}, /*5*/
424 {85.07, 599.31, PathPointTypeBezier, 0, 0}, /*6*/
425 {101.85, 407.45, PathPointTypeBezier, 0, 0}, /*7*/
426 {102.54, 399.66, PathPointTypeBezier, 0, 0}, /*8*/
427 {103.40, 391.91, PathPointTypeBezier, 0, 0}, /*9*/
428 {104.46, 384.21, PathPointTypeBezier, 0, 0}, /*10*/
429 {409.92, 110.20, PathPointTypeLine, 0, 0}, /*11*/
430 {543.96, 156.53, PathPointTypeBezier, 0, 0}, /*12*/
431 {625.80, 346.22, PathPointTypeBezier, 0, 0}, /*13*/
432 {592.71, 533.88, PathPointTypeBezier, 0, 0}, /*14*/
433 {592.47, 535.28, PathPointTypeBezier, 0, 0}, /*15*/
434 {592.22, 536.67, PathPointTypeBezier, 0, 0}, /*16*/
435 {591.96, 538.06, PathPointTypeBezier, 0, 0}, /*17*/
436 {319.61, 797.40, PathPointTypeLine, 0, 0}, /*18*/
437 {182.56, 773.90, PathPointTypeBezier, 0, 0}, /*19*/
438 {85.07, 599.31, PathPointTypeBezier, 0, 0}, /*20*/
439 {101.85, 407.45, PathPointTypeBezier, 0, 0}, /*21*/
440 {102.54, 399.66, PathPointTypeBezier, 0, 0}, /*22*/
441 {103.40, 391.91, PathPointTypeBezier, 0, 0}, /*23*/
442 {104.46, 384.21, PathPointTypeBezier, 0, 0} /*24*/
445 static void test_pathpath(void)
447 GpStatus status;
448 GpPath* path1, *path2;
450 GdipCreatePath(FillModeAlternate, &path2);
451 GdipAddPathArc(path2, 100.0, 100.0, 500.0, 700.0, 95.0, 100.0);
453 GdipCreatePath(FillModeAlternate, &path1);
454 GdipAddPathArc(path1, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
455 status = GdipAddPathPath(path1, path2, FALSE);
456 expect(Ok, status);
457 GdipAddPathArc(path1, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
458 status = GdipAddPathPath(path1, path2, TRUE);
459 expect(Ok, status);
461 ok_path(path1, pathpath_path, ARRAY_SIZE(pathpath_path), FALSE);
463 GdipDeletePath(path1);
464 GdipDeletePath(path2);
467 static path_test_t ellipse_path[] = {
468 {30.00, 125.25, PathPointTypeStart, 0, 0}, /*0*/
469 {30.00, 139.20, PathPointTypeBezier, 0, 0}, /*1*/
470 {25.52, 150.50, PathPointTypeBezier, 0, 0}, /*2*/
471 {20.00, 150.50, PathPointTypeBezier, 0, 0}, /*3*/
472 {14.48, 150.50, PathPointTypeBezier, 0, 0}, /*4*/
473 {10.00, 139.20, PathPointTypeBezier, 0, 0}, /*5*/
474 {10.00, 125.25, PathPointTypeBezier, 0, 0}, /*6*/
475 {10.00, 111.30, PathPointTypeBezier, 0, 0}, /*7*/
476 {14.48, 100.00, PathPointTypeBezier, 0, 0}, /*8*/
477 {20.00, 100.00, PathPointTypeBezier, 0, 0}, /*9*/
478 {25.52, 100.00, PathPointTypeBezier, 0, 0}, /*10*/
479 {30.00, 111.30, PathPointTypeBezier, 0, 0}, /*11*/
480 {30.00, 125.25, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0}, /*12*/
481 {7.00, 11.00, PathPointTypeStart, 0, 0}, /*13*/
482 {13.00, 17.00, PathPointTypeLine, 0, 0}, /*14*/
483 {5.00, 195.00, PathPointTypeStart, 0, 0}, /*15*/
484 {5.00, 192.24, PathPointTypeBezier, 0, 0}, /*16*/
485 {6.12, 190.00, PathPointTypeBezier, 0, 0}, /*17*/
486 {7.50, 190.00, PathPointTypeBezier, 0, 0}, /*18*/
487 {8.88, 190.00, PathPointTypeBezier, 0, 0}, /*19*/
488 {10.00, 192.24, PathPointTypeBezier, 0, 0}, /*20*/
489 {10.00, 195.00, PathPointTypeBezier, 0, 0}, /*21*/
490 {10.00, 197.76, PathPointTypeBezier, 0, 0}, /*22*/
491 {8.88, 200.00, PathPointTypeBezier, 0, 0}, /*23*/
492 {7.50, 200.00, PathPointTypeBezier, 0, 0}, /*24*/
493 {6.12, 200.00, PathPointTypeBezier, 0, 0}, /*25*/
494 {5.00, 197.76, PathPointTypeBezier, 0, 0}, /*26*/
495 {5.00, 195.00, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0}, /*27*/
496 {10.00, 300.50, PathPointTypeStart, 0, 0}, /*28*/
497 {10.00, 300.78, PathPointTypeBezier, 0, 0}, /*29*/
498 {10.00, 301.00, PathPointTypeBezier, 0, 0}, /*30*/
499 {10.00, 301.00, PathPointTypeBezier, 0, 0}, /*31*/
500 {10.00, 301.00, PathPointTypeBezier, 0, 0}, /*32*/
501 {10.00, 300.78, PathPointTypeBezier, 0, 0}, /*33*/
502 {10.00, 300.50, PathPointTypeBezier, 0, 0}, /*34*/
503 {10.00, 300.22, PathPointTypeBezier, 0, 0}, /*35*/
504 {10.00, 300.00, PathPointTypeBezier, 0, 0}, /*36*/
505 {10.00, 300.00, PathPointTypeBezier, 0, 0}, /*37*/
506 {10.00, 300.00, PathPointTypeBezier, 0, 0}, /*38*/
507 {10.00, 300.22, PathPointTypeBezier, 0, 0}, /*39*/
508 {10.00, 300.50, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0} /*40*/
511 static void test_ellipse(void)
513 GpStatus status;
514 GpPath *path;
515 GpPointF points[2];
517 points[0].X = 7.0;
518 points[0].Y = 11.0;
519 points[1].X = 13.0;
520 points[1].Y = 17.0;
522 GdipCreatePath(FillModeAlternate, &path);
523 status = GdipAddPathEllipse(path, 10.0, 100.0, 20.0, 50.5);
524 expect(Ok, status);
525 GdipAddPathLine2(path, points, 2);
526 status = GdipAddPathEllipse(path, 10.0, 200.0, -5.0, -10.0);
527 expect(Ok, status);
528 GdipClosePathFigure(path);
529 status = GdipAddPathEllipse(path, 10.0, 300.0, 0.0, 1.0);
530 expect(Ok, status);
532 ok_path(path, ellipse_path, ARRAY_SIZE(ellipse_path), FALSE);
534 GdipDeletePath(path);
537 static path_test_t linei_path[] = {
538 {5.00, 5.00, PathPointTypeStart, 0, 0}, /*0*/
539 {6.00, 8.00, PathPointTypeLine, 0, 0}, /*1*/
540 {409.92, 110.20, PathPointTypeLine, 0, 0}, /*2*/
541 {543.96, 156.53, PathPointTypeBezier, 0, 0}, /*3*/
542 {625.80, 346.22, PathPointTypeBezier, 0, 0}, /*4*/
543 {592.71, 533.88, PathPointTypeBezier, 0, 0}, /*5*/
544 {592.47, 535.28, PathPointTypeBezier, 0, 0}, /*6*/
545 {592.22, 536.67, PathPointTypeBezier, 0, 0}, /*7*/
546 {591.96, 538.06, PathPointTypeBezier, 0, 0}, /*8*/
547 {15.00, 15.00, PathPointTypeLine, 0, 0}, /*9*/
548 {26.00, 28.00, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*10*/
549 {35.00, 35.00, PathPointTypeStart, 0, 0}, /*11*/
550 {36.00, 38.00, PathPointTypeLine, 0, 0} /*12*/
553 static void test_linei(void)
555 GpStatus status;
556 GpPath *path;
558 GdipCreatePath(FillModeAlternate, &path);
559 status = GdipAddPathLineI(path, 5.0, 5.0, 6.0, 8.0);
560 expect(Ok, status);
561 GdipAddPathArc(path, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
562 status = GdipAddPathLineI(path, 15.0, 15.0, 26.0, 28.0);
563 expect(Ok, status);
564 GdipClosePathFigure(path);
565 status = GdipAddPathLineI(path, 35.0, 35.0, 36.0, 38.0);
566 expect(Ok, status);
568 ok_path(path, linei_path, ARRAY_SIZE(linei_path), FALSE);
570 GdipDeletePath(path);
573 static path_test_t poly_path[] = {
574 {5.00, 5.00, PathPointTypeStart, 0, 0}, /*1*/
575 {6.00, 8.00, PathPointTypeLine, 0, 0}, /*2*/
576 {0.00, 0.00, PathPointTypeStart, 0, 0}, /*3*/
577 {10.00, 10.00, PathPointTypeLine, 0, 0}, /*4*/
578 {10.00, 20.00, PathPointTypeLine, 0, 0}, /*5*/
579 {30.00, 10.00, PathPointTypeLine, 0, 0}, /*6*/
580 {20.00, 0.00, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*7*/
583 static void test_polygon(void)
585 GpStatus status;
586 GpPath *path;
587 GpPointF points[5];
589 points[0].X = 0.0;
590 points[0].Y = 0.0;
591 points[1].X = 10.0;
592 points[1].Y = 10.0;
593 points[2].X = 10.0;
594 points[2].Y = 20.0;
595 points[3].X = 30.0;
596 points[3].Y = 10.0;
597 points[4].X = 20.0;
598 points[4].Y = 0.0;
600 GdipCreatePath(FillModeAlternate, &path);
602 /* NULL args */
603 status = GdipAddPathPolygon(NULL, points, 5);
604 expect(InvalidParameter, status);
605 status = GdipAddPathPolygon(path, NULL, 5);
606 expect(InvalidParameter, status);
607 /* Polygon should have 3 points at least */
608 status = GdipAddPathPolygon(path, points, 2);
609 expect(InvalidParameter, status);
611 /* to test how it prolongs not empty path */
612 status = GdipAddPathLine(path, 5.0, 5.0, 6.0, 8.0);
613 expect(Ok, status);
614 status = GdipAddPathPolygon(path, points, 5);
615 expect(Ok, status);
616 /* check resulting path */
617 ok_path(path, poly_path, ARRAY_SIZE(poly_path), FALSE);
619 GdipDeletePath(path);
622 static path_test_t rect_path[] = {
623 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
624 {105.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
625 {105.0, 55.0, PathPointTypeLine, 0, 0}, /*2*/
626 {5.0, 55.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0}, /*3*/
628 {100.0, 50.0, PathPointTypeStart, 0, 0}, /*4*/
629 {220.0, 50.0, PathPointTypeLine, 0, 0}, /*5*/
630 {220.0, 80.0, PathPointTypeLine, 0, 0}, /*6*/
631 {100.0, 80.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0} /*7*/
634 static void test_rect(void)
636 GpStatus status;
637 GpPath *path;
638 GpRectF rects[2];
640 GdipCreatePath(FillModeAlternate, &path);
641 status = GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
642 expect(Ok, status);
643 status = GdipAddPathRectangle(path, 100.0, 50.0, 120.0, 30.0);
644 expect(Ok, status);
646 ok_path(path, rect_path, ARRAY_SIZE(rect_path), FALSE);
648 GdipDeletePath(path);
650 GdipCreatePath(FillModeAlternate, &path);
652 rects[0].X = 5.0;
653 rects[0].Y = 5.0;
654 rects[0].Width = 100.0;
655 rects[0].Height = 50.0;
656 rects[1].X = 100.0;
657 rects[1].Y = 50.0;
658 rects[1].Width = 120.0;
659 rects[1].Height = 30.0;
661 status = GdipAddPathRectangles(path, (GDIPCONST GpRectF*)&rects, 2);
662 expect(Ok, status);
664 ok_path(path, rect_path, ARRAY_SIZE(rect_path), FALSE);
666 GdipDeletePath(path);
669 static void test_lastpoint(void)
671 GpStatus status;
672 GpPath *path;
673 GpPointF ptf;
675 GdipCreatePath(FillModeAlternate, &path);
676 status = GdipAddPathRectangle(path, 5.0, 5.0, 100.0, 50.0);
677 expect(Ok, status);
679 /* invalid args */
680 status = GdipGetPathLastPoint(NULL, &ptf);
681 expect(InvalidParameter, status);
682 status = GdipGetPathLastPoint(path, NULL);
683 expect(InvalidParameter, status);
684 status = GdipGetPathLastPoint(NULL, NULL);
685 expect(InvalidParameter, status);
687 status = GdipGetPathLastPoint(path, &ptf);
688 expect(Ok, status);
689 expect(TRUE, (ptf.X == 5.0) && (ptf.Y == 55.0));
691 GdipDeletePath(path);
694 static path_test_t addcurve_path[] = {
695 {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/
696 {3.3, 3.3, PathPointTypeBezier, 0, 0}, /*1*/
697 {6.7, 3.3, PathPointTypeBezier, 0, 0}, /*2*/
698 {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*3*/
699 {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*4*/
700 {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*5*/
701 {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*6*/
702 {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*7*/
703 {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*8*/
704 {30.0, 10.0, PathPointTypeBezier, 0, 0} /*9*/
706 static path_test_t addcurve_path2[] = {
707 {100.0,120.0,PathPointTypeStart, 0, 0}, /*0*/
708 {123.0,10.0, PathPointTypeLine, 0, 0}, /*1*/
709 {0.0, 0.0, PathPointTypeLine, 0, 0}, /*2*/
710 {3.3, 3.3, PathPointTypeBezier, 0, 0}, /*3*/
711 {6.7, 3.3, PathPointTypeBezier, 0, 0}, /*4*/
712 {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*5*/
713 {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*6*/
714 {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*7*/
715 {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*8*/
716 {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*9*/
717 {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*10*/
718 {30.0, 10.0, PathPointTypeBezier, 0, 0} /*11*/
720 static path_test_t addcurve_path3[] = {
721 {10.0, 10.0, PathPointTypeStart, 0, 0}, /*0*/
722 {13.3, 16.7, PathPointTypeBezier, 0, 1}, /*1*/
723 {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*2*/
724 {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*3*/
725 {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*4*/
726 {23.3, 13.3, PathPointTypeBezier, 0, 0}, /*5*/
727 {30.0, 10.0, PathPointTypeBezier, 0, 0} /*6*/
729 static void test_addcurve(void)
731 GpStatus status;
732 GpPath *path;
733 GpPointF points[4];
735 points[0].X = 0.0;
736 points[0].Y = 0.0;
737 points[1].X = 10.0;
738 points[1].Y = 10.0;
739 points[2].X = 10.0;
740 points[2].Y = 20.0;
741 points[3].X = 30.0;
742 points[3].Y = 10.0;
744 GdipCreatePath(FillModeAlternate, &path);
746 /* NULL args */
747 status = GdipAddPathCurve2(NULL, NULL, 0, 0.0);
748 expect(InvalidParameter, status);
749 status = GdipAddPathCurve2(path, NULL, 0, 0.0);
750 expect(InvalidParameter, status);
751 status = GdipAddPathCurve2(path, points, -1, 0.0);
752 expect(InvalidParameter, status);
753 status = GdipAddPathCurve2(path, points, 1, 1.0);
754 expect(InvalidParameter, status);
756 /* add to empty path */
757 status = GdipAddPathCurve2(path, points, 4, 1.0);
758 expect(Ok, status);
759 ok_path(path, addcurve_path, ARRAY_SIZE(addcurve_path), FALSE);
760 GdipDeletePath(path);
762 /* add to notempty path and opened figure */
763 GdipCreatePath(FillModeAlternate, &path);
764 GdipAddPathLine(path, 100.0, 120.0, 123.0, 10.0);
765 status = GdipAddPathCurve2(path, points, 4, 1.0);
766 expect(Ok, status);
767 ok_path(path, addcurve_path2, ARRAY_SIZE(addcurve_path2), FALSE);
769 /* NULL args */
770 GdipResetPath(path);
771 status = GdipAddPathCurve3(NULL, NULL, 0, 0, 0, 0.0);
772 expect(InvalidParameter, status);
773 status = GdipAddPathCurve3(path, NULL, 0, 0, 0, 0.0);
774 expect(InvalidParameter, status);
775 /* wrong count, offset.. */
776 status = GdipAddPathCurve3(path, points, 0, 0, 0, 0.0);
777 expect(InvalidParameter, status);
778 status = GdipAddPathCurve3(path, points, 4, 0, 0, 0.0);
779 expect(InvalidParameter, status);
780 status = GdipAddPathCurve3(path, points, 4, 0, 4, 0.0);
781 expect(InvalidParameter, status);
782 status = GdipAddPathCurve3(path, points, 4, 1, 3, 0.0);
783 expect(InvalidParameter, status);
784 status = GdipAddPathCurve3(path, points, 4, 1, 0, 0.0);
785 expect(InvalidParameter, status);
786 status = GdipAddPathCurve3(path, points, 4, 3, 1, 0.0);
787 expect(InvalidParameter, status);
789 /* use all points */
790 status = GdipAddPathCurve3(path, points, 4, 0, 3, 1.0);
791 expect(Ok, status);
792 ok_path(path, addcurve_path, ARRAY_SIZE(addcurve_path), FALSE);
793 GdipResetPath(path);
795 status = GdipAddPathCurve3(path, points, 4, 1, 2, 1.0);
796 expect(Ok, status);
797 ok_path(path, addcurve_path3, ARRAY_SIZE(addcurve_path3), FALSE);
799 GdipDeletePath(path);
802 static path_test_t addclosedcurve_path[] = {
803 {0.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/
804 {-6.7, 0.0, PathPointTypeBezier, 0, 0}, /*1*/
805 {6.7, 3.3, PathPointTypeBezier, 0, 0}, /*2*/
806 {10.0, 10.0, PathPointTypeBezier, 0, 0}, /*3*/
807 {13.3, 16.7, PathPointTypeBezier, 0, 0}, /*4*/
808 {3.3, 20.0, PathPointTypeBezier, 0, 0}, /*5*/
809 {10.0, 20.0, PathPointTypeBezier, 0, 0}, /*6*/
810 {16.7, 20.0, PathPointTypeBezier, 0, 0}, /*7*/
811 {33.3, 16.7, PathPointTypeBezier, 0, 0}, /*8*/
812 {30.0, 10.0, PathPointTypeBezier, 0, 0}, /*9*/
813 {26.7, 3.3, PathPointTypeBezier, 0, 0}, /*10*/
814 {6.7, 0.0, PathPointTypeBezier, 0, 0}, /*11*/
815 {0.0, 0.0, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0} /*12*/
817 static void test_addclosedcurve(void)
819 GpStatus status;
820 GpPath *path;
821 GpPointF points[4];
823 points[0].X = 0.0;
824 points[0].Y = 0.0;
825 points[1].X = 10.0;
826 points[1].Y = 10.0;
827 points[2].X = 10.0;
828 points[2].Y = 20.0;
829 points[3].X = 30.0;
830 points[3].Y = 10.0;
832 GdipCreatePath(FillModeAlternate, &path);
834 /* NULL args */
835 status = GdipAddPathClosedCurve2(NULL, NULL, 0, 0.0);
836 expect(InvalidParameter, status);
837 status = GdipAddPathClosedCurve2(path, NULL, 0, 0.0);
838 expect(InvalidParameter, status);
839 status = GdipAddPathClosedCurve2(path, points, -1, 0.0);
840 expect(InvalidParameter, status);
841 status = GdipAddPathClosedCurve2(path, points, 1, 1.0);
842 expect(InvalidParameter, status);
844 /* add to empty path */
845 status = GdipAddPathClosedCurve2(path, points, 4, 1.0);
846 expect(Ok, status);
847 ok_path(path, addclosedcurve_path, ARRAY_SIZE(addclosedcurve_path), FALSE);
848 GdipDeletePath(path);
851 static path_test_t reverse_path[] = {
852 {0.0, 20.0, PathPointTypeStart, 0, 0}, /*0*/
853 {25.0, 25.0, PathPointTypeLine, 0, 0}, /*1*/
854 {0.0, 30.0, PathPointTypeLine, 0, 0}, /*2*/
855 {15.0, 35.0, PathPointTypeStart, 0, 0}, /*3*/
856 {0.0, 40.0, PathPointTypeLine, 0, 0}, /*4*/
857 {5.0, 45.0, PathPointTypeLine, 0, 0}, /*5*/
858 {0.0, 50.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 0} /*6*/
861 static void test_reverse(void)
863 GpStatus status;
864 GpPath *path;
865 GpPointF pts[7];
866 INT i;
868 for(i = 0; i < 7; i++){
869 pts[i].X = i * 5.0 * (REAL)(i % 2);
870 pts[i].Y = 50.0 - i * 5.0;
873 GdipCreatePath(FillModeAlternate, &path);
875 /* NULL argument */
876 status = GdipReversePath(NULL);
877 expect(InvalidParameter, status);
879 /* empty path */
880 status = GdipReversePath(path);
881 expect(Ok, status);
883 GdipAddPathLine2(path, pts, 4);
884 GdipClosePathFigure(path);
885 GdipAddPathLine2(path, &(pts[4]), 3);
887 status = GdipReversePath(path);
888 expect(Ok, status);
889 ok_path(path, reverse_path, ARRAY_SIZE(reverse_path), FALSE);
891 GdipDeletePath(path);
894 static path_test_t addpie_path[] = {
895 {50.0, 25.0, PathPointTypeStart, 0, 0}, /*0*/
896 {97.2, 33.3, PathPointTypeLine, 0, 0}, /*1*/
897 {91.8, 40.9, PathPointTypeBezier,0, 0}, /*2*/
898 {79.4, 46.8, PathPointTypeBezier,0, 0}, /*3*/
899 {63.9, 49.0, PathPointTypeBezier | PathPointTypeCloseSubpath, 0, 0} /*4*/
901 static path_test_t addpie_path2[] = {
902 {0.0, 30.0, PathPointTypeStart | PathPointTypeCloseSubpath, 0, 0} /*0*/
904 static path_test_t addpie_path3[] = {
905 {30.0, 0.0, PathPointTypeStart | PathPointTypeCloseSubpath, 0, 0} /*0*/
907 static void test_addpie(void)
909 GpStatus status;
910 GpPath *path;
912 GdipCreatePath(FillModeAlternate, &path);
914 /* NULL argument */
915 status = GdipAddPathPie(NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
916 expect(InvalidParameter, status);
918 status = GdipAddPathPie(path, 0.0, 0.0, 100.0, 50.0, 10.0, 50.0);
919 expect(Ok, status);
920 ok_path(path, addpie_path, ARRAY_SIZE(addpie_path), FALSE);
921 status = GdipResetPath(path);
922 expect(Ok, status);
924 /* zero width base ellipse */
925 status = GdipAddPathPie(path, 0.0, 0.0, 0.0, 60.0, -90.0, 24.0);
926 expect(InvalidParameter, status);
927 ok_path(path, addpie_path2, ARRAY_SIZE(addpie_path2), FALSE);
928 status = GdipResetPath(path);
929 expect(Ok, status);
931 /* zero height base ellipse */
932 status = GdipAddPathPie(path, 0.0, 0.0, 60.0, 0.0 , -90.0, 24.0);
933 expect(InvalidParameter, status);
934 ok_path(path, addpie_path3, ARRAY_SIZE(addpie_path3), FALSE);
936 GdipDeletePath(path);
939 static path_test_t flattenellipse_path[] = {
940 {100.0, 25.0,PathPointTypeStart, 0, 0}, /*0*/
941 {99.0, 30.0, PathPointTypeLine, 0, 0}, /*1*/
942 {96.0, 34.8, PathPointTypeLine, 0, 0}, /*2*/
943 {91.5, 39.0, PathPointTypeLine, 0, 0}, /*3*/
944 {85.5, 42.8, PathPointTypeLine, 0, 0}, /*4*/
945 {69.5, 48.0, PathPointTypeLine, 0, 1}, /*5*/
946 {50.0, 50.0, PathPointTypeLine, 0, 1}, /*6*/
947 {30.5, 48.0, PathPointTypeLine, 0, 1}, /*7*/
948 {14.8, 42.8, PathPointTypeLine, 0, 1}, /*8*/
949 {8.5, 39.0, PathPointTypeLine, 0, 1}, /*9*/
950 {4.0, 34.8, PathPointTypeLine, 0, 1}, /*10*/
951 {1.0, 30.0, PathPointTypeLine, 0, 1}, /*11*/
952 {0.0, 25.0, PathPointTypeLine, 0, 1}, /*12*/
953 {1.0, 20.0, PathPointTypeLine, 0, 1}, /*13*/
954 {4.0, 15.3, PathPointTypeLine, 0, 1}, /*14*/
955 {8.5, 11.0, PathPointTypeLine, 0, 1}, /*15*/
956 {14.8, 7.3, PathPointTypeLine, 0, 1}, /*16*/
957 {30.5, 2.0, PathPointTypeLine, 0, 1}, /*17*/
958 {50.0, 0.0, PathPointTypeLine, 0, 1}, /*18*/
959 {69.5, 2.0, PathPointTypeLine, 0, 1}, /*19*/
960 {85.5, 7.3, PathPointTypeLine, 0, 1}, /*20*/
961 {91.5, 11.0, PathPointTypeLine, 0, 1}, /*21*/
962 {96.0, 15.3, PathPointTypeLine, 0, 1}, /*22*/
963 {99.0, 20.0, PathPointTypeLine, 0, 1}, /*23*/
964 {100.0,25.0, PathPointTypeLine | PathPointTypeCloseSubpath, 0, 1} /*24*/
967 static path_test_t flattenline_path[] = {
968 {5.0, 10.0,PathPointTypeStart, 0, 0}, /*0*/
969 {50.0, 100.0, PathPointTypeLine, 0, 0} /*1*/
972 static path_test_t flattenarc_path[] = {
973 {100.0, 25.0,PathPointTypeStart, 0, 0}, /*0*/
974 {99.0, 30.0, PathPointTypeLine, 0, 0}, /*1*/
975 {96.0, 34.8, PathPointTypeLine, 0, 0}, /*2*/
976 {91.5, 39.0, PathPointTypeLine, 0, 0}, /*3*/
977 {85.5, 42.8, PathPointTypeLine, 0, 0}, /*4*/
978 {69.5, 48.0, PathPointTypeLine, 0, 1}, /*5*/
979 {50.0, 50.0, PathPointTypeLine, 0, 1} /*6*/
982 static path_test_t flattenquater_path[] = {
983 {100.0, 50.0,PathPointTypeStart, 0, 0}, /*0*/
984 {99.0, 60.0, PathPointTypeLine, 0, 0}, /*1*/
985 {96.0, 69.5, PathPointTypeLine, 0, 0}, /*2*/
986 {91.5, 78.0, PathPointTypeLine, 0, 0}, /*3*/
987 {85.5, 85.5, PathPointTypeLine, 0, 0}, /*4*/
988 {78.0, 91.5, PathPointTypeLine, 0, 0}, /*5*/
989 {69.5, 96.0, PathPointTypeLine, 0, 0}, /*6*/
990 {60.0, 99.0, PathPointTypeLine, 0, 0}, /*7*/
991 {50.0, 100.0,PathPointTypeLine, 0, 0} /*8*/
994 static void test_flatten(void)
996 GpStatus status;
997 GpPath *path;
998 GpMatrix *m;
1000 status = GdipCreatePath(FillModeAlternate, &path);
1001 expect(Ok, status);
1002 status = GdipCreateMatrix(&m);
1003 expect(Ok, status);
1005 /* NULL arguments */
1006 status = GdipFlattenPath(NULL, NULL, 0.0);
1007 expect(InvalidParameter, status);
1008 status = GdipFlattenPath(NULL, m, 0.0);
1009 expect(InvalidParameter, status);
1011 /* flatten empty path */
1012 status = GdipFlattenPath(path, NULL, 1.0);
1013 expect(Ok, status);
1015 status = GdipTransformPath(path, 0);
1016 expect(Ok, status);
1018 status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 50.0);
1019 expect(Ok, status);
1021 status = GdipFlattenPath(path, NULL, 1.0);
1022 expect(Ok, status);
1023 ok_path(path, flattenellipse_path, ARRAY_SIZE(flattenellipse_path), TRUE);
1025 status = GdipResetPath(path);
1026 expect(Ok, status);
1027 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 100.0);
1028 expect(Ok, status);
1029 status = GdipFlattenPath(path, NULL, 1.0);
1030 expect(Ok, status);
1031 ok_path(path, flattenline_path, ARRAY_SIZE(flattenline_path), FALSE);
1033 status = GdipResetPath(path);
1034 expect(Ok, status);
1035 status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 50.0, 0.0, 90.0);
1036 expect(Ok, status);
1037 status = GdipFlattenPath(path, NULL, 1.0);
1038 expect(Ok, status);
1039 ok_path(path, flattenarc_path, ARRAY_SIZE(flattenarc_path), TRUE);
1041 /* easy case - quater of a full circle */
1042 status = GdipResetPath(path);
1043 expect(Ok, status);
1044 status = GdipAddPathArc(path, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1045 expect(Ok, status);
1046 status = GdipFlattenPath(path, NULL, 1.0);
1047 expect(Ok, status);
1048 ok_path(path, flattenquater_path, ARRAY_SIZE(flattenquater_path), FALSE);
1050 GdipDeleteMatrix(m);
1051 GdipDeletePath(path);
1054 static path_test_t widenline_path[] = {
1055 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1056 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1057 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1058 {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/
1061 static path_test_t widenline_wide_path[] = {
1062 {5.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/
1063 {50.0, 0.0, PathPointTypeLine, 0, 0}, /*1*/
1064 {50.0, 20.0, PathPointTypeLine, 0, 0}, /*2*/
1065 {5.0, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/
1068 static path_test_t widenline_dash_path[] = {
1069 {5.0, 0.0, PathPointTypeStart, 0, 0}, /*0*/
1070 {35.0, 0.0, PathPointTypeLine, 0, 0}, /*1*/
1071 {35.0, 10.0, PathPointTypeLine, 0, 0}, /*2*/
1072 {5.0, 10.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/
1073 {45.0, 0.0, PathPointTypeStart, 0, 0}, /*4*/
1074 {50.0, 0.0, PathPointTypeLine, 0, 0}, /*5*/
1075 {50.0, 10.0, PathPointTypeLine, 0, 0}, /*6*/
1076 {45.0, 10.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/
1079 static void test_widen(void)
1081 GpStatus status;
1082 GpPath *path;
1083 GpPen *pen;
1084 GpMatrix *m;
1085 INT count=-1;
1087 status = GdipCreatePath(FillModeAlternate, &path);
1088 expect(Ok, status);
1089 status = GdipCreatePen1(0xffffffff, 10.0, UnitPixel, &pen);
1090 expect(Ok, status);
1091 status = GdipCreateMatrix(&m);
1092 expect(Ok, status);
1094 /* NULL arguments */
1095 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1096 expect(Ok, status);
1097 status = GdipWidenPath(NULL, NULL, NULL, 0.0);
1098 expect(InvalidParameter, status);
1099 status = GdipWidenPath(path, pen, m, 0.0);
1100 expect(Ok, status);
1101 status = GdipWidenPath(path, pen, NULL, 1.0);
1102 expect(Ok, status);
1103 status = GdipWidenPath(path, NULL, m, 1.0);
1104 expect(InvalidParameter, status);
1105 status = GdipWidenPath(NULL, pen, m, 1.0);
1106 expect(InvalidParameter, status);
1108 /* widen empty path */
1109 status = GdipResetPath(path);
1110 expect(Ok, status);
1111 status = GdipWidenPath(path, pen, m, 1.0);
1112 expect(OutOfMemory, status);
1114 /* horizontal line */
1115 status = GdipResetPath(path);
1116 expect(Ok, status);
1117 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1118 expect(Ok, status);
1120 status = GdipWidenPath(path, pen, m, 1.0);
1121 expect(Ok, status);
1122 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1124 /* horizontal 2x stretch */
1125 status = GdipResetPath(path);
1126 expect(Ok, status);
1127 status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
1128 expect(Ok, status);
1130 status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
1131 expect(Ok, status);
1133 status = GdipWidenPath(path, pen, m, 1.0);
1134 expect(Ok, status);
1135 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1137 /* vertical 2x stretch */
1138 status = GdipResetPath(path);
1139 expect(Ok, status);
1140 status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
1141 expect(Ok, status);
1143 status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
1144 expect(Ok, status);
1146 status = GdipWidenPath(path, pen, m, 1.0);
1147 expect(Ok, status);
1148 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1150 status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
1151 expect(Ok, status);
1153 /* dashed line */
1154 status = GdipResetPath(path);
1155 expect(Ok, status);
1156 status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
1157 expect(Ok, status);
1159 status = GdipSetPenDashStyle(pen, DashStyleDash);
1160 expect(Ok, status);
1162 status = GdipWidenPath(path, pen, m, 1.0);
1163 expect(Ok, status);
1164 ok_path(path, widenline_dash_path, ARRAY_SIZE(widenline_dash_path), FALSE);
1166 status = GdipSetPenDashStyle(pen, DashStyleSolid);
1167 expect(Ok, status);
1169 /* pen width in UnitWorld */
1170 GdipDeletePen(pen);
1171 status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
1172 expect(Ok, status);
1174 status = GdipResetPath(path);
1175 expect(Ok, status);
1176 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1177 expect(Ok, status);
1179 status = GdipWidenPath(path, pen, m, 1.0);
1180 expect(Ok, status);
1181 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1183 /* horizontal 2x stretch */
1184 status = GdipResetPath(path);
1185 expect(Ok, status);
1186 status = GdipAddPathLine(path, 2.5, 10.0, 25.0, 10.0);
1187 expect(Ok, status);
1189 status = GdipScaleMatrix(m, 2.0, 1.0, MatrixOrderAppend);
1190 expect(Ok, status);
1192 status = GdipWidenPath(path, pen, m, 1.0);
1193 expect(Ok, status);
1194 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1196 /* vertical 2x stretch */
1197 status = GdipResetPath(path);
1198 expect(Ok, status);
1199 status = GdipAddPathLine(path, 5.0, 5.0, 50.0, 5.0);
1200 expect(Ok, status);
1202 status = GdipScaleMatrix(m, 0.5, 2.0, MatrixOrderAppend);
1203 expect(Ok, status);
1205 status = GdipWidenPath(path, pen, m, 1.0);
1206 expect(Ok, status);
1207 ok_path(path, widenline_wide_path, ARRAY_SIZE(widenline_wide_path), FALSE);
1209 status = GdipScaleMatrix(m, 1.0, 0.5, MatrixOrderAppend);
1210 expect(Ok, status);
1212 /* pen width in UnitInch */
1213 GdipDeletePen(pen);
1214 status = GdipCreatePen1(0xffffffff, 10.0, UnitWorld, &pen);
1215 expect(Ok, status);
1217 status = GdipResetPath(path);
1218 expect(Ok, status);
1219 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1220 expect(Ok, status);
1222 status = GdipWidenPath(path, pen, m, 1.0);
1223 expect(Ok, status);
1224 ok_path(path, widenline_path, ARRAY_SIZE(widenline_path), FALSE);
1226 /* pen width = 0 pixels - native fails to widen but can draw with this pen */
1227 GdipDeletePen(pen);
1228 status = GdipCreatePen1(0xffffffff, 0.0, UnitPixel, &pen);
1229 expect(Ok, status);
1231 status = GdipResetPath(path);
1232 expect(Ok, status);
1233 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1234 expect(Ok, status);
1236 status = GdipWidenPath(path, pen, m, 1.0);
1237 expect(Ok, status);
1239 status = GdipGetPointCount(path, &count);
1240 expect(Ok, status);
1241 todo_wine expect(0, count);
1243 GdipDeleteMatrix(m);
1244 GdipDeletePen(pen);
1245 GdipDeletePath(path);
1248 static path_test_t widenline_capflat_path[] = {
1249 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1250 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1251 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1252 {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/
1255 static path_test_t widenline_capsquare_path[] = {
1256 {0.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1257 {55.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1258 {55.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1259 {0.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*3*/
1262 static path_test_t widenline_capround_path[] = {
1263 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1264 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1265 {52.761421, 5.0, PathPointTypeBezier, 0, 0}, /*2*/
1266 {55.0, 7.238576, PathPointTypeBezier, 0, 0}, /*3*/
1267 {55.0, 10.0, PathPointTypeBezier, 0, 0}, /*4*/
1268 {55.0, 12.761423, PathPointTypeBezier, 0, 0}, /*5*/
1269 {52.761421, 15.0, PathPointTypeBezier, 0, 0}, /*6*/
1270 {50.0, 15.0, PathPointTypeBezier, 0, 0}, /*7*/
1271 {5.0, 15.0, PathPointTypeLine, 0, 0}, /*8*/
1272 {2.238576, 15.0, PathPointTypeBezier, 0, 0}, /*9*/
1273 {0.0, 12.761423, PathPointTypeBezier, 0, 0}, /*10*/
1274 {0.0, 10.0, PathPointTypeBezier, 0, 0}, /*11*/
1275 {0.0, 7.238576, PathPointTypeBezier, 0, 0}, /*12*/
1276 {2.238576, 5.0, PathPointTypeBezier, 0, 0}, /*13*/
1277 {5.0, 5.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*14*/
1280 static path_test_t widenline_captriangle_path[] = {
1281 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1282 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1283 {55.0, 10.0, PathPointTypeLine, 0, 0}, /*2*/
1284 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*3*/
1285 {5.0, 15.0, PathPointTypeLine, 0, 0}, /*4*/
1286 {0.0, 10.0, PathPointTypeLine, 0, 0}, /*5*/
1287 {5.0, 5.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0} /*6*/
1290 static path_test_t widenline_capsquareanchor_path[] = {
1291 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1292 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1293 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1294 {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/
1295 {12.071068, 2.928932, PathPointTypeStart, 0, 0}, /*4*/
1296 {12.071068, 17.071066, PathPointTypeLine, 0, 0}, /*5*/
1297 {-2.071068, 17.071066, PathPointTypeLine, 0, 0}, /*6*/
1298 {-2.071068, 2.928932, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/
1299 {42.928928, 17.071068, PathPointTypeStart, 0, 0}, /*8*/
1300 {42.928928, 2.928932, PathPointTypeLine, 0, 0}, /*9*/
1301 {57.071068, 2.928932, PathPointTypeLine, 0, 0}, /*10*/
1302 {57.071068, 17.071068, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*11*/
1305 static path_test_t widenline_caproundanchor_path[] = {
1306 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1307 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1308 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1309 {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/
1310 {5.0, 20.0, PathPointTypeStart, 0, 0}, /*4*/
1311 {-0.522847, 20.0, PathPointTypeBezier, 0, 0}, /*5*/
1312 {-5.0, 15.522846, PathPointTypeBezier, 0, 0}, /*6*/
1313 {-5.0, 10.0, PathPointTypeBezier, 0, 0}, /*7*/
1314 {-5.0, 4.477152, PathPointTypeBezier, 0, 0}, /*8*/
1315 {-0.522847, 0.0, PathPointTypeBezier, 0, 0}, /*9*/
1316 {5.0, 0.0, PathPointTypeBezier, 0, 0}, /*10*/
1317 {10.522847, 0.0, PathPointTypeBezier, 0, 0}, /*11*/
1318 {15.0, 4.477152, PathPointTypeBezier, 0, 0}, /*12*/
1319 {15.0, 10.0, PathPointTypeBezier, 0, 0}, /*13*/
1320 {15.0, 15.522846, PathPointTypeBezier, 0, 0}, /*14*/
1321 {10.522847, 20.0, PathPointTypeBezier, 0, 0}, /*15*/
1322 {5.0, 20.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*16*/
1323 {50.0, 0.0, PathPointTypeStart, 0, 0}, /*17*/
1324 {55.522846, 0.0, PathPointTypeBezier, 0, 0}, /*18*/
1325 {60.0, 4.477153, PathPointTypeBezier, 0, 0}, /*19*/
1326 {60.0, 10.0, PathPointTypeBezier, 0, 0}, /*20*/
1327 {60.0, 15.522847, PathPointTypeBezier, 0, 0}, /*21*/
1328 {55.522846, 20.0, PathPointTypeBezier, 0, 0}, /*22*/
1329 {50.0, 20.0, PathPointTypeBezier, 0, 0}, /*23*/
1330 {44.477150, 20.0, PathPointTypeBezier, 0, 0}, /*24*/
1331 {40.0, 15.522847, PathPointTypeBezier, 0, 0}, /*25*/
1332 {40.0, 10.0, PathPointTypeBezier, 0, 0}, /*26*/
1333 {40.0, 4.477153, PathPointTypeBezier, 0, 0}, /*27*/
1334 {44.477150, 0.0, PathPointTypeBezier, 0, 0}, /*28*/
1335 {50.0, 0.0, PathPointTypeBezier|PathPointTypeCloseSubpath, 0, 0}, /*29*/
1338 static path_test_t widenline_capdiamondanchor_path[] = {
1339 {5.0, 5.0, PathPointTypeStart, 0, 0}, /*0*/
1340 {50.0, 5.0, PathPointTypeLine, 0, 0}, /*1*/
1341 {50.0, 15.0, PathPointTypeLine, 0, 0}, /*2*/
1342 {5.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*3*/
1343 {-5.0, 10.0, PathPointTypeStart, 0, 0}, /*4*/
1344 {5.0, 0.0, PathPointTypeLine, 0, 0}, /*5*/
1345 {15.0, 10.0, PathPointTypeLine, 0, 0}, /*6*/
1346 {5.0, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*7*/
1347 {60.0, 10.0, PathPointTypeStart, 0, 0}, /*8*/
1348 {50.0, 20.0, PathPointTypeLine, 0, 0}, /*9*/
1349 {40.0, 10.0, PathPointTypeLine, 0, 0}, /*10*/
1350 {50.0, 0.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*11*/
1353 static path_test_t widenline_caparrowanchor_path[] = {
1354 {15.0, 5.0, PathPointTypeStart, 0, 1}, /*0*/
1355 {40.0, 5.0, PathPointTypeLine, 0, 1}, /*1*/
1356 {40.0, 15.0, PathPointTypeLine, 0, 1}, /*2*/
1357 {15.0, 15.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 1}, /*3*/
1358 {5.0, 10.0, PathPointTypeStart, 0, 0}, /*4*/
1359 {22.320507, 0.0, PathPointTypeLine, 0, 0}, /*5*/
1360 {22.320507, 20.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*6*/
1361 {50.0, 10.0, PathPointTypeStart, 0, 0}, /*7*/
1362 {32.679489, 20.0, PathPointTypeLine, 0, 0}, /*8*/
1363 {32.679489, 0.0, PathPointTypeLine|PathPointTypeCloseSubpath, 0, 0}, /*9*/
1366 static void test_widen_cap(void)
1368 struct
1370 LineCap type;
1371 const path_test_t *expected;
1372 INT expected_size;
1373 BOOL todo_size;
1375 caps[] =
1377 { LineCapFlat, widenline_capflat_path,
1378 ARRAY_SIZE(widenline_capflat_path) },
1379 { LineCapSquare, widenline_capsquare_path,
1380 ARRAY_SIZE(widenline_capsquare_path) },
1381 { LineCapRound, widenline_capround_path,
1382 ARRAY_SIZE(widenline_capround_path) },
1383 { LineCapTriangle, widenline_captriangle_path,
1384 ARRAY_SIZE(widenline_captriangle_path) },
1385 { LineCapNoAnchor, widenline_capflat_path,
1386 ARRAY_SIZE(widenline_capflat_path) },
1387 { LineCapSquareAnchor, widenline_capsquareanchor_path,
1388 ARRAY_SIZE(widenline_capsquareanchor_path) },
1389 { LineCapRoundAnchor, widenline_caproundanchor_path,
1390 ARRAY_SIZE(widenline_caproundanchor_path) },
1391 { LineCapDiamondAnchor, widenline_capdiamondanchor_path,
1392 ARRAY_SIZE(widenline_capdiamondanchor_path), TRUE },
1393 { LineCapArrowAnchor, widenline_caparrowanchor_path,
1394 ARRAY_SIZE(widenline_caparrowanchor_path), TRUE },
1396 GpStatus status;
1397 GpPath *path;
1398 GpPen *pen;
1399 int i;
1401 status = GdipCreatePath(FillModeAlternate, &path);
1402 expect(Ok, status);
1403 status = GdipCreatePen1(0xffffffff, 10.0, UnitPixel, &pen);
1404 expect(Ok, status);
1406 for (i = 0; i < ARRAY_SIZE(caps); i++)
1408 status = GdipResetPath(path);
1409 expect(Ok, status);
1410 status = GdipAddPathLine(path, 5.0, 10.0, 50.0, 10.0);
1411 expect(Ok, status);
1412 status = GdipSetPenStartCap(pen, caps[i].type);
1413 expect(Ok, status);
1414 status = GdipSetPenEndCap(pen, caps[i].type);
1415 expect(Ok, status);
1417 status = GdipWidenPath(path, pen, NULL, FlatnessDefault);
1418 expect(Ok, status);
1419 ok_path(path, caps[i].expected, caps[i].expected_size, caps[i].todo_size);
1422 GdipDeletePen(pen);
1423 GdipDeletePath(path);
1426 static void test_isvisible(void)
1428 GpPath *path;
1429 GpGraphics *graphics = NULL;
1430 HDC hdc = GetDC(0);
1431 BOOL result;
1432 GpStatus status;
1434 status = GdipCreateFromHDC(hdc, &graphics);
1435 expect(Ok, status);
1436 status = GdipCreatePath(FillModeAlternate, &path);
1437 expect(Ok, status);
1439 /* NULL */
1440 status = GdipIsVisiblePathPoint(NULL, 0.0, 0.0, NULL, NULL);
1441 expect(InvalidParameter, status);
1442 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, NULL);
1443 expect(InvalidParameter, status);
1444 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, NULL);
1445 expect(InvalidParameter, status);
1446 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, graphics, NULL);
1447 expect(InvalidParameter, status);
1449 /* empty path */
1450 result = TRUE;
1451 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, &result);
1452 expect(Ok, status);
1453 expect(FALSE, result);
1454 /* rect */
1455 status = GdipAddPathRectangle(path, 0.0, 0.0, 10.0, 10.0);
1456 expect(Ok, status);
1457 result = FALSE;
1458 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, NULL, &result);
1459 expect(Ok, status);
1460 expect(TRUE, result);
1461 result = TRUE;
1462 status = GdipIsVisiblePathPoint(path, 11.0, 11.0, NULL, &result);
1463 expect(Ok, status);
1464 expect(FALSE, result);
1465 /* not affected by clipping */
1466 status = GdipSetClipRect(graphics, 5.0, 5.0, 5.0, 5.0, CombineModeReplace);
1467 expect(Ok, status);
1468 result = FALSE;
1469 status = GdipIsVisiblePathPoint(path, 0.0, 0.0, graphics, &result);
1470 expect(Ok, status);
1471 expect(TRUE, result);
1473 GdipDeletePath(path);
1474 GdipDeleteGraphics(graphics);
1475 ReleaseDC(0, hdc);
1478 static void test_empty_rect(void)
1480 GpPath *path;
1481 GpStatus status;
1482 INT count;
1483 BOOL result;
1485 status = GdipCreatePath(FillModeAlternate, &path);
1486 expect(Ok, status);
1488 status = GdipAddPathRectangle(path, 0.0, 0.0, -5.0, 5.0);
1489 expect(Ok, status);
1491 status = GdipGetPointCount(path, &count);
1492 expect(Ok, status);
1493 expect(0, count);
1495 status = GdipIsVisiblePathPoint(path, -2.0, 2.0, NULL, &result);
1496 expect(Ok, status);
1497 expect(FALSE, result);
1499 status = GdipAddPathRectangle(path, 0.0, 0.0, 5.0, -5.0);
1500 expect(Ok, status);
1502 status = GdipGetPointCount(path, &count);
1503 expect(Ok, status);
1504 expect(0, count);
1506 status = GdipAddPathRectangle(path, 0.0, 0.0, 0.0, 5.0);
1507 expect(Ok, status);
1509 status = GdipGetPointCount(path, &count);
1510 expect(Ok, status);
1511 expect(0, count);
1513 status = GdipAddPathRectangle(path, 0.0, 0.0, 5.0, 0.0);
1514 expect(Ok, status);
1516 status = GdipGetPointCount(path, &count);
1517 expect(Ok, status);
1518 expect(0, count);
1520 status = GdipAddPathRectangle(path, 0.0, 0.0, 5.0, 0.1);
1521 expect(Ok, status);
1523 status = GdipGetPointCount(path, &count);
1524 expect(Ok, status);
1525 expect(4, count);
1527 GdipDeletePath(path);
1530 START_TEST(graphicspath)
1532 struct GdiplusStartupInput gdiplusStartupInput;
1533 ULONG_PTR gdiplusToken;
1534 HMODULE hmsvcrt;
1535 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
1537 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1538 hmsvcrt = LoadLibraryA("msvcrt");
1539 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
1540 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
1542 gdiplusStartupInput.GdiplusVersion = 1;
1543 gdiplusStartupInput.DebugEventCallback = NULL;
1544 gdiplusStartupInput.SuppressBackgroundThread = 0;
1545 gdiplusStartupInput.SuppressExternalCodecs = 0;
1547 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1549 test_constructor_destructor();
1550 test_getpathdata();
1551 test_line2();
1552 test_arc();
1553 test_worldbounds();
1554 test_pathpath();
1555 test_ellipse();
1556 test_linei();
1557 test_rect();
1558 test_polygon();
1559 test_lastpoint();
1560 test_addcurve();
1561 test_addclosedcurve();
1562 test_reverse();
1563 test_addpie();
1564 test_flatten();
1565 test_widen();
1566 test_widen_cap();
1567 test_isvisible();
1568 test_empty_rect();
1570 GdiplusShutdown(gdiplusToken);