* The Shell.. for a long time we dreamed of having a compatible, properly working...
[reactos.git] / rostests / winetests / gdiplus / graphics.c
1 /*
2 * Unit test suite for graphics objects
3 *
4 * Copyright (C) 2007 Google (Evan Stade)
5 * Copyright (C) 2012 Dmitry Timoshkov
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22 #include <math.h>
23
24 #define WIN32_NO_STATUS
25 #define _INC_WINDOWS
26 #define COM_NO_WINDOWS_H
27
28 //#include "windows.h"
29 #include <wine/test.h>
30 #include <wingdi.h>
31 #include <objbase.h>
32 #include <gdiplus.h>
33
34 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (INT)(expected), (INT)(got))
35 #define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
36 #define expectf(expected, got) expectf_((expected), (got), 0.001)
37 #define TABLE_LEN (23)
38
39 static const REAL mm_per_inch = 25.4;
40 static const REAL point_per_inch = 72.0;
41 static HWND hwnd;
42
43 static void set_rect_empty(RectF *rc)
44 {
45 rc->X = 0.0;
46 rc->Y = 0.0;
47 rc->Width = 0.0;
48 rc->Height = 0.0;
49 }
50
51 /* converts a given unit to its value in pixels */
52 static REAL units_to_pixels(REAL units, GpUnit unit, REAL dpi)
53 {
54 switch (unit)
55 {
56 case UnitPixel:
57 case UnitDisplay:
58 return units;
59 case UnitPoint:
60 return units * dpi / point_per_inch;
61 case UnitInch:
62 return units * dpi;
63 case UnitDocument:
64 return units * dpi / 300.0; /* Per MSDN */
65 case UnitMillimeter:
66 return units * dpi / mm_per_inch;
67 default:
68 ok(0, "Unsupported unit: %d\n", unit);
69 return 0;
70 }
71 }
72
73 /* converts value in pixels to a given unit */
74 static REAL pixels_to_units(REAL pixels, GpUnit unit, REAL dpi)
75 {
76 switch (unit)
77 {
78 case UnitPixel:
79 case UnitDisplay:
80 return pixels;
81 case UnitPoint:
82 return pixels * point_per_inch / dpi;
83 case UnitInch:
84 return pixels / dpi;
85 case UnitDocument:
86 return pixels * 300.0 / dpi;
87 case UnitMillimeter:
88 return pixels * mm_per_inch / dpi;
89 default:
90 ok(0, "Unsupported unit: %d\n", unit);
91 return 0;
92 }
93 }
94
95 static REAL units_scale(GpUnit from, GpUnit to, REAL dpi)
96 {
97 REAL pixels = units_to_pixels(1.0, from, dpi);
98 return pixels_to_units(pixels, to, dpi);
99 }
100
101 static GpGraphics *create_graphics(REAL res_x, REAL res_y, GpUnit unit, REAL scale, GpImage **image)
102 {
103 GpStatus status;
104 union
105 {
106 GpBitmap *bitmap;
107 GpImage *image;
108 } u;
109 GpGraphics *graphics = NULL;
110 REAL res;
111
112 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, NULL, &u.bitmap);
113 expect(Ok, status);
114
115 status = GdipBitmapSetResolution(u.bitmap, res_x, res_y);
116 expect(Ok, status);
117 status = GdipGetImageHorizontalResolution(u.image, &res);
118 expect(Ok, status);
119 expectf(res_x, res);
120 status = GdipGetImageVerticalResolution(u.image, &res);
121 expect(Ok, status);
122 expectf(res_y, res);
123
124 status = GdipGetImageGraphicsContext(u.image, &graphics);
125 expect(Ok, status);
126
127 *image = u.image;
128
129 status = GdipGetDpiX(graphics, &res);
130 expect(Ok, status);
131 expectf(res_x, res);
132 status = GdipGetDpiY(graphics, &res);
133 expect(Ok, status);
134 expectf(res_y, res);
135
136 status = GdipSetPageUnit(graphics, unit);
137 expect(Ok, status);
138 status = GdipSetPageScale(graphics, scale);
139 expect(Ok, status);
140
141 return graphics;
142 }
143
144 static void test_constructor_destructor(void)
145 {
146 GpStatus stat;
147 GpGraphics *graphics = NULL;
148 HDC hdc = GetDC( hwnd );
149
150 stat = GdipCreateFromHDC(NULL, &graphics);
151 expect(OutOfMemory, stat);
152 stat = GdipDeleteGraphics(graphics);
153 expect(InvalidParameter, stat);
154
155 stat = GdipCreateFromHDC(hdc, &graphics);
156 expect(Ok, stat);
157 stat = GdipDeleteGraphics(graphics);
158 expect(Ok, stat);
159
160 stat = GdipCreateFromHWND(NULL, &graphics);
161 expect(Ok, stat);
162 stat = GdipDeleteGraphics(graphics);
163 expect(Ok, stat);
164
165 stat = GdipCreateFromHWNDICM(NULL, &graphics);
166 expect(Ok, stat);
167 stat = GdipDeleteGraphics(graphics);
168 expect(Ok, stat);
169
170 stat = GdipDeleteGraphics(NULL);
171 expect(InvalidParameter, stat);
172 ReleaseDC(hwnd, hdc);
173 }
174
175 typedef struct node{
176 GraphicsState data;
177 struct node * next;
178 } node;
179
180 /* Linked list prepend function. */
181 static void log_state(GraphicsState data, node ** log)
182 {
183 node * new_entry = HeapAlloc(GetProcessHeap(), 0, sizeof(node));
184
185 new_entry->data = data;
186 new_entry->next = *log;
187 *log = new_entry;
188 }
189
190 /* Checks if there are duplicates in the list, and frees it. */
191 static void check_no_duplicates(node * log)
192 {
193 INT dups = 0;
194 node * temp = NULL;
195 node * temp2 = NULL;
196 node * orig = log;
197
198 if(!log)
199 goto end;
200
201 do{
202 temp = log;
203 while((temp = temp->next)){
204 if(log->data == temp->data){
205 dups++;
206 break;
207 }
208 if(dups > 0)
209 break;
210 }
211 }while((log = log->next));
212
213 temp = orig;
214 do{
215 temp2 = temp->next;
216 HeapFree(GetProcessHeap(), 0, temp);
217 temp = temp2;
218 }while(temp);
219
220 end:
221 expect(0, dups);
222 }
223
224 static void test_save_restore(void)
225 {
226 GpStatus stat;
227 GraphicsState state_a, state_b, state_c;
228 InterpolationMode mode;
229 GpGraphics *graphics1, *graphics2;
230 node * state_log = NULL;
231 HDC hdc = GetDC( hwnd );
232 state_a = state_b = state_c = 0xdeadbeef;
233
234 /* Invalid saving. */
235 GdipCreateFromHDC(hdc, &graphics1);
236 stat = GdipSaveGraphics(graphics1, NULL);
237 expect(InvalidParameter, stat);
238 stat = GdipSaveGraphics(NULL, &state_a);
239 expect(InvalidParameter, stat);
240 GdipDeleteGraphics(graphics1);
241
242 log_state(state_a, &state_log);
243
244 /* Basic save/restore. */
245 GdipCreateFromHDC(hdc, &graphics1);
246 GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
247 stat = GdipSaveGraphics(graphics1, &state_a);
248 expect(Ok, stat);
249 GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
250 stat = GdipRestoreGraphics(graphics1, state_a);
251 expect(Ok, stat);
252 GdipGetInterpolationMode(graphics1, &mode);
253 expect(InterpolationModeBilinear, mode);
254 GdipDeleteGraphics(graphics1);
255
256 log_state(state_a, &state_log);
257
258 /* Restoring garbage doesn't affect saves. */
259 GdipCreateFromHDC(hdc, &graphics1);
260 GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
261 GdipSaveGraphics(graphics1, &state_a);
262 GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
263 GdipSaveGraphics(graphics1, &state_b);
264 GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
265 stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
266 expect(Ok, stat);
267 GdipRestoreGraphics(graphics1, state_b);
268 GdipGetInterpolationMode(graphics1, &mode);
269 expect(InterpolationModeBicubic, mode);
270 GdipRestoreGraphics(graphics1, state_a);
271 GdipGetInterpolationMode(graphics1, &mode);
272 expect(InterpolationModeBilinear, mode);
273 GdipDeleteGraphics(graphics1);
274
275 log_state(state_a, &state_log);
276 log_state(state_b, &state_log);
277
278 /* Restoring older state invalidates newer saves (but not older saves). */
279 GdipCreateFromHDC(hdc, &graphics1);
280 GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
281 GdipSaveGraphics(graphics1, &state_a);
282 GdipSetInterpolationMode(graphics1, InterpolationModeBicubic);
283 GdipSaveGraphics(graphics1, &state_b);
284 GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
285 GdipSaveGraphics(graphics1, &state_c);
286 GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
287 GdipRestoreGraphics(graphics1, state_b);
288 GdipGetInterpolationMode(graphics1, &mode);
289 expect(InterpolationModeBicubic, mode);
290 GdipRestoreGraphics(graphics1, state_c);
291 GdipGetInterpolationMode(graphics1, &mode);
292 expect(InterpolationModeBicubic, mode);
293 GdipRestoreGraphics(graphics1, state_a);
294 GdipGetInterpolationMode(graphics1, &mode);
295 expect(InterpolationModeBilinear, mode);
296 GdipDeleteGraphics(graphics1);
297
298 log_state(state_a, &state_log);
299 log_state(state_b, &state_log);
300 log_state(state_c, &state_log);
301
302 /* Restoring older save from one graphics object does not invalidate
303 * newer save from other graphics object. */
304 GdipCreateFromHDC(hdc, &graphics1);
305 GdipCreateFromHDC(hdc, &graphics2);
306 GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
307 GdipSaveGraphics(graphics1, &state_a);
308 GdipSetInterpolationMode(graphics2, InterpolationModeBicubic);
309 GdipSaveGraphics(graphics2, &state_b);
310 GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
311 GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
312 GdipRestoreGraphics(graphics1, state_a);
313 GdipGetInterpolationMode(graphics1, &mode);
314 expect(InterpolationModeBilinear, mode);
315 GdipRestoreGraphics(graphics2, state_b);
316 GdipGetInterpolationMode(graphics2, &mode);
317 expect(InterpolationModeBicubic, mode);
318 GdipDeleteGraphics(graphics1);
319 GdipDeleteGraphics(graphics2);
320
321 /* You can't restore a state to a graphics object that didn't save it. */
322 GdipCreateFromHDC(hdc, &graphics1);
323 GdipCreateFromHDC(hdc, &graphics2);
324 GdipSetInterpolationMode(graphics1, InterpolationModeBilinear);
325 GdipSaveGraphics(graphics1, &state_a);
326 GdipSetInterpolationMode(graphics1, InterpolationModeNearestNeighbor);
327 GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
328 GdipRestoreGraphics(graphics2, state_a);
329 GdipGetInterpolationMode(graphics2, &mode);
330 expect(InterpolationModeNearestNeighbor, mode);
331 GdipDeleteGraphics(graphics1);
332 GdipDeleteGraphics(graphics2);
333
334 log_state(state_a, &state_log);
335
336 /* The same state value should never be returned twice. */
337 todo_wine
338 check_no_duplicates(state_log);
339
340 ReleaseDC(hwnd, hdc);
341 }
342
343 static void test_GdipFillClosedCurve2(void)
344 {
345 GpStatus status;
346 GpGraphics *graphics = NULL;
347 GpSolidFill *brush = NULL;
348 HDC hdc = GetDC( hwnd );
349 GpPointF points[3];
350
351 points[0].X = 0;
352 points[0].Y = 0;
353
354 points[1].X = 40;
355 points[1].Y = 20;
356
357 points[2].X = 10;
358 points[2].Y = 40;
359
360 /* make a graphics object and brush object */
361 ok(hdc != NULL, "Expected HDC to be initialized\n");
362
363 status = GdipCreateFromHDC(hdc, &graphics);
364 expect(Ok, status);
365 ok(graphics != NULL, "Expected graphics to be initialized\n");
366
367 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
368
369 /* InvalidParameter cases: null graphics, null brush, null points */
370 status = GdipFillClosedCurve2(NULL, NULL, NULL, 3, 0.5, FillModeAlternate);
371 expect(InvalidParameter, status);
372
373 status = GdipFillClosedCurve2(graphics, NULL, NULL, 3, 0.5, FillModeAlternate);
374 expect(InvalidParameter, status);
375
376 status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
377 expect(InvalidParameter, status);
378
379 status = GdipFillClosedCurve2(NULL, NULL, points, 3, 0.5, FillModeAlternate);
380 expect(InvalidParameter, status);
381
382 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
383 expect(InvalidParameter, status);
384
385 status = GdipFillClosedCurve2(graphics, NULL, points, 3, 0.5, FillModeAlternate);
386 expect(InvalidParameter, status);
387
388 status = GdipFillClosedCurve2(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
389 expect(InvalidParameter, status);
390
391 /* InvalidParameter cases: invalid count */
392 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
393 expect(InvalidParameter, status);
394
395 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
396 expect(InvalidParameter, status);
397
398 /* Valid test cases */
399 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
400 expect(Ok, status);
401
402 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
403 expect(Ok, status);
404
405 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
406 expect(Ok, status);
407
408 GdipDeleteGraphics(graphics);
409 GdipDeleteBrush((GpBrush*)brush);
410
411 ReleaseDC(hwnd, hdc);
412 }
413
414 static void test_GdipFillClosedCurve2I(void)
415 {
416 GpStatus status;
417 GpGraphics *graphics = NULL;
418 GpSolidFill *brush = NULL;
419 HDC hdc = GetDC( hwnd );
420 GpPoint points[3];
421
422 points[0].X = 0;
423 points[0].Y = 0;
424
425 points[1].X = 40;
426 points[1].Y = 20;
427
428 points[2].X = 10;
429 points[2].Y = 40;
430
431 /* make a graphics object and brush object */
432 ok(hdc != NULL, "Expected HDC to be initialized\n");
433
434 status = GdipCreateFromHDC(hdc, &graphics);
435 expect(Ok, status);
436 ok(graphics != NULL, "Expected graphics to be initialized\n");
437
438 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
439
440 /* InvalidParameter cases: null graphics, null brush */
441 /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
442 when points == NULL, so don't test this condition */
443 status = GdipFillClosedCurve2I(NULL, NULL, points, 3, 0.5, FillModeAlternate);
444 expect(InvalidParameter, status);
445
446 status = GdipFillClosedCurve2I(graphics, NULL, points, 3, 0.5, FillModeAlternate);
447 expect(InvalidParameter, status);
448
449 status = GdipFillClosedCurve2I(NULL, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
450 expect(InvalidParameter, status);
451
452 /* InvalidParameter cases: invalid count */
453 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
454 expect(InvalidParameter, status);
455
456 /* OutOfMemory cases: large (unsigned) int */
457 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
458 expect(OutOfMemory, status);
459
460 /* Valid test cases */
461 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 1, 0.5, FillModeAlternate);
462 expect(Ok, status);
463
464 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 2, 0.5, FillModeAlternate);
465 expect(Ok, status);
466
467 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 3, 0.5, FillModeAlternate);
468 expect(Ok, status);
469
470 GdipDeleteGraphics(graphics);
471 GdipDeleteBrush((GpBrush*)brush);
472
473 ReleaseDC(hwnd, hdc);
474 }
475
476 static void test_GdipDrawArc(void)
477 {
478 GpStatus status;
479 GpGraphics *graphics = NULL;
480 GpPen *pen = NULL;
481 HDC hdc = GetDC( hwnd );
482
483 /* make a graphics object and pen object */
484 ok(hdc != NULL, "Expected HDC to be initialized\n");
485
486 status = GdipCreateFromHDC(hdc, &graphics);
487 expect(Ok, status);
488 ok(graphics != NULL, "Expected graphics to be initialized\n");
489
490 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
491 expect(Ok, status);
492 ok(pen != NULL, "Expected pen to be initialized\n");
493
494 /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
495 status = GdipDrawArc(NULL, NULL, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
496 expect(InvalidParameter, status);
497
498 status = GdipDrawArc(graphics, NULL, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
499 expect(InvalidParameter, status);
500
501 status = GdipDrawArc(NULL, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
502 expect(InvalidParameter, status);
503
504 status = GdipDrawArc(graphics, pen, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
505 expect(InvalidParameter, status);
506
507 status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
508 expect(InvalidParameter, status);
509
510 /* successful case */
511 status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
512 expect(Ok, status);
513
514 GdipDeletePen(pen);
515 GdipDeleteGraphics(graphics);
516
517 ReleaseDC(hwnd, hdc);
518 }
519
520 static void test_GdipDrawArcI(void)
521 {
522 GpStatus status;
523 GpGraphics *graphics = NULL;
524 GpPen *pen = NULL;
525 HDC hdc = GetDC( hwnd );
526
527 /* make a graphics object and pen object */
528 ok(hdc != NULL, "Expected HDC to be initialized\n");
529
530 status = GdipCreateFromHDC(hdc, &graphics);
531 expect(Ok, status);
532 ok(graphics != NULL, "Expected graphics to be initialized\n");
533
534 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
535 expect(Ok, status);
536 ok(pen != NULL, "Expected pen to be initialized\n");
537
538 /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
539 status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
540 expect(InvalidParameter, status);
541
542 status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
543 expect(InvalidParameter, status);
544
545 status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
546 expect(InvalidParameter, status);
547
548 status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
549 expect(InvalidParameter, status);
550
551 status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
552 expect(InvalidParameter, status);
553
554 /* successful case */
555 status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
556 expect(Ok, status);
557
558 GdipDeletePen(pen);
559 GdipDeleteGraphics(graphics);
560
561 ReleaseDC(hwnd, hdc);
562 }
563
564 static void test_BeginContainer2(void)
565 {
566 GpMatrix *transform;
567 GpRectF clip;
568 REAL defClip[] = {5, 10, 15, 20};
569 REAL elems[6], defTrans[] = {1, 2, 3, 4, 5, 6};
570 GraphicsContainer cont1, cont2, cont3, cont4;
571 CompositingQuality compqual, defCompqual = CompositingQualityHighSpeed;
572 CompositingMode compmode, defCompmode = CompositingModeSourceOver;
573 InterpolationMode interp, defInterp = InterpolationModeHighQualityBicubic;
574 REAL scale, defScale = 17;
575 GpUnit unit, defUnit = UnitPixel;
576 PixelOffsetMode offsetmode, defOffsetmode = PixelOffsetModeHighSpeed;
577 SmoothingMode smoothmode, defSmoothmode = SmoothingModeAntiAlias;
578 UINT contrast, defContrast = 5;
579 TextRenderingHint texthint, defTexthint = TextRenderingHintAntiAlias;
580
581 GpStatus status;
582 GpGraphics *graphics = NULL;
583 HDC hdc = GetDC( hwnd );
584
585 ok(hdc != NULL, "Expected HDC to be initialized\n");
586
587 status = GdipCreateFromHDC(hdc, &graphics);
588 expect(Ok, status);
589 ok(graphics != NULL, "Expected graphics to be initialized\n");
590
591 /* null graphics, null container */
592 status = GdipBeginContainer2(NULL, &cont1);
593 expect(InvalidParameter, status);
594
595 status = GdipBeginContainer2(graphics, NULL);
596 expect(InvalidParameter, status);
597
598 status = GdipEndContainer(NULL, cont1);
599 expect(InvalidParameter, status);
600
601 /* test all quality-related values */
602 GdipSetCompositingMode(graphics, defCompmode);
603 GdipSetCompositingQuality(graphics, defCompqual);
604 GdipSetInterpolationMode(graphics, defInterp);
605 GdipSetPageScale(graphics, defScale);
606 GdipSetPageUnit(graphics, defUnit);
607 GdipSetPixelOffsetMode(graphics, defOffsetmode);
608 GdipSetSmoothingMode(graphics, defSmoothmode);
609 GdipSetTextContrast(graphics, defContrast);
610 GdipSetTextRenderingHint(graphics, defTexthint);
611
612 status = GdipBeginContainer2(graphics, &cont1);
613 expect(Ok, status);
614
615 GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
616 GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
617 GdipSetInterpolationMode(graphics, InterpolationModeBilinear);
618 GdipSetPageScale(graphics, 10);
619 GdipSetPageUnit(graphics, UnitDocument);
620 GdipSetPixelOffsetMode(graphics, PixelOffsetModeHalf);
621 GdipSetSmoothingMode(graphics, SmoothingModeNone);
622 GdipSetTextContrast(graphics, 7);
623 GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit);
624
625 status = GdipEndContainer(graphics, cont1);
626 expect(Ok, status);
627
628 GdipGetCompositingMode(graphics, &compmode);
629 ok(defCompmode == compmode, "Expected Compositing Mode to be restored to %d, got %d\n", defCompmode, compmode);
630
631 GdipGetCompositingQuality(graphics, &compqual);
632 ok(defCompqual == compqual, "Expected Compositing Quality to be restored to %d, got %d\n", defCompqual, compqual);
633
634 GdipGetInterpolationMode(graphics, &interp);
635 ok(defInterp == interp, "Expected Interpolation Mode to be restored to %d, got %d\n", defInterp, interp);
636
637 GdipGetPageScale(graphics, &scale);
638 ok(fabs(defScale - scale) < 0.0001, "Expected Page Scale to be restored to %f, got %f\n", defScale, scale);
639
640 GdipGetPageUnit(graphics, &unit);
641 ok(defUnit == unit, "Expected Page Unit to be restored to %d, got %d\n", defUnit, unit);
642
643 GdipGetPixelOffsetMode(graphics, &offsetmode);
644 ok(defOffsetmode == offsetmode, "Expected Pixel Offset Mode to be restored to %d, got %d\n", defOffsetmode, offsetmode);
645
646 GdipGetSmoothingMode(graphics, &smoothmode);
647 ok(defSmoothmode == smoothmode, "Expected Smoothing Mode to be restored to %d, got %d\n", defSmoothmode, smoothmode);
648
649 GdipGetTextContrast(graphics, &contrast);
650 ok(defContrast == contrast, "Expected Text Contrast to be restored to %d, got %d\n", defContrast, contrast);
651
652 GdipGetTextRenderingHint(graphics, &texthint);
653 ok(defTexthint == texthint, "Expected Text Hint to be restored to %d, got %d\n", defTexthint, texthint);
654
655 /* test world transform */
656 status = GdipBeginContainer2(graphics, &cont1);
657 expect(Ok, status);
658
659 status = GdipCreateMatrix2(defTrans[0], defTrans[1], defTrans[2], defTrans[3],
660 defTrans[4], defTrans[5], &transform);
661 expect(Ok, status);
662 GdipSetWorldTransform(graphics, transform);
663 GdipDeleteMatrix(transform);
664 transform = NULL;
665
666 status = GdipBeginContainer2(graphics, &cont2);
667 expect(Ok, status);
668
669 status = GdipCreateMatrix2(10, 20, 30, 40, 50, 60, &transform);
670 expect(Ok, status);
671 GdipSetWorldTransform(graphics, transform);
672 GdipDeleteMatrix(transform);
673 transform = NULL;
674
675 status = GdipEndContainer(graphics, cont2);
676 expect(Ok, status);
677
678 status = GdipCreateMatrix(&transform);
679 expect(Ok, status);
680 GdipGetWorldTransform(graphics, transform);
681 GdipGetMatrixElements(transform, elems);
682 ok(fabs(defTrans[0] - elems[0]) < 0.0001 &&
683 fabs(defTrans[1] - elems[1]) < 0.0001 &&
684 fabs(defTrans[2] - elems[2]) < 0.0001 &&
685 fabs(defTrans[3] - elems[3]) < 0.0001 &&
686 fabs(defTrans[4] - elems[4]) < 0.0001 &&
687 fabs(defTrans[5] - elems[5]) < 0.0001,
688 "Expected World Transform Matrix to be restored to [%f, %f, %f, %f, %f, %f], got [%f, %f, %f, %f, %f, %f]\n",
689 defTrans[0], defTrans[1], defTrans[2], defTrans[3], defTrans[4], defTrans[5],
690 elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
691 GdipDeleteMatrix(transform);
692 transform = NULL;
693
694 status = GdipEndContainer(graphics, cont1);
695 expect(Ok, status);
696
697 /* test clipping */
698 status = GdipBeginContainer2(graphics, &cont1);
699 expect(Ok, status);
700
701 GdipSetClipRect(graphics, defClip[0], defClip[1], defClip[2], defClip[3], CombineModeReplace);
702
703 status = GdipBeginContainer2(graphics, &cont2);
704 expect(Ok, status);
705
706 GdipSetClipRect(graphics, 2, 4, 6, 8, CombineModeReplace);
707
708 status = GdipEndContainer(graphics, cont2);
709 expect(Ok, status);
710
711 status = GdipGetClipBounds(graphics, &clip);
712 expect(Ok, status);
713
714 ok(fabs(defClip[0] - clip.X) < 0.0001 &&
715 fabs(defClip[1] - clip.Y) < 0.0001 &&
716 fabs(defClip[2] - clip.Width) < 0.0001 &&
717 fabs(defClip[3] - clip.Height) < 0.0001,
718 "Expected Clipping Rectangle to be restored to [%f, %f, %f, %f], got [%f, %f, %f, %f]\n",
719 defClip[0], defClip[1], defClip[2], defClip[3],
720 clip.X, clip.Y, clip.Width, clip.Height);
721
722 status = GdipEndContainer(graphics, cont1);
723 expect(Ok, status);
724
725 /* nesting */
726 status = GdipBeginContainer2(graphics, &cont1);
727 expect(Ok, status);
728
729 status = GdipBeginContainer2(graphics, &cont2);
730 expect(Ok, status);
731
732 status = GdipBeginContainer2(graphics, &cont3);
733 expect(Ok, status);
734
735 status = GdipEndContainer(graphics, cont3);
736 expect(Ok, status);
737
738 status = GdipBeginContainer2(graphics, &cont4);
739 expect(Ok, status);
740
741 status = GdipEndContainer(graphics, cont4);
742 expect(Ok, status);
743
744 /* skip cont2 */
745 status = GdipEndContainer(graphics, cont1);
746 expect(Ok, status);
747
748 /* end an already-ended container */
749 status = GdipEndContainer(graphics, cont1);
750 expect(Ok, status);
751
752 GdipDeleteGraphics(graphics);
753 ReleaseDC(hwnd, hdc);
754 }
755
756 static void test_GdipDrawBezierI(void)
757 {
758 GpStatus status;
759 GpGraphics *graphics = NULL;
760 GpPen *pen = NULL;
761 HDC hdc = GetDC( hwnd );
762
763 /* make a graphics object and pen object */
764 ok(hdc != NULL, "Expected HDC to be initialized\n");
765
766 status = GdipCreateFromHDC(hdc, &graphics);
767 expect(Ok, status);
768 ok(graphics != NULL, "Expected graphics to be initialized\n");
769
770 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
771 expect(Ok, status);
772 ok(pen != NULL, "Expected pen to be initialized\n");
773
774 /* InvalidParameter cases: null graphics, null pen */
775 status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
776 expect(InvalidParameter, status);
777
778 status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
779 expect(InvalidParameter, status);
780
781 status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
782 expect(InvalidParameter, status);
783
784 /* successful case */
785 status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
786 expect(Ok, status);
787
788 GdipDeletePen(pen);
789 GdipDeleteGraphics(graphics);
790
791 ReleaseDC(hwnd, hdc);
792 }
793
794 static void test_GdipDrawCurve3(void)
795 {
796 GpStatus status;
797 GpGraphics *graphics = NULL;
798 GpPen *pen = NULL;
799 HDC hdc = GetDC( hwnd );
800 GpPointF points[3];
801
802 points[0].X = 0;
803 points[0].Y = 0;
804
805 points[1].X = 40;
806 points[1].Y = 20;
807
808 points[2].X = 10;
809 points[2].Y = 40;
810
811 /* make a graphics object and pen object */
812 ok(hdc != NULL, "Expected HDC to be initialized\n");
813
814 status = GdipCreateFromHDC(hdc, &graphics);
815 expect(Ok, status);
816 ok(graphics != NULL, "Expected graphics to be initialized\n");
817
818 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
819 expect(Ok, status);
820 ok(pen != NULL, "Expected pen to be initialized\n");
821
822 /* InvalidParameter cases: null graphics, null pen */
823 status = GdipDrawCurve3(NULL, NULL, points, 3, 0, 2, 1);
824 expect(InvalidParameter, status);
825
826 status = GdipDrawCurve3(graphics, NULL, points, 3, 0, 2, 1);
827 expect(InvalidParameter, status);
828
829 status = GdipDrawCurve3(NULL, pen, points, 3, 0, 2, 1);
830 expect(InvalidParameter, status);
831
832 /* InvalidParameter cases: invalid count */
833 status = GdipDrawCurve3(graphics, pen, points, -1, 0, 2, 1);
834 expect(InvalidParameter, status);
835
836 status = GdipDrawCurve3(graphics, pen, points, 0, 0, 2, 1);
837 expect(InvalidParameter, status);
838
839 status = GdipDrawCurve3(graphics, pen, points, 1, 0, 0, 1);
840 expect(InvalidParameter, status);
841
842 status = GdipDrawCurve3(graphics, pen, points, 3, 4, 2, 1);
843 expect(InvalidParameter, status);
844
845 /* InvalidParameter cases: invalid number of segments */
846 status = GdipDrawCurve3(graphics, pen, points, 3, 0, -1, 1);
847 expect(InvalidParameter, status);
848
849 status = GdipDrawCurve3(graphics, pen, points, 3, 1, 2, 1);
850 expect(InvalidParameter, status);
851
852 status = GdipDrawCurve3(graphics, pen, points, 2, 0, 2, 1);
853 expect(InvalidParameter, status);
854
855 /* Valid test cases */
856 status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, 1);
857 expect(Ok, status);
858
859 status = GdipDrawCurve3(graphics, pen, points, 3, 0, 2, 2);
860 expect(Ok, status);
861
862 status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, -2);
863 expect(Ok, status);
864
865 status = GdipDrawCurve3(graphics, pen, points, 3, 1, 1, 0);
866 expect(Ok, status);
867
868 GdipDeletePen(pen);
869 GdipDeleteGraphics(graphics);
870
871 ReleaseDC(hwnd, hdc);
872 }
873
874 static void test_GdipDrawCurve3I(void)
875 {
876 GpStatus status;
877 GpGraphics *graphics = NULL;
878 GpPen *pen = NULL;
879 HDC hdc = GetDC( hwnd );
880 GpPoint points[3];
881
882 points[0].X = 0;
883 points[0].Y = 0;
884
885 points[1].X = 40;
886 points[1].Y = 20;
887
888 points[2].X = 10;
889 points[2].Y = 40;
890
891 /* make a graphics object and pen object */
892 ok(hdc != NULL, "Expected HDC to be initialized\n");
893
894 status = GdipCreateFromHDC(hdc, &graphics);
895 expect(Ok, status);
896 ok(graphics != NULL, "Expected graphics to be initialized\n");
897
898 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
899 expect(Ok, status);
900 ok(pen != NULL, "Expected pen to be initialized\n");
901
902 /* InvalidParameter cases: null graphics, null pen */
903 status = GdipDrawCurve3I(NULL, NULL, points, 3, 0, 2, 1);
904 expect(InvalidParameter, status);
905
906 status = GdipDrawCurve3I(graphics, NULL, points, 3, 0, 2, 1);
907 expect(InvalidParameter, status);
908
909 status = GdipDrawCurve3I(NULL, pen, points, 3, 0, 2, 1);
910 expect(InvalidParameter, status);
911
912 /* InvalidParameter cases: invalid count */
913 status = GdipDrawCurve3I(graphics, pen, points, -1, -1, -1, 1);
914 expect(OutOfMemory, status);
915
916 status = GdipDrawCurve3I(graphics, pen, points, 0, 0, 2, 1);
917 expect(InvalidParameter, status);
918
919 status = GdipDrawCurve3I(graphics, pen, points, 1, 0, 0, 1);
920 expect(InvalidParameter, status);
921
922 status = GdipDrawCurve3I(graphics, pen, points, 3, 4, 2, 1);
923 expect(InvalidParameter, status);
924
925 /* InvalidParameter cases: invalid number of segments */
926 status = GdipDrawCurve3I(graphics, pen, points, 3, 0, -1, 1);
927 expect(InvalidParameter, status);
928
929 status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 2, 1);
930 expect(InvalidParameter, status);
931
932 status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 2, 1);
933 expect(InvalidParameter, status);
934
935 /* Valid test cases */
936 status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, 1);
937 expect(Ok, status);
938
939 status = GdipDrawCurve3I(graphics, pen, points, 3, 0, 2, 2);
940 expect(Ok, status);
941
942 status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, -2);
943 expect(Ok, status);
944
945 status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 1, 0);
946 expect(Ok, status);
947
948 GdipDeletePen(pen);
949 GdipDeleteGraphics(graphics);
950
951 ReleaseDC(hwnd, hdc);
952 }
953
954 static void test_GdipDrawCurve2(void)
955 {
956 GpStatus status;
957 GpGraphics *graphics = NULL;
958 GpPen *pen = NULL;
959 HDC hdc = GetDC( hwnd );
960 GpPointF points[3];
961
962 points[0].X = 0;
963 points[0].Y = 0;
964
965 points[1].X = 40;
966 points[1].Y = 20;
967
968 points[2].X = 10;
969 points[2].Y = 40;
970
971 /* make a graphics object and pen object */
972 ok(hdc != NULL, "Expected HDC to be initialized\n");
973
974 status = GdipCreateFromHDC(hdc, &graphics);
975 expect(Ok, status);
976 ok(graphics != NULL, "Expected graphics to be initialized\n");
977
978 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
979 expect(Ok, status);
980 ok(pen != NULL, "Expected pen to be initialized\n");
981
982 /* InvalidParameter cases: null graphics, null pen */
983 status = GdipDrawCurve2(NULL, NULL, points, 3, 1);
984 expect(InvalidParameter, status);
985
986 status = GdipDrawCurve2(graphics, NULL, points, 3, 1);
987 expect(InvalidParameter, status);
988
989 status = GdipDrawCurve2(NULL, pen, points, 3, 1);
990 expect(InvalidParameter, status);
991
992 /* InvalidParameter cases: invalid count */
993 status = GdipDrawCurve2(graphics, pen, points, -1, 1);
994 expect(InvalidParameter, status);
995
996 status = GdipDrawCurve2(graphics, pen, points, 0, 1);
997 expect(InvalidParameter, status);
998
999 status = GdipDrawCurve2(graphics, pen, points, 1, 1);
1000 expect(InvalidParameter, status);
1001
1002 /* Valid test cases */
1003 status = GdipDrawCurve2(graphics, pen, points, 2, 1);
1004 expect(Ok, status);
1005
1006 status = GdipDrawCurve2(graphics, pen, points, 3, 2);
1007 expect(Ok, status);
1008
1009 status = GdipDrawCurve2(graphics, pen, points, 3, -2);
1010 expect(Ok, status);
1011
1012 status = GdipDrawCurve2(graphics, pen, points, 3, 0);
1013 expect(Ok, status);
1014
1015 GdipDeletePen(pen);
1016 GdipDeleteGraphics(graphics);
1017
1018 ReleaseDC(hwnd, hdc);
1019 }
1020
1021 static void test_GdipDrawCurve2I(void)
1022 {
1023 GpStatus status;
1024 GpGraphics *graphics = NULL;
1025 GpPen *pen = NULL;
1026 HDC hdc = GetDC( hwnd );
1027 GpPoint points[3];
1028
1029 points[0].X = 0;
1030 points[0].Y = 0;
1031
1032 points[1].X = 40;
1033 points[1].Y = 20;
1034
1035 points[2].X = 10;
1036 points[2].Y = 40;
1037
1038 /* make a graphics object and pen object */
1039 ok(hdc != NULL, "Expected HDC to be initialized\n");
1040
1041 status = GdipCreateFromHDC(hdc, &graphics);
1042 expect(Ok, status);
1043 ok(graphics != NULL, "Expected graphics to be initialized\n");
1044
1045 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1046 expect(Ok, status);
1047 ok(pen != NULL, "Expected pen to be initialized\n");
1048
1049 /* InvalidParameter cases: null graphics, null pen */
1050 status = GdipDrawCurve2I(NULL, NULL, points, 3, 1);
1051 expect(InvalidParameter, status);
1052
1053 status = GdipDrawCurve2I(graphics, NULL, points, 3, 1);
1054 expect(InvalidParameter, status);
1055
1056 status = GdipDrawCurve2I(NULL, pen, points, 3, 1);
1057 expect(InvalidParameter, status);
1058
1059 /* InvalidParameter cases: invalid count */
1060 status = GdipDrawCurve2I(graphics, pen, points, -1, 1);
1061 expect(OutOfMemory, status);
1062
1063 status = GdipDrawCurve2I(graphics, pen, points, 0, 1);
1064 expect(InvalidParameter, status);
1065
1066 status = GdipDrawCurve2I(graphics, pen, points, 1, 1);
1067 expect(InvalidParameter, status);
1068
1069 /* Valid test cases */
1070 status = GdipDrawCurve2I(graphics, pen, points, 2, 1);
1071 expect(Ok, status);
1072
1073 status = GdipDrawCurve2I(graphics, pen, points, 3, 2);
1074 expect(Ok, status);
1075
1076 status = GdipDrawCurve2I(graphics, pen, points, 3, -2);
1077 expect(Ok, status);
1078
1079 status = GdipDrawCurve2I(graphics, pen, points, 3, 0);
1080 expect(Ok, status);
1081
1082 GdipDeletePen(pen);
1083 GdipDeleteGraphics(graphics);
1084
1085 ReleaseDC(hwnd, hdc);
1086 }
1087
1088 static void test_GdipDrawCurve(void)
1089 {
1090 GpStatus status;
1091 GpGraphics *graphics = NULL;
1092 GpPen *pen = NULL;
1093 HDC hdc = GetDC( hwnd );
1094 GpPointF points[3];
1095
1096 points[0].X = 0;
1097 points[0].Y = 0;
1098
1099 points[1].X = 40;
1100 points[1].Y = 20;
1101
1102 points[2].X = 10;
1103 points[2].Y = 40;
1104
1105 /* make a graphics object and pen object */
1106 ok(hdc != NULL, "Expected HDC to be initialized\n");
1107
1108 status = GdipCreateFromHDC(hdc, &graphics);
1109 expect(Ok, status);
1110 ok(graphics != NULL, "Expected graphics to be initialized\n");
1111
1112 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1113 expect(Ok, status);
1114 ok(pen != NULL, "Expected pen to be initialized\n");
1115
1116 /* InvalidParameter cases: null graphics, null pen */
1117 status = GdipDrawCurve(NULL, NULL, points, 3);
1118 expect(InvalidParameter, status);
1119
1120 status = GdipDrawCurve(graphics, NULL, points, 3);
1121 expect(InvalidParameter, status);
1122
1123 status = GdipDrawCurve(NULL, pen, points, 3);
1124 expect(InvalidParameter, status);
1125
1126 /* InvalidParameter cases: invalid count */
1127 status = GdipDrawCurve(graphics, pen, points, -1);
1128 expect(InvalidParameter, status);
1129
1130 status = GdipDrawCurve(graphics, pen, points, 0);
1131 expect(InvalidParameter, status);
1132
1133 status = GdipDrawCurve(graphics, pen, points, 1);
1134 expect(InvalidParameter, status);
1135
1136 /* Valid test cases */
1137 status = GdipDrawCurve(graphics, pen, points, 2);
1138 expect(Ok, status);
1139
1140 status = GdipDrawCurve(graphics, pen, points, 3);
1141 expect(Ok, status);
1142
1143 GdipDeletePen(pen);
1144 GdipDeleteGraphics(graphics);
1145
1146 ReleaseDC(hwnd, hdc);
1147 }
1148
1149 static void test_GdipDrawCurveI(void)
1150 {
1151 GpStatus status;
1152 GpGraphics *graphics = NULL;
1153 GpPen *pen = NULL;
1154 HDC hdc = GetDC( hwnd );
1155 GpPoint points[3];
1156
1157 points[0].X = 0;
1158 points[0].Y = 0;
1159
1160 points[1].X = 40;
1161 points[1].Y = 20;
1162
1163 points[2].X = 10;
1164 points[2].Y = 40;
1165
1166 /* make a graphics object and pen object */
1167 ok(hdc != NULL, "Expected HDC to be initialized\n");
1168
1169 status = GdipCreateFromHDC(hdc, &graphics);
1170 expect(Ok, status);
1171 ok(graphics != NULL, "Expected graphics to be initialized\n");
1172
1173 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1174 expect(Ok, status);
1175 ok(pen != NULL, "Expected pen to be initialized\n");
1176
1177 /* InvalidParameter cases: null graphics, null pen */
1178 status = GdipDrawCurveI(NULL, NULL, points, 3);
1179 expect(InvalidParameter, status);
1180
1181 status = GdipDrawCurveI(graphics, NULL, points, 3);
1182 expect(InvalidParameter, status);
1183
1184 status = GdipDrawCurveI(NULL, pen, points, 3);
1185 expect(InvalidParameter, status);
1186
1187 /* InvalidParameter cases: invalid count */
1188 status = GdipDrawCurveI(graphics, pen, points, -1);
1189 expect(OutOfMemory, status);
1190
1191 status = GdipDrawCurveI(graphics, pen, points, 0);
1192 expect(InvalidParameter, status);
1193
1194 status = GdipDrawCurveI(graphics, pen, points, 1);
1195 expect(InvalidParameter, status);
1196
1197 /* Valid test cases */
1198 status = GdipDrawCurveI(graphics, pen, points, 2);
1199 expect(Ok, status);
1200
1201 status = GdipDrawCurveI(graphics, pen, points, 3);
1202 expect(Ok, status);
1203
1204 GdipDeletePen(pen);
1205 GdipDeleteGraphics(graphics);
1206
1207 ReleaseDC(hwnd, hdc);
1208 }
1209
1210 static void test_GdipDrawLineI(void)
1211 {
1212 GpStatus status;
1213 GpGraphics *graphics = NULL;
1214 GpPen *pen = NULL;
1215 HDC hdc = GetDC( hwnd );
1216
1217 /* make a graphics object and pen object */
1218 ok(hdc != NULL, "Expected HDC to be initialized\n");
1219
1220 status = GdipCreateFromHDC(hdc, &graphics);
1221 expect(Ok, status);
1222 ok(graphics != NULL, "Expected graphics to be initialized\n");
1223
1224 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1225 expect(Ok, status);
1226 ok(pen != NULL, "Expected pen to be initialized\n");
1227
1228 /* InvalidParameter cases: null graphics, null pen */
1229 status = GdipDrawLineI(NULL, NULL, 0, 0, 0, 0);
1230 expect(InvalidParameter, status);
1231
1232 status = GdipDrawLineI(graphics, NULL, 0, 0, 0, 0);
1233 expect(InvalidParameter, status);
1234
1235 status = GdipDrawLineI(NULL, pen, 0, 0, 0, 0);
1236 expect(InvalidParameter, status);
1237
1238 /* successful case */
1239 status = GdipDrawLineI(graphics, pen, 0, 0, 0, 0);
1240 expect(Ok, status);
1241
1242 GdipDeletePen(pen);
1243 GdipDeleteGraphics(graphics);
1244
1245 ReleaseDC(hwnd, hdc);
1246 }
1247
1248 static void test_GdipDrawImagePointsRect(void)
1249 {
1250 GpStatus status;
1251 GpGraphics *graphics = NULL;
1252 GpPointF ptf[4];
1253 GpBitmap *bm = NULL;
1254 BYTE rbmi[sizeof(BITMAPINFOHEADER)];
1255 BYTE buff[400];
1256 BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
1257 HDC hdc = GetDC( hwnd );
1258 if (!hdc)
1259 return;
1260
1261 memset(rbmi, 0, sizeof(rbmi));
1262 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1263 bmi->bmiHeader.biWidth = 10;
1264 bmi->bmiHeader.biHeight = 10;
1265 bmi->bmiHeader.biPlanes = 1;
1266 bmi->bmiHeader.biBitCount = 32;
1267 bmi->bmiHeader.biCompression = BI_RGB;
1268 status = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
1269 expect(Ok, status);
1270 ok(NULL != bm, "Expected bitmap to be initialized\n");
1271 status = GdipCreateFromHDC(hdc, &graphics);
1272 expect(Ok, status);
1273 ptf[0].X = 0;
1274 ptf[0].Y = 0;
1275 ptf[1].X = 10;
1276 ptf[1].Y = 0;
1277 ptf[2].X = 0;
1278 ptf[2].Y = 10;
1279 ptf[3].X = 10;
1280 ptf[3].Y = 10;
1281 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 4, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1282 expect(NotImplemented, status);
1283 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 2, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1284 expect(InvalidParameter, status);
1285 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1286 expect(Ok, status);
1287 status = GdipDrawImagePointsRect(graphics, NULL, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1288 expect(InvalidParameter, status);
1289 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, NULL, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1290 expect(InvalidParameter, status);
1291 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 0, 0, UnitPixel, NULL, NULL, NULL);
1292 expect(Ok, status);
1293 memset(ptf, 0, sizeof(ptf));
1294 status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
1295 expect(Ok, status);
1296
1297 GdipDisposeImage((GpImage*)bm);
1298 GdipDeleteGraphics(graphics);
1299 ReleaseDC(hwnd, hdc);
1300 }
1301
1302 static void test_GdipDrawLinesI(void)
1303 {
1304 GpStatus status;
1305 GpGraphics *graphics = NULL;
1306 GpPen *pen = NULL;
1307 GpPoint *ptf = NULL;
1308 HDC hdc = GetDC( hwnd );
1309
1310 /* make a graphics object and pen object */
1311 ok(hdc != NULL, "Expected HDC to be initialized\n");
1312
1313 status = GdipCreateFromHDC(hdc, &graphics);
1314 expect(Ok, status);
1315 ok(graphics != NULL, "Expected graphics to be initialized\n");
1316
1317 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1318 expect(Ok, status);
1319 ok(pen != NULL, "Expected pen to be initialized\n");
1320
1321 /* make some arbitrary valid points*/
1322 ptf = GdipAlloc(2 * sizeof(GpPointF));
1323
1324 ptf[0].X = 1;
1325 ptf[0].Y = 1;
1326
1327 ptf[1].X = 2;
1328 ptf[1].Y = 2;
1329
1330 /* InvalidParameter cases: null graphics, null pen, null points, count < 2*/
1331 status = GdipDrawLinesI(NULL, NULL, NULL, 0);
1332 expect(InvalidParameter, status);
1333
1334 status = GdipDrawLinesI(graphics, pen, ptf, 0);
1335 expect(InvalidParameter, status);
1336
1337 status = GdipDrawLinesI(graphics, NULL, ptf, 2);
1338 expect(InvalidParameter, status);
1339
1340 status = GdipDrawLinesI(NULL, pen, ptf, 2);
1341 expect(InvalidParameter, status);
1342
1343 /* successful case */
1344 status = GdipDrawLinesI(graphics, pen, ptf, 2);
1345 expect(Ok, status);
1346
1347 GdipFree(ptf);
1348 GdipDeletePen(pen);
1349 GdipDeleteGraphics(graphics);
1350
1351 ReleaseDC(hwnd, hdc);
1352 }
1353
1354 static void test_GdipFillClosedCurve(void)
1355 {
1356 GpStatus status;
1357 GpGraphics *graphics = NULL;
1358 GpSolidFill *brush = NULL;
1359 HDC hdc = GetDC( hwnd );
1360 GpPointF points[3];
1361
1362 points[0].X = 0;
1363 points[0].Y = 0;
1364
1365 points[1].X = 40;
1366 points[1].Y = 20;
1367
1368 points[2].X = 10;
1369 points[2].Y = 40;
1370
1371 /* make a graphics object and brush object */
1372 ok(hdc != NULL, "Expected HDC to be initialized\n");
1373
1374 status = GdipCreateFromHDC(hdc, &graphics);
1375 expect(Ok, status);
1376 ok(graphics != NULL, "Expected graphics to be initialized\n");
1377
1378 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1379
1380 /* InvalidParameter cases: null graphics, null brush, null points */
1381 status = GdipFillClosedCurve(NULL, NULL, NULL, 3);
1382 expect(InvalidParameter, status);
1383
1384 status = GdipFillClosedCurve(graphics, NULL, NULL, 3);
1385 expect(InvalidParameter, status);
1386
1387 status = GdipFillClosedCurve(NULL, (GpBrush*)brush, NULL, 3);
1388 expect(InvalidParameter, status);
1389
1390 status = GdipFillClosedCurve(NULL, NULL, points, 3);
1391 expect(InvalidParameter, status);
1392
1393 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, NULL, 3);
1394 expect(InvalidParameter, status);
1395
1396 status = GdipFillClosedCurve(graphics, NULL, points, 3);
1397 expect(InvalidParameter, status);
1398
1399 status = GdipFillClosedCurve(NULL, (GpBrush*)brush, points, 3);
1400 expect(InvalidParameter, status);
1401
1402 /* InvalidParameter cases: invalid count */
1403 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, -1);
1404 expect(InvalidParameter, status);
1405
1406 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 0);
1407 expect(InvalidParameter, status);
1408
1409 /* Valid test cases */
1410 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 1);
1411 expect(Ok, status);
1412
1413 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 2);
1414 expect(Ok, status);
1415
1416 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 3);
1417 expect(Ok, status);
1418
1419 GdipDeleteGraphics(graphics);
1420 GdipDeleteBrush((GpBrush*)brush);
1421
1422 ReleaseDC(hwnd, hdc);
1423 }
1424
1425 static void test_GdipFillClosedCurveI(void)
1426 {
1427 GpStatus status;
1428 GpGraphics *graphics = NULL;
1429 GpSolidFill *brush = NULL;
1430 HDC hdc = GetDC( hwnd );
1431 GpPoint points[3];
1432
1433 points[0].X = 0;
1434 points[0].Y = 0;
1435
1436 points[1].X = 40;
1437 points[1].Y = 20;
1438
1439 points[2].X = 10;
1440 points[2].Y = 40;
1441
1442 /* make a graphics object and brush object */
1443 ok(hdc != NULL, "Expected HDC to be initialized\n");
1444
1445 status = GdipCreateFromHDC(hdc, &graphics);
1446 expect(Ok, status);
1447 ok(graphics != NULL, "Expected graphics to be initialized\n");
1448
1449 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1450
1451 /* InvalidParameter cases: null graphics, null brush */
1452 /* Note: GdipFillClosedCurveI and GdipFillClosedCurve2I hang in Windows
1453 when points == NULL, so don't test this condition */
1454 status = GdipFillClosedCurveI(NULL, NULL, points, 3);
1455 expect(InvalidParameter, status);
1456
1457 status = GdipFillClosedCurveI(graphics, NULL, points, 3);
1458 expect(InvalidParameter, status);
1459
1460 status = GdipFillClosedCurveI(NULL, (GpBrush*)brush, points, 3);
1461 expect(InvalidParameter, status);
1462
1463 /* InvalidParameter cases: invalid count */
1464 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 0);
1465 expect(InvalidParameter, status);
1466
1467 /* OutOfMemory cases: large (unsigned) int */
1468 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, -1);
1469 expect(OutOfMemory, status);
1470
1471 /* Valid test cases */
1472 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 1);
1473 expect(Ok, status);
1474
1475 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 2);
1476 expect(Ok, status);
1477
1478 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 3);
1479 expect(Ok, status);
1480
1481 GdipDeleteGraphics(graphics);
1482 GdipDeleteBrush((GpBrush*)brush);
1483
1484 ReleaseDC(hwnd, hdc);
1485 }
1486
1487 static void test_Get_Release_DC(void)
1488 {
1489 GpStatus status;
1490 GpGraphics *graphics = NULL;
1491 GpPen *pen;
1492 GpSolidFill *brush;
1493 GpPath *path;
1494 HDC hdc = GetDC( hwnd );
1495 HDC retdc;
1496 REAL r;
1497 CompositingQuality quality;
1498 CompositingMode compmode;
1499 InterpolationMode intmode;
1500 GpMatrix *m;
1501 GpRegion *region;
1502 GpUnit unit;
1503 PixelOffsetMode offsetmode;
1504 SmoothingMode smoothmode;
1505 TextRenderingHint texthint;
1506 GpPointF ptf[5];
1507 GpPoint pt[5];
1508 GpRectF rectf[2];
1509 GpRect rect[2];
1510 GpRegion *clip;
1511 INT i;
1512 BOOL res;
1513 ARGB color = 0x00000000;
1514 HRGN hrgn = CreateRectRgn(0, 0, 10, 10);
1515
1516 pt[0].X = 10;
1517 pt[0].Y = 10;
1518 pt[1].X = 20;
1519 pt[1].Y = 15;
1520 pt[2].X = 40;
1521 pt[2].Y = 80;
1522 pt[3].X = -20;
1523 pt[3].Y = 20;
1524 pt[4].X = 50;
1525 pt[4].Y = 110;
1526
1527 for(i = 0; i < 5;i++){
1528 ptf[i].X = (REAL)pt[i].X;
1529 ptf[i].Y = (REAL)pt[i].Y;
1530 }
1531
1532 rect[0].X = 0;
1533 rect[0].Y = 0;
1534 rect[0].Width = 50;
1535 rect[0].Height = 70;
1536 rect[1].X = 0;
1537 rect[1].Y = 0;
1538 rect[1].Width = 10;
1539 rect[1].Height = 20;
1540
1541 for(i = 0; i < 2;i++){
1542 rectf[i].X = (REAL)rect[i].X;
1543 rectf[i].Y = (REAL)rect[i].Y;
1544 rectf[i].Height = (REAL)rect[i].Height;
1545 rectf[i].Width = (REAL)rect[i].Width;
1546 }
1547
1548 status = GdipCreateMatrix(&m);
1549 expect(Ok, status);
1550 GdipCreateRegion(&region);
1551 GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
1552 GdipCreatePath(FillModeAlternate, &path);
1553 GdipCreateRegion(&clip);
1554
1555 status = GdipCreateFromHDC(hdc, &graphics);
1556 expect(Ok, status);
1557 ok(graphics != NULL, "Expected graphics to be initialized\n");
1558 status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
1559 expect(Ok, status);
1560
1561 /* NULL arguments */
1562 status = GdipGetDC(NULL, NULL);
1563 expect(InvalidParameter, status);
1564 status = GdipGetDC(graphics, NULL);
1565 expect(InvalidParameter, status);
1566 status = GdipGetDC(NULL, &retdc);
1567 expect(InvalidParameter, status);
1568
1569 status = GdipReleaseDC(NULL, NULL);
1570 expect(InvalidParameter, status);
1571 status = GdipReleaseDC(graphics, NULL);
1572 expect(InvalidParameter, status);
1573 status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
1574 expect(InvalidParameter, status);
1575
1576 /* Release without Get */
1577 status = GdipReleaseDC(graphics, hdc);
1578 expect(InvalidParameter, status);
1579
1580 retdc = NULL;
1581 status = GdipGetDC(graphics, &retdc);
1582 expect(Ok, status);
1583 ok(retdc == hdc, "Invalid HDC returned\n");
1584 /* call it once more */
1585 status = GdipGetDC(graphics, &retdc);
1586 expect(ObjectBusy, status);
1587
1588 /* try all Graphics calls here */
1589 status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
1590 expect(ObjectBusy, status);
1591 status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
1592 expect(ObjectBusy, status);
1593 status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
1594 expect(ObjectBusy, status);
1595 status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
1596 expect(ObjectBusy, status);
1597 status = GdipDrawBeziers(graphics, pen, ptf, 5);
1598 expect(ObjectBusy, status);
1599 status = GdipDrawBeziersI(graphics, pen, pt, 5);
1600 expect(ObjectBusy, status);
1601 status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
1602 expect(ObjectBusy, status);
1603 status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
1604 expect(ObjectBusy, status);
1605 status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
1606 expect(ObjectBusy, status);
1607 status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
1608 expect(ObjectBusy, status);
1609 status = GdipDrawCurve(graphics, pen, ptf, 5);
1610 expect(ObjectBusy, status);
1611 status = GdipDrawCurveI(graphics, pen, pt, 5);
1612 expect(ObjectBusy, status);
1613 status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
1614 expect(ObjectBusy, status);
1615 status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
1616 expect(ObjectBusy, status);
1617 status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
1618 expect(ObjectBusy, status);
1619 status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
1620 expect(ObjectBusy, status);
1621 /* GdipDrawImage/GdipDrawImageI */
1622 /* GdipDrawImagePointsRect/GdipDrawImagePointsRectI */
1623 /* GdipDrawImageRectRect/GdipDrawImageRectRectI */
1624 /* GdipDrawImageRect/GdipDrawImageRectI */
1625 status = GdipDrawLine(graphics, pen, 0.0, 0.0, 100.0, 200.0);
1626 expect(ObjectBusy, status);
1627 status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
1628 expect(ObjectBusy, status);
1629 status = GdipDrawLines(graphics, pen, ptf, 5);
1630 expect(ObjectBusy, status);
1631 status = GdipDrawLinesI(graphics, pen, pt, 5);
1632 expect(ObjectBusy, status);
1633 status = GdipDrawPath(graphics, pen, path);
1634 expect(ObjectBusy, status);
1635 status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1636 expect(ObjectBusy, status);
1637 status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
1638 expect(ObjectBusy, status);
1639 status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
1640 expect(ObjectBusy, status);
1641 status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
1642 expect(ObjectBusy, status);
1643 status = GdipDrawRectangles(graphics, pen, rectf, 2);
1644 expect(ObjectBusy, status);
1645 status = GdipDrawRectanglesI(graphics, pen, rect, 2);
1646 expect(ObjectBusy, status);
1647 /* GdipDrawString */
1648 status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
1649 expect(ObjectBusy, status);
1650 status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
1651 expect(ObjectBusy, status);
1652 status = GdipFillClosedCurve(graphics, (GpBrush*)brush, ptf, 5);
1653 expect(ObjectBusy, status);
1654 status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, pt, 5);
1655 expect(ObjectBusy, status);
1656 status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1657 expect(ObjectBusy, status);
1658 status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1659 expect(ObjectBusy, status);
1660 status = GdipFillPath(graphics, (GpBrush*)brush, path);
1661 expect(ObjectBusy, status);
1662 status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
1663 expect(ObjectBusy, status);
1664 status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
1665 expect(ObjectBusy, status);
1666 status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
1667 expect(ObjectBusy, status);
1668 status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
1669 expect(ObjectBusy, status);
1670 status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
1671 expect(ObjectBusy, status);
1672 status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
1673 expect(ObjectBusy, status);
1674 status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1675 expect(ObjectBusy, status);
1676 status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1677 expect(ObjectBusy, status);
1678 status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
1679 expect(ObjectBusy, status);
1680 status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
1681 expect(ObjectBusy, status);
1682 status = GdipFillRegion(graphics, (GpBrush*)brush, region);
1683 expect(ObjectBusy, status);
1684 status = GdipFlush(graphics, FlushIntentionFlush);
1685 expect(ObjectBusy, status);
1686 status = GdipGetClipBounds(graphics, rectf);
1687 expect(ObjectBusy, status);
1688 status = GdipGetClipBoundsI(graphics, rect);
1689 expect(ObjectBusy, status);
1690 status = GdipGetCompositingMode(graphics, &compmode);
1691 expect(ObjectBusy, status);
1692 status = GdipGetCompositingQuality(graphics, &quality);
1693 expect(ObjectBusy, status);
1694 status = GdipGetInterpolationMode(graphics, &intmode);
1695 expect(ObjectBusy, status);
1696 status = GdipGetNearestColor(graphics, &color);
1697 expect(ObjectBusy, status);
1698 status = GdipGetPageScale(graphics, &r);
1699 expect(ObjectBusy, status);
1700 status = GdipGetPageUnit(graphics, &unit);
1701 expect(ObjectBusy, status);
1702 status = GdipGetPixelOffsetMode(graphics, &offsetmode);
1703 expect(ObjectBusy, status);
1704 status = GdipGetSmoothingMode(graphics, &smoothmode);
1705 expect(ObjectBusy, status);
1706 status = GdipGetTextRenderingHint(graphics, &texthint);
1707 expect(ObjectBusy, status);
1708 status = GdipGetWorldTransform(graphics, m);
1709 expect(ObjectBusy, status);
1710 status = GdipGraphicsClear(graphics, 0xdeadbeef);
1711 expect(ObjectBusy, status);
1712 status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
1713 expect(ObjectBusy, status);
1714 status = GdipIsVisiblePointI(graphics, 0, 0, &res);
1715 expect(ObjectBusy, status);
1716 /* GdipMeasureCharacterRanges */
1717 /* GdipMeasureString */
1718 status = GdipResetClip(graphics);
1719 expect(ObjectBusy, status);
1720 status = GdipResetWorldTransform(graphics);
1721 expect(ObjectBusy, status);
1722 /* GdipRestoreGraphics */
1723 status = GdipRotateWorldTransform(graphics, 15.0, MatrixOrderPrepend);
1724 expect(ObjectBusy, status);
1725 /* GdipSaveGraphics */
1726 status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
1727 expect(ObjectBusy, status);
1728 status = GdipSetCompositingMode(graphics, CompositingModeSourceOver);
1729 expect(ObjectBusy, status);
1730 status = GdipSetCompositingQuality(graphics, CompositingQualityDefault);
1731 expect(ObjectBusy, status);
1732 status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
1733 expect(ObjectBusy, status);
1734 status = GdipSetPageScale(graphics, 1.0);
1735 expect(ObjectBusy, status);
1736 status = GdipSetPageUnit(graphics, UnitWorld);
1737 expect(ObjectBusy, status);
1738 status = GdipSetPixelOffsetMode(graphics, PixelOffsetModeDefault);
1739 expect(ObjectBusy, status);
1740 status = GdipSetSmoothingMode(graphics, SmoothingModeDefault);
1741 expect(ObjectBusy, status);
1742 status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
1743 expect(ObjectBusy, status);
1744 status = GdipSetWorldTransform(graphics, m);
1745 expect(ObjectBusy, status);
1746 status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
1747 expect(ObjectBusy, status);
1748 status = GdipSetClipHrgn(graphics, hrgn, CombineModeReplace);
1749 expect(ObjectBusy, status);
1750 status = GdipSetClipPath(graphics, path, CombineModeReplace);
1751 expect(ObjectBusy, status);
1752 status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
1753 expect(ObjectBusy, status);
1754 status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
1755 expect(ObjectBusy, status);
1756 status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1757 expect(ObjectBusy, status);
1758 status = GdipTranslateClip(graphics, 0.0, 0.0);
1759 expect(ObjectBusy, status);
1760 status = GdipTranslateClipI(graphics, 0, 0);
1761 expect(ObjectBusy, status);
1762 status = GdipDrawPolygon(graphics, pen, ptf, 5);
1763 expect(ObjectBusy, status);
1764 status = GdipDrawPolygonI(graphics, pen, pt, 5);
1765 expect(ObjectBusy, status);
1766 status = GdipGetDpiX(graphics, &r);
1767 expect(ObjectBusy, status);
1768 status = GdipGetDpiY(graphics, &r);
1769 expect(ObjectBusy, status);
1770 status = GdipMultiplyWorldTransform(graphics, m, MatrixOrderPrepend);
1771 expect(ObjectBusy, status);
1772 status = GdipGetClip(graphics, region);
1773 expect(ObjectBusy, status);
1774 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 5);
1775 expect(ObjectBusy, status);
1776
1777 /* try to delete before release */
1778 status = GdipDeleteGraphics(graphics);
1779 expect(ObjectBusy, status);
1780
1781 status = GdipReleaseDC(graphics, retdc);
1782 expect(Ok, status);
1783
1784 GdipDeletePen(pen);
1785 GdipDeleteGraphics(graphics);
1786
1787 GdipDeleteRegion(clip);
1788 GdipDeletePath(path);
1789 GdipDeleteBrush((GpBrush*)brush);
1790 GdipDeleteRegion(region);
1791 GdipDeleteMatrix(m);
1792 DeleteObject(hrgn);
1793
1794 ReleaseDC(hwnd, hdc);
1795 }
1796
1797 static void test_transformpoints(void)
1798 {
1799 GpStatus status;
1800 GpGraphics *graphics = NULL;
1801 HDC hdc = GetDC( hwnd );
1802 GpPointF ptf[2];
1803 GpPoint pt[2];
1804
1805 status = GdipCreateFromHDC(hdc, &graphics);
1806 expect(Ok, status);
1807
1808 /* NULL arguments */
1809 status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1810 expect(InvalidParameter, status);
1811 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0);
1812 expect(InvalidParameter, status);
1813 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 0);
1814 expect(InvalidParameter, status);
1815 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1);
1816 expect(InvalidParameter, status);
1817
1818 ptf[0].X = 1.0;
1819 ptf[0].Y = 0.0;
1820 ptf[1].X = 0.0;
1821 ptf[1].Y = 1.0;
1822 status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1823 expect(Ok, status);
1824 expectf(1.0, ptf[0].X);
1825 expectf(0.0, ptf[0].Y);
1826 expectf(0.0, ptf[1].X);
1827 expectf(1.0, ptf[1].Y);
1828
1829 status = GdipTranslateWorldTransform(graphics, 5.0, 5.0, MatrixOrderAppend);
1830 expect(Ok, status);
1831 status = GdipSetPageUnit(graphics, UnitPixel);
1832 expect(Ok, status);
1833 status = GdipSetPageScale(graphics, 3.0);
1834 expect(Ok, status);
1835
1836 ptf[0].X = 1.0;
1837 ptf[0].Y = 0.0;
1838 ptf[1].X = 0.0;
1839 ptf[1].Y = 1.0;
1840 status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
1841 expect(Ok, status);
1842 expectf(18.0, ptf[0].X);
1843 expectf(15.0, ptf[0].Y);
1844 expectf(15.0, ptf[1].X);
1845 expectf(18.0, ptf[1].Y);
1846
1847 ptf[0].X = 1.0;
1848 ptf[0].Y = 0.0;
1849 ptf[1].X = 0.0;
1850 ptf[1].Y = 1.0;
1851 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 2);
1852 expect(Ok, status);
1853 expectf(6.0, ptf[0].X);
1854 expectf(5.0, ptf[0].Y);
1855 expectf(5.0, ptf[1].X);
1856 expectf(6.0, ptf[1].Y);
1857
1858 ptf[0].X = 1.0;
1859 ptf[0].Y = 0.0;
1860 ptf[1].X = 0.0;
1861 ptf[1].Y = 1.0;
1862 status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpacePage, ptf, 2);
1863 expect(Ok, status);
1864 expectf(3.0, ptf[0].X);
1865 expectf(0.0, ptf[0].Y);
1866 expectf(0.0, ptf[1].X);
1867 expectf(3.0, ptf[1].Y);
1868
1869 ptf[0].X = 18.0;
1870 ptf[0].Y = 15.0;
1871 ptf[1].X = 15.0;
1872 ptf[1].Y = 18.0;
1873 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
1874 expect(Ok, status);
1875 expectf(1.0, ptf[0].X);
1876 expectf(0.0, ptf[0].Y);
1877 expectf(0.0, ptf[1].X);
1878 expectf(1.0, ptf[1].Y);
1879
1880 ptf[0].X = 6.0;
1881 ptf[0].Y = 5.0;
1882 ptf[1].X = 5.0;
1883 ptf[1].Y = 6.0;
1884 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpacePage, ptf, 2);
1885 expect(Ok, status);
1886 expectf(1.0, ptf[0].X);
1887 expectf(0.0, ptf[0].Y);
1888 expectf(0.0, ptf[1].X);
1889 expectf(1.0, ptf[1].Y);
1890
1891 ptf[0].X = 3.0;
1892 ptf[0].Y = 0.0;
1893 ptf[1].X = 0.0;
1894 ptf[1].Y = 3.0;
1895 status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceDevice, ptf, 2);
1896 expect(Ok, status);
1897 expectf(1.0, ptf[0].X);
1898 expectf(0.0, ptf[0].Y);
1899 expectf(0.0, ptf[1].X);
1900 expectf(1.0, ptf[1].Y);
1901
1902 pt[0].X = 1;
1903 pt[0].Y = 0;
1904 pt[1].X = 0;
1905 pt[1].Y = 1;
1906 status = GdipTransformPointsI(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, pt, 2);
1907 expect(Ok, status);
1908 expect(18, pt[0].X);
1909 expect(15, pt[0].Y);
1910 expect(15, pt[1].X);
1911 expect(18, pt[1].Y);
1912
1913 GdipDeleteGraphics(graphics);
1914 ReleaseDC(hwnd, hdc);
1915 }
1916
1917 static void test_get_set_clip(void)
1918 {
1919 GpStatus status;
1920 GpGraphics *graphics = NULL;
1921 HDC hdc = GetDC( hwnd );
1922 GpRegion *clip;
1923 GpRectF rect;
1924 BOOL res;
1925
1926 status = GdipCreateFromHDC(hdc, &graphics);
1927 expect(Ok, status);
1928
1929 rect.X = rect.Y = 0.0;
1930 rect.Height = rect.Width = 100.0;
1931
1932 status = GdipCreateRegionRect(&rect, &clip);
1933 expect(Ok, status);
1934
1935 /* NULL arguments */
1936 status = GdipGetClip(NULL, NULL);
1937 expect(InvalidParameter, status);
1938 status = GdipGetClip(graphics, NULL);
1939 expect(InvalidParameter, status);
1940 status = GdipGetClip(NULL, clip);
1941 expect(InvalidParameter, status);
1942
1943 status = GdipSetClipRegion(NULL, NULL, CombineModeReplace);
1944 expect(InvalidParameter, status);
1945 status = GdipSetClipRegion(graphics, NULL, CombineModeReplace);
1946 expect(InvalidParameter, status);
1947
1948 status = GdipSetClipPath(NULL, NULL, CombineModeReplace);
1949 expect(InvalidParameter, status);
1950 status = GdipSetClipPath(graphics, NULL, CombineModeReplace);
1951 expect(InvalidParameter, status);
1952
1953 res = FALSE;
1954 status = GdipGetClip(graphics, clip);
1955 expect(Ok, status);
1956 status = GdipIsInfiniteRegion(clip, graphics, &res);
1957 expect(Ok, status);
1958 expect(TRUE, res);
1959
1960 /* remains infinite after reset */
1961 res = FALSE;
1962 status = GdipResetClip(graphics);
1963 expect(Ok, status);
1964 status = GdipGetClip(graphics, clip);
1965 expect(Ok, status);
1966 status = GdipIsInfiniteRegion(clip, graphics, &res);
1967 expect(Ok, status);
1968 expect(TRUE, res);
1969
1970 /* set to empty and then reset to infinite */
1971 status = GdipSetEmpty(clip);
1972 expect(Ok, status);
1973 status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1974 expect(Ok, status);
1975
1976 status = GdipGetClip(graphics, clip);
1977 expect(Ok, status);
1978 res = FALSE;
1979 status = GdipIsEmptyRegion(clip, graphics, &res);
1980 expect(Ok, status);
1981 expect(TRUE, res);
1982 status = GdipResetClip(graphics);
1983 expect(Ok, status);
1984 status = GdipGetClip(graphics, clip);
1985 expect(Ok, status);
1986 res = FALSE;
1987 status = GdipIsInfiniteRegion(clip, graphics, &res);
1988 expect(Ok, status);
1989 expect(TRUE, res);
1990
1991 GdipDeleteRegion(clip);
1992
1993 GdipDeleteGraphics(graphics);
1994 ReleaseDC(hwnd, hdc);
1995 }
1996
1997 static void test_isempty(void)
1998 {
1999 GpStatus status;
2000 GpGraphics *graphics = NULL;
2001 HDC hdc = GetDC( hwnd );
2002 GpRegion *clip;
2003 BOOL res;
2004
2005 status = GdipCreateFromHDC(hdc, &graphics);
2006 expect(Ok, status);
2007
2008 status = GdipCreateRegion(&clip);
2009 expect(Ok, status);
2010
2011 /* NULL */
2012 status = GdipIsClipEmpty(NULL, NULL);
2013 expect(InvalidParameter, status);
2014 status = GdipIsClipEmpty(graphics, NULL);
2015 expect(InvalidParameter, status);
2016 status = GdipIsClipEmpty(NULL, &res);
2017 expect(InvalidParameter, status);
2018
2019 /* default is infinite */
2020 res = TRUE;
2021 status = GdipIsClipEmpty(graphics, &res);
2022 expect(Ok, status);
2023 expect(FALSE, res);
2024
2025 GdipDeleteRegion(clip);
2026
2027 GdipDeleteGraphics(graphics);
2028 ReleaseDC(hwnd, hdc);
2029 }
2030
2031 static void test_clear(void)
2032 {
2033 GpStatus status;
2034
2035 status = GdipGraphicsClear(NULL, 0xdeadbeef);
2036 expect(InvalidParameter, status);
2037 }
2038
2039 static void test_textcontrast(void)
2040 {
2041 GpStatus status;
2042 HDC hdc = GetDC( hwnd );
2043 GpGraphics *graphics;
2044 UINT contrast;
2045
2046 status = GdipGetTextContrast(NULL, NULL);
2047 expect(InvalidParameter, status);
2048
2049 status = GdipCreateFromHDC(hdc, &graphics);
2050 expect(Ok, status);
2051
2052 status = GdipGetTextContrast(graphics, NULL);
2053 expect(InvalidParameter, status);
2054 status = GdipGetTextContrast(graphics, &contrast);
2055 expect(Ok, status);
2056 expect(4, contrast);
2057
2058 GdipDeleteGraphics(graphics);
2059 ReleaseDC(hwnd, hdc);
2060 }
2061
2062 static void test_GdipDrawString(void)
2063 {
2064 GpStatus status;
2065 GpGraphics *graphics = NULL;
2066 GpFont *fnt = NULL;
2067 RectF rect;
2068 GpStringFormat *format;
2069 GpBrush *brush;
2070 LOGFONTA logfont;
2071 HDC hdc = GetDC( hwnd );
2072 static const WCHAR string[] = {'T','e','s','t',0};
2073 static const PointF positions[4] = {{0,0}, {1,1}, {2,2}, {3,3}};
2074 GpMatrix *matrix;
2075
2076 memset(&logfont,0,sizeof(logfont));
2077 strcpy(logfont.lfFaceName,"Arial");
2078 logfont.lfHeight = 12;
2079 logfont.lfCharSet = DEFAULT_CHARSET;
2080
2081 status = GdipCreateFromHDC(hdc, &graphics);
2082 expect(Ok, status);
2083
2084 status = GdipCreateFontFromLogfontA(hdc, &logfont, &fnt);
2085 if (status == NotTrueTypeFont || status == FileNotFound)
2086 {
2087 skip("Arial not installed.\n");
2088 return;
2089 }
2090 expect(Ok, status);
2091
2092 status = GdipCreateSolidFill((ARGB)0xdeadbeef, (GpSolidFill**)&brush);
2093 expect(Ok, status);
2094
2095 status = GdipCreateStringFormat(0,0,&format);
2096 expect(Ok, status);
2097
2098 rect.X = 0;
2099 rect.Y = 0;
2100 rect.Width = 0;
2101 rect.Height = 12;
2102
2103 status = GdipDrawString(graphics, string, 4, fnt, &rect, format, brush);
2104 expect(Ok, status);
2105
2106 status = GdipCreateMatrix(&matrix);
2107 expect(Ok, status);
2108
2109 status = GdipDrawDriverString(NULL, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2110 expect(InvalidParameter, status);
2111
2112 status = GdipDrawDriverString(graphics, NULL, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2113 expect(InvalidParameter, status);
2114
2115 status = GdipDrawDriverString(graphics, string, 4, NULL, brush, positions, DriverStringOptionsCmapLookup, matrix);
2116 expect(InvalidParameter, status);
2117
2118 status = GdipDrawDriverString(graphics, string, 4, fnt, NULL, positions, DriverStringOptionsCmapLookup, matrix);
2119 expect(InvalidParameter, status);
2120
2121 status = GdipDrawDriverString(graphics, string, 4, fnt, brush, NULL, DriverStringOptionsCmapLookup, matrix);
2122 expect(InvalidParameter, status);
2123
2124 status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup|0x10, matrix);
2125 expect(Ok, status);
2126
2127 status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, NULL);
2128 expect(Ok, status);
2129
2130 status = GdipDrawDriverString(graphics, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2131 expect(Ok, status);
2132
2133 GdipDeleteMatrix(matrix);
2134 GdipDeleteGraphics(graphics);
2135 GdipDeleteBrush(brush);
2136 GdipDeleteFont(fnt);
2137 GdipDeleteStringFormat(format);
2138
2139 ReleaseDC(hwnd, hdc);
2140 }
2141
2142 static void test_GdipGetVisibleClipBounds_screen(void)
2143 {
2144 GpStatus status;
2145 GpGraphics *graphics = NULL;
2146 HDC hdc = GetDC(0);
2147 GpRectF rectf, exp, clipr;
2148 GpRect recti;
2149
2150 ok(hdc != NULL, "Expected HDC to be initialized\n");
2151
2152 status = GdipCreateFromHDC(hdc, &graphics);
2153 expect(Ok, status);
2154 ok(graphics != NULL, "Expected graphics to be initialized\n");
2155
2156 /* no clipping rect */
2157 exp.X = 0;
2158 exp.Y = 0;
2159 exp.Width = GetDeviceCaps(hdc, HORZRES);
2160 exp.Height = GetDeviceCaps(hdc, VERTRES);
2161
2162 status = GdipGetVisibleClipBounds(graphics, &rectf);
2163 expect(Ok, status);
2164 ok(rectf.X == exp.X &&
2165 rectf.Y == exp.Y &&
2166 rectf.Width == exp.Width &&
2167 rectf.Height == exp.Height,
2168 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2169 "the screen (%0.f, %0.f, %0.f, %0.f)\n",
2170 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2171 exp.X, exp.Y, exp.Width, exp.Height);
2172
2173 /* clipping rect entirely within window */
2174 exp.X = clipr.X = 10;
2175 exp.Y = clipr.Y = 12;
2176 exp.Width = clipr.Width = 14;
2177 exp.Height = clipr.Height = 16;
2178
2179 status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2180 expect(Ok, status);
2181
2182 status = GdipGetVisibleClipBounds(graphics, &rectf);
2183 expect(Ok, status);
2184 ok(rectf.X == exp.X &&
2185 rectf.Y == exp.Y &&
2186 rectf.Width == exp.Width &&
2187 rectf.Height == exp.Height,
2188 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2189 "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2190 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2191 exp.X, exp.Y, exp.Width, exp.Height);
2192
2193 /* clipping rect partially outside of screen */
2194 clipr.X = -10;
2195 clipr.Y = -12;
2196 clipr.Width = 20;
2197 clipr.Height = 24;
2198
2199 status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2200 expect(Ok, status);
2201
2202 exp.X = 0;
2203 exp.Y = 0;
2204 exp.Width = 10;
2205 exp.Height = 12;
2206
2207 status = GdipGetVisibleClipBounds(graphics, &rectf);
2208 expect(Ok, status);
2209 ok(rectf.X == exp.X &&
2210 rectf.Y == exp.Y &&
2211 rectf.Width == exp.Width &&
2212 rectf.Height == exp.Height,
2213 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2214 "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2215 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2216 exp.X, exp.Y, exp.Width, exp.Height);
2217
2218 status = GdipGetVisibleClipBoundsI(graphics, &recti);
2219 expect(Ok, status);
2220 ok(recti.X == exp.X &&
2221 recti.Y == exp.Y &&
2222 recti.Width == exp.Width &&
2223 recti.Height == exp.Height,
2224 "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2225 "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2226 recti.X, recti.Y, recti.Width, recti.Height,
2227 exp.X, exp.Y, exp.Width, exp.Height);
2228
2229 GdipDeleteGraphics(graphics);
2230 ReleaseDC(0, hdc);
2231 }
2232
2233 static void test_GdipGetVisibleClipBounds_window(void)
2234 {
2235 GpStatus status;
2236 GpGraphics *graphics = NULL;
2237 GpRectF rectf, window, exp, clipr;
2238 GpRect recti;
2239 HDC hdc;
2240 PAINTSTRUCT ps;
2241 RECT wnd_rect;
2242
2243 /* get client area size */
2244 ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n");
2245 window.X = wnd_rect.left;
2246 window.Y = wnd_rect.top;
2247 window.Width = wnd_rect.right - wnd_rect.left;
2248 window.Height = wnd_rect.bottom - wnd_rect.top;
2249
2250 hdc = BeginPaint(hwnd, &ps);
2251
2252 status = GdipCreateFromHDC(hdc, &graphics);
2253 expect(Ok, status);
2254 ok(graphics != NULL, "Expected graphics to be initialized\n");
2255
2256 status = GdipGetVisibleClipBounds(graphics, &rectf);
2257 expect(Ok, status);
2258 ok(rectf.X == window.X &&
2259 rectf.Y == window.Y &&
2260 rectf.Width == window.Width &&
2261 rectf.Height == window.Height,
2262 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2263 "the window (%0.f, %0.f, %0.f, %0.f)\n",
2264 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2265 window.X, window.Y, window.Width, window.Height);
2266
2267 /* clipping rect entirely within window */
2268 exp.X = clipr.X = 20;
2269 exp.Y = clipr.Y = 8;
2270 exp.Width = clipr.Width = 30;
2271 exp.Height = clipr.Height = 20;
2272
2273 status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2274 expect(Ok, status);
2275
2276 status = GdipGetVisibleClipBounds(graphics, &rectf);
2277 expect(Ok, status);
2278 ok(rectf.X == exp.X &&
2279 rectf.Y == exp.Y &&
2280 rectf.Width == exp.Width &&
2281 rectf.Height == exp.Height,
2282 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2283 "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2284 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2285 exp.X, exp.Y, exp.Width, exp.Height);
2286
2287 /* clipping rect partially outside of window */
2288 clipr.X = window.Width - 10;
2289 clipr.Y = window.Height - 15;
2290 clipr.Width = 20;
2291 clipr.Height = 30;
2292
2293 status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
2294 expect(Ok, status);
2295
2296 exp.X = window.Width - 10;
2297 exp.Y = window.Height - 15;
2298 exp.Width = 10;
2299 exp.Height = 15;
2300
2301 status = GdipGetVisibleClipBounds(graphics, &rectf);
2302 expect(Ok, status);
2303 ok(rectf.X == exp.X &&
2304 rectf.Y == exp.Y &&
2305 rectf.Width == exp.Width &&
2306 rectf.Height == exp.Height,
2307 "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
2308 "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2309 rectf.X, rectf.Y, rectf.Width, rectf.Height,
2310 exp.X, exp.Y, exp.Width, exp.Height);
2311
2312 status = GdipGetVisibleClipBoundsI(graphics, &recti);
2313 expect(Ok, status);
2314 ok(recti.X == exp.X &&
2315 recti.Y == exp.Y &&
2316 recti.Width == exp.Width &&
2317 recti.Height == exp.Height,
2318 "Expected clip bounds (%d, %d, %d, %d) to be the size of "
2319 "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
2320 recti.X, recti.Y, recti.Width, recti.Height,
2321 exp.X, exp.Y, exp.Width, exp.Height);
2322
2323 GdipDeleteGraphics(graphics);
2324 EndPaint(hwnd, &ps);
2325 }
2326
2327 static void test_GdipGetVisibleClipBounds(void)
2328 {
2329 GpGraphics* graphics = NULL;
2330 GpRectF rectf;
2331 GpRect rect;
2332 HDC hdc = GetDC( hwnd );
2333 GpStatus status;
2334
2335 status = GdipCreateFromHDC(hdc, &graphics);
2336 expect(Ok, status);
2337 ok(graphics != NULL, "Expected graphics to be initialized\n");
2338
2339 /* test null parameters */
2340 status = GdipGetVisibleClipBounds(graphics, NULL);
2341 expect(InvalidParameter, status);
2342
2343 status = GdipGetVisibleClipBounds(NULL, &rectf);
2344 expect(InvalidParameter, status);
2345
2346 status = GdipGetVisibleClipBoundsI(graphics, NULL);
2347 expect(InvalidParameter, status);
2348
2349 status = GdipGetVisibleClipBoundsI(NULL, &rect);
2350 expect(InvalidParameter, status);
2351
2352 GdipDeleteGraphics(graphics);
2353 ReleaseDC(hwnd, hdc);
2354
2355 test_GdipGetVisibleClipBounds_screen();
2356 test_GdipGetVisibleClipBounds_window();
2357 }
2358
2359 static void test_fromMemoryBitmap(void)
2360 {
2361 GpStatus status;
2362 GpGraphics *graphics = NULL;
2363 GpBitmap *bitmap = NULL;
2364 BYTE bits[48] = {0};
2365 HDC hdc=NULL;
2366 COLORREF color;
2367
2368 status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, bits, &bitmap);
2369 expect(Ok, status);
2370
2371 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2372 expect(Ok, status);
2373
2374 status = GdipGraphicsClear(graphics, 0xff686868);
2375 expect(Ok, status);
2376
2377 GdipDeleteGraphics(graphics);
2378
2379 /* drawing writes to the memory provided */
2380 expect(0x68, bits[10]);
2381
2382 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2383 expect(Ok, status);
2384
2385 status = GdipGetDC(graphics, &hdc);
2386 expect(Ok, status);
2387 ok(hdc != NULL, "got NULL hdc\n");
2388
2389 color = GetPixel(hdc, 0, 0);
2390 /* The HDC is write-only, and native fills with a solid color to figure out
2391 * which pixels have changed. */
2392 todo_wine expect(0x0c0b0d, color);
2393
2394 SetPixel(hdc, 0, 0, 0x797979);
2395 SetPixel(hdc, 1, 0, 0x0c0b0d);
2396
2397 status = GdipReleaseDC(graphics, hdc);
2398 expect(Ok, status);
2399
2400 GdipDeleteGraphics(graphics);
2401
2402 expect(0x79, bits[0]);
2403 todo_wine expect(0x68, bits[3]);
2404
2405 GdipDisposeImage((GpImage*)bitmap);
2406
2407 /* We get the same kind of write-only HDC for a "normal" bitmap */
2408 status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, NULL, &bitmap);
2409 expect(Ok, status);
2410
2411 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2412 expect(Ok, status);
2413
2414 status = GdipGetDC(graphics, &hdc);
2415 expect(Ok, status);
2416 ok(hdc != NULL, "got NULL hdc\n");
2417
2418 color = GetPixel(hdc, 0, 0);
2419 todo_wine expect(0x0c0b0d, color);
2420
2421 status = GdipReleaseDC(graphics, hdc);
2422 expect(Ok, status);
2423
2424 GdipDeleteGraphics(graphics);
2425
2426 GdipDisposeImage((GpImage*)bitmap);
2427 }
2428
2429 static void test_GdipIsVisiblePoint(void)
2430 {
2431 GpStatus status;
2432 GpGraphics *graphics = NULL;
2433 HDC hdc = GetDC( hwnd );
2434 REAL x, y;
2435 BOOL val;
2436
2437 ok(hdc != NULL, "Expected HDC to be initialized\n");
2438
2439 status = GdipCreateFromHDC(hdc, &graphics);
2440 expect(Ok, status);
2441 ok(graphics != NULL, "Expected graphics to be initialized\n");
2442
2443 /* null parameters */
2444 status = GdipIsVisiblePoint(NULL, 0, 0, &val);
2445 expect(InvalidParameter, status);
2446
2447 status = GdipIsVisiblePoint(graphics, 0, 0, NULL);
2448 expect(InvalidParameter, status);
2449
2450 status = GdipIsVisiblePointI(NULL, 0, 0, &val);
2451 expect(InvalidParameter, status);
2452
2453 status = GdipIsVisiblePointI(graphics, 0, 0, NULL);
2454 expect(InvalidParameter, status);
2455
2456 x = 0;
2457 y = 0;
2458 status = GdipIsVisiblePoint(graphics, x, y, &val);
2459 expect(Ok, status);
2460 ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2461
2462 x = -10;
2463 y = 0;
2464 status = GdipIsVisiblePoint(graphics, x, y, &val);
2465 expect(Ok, status);
2466 ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2467
2468 x = 0;
2469 y = -5;
2470 status = GdipIsVisiblePoint(graphics, x, y, &val);
2471 expect(Ok, status);
2472 ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2473
2474 x = 1;
2475 y = 1;
2476 status = GdipIsVisiblePoint(graphics, x, y, &val);
2477 expect(Ok, status);
2478 ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2479
2480 status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2481 expect(Ok, status);
2482
2483 x = 1;
2484 y = 1;
2485 status = GdipIsVisiblePoint(graphics, x, y, &val);
2486 expect(Ok, status);
2487 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2488
2489 x = 15.5;
2490 y = 40.5;
2491 status = GdipIsVisiblePoint(graphics, x, y, &val);
2492 expect(Ok, status);
2493 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2494
2495 /* translate into the center of the rect */
2496 GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2497
2498 x = 0;
2499 y = 0;
2500 status = GdipIsVisiblePoint(graphics, x, y, &val);
2501 expect(Ok, status);
2502 ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
2503
2504 x = 25;
2505 y = 40;
2506 status = GdipIsVisiblePoint(graphics, x, y, &val);
2507 expect(Ok, status);
2508 ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
2509
2510 GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2511
2512 /* corner cases */
2513 x = 9;
2514 y = 19;
2515 status = GdipIsVisiblePoint(graphics, x, y, &val);
2516 expect(Ok, status);
2517 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2518
2519 x = 9.25;
2520 y = 19.25;
2521 status = GdipIsVisiblePoint(graphics, x, y, &val);
2522 expect(Ok, status);
2523 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2524
2525 x = 9.5;
2526 y = 19.5;
2527 status = GdipIsVisiblePoint(graphics, x, y, &val);
2528 expect(Ok, status);
2529 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2530
2531 x = 9.75;
2532 y = 19.75;
2533 status = GdipIsVisiblePoint(graphics, x, y, &val);
2534 expect(Ok, status);
2535 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2536
2537 x = 10;
2538 y = 20;
2539 status = GdipIsVisiblePoint(graphics, x, y, &val);
2540 expect(Ok, status);
2541 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2542
2543 x = 40;
2544 y = 20;
2545 status = GdipIsVisiblePoint(graphics, x, y, &val);
2546 expect(Ok, status);
2547 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2548
2549 x = 39;
2550 y = 59;
2551 status = GdipIsVisiblePoint(graphics, x, y, &val);
2552 expect(Ok, status);
2553 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2554
2555 x = 39.25;
2556 y = 59.25;
2557 status = GdipIsVisiblePoint(graphics, x, y, &val);
2558 expect(Ok, status);
2559 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2560
2561 x = 39.5;
2562 y = 39.5;
2563 status = GdipIsVisiblePoint(graphics, x, y, &val);
2564 expect(Ok, status);
2565 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2566
2567 x = 39.75;
2568 y = 59.75;
2569 status = GdipIsVisiblePoint(graphics, x, y, &val);
2570 expect(Ok, status);
2571 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2572
2573 x = 40;
2574 y = 60;
2575 status = GdipIsVisiblePoint(graphics, x, y, &val);
2576 expect(Ok, status);
2577 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2578
2579 x = 40.15;
2580 y = 60.15;
2581 status = GdipIsVisiblePoint(graphics, x, y, &val);
2582 expect(Ok, status);
2583 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2584
2585 x = 10;
2586 y = 60;
2587 status = GdipIsVisiblePoint(graphics, x, y, &val);
2588 expect(Ok, status);
2589 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2590
2591 /* integer version */
2592 x = 25;
2593 y = 30;
2594 status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2595 expect(Ok, status);
2596 ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
2597
2598 x = 50;
2599 y = 100;
2600 status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
2601 expect(Ok, status);
2602 ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
2603
2604 GdipDeleteGraphics(graphics);
2605 ReleaseDC(hwnd, hdc);
2606 }
2607
2608 static void test_GdipIsVisibleRect(void)
2609 {
2610 GpStatus status;
2611 GpGraphics *graphics = NULL;
2612 HDC hdc = GetDC( hwnd );
2613 REAL x, y, width, height;
2614 BOOL val;
2615
2616 ok(hdc != NULL, "Expected HDC to be initialized\n");
2617
2618 status = GdipCreateFromHDC(hdc, &graphics);
2619 expect(Ok, status);
2620 ok(graphics != NULL, "Expected graphics to be initialized\n");
2621
2622 status = GdipIsVisibleRect(NULL, 0, 0, 0, 0, &val);
2623 expect(InvalidParameter, status);
2624
2625 status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL);
2626 expect(InvalidParameter, status);
2627
2628 status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val);
2629 expect(InvalidParameter, status);
2630
2631 status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL);
2632 expect(InvalidParameter, status);
2633
2634 /* entirely within the visible region */
2635 x = 0; width = 10;
2636 y = 0; height = 10;
2637 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2638 expect(Ok, status);
2639 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2640
2641 /* partially outside */
2642 x = -10; width = 20;
2643 y = -10; height = 20;
2644 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2645 expect(Ok, status);
2646 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2647
2648 /* entirely outside */
2649 x = -10; width = 5;
2650 y = -10; height = 5;
2651 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2652 expect(Ok, status);
2653 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2654
2655 status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
2656 expect(Ok, status);
2657
2658 /* entirely within the visible region */
2659 x = 12; width = 10;
2660 y = 22; height = 10;
2661 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2662 expect(Ok, status);
2663 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2664
2665 /* partially outside */
2666 x = 35; width = 10;
2667 y = 55; height = 10;
2668 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2669 expect(Ok, status);
2670 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2671
2672 /* entirely outside */
2673 x = 45; width = 5;
2674 y = 65; height = 5;
2675 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2676 expect(Ok, status);
2677 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2678
2679 /* translate into center of clipping rect */
2680 GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
2681
2682 x = 0; width = 10;
2683 y = 0; height = 10;
2684 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2685 expect(Ok, status);
2686 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2687
2688 x = 25; width = 5;
2689 y = 40; height = 5;
2690 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2691 expect(Ok, status);
2692 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2693
2694 GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
2695
2696 /* corners entirely outside, but some intersections */
2697 x = 0; width = 70;
2698 y = 0; height = 90;
2699 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2700 expect(Ok, status);
2701 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2702
2703 x = 0; width = 70;
2704 y = 0; height = 30;
2705 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2706 expect(Ok, status);
2707 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2708
2709 x = 0; width = 30;
2710 y = 0; height = 90;
2711 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2712 expect(Ok, status);
2713 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2714
2715 /* edge cases */
2716 x = 0; width = 10;
2717 y = 20; height = 40;
2718 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2719 expect(Ok, status);
2720 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2721
2722 x = 10; width = 30;
2723 y = 0; height = 20;
2724 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2725 expect(Ok, status);
2726 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2727
2728 x = 40; width = 10;
2729 y = 20; height = 40;
2730 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2731 expect(Ok, status);
2732 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2733
2734 x = 10; width = 30;
2735 y = 60; height = 10;
2736 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2737 expect(Ok, status);
2738 ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
2739
2740 /* rounding tests */
2741 x = 0.4; width = 10.4;
2742 y = 20; height = 40;
2743 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2744 expect(Ok, status);
2745 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2746
2747 x = 10; width = 30;
2748 y = 0.4; height = 20.4;
2749 status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
2750 expect(Ok, status);
2751 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2752
2753 /* integer version */
2754 x = 0; width = 30;
2755 y = 0; height = 90;
2756 status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2757 expect(Ok, status);
2758 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2759
2760 x = 12; width = 10;
2761 y = 22; height = 10;
2762 status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
2763 expect(Ok, status);
2764 ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
2765
2766 GdipDeleteGraphics(graphics);
2767 ReleaseDC(hwnd, hdc);
2768 }
2769
2770 static void test_GdipGetNearestColor(void)
2771 {
2772 GpStatus status;
2773 GpGraphics *graphics;
2774 GpBitmap *bitmap;
2775 ARGB color = 0xdeadbeef;
2776 HDC hdc = GetDC( hwnd );
2777
2778 /* create a graphics object */
2779 ok(hdc != NULL, "Expected HDC to be initialized\n");
2780
2781 status = GdipCreateFromHDC(hdc, &graphics);
2782 expect(Ok, status);
2783 ok(graphics != NULL, "Expected graphics to be initialized\n");
2784
2785 status = GdipGetNearestColor(graphics, NULL);
2786 expect(InvalidParameter, status);
2787
2788 status = GdipGetNearestColor(NULL, &color);
2789 expect(InvalidParameter, status);
2790 GdipDeleteGraphics(graphics);
2791
2792 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, &bitmap);
2793 expect(Ok, status);
2794 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2795 ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2796 if (status == Ok)
2797 {
2798 status = GdipGetNearestColor(graphics, &color);
2799 expect(Ok, status);
2800 expect(0xdeadbeef, color);
2801 GdipDeleteGraphics(graphics);
2802 }
2803 GdipDisposeImage((GpImage*)bitmap);
2804
2805 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, &bitmap);
2806 expect(Ok, status);
2807 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2808 ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2809 if (status == Ok)
2810 {
2811 status = GdipGetNearestColor(graphics, &color);
2812 expect(Ok, status);
2813 expect(0xdeadbeef, color);
2814 GdipDeleteGraphics(graphics);
2815 }
2816 GdipDisposeImage((GpImage*)bitmap);
2817
2818 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, &bitmap);
2819 expect(Ok, status);
2820 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2821 ok(broken(status == OutOfMemory) /* winver < Win7 */ || status == Ok, "status=%u\n", status);
2822 if (status == Ok)
2823 {
2824 status = GdipGetNearestColor(graphics, &color);
2825 expect(Ok, status);
2826 expect(0xdeadbeef, color);
2827 GdipDeleteGraphics(graphics);
2828 }
2829 GdipDisposeImage((GpImage*)bitmap);
2830
2831 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, &bitmap);
2832 expect(Ok, status);
2833 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2834 todo_wine expect(OutOfMemory, status);
2835 if (status == Ok)
2836 GdipDeleteGraphics(graphics);
2837 GdipDisposeImage((GpImage*)bitmap);
2838
2839 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bitmap);
2840 expect(Ok, status);
2841 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2842 expect(Ok, status);
2843 status = GdipGetNearestColor(graphics, &color);
2844 expect(Ok, status);
2845 expect(0xdeadbeef, color);
2846 GdipDeleteGraphics(graphics);
2847 GdipDisposeImage((GpImage*)bitmap);
2848
2849 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, &bitmap);
2850 expect(Ok, status);
2851 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2852 expect(Ok, status);
2853 status = GdipGetNearestColor(graphics, &color);
2854 expect(Ok, status);
2855 expect(0xdeadbeef, color);
2856 GdipDeleteGraphics(graphics);
2857 GdipDisposeImage((GpImage*)bitmap);
2858
2859 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, &bitmap);
2860 expect(Ok, status);
2861 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2862 expect(Ok, status);
2863 status = GdipGetNearestColor(graphics, &color);
2864 expect(Ok, status);
2865 expect(0xdeadbeef, color);
2866 GdipDeleteGraphics(graphics);
2867 GdipDisposeImage((GpImage*)bitmap);
2868
2869 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, &bitmap);
2870 expect(Ok, status);
2871 if (status == Ok)
2872 {
2873 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2874 expect(Ok, status);
2875 status = GdipGetNearestColor(graphics, &color);
2876 expect(Ok, status);
2877 expect(0xdeadbeef, color);
2878 GdipDeleteGraphics(graphics);
2879 GdipDisposeImage((GpImage*)bitmap);
2880 }
2881
2882 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, &bitmap);
2883 expect(Ok, status);
2884 if (status == Ok)
2885 {
2886 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2887 expect(Ok, status);
2888 status = GdipGetNearestColor(graphics, &color);
2889 expect(Ok, status);
2890 expect(0xdeadbeef, color);
2891 GdipDeleteGraphics(graphics);
2892 GdipDisposeImage((GpImage*)bitmap);
2893 }
2894
2895 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, &bitmap);
2896 expect(Ok, status);
2897 if (status == Ok)
2898 {
2899 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2900 expect(Ok, status);
2901 status = GdipGetNearestColor(graphics, &color);
2902 expect(Ok, status);
2903 expect(0xdeadbeef, color);
2904 GdipDeleteGraphics(graphics);
2905 GdipDisposeImage((GpImage*)bitmap);
2906 }
2907
2908 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, &bitmap);
2909 expect(Ok, status);
2910 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2911 expect(Ok, status);
2912 status = GdipGetNearestColor(graphics, &color);
2913 expect(Ok, status);
2914 todo_wine expect(0xffa8bce8, color);
2915 GdipDeleteGraphics(graphics);
2916 GdipDisposeImage((GpImage*)bitmap);
2917
2918 status = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, &bitmap);
2919 expect(Ok, status);
2920 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
2921 expect(Ok, status);
2922 status = GdipGetNearestColor(graphics, &color);
2923 expect(Ok, status);
2924 todo_wine
2925 ok(color == 0xffa8b8e8 ||
2926 broken(color == 0xffa0b8e0), /* Win98/WinMe */
2927 "Expected ffa8b8e8, got %.8x\n", color);
2928 GdipDeleteGraphics(graphics);
2929 GdipDisposeImage((GpImage*)bitmap);
2930
2931 ReleaseDC(hwnd, hdc);
2932 }
2933
2934 #if CORE_6659_IS_FIXED
2935 static void test_string_functions(void)
2936 {
2937 GpStatus status;
2938 GpGraphics *graphics;
2939 GpFontFamily *family;
2940 GpFont *font;
2941 RectF rc, char_bounds, bounds;
2942 GpBrush *brush;
2943 ARGB color = 0xff000000;
2944 HDC hdc = GetDC( hwnd );
2945 const WCHAR fontname[] = {'T','a','h','o','m','a',0};
2946 const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
2947 const WCHAR teststring2[] = {'j',0};
2948 REAL char_width, char_height;
2949 INT codepointsfitted, linesfilled;
2950 GpStringFormat *format;
2951 CharacterRange ranges[3] = {{0, 1}, {1, 3}, {5, 1}};
2952 GpRegion *regions[4];
2953 BOOL region_isempty[4];
2954 int i;
2955 PointF positions[8];
2956 GpMatrix *identity;
2957
2958 ok(hdc != NULL, "Expected HDC to be initialized\n");
2959 status = GdipCreateFromHDC(hdc, &graphics);
2960 expect(Ok, status);
2961 ok(graphics != NULL, "Expected graphics to be initialized\n");
2962
2963 status = GdipCreateFontFamilyFromName(fontname, NULL, &family);
2964 expect(Ok, status);
2965
2966 status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font);
2967 expect(Ok, status);
2968
2969 status = GdipCreateSolidFill(color, (GpSolidFill**)&brush);
2970 expect(Ok, status);
2971
2972 status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
2973 expect(Ok, status);
2974
2975 rc.X = 0;
2976 rc.Y = 0;
2977 rc.Width = 100.0;
2978 rc.Height = 100.0;
2979
2980 status = GdipDrawString(NULL, teststring, 6, font, &rc, NULL, brush);
2981 expect(InvalidParameter, status);
2982
2983 status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush);
2984 expect(InvalidParameter, status);
2985
2986 status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush);
2987 expect(InvalidParameter, status);
2988
2989 status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush);
2990 expect(InvalidParameter, status);
2991
2992 status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL);
2993 expect(InvalidParameter, status);
2994
2995 status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, brush);
2996 expect(Ok, status);
2997
2998 status = GdipMeasureString(NULL, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
2999 expect(InvalidParameter, status);
3000
3001 status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3002 expect(InvalidParameter, status);
3003
3004 status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3005 expect(InvalidParameter, status);
3006
3007 status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled);
3008 expect(InvalidParameter, status);
3009
3010 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled);
3011 expect(InvalidParameter, status);
3012
3013 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, NULL, &linesfilled);
3014 expect(Ok, status);
3015
3016 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, NULL);
3017 expect(Ok, status);
3018
3019 status = GdipMeasureString(graphics, teststring, 1, font, &rc, NULL, &char_bounds, &codepointsfitted, &linesfilled);
3020 expect(Ok, status);
3021 expectf(0.0, char_bounds.X);
3022 expectf(0.0, char_bounds.Y);
3023 ok(char_bounds.Width > 0, "got %0.2f\n", bounds.Width);
3024 ok(char_bounds.Height > 0, "got %0.2f\n", bounds.Height);
3025 expect(1, codepointsfitted);
3026 expect(1, linesfilled);
3027
3028 status = GdipMeasureString(graphics, teststring, 2, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3029 expect(Ok, status);
3030 expectf(0.0, bounds.X);
3031 expectf(0.0, bounds.Y);
3032 ok(bounds.Width > char_bounds.Width, "got %0.2f, expected at least %0.2f\n", bounds.Width, char_bounds.Width);
3033 expectf(char_bounds.Height, bounds.Height);
3034 expect(2, codepointsfitted);
3035 expect(1, linesfilled);
3036 char_width = bounds.Width - char_bounds.Width;
3037
3038 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3039 expect(Ok, status);
3040 expectf(0.0, bounds.X);
3041 expectf(0.0, bounds.Y);
3042 ok(bounds.Width > char_bounds.Width + char_width * 2, "got %0.2f, expected at least %0.2f\n",
3043 bounds.Width, char_bounds.Width + char_width * 2);
3044 ok(bounds.Height > char_bounds.Height, "got %0.2f, expected at least %0.2f\n", bounds.Height, char_bounds.Height);
3045 expect(6, codepointsfitted);
3046 expect(2, linesfilled);
3047 char_height = bounds.Height - char_bounds.Height;
3048
3049 /* Measure the first line. */
3050 status = GdipMeasureString(graphics, teststring, 4, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3051 expect(Ok, status);
3052 expectf(0.0, bounds.X);
3053 expectf(0.0, bounds.Y);
3054 expect(4, codepointsfitted);
3055 expect(1, linesfilled);
3056
3057 /* Give just enough space to fit the first line. */
3058 rc.Width = bounds.Width;
3059 status = GdipMeasureString(graphics, teststring, 5, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3060 expect(Ok, status);
3061 expectf(0.0, bounds.X);
3062 expectf(0.0, bounds.Y);
3063 todo_wine expect(5, codepointsfitted);
3064 todo_wine expect(1, linesfilled);
3065
3066 /* Cut off everything after the first space. */
3067 rc.Width = char_bounds.Width + char_width * 2.1;
3068
3069 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3070 expect(Ok, status);
3071 expectf(0.0, bounds.X);
3072 expectf(0.0, bounds.Y);
3073 expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
3074 expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
3075 expect(6, codepointsfitted);
3076 expect(3, linesfilled);
3077
3078 /* Cut off everything including the first space. */
3079 rc.Width = char_bounds.Width + char_width * 1.7;
3080
3081 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3082 expect(Ok, status);
3083 expectf(0.0, bounds.X);
3084 expectf(0.0, bounds.Y);
3085 expectf_(char_bounds.Width + char_width, bounds.Width, 0.01);
3086 expectf_(char_bounds.Height + char_height * 2, bounds.Height, 0.01);
3087 expect(6, codepointsfitted);
3088 expect(3, linesfilled);
3089
3090 /* Cut off everything after the first character. */
3091 rc.Width = char_bounds.Width + char_width * 0.8;
3092
3093 status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3094 expect(Ok, status);
3095 expectf(0.0, bounds.X);
3096 expectf(0.0, bounds.Y);
3097 expectf_(char_bounds.Width, bounds.Width, 0.01);
3098 expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05);
3099 expect(6, codepointsfitted);
3100 todo_wine expect(4, linesfilled);
3101
3102 for (i = 0; i < 4; i++)
3103 regions[i] = (GpRegion *)0xdeadbeef;
3104
3105 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 0, regions);
3106 expect(Ok, status);
3107
3108 for (i = 0; i < 4; i++)
3109 ok(regions[i] == (GpRegion *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", regions[i]);
3110
3111 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3112 expect(Ok, status);
3113
3114 for (i = 0; i < 4; i++)
3115 ok(regions[i] == (GpRegion *)0xdeadbeef, "expected 0xdeadbeef, got %p\n", regions[i]);
3116
3117 status = GdipSetStringFormatMeasurableCharacterRanges(format, 3, ranges);
3118 expect(Ok, status);
3119
3120 set_rect_empty(&rc);
3121
3122 for (i=0; i<4; i++)
3123 {
3124 status = GdipCreateRegion(&regions[i]);
3125 expect(Ok, status);
3126 status = GdipSetEmpty(regions[i]);
3127 expect(Ok, status);
3128 }
3129
3130 status = GdipMeasureCharacterRanges(NULL, teststring, 6, font, &rc, format, 3, regions);
3131 expect(InvalidParameter, status);
3132
3133 status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
3134 expect(InvalidParameter, status);
3135
3136 status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
3137 expect(InvalidParameter, status);
3138
3139 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
3140 expect(InvalidParameter, status);
3141
3142 if (0)
3143 {
3144 /* Crashes on Windows XP */
3145 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
3146 expect(InvalidParameter, status);
3147 }
3148
3149 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, NULL);
3150 expect(InvalidParameter, status);
3151
3152 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 2, regions);
3153 expect(InvalidParameter, status);
3154
3155 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3156 expect(Ok, status);
3157
3158 for (i = 0; i < 4; i++)
3159 {
3160 status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3161 expect(Ok, status);
3162 }
3163
3164 ok(region_isempty[0], "region should be empty\n");
3165 ok(region_isempty[1], "region should be empty\n");
3166 ok(region_isempty[2], "region should be empty\n");
3167 ok(region_isempty[3], "region should be empty\n");
3168
3169 rc.Width = 100.0;
3170 rc.Height = 100.0;
3171
3172 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 4, regions);
3173 expect(Ok, status);
3174
3175 for (i=0; i<4; i++)
3176 {
3177 status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3178 expect(Ok, status);
3179 }
3180
3181 ok(!region_isempty[0], "region shouldn't be empty\n");
3182 ok(!region_isempty[1], "region shouldn't be empty\n");
3183 ok(!region_isempty[2], "region shouldn't be empty\n");
3184 ok(region_isempty[3], "region should be empty\n");
3185
3186 /* Cut off everything after the first space, and the second line. */
3187 rc.Width = char_bounds.Width + char_width * 2.1;
3188 rc.Height = char_bounds.Height + char_height * 0.5;
3189
3190 status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, format, 3, regions);
3191 expect(Ok, status);
3192
3193 for (i=0; i<4; i++)
3194 {
3195 status = GdipIsEmptyRegion(regions[i], graphics, &region_isempty[i]);
3196 expect(Ok, status);
3197 }
3198
3199 ok(!region_isempty[0], "region shouldn't be empty\n");
3200 ok(!region_isempty[1], "region shouldn't be empty\n");
3201 ok(region_isempty[2], "region should be empty\n");
3202 ok(region_isempty[3], "region should be empty\n");
3203
3204 for (i=0; i<4; i++)
3205 GdipDeleteRegion(regions[i]);
3206
3207 status = GdipCreateMatrix(&identity);
3208 expect(Ok, status);
3209
3210 rc.X = 0;
3211 rc.Y = 0;
3212 rc.Width = 0;
3213 rc.Height = 0;
3214 memset(positions, 0, sizeof(positions));
3215 status = GdipMeasureDriverString(NULL, teststring, 6, font, positions,
3216 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3217 identity, &rc);
3218 expect(InvalidParameter, status);
3219
3220 status = GdipMeasureDriverString(graphics, NULL, 6, font, positions,
3221 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3222 identity, &rc);
3223 expect(InvalidParameter, status);
3224
3225 status = GdipMeasureDriverString(graphics, teststring, 6, NULL, positions,
3226 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3227 identity, &rc);
3228 expect(InvalidParameter, status);
3229
3230 status = GdipMeasureDriverString(graphics, teststring, 6, font, NULL,
3231 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3232 identity, &rc);
3233 expect(InvalidParameter, status);
3234
3235 status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3236 0x100, identity, &rc);
3237 expect(Ok, status);
3238
3239 status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3240 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3241 NULL, &rc);
3242 expect(Ok, status);
3243
3244 status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3245 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3246 identity, NULL);
3247 expect(InvalidParameter, status);
3248
3249 rc.X = 0;
3250 rc.Y = 0;
3251 rc.Width = 0;
3252 rc.Height = 0;
3253 status = GdipMeasureDriverString(graphics, teststring, 6, font, positions,
3254 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3255 identity, &rc);
3256 expect(Ok, status);
3257
3258 expectf(0.0, rc.X);
3259 ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3260 ok(rc.Width > 0.0, "unexpected Width %0.2f\n", rc.Width);
3261 ok(rc.Height > 0.0, "unexpected Y %0.2f\n", rc.Y);
3262
3263 char_width = rc.Width;
3264 char_height = rc.Height;
3265
3266 rc.X = 0;
3267 rc.Y = 0;
3268 rc.Width = 0;
3269 rc.Height = 0;
3270 status = GdipMeasureDriverString(graphics, teststring, 4, font, positions,
3271 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3272 identity, &rc);
3273 expect(Ok, status);
3274
3275 expectf(0.0, rc.X);
3276 ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3277 ok(rc.Width < char_width, "got Width %0.2f, expecting less than %0.2f\n", rc.Width, char_width);
3278 expectf(char_height, rc.Height);
3279
3280 rc.X = 0;
3281 rc.Y = 0;
3282 rc.Width = 0;
3283 rc.Height = 0;
3284 status = GdipMeasureDriverString(graphics, teststring2, 1, font, positions,
3285 DriverStringOptionsCmapLookup|DriverStringOptionsRealizedAdvance,
3286 identity, &rc);
3287 expect(Ok, status);
3288
3289 expectf(rc.X, 0.0);
3290 ok(rc.Y < 0.0, "unexpected Y %0.2f\n", rc.Y);
3291 ok(rc.Width > 0, "unexpected Width %0.2f\n", rc.Width);
3292 expectf(rc.Height, char_height);
3293
3294 GdipDeleteMatrix(identity);
3295 GdipDeleteStringFormat(format);
3296 GdipDeleteBrush(brush);
3297 GdipDeleteFont(font);
3298 GdipDeleteFontFamily(family);
3299 GdipDeleteGraphics(graphics);
3300
3301 ReleaseDC(hwnd, hdc);
3302 }
3303 #endif /* CORE_6659_IS_FIXED */
3304
3305 static void test_get_set_interpolation(void)
3306 {
3307 GpGraphics *graphics;
3308 HDC hdc = GetDC( hwnd );
3309 GpStatus status;
3310 InterpolationMode mode;
3311
3312 ok(hdc != NULL, "Expected HDC to be initialized\n");
3313 status = GdipCreateFromHDC(hdc, &graphics);
3314 expect(Ok, status);
3315 ok(graphics != NULL, "Expected graphics to be initialized\n");
3316
3317 status = GdipGetInterpolationMode(NULL, &mode);
3318 expect(InvalidParameter, status);
3319
3320 if (0)
3321 {
3322 /* Crashes on Windows XP */
3323 status = GdipGetInterpolationMode(graphics, NULL);
3324 expect(InvalidParameter, status);
3325 }
3326
3327 status = GdipSetInterpolationMode(NULL, InterpolationModeNearestNeighbor);
3328 expect(InvalidParameter, status);
3329
3330 /* out of range */
3331 status = GdipSetInterpolationMode(graphics, InterpolationModeHighQualityBicubic+1);
3332 expect(InvalidParameter, status);
3333
3334 status = GdipSetInterpolationMode(graphics, InterpolationModeInvalid);
3335 expect(InvalidParameter, status);
3336
3337 status = GdipGetInterpolationMode(graphics, &mode);
3338 expect(Ok, status);
3339 expect(InterpolationModeBilinear, mode);
3340
3341 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor);
3342 expect(Ok, status);
3343
3344 status = GdipGetInterpolationMode(graphics, &mode);
3345 expect(Ok, status);
3346 expect(InterpolationModeNearestNeighbor, mode);
3347
3348 status = GdipSetInterpolationMode(graphics, InterpolationModeDefault);
3349 expect(Ok, status);
3350
3351 status = GdipGetInterpolationMode(graphics, &mode);
3352 expect(Ok, status);
3353 expect(InterpolationModeBilinear, mode);
3354
3355 status = GdipSetInterpolationMode(graphics, InterpolationModeLowQuality);
3356 expect(Ok, status);
3357
3358 status = GdipGetInterpolationMode(graphics, &mode);
3359 expect(Ok, status);
3360 expect(InterpolationModeBilinear, mode);
3361
3362 status = GdipSetInterpolationMode(graphics, InterpolationModeHighQuality);
3363 expect(Ok, status);
3364
3365 status = GdipGetInterpolationMode(graphics, &mode);
3366 expect(Ok, status);
3367 expect(InterpolationModeHighQualityBicubic, mode);
3368
3369 GdipDeleteGraphics(graphics);
3370
3371 ReleaseDC(hwnd, hdc);
3372 }
3373
3374 static void test_get_set_textrenderinghint(void)
3375 {
3376 GpGraphics *graphics;
3377 HDC hdc = GetDC( hwnd );
3378 GpStatus status;
3379 TextRenderingHint hint;
3380
3381 ok(hdc != NULL, "Expected HDC to be initialized\n");
3382 status = GdipCreateFromHDC(hdc, &graphics);
3383 expect(Ok, status);
3384 ok(graphics != NULL, "Expected graphics to be initialized\n");
3385
3386 status = GdipGetTextRenderingHint(NULL, &hint);
3387 expect(InvalidParameter, status);
3388
3389 status = GdipGetTextRenderingHint(graphics, NULL);
3390 expect(InvalidParameter, status);
3391
3392 status = GdipSetTextRenderingHint(NULL, TextRenderingHintAntiAlias);
3393 expect(InvalidParameter, status);
3394
3395 /* out of range */
3396 status = GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit+1);
3397 expect(InvalidParameter, status);
3398
3399 status = GdipGetTextRenderingHint(graphics, &hint);
3400 expect(Ok, status);
3401 expect(TextRenderingHintSystemDefault, hint);
3402
3403 status = GdipSetTextRenderingHint(graphics, TextRenderingHintSystemDefault);
3404 expect(Ok, status);
3405
3406 status = GdipGetTextRenderingHint(graphics, &hint);
3407 expect(Ok, status);
3408 expect(TextRenderingHintSystemDefault, hint);
3409
3410 status = GdipSetTextRenderingHint(graphics, TextRenderingHintAntiAliasGridFit);
3411 expect(Ok, status);
3412
3413 status = GdipGetTextRenderingHint(graphics, &hint);
3414 expect(Ok, status);
3415 expect(TextRenderingHintAntiAliasGridFit, hint);
3416
3417 GdipDeleteGraphics(graphics);
3418
3419 ReleaseDC(hwnd, hdc);
3420 }
3421
3422 static void test_getdc_scaled(void)
3423 {
3424 GpStatus status;
3425 GpGraphics *graphics = NULL;
3426 GpBitmap *bitmap = NULL;
3427 HDC hdc=NULL;
3428 HBRUSH hbrush, holdbrush;
3429 ARGB color;
3430
3431 status = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, NULL, &bitmap);
3432 expect(Ok, status);
3433
3434 status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
3435 expect(Ok, status);
3436
3437 status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
3438 expect(Ok, status);
3439
3440 status = GdipGetDC(graphics, &hdc);
3441 expect(Ok, status);
3442 ok(hdc != NULL, "got NULL hdc\n");
3443
3444 hbrush = CreateSolidBrush(RGB(255, 0, 0));
3445
3446 holdbrush = SelectObject(hdc, hbrush);
3447
3448 Rectangle(hdc, 2, 2, 6, 6);
3449
3450 SelectObject(hdc, holdbrush);
3451
3452 DeleteObject(hbrush);
3453
3454 status = GdipReleaseDC(graphics, hdc);
3455 expect(Ok, status);
3456
3457 GdipDeleteGraphics(graphics);
3458
3459 status = GdipBitmapGetPixel(bitmap, 3, 3, &color);
3460 expect(Ok, status);
3461 expect(0xffff0000, color);
3462
3463 status = GdipBitmapGetPixel(bitmap, 8, 8, &color);
3464 expect(Ok, status);
3465 expect(0xff000000, color);
3466
3467 GdipDisposeImage((GpImage*)bitmap);
3468 }
3469
3470 static void test_GdipMeasureString(void)
3471 {
3472 static const struct test_data
3473 {
3474 REAL res_x, res_y, page_scale;
3475 GpUnit unit;
3476 } td[] =
3477 {
3478 { 200.0, 200.0, 1.0, UnitPixel }, /* base */
3479 { 200.0, 200.0, 2.0, UnitPixel },
3480 { 200.0, 200.0, 1.0, UnitDisplay },
3481 { 200.0, 200.0, 2.0, UnitDisplay },
3482 { 200.0, 200.0, 1.0, UnitInch },
3483 { 200.0, 200.0, 2.0, UnitInch },
3484 { 200.0, 600.0, 1.0, UnitPoint },
3485 { 200.0, 600.0, 2.0, UnitPoint },
3486 { 200.0, 600.0, 1.0, UnitDocument },
3487 { 200.0, 600.0, 2.0, UnitDocument },
3488 { 200.0, 600.0, 1.0, UnitMillimeter },
3489 { 200.0, 600.0, 2.0, UnitMillimeter },
3490 { 200.0, 600.0, 1.0, UnitDisplay },
3491 { 200.0, 600.0, 2.0, UnitDisplay },
3492 { 200.0, 600.0, 1.0, UnitPixel },
3493 { 200.0, 600.0, 2.0, UnitPixel },
3494 };
3495 static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3496 static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3497 GpStatus status;
3498 GpGraphics *graphics;
3499 GpFontFamily *family;
3500 GpFont *font;
3501 GpStringFormat *format;
3502 RectF bounds, rc;
3503 REAL base_cx = 0, base_cy = 0, height;
3504 INT chars, lines;
3505 LOGFONTW lf;
3506 UINT i;
3507 REAL font_size;
3508 GpUnit font_unit, unit;
3509
3510 status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
3511 expect(Ok, status);
3512 status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3513 expect(Ok, status);
3514
3515 /* font size in pixels */
3516 status = GdipCreateFont(family, 100.0, FontStyleRegular, UnitPixel, &font);
3517 expect(Ok, status);
3518 status = GdipGetFontSize(font, &font_size);
3519 expect(Ok, status);
3520 expectf(100.0, font_size);
3521 status = GdipGetFontUnit(font, &font_unit);
3522 expect(Ok, status);
3523 expect(UnitPixel, font_unit);
3524
3525 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3526 {
3527 GpImage *image;
3528
3529 graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale, &image);
3530
3531 lf.lfHeight = 0xdeadbeef;
3532 status = GdipGetLogFontW(font, graphics, &lf);
3533 expect(Ok, status);
3534 height = units_to_pixels(font_size, td[i].unit, td[i].res_y);
3535 if (td[i].unit != UnitDisplay)
3536 height *= td[i].page_scale;
3537 ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3538 i, (LONG)(height + 0.5), height, lf.lfHeight);
3539
3540 height = font_size + 2.0 * font_size / 6.0;
3541
3542 set_rect_empty(&rc);
3543 set_rect_empty(&bounds);
3544 status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3545 expect(Ok, status);
3546
3547 if (i == 0)
3548 {
3549 base_cx = bounds.Width;
3550 base_cy = bounds.Height;
3551 }
3552
3553 expectf(0.0, bounds.X);
3554 expectf(0.0, bounds.Y);
3555 todo_wine
3556 expectf_(height, bounds.Height, height / 100.0);
3557 expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3558 expect(7, chars);
3559 expect(1, lines);
3560
3561 /* make sure it really fits */
3562 bounds.Width += 1.0;
3563 bounds.Height += 1.0;
3564 rc = bounds;
3565 rc.X = 50.0;
3566 rc.Y = 50.0;
3567 set_rect_empty(&bounds);
3568 status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3569 expect(Ok, status);
3570 expectf(50.0, bounds.X);
3571 expectf(50.0, bounds.Y);
3572 todo_wine
3573 expectf_(height, bounds.Height, height / 100.0);
3574 expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3575 expect(7, chars);
3576 expect(1, lines);
3577
3578 status = GdipDeleteGraphics(graphics);
3579 expect(Ok, status);
3580
3581 status = GdipDisposeImage(image);
3582 expect(Ok, status);
3583 }
3584
3585 GdipDeleteFont(font);
3586
3587 /* font size in logical units */
3588 /* UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3589 for (unit = 3; unit <= 6; unit++)
3590 {
3591 /* create a font which final height is 100.0 pixels with 200 dpi device */
3592 /* height + 2 * (height/6) = 100 => height = 100 * 3 / 4 => 75 */
3593 height = pixels_to_units(75.0, unit, 200.0);
3594 status = GdipCreateFont(family, height, FontStyleRegular, unit, &font);
3595 expect(Ok, status);
3596 status = GdipGetFontSize(font, &font_size);
3597 expect(Ok, status);
3598 expectf(height, font_size);
3599 status = GdipGetFontUnit(font, &font_unit);
3600 expect(Ok, status);
3601 expect(unit, font_unit);
3602
3603 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3604 {
3605 REAL unit_scale;
3606 GpImage *image;
3607
3608 graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].page_scale, &image);
3609
3610 lf.lfHeight = 0xdeadbeef;
3611 status = GdipGetLogFontW(font, graphics, &lf);
3612 expect(Ok, status);
3613 if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3614 height = units_to_pixels(font_size, font_unit, td[i].res_x);
3615 else
3616 height = units_to_pixels(font_size, font_unit, td[i].res_y);
3617 /*trace("%.1f font units = %f pixels with %.1f dpi, page_scale %.1f\n", font_size, height, td[i].res_y, td[i].page_scale);*/
3618 ok(-lf.lfHeight == (LONG)(height + 0.5), "%u: expected %d (%f), got %d\n",
3619 i, (LONG)(height + 0.5), height, lf.lfHeight);
3620
3621 if (td[i].unit == UnitDisplay || td[i].unit == UnitPixel)
3622 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_x);
3623 else
3624 unit_scale = units_scale(font_unit, td[i].unit, td[i].res_y);
3625 /*trace("%u: %d to %d, %.1f dpi => unit_scale %f\n", i, font_unit, td[i].unit, td[i].res_y, unit_scale);*/
3626 height = (font_size + 2.0 * font_size / 6.0) * unit_scale;
3627 if (td[i].unit != UnitDisplay)
3628 height /= td[i].page_scale;
3629 /*trace("%u: %.1f font units = %f units with %.1f dpi, page_scale %.1f\n", i, font_size, height, td[i].res_y, td[i].page_scale);*/
3630
3631 set_rect_empty(&rc);
3632 set_rect_empty(&bounds);
3633 status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3634 expect(Ok, status);
3635
3636 if (i == 0)
3637 {
3638 base_cx = bounds.Width;
3639 base_cy = bounds.Height;
3640 }
3641
3642 expectf(0.0, bounds.X);
3643 expectf(0.0, bounds.Y);
3644 todo_wine
3645 expectf_(height, bounds.Height, height / 85.0);
3646 expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3647 expect(7, chars);
3648 expect(1, lines);
3649
3650 /* make sure it really fits */
3651 bounds.Width += 1.0;
3652 bounds.Height += 1.0;
3653 rc = bounds;
3654 rc.X = 50.0;
3655 rc.Y = 50.0;
3656 set_rect_empty(&bounds);
3657 status = GdipMeasureString(graphics, string, -1, font, &rc, format, &bounds, &chars, &lines);
3658 expect(Ok, status);
3659 expectf(50.0, bounds.X);
3660 expectf(50.0, bounds.Y);
3661 todo_wine
3662 expectf_(height, bounds.Height, height / 85.0);
3663 expectf_(bounds.Height / base_cy, bounds.Width / base_cx, 0.1);
3664 expect(7, chars);
3665 expect(1, lines);
3666
3667 /* verify the result */
3668 height = units_to_pixels(bounds.Height, td[i].unit, td[i].res_x);
3669 if (td[i].unit != UnitDisplay)
3670 height *= td[i].page_scale;
3671 /*trace("%u: unit %u, %.1fx%.1f dpi, scale %.1f, height %f, pixels %f\n",
3672 i, td[i].unit, td[i].res_x, td[i].res_y, td[i].page_scale, bounds.Height, height);*/
3673 todo_wine
3674 expectf_(100.0, height, 1.1);
3675
3676 status = GdipDeleteGraphics(graphics);
3677 expect(Ok, status);
3678
3679 status = GdipDisposeImage(image);
3680 expect(Ok, status);
3681 }
3682
3683 GdipDeleteFont(font);
3684 }
3685
3686 GdipDeleteFontFamily(family);
3687 GdipDeleteStringFormat(format);
3688 }
3689
3690 static void test_transform(void)
3691 {
3692 static const struct test_data
3693 {
3694 REAL res_x, res_y, scale;
3695 GpUnit unit;
3696 GpPointF in[2], out[2];
3697 } td[] =
3698 {
3699 { 96.0, 96.0, 1.0, UnitPixel,
3700 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3701 { 96.0, 96.0, 1.0, UnitDisplay,
3702 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3703 { 96.0, 96.0, 1.0, UnitInch,
3704 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 9600.0, 0.0 }, { 0.0, 9600.0 } } },
3705 { 123.0, 456.0, 1.0, UnitPoint,
3706 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 170.833313, 0.0 }, { 0.0, 633.333252 } } },
3707 { 123.0, 456.0, 1.0, UnitDocument,
3708 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 40.999996, 0.0 }, { 0.0, 151.999985 } } },
3709 { 123.0, 456.0, 2.0, UnitMillimeter,
3710 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 968.503845, 0.0 }, { 0.0, 3590.550781 } } },
3711 { 196.0, 296.0, 1.0, UnitDisplay,
3712 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3713 { 196.0, 296.0, 1.0, UnitPixel,
3714 { { 100.0, 0.0 }, { 0.0, 100.0 } }, { { 100.0, 0.0 }, { 0.0, 100.0 } } },
3715 };
3716 GpStatus status;
3717 GpGraphics *graphics;
3718 GpImage *image;
3719 GpPointF ptf[2];
3720 UINT i;
3721
3722 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
3723 {
3724 graphics = create_graphics(td[i].res_x, td[i].res_y, td[i].unit, td[i].scale, &image);
3725 ptf[0].X = td[i].in[0].X;
3726 ptf[0].Y = td[i].in[0].Y;
3727 ptf[1].X = td[i].in[1].X;
3728 ptf[1].Y = td[i].in[1].Y;
3729 status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2);
3730 expect(Ok, status);
3731 expectf(td[i].out[0].X, ptf[0].X);
3732 expectf(td[i].out[0].Y, ptf[0].Y);
3733 expectf(td[i].out[1].X, ptf[1].X);
3734 expectf(td[i].out[1].Y, ptf[1].Y);
3735 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
3736 expect(Ok, status);
3737 expectf(td[i].in[0].X, ptf[0].X);
3738 expectf(td[i].in[0].Y, ptf[0].Y);
3739 expectf(td[i].in[1].X, ptf[1].X);
3740 expectf(td[i].in[1].Y, ptf[1].Y);
3741 status = GdipDeleteGraphics(graphics);
3742 expect(Ok, status);
3743 status = GdipDisposeImage(image);
3744 expect(Ok, status);
3745 }
3746 }
3747
3748 /* Many people on the net ask why there is so much difference in rendered
3749 * text height between gdiplus and gdi32, this test suggests an answer to
3750 * that question. Important: this test assumes that font dpi == device dpi.
3751 */
3752 static void test_font_height_scaling(void)
3753 {
3754 static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3755 static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
3756 HDC hdc;
3757 GpStringFormat *format;
3758 CharacterRange range = { 0, 7 };
3759 GpRegion *region;
3760 GpGraphics *graphics;
3761 GpFontFamily *family;
3762 GpFont *font;
3763 GpStatus status;
3764 RectF bounds, rect;
3765 REAL height, dpi, scale;
3766 PointF ptf;
3767 GpUnit gfx_unit, font_unit;
3768
3769 status = GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &format);
3770 expect(Ok, status);
3771 status = GdipSetStringFormatMeasurableCharacterRanges(format, 1, &range);
3772 expect(Ok, status);
3773 status = GdipCreateRegion(&region);
3774 expect(Ok, status);
3775
3776 status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3777 expect(Ok, status);
3778
3779 hdc = CreateCompatibleDC(0);
3780 status = GdipCreateFromHDC(hdc, &graphics);
3781
3782 status = GdipGetDpiY(graphics, &dpi);
3783 expect(Ok, status);
3784
3785 /* First check if tested functionality works:
3786 * under XP if font and graphics units differ then GdipTransformPoints
3787 * followed by GdipSetPageUnit to change the graphics units breaks region
3788 * scaling in GdipMeasureCharacterRanges called later.
3789 */
3790 status = GdipSetPageUnit(graphics, UnitDocument);
3791 expect(Ok, status);
3792
3793 ptf.X = 0.0;
3794 ptf.Y = 0.0;
3795 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3796 expect(Ok, status);
3797
3798 status = GdipSetPageUnit(graphics, UnitInch);
3799 expect(Ok, status);
3800
3801 status = GdipCreateFont(family, 720.0, FontStyleRegular, UnitPoint, &font);
3802 expect(Ok, status);
3803
3804 set_rect_empty(&rect);
3805 set_rect_empty(&bounds);
3806 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
3807 expect(Ok, status);
3808 trace("test bounds: %f,%f,%f,%f\n", bounds.X, bounds.Y, bounds.Width, bounds.Height);
3809
3810 set_rect_empty(&rect);
3811 rect.Width = 32000.0;
3812 rect.Height = 32000.0;
3813 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
3814 expect(Ok, status);
3815
3816 set_rect_empty(&rect);
3817 status = GdipGetRegionBounds(region, graphics, &rect);
3818 expect(Ok, status);
3819 trace("test region: %f,%f,%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);
3820
3821 GdipDeleteFont(font);
3822
3823 scale = rect.Height / bounds.Height;
3824 if (fabs(scale - 1.0) > 0.1)
3825 {
3826 win_skip("GdipGetRegionBounds is broken, scale %f (should be near 1.0)\n", scale);
3827 goto cleanup;
3828 }
3829
3830 status = GdipScaleWorldTransform(graphics, 0.01, 0.01, MatrixOrderAppend);
3831 expect(Ok, status);
3832
3833 /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3834 /* UnitPixel as a font base unit is not tested because it drastically
3835 differs in behaviour */
3836 for (font_unit = 3; font_unit <= 6; font_unit++)
3837 {
3838 /* create a font for the final text height of 100 pixels */
3839 /* height + 2 * (height/6) = 100 => height = 100 * 3 / 4 => 75 */
3840 status = GdipSetPageUnit(graphics, font_unit);
3841 expect(Ok, status);
3842 ptf.X = 0;
3843 ptf.Y = 75.0;
3844 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, &ptf, 1);
3845 expect(Ok, status);
3846 height = ptf.Y;
3847 /*trace("height %f units\n", height);*/
3848 status = GdipCreateFont(family, height, FontStyleRegular, font_unit, &font);
3849 expect(Ok, status);
3850
3851 /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
3852 for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
3853 {
3854 static const WCHAR doubleW[2] = { 'W','W' };
3855 RectF bounds_1, bounds_2;
3856 REAL margin, margin_y, font_height;
3857 int match;
3858
3859 status = GdipSetPageUnit(graphics, gfx_unit);
3860 expect(Ok, status);
3861
3862 margin_y = units_to_pixels(height / 8.0, font_unit, dpi);
3863 margin_y = pixels_to_units(margin_y, gfx_unit, dpi);
3864
3865 status = GdipGetFontHeight(font, graphics, &font_height);
3866 expect(Ok, status);
3867
3868 set_rect_empty(&rect);
3869 set_rect_empty(&bounds);
3870 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, NULL, NULL);
3871 expect(Ok, status);
3872 /*trace("bounds: %f,%f,%f,%f\n", bounds.X, bounds.Y, bounds.Width, bounds.Height);*/
3873 todo_wine
3874 expectf_(font_height + margin_y, bounds.Height, 0.005);
3875
3876 ptf.X = 0;
3877 ptf.Y = bounds.Height;
3878 status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, &ptf, 1);
3879 expect(Ok, status);
3880 match = fabs(100.0 - ptf.Y) <= 1.0;
3881 todo_wine
3882 ok(match, "Expected 100.0, got %f\n", ptf.Y);
3883
3884 /* verify the result */
3885 ptf.Y = units_to_pixels(bounds.Height, gfx_unit, dpi);
3886 ptf.Y /= 100.0;
3887 match = fabs(100.0 - ptf.Y) <= 1.0;
3888 todo_wine
3889 ok(match, "Expected 100.0, got %f\n", ptf.Y);
3890
3891 /* bounds.width of 1 glyph: [margin]+[width]+[margin] */
3892 set_rect_empty(&rect);
3893 set_rect_empty(&bounds_1);
3894 status = GdipMeasureString(graphics, doubleW, 1, font, &rect, format, &bounds_1, NULL, NULL);
3895 expect(Ok, status);
3896 /* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
3897 set_rect_empty(&rect);
3898 set_rect_empty(&bounds_2);
3899 status = GdipMeasureString(graphics, doubleW, 2, font, &rect, format, &bounds_2, NULL, NULL);
3900 expect(Ok, status);
3901
3902 /* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
3903 margin = bounds_1.Width - bounds_2.Width / 2.0;
3904 /*trace("margin %f\n", margin);*/
3905 ok(margin > 0.0, "wrong margin %f\n", margin);
3906
3907 set_rect_empty(&rect);
3908 rect.Width = 320000.0;
3909 rect.Height = 320000.0;
3910 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
3911 expect(Ok, status);
3912 set_rect_empty(&rect);
3913 status = GdipGetRegionBounds(region, graphics, &rect);
3914 expect(Ok, status);
3915 /*trace("region: %f,%f,%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);*/
3916 ok(rect.X > 0.0, "wrong rect.X %f\n", rect.X);
3917 expectf(0.0, rect.Y);
3918 match = fabs(1.0 - margin / rect.X) <= 0.05;
3919 ok(match, "Expected %f, got %f\n", margin, rect.X);
3920 match = fabs(1.0 - font_height / rect.Height) <= 0.1;
3921 ok(match, "Expected %f, got %f\n", font_height, rect.Height);
3922 match = fabs(1.0 - bounds.Width / (rect.Width + margin * 2.0)) <= 0.05;
3923 ok(match, "Expected %f, got %f\n", bounds.Width, rect.Width + margin * 2.0);
3924 }
3925
3926 GdipDeleteFont(font);
3927 }
3928
3929 cleanup:
3930 status = GdipDeleteGraphics(graphics);
3931 expect(Ok, status);
3932 DeleteDC(hdc);
3933
3934 GdipDeleteFontFamily(family);
3935 GdipDeleteRegion(region);
3936 GdipDeleteStringFormat(format);
3937 }
3938
3939 static void test_measure_string(void)
3940 {
3941 static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
3942 static const WCHAR string[] = { 'A','0','1',0 };
3943 HDC hdc;
3944 GpStringFormat *format;
3945 CharacterRange range;
3946 GpRegion *region;
3947 GpGraphics *graphics;
3948 GpFontFamily *family;
3949 GpFont *font;
3950 GpStatus status;
3951 RectF bounds, rect;
3952 REAL width, height, width_1, width_2;
3953 REAL margin_x, margin_y, width_rgn, height_rgn;
3954 int lines, glyphs;
3955
3956 status = GdipCreateStringFormat(StringFormatFlagsNoWrap, LANG_NEUTRAL, &format);
3957 expect(Ok, status);
3958 expect(Ok, status);
3959
3960 status = GdipCreateRegion(&region);
3961 expect(Ok, status);
3962
3963 status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
3964 expect(Ok, status);
3965
3966 hdc = CreateCompatibleDC(0);
3967 status = GdipCreateFromHDC(hdc, &graphics);
3968
3969 status = GdipCreateFont(family, 20, FontStyleRegular, UnitPixel, &font);
3970 expect(Ok, status);
3971
3972 margin_x = 20.0 / 6.0;
3973 margin_y = 20.0 / 8.0;
3974
3975 set_rect_empty(&rect);
3976 set_rect_empty(&bounds);
3977 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3978 expect(Ok, status);
3979 expect(3, glyphs);
3980 expect(1, lines);
3981 expectf(0.0, bounds.X);
3982 expectf(0.0, bounds.Y);
3983 width = bounds.Width;
3984 height = bounds.Height;
3985
3986 set_rect_empty(&rect);
3987 rect.Height = height / 2.0;
3988 set_rect_empty(&bounds);
3989 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
3990 expect(Ok, status);
3991 expect(3, glyphs);
3992 expect(1, lines);
3993 expectf(0.0, bounds.X);
3994 expectf(0.0, bounds.Y);
3995 expectf(width, bounds.Width);
3996 todo_wine
3997 expectf(height / 2.0, bounds.Height);
3998
3999 range.First = 0;
4000 range.Length = lstrlenW(string);
4001 status = GdipSetStringFormatMeasurableCharacterRanges(format, 1, &range);
4002 expect(Ok, status);
4003
4004 rect.X = 5.0;
4005 rect.Y = 5.0;
4006 rect.Width = 32000.0;
4007 rect.Height = 32000.0;
4008 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4009 expect(Ok, status);
4010 set_rect_empty(&bounds);
4011 status = GdipGetRegionBounds(region, graphics, &bounds);
4012 expect(Ok, status);
4013 expectf_(5.0 + margin_x, bounds.X, 1.0);
4014 expectf(5.0, bounds.Y);
4015 expectf_(width - margin_x*2.0, bounds.Width, 1.0);
4016 todo_wine
4017 expectf_(height - margin_y, bounds.Height, 1.0);
4018
4019 width_rgn = bounds.Width;
4020 height_rgn = bounds.Height;
4021
4022 range.First = 0;
4023 range.Length = 1;
4024 status = GdipSetStringFormatMeasurableCharacterRanges(format, 1, &range);
4025 expect(Ok, status);
4026
4027 set_rect_empty(&rect);
4028 rect.Width = 32000.0;
4029 rect.Height = 32000.0;
4030 status = GdipMeasureCharacterRanges(graphics, string, 1, font, &rect, format, 1, &region);
4031 expect(Ok, status);
4032 set_rect_empty(&bounds);
4033 status = GdipGetRegionBounds(region, graphics, &bounds);
4034 expect(Ok, status);
4035 expectf_(margin_x, bounds.X, 1.0);
4036 expectf(0.0, bounds.Y);
4037 ok(bounds.Width < width_rgn / 2.0, "width of 1 glyph is wrong\n");
4038 expectf(height_rgn, bounds.Height);
4039 width_1 = bounds.Width;
4040
4041 range.First = 0;
4042 range.Length = lstrlenW(string);
4043 status = GdipSetStringFormatMeasurableCharacterRanges(format, 1, &range);
4044 expect(Ok, status);
4045
4046 rect.X = 5.0;
4047 rect.Y = 5.0;
4048 rect.Width = 0.0;
4049 rect.Height = 0.0;
4050 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4051 expect(Ok, status);
4052 set_rect_empty(&bounds);
4053 status = GdipGetRegionBounds(region, graphics, &bounds);
4054 expect(Ok, status);
4055 expectf(0.0, bounds.X);
4056 expectf(0.0, bounds.Y);
4057 expectf(0.0, bounds.Width);
4058 expectf(0.0, bounds.Height);
4059
4060 rect.X = 5.0;
4061 rect.Y = 5.0;
4062 rect.Width = width_rgn / 2.0;
4063 rect.Height = 32000.0;
4064 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4065 expect(Ok, status);
4066 set_rect_empty(&bounds);
4067 status = GdipGetRegionBounds(region, graphics, &bounds);
4068 expect(Ok, status);
4069 expectf_(5.0 + margin_x, bounds.X, 1.0);
4070 expectf(5.0, bounds.Y);
4071 expectf_(width_1, bounds.Width, 1.0);
4072 todo_wine
4073 expectf_(height - margin_y, bounds.Height, 1.0);
4074
4075 status = GdipSetStringFormatFlags(format, StringFormatFlagsNoWrap | StringFormatFlagsNoClip);
4076
4077 rect.X = 5.0;
4078 rect.Y = 5.0;
4079 rect.Width = 0.0;
4080 rect.Height = 0.0;
4081 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4082 expect(Ok, status);
4083 set_rect_empty(&bounds);
4084 status = GdipGetRegionBounds(region, graphics, &bounds);
4085 expect(Ok, status);
4086 expectf_(5.0 + margin_x, bounds.X, 1.0);
4087 expectf(5.0, bounds.Y);
4088 expectf(width_rgn, bounds.Width);
4089 expectf(height_rgn, bounds.Height);
4090
4091 rect.X = 5.0;
4092 rect.Y = 5.0;
4093 rect.Width = width_rgn / 2.0;
4094 rect.Height = 32000.0;
4095 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4096 expect(Ok, status);
4097 set_rect_empty(&bounds);
4098 status = GdipGetRegionBounds(region, graphics, &bounds);
4099 expect(Ok, status);
4100 expectf_(5.0 + margin_x, bounds.X, 1.0);
4101 expectf(5.0, bounds.Y);
4102 expectf_(width_1, bounds.Width, 1.0);
4103 expectf(height_rgn, bounds.Height);
4104
4105 set_rect_empty(&rect);
4106 rect.Height = height / 2.0;
4107 set_rect_empty(&bounds);
4108 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4109 expect(Ok, status);
4110 expect(3, glyphs);
4111 expect(1, lines);
4112 expectf(0.0, bounds.X);
4113 expectf(0.0, bounds.Y);
4114 expectf_(width, bounds.Width, 0.01);
4115 todo_wine
4116 expectf(height, bounds.Height);
4117
4118 set_rect_empty(&rect);
4119 set_rect_empty(&bounds);
4120 status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds, &glyphs, &lines);
4121 expect(Ok, status);
4122 expect(1, glyphs);
4123 expect(1, lines);
4124 expectf(0.0, bounds.X);
4125 expectf(0.0, bounds.Y);
4126 ok(bounds.Width < width / 2.0, "width of 1 glyph is wrong\n");
4127 expectf(height, bounds.Height);
4128 width_1 = bounds.Width;
4129
4130 set_rect_empty(&rect);
4131 set_rect_empty(&bounds);
4132 status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds, &glyphs, &lines);
4133 expect(Ok, status);
4134 expect(2, glyphs);
4135 expect(1, lines);
4136 expectf(0.0, bounds.X);
4137 expectf(0.0, bounds.Y);
4138 ok(bounds.Width < width, "width of 2 glyphs is wrong\n");
4139 ok(bounds.Width > width_1, "width of 2 glyphs is wrong\n");
4140 expectf(height, bounds.Height);
4141 width_2 = bounds.Width;
4142
4143 set_rect_empty(&rect);
4144 rect.Width = width / 2.0;
4145 set_rect_empty(&bounds);
4146 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4147 expect(Ok, status);
4148 expect(1, glyphs);
4149 expect(1, lines);
4150 expectf(0.0, bounds.X);
4151 expectf(0.0, bounds.Y);
4152 expectf_(width_1, bounds.Width, 0.01);
4153 expectf(height, bounds.Height);
4154
4155 set_rect_empty(&rect);
4156 rect.Height = height;
4157 rect.Width = width - 0.05;
4158 set_rect_empty(&bounds);
4159 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4160 expect(Ok, status);
4161 expect(2, glyphs);
4162 expect(1, lines);
4163 expectf(0.0, bounds.X);
4164 expectf(0.0, bounds.Y);
4165 expectf_(width_2, bounds.Width, 0.01);
4166 expectf(height, bounds.Height);
4167
4168 set_rect_empty(&rect);
4169 rect.Height = height;
4170 rect.Width = width_2 - 0.05;
4171 set_rect_empty(&bounds);
4172 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4173 expect(Ok, status);
4174 expect(1, glyphs);
4175 expect(1, lines);
4176 expectf(0.0, bounds.X);
4177 expectf(0.0, bounds.Y);
4178 expectf_(width_1, bounds.Width, 0.01);
4179 expectf(height, bounds.Height);
4180
4181 /* Default (Near) alignment */
4182 rect.X = 5.0;
4183 rect.Y = 5.0;
4184 rect.Width = width * 2.0;
4185 rect.Height = height * 2.0;
4186 set_rect_empty(&bounds);
4187 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4188 expect(Ok, status);
4189 expect(3, glyphs);
4190 expect(1, lines);
4191 expectf(5.0, bounds.X);
4192 expectf(5.0, bounds.Y);
4193 expectf_(width, bounds.Width, 0.01);
4194 expectf(height, bounds.Height);
4195
4196 rect.X = 5.0;
4197 rect.Y = 5.0;
4198 rect.Width = 32000.0;
4199 rect.Height = 32000.0;
4200 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4201 expect(Ok, status);
4202 set_rect_empty(&bounds);
4203 status = GdipGetRegionBounds(region, graphics, &bounds);
4204 expect(Ok, status);
4205 expectf_(5.0 + margin_x, bounds.X, 1.0);
4206 expectf(5.0, bounds.Y);
4207 expectf_(width - margin_x*2.0, bounds.Width, 1.0);
4208 todo_wine
4209 expectf_(height - margin_y, bounds.Height, 1.0);
4210
4211 width_rgn = bounds.Width;
4212 height_rgn = bounds.Height;
4213
4214 /* Center alignment */
4215 GdipSetStringFormatAlign(format, StringAlignmentCenter);
4216 GdipSetStringFormatLineAlign(format, StringAlignmentCenter);
4217
4218 rect.X = 5.0;
4219 rect.Y = 5.0;
4220 rect.Width = width * 2.0;
4221 rect.Height = height * 2.0;
4222 set_rect_empty(&bounds);
4223 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4224 expect(Ok, status);
4225 expect(3, glyphs);
4226 expect(1, lines);
4227 todo_wine
4228 expectf_(5.0 + width/2.0, bounds.X, 0.01);
4229 todo_wine
4230 expectf(5.0 + height/2.0, bounds.Y);
4231 expectf_(width, bounds.Width, 0.01);
4232 expectf(height, bounds.Height);
4233
4234 rect.X = 5.0;
4235 rect.Y = 5.0;
4236 rect.Width = 0.0;
4237 rect.Height = 0.0;
4238 set_rect_empty(&bounds);
4239 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4240 expect(Ok, status);
4241 expect(3, glyphs);
4242 expect(1, lines);
4243 todo_wine
4244 expectf_(5.0 - width/2.0, bounds.X, 0.01);
4245 todo_wine
4246 expectf(5.0 - height/2.0, bounds.Y);
4247 expectf_(width, bounds.Width, 0.01);
4248 expectf(height, bounds.Height);
4249
4250 rect.X = 5.0;
4251 rect.Y = 5.0;
4252 rect.Width = width_rgn * 2.0;
4253 rect.Height = height_rgn * 2.0;
4254 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4255 expect(Ok, status);
4256 set_rect_empty(&bounds);
4257 status = GdipGetRegionBounds(region, graphics, &bounds);
4258 expect(Ok, status);
4259 todo_wine
4260 expectf_(5.0 + width_rgn/2.0, bounds.X, 1.0);
4261 todo_wine
4262 expectf_(5.0 + height_rgn/2.0, bounds.Y, 1.0);
4263 expectf_(width_rgn, bounds.Width, 1.0);
4264 expectf_(height_rgn, bounds.Height, 1.0);
4265
4266 rect.X = 5.0;
4267 rect.Y = 5.0;
4268 rect.Width = 0.0;
4269 rect.Height = 0.0;
4270 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4271 expect(Ok, status);
4272 set_rect_empty(&bounds);
4273 status = GdipGetRegionBounds(region, graphics, &bounds);
4274 expect(Ok, status);
4275 todo_wine
4276 expectf_(5.0 - width_rgn/2.0, bounds.X, 1.0);
4277 todo_wine
4278 expectf_(5.0 - height_rgn/2.0, bounds.Y, 1.0);
4279 expectf_(width_rgn, bounds.Width, 1.0);
4280 expectf_(height_rgn, bounds.Height, 1.0);
4281
4282 /* Far alignment */
4283 GdipSetStringFormatAlign(format, StringAlignmentFar);
4284 GdipSetStringFormatLineAlign(format, StringAlignmentFar);
4285
4286 rect.X = 5.0;
4287 rect.Y = 5.0;
4288 rect.Width = width * 2.0;
4289 rect.Height = height * 2.0;
4290 set_rect_empty(&bounds);
4291 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4292 expect(Ok, status);
4293 expect(3, glyphs);
4294 expect(1, lines);
4295 todo_wine
4296 expectf_(5.0 + width, bounds.X, 0.01);
4297 todo_wine
4298 expectf(5.0 + height, bounds.Y);
4299 expectf_(width, bounds.Width, 0.01);
4300 expectf(height, bounds.Height);
4301
4302 rect.X = 5.0;
4303 rect.Y = 5.0;
4304 rect.Width = 0.0;
4305 rect.Height = 0.0;
4306 set_rect_empty(&bounds);
4307 status = GdipMeasureString(graphics, string, -1, font, &rect, format, &bounds, &glyphs, &lines);
4308 expect(Ok, status);
4309 expect(3, glyphs);
4310 expect(1, lines);
4311 todo_wine
4312 expectf_(5.0 - width, bounds.X, 0.01);
4313 todo_wine
4314 expectf(5.0 - height, bounds.Y);
4315 expectf_(width, bounds.Width, 0.01);
4316 expectf(height, bounds.Height);
4317
4318 rect.X = 5.0;
4319 rect.Y = 5.0;
4320 rect.Width = width_rgn * 2.0;
4321 rect.Height = height_rgn * 2.0;
4322 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4323 expect(Ok, status);
4324 set_rect_empty(&bounds);
4325 status = GdipGetRegionBounds(region, graphics, &bounds);
4326 expect(Ok, status);
4327 todo_wine
4328 expectf_(5.0 + width_rgn, bounds.X, 2.0);
4329 todo_wine
4330 expectf_(5.0 + height_rgn, bounds.Y, 1.0);
4331 expectf_(width_rgn, bounds.Width, 1.0);
4332 expectf_(height_rgn, bounds.Height, 1.0);
4333
4334 rect.X = 5.0;
4335 rect.Y = 5.0;
4336 rect.Width = 0.0;
4337 rect.Height = 0.0;
4338 status = GdipMeasureCharacterRanges(graphics, string, -1, font, &rect, format, 1, &region);
4339 expect(Ok, status);
4340 set_rect_empty(&bounds);
4341 status = GdipGetRegionBounds(region, graphics, &bounds);
4342 expect(Ok, status);
4343 todo_wine
4344 expectf_(5.0 - width_rgn, bounds.X, 2.0);
4345 todo_wine
4346 expectf_(5.0 - height_rgn, bounds.Y, 1.0);
4347 expectf_(width_rgn, bounds.Width, 1.0);
4348 expectf_(height_rgn, bounds.Height, 1.0);
4349
4350 status = GdipDeleteFont(font);
4351 expect(Ok, status);
4352
4353 status = GdipDeleteGraphics(graphics);
4354 expect(Ok, status);
4355 DeleteDC(hdc);
4356
4357 GdipDeleteFontFamily(family);
4358 GdipDeleteRegion(region);
4359 GdipDeleteStringFormat(format);
4360 }
4361
4362 static void test_measured_extra_space(void)
4363 {
4364 static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
4365 static const WCHAR string[2] = { 'W','W' };
4366 GpStringFormat *format;
4367 HDC hdc;
4368 GpGraphics *graphics;
4369 GpFontFamily *family;
4370 GpFont *font;
4371 GpStatus status;
4372 GpUnit gfx_unit, font_unit;
4373 RectF bounds_1, bounds_2, rect;
4374 REAL margin, font_size, dpi;
4375
4376 status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
4377 expect(Ok, status);
4378
4379 status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
4380 expect(Ok, status);
4381 hdc = CreateCompatibleDC(0);
4382 status = GdipCreateFromHDC(hdc, &graphics);
4383 expect(Ok, status);
4384
4385 status = GdipGetDpiX(graphics, &dpi);
4386 expect(Ok, status);
4387
4388 /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
4389 /* UnitPixel as a font base unit is not tested because it differs in behaviour */
4390 for (font_unit = 3; font_unit <= 6; font_unit++)
4391 {
4392 status = GdipCreateFont(family, 1234.0, FontStyleRegular, font_unit, &font);
4393 expect(Ok, status);
4394
4395 status = GdipGetFontSize(font, &font_size);
4396 expect(Ok, status);
4397 font_size = units_to_pixels(font_size, font_unit, dpi);
4398 /*trace("font size/6 = %f pixels\n", font_size / 6.0);*/
4399
4400 /* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
4401 for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
4402 {
4403 status = GdipSetPageUnit(graphics, gfx_unit);
4404 expect(Ok, status);
4405
4406 /* bounds.width of 1 glyph: [margin]+[width]+[margin] */
4407 set_rect_empty(&rect);
4408 set_rect_empty(&bounds_1);
4409 status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds_1, NULL, NULL);
4410 expect(Ok, status);
4411 /* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
4412 set_rect_empty(&rect);
4413 set_rect_empty(&bounds_2);
4414 status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds_2, NULL, NULL);
4415 expect(Ok, status);
4416
4417 /* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
4418 margin = units_to_pixels(bounds_1.Width - bounds_2.Width / 2.0, gfx_unit, dpi);
4419 /*trace("margin %f pixels\n", margin);*/
4420 expectf_(font_size / 6.0, margin, font_size / 100.0);
4421 }
4422
4423 GdipDeleteFont(font);
4424 }
4425
4426 GdipDeleteGraphics(graphics);
4427 DeleteDC(hdc);
4428 GdipDeleteFontFamily(family);
4429 GdipDeleteStringFormat(format);
4430 }
4431
4432 static void test_alpha_hdc(void)
4433 {
4434 GpStatus status;
4435 HDC hdc;
4436 HBITMAP hbm, old_hbm;
4437 GpGraphics *graphics;
4438 ULONG *bits;
4439 BITMAPINFO bmi;
4440 GpRectF bounds;
4441
4442 hdc = CreateCompatibleDC(0);
4443 ok(hdc != NULL, "CreateCompatibleDC failed\n");
4444 bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
4445 bmi.bmiHeader.biHeight = 5;
4446 bmi.bmiHeader.biWidth = 5;
4447 bmi.bmiHeader.biBitCount = 32;
4448 bmi.bmiHeader.biPlanes = 1;
4449 bmi.bmiHeader.biCompression = BI_RGB;
4450 bmi.bmiHeader.biClrUsed = 0;
4451
4452 hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
4453 ok(hbm != NULL, "CreateDIBSection failed\n");
4454
4455 old_hbm = SelectObject(hdc, hbm);
4456
4457 status = GdipCreateFromHDC(hdc, &graphics);
4458 expect(Ok, status);
4459
4460 status = GdipGetVisibleClipBounds(graphics, &bounds);
4461 expect(Ok, status);
4462 expectf(0.0, bounds.X);
4463 expectf(0.0, bounds.Y);
4464 expectf(5.0, bounds.Width);
4465 expectf(5.0, bounds.Height);
4466
4467 bits[0] = 0xdeadbeef;
4468
4469 status = GdipGraphicsClear(graphics, 0xffaaaaaa);
4470 expect(Ok, status);
4471
4472 expect(0xffaaaaaa, bits[0]);
4473
4474 SelectObject(hdc, old_hbm);
4475
4476 bits[0] = 0xdeadbeef;
4477
4478 status = GdipGraphicsClear(graphics, 0xffbbbbbb);
4479 expect(Ok, status);
4480
4481 todo_wine expect(0xffbbbbbb, bits[0]);
4482
4483 GdipDeleteGraphics(graphics);
4484
4485 DeleteObject(hbm);
4486 DeleteDC(hdc);
4487 }
4488
4489 static void test_bitmapfromgraphics(void)
4490 {
4491 GpStatus stat;
4492 GpGraphics *graphics = NULL;
4493 HDC hdc = GetDC( hwnd );
4494 GpBitmap *bitmap = NULL;
4495 PixelFormat format;
4496 REAL imageres, graphicsres;
4497 UINT width, height;
4498
4499 stat = GdipCreateFromHDC(hdc, &graphics);
4500 expect(Ok, stat);
4501
4502 stat = GdipCreateBitmapFromGraphics(12, 13, NULL, &bitmap);
4503 expect(InvalidParameter, stat);
4504
4505 stat = GdipCreateBitmapFromGraphics(12, 13, graphics, NULL);
4506 expect(InvalidParameter, stat);
4507
4508 stat = GdipCreateBitmapFromGraphics(12, 13, graphics, &bitmap);
4509 expect(Ok, stat);
4510
4511 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
4512 expect(Ok, stat);
4513 expect(PixelFormat32bppPARGB, format);
4514
4515 stat = GdipGetDpiX(graphics, &graphicsres);
4516 expect(Ok, stat);
4517
4518 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &imageres);
4519 expect(Ok, stat);
4520 expectf(graphicsres, imageres);
4521
4522 stat = GdipGetDpiY(graphics, &graphicsres);
4523 expect(Ok, stat);
4524
4525 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &imageres);
4526 expect(Ok, stat);
4527 expectf(graphicsres, imageres);
4528
4529 stat = GdipGetImageWidth((GpImage*)bitmap, &width);
4530 expect(Ok, stat);
4531 expect(12, width);
4532
4533 stat = GdipGetImageHeight((GpImage*)bitmap, &height);
4534 expect(Ok, stat);
4535 expect(13, height);
4536
4537 GdipDeleteGraphics(graphics);
4538 GdipDisposeImage((GpImage*)bitmap);
4539 }
4540
4541 static void test_clipping(void)
4542 {
4543 HDC hdc;
4544 GpStatus status;
4545 GpGraphics *graphics;
4546 GpRegion *region, *region100x100;
4547 GpMatrix *matrix;
4548 GpRectF rect;
4549 GpPointF ptf[4];
4550 GpUnit unit;
4551 HRGN hrgn;
4552 int ret;
4553 RECT rc;
4554
4555 hdc = CreateCompatibleDC(0);
4556 status = GdipCreateFromHDC(hdc, &graphics);
4557 expect(Ok, status);
4558
4559 status = GdipGetPageUnit(graphics, &unit);
4560 expect(Ok, status);
4561 expect(UnitDisplay, unit);
4562
4563 status = GdipCreateRegion(&region);
4564 expect(Ok, status);
4565 status = GdipSetEmpty(region);
4566 expect(Ok, status);
4567
4568 status = GdipCreateRegion(&region100x100);
4569 expect(Ok, status);
4570 status = GdipSetEmpty(region100x100);
4571 expect(Ok, status);
4572
4573 rect.X = rect.Y = 100.0;
4574 rect.Width = rect.Height = 100.0;
4575 status = GdipCombineRegionRect(region100x100, &rect, CombineModeUnion);
4576 expect(Ok, status);
4577 status = GdipSetClipRegion(graphics, region100x100, CombineModeReplace);
4578 expect(Ok, status);
4579
4580 status = GdipGetClipBounds(graphics, &rect);
4581 expect(Ok, status);
4582 ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0,
4583 "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4584
4585 status = GdipSetEmpty(region);
4586 expect(Ok, status);
4587 status = GdipGetClip(graphics, region);
4588 expect(Ok, status);
4589 status = GdipGetRegionBounds(region, graphics, &rect);
4590 expect(Ok, status);
4591 ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0,
4592 "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4593
4594 ptf[0].X = 100.0;
4595 ptf[0].Y = 100.0;
4596 ptf[1].X = 200.0;
4597 ptf[1].Y = 200.0;
4598 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4599 expect(Ok, status);
4600 ok(ptf[0].X == 100.0 && ptf[0].Y == 100.0 && ptf[1].X == 200.0 && ptf[1].Y == 200.0,
4601 "expected 100.0,100.0-200.0,200.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4602
4603 status = GdipCreateMatrix(&matrix);
4604 expect(Ok, status);
4605 status = GdipScaleMatrix(matrix, 2.0, 4.0, MatrixOrderAppend);
4606 expect(Ok, status);
4607 status = GdipTranslateMatrix(matrix, 10.0, 20.0, MatrixOrderAppend);
4608 expect(Ok, status);
4609 status = GdipSetWorldTransform(graphics, matrix);
4610 expect(Ok, status);
4611
4612 status = GdipGetClipBounds(graphics, &rect);
4613 expect(Ok, status);
4614 ok(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0,
4615 "expected 45.0,20.0-50.0,25.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4616
4617 status = GdipSetEmpty(region);
4618 expect(Ok, status);
4619 status = GdipGetClip(graphics, region);
4620 expect(Ok, status);
4621 status = GdipGetRegionBounds(region, graphics, &rect);
4622 expect(Ok, status);
4623 ok(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0,
4624 "expected 45.0,20.0-50.0,25.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4625
4626 status = GdipGetRegionBounds(region100x100, graphics, &rect);
4627 expect(Ok, status);
4628 ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0,
4629 "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4630
4631 status = GdipGetRegionHRgn(region, NULL, &hrgn);
4632 expect(Ok, status);
4633 ret = GetRgnBox(hrgn, &rc);
4634 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4635 ok(rc.left == 45 && rc.top == 20 && rc.right == 95 && rc.bottom == 45,
4636 "expected 45,20-95,45, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4637 DeleteObject(hrgn);
4638
4639 status = GdipGetRegionHRgn(region, graphics, &hrgn);
4640 expect(Ok, status);
4641 ret = GetRgnBox(hrgn, &rc);
4642 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4643 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4644 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4645 DeleteObject(hrgn);
4646
4647 ptf[0].X = 100.0;
4648 ptf[0].Y = 100.0;
4649 ptf[1].X = 200.0;
4650 ptf[1].Y = 200.0;
4651 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4652 expect(Ok, status);
4653 ok(ptf[0].X == 45.0 && ptf[0].Y == 20.0 && ptf[1].X == 95.0 && ptf[1].Y == 45.0,
4654 "expected 45.0,20.0-95.0,45.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4655
4656 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
4657 expect(Ok, status);
4658 ret = GetRgnBox(hrgn, &rc);
4659 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4660 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4661 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4662 DeleteObject(hrgn);
4663
4664 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
4665 expect(Ok, status);
4666 ret = GetRgnBox(hrgn, &rc);
4667 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4668 ok(rc.left == 210 && rc.top == 420 && rc.right == 410 && rc.bottom == 820,
4669 "expected 210,420-410,820, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4670 DeleteObject(hrgn);
4671
4672 ptf[0].X = 210.0;
4673 ptf[0].Y = 420.0;
4674 ptf[1].X = 410.0;
4675 ptf[1].Y = 820.0;
4676 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4677 expect(Ok, status);
4678 ok(ptf[0].X == 100.0 && ptf[0].Y == 100.0 && ptf[1].X == 200.0 && ptf[1].Y == 200.0,
4679 "expected 100.0,100.0-200.0,200.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4680
4681 status = GdipSetPageScale(graphics, 2.0);
4682 expect(Ok, status);
4683
4684 status = GdipGetClipBounds(graphics, &rect);
4685 expect(Ok, status);
4686 ok(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0,
4687 "expected 45.0,20.0-50.0,25.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4688
4689 status = GdipSetEmpty(region);
4690 expect(Ok, status);
4691 status = GdipGetClip(graphics, region);
4692 expect(Ok, status);
4693 status = GdipGetRegionBounds(region, graphics, &rect);
4694 expect(Ok, status);
4695 ok(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0,
4696 "expected 45.0,20.0-50.0,25.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4697
4698 status = GdipGetRegionBounds(region100x100, graphics, &rect);
4699 expect(Ok, status);
4700 ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0,
4701 "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4702
4703 status = GdipGetRegionHRgn(region, NULL, &hrgn);
4704 expect(Ok, status);
4705 ret = GetRgnBox(hrgn, &rc);
4706 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4707 ok(rc.left == 45 && rc.top == 20 && rc.right == 95 && rc.bottom == 45,
4708 "expected 45,20-95,45, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4709 DeleteObject(hrgn);
4710
4711 status = GdipGetRegionHRgn(region, graphics, &hrgn);
4712 expect(Ok, status);
4713 ret = GetRgnBox(hrgn, &rc);
4714 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4715 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4716 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4717 DeleteObject(hrgn);
4718
4719 ptf[0].X = 100.0;
4720 ptf[0].Y = 100.0;
4721 ptf[1].X = 200.0;
4722 ptf[1].Y = 200.0;
4723 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4724 expect(Ok, status);
4725 ok(ptf[0].X == 45.0 && ptf[0].Y == 20.0 && ptf[1].X == 95.0 && ptf[1].Y == 45.0,
4726 "expected 45.0,20.0-95.0,45.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4727
4728 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
4729 expect(Ok, status);
4730 ret = GetRgnBox(hrgn, &rc);
4731 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4732 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4733 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4734 DeleteObject(hrgn);
4735
4736 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
4737 expect(Ok, status);
4738 ret = GetRgnBox(hrgn, &rc);
4739 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4740 ok(rc.left == 210 && rc.top == 420 && rc.right == 410 && rc.bottom == 820,
4741 "expected 210,420-410,820, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4742 DeleteObject(hrgn);
4743
4744 ptf[0].X = 210.0;
4745 ptf[0].Y = 420.0;
4746 ptf[1].X = 410.0;
4747 ptf[1].Y = 820.0;
4748 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4749 expect(Ok, status);
4750 ok(ptf[0].X == 100.0 && ptf[0].Y == 100.0 && ptf[1].X == 200.0 && ptf[1].Y == 200.0,
4751 "expected 100.0,100.0-200.0,200.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4752
4753 GdipSetPageUnit(graphics, UnitPoint);
4754 expect(Ok, status);
4755
4756 status = GdipGetClipBounds(graphics, &rect);
4757 expect(Ok, status);
4758 ok((rect.X == 13.75 && rect.Y == 4.375 && rect.Width == 18.75 && rect.Height == 9.375) ||
4759 /* rounding under Wine is slightly different */
4760 (rect.X == 14.0 && rect.Y == 4.0 && rect.Width == 19.0 && rect.Height == 10.0) /* Wine */ ||
4761 broken(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0) /* before Win7 */,
4762 "expected 13.75,4.375-18.75,9.375, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4763
4764 status = GdipSetEmpty(region);
4765 expect(Ok, status);
4766 status = GdipGetClip(graphics, region);
4767 expect(Ok, status);
4768 status = GdipGetRegionBounds(region, graphics, &rect);
4769 expect(Ok, status);
4770 ok((rect.X == 13.75 && rect.Y == 4.375 && rect.Width == 18.75 && rect.Height == 9.375) ||
4771 /* rounding under Wine is slightly different */
4772 (rect.X == 14.0 && rect.Y == 4.0 && rect.Width == 19.0 && rect.Height == 10.0) /* Wine */ ||
4773 broken(rect.X == 45.0 && rect.Y == 20.0 && rect.Width == 50.0 && rect.Height == 25.0) /* before Win7 */,
4774 "expected 13.75,4.375-18.75,9.375, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4775
4776 status = GdipGetRegionBounds(region100x100, graphics, &rect);
4777 expect(Ok, status);
4778 ok(rect.X == 100.0 && rect.Y == 100.0 && rect.Width == 100.0 && rect.Height == 100.0,
4779 "expected 100.0,100.0-100.0,100.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4780
4781 status = GdipGetRegionHRgn(region, NULL, &hrgn);
4782 expect(Ok, status);
4783 ret = GetRgnBox(hrgn, &rc);
4784 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4785 ok((rc.left == 14 && rc.top == 5 && rc.right == 33 && rc.bottom == 14) ||
4786 /* rounding under Wine is slightly different */
4787 (rc.left == 14 && rc.top == 4 && rc.right == 33 && rc.bottom == 14) /* Wine */ ||
4788 broken(rc.left == 45 && rc.top == 20 && rc.right == 95 && rc.bottom == 45) /* before Win7 */,
4789 "expected 14,5-33,14, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4790 DeleteObject(hrgn);
4791
4792 status = GdipGetRegionHRgn(region, graphics, &hrgn);
4793 expect(Ok, status);
4794 ret = GetRgnBox(hrgn, &rc);
4795 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4796 ok((rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) ||
4797 broken(rc.left == 267 && rc.top == 267 && rc.right == 534 && rc.bottom == 534) /* before Win7 */,
4798 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4799 DeleteObject(hrgn);
4800
4801 ptf[0].X = 100.0;
4802 ptf[0].Y = 100.0;
4803 ptf[1].X = 200.0;
4804 ptf[1].Y = 200.0;
4805 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4806 expect(Ok, status);
4807 ok((ptf[0].X == 13.75 && ptf[0].Y == 4.375 && ptf[1].X == 32.5 && ptf[1].Y == 13.75) ||
4808 broken(ptf[0].X == 45.0 && ptf[0].Y == 20.0 && ptf[1].X == 95.0 && ptf[1].Y == 45.0) /* before Win7 */,
4809 "expected 13.75,4.375-32.5,13.75, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
4810
4811 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
4812 expect(Ok, status);
4813 ret = GetRgnBox(hrgn, &rc);
4814 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4815 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4816 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4817 DeleteObject(hrgn);
4818
4819 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
4820 expect(Ok, status);
4821 ret = GetRgnBox(hrgn, &rc);
4822 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4823 ok((rc.left == 560 && rc.top == 1120 && rc.right == 1094 && rc.bottom == 2187) ||
4824 /* rounding under Wine is slightly different */
4825 (rc.left == 560 && rc.top == 1120 && rc.right == 1093 && rc.bottom == 2187) /* Wine */,
4826 "expected 560,1120-1094,2187, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4827 DeleteObject(hrgn);
4828
4829 ptf[0].X = 560.0;
4830 ptf[0].Y = 1120.0;
4831 ptf[1].X = 1094.0;
4832 ptf[1].Y = 2187.0;
4833 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4834 expect(Ok, status);
4835 if (fabs(ptf[0].X - 100.0) < 0.001)
4836 {
4837 expectf(100.0, ptf[0].X);
4838 expectf(100.0, ptf[0].Y);
4839 expectf(200.125, ptf[1].X);
4840 expectf(200.03125, ptf[1].Y);
4841 }
4842 else /* before Win7 */
4843 {
4844 ok(broken(fabs(ptf[0].X - 275.0) < 0.001), "expected 275.0, got %f\n", ptf[0].X);
4845 ok(broken(fabs(ptf[0].Y - 275.0) < 0.001), "expected 275.0, got %f\n", ptf[0].Y);
4846 ok(broken(fabs(ptf[1].X - 542.0) < 0.001), "expected 542.0, got %f\n", ptf[1].X);
4847 ok(broken(fabs(ptf[1].Y - 541.75) < 0.001), "expected 541.75, got %f\n", ptf[1].Y);
4848 }
4849
4850 status = GdipTransformRegion(region100x100, matrix);
4851 expect(Ok, status);
4852
4853 status = GdipGetRegionBounds(region100x100, graphics, &rect);
4854 expect(Ok, status);
4855 ok(rect.X == 210.0 && rect.Y == 420.0 && rect.Width == 200.0 && rect.Height == 400.0,
4856 "expected 210.0,420.0-200.0,400.0, got %.2f,%.2f-%.2f,%.2f\n", rect.X, rect.Y, rect.Width, rect.Height);
4857
4858 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
4859 expect(Ok, status);
4860 ret = GetRgnBox(hrgn, &rc);
4861 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4862 ok(rc.left == 210 && rc.top == 420 && rc.right == 410 && rc.bottom == 820,
4863 "expected 210,420-410,820, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4864 DeleteObject(hrgn);
4865
4866 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
4867 expect(Ok, status);
4868 ret = GetRgnBox(hrgn, &rc);
4869 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4870 ok((rc.left == 1147 && rc.top == 4534 && rc.right == 2214 && rc.bottom == 8800) ||
4871 /* rounding under Wine is slightly different */
4872 (rc.left == 1147 && rc.top == 4533 && rc.right == 2213 && rc.bottom == 8800) /* Wine */,
4873 "expected 1147,4534-2214,8800, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4874 DeleteObject(hrgn);
4875
4876 ptf[0].X = 1147.0;
4877 ptf[0].Y = 4534.0;
4878 ptf[1].X = 2214.0;
4879 ptf[1].Y = 8800.0;
4880 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
4881 expect(Ok, status);
4882 if (fabs(ptf[0].X - 210.0625) < 0.001)
4883 {
4884 expectf(210.0625, ptf[0].X);
4885 expectf(420.0625, ptf[0].Y);
4886 expectf(410.125, ptf[1].X);
4887 expectf(820.0, ptf[1].Y);
4888 }
4889 else /* before Win7 */
4890 {
4891 ok(broken(fabs(ptf[0].X - 568.5) < 0.001), "expected 568.5, got %f\n", ptf[0].X);
4892 ok(broken(fabs(ptf[0].Y - 1128.5) < 0.001), "expected 1128.5, got %f\n", ptf[0].Y);
4893 ok(broken(fabs(ptf[1].X - 1102.0) < 0.001), "expected 1102.0, got %f\n", ptf[1].X);
4894 ok(broken(fabs(ptf[1].Y - 2195.0) < 0.001), "expected 2195.0, got %f\n", ptf[1].Y);
4895 }
4896
4897 status = GdipRotateMatrix(matrix, 30.0, MatrixOrderAppend);
4898 expect(Ok, status);
4899 status = GdipSetWorldTransform(graphics, matrix);
4900 expect(Ok, status);
4901
4902 status = GdipGetClipBounds(graphics, &rect);
4903 expect(Ok, status);
4904 expectf_(20.612978, rect.X, 1.0);
4905 expectf_(-6.256012, rect.Y, 1.5);
4906 expectf_(25.612978, rect.Width, 1.0);
4907 expectf_(12.806489, rect.Height, 1.0);
4908
4909 status = GdipSetEmpty(region);
4910 expect(Ok, status);
4911 status = GdipGetClip(graphics, region);
4912 expect(Ok, status);
4913 status = GdipGetRegionBounds(region, graphics, &rect);
4914 expect(Ok, status);
4915 /* rounding under Wine is slightly different */
4916 expectf_(20.612978, rect.X, 1.0);
4917 expectf_(-6.256012, rect.Y, 1.5);
4918 expectf_(25.612978, rect.Width, 1.0);
4919 expectf_(12.806489, rect.Height, 1.0);
4920
4921 status = GdipGetRegionBounds(region100x100, graphics, &rect);
4922 expect(Ok, status);
4923 ok(rect.X == 210.0 && rect.Y == 420.0 && rect.Width == 200.0 && rect.Height == 400.0,
4924 "expected 210.0,420.0-200.0,400.0, got %f,%f-%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);
4925
4926 status = GdipGetRegionHRgn(region, NULL, &hrgn);
4927 expect(Ok, status);
4928 ret = GetRgnBox(hrgn, &rc);
4929 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
4930 ok((rc.left == 22 && rc.top == -6 && rc.right == 46 && rc.bottom == 7) ||
4931 /* rounding under Wine is slightly different */
4932 (rc.left == 21 && rc.top == -5 && rc.right == 46 && rc.bottom == 7) /* Wine */,
4933 "expected (22,-6)-(46,7), got (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
4934 DeleteObject(hrgn);
4935
4936 status = GdipGetRegionHRgn(region, graphics, &hrgn);
4937 expect(Ok, status);
4938 ret = GetRgnBox(hrgn, &rc);
4939 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4940 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
4941 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4942 DeleteObject(hrgn);
4943
4944 ptf[0].X = 100.0;
4945 ptf[0].Y = 100.0;
4946 ptf[1].X = 200.0;
4947 ptf[1].Y = 200.0;
4948 ptf[2].X = 200.0;
4949 ptf[2].Y = 100.0;
4950 ptf[3].X = 100.0;
4951 ptf[3].Y = 200.0;
4952 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
4953 expect(Ok, status);
4954 expectf(20.612978, ptf[0].X);
4955 expectf(-1.568512, ptf[0].Y);
4956 expectf(46.225956, ptf[1].X);
4957 expectf(1.862977, ptf[1].Y);
4958 expectf(36.850956, ptf[2].X);
4959 expectf(-6.256012, ptf[2].Y);
4960 expectf(29.987980, ptf[3].X);
4961 expectf(6.550478, ptf[3].Y);
4962
4963 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
4964 expect(Ok, status);
4965 ret = GetRgnBox(hrgn, &rc);
4966 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
4967 ok(rc.left == 210 && rc.top == 420 && rc.right == 410 && rc.bottom == 820,
4968 "expected 210,420-410,820, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
4969 DeleteObject(hrgn);
4970
4971 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
4972 expect(Ok, status);
4973 ret = GetRgnBox(hrgn, &rc);
4974 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
4975 ok((rc.left == -3406 && rc.top == 4500 && rc.right == -350 && rc.bottom == 8728) ||
4976 /* rounding under Wine is slightly different */
4977 (rc.left == -3407 && rc.top == 4500 && rc.right == -350 && rc.bottom == 8728) /* Wine */,
4978 "expected (-3406,4500)-(-350,8728), got (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
4979 DeleteObject(hrgn);
4980
4981 ptf[0].X = -3406.0;
4982 ptf[0].Y = 4500.0;
4983 ptf[1].X = -350.0;
4984 ptf[1].Y = 8728.0;
4985 ptf[2].X = -350.0;
4986 ptf[2].Y = 4500.0;
4987 ptf[3].X = -3406.0;
4988 ptf[3].Y = 8728.0;
4989 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
4990 expect(Ok, status);
4991 expectf(-136.190491, ptf[0].X);
4992 expectf(520.010742, ptf[0].Y);
4993 expectf(756.417175, ptf[1].X);
4994 expectf(720.031616, ptf[1].Y);
4995 expectf(360.042114, ptf[2].X);
4996 expectf(376.760742, ptf[2].Y);
4997 expectf(260.184570, ptf[3].X);
4998 expectf(863.281616, ptf[3].Y);
4999
5000 status = GdipRotateMatrix(matrix, -90.0, MatrixOrderAppend);
5001 expect(Ok, status);
5002 status = GdipSetWorldTransform(graphics, matrix);
5003 expect(Ok, status);
5004
5005 status = GdipGetClipBounds(graphics, &rect);
5006 expect(Ok, status);
5007 expectf_(-28.100956, rect.X, 1.0);
5008 expectf_(7.806488, rect.Y, 1.5);
5009 expectf_(25.612978, rect.Width, 1.0);
5010 expectf_(12.806489, rect.Height, 1.0);
5011
5012 status = GdipSetEmpty(region);
5013 expect(Ok, status);
5014 status = GdipGetClip(graphics, region);
5015 expect(Ok, status);
5016 status = GdipGetRegionBounds(region, graphics, &rect);
5017 expect(Ok, status);
5018 /* rounding under Wine is slightly different */
5019 expectf_(-28.100956, rect.X, 1.0);
5020 expectf_(7.806488, rect.Y, 1.5);
5021 expectf_(25.612978, rect.Width, 1.0);
5022 expectf_(12.806489, rect.Height, 1.0);
5023
5024 status = GdipGetRegionBounds(region100x100, graphics, &rect);
5025 expect(Ok, status);
5026 ok(rect.X == 210.0 && rect.Y == 420.0 && rect.Width == 200.0 && rect.Height == 400.0,
5027 "expected 210.0,420.0-200.0,400.0, got %f,%f-%f,%f\n", rect.X, rect.Y, rect.Width, rect.Height);
5028
5029 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5030 expect(Ok, status);
5031 ret = GetRgnBox(hrgn, &rc);
5032 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
5033 ok((rc.left == -27 && rc.top == 8 && rc.right == -2 && rc.bottom == 21) ||
5034 /* rounding under Wine is slightly different */
5035 (rc.left == -28 && rc.top == 9 && rc.right == -2 && rc.bottom == 21) /* Wine */,
5036 "expected (-27,8)-(-2,21), got (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
5037 DeleteObject(hrgn);
5038
5039 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5040 expect(Ok, status);
5041 ret = GetRgnBox(hrgn, &rc);
5042 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5043 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5044 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5045 DeleteObject(hrgn);
5046
5047 ptf[0].X = 100.0;
5048 ptf[0].Y = 100.0;
5049 ptf[1].X = 200.0;
5050 ptf[1].Y = 200.0;
5051 ptf[2].X = 200.0;
5052 ptf[2].Y = 100.0;
5053 ptf[3].X = 100.0;
5054 ptf[3].Y = 200.0;
5055 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
5056 expect(Ok, status);
5057 expectf(-11.862979, ptf[0].X);
5058 expectf(7.806488, ptf[0].Y);
5059 expectf(-18.725958, ptf[1].X);
5060 expectf(20.612976, ptf[1].Y);
5061 expectf(-2.487981, ptf[2].X);
5062 expectf(15.925477, ptf[2].Y);
5063 expectf(-28.100956, ptf[3].X);
5064 expectf(12.493987, ptf[3].Y);
5065
5066 status = GdipGetRegionHRgn(region100x100, NULL, &hrgn);
5067 expect(Ok, status);
5068 ret = GetRgnBox(hrgn, &rc);
5069 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5070 ok(rc.left == 210 && rc.top == 420 && rc.right == 410 && rc.bottom == 820,
5071 "expected 210,420-410,820, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5072 DeleteObject(hrgn);
5073
5074 status = GdipGetRegionHRgn(region100x100, graphics, &hrgn);
5075 expect(Ok, status);
5076 ret = GetRgnBox(hrgn, &rc);
5077 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
5078 ok((rc.left == 4500 && rc.top == 351 && rc.right == 8728 && rc.bottom == 3407) ||
5079 /* rounding under Wine is slightly different */
5080 (rc.left == 4499 && rc.top == 351 && rc.right == 8728 && rc.bottom == 3407) /* Wine */,
5081 "expected (4500,351)-(8728,3407), got (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
5082 DeleteObject(hrgn);
5083
5084 ptf[0].X = -3406.0;
5085 ptf[0].Y = 4500.0;
5086 ptf[1].X = -350.0;
5087 ptf[1].Y = 8728.0;
5088 ptf[2].X = -350.0;
5089 ptf[2].Y = 4500.0;
5090 ptf[3].X = -3406.0;
5091 ptf[3].Y = 8728.0;
5092 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
5093 expect(Ok, status);
5094 expectf(-1055.021484, ptf[0].X);
5095 expectf(-70.595329, ptf[0].Y);
5096 expectf(-1455.063232, ptf[1].X);
5097 expectf(375.708435, ptf[1].Y);
5098 expectf(-768.521484, ptf[2].X);
5099 expectf(177.520981, ptf[2].Y);
5100 expectf(-1741.563110, ptf[3].X);
5101 expectf(127.592125, ptf[3].Y);
5102
5103 GdipDeleteMatrix(matrix);
5104 GdipDeleteRegion(region);
5105 GdipDeleteRegion(region100x100);
5106 GdipDeleteGraphics(graphics);
5107 DeleteDC(hdc);
5108 }
5109
5110 static void test_clipping_2(void)
5111 {
5112
5113 HDC hdc;
5114 GpStatus status;
5115 GpGraphics *graphics;
5116 GpRegion *region;
5117 GpMatrix *matrix;
5118 GpRectF rect;
5119 GpPointF ptf[4];
5120 GpUnit unit;
5121 HRGN hrgn;
5122 int ret;
5123 RECT rc;
5124
5125 hdc = CreateCompatibleDC(0);
5126 status = GdipCreateFromHDC(hdc, &graphics);
5127 expect(Ok, status);
5128
5129 status = GdipGetPageUnit(graphics, &unit);
5130 expect(Ok, status);
5131 expect(UnitDisplay, unit);
5132
5133 GdipSetPageUnit(graphics, UnitInch);
5134
5135 status = GdipCreateRegion(&region);
5136 expect(Ok, status);
5137 status = GdipSetEmpty(region);
5138 expect(Ok, status);
5139 rect.X = rect.Y = 100.0;
5140 rect.Width = rect.Height = 100.0;
5141 status = GdipCombineRegionRect(region, &rect, CombineModeUnion);
5142 expect(Ok, status);
5143 status = GdipSetClipRegion(graphics, region, CombineModeReplace);
5144 expect(Ok, status);
5145
5146 status = GdipGetClip(graphics, region);
5147 expect(Ok, status);
5148 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5149 expect(Ok, status);
5150 ret = GetRgnBox(hrgn, &rc);
5151 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5152 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5153 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5154 DeleteObject(hrgn);
5155 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5156 expect(Ok, status);
5157 ret = GetRgnBox(hrgn, &rc);
5158 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5159 ok(rc.left == 9600 && rc.top == 9600 && rc.right == 19200 && rc.bottom == 19200,
5160 "expected 9600,9600-19200,19200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5161 DeleteObject(hrgn);
5162
5163 ptf[0].X = 9600.0;
5164 ptf[0].Y = 9600.0;
5165 ptf[1].X = 19200.0;
5166 ptf[1].Y = 19200.0;
5167 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5168 expect(Ok, status);
5169 expectf(100.0, ptf[0].X);
5170 expectf(100.0, ptf[0].Y);
5171 expectf(200.0, ptf[1].X);
5172 expectf(200.0, ptf[1].X);
5173
5174 GdipSetPageUnit(graphics, UnitPoint);
5175
5176 status = GdipGetClip(graphics, region);
5177 expect(Ok, status);
5178 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5179 expect(Ok, status);
5180 ret = GetRgnBox(hrgn, &rc);
5181 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5182 ok((rc.left == 7200 && rc.top == 7200 && rc.right == 14400 && rc.bottom == 14400) ||
5183 broken(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) /* before Win7 */,
5184 "expected 7200,7200-14400,14400, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5185 DeleteObject(hrgn);
5186 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5187 expect(Ok, status);
5188 ret = GetRgnBox(hrgn, &rc);
5189 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5190 ok((rc.left == 9600 && rc.top == 9600 && rc.right == 19200 && rc.bottom == 19200) ||
5191 broken(rc.left == 134 && rc.top == 134 && rc.right == 267 && rc.bottom == 267) /* before Win7 */,
5192 "expected 9600,9600-19200,19200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5193 DeleteObject(hrgn);
5194
5195 ptf[0].X = 9600.0;
5196 ptf[0].Y = 9600.0;
5197 ptf[1].X = 19200.0;
5198 ptf[1].Y = 19200.0;
5199 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5200 expect(Ok, status);
5201 if (fabs(ptf[0].X - 7200.0) < 0.001)
5202 ok(ptf[0].X == 7200.0 && ptf[0].Y == 7200.0 && ptf[1].X == 14400.0 && ptf[1].Y == 14400.0,
5203 "expected 7200.0,7200.0-14400.0,14400.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
5204 else /* before Win7 */
5205 {
5206 ok(broken(fabs(ptf[0].X - 100.0) < 0.001), "expected 100.0, got %f\n", ptf[0].X);
5207 ok(broken(fabs(ptf[0].Y - 100.0) < 0.001), "expected 100.0, got %f\n", ptf[0].Y);
5208 ok(broken(fabs(ptf[1].X - 200.0) < 0.001), "expected 200.0, got %f\n", ptf[1].X);
5209 ok(broken(fabs(ptf[1].Y - 200.0) < 0.001), "expected 200.0, got %f\n", ptf[1].Y);
5210 }
5211
5212 GdipDeleteRegion(region);
5213
5214 GdipSetPageUnit(graphics, UnitPixel);
5215
5216 status = GdipCreateRegion(&region);
5217 expect(Ok, status);
5218 status = GdipSetEmpty(region);
5219 expect(Ok, status);
5220 rect.X = rect.Y = 100.0;
5221 rect.Width = rect.Height = 100.0;
5222 status = GdipCombineRegionRect(region, &rect, CombineModeUnion);
5223 expect(Ok, status);
5224 status = GdipSetClipRegion(graphics, region, CombineModeReplace);
5225 expect(Ok, status);
5226
5227 status = GdipGetClip(graphics, region);
5228 expect(Ok, status);
5229 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5230 expect(Ok, status);
5231 ret = GetRgnBox(hrgn, &rc);
5232 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5233 ok((rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) ||
5234 broken(rc.left == 2 && rc.top == 2 && rc.right == 3 && rc.bottom == 3) /* before Win7 */,
5235 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5236 DeleteObject(hrgn);
5237 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5238 expect(Ok, status);
5239 ret = GetRgnBox(hrgn, &rc);
5240 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5241 ok((rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) ||
5242 broken(rc.left == 2 && rc.top == 2 && rc.right == 3 && rc.bottom == 3) /* before Win7 */,
5243 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5244 DeleteObject(hrgn);
5245
5246 ptf[0].X = 100.0;
5247 ptf[0].Y = 100.0;
5248 ptf[1].X = 200.0;
5249 ptf[1].Y = 200.0;
5250 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5251 expect(Ok, status);
5252 if (fabs(ptf[0].X - 100.0) < 0.001)
5253 ok(ptf[0].X == 100.0 && ptf[0].Y == 100.0 && ptf[1].X == 200.0 && ptf[1].Y == 200.0,
5254 "expected 100.0,100.0-200.0,200.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
5255 else /* before Win7 */
5256 {
5257 ok(broken(fabs(ptf[0].X - 1.041667) < 0.001), "expected 1.041667, got %f\n", ptf[0].X);
5258 ok(broken(fabs(ptf[0].Y - 1.041667) < 0.001), "expected 1.041667, got %f\n", ptf[0].Y);
5259 ok(broken(fabs(ptf[1].X - 2.083333) < 0.001), "expected 2.083333, got %f\n", ptf[1].X);
5260 ok(broken(fabs(ptf[1].Y - 2.083333) < 0.001), "expected 2.083333, got %f\n", ptf[1].Y);
5261 }
5262
5263 GdipSetPageUnit(graphics, UnitPoint);
5264
5265 status = GdipGetClip(graphics, region);
5266 expect(Ok, status);
5267 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5268 expect(Ok, status);
5269 ret = GetRgnBox(hrgn, &rc);
5270 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5271 ok((rc.left == 75 && rc.top == 75 && rc.right == 150 && rc.bottom == 150) ||
5272 broken(rc.left == 2 && rc.top == 2 && rc.right == 3 && rc.bottom == 3) /* before Win7 */,
5273 "expected 75,75-150,150, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5274 DeleteObject(hrgn);
5275 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5276 expect(Ok, status);
5277 ret = GetRgnBox(hrgn, &rc);
5278 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5279 ok((rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) ||
5280 broken(rc.left == 2 && rc.top == 2 && rc.right == 3 && rc.bottom == 3) /* before Win7 */,
5281 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5282 DeleteObject(hrgn);
5283
5284 ptf[0].X = 100.0;
5285 ptf[0].Y = 100.0;
5286 ptf[1].X = 200.0;
5287 ptf[1].Y = 200.0;
5288 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5289 expect(Ok, status);
5290 if (fabs(ptf[0].X - 75.0) < 0.001)
5291 ok(ptf[0].X == 75.0 && ptf[0].Y == 75.0 && ptf[1].X == 150.0 && ptf[1].Y == 150.0,
5292 "expected 75.0,75.0-150.0,150.0, got %f,%f-%f,%f\n", ptf[0].X, ptf[0].Y, ptf[1].X, ptf[1].Y);
5293 else /* before Win7 */
5294 {
5295 ok(broken(fabs(ptf[0].X - 1.041667) < 0.001), "expected 1.041667, got %f\n", ptf[0].X);
5296 ok(broken(fabs(ptf[0].Y - 1.041667) < 0.001), "expected 1.041667, got %f\n", ptf[0].Y);
5297 ok(broken(fabs(ptf[1].X - 2.083333) < 0.001), "expected 2.083333, got %f\n", ptf[1].X);
5298 ok(broken(fabs(ptf[1].Y - 2.083333) < 0.001), "expected 2.083333, got %f\n", ptf[1].Y);
5299 }
5300
5301 status = GdipCreateMatrix(&matrix);
5302 expect(Ok, status);
5303 status = GdipTranslateMatrix(matrix, 10.0, 10.0, MatrixOrderAppend);
5304 expect(Ok, status);
5305 status = GdipSetWorldTransform(graphics, matrix);
5306 expect(Ok, status);
5307 GdipDeleteMatrix(matrix);
5308
5309 status = GdipGetClip(graphics, region);
5310 expect(Ok, status);
5311 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5312 expect(Ok, status);
5313 ret = GetRgnBox(hrgn, &rc);
5314 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5315 ok(rc.left == 65 && rc.top == 65 && rc.right == 140 && rc.bottom == 140,
5316 "expected 65,65-140,140, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5317 DeleteObject(hrgn);
5318 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5319 expect(Ok, status);
5320 ret = GetRgnBox(hrgn, &rc);
5321 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5322 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5323 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5324 DeleteObject(hrgn);
5325
5326 ptf[0].X = 100.0;
5327 ptf[0].Y = 100.0;
5328 ptf[1].X = 200.0;
5329 ptf[1].Y = 200.0;
5330 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5331 expect(Ok, status);
5332 expectf(65.0, ptf[0].X);
5333 expectf(65.0, ptf[0].Y);
5334 expectf(140.0, ptf[1].X);
5335 expectf(140.0, ptf[1].X);
5336
5337 status = GdipCreateMatrix(&matrix);
5338 expect(Ok, status);
5339 status = GdipScaleMatrix(matrix, 0.25, 0.5, MatrixOrderAppend);
5340 expect(Ok, status);
5341 status = GdipSetWorldTransform(graphics, matrix);
5342 expect(Ok, status);
5343 GdipDeleteMatrix(matrix);
5344
5345 status = GdipGetClip(graphics, region);
5346 expect(Ok, status);
5347 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5348 expect(Ok, status);
5349 ret = GetRgnBox(hrgn, &rc);
5350 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5351 ok(rc.left == 300 && rc.top == 150 && rc.right == 600 && rc.bottom == 300,
5352 "expected 300,150-600,300, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5353 DeleteObject(hrgn);
5354 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5355 expect(Ok, status);
5356 ret = GetRgnBox(hrgn, &rc);
5357 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5358 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5359 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5360 DeleteObject(hrgn);
5361
5362 ptf[0].X = 100.0;
5363 ptf[0].Y = 100.0;
5364 ptf[1].X = 200.0;
5365 ptf[1].Y = 200.0;
5366 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5367 expect(Ok, status);
5368 expectf(300.0, ptf[0].X);
5369 expectf(150.0, ptf[0].Y);
5370 expectf(600.0, ptf[1].X);
5371 expectf(300.0, ptf[1].Y);
5372
5373 status = GdipSetPageScale(graphics, 2.0);
5374 expect(Ok, status);
5375
5376 status = GdipGetClip(graphics, region);
5377 expect(Ok, status);
5378 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5379 expect(Ok, status);
5380 ret = GetRgnBox(hrgn, &rc);
5381 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5382 ok((rc.left == 150 && rc.top == 75 && rc.right == 300 && rc.bottom == 150) ||
5383 broken(rc.left == 300 && rc.top == 150 && rc.right == 600 && rc.bottom == 300) /* before Win7 */,
5384 "expected 150,75-300,150, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5385 DeleteObject(hrgn);
5386 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5387 expect(Ok, status);
5388 ret = GetRgnBox(hrgn, &rc);
5389 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5390 ok((rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200) ||
5391 broken(rc.left == 200 && rc.top == 200 && rc.right == 400 && rc.bottom == 400) /* before Win7 */,
5392 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5393 DeleteObject(hrgn);
5394
5395 ptf[0].X = 100.0;
5396 ptf[0].Y = 100.0;
5397 ptf[1].X = 200.0;
5398 ptf[1].Y = 200.0;
5399 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2);
5400 expect(Ok, status);
5401 if (fabs(ptf[0].X - 150.0) < 0.001)
5402 {
5403 expectf(150.0, ptf[0].X);
5404 expectf(75.0, ptf[0].Y);
5405 expectf(300.0, ptf[1].X);
5406 expectf(150.0, ptf[1].Y);
5407 }
5408 else /* before Win7 */
5409 {
5410 ok(broken(fabs(ptf[0].X - 300.0) < 0.001), "expected 300.0, got %f\n", ptf[0].X);
5411 ok(broken(fabs(ptf[0].Y - 150.0) < 0.001), "expected 150.0, got %f\n", ptf[0].Y);
5412 ok(broken(fabs(ptf[1].X - 600.0) < 0.001), "expected 600.0, got %f\n", ptf[1].X);
5413 ok(broken(fabs(ptf[1].Y - 300.0) < 0.001), "expected 300.0, got %f\n", ptf[1].Y);
5414 }
5415
5416 status = GdipCreateMatrix(&matrix);
5417 expect(Ok, status);
5418 status = GdipRotateMatrix(matrix, 45.0, MatrixOrderAppend);
5419 expect(Ok, status);
5420 status = GdipSetWorldTransform(graphics, matrix);
5421 expect(Ok, status);
5422 GdipDeleteMatrix(matrix);
5423
5424 status = GdipGetClip(graphics, region);
5425 expect(Ok, status);
5426 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5427 expect(Ok, status);
5428 ret = GetRgnBox(hrgn, &rc);
5429 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
5430 ok((rc.left == 54 && rc.top == -26 && rc.right == 107 && rc.bottom == 27) ||
5431 /* rounding under Wine is slightly different */
5432 (rc.left == 53 && rc.top == -26 && rc.right == 106 && rc.bottom == 27) /* Wine */,
5433 "expected 54,-26-107,27, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5434 DeleteObject(hrgn);
5435 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5436 expect(Ok, status);
5437 ret = GetRgnBox(hrgn, &rc);
5438 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5439 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5440 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5441 DeleteObject(hrgn);
5442
5443 ptf[0].X = 100.0;
5444 ptf[0].Y = 100.0;
5445 ptf[1].X = 200.0;
5446 ptf[1].Y = 200.0;
5447 ptf[2].X = 200.0;
5448 ptf[2].Y = 100.0;
5449 ptf[3].X = 100.0;
5450 ptf[3].Y = 200.0;
5451 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
5452 expect(Ok, status);
5453 expectf(53.033016, ptf[0].X);
5454 expectf(0.0, ptf[0].Y);
5455 expectf(106.066032, ptf[1].X);
5456 expectf(0.0, ptf[1].Y);
5457 expectf(79.549522, ptf[2].X);
5458 expectf(-26.516510, ptf[2].Y);
5459 expectf(79.549522, ptf[3].X);
5460 expectf(26.516508, ptf[3].Y);
5461
5462 status = GdipCreateMatrix(&matrix);
5463 expect(Ok, status);
5464 status = GdipRotateMatrix(matrix, -45.0, MatrixOrderAppend);
5465 expect(Ok, status);
5466 status = GdipSetWorldTransform(graphics, matrix);
5467 expect(Ok, status);
5468 GdipDeleteMatrix(matrix);
5469
5470 status = GdipGetClip(graphics, region);
5471 expect(Ok, status);
5472 status = GdipGetRegionHRgn(region, NULL, &hrgn);
5473 expect(Ok, status);
5474 ret = GetRgnBox(hrgn, &rc);
5475 ok(ret == COMPLEXREGION, "expected COMPLEXREGION, got %d\n", ret);
5476 ok((rc.left == -26 && rc.top == 54 && rc.right == 27 && rc.bottom == 107) ||
5477 /* rounding under Wine is slightly different */
5478 (rc.left == -27 && rc.top == 54 && rc.right == 27 && rc.bottom == 106) /* Wine */,
5479 "expected -26,54-27,107, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5480 DeleteObject(hrgn);
5481 status = GdipGetRegionHRgn(region, graphics, &hrgn);
5482 expect(Ok, status);
5483 ret = GetRgnBox(hrgn, &rc);
5484 ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
5485 ok(rc.left == 100 && rc.top == 100 && rc.right == 200 && rc.bottom == 200,
5486 "expected 100,100-200,200, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
5487 DeleteObject(hrgn);
5488
5489 ptf[0].X = 100.0;
5490 ptf[0].Y = 100.0;
5491 ptf[1].X = 200.0;
5492 ptf[1].Y = 200.0;
5493 ptf[2].X = 200.0;
5494 ptf[2].Y = 100.0;
5495 ptf[3].X = 100.0;
5496 ptf[3].Y = 200.0;
5497 status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 4);
5498 expect(Ok, status);
5499 expectf(0.0, ptf[0].X);
5500 expectf(53.033005, ptf[0].Y);
5501 expectf(0.0, ptf[1].X);
5502 expectf(106.066010, ptf[1].Y);
5503 expectf(26.516491, ptf[2].X);
5504 expectf(79.549507, ptf[2].Y);
5505 expectf(-26.516520, ptf[3].X);
5506 expectf(79.549500, ptf[3].Y);
5507
5508 GdipDeleteRegion(region);
5509 GdipDeleteGraphics(graphics);
5510 DeleteDC(hdc);
5511 }
5512
5513
5514 static void test_GdipFillRectangles(void)
5515 {
5516 GpStatus status;
5517 GpGraphics *graphics = NULL;
5518 GpBrush *brush = NULL;
5519 HDC hdc = GetDC( hwnd );
5520 GpRectF rects[2] = {{0,0,10,10}, {10,10,10,10}};
5521
5522 ok(hdc != NULL, "Expected HDC to be initialized\n");
5523
5524 status = GdipCreateFromHDC(hdc, &graphics);
5525 expect(Ok, status);
5526 ok(graphics != NULL, "Expected graphics to be initialized\n");
5527
5528 status = GdipCreateSolidFill((ARGB)0xffff00ff, (GpSolidFill**)&brush);
5529 expect(Ok, status);
5530 ok(brush != NULL, "Expected brush to be initialized\n");
5531
5532 status = GdipFillRectangles(NULL, brush, rects, 2);
5533 expect(InvalidParameter, status);
5534
5535 status = GdipFillRectangles(graphics, NULL, rects, 2);
5536 expect(InvalidParameter, status);
5537
5538 status = GdipFillRectangles(graphics, brush, NULL, 2);
5539 expect(InvalidParameter, status);
5540
5541 status = GdipFillRectangles(graphics, brush, rects, 0);
5542 expect(InvalidParameter, status);
5543
5544 status = GdipFillRectangles(graphics, brush, rects, -1);
5545 expect(InvalidParameter, status);
5546
5547 status = GdipFillRectangles(graphics, brush, rects, 1);
5548 expect(Ok, status);
5549
5550 status = GdipFillRectangles(graphics, brush, rects, 2);
5551 expect(Ok, status);
5552
5553 GdipDeleteBrush(brush);
5554 GdipDeleteGraphics(graphics);
5555
5556 ReleaseDC(hwnd, hdc);
5557 }
5558
5559 START_TEST(graphics)
5560 {
5561 struct GdiplusStartupInput gdiplusStartupInput;
5562 ULONG_PTR gdiplusToken;
5563 WNDCLASSA class;
5564
5565 memset( &class, 0, sizeof(class) );
5566 class.lpszClassName = "gdiplus_test";
5567 class.style = CS_HREDRAW | CS_VREDRAW;
5568 class.lpfnWndProc = DefWindowProcA;
5569 class.hInstance = GetModuleHandleA(0);
5570 class.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
5571 class.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
5572 class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
5573 RegisterClassA( &class );
5574 hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5575 CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, 0, 0, GetModuleHandleA(0), 0 );
5576 ok(hwnd != NULL, "Expected window to be created\n");
5577
5578 gdiplusStartupInput.GdiplusVersion = 1;
5579 gdiplusStartupInput.DebugEventCallback = NULL;
5580 gdiplusStartupInput.SuppressBackgroundThread = 0;
5581 gdiplusStartupInput.SuppressExternalCodecs = 0;
5582
5583 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
5584
5585 test_clipping();
5586 test_clipping_2();
5587 test_measured_extra_space();
5588 test_measure_string();
5589 test_font_height_scaling();
5590 test_transform();
5591 test_GdipMeasureString();
5592 test_constructor_destructor();
5593 test_save_restore();
5594 test_GdipFillClosedCurve2();
5595 test_GdipFillClosedCurve2I();
5596 test_GdipDrawBezierI();
5597 test_GdipDrawArc();
5598 test_GdipDrawArcI();
5599 test_GdipDrawCurve();
5600 test_GdipDrawCurveI();
5601 test_GdipDrawCurve2();
5602 test_GdipDrawCurve2I();
5603 test_GdipDrawCurve3();
5604 test_GdipDrawCurve3I();
5605 test_GdipDrawLineI();
5606 test_GdipDrawLinesI();
5607 test_GdipDrawImagePointsRect();
5608 test_GdipFillClosedCurve();
5609 test_GdipFillClosedCurveI();
5610 test_GdipDrawString();
5611 test_GdipGetNearestColor();
5612 test_GdipGetVisibleClipBounds();
5613 test_GdipIsVisiblePoint();
5614 test_GdipIsVisibleRect();
5615 test_Get_Release_DC();
5616 test_BeginContainer2();
5617 test_transformpoints();
5618 test_get_set_clip();
5619 test_isempty();
5620 test_clear();
5621 test_textcontrast();
5622 test_fromMemoryBitmap();
5623 #if CORE_6659_IS_FIXED
5624 test_string_functions();
5625 #endif
5626 test_get_set_interpolation();
5627 test_get_set_textrenderinghint();
5628 test_getdc_scaled();
5629 test_alpha_hdc();
5630 test_bitmapfromgraphics();
5631 test_GdipFillRectangles();
5632
5633 GdiplusShutdown(gdiplusToken);
5634 DestroyWindow( hwnd );
5635 }