ReactOS  0.4.12-dev-432-g3463b2d
graphics.c
Go to the documentation of this file.
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 */
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 */
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 
91 {
93  return pixels_to_units(pixels, to, dpi);
94 }
95 
97 {
99  union
100  {
101  GpBitmap *bitmap;
102  GpImage *image;
103  } u;
105  REAL res;
106 
108  expect(Ok, status);
109 
110  status = GdipBitmapSetResolution(u.bitmap, res_x, res_y);
111  expect(Ok, status);
113  expect(Ok, status);
114  expectf(res_x, res);
116  expect(Ok, status);
117  expectf(res_y, res);
118 
120  expect(Ok, status);
121 
122  *image = u.image;
123 
125  expect(Ok, status);
126  expectf(res_x, res);
128  expect(Ok, status);
129  expectf(res_y, res);
130 
132  expect(Ok, status);
134  expect(Ok, status);
135 
136  return graphics;
137 }
138 
140 {
141  GpStatus stat;
143  HDC hdc = GetDC( hwnd );
144 
149 
151  expect(Ok, stat);
153  expect(Ok, stat);
154 
156  expect(Ok, stat);
158  expect(Ok, stat);
159 
161  expect(Ok, stat);
163  expect(Ok, stat);
164 
167  ReleaseDC(hwnd, hdc);
168 }
169 
170 typedef struct node{
172  struct node * next;
173 } node;
174 
175 /* Linked list prepend function. */
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. */
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;
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;
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);
233  stat = GdipSaveGraphics(NULL, &state_a);
235  GdipDeleteGraphics(graphics1);
236 
237  log_state(state_a, &state_log);
238 
239  /* Basic save/restore. */
240  GdipCreateFromHDC(hdc, &graphics1);
242  stat = GdipSaveGraphics(graphics1, &state_a);
243  expect(Ok, stat);
245  stat = GdipRestoreGraphics(graphics1, state_a);
246  expect(Ok, stat);
247  GdipGetInterpolationMode(graphics1, &mode);
249  GdipDeleteGraphics(graphics1);
250 
251  log_state(state_a, &state_log);
252 
253  /* Restoring garbage doesn't affect saves. */
254  GdipCreateFromHDC(hdc, &graphics1);
256  GdipSaveGraphics(graphics1, &state_a);
258  GdipSaveGraphics(graphics1, &state_b);
260  stat = GdipRestoreGraphics(graphics1, 0xdeadbeef);
261  expect(Ok, stat);
262  GdipRestoreGraphics(graphics1, state_b);
263  GdipGetInterpolationMode(graphics1, &mode);
265  GdipRestoreGraphics(graphics1, state_a);
266  GdipGetInterpolationMode(graphics1, &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);
276  GdipSaveGraphics(graphics1, &state_a);
278  GdipSaveGraphics(graphics1, &state_b);
280  GdipSaveGraphics(graphics1, &state_c);
282  GdipRestoreGraphics(graphics1, state_b);
283  GdipGetInterpolationMode(graphics1, &mode);
285  GdipRestoreGraphics(graphics1, state_c);
286  GdipGetInterpolationMode(graphics1, &mode);
288  GdipRestoreGraphics(graphics1, state_a);
289  GdipGetInterpolationMode(graphics1, &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);
302  GdipSaveGraphics(graphics1, &state_a);
304  GdipSaveGraphics(graphics2, &state_b);
307  GdipRestoreGraphics(graphics1, state_a);
308  GdipGetInterpolationMode(graphics1, &mode);
310  GdipRestoreGraphics(graphics2, state_b);
311  GdipGetInterpolationMode(graphics2, &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);
320  GdipSaveGraphics(graphics1, &state_a);
323  GdipRestoreGraphics(graphics2, state_a);
324  GdipGetInterpolationMode(graphics2, &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);
334  stat = GdipSaveGraphics(graphics1, &state_a);
335  expect(Ok, stat);
337  stat = GdipEndContainer(graphics1, state_a);
338  expect(Ok, stat);
339  GdipGetInterpolationMode(graphics1, &mode);
341  stat = GdipRestoreGraphics(graphics1, state_a);
342  expect(Ok, stat);
343  GdipGetInterpolationMode(graphics1, &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);
352  stat = GdipBeginContainer2(graphics1, &state_a);
353  expect(Ok, stat);
355  stat = GdipRestoreGraphics(graphics1, state_a);
356  expect(Ok, stat);
357  GdipGetInterpolationMode(graphics1, &mode);
359  stat = GdipEndContainer(graphics1, state_a);
360  expect(Ok, stat);
361  GdipGetInterpolationMode(graphics1, &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);
371  stat = GdipBeginContainer2(graphics1, &state_a);
372  expect(Ok, stat);
374  stat = GdipSaveGraphics(graphics1, &state_b);
375  expect(Ok, stat);
377  stat = GdipEndContainer(graphics1, state_a);
378  expect(Ok, stat);
379  GdipGetInterpolationMode(graphics1, &mode);
381  stat = GdipRestoreGraphics(graphics1, state_b);
382  expect(Ok, stat);
383  GdipGetInterpolationMode(graphics1, &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 {
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 */
426 
427  status = GdipFillClosedCurve2(graphics, NULL, NULL, 3, 0.5, FillModeAlternate);
429 
432 
435 
436  status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, NULL, 3, 0.5, FillModeAlternate);
438 
441 
444 
445  /* InvalidParameter cases: invalid count */
446  status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
448 
449  status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
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 {
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 */
499 
502 
505 
506  /* InvalidParameter cases: invalid count */
507  status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, 0, 0.5, FillModeAlternate);
509 
510  /* OutOfMemory cases: large (unsigned) int */
511  status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, points, -1, 0.5, FillModeAlternate);
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 {
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);
551 
552  status = GdipDrawArc(graphics, NULL, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
554 
555  status = GdipDrawArc(NULL, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
557 
558  status = GdipDrawArc(graphics, pen, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
560 
561  status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
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 {
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);
595 
596  status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
598 
599  status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
601 
602  status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
604 
605  status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
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 {
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;
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 
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);
648 
649  status = GdipBeginContainer2(graphics, NULL);
651 
652  status = GdipEndContainer(NULL, cont1);
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 
672  GdipSetPageScale(graphics, 10);
673  GdipSetPageUnit(graphics, UnitDocument);
676  GdipSetTextContrast(graphics, 7);
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);
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);
727  transform = NULL;
728 
729  status = GdipEndContainer(graphics, cont2);
730  expect(Ok, status);
731 
733  expect(Ok, status);
734  GdipGetWorldTransform(graphics, transform);
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]);
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 {
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);
832 
833  status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
835 
836  status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
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 {
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);
880 
881  status = GdipDrawCurve3(graphics, NULL, points, 3, 0, 2, 1);
883 
884  status = GdipDrawCurve3(NULL, pen, points, 3, 0, 2, 1);
886 
887  /* InvalidParameter cases: invalid count */
888  status = GdipDrawCurve3(graphics, pen, points, -1, 0, 2, 1);
890 
891  status = GdipDrawCurve3(graphics, pen, points, 0, 0, 2, 1);
893 
894  status = GdipDrawCurve3(graphics, pen, points, 1, 0, 0, 1);
896 
897  status = GdipDrawCurve3(graphics, pen, points, 3, 4, 2, 1);
899 
900  /* InvalidParameter cases: invalid number of segments */
901  status = GdipDrawCurve3(graphics, pen, points, 3, 0, -1, 1);
903 
904  status = GdipDrawCurve3(graphics, pen, points, 3, 1, 2, 1);
906 
907  status = GdipDrawCurve3(graphics, pen, points, 2, 0, 2, 1);
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 {
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);
960 
961  status = GdipDrawCurve3I(graphics, NULL, points, 3, 0, 2, 1);
963 
964  status = GdipDrawCurve3I(NULL, pen, points, 3, 0, 2, 1);
966 
967  /* InvalidParameter cases: invalid count */
968  status = GdipDrawCurve3I(graphics, pen, points, -1, -1, -1, 1);
970 
971  status = GdipDrawCurve3I(graphics, pen, points, 0, 0, 2, 1);
973 
974  status = GdipDrawCurve3I(graphics, pen, points, 1, 0, 0, 1);
976 
977  status = GdipDrawCurve3I(graphics, pen, points, 3, 4, 2, 1);
979 
980  /* InvalidParameter cases: invalid number of segments */
981  status = GdipDrawCurve3I(graphics, pen, points, 3, 0, -1, 1);
983 
984  status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 2, 1);
986 
987  status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 2, 1);
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);
1040 
1041  status = GdipDrawCurve2(graphics, NULL, points, 3, 1);
1043 
1044  status = GdipDrawCurve2(NULL, pen, points, 3, 1);
1046 
1047  /* InvalidParameter cases: invalid count */
1048  status = GdipDrawCurve2(graphics, pen, points, -1, 1);
1050 
1051  status = GdipDrawCurve2(graphics, pen, points, 0, 1);
1053 
1054  status = GdipDrawCurve2(graphics, pen, points, 1, 1);
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);
1107 
1108  status = GdipDrawCurve2I(graphics, NULL, points, 3, 1);
1110 
1111  status = GdipDrawCurve2I(NULL, pen, points, 3, 1);
1113 
1114  /* InvalidParameter cases: invalid count */
1115  status = GdipDrawCurve2I(graphics, pen, points, -1, 1);
1117 
1118  status = GdipDrawCurve2I(graphics, pen, points, 0, 1);
1120 
1121  status = GdipDrawCurve2I(graphics, pen, points, 1, 1);
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 */
1174 
1175  status = GdipDrawCurve(graphics, NULL, points, 3);
1177 
1178  status = GdipDrawCurve(NULL, pen, points, 3);
1180 
1181  /* InvalidParameter cases: invalid count */
1182  status = GdipDrawCurve(graphics, pen, points, -1);
1184 
1185  status = GdipDrawCurve(graphics, pen, points, 0);
1187 
1188  status = GdipDrawCurve(graphics, pen, points, 1);
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 */
1235 
1236  status = GdipDrawCurveI(graphics, NULL, points, 3);
1238 
1239  status = GdipDrawCurveI(NULL, pen, points, 3);
1241 
1242  /* InvalidParameter cases: invalid count */
1243  status = GdipDrawCurveI(graphics, pen, points, -1);
1245 
1246  status = GdipDrawCurveI(graphics, pen, points, 0);
1248 
1249  status = GdipDrawCurveI(graphics, pen, points, 1);
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);
1286 
1287  status = GdipDrawLineI(graphics, NULL, 0, 0, 0, 0);
1289 
1290  status = GdipDrawLineI(NULL, pen, 0, 0, 0, 0);
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 
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;
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);
1338  status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, ptf, 2, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
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);
1344  status = GdipDrawImagePointsRect(graphics, (GpImage*)bm, NULL, 3, 0, 0, 10, 10, UnitPixel, NULL, NULL, NULL);
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*/
1388 
1389  status = GdipDrawLinesI(graphics, pen, ptf, 0);
1391 
1392  status = GdipDrawLinesI(graphics, NULL, ptf, 2);
1394 
1395  status = GdipDrawLinesI(NULL, pen, ptf, 2);
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 */
1438 
1439  status = GdipFillClosedCurve(graphics, NULL, NULL, 3);
1441 
1442  status = GdipFillClosedCurve(NULL, (GpBrush*)brush, NULL, 3);
1444 
1447 
1448  status = GdipFillClosedCurve(graphics, (GpBrush*)brush, NULL, 3);
1450 
1451  status = GdipFillClosedCurve(graphics, NULL, points, 3);
1453 
1454  status = GdipFillClosedCurve(NULL, (GpBrush*)brush, points, 3);
1456 
1457  /* InvalidParameter cases: invalid count */
1458  status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, -1);
1460 
1461  status = GdipFillClosedCurve(graphics, (GpBrush*)brush, points, 0);
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 */
1511 
1512  status = GdipFillClosedCurveI(graphics, NULL, points, 3);
1514 
1515  status = GdipFillClosedCurveI(NULL, (GpBrush*)brush, points, 3);
1517 
1518  /* InvalidParameter cases: invalid count */
1519  status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, 0);
1521 
1522  /* OutOfMemory cases: large (unsigned) int */
1523  status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, points, -1);
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");
1558  expect(Ok, status);
1559  ok(path != NULL, "Expected path to be initialized\n");
1560 
1561  /* Empty path */
1563  status = GdipFillPath(graphics, (GpBrush *)brush, path);
1564  expect(Ok, status);
1565 
1566  /* Not closed 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 */
1577  status = GdipAddPathRectangle(path, 0, 0, 4, 4);
1578  expect(Ok, status);
1579  status = GdipFillPath(graphics, (GpBrush *)brush, path);
1580  expect(Ok, status);
1581 
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;
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 
1650  expect(Ok, status);
1651  status = GdipCreateRegion(&region);
1652  expect(Ok, status);
1653  GdipCreateSolidFill((ARGB)0xdeadbeef, &brush);
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);
1667  status = GdipGetDC(graphics, NULL);
1669  status = GdipGetDC(NULL, &retdc);
1671 
1674  status = GdipReleaseDC(graphics, NULL);
1676  status = GdipReleaseDC(NULL, (HDC)0xdeadbeef);
1678 
1679  /* Release without Get */
1680  status = GdipReleaseDC(graphics, hdc);
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);
1690 
1691  /* try all Graphics calls here */
1692  status = GdipDrawArc(graphics, pen, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0);
1694  status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0.0, 0.0);
1696  status = GdipDrawBezier(graphics, pen, 0.0, 10.0, 20.0, 15.0, 35.0, -10.0, 10.0, 10.0);
1698  status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
1700  status = GdipDrawBeziers(graphics, pen, ptf, 5);
1702  status = GdipDrawBeziersI(graphics, pen, pt, 5);
1704  status = GdipDrawClosedCurve(graphics, pen, ptf, 5);
1706  status = GdipDrawClosedCurveI(graphics, pen, pt, 5);
1708  status = GdipDrawClosedCurve2(graphics, pen, ptf, 5, 1.0);
1710  status = GdipDrawClosedCurve2I(graphics, pen, pt, 5, 1.0);
1712  status = GdipDrawCurve(graphics, pen, ptf, 5);
1714  status = GdipDrawCurveI(graphics, pen, pt, 5);
1716  status = GdipDrawCurve2(graphics, pen, ptf, 5, 1.0);
1718  status = GdipDrawCurve2I(graphics, pen, pt, 5, 1.0);
1720  status = GdipDrawEllipse(graphics, pen, 0.0, 0.0, 100.0, 50.0);
1722  status = GdipDrawEllipseI(graphics, pen, 0, 0, 100, 50);
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);
1730  status = GdipDrawLineI(graphics, pen, 0, 0, 100, 200);
1732  status = GdipDrawLines(graphics, pen, ptf, 5);
1734  status = GdipDrawLinesI(graphics, pen, pt, 5);
1736  status = GdipDrawPath(graphics, pen, path);
1738  status = GdipDrawPie(graphics, pen, 0.0, 0.0, 100.0, 100.0, 0.0, 90.0);
1740  status = GdipDrawPieI(graphics, pen, 0, 0, 100, 100, 0.0, 90.0);
1742  status = GdipDrawRectangle(graphics, pen, 0.0, 0.0, 100.0, 300.0);
1744  status = GdipDrawRectangleI(graphics, pen, 0, 0, 100, 300);
1746  status = GdipDrawRectangles(graphics, pen, rectf, 2);
1748  status = GdipDrawRectanglesI(graphics, pen, rect, 2);
1750  /* GdipDrawString */
1751  status = GdipFillClosedCurve2(graphics, (GpBrush*)brush, ptf, 5, 1.0, FillModeAlternate);
1753  status = GdipFillClosedCurve2I(graphics, (GpBrush*)brush, pt, 5, 1.0, FillModeAlternate);
1755  status = GdipFillClosedCurve(graphics, (GpBrush*)brush, ptf, 5);
1757  status = GdipFillClosedCurveI(graphics, (GpBrush*)brush, pt, 5);
1759  status = GdipFillEllipse(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1761  status = GdipFillEllipseI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1763  status = GdipFillPath(graphics, (GpBrush*)brush, path);
1765  status = GdipFillPie(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0, 0.0, 15.0);
1767  status = GdipFillPieI(graphics, (GpBrush*)brush, 0, 0, 100, 100, 0.0, 15.0);
1769  status = GdipFillPolygon(graphics, (GpBrush*)brush, ptf, 5, FillModeAlternate);
1771  status = GdipFillPolygonI(graphics, (GpBrush*)brush, pt, 5, FillModeAlternate);
1773  status = GdipFillPolygon2(graphics, (GpBrush*)brush, ptf, 5);
1775  status = GdipFillPolygon2I(graphics, (GpBrush*)brush, pt, 5);
1777  status = GdipFillRectangle(graphics, (GpBrush*)brush, 0.0, 0.0, 100.0, 100.0);
1779  status = GdipFillRectangleI(graphics, (GpBrush*)brush, 0, 0, 100, 100);
1781  status = GdipFillRectangles(graphics, (GpBrush*)brush, rectf, 2);
1783  status = GdipFillRectanglesI(graphics, (GpBrush*)brush, rect, 2);
1785  status = GdipFillRegion(graphics, (GpBrush*)brush, region);
1787  status = GdipFlush(graphics, FlushIntentionFlush);
1789  status = GdipGetClipBounds(graphics, rectf);
1791  status = GdipGetClipBoundsI(graphics, rect);
1793  status = GdipGetCompositingMode(graphics, &compmode);
1797  status = GdipGetInterpolationMode(graphics, &intmode);
1799  status = GdipGetNearestColor(graphics, &color);
1801  status = GdipGetPageScale(graphics, &r);
1803  status = GdipGetPageUnit(graphics, &unit);
1805  status = GdipGetPixelOffsetMode(graphics, &offsetmode);
1807  status = GdipGetSmoothingMode(graphics, &smoothmode);
1809  status = GdipGetTextRenderingHint(graphics, &texthint);
1811  status = GdipGetWorldTransform(graphics, m);
1813  status = GdipGraphicsClear(graphics, 0xdeadbeef);
1815  status = GdipIsVisiblePoint(graphics, 0.0, 0.0, &res);
1817  status = GdipIsVisiblePointI(graphics, 0, 0, &res);
1819  /* GdipMeasureCharacterRanges */
1820  /* GdipMeasureString */
1821  status = GdipResetClip(graphics);
1823  status = GdipResetWorldTransform(graphics);
1825  /* GdipRestoreGraphics */
1828  /* GdipSaveGraphics */
1829  status = GdipScaleWorldTransform(graphics, 1.0, 1.0, MatrixOrderPrepend);
1837  status = GdipSetPageScale(graphics, 1.0);
1839  status = GdipSetPageUnit(graphics, UnitWorld);
1847  status = GdipSetWorldTransform(graphics, m);
1849  status = GdipTranslateWorldTransform(graphics, 0.0, 0.0, MatrixOrderPrepend);
1855  status = GdipSetClipRect(graphics, 0.0, 0.0, 10.0, 10.0, CombineModeReplace);
1857  status = GdipSetClipRectI(graphics, 0, 0, 10, 10, CombineModeReplace);
1859  status = GdipSetClipRegion(graphics, clip, CombineModeReplace);
1861  status = GdipTranslateClip(graphics, 0.0, 0.0);
1863  status = GdipTranslateClipI(graphics, 0, 0);
1865  status = GdipDrawPolygon(graphics, pen, ptf, 5);
1867  status = GdipDrawPolygonI(graphics, pen, pt, 5);
1869  status = GdipGetDpiX(graphics, &r);
1871  status = GdipGetDpiY(graphics, &r);
1875  status = GdipGetClip(graphics, region);
1879 
1880  /* try to delete before release */
1881  status = GdipDeleteGraphics(graphics);
1883 
1884  status = GdipReleaseDC(graphics, retdc);
1885  expect(Ok, status);
1886 
1887  GdipDeletePen(pen);
1888  GdipDeleteGraphics(graphics);
1889 
1890  GdipDeleteRegion(clip);
1892  GdipDeleteBrush((GpBrush*)brush);
1893  GdipDeleteRegion(region);
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 */
1920 
1923  status = GdipTransformPoints(graphics, -1, CoordinateSpaceWorld, ptf, 2);
1927  status = GdipTransformPoints(graphics, CoordinateSpaceDevice, -1, ptf, 2);
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;
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;
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;
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;
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;
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;
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;
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;
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 */
2050  status = GdipGetClip(graphics, NULL);
2052  status = GdipGetClip(NULL, clip);
2054 
2059 
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 */
2218  status = GdipIsClipEmpty(graphics, NULL);
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);
2241 }
2242 
2243 static void test_textcontrast(void)
2244 {
2245  GpStatus status;
2246  HDC hdc = GetDC( hwnd );
2247  GpGraphics *graphics;
2248  UINT contrast;
2249 
2252 
2253  status = GdipCreateFromHDC(hdc, &graphics);
2254  expect(Ok, status);
2255 
2256  status = GdipGetTextContrast(graphics, NULL);
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;
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);
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 
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 
2311  expect(Ok, status);
2312 
2313  status = GdipDrawDriverString(NULL, string, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2315 
2316  status = GdipDrawDriverString(graphics, NULL, 4, fnt, brush, positions, DriverStringOptionsCmapLookup, matrix);
2318 
2319  status = GdipDrawDriverString(graphics, string, 4, NULL, brush, positions, DriverStringOptionsCmapLookup, matrix);
2321 
2322  status = GdipDrawDriverString(graphics, string, 4, fnt, NULL, positions, DriverStringOptionsCmapLookup, matrix);
2324 
2325  status = GdipDrawDriverString(graphics, string, 4, fnt, brush, NULL, DriverStringOptionsCmapLookup, matrix);
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 
2338  GdipDeleteGraphics(graphics);
2339  GdipDeleteBrush(brush);
2340  GdipDeleteFont(fnt);
2342 
2343  ReleaseDC(hwnd, hdc);
2344 }
2345 
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 
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 
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);
2569 
2572 
2573  status = GdipGetVisibleClipBoundsI(graphics, NULL);
2575 
2578 
2579  GdipDeleteGraphics(graphics);
2580  ReleaseDC(hwnd, hdc);
2581 
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 
2596  expect(Ok, status);
2597 
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 
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 
2633 
2634  /* We get the same kind of write-only HDC for a "normal" bitmap */
2636  expect(Ok, status);
2637 
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 
2654 
2655  /* If we don't draw to the HDC, the bits are never accessed */
2657  expect(Ok, status);
2658 
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 
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);
2694 
2695  status = GdipIsVisiblePoint(graphics, 0, 0, NULL);
2697 
2698  status = GdipIsVisiblePointI(NULL, 0, 0, &val);
2700 
2701  status = GdipIsVisiblePointI(graphics, 0, 0, NULL);
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 */
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);
2872 
2873  status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL);
2875 
2876  status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val);
2878 
2879  status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL);
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 */
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);
3035 
3038  GdipDeleteGraphics(graphics);
3039 
3041  expect(Ok, status);
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  }
3052 
3054  expect(Ok, status);
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  }
3065 
3067  expect(Ok, status);
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  }
3078 
3080  expect(Ok, status);
3083  if (status == Ok)
3084  GdipDeleteGraphics(graphics);
3086 
3088  expect(Ok, status);
3090  expect(Ok, status);
3091  status = GdipGetNearestColor(graphics, &color);
3092  expect(Ok, status);
3093  expect(0xdeadbeef, color);
3094  GdipDeleteGraphics(graphics);
3096 
3098  expect(Ok, status);
3100  expect(Ok, status);
3101  status = GdipGetNearestColor(graphics, &color);
3102  expect(Ok, status);
3103  expect(0xdeadbeef, color);
3104  GdipDeleteGraphics(graphics);
3106 
3108  expect(Ok, status);
3110  expect(Ok, status);
3111  status = GdipGetNearestColor(graphics, &color);
3112  expect(Ok, status);
3113  expect(0xdeadbeef, color);
3114  GdipDeleteGraphics(graphics);
3116 
3118  expect(Ok, status);
3119  if (status == Ok)
3120  {
3122  expect(Ok, status);
3123  status = GdipGetNearestColor(graphics, &color);
3124  expect(Ok, status);
3125  expect(0xdeadbeef, color);
3126  GdipDeleteGraphics(graphics);
3128  }
3129 
3131  expect(Ok, status);
3132  if (status == Ok)
3133  {
3135  expect(Ok, status);
3136  status = GdipGetNearestColor(graphics, &color);
3137  expect(Ok, status);
3138  expect(0xdeadbeef, color);
3139  GdipDeleteGraphics(graphics);
3141  }
3142 
3144  expect(Ok, status);
3145  if (status == Ok)
3146  {
3148  expect(Ok, status);
3149  status = GdipGetNearestColor(graphics, &color);
3150  expect(Ok, status);
3151  expect(0xdeadbeef, color);
3152  GdipDeleteGraphics(graphics);
3154  }
3155 
3157  expect(Ok, status);
3159  expect(Ok, status);
3160  status = GdipGetNearestColor(graphics, &color);
3161  expect(Ok, status);
3162  todo_wine expect(0xffa8bce8, color);
3163  GdipDeleteGraphics(graphics);
3165 
3167  expect(Ok, status);
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);
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;
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 
3217  expect(Ok, status);
3218 
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);
3229 
3230  status = GdipDrawString(graphics, NULL, 6, font, &rc, NULL, brush);
3232 
3233  status = GdipDrawString(graphics, teststring, 6, NULL, &rc, NULL, brush);
3235 
3236  status = GdipDrawString(graphics, teststring, 6, font, NULL, NULL, brush);
3238 
3239  status = GdipDrawString(graphics, teststring, 6, font, &rc, NULL, NULL);
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);
3247 
3248  status = GdipMeasureString(graphics, NULL, 6, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3250 
3251  status = GdipMeasureString(graphics, teststring, 6, NULL, &rc, NULL, &bounds, &codepointsfitted, &linesfilled);
3253 
3254  status = GdipMeasureString(graphics, teststring, 6, font, NULL, NULL, &bounds, &codepointsfitted, &linesfilled);
3256 
3257  status = GdipMeasureString(graphics, teststring, 6, font, &rc, NULL, NULL, &codepointsfitted, &linesfilled);
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 
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);
3379 
3380  status = GdipMeasureCharacterRanges(graphics, NULL, 6, font, &rc, format, 3, regions);
3382 
3383  status = GdipMeasureCharacterRanges(graphics, teststring, 6, NULL, &rc, format, 3, regions);
3385 
3386  status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, NULL, format, 3, regions);
3388 
3389  if (0)
3390  {
3391  /* Crashes on Windows XP */
3392  status = GdipMeasureCharacterRanges(graphics, teststring, 6, font, &rc, NULL, 3, regions);
3394  }
3395 
3396  status =