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