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