' Classes/System/Drawing/Graphics.ab

#ifndef __SYSTEM_DRAWING_GRAPHICS_AB__
#define __SYSTEM_DRAWING_GRAPHICS_AB__

Class Brush : End Class
Class Pen : End Class
Class StringFormat : End Class
Class Image : End Class
Class ImageAttributes : End Class
Class Metafile : End Class
Class Region : End Class
Class GraphicsPath : End Class
Class CachedBitmap : End Class

#include <GdiplusGpStubs.ab>
#include <GdiPlusFlat.ab>
#include <Classes/System/Drawing/misc.ab>
#include <Classes/System/Drawing/Rectangle.ab>
#include <Classes/System/Drawing/RectangleF.ab>
#include <Classes/System/Drawing/Point.ab>
#include <Classes/System/Drawing/PointF.ab>
#include <Classes/System/Drawing/SizeF.ab>
#include <Classes/System/Drawing/Font.ab>
'#include <Classes/System/Drawing/Brush.ab>
'#include <Classes/System/Drawing/Pen.ab>
'#include <Classes/System/Drawing/Region.ab>
'#include <Classes/System/Drawing/StringFormat.ab>
'#include <Classes/System/Drawing/Image.ab>
#include <Classes/System/Drawing/Drawing2D/misc.ab>
#include <Classes/System/Drawing/Drawing2D/Matrix.ab>

