[CRT] Massively improve performance of rand_s
[reactos.git] / modules / rostests / winetests / gdiplus / brush.c
1 /*
2 * Unit test suite for brushes
3 *
4 * Copyright (C) 2007 Google (Evan Stade)
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include <math.h>
22
23 #include "objbase.h"
24 #include "gdiplus.h"
25 #include "wine/test.h"
26
27 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
28 #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
29
30 static HWND hwnd;
31
32 static void test_constructor_destructor(void)
33 {
34 GpStatus status;
35 GpSolidFill *brush = NULL;
36
37 status = GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
38 expect(Ok, status);
39 ok(brush != NULL, "Expected brush to be initialized\n");
40
41 status = GdipDeleteBrush(NULL);
42 expect(InvalidParameter, status);
43
44 status = GdipDeleteBrush((GpBrush*) brush);
45 expect(Ok, status);
46 }
47
48 static void test_createHatchBrush(void)
49 {
50 GpStatus status;
51 GpHatch *brush;
52
53 status = GdipCreateHatchBrush(HatchStyleMin, 1, 2, &brush);
54 expect(Ok, status);
55 ok(brush != NULL, "Expected the brush to be initialized.\n");
56
57 GdipDeleteBrush((GpBrush *)brush);
58
59 status = GdipCreateHatchBrush(HatchStyleMax, 1, 2, &brush);
60 expect(Ok, status);
61 ok(brush != NULL, "Expected the brush to be initialized.\n");
62
63 GdipDeleteBrush((GpBrush *)brush);
64
65 status = GdipCreateHatchBrush(HatchStyle05Percent, 1, 2, NULL);
66 expect(InvalidParameter, status);
67
68 status = GdipCreateHatchBrush((HatchStyle)(HatchStyleMin - 1), 1, 2, &brush);
69 expect(InvalidParameter, status);
70
71 status = GdipCreateHatchBrush((HatchStyle)(HatchStyleMax + 1), 1, 2, &brush);
72 expect(InvalidParameter, status);
73 }
74
75 static void test_createLineBrushFromRectWithAngle(void)
76 {
77 GpStatus status;
78 GpLineGradient *brush;
79 GpRectF rect1 = { 1, 3, 1, 2 };
80 GpRectF rect2 = { 1, 3, -1, -2 };
81 GpRectF rect3 = { 1, 3, 0, 1 };
82 GpRectF rect4 = { 1, 3, 1, 0 };
83
84 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 0, TRUE, WrapModeTile, &brush);
85 expect(Ok, status);
86 GdipDeleteBrush((GpBrush *) brush);
87
88 status = GdipCreateLineBrushFromRectWithAngle(&rect2, 10, 11, 135, TRUE, (WrapMode)(WrapModeTile - 1), &brush);
89 expect(Ok, status);
90 GdipDeleteBrush((GpBrush *) brush);
91
92 status = GdipCreateLineBrushFromRectWithAngle(&rect2, 10, 11, -225, FALSE, (WrapMode)(WrapModeTile - 1), &brush);
93 expect(Ok, status);
94 GdipDeleteBrush((GpBrush *) brush);
95
96 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 405, TRUE, (WrapMode)(WrapModeClamp + 1), &brush);
97 expect(Ok, status);
98 GdipDeleteBrush((GpBrush *) brush);
99
100 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 45, FALSE, (WrapMode)(WrapModeClamp + 1), &brush);
101 expect(Ok, status);
102 GdipDeleteBrush((GpBrush *) brush);
103
104 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeTileFlipX, &brush);
105 expect(Ok, status);
106
107 status = GdipCreateLineBrushFromRectWithAngle(NULL, 10, 11, 90, TRUE, WrapModeTile, &brush);
108 expect(InvalidParameter, status);
109
110 status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeTileFlipXY, &brush);
111 expect(OutOfMemory, status);
112
113 status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeTileFlipXY, &brush);
114 expect(OutOfMemory, status);
115
116 status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeTileFlipXY, NULL);
117 expect(InvalidParameter, status);
118
119 status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeTileFlipXY, NULL);
120 expect(InvalidParameter, status);
121
122 status = GdipCreateLineBrushFromRectWithAngle(&rect3, 10, 11, 90, TRUE, WrapModeClamp, &brush);
123 expect(InvalidParameter, status);
124
125 status = GdipCreateLineBrushFromRectWithAngle(&rect4, 10, 11, 90, TRUE, WrapModeClamp, &brush);
126 expect(InvalidParameter, status);
127
128 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeClamp, &brush);
129 expect(InvalidParameter, status);
130
131 status = GdipCreateLineBrushFromRectWithAngle(&rect1, 10, 11, 90, TRUE, WrapModeTile, NULL);
132 expect(InvalidParameter, status);
133
134 GdipDeleteBrush((GpBrush *) brush);
135 }
136
137 static void test_type(void)
138 {
139 GpStatus status;
140 GpBrushType bt;
141 GpSolidFill *brush = NULL;
142
143 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
144
145 status = GdipGetBrushType((GpBrush*)brush, &bt);
146 expect(Ok, status);
147 expect(BrushTypeSolidColor, bt);
148
149 GdipDeleteBrush((GpBrush*) brush);
150 }
151 static GpPointF blendcount_ptf[] = {{0.0, 0.0},
152 {50.0, 50.0}};
153 static void test_gradientblendcount(void)
154 {
155 GpStatus status;
156 GpPathGradient *brush;
157 INT count;
158
159 status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &brush);
160 expect(Ok, status);
161
162 status = GdipGetPathGradientBlendCount(NULL, NULL);
163 expect(InvalidParameter, status);
164 status = GdipGetPathGradientBlendCount(NULL, &count);
165 expect(InvalidParameter, status);
166 status = GdipGetPathGradientBlendCount(brush, NULL);
167 expect(InvalidParameter, status);
168
169 status = GdipGetPathGradientBlendCount(brush, &count);
170 expect(Ok, status);
171 expect(1, count);
172
173 GdipDeleteBrush((GpBrush*) brush);
174 }
175
176 static GpPointF getblend_ptf[] = {{0.0, 0.0},
177 {50.0, 50.0}};
178 static void test_getblend(void)
179 {
180 GpStatus status;
181 GpPathGradient *brush;
182 REAL blends[4];
183 REAL pos[4];
184
185 status = GdipCreatePathGradient(getblend_ptf, 2, WrapModeClamp, &brush);
186 expect(Ok, status);
187
188 /* check some invalid parameters combinations */
189 status = GdipGetPathGradientBlend(NULL, NULL, NULL, -1);
190 expect(InvalidParameter, status);
191 status = GdipGetPathGradientBlend(brush,NULL, NULL, -1);
192 expect(InvalidParameter, status);
193 status = GdipGetPathGradientBlend(NULL, blends,NULL, -1);
194 expect(InvalidParameter, status);
195 status = GdipGetPathGradientBlend(NULL, NULL, pos, -1);
196 expect(InvalidParameter, status);
197 status = GdipGetPathGradientBlend(NULL, NULL, NULL, 1);
198 expect(InvalidParameter, status);
199
200 blends[0] = (REAL)0xdeadbeef;
201 pos[0] = (REAL)0xdeadbeef;
202 status = GdipGetPathGradientBlend(brush, blends, pos, 1);
203 expect(Ok, status);
204 expectf(1.0, blends[0]);
205 expectf((REAL)0xdeadbeef, pos[0]);
206
207 GdipDeleteBrush((GpBrush*) brush);
208 }
209
210 static GpPointF getbounds_ptf[] = {{0.0, 20.0},
211 {50.0, 50.0},
212 {21.0, 25.0},
213 {25.0, 46.0}};
214 static void test_getbounds(void)
215 {
216 GpStatus status;
217 GpPathGradient *brush;
218 GpRectF bounds;
219
220 status = GdipCreatePathGradient(getbounds_ptf, 4, WrapModeClamp, &brush);
221 expect(Ok, status);
222
223 status = GdipGetPathGradientRect(NULL, NULL);
224 expect(InvalidParameter, status);
225 status = GdipGetPathGradientRect(brush, NULL);
226 expect(InvalidParameter, status);
227 status = GdipGetPathGradientRect(NULL, &bounds);
228 expect(InvalidParameter, status);
229
230 status = GdipGetPathGradientRect(brush, &bounds);
231 expect(Ok, status);
232 expectf(0.0, bounds.X);
233 expectf(20.0, bounds.Y);
234 expectf(50.0, bounds.Width);
235 expectf(30.0, bounds.Height);
236
237 GdipDeleteBrush((GpBrush*) brush);
238 }
239
240 static void test_getgamma(void)
241 {
242 GpStatus status;
243 GpLineGradient *line;
244 GpPointF start, end;
245 BOOL gamma;
246
247 start.X = start.Y = 0.0;
248 end.X = end.Y = 100.0;
249
250 status = GdipCreateLineBrush(&start, &end, (ARGB)0xdeadbeef, 0xdeadbeef, WrapModeTile, &line);
251 expect(Ok, status);
252
253 /* NULL arguments */
254 status = GdipGetLineGammaCorrection(NULL, NULL);
255 expect(InvalidParameter, status);
256 status = GdipGetLineGammaCorrection(line, NULL);
257 expect(InvalidParameter, status);
258 status = GdipGetLineGammaCorrection(NULL, &gamma);
259 expect(InvalidParameter, status);
260
261 GdipDeleteBrush((GpBrush*)line);
262 }
263
264 static void test_transform(void)
265 {
266 GpStatus status;
267 GpTexture *texture;
268 GpLineGradient *line;
269 GpGraphics *graphics = NULL;
270 GpBitmap *bitmap;
271 HDC hdc = GetDC(0);
272 GpMatrix *m, *m1;
273 BOOL res;
274 GpPointF start, end;
275 GpRectF rectf;
276 REAL elements[6];
277
278 /* GpTexture */
279 status = GdipCreateMatrix2(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, &m);
280 expect(Ok, status);
281
282 status = GdipCreateFromHDC(hdc, &graphics);
283 expect(Ok, status);
284 status = GdipCreateBitmapFromGraphics(1, 1, graphics, &bitmap);
285 expect(Ok, status);
286
287 status = GdipCreateTexture((GpImage*)bitmap, WrapModeTile, &texture);
288 expect(Ok, status);
289
290 /* NULL */
291 status = GdipGetTextureTransform(NULL, NULL);
292 expect(InvalidParameter, status);
293 status = GdipGetTextureTransform(texture, NULL);
294 expect(InvalidParameter, status);
295
296 /* get default value - identity matrix */
297 status = GdipGetTextureTransform(texture, m);
298 expect(Ok, status);
299 status = GdipIsMatrixIdentity(m, &res);
300 expect(Ok, status);
301 expect(TRUE, res);
302 /* set and get then */
303 status = GdipCreateMatrix2(2.0, 0.0, 0.0, 2.0, 0.0, 0.0, &m1);
304 expect(Ok, status);
305 status = GdipSetTextureTransform(texture, m1);
306 expect(Ok, status);
307 status = GdipGetTextureTransform(texture, m);
308 expect(Ok, status);
309 status = GdipIsMatrixEqual(m, m1, &res);
310 expect(Ok, status);
311 expect(TRUE, res);
312 /* reset */
313 status = GdipResetTextureTransform(texture);
314 expect(Ok, status);
315 status = GdipGetTextureTransform(texture, m);
316 expect(Ok, status);
317 status = GdipIsMatrixIdentity(m, &res);
318 expect(Ok, status);
319 expect(TRUE, res);
320
321 status = GdipDeleteBrush((GpBrush*)texture);
322 expect(Ok, status);
323
324 status = GdipDeleteMatrix(m1);
325 expect(Ok, status);
326 status = GdipDeleteMatrix(m);
327 expect(Ok, status);
328 status = GdipDisposeImage((GpImage*)bitmap);
329 expect(Ok, status);
330 status = GdipDeleteGraphics(graphics);
331 expect(Ok, status);
332
333
334
335 status = GdipCreateFromHWND(hwnd, &graphics);
336 expect(Ok, status);
337
338 /* GpLineGradient */
339 /* create with vertical gradient line */
340 start.X = start.Y = end.X = 0.0;
341 end.Y = 100.0;
342
343 status = GdipCreateLineBrush(&start, &end, (ARGB)0xffff0000, 0xff00ff00, WrapModeTile, &line);
344 expect(Ok, status);
345
346 status = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, &m);
347 expect(Ok, status);
348
349 /* NULL arguments */
350 status = GdipResetLineTransform(NULL);
351 expect(InvalidParameter, status);
352 status = GdipSetLineTransform(NULL, m);
353 expect(InvalidParameter, status);
354 status = GdipSetLineTransform(line, NULL);
355 expect(InvalidParameter, status);
356 status = GdipGetLineTransform(NULL, m);
357 expect(InvalidParameter, status);
358 status = GdipGetLineTransform(line, NULL);
359 expect(InvalidParameter, status);
360 status = GdipScaleLineTransform(NULL, 1, 1, MatrixOrderPrepend);
361 expect(InvalidParameter, status);
362 status = GdipMultiplyLineTransform(NULL, m, MatrixOrderPrepend);
363 expect(InvalidParameter, status);
364 status = GdipTranslateLineTransform(NULL, 0, 0, MatrixOrderPrepend);
365 expect(InvalidParameter, status);
366
367 /* initial transform */
368 status = GdipGetLineTransform(line, m);
369 expect(Ok, status);
370
371 status = GdipGetMatrixElements(m, elements);
372 expect(Ok, status);
373 expectf(0.0, elements[0]);
374 expectf(1.0, elements[1]);
375 expectf(-1.0, elements[2]);
376 expectf(0.0, elements[3]);
377 expectf(50.0, elements[4]);
378 expectf(50.0, elements[5]);
379
380 status = GdipGetLineRect(line, &rectf);
381 expect(Ok, status);
382 expectf(-50.0, rectf.X);
383 expectf(0.0, rectf.Y);
384 expectf(100.0, rectf.Width);
385 expectf(100.0, rectf.Height);
386
387 status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 0, 200, 200);
388 expect(Ok, status);
389
390 /* manually set transform */
391 GdipSetMatrixElements(m, 2.0, 0.0, 0.0, 4.0, 0.0, 0.0);
392
393 status = GdipSetLineTransform(line, m);
394 expect(Ok, status);
395
396 status = GdipGetLineTransform(line, m);
397 expect(Ok, status);
398
399 status = GdipGetMatrixElements(m, elements);
400 expect(Ok, status);
401 expectf(2.0, elements[0]);
402 expectf(0.0, elements[1]);
403 expectf(0.0, elements[2]);
404 expectf(4.0, elements[3]);
405 expectf(0.0, elements[4]);
406 expectf(0.0, elements[5]);
407
408 status = GdipGetLineRect(line, &rectf);
409 expect(Ok, status);
410 expectf(-50.0, rectf.X);
411 expectf(0.0, rectf.Y);
412 expectf(100.0, rectf.Width);
413 expectf(100.0, rectf.Height);
414
415 status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 0, 200, 200);
416 expect(Ok, status);
417
418 /* scale transform */
419 status = GdipScaleLineTransform(line, 4.0, 0.5, MatrixOrderAppend);
420 expect(Ok, status);
421
422 status = GdipGetLineTransform(line, m);
423 expect(Ok, status);
424
425 status = GdipGetMatrixElements(m, elements);
426 expect(Ok, status);
427 expectf(8.0, elements[0]);
428 expectf(0.0, elements[1]);
429 expectf(0.0, elements[2]);
430 expectf(2.0, elements[3]);
431 expectf(0.0, elements[4]);
432 expectf(0.0, elements[5]);
433
434 status = GdipGetLineRect(line, &rectf);
435 expect(Ok, status);
436 expectf(-50.0, rectf.X);
437 expectf(0.0, rectf.Y);
438 expectf(100.0, rectf.Width);
439 expectf(100.0, rectf.Height);
440
441 status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 0, 200, 200);
442 expect(Ok, status);
443
444 /* translate transform */
445 status = GdipTranslateLineTransform(line, 10.0, -20.0, MatrixOrderAppend);
446 expect(Ok, status);
447
448 status = GdipGetLineTransform(line, m);
449 expect(Ok, status);
450
451 status = GdipGetMatrixElements(m, elements);
452 expect(Ok, status);
453 expectf(8.0, elements[0]);
454 expectf(0.0, elements[1]);
455 expectf(0.0, elements[2]);
456 expectf(2.0, elements[3]);
457 expectf(10.0, elements[4]);
458 expectf(-20.0, elements[5]);
459
460 status = GdipGetLineRect(line, &rectf);
461 expect(Ok, status);
462 expectf(-50.0, rectf.X);
463 expectf(0.0, rectf.Y);
464 expectf(100.0, rectf.Width);
465 expectf(100.0, rectf.Height);
466
467 status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 200, 200, 200);
468 expect(Ok, status);
469
470 /* multiply transform */
471 GdipSetMatrixElements(m, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
472 GdipRotateMatrix(m, 45.0, MatrixOrderAppend);
473 GdipScaleMatrix(m, 0.25, 0.5, MatrixOrderAppend);
474
475 status = GdipMultiplyLineTransform(line, m, MatrixOrderAppend);
476 expect(Ok, status);
477
478 /* NULL transform does nothing */
479 status = GdipMultiplyLineTransform(line, NULL, MatrixOrderAppend);
480 expect(Ok, status);
481
482 status = GdipGetLineTransform(line, m);
483 expect(Ok, status);
484
485 status = GdipGetMatrixElements(m, elements);
486 expect(Ok, status);
487 expectf(1.414214, elements[0]);
488 expectf(2.828427, elements[1]);
489 expectf(-0.353553, elements[2]);
490 expectf(0.707107, elements[3]);
491 expectf(5.303300, elements[4]);
492 expectf(-3.535534, elements[5]);
493
494 status = GdipGetLineRect(line, &rectf);
495 expect(Ok, status);
496 expectf(-50.0, rectf.X);
497 expectf(0.0, rectf.Y);
498 expectf(100.0, rectf.Width);
499 expectf(100.0, rectf.Height);
500
501 status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 200, 200, 200);
502 expect(Ok, status);
503
504 /* reset transform sets to identity */
505 status = GdipResetLineTransform(line);
506 expect(Ok, status);
507
508 status = GdipGetLineTransform(line, m);
509 expect(Ok, status);
510
511 status = GdipGetMatrixElements(m, elements);
512 expect(Ok, status);
513 expectf(1.0, elements[0]);
514 expectf(0.0, elements[1]);
515 expectf(0.0, elements[2]);
516 expectf(1.0, elements[3]);
517 expectf(0.0, elements[4]);
518 expectf(0.0, elements[5]);
519
520 status = GdipGetLineRect(line, &rectf);
521 expect(Ok, status);
522 expectf(-50.0, rectf.X);
523 expectf(0.0, rectf.Y);
524 expectf(100.0, rectf.Width);
525 expectf(100.0, rectf.Height);
526
527 status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 200, 200, 200);
528 expect(Ok, status);
529
530 GdipDeleteBrush((GpBrush*)line);
531
532 /* passing negative Width/Height to LinearGradientModeHorizontal */
533 rectf.X = rectf.Y = 10.0;
534 rectf.Width = rectf.Height = -100.0;
535 status = GdipCreateLineBrushFromRect(&rectf, (ARGB)0xffff0000, 0xff00ff00,
536 LinearGradientModeHorizontal, WrapModeTile, &line);
537 expect(Ok, status);
538 memset(&rectf, 0, sizeof(GpRectF));
539 status = GdipGetLineRect(line, &rectf);
540 expect(Ok, status);
541 expectf(10.0, rectf.X);
542 expectf(10.0, rectf.Y);
543 expectf(-100.0, rectf.Width);
544 expectf(-100.0, rectf.Height);
545 status = GdipGetLineTransform(line, m);
546 expect(Ok, status);
547 status = GdipGetMatrixElements(m, elements);
548 expect(Ok,status);
549 expectf(1.0, elements[0]);
550 expectf(0.0, elements[1]);
551 expectf(0.0, elements[2]);
552 expectf(1.0, elements[3]);
553 expectf(0.0, elements[4]);
554 expectf(0.0, elements[5]);
555 status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 400, 200, 200);
556 expect(Ok, status);
557 status = GdipDeleteBrush((GpBrush*)line);
558 expect(Ok,status);
559
560 if(0){
561 /* enable to visually compare with Windows */
562 MSG msg;
563 while(GetMessageW(&msg, hwnd, 0, 0) > 0){
564 TranslateMessage(&msg);
565 DispatchMessageW(&msg);
566 }
567 }
568
569 GdipDeleteMatrix(m);
570 GdipDeleteGraphics(graphics);
571 ReleaseDC(0, hdc);
572 }
573
574 static void test_texturewrap(void)
575 {
576 GpStatus status;
577 GpTexture *texture;
578 GpGraphics *graphics = NULL;
579 GpBitmap *bitmap;
580 HDC hdc = GetDC(0);
581 GpWrapMode wrap;
582
583 status = GdipCreateFromHDC(hdc, &graphics);
584 expect(Ok, status);
585 status = GdipCreateBitmapFromGraphics(1, 1, graphics, &bitmap);
586 expect(Ok, status);
587
588 status = GdipCreateTexture((GpImage*)bitmap, WrapModeTile, &texture);
589 expect(Ok, status);
590
591 /* NULL */
592 status = GdipGetTextureWrapMode(NULL, NULL);
593 expect(InvalidParameter, status);
594 status = GdipGetTextureWrapMode(texture, NULL);
595 expect(InvalidParameter, status);
596 status = GdipGetTextureWrapMode(NULL, &wrap);
597 expect(InvalidParameter, status);
598
599 /* get */
600 wrap = WrapModeClamp;
601 status = GdipGetTextureWrapMode(texture, &wrap);
602 expect(Ok, status);
603 expect(WrapModeTile, wrap);
604 /* set, then get */
605 wrap = WrapModeClamp;
606 status = GdipSetTextureWrapMode(texture, wrap);
607 expect(Ok, status);
608 wrap = WrapModeTile;
609 status = GdipGetTextureWrapMode(texture, &wrap);
610 expect(Ok, status);
611 expect(WrapModeClamp, wrap);
612
613 status = GdipDeleteBrush((GpBrush*)texture);
614 expect(Ok, status);
615 status = GdipDisposeImage((GpImage*)bitmap);
616 expect(Ok, status);
617 status = GdipDeleteGraphics(graphics);
618 expect(Ok, status);
619 ReleaseDC(0, hdc);
620 }
621
622 static void test_gradientgetrect(void)
623 {
624 static const struct
625 {
626 LinearGradientMode mode;
627 GpRectF rect;
628 REAL transform[6];
629 }
630 create_from_rect[] =
631 {
632 { LinearGradientModeHorizontal, { 10.0f, 10.0f, -100.0f, -100.0f } },
633 { LinearGradientModeHorizontal, { 10.0f, 10.0f, 100.0f, 100.0f } },
634 { LinearGradientModeHorizontal, { 10.0f, -5.0f, 100.0f, 50.0f } },
635 { LinearGradientModeHorizontal, { -5.0f, 10.0f, 100.0f, 50.0f } },
636 { LinearGradientModeVertical, { 0.0f, 0.0f, 100.0f, 10.0f }, { 0.0f, 0.1f, -10.0f, -0.0f, 100.0f, 0.0f } },
637 { LinearGradientModeVertical, { 10.0f, -12.0f, 100.0f, 105.0f }, { 0.0f, 1.05f, -0.952f, 0.0f, 98.571f, -22.5f } },
638 };
639 static const struct
640 {
641 GpPointF pt1, pt2;
642 GpRectF rect;
643 REAL transform[6];
644 }
645 create_from_pt[] =
646 {
647 { { 1.0f, 1.0f }, { 100.0f, 100.0f }, { 1.0f, 1.0f, 99.0f, 99.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 50.50f, -50.50f } },
648 { { 0.0f, 0.0f }, { 0.0f, 10.0f }, { -5.0f, 0.0f, 10.0f, 10.0f }, { 0.0f, 1.0f, -1.0f, 0.0f, 5.0f, 5.0f } },
649 { { 0.0f, 0.0f }, { 10.0f, 0.0f }, { 0.0f, -5.0f, 10.0f, 10.0f }, { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f } },
650 /* Slope = -1 */
651 { { 0.0f, 0.0f }, { 20.0f, -20.0f }, { 0.0f, -20.0f, 20.0f, 20.0f }, { 1.0f, -1.0f, 1.0f, 1.0f, 10.0f, 10.0f } },
652 /* Slope = 1/100 */
653 { { 0.0f, 0.0f }, { 100.0f, 1.0f }, { 0.0f, 0.0f, 100.0f, 1.0f }, { 1.0f, 0.01f, -0.02f, 2.0f, 0.01f, -1.0f } },
654 { { 10.0f, 10.0f }, { -90.0f, 10.0f }, { -90.0f, -40.0f, 100.0f, 100.0f }, { -1.0f, 0.0f, 0.0f, -1.0f, -80.0f, 20.0f } },
655 };
656 static const struct
657 {
658 GpRectF rect;
659 REAL angle;
660 BOOL is_scalable;
661 REAL transform[6];
662 }
663 create_with_angle[] =
664 {
665 { { 10.0f, 10.0f, -100.0f, -100.0f }, 0.0f, TRUE },
666 { { 10.0f, 10.0f, -100.0f, -100.0f }, 0.0f, FALSE },
667 { { 10.0f, 10.0f, 100.0f, 100.0f }, 0.0f, FALSE },
668 { { 10.0f, 10.0f, 100.0f, 100.0f }, 0.0f, TRUE },
669 { { 10.0f, -5.0f, 100.0f, 50.0f }, 0.0f, FALSE },
670 { { 10.0f, -5.0f, 100.0f, 50.0f }, 0.0f, TRUE },
671 { { -5.0f, 10.0f, 100.0f, 50.0f }, 0.0f, FALSE },
672 { { -5.0f, 10.0f, 100.0f, 50.0f }, 0.0f, TRUE },
673 { { 0.0f, 0.0f, 100.0f, 10.0f }, -90.0f, TRUE, { 0.0f, -0.1f, 10.0f, 0.0f, 0.0f, 10.0f } },
674 { { 10.0f, -12.0f, 100.0f, 105.0f }, -90.0f, TRUE, { 0.0f, -1.05f, 0.952f, 0.0f, 21.429f, 103.5f } },
675 { { 0.0f, 0.0f, 100.0f, 10.0f }, -90.0f, FALSE, { 0.0f, -0.1f, 10.0f, -0.0f, 0.0f, 10.0f } },
676 { { 10.0f, -12.0f, 100.0f, 105.0f }, -90.0f, FALSE, { 0.0f, -1.05f, 0.952f, 0.0f, 21.429f, 103.5f } },
677 };
678 GpLineGradient *brush;
679 GpMatrix *transform;
680 REAL elements[6];
681 GpStatus status;
682 unsigned int i;
683 ARGB colors[2];
684 GpRectF rectf;
685
686 status = GdipCreateMatrix(&transform);
687 expect(Ok, status);
688
689 for (i = 0; i < ARRAY_SIZE(create_from_pt); ++i)
690 {
691 status = GdipCreateLineBrush(&create_from_pt[i].pt1, &create_from_pt[i].pt2, 0x1, 0x2, WrapModeTile, &brush);
692 ok(status == Ok, "Failed to create a brush, %d.\n", status);
693
694 memset(&rectf, 0, sizeof(rectf));
695 status = GdipGetLineRect(brush, &rectf);
696 ok(status == Ok, "Failed to get brush rect, %d.\n", status);
697 ok(!memcmp(&rectf, &create_from_pt[i].rect, sizeof(rectf)), "Unexpected brush rect.\n");
698
699 status = GdipGetLineTransform(brush, transform);
700 ok(status == Ok, "Failed to get brush transform, %d.\n", status);
701
702 status = GdipGetMatrixElements(transform, elements);
703 ok(status == Ok, "Failed to get matrix elements, %d.\n", status);
704
705 #define expectf2(expected, got) ok(fabs(expected - got) < 0.001, "%u: expected %.3f, got %.3f.\n", i, expected, got)
706 expectf2(create_from_pt[i].transform[0], elements[0]);
707 expectf2(create_from_pt[i].transform[1], elements[1]);
708 expectf2(create_from_pt[i].transform[2], elements[2]);
709 expectf2(create_from_pt[i].transform[3], elements[3]);
710 expectf2(create_from_pt[i].transform[4], elements[4]);
711 expectf2(create_from_pt[i].transform[5], elements[5]);
712 #undef expect2f
713
714 status = GdipGetLineColors(brush, colors);
715 ok(status == Ok, "Failed to get line colors, %d.\n", status);
716 ok(colors[0] == 0x1 && colors[1] == 0x2, "Unexpected brush colors.\n");
717
718 status = GdipDeleteBrush((GpBrush *)brush);
719 ok(status == Ok, "Failed to delete a brush, %d.\n", status);
720 }
721
722 /* zero height rect */
723 rectf.X = rectf.Y = 10.0;
724 rectf.Width = 100.0;
725 rectf.Height = 0.0;
726 status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeVertical,
727 WrapModeTile, &brush);
728 expect(OutOfMemory, status);
729
730 /* zero width rect */
731 rectf.X = rectf.Y = 10.0;
732 rectf.Width = 0.0;
733 rectf.Height = 100.0;
734 status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal,
735 WrapModeTile, &brush);
736 expect(OutOfMemory, status);
737
738 for (i = 0; i < ARRAY_SIZE(create_from_rect); ++i)
739 {
740 ARGB colors[2];
741 BOOL ret;
742
743 status = GdipCreateLineBrushFromRect(&create_from_rect[i].rect, 0x1, 0x2, create_from_rect[i].mode,
744 WrapModeTile, &brush);
745 ok(status == Ok, "Failed to create a brush, %d.\n", status);
746
747 memset(&rectf, 0, sizeof(rectf));
748 status = GdipGetLineRect(brush, &rectf);
749 ok(status == Ok, "Failed to get brush rect, %d.\n", status);
750 ok(!memcmp(&rectf, &create_from_rect[i].rect, sizeof(rectf)), "Unexpected brush rect.\n");
751
752 status = GdipGetLineTransform(brush, transform);
753 ok(status == Ok, "Failed to get brush transform, %d.\n", status);
754
755 if (create_from_rect[i].mode == LinearGradientModeHorizontal)
756 {
757 status = GdipIsMatrixIdentity(transform, &ret);
758 ok(status == Ok, "Unexpected ret value %d.\n", status);
759 }
760 else
761 {
762 status = GdipGetMatrixElements(transform, elements);
763 ok(status == Ok, "Failed to get matrix elements, %d.\n", status);
764
765 #define expectf2(expected, got) ok(fabs(expected - got) < 0.001, "%u: expected %.3f, got %.3f.\n", i, expected, got)
766 expectf2(create_from_rect[i].transform[0], elements[0]);
767 expectf2(create_from_rect[i].transform[1], elements[1]);
768 expectf2(create_from_rect[i].transform[2], elements[2]);
769 expectf2(create_from_rect[i].transform[3], elements[3]);
770 expectf2(create_from_rect[i].transform[4], elements[4]);
771 expectf2(create_from_rect[i].transform[5], elements[5]);
772 #undef expectf2
773 }
774
775 status = GdipGetLineColors(brush, colors);
776 ok(status == Ok, "Failed to get line colors, %d.\n", status);
777 ok(colors[0] == 0x1 && colors[1] == 0x2, "Unexpected brush colors.\n");
778
779 status = GdipDeleteBrush((GpBrush*)brush);
780 ok(status == Ok, "Failed to delete a brush, %d.\n", status);
781 }
782
783 for (i = 0; i < ARRAY_SIZE(create_with_angle); ++i)
784 {
785 ARGB colors[2];
786 BOOL ret;
787
788 status = GdipCreateLineBrushFromRectWithAngle(&create_with_angle[i].rect, 0x1, 0x2, create_with_angle[i].angle,
789 create_with_angle[i].is_scalable, WrapModeTile, &brush);
790 ok(status == Ok, "Failed to create a brush, %d.\n", status);
791
792 memset(&rectf, 0, sizeof(rectf));
793 status = GdipGetLineRect(brush, &rectf);
794 ok(status == Ok, "Failed to get brush rect, %d.\n", status);
795 ok(!memcmp(&rectf, &create_with_angle[i].rect, sizeof(rectf)), "%u: unexpected brush rect {%f,%f,%f,%f}.\n",
796 i, rectf.X, rectf.Y, rectf.Width, rectf.Height);
797
798 status = GdipGetLineTransform(brush, transform);
799 ok(status == Ok, "Failed to get brush transform, %d.\n", status);
800
801 if (create_with_angle[i].angle == 0.0f)
802 {
803 status = GdipIsMatrixIdentity(transform, &ret);
804 ok(status == Ok, "Unexpected ret value %d.\n", status);
805 }
806 else
807 {
808 status = GdipGetMatrixElements(transform, elements);
809 ok(status == Ok, "Failed to get matrix elements, %d.\n", status);
810
811 #define expectf2(expected, got) ok(fabs(expected - got) < 0.001, "%u: expected %.3f, got %.3f.\n", i, expected, got)
812 expectf2(create_with_angle[i].transform[0], elements[0]);
813 expectf2(create_with_angle[i].transform[1], elements[1]);
814 expectf2(create_with_angle[i].transform[2], elements[2]);
815 expectf2(create_with_angle[i].transform[3], elements[3]);
816 expectf2(create_with_angle[i].transform[4], elements[4]);
817 expectf2(create_with_angle[i].transform[5], elements[5]);
818 #undef expectf2
819 }
820
821 status = GdipGetLineColors(brush, colors);
822 ok(status == Ok, "Failed to get line colors, %d.\n", status);
823 ok(colors[0] == 0x1 && colors[1] == 0x2, "Unexpected brush colors.\n");
824
825 status = GdipDeleteBrush((GpBrush*)brush);
826 ok(status == Ok, "Failed to delete a brush, %d.\n", status);
827 }
828
829 GdipDeleteMatrix(transform);
830 }
831
832 static void test_lineblend(void)
833 {
834 GpLineGradient *brush;
835 GpStatus status;
836 GpPointF pt1, pt2;
837 INT count=10;
838 int i;
839 const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f};
840 const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
841 const REAL two_positions[2] = {0.0f, 1.0f};
842 const ARGB colors[5] = {0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffffffff};
843 REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
844 REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
845 ARGB res_colors[6] = {0xdeadbeef, 0, 0, 0, 0};
846
847 pt1.X = pt1.Y = pt2.Y = pt2.X = 1.0;
848 status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
849 expect(OutOfMemory, status);
850
851 pt1.X = pt1.Y = 1.0;
852 pt2.X = pt2.Y = 100.0;
853 status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
854 expect(Ok, status);
855
856 status = GdipGetLineBlendCount(NULL, &count);
857 expect(InvalidParameter, status);
858
859 status = GdipGetLineBlendCount(brush, NULL);
860 expect(InvalidParameter, status);
861
862 status = GdipGetLineBlendCount(brush, &count);
863 expect(Ok, status);
864 expect(1, count);
865
866 status = GdipGetLineBlend(NULL, res_factors, res_positions, 1);
867 expect(InvalidParameter, status);
868
869 status = GdipGetLineBlend(brush, NULL, res_positions, 1);
870 expect(InvalidParameter, status);
871
872 status = GdipGetLineBlend(brush, res_factors, NULL, 1);
873 expect(InvalidParameter, status);
874
875 status = GdipGetLineBlend(brush, res_factors, res_positions, 0);
876 expect(InvalidParameter, status);
877
878 status = GdipGetLineBlend(brush, res_factors, res_positions, -1);
879 expect(InvalidParameter, status);
880
881 status = GdipGetLineBlend(brush, res_factors, res_positions, 1);
882 expect(Ok, status);
883
884 status = GdipGetLineBlend(brush, res_factors, res_positions, 2);
885 expect(Ok, status);
886
887 status = GdipSetLineBlend(NULL, factors, positions, 5);
888 expect(InvalidParameter, status);
889
890 status = GdipSetLineBlend(brush, NULL, positions, 5);
891 expect(InvalidParameter, status);
892
893 status = GdipSetLineBlend(brush, factors, NULL, 5);
894 expect(InvalidParameter, status);
895
896 status = GdipSetLineBlend(brush, factors, positions, 0);
897 expect(InvalidParameter, status);
898
899 status = GdipSetLineBlend(brush, factors, positions, -1);
900 expect(InvalidParameter, status);
901
902 /* leave off the 0.0 position */
903 status = GdipSetLineBlend(brush, &factors[1], &positions[1], 4);
904 expect(InvalidParameter, status);
905
906 /* leave off the 1.0 position */
907 status = GdipSetLineBlend(brush, factors, positions, 4);
908 expect(InvalidParameter, status);
909
910 status = GdipSetLineBlend(brush, factors, positions, 5);
911 expect(Ok, status);
912
913 status = GdipGetLineBlendCount(brush, &count);
914 expect(Ok, status);
915 expect(5, count);
916
917 status = GdipGetLineBlend(brush, res_factors, res_positions, 4);
918 expect(InsufficientBuffer, status);
919
920 status = GdipGetLineBlend(brush, res_factors, res_positions, 5);
921 expect(Ok, status);
922
923 for (i=0; i<5; i++)
924 {
925 expectf(factors[i], res_factors[i]);
926 expectf(positions[i], res_positions[i]);
927 }
928
929 status = GdipGetLineBlend(brush, res_factors, res_positions, 6);
930 expect(Ok, status);
931
932 status = GdipSetLineBlend(brush, factors, positions, 1);
933 expect(Ok, status);
934
935 status = GdipGetLineBlendCount(brush, &count);
936 expect(Ok, status);
937 expect(1, count);
938
939 status = GdipGetLineBlend(brush, res_factors, res_positions, 1);
940 expect(Ok, status);
941
942 status = GdipGetLinePresetBlendCount(NULL, &count);
943 expect(InvalidParameter, status);
944
945 status = GdipGetLinePresetBlendCount(brush, NULL);
946 expect(InvalidParameter, status);
947
948 status = GdipGetLinePresetBlendCount(brush, &count);
949 expect(Ok, status);
950 expect(0, count);
951
952 status = GdipGetLinePresetBlend(NULL, res_colors, res_positions, 1);
953 expect(InvalidParameter, status);
954
955 status = GdipGetLinePresetBlend(brush, NULL, res_positions, 1);
956 expect(InvalidParameter, status);
957
958 status = GdipGetLinePresetBlend(brush, res_colors, NULL, 1);
959 expect(InvalidParameter, status);
960
961 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 0);
962 expect(InvalidParameter, status);
963
964 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, -1);
965 expect(InvalidParameter, status);
966
967 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 1);
968 expect(InvalidParameter, status);
969
970 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 2);
971 expect(GenericError, status);
972
973 status = GdipSetLinePresetBlend(NULL, colors, positions, 5);
974 expect(InvalidParameter, status);
975
976 status = GdipSetLinePresetBlend(brush, NULL, positions, 5);
977 expect(InvalidParameter, status);
978
979 status = GdipSetLinePresetBlend(brush, colors, NULL, 5);
980 expect(InvalidParameter, status);
981
982 status = GdipSetLinePresetBlend(brush, colors, positions, 0);
983 expect(InvalidParameter, status);
984
985 status = GdipSetLinePresetBlend(brush, colors, positions, -1);
986 expect(InvalidParameter, status);
987
988 status = GdipSetLinePresetBlend(brush, colors, positions, 1);
989 expect(InvalidParameter, status);
990
991 /* leave off the 0.0 position */
992 status = GdipSetLinePresetBlend(brush, &colors[1], &positions[1], 4);
993 expect(InvalidParameter, status);
994
995 /* leave off the 1.0 position */
996 status = GdipSetLinePresetBlend(brush, colors, positions, 4);
997 expect(InvalidParameter, status);
998
999 status = GdipSetLinePresetBlend(brush, colors, positions, 5);
1000 expect(Ok, status);
1001
1002 status = GdipGetLinePresetBlendCount(brush, &count);
1003 expect(Ok, status);
1004 expect(5, count);
1005
1006 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 4);
1007 expect(InsufficientBuffer, status);
1008
1009 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 5);
1010 expect(Ok, status);
1011
1012 for (i=0; i<5; i++)
1013 {
1014 expect(colors[i], res_colors[i]);
1015 expectf(positions[i], res_positions[i]);
1016 }
1017
1018 status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 6);
1019 expect(Ok, status);
1020
1021 status = GdipSetLinePresetBlend(brush, colors, two_positions, 2);
1022 expect(Ok, status);
1023
1024 status = GdipDeleteBrush((GpBrush*)brush);
1025 expect(Ok, status);
1026 }
1027
1028 static void test_linelinearblend(void)
1029 {
1030 GpLineGradient *brush;
1031 GpStatus status;
1032 GpPointF pt1, pt2;
1033 INT count=10;
1034 REAL res_factors[3] = {0.3f};
1035 REAL res_positions[3] = {0.3f};
1036
1037 status = GdipSetLineLinearBlend(NULL, 0.6, 0.8);
1038 expect(InvalidParameter, status);
1039
1040 pt1.X = pt1.Y = 1.0;
1041 pt2.X = pt2.Y = 100.0;
1042 status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
1043 expect(Ok, status);
1044
1045
1046 status = GdipSetLineLinearBlend(brush, 0.6, 0.8);
1047 expect(Ok, status);
1048
1049 status = GdipGetLineBlendCount(brush, &count);
1050 expect(Ok, status);
1051 expect(3, count);
1052
1053 status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
1054 expect(Ok, status);
1055 expectf(0.0, res_factors[0]);
1056 expectf(0.0, res_positions[0]);
1057 expectf(0.8, res_factors[1]);
1058 expectf(0.6, res_positions[1]);
1059 expectf(0.0, res_factors[2]);
1060 expectf(1.0, res_positions[2]);
1061
1062
1063 status = GdipSetLineLinearBlend(brush, 0.0, 0.8);
1064 expect(Ok, status);
1065
1066 status = GdipGetLineBlendCount(brush, &count);
1067 expect(Ok, status);
1068 expect(2, count);
1069
1070 status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
1071 expect(Ok, status);
1072 expectf(0.8, res_factors[0]);
1073 expectf(0.0, res_positions[0]);
1074 expectf(0.0, res_factors[1]);
1075 expectf(1.0, res_positions[1]);
1076
1077
1078 status = GdipSetLineLinearBlend(brush, 1.0, 0.8);
1079 expect(Ok, status);
1080
1081 status = GdipGetLineBlendCount(brush, &count);
1082 expect(Ok, status);
1083 expect(2, count);
1084
1085 status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
1086 expect(Ok, status);
1087 expectf(0.0, res_factors[0]);
1088 expectf(0.0, res_positions[0]);
1089 expectf(0.8, res_factors[1]);
1090 expectf(1.0, res_positions[1]);
1091
1092 status = GdipDeleteBrush((GpBrush*)brush);
1093 expect(Ok, status);
1094 }
1095
1096 static void test_gradientsurroundcolorcount(void)
1097 {
1098 GpStatus status;
1099 GpPathGradient *grad;
1100 ARGB color[3];
1101 INT count;
1102
1103 status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad);
1104 expect(Ok, status);
1105
1106 count = 0;
1107 status = GdipGetPathGradientSurroundColorCount(grad, &count);
1108 expect(Ok, status);
1109 expect(2, count);
1110
1111 color[0] = color[1] = color[2] = 0xdeadbeef;
1112 count = 3;
1113 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1114 expect(Ok, status);
1115 expect(1, count);
1116 expect(0xffffffff, color[0]);
1117 expect(0xffffffff, color[1]);
1118 expect(0xdeadbeef, color[2]);
1119
1120 color[0] = color[1] = color[2] = 0xdeadbeef;
1121 count = 2;
1122 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1123 expect(Ok, status);
1124 expect(1, count);
1125 expect(0xffffffff, color[0]);
1126 expect(0xffffffff, color[1]);
1127 expect(0xdeadbeef, color[2]);
1128
1129 color[0] = color[1] = color[2] = 0xdeadbeef;
1130 count = 1;
1131 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1132 expect(InvalidParameter, status);
1133 expect(1, count);
1134 expect(0xdeadbeef, color[0]);
1135 expect(0xdeadbeef, color[1]);
1136 expect(0xdeadbeef, color[2]);
1137
1138 color[0] = color[1] = color[2] = 0xdeadbeef;
1139 count = 0;
1140 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1141 expect(InvalidParameter, status);
1142 expect(0, count);
1143 expect(0xdeadbeef, color[0]);
1144 expect(0xdeadbeef, color[1]);
1145 expect(0xdeadbeef, color[2]);
1146
1147 count = 3;
1148 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1149 expect(InvalidParameter, status);
1150
1151 count = 2;
1152
1153 color[0] = 0x00ff0000;
1154 color[1] = 0x0000ff00;
1155
1156 status = GdipSetPathGradientSurroundColorsWithCount(NULL, color, &count);
1157 expect(InvalidParameter, status);
1158
1159 status = GdipSetPathGradientSurroundColorsWithCount(grad, NULL, &count);
1160 expect(InvalidParameter, status);
1161
1162 /* WinXP crashes on this test */
1163 if(0)
1164 {
1165 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, NULL);
1166 expect(InvalidParameter, status);
1167 }
1168
1169 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1170 expect(Ok, status);
1171 expect(2, count);
1172
1173 status = GdipGetPathGradientSurroundColorCount(NULL, &count);
1174 expect(InvalidParameter, status);
1175
1176 status = GdipGetPathGradientSurroundColorCount(grad, NULL);
1177 expect(InvalidParameter, status);
1178
1179 count = 0;
1180 status = GdipGetPathGradientSurroundColorCount(grad, &count);
1181 expect(Ok, status);
1182 expect(2, count);
1183
1184 color[0] = color[1] = color[2] = 0xdeadbeef;
1185 count = 2;
1186 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1187 expect(Ok, status);
1188 expect(2, count);
1189 expect(0x00ff0000, color[0]);
1190 expect(0x0000ff00, color[1]);
1191 expect(0xdeadbeef, color[2]);
1192
1193 count = 1;
1194 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1195 expect(Ok, status);
1196 expect(1, count);
1197
1198 count = 0;
1199 status = GdipGetPathGradientSurroundColorCount(grad, &count);
1200 expect(Ok, status);
1201 expect(2, count);
1202
1203 /* If all colors are the same, count is set to 1. */
1204 color[0] = color[1] = 0;
1205 count = 2;
1206 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1207 expect(Ok, status);
1208 expect(2, count);
1209
1210 color[0] = color[1] = color[2] = 0xdeadbeef;
1211 count = 2;
1212 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1213 expect(Ok, status);
1214 expect(1, count);
1215 expect(0x00000000, color[0]);
1216 expect(0x00000000, color[1]);
1217 expect(0xdeadbeef, color[2]);
1218
1219 color[0] = color[1] = 0xff00ff00;
1220 count = 2;
1221 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1222 expect(Ok, status);
1223 expect(2, count);
1224
1225 color[0] = color[1] = color[2] = 0xdeadbeef;
1226 count = 2;
1227 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1228 expect(Ok, status);
1229 expect(1, count);
1230 expect(0xff00ff00, color[0]);
1231 expect(0xff00ff00, color[1]);
1232 expect(0xdeadbeef, color[2]);
1233
1234 count = 0;
1235 status = GdipSetPathGradientSurroundColorsWithCount(grad, color, &count);
1236 expect(InvalidParameter, status);
1237 expect(0, count);
1238
1239 GdipDeleteBrush((GpBrush*)grad);
1240
1241 status = GdipCreatePathGradient(getbounds_ptf, 3, WrapModeClamp, &grad);
1242 expect(Ok, status);
1243
1244 color[0] = color[1] = color[2] = 0xdeadbeef;
1245 count = 3;
1246 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1247 expect(Ok, status);
1248 expect(1, count);
1249 expect(0xffffffff, color[0]);
1250 expect(0xffffffff, color[1]);
1251 expect(0xffffffff, color[2]);
1252
1253 color[0] = color[1] = color[2] = 0xdeadbeef;
1254 count = 2;
1255 status = GdipGetPathGradientSurroundColorsWithCount(grad, color, &count);
1256 expect(InvalidParameter, status);
1257 expect(2, count);
1258 expect(0xdeadbeef, color[0]);
1259 expect(0xdeadbeef, color[1]);
1260 expect(0xdeadbeef, color[2]);
1261
1262 count = 0;
1263 status = GdipGetPathGradientSurroundColorCount(grad, &count);
1264 expect(Ok, status);
1265 expect(3, count);
1266
1267 GdipDeleteBrush((GpBrush*)grad);
1268 }
1269
1270 static void test_pathgradientpath(void)
1271 {
1272 GpStatus status;
1273 GpPath *path=NULL;
1274 GpPathGradient *grad=NULL;
1275
1276 status = GdipCreatePathGradient(blendcount_ptf, 2, WrapModeClamp, &grad);
1277 expect(Ok, status);
1278
1279 status = GdipGetPathGradientPath(grad, NULL);
1280 expect(NotImplemented, status);
1281
1282 status = GdipCreatePath(FillModeWinding, &path);
1283 expect(Ok, status);
1284
1285 status = GdipGetPathGradientPath(NULL, path);
1286 expect(NotImplemented, status);
1287
1288 status = GdipGetPathGradientPath(grad, path);
1289 expect(NotImplemented, status);
1290
1291 status = GdipDeletePath(path);
1292 expect(Ok, status);
1293
1294 status = GdipDeleteBrush((GpBrush*)grad);
1295 expect(Ok, status);
1296 }
1297
1298 static void test_pathgradientcenterpoint(void)
1299 {
1300 static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
1301 GpStatus status;
1302 GpPathGradient *grad;
1303 GpPointF point;
1304
1305 status = GdipCreatePathGradient(path_points+1, 2, WrapModeClamp, &grad);
1306 expect(Ok, status);
1307
1308 status = GdipGetPathGradientCenterPoint(NULL, &point);
1309 expect(InvalidParameter, status);
1310
1311 status = GdipGetPathGradientCenterPoint(grad, NULL);
1312 expect(InvalidParameter, status);
1313
1314 status = GdipGetPathGradientCenterPoint(grad, &point);
1315 expect(Ok, status);
1316 expectf(1.5, point.X);
1317 expectf(2.0, point.Y);
1318
1319 status = GdipSetPathGradientCenterPoint(NULL, &point);
1320 expect(InvalidParameter, status);
1321
1322 status = GdipSetPathGradientCenterPoint(grad, NULL);
1323 expect(InvalidParameter, status);
1324
1325 point.X = 10.0;
1326 point.Y = 15.0;
1327 status = GdipSetPathGradientCenterPoint(grad, &point);
1328 expect(Ok, status);
1329
1330 point.X = point.Y = -1;
1331 status = GdipGetPathGradientCenterPoint(grad, &point);
1332 expect(Ok, status);
1333 expectf(10.0, point.X);
1334 expectf(15.0, point.Y);
1335
1336 status = GdipDeleteBrush((GpBrush*)grad);
1337 expect(Ok, status);
1338
1339 status = GdipCreatePathGradient(path_points, 3, WrapModeClamp, &grad);
1340 expect(Ok, status);
1341
1342 status = GdipGetPathGradientCenterPoint(grad, &point);
1343 expect(Ok, status);
1344 todo_wine expectf(1.0, point.X);
1345 todo_wine expectf(4.0/3.0, point.Y);
1346
1347 status = GdipDeleteBrush((GpBrush*)grad);
1348 expect(Ok, status);
1349 }
1350
1351 static void test_pathgradientpresetblend(void)
1352 {
1353 static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
1354 GpStatus status;
1355 GpPathGradient *grad;
1356 INT count;
1357 int i;
1358 const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
1359 const REAL two_positions[2] = {0.0f, 1.0f};
1360 const ARGB colors[5] = {0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffffffff};
1361 REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
1362 ARGB res_colors[6] = {0xdeadbeef, 0, 0, 0, 0};
1363
1364 status = GdipCreatePathGradient(path_points+1, 2, WrapModeClamp, &grad);
1365 expect(Ok, status);
1366
1367 status = GdipGetPathGradientPresetBlendCount(NULL, &count);
1368 expect(InvalidParameter, status);
1369
1370 status = GdipGetPathGradientPresetBlendCount(grad, NULL);
1371 expect(InvalidParameter, status);
1372
1373 status = GdipGetPathGradientPresetBlendCount(grad, &count);
1374 expect(Ok, status);
1375 expect(0, count);
1376
1377 status = GdipGetPathGradientPresetBlend(NULL, res_colors, res_positions, 1);
1378 expect(InvalidParameter, status);
1379
1380 status = GdipGetPathGradientPresetBlend(grad, NULL, res_positions, 1);
1381 expect(InvalidParameter, status);
1382
1383 status = GdipGetPathGradientPresetBlend(grad, res_colors, NULL, 1);
1384 expect(InvalidParameter, status);
1385
1386 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 0);
1387 expect(InvalidParameter, status);
1388
1389 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, -1);
1390 expect(OutOfMemory, status);
1391
1392 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 1);
1393 expect(InvalidParameter, status);
1394
1395 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 2);
1396 expect(GenericError, status);
1397
1398 status = GdipSetPathGradientPresetBlend(NULL, colors, positions, 5);
1399 expect(InvalidParameter, status);
1400
1401 status = GdipSetPathGradientPresetBlend(grad, NULL, positions, 5);
1402 expect(InvalidParameter, status);
1403
1404 if (0)
1405 {
1406 /* crashes on windows xp */
1407 status = GdipSetPathGradientPresetBlend(grad, colors, NULL, 5);
1408 expect(InvalidParameter, status);
1409 }
1410
1411 status = GdipSetPathGradientPresetBlend(grad, colors, positions, 0);
1412 expect(InvalidParameter, status);
1413
1414 status = GdipSetPathGradientPresetBlend(grad, colors, positions, -1);
1415 expect(InvalidParameter, status);
1416
1417 status = GdipSetPathGradientPresetBlend(grad, colors, positions, 1);
1418 expect(InvalidParameter, status);
1419
1420 /* leave off the 0.0 position */
1421 status = GdipSetPathGradientPresetBlend(grad, &colors[1], &positions[1], 4);
1422 expect(InvalidParameter, status);
1423
1424 /* leave off the 1.0 position */
1425 status = GdipSetPathGradientPresetBlend(grad, colors, positions, 4);
1426 expect(InvalidParameter, status);
1427
1428 status = GdipSetPathGradientPresetBlend(grad, colors, positions, 5);
1429 expect(Ok, status);
1430
1431 status = GdipGetPathGradientPresetBlendCount(grad, &count);
1432 expect(Ok, status);
1433 expect(5, count);
1434
1435 if (0)
1436 {
1437 /* Native GdipGetPathGradientPresetBlend seems to copy starting from
1438 * the end of each array and do no bounds checking. This is so braindead
1439 * I'm not going to copy it. */
1440
1441 res_colors[0] = 0xdeadbeef;
1442 res_positions[0] = 0.3;
1443
1444 status = GdipGetPathGradientPresetBlend(grad, &res_colors[1], &res_positions[1], 4);
1445 expect(Ok, status);
1446
1447 expect(0xdeadbeef, res_colors[0]);
1448 expectf(0.3, res_positions[0]);
1449
1450 for (i=1; i<5; i++)
1451 {
1452 expect(colors[i], res_colors[i]);
1453 expectf(positions[i], res_positions[i]);
1454 }
1455
1456 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 6);
1457 expect(Ok, status);
1458
1459 for (i=0; i<5; i++)
1460 {
1461 expect(colors[i], res_colors[i+1]);
1462 expectf(positions[i], res_positions[i+1]);
1463 }
1464 }
1465
1466 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 5);
1467 expect(Ok, status);
1468
1469 for (i=0; i<5; i++)
1470 {
1471 expect(colors[i], res_colors[i]);
1472 expectf(positions[i], res_positions[i]);
1473 }
1474
1475 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 0);
1476 expect(InvalidParameter, status);
1477
1478 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, -1);
1479 expect(OutOfMemory, status);
1480
1481 status = GdipGetPathGradientPresetBlend(grad, res_colors, res_positions, 1);
1482 expect(InvalidParameter, status);
1483
1484 status = GdipSetPathGradientPresetBlend(grad, colors, two_positions, 2);
1485 expect(Ok, status);
1486
1487 status = GdipDeleteBrush((GpBrush*)grad);
1488 expect(Ok, status);
1489 }
1490
1491 static void test_pathgradientblend(void)
1492 {
1493 static const GpPointF path_points[] = {{0,0}, {3,0}, {0,4}};
1494 GpPathGradient *brush;
1495 GpStatus status;
1496 INT count, i;
1497 const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f};
1498 const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
1499 REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
1500 REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
1501
1502 status = GdipCreatePathGradient(path_points, 3, WrapModeClamp, &brush);
1503 expect(Ok, status);
1504
1505 status = GdipGetPathGradientBlendCount(NULL, &count);
1506 expect(InvalidParameter, status);
1507
1508 status = GdipGetPathGradientBlendCount(brush, NULL);
1509 expect(InvalidParameter, status);
1510
1511 status = GdipGetPathGradientBlendCount(brush, &count);
1512 expect(Ok, status);
1513 expect(1, count);
1514
1515 status = GdipGetPathGradientBlend(NULL, res_factors, res_positions, 1);
1516 expect(InvalidParameter, status);
1517
1518 status = GdipGetPathGradientBlend(brush, NULL, res_positions, 1);
1519 expect(InvalidParameter, status);
1520
1521 status = GdipGetPathGradientBlend(brush, res_factors, NULL, 1);
1522 expect(InvalidParameter, status);
1523
1524 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 0);
1525 expect(InvalidParameter, status);
1526
1527 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, -1);
1528 expect(InvalidParameter, status);
1529
1530 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 1);
1531 expect(Ok, status);
1532
1533 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 2);
1534 expect(Ok, status);
1535
1536 status = GdipSetPathGradientBlend(NULL, factors, positions, 5);
1537 expect(InvalidParameter, status);
1538
1539 status = GdipSetPathGradientBlend(brush, NULL, positions, 5);
1540 expect(InvalidParameter, status);
1541
1542 status = GdipSetPathGradientBlend(brush, factors, NULL, 5);
1543 expect(InvalidParameter, status);
1544
1545 status = GdipSetPathGradientBlend(brush, factors, positions, 0);
1546 expect(InvalidParameter, status);
1547
1548 status = GdipSetPathGradientBlend(brush, factors, positions, -1);
1549 expect(InvalidParameter, status);
1550
1551 /* leave off the 0.0 position */
1552 status = GdipSetPathGradientBlend(brush, &factors[1], &positions[1], 4);
1553 expect(InvalidParameter, status);
1554
1555 /* leave off the 1.0 position */
1556 status = GdipSetPathGradientBlend(brush, factors, positions, 4);
1557 expect(InvalidParameter, status);
1558
1559 status = GdipSetPathGradientBlend(brush, factors, positions, 5);
1560 expect(Ok, status);
1561
1562 status = GdipGetPathGradientBlendCount(brush, &count);
1563 expect(Ok, status);
1564 expect(5, count);
1565
1566 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 4);
1567 expect(InsufficientBuffer, status);
1568
1569 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 5);
1570 expect(Ok, status);
1571
1572 for (i=0; i<5; i++)
1573 {
1574 expectf(factors[i], res_factors[i]);
1575 expectf(positions[i], res_positions[i]);
1576 }
1577
1578 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 6);
1579 expect(Ok, status);
1580
1581 status = GdipSetPathGradientBlend(brush, factors, positions, 1);
1582 expect(Ok, status);
1583
1584 status = GdipGetPathGradientBlendCount(brush, &count);
1585 expect(Ok, status);
1586 expect(1, count);
1587
1588 status = GdipGetPathGradientBlend(brush, res_factors, res_positions, 1);
1589 expect(Ok, status);
1590
1591 status = GdipDeleteBrush((GpBrush*)brush);
1592 expect(Ok, status);
1593 }
1594
1595 static void test_getHatchStyle(void)
1596 {
1597 GpStatus status;
1598 GpHatch *brush;
1599 GpHatchStyle hatchStyle;
1600
1601 GdipCreateHatchBrush(HatchStyleHorizontal, 11, 12, &brush);
1602
1603 status = GdipGetHatchStyle(NULL, &hatchStyle);
1604 expect(InvalidParameter, status);
1605
1606 status = GdipGetHatchStyle(brush, NULL);
1607 expect(InvalidParameter, status);
1608
1609 status = GdipGetHatchStyle(brush, &hatchStyle);
1610 expect(Ok, status);
1611 expect(HatchStyleHorizontal, hatchStyle);
1612
1613 GdipDeleteBrush((GpBrush *)brush);
1614 }
1615
1616 START_TEST(brush)
1617 {
1618 struct GdiplusStartupInput gdiplusStartupInput;
1619 ULONG_PTR gdiplusToken;
1620 HMODULE hmsvcrt;
1621 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
1622 WNDCLASSA class;
1623
1624 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
1625 hmsvcrt = LoadLibraryA("msvcrt");
1626 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
1627 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
1628
1629 memset( &class, 0, sizeof(class) );
1630 class.lpszClassName = "gdiplus_test";
1631 class.style = CS_HREDRAW | CS_VREDRAW;
1632 class.lpfnWndProc = DefWindowProcA;
1633 class.hInstance = GetModuleHandleA(0);
1634 class.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
1635 class.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
1636 class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1637 RegisterClassA( &class );
1638 hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1639 CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, 0, 0, GetModuleHandleA(0), 0 );
1640 ok(hwnd != NULL, "Expected window to be created\n");
1641
1642 gdiplusStartupInput.GdiplusVersion = 1;
1643 gdiplusStartupInput.DebugEventCallback = NULL;
1644 gdiplusStartupInput.SuppressBackgroundThread = 0;
1645 gdiplusStartupInput.SuppressExternalCodecs = 0;
1646
1647 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
1648
1649 test_constructor_destructor();
1650 test_createHatchBrush();
1651 test_createLineBrushFromRectWithAngle();
1652 test_type();
1653 test_gradientblendcount();
1654 test_getblend();
1655 test_getbounds();
1656 test_getgamma();
1657 test_transform();
1658 test_texturewrap();
1659 test_gradientgetrect();
1660 test_lineblend();
1661 test_linelinearblend();
1662 test_gradientsurroundcolorcount();
1663 test_pathgradientpath();
1664 test_pathgradientcenterpoint();
1665 test_pathgradientpresetblend();
1666 test_pathgradientblend();
1667 test_getHatchStyle();
1668
1669 GdiplusShutdown(gdiplusToken);
1670 DestroyWindow(hwnd);
1671 }