1/**************************************************************************\
2*
3* Copyright (c) 1998-2000, Microsoft Corp.  All Rights Reserved.
4*
5* Module Name:
6*
7*   GdiplusGraphics.h
8*
9* Abstract:
10*
11*   Declarations for Graphics class
12*
13\**************************************************************************/
14
15#ifndef _GDIPLUSGRAPHICS_H
16#define _GDIPLUSGRAPHICS_H
17
18/**
19 * Represent a graphics context
20 */
21class Graphics : public GdiplusBase
22{
23public:
24    friend class Region;
25    friend class GraphicsPath;
26    friend class Image;
27    friend class Bitmap;
28    friend class Metafile;
29    friend class Font;
30    friend class FontFamily;
31    friend class FontCollection;
32    friend class CachedBitmap;
33
34    // Get a graphics context from an existing Win32 HDC or HWND
35    static Graphics* FromHDC(IN HDC hdc)
36    {
37        return new Graphics(hdc);
38    }
39
40    static Graphics* FromHDC(IN HDC hdc,
41                             IN HANDLE hdevice)
42    {
43        return new Graphics(hdc, hdevice);
44    }
45
46    static Graphics* FromHWND(IN HWND hwnd,
47                              IN BOOL icm = FALSE)
48    {
49        return new Graphics(hwnd, icm);
50    }
51
52    static Graphics* FromImage(IN Image *image)
53    {
54        return new Graphics(image);
55    }
56
57    Graphics(IN HDC hdc)
58    {
59        GpGraphics *graphics = NULL;
60
61        lastResult = DllExports::GdipCreateFromHDC(hdc, &graphics);
62
63        SetNativeGraphics(graphics);
64    }
65
66    Graphics(IN HDC hdc,
67             IN HANDLE hdevice)
68    {
69        GpGraphics *graphics = NULL;
70
71        lastResult = DllExports::GdipCreateFromHDC2(hdc, hdevice, &graphics);
72
73        SetNativeGraphics(graphics);
74    }
75
76    Graphics(IN HWND hwnd,
77             IN BOOL icm = FALSE)
78    {
79        GpGraphics *graphics = NULL;
80
81        if (icm)
82        {
83            lastResult = DllExports::GdipCreateFromHWNDICM(hwnd, &graphics);
84        }
85        else
86        {
87            lastResult = DllExports::GdipCreateFromHWND(hwnd, &graphics);
88        }
89
90        SetNativeGraphics(graphics);
91    }
92
93    Graphics(IN Image* image)
94    {
95        GpGraphics *graphics = NULL;
96
97        if (image != NULL)
98        {
99            lastResult = DllExports::GdipGetImageGraphicsContext(
100                                                                image->nativeImage, &graphics);
101        }
102        SetNativeGraphics(graphics);
103    }
104
105    ~Graphics()
106    {
107        DllExports::GdipDeleteGraphics(nativeGraphics);
108    }
109
110    VOID Flush(IN FlushIntention intention = FlushIntentionFlush)
111    {
112        DllExports::GdipFlush(nativeGraphics, intention);
113    }
114
115    //------------------------------------------------------------------------
116    // Interop methods
117    //------------------------------------------------------------------------
118
119    // Locks the graphics until ReleaseDC is called
120    HDC GetHDC()
121    {
122        HDC     hdc = NULL;
123
124        SetStatus(DllExports::GdipGetDC(nativeGraphics, &hdc));
125
126        return hdc;
127    }
128
129    VOID ReleaseHDC(IN HDC hdc)
130    {
131        SetStatus(DllExports::GdipReleaseDC(nativeGraphics, hdc));
132    }
133
134    //------------------------------------------------------------------------
135    // Rendering modes
136    //------------------------------------------------------------------------
137
138    Status SetRenderingOrigin(IN INT x, IN INT y)
139    {
140        return SetStatus(
141            DllExports::GdipSetRenderingOrigin(
142                nativeGraphics, x, y
143            )
144        );
145    }
146
147    Status GetRenderingOrigin(OUT INT *x, OUT INT *y) const
148    {
149        return SetStatus(
150            DllExports::GdipGetRenderingOrigin(
151                nativeGraphics, x, y
152            )
153        );
154    }
155
156    Status SetCompositingMode(IN CompositingMode compositingMode)
157    {
158        return SetStatus(DllExports::GdipSetCompositingMode(nativeGraphics,
159                                                            compositingMode));
160    }
161
162    CompositingMode GetCompositingMode() const
163    {
164        CompositingMode mode;
165
166        SetStatus(DllExports::GdipGetCompositingMode(nativeGraphics,
167                                                     &mode));
168
169        return mode;
170    }
171
172    Status SetCompositingQuality(IN CompositingQuality compositingQuality)
173    {
174        return SetStatus(DllExports::GdipSetCompositingQuality(
175            nativeGraphics,
176            compositingQuality));
177    }
178
179    CompositingQuality GetCompositingQuality() const
180    {
181        CompositingQuality quality;
182
183        SetStatus(DllExports::GdipGetCompositingQuality(
184            nativeGraphics,
185            &quality));
186
187        return quality;
188    }
189
190    Status SetTextRenderingHint(IN TextRenderingHint newMode)
191    {
192#ifndef DCR_USE_NEW_186764
193		/* temporarly set the high bit to warn that we are using the new definition for the flag */
194		newMode = (TextRenderingHint) (newMode | 0x0f000);
195#endif // DCR_USE_NEW_186764
196        return SetStatus(DllExports::GdipSetTextRenderingHint(nativeGraphics,
197                                                          newMode));
198    }
199
200    TextRenderingHint GetTextRenderingHint() const
201    {
202        TextRenderingHint hint;
203
204        SetStatus(DllExports::GdipGetTextRenderingHint(nativeGraphics,
205                                                   &hint));
206
207        return hint;
208    }
209
210#ifdef DCR_USE_NEW_188922
211    Status SetTextContrast(IN UINT contrast)
212    {
213        return SetStatus(DllExports::GdipSetTextContrast(nativeGraphics,
214                                                          contrast));
215    }
216
217    UINT GetTextContrast() const
218    {
219        UINT contrast;
220
221        SetStatus(DllExports::GdipGetTextContrast(nativeGraphics,
222                                                    &contrast));
223
224        return contrast;
225    }
226#else
227    Status SetTextGammaValue(IN UINT gammaValue)
228    {
229        return SetStatus(DllExports::GdipSetTextGammaValue(nativeGraphics,
230                                                          gammaValue));
231    }
232
233    UINT GetTextGammaValue() const
234    {
235        UINT gammaValue;
236
237        SetStatus(DllExports::GdipGetTextGammaValue(nativeGraphics,
238                                                    &gammaValue));
239
240        return gammaValue;
241    }
242
243#endif // DCR_USE_NEW_188922
244
245
246    InterpolationMode GetInterpolationMode() const
247    {
248        InterpolationMode mode = InterpolationModeInvalid;
249
250        SetStatus(DllExports::GdipGetInterpolationMode(nativeGraphics,
251                                                           &mode));
252
253        return mode;
254    }
255
256    Status SetInterpolationMode(IN InterpolationMode interpolationMode)
257    {
258        return SetStatus(DllExports::GdipSetInterpolationMode(nativeGraphics,
259                                                           interpolationMode));
260    }
261
262    SmoothingMode GetSmoothingMode() const
263    {
264        SmoothingMode smoothingMode = SmoothingModeInvalid;
265
266        SetStatus(DllExports::GdipGetSmoothingMode(nativeGraphics,
267                                                   &smoothingMode));
268
269        return smoothingMode;
270    }
271
272    Status SetSmoothingMode(IN SmoothingMode smoothingMode)
273    {
274        return SetStatus(DllExports::GdipSetSmoothingMode(nativeGraphics,
275                                                          smoothingMode));
276    }
277
278    PixelOffsetMode GetPixelOffsetMode() const
279    {
280        PixelOffsetMode pixelOffsetMode = PixelOffsetModeInvalid;
281
282        SetStatus(DllExports::GdipGetPixelOffsetMode(nativeGraphics,
283                                                     &pixelOffsetMode));
284
285        return pixelOffsetMode;
286    }
287
288    Status SetPixelOffsetMode(IN PixelOffsetMode pixelOffsetMode)
289    {
290        return SetStatus(DllExports::GdipSetPixelOffsetMode(nativeGraphics,
291                                                            pixelOffsetMode));
292    }
293
294    //------------------------------------------------------------------------
295    // Manipulate the current world transform
296    //------------------------------------------------------------------------
297
298    Status SetTransform(IN const Matrix* matrix)
299    {
300        return SetStatus(DllExports::GdipSetWorldTransform(nativeGraphics,
301                                                        matrix->nativeMatrix));
302    }
303    Status ResetTransform()
304    {
305        return SetStatus(DllExports::GdipResetWorldTransform(nativeGraphics));
306    }
307
308    Status MultiplyTransform(IN const Matrix* matrix,
309                             IN MatrixOrder order = MatrixOrderPrepend)
310    {
311        return SetStatus(DllExports::GdipMultiplyWorldTransform(nativeGraphics,
312                                                                matrix->nativeMatrix,
313                                                                order));
314    }
315
316    Status TranslateTransform(IN REAL dx,
317                              IN REAL dy,
318                              IN MatrixOrder order = MatrixOrderPrepend)
319    {
320        return SetStatus(DllExports::GdipTranslateWorldTransform(nativeGraphics,
321                                                               dx, dy, order));
322    }
323
324    Status ScaleTransform(IN REAL sx,
325                          IN REAL sy,
326                          IN MatrixOrder order = MatrixOrderPrepend)
327    {
328        return SetStatus(DllExports::GdipScaleWorldTransform(nativeGraphics,
329                                                             sx, sy, order));
330    }
331
332    Status RotateTransform(IN REAL angle,
333                           IN MatrixOrder order = MatrixOrderPrepend)
334    {
335        return SetStatus(DllExports::GdipRotateWorldTransform(nativeGraphics,
336                                                              angle, order));
337    }
338
339    /**
340     * Return the current world transform
341     */
342
343    Status GetTransform(OUT Matrix* matrix) const
344    {
345        return SetStatus(DllExports::GdipGetWorldTransform(nativeGraphics,
346                                                           matrix->nativeMatrix));
347    }
348
349    /**
350     * Manipulate the current page transform
351     */
352
353    Status SetPageUnit(IN Unit unit)
354    {
355        return SetStatus(DllExports::GdipSetPageUnit(nativeGraphics,
356                                                     unit));
357    }
358
359    Status SetPageScale(IN REAL scale)
360    {
361        return SetStatus(DllExports::GdipSetPageScale(nativeGraphics,
362                                                      scale));
363    }
364
365    /**
366     * Retrieve the current page transform information
367     * notes @ these are atomic
368     */
369    Unit GetPageUnit() const
370    {
371        Unit unit;
372
373        SetStatus(DllExports::GdipGetPageUnit(nativeGraphics, &unit));
374
375        return unit;
376    }
377
378    REAL GetPageScale() const
379    {
380        REAL scale;
381
382        SetStatus(DllExports::GdipGetPageScale(nativeGraphics, &scale));
383
384        return scale;
385    }
386
387    REAL GetDpiX() const
388    {
389        REAL dpi;
390
391        SetStatus(DllExports::GdipGetDpiX(nativeGraphics, &dpi));
392
393        return dpi;
394    }
395
396    REAL GetDpiY() const
397    {
398        REAL dpi;
399
400        SetStatus(DllExports::GdipGetDpiY(nativeGraphics, &dpi));
401
402        return dpi;
403    }
404
405    /**
406     * Transform points in the current graphics context
407     */
408    // float version
409    Status TransformPoints(IN CoordinateSpace destSpace,
410                           IN CoordinateSpace srcSpace,
411                           IN OUT PointF* pts,
412                           IN INT count) const
413    {
414        return SetStatus(DllExports::GdipTransformPoints(nativeGraphics,
415                                                         destSpace,
416                                                         srcSpace,
417                                                         pts,
418                                                         count));
419    }
420
421    // integer version
422    Status TransformPoints(IN CoordinateSpace destSpace,
423                           IN CoordinateSpace srcSpace,
424                           IN OUT Point* pts,
425                           IN INT count) const
426    {
427
428        return SetStatus(DllExports::GdipTransformPointsI(nativeGraphics,
429                                                          destSpace,
430                                                          srcSpace,
431                                                          pts,
432                                                          count));
433    }
434
435    //------------------------------------------------------------------------
436    // GetNearestColor (for <= 8bpp surfaces)
437    // Note: alpha is ignored
438    //------------------------------------------------------------------------
439    Status GetNearestColor(IN OUT Color* color) const
440    {
441        if (color == NULL)
442        {
443            return SetStatus(InvalidParameter);
444        }
445
446        ARGB argb = color->GetValue();
447
448        Status status = SetStatus(DllExports::GdipGetNearestColor(nativeGraphics, &argb));
449
450        color->SetValue(argb);
451
452        return status;
453    }
454
455    /**
456     * Vector drawing methods
457     *
458     * @notes Do we need a set of methods that take
459     *  integer coordinate parameters?
460     */
461
462    // float version
463    Status DrawLine(IN const Pen* pen,
464                    IN REAL x1,
465                    IN REAL y1,
466                    IN REAL x2,
467                    IN REAL y2)
468    {
469        return SetStatus(DllExports::GdipDrawLine(nativeGraphics,
470                                                  pen->nativePen, x1, y1, x2,
471                                                  y2));
472    }
473
474    Status DrawLine(IN const Pen* pen,
475                    IN const PointF& pt1,
476                    IN const PointF& pt2)
477    {
478        return DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y);
479    }
480
481    Status DrawLines(IN const Pen* pen,
482                     IN const PointF* points,
483                     IN INT count)
484    {
485        return SetStatus(DllExports::GdipDrawLines(nativeGraphics,
486                                                   pen->nativePen,
487                                                   points, count));
488    }
489
490    // int version
491    Status DrawLine(IN const Pen* pen,
492                    IN INT x1,
493                    IN INT y1,
494                    IN INT x2,
495                    IN INT y2)
496    {
497        return SetStatus(DllExports::GdipDrawLineI(nativeGraphics,
498                                                   pen->nativePen,
499                                                   x1,
500                                                   y1,
501                                                   x2,
502                                                   y2));
503    }
504
505    Status DrawLine(IN const Pen* pen,
506                    IN const Point& pt1,
507                    IN const Point& pt2)
508    {
509        return DrawLine(pen,
510                        pt1.X,
511                        pt1.Y,
512                        pt2.X,
513                        pt2.Y);
514    }
515
516    Status DrawLines(IN const Pen* pen,
517                     IN const Point* points,
518                     IN INT count)
519    {
520        return SetStatus(DllExports::GdipDrawLinesI(nativeGraphics,
521                                                    pen->nativePen,
522                                                    points,
523                                                    count));
524    }
525
526    // float version
527    Status DrawArc(IN const Pen* pen,
528                   IN REAL x,
529                   IN REAL y,
530                   IN REAL width,
531                   IN REAL height,
532                   IN REAL startAngle,
533                   IN REAL sweepAngle)
534    {
535        return SetStatus(DllExports::GdipDrawArc(nativeGraphics,
536                                                 pen->nativePen,
537                                                 x,
538                                                 y,
539                                                 width,
540                                                 height,
541                                                 startAngle,
542                                                 sweepAngle));
543    }
544
545    Status DrawArc(IN const Pen* pen,
546                   IN const RectF& rect,
547                   IN REAL startAngle,
548                   IN REAL sweepAngle)
549    {
550        return DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height,
551                       startAngle, sweepAngle);
552    }
553
554    // int version
555    Status DrawArc(IN const Pen* pen,
556                   IN INT x,
557                   IN INT y,
558                   IN INT width,
559                   IN INT height,
560                   IN REAL startAngle,
561                   IN REAL sweepAngle)
562    {
563        return SetStatus(DllExports::GdipDrawArcI(nativeGraphics,
564                                                  pen->nativePen,
565                                                  x,
566                                                  y,
567                                                  width,
568                                                  height,
569                                                  startAngle,
570                                                  sweepAngle));
571    }
572
573
574    Status DrawArc(IN const Pen* pen,
575                   IN const Rect& rect,
576                   IN REAL startAngle,
577                   IN REAL sweepAngle)
578    {
579        return DrawArc(pen,
580                       rect.X,
581                       rect.Y,
582                       rect.Width,
583                       rect.Height,
584                       startAngle,
585                       sweepAngle);
586    }
587
588    // float version
589    Status DrawBezier(IN const Pen* pen,
590                      IN REAL x1,
591                      IN REAL y1,
592                      IN REAL x2,
593                      IN REAL y2,
594                      IN REAL x3,
595                      IN REAL y3,
596                      IN REAL x4,
597                      IN REAL y4)
598    {
599        return SetStatus(DllExports::GdipDrawBezier(nativeGraphics,
600                                                    pen->nativePen, x1, y1,
601                                                    x2, y2, x3, y3, x4, y4));
602    }
603
604    Status DrawBezier(IN const Pen* pen,
605                      IN const PointF& pt1,
606                      IN const PointF& pt2,
607                      IN const PointF& pt3,
608                      IN const PointF& pt4)
609    {
610        return DrawBezier(pen,
611                          pt1.X,
612                          pt1.Y,
613                          pt2.X,
614                          pt2.Y,
615                          pt3.X,
616                          pt3.Y,
617                          pt4.X,
618                          pt4.Y);
619    }
620
621    Status DrawBeziers(IN const Pen* pen,
622                       IN const PointF* points,
623                       IN INT count)
624    {
625        return SetStatus(DllExports::GdipDrawBeziers(nativeGraphics,
626                                                     pen->nativePen,
627                                                     points,
628                                                     count));
629    }
630
631    // int version
632    Status DrawBezier(IN const Pen* pen,
633                      IN INT x1,
634                      IN INT y1,
635                      IN INT x2,
636                      IN INT y2,
637                      IN INT x3,
638                      IN INT y3,
639                      IN INT x4,
640                      IN INT y4)
641    {
642        return SetStatus(DllExports::GdipDrawBezierI(nativeGraphics,
643                                                     pen->nativePen,
644                                                     x1,
645                                                     y1,
646                                                     x2,
647                                                     y2,
648                                                     x3,
649                                                     y3,
650                                                     x4,
651                                                     y4));
652    }
653
654    Status DrawBezier(IN const Pen* pen,
655                      IN const Point& pt1,
656                      IN const Point& pt2,
657                      IN const Point& pt3,
658                      IN const Point& pt4)
659    {
660        return DrawBezier(pen,
661                          pt1.X,
662                          pt1.Y,
663                          pt2.X,
664                          pt2.Y,
665                          pt3.X,
666                          pt3.Y,
667                          pt4.X,
668                          pt4.Y);
669    }
670
671    Status DrawBeziers(IN const Pen* pen,
672                       IN const Point* points,
673                       IN INT count)
674    {
675        return SetStatus(DllExports::GdipDrawBeziersI(nativeGraphics,
676                                                      pen->nativePen,
677                                                      points,
678                                                      count));
679    }
680
681    // float version
682    Status DrawRectangle(IN const Pen* pen,
683                         IN const RectF& rect)
684    {
685        return DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
686    }
687
688    Status DrawRectangle(IN const Pen* pen,
689                         IN REAL x,
690                         IN REAL y,
691                         IN REAL width,
692                         IN REAL height)
693    {
694        return SetStatus(DllExports::GdipDrawRectangle(nativeGraphics,
695                                                       pen->nativePen, x, y,
696                                                       width, height));
697    }
698
699    Status DrawRectangles(IN const Pen* pen,
700                          IN const RectF* rects,
701                          IN INT count)
702    {
703        return SetStatus(DllExports::GdipDrawRectangles(nativeGraphics,
704                                                        pen->nativePen,
705                                                        rects, count));
706    }
707
708    // integer version
709    Status DrawRectangle(IN const Pen* pen,
710                         IN const Rect& rect)
711    {
712        return DrawRectangle(pen,
713                             rect.X,
714                             rect.Y,
715                             rect.Width,
716                             rect.Height);
717    }
718
719    Status DrawRectangle(IN const Pen* pen,
720                         IN INT x,
721                         IN INT y,
722                         IN INT width,
723                         IN INT height)
724    {
725        return SetStatus(DllExports::GdipDrawRectangleI(nativeGraphics,
726                                                        pen->nativePen,
727                                                        x,
728                                                        y,
729                                                        width,
730                                                        height));
731    }
732
733    Status DrawRectangles(IN const Pen* pen,
734                          IN const Rect* rects,
735                          IN INT count)
736    {
737        return SetStatus(DllExports::GdipDrawRectanglesI(nativeGraphics,
738                                                         pen->nativePen,
739                                                         rects,
740                                                         count));
741    }
742
743    // float version
744    Status DrawEllipse(IN const Pen* pen,
745                       IN const RectF& rect)
746    {
747        return DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height);
748    }
749
750    Status DrawEllipse(IN const Pen* pen,
751                       IN REAL x,
752                       IN REAL y,
753                       IN REAL width,
754                       IN REAL height)
755    {
756        return SetStatus(DllExports::GdipDrawEllipse(nativeGraphics,
757                                                     pen->nativePen,
758                                                     x,
759                                                     y,
760                                                     width,
761                                                     height));
762    }
763
764    // integer version
765    Status DrawEllipse(IN const Pen* pen,
766                       IN const Rect& rect)
767    {
768        return DrawEllipse(pen,
769                           rect.X,
770                           rect.Y,
771                           rect.Width,
772                           rect.Height);
773    }
774
775    Status DrawEllipse(IN const Pen* pen,
776                       IN INT x,
777                       IN INT y,
778                       IN INT width,
779                       IN INT height)
780    {
781        return SetStatus(DllExports::GdipDrawEllipseI(nativeGraphics,
782                                                      pen->nativePen,
783                                                      x,
784                                                      y,
785                                                      width,
786                                                      height));
787    }
788
789    // floating point version
790    Status DrawPie(IN const Pen* pen,
791                   IN const RectF& rect,
792                   IN REAL startAngle,
793                   IN REAL sweepAngle)
794    {
795        return DrawPie(pen,
796                       rect.X,
797                       rect.Y,
798                       rect.Width,
799                       rect.Height,
800                       startAngle,
801                       sweepAngle);
802    }
803
804    Status DrawPie(IN const Pen* pen,
805                   IN REAL x,
806                   IN REAL y,
807                   IN REAL width,
808                   IN REAL height,
809                   IN REAL startAngle,
810                   IN REAL sweepAngle)
811    {
812        return SetStatus(DllExports::GdipDrawPie(nativeGraphics,
813                                                 pen->nativePen,
814                                                 x,
815                                                 y,
816                                                 width,
817                                                 height,
818                                                 startAngle,
819                                                 sweepAngle));
820    }
821
822    // integer point version
823    Status DrawPie(IN const Pen* pen,
824                   IN const Rect& rect,
825                   IN REAL startAngle,
826                   IN REAL sweepAngle)
827    {
828        return DrawPie(pen,
829                       rect.X,
830                       rect.Y,
831                       rect.Width,
832                       rect.Height,
833                       startAngle,
834                       sweepAngle);
835    }
836
837    Status DrawPie(IN const Pen* pen,
838                   IN INT x,
839                   IN INT y,
840                   IN INT width,
841                   IN INT height,
842                   IN REAL startAngle,
843                   IN REAL sweepAngle)
844    {
845        return SetStatus(DllExports::GdipDrawPieI(nativeGraphics,
846                                                  pen->nativePen,
847                                                  x,
848                                                  y,
849                                                  width,
850                                                  height,
851                                                  startAngle,
852                                                  sweepAngle));
853    }
854
855    // float version
856    Status DrawPolygon(IN const Pen* pen,
857                       IN const PointF* points,
858                       IN INT count)
859    {
860        return SetStatus(DllExports::GdipDrawPolygon(nativeGraphics,
861                                                     pen->nativePen,
862                                                     points,
863                                                     count));
864    }
865
866    // integer version
867    Status DrawPolygon(IN const Pen* pen,
868                       IN const Point* points,
869                       IN INT count)
870    {
871        return SetStatus(DllExports::GdipDrawPolygonI(nativeGraphics,
872                                                      pen->nativePen,
873                                                      points,
874                                                      count));
875    }
876
877    // float version
878    Status DrawPath(IN const Pen* pen,
879                    IN const GraphicsPath* path)
880    {
881        return SetStatus(DllExports::GdipDrawPath(nativeGraphics,
882                                                  pen ? pen->nativePen : NULL,
883                                                  path ? path->nativePath : NULL));
884    }
885
886    // float version
887    Status DrawCurve(IN const Pen* pen,
888                     IN const PointF* points,
889                     IN INT count)
890    {
891        return SetStatus(DllExports::GdipDrawCurve(nativeGraphics,
892                                                   pen->nativePen, points,
893                                                   count));
894    }
895
896    Status DrawCurve(IN const Pen* pen,
897                     IN const PointF* points,
898                     IN INT count,
899                     IN REAL tension)
900    {
901        return SetStatus(DllExports::GdipDrawCurve2(nativeGraphics,
902                                                    pen->nativePen, points,
903                                                    count, tension));
904    }
905
906    Status DrawCurve(IN const Pen* pen,
907                     IN const PointF* points,
908                     IN INT count,
909                     IN INT offset,
910                     IN INT numberOfSegments,
911                     IN REAL tension = 0.5f)
912    {
913        return SetStatus(DllExports::GdipDrawCurve3(nativeGraphics,
914                                                    pen->nativePen, points,
915                                                    count, offset,
916                                                    numberOfSegments, tension));
917    }
918
919    // integer version
920    Status DrawCurve(IN const Pen* pen,
921                     IN const Point* points,
922                     IN INT count)
923    {
924        return SetStatus(DllExports::GdipDrawCurveI(nativeGraphics,
925                                                    pen->nativePen,
926                                                    points,
927                                                    count));
928    }
929
930    Status DrawCurve(IN const Pen* pen,
931                     IN const Point* points,
932                     IN INT count,
933                     IN REAL tension)
934    {
935        return SetStatus(DllExports::GdipDrawCurve2I(nativeGraphics,
936                                                     pen->nativePen,
937                                                     points,
938                                                     count,
939                                                     tension));
940    }
941
942    Status DrawCurve(IN const Pen* pen,
943                     IN const Point* points,
944                     IN INT count,
945                     IN INT offset,
946                     IN INT numberOfSegments,
947                     IN REAL tension = 0.5f)
948    {
949        return SetStatus(DllExports::GdipDrawCurve3I(nativeGraphics,
950                                                     pen->nativePen,
951                                                     points,
952                                                     count,
953                                                     offset,
954                                                     numberOfSegments,
955                                                     tension));
956    }
957
958    // float version
959    Status DrawClosedCurve(IN const Pen* pen,
960                           IN const PointF* points,
961                           IN INT count)
962    {
963        return SetStatus(DllExports::GdipDrawClosedCurve(nativeGraphics,
964                                                         pen->nativePen,
965                                                         points, count));
966    }
967
968    Status DrawClosedCurve(IN const Pen *pen,
969                           IN const PointF* points,
970                           IN INT count,
971                           IN REAL tension)
972    {
973        return SetStatus(DllExports::GdipDrawClosedCurve2(nativeGraphics,
974                                                          pen->nativePen,
975                                                          points, count,
976                                                          tension));
977    }
978
979    // integer version
980    Status DrawClosedCurve(IN const Pen* pen,
981                           IN const Point* points,
982                           IN INT count)
983    {
984        return SetStatus(DllExports::GdipDrawClosedCurveI(nativeGraphics,
985                                                          pen->nativePen,
986                                                          points,
987                                                          count));
988    }
989
990    Status DrawClosedCurve(IN const Pen *pen,
991                           IN const Point* points,
992                           IN INT count,
993                           IN REAL tension)
994    {
995        return SetStatus(DllExports::GdipDrawClosedCurve2I(nativeGraphics,
996                                                           pen->nativePen,
997                                                           points,
998                                                           count,
999                                                           tension));
1000    }
1001
1002    Status Clear(IN const Color &color)
1003    {
1004        return SetStatus(DllExports::GdipGraphicsClear(
1005            nativeGraphics,
1006            color.GetValue()));
1007    }
1008
1009    // float version
1010    Status FillRectangle(IN const Brush* brush,
1011                         IN const RectF& rect)
1012    {
1013        return FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height);
1014    }
1015
1016    Status FillRectangle(IN const Brush* brush,
1017                         IN REAL x,
1018                         IN REAL y,
1019                         IN REAL width,
1020                         IN REAL height)
1021    {
1022        return SetStatus(DllExports::GdipFillRectangle(nativeGraphics,
1023                                                       brush->nativeBrush, x, y,
1024                                                       width, height));
1025    }
1026
1027    Status FillRectangles(IN const Brush* brush,
1028                          IN const RectF* rects,
1029                          IN INT count)
1030    {
1031        return SetStatus(DllExports::GdipFillRectangles(nativeGraphics,
1032                                                        brush->nativeBrush,
1033                                                        rects, count));
1034    }
1035
1036    // integer version
1037    Status FillRectangle(IN const Brush* brush,
1038                         IN const Rect& rect)
1039    {
1040        return FillRectangle(brush,
1041                             rect.X,
1042                             rect.Y,
1043                             rect.Width,
1044                             rect.Height);
1045    }
1046
1047    Status FillRectangle(IN const Brush* brush,
1048                         IN INT x,
1049                         IN INT y,
1050                         IN INT width,
1051                         IN INT height)
1052    {
1053        return SetStatus(DllExports::GdipFillRectangleI(nativeGraphics,
1054                                                        brush->nativeBrush,
1055                                                        x,
1056                                                        y,
1057                                                        width,
1058                                                        height));
1059    }
1060
1061    Status FillRectangles(IN const Brush* brush,
1062                          IN const Rect* rects,
1063                          IN INT count)
1064    {
1065        return SetStatus(DllExports::GdipFillRectanglesI(nativeGraphics,
1066                                                         brush->nativeBrush,
1067                                                         rects,
1068                                                         count));
1069    }
1070
1071    // float version
1072    Status FillPolygon(IN const Brush* brush,
1073                       IN const PointF* points,
1074                       IN INT count)
1075    {
1076        return FillPolygon(brush, points, count, FillModeAlternate);
1077    }
1078
1079    Status FillPolygon(IN const Brush* brush,
1080                       IN const PointF* points,
1081                       IN INT count,
1082                       IN FillMode fillMode)
1083    {
1084        return SetStatus(DllExports::GdipFillPolygon(nativeGraphics,
1085                                                     brush->nativeBrush,
1086                                                     points, count, fillMode));
1087    }
1088
1089    // integer version
1090    Status FillPolygon(IN const Brush* brush,
1091                       IN const Point* points,
1092                       IN INT count)
1093    {
1094        return FillPolygon(brush, points, count, FillModeAlternate);
1095    }
1096
1097    Status FillPolygon(IN const Brush* brush,
1098                       IN const Point* points,
1099                       IN INT count,
1100                       IN FillMode fillMode)
1101    {
1102        return SetStatus(DllExports::GdipFillPolygonI(nativeGraphics,
1103                                                      brush->nativeBrush,
1104                                                      points, count,
1105                                                      fillMode));
1106    }
1107
1108    // float version
1109    Status FillEllipse(IN const Brush* brush,
1110                       IN const RectF& rect)
1111    {
1112        return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
1113    }
1114
1115    Status FillEllipse(IN const Brush* brush,
1116                       IN REAL x,
1117                       IN REAL y,
1118                       IN REAL width,
1119                       IN REAL height)
1120    {
1121        return SetStatus(DllExports::GdipFillEllipse(nativeGraphics,
1122                                                     brush->nativeBrush, x, y,
1123                                                     width, height));
1124    }
1125
1126    // integer version
1127    Status FillEllipse(IN const Brush* brush,
1128                       IN const Rect& rect)
1129    {
1130        return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
1131    }
1132
1133    Status FillEllipse(IN const Brush* brush,
1134                       IN INT x,
1135                       IN INT y,
1136                       IN INT width,
1137                       IN INT height)
1138    {
1139        return SetStatus(DllExports::GdipFillEllipseI(nativeGraphics,
1140                                                      brush->nativeBrush,
1141                                                      x,
1142                                                      y,
1143                                                      width,
1144                                                      height));
1145    }
1146
1147    // float version
1148    Status FillPie(IN const Brush* brush,
1149                   IN const RectF& rect,
1150                   IN REAL startAngle,
1151                   IN REAL sweepAngle)
1152    {
1153        return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
1154                       startAngle, sweepAngle);
1155    }
1156
1157    Status FillPie(IN const Brush* brush,
1158                   IN REAL x,
1159                   IN REAL y,
1160                   IN REAL width,
1161                   IN REAL height,
1162                   IN REAL startAngle,
1163                   IN REAL sweepAngle)
1164    {
1165        return SetStatus(DllExports::GdipFillPie(nativeGraphics,
1166                                                 brush->nativeBrush, x, y,
1167                                                 width, height, startAngle,
1168                                                 sweepAngle));
1169    }
1170
1171    // integer version
1172    Status FillPie(IN const Brush* brush,
1173                   IN const Rect& rect,
1174                   IN REAL startAngle,
1175                   IN REAL sweepAngle)
1176    {
1177        return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
1178                       startAngle, sweepAngle);
1179    }
1180
1181    Status FillPie(IN const Brush* brush,
1182                   IN INT x,
1183                   IN INT y,
1184                   IN INT width,
1185                   IN INT height,
1186                   IN REAL startAngle,
1187                   IN REAL sweepAngle)
1188    {
1189        return SetStatus(DllExports::GdipFillPieI(nativeGraphics,
1190                                                  brush->nativeBrush,
1191                                                  x,
1192                                                  y,
1193                                                  width,
1194                                                  height,
1195                                                  startAngle,
1196                                                  sweepAngle));
1197    }
1198
1199    Status FillPath(IN const Brush* brush,
1200                    IN const GraphicsPath* path)
1201    {
1202        return SetStatus(DllExports::GdipFillPath(nativeGraphics,
1203                                                  brush->nativeBrush,
1204                                                  path->nativePath));
1205    }
1206
1207    // float version
1208    Status FillClosedCurve(IN const Brush* brush,
1209                           IN const PointF* points,
1210                           IN INT count)
1211    {
1212        return SetStatus(DllExports::GdipFillClosedCurve(nativeGraphics,
1213                                                         brush->nativeBrush,
1214                                                         points, count));
1215
1216    }
1217
1218    Status FillClosedCurve(IN const Brush* brush,
1219                           IN const PointF* points,
1220                           IN INT count,
1221                           IN FillMode fillMode,
1222                           IN REAL tension = 0.5f)
1223    {
1224        return SetStatus(DllExports::GdipFillClosedCurve2(nativeGraphics,
1225                                                          brush->nativeBrush,
1226                                                          points, count,
1227                                                          tension, fillMode));
1228    }
1229
1230    // integer version
1231    Status FillClosedCurve(IN const Brush* brush,
1232                           IN const Point* points,
1233                           IN INT count)
1234    {
1235        return SetStatus(DllExports::GdipFillClosedCurveI(nativeGraphics,
1236                                                          brush->nativeBrush,
1237                                                          points,
1238                                                          count));
1239    }
1240
1241    Status FillClosedCurve(IN const Brush* brush,
1242                           IN const Point* points,
1243                           IN INT count,
1244                           IN FillMode fillMode,
1245                           IN REAL tension = 0.5f)
1246    {
1247        return SetStatus(DllExports::GdipFillClosedCurve2I(nativeGraphics,
1248                                                           brush->nativeBrush,
1249                                                           points, count,
1250                                                           tension, fillMode));
1251    }
1252
1253    // float version
1254    Status FillRegion(IN const Brush* brush,
1255                      IN const Region* region)
1256    {
1257        return SetStatus(DllExports::GdipFillRegion(nativeGraphics,
1258                                                    brush->nativeBrush,
1259                                                    region->nativeRegion));
1260    }
1261
1262    // DrawString and MeasureString
1263    Status
1264    DrawString(
1265        IN const WCHAR        *string,
1266        IN INT                 length,
1267        IN const Font         *font,
1268        IN const RectF        &layoutRect,
1269        IN const StringFormat *stringFormat,
1270        IN const Brush        *brush
1271    )
1272    {
1273        return SetStatus(DllExports::GdipDrawString(
1274            nativeGraphics,
1275            string,
1276            length,
1277            font ? font->nativeFont : NULL,
1278            &layoutRect,
1279            stringFormat ? stringFormat->nativeFormat : NULL,
1280            brush ? brush->nativeBrush : NULL
1281        ));
1282    }
1283
1284    Status
1285    DrawString(
1286        const WCHAR        *string,
1287        INT                 length,
1288        const Font         *font,
1289        const PointF       &origin,
1290        const Brush        *brush
1291    )
1292    {
1293        RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
1294
1295        return SetStatus(DllExports::GdipDrawString(
1296            nativeGraphics,
1297            string,
1298            length,
1299            font ? font->nativeFont : NULL,
1300            &rect,
1301            NULL,
1302            brush ? brush->nativeBrush : NULL
1303        ));
1304    }
1305
1306    Status
1307    DrawString(
1308        const WCHAR        *string,
1309        INT                 length,
1310        const Font         *font,
1311        const PointF       &origin,
1312        const StringFormat *stringFormat,
1313        const Brush        *brush
1314    )
1315    {
1316        RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
1317
1318        return SetStatus(DllExports::GdipDrawString(
1319            nativeGraphics,
1320            string,
1321            length,
1322            font ? font->nativeFont : NULL,
1323            &rect,
1324            stringFormat ? stringFormat->nativeFormat : NULL,
1325            brush ? brush->nativeBrush : NULL
1326        ));
1327    }
1328
1329    Status
1330    MeasureString(
1331        IN const WCHAR        *string,
1332        IN INT                 length,
1333        IN const Font         *font,
1334        IN const RectF        &layoutRect,
1335        IN const StringFormat *stringFormat,
1336        OUT RectF             *boundingBox,
1337        OUT INT               *codepointsFitted = 0,
1338        OUT INT               *linesFilled      = 0
1339    ) const
1340    {
1341        return SetStatus(DllExports::GdipMeasureString(
1342            nativeGraphics,
1343            string,
1344            length,
1345            font ? font->nativeFont : NULL,
1346            &layoutRect,
1347            stringFormat ? stringFormat->nativeFormat : NULL,
1348            boundingBox,
1349            codepointsFitted,
1350            linesFilled
1351        ));
1352    }
1353
1354    Status
1355    MeasureString(
1356        IN const WCHAR        *string,
1357        IN INT                 length,
1358        IN const Font         *font,
1359        IN const SizeF        &layoutRectSize,
1360        IN const StringFormat *stringFormat,
1361        OUT SizeF             *size,
1362        OUT INT               *codepointsFitted = 0,
1363        OUT INT               *linesFilled      = 0
1364    ) const
1365    {
1366        RectF   layoutRect(0, 0, layoutRectSize.Width, layoutRectSize.Height);
1367        RectF   boundingBox;
1368        Status  status;
1369
1370        if (size == NULL)
1371        {
1372            return SetStatus(InvalidParameter);
1373        }
1374
1375        status = SetStatus(DllExports::GdipMeasureString(
1376            nativeGraphics,
1377            string,
1378            length,
1379            font ? font->nativeFont : NULL,
1380            &layoutRect,
1381            stringFormat ? stringFormat->nativeFormat : NULL,
1382            size ? &boundingBox : NULL,
1383            codepointsFitted,
1384            linesFilled
1385        ));
1386
1387        if (size && status == Ok)
1388        {
1389            size->Width  = boundingBox.Width;
1390            size->Height = boundingBox.Height;
1391        }
1392
1393        return status;
1394    }
1395
1396    Status
1397    MeasureString(
1398        IN const WCHAR        *string,
1399        IN INT                 length,
1400        IN const Font         *font,
1401        IN const PointF       &origin,
1402        IN const StringFormat *stringFormat,
1403        OUT RectF             *boundingBox
1404    ) const
1405    {
1406        RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
1407
1408        return SetStatus(DllExports::GdipMeasureString(
1409            nativeGraphics,
1410            string,
1411            length,
1412            font ? font->nativeFont : NULL,
1413            &rect,
1414            stringFormat ? stringFormat->nativeFormat : NULL,
1415            boundingBox,
1416            NULL,
1417            NULL
1418        ));
1419    }
1420
1421
1422    Status
1423    MeasureString(
1424        IN const WCHAR  *string,
1425        IN INT           length,
1426        IN const Font   *font,
1427        IN const RectF  &layoutRect,
1428        OUT RectF       *boundingBox
1429    ) const
1430    {
1431        return SetStatus(DllExports::GdipMeasureString(
1432            nativeGraphics,
1433            string,
1434            length,
1435            font ? font->nativeFont : NULL,
1436            &layoutRect,
1437            NULL,
1438            boundingBox,
1439            NULL,
1440            NULL
1441        ));
1442    }
1443
1444    Status
1445    MeasureString(
1446        IN const WCHAR  *string,
1447        IN INT           length,
1448        IN const Font   *font,
1449        IN const PointF &origin,
1450        OUT RectF       *boundingBox
1451    ) const
1452    {
1453        RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
1454
1455        return SetStatus(DllExports::GdipMeasureString(
1456            nativeGraphics,
1457            string,
1458            length,
1459            font ? font->nativeFont : NULL,
1460            &rect,
1461            NULL,
1462            boundingBox,
1463            NULL,
1464            NULL
1465        ));
1466    }
1467
1468
1469#ifdef DCR_USE_NEW_174340
1470    Status
1471    MeasureCharacterRanges(
1472        IN const WCHAR        *string,
1473        IN INT                 length,
1474        IN const Font         *font,
1475        IN const RectF        &layoutRect,
1476        IN const StringFormat *stringFormat,
1477        IN INT                 regionCount,
1478        OUT Region            *regions
1479    ) const
1480    {
1481        if (!regions || regionCount <= 0)
1482        {
1483            return InvalidParameter;
1484        }
1485
1486        GpRegion **nativeRegions = new GpRegion* [regionCount];
1487
1488        if (!nativeRegions)
1489        {
1490            return OutOfMemory;
1491        }
1492
1493        for (INT i = 0; i < regionCount; i++)
1494        {
1495            nativeRegions[i] = regions[i].nativeRegion;
1496        }
1497
1498        Status status = SetStatus(DllExports::GdipMeasureCharacterRanges(
1499            nativeGraphics,
1500            string,
1501            length,
1502            font ? font->nativeFont : NULL,
1503            layoutRect,
1504            stringFormat ? stringFormat->nativeFormat : NULL,
1505            regionCount,
1506            nativeRegions
1507        ));
1508
1509        delete [] nativeRegions;
1510
1511        return status;
1512    }
1513#endif
1514
1515
1516#ifndef DCR_USE_NEW_174340
1517    Status
1518    MeasureStringRegion(
1519        IN const WCHAR        *string,
1520        IN INT                 length,
1521        IN const Font         *font,
1522        IN const RectF        &layoutRect,
1523        IN const StringFormat *stringFormat,
1524        IN INT                 firstCharacterIndex,
1525        IN INT                 characterCount,
1526        OUT Region            *region
1527    ) const
1528    {
1529        if (region == NULL)
1530        {
1531            return SetStatus(InvalidParameter);
1532        }
1533
1534        return (SetStatus(DllExports::GdipMeasureStringRegion(
1535            nativeGraphics,
1536            string,
1537            length,
1538            font ? font->nativeFont : NULL,
1539            layoutRect,
1540            stringFormat ? stringFormat->nativeFormat : NULL,
1541            firstCharacterIndex,
1542            characterCount,
1543            region->nativeRegion)));
1544    }
1545#endif
1546
1547    Status DrawDriverString(
1548        IN const UINT16  *text,
1549        IN INT            length,
1550        IN const Font    *font,
1551        IN const Brush   *brush,
1552        IN const PointF  *positions,
1553        IN INT            flags,
1554        IN const Matrix        *matrix
1555    )
1556    {
1557        return SetStatus(DllExports::GdipDrawDriverString(
1558            nativeGraphics,
1559            text,
1560            length,
1561            font ? font->nativeFont : NULL,
1562            brush ? brush->nativeBrush : NULL,
1563            positions,
1564            flags,
1565            matrix ? matrix->nativeMatrix : NULL
1566        ));
1567    }
1568
1569    Status MeasureDriverString(
1570        IN const UINT16  *text,
1571        IN INT            length,
1572        IN const Font    *font,
1573        IN const PointF  *positions,
1574        IN INT            flags,
1575        IN const Matrix        *matrix,
1576        OUT RectF        *boundingBox
1577    ) const
1578    {
1579        return SetStatus(DllExports::GdipMeasureDriverString(
1580            nativeGraphics,
1581            text,
1582            length,
1583            font ? font->nativeFont : NULL,
1584            positions,
1585            flags,
1586            matrix ? matrix->nativeMatrix : NULL,
1587            boundingBox
1588        ));
1589    }
1590
1591#ifndef DCR_USE_NEW_168772
1592    Status DriverStringPointToCodepoint(
1593        IN const UINT16  *text,
1594        IN INT            length,
1595        IN const Font    *font,
1596        IN const PointF  *positions,
1597        IN INT            flags,
1598        IN const Matrix  *matrix,
1599        IN const PointF  &hit,
1600        OUT INT          *index,
1601        OUT BOOL         *rightEdge,
1602        OUT REAL         *distance
1603    )
1604    {
1605        return SetStatus(DllExports::GdipDriverStringPointToCodepoint(
1606            nativeGraphics,
1607            text,
1608            length,
1609            font ? font->nativeFont : NULL,
1610            positions,
1611            flags,
1612            matrix ? matrix->nativeMatrix : NULL,
1613            &hit,
1614            index,
1615            rightEdge,
1616            distance
1617        ));
1618    }
1619#endif
1620
1621    // Draw a cached bitmap on this graphics destination offset by
1622    // x, y. Note this will fail with WrongState if the CachedBitmap
1623    // native format differs from this Graphics.
1624
1625    Status DrawCachedBitmap(IN CachedBitmap *cb,
1626                            IN INT x,
1627                            IN INT y)
1628    {
1629        return SetStatus(DllExports::GdipDrawCachedBitmap(
1630            nativeGraphics,
1631            cb->nativeCachedBitmap,
1632            x, y
1633        ));
1634    }
1635
1636    /**
1637     * Draw images (both bitmap and vector)
1638     */
1639    // float version
1640    Status DrawImage(IN Image* image,
1641                     IN const PointF& point)
1642    {
1643        return DrawImage(image, point.X, point.Y);
1644    }
1645
1646    Status DrawImage(IN Image* image,
1647                     IN REAL x,
1648                     IN REAL y)
1649    {
1650        return SetStatus(DllExports::GdipDrawImage(nativeGraphics,
1651                                                   image ? image->nativeImage
1652                                                         : NULL,
1653                                                   x,
1654                                                   y));
1655    }
1656
1657    Status DrawImage(IN Image* image,
1658                     IN const RectF& rect)
1659    {
1660        return DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
1661    }
1662
1663    Status DrawImage(IN Image* image,
1664                     IN REAL x,
1665                     IN REAL y,
1666                     IN REAL width,
1667                     IN REAL height)
1668    {
1669        return SetStatus(DllExports::GdipDrawImageRect(nativeGraphics,
1670                                                       image ? image->nativeImage
1671                                                             : NULL,
1672                                                       x,
1673                                                       y,
1674                                                       width,
1675                                                       height));
1676    }
1677
1678    // integer version
1679    Status DrawImage(IN Image* image,
1680                     IN const Point& point)
1681    {
1682        return DrawImage(image, point.X, point.Y);
1683    }
1684
1685    Status DrawImage(IN Image* image,
1686                     IN INT x,
1687                     IN INT y)
1688    {
1689        return SetStatus(DllExports::GdipDrawImageI(nativeGraphics,
1690                                                    image ? image->nativeImage
1691                                                          : NULL,
1692                                                    x,
1693                                                    y));
1694    }
1695
1696    Status DrawImage(IN Image* image,
1697                     IN const Rect& rect)
1698    {
1699        return DrawImage(image,
1700                         rect.X,
1701                         rect.Y,
1702                         rect.Width,
1703                         rect.Height);
1704    }
1705
1706    Status DrawImage(IN Image* image,
1707                     IN INT x,
1708                     IN INT y,
1709                     IN INT width,
1710                     IN INT height) {
1711        return SetStatus(DllExports::GdipDrawImageRectI(nativeGraphics,
1712                                                        image ? image->nativeImage
1713                                                              : NULL,
1714                                                        x,
1715                                                        y,
1716                                                        width,
1717                                                        height));
1718    }
1719
1720    /**
1721     * Affine or perspective blt
1722     *  destPoints.length = 3: rect => parallelogram
1723     *      destPoints[0] <=> top-left corner of the source rectangle
1724     *      destPoints[1] <=> top-right corner
1725     *      destPoints[2] <=> bottom-left corner
1726     *  destPoints.length = 4: rect => quad
1727     *      destPoints[3] <=> bottom-right corner
1728     *
1729     *  @notes Perspective blt only works for bitmap images.
1730     */
1731    Status DrawImage(IN Image* image,
1732                     IN const PointF* destPoints,
1733                     IN INT count)
1734    {
1735        if (count != 3 && count != 4)
1736            return SetStatus(InvalidParameter);
1737
1738        return SetStatus(DllExports::GdipDrawImagePoints(nativeGraphics,
1739                                                         image ? image->nativeImage
1740                                                               : NULL,
1741                                                         destPoints, count));
1742    }
1743
1744    Status DrawImage(IN Image* image,
1745                     IN const Point* destPoints,
1746                     IN INT count)
1747    {
1748        if (count != 3 && count != 4)
1749            return SetStatus(InvalidParameter);
1750
1751        return SetStatus(DllExports::GdipDrawImagePointsI(nativeGraphics,
1752                                                          image ? image->nativeImage
1753                                                                : NULL,
1754                                                          destPoints,
1755                                                          count));
1756    }
1757
1758    /**
1759     * We need another set of methods similar to the ones above
1760     * that take an additional Rect parameter to specify the
1761     * portion of the source image to be drawn.
1762     */
1763    // float version
1764    Status DrawImage(IN Image* image,
1765                     IN REAL x,
1766                     IN REAL y,
1767                     IN REAL srcx,
1768                     IN REAL srcy,
1769                     IN REAL srcwidth,
1770                     IN REAL srcheight,
1771                     IN Unit srcUnit)
1772    {
1773        return SetStatus(DllExports::GdipDrawImagePointRect(nativeGraphics,
1774                                                            image ? image->nativeImage
1775                                                                  : NULL,
1776                                                            x, y,
1777                                                            srcx, srcy,
1778                                                            srcwidth, srcheight, srcUnit));
1779    }
1780
1781    Status DrawImage(IN Image* image,
1782                     IN const RectF& destRect,
1783                     IN REAL srcx,
1784                     IN REAL srcy,
1785                     IN REAL srcwidth,
1786                     IN REAL srcheight,
1787                     IN Unit srcUnit,
1788                     IN const ImageAttributes* imageAttributes = NULL,
1789                     IN DrawImageAbort callback = NULL,
1790                     IN VOID* callbackData = NULL)
1791    {
1792        return SetStatus(DllExports::GdipDrawImageRectRect(nativeGraphics,
1793                                                           image ? image->nativeImage
1794                                                                 : NULL,
1795                                                           destRect.X,
1796                                                           destRect.Y,
1797                                                           destRect.Width,
1798                                                           destRect.Height,
1799                                                           srcx, srcy,
1800                                                           srcwidth, srcheight,
1801                                                           srcUnit,
1802                                                           imageAttributes
1803                                                            ? imageAttributes->nativeImageAttr
1804                                                            : NULL,
1805                                                           callback,
1806                                                           callbackData));
1807    }
1808
1809    Status DrawImage(IN Image* image,
1810                     IN const PointF* destPoints,
1811                     IN INT count,
1812                     IN REAL srcx,
1813                     IN REAL srcy,
1814                     IN REAL srcwidth,
1815                     IN REAL srcheight,
1816                     IN Unit srcUnit,
1817                     IN const ImageAttributes* imageAttributes = NULL,
1818                     IN DrawImageAbort callback = NULL,
1819                     IN VOID* callbackData = NULL)
1820    {
1821        return SetStatus(DllExports::GdipDrawImagePointsRect(nativeGraphics,
1822                                                             image ? image->nativeImage
1823                                                                   : NULL,
1824                                                             destPoints, count,
1825                                                             srcx, srcy,
1826                                                             srcwidth,
1827                                                             srcheight,
1828                                                             srcUnit,
1829                                                             imageAttributes
1830                                                              ? imageAttributes->nativeImageAttr
1831                                                              : NULL,
1832                                                             callback,
1833                                                             callbackData));
1834    }
1835
1836    // integer version
1837    Status DrawImage(IN Image* image,
1838                     IN INT x,
1839                     IN INT y,
1840                     IN INT srcx,
1841                     IN INT srcy,
1842                     IN INT srcwidth,
1843                     IN INT srcheight,
1844                     IN Unit srcUnit)
1845    {
1846        return SetStatus(DllExports::GdipDrawImagePointRectI(nativeGraphics,
1847                                                             image ? image->nativeImage
1848                                                                   : NULL,
1849                                                             x,
1850                                                             y,
1851                                                             srcx,
1852                                                             srcy,
1853                                                             srcwidth,
1854                                                             srcheight,
1855                                                             srcUnit));
1856    }
1857
1858    Status DrawImage(IN Image* image,
1859                     IN const Rect& destRect,
1860                     IN INT srcx,
1861                     IN INT srcy,
1862                     IN INT srcwidth,
1863                     IN INT srcheight,
1864                     IN Unit srcUnit,
1865                     IN const ImageAttributes* imageAttributes = NULL,
1866                     IN DrawImageAbort callback = NULL,
1867                     IN VOID* callbackData = NULL)
1868    {
1869        return SetStatus(DllExports::GdipDrawImageRectRectI(nativeGraphics,
1870                                                            image ? image->nativeImage
1871                                                                  : NULL,
1872                                                            destRect.X,
1873                                                            destRect.Y,
1874                                                            destRect.Width,
1875                                                            destRect.Height,
1876                                                            srcx,
1877                                                            srcy,
1878                                                            srcwidth,
1879                                                            srcheight,
1880                                                            srcUnit,
1881                                                            imageAttributes
1882                                                            ? imageAttributes->nativeImageAttr
1883                                                            : NULL,
1884                                                            callback,
1885                                                            callbackData));
1886    }
1887
1888    Status DrawImage(IN Image* image,
1889                     IN const Point* destPoints,
1890                     IN INT count,
1891                     IN INT srcx,
1892                     IN INT srcy,
1893                     IN INT srcwidth,
1894                     IN INT srcheight,
1895                     IN Unit srcUnit,
1896                     IN const ImageAttributes* imageAttributes = NULL,
1897                     IN DrawImageAbort callback = NULL,
1898                     IN VOID* callbackData = NULL)
1899    {
1900        return SetStatus(DllExports::GdipDrawImagePointsRectI(nativeGraphics,
1901                                                              image ? image->nativeImage
1902                                                                    : NULL,
1903                                                              destPoints,
1904                                                              count,
1905                                                              srcx,
1906                                                              srcy,
1907                                                              srcwidth,
1908                                                              srcheight,
1909                                                              srcUnit,
1910                                                              imageAttributes
1911                                                               ? imageAttributes->nativeImageAttr
1912                                                               : NULL,
1913                                                              callback,
1914                                                              callbackData));
1915    }
1916
1917    // The following methods are for playing an EMF+ to a graphics
1918    // via the enumeration interface.  Each record of the EMF+ is
1919    // sent to the callback (along with the callbackData).  Then
1920    // the callback can invoke the Metafile::PlayRecord method
1921    // to play the particular record.
1922
1923    Status
1924    EnumerateMetafile(
1925        IN const Metafile *        metafile,
1926        IN const PointF &          destPoint,
1927        IN EnumerateMetafileProc   callback,
1928        IN VOID *                  callbackData    = NULL,
1929        IN const ImageAttributes *       imageAttributes = NULL
1930        )
1931    {
1932        return SetStatus(DllExports::GdipEnumerateMetafileDestPoint(
1933                    nativeGraphics,
1934                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
1935                    destPoint,
1936                    callback,
1937                    callbackData,
1938                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
1939    }
1940
1941    Status
1942    EnumerateMetafile(
1943        IN const Metafile *        metafile,
1944        IN const Point &           destPoint,
1945        IN EnumerateMetafileProc   callback,
1946        IN VOID *                  callbackData    = NULL,
1947        IN const ImageAttributes *       imageAttributes = NULL
1948        )
1949    {
1950        return SetStatus(DllExports::GdipEnumerateMetafileDestPointI(
1951                    nativeGraphics,
1952                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
1953                    destPoint,
1954                    callback,
1955                    callbackData,
1956                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
1957    }
1958
1959    Status
1960    EnumerateMetafile(
1961        IN const Metafile *        metafile,
1962        IN const RectF &           destRect,
1963        IN EnumerateMetafileProc   callback,
1964        IN VOID *                  callbackData    = NULL,
1965        IN const ImageAttributes *       imageAttributes = NULL
1966        )
1967    {
1968        return SetStatus(DllExports::GdipEnumerateMetafileDestRect(
1969                    nativeGraphics,
1970                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
1971                    destRect,
1972                    callback,
1973                    callbackData,
1974                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
1975    }
1976
1977    Status
1978    EnumerateMetafile(
1979        IN const Metafile *        metafile,
1980        IN const Rect &            destRect,
1981        IN EnumerateMetafileProc   callback,
1982        IN VOID *                  callbackData    = NULL,
1983        IN const ImageAttributes *       imageAttributes = NULL
1984        )
1985    {
1986        return SetStatus(DllExports::GdipEnumerateMetafileDestRectI(
1987                    nativeGraphics,
1988                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
1989                    destRect,
1990                    callback,
1991                    callbackData,
1992                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
1993    }
1994
1995    Status
1996    EnumerateMetafile(
1997        IN const Metafile *        metafile,
1998        IN const PointF *          destPoints,
1999        IN INT                     count,
2000        IN EnumerateMetafileProc   callback,
2001        IN VOID *                  callbackData    = NULL,
2002        IN const ImageAttributes *       imageAttributes = NULL
2003        )
2004    {
2005        return SetStatus(DllExports::GdipEnumerateMetafileDestPoints(
2006                    nativeGraphics,
2007                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2008                    destPoints,
2009                    count,
2010                    callback,
2011                    callbackData,
2012                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2013    }
2014
2015    Status
2016    EnumerateMetafile(
2017        IN const Metafile *        metafile,
2018        IN const Point *           destPoints,
2019        IN INT                     count,
2020        IN EnumerateMetafileProc   callback,
2021        IN VOID *                  callbackData    = NULL,
2022        IN const ImageAttributes *       imageAttributes = NULL
2023        )
2024    {
2025        return SetStatus(DllExports::GdipEnumerateMetafileDestPointsI(
2026                    nativeGraphics,
2027                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2028                    destPoints,
2029                    count,
2030                    callback,
2031                    callbackData,
2032                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2033    }
2034
2035    Status
2036    EnumerateMetafile(
2037        IN const Metafile *        metafile,
2038        IN const PointF &          destPoint,
2039        IN const RectF &           srcRect,
2040        IN Unit                    srcUnit,
2041        IN EnumerateMetafileProc   callback,
2042        IN VOID *                  callbackData    = NULL,
2043        IN const ImageAttributes *       imageAttributes = NULL
2044        )
2045    {
2046        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoint(
2047                    nativeGraphics,
2048                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2049                    destPoint,
2050                    srcRect,
2051                    srcUnit,
2052                    callback,
2053                    callbackData,
2054                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2055    }
2056
2057    Status
2058    EnumerateMetafile(
2059        IN const Metafile *        metafile,
2060        IN const Point &           destPoint,
2061        IN const Rect &            srcRect,
2062        IN Unit                    srcUnit,
2063        IN EnumerateMetafileProc   callback,
2064        IN VOID *                  callbackData    = NULL,
2065        IN const ImageAttributes *       imageAttributes = NULL
2066        )
2067    {
2068        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointI(
2069                    nativeGraphics,
2070                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2071                    destPoint,
2072                    srcRect,
2073                    srcUnit,
2074                    callback,
2075                    callbackData,
2076                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2077    }
2078
2079    Status
2080    EnumerateMetafile(
2081        IN const Metafile *        metafile,
2082        IN const RectF &           destRect,
2083        IN const RectF &           srcRect,
2084        IN Unit                    srcUnit,
2085        IN EnumerateMetafileProc   callback,
2086        IN VOID *                  callbackData    = NULL,
2087        IN const ImageAttributes *       imageAttributes = NULL
2088        )
2089    {
2090        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRect(
2091                    nativeGraphics,
2092                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2093                    destRect,
2094                    srcRect,
2095                    srcUnit,
2096                    callback,
2097                    callbackData,
2098                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2099    }
2100
2101    Status
2102    EnumerateMetafile(
2103        IN const Metafile *        metafile,
2104        IN const Rect &            destRect,
2105        IN const Rect &            srcRect,
2106        IN Unit                    srcUnit,
2107        IN EnumerateMetafileProc   callback,
2108        IN VOID *                  callbackData    = NULL,
2109        IN const ImageAttributes *       imageAttributes = NULL
2110        )
2111    {
2112        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRectI(
2113                    nativeGraphics,
2114                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2115                    destRect,
2116                    srcRect,
2117                    srcUnit,
2118                    callback,
2119                    callbackData,
2120                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2121    }
2122
2123    Status
2124    EnumerateMetafile(
2125        IN const Metafile *        metafile,
2126        IN const PointF *          destPoints,
2127        IN INT                     count,
2128        IN const RectF &           srcRect,
2129        IN Unit                    srcUnit,
2130        IN EnumerateMetafileProc   callback,
2131        IN VOID *                  callbackData    = NULL,
2132        IN const ImageAttributes *       imageAttributes = NULL
2133        )
2134    {
2135        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoints(
2136                    nativeGraphics,
2137                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2138                    destPoints,
2139                    count,
2140                    srcRect,
2141                    srcUnit,
2142                    callback,
2143                    callbackData,
2144                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2145    }
2146
2147    Status
2148    EnumerateMetafile(
2149        IN const Metafile *        metafile,
2150        IN const Point *           destPoints,
2151        IN INT                     count,
2152        IN const Rect &            srcRect,
2153        IN Unit                    srcUnit,
2154        IN EnumerateMetafileProc   callback,
2155        IN VOID *                  callbackData    = NULL,
2156        IN const ImageAttributes *       imageAttributes = NULL
2157        )
2158    {
2159        return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointsI(
2160                    nativeGraphics,
2161                    (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
2162                    destPoints,
2163                    count,
2164                    srcRect,
2165                    srcUnit,
2166                    callback,
2167                    callbackData,
2168                    imageAttributes ? imageAttributes->nativeImageAttr : NULL));
2169    }
2170
2171    /**
2172      * Clipping region operations
2173      *
2174      * @notes Simply incredible redundancy here.
2175      */
2176    Status SetClip(IN const Graphics* g,
2177                   IN CombineMode combineMode = CombineModeReplace)
2178    {
2179        return SetStatus(DllExports::GdipSetClipGraphics(nativeGraphics,
2180                                                         g->nativeGraphics,
2181                                                         combineMode));
2182    }
2183
2184    Status SetClip(IN const RectF& rect,
2185                   IN CombineMode combineMode = CombineModeReplace)
2186    {
2187        return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
2188                                                     rect.X, rect.Y,
2189                                                     rect.Width, rect.Height,
2190                                                     combineMode));
2191    }
2192
2193    Status SetClip(IN const Rect& rect,
2194                   IN CombineMode combineMode = CombineModeReplace)
2195    {
2196        return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
2197                                                      rect.X, rect.Y,
2198                                                      rect.Width, rect.Height,
2199                                                      combineMode));
2200    }
2201
2202    Status SetClip(IN const GraphicsPath* path,
2203                   IN CombineMode combineMode = CombineModeReplace)
2204    {
2205        return SetStatus(DllExports::GdipSetClipPath(nativeGraphics,
2206                                                     path->nativePath,
2207                                                     combineMode));
2208    }
2209
2210    Status SetClip(IN const Region* region,
2211                   IN CombineMode combineMode = CombineModeReplace)
2212    {
2213        return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
2214                                                       region->nativeRegion,
2215                                                       combineMode));
2216    }
2217
2218    // This is different than the other SetClip methods because it assumes
2219    // that the HRGN is already in device units, so it doesn't transform
2220    // the coordinates in the HRGN.
2221    Status SetClip(IN HRGN hRgn,
2222                   IN CombineMode combineMode = CombineModeReplace)
2223    {
2224        return SetStatus(DllExports::GdipSetClipHrgn(nativeGraphics, hRgn,
2225                                                     combineMode));
2226    }
2227
2228    Status IntersectClip(IN const RectF& rect)
2229    {
2230        return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
2231                                                     rect.X, rect.Y,
2232                                                     rect.Width, rect.Height,
2233                                                     CombineModeIntersect));
2234    }
2235
2236    Status IntersectClip(IN const Rect& rect)
2237    {
2238        return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
2239                                                      rect.X, rect.Y,
2240                                                      rect.Width, rect.Height,
2241                                                      CombineModeIntersect));
2242    }
2243
2244    Status IntersectClip(IN const Region* region)
2245    {
2246        return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
2247                                                       region->nativeRegion,
2248                                                       CombineModeIntersect));
2249    }
2250
2251    Status ExcludeClip(IN const RectF& rect)
2252    {
2253        return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
2254                                                     rect.X, rect.Y,
2255                                                     rect.Width, rect.Height,
2256                                                     CombineModeExclude));
2257    }
2258
2259    Status ExcludeClip(IN const Rect& rect)
2260    {
2261        return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
2262                                                      rect.X, rect.Y,
2263                                                      rect.Width, rect.Height,
2264                                                      CombineModeExclude));
2265    }
2266
2267    Status ExcludeClip(IN const Region* region)
2268    {
2269        return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
2270                                                       region->nativeRegion,
2271                                                       CombineModeExclude));
2272    }
2273
2274    Status ResetClip()
2275    {
2276        return SetStatus(DllExports::GdipResetClip(nativeGraphics));
2277    }
2278
2279    Status TranslateClip(IN REAL dx,
2280                         IN REAL dy)
2281    {
2282        return SetStatus(DllExports::GdipTranslateClip(nativeGraphics, dx, dy));
2283    }
2284
2285    Status TranslateClip(IN INT dx,
2286                         IN INT dy)
2287    {
2288        return SetStatus(DllExports::GdipTranslateClipI(nativeGraphics,
2289                                                        dx, dy));
2290    }
2291
2292    /**
2293     *  GetClip region from graphics context
2294     */
2295    Status GetClip(OUT Region* region) const
2296    {
2297        return SetStatus(DllExports::GdipGetClip(nativeGraphics,
2298                                                 region->nativeRegion));
2299    }
2300
2301    /**
2302     * Hit testing operations
2303     */
2304    Status GetClipBounds(OUT RectF* rect) const
2305    {
2306        return SetStatus(DllExports::GdipGetClipBounds(nativeGraphics, rect));
2307    }
2308
2309    Status GetClipBounds(OUT Rect* rect) const
2310    {
2311        return SetStatus(DllExports::GdipGetClipBoundsI(nativeGraphics, rect));
2312    }
2313
2314    BOOL IsClipEmpty() const
2315    {
2316        BOOL booln = FALSE;
2317
2318        SetStatus(DllExports::GdipIsClipEmpty(nativeGraphics, &booln));
2319
2320        return booln;
2321    }
2322
2323    Status GetVisibleClipBounds(OUT RectF *rect) const
2324    {
2325
2326        return SetStatus(DllExports::GdipGetVisibleClipBounds(nativeGraphics,
2327                                                              rect));
2328    }
2329
2330    Status GetVisibleClipBounds(OUT Rect *rect) const
2331    {
2332       return SetStatus(DllExports::GdipGetVisibleClipBoundsI(nativeGraphics,
2333                                                              rect));
2334    }
2335
2336    BOOL IsVisibleClipEmpty() const
2337    {
2338        BOOL booln = FALSE;
2339
2340        SetStatus(DllExports::GdipIsVisibleClipEmpty(nativeGraphics, &booln));
2341
2342        return booln;
2343    }
2344
2345    BOOL IsVisible(IN INT x,
2346                   IN INT y) const
2347    {
2348        return IsVisible(Point(x,y));
2349    }
2350
2351    BOOL IsVisible(IN const Point& point) const
2352    {
2353        BOOL booln = FALSE;
2354
2355        SetStatus(DllExports::GdipIsVisiblePointI(nativeGraphics,
2356                                                  point.X,
2357                                                  point.Y,
2358                                                  &booln));
2359
2360        return booln;
2361    }
2362
2363    BOOL IsVisible(IN INT x,
2364                   IN INT y,
2365                   IN INT width,
2366                   IN INT height) const
2367    {
2368        return IsVisible(Rect(x, y, width, height));
2369    }
2370
2371    BOOL IsVisible(IN const Rect& rect) const
2372    {
2373
2374        BOOL booln = TRUE;
2375
2376        SetStatus(DllExports::GdipIsVisibleRectI(nativeGraphics,
2377                                                 rect.X,
2378                                                 rect.Y,
2379                                                 rect.Width,
2380                                                 rect.Height,
2381                                                 &booln));
2382        return booln;
2383    }
2384
2385    BOOL IsVisible(IN REAL x,
2386                   IN REAL y) const
2387    {
2388        return IsVisible(PointF(x, y));
2389    }
2390
2391    BOOL IsVisible(IN const PointF& point) const
2392    {
2393        BOOL booln = FALSE;
2394
2395        SetStatus(DllExports::GdipIsVisiblePoint(nativeGraphics,
2396                                                 point.X,
2397                                                 point.Y,
2398                                                 &booln));
2399
2400        return booln;
2401    }
2402
2403    BOOL IsVisible(IN REAL x,
2404                   IN REAL y,
2405                   IN REAL width,
2406                   IN REAL height) const
2407    {
2408        return IsVisible(RectF(x, y, width, height));
2409    }
2410
2411    BOOL IsVisible(IN const RectF& rect) const
2412    {
2413        BOOL booln = TRUE;
2414
2415        SetStatus(DllExports::GdipIsVisibleRect(nativeGraphics,
2416                                                rect.X,
2417                                                rect.Y,
2418                                                rect.Width,
2419                                                rect.Height,
2420                                                &booln));
2421        return booln;
2422    }
2423
2424    /**
2425     * Save/restore graphics state
2426     */
2427    GraphicsState Save() const
2428    {
2429        GraphicsState gstate;
2430
2431        SetStatus(DllExports::GdipSaveGraphics(nativeGraphics, &gstate));
2432
2433        return gstate;
2434    }
2435
2436    Status Restore(IN GraphicsState gstate)
2437    {
2438        return SetStatus(DllExports::GdipRestoreGraphics(nativeGraphics,
2439                                                         gstate));
2440    }
2441
2442    /**
2443     * Begin and end container drawing
2444     */
2445    GraphicsContainer BeginContainer(IN const RectF &dstrect,
2446                                     IN const RectF &srcrect,
2447                                     IN Unit         unit)
2448    {
2449        GraphicsContainer state;
2450
2451        SetStatus(DllExports::GdipBeginContainer(nativeGraphics, &dstrect,
2452                                                 &srcrect, unit, &state));
2453
2454        return state;
2455    }
2456
2457    /**
2458     * Begin and end container drawing
2459     */
2460    GraphicsContainer BeginContainer(IN const Rect    &dstrect,
2461                                     IN const Rect    &srcrect,
2462                                     IN Unit           unit)
2463    {
2464        GraphicsContainer state;
2465
2466        SetStatus(DllExports::GdipBeginContainerI(nativeGraphics, &dstrect,
2467                                                  &srcrect, unit, &state));
2468
2469        return state;
2470    }
2471
2472    GraphicsContainer BeginContainer()
2473    {
2474        GraphicsContainer state;
2475
2476        SetStatus(DllExports::GdipBeginContainer2(nativeGraphics, &state));
2477
2478        return state;
2479    }
2480
2481    Status EndContainer(IN GraphicsContainer state)
2482    {
2483        return SetStatus(DllExports::GdipEndContainer(nativeGraphics, state));
2484    }
2485
2486    // only valid when recording metafiles
2487    Status AddMetafileComment(IN const BYTE * data,
2488                              IN UINT sizeData)
2489    {
2490        return SetStatus(DllExports::GdipComment(nativeGraphics, sizeData, data));
2491    }
2492
2493    /**
2494     * Get/SetLayout
2495     * Support for Middle East localization (right-to-left mirroring)
2496     */
2497    GraphicsLayout GetLayout() const
2498    {
2499        GraphicsLayout layout;
2500
2501        SetStatus(DllExports::GdipGetGraphicsLayout(nativeGraphics, &layout));
2502
2503        return layout;
2504    }
2505
2506    Status SetLayout(IN const GraphicsLayout layout)
2507    {
2508        return SetStatus(
2509            DllExports::GdipSetGraphicsLayout(nativeGraphics, layout)
2510        );
2511    }
2512
2513    static HPALETTE GetHalftonePalette()
2514    {
2515        return DllExports::GdipCreateHalftonePalette();
2516    }
2517
2518    Status GetLastStatus() const
2519    {
2520        Status lastStatus = lastResult;
2521        lastResult = Ok;
2522
2523        return lastStatus;
2524    }
2525
2526protected:
2527
2528#ifdef DCR_USE_NEW_250932
2529
2530private:
2531    Graphics(const Graphics &);
2532    Graphics& operator=(const Graphics &);
2533protected:
2534
2535#else
2536
2537    Graphics(const Graphics& graphics)
2538    {
2539        graphics;
2540        SetStatus(NotImplemented);
2541    }
2542
2543    Graphics& operator=(const Graphics& graphics)
2544    {
2545        graphics;
2546        SetStatus(NotImplemented);
2547        return *this;
2548    }
2549
2550#endif
2551
2552    Graphics(GpGraphics* graphics)
2553    {
2554        lastResult = Ok;
2555        SetNativeGraphics(graphics);
2556    }
2557
2558    VOID SetNativeGraphics(GpGraphics *graphics)
2559    {
2560        this->nativeGraphics = graphics;
2561    }
2562
2563    Status SetStatus(Status status) const
2564    {
2565        if (status != Ok)
2566            return (lastResult = status);
2567        else
2568            return status;
2569    }
2570
2571    // Methods necessary to subclass Graphics for extension test.
2572
2573    GpGraphics* GetNativeGraphics() const
2574    {
2575        return this->nativeGraphics;
2576    }
2577
2578    GpPen* GetNativePen(const Pen* pen)
2579    {
2580        return pen->nativePen;
2581    }
2582
2583protected:
2584    GpGraphics* nativeGraphics;
2585    mutable Status lastResult;
2586
2587};
2588
2589//----------------------------------------------------------------------------
2590// Extra implementation of GraphicsPath methods that use Graphics
2591//----------------------------------------------------------------------------
2592
2593/**
2594 * Get the bounds of the path object with the given transform.
2595 * This is not always the tightest bounds.
2596 */
2597
2598inline Status
2599GraphicsPath::GetBounds(
2600    OUT RectF* bounds,
2601    IN const Matrix* matrix,
2602    IN const Pen* pen) const
2603{
2604    GpMatrix* nativeMatrix = NULL;
2605    GpPen* nativePen = NULL;
2606
2607    if (matrix)
2608        nativeMatrix = matrix->nativeMatrix;
2609
2610    if (pen)
2611        nativePen = pen->nativePen;
2612
2613    return SetStatus(DllExports::GdipGetPathWorldBounds(nativePath, bounds,
2614                                                   nativeMatrix, nativePen));
2615}
2616
2617// integer version
2618inline Status
2619GraphicsPath::GetBounds(
2620    OUT Rect* bounds,
2621    IN const Matrix* matrix,
2622    IN const Pen* pen
2623) const
2624{
2625    GpMatrix* nativeMatrix = NULL;
2626    GpPen* nativePen = NULL;
2627
2628    if (matrix)
2629        nativeMatrix = matrix->nativeMatrix;
2630
2631    if (pen)
2632        nativePen = pen->nativePen;
2633
2634    return SetStatus(DllExports::GdipGetPathWorldBoundsI(nativePath, bounds,
2635                                                    nativeMatrix, nativePen));
2636}
2637
2638//----------------------------------------------------------------------------
2639// Hit testing operations
2640//----------------------------------------------------------------------------
2641
2642inline BOOL
2643GraphicsPath::IsVisible(
2644    IN REAL x,
2645    IN REAL y,
2646    IN const Graphics* g) const
2647{
2648   BOOL booln = FALSE;
2649
2650   GpGraphics* nativeGraphics = NULL;
2651
2652   if (g)
2653       nativeGraphics = g->nativeGraphics;
2654
2655   SetStatus(DllExports::GdipIsVisiblePathPoint(nativePath,
2656                                                x, y, nativeGraphics,
2657                                                &booln));
2658   return booln;
2659}
2660
2661inline BOOL
2662GraphicsPath::IsVisible(
2663    IN INT x,
2664    IN INT y,
2665    IN const Graphics* g) const
2666{
2667   BOOL booln = FALSE;
2668
2669   GpGraphics* nativeGraphics = NULL;
2670
2671   if (g)
2672       nativeGraphics = g->nativeGraphics;
2673
2674   SetStatus(DllExports::GdipIsVisiblePathPointI(nativePath,
2675                                                 x, y, nativeGraphics,
2676                                                 &booln));
2677   return booln;
2678}
2679
2680inline BOOL
2681GraphicsPath::IsOutlineVisible(
2682    IN REAL x,
2683    IN REAL y,
2684    IN const Pen* pen,
2685    IN const Graphics* g) const
2686{
2687    BOOL booln = FALSE;
2688
2689    GpGraphics* nativeGraphics = NULL;
2690    GpPen* nativePen = NULL;
2691
2692    if(g)
2693        nativeGraphics = g->nativeGraphics;
2694    if(pen)
2695        nativePen = pen->nativePen;
2696
2697    SetStatus(DllExports::GdipIsOutlineVisiblePathPoint(nativePath,
2698                                                        x, y, nativePen, nativeGraphics,
2699                                                        &booln));
2700    return booln;
2701}
2702
2703inline BOOL
2704GraphicsPath::IsOutlineVisible(
2705    IN INT x,
2706    IN INT y,
2707    IN const Pen* pen,
2708    IN const Graphics* g) const
2709{
2710    BOOL booln = FALSE;
2711
2712    GpGraphics* nativeGraphics = NULL;
2713    GpPen* nativePen = NULL;
2714
2715    if(g)
2716        nativeGraphics = g->nativeGraphics;
2717    if(pen)
2718        nativePen = pen->nativePen;
2719
2720    SetStatus(DllExports::GdipIsOutlineVisiblePathPointI(nativePath,
2721                                                         x, y, nativePen, nativeGraphics,
2722                                                         &booln));
2723    return booln;
2724}
2725
2726#endif
2727