Class Graphics
Public
	'=========================================================================
	' Properties
	'=========================================================================
	Const Function Clip() As Region
		Dim r As Region
		GetClip(r)
		Return r
	End Function

	Sub Clip(region As /*Const*/ Region)
		SetClip(region, CombineMode.Replace)
	End Sub

	Const Function ClipBounds() As RectangleF
		Dim rc As RectangleF
		GetClipBounds(rc)
		Return rc
	End Function

	Sub ClipBounds(rc As RectangleF)
		SetClipBounds(rc)
	End Sub

	Function CompositingMode() As CompositingMode
		Return GetCompositingMode()
	End Function

	Sub CompositingMode(mode As CompositingMode)
		SetCompositingMode(mode)
	End Sub

	Function CompositingQuality() As CompositingQuality
		Return GetCompositingQuality()
	End Function

	Sub CompositingQuality(cq As CompositingQuality)
		SetCompositingQuality(cq)
	End Sub

	Const Function DpiX() As Single
		Dim dpi As Single
		SetStatus(GdipGetDpiX(nativeGraphics, dpi))
		Return dpi
	End Function

	Const Function DpiY() As Single
		Dim dpi As Single
		SetStatus(GdipGetDpiY(nativeGraphics, dpi))
		Return dpi
	End Function

	Const Function InterpolationMode() As InterpolationMode
		Return GetInterpolationMode()
	End Function

	Sub InterpolationMode(im As InterpolationMode)
		SetInterpolationMode(im)
	End Sub

	Const Function IsClipEmpty() As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsClipEmpty(nativeGraphics, b))
		Return b
	End Function

	Const Function IsVisibleClipEmpty() As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsVisibleClipEmpty(nativeGraphics, b))
		Return b
	End Function

	Function PageScale(scale As Single) As Status
		Return SetStatus(GdipSetPageScale(nativeGraphics, scale))
	End Function

	Const Function PageScale() As Single
		Dim scale As Single
		SetStatus(GdipGetPageScale(nativeGraphics, scale))
		Return scale
	End Function

	Const Function PageUnit() As GraphicsUnit
		Dim unit As GraphicsUnit
		SetStatus(GdipGetPageUnit(nativeGraphics, unit))
		Return unit
	End Function

	Function PageUnit(unit As GraphicsUnit) As Status
		Return SetStatus(GdipSetPageUnit(nativeGraphics, unit))
	End Function

	Function PixelOffsetMode() As PixelOffsetMode
		Return GetPixelOffsetMode()
	End Function

	Sub PixelOffsetMode(mode  As PixelOffsetMode)
		SetPixelOffsetMode(mode)
	End Sub

	Function RenderingOrigin() As Point
		Dim pt As Point
		GetRenderingOrigin(pt.X, pt.Y)
		Return pt
	End Function

	Sub RenderingOrigin(pt As Point)
		SetRenderingOrigin(pt.X, pt.Y)
	End Sub

	Function SmoothingMode() As SmoothingMode
		Return GetSmoothingMode()
	End Function

	Sub SmoothingMode(mode As SmoothingMode)
		SetSmoothingMode(mode)
	End Sub

	Function TextContrast() As DWord
		Return GetTextContrast()
	End Function

	Sub TextContrast(contrast As DWord)
		SetTextContrast(contrast)
	End Sub

	Function TextRenderingHint() As TextRenderingHint
		Return GetTextRenderingHint()
	End Function

	Sub TextRenderingHint(mode As TextRenderingHint)
		SetTextRenderingHint(mode)
	End Sub

	Function Transform() As Matrix
		Dim matrix As Matrix
		GetTransform(matrix)
		Return matrix
	End Function

	Sub Transform(matrix As Matrix)
		SetTransform(matirx)
	End Sub

	Function VisibleClipBounds() As RectangleF
		Dim rc As RectangleF
		GetVisibleClipBounds(rc)
		Return rc
	End Function

	'=========================================================================
	' Methods
	'=========================================================================
	Static Function FromHDC(hdc As HDC) As Graphics
		Return New Graphics(hdc)
	End Function

	Static Function FromHDC(hdc As HDC, hdevice As HANDLE) As Graphics
		Return New Graphics(hdc, hdevice)
	End Function

	Static Function FromHWND(hwnd As HWND) As Graphics
		Return New Graphics(hwnd, FALSE)
	End Function

	Static Function FromHWND(hwnd As DWord, icm As BOOL) As Graphics
		Return New Graphics(hwnd, icm)
	End Function

	Static Function FromImage(image As Image) As Graphics
		Return New Graphics(image)
	End Function

	Sub Graphics(hdc As HDC)
		Dim graphics = 0 As GpGraphics
		lastResult = GdipCreateFromHDC(hdc, graphics)
		SetNativeGraphics(graphics)
	End Sub

	Sub Graphics(hdc As HDC, hdevice As HANDLE)
		Dim graphics = 0 As *GpGraphics
		lastResult = GdipCreateFromHDC2(hdc, hdevice, graphics)
		SetNativeGraphics(graphics)
	End Sub

	Sub Graphics(hwnd As HWND)
		Dim graphics = 0 As *GpGraphics
		lastResult = GdipCreateFromHWND(hwnd, graphics)
		SetNativeGraphics(graphics)
	End Sub

	Sub Graphics(hwnd As HWND, icm As BOOL)
		Dim graphics = 0 As *GpGraphics
		If icm <> FALSE Then
			lastResult = GdipCreateFromHWNDICM(hwnd, graphics)
		Else
			lastResult = GdipCreateFromHWND(hwnd, graphics)
		End If
		SetNativeGraphics(graphics)
	End Sub

	Sub Graphics(image As Image)
		Dim graphics = 0 As *GpGraphics
		If (image != 0)
			lastResult = GdipGetImageGraphicsContext(image->NativeImage, graphics)
		End If
		SetNativeGraphics(graphics)
	End Sub

	Sub ~Graphics()
		GdipDeleteGraphics(nativeGraphics)
	End Sub

	Sub Flush()
		GdipFlush(nativeGraphics, FlushIntention.Flush)
	End Sub

	Sub Flush(intention As FlushIntention)
		GdipFlush(nativeGraphics, intention)
	End Sub

	'------------------------------------------------------------------------
	' GDI Interop methods
	'------------------------------------------------------------------------

	' Locks the graphics until ReleaseDC is called

	Function GetHDC() As HDC
		Dim hdc = 0 As HDC
		SetStatus(GdipGetDC(nativeGraphics, hdc))
		Return hdc
	End Function

	Sub ReleaseHDC(hdc As HDC)
		SetStatus(GdipReleaseDC(nativeGraphics, hdc))
	End Sub

	'------------------------------------------------------------------------
	' Rendering modes
	'------------------------------------------------------------------------

	Function SetRenderingOrigin(x As Long, y As Long) As Status
		Return SetStatus(GdipSetRenderingOrigin(nativeGraphics, x, y))
	End Function

	Const Function GetRenderingOrigin(x As Long, y As Long) As Status
		Return SetStatus(GdipGetRenderingOrigin(nativeGraphics, x, y))
	End Function

	Function SetCompositingMode(compositingMode As CompositingMode) As Status
		Return SetStatus(GdipSetCompositingMode(nativeGraphics, compositingMode))
	End Function

	Const Function GetCompositingMode() As CompositingMode
		Dim mode As CompositingMode
		SetStatus(GdipGetCompositingMode(nativeGraphics, mode))
		Return mode
	End Function

	Function SetCompositingQuality(compositingQuality As CompositingQuality)
		Return SetStatus(GdipSetCompositingQuality(nativeGraphics, compositingQuality))
	End Function

	Const Function GetCompositingQuality() As CompositingQuality
		Dim quality As CompositingQuality
		SetStatus(GdipGetCompositingQuality(nativeGraphics, quality))
		Return quality
	End Function

	Function SetTextRenderingHint(newMode As TextRenderingHint) As Status
		Return SetStatus(GdipSetTextRenderingHint(nativeGraphics, newMode))
	End Function

	Const Function GetTextRenderingHint() As TextRenderingHint
		Dim hint As TextRenderingHint
		SetStatus(GdipGetTextRenderingHint(nativeGraphics, hint))
		Return hint
	End Function

	Function SetTextContrast(contrast As DWord) As Status
		Return SetStatus(GdipSetTextContrast(nativeGraphics, contrast))
	End Function

	Const Function GetTextContrast() As DWord
		Dim contrast As DWord
		SetStatus(GdipGetTextContrast(nativeGraphics, contrast))
		Return contrast
	End Function

	Const Function GetInterpolationMode() As InterpolationMode
		Dim mode = InterpolationMode.Invalid As InterpolationMode
		SetStatus(GdipGetInterpolationMode(nativeGraphics, mode))
		Return mode
	End Function

	Function SetInterpolationMode(interpolationMode As InterpolationMode) As Status
		Return SetStatus(GdipSetInterpolationMode(nativeGraphics, interpolationMode))
	End Function

	Const Function GetSmoothingMode() As SmoothingMode
		Dim smoothingMode = SmoothingMode.Invalid As SmoothingMode
		SetStatus(GdipGetSmoothingMode(nativeGraphics, smoothingMode))
		Return smoothingMode
	End Function

	Function SetSmoothingMode(smoothingMode As SmoothingMode) As Status
		Return SetStatus(GdipSetSmoothingMode(nativeGraphics, smoothingMode))
	End Function

	Const Function GetPixelOffsetMode() As PixelOffsetMode
		Dim pixelOffsetMode = PixelOffsetMode.Invalid As PixelOffsetMode
		SetStatus(GdipGetPixelOffsetMode(nativeGraphics, pixelOffsetMode))
		Return pixelOffsetMode
	End Function

	Function SetPixelOffsetMode(pixelOffsetMode As PixelOffsetMode) As Status
		Return SetStatus(GdipSetPixelOffsetMode(nativeGraphics, pixelOffsetMode))
	End Function

	'------------------------------------------------------------------------
	' Manipulate current world transform
	'------------------------------------------------------------------------

	Function SetTransform(matrix As /*Const*/ *Matrix) As Status
		Return SetStatus(GdipSetWorldTransform(nativeGraphics, matrix->nativeMatrix))
	End Function

	Function ResetTransform() As Status
		Return SetStatus(GdipResetWorldTransform(nativeGraphics))
	End Function

	Function MultiplyTransform(matrix As /*Const*/ Matrix) As Status
		Return SetStatus(GdipMultiplyWorldTransform(nativeGraphics, matrix->nativeMatrix, MatrixOrder.Prepend))
	End Function

	Function MultiplyTransform(matrix As /*Const*/ Matrix, order As MatrixOrder) As Status
		Return SetStatus(GdipMultiplyWorldTransform(nativeGraphics, matrix->nativeMatrix, order))
	End Function

	Function TranslateTransform(dx As Single, dy As Single) As Status
		Return SetStatus(GdipTranslateWorldTransform(nativeGraphics, dx, dy, MatrixOrder.Prepend))
	End Function

	Function TranslateTransform(dx As Single, dy As Single, order As MatrixOrder) As Status
		Return SetStatus(GdipTranslateWorldTransform(nativeGraphics, dx, dy, order))
	End Function

	Function ScaleTransform(sx As Single, sy As Single) As Status
		Return SetStatus(GdipScaleWorldTransform(nativeGraphics, sx, sy, MatrixOrder.Prepend))
	End Function

	Function ScaleTransform(sx As Single, sy As Single, order As MatrixOrder) As Status
		Return SetStatus(GdipScaleWorldTransform(nativeGraphics, sx, sy, order))
	End Function

	Function RotateTransform(angle As Single) As Status
		Return SetStatus(GdipRotateWorldTransform(nativeGraphics, angle, MatrixOrder.Prepend))
	End Function

	Function RotateTransform(angle As Single, order As MatrixOrder) As Status
		Return SetStatus(GdipRotateWorldTransform(nativeGraphics, angle, order))
	End Function

	Const Function GetTransform(matrix As Matrix) As Status
		Return SetStatus(GdipGetWorldTransform(nativeGraphics, matrix->nativeMatrix))
	End Function

	Const Function TransformPoints(destSpace As CoordinateSpace, srcSpace As CoordinateSpace, pts As PointF, count As Long) As Status
		Return SetStatus(GdipTransformPoints(nativeGraphics, destSpace, srcSpace, pts, count))
	End Function

	Const Function TransformPoints(destSpace As CoordinateSpace, srcSpace As CoordinateSpace, pts As Point, count As Long) As Status
		Return SetStatus(GdipTransformPointsI(nativeGraphics, destSpace, srcSpace, pts, count))
	End Function

	'------------------------------------------------------------------------
	' GetNearestColor (for <= 8bpp surfaces).	Note: Alpha is ignored.
	'------------------------------------------------------------------------

	Const Function GetNearestColor(color As Color) As Status
		Dim argb = color->Value
		Dim status = SetStatus(GdipGetNearestColor(nativeGraphics, argb))
		color->Value = argb
		Return status
	End Function

	Function DrawLine(pen As /*Const*/ Pen, x1 As Single, y1 As Single, x2 As Single, y2 As Single) As Status
		Return SetStatus(GdipDrawLine(nativeGraphics, pen->nativePen, x1, y1, x2, y2))
	End Function

	Function DrawLine(pen As /*Const*/ Pen, pt1 As /*Const*/ PointF, pt2 As /*Const*/ PointF) As Status
		Return DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y)
	End Function

	Function DrawLines(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipDrawLines(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawLine(pen As /*Const*/ Pen, x1 As Long, y1 As Long, x2 As Long, y2 As Long) As Status
		Return SetStatus(GdipDrawLineI(nativeGraphics, pen->nativePen, x1, y1, x2, y2))
	End Function

	Function DrawLine(pen As /*Const*/ Pen, pt1 As /*Const*/ Point, pt2 As /*Const*/ Point) As Status
		Return DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y)
	End Function

	Function DrawLines(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipDrawLinesI(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawArc(pen As /*Const*/ Pen, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipDrawArc(nativeGraphics, pen->nativePen, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function DrawArc(pen As /*Const*/ Pen, rect As /*Const*/ RectangleF, startAngle As Single, sweepAngle As Single) As Status
		Return DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function DrawArc(pen As /*Const*/ Pen, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipDrawArcI(nativeGraphics, pen->nativePen, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function DrawArc(pen As /*Const*/ Pen, rect As /*Const*/ Rectangle, startAngle As Single, sweepAngle As Single) As Status
		Return DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function DrawBezier(pen As /*Const*/ Pen, x1 As Single, y1 As Single, x2 As Single, y2 As Single, x3 As Single, y3 As Single, x4 As Single, y4 As Single) As Status
		Return SetStatus(GdipDrawBezier(nativeGraphics, pen->nativePen, x1, y1,x2, y2, x3, y3, x4, y4))
	End Function

	Function DrawBezier(pen As /*Const*/ Pen, pt1 As /*Const*/ PointF, pt2 As /*Const*/ PointF, pt3 As /*Const*/ PointF, pt4 As /*Const*/ PointF) As Status
		Return DrawBezier(pen, pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y)
	End Function

	Function DrawBeziers(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipDrawBeziers(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawBezier(pen As /*Const*/ Pen, x1 As Long, y1 As Long, x2 As Long, y2 As Long, x3 As Long, y3 As Long, x4 As Long, y4 As Long) As Status
		Return SetStatus(GdipDrawBezierI(nativeGraphics, pen->nativePen, x1, y1, x2, y2, x3, y3, x4, y4))
	End Function

	Function DrawBezier(pen As /*Const*/ Pen, pt1 As /*Const*/ Point, pt2 As /*Const*/ Point, pt3 As /*Const*/ Point, pt4 As /*Const*/ Point) As Status
		Return DrawBezier(pen pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y)
	End Function

	Function DrawBeziers(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipDrawBeziersI(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawRectangle(pen As /*Const*/ Pen, rect As /*Const*/ RectangleF) As Status
		Return DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawRectangle(pen As /*Const*/ Pen, x As Single, y As Single, width As Single, height As Single) As Status
		Return SetStatus(GdipDrawRectangle(nativeGraphics, pen->nativePen, x, y, width, height))
	End Function

	Function DrawRectangles(pen As /*Const*/ Pen, rects As /*Const*/ *RectangleF, count As Long) As Status
		Return SetStatus(GdipDrawRectangles(nativeGraphics, pen->nativePen, rects, count))
	End Function

	Function DrawRectangle(pen As /*Const*/ Pen, rect As /*Const*/ Rectangle) As Status
		Return DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawRectangle(pen As /*Const*/ Pen, x As Long, y As Long, width As Long, height As Long) As Status
		Return SetStatus(GdipDrawRectangleI(nativeGraphics, pen->nativePen, x, y, width, height))
	End Function

	Function DrawRectangles(pen As /*Const*/ Pen, rects As /*Const*/ *Rectangle,  count As Long) As Status
		Return SetStatus(GdipDrawRectanglesI(nativeGraphics, pen->nativePen, rects, count))
	End Function

	Function DrawEllipse(pen As /*Const*/ Pen, rect As /*Const*/ RectangleF) As Status
		Return DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawEllipse(pen As /*Const*/ Pen, x As Single, y As Single, width As Single, height As Single) As Status
		Return SetStatus(GdipDrawEllipse(nativeGraphics, pen->nativePen, x, y, width, height))
	End Function

	Function DrawEllipse(pen As /*Const*/ Pen, rect As /*Const*/ Rectangle) As Status
		Return DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawEllipse(pen As /*Const*/ Pen, x As Long, y As Long, width As Long, height As Long) As Status
		Return SetStatus(GdipDrawEllipseI(nativeGraphics, pen->nativePen, x, y, width, height))
	End Function

	Function DrawPie(pen As /*Const*/ Pen, rect As /*Const*/ RectangleF, startAngle As Single, sweepAngle As Single) As Status
		Return DrawPie(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function DrawPie(pen As /*Const*/ Pen, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipDrawPie(nativeGraphics, pen->nativePen, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function DrawPie(pen As /*Const*/ Pen, rect As /*Const*/ Rectangle, startAngle As Single, sweepAngle As Single) As Status
		Return DrawPie(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function DrawPie(pen As /*Const*/ Pen, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipDrawPieI(nativeGraphics, pen->nativePen, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function DrawPolygon(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipDrawPolygon(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawPolygon(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipDrawPolygonI(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawPath(pen As /*Const*/ Pen, path As /*Const*/ GraphicsPath) As Status
		Return SetStatus(GdipDrawPath(nativeGraphics, pen->nativePen, path->nativePath))
'		Return SetStatus(GdipDrawPath(nativeGraphics, pen ? pen->nativePen : NULL, path ? path->nativePath : NULL))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipDrawCurve(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long, tension As Single) As Status
		Return SetStatus(GdipDrawCurve2(nativeGraphics, pen->nativePen, points,count, tension))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long, offset As Long, numberOfSegments As Long) As Status
		Return SetStatus(GdipDrawCurve3(nativeGraphics, pen->nativePen, points, count, offset,numberOfSegments, 0.5))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long, offset As Long, numberOfSegments As Long, tension As Single) As Status
		Return SetStatus(GdipDrawCurve3(nativeGraphics, pen->nativePen, points, count, offset,numberOfSegments, tension))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipDrawCurveI(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long, tension As Single) As Status
		Return SetStatus(GdipDrawCurve2I(nativeGraphics, pen->nativePen, points, count, tension))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long, offset As Long, numberOfSegments As Long) As Status
		Return SetStatus(GdipDrawCurve3I(nativeGraphics, pen->nativePen, points, count, offset, numberOfSegments, 0.5))
	End Function

	Function DrawCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long, offset As Long, numberOfSegments As Long, tension As Single) As Status
		Return SetStatus(GdipDrawCurve3I(nativeGraphics, pen->nativePen, points, count, offset, numberOfSegments, tension))
	End Function

	Function DrawClosedCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipDrawClosedCurve(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawClosedCurve(pen As /*Const*/ Pen, points As /*Const*/ *PointF, count As Long, tension As Single) As Status
		Return SetStatus(GdipDrawClosedCurve2(nativeGraphics, pen->nativePen, points, count, tension))
	End Function

	Function DrawClosedCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipDrawClosedCurveI(nativeGraphics, pen->nativePen, points, count))
	End Function

	Function DrawClosedCurve(pen As /*Const*/ Pen, points As /*Const*/ *Point, count As Long, tension As Single) As Status
		Return SetStatus(GdipDrawClosedCurve2I(nativeGraphics, pen->nativePen, points, count, tension))
	End Function

	Function Clear(color As /*Const*/ Color) As Status
		Return SetStatus(GdipGraphicsClear(nativeGraphics, color.Value))
	End Function

	Function FillRectangle(brush As /*Const*/ Brush, rect As /*Const*/ RectangleF) As Status
		Return FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function FillRectangle(brush As /*Const*/ Brush, x As Single, y As Single, width As Single, height As Single) As Status
		Return SetStatus(GdipFillRectangle(nativeGraphics, brush->nativeBrush, x, y, width, height))
	End Function

	Function FillRectangles(brush As /*Const*/ Brush, rects As /*Const*/ *RectangleF, count As Long) As Status
		Return SetStatus(GdipFillRectangles(nativeGraphics,brush->nativeBrush,rects, count))
	End Function

	Function FillRectangle(brush As /*Const*/ Brush, rect As /*Const*/ Rectangle) As Status
		Return FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function FillRectangle(brush As /*Const*/ Brush, x As Long, y As Long, width As Long, height As Long) As Status
		Return SetStatus(GdipFillRectangleI(nativeGraphics, brush->nativeBrush, x, y, width, height))
	End Function

	Function FillRectangles(brush As /*Const*/ Brush, rects As /*Const*/ *Rectangle, count As Long) As Status
		Return SetStatus(GdipFillRectanglesI(nativeGraphics, brush->nativeBrush, rects, count))
	End Function

	Function FillPolygon(brush As /*Const*/ Brush, points As /*Const*/ *PointF, count As Long) As Status
		Return FillPolygon(brush, points, count, FillModeAlternate)
	End Function

	Function FillPolygon(brush As /*Const*/ Brush, points As /*Const*/ *PointF, count As Long, fillMode As FillMode) As Status
		Return SetStatus(GdipFillPolygon(nativeGraphics, brush->nativeBrush, points, count, fillMode))
	End Function

	Function FillPolygon(brush As /*Const*/ Brush, points As /*Const*/ *Point, count As Long) As Status
		Return FillPolygon(brush, points, count, FillModeAlternate)
	End Function

	Function FillPolygon(brush As /*Const*/ Brush, points As /*Const*/ *Point, count As Long, fillMode As FillMode) As Status
		Return SetStatus(GdipFillPolygonI(nativeGraphics, brush->nativeBrush, points, count, fillMode))
	End Function

	Function FillEllipse(brush As /*Const*/ Brush, rect As /*Const*/ RectangleF) As Status
		Return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function FillEllipse(brush As /*Const*/ Brush, x As Single, y As Single, width As Single, height As Single) As Status
		Return SetStatus(GdipFillEllipse(nativeGraphics, brush->nativeBrush, x, y, width, height))
	End Function

	Function FillEllipse(brush As /*Const*/ Brush, rect As /*Const*/ Rectangle) As Status
		Return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function FillEllipse(brush As /*Const*/ Brush, x As Long, y As Long, width As Long, height As Long) As Status
		Return SetStatus(GdipFillEllipseI(nativeGraphics, brush->nativeBrush, x, y, width, height))
	End Function

	Function FillPie(brush As /*Const*/ Brush, rect As /*Const*/ RectangleF, startAngle As Single, sweepAngle As Single) As Status
		Return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function FillPie(brush As /*Const*/ Brush, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipFillPie(nativeGraphics, brush->nativeBrush, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function FillPie(brush As /*Const*/ Brush, rect As /*Const*/ Rectangle, startAngle As Single, sweepAngle As Single) As Status
		Return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Function

	Function FillPie(brush As /*Const*/ Brush, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single) As Status
		Return SetStatus(GdipFillPieI(nativeGraphics, brush->nativeBrush, x, y, width, height, startAngle, sweepAngle))
	End Function

	Function FillPath(brush As /*Const*/ Brush, path As /*Const*/ GraphicsPath) As Status
		Return SetStatus(GdipFillPath(nativeGraphics, brush->nativeBrush, path->nativePath))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *PointF, count As Long) As Status
		Return SetStatus(GdipFillClosedCurve(nativeGraphics, brush->nativeBrush, points, count))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *PointF, count As Long, fillMode As FillMode) As Status
		Return SetStatus(GdipFillClosedCurve2(nativeGraphics, brush->nativeBrush, points, count, 0.5, fillMode))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *PointF, count As Long, fillMode As FillMode, tension As Single) As Status
		Return SetStatus(GdipFillClosedCurve2(nativeGraphics, brush->nativeBrush, points, count, tension, fillMode))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *Point, count As Long) As Status
		Return SetStatus(GdipFillClosedCurveI(nativeGraphics, brush->nativeBrush, points, count))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *Point, count As Long, fillMode As FillMode) As Status
		Return SetStatus(GdipFillClosedCurve2I(nativeGraphics, brush->nativeBrush, points, count, 0.5, fillMode))
	End Function

	Function FillClosedCurve(brush As /*Const*/ Brush, points As /*Const*/ *Point, count As Long, fillMode As FillMode, tension As Single) As Status
		Return SetStatus(GdipFillClosedCurve2I(nativeGraphics, brush->nativeBrush, points, count, tension, fillMode))
	End Function

	Function FillRegion(brush As /*Const*/ Brush, region As /*Const*/ Region) As Status
		Return SetStatus(GdipFillRegion(nativeGraphics, brush->nativeBrush, region->nativeRegion))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ RectangleF) As Status
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Return SetStatus(GdipDrawString( nativeGraphics, str, length, nativeFont, layoutRect, 0, 0))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ Rectangle,
		stringFormat As /*Const*/ StringFormat, brush As /*Const*/ Brush) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(layoutRect) <> 0 Then
			nativeFormat = layoutRect.nativeFormat
		Else
			nativeFormat = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, layoutRect, nativeFormat, 0))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ RectangleF,
		stringFormat As /*Const*/ StringFormat, brush As /*Const*/ Brush) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If
		Dim nativeBrush As *GpBrush
		If VarPtr(brush) <> 0 Then
			nativeBrush = brush.nativeFormat
		Else
			nativeBrush = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, layoutRect, nativeFormat, nativeBrush))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, origin As /*Const*/ Point) As Status
		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, rect, 0, 0))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, origin As /*Const*/ PointF,
		brush As /*Const*/ Brush) As Status

		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeBrush As *GpBrush
		If VarPtr(brush) <> 0 Then
			nativeBrush = brush.nativeFormat
		Else
			nativeBrush = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, rect, 0, nativeBrush))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, origin As /*Const*/ PointF) As Status
		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, rect, 0, 0))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, origin As /*Const*/ PointF,
		stringFormat As /*Const*/ StringFormat) As Status

		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If
		Return SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, rect, nativeFormat, 0))
	End Function

	Function DrawString(str As PCWSTR, length As Long, font As /*Const*/ Font, origin As /*Const*/ PointF,
		stringFormat As /*Const*/ StringFormat, brush As /*Const*/ Brush) As Status

		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If
		If VarPtr(brush) <> 0 Then
			nativeBrush = brush.nativeFormat
		Else
			nativeBrush = 0
		End If
		Return SetStatus(GdipDrawString( nativeGraphics, str, length, nativeFont, rect, nativeFormat, nativeBrush))
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ RectangleF,
		stringFormat As /*Const*/ StringFormat, boundingBox As RectangleF) As Status

		Return MeasureString(str, length, font, layoutRect, stringFormat, boundingBox, ByVal 0, ByVal 0)
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ RectangleF,
		stringFormat As /*Const*/ StringFormat, boundingBox As RectangleF,
		codepointsFitted As Long) As Status

		Return MeasureString(str, length, font, layoutRect, stringFormat, boundingBox, codepointsFitted, ByVal 0)
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font, layoutRect As /*Const*/ RectangleF,
		stringFormat As /*Const*/ StringFormat, boundingBox As RectangleF,
		codepointsFitted As Long, linesFilled As Long) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If
		Return SetStatus(GdipMeasureString(nativeGraphics, str, length, nativeFont, layoutRect, nativeFormat,
			boundingBox, codepointsFitted, linesFilled))
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		layoutRectSize As /*Const*/ SizeF, stringFormat As /*Const*/ StringFormat,
		size As SizeF) As Status

			Return MeasureString(str, length, font, layoutRectSize, stringFormat, size, ByVal 0, ByVal 0)
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		layoutRectSize As /*Const*/ SizeF, stringFormat As /*Const*/ StringFormat,
		size As SizeF, codepointsFitted As Long) As Status

			Return MeasureString(str, length, font, layoutRectSize, stringFormat, size, codepointsFitted, ByVal 0)
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		layoutRectSize As /*Const*/ SizeF, stringFormat As /*Const*/ StringFormat,
		size As SizeF, codepointsFitted As Long, linesFilled As Long) As Status

		Dim layoutRect As RectangleF(0, 0, layoutRectSize.Width, layoutRectSize.Height)
		Dim boundingBox As RectangleF, pBoundingBox As *RectangleF
		If VarPtr(size) <> 0 Then
			pBoundingBox = VarPtr(boundingBox)
		Else
			pBoundingBox = 0
		End If

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If
		Dim status = SetStatus(GdipMeasureString(nativeGraphics, str, length,
			nativeFont, layoutRect, nativeFormat, pBoundingBox, codepointsFitted, linesFilled))

		If VarPtr(size) <> 0 And status = Status.Ok Then
			size.Width  = boundingBox.Width
			size.Height = boundingBox.Height
		End Function

		Return status
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		origin As /*Const*/ PointF, stringFormat As /*Const*/ StringFormat,
		boundingBox As RectangleF) As Status

		Dim rect As RectangleF(origin.X, origin.Y, 0.0f, 0.0f)
		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If

		Return SetStatus(GdipMeasureString(nativeGraphics, str, length, nativeFont, rect, nativeFormat, boundingBox, 0, 0))
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		layoutRect As /*Const*/ RectangleF, boundingBox As RectangleF) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If

		Return SetStatus(GdipMeasureString(nativeGraphics, str, length, nativeFont, layoutRect, 0, boundingBox, 0, 0))
	End Function

	Const Function MeasureString(str As PCWSTR, length As Long, font As /*Const*/ Font,
		origin As /*Const*/ PointF, boundingBox As RectangleF) As Status
		Dim rect As RectangleF(origin.X, origin.Y, 0.0, 0.0)

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Return SetStatus(GdipMeasureString(nativeGraphics, str, length, nativeFont, rect, 0, boundingBox, 0, 0))
	End Function

	Const Function MeasureCharacterRanges(str As PCWSTR, length As Long, font As /*Const*/ Font,
		layoutRect As /*Const*/ RectangleF, stringFormat As /*Const*/ StringFormat,
		regionCount As Long, regions As *Region) As Status
		If regions = 0 Or regionCount <= 0 Then
			Return InvalidParameter
		End If

		Dim nativeRegions = _System_malloc(regionCount * SizeOf (GpRegion*)) As **GpRegion

		If nativeRegions = 0 Then
			Return OutOfMemory
		End If

		Dim i As Long
		For i = 0 To regionCount
			nativeRegions[i] = regions[i].nativeRegion
		Next

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeFormat As *GpStringFormat
		If VarPtr(stringFormat) <> 0 Then
			nativeFormat = stringFormat.nativeFormat
		Else
			nativeFormat = 0
		End If

		Dim status = SetStatus(GdipMeasureCharacterRanges(nativeGraphics,
			str, length, nativeFont, layoutRect, nativeFormat,regionCount, nativeRegions))
		_System_free(nativeRegions)
		Return status
	End Function

	Function DrawDriverString(text As /*Const*/ Word, length As Long, font As /*Const*/ Font,
		brush As /*Const*/ Brush, positions As /*Const*/ *PointF, flags As Long) As Status

		Return DrawDriverString(text, length, font, brush, positions, flags, ByVal 0)
	End Function

	Function DrawDriverString(text As /*Const*/ Word, length As Long, font As /*Const*/ Font,
		brush As /*Const*/ Brush, positions As /*Const*/ *PointF, flags As Long, matrix As /*Const*/ Matrix) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeBrush As *GpBrush
		If VarPtr(brush) <> 0 Then
			nativeBrush = brush.nativeBrush
		Else
			nativeBrush = 0
		End If
		Dim nativeMatrix As *GpMatrix
		If VarPtr(matrix) <> 0 Then
			nativeMatrix = matrix.nativeMatrix
		Else
			nativeMatrix = 0
		End If
		Return SetStatus(GdipDrawDriverString(nativeGraphics, text, length, nativeFont, nativeBrush, positions, flags, nativeMatrix))
	End Function

	Const Function MeasureDriverString(text As /*Const*/ Word, length As Long, font As /*Const*/ Font,
		positions As /*Const*/ *PointF, flags As Long, matrix As /*Const*/ Matrix, boundingBox As RectangleF) As Status

		Dim nativeFont As *GpFont
		If VarPtr(font) <> 0 Then
			nativeFont = font.nativeFormat
		Else
			nativeFont = 0
		End If
		Dim nativeMatrix As *GpMatrix
		If VarPtr(matrix) <> 0 Then
			nativeMatrix = matrix.nativeMatrix
		Else
			nativeMatrix = 0
		End If
		Return SetStatus(GdipMeasureDriverString(nativeGraphics, text, length, nativeFont, positions, flags, nativeMatrix, boundingBox))
	End Function

	' Draw a cached bitmap on this graphics destination offset by
	' x, y. Note this will fail with WrongState if the CachedBitmap
	' native format differs from this Graphics.

	Function DrawCachedBitmap(cb As CachedBitmap, x As Long, y As Long) As Status
		Return SetStatus(GdipDrawCachedBitmap(nativeGraphics, cb->nativeCachedBitmap, x, y))
	End Function

	Function DrawImage(image As Image, point As /*Const*/ PointF) As Status
		Return DrawImage(image, point.X, point.Y)
	End Function

	Function DrawImage(image As Image, x As Single, y As Single) As Status
		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImage(nativeGraphics, nativeImage, x, y))
	End Function

	Function DrawImage(image As Image, rect As /*Const*/ RectangleF) As Status
		Return DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawImage(image As Image, x As Single, y As Single, width As Single, height As Single) As Status
		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImageRect(nativeGraphics, nativeImage, x, y, width, height))
	End Function

	Function DrawImage(image As Image, point As /*Const*/ Point) As Status
		Return DrawImage(image, point.X, point.Y) As Status
	End Function

	Function DrawImage(image As Image, x As Long, y As Long) As Status
		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImageI(nativeGraphics, nativeImage, x, y))
	End Function

	Function DrawImage(image As Image, rect As /*Const*/ Rectangle) As Status
		Return DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height)
	End Function

	Function DrawImage(image As Image, x As Long, y As Long, width As Long, height As Long) As Status
		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImageRectI(nativeGraphics, nativeImage, x, y, width, height))
	End Function

	' Affine Draw Image
	' destPoints.length = 3: rect => parallelogram
	'	   destPoints[0] <=> top-left corner of the source rectangle
	'	   destPoints[1] <=> top-right corner
	'	   destPoints[2] <=> bottom-left corner
	' destPoints.length = 4: rect => quad
	'	   destPoints[3] <=> bottom-right corner

	Function DrawImage(image As Image, destPoints As /*Const*/ PointF, count As Long) As Status
		If count <> 3 And count <> 4 Then
			Return SetStatus(InvalidParameter)
		End If

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImagePoints(nativeGraphics, nativeImage, destPoints, count))
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ Point, count As Long) As Status
		If count <> 3 And count <> 4 Then
			Return SetStatus(InvalidParameter)
		End If

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImagePointsI(nativeGraphics, nativeImage, destPoints, count))
	End Function

	Function DrawImage(image As Image, x As Single, y As Single,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImagePointRect(nativeGraphics, nativeImage, x, y, srcx, srcy, srcwidth, srcheight, srcUnit))
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ RectangleF,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, 0, 0, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ RectangleF,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, 0, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ RectangleF,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes,
		callback As DrawImageAbort) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ RectangleF,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipDrawImageRectRect(nativeGraphics, nativeImageAttr,
			destRect.X, destRect.Y, destRect.Width, destRect.Height, srcx, srcy, srcwidth, srcheight,
			srcUnit, nativeImageAttr, callback, callbackData))
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ PointF, count As Long,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, 0, 0, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ PointF, count As Long,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, 0, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ PointF, count As Long,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes,
		callback As DrawImageAbort) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ PointF, count As Long,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipDrawImagePointsRect(nativeGraphics, nativeImage, destPoints, count,
			srcx, srcy, srcwidth, srcheight, srcUnit, nativeImageAttr, callback, callbackData))
	End Function

	Function DrawImage(image As Image, x As Long, y As Long,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Return SetStatus(GdipDrawImagePointRectI(nativeGraphics, nativeImage, x, y, srcx, srcy, srcwidth, srcheight, srcUnit))
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ Rectangle,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, 0, 0, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ Rectangle,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, 0, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ Rectangle,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort) As Status

		Return DrawImage(image, destRect, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback, 0)
	End Function

	Function DrawImage(image As Image, destRect As /*Const*/ Rectangle,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipDrawImageRectRectI(nativeGraphics, nativeImage,
			destRect.X, destRect.Y, destRect.Width, destRect.Height,
			srcx, srcy, srcwidth, srcheight, srcUnit, nativeImageAttr, callback, callbackData))
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ Point, count As Long,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, 0, 0, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ Point, count As Long,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, 0, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ Point, count As Long, _
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit, _
		imageAttributes As /*Const*/ ImageAttributes,
		callback As DrawImageAbort) As Status

		Return DrawImage(image, destPoints, count, srcx, srcy, srcwidth, srcheight, srcUnit, imageAttributes, callback, 0)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ Point, count As Long,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit,
		imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status

		Dim nativeImage As *GpImage
		If VarPtr(image) <> 0 Then
			nativeImage = image.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipDrawImagePointsRectI(nativeGraphics, nativeImage, destPoints, count,
			srcx, srcy, srcwidth, srcheight, srcUnit, nativeImageAttr, callback, callbackData))
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *Point, count As Long, srcRect As Rectangle, srcUnit As GraphicsUnit) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *PointF, count As Long, srcRect As RectangleF, srcUnit As GraphicsUnit) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit)
	End Function

	Function DrawImage(image As Image, x As Long, y As Long, srcRect As Rectangle, srcUnit As GraphicsUnit) As Status
		Return DrawImage(image, x, y, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit)
	End Function

	Function DrawImage(image As Image, x As Single, y As Single, srcRect As RectangleF, srcUnit As GraphicsUnit) As Status
		Return DrawImage(image, x, y, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *Point, count As Long, srcRect As Rectangle, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *PointF, count As Long, srcRect As RectangleF, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *Point, count As Long, srcRect As Rectangle, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes, callback)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *PointF, count As Long, srcRect As RectangleF, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes, callback)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *Point, count As Long, srcRect As Rectangle, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes, callback, callbackData)
	End Function

	Function DrawImage(image As Image, destPoints As /*Const*/ *PointF, count As Long, srcRect As RectangleF, srcUnit As GraphicsUnit, imageAttributes As /*Const*/ ImageAttributes, callback As DrawImageAbort, callbackData As VoidPtr) As Status
		Return DrawImage(image, destPoints, count, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, srcUnit, imageAttributes, callback, callbackData)
	End Function

	' The following methods are for playing an EMF+ to a graphics
	' via the enumeration interface.  Each record of the EMF+ is
	' sent to the callback (along with the callbackData).	Then
	' the callback can invoke the Metafile::PlayRecord method
	' to play the particular record.

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ PointF,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoint, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ PointF,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoint, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ PointF,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestPoint(nativeGraphics,
			nativeImage, destPoint, callback, callbackData,nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ Point,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoint, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ Point,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoint, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoint As /*Const*/ Point,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestPointI(nativeGraphics,
			nativeImage, destPoint, callback, callbackData,nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ RectangleF,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destRect, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ RectangleF,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destRect, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ RectangleF,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestRect(nativeGraphics,
			nativeImage, destRect, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ Rectangle,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destRect, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ Rectangle,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destRect, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destRect As /*Const*/ Rectangle,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestRectI(nativeGraphics,
			nativeImage, destRect, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *PointF, count As Long,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoints, count, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *PointF, count As Long,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoints, count, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *PointF, count As Long,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestPoints(nativeGraphics,
			nativeImage,destPoints, count, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *Point, count As Long,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoints, count, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *Point, count As Long,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoints, count, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, destPoints As /*Const*/ *Point, count As Long,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileDestPointsI(nativeGraphics,
			nativeImage,destPoints, count, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile,
		destPoint As /*Const*/ PointF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoint, count, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile,
		destPoint As /*Const*/ PointF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoint, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile,
		destPoint As /*Const*/ PointF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestPoint(nativeGraphics, _
			nativeImage, destPoint, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoint As /*Const*/ Point, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoint, count, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoint As /*Const*/ Point, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoint, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoint As /*Const*/ Point, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestPointI(nativeGraphics, _
			nativeImage, destPoint, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ RectangleF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destRect, count, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ RectangleF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destRect, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ RectangleF, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestRect(nativeGraphics, _
			nativeImage, destRect, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ Rectangle, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destRect, srcRect, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ Rectangle, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destRect, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destRect As /*Const*/ Rectangle, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestRectI(nativeGraphics, _
			nativeImage, destRect, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *PointF, count As Long, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoints, count, srcRect, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *PointF, count As Long, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoints, count, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *PointF, count As Long, srcRect As /*Const*/ RectangleF, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestPoints(nativeGraphics, _
			nativeImage, destPoints, count, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *Point, count As Long, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc) As Status

		Return EnumerateMetafile(metafile, destPoints, count, srcRect, srcUnit, callback, 0, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *Point, count As Long, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr) As Status

		Return EnumerateMetafile(metafile, destPoints, count, srcRect, srcUnit, callback, callbackData, 0)
	End Function

	Function EnumerateMetafile(metafile As /*Const*/ Metafile, _
		destPoints As /*Const*/ *Point, count As Long, srcRect As /*Const*/ Rectangle, srcUnit As GraphicsUnit, _
		callback As EnumerateMetafileProc, callbackData As VoidPtr, imageAttributes As /*Const*/ ImageAttributes) As Status

		Dim nativeImage As /*Const*/ *GpMetafile
		If VarPtr(metafile) <> 0 Then
			nativeImage = metafile.NativeImage
		Else
			nativeImage = 0
		End If
		Dim nativeImageAttr As *GpImageAttributes
		If VarPtr(imageAttributes) <> 0 Then
			nativeImageAttr = image.NativeImageAttr
		Else
			nativeImageAttr = 0
		End If

		Return SetStatus(GdipEnumerateMetafileSrcRectDestPointsI(nativeGraphics, nativeImage, _
			destPoints, count, srcRect, srcUnit, callback, callbackData, nativeImageAttr))
	End Function

	Function SetClip(g As /*Const*/ Graphics) As Status
		Return SetClip(g, CombineMode.Replace)
	End Function

	Function SetClip(rc As /*Const*/ RectangleF) As Status
		Return SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Replace))
	End Function

	Function SetClip(rc As /*Const*/ Rectangle) As Status
		Return SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Replace))
	End Function

	Function SetClip(path As /*Const*/ GraphicsPath) As Status
		Return SetStatus(GdipSetClipPath(nativeGraphics, path->nativePath, CombineMode.Replace))
	End Function

	Function SetClip(region As /*Const*/ Region) As Status
		Return SetStatus(GdipSetClipRegion(nativeGraphics, region->nativeRegion, CombineMode.Replace))
	End Function

	Function SetClip(g As /*Const*/ Graphics, combineMode As CombineMode) As Status
		Return SetStatus(GdipSetClipGraphics(nativeGraphics, g->nativeGraphics, combineMode))
	End Function

	Function SetClip(rc As /*Const*/ RectangleF, combineMode As CombineMode) As Status
		Return SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, combineMode))
	End Function

	Function SetClip(rc As /*Const*/ Rectangle, combineMode As CombineMode) As Status
		Return SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, combineMode))
	End Function

	Function SetClip(path As /*Const*/ GraphicsPath, combineMode As CombineMode) As Status
		Return SetStatus(GdipSetClipPath(nativeGraphics, path->nativePath, combineMode))
	End Function

	Function SetClip(region As /*Const*/ Region, combineMode As CombineMode) As Status
		Return SetStatus(GdipSetClipRegion(nativeGraphics, region->nativeRegion, combineMode))
	End Function

	' This is different than the other SetClip methods because it assumes
	' that the HRGN is already in device units, so it doesn't transform
	' the coordinates in the HRGN.

	Function SetClip(hrgn As HRGN, combineMode As CombineMode /* = CombineModeReplace*/) As Status
		Return SetStatus(GdipSetClipHrgn(nativeGraphics, hrgn, combineMode))
	End Function

	Function IntersectClip(rc As /*Const*/ RectangleF) As Status
		Return SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Intersect))
	End Function

	Function IntersectClip(rc As /*Const*/ Rectangle) As Status
		Return SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Intersect))
	End Function

	Function IntersectClip(region As /*Const*/ Region) As Status
		Return SetStatus(GdipSetClipRegion(nativeGraphics, region->nativeRegion, CombineMode.Intersect))
	End Function

	Function ExcludeClip(rc As /*Const*/ RectangleF) As Status
		Return SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Exclude))
	End Function

	Function ExcludeClip(rc As /*Const*/ Rectangle) As Status
		Return SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, CombineMode.Exclude))
	End Function

	Function ExcludeClip(region As /*Const*/ Region) As Status
		Return SetStatus(GdipSetClipRegion(nativeGraphics, region->nativeRegion, CombineMode.Exclude))
	End Function

	Function ResetClip() As Status
		Return SetStatus(GdipResetClip(nativeGraphics))
	End Function

	Function TranslateClip(dx As Single, dy As Single) As Status
		Return SetStatus(GdipTranslateClip(nativeGraphics, dx, dy))
	End Function

	Function TranslateClip(dx As Long, dy As Long) As Status
		Return SetStatus(GdipTranslateClipI(nativeGraphics, dx, dy))
	End Function

	Const Function GetClip(region As Region) As Status
		Return SetStatus(GdipGetClip(nativeGraphics, region->nativeRegion))
	End Function

	Const Function GetClipBounds(rc As RectangleF) As Status
		Return SetStatus(GdipGetClipBounds(nativeGraphics, rc))
	End Function

	Const Function GetClipBounds(rc As Rectangle) As Status
		Return SetStatus(GdipGetClipBoundsI(nativeGraphics, rc))
	End Function

	Const Function GetVisibleClipBounds(rc As RectangleF) As Status
		Return SetStatus(GdipGetVisibleClipBounds(nativeGraphics, rc))
	End Function

	Const Function GetVisibleClipBounds(rc As Rectangle) As Status
		Return SetStatus(GdipGetVisibleClipBoundsI(nativeGraphics, rc))
	End Function

	Const Function IsVisible(x As Long, y As Long) As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsVisiblePointI(nativeGraphics, x, y, b))
		Return b
	End Function

	Const Function IsVisible(pt As /*Const*/ Point) As BOOL
		Return IsVisible(pt.X, pt.Y)
	End Function

	Const Function IsVisible(x As Long, y As Long, width As Long, height As Long) As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsVisibleRectI(nativeGraphics, x, y, width, height, b))
		Return b
	End Function

	Const Function IsVisible(rc As /*Const*/ Rectangle) As BOOL
		Return IsVisible(rc.X, rc.Y, rc.Width, rc.Height)
	End Function

	Const Function IsVisible(x As Single, y As Single) As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsVisiblePoint(nativeGraphics, x, y, b))
		Return b
	End Function

	Const Function IsVisible(point As /*Const*/ PointF) As BOOL
		Return IsVisible(pt.X, pt.Y)
	End Function

	Const Function IsVisible(x As Single, y As Single, width As Single, height As Single) As BOOL
		Dim b = FALSE As BOOL
		SetStatus(GdipIsVisibleRect(nativeGraphics, x, y, width, height, b))
		Return b
	End Function

	Const Function IsVisible(rect As /*Const*/ RectangleF) As BOOL
		Return IsVisible(rc.X, rc.Y, rc.Width, rc.Height)
	End Function

	Const Function Save() As GraphicsState
		Dim gstate As GraphicsState
		SetStatus(GdipSaveGraphics(nativeGraphics, state))
		Return gstate
	End Function

	Function Restore(gstate As GraphicsState)
		Return SetStatus(GdipRestoreGraphics(nativeGraphics, gstate))
	End Function

	Function BeginContainer(dstrect As /*Const*/ RectangleF, srcrect As /*Const*/ RectangleF, unit As GraphicsUnit) As GraphicsContainer
		Dim state As GraphicsContainer
		SetStatus(GdipBeginContainer(nativeGraphics, dstrect, srcrect, unit, state))
		Return state
	End Function

	Function BeginContainer(dstrect As /*Const*/ Rectangle, srcrect As /*Const*/ Rectangle, unit As GraphicsUnit) As GraphicsContainer
		Dim state As GraphicsContainer
		SetStatus(GdipBeginContainerI(nativeGraphics, dstrect, srcrect, unit, state))
		Return state
	End Function

	Function BeginContainer() As GraphicsContainer
		Dim state As GraphicsContainer
		SetStatus(GdipBeginContainer2(nativeGraphics, state))
		Return state
	End Function

	Function EndContainer(state As GraphicsContainer) As Status
		Return SetStatus(GdipEndContainer(nativeGraphics, state))
	End Function

	' Only valid when recording metafiles.

	Function AddMetafileComment(data As /*Const*/ *Byte, sizeData As DWord)
		Return SetStatus(GdipComment(nativeGraphics, sizeData, data))
	End Function

	Static Function GetHalftonePalette() As HPALETTE
		Return GdipCreateHalftonePalette()
	End Function

	Const Function GetLastStatus() As Status
		Dim lastStatus = lastResult
		lastResult = Status.Ok
		Return lastStatus
	End Function

Private
'	Sub Graphics(gr As Graphics)
'		Debug
'	End Sub
	Sub Operator =(gr As Graphics)
		Debug
	End Sub

Protected
	Sub Graphics(graphics As *GpGraphics)
		lastResult = Status.Ok
		SetNativeGraphics(graphics)
	End Sub

	Sub SetNativeGraphics(graphics As *GpGraphics)
		This.nativeGraphics = graphics
	End Sub

	Const Function SetStatus(status As Status) As Status
		If status <> Status.Ok Then
			lastResult = status
		End If
		Return status
	End Function

	Const Function GetNativeGraphics() As *GpGraphics
		Return This.nativeGraphics
	End Function

	Function GetNativePen(pen As /*Const*/ *Pen) As *GpPen
		Return pen->nativePen
	End Function

Protected
	nativeGraphics As *GpGraphics
	lastResult As /*Mutable*/ Status
End Class

#endif
