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
23 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
24 #define expectf(expected, got) ok(fabs(expected - got) < 2.0, "Expected %.2f, got %.2f\n", expected, got)
25 #define POINT_TYPE_MAX_LEN (75)
27 static void stringify_point_type(PathPointType type
, char * name
)
31 switch(type
& PathPointTypePathTypeMask
){
32 case PathPointTypeStart
:
33 strcat(name
, "PathPointTypeStart");
35 case PathPointTypeLine
:
36 strcat(name
, "PathPointTypeLine");
38 case PathPointTypeBezier
:
39 strcat(name
, "PathPointTypeBezier");
42 strcat(name
, "Unknown type");
46 type
&= ~PathPointTypePathTypeMask
;
47 if(type
& ~((PathPointTypePathMarker
| PathPointTypeCloseSubpath
))){
49 strcat(name
, "Unknown type");
53 if(type
& PathPointTypePathMarker
)
54 strcat(name
, " | PathPointTypePathMarker");
55 if(type
& PathPointTypeCloseSubpath
)
56 strcat(name
, " | PathPointTypeCloseSubpath");
59 /* this helper structure and function modeled after gdi path.c test */
65 /* How many extra entries before this one only on wine
66 * but not on native? */
67 int wine_only_entries_preceding
;
69 /* 0 - This entry matches on wine.
70 * 1 - This entry corresponds to a single entry on wine that does not match the native entry.
71 * 2 - This entry is currently skipped on wine but present on native. */
75 static void ok_path(GpPath
* path
, const path_test_t
*expected
, INT expected_size
, BOOL todo_size
)
78 INT size
, idx
= 0, eidx
= 0, numskip
;
80 char ename
[POINT_TYPE_MAX_LEN
], name
[POINT_TYPE_MAX_LEN
];
82 if(GdipGetPointCount(path
, &size
) != Ok
){
83 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
87 todo_wine_if (todo_size
)
88 ok(size
== expected_size
, "Path size %d does not match expected size %d\n",
91 points
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(GpPointF
));
92 types
= HeapAlloc(GetProcessHeap(), 0, size
);
94 if(GdipGetPathPoints(path
, points
, size
) != Ok
|| GdipGetPathTypes(path
, types
, size
) != Ok
){
95 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
99 numskip
= expected_size
? expected
[eidx
].wine_only_entries_preceding
: 0;
100 while (idx
< size
&& eidx
< expected_size
){
101 /* We allow a few pixels fudge in matching X and Y coordinates to account for imprecision in
102 * floating point to integer conversion */
103 BOOL match
= (types
[idx
] == expected
[eidx
].type
) &&
104 fabs(points
[idx
].X
- expected
[eidx
].X
) <= 2.0 &&
105 fabs(points
[idx
].Y
- expected
[eidx
].Y
) <= 2.0;
107 stringify_point_type(expected
[eidx
].type
, ename
);
108 stringify_point_type(types
[idx
], name
);
110 todo_wine_if (expected
[eidx
].todo
|| numskip
)
111 ok(match
, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx
,
112 ename
, expected
[eidx
].X
, expected
[eidx
].Y
,
113 name
, points
[idx
].X
, points
[idx
].Y
);
115 if (match
|| expected
[eidx
].todo
!= 2)
117 if (match
|| !numskip
--)
118 numskip
= expected
[++eidx
].wine_only_entries_preceding
;
122 HeapFree(GetProcessHeap(), 0, types
);
123 HeapFree(GetProcessHeap(), 0, points
);
126 static void test_constructor_destructor(void)
131 status
= GdipCreatePath(FillModeAlternate
, &path
);
133 ok(path
!= NULL
, "Expected path to be initialized\n");
135 status
= GdipDeletePath(NULL
);
136 expect(InvalidParameter
, status
);
138 status
= GdipDeletePath(path
);
142 static void test_getpathdata(void)
149 status
= GdipCreatePath(FillModeAlternate
, &path
);
151 status
= GdipAddPathLine(path
, 5.0, 5.0, 100.0, 50.0);
154 status
= GdipGetPointCount(path
, &count
);
159 data
.Types
= GdipAlloc(sizeof(BYTE
) * count
);
160 data
.Points
= GdipAlloc(sizeof(PointF
) * count
);
162 status
= GdipGetPathData(path
, &data
);
164 expect((data
.Points
[0].X
== 5.0) && (data
.Points
[0].Y
== 5.0) &&
165 (data
.Points
[1].X
== 100.0) && (data
.Points
[1].Y
== 50.0), TRUE
);
166 expect((data
.Types
[0] == PathPointTypeStart
) && (data
.Types
[1] == PathPointTypeLine
), TRUE
);
168 GdipFree(data
.Points
);
169 GdipFree(data
.Types
);
170 GdipDeletePath(path
);
173 static path_test_t line2_path
[] = {
174 {0.0, 50.0, PathPointTypeStart
, 0, 0}, /*0*/
175 {5.0, 45.0, PathPointTypeLine
, 0, 0}, /*1*/
176 {0.0, 40.0, PathPointTypeLine
, 0, 0}, /*2*/
177 {15.0, 35.0, PathPointTypeLine
, 0, 0}, /*3*/
178 {0.0, 30.0, PathPointTypeLine
, 0, 0}, /*4*/
179 {25.0, 25.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*5*/
180 {0.0, 20.0, PathPointTypeStart
, 0, 0}, /*6*/
181 {35.0, 15.0, PathPointTypeLine
, 0, 0}, /*7*/
182 {0.0, 10.0, PathPointTypeLine
, 0, 0} /*8*/
185 static void test_line2(void)
190 GpPointF line2_points
[9];
192 for(i
= 0; i
< 9; i
++){
193 line2_points
[i
].X
= i
* 5.0 * (REAL
)(i
% 2);
194 line2_points
[i
].Y
= 50.0 - i
* 5.0;
197 GdipCreatePath(FillModeAlternate
, &path
);
198 status
= GdipAddPathLine2(path
, line2_points
, 3);
200 status
= GdipAddPathLine2(path
, &(line2_points
[3]), 3);
202 status
= GdipClosePathFigure(path
);
204 status
= GdipAddPathLine2(path
, &(line2_points
[6]), 3);
207 ok_path(path
, line2_path
, sizeof(line2_path
)/sizeof(path_test_t
), FALSE
);
209 GdipDeletePath(path
);
212 static path_test_t arc_path
[] = {
213 {600.0, 450.0, PathPointTypeStart
, 0, 0}, /*0*/
214 {600.0, 643.3, PathPointTypeBezier
, 0, 0}, /*1*/
215 {488.1, 800.0, PathPointTypeBezier
, 0, 0}, /*2*/
216 {350.0, 800.0, PathPointTypeBezier
, 0, 0}, /*3*/
217 {600.0, 450.0, PathPointTypeLine
, 0, 0}, /*4*/
218 {600.0, 643.3, PathPointTypeBezier
, 0, 0}, /*5*/
219 {488.1, 800.0, PathPointTypeBezier
, 0, 0}, /*6*/
220 {350.0, 800.0, PathPointTypeBezier
, 0, 0}, /*7*/
221 {329.8, 800.0, PathPointTypeBezier
, 0, 0}, /*8*/
222 {309.7, 796.6, PathPointTypeBezier
, 0, 0}, /*9*/
223 {290.1, 789.8, PathPointTypeBezier
, 0, 0}, /*10*/
224 {409.9, 110.2, PathPointTypeLine
, 0, 0}, /*11*/
225 {544.0, 156.5, PathPointTypeBezier
, 0, 0}, /*12*/
226 {625.8, 346.2, PathPointTypeBezier
, 0, 0}, /*13*/
227 {592.7, 533.9, PathPointTypeBezier
, 0, 0}, /*14*/
228 {592.5, 535.3, PathPointTypeBezier
, 0, 0}, /*15*/
229 {592.2, 536.7, PathPointTypeBezier
, 0, 0}, /*16*/
230 {592.0, 538.1, PathPointTypeBezier
, 0, 0}, /*17*/
231 {409.9, 789.8, PathPointTypeLine
, 0, 0}, /*18*/
232 {544.0, 743.5, PathPointTypeBezier
, 0, 0}, /*19*/
233 {625.8, 553.8, PathPointTypeBezier
, 0, 0}, /*20*/
234 {592.7, 366.1, PathPointTypeBezier
, 0, 0}, /*21*/
235 {592.5, 364.7, PathPointTypeBezier
, 0, 0}, /*22*/
236 {592.2, 363.3, PathPointTypeBezier
, 0, 0}, /*23*/
237 {592.0, 361.9, PathPointTypeBezier
, 0, 0}, /*24*/
238 {540.4, 676.9, PathPointTypeLine
, 0, 0}, /*25*/
239 {629.9, 529.7, PathPointTypeBezier
, 0, 0}, /*26*/
240 {617.2, 308.8, PathPointTypeBezier
, 0, 0}, /*27*/
241 {512.1, 183.5, PathPointTypeBezier
, 0, 0}, /*28*/
242 {406.9, 58.2, PathPointTypeBezier
, 0, 0}, /*29*/
243 {249.1, 75.9, PathPointTypeBezier
, 0, 0}, /*30*/
244 {159.6, 223.1, PathPointTypeBezier
, 0, 0}, /*31*/
245 {70.1, 370.3, PathPointTypeBezier
, 0, 0}, /*32*/
246 {82.8, 591.2, PathPointTypeBezier
, 0, 0}, /*33*/
247 {187.9, 716.5, PathPointTypeBezier
, 0, 0}, /*34*/
248 {293.1, 841.8, PathPointTypeBezier
, 0, 0}, /*35*/
249 {450.9, 824.1, PathPointTypeBezier
, 0, 0}, /*36*/
250 {540.4, 676.9, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 1} /*37*/
253 static void test_arc(void)
258 GdipCreatePath(FillModeAlternate
, &path
);
259 /* Exactly 90 degrees */
260 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
262 /* Over 90 degrees */
263 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
265 /* Negative start angle */
266 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
268 /* Negative sweep angle */
269 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 80.0, -100.0);
271 /* More than a full revolution */
272 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 50.0, -400.0);
275 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 50.0, 0.0);
278 ok_path(path
, arc_path
, sizeof(arc_path
)/sizeof(path_test_t
), FALSE
);
280 GdipDeletePath(path
);
283 static void test_worldbounds(void)
290 GpPointF line2_points
[10];
293 for(i
= 0; i
< 10; i
++){
294 line2_points
[i
].X
= 200.0 + i
* 50.0 * (i
% 2);
295 line2_points
[i
].Y
= 200.0 + i
* 50.0 * !(i
% 2);
297 GdipCreatePen1((ARGB
)0xdeadbeef, 20.0, UnitWorld
, &pen
);
298 GdipSetPenEndCap(pen
, LineCapSquareAnchor
);
299 GdipCreateMatrix2(1.5, 0.0, 1.0, 1.2, 10.4, 10.2, &matrix
);
301 GdipCreatePath(FillModeAlternate
, &path
);
302 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
303 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
304 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, NULL
);
306 GdipDeletePath(path
);
308 expectf(200.0, bounds
.X
);
309 expectf(200.0, bounds
.Y
);
310 expectf(450.0, bounds
.Width
);
311 expectf(600.0, bounds
.Height
);
313 GdipCreatePath(FillModeAlternate
, &path
);
314 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
315 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
316 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, NULL
);
318 GdipDeletePath(path
);
320 expectf(510.4, bounds
.X
);
321 expectf(250.2, bounds
.Y
);
322 expectf(1275.0, bounds
.Width
);
323 expectf(720.0, bounds
.Height
);
325 GdipCreatePath(FillModeAlternate
, &path
);
326 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
327 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
328 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
330 GdipDeletePath(path
);
332 expectf(100.0, bounds
.X
);
333 expectf(100.0, bounds
.Y
);
334 expectf(650.0, bounds
.Width
);
335 expectf(800.0, bounds
.Height
);
337 GdipCreatePath(FillModeAlternate
, &path
);
338 GdipAddPathLine2(path
, &(line2_points
[0]), 2);
339 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
341 GdipDeletePath(path
);
343 expectf(156.0, bounds
.X
);
344 expectf(156.0, bounds
.Y
);
345 expectf(138.0, bounds
.Width
);
346 expectf(88.0, bounds
.Height
);
348 line2_points
[2].X
= 2 * line2_points
[1].X
- line2_points
[0].X
;
349 line2_points
[2].Y
= 2 * line2_points
[1].Y
- line2_points
[0].Y
;
351 GdipCreatePath(FillModeAlternate
, &path
);
352 GdipAddPathLine2(path
, &(line2_points
[0]), 3);
353 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
355 GdipDeletePath(path
);
357 expectf(100.0, bounds
.X
);
358 expectf(100.0, bounds
.Y
);
359 expectf(300.0, bounds
.Width
);
360 expectf(200.0, bounds
.Height
);
362 GdipCreatePath(FillModeAlternate
, &path
);
363 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 45.0, 20.0);
364 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
366 GdipDeletePath(path
);
368 expectf(386.7, bounds
.X
);
369 expectf(553.4, bounds
.Y
);
370 expectf(266.8, bounds
.Width
);
371 expectf(289.6, bounds
.Height
);
373 GdipCreatePath(FillModeAlternate
, &path
);
374 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, pen
);
376 GdipDeletePath(path
);
378 expectf(0.0, bounds
.X
);
379 expectf(0.0, bounds
.Y
);
380 expectf(0.0, bounds
.Width
);
381 expectf(0.0, bounds
.Height
);
383 GdipCreatePath(FillModeAlternate
, &path
);
384 GdipAddPathLine2(path
, &(line2_points
[0]), 2);
385 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, pen
);
387 GdipDeletePath(path
);
390 expectf(427.9, bounds
.X
);
391 expectf(167.7, bounds
.Y
);
392 expectf(239.9, bounds
.Width
);
393 expectf(164.9, bounds
.Height
);
396 GdipDeleteMatrix(matrix
);
397 GdipCreateMatrix2(0.9, -0.5, -0.5, -1.2, 10.4, 10.2, &matrix
);
398 GdipCreatePath(FillModeAlternate
, &path
);
399 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
400 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
401 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, NULL
);
403 GdipDeletePath(path
);
404 GdipDeleteMatrix(matrix
);
406 expectf(-209.6, bounds
.X
);
407 expectf(-1274.8, bounds
.Y
);
408 expectf(705.0, bounds
.Width
);
409 expectf(945.0, bounds
.Height
);
414 static path_test_t pathpath_path
[] = {
415 {600.00, 450.00, PathPointTypeStart
, 0, 0}, /*0*/
416 {600.00, 643.30, PathPointTypeBezier
, 0, 0}, /*1*/
417 {488.07, 800.00, PathPointTypeBezier
, 0, 0}, /*2*/
418 {350.00, 800.00, PathPointTypeBezier
, 0, 0}, /*3*/
419 {319.61, 797.40, PathPointTypeStart
, 0, 0}, /*4*/
420 {182.56, 773.90, PathPointTypeBezier
, 0, 0}, /*5*/
421 {85.07, 599.31, PathPointTypeBezier
, 0, 0}, /*6*/
422 {101.85, 407.45, PathPointTypeBezier
, 0, 0}, /*7*/
423 {102.54, 399.66, PathPointTypeBezier
, 0, 0}, /*8*/
424 {103.40, 391.91, PathPointTypeBezier
, 0, 0}, /*9*/
425 {104.46, 384.21, PathPointTypeBezier
, 0, 0}, /*10*/
426 {409.92, 110.20, PathPointTypeLine
, 0, 0}, /*11*/
427 {543.96, 156.53, PathPointTypeBezier
, 0, 0}, /*12*/
428 {625.80, 346.22, PathPointTypeBezier
, 0, 0}, /*13*/
429 {592.71, 533.88, PathPointTypeBezier
, 0, 0}, /*14*/
430 {592.47, 535.28, PathPointTypeBezier
, 0, 0}, /*15*/
431 {592.22, 536.67, PathPointTypeBezier
, 0, 0}, /*16*/
432 {591.96, 538.06, PathPointTypeBezier
, 0, 0}, /*17*/
433 {319.61, 797.40, PathPointTypeLine
, 0, 0}, /*18*/
434 {182.56, 773.90, PathPointTypeBezier
, 0, 0}, /*19*/
435 {85.07, 599.31, PathPointTypeBezier
, 0, 0}, /*20*/
436 {101.85, 407.45, PathPointTypeBezier
, 0, 0}, /*21*/
437 {102.54, 399.66, PathPointTypeBezier
, 0, 0}, /*22*/
438 {103.40, 391.91, PathPointTypeBezier
, 0, 0}, /*23*/
439 {104.46, 384.21, PathPointTypeBezier
, 0, 0} /*24*/
442 static void test_pathpath(void)
445 GpPath
* path1
, *path2
;
447 GdipCreatePath(FillModeAlternate
, &path2
);
448 GdipAddPathArc(path2
, 100.0, 100.0, 500.0, 700.0, 95.0, 100.0);
450 GdipCreatePath(FillModeAlternate
, &path1
);
451 GdipAddPathArc(path1
, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
452 status
= GdipAddPathPath(path1
, path2
, FALSE
);
454 GdipAddPathArc(path1
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
455 status
= GdipAddPathPath(path1
, path2
, TRUE
);
458 ok_path(path1
, pathpath_path
, sizeof(pathpath_path
)/sizeof(path_test_t
), FALSE
);
460 GdipDeletePath(path1
);
461 GdipDeletePath(path2
);
464 static path_test_t ellipse_path
[] = {
465 {30.00, 125.25, PathPointTypeStart
, 0, 0}, /*0*/
466 {30.00, 139.20, PathPointTypeBezier
, 0, 0}, /*1*/
467 {25.52, 150.50, PathPointTypeBezier
, 0, 0}, /*2*/
468 {20.00, 150.50, PathPointTypeBezier
, 0, 0}, /*3*/
469 {14.48, 150.50, PathPointTypeBezier
, 0, 0}, /*4*/
470 {10.00, 139.20, PathPointTypeBezier
, 0, 0}, /*5*/
471 {10.00, 125.25, PathPointTypeBezier
, 0, 0}, /*6*/
472 {10.00, 111.30, PathPointTypeBezier
, 0, 0}, /*7*/
473 {14.48, 100.00, PathPointTypeBezier
, 0, 0}, /*8*/
474 {20.00, 100.00, PathPointTypeBezier
, 0, 0}, /*9*/
475 {25.52, 100.00, PathPointTypeBezier
, 0, 0}, /*10*/
476 {30.00, 111.30, PathPointTypeBezier
, 0, 0}, /*11*/
477 {30.00, 125.25, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0}, /*12*/
478 {7.00, 11.00, PathPointTypeStart
, 0, 0}, /*13*/
479 {13.00, 17.00, PathPointTypeLine
, 0, 0}, /*14*/
480 {5.00, 195.00, PathPointTypeStart
, 0, 0}, /*15*/
481 {5.00, 192.24, PathPointTypeBezier
, 0, 0}, /*16*/
482 {6.12, 190.00, PathPointTypeBezier
, 0, 0}, /*17*/
483 {7.50, 190.00, PathPointTypeBezier
, 0, 0}, /*18*/
484 {8.88, 190.00, PathPointTypeBezier
, 0, 0}, /*19*/
485 {10.00, 192.24, PathPointTypeBezier
, 0, 0}, /*20*/
486 {10.00, 195.00, PathPointTypeBezier
, 0, 0}, /*21*/
487 {10.00, 197.76, PathPointTypeBezier
, 0, 0}, /*22*/
488 {8.88, 200.00, PathPointTypeBezier
, 0, 0}, /*23*/
489 {7.50, 200.00, PathPointTypeBezier
, 0, 0}, /*24*/
490 {6.12, 200.00, PathPointTypeBezier
, 0, 0}, /*25*/
491 {5.00, 197.76, PathPointTypeBezier
, 0, 0}, /*26*/
492 {5.00, 195.00, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0}, /*27*/
493 {10.00, 300.50, PathPointTypeStart
, 0, 0}, /*28*/
494 {10.00, 300.78, PathPointTypeBezier
, 0, 0}, /*29*/
495 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*30*/
496 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*31*/
497 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*32*/
498 {10.00, 300.78, PathPointTypeBezier
, 0, 0}, /*33*/
499 {10.00, 300.50, PathPointTypeBezier
, 0, 0}, /*34*/
500 {10.00, 300.22, PathPointTypeBezier
, 0, 0}, /*35*/
501 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*36*/
502 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*37*/
503 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*38*/
504 {10.00, 300.22, PathPointTypeBezier
, 0, 0}, /*39*/
505 {10.00, 300.50, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*40*/
508 static void test_ellipse(void)
519 GdipCreatePath(FillModeAlternate
, &path
);
520 status
= GdipAddPathEllipse(path
, 10.0, 100.0, 20.0, 50.5);
522 GdipAddPathLine2(path
, points
, 2);
523 status
= GdipAddPathEllipse(path
, 10.0, 200.0, -5.0, -10.0);
525 GdipClosePathFigure(path
);
526 status
= GdipAddPathEllipse(path
, 10.0, 300.0, 0.0, 1.0);
529 ok_path(path
, ellipse_path
, sizeof(ellipse_path
)/sizeof(path_test_t
), FALSE
);
531 GdipDeletePath(path
);
534 static path_test_t linei_path
[] = {
535 {5.00, 5.00, PathPointTypeStart
, 0, 0}, /*0*/
536 {6.00, 8.00, PathPointTypeLine
, 0, 0}, /*1*/
537 {409.92, 110.20, PathPointTypeLine
, 0, 0}, /*2*/
538 {543.96, 156.53, PathPointTypeBezier
, 0, 0}, /*3*/
539 {625.80, 346.22, PathPointTypeBezier
, 0, 0}, /*4*/
540 {592.71, 533.88, PathPointTypeBezier
, 0, 0}, /*5*/
541 {592.47, 535.28, PathPointTypeBezier
, 0, 0}, /*6*/
542 {592.22, 536.67, PathPointTypeBezier
, 0, 0}, /*7*/
543 {591.96, 538.06, PathPointTypeBezier
, 0, 0}, /*8*/
544 {15.00, 15.00, PathPointTypeLine
, 0, 0}, /*9*/
545 {26.00, 28.00, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*10*/
546 {35.00, 35.00, PathPointTypeStart
, 0, 0}, /*11*/
547 {36.00, 38.00, PathPointTypeLine
, 0, 0} /*12*/
550 static void test_linei(void)
555 GdipCreatePath(FillModeAlternate
, &path
);
556 status
= GdipAddPathLineI(path
, 5.0, 5.0, 6.0, 8.0);
558 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
559 status
= GdipAddPathLineI(path
, 15.0, 15.0, 26.0, 28.0);
561 GdipClosePathFigure(path
);
562 status
= GdipAddPathLineI(path
, 35.0, 35.0, 36.0, 38.0);
565 ok_path(path
, linei_path
, sizeof(linei_path
)/sizeof(path_test_t
), FALSE
);
567 GdipDeletePath(path
);
570 static path_test_t poly_path
[] = {
571 {5.00, 5.00, PathPointTypeStart
, 0, 0}, /*1*/
572 {6.00, 8.00, PathPointTypeLine
, 0, 0}, /*2*/
573 {0.00, 0.00, PathPointTypeStart
, 0, 0}, /*3*/
574 {10.00, 10.00, PathPointTypeLine
, 0, 0}, /*4*/
575 {10.00, 20.00, PathPointTypeLine
, 0, 0}, /*5*/
576 {30.00, 10.00, PathPointTypeLine
, 0, 0}, /*6*/
577 {20.00, 0.00, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*7*/
580 static void test_polygon(void)
597 GdipCreatePath(FillModeAlternate
, &path
);
600 status
= GdipAddPathPolygon(NULL
, points
, 5);
601 expect(InvalidParameter
, status
);
602 status
= GdipAddPathPolygon(path
, NULL
, 5);
603 expect(InvalidParameter
, status
);
604 /* Polygon should have 3 points at least */
605 status
= GdipAddPathPolygon(path
, points
, 2);
606 expect(InvalidParameter
, status
);
608 /* to test how it prolongs not empty path */
609 status
= GdipAddPathLine(path
, 5.0, 5.0, 6.0, 8.0);
611 status
= GdipAddPathPolygon(path
, points
, 5);
613 /* check resulting path */
614 ok_path(path
, poly_path
, sizeof(poly_path
)/sizeof(path_test_t
), FALSE
);
616 GdipDeletePath(path
);
619 static path_test_t rect_path
[] = {
620 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
621 {105.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
622 {105.0, 55.0, PathPointTypeLine
, 0, 0}, /*2*/
623 {5.0, 55.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*3*/
625 {100.0, 50.0, PathPointTypeStart
, 0, 0}, /*4*/
626 {220.0, 50.0, PathPointTypeLine
, 0, 0}, /*5*/
627 {220.0, 80.0, PathPointTypeLine
, 0, 0}, /*6*/
628 {100.0, 80.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0} /*7*/
631 static void test_rect(void)
637 GdipCreatePath(FillModeAlternate
, &path
);
638 status
= GdipAddPathRectangle(path
, 5.0, 5.0, 100.0, 50.0);
640 status
= GdipAddPathRectangle(path
, 100.0, 50.0, 120.0, 30.0);
643 ok_path(path
, rect_path
, sizeof(rect_path
)/sizeof(path_test_t
), FALSE
);
645 GdipDeletePath(path
);
647 GdipCreatePath(FillModeAlternate
, &path
);
651 rects
[0].Width
= 100.0;
652 rects
[0].Height
= 50.0;
655 rects
[1].Width
= 120.0;
656 rects
[1].Height
= 30.0;
658 status
= GdipAddPathRectangles(path
, (GDIPCONST GpRectF
*)&rects
, 2);
661 ok_path(path
, rect_path
, sizeof(rect_path
)/sizeof(path_test_t
), FALSE
);
663 GdipDeletePath(path
);
666 static void test_lastpoint(void)
672 GdipCreatePath(FillModeAlternate
, &path
);
673 status
= GdipAddPathRectangle(path
, 5.0, 5.0, 100.0, 50.0);
677 status
= GdipGetPathLastPoint(NULL
, &ptf
);
678 expect(InvalidParameter
, status
);
679 status
= GdipGetPathLastPoint(path
, NULL
);
680 expect(InvalidParameter
, status
);
681 status
= GdipGetPathLastPoint(NULL
, NULL
);
682 expect(InvalidParameter
, status
);
684 status
= GdipGetPathLastPoint(path
, &ptf
);
686 expect(TRUE
, (ptf
.X
== 5.0) && (ptf
.Y
== 55.0));
688 GdipDeletePath(path
);
691 static path_test_t addcurve_path
[] = {
692 {0.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
693 {3.3, 3.3, PathPointTypeBezier
, 0, 0}, /*1*/
694 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*2*/
695 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*3*/
696 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*4*/
697 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*5*/
698 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*6*/
699 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
700 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*8*/
701 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*9*/
703 static path_test_t addcurve_path2
[] = {
704 {100.0,120.0,PathPointTypeStart
, 0, 0}, /*0*/
705 {123.0,10.0, PathPointTypeLine
, 0, 0}, /*1*/
706 {0.0, 0.0, PathPointTypeLine
, 0, 0}, /*2*/
707 {3.3, 3.3, PathPointTypeBezier
, 0, 0}, /*3*/
708 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*4*/
709 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*5*/
710 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*6*/
711 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
712 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*8*/
713 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*9*/
714 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*10*/
715 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*11*/
717 static path_test_t addcurve_path3
[] = {
718 {10.0, 10.0, PathPointTypeStart
, 0, 0}, /*0*/
719 {13.3, 16.7, PathPointTypeBezier
, 0, 1}, /*1*/
720 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*2*/
721 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*3*/
722 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*4*/
723 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*5*/
724 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*6*/
726 static void test_addcurve(void)
741 GdipCreatePath(FillModeAlternate
, &path
);
744 status
= GdipAddPathCurve2(NULL
, NULL
, 0, 0.0);
745 expect(InvalidParameter
, status
);
746 status
= GdipAddPathCurve2(path
, NULL
, 0, 0.0);
747 expect(InvalidParameter
, status
);
748 status
= GdipAddPathCurve2(path
, points
, -1, 0.0);
749 expect(InvalidParameter
, status
);
750 status
= GdipAddPathCurve2(path
, points
, 1, 1.0);
751 expect(InvalidParameter
, status
);
753 /* add to empty path */
754 status
= GdipAddPathCurve2(path
, points
, 4, 1.0);
756 ok_path(path
, addcurve_path
, sizeof(addcurve_path
)/sizeof(path_test_t
), FALSE
);
757 GdipDeletePath(path
);
759 /* add to notempty path and opened figure */
760 GdipCreatePath(FillModeAlternate
, &path
);
761 GdipAddPathLine(path
, 100.0, 120.0, 123.0, 10.0);
762 status
= GdipAddPathCurve2(path
, points
, 4, 1.0);
764 ok_path(path
, addcurve_path2
, sizeof(addcurve_path2
)/sizeof(path_test_t
), FALSE
);
768 status
= GdipAddPathCurve3(NULL
, NULL
, 0, 0, 0, 0.0);
769 expect(InvalidParameter
, status
);
770 status
= GdipAddPathCurve3(path
, NULL
, 0, 0, 0, 0.0);
771 expect(InvalidParameter
, status
);
772 /* wrong count, offset.. */
773 status
= GdipAddPathCurve3(path
, points
, 0, 0, 0, 0.0);
774 expect(InvalidParameter
, status
);
775 status
= GdipAddPathCurve3(path
, points
, 4, 0, 0, 0.0);
776 expect(InvalidParameter
, status
);
777 status
= GdipAddPathCurve3(path
, points
, 4, 0, 4, 0.0);
778 expect(InvalidParameter
, status
);
779 status
= GdipAddPathCurve3(path
, points
, 4, 1, 3, 0.0);
780 expect(InvalidParameter
, status
);
781 status
= GdipAddPathCurve3(path
, points
, 4, 1, 0, 0.0);
782 expect(InvalidParameter
, status
);
783 status
= GdipAddPathCurve3(path
, points
, 4, 3, 1, 0.0);
784 expect(InvalidParameter
, status
);
787 status
= GdipAddPathCurve3(path
, points
, 4, 0, 3, 1.0);
789 ok_path(path
, addcurve_path
, sizeof(addcurve_path
)/sizeof(path_test_t
), FALSE
);
792 status
= GdipAddPathCurve3(path
, points
, 4, 1, 2, 1.0);
794 ok_path(path
, addcurve_path3
, sizeof(addcurve_path3
)/sizeof(path_test_t
), FALSE
);
796 GdipDeletePath(path
);
799 static path_test_t addclosedcurve_path
[] = {
800 {0.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
801 {-6.7, 0.0, PathPointTypeBezier
, 0, 0}, /*1*/
802 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*2*/
803 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*3*/
804 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*4*/
805 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*5*/
806 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*6*/
807 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
808 {33.3, 16.7, PathPointTypeBezier
, 0, 0}, /*8*/
809 {30.0, 10.0, PathPointTypeBezier
, 0, 0}, /*9*/
810 {26.7, 3.3, PathPointTypeBezier
, 0, 0}, /*10*/
811 {6.7, 0.0, PathPointTypeBezier
, 0, 0}, /*11*/
812 {0.0, 0.0, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*12*/
814 static void test_addclosedcurve(void)
829 GdipCreatePath(FillModeAlternate
, &path
);
832 status
= GdipAddPathClosedCurve2(NULL
, NULL
, 0, 0.0);
833 expect(InvalidParameter
, status
);
834 status
= GdipAddPathClosedCurve2(path
, NULL
, 0, 0.0);
835 expect(InvalidParameter
, status
);
836 status
= GdipAddPathClosedCurve2(path
, points
, -1, 0.0);
837 expect(InvalidParameter
, status
);
838 status
= GdipAddPathClosedCurve2(path
, points
, 1, 1.0);
839 expect(InvalidParameter
, status
);
841 /* add to empty path */
842 status
= GdipAddPathClosedCurve2(path
, points
, 4, 1.0);
844 ok_path(path
, addclosedcurve_path
, sizeof(addclosedcurve_path
)/sizeof(path_test_t
), FALSE
);
845 GdipDeletePath(path
);
848 static path_test_t reverse_path
[] = {
849 {0.0, 20.0, PathPointTypeStart
, 0, 0}, /*0*/
850 {25.0, 25.0, PathPointTypeLine
, 0, 0}, /*1*/
851 {0.0, 30.0, PathPointTypeLine
, 0, 0}, /*2*/
852 {15.0, 35.0, PathPointTypeStart
, 0, 0}, /*3*/
853 {0.0, 40.0, PathPointTypeLine
, 0, 0}, /*4*/
854 {5.0, 45.0, PathPointTypeLine
, 0, 0}, /*5*/
855 {0.0, 50.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0} /*6*/
858 static void test_reverse(void)
865 for(i
= 0; i
< 7; i
++){
866 pts
[i
].X
= i
* 5.0 * (REAL
)(i
% 2);
867 pts
[i
].Y
= 50.0 - i
* 5.0;
870 GdipCreatePath(FillModeAlternate
, &path
);
873 status
= GdipReversePath(NULL
);
874 expect(InvalidParameter
, status
);
877 status
= GdipReversePath(path
);
880 GdipAddPathLine2(path
, pts
, 4);
881 GdipClosePathFigure(path
);
882 GdipAddPathLine2(path
, &(pts
[4]), 3);
884 status
= GdipReversePath(path
);
886 ok_path(path
, reverse_path
, sizeof(reverse_path
)/sizeof(path_test_t
), FALSE
);
888 GdipDeletePath(path
);
891 static path_test_t addpie_path
[] = {
892 {50.0, 25.0, PathPointTypeStart
, 0, 0}, /*0*/
893 {97.2, 33.3, PathPointTypeLine
, 0, 0}, /*1*/
894 {91.8, 40.9, PathPointTypeBezier
,0, 0}, /*2*/
895 {79.4, 46.8, PathPointTypeBezier
,0, 0}, /*3*/
896 {63.9, 49.0, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*4*/
898 static path_test_t addpie_path2
[] = {
899 {0.0, 30.0, PathPointTypeStart
| PathPointTypeCloseSubpath
, 0, 0} /*0*/
901 static path_test_t addpie_path3
[] = {
902 {30.0, 0.0, PathPointTypeStart
| PathPointTypeCloseSubpath
, 0, 0} /*0*/
904 static void test_addpie(void)
909 GdipCreatePath(FillModeAlternate
, &path
);
912 status
= GdipAddPathPie(NULL
, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
913 expect(InvalidParameter
, status
);
915 status
= GdipAddPathPie(path
, 0.0, 0.0, 100.0, 50.0, 10.0, 50.0);
917 ok_path(path
, addpie_path
, sizeof(addpie_path
)/sizeof(path_test_t
), FALSE
);
918 status
= GdipResetPath(path
);
921 /* zero width base ellipse */
922 status
= GdipAddPathPie(path
, 0.0, 0.0, 0.0, 60.0, -90.0, 24.0);
923 expect(InvalidParameter
, status
);
924 ok_path(path
, addpie_path2
, sizeof(addpie_path2
)/sizeof(path_test_t
), FALSE
);
925 status
= GdipResetPath(path
);
928 /* zero height base ellipse */
929 status
= GdipAddPathPie(path
, 0.0, 0.0, 60.0, 0.0 , -90.0, 24.0);
930 expect(InvalidParameter
, status
);
931 ok_path(path
, addpie_path3
, sizeof(addpie_path3
)/sizeof(path_test_t
), FALSE
);
933 GdipDeletePath(path
);
936 static path_test_t flattenellipse_path
[] = {
937 {100.0, 25.0,PathPointTypeStart
, 0, 0}, /*0*/
938 {99.0, 30.0, PathPointTypeLine
, 0, 0}, /*1*/
939 {96.0, 34.8, PathPointTypeLine
, 0, 0}, /*2*/
940 {91.5, 39.0, PathPointTypeLine
, 0, 0}, /*3*/
941 {85.5, 42.8, PathPointTypeLine
, 0, 0}, /*4*/
942 {69.5, 48.0, PathPointTypeLine
, 0, 1}, /*5*/
943 {50.0, 50.0, PathPointTypeLine
, 0, 1}, /*6*/
944 {30.5, 48.0, PathPointTypeLine
, 0, 1}, /*7*/
945 {14.8, 42.8, PathPointTypeLine
, 0, 1}, /*8*/
946 {8.5, 39.0, PathPointTypeLine
, 0, 1}, /*9*/
947 {4.0, 34.8, PathPointTypeLine
, 0, 1}, /*10*/
948 {1.0, 30.0, PathPointTypeLine
, 0, 1}, /*11*/
949 {0.0, 25.0, PathPointTypeLine
, 0, 1}, /*12*/
950 {1.0, 20.0, PathPointTypeLine
, 0, 1}, /*13*/
951 {4.0, 15.3, PathPointTypeLine
, 0, 1}, /*14*/
952 {8.5, 11.0, PathPointTypeLine
, 0, 1}, /*15*/
953 {14.8, 7.3, PathPointTypeLine
, 0, 1}, /*16*/
954 {30.5, 2.0, PathPointTypeLine
, 0, 1}, /*17*/
955 {50.0, 0.0, PathPointTypeLine
, 0, 1}, /*18*/
956 {69.5, 2.0, PathPointTypeLine
, 0, 1}, /*19*/
957 {85.5, 7.3, PathPointTypeLine
, 0, 1}, /*20*/
958 {91.5, 11.0, PathPointTypeLine
, 0, 1}, /*21*/
959 {96.0, 15.3, PathPointTypeLine
, 0, 1}, /*22*/
960 {99.0, 20.0, PathPointTypeLine
, 0, 1}, /*23*/
961 {100.0,25.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 1} /*24*/
964 static path_test_t flattenline_path
[] = {
965 {5.0, 10.0,PathPointTypeStart
, 0, 0}, /*0*/
966 {50.0, 100.0, PathPointTypeLine
, 0, 0} /*1*/
969 static path_test_t flattenarc_path
[] = {
970 {100.0, 25.0,PathPointTypeStart
, 0, 0}, /*0*/
971 {99.0, 30.0, PathPointTypeLine
, 0, 0}, /*1*/
972 {96.0, 34.8, PathPointTypeLine
, 0, 0}, /*2*/
973 {91.5, 39.0, PathPointTypeLine
, 0, 0}, /*3*/
974 {85.5, 42.8, PathPointTypeLine
, 0, 0}, /*4*/
975 {69.5, 48.0, PathPointTypeLine
, 0, 1}, /*5*/
976 {50.0, 50.0, PathPointTypeLine
, 0, 1} /*6*/
979 static path_test_t flattenquater_path
[] = {
980 {100.0, 50.0,PathPointTypeStart
, 0, 0}, /*0*/
981 {99.0, 60.0, PathPointTypeLine
, 0, 0}, /*1*/
982 {96.0, 69.5, PathPointTypeLine
, 0, 0}, /*2*/
983 {91.5, 78.0, PathPointTypeLine
, 0, 0}, /*3*/
984 {85.5, 85.5, PathPointTypeLine
, 0, 0}, /*4*/
985 {78.0, 91.5, PathPointTypeLine
, 0, 0}, /*5*/
986 {69.5, 96.0, PathPointTypeLine
, 0, 0}, /*6*/
987 {60.0, 99.0, PathPointTypeLine
, 0, 0}, /*7*/
988 {50.0, 100.0,PathPointTypeLine
, 0, 0} /*8*/
991 static void test_flatten(void)
997 status
= GdipCreatePath(FillModeAlternate
, &path
);
999 status
= GdipCreateMatrix(&m
);
1002 /* NULL arguments */
1003 status
= GdipFlattenPath(NULL
, NULL
, 0.0);
1004 expect(InvalidParameter
, status
);
1005 status
= GdipFlattenPath(NULL
, m
, 0.0);
1006 expect(InvalidParameter
, status
);
1008 /* flatten empty path */
1009 status
= GdipFlattenPath(path
, NULL
, 1.0);
1012 status
= GdipTransformPath(path
, 0);
1015 status
= GdipAddPathEllipse(path
, 0.0, 0.0, 100.0, 50.0);
1018 status
= GdipFlattenPath(path
, NULL
, 1.0);
1020 ok_path(path
, flattenellipse_path
, sizeof(flattenellipse_path
)/sizeof(path_test_t
), TRUE
);
1022 status
= GdipResetPath(path
);
1024 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 100.0);
1026 status
= GdipFlattenPath(path
, NULL
, 1.0);
1028 ok_path(path
, flattenline_path
, sizeof(flattenline_path
)/sizeof(path_test_t
), FALSE
);
1030 status
= GdipResetPath(path
);
1032 status
= GdipAddPathArc(path
, 0.0, 0.0, 100.0, 50.0, 0.0, 90.0);
1034 status
= GdipFlattenPath(path
, NULL
, 1.0);
1036 ok_path(path
, flattenarc_path
, sizeof(flattenarc_path
)/sizeof(path_test_t
), TRUE
);
1038 /* easy case - quater of a full circle */
1039 status
= GdipResetPath(path
);
1041 status
= GdipAddPathArc(path
, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1043 status
= GdipFlattenPath(path
, NULL
, 1.0);
1045 ok_path(path
, flattenquater_path
, sizeof(flattenquater_path
)/sizeof(path_test_t
), FALSE
);
1047 GdipDeleteMatrix(m
);
1048 GdipDeletePath(path
);
1051 static path_test_t widenline_path
[] = {
1052 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1053 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1054 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1055 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1058 static path_test_t widenline_wide_path
[] = {
1059 {5.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
1060 {50.0, 0.0, PathPointTypeLine
, 0, 0}, /*1*/
1061 {50.0, 20.0, PathPointTypeLine
, 0, 0}, /*2*/
1062 {5.0, 20.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1065 static path_test_t widenline_dash_path
[] = {
1066 {5.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
1067 {35.0, 0.0, PathPointTypeLine
, 0, 0}, /*1*/
1068 {35.0, 10.0, PathPointTypeLine
, 0, 0}, /*2*/
1069 {5.0, 10.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1070 {45.0, 0.0, PathPointTypeStart
, 0, 0}, /*4*/
1071 {50.0, 0.0, PathPointTypeLine
, 0, 0}, /*5*/
1072 {50.0, 10.0, PathPointTypeLine
, 0, 0}, /*6*/
1073 {45.0, 10.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1076 static void test_widen(void)
1084 status
= GdipCreatePath(FillModeAlternate
, &path
);
1086 status
= GdipCreatePen1(0xffffffff, 10.0, UnitPixel
, &pen
);
1088 status
= GdipCreateMatrix(&m
);
1091 /* NULL arguments */
1092 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1094 status
= GdipWidenPath(NULL
, NULL
, NULL
, 0.0);
1095 expect(InvalidParameter
, status
);
1096 status
= GdipWidenPath(path
, pen
, m
, 0.0);
1098 status
= GdipWidenPath(path
, pen
, NULL
, 1.0);
1100 status
= GdipWidenPath(path
, NULL
, m
, 1.0);
1101 expect(InvalidParameter
, status
);
1102 status
= GdipWidenPath(NULL
, pen
, m
, 1.0);
1103 expect(InvalidParameter
, status
);
1105 /* widen empty path */
1106 status
= GdipResetPath(path
);
1108 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1109 expect(OutOfMemory
, status
);
1111 /* horizontal line */
1112 status
= GdipResetPath(path
);
1114 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1117 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1119 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1121 /* horizontal 2x stretch */
1122 status
= GdipResetPath(path
);
1124 status
= GdipAddPathLine(path
, 2.5, 10.0, 25.0, 10.0);
1127 status
= GdipScaleMatrix(m
, 2.0, 1.0, MatrixOrderAppend
);
1130 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1132 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1134 /* vertical 2x stretch */
1135 status
= GdipResetPath(path
);
1137 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1140 status
= GdipScaleMatrix(m
, 0.5, 2.0, MatrixOrderAppend
);
1143 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1145 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1147 status
= GdipScaleMatrix(m
, 1.0, 0.5, MatrixOrderAppend
);
1151 status
= GdipResetPath(path
);
1153 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1156 status
= GdipSetPenDashStyle(pen
, DashStyleDash
);
1159 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1161 ok_path(path
, widenline_dash_path
, sizeof(widenline_dash_path
)/sizeof(path_test_t
), FALSE
);
1163 status
= GdipSetPenDashStyle(pen
, DashStyleSolid
);
1166 /* pen width in UnitWorld */
1168 status
= GdipCreatePen1(0xffffffff, 10.0, UnitWorld
, &pen
);
1171 status
= GdipResetPath(path
);
1173 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1176 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1178 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1180 /* horizontal 2x stretch */
1181 status
= GdipResetPath(path
);
1183 status
= GdipAddPathLine(path
, 2.5, 10.0, 25.0, 10.0);
1186 status
= GdipScaleMatrix(m
, 2.0, 1.0, MatrixOrderAppend
);
1189 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1191 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1193 /* vertical 2x stretch */
1194 status
= GdipResetPath(path
);
1196 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1199 status
= GdipScaleMatrix(m
, 0.5, 2.0, MatrixOrderAppend
);
1202 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1204 ok_path(path
, widenline_wide_path
, sizeof(widenline_wide_path
)/sizeof(path_test_t
), FALSE
);
1206 status
= GdipScaleMatrix(m
, 1.0, 0.5, MatrixOrderAppend
);
1209 /* pen width in UnitInch */
1211 status
= GdipCreatePen1(0xffffffff, 10.0, UnitWorld
, &pen
);
1214 status
= GdipResetPath(path
);
1216 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1219 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1221 ok_path(path
, widenline_path
, sizeof(widenline_path
)/sizeof(path_test_t
), FALSE
);
1223 /* pen width = 0 pixels - native fails to widen but can draw with this pen */
1225 status
= GdipCreatePen1(0xffffffff, 0.0, UnitPixel
, &pen
);
1228 status
= GdipResetPath(path
);
1230 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1233 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1236 status
= GdipGetPointCount(path
, &count
);
1238 todo_wine
expect(0, count
);
1240 GdipDeleteMatrix(m
);
1242 GdipDeletePath(path
);
1245 static void test_isvisible(void)
1248 GpGraphics
*graphics
= NULL
;
1253 status
= GdipCreateFromHDC(hdc
, &graphics
);
1255 status
= GdipCreatePath(FillModeAlternate
, &path
);
1259 status
= GdipIsVisiblePathPoint(NULL
, 0.0, 0.0, NULL
, NULL
);
1260 expect(InvalidParameter
, status
);
1261 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, NULL
);
1262 expect(InvalidParameter
, status
);
1263 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, NULL
);
1264 expect(InvalidParameter
, status
);
1265 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, graphics
, NULL
);
1266 expect(InvalidParameter
, status
);
1270 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, &result
);
1272 expect(FALSE
, result
);
1274 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 10.0, 10.0);
1277 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, &result
);
1279 expect(TRUE
, result
);
1281 status
= GdipIsVisiblePathPoint(path
, 11.0, 11.0, NULL
, &result
);
1283 expect(FALSE
, result
);
1284 /* not affected by clipping */
1285 status
= GdipSetClipRect(graphics
, 5.0, 5.0, 5.0, 5.0, CombineModeReplace
);
1288 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, graphics
, &result
);
1290 expect(TRUE
, result
);
1292 GdipDeletePath(path
);
1293 GdipDeleteGraphics(graphics
);
1297 static void test_empty_rect(void)
1303 status
= GdipCreatePath(FillModeAlternate
, &path
);
1306 status
= GdipAddPathRectangle(path
, 0.0, 0.0, -5.0, 5.0);
1309 status
= GdipIsVisiblePathPoint(path
, -2.0, 2.0, NULL
, &result
);
1311 expect(FALSE
, status
);
1313 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 5.0, -5.0);
1316 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 0.0, 5.0);
1319 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 5.0, 0.0);
1322 GdipDeletePath(path
);
1325 START_TEST(graphicspath
)
1327 struct GdiplusStartupInput gdiplusStartupInput
;
1328 ULONG_PTR gdiplusToken
;
1330 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
1332 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1333 hmsvcrt
= LoadLibraryA("msvcrt");
1334 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
1335 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
1337 gdiplusStartupInput
.GdiplusVersion
= 1;
1338 gdiplusStartupInput
.DebugEventCallback
= NULL
;
1339 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
1340 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
1342 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
1344 test_constructor_destructor();
1356 test_addclosedcurve();
1364 GdiplusShutdown(gdiplusToken
);