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