2 * Unit test suite for pens (and init)
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
25 #include "wine/test.h"
27 #define expect(expected,got) expect_(__LINE__, expected, got)
28 static inline void expect_(unsigned line
, DWORD expected
, DWORD got
)
30 ok_(__FILE__
, line
)(expected
== got
, "Expected %.8ld, got %.8ld\n", expected
, got
);
32 #define expectf(expected, got) ok(fabs(got - expected) < 0.1, "Expected %.2f, got %.2f\n", expected, got)
34 static void test_startup(void)
38 struct GdiplusStartupInput gdiplusStartupInput
;
39 ULONG_PTR gdiplusToken
;
42 gdiplusStartupInput
.DebugEventCallback
= NULL
;
43 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
44 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
46 for (gpversion
=1; gpversion
<256; gpversion
++)
48 gdiplusStartupInput
.GdiplusVersion
= gpversion
;
49 status
= GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
50 ok(status
== Ok
|| status
== UnsupportedGdiplusVersion
,
51 "GdiplusStartup returned %x\n", status
);
52 GdiplusShutdown(gdiplusToken
);
60 ok(gpversion
> 0 && gpversion
<= 2, "unexpected gdiplus version %i\n", gpversion
);
61 trace("gdiplus version is %i\n", gpversion
);
63 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
66 expect(GdiplusNotInitialized
, status
);
71 static void test_constructor_destructor(void)
76 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, NULL
);
77 expect(InvalidParameter
, status
);
78 ok(pen
== NULL
, "Expected pen to be NULL\n");
80 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
82 ok(pen
!= NULL
, "Expected pen to be initialized\n");
84 status
= GdipDeletePen(NULL
);
85 expect(InvalidParameter
, status
);
87 status
= GdipDeletePen(pen
);
91 static void test_constructor_destructor2(void)
95 GpBrush
*brush
= NULL
;
98 status
= GdipCreatePen2(NULL
, 10.0f
, UnitPixel
, &pen
);
99 expect(InvalidParameter
, status
);
100 ok(pen
== NULL
, "Expected pen to be NULL\n");
107 status
= GdipCreateLineBrush(&points
[0], &points
[1], (ARGB
)0xffff00ff,
108 (ARGB
)0xff0000ff, WrapModeTile
, (GpLineGradient
**)&brush
);
110 ok(brush
!= NULL
, "Expected brush to be initialized\n");
112 status
= GdipCreatePen2(brush
, 10.0f
, UnitPixel
, &pen
);
114 ok(pen
!= NULL
, "Expected pen to be initialized\n");
116 status
= GdipDeletePen(pen
);
119 status
= GdipDeleteBrush(brush
);
123 static void test_brushfill(void)
127 GpBrush
*brush
, *brush2
;
132 GdipCreatePen1(0xdeadbeef, 4.5, UnitWorld
, &pen
);
133 status
= GdipGetPenBrushFill(pen
, &brush
);
135 GdipGetBrushType(brush
, &type
);
136 expect(BrushTypeSolidColor
, type
);
137 GdipGetPenColor(pen
, &color
);
138 expect(0xdeadbeef, color
);
139 GdipDeleteBrush(brush
);
141 /* color controlled by brush */
142 GdipCreateSolidFill(0xabaddeed, (GpSolidFill
**)&brush
);
143 status
= GdipSetPenBrushFill(pen
, brush
);
145 GdipGetPenColor(pen
, &color
);
146 expect(0xabaddeed, color
);
147 GdipDeleteBrush(brush
);
150 /* get returns a clone, not a reference */
151 GdipGetPenBrushFill(pen
, &brush
);
152 GdipSetSolidFillColor((GpSolidFill
*)brush
, 0xbeadfeed);
153 GdipGetPenBrushFill(pen
, &brush2
);
154 ok(brush
!= brush2
, "Expected to get a clone, not a copy of the reference\n");
155 GdipGetSolidFillColor((GpSolidFill
*)brush2
, &color
);
156 expect(0xabaddeed, color
);
157 GdipDeleteBrush(brush
);
158 GdipDeleteBrush(brush2
);
160 /* brush cannot be NULL */
161 status
= GdipSetPenBrushFill(pen
, NULL
);
162 expect(InvalidParameter
, status
);
167 static void test_dasharray(void)
174 GdipCreatePen1(0xdeadbeef, 10.0, UnitWorld
, &pen
);
182 dashes
[7] = dashes
[8] = dashes
[9] = dashes
[10] = dashes
[11] = 1.0;
184 /* setting the array sets the type to custom */
185 GdipGetPenDashStyle(pen
, &style
);
186 expect(DashStyleSolid
, style
);
187 status
= GdipSetPenDashArray(pen
, dashes
, 2);
189 GdipGetPenDashStyle(pen
, &style
);
190 expect(DashStyleCustom
, style
);
192 /* Getting the array on a non-custom pen returns invalid parameter (unless
193 * you are getting 0 elements).*/
194 GdipSetPenDashStyle(pen
, DashStyleSolid
);
195 status
= GdipGetPenDashArray(pen
, &dashes
[5], 2);
196 expect(InvalidParameter
, status
);
197 status
= GdipGetPenDashArray(pen
, &dashes
[5], 0);
200 /* What does setting DashStyleCustom do to the array length? */
201 GdipSetPenDashArray(pen
, dashes
, 2);
202 GdipSetPenDashStyle(pen
, DashStyleCustom
);
203 status
= GdipGetPenDashArray(pen
, &dashes
[5], 2);
205 expectf(10.0, dashes
[5]);
206 expectf(11.0, dashes
[6]);
208 /* Set the array, then get with different sized buffers. */
209 status
= GdipSetPenDashArray(pen
, dashes
, 5);
213 status
= GdipGetPenDashArray(pen
, &dashes
[5], 1);
214 expect(Ok
, status
); /* not InsufficientBuffer! */
215 expectf(10.0, dashes
[5]);
216 expectf(-100.0, dashes
[6]);
218 status
= GdipGetPenDashArray(pen
, &dashes
[5], 6);
219 expect(InvalidParameter
, status
); /* not Ok! */
220 expectf(-100.0, dashes
[5]);
221 expectf(-100.0, dashes
[6]);
223 /* Some invalid array values. */
224 status
= GdipSetPenDashArray(pen
, &dashes
[7], 5);
227 status
= GdipSetPenDashArray(pen
, &dashes
[7], 5);
228 expect(InvalidParameter
, status
);
230 status
= GdipSetPenDashArray(pen
, &dashes
[7], 5);
231 expect(InvalidParameter
, status
);
233 /* Try to set with count = 0. */
234 GdipSetPenDashStyle(pen
, DashStyleDot
);
235 if (0) /* corrupts stack on 64-bit Vista */
237 status
= GdipSetPenDashArray(pen
, dashes
, 0);
238 ok(status
== OutOfMemory
|| status
== InvalidParameter
,
239 "Expected OutOfMemory or InvalidParameter, got %.8x\n", status
);
241 status
= GdipSetPenDashArray(pen
, dashes
, -1);
242 ok(status
== OutOfMemory
|| status
== InvalidParameter
,
243 "Expected OutOfMemory or InvalidParameter, got %.8x\n", status
);
244 GdipGetPenDashStyle(pen
, &style
);
245 expect(DashStyleDot
, style
);
250 static void test_customcap(void)
254 GpCustomLineCap
*custom
;
256 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
260 status
= GdipGetPenCustomStartCap(NULL
, NULL
);
261 expect(InvalidParameter
, status
);
262 status
= GdipGetPenCustomStartCap(pen
, NULL
);
263 expect(InvalidParameter
, status
);
264 status
= GdipGetPenCustomStartCap(NULL
, &custom
);
265 expect(InvalidParameter
, status
);
267 status
= GdipGetPenCustomEndCap(NULL
, NULL
);
268 expect(InvalidParameter
, status
);
269 status
= GdipGetPenCustomEndCap(pen
, NULL
);
270 expect(InvalidParameter
, status
);
271 status
= GdipGetPenCustomEndCap(NULL
, &custom
);
272 expect(InvalidParameter
, status
);
274 /* native crashes on pen == NULL, custom != NULL */
275 status
= GdipSetPenCustomStartCap(NULL
, NULL
);
276 expect(InvalidParameter
, status
);
277 status
= GdipSetPenCustomStartCap(pen
, NULL
);
278 expect(InvalidParameter
, status
);
280 status
= GdipSetPenCustomEndCap(NULL
, NULL
);
281 expect(InvalidParameter
, status
);
282 status
= GdipSetPenCustomEndCap(pen
, NULL
);
283 expect(InvalidParameter
, status
);
285 /* get without setting previously */
286 custom
= (GpCustomLineCap
*)0xdeadbeef;
287 status
= GdipGetPenCustomEndCap(pen
, &custom
);
289 ok(custom
== NULL
,"Expect CustomCap == NULL\n");
291 custom
= (GpCustomLineCap
*)0xdeadbeef;
292 status
= GdipGetPenCustomStartCap(pen
, &custom
);
294 ok(custom
== NULL
,"Expect CustomCap == NULL\n");
299 static void test_penfilltype(void)
303 GpLineGradient
*line
;
309 status
= GdipGetPenFillType(NULL
, NULL
);
310 expect(InvalidParameter
, status
);
312 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
314 status
= GdipGetPenFillType(pen
, NULL
);
315 expect(InvalidParameter
, status
);
317 /* created with GdipCreatePen1() */
318 status
= GdipGetPenFillType(pen
, &type
);
320 expect(PenTypeSolidColor
, type
);
323 /* based on SolidBrush */
324 status
= GdipCreateSolidFill((ARGB
)0xffff00ff, &solid
);
326 status
= GdipCreatePen2((GpBrush
*)solid
, 10.0f
, UnitPixel
, &pen
);
328 status
= GdipGetPenFillType(pen
, &type
);
330 expect(PenTypeSolidColor
, type
);
332 GdipDeleteBrush((GpBrush
*)solid
);
334 /* based on LinearGradientBrush */
337 status
= GdipCreateLineBrush(&a
, &b
, (ARGB
)0xffff00ff, (ARGB
)0xffff0000,
338 WrapModeTile
, &line
);
340 status
= GdipCreatePen2((GpBrush
*)line
, 10.0f
, UnitPixel
, &pen
);
342 status
= GdipGetPenFillType(pen
, &type
);
344 expect(PenTypeLinearGradient
, type
);
346 GdipDeleteBrush((GpBrush
*)line
);
349 static void test_compoundarray(void)
353 static const REAL testvalues
[] = {0.2, 0.4, 0.6, 0.8};
354 static const REAL notSortedValues
[] = {0.2, 0.6, 0.4, 0.8};
355 static const REAL negativeValues
[] = {-1.2, 0.4, 0.6, 0.8};
356 static const REAL tooLargeValues
[] = {0.2, 0.4, 0.6, 2.8};
359 status
= GdipSetPenCompoundArray(NULL
, testvalues
, 4);
360 expect(InvalidParameter
, status
);
362 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
365 status
= GdipGetPenCompoundCount(NULL
, NULL
);
366 expect(InvalidParameter
, status
);
368 status
= GdipGetPenCompoundCount(pen
, NULL
);
369 expect(InvalidParameter
, status
);
372 status
= GdipGetPenCompoundCount(pen
, &count
);
374 ok(count
== 0, "Unexpected compound count %d\n", count
);
376 status
= GdipSetPenCompoundArray(pen
, NULL
, 0);
377 expect(InvalidParameter
, status
);
378 status
= GdipSetPenCompoundArray(pen
, NULL
, 4);
379 expect(InvalidParameter
, status
);
380 status
= GdipSetPenCompoundArray(pen
, testvalues
, 3);
381 expect(InvalidParameter
, status
);
382 status
= GdipSetPenCompoundArray(pen
, testvalues
, 0);
383 expect(InvalidParameter
, status
);
384 status
= GdipSetPenCompoundArray(pen
, testvalues
, -2);
385 expect(InvalidParameter
, status
);
387 status
= GdipSetPenCompoundArray(pen
, notSortedValues
, 4);
388 expect(InvalidParameter
, status
);
389 status
= GdipSetPenCompoundArray(pen
, negativeValues
, 4);
390 expect(InvalidParameter
, status
);
391 status
= GdipSetPenCompoundArray(pen
, tooLargeValues
, 4);
392 expect(InvalidParameter
, status
);
394 status
= GdipSetPenCompoundArray(pen
, testvalues
, 4);
396 status
= GdipSetPenCompoundArray(pen
, NULL
, 0);
397 expect(InvalidParameter
, status
);
400 status
= GdipGetPenCompoundCount(pen
, &count
);
403 ok(count
== 4, "Unexpected compound count %d\n", count
);
408 static void get_pen_transform(GpPen
*pen
, REAL
*values
)
413 status
= GdipCreateMatrix(&matrix
);
416 status
= GdipGetPenTransform(pen
, matrix
);
418 status
= GdipGetMatrixElements(matrix
, values
);
421 GdipDeleteMatrix(matrix
);
424 static void test_transform(void)
428 GpMatrix
*matrix
, *matrix2
;
431 status
= GdipCreatePen1((ARGB
)0xffff00ff, 10.0f
, UnitPixel
, &pen
);
434 status
= GdipCreateMatrix(&matrix
);
437 status
= GdipGetPenTransform(pen
, matrix
);
440 status
= GdipGetMatrixElements(matrix
, values
);
443 expectf(1.0, values
[0]);
444 expectf(0.0, values
[1]);
445 expectf(0.0, values
[2]);
446 expectf(1.0, values
[3]);
447 expectf(0.0, values
[4]);
448 expectf(0.0, values
[5]);
450 GdipCreateMatrix2(3.0, -2.0, 5.0, 2.0, 6.0, 3.0, &matrix2
);
451 status
= GdipSetPenTransform(pen
, matrix2
);
453 GdipDeleteMatrix(matrix2
);
455 status
= GdipGetPenTransform(pen
, matrix
);
457 status
= GdipGetMatrixElements(matrix
, values
);
459 expectf(3.0, values
[0]);
460 expectf(-2.0, values
[1]);
461 expectf(5.0, values
[2]);
462 expectf(2.0, values
[3]);
463 expectf(6.0, values
[4]);
464 expectf(3.0, values
[5]);
467 status
= GdipTranslatePenTransform(NULL
, 1.0, -2.0, MatrixOrderAppend
);
468 expect(InvalidParameter
, status
);
470 status
= GdipTranslatePenTransform(pen
, 1.0, -2.0, MatrixOrderAppend
);
473 status
= GdipGetPenTransform(pen
, matrix
);
475 status
= GdipGetMatrixElements(matrix
, values
);
477 expectf(3.0, values
[0]);
478 expectf(-2.0, values
[1]);
479 expectf(5.0, values
[2]);
480 expectf(2.0, values
[3]);
481 expectf(7.0, values
[4]);
482 expectf(1.0, values
[5]);
484 status
= GdipTranslatePenTransform(pen
, -3.0, 5.0, MatrixOrderPrepend
);
487 status
= GdipGetPenTransform(pen
, matrix
);
489 status
= GdipGetMatrixElements(matrix
, values
);
491 expectf(3.0, values
[0]);
492 expectf(-2.0, values
[1]);
493 expectf(5.0, values
[2]);
494 expectf(2.0, values
[3]);
495 expectf(23.0, values
[4]);
496 expectf(17.0, values
[5]);
498 status
= GdipResetPenTransform(pen
);
501 status
= GdipGetPenTransform(pen
, matrix
);
503 status
= GdipGetMatrixElements(matrix
, values
);
506 expectf(1.0, values
[0]);
507 expectf(0.0, values
[1]);
508 expectf(0.0, values
[2]);
509 expectf(1.0, values
[3]);
510 expectf(0.0, values
[4]);
511 expectf(0.0, values
[5]);
514 status
= GdipScalePenTransform(NULL
, 1.0, 1.0, MatrixOrderPrepend
);
515 expect(InvalidParameter
, status
);
517 status
= GdipScalePenTransform(pen
, 1.0, 1.0, MatrixOrderPrepend
);
520 get_pen_transform(pen
, values
);
521 expectf(1.0, values
[0]);
522 expectf(0.0, values
[1]);
523 expectf(0.0, values
[2]);
524 expectf(1.0, values
[3]);
525 expectf(0.0, values
[4]);
526 expectf(0.0, values
[5]);
528 status
= GdipScalePenTransform(pen
, 2.0, -10.0, MatrixOrderPrepend
);
531 get_pen_transform(pen
, values
);
532 expectf(2.0, values
[0]);
533 expectf(0.0, values
[1]);
534 expectf(0.0, values
[2]);
535 expectf(-10.0, values
[3]);
536 expectf(0.0, values
[4]);
537 expectf(0.0, values
[5]);
539 status
= GdipScalePenTransform(pen
, 2.0, -10.0, MatrixOrderAppend
);
542 get_pen_transform(pen
, values
);
543 expectf(4.0, values
[0]);
544 expectf(0.0, values
[1]);
545 expectf(0.0, values
[2]);
546 expectf(100.0, values
[3]);
547 expectf(0.0, values
[4]);
548 expectf(0.0, values
[5]);
550 status
= GdipTranslatePenTransform(pen
, 1.0, -2.0, MatrixOrderAppend
);
553 get_pen_transform(pen
, values
);
554 expectf(4.0, values
[0]);
555 expectf(0.0, values
[1]);
556 expectf(0.0, values
[2]);
557 expectf(100.0, values
[3]);
558 expectf(1.0, values
[4]);
559 expectf(-2.0, values
[5]);
561 status
= GdipScalePenTransform(pen
, 2.0, -10.0, MatrixOrderPrepend
);
564 get_pen_transform(pen
, values
);
565 expectf(8.0, values
[0]);
566 expectf(0.0, values
[1]);
567 expectf(0.0, values
[2]);
568 expectf(-1000.0, values
[3]);
569 expectf(1.0, values
[4]);
570 expectf(-2.0, values
[5]);
573 status
= GdipResetPenTransform(pen
);
576 status
= GdipSetMatrixElements(matrix
, 2.0, 1.0, 1.0, 4.0, 1.0, 2.0);
579 status
= GdipMultiplyPenTransform(NULL
, matrix
, MatrixOrderPrepend
);
580 expect(InvalidParameter
, status
);
582 status
= GdipMultiplyPenTransform(pen
, matrix
, MatrixOrderPrepend
);
585 get_pen_transform(pen
, values
);
586 expectf(2.0, values
[0]);
587 expectf(1.0, values
[1]);
588 expectf(1.0, values
[2]);
589 expectf(4.0, values
[3]);
590 expectf(1.0, values
[4]);
591 expectf(2.0, values
[5]);
593 status
= GdipScalePenTransform(pen
, 2.0, -10.0, MatrixOrderAppend
);
596 status
= GdipMultiplyPenTransform(pen
, matrix
, MatrixOrderAppend
);
599 get_pen_transform(pen
, values
);
600 expectf(-2.0, values
[0]);
601 expectf(-36.0, values
[1]);
602 expectf(-36.0, values
[2]);
603 expectf(-158.0, values
[3]);
604 expectf(-15.0, values
[4]);
605 expectf(-76.0, values
[5]);
608 status
= GdipResetPenTransform(pen
);
611 status
= GdipSetMatrixElements(matrix
, 2.0, 1.0, 1.0, 4.0, 1.0, 2.0);
614 status
= GdipSetPenTransform(pen
, matrix
);
617 status
= GdipRotatePenTransform(NULL
, 10.0, MatrixOrderPrepend
);
618 expect(InvalidParameter
, status
);
620 status
= GdipRotatePenTransform(pen
, 45.0, MatrixOrderPrepend
);
623 get_pen_transform(pen
, values
);
624 expectf(2.12, values
[0]);
625 expectf(3.54, values
[1]);
626 expectf(-0.71, values
[2]);
627 expectf(2.12, values
[3]);
628 expectf(1.0, values
[4]);
629 expectf(2.0, values
[5]);
631 status
= GdipScalePenTransform(pen
, 2.0, -10.0, MatrixOrderAppend
);
634 status
= GdipRotatePenTransform(pen
, 180.0, MatrixOrderAppend
);
637 get_pen_transform(pen
, values
);
638 expectf(-4.24, values
[0]);
639 expectf(35.36, values
[1]);
640 expectf(1.41, values
[2]);
641 expectf(21.21, values
[3]);
642 expectf(-2.0, values
[4]);
643 expectf(20.0, values
[5]);
647 GdipDeleteMatrix(matrix
);
652 struct GdiplusStartupInput gdiplusStartupInput
;
653 ULONG_PTR gdiplusToken
;
655 int (CDECL
* _controlfp_s
)(unsigned int *cur
, unsigned int newval
, unsigned int mask
);
657 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
658 hmsvcrt
= LoadLibraryA("msvcrt");
659 _controlfp_s
= (void*)GetProcAddress(hmsvcrt
, "_controlfp_s");
660 if (_controlfp_s
) _controlfp_s(0, 0, 0x0008001e);
664 gdiplusStartupInput
.GdiplusVersion
= 1;
665 gdiplusStartupInput
.DebugEventCallback
= NULL
;
666 gdiplusStartupInput
.SuppressBackgroundThread
= 0;
667 gdiplusStartupInput
.SuppressExternalCodecs
= 0;
669 GdiplusStartup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
671 test_constructor_destructor();
672 test_constructor_destructor2();
677 test_compoundarray();
680 GdiplusShutdown(gdiplusToken
);