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 #include "wine/test.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
)
34 switch(type
& PathPointTypePathTypeMask
){
35 case PathPointTypeStart
:
36 strcat(name
, "PathPointTypeStart");
38 case PathPointTypeLine
:
39 strcat(name
, "PathPointTypeLine");
41 case PathPointTypeBezier
:
42 strcat(name
, "PathPointTypeBezier");
45 strcat(name
, "Unknown type");
49 type
&= ~PathPointTypePathTypeMask
;
50 if(type
& ~((PathPointTypePathMarker
| PathPointTypeCloseSubpath
))){
52 strcat(name
, "Unknown type");
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 */
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. */
78 #define ok_path(a,b,c,d) _ok_path_fudge(a,b,c,d,2.0,__LINE__)
79 #define ok_path_fudge(a,b,c,d,e) _ok_path_fudge(a,b,c,d,e,__LINE__)
80 static void _ok_path_fudge(GpPath
* path
, const path_test_t
*expected
, INT expected_size
,
81 BOOL todo_size
, REAL fudge
, int line
)
84 INT size
, idx
= 0, eidx
= 0, numskip
;
86 char ename
[POINT_TYPE_MAX_LEN
], name
[POINT_TYPE_MAX_LEN
];
88 if(GdipGetPointCount(path
, &size
) != Ok
){
89 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
93 todo_wine_if (todo_size
)
94 ok_(__FILE__
,line
)(size
== expected_size
, "Path size %d does not match expected size %d\n",
97 points
= HeapAlloc(GetProcessHeap(), 0, size
* sizeof(GpPointF
));
98 types
= HeapAlloc(GetProcessHeap(), 0, size
);
100 if(GdipGetPathPoints(path
, points
, size
) != Ok
|| GdipGetPathTypes(path
, types
, size
) != Ok
){
101 skip("Cannot perform path comparisons due to failure to retrieve path.\n");
105 numskip
= expected_size
? expected
[eidx
].wine_only_entries_preceding
: 0;
106 while (idx
< size
&& eidx
< expected_size
){
107 /* We allow a few pixels fudge in matching X and Y coordinates to account for imprecision in
108 * floating point to integer conversion */
109 BOOL match
= (types
[idx
] == expected
[eidx
].type
) &&
110 fabs(points
[idx
].X
- expected
[eidx
].X
) <= fudge
&&
111 fabs(points
[idx
].Y
- expected
[eidx
].Y
) <= fudge
;
113 stringify_point_type(expected
[eidx
].type
, ename
);
114 stringify_point_type(types
[idx
], name
);
116 todo_wine_if (expected
[eidx
].todo
|| numskip
)
117 ok_(__FILE__
,line
)(match
, "Expected #%d: %s (%.1f,%.1f) but got %s (%.1f,%.1f)\n", eidx
,
118 ename
, expected
[eidx
].X
, expected
[eidx
].Y
,
119 name
, points
[idx
].X
, points
[idx
].Y
);
121 if (match
|| expected
[eidx
].todo
!= 2)
123 if (match
|| !numskip
--)
124 numskip
= expected
[++eidx
].wine_only_entries_preceding
;
128 HeapFree(GetProcessHeap(), 0, types
);
129 HeapFree(GetProcessHeap(), 0, points
);
132 static void test_constructor_destructor(void)
137 status
= GdipCreatePath(FillModeAlternate
, &path
);
139 ok(path
!= NULL
, "Expected path to be initialized\n");
141 status
= GdipDeletePath(NULL
);
142 expect(InvalidParameter
, status
);
144 status
= GdipDeletePath(path
);
148 static void test_getpathdata(void)
155 status
= GdipCreatePath(FillModeAlternate
, &path
);
157 status
= GdipAddPathLine(path
, 5.0, 5.0, 100.0, 50.0);
160 status
= GdipGetPointCount(path
, &count
);
165 data
.Types
= GdipAlloc(sizeof(BYTE
) * count
);
166 data
.Points
= GdipAlloc(sizeof(PointF
) * count
);
168 status
= GdipGetPathData(path
, &data
);
170 expect((data
.Points
[0].X
== 5.0) && (data
.Points
[0].Y
== 5.0) &&
171 (data
.Points
[1].X
== 100.0) && (data
.Points
[1].Y
== 50.0), TRUE
);
172 expect((data
.Types
[0] == PathPointTypeStart
) && (data
.Types
[1] == PathPointTypeLine
), TRUE
);
174 GdipFree(data
.Points
);
175 GdipFree(data
.Types
);
176 GdipDeletePath(path
);
179 static void test_createpath2(void)
184 INT i
, count
, expect_count
;
186 PointF test_line_points
[] = {{1.0,1.0}, {2.0,1.0}, {2.0,2.0}};
187 BYTE test_line_types
[] = {PathPointTypeStart
, PathPointTypeLine
, PathPointTypeStart
};
189 PointF test_bez_points
[] = {{1.0,1.0}, {2.0,1.0}, {3.0,1.0}, {4.0,1.0},
190 {5.0,1.0}, {6.0,1.0}, {7.0,1.0}};
191 BYTE test_bez_types
[] = {PathPointTypeStart
, PathPointTypeBezier
,
192 PathPointTypeBezier
, PathPointTypeBezier
, PathPointTypeBezier
,
193 PathPointTypeBezier
, PathPointTypeBezier
};
195 status
= GdipCreatePath2(test_line_points
, test_line_types
, 2, FillModeAlternate
, &path
);
197 status
= GdipGetPointCount(path
, &count
);
200 GdipDeletePath(path
);
202 status
= GdipCreatePath2(test_line_points
, test_line_types
, 1, FillModeAlternate
, &path
);
204 status
= GdipGetPointCount(path
, &count
);
207 GdipDeletePath(path
);
209 path
= (void *)0xdeadbeef;
210 status
= GdipCreatePath2(test_line_points
, test_line_types
, 0, FillModeAlternate
, &path
);
211 expect(OutOfMemory
, status
);
212 ok(!path
, "Expected NULL, got %p\n", path
);
213 if(path
&& path
!= (void *)0xdeadbeef)
214 GdipDeletePath(path
);
216 path
= (void *)0xdeadbeef;
217 status
= GdipCreatePath2(test_line_points
, test_line_types
, -1, FillModeAlternate
, &path
);
218 expect(OutOfMemory
, status
);
219 ok(!path
, "Expected NULL, got %p\n", path
);
220 if(path
&& path
!= (void *)0xdeadbeef)
221 GdipDeletePath(path
);
223 path
= (void *)0xdeadbeef;
224 status
= GdipCreatePath2(NULL
, test_line_types
, 2, FillModeAlternate
, &path
);
225 expect(InvalidParameter
, status
);
226 ok(path
== (void *)0xdeadbeef, "Expected %p, got %p\n", (void *)0xdeadbeef, path
);
227 if(path
&& path
!= (void *)0xdeadbeef)
228 GdipDeletePath(path
);
230 path
= (void *)0xdeadbeef;
231 status
= GdipCreatePath2(test_line_points
, NULL
, 2, FillModeAlternate
, &path
);
232 expect(InvalidParameter
, status
);
233 ok(path
== (void *)0xdeadbeef, "Expected %p, got %p\n", (void *)0xdeadbeef, path
);
234 if(path
&& path
!= (void *)0xdeadbeef)
235 GdipDeletePath(path
);
237 status
= GdipCreatePath2(test_line_points
, test_line_types
, 2, FillModeAlternate
, NULL
);
238 expect(InvalidParameter
, status
);
240 /* Multi-point paths should not end with Start */
241 status
= GdipCreatePath2(test_line_points
, test_line_types
, 3, FillModeAlternate
, &path
);
243 status
= GdipGetPointCount(path
, &count
);
246 GdipDeletePath(path
);
248 /* Zero-length line points do not get altered */
249 test_line_points
[1].X
= test_line_points
[0].X
;
250 test_line_points
[1].Y
= test_line_points
[0].Y
;
251 status
= GdipCreatePath2(test_line_points
, test_line_types
, 2, FillModeAlternate
, &path
);
253 status
= GdipGetPointCount(path
, &count
);
256 GdipDeletePath(path
);
258 /* The type of the first point is always converted to PathPointTypeStart */
259 test_line_types
[0] = PathPointTypeLine
;
260 status
= GdipCreatePath2(test_line_points
, test_line_types
, 1, FillModeAlternate
, &path
);
262 status
= GdipGetPointCount(path
, &count
);
266 data
.Types
= GdipAlloc(sizeof(BYTE
) * count
);
267 data
.Points
= GdipAlloc(sizeof(PointF
) * count
);
268 status
= GdipGetPathData(path
, &data
);
270 expect((data
.Points
[0].X
== 1.0) && (data
.Points
[0].Y
== 1.0), TRUE
);
271 expect(data
.Types
[0], PathPointTypeStart
);
272 GdipFree(data
.Points
);
273 GdipFree(data
.Types
);
274 GdipDeletePath(path
);
276 /* Bezier points must come in groups of three */
277 for(i
= 2; i
<= 7; i
++) {
278 expect_count
= (i
% 3 == 1) ? i
: 0;
279 status
= GdipCreatePath2(test_bez_points
, test_bez_types
, i
, FillModeAlternate
, &path
);
281 status
= GdipGetPointCount(path
, &count
);
283 expect(expect_count
, count
);
284 GdipDeletePath(path
);
288 static path_test_t line2_path
[] = {
289 {0.0, 50.0, PathPointTypeStart
, 0, 0}, /*0*/
290 {5.0, 45.0, PathPointTypeLine
, 0, 0}, /*1*/
291 {0.0, 40.0, PathPointTypeLine
, 0, 0}, /*2*/
292 {15.0, 35.0, PathPointTypeLine
, 0, 0}, /*3*/
293 {0.0, 30.0, PathPointTypeLine
, 0, 0}, /*4*/
294 {25.0, 25.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*5*/
295 {0.0, 20.0, PathPointTypeStart
, 0, 0}, /*6*/
296 {35.0, 15.0, PathPointTypeLine
, 0, 0}, /*7*/
297 {0.0, 10.0, PathPointTypeLine
, 0, 0} /*8*/
300 static void test_line2(void)
305 GpPointF line2_points
[9];
307 for(i
= 0; i
< 9; i
++){
308 line2_points
[i
].X
= i
* 5.0 * (REAL
)(i
% 2);
309 line2_points
[i
].Y
= 50.0 - i
* 5.0;
312 GdipCreatePath(FillModeAlternate
, &path
);
314 status
= GdipAddPathLine2(NULL
, line2_points
, 2);
315 expect(InvalidParameter
, status
);
316 status
= GdipAddPathLine2(path
, NULL
, 2);
317 expect(InvalidParameter
, status
);
318 status
= GdipAddPathLine2(path
, line2_points
, 0);
319 expect(InvalidParameter
, status
);
320 status
= GdipAddPathLine2(path
, line2_points
, -1);
321 expect(InvalidParameter
, status
);
323 status
= GdipAddPathLine2(path
, line2_points
, 3);
325 status
= GdipAddPathLine2(path
, &(line2_points
[3]), 3);
327 status
= GdipClosePathFigure(path
);
329 status
= GdipAddPathLine2(path
, &(line2_points
[6]), 3);
332 ok_path(path
, line2_path
, ARRAY_SIZE(line2_path
), FALSE
);
335 status
= GdipAddPathLine2(path
, line2_points
, 3);
337 status
= GdipAddPathLine2(path
, &(line2_points
[2]), 3);
340 ok_path(path
, line2_path
, 5, FALSE
);
342 GdipDeletePath(path
);
345 static path_test_t bezier_path
[] = {
346 {10.0, 10.0, PathPointTypeStart
, 0, 0}, /*0*/
347 {20.0, 10.0, PathPointTypeBezier
, 0, 0}, /*1*/
348 {20.0, 20.0, PathPointTypeBezier
, 0, 0}, /*2*/
349 {30.0, 20.0, PathPointTypeBezier
, 0, 0}, /*3*/
350 {40.0, 20.0, PathPointTypeBezier
, 0, 0}, /*4*/
351 {40.0, 30.0, PathPointTypeBezier
, 0, 0}, /*5*/
352 {50.0, 30.0, PathPointTypeBezier
, 0, 0}, /*6*/
353 {50.0, 10.0, PathPointTypeLine
, 0, 0}, /*7*/
354 {60.0, 10.0, PathPointTypeBezier
, 0, 0}, /*8*/
355 {60.0, 20.0, PathPointTypeBezier
, 0, 0}, /*9*/
356 {70.0, 20.0, PathPointTypeBezier
, 0, 0} /*10*/
359 static void test_bezier(void)
364 GdipCreatePath(FillModeAlternate
, &path
);
366 status
= GdipAddPathBezier(path
, 10.0, 10.0, 20.0, 10.0, 20.0, 20.0, 30.0, 20.0);
368 status
= GdipAddPathBezier(path
, 30.0, 20.0, 40.0, 20.0, 40.0, 30.0, 50.0, 30.0);
370 status
= GdipAddPathBezier(path
, 50.0, 10.0, 60.0, 10.0, 60.0, 20.0, 70.0, 20.0);
373 ok_path(path
, bezier_path
, ARRAY_SIZE(bezier_path
), FALSE
);
375 GdipDeletePath(path
);
378 static void test_beziers(void)
382 PointF bezier_points1
[] = {{10.0,10.0}, {20.0,10.0}, {20.0,20.0}, {30.0,20.0}};
383 PointF bezier_points2
[] = {{30.0,20.0}, {40.0,20.0}, {40.0,30.0}, {50.0,30.0}};
384 PointF bezier_points3
[] = {{50.0,10.0}, {60.0,10.0}, {60.0,20.0}, {70.0,20.0}};
386 GdipCreatePath(FillModeAlternate
, &path
);
388 status
= GdipAddPathBeziers(path
, bezier_points1
, 4);
390 status
= GdipAddPathBeziers(path
, bezier_points2
, 4);
392 status
= GdipAddPathBeziers(path
, bezier_points3
, 4);
395 ok_path(path
, bezier_path
, ARRAY_SIZE(bezier_path
), FALSE
);
397 GdipDeletePath(path
);
400 static path_test_t arc_path
[] = {
401 {600.0, 450.0, PathPointTypeStart
, 0, 0}, /*0*/
402 {600.0, 643.3, PathPointTypeBezier
, 0, 0}, /*1*/
403 {488.1, 800.0, PathPointTypeBezier
, 0, 0}, /*2*/
404 {350.0, 800.0, PathPointTypeBezier
, 0, 0}, /*3*/
405 {600.0, 450.0, PathPointTypeLine
, 0, 0}, /*4*/
406 {600.0, 643.3, PathPointTypeBezier
, 0, 0}, /*5*/
407 {488.1, 800.0, PathPointTypeBezier
, 0, 0}, /*6*/
408 {350.0, 800.0, PathPointTypeBezier
, 0, 0}, /*7*/
409 {329.8, 800.0, PathPointTypeBezier
, 0, 0}, /*8*/
410 {309.7, 796.6, PathPointTypeBezier
, 0, 0}, /*9*/
411 {290.1, 789.8, PathPointTypeBezier
, 0, 0}, /*10*/
412 {409.9, 110.2, PathPointTypeLine
, 0, 0}, /*11*/
413 {544.0, 156.5, PathPointTypeBezier
, 0, 0}, /*12*/
414 {625.8, 346.2, PathPointTypeBezier
, 0, 0}, /*13*/
415 {592.7, 533.9, PathPointTypeBezier
, 0, 0}, /*14*/
416 {592.5, 535.3, PathPointTypeBezier
, 0, 0}, /*15*/
417 {592.2, 536.7, PathPointTypeBezier
, 0, 0}, /*16*/
418 {592.0, 538.1, PathPointTypeBezier
, 0, 0}, /*17*/
419 {409.9, 789.8, PathPointTypeLine
, 0, 0}, /*18*/
420 {544.0, 743.5, PathPointTypeBezier
, 0, 0}, /*19*/
421 {625.8, 553.8, PathPointTypeBezier
, 0, 0}, /*20*/
422 {592.7, 366.1, PathPointTypeBezier
, 0, 0}, /*21*/
423 {592.5, 364.7, PathPointTypeBezier
, 0, 0}, /*22*/
424 {592.2, 363.3, PathPointTypeBezier
, 0, 0}, /*23*/
425 {592.0, 361.9, PathPointTypeBezier
, 0, 0}, /*24*/
426 {540.4, 676.9, PathPointTypeLine
, 0, 0}, /*25*/
427 {629.9, 529.7, PathPointTypeBezier
, 0, 0}, /*26*/
428 {617.2, 308.8, PathPointTypeBezier
, 0, 0}, /*27*/
429 {512.1, 183.5, PathPointTypeBezier
, 0, 0}, /*28*/
430 {406.9, 58.2, PathPointTypeBezier
, 0, 0}, /*29*/
431 {249.1, 75.9, PathPointTypeBezier
, 0, 0}, /*30*/
432 {159.6, 223.1, PathPointTypeBezier
, 0, 0}, /*31*/
433 {70.1, 370.3, PathPointTypeBezier
, 0, 0}, /*32*/
434 {82.8, 591.2, PathPointTypeBezier
, 0, 0}, /*33*/
435 {187.9, 716.5, PathPointTypeBezier
, 0, 0}, /*34*/
436 {293.1, 841.8, PathPointTypeBezier
, 0, 0}, /*35*/
437 {450.9, 824.1, PathPointTypeBezier
, 0, 0}, /*36*/
438 {540.4, 676.9, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 1} /*37*/
440 static path_test_t arc_path2
[] = {
441 {1.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
442 {1.0, 0.5, PathPointTypeLine
, 0, 0}, /*1*/
443 {1.0, 0.776142, PathPointTypeBezier
, 0, 0}, /*2*/
444 {0.776142, 1.0, PathPointTypeBezier
, 0, 0}, /*3*/
445 {0.5, 1.0, PathPointTypeBezier
, 0, 0} /*4*/
448 static void test_arc(void)
453 GdipCreatePath(FillModeAlternate
, &path
);
454 /* Exactly 90 degrees */
455 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
457 /* Over 90 degrees */
458 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
460 /* Negative start angle */
461 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
463 /* Negative sweep angle */
464 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 80.0, -100.0);
466 /* More than a full revolution */
467 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 50.0, -400.0);
470 status
= GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 50.0, 0.0);
473 ok_path(path
, arc_path
, ARRAY_SIZE(arc_path
), FALSE
);
476 GdipAddPathLine(path
, 1.0, 0.0, 1.0, 0.5);
477 status
= GdipAddPathArc(path
, 0.0, 0.0, 1.0, 1.0, 0.0, 90.0);
480 ok_path_fudge(path
, arc_path2
, ARRAY_SIZE(arc_path2
), FALSE
, 0.000005);
482 GdipDeletePath(path
);
485 static void test_worldbounds(void)
492 GpPointF line2_points
[10];
495 for(i
= 0; i
< 10; i
++){
496 line2_points
[i
].X
= 200.0 + i
* 50.0 * (i
% 2);
497 line2_points
[i
].Y
= 200.0 + i
* 50.0 * !(i
% 2);
499 GdipCreatePen1((ARGB
)0xdeadbeef, 20.0, UnitWorld
, &pen
);
500 GdipSetPenEndCap(pen
, LineCapSquareAnchor
);
501 GdipCreateMatrix2(1.5, 0.0, 1.0, 1.2, 10.4, 10.2, &matrix
);
503 GdipCreatePath(FillModeAlternate
, &path
);
504 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
505 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
506 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, NULL
);
508 GdipDeletePath(path
);
510 expectf(200.0, bounds
.X
);
511 expectf(200.0, bounds
.Y
);
512 expectf(450.0, bounds
.Width
);
513 expectf(600.0, bounds
.Height
);
515 GdipCreatePath(FillModeAlternate
, &path
);
516 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
517 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
518 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, NULL
);
520 GdipDeletePath(path
);
522 expectf(510.4, bounds
.X
);
523 expectf(250.2, bounds
.Y
);
524 expectf(1275.0, bounds
.Width
);
525 expectf(720.0, bounds
.Height
);
527 GdipCreatePath(FillModeAlternate
, &path
);
528 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
529 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
530 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
532 GdipDeletePath(path
);
534 expectf(100.0, bounds
.X
);
535 expectf(100.0, bounds
.Y
);
536 expectf(650.0, bounds
.Width
);
537 expectf(800.0, bounds
.Height
);
539 GdipCreatePath(FillModeAlternate
, &path
);
540 GdipAddPathLine2(path
, &(line2_points
[0]), 2);
541 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
543 GdipDeletePath(path
);
545 expectf(156.0, bounds
.X
);
546 expectf(156.0, bounds
.Y
);
547 expectf(138.0, bounds
.Width
);
548 expectf(88.0, bounds
.Height
);
550 line2_points
[2].X
= 2 * line2_points
[1].X
- line2_points
[0].X
;
551 line2_points
[2].Y
= 2 * line2_points
[1].Y
- line2_points
[0].Y
;
553 GdipCreatePath(FillModeAlternate
, &path
);
554 GdipAddPathLine2(path
, &(line2_points
[0]), 3);
555 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
557 GdipDeletePath(path
);
559 expectf(100.0, bounds
.X
);
560 expectf(100.0, bounds
.Y
);
561 expectf(300.0, bounds
.Width
);
562 expectf(200.0, bounds
.Height
);
564 GdipCreatePath(FillModeAlternate
, &path
);
565 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 45.0, 20.0);
566 status
= GdipGetPathWorldBounds(path
, &bounds
, NULL
, pen
);
568 GdipDeletePath(path
);
570 expectf(386.7, bounds
.X
);
571 expectf(553.4, bounds
.Y
);
572 expectf(266.8, bounds
.Width
);
573 expectf(289.6, bounds
.Height
);
575 GdipCreatePath(FillModeAlternate
, &path
);
576 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, pen
);
578 GdipDeletePath(path
);
580 expectf(0.0, bounds
.X
);
581 expectf(0.0, bounds
.Y
);
582 expectf(0.0, bounds
.Width
);
583 expectf(0.0, bounds
.Height
);
585 GdipCreatePath(FillModeAlternate
, &path
);
586 GdipAddPathLine2(path
, &(line2_points
[0]), 2);
587 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, pen
);
589 GdipDeletePath(path
);
592 expectf(427.9, bounds
.X
);
593 expectf(167.7, bounds
.Y
);
594 expectf(239.9, bounds
.Width
);
595 expectf(164.9, bounds
.Height
);
598 GdipDeleteMatrix(matrix
);
599 GdipCreateMatrix2(0.9, -0.5, -0.5, -1.2, 10.4, 10.2, &matrix
);
600 GdipCreatePath(FillModeAlternate
, &path
);
601 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, 0.0, 100.0);
602 GdipAddPathLine2(path
, &(line2_points
[0]), 10);
603 status
= GdipGetPathWorldBounds(path
, &bounds
, matrix
, NULL
);
605 GdipDeletePath(path
);
606 GdipDeleteMatrix(matrix
);
608 expectf(-209.6, bounds
.X
);
609 expectf(-1274.8, bounds
.Y
);
610 expectf(705.0, bounds
.Width
);
611 expectf(945.0, bounds
.Height
);
616 static path_test_t pathpath_path
[] = {
617 {600.00, 450.00, PathPointTypeStart
, 0, 0}, /*0*/
618 {600.00, 643.30, PathPointTypeBezier
, 0, 0}, /*1*/
619 {488.07, 800.00, PathPointTypeBezier
, 0, 0}, /*2*/
620 {350.00, 800.00, PathPointTypeBezier
, 0, 0}, /*3*/
621 {319.61, 797.40, PathPointTypeStart
, 0, 0}, /*4*/
622 {182.56, 773.90, PathPointTypeBezier
, 0, 0}, /*5*/
623 {85.07, 599.31, PathPointTypeBezier
, 0, 0}, /*6*/
624 {101.85, 407.45, PathPointTypeBezier
, 0, 0}, /*7*/
625 {102.54, 399.66, PathPointTypeBezier
, 0, 0}, /*8*/
626 {103.40, 391.91, PathPointTypeBezier
, 0, 0}, /*9*/
627 {104.46, 384.21, PathPointTypeBezier
, 0, 0}, /*10*/
628 {409.92, 110.20, PathPointTypeLine
, 0, 0}, /*11*/
629 {543.96, 156.53, PathPointTypeBezier
, 0, 0}, /*12*/
630 {625.80, 346.22, PathPointTypeBezier
, 0, 0}, /*13*/
631 {592.71, 533.88, PathPointTypeBezier
, 0, 0}, /*14*/
632 {592.47, 535.28, PathPointTypeBezier
, 0, 0}, /*15*/
633 {592.22, 536.67, PathPointTypeBezier
, 0, 0}, /*16*/
634 {591.96, 538.06, PathPointTypeBezier
, 0, 0}, /*17*/
635 {319.61, 797.40, PathPointTypeLine
, 0, 0}, /*18*/
636 {182.56, 773.90, PathPointTypeBezier
, 0, 0}, /*19*/
637 {85.07, 599.31, PathPointTypeBezier
, 0, 0}, /*20*/
638 {101.85, 407.45, PathPointTypeBezier
, 0, 0}, /*21*/
639 {102.54, 399.66, PathPointTypeBezier
, 0, 0}, /*22*/
640 {103.40, 391.91, PathPointTypeBezier
, 0, 0}, /*23*/
641 {104.46, 384.21, PathPointTypeBezier
, 0, 0} /*24*/
644 static void test_pathpath(void)
647 GpPath
* path1
, *path2
;
649 GdipCreatePath(FillModeAlternate
, &path2
);
650 GdipAddPathArc(path2
, 100.0, 100.0, 500.0, 700.0, 95.0, 100.0);
652 GdipCreatePath(FillModeAlternate
, &path1
);
653 GdipAddPathArc(path1
, 100.0, 100.0, 500.0, 700.0, 0.0, 90.0);
654 status
= GdipAddPathPath(path1
, path2
, FALSE
);
656 GdipAddPathArc(path1
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
657 status
= GdipAddPathPath(path1
, path2
, TRUE
);
660 ok_path(path1
, pathpath_path
, ARRAY_SIZE(pathpath_path
), FALSE
);
662 GdipDeletePath(path1
);
663 GdipDeletePath(path2
);
666 static path_test_t ellipse_path
[] = {
667 {30.00, 125.25, PathPointTypeStart
, 0, 0}, /*0*/
668 {30.00, 139.20, PathPointTypeBezier
, 0, 0}, /*1*/
669 {25.52, 150.50, PathPointTypeBezier
, 0, 0}, /*2*/
670 {20.00, 150.50, PathPointTypeBezier
, 0, 0}, /*3*/
671 {14.48, 150.50, PathPointTypeBezier
, 0, 0}, /*4*/
672 {10.00, 139.20, PathPointTypeBezier
, 0, 0}, /*5*/
673 {10.00, 125.25, PathPointTypeBezier
, 0, 0}, /*6*/
674 {10.00, 111.30, PathPointTypeBezier
, 0, 0}, /*7*/
675 {14.48, 100.00, PathPointTypeBezier
, 0, 0}, /*8*/
676 {20.00, 100.00, PathPointTypeBezier
, 0, 0}, /*9*/
677 {25.52, 100.00, PathPointTypeBezier
, 0, 0}, /*10*/
678 {30.00, 111.30, PathPointTypeBezier
, 0, 0}, /*11*/
679 {30.00, 125.25, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0}, /*12*/
680 {7.00, 11.00, PathPointTypeStart
, 0, 0}, /*13*/
681 {13.00, 17.00, PathPointTypeLine
, 0, 0}, /*14*/
682 {5.00, 195.00, PathPointTypeStart
, 0, 0}, /*15*/
683 {5.00, 192.24, PathPointTypeBezier
, 0, 0}, /*16*/
684 {6.12, 190.00, PathPointTypeBezier
, 0, 0}, /*17*/
685 {7.50, 190.00, PathPointTypeBezier
, 0, 0}, /*18*/
686 {8.88, 190.00, PathPointTypeBezier
, 0, 0}, /*19*/
687 {10.00, 192.24, PathPointTypeBezier
, 0, 0}, /*20*/
688 {10.00, 195.00, PathPointTypeBezier
, 0, 0}, /*21*/
689 {10.00, 197.76, PathPointTypeBezier
, 0, 0}, /*22*/
690 {8.88, 200.00, PathPointTypeBezier
, 0, 0}, /*23*/
691 {7.50, 200.00, PathPointTypeBezier
, 0, 0}, /*24*/
692 {6.12, 200.00, PathPointTypeBezier
, 0, 0}, /*25*/
693 {5.00, 197.76, PathPointTypeBezier
, 0, 0}, /*26*/
694 {5.00, 195.00, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0}, /*27*/
695 {10.00, 300.50, PathPointTypeStart
, 0, 0}, /*28*/
696 {10.00, 300.78, PathPointTypeBezier
, 0, 0}, /*29*/
697 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*30*/
698 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*31*/
699 {10.00, 301.00, PathPointTypeBezier
, 0, 0}, /*32*/
700 {10.00, 300.78, PathPointTypeBezier
, 0, 0}, /*33*/
701 {10.00, 300.50, PathPointTypeBezier
, 0, 0}, /*34*/
702 {10.00, 300.22, PathPointTypeBezier
, 0, 0}, /*35*/
703 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*36*/
704 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*37*/
705 {10.00, 300.00, PathPointTypeBezier
, 0, 0}, /*38*/
706 {10.00, 300.22, PathPointTypeBezier
, 0, 0}, /*39*/
707 {10.00, 300.50, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*40*/
710 static void test_ellipse(void)
721 GdipCreatePath(FillModeAlternate
, &path
);
722 status
= GdipAddPathEllipse(path
, 10.0, 100.0, 20.0, 50.5);
724 GdipAddPathLine2(path
, points
, 2);
725 status
= GdipAddPathEllipse(path
, 10.0, 200.0, -5.0, -10.0);
727 GdipClosePathFigure(path
);
728 status
= GdipAddPathEllipse(path
, 10.0, 300.0, 0.0, 1.0);
731 ok_path(path
, ellipse_path
, ARRAY_SIZE(ellipse_path
), FALSE
);
733 GdipDeletePath(path
);
736 static path_test_t linei_path
[] = {
737 {5.00, 5.00, PathPointTypeStart
, 0, 0}, /*0*/
738 {6.00, 8.00, PathPointTypeLine
, 0, 0}, /*1*/
739 {409.92, 110.20, PathPointTypeLine
, 0, 0}, /*2*/
740 {543.96, 156.53, PathPointTypeBezier
, 0, 0}, /*3*/
741 {625.80, 346.22, PathPointTypeBezier
, 0, 0}, /*4*/
742 {592.71, 533.88, PathPointTypeBezier
, 0, 0}, /*5*/
743 {592.47, 535.28, PathPointTypeBezier
, 0, 0}, /*6*/
744 {592.22, 536.67, PathPointTypeBezier
, 0, 0}, /*7*/
745 {591.96, 538.06, PathPointTypeBezier
, 0, 0}, /*8*/
746 {15.00, 15.00, PathPointTypeLine
, 0, 0}, /*9*/
747 {26.00, 28.00, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*10*/
748 {35.00, 35.00, PathPointTypeStart
, 0, 0}, /*11*/
749 {36.00, 38.00, PathPointTypeLine
, 0, 0}, /*12*/
750 {39.00, 40.00, PathPointTypeLine
, 0, 0} /*13*/
753 static void test_linei(void)
758 GdipCreatePath(FillModeAlternate
, &path
);
759 status
= GdipAddPathLineI(path
, 5.0, 5.0, 6.0, 8.0);
761 GdipAddPathArc(path
, 100.0, 100.0, 500.0, 700.0, -80.0, 100.0);
762 status
= GdipAddPathLineI(path
, 15.0, 15.0, 26.0, 28.0);
764 GdipClosePathFigure(path
);
765 status
= GdipAddPathLineI(path
, 35.0, 35.0, 36.0, 38.0);
767 status
= GdipAddPathLineI(path
, 36, 38, 39, 40);
770 ok_path(path
, linei_path
, ARRAY_SIZE(linei_path
), FALSE
);
772 GdipDeletePath(path
);
775 static path_test_t poly_path
[] = {
776 {5.00, 5.00, PathPointTypeStart
, 0, 0}, /*1*/
777 {6.00, 8.00, PathPointTypeLine
, 0, 0}, /*2*/
778 {0.00, 0.00, PathPointTypeStart
, 0, 0}, /*3*/
779 {10.00, 10.00, PathPointTypeLine
, 0, 0}, /*4*/
780 {10.00, 20.00, PathPointTypeLine
, 0, 0}, /*5*/
781 {30.00, 10.00, PathPointTypeLine
, 0, 0}, /*6*/
782 {20.00, 0.00, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*7*/
785 static void test_polygon(void)
802 GdipCreatePath(FillModeAlternate
, &path
);
805 status
= GdipAddPathPolygon(NULL
, points
, 5);
806 expect(InvalidParameter
, status
);
807 status
= GdipAddPathPolygon(path
, NULL
, 5);
808 expect(InvalidParameter
, status
);
809 /* Polygon should have 3 points at least */
810 status
= GdipAddPathPolygon(path
, points
, 2);
811 expect(InvalidParameter
, status
);
813 /* to test how it prolongs not empty path */
814 status
= GdipAddPathLine(path
, 5.0, 5.0, 6.0, 8.0);
816 status
= GdipAddPathPolygon(path
, points
, 5);
818 /* check resulting path */
819 ok_path(path
, poly_path
, ARRAY_SIZE(poly_path
), FALSE
);
821 GdipDeletePath(path
);
824 static path_test_t rect_path
[] = {
825 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
826 {105.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
827 {105.0, 55.0, PathPointTypeLine
, 0, 0}, /*2*/
828 {5.0, 55.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0}, /*3*/
830 {100.0, 50.0, PathPointTypeStart
, 0, 0}, /*4*/
831 {220.0, 50.0, PathPointTypeLine
, 0, 0}, /*5*/
832 {220.0, 80.0, PathPointTypeLine
, 0, 0}, /*6*/
833 {100.0, 80.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0} /*7*/
836 static void test_rect(void)
842 GdipCreatePath(FillModeAlternate
, &path
);
843 status
= GdipAddPathRectangle(path
, 5.0, 5.0, 100.0, 50.0);
845 status
= GdipAddPathRectangle(path
, 100.0, 50.0, 120.0, 30.0);
848 ok_path(path
, rect_path
, ARRAY_SIZE(rect_path
), FALSE
);
850 GdipDeletePath(path
);
852 GdipCreatePath(FillModeAlternate
, &path
);
856 rects
[0].Width
= 100.0;
857 rects
[0].Height
= 50.0;
860 rects
[1].Width
= 120.0;
861 rects
[1].Height
= 30.0;
863 status
= GdipAddPathRectangles(path
, (GDIPCONST GpRectF
*)&rects
, 2);
866 ok_path(path
, rect_path
, ARRAY_SIZE(rect_path
), FALSE
);
868 GdipDeletePath(path
);
871 static void test_lastpoint(void)
877 GdipCreatePath(FillModeAlternate
, &path
);
878 status
= GdipAddPathRectangle(path
, 5.0, 5.0, 100.0, 50.0);
882 status
= GdipGetPathLastPoint(NULL
, &ptf
);
883 expect(InvalidParameter
, status
);
884 status
= GdipGetPathLastPoint(path
, NULL
);
885 expect(InvalidParameter
, status
);
886 status
= GdipGetPathLastPoint(NULL
, NULL
);
887 expect(InvalidParameter
, status
);
889 status
= GdipGetPathLastPoint(path
, &ptf
);
891 expect(TRUE
, (ptf
.X
== 5.0) && (ptf
.Y
== 55.0));
893 GdipDeletePath(path
);
896 static path_test_t addcurve_path
[] = {
897 {0.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
898 {3.3, 3.3, PathPointTypeBezier
, 0, 0}, /*1*/
899 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*2*/
900 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*3*/
901 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*4*/
902 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*5*/
903 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*6*/
904 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
905 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*8*/
906 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*9*/
908 static path_test_t addcurve_path2
[] = {
909 {100.0,120.0,PathPointTypeStart
, 0, 0}, /*0*/
910 {123.0,10.0, PathPointTypeLine
, 0, 0}, /*1*/
911 {0.0, 0.0, PathPointTypeLine
, 0, 0}, /*2*/
912 {3.3, 3.3, PathPointTypeBezier
, 0, 0}, /*3*/
913 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*4*/
914 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*5*/
915 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*6*/
916 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
917 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*8*/
918 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*9*/
919 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*10*/
920 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*11*/
922 static path_test_t addcurve_path3
[] = {
923 {10.0, 10.0, PathPointTypeStart
, 0, 0}, /*0*/
924 {13.3, 16.7, PathPointTypeBezier
, 0, 1}, /*1*/
925 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*2*/
926 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*3*/
927 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*4*/
928 {23.3, 13.3, PathPointTypeBezier
, 0, 0}, /*5*/
929 {30.0, 10.0, PathPointTypeBezier
, 0, 0} /*6*/
931 static void test_addcurve(void)
946 GdipCreatePath(FillModeAlternate
, &path
);
949 status
= GdipAddPathCurve2(NULL
, NULL
, 0, 0.0);
950 expect(InvalidParameter
, status
);
951 status
= GdipAddPathCurve2(path
, NULL
, 0, 0.0);
952 expect(InvalidParameter
, status
);
953 status
= GdipAddPathCurve2(path
, points
, -1, 0.0);
954 expect(InvalidParameter
, status
);
955 status
= GdipAddPathCurve2(path
, points
, 1, 1.0);
956 expect(InvalidParameter
, status
);
958 /* add to empty path */
959 status
= GdipAddPathCurve2(path
, points
, 4, 1.0);
961 ok_path(path
, addcurve_path
, ARRAY_SIZE(addcurve_path
), FALSE
);
962 GdipDeletePath(path
);
964 /* add to notempty path and opened figure */
965 GdipCreatePath(FillModeAlternate
, &path
);
966 GdipAddPathLine(path
, 100.0, 120.0, 123.0, 10.0);
967 status
= GdipAddPathCurve2(path
, points
, 4, 1.0);
969 ok_path(path
, addcurve_path2
, ARRAY_SIZE(addcurve_path2
), FALSE
);
973 status
= GdipAddPathCurve3(NULL
, NULL
, 0, 0, 0, 0.0);
974 expect(InvalidParameter
, status
);
975 status
= GdipAddPathCurve3(path
, NULL
, 0, 0, 0, 0.0);
976 expect(InvalidParameter
, status
);
977 /* wrong count, offset.. */
978 status
= GdipAddPathCurve3(path
, points
, 0, 0, 0, 0.0);
979 expect(InvalidParameter
, status
);
980 status
= GdipAddPathCurve3(path
, points
, 4, 0, 0, 0.0);
981 expect(InvalidParameter
, status
);
982 status
= GdipAddPathCurve3(path
, points
, 4, 0, 4, 0.0);
983 expect(InvalidParameter
, status
);
984 status
= GdipAddPathCurve3(path
, points
, 4, 1, 3, 0.0);
985 expect(InvalidParameter
, status
);
986 status
= GdipAddPathCurve3(path
, points
, 4, 1, 0, 0.0);
987 expect(InvalidParameter
, status
);
988 status
= GdipAddPathCurve3(path
, points
, 4, 3, 1, 0.0);
989 expect(InvalidParameter
, status
);
992 status
= GdipAddPathCurve3(path
, points
, 4, 0, 3, 1.0);
994 ok_path(path
, addcurve_path
, ARRAY_SIZE(addcurve_path
), FALSE
);
997 status
= GdipAddPathCurve3(path
, points
, 4, 1, 2, 1.0);
999 ok_path(path
, addcurve_path3
, ARRAY_SIZE(addcurve_path3
), FALSE
);
1001 GdipDeletePath(path
);
1004 static path_test_t addclosedcurve_path
[] = {
1005 {0.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
1006 {-6.7, 0.0, PathPointTypeBezier
, 0, 0}, /*1*/
1007 {6.7, 3.3, PathPointTypeBezier
, 0, 0}, /*2*/
1008 {10.0, 10.0, PathPointTypeBezier
, 0, 0}, /*3*/
1009 {13.3, 16.7, PathPointTypeBezier
, 0, 0}, /*4*/
1010 {3.3, 20.0, PathPointTypeBezier
, 0, 0}, /*5*/
1011 {10.0, 20.0, PathPointTypeBezier
, 0, 0}, /*6*/
1012 {16.7, 20.0, PathPointTypeBezier
, 0, 0}, /*7*/
1013 {33.3, 16.7, PathPointTypeBezier
, 0, 0}, /*8*/
1014 {30.0, 10.0, PathPointTypeBezier
, 0, 0}, /*9*/
1015 {26.7, 3.3, PathPointTypeBezier
, 0, 0}, /*10*/
1016 {6.7, 0.0, PathPointTypeBezier
, 0, 0}, /*11*/
1017 {0.0, 0.0, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*12*/
1019 static void test_addclosedcurve(void)
1034 GdipCreatePath(FillModeAlternate
, &path
);
1037 status
= GdipAddPathClosedCurve2(NULL
, NULL
, 0, 0.0);
1038 expect(InvalidParameter
, status
);
1039 status
= GdipAddPathClosedCurve2(path
, NULL
, 0, 0.0);
1040 expect(InvalidParameter
, status
);
1041 status
= GdipAddPathClosedCurve2(path
, points
, -1, 0.0);
1042 expect(InvalidParameter
, status
);
1043 status
= GdipAddPathClosedCurve2(path
, points
, 1, 1.0);
1044 expect(InvalidParameter
, status
);
1046 /* add to empty path */
1047 status
= GdipAddPathClosedCurve2(path
, points
, 4, 1.0);
1049 ok_path(path
, addclosedcurve_path
, ARRAY_SIZE(addclosedcurve_path
), FALSE
);
1050 GdipDeletePath(path
);
1053 static path_test_t reverse_path
[] = {
1054 {0.0, 20.0, PathPointTypeStart
, 0, 0}, /*0*/
1055 {25.0, 25.0, PathPointTypeLine
, 0, 0}, /*1*/
1056 {0.0, 30.0, PathPointTypeLine
, 0, 0}, /*2*/
1057 {15.0, 35.0, PathPointTypeStart
, 0, 0}, /*3*/
1058 {0.0, 40.0, PathPointTypeLine
, 0, 0}, /*4*/
1059 {5.0, 45.0, PathPointTypeLine
, 0, 0}, /*5*/
1060 {0.0, 50.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 0} /*6*/
1063 static void test_reverse(void)
1070 for(i
= 0; i
< 7; i
++){
1071 pts
[i
].X
= i
* 5.0 * (REAL
)(i
% 2);
1072 pts
[i
].Y
= 50.0 - i
* 5.0;
1075 GdipCreatePath(FillModeAlternate
, &path
);
1078 status
= GdipReversePath(NULL
);
1079 expect(InvalidParameter
, status
);
1082 status
= GdipReversePath(path
);
1085 GdipAddPathLine2(path
, pts
, 4);
1086 GdipClosePathFigure(path
);
1087 GdipAddPathLine2(path
, &(pts
[4]), 3);
1089 status
= GdipReversePath(path
);
1091 ok_path(path
, reverse_path
, ARRAY_SIZE(reverse_path
), FALSE
);
1093 GdipDeletePath(path
);
1096 static path_test_t addpie_path
[] = {
1097 {50.0, 25.0, PathPointTypeStart
, 0, 0}, /*0*/
1098 {97.2, 33.3, PathPointTypeLine
, 0, 0}, /*1*/
1099 {91.8, 40.9, PathPointTypeBezier
,0, 0}, /*2*/
1100 {79.4, 46.8, PathPointTypeBezier
,0, 0}, /*3*/
1101 {63.9, 49.0, PathPointTypeBezier
| PathPointTypeCloseSubpath
, 0, 0} /*4*/
1103 static path_test_t addpie_path2
[] = {
1104 {0.0, 30.0, PathPointTypeStart
| PathPointTypeCloseSubpath
, 0, 0} /*0*/
1106 static path_test_t addpie_path3
[] = {
1107 {30.0, 0.0, PathPointTypeStart
| PathPointTypeCloseSubpath
, 0, 0} /*0*/
1109 static void test_addpie(void)
1114 GdipCreatePath(FillModeAlternate
, &path
);
1117 status
= GdipAddPathPie(NULL
, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
1118 expect(InvalidParameter
, status
);
1120 status
= GdipAddPathPie(path
, 0.0, 0.0, 100.0, 50.0, 10.0, 50.0);
1122 ok_path(path
, addpie_path
, ARRAY_SIZE(addpie_path
), FALSE
);
1123 status
= GdipResetPath(path
);
1126 /* zero width base ellipse */
1127 status
= GdipAddPathPie(path
, 0.0, 0.0, 0.0, 60.0, -90.0, 24.0);
1128 expect(InvalidParameter
, status
);
1129 ok_path(path
, addpie_path2
, ARRAY_SIZE(addpie_path2
), FALSE
);
1130 status
= GdipResetPath(path
);
1133 /* zero height base ellipse */
1134 status
= GdipAddPathPie(path
, 0.0, 0.0, 60.0, 0.0 , -90.0, 24.0);
1135 expect(InvalidParameter
, status
);
1136 ok_path(path
, addpie_path3
, ARRAY_SIZE(addpie_path3
), FALSE
);
1138 GdipDeletePath(path
);
1141 static path_test_t flattenellipse_path
[] = {
1142 {100.0, 25.0,PathPointTypeStart
, 0, 0}, /*0*/
1143 {99.0, 30.0, PathPointTypeLine
, 0, 0}, /*1*/
1144 {96.0, 34.8, PathPointTypeLine
, 0, 0}, /*2*/
1145 {91.5, 39.0, PathPointTypeLine
, 0, 0}, /*3*/
1146 {85.5, 42.8, PathPointTypeLine
, 0, 0}, /*4*/
1147 {69.5, 48.0, PathPointTypeLine
, 0, 1}, /*5*/
1148 {50.0, 50.0, PathPointTypeLine
, 0, 1}, /*6*/
1149 {30.5, 48.0, PathPointTypeLine
, 0, 1}, /*7*/
1150 {14.8, 42.8, PathPointTypeLine
, 0, 1}, /*8*/
1151 {8.5, 39.0, PathPointTypeLine
, 0, 1}, /*9*/
1152 {4.0, 34.8, PathPointTypeLine
, 0, 1}, /*10*/
1153 {1.0, 30.0, PathPointTypeLine
, 0, 1}, /*11*/
1154 {0.0, 25.0, PathPointTypeLine
, 0, 1}, /*12*/
1155 {1.0, 20.0, PathPointTypeLine
, 0, 1}, /*13*/
1156 {4.0, 15.3, PathPointTypeLine
, 0, 1}, /*14*/
1157 {8.5, 11.0, PathPointTypeLine
, 0, 1}, /*15*/
1158 {14.8, 7.3, PathPointTypeLine
, 0, 1}, /*16*/
1159 {30.5, 2.0, PathPointTypeLine
, 0, 1}, /*17*/
1160 {50.0, 0.0, PathPointTypeLine
, 0, 1}, /*18*/
1161 {69.5, 2.0, PathPointTypeLine
, 0, 1}, /*19*/
1162 {85.5, 7.3, PathPointTypeLine
, 0, 1}, /*20*/
1163 {91.5, 11.0, PathPointTypeLine
, 0, 1}, /*21*/
1164 {96.0, 15.3, PathPointTypeLine
, 0, 1}, /*22*/
1165 {99.0, 20.0, PathPointTypeLine
, 0, 1}, /*23*/
1166 {100.0,25.0, PathPointTypeLine
| PathPointTypeCloseSubpath
, 0, 1} /*24*/
1169 static path_test_t flattenline_path
[] = {
1170 {5.0, 10.0,PathPointTypeStart
, 0, 0}, /*0*/
1171 {50.0, 100.0, PathPointTypeLine
, 0, 0} /*1*/
1174 static path_test_t flattenarc_path
[] = {
1175 {100.0, 25.0,PathPointTypeStart
, 0, 0}, /*0*/
1176 {99.0, 30.0, PathPointTypeLine
, 0, 0}, /*1*/
1177 {96.0, 34.8, PathPointTypeLine
, 0, 0}, /*2*/
1178 {91.5, 39.0, PathPointTypeLine
, 0, 0}, /*3*/
1179 {85.5, 42.8, PathPointTypeLine
, 0, 0}, /*4*/
1180 {69.5, 48.0, PathPointTypeLine
, 0, 1}, /*5*/
1181 {50.0, 50.0, PathPointTypeLine
, 0, 1} /*6*/
1184 static path_test_t flattenquater_path
[] = {
1185 {100.0, 50.0,PathPointTypeStart
, 0, 0}, /*0*/
1186 {99.0, 60.0, PathPointTypeLine
, 0, 0}, /*1*/
1187 {96.0, 69.5, PathPointTypeLine
, 0, 0}, /*2*/
1188 {91.5, 78.0, PathPointTypeLine
, 0, 0}, /*3*/
1189 {85.5, 85.5, PathPointTypeLine
, 0, 0}, /*4*/
1190 {78.0, 91.5, PathPointTypeLine
, 0, 0}, /*5*/
1191 {69.5, 96.0, PathPointTypeLine
, 0, 0}, /*6*/
1192 {60.0, 99.0, PathPointTypeLine
, 0, 0}, /*7*/
1193 {50.0, 100.0,PathPointTypeLine
, 0, 0} /*8*/
1196 static void test_flatten(void)
1202 status
= GdipCreatePath(FillModeAlternate
, &path
);
1204 status
= GdipCreateMatrix(&m
);
1207 /* NULL arguments */
1208 status
= GdipFlattenPath(NULL
, NULL
, 0.0);
1209 expect(InvalidParameter
, status
);
1210 status
= GdipFlattenPath(NULL
, m
, 0.0);
1211 expect(InvalidParameter
, status
);
1213 /* flatten empty path */
1214 status
= GdipFlattenPath(path
, NULL
, 1.0);
1217 status
= GdipTransformPath(path
, 0);
1220 status
= GdipAddPathEllipse(path
, 0.0, 0.0, 100.0, 50.0);
1223 status
= GdipFlattenPath(path
, NULL
, 1.0);
1225 ok_path(path
, flattenellipse_path
, ARRAY_SIZE(flattenellipse_path
), TRUE
);
1227 status
= GdipResetPath(path
);
1229 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 100.0);
1231 status
= GdipFlattenPath(path
, NULL
, 1.0);
1233 ok_path(path
, flattenline_path
, ARRAY_SIZE(flattenline_path
), FALSE
);
1235 status
= GdipResetPath(path
);
1237 status
= GdipAddPathArc(path
, 0.0, 0.0, 100.0, 50.0, 0.0, 90.0);
1239 status
= GdipFlattenPath(path
, NULL
, 1.0);
1241 ok_path(path
, flattenarc_path
, ARRAY_SIZE(flattenarc_path
), TRUE
);
1243 /* easy case - quater of a full circle */
1244 status
= GdipResetPath(path
);
1246 status
= GdipAddPathArc(path
, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1248 status
= GdipFlattenPath(path
, NULL
, 1.0);
1250 ok_path(path
, flattenquater_path
, ARRAY_SIZE(flattenquater_path
), FALSE
);
1252 GdipDeleteMatrix(m
);
1253 GdipDeletePath(path
);
1256 static path_test_t widenline_path
[] = {
1257 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1258 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1259 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1260 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1263 static path_test_t widenline_wide_path
[] = {
1264 {5.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
1265 {50.0, 0.0, PathPointTypeLine
, 0, 0}, /*1*/
1266 {50.0, 20.0, PathPointTypeLine
, 0, 0}, /*2*/
1267 {5.0, 20.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1270 static path_test_t widenline_dash_path
[] = {
1271 {5.0, 0.0, PathPointTypeStart
, 0, 0}, /*0*/
1272 {35.0, 0.0, PathPointTypeLine
, 0, 0}, /*1*/
1273 {35.0, 10.0, PathPointTypeLine
, 0, 0}, /*2*/
1274 {5.0, 10.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1275 {45.0, 0.0, PathPointTypeStart
, 0, 0}, /*4*/
1276 {50.0, 0.0, PathPointTypeLine
, 0, 0}, /*5*/
1277 {50.0, 10.0, PathPointTypeLine
, 0, 0}, /*6*/
1278 {45.0, 10.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1281 static path_test_t widenline_unit_path
[] = {
1282 {5.0, 9.5, PathPointTypeStart
, 0, 0}, /*0*/
1283 {50.0, 9.5, PathPointTypeLine
, 0, 0}, /*1*/
1284 {50.0, 10.5, PathPointTypeLine
, 0, 0}, /*2*/
1285 {5.0, 10.5, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1288 static void test_widen(void)
1296 status
= GdipCreatePath(FillModeAlternate
, &path
);
1298 status
= GdipCreatePen1(0xffffffff, 10.0, UnitPixel
, &pen
);
1300 status
= GdipCreateMatrix(&m
);
1303 /* NULL arguments */
1304 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1306 status
= GdipWidenPath(NULL
, NULL
, NULL
, 0.0);
1307 expect(InvalidParameter
, status
);
1308 status
= GdipWidenPath(path
, pen
, m
, 0.0);
1310 status
= GdipWidenPath(path
, pen
, NULL
, 1.0);
1312 status
= GdipWidenPath(path
, NULL
, m
, 1.0);
1313 expect(InvalidParameter
, status
);
1314 status
= GdipWidenPath(NULL
, pen
, m
, 1.0);
1315 expect(InvalidParameter
, status
);
1317 /* widen empty path */
1318 status
= GdipResetPath(path
);
1320 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1321 expect(OutOfMemory
, status
);
1323 /* horizontal line */
1324 status
= GdipResetPath(path
);
1326 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1329 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1331 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1333 /* horizontal 2x stretch */
1334 status
= GdipResetPath(path
);
1336 status
= GdipAddPathLine(path
, 2.5, 10.0, 25.0, 10.0);
1339 status
= GdipScaleMatrix(m
, 2.0, 1.0, MatrixOrderAppend
);
1342 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1344 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1346 /* vertical 2x stretch */
1347 status
= GdipResetPath(path
);
1349 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1352 status
= GdipScaleMatrix(m
, 0.5, 2.0, MatrixOrderAppend
);
1355 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1357 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1359 status
= GdipScaleMatrix(m
, 1.0, 0.5, MatrixOrderAppend
);
1363 status
= GdipResetPath(path
);
1365 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1368 status
= GdipSetPenDashStyle(pen
, DashStyleDash
);
1371 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1373 ok_path(path
, widenline_dash_path
, ARRAY_SIZE(widenline_dash_path
), FALSE
);
1375 status
= GdipSetPenDashStyle(pen
, DashStyleSolid
);
1378 /* pen width in UnitWorld */
1380 status
= GdipCreatePen1(0xffffffff, 10.0, UnitWorld
, &pen
);
1383 status
= GdipResetPath(path
);
1385 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1388 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1390 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1392 /* horizontal 2x stretch */
1393 status
= GdipResetPath(path
);
1395 status
= GdipAddPathLine(path
, 2.5, 10.0, 25.0, 10.0);
1398 status
= GdipScaleMatrix(m
, 2.0, 1.0, MatrixOrderAppend
);
1401 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1403 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1405 /* vertical 2x stretch */
1406 status
= GdipResetPath(path
);
1408 status
= GdipAddPathLine(path
, 5.0, 5.0, 50.0, 5.0);
1411 status
= GdipScaleMatrix(m
, 0.5, 2.0, MatrixOrderAppend
);
1414 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1416 ok_path(path
, widenline_wide_path
, ARRAY_SIZE(widenline_wide_path
), FALSE
);
1418 status
= GdipScaleMatrix(m
, 1.0, 0.5, MatrixOrderAppend
);
1421 /* pen width in UnitInch */
1423 status
= GdipCreatePen1(0xffffffff, 10.0, UnitWorld
, &pen
);
1426 status
= GdipResetPath(path
);
1428 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1431 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1433 ok_path(path
, widenline_path
, ARRAY_SIZE(widenline_path
), FALSE
);
1435 /* pen width = 0 pixels - native fails to widen but can draw with this pen */
1437 status
= GdipCreatePen1(0xffffffff, 0.0, UnitPixel
, &pen
);
1440 status
= GdipResetPath(path
);
1442 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1445 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1448 status
= GdipGetPointCount(path
, &count
);
1452 /* pen width = 0 pixels, UnitWorld - result is a path 1 unit wide */
1454 status
= GdipCreatePen1(0xffffffff, 0.0, UnitWorld
, &pen
);
1457 status
= GdipResetPath(path
);
1459 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1462 status
= GdipWidenPath(path
, pen
, m
, 1.0);
1465 status
= GdipGetPointCount(path
, &count
);
1467 ok_path_fudge(path
, widenline_unit_path
, ARRAY_SIZE(widenline_unit_path
), FALSE
, 0.000005);
1469 GdipDeleteMatrix(m
);
1471 GdipDeletePath(path
);
1474 static path_test_t widenline_capflat_path
[] = {
1475 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1476 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1477 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1478 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1481 static path_test_t widenline_capsquare_path
[] = {
1482 {0.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1483 {55.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1484 {55.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1485 {0.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*3*/
1488 static path_test_t widenline_capround_path
[] = {
1489 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1490 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1491 {52.761421, 5.0, PathPointTypeBezier
, 0, 0}, /*2*/
1492 {55.0, 7.238576, PathPointTypeBezier
, 0, 0}, /*3*/
1493 {55.0, 10.0, PathPointTypeBezier
, 0, 0}, /*4*/
1494 {55.0, 12.761423, PathPointTypeBezier
, 0, 0}, /*5*/
1495 {52.761421, 15.0, PathPointTypeBezier
, 0, 0}, /*6*/
1496 {50.0, 15.0, PathPointTypeBezier
, 0, 0}, /*7*/
1497 {5.0, 15.0, PathPointTypeLine
, 0, 0}, /*8*/
1498 {2.238576, 15.0, PathPointTypeBezier
, 0, 0}, /*9*/
1499 {0.0, 12.761423, PathPointTypeBezier
, 0, 0}, /*10*/
1500 {0.0, 10.0, PathPointTypeBezier
, 0, 0}, /*11*/
1501 {0.0, 7.238576, PathPointTypeBezier
, 0, 0}, /*12*/
1502 {2.238576, 5.0, PathPointTypeBezier
, 0, 0}, /*13*/
1503 {5.0, 5.0, PathPointTypeBezier
|PathPointTypeCloseSubpath
, 0, 0}, /*14*/
1506 static path_test_t widenline_captriangle_path
[] = {
1507 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1508 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1509 {55.0, 10.0, PathPointTypeLine
, 0, 0}, /*2*/
1510 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*3*/
1511 {5.0, 15.0, PathPointTypeLine
, 0, 0}, /*4*/
1512 {0.0, 10.0, PathPointTypeLine
, 0, 0}, /*5*/
1513 {5.0, 5.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0} /*6*/
1516 static path_test_t widenline_capsquareanchor_path
[] = {
1517 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1518 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1519 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1520 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1521 {12.071068, 2.928932, PathPointTypeStart
, 0, 0}, /*4*/
1522 {12.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*5*/
1523 {-2.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*6*/
1524 {-2.071068, 2.928932, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1525 {42.928928, 17.071068, PathPointTypeStart
, 0, 0}, /*8*/
1526 {42.928928, 2.928932, PathPointTypeLine
, 0, 0}, /*9*/
1527 {57.071068, 2.928932, PathPointTypeLine
, 0, 0}, /*10*/
1528 {57.071068, 17.071068, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*11*/
1531 static path_test_t widenline_caproundanchor_path
[] = {
1532 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1533 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1534 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1535 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1536 {5.0, 20.0, PathPointTypeStart
, 0, 0}, /*4*/
1537 {-0.522847, 20.0, PathPointTypeBezier
, 0, 0}, /*5*/
1538 {-5.0, 15.522846, PathPointTypeBezier
, 0, 0}, /*6*/
1539 {-5.0, 10.0, PathPointTypeBezier
, 0, 0}, /*7*/
1540 {-5.0, 4.477152, PathPointTypeBezier
, 0, 0}, /*8*/
1541 {-0.522847, 0.0, PathPointTypeBezier
, 0, 0}, /*9*/
1542 {5.0, 0.0, PathPointTypeBezier
, 0, 0}, /*10*/
1543 {10.522847, 0.0, PathPointTypeBezier
, 0, 0}, /*11*/
1544 {15.0, 4.477152, PathPointTypeBezier
, 0, 0}, /*12*/
1545 {15.0, 10.0, PathPointTypeBezier
, 0, 0}, /*13*/
1546 {15.0, 15.522846, PathPointTypeBezier
, 0, 0}, /*14*/
1547 {10.522847, 20.0, PathPointTypeBezier
, 0, 0}, /*15*/
1548 {5.0, 20.0, PathPointTypeBezier
|PathPointTypeCloseSubpath
, 0, 0}, /*16*/
1549 {50.0, 0.0, PathPointTypeStart
, 0, 0}, /*17*/
1550 {55.522846, 0.0, PathPointTypeBezier
, 0, 0}, /*18*/
1551 {60.0, 4.477153, PathPointTypeBezier
, 0, 0}, /*19*/
1552 {60.0, 10.0, PathPointTypeBezier
, 0, 0}, /*20*/
1553 {60.0, 15.522847, PathPointTypeBezier
, 0, 0}, /*21*/
1554 {55.522846, 20.0, PathPointTypeBezier
, 0, 0}, /*22*/
1555 {50.0, 20.0, PathPointTypeBezier
, 0, 0}, /*23*/
1556 {44.477150, 20.0, PathPointTypeBezier
, 0, 0}, /*24*/
1557 {40.0, 15.522847, PathPointTypeBezier
, 0, 0}, /*25*/
1558 {40.0, 10.0, PathPointTypeBezier
, 0, 0}, /*26*/
1559 {40.0, 4.477153, PathPointTypeBezier
, 0, 0}, /*27*/
1560 {44.477150, 0.0, PathPointTypeBezier
, 0, 0}, /*28*/
1561 {50.0, 0.0, PathPointTypeBezier
|PathPointTypeCloseSubpath
, 0, 0}, /*29*/
1564 static path_test_t widenline_capdiamondanchor_path
[] = {
1565 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1566 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1567 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1568 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1569 {-5.0, 10.0, PathPointTypeStart
, 0, 0}, /*4*/
1570 {5.0, 0.0, PathPointTypeLine
, 0, 0}, /*5*/
1571 {15.0, 10.0, PathPointTypeLine
, 0, 0}, /*6*/
1572 {5.0, 20.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1573 {60.0, 10.0, PathPointTypeStart
, 0, 0}, /*8*/
1574 {50.0, 20.0, PathPointTypeLine
, 0, 0}, /*9*/
1575 {40.0, 10.0, PathPointTypeLine
, 0, 0}, /*10*/
1576 {50.0, 0.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*11*/
1579 static path_test_t widenline_caparrowanchor_path
[] = {
1580 {15.0, 5.0, PathPointTypeStart
, 0, 1}, /*0*/
1581 {40.0, 5.0, PathPointTypeLine
, 0, 1}, /*1*/
1582 {40.0, 15.0, PathPointTypeLine
, 0, 1}, /*2*/
1583 {15.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 1}, /*3*/
1584 {5.0, 10.0, PathPointTypeStart
, 0, 0}, /*4*/
1585 {22.320507, 0.0, PathPointTypeLine
, 0, 0}, /*5*/
1586 {22.320507, 20.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*6*/
1587 {50.0, 10.0, PathPointTypeStart
, 0, 0}, /*7*/
1588 {32.679489, 20.0, PathPointTypeLine
, 0, 0}, /*8*/
1589 {32.679489, 0.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*9*/
1592 static path_test_t widenline_capsquareanchor_thin_path
[] = {
1593 {6.414213, 8.585786, PathPointTypeStart
, 0, 0}, /*0*/
1594 {6.414213, 11.414213, PathPointTypeLine
, 0, 0}, /*1*/
1595 {3.585786, 11.414213, PathPointTypeLine
, 0, 0}, /*2*/
1596 {3.585786, 8.585786, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1597 {48.585785, 11.414213, PathPointTypeStart
, 0, 0}, /*4*/
1598 {48.585785, 8.585786, PathPointTypeLine
, 0, 0}, /*5*/
1599 {51.414211, 8.585786, PathPointTypeLine
, 0, 0}, /*6*/
1600 {51.414211, 11.414213, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1603 static path_test_t widenline_capsquareanchor_dashed_path
[] = {
1604 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1605 {35.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1606 {35.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1607 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1608 {45.0, 5.0, PathPointTypeStart
, 0, 0}, /*4*/
1609 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*5*/
1610 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*6*/
1611 {45.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1612 {12.071068, 2.928932, PathPointTypeStart
, 0, 0}, /*8*/
1613 {12.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*9*/
1614 {-2.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*10*/
1615 {-2.071068, 2.928932, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*11*/
1616 {42.928928, 17.071068, PathPointTypeStart
, 0, 0}, /*12*/
1617 {42.928928, 2.928932, PathPointTypeLine
, 0, 0}, /*13*/
1618 {57.071068, 2.928932, PathPointTypeLine
, 0, 0}, /*14*/
1619 {57.071068, 17.071068, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*15*/
1622 static path_test_t widenline_capsquareanchor_multifigure_path
[] = {
1623 {5.0, 5.0, PathPointTypeStart
, 0, 0}, /*0*/
1624 {25.0, 5.0, PathPointTypeLine
, 0, 0}, /*1*/
1625 {25.0, 15.0, PathPointTypeLine
, 0, 0}, /*2*/
1626 {5.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*3*/
1627 {30.0, 5.0, PathPointTypeStart
, 0, 0}, /*4*/
1628 {50.0, 5.0, PathPointTypeLine
, 0, 0}, /*5*/
1629 {50.0, 15.0, PathPointTypeLine
, 0, 0}, /*6*/
1630 {30.0, 15.0, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*7*/
1631 {12.071068, 2.928932, PathPointTypeStart
, 0, 0}, /*8*/
1632 {12.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*9*/
1633 {-2.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*10*/
1634 {-2.071068, 2.928932, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*11*/
1635 {17.928930, 17.071068, PathPointTypeStart
, 0, 0}, /*12*/
1636 {17.928930, 2.928932, PathPointTypeLine
, 0, 0}, /*13*/
1637 {32.071068, 2.928932, PathPointTypeLine
, 0, 0}, /*14*/
1638 {32.071068, 17.071068, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*15*/
1639 {37.071068, 2.928932, PathPointTypeStart
, 0, 0}, /*16*/
1640 {37.071068, 17.071066, PathPointTypeLine
, 0, 0}, /*17*/
1641 {22.928930, 17.071066, PathPointTypeLine
, 0, 0}, /*18*/
1642 {22.928930, 2.928932, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*19*/
1643 {42.928928, 17.071068, PathPointTypeStart
, 0, 0}, /*20*/
1644 {42.928928, 2.928932, PathPointTypeLine
, 0, 0}, /*21*/
1645 {57.071068, 2.928932, PathPointTypeLine
, 0, 0}, /*22*/
1646 {57.071068, 17.071068, PathPointTypeLine
|PathPointTypeCloseSubpath
, 0, 0}, /*23*/
1649 static void test_widen_cap(void)
1655 const path_test_t
*expected
;
1662 { LineCapFlat
, 10.0, widenline_capflat_path
,
1663 ARRAY_SIZE(widenline_capflat_path
) },
1664 { LineCapSquare
, 10.0, widenline_capsquare_path
,
1665 ARRAY_SIZE(widenline_capsquare_path
) },
1666 { LineCapRound
, 10.0, widenline_capround_path
,
1667 ARRAY_SIZE(widenline_capround_path
) },
1668 { LineCapTriangle
, 10.0, widenline_captriangle_path
,
1669 ARRAY_SIZE(widenline_captriangle_path
) },
1670 { LineCapNoAnchor
, 10.0, widenline_capflat_path
,
1671 ARRAY_SIZE(widenline_capflat_path
) },
1672 { LineCapSquareAnchor
, 10.0, widenline_capsquareanchor_path
,
1673 ARRAY_SIZE(widenline_capsquareanchor_path
) },
1674 { LineCapRoundAnchor
, 10.0, widenline_caproundanchor_path
,
1675 ARRAY_SIZE(widenline_caproundanchor_path
) },
1676 { LineCapDiamondAnchor
, 10.0, widenline_capdiamondanchor_path
,
1677 ARRAY_SIZE(widenline_capdiamondanchor_path
) },
1678 { LineCapArrowAnchor
, 10.0, widenline_caparrowanchor_path
,
1679 ARRAY_SIZE(widenline_caparrowanchor_path
), FALSE
, TRUE
},
1680 { LineCapSquareAnchor
, 0.0, widenline_capsquareanchor_thin_path
,
1681 ARRAY_SIZE(widenline_capsquareanchor_thin_path
) },
1682 { LineCapSquareAnchor
, 10.0, widenline_capsquareanchor_dashed_path
,
1683 ARRAY_SIZE(widenline_capsquareanchor_dashed_path
), TRUE
},
1690 status
= GdipCreatePath(FillModeAlternate
, &path
);
1693 for (i
= 0; i
< ARRAY_SIZE(caps
); i
++)
1695 status
= GdipCreatePen1(0xffffffff, caps
[i
].line_width
, UnitPixel
, &pen
);
1699 status
= GdipSetPenDashStyle(pen
, DashStyleDash
);
1703 status
= GdipResetPath(path
);
1705 status
= GdipAddPathLine(path
, 5.0, 10.0, 50.0, 10.0);
1707 status
= GdipSetPenStartCap(pen
, caps
[i
].type
);
1709 status
= GdipSetPenEndCap(pen
, caps
[i
].type
);
1712 status
= GdipWidenPath(path
, pen
, NULL
, FlatnessDefault
);
1714 ok_path_fudge(path
, caps
[i
].expected
, caps
[i
].expected_size
, caps
[i
].todo_size
, 0.000005);
1719 status
= GdipCreatePen1(0xffffffff, 10.0, UnitPixel
, &pen
);
1721 status
= GdipResetPath(path
);
1723 status
= GdipAddPathLine(path
, 5.0, 10.0, 25.0, 10.0);
1725 status
= GdipStartPathFigure(path
);
1727 status
= GdipAddPathLine(path
, 30.0, 10.0, 50.0, 10.0);
1729 status
= GdipSetPenStartCap(pen
, LineCapSquareAnchor
);
1731 status
= GdipSetPenEndCap(pen
, LineCapSquareAnchor
);
1733 status
= GdipWidenPath(path
, pen
, NULL
, FlatnessDefault
);
1735 ok_path_fudge(path
, widenline_capsquareanchor_multifigure_path
,
1736 ARRAY_SIZE(widenline_capsquareanchor_multifigure_path
), FALSE
, 0.000005);
1739 GdipDeletePath(path
);
1742 static void test_isvisible(void)
1745 GpGraphics
*graphics
= NULL
;
1750 status
= GdipCreateFromHDC(hdc
, &graphics
);
1752 status
= GdipCreatePath(FillModeAlternate
, &path
);
1756 status
= GdipIsVisiblePathPoint(NULL
, 0.0, 0.0, NULL
, NULL
);
1757 expect(InvalidParameter
, status
);
1758 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, NULL
);
1759 expect(InvalidParameter
, status
);
1760 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, NULL
);
1761 expect(InvalidParameter
, status
);
1762 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, graphics
, NULL
);
1763 expect(InvalidParameter
, status
);
1767 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, &result
);
1769 expect(FALSE
, result
);
1771 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 10.0, 10.0);
1774 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, NULL
, &result
);
1776 expect(TRUE
, result
);
1778 status
= GdipIsVisiblePathPoint(path
, 11.0, 11.0, NULL
, &result
);
1780 expect(FALSE
, result
);
1781 /* not affected by clipping */
1782 status
= GdipSetClipRect(graphics
, 5.0, 5.0, 5.0, 5.0, CombineModeReplace
);
1785 status
= GdipIsVisiblePathPoint(path
, 0.0, 0.0, graphics
, &result
);
1787 expect(TRUE
, result
);
1789 GdipDeletePath(path
);
1790 GdipDeleteGraphics(graphics
);
1794 static void test_empty_rect(void)
1801 status
= GdipCreatePath(FillModeAlternate
, &path
);
1804 status
= GdipAddPathRectangle(path
, 0.0, 0.0, -5.0, 5.0);
1807 status
= GdipGetPointCount(path
, &count
);
1811 status
= GdipIsVisiblePathPoint(path
, -2.0, 2.0, NULL
, &result
);
1813 expect(FALSE
, result
);
1815 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 5.0, -5.0);
1818 status
= GdipGetPointCount(path
, &count
);
1822 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 0.0, 5.0);
1825 status
= GdipGetPointCount(path
, &count
);
1829 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 5.0, 0.0);
1832 status
= GdipGetPointCount(path
, &count
);
1836 status
= GdipAddPathRectangle(path
, 0.0, 0.0, 5.0, 0.1);
1839 status
= GdipGetPointCount(path
, &count
);
1843 GdipDeletePath(path
);
1846 START_TEST(graphicspath
)
1848 struct GdiplusStartupInput gdiplusStartupInput
;
1849 ULONG_PTR gdiplusToken
;
1851 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
1853 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1854 hmsvcrt
= LoadLibraryA("msvcrt");
1855 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
1856 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
1858 gdiplusStartupInput
.GdiplusVersion
= 1;
1859 gdiplusStartupInput
.DebugEventCallback
= NULL
;
1860 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
1861 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
1863 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
1865 test_constructor_destructor();
1880 test_addclosedcurve();
1889 GdiplusShutdown(gdiplusToken
);