' Classes/System/Drawing/Graphics.ab

Namespace System
Namespace Drawing

Class ImageAttributes
Public
	nativeImage As *GpImageAttributes
End Class
Class Metafile
Inherits Image
End Class
Class Region
Public
	nativeRegion As *GpRegion
End Class
Class GraphicsPath
Public
	Sub GraphicsPath(native As *GpPath)
		nativePath = native
	End Sub
	Function NativePath() As *GpPath
	End Function
	nativePath As *GpPath
End Class
Class CachedBitmap
Public
	nativeCachedBitmap As *GpCachedBitmap
End Class

Delegate Function EnumerateMetafileProc(recordType As Imaging.EmfPlusRecordType, flags As DWord, dataSize As DWord, data As *Byte, callbackData As VoidPtr) As Boolean

Namespace Detail

TypeDef NativeEnumerateMetafileProc = *Function(recordType As Imaging.EmfPlusRecordType, flags As DWord, dataSize As DWord, data As *Byte, callbackData As VoidPtr) As Boolean

Type EnumerateMetafileProcData
	Proc As EnumerateMetafileProc
	Data As VoidPtr
End Type

Function NativeEnumerateMetafileProcEntry(recordType As Imaging.EmfPlusRecordType, flags As DWord, dataSize As DWord, data As *Byte, callbackData As VoidPtr) As Boolean
	Dim procData = callbackData As *EnumerateMetafileProcData
	Dim proc = procData->Proc
	NativeEnumerateMetafileProcEntry = proc(recordType, flags, dataSize, data, procData->Data)
End Function

End Namespace

Class Graphics
Public
	'=========================================================================
	' Properties
	'=========================================================================
	Const Function Clip() As Region
		Clip = New Region
		SetStatus(GdipGetClip(nativeGraphics, Clip.nativeRegion))
	End Function

	Sub Clip(region As Region)
		Imports System.Drawing.Drawing2D
		SetStatus(GdipSetClipRegion(nativeGraphics, region.nativeRegion, CombineMode.Replace))
	End Sub

	Const Function ClipBounds() As RectangleF
		SetStatus(GdipGetClipBounds(nativeGraphics, ClipBounds))
	End Function

	Const Function ClipBoundsI() As Rectangle
		SetStatus(GdipGetClipBoundsI(nativeGraphics, ClipBoundsI))
	End Function
/*
	Const Function CompositingMode() As Drawing2D.CompositingMode
		SetStatus(GdipGetCompositingMode(nativeGraphics, CompositingMode))
	End Function

	Sub CompositingMode(mode As Drawing2D.CompositingMode)
		SetStatus(GdipSetCompositingMode(nativeGraphics, mode))
	End Sub

	Function CompositingQuality() As Drawing2D.CompositingQuality
		SetStatus(GdipGetCompositingQuality(nativeGraphics, CompositingQuality))
	End Function

	Sub CompositingQuality(cq As Drawing2D.CompositingQuality)
		Return SetStatus(GdipSetCompositingQuality(nativeGraphics, cq))
	End Sub
*/
	Const Function DpiX() As Single
		SetStatus(GdipGetDpiX(nativeGraphics, DpiX))
	End Function

	Const Function DpiY() As Single
		SetStatus(GdipGetDpiY(nativeGraphics, DpiY))
	End Function
/*
	Const Function InterpolationMode() As Drawing2D.InterpolationMode
		SetStatus(GdipGetInterpolationMode(nativeGraphics, InterpolationMode))
	End Function

	Sub InterpolationMode(im As Drawing2D.InterpolationMode)
		InterpolationMode = SetStatus(GdipSetInterpolationMode(nativeGraphics, im))
	End Sub
*/
	Const Function IsClipEmpty() As Boolean
		Dim b = FALSE As BOOL
		SetStatus(GdipIsClipEmpty(nativeGraphics, b))
		IsClipEmpty = b As Boolean
	End Function

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

	Sub PageScale(scale As Single)
		SetStatus(GdipSetPageScale(nativeGraphics, scale))
	End Sub

	Const Function PageScale() As Single
		SetStatus(GdipGetPageScale(nativeGraphics, PageScale))
	End Function
/*
	Const Function PageUnit() As GraphicsUnit
		SetStatus(GdipGetPageUnit(nativeGraphics, PageUnit))
	End Function
*/
	Sub PageUnit(unit As GraphicsUnit)
		SetStatus(GdipSetPageUnit(nativeGraphics, unit))
	End Sub
/*
	Function PixelOffsetMode() As Drawing2D.PixelOffsetMode
		PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Invalid
		SetStatus(GdipGetPixelOffsetMode(nativeGraphics, PixelOffsetMode))
	End Function
*/
	Sub PixelOffsetMode(mode As Drawing2D.PixelOffsetMode)
		SetStatus(GdipSetPixelOffsetMode(nativeGraphics, mode))
	End Sub

	Function RenderingOrigin() As Point
		With RenderingOrigin
			.X = 0
			.Y = 0
			SetStatus(GdipGetRenderingOrigin(nativeGraphics, .X, .Y))
		End With
	End Function

	Sub RenderingOrigin(pt As Point)
		SetStatus(GdipSetRenderingOrigin(nativeGraphics, pt.X, pt.Y))
	End Sub
/*
	Function SmoothingMode() As Drawing2D.SmoothingMode
		SetStatus(GdipGetSmoothingMode(nativeGraphics, SmoothingMode))
	End Function
*/
	Sub SmoothingMode(mode As Drawing2D.SmoothingMode)
		SetStatus(GdipSetSmoothingMode(nativeGraphics, mode))
	End Sub

	Function TextContrast() As DWord
		SetStatus(GdipGetTextContrast(nativeGraphics, TextContrast))
	End Function

	Sub TextContrast(contrast As DWord)
		SetStatus(GdipSetTextContrast(nativeGraphics, contrast))
	End Sub
/*
	Function TextRenderingHint() As Text.TextRenderingHint
		SetStatus(GdipGetTextRenderingHint(nativeGraphics, ByVal VarPtr(TextRenderingHint)))
	End Function
*/
	Sub TextRenderingHint(mode As TextRenderingHint)
		SetStatus(GdipSetTextRenderingHint(nativeGraphics, mode))
	End Sub

	Function Transform() As Drawing2D.Matrix
		Dim native As *GpMatrix
		SetStatus(GdipGetWorldTransform(nativeGraphics, native))
		Transform = New Drawing2D.Matrix(native)
	End Function

	Sub Transform(matrix As Drawing2D.Matrix)
		SetStatus(GdipSetWorldTransform(nativeGraphics, matrix.nativeMatrix))
	End Sub

	Function VisibleClipBounds() As RectangleF
		SetStatus(GdipGetVisibleClipBounds(nativeGraphics, VisibleClipBounds))
	End Function

	Function VisibleClipBoundsI() As Rectangle
		SetStatus(GdipGetVisibleClipBoundsI(nativeGraphics, VisibleClipBoundsI))
	End Function

	'=========================================================================
	' Methods
	'=========================================================================
	Static Function FromHDC(hdc As HDC) As Graphics
		Dim graphics = 0 As *GpGraphics
		SetStatus(GdipCreateFromHDC(hdc, graphics))
		Return New Graphics(graphics)
	End Function

	Static Function FromHDC(hdc As HDC, hdevice As HANDLE) As Graphics
		Dim graphics = 0 As *GpGraphics
		SetStatus(GdipCreateFromHDC2(hdc, hdevice, graphics))
		Return New Graphics(graphics)
	End Function

	Static Function FromHwnd(hwnd As HWND) As Graphics
		Dim graphics = 0 As *GpGraphics
		SetStatus(GdipCreateFromHWND(hwnd, graphics))
		Return New Graphics(graphics)
	End Function

	Static Function FromHwnd(hwnd As HWND, icm As Boolean) As Graphics
		Dim graphics = 0 As *GpGraphics
		If icm Then
			SetStatus(GdipCreateFromHWNDICM(hwnd, graphics))
		Else
			SetStatus(GdipCreateFromHWND(hwnd, graphics))
		End If
		Return New Graphics(graphics)
	End Function

	Static Function FromImage(image As Image) As Graphics
		If ActiveBasic.IsNothing(image) Then
			Throw New ArgumentNullException("image")
		End If
		Dim graphics = 0 As *GpGraphics
		SetStatus(GdipGetImageGraphicsContext(image.nativeImage, graphics))
		Return New Graphics(graphics)
	End Function

	Sub Dispose()
		GdipDeleteGraphics(nativeGraphics)
		nativeGraphics = 0
	End Sub

	Sub ~Graphics()
		Dispose()
	End Sub

	Sub Flush()
		GdipFlush(nativeGraphics, System.Drawing.Drawing2D.FlushIntention.Flush)
	End Sub

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

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

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

	Sub ResetTransform()
		SetStatus(GdipResetWorldTransform(nativeGraphics))
	End Sub

	Sub MultiplyTransform(matrix As Drawing2D.Matrix)
		SetStatus(GdipMultiplyWorldTransform(nativeGraphics, matrix.nativeMatrix, System.Drawing.Drawing2D.MatrixOrder.Prepend))
	End Sub

	Sub MultiplyTransform(matrix As Drawing2D.Matrix, order As Drawing2D.MatrixOrder)
		SetStatus(GdipMultiplyWorldTransform(nativeGraphics, matrix.nativeMatrix, order))
	End Sub

	Sub TranslateTransform(dx As Single, dy As Single)
		SetStatus(GdipTranslateWorldTransform(nativeGraphics, dx, dy, System.Drawing.Drawing2D.MatrixOrder.Prepend))
	End Sub

	Sub TranslateTransform(dx As Single, dy As Single, order As Drawing2D.MatrixOrder)
		SetStatus(GdipTranslateWorldTransform(nativeGraphics, dx, dy, order))
	End Sub

	Sub ScaleTransform(sx As Single, sy As Single)
		SetStatus(GdipScaleWorldTransform(nativeGraphics, sx, sy, System.Drawing.Drawing2D.MatrixOrder.Prepend))
	End Sub

	Sub ScaleTransform(sx As Single, sy As Single, order As Drawing2D.MatrixOrder)
		SetStatus(GdipScaleWorldTransform(nativeGraphics, sx, sy, order))
	End Sub

	Sub RotateTransform(angle As Single)
		SetStatus(GdipRotateWorldTransform(nativeGraphics, angle, System.Drawing.Drawing2D.MatrixOrder.Prepend))
	End Sub

	Sub RotateTransform(angle As Single, order As Drawing2D.MatrixOrder)
		SetStatus(GdipRotateWorldTransform(nativeGraphics, angle, order))
	End Sub

	Sub TransformPoints(destSpace As Drawing2D.CoordinateSpace, srcSpace As Drawing2D.CoordinateSpace, pts As *PointF, count As Long)
		SetStatus(GdipTransformPoints(nativeGraphics, destSpace, srcSpace, pts, count))
	End Sub

	Sub TransformPoints(destSpace As Drawing2D.CoordinateSpace, srcSpace As Drawing2D.CoordinateSpace, pts As *Point, count As Long)
		SetStatus(GdipTransformPointsI(nativeGraphics, destSpace, srcSpace, pts, count))
	End Sub

	Const Function GetNearestColor(color As Color) As Color
		GetNearestColor = color
		SetStatus(GdipGetNearestColor(nativeGraphics, GetNearestColor))
	End Function

	Sub DrawLine(pen As Pen, x1 As Single, y1 As Single, x2 As Single, y2 As Single)
		SetStatus(GdipDrawLine(nativeGraphics, pen.NativePen, x1, y1, x2, y2))
	End Sub

	Sub DrawLine(pen As Pen, ByRef pt1 As PointF, ByRef pt2 As PointF)
		DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y)
	End Sub

	Sub DrawLines(pen As Pen, points As *PointF, count As Long)
		SetStatus(GdipDrawLines(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawLine(pen As Pen, x1 As Long, y1 As Long, x2 As Long, y2 As Long)
		SetStatus(GdipDrawLineI(nativeGraphics, pen.NativePen, x1, y1, x2, y2))
	End Sub

	Sub DrawLine(pen As Pen, ByRef pt1 As Point, ByRef pt2 As Point)
		DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y)
	End Sub

	Sub DrawLines(pen As Pen, points As *Point, count As Long)
		SetStatus(GdipDrawLinesI(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawArc(pen As Pen, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipDrawArc(nativeGraphics, pen.NativePen, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub DrawArc(pen As Pen, ByRef rect As RectangleF, startAngle As Single, sweepAngle As Single)
		DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub DrawArc(pen As Pen, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipDrawArcI(nativeGraphics, pen.NativePen, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub DrawArc(pen As Pen, ByRef rect As Rectangle, startAngle As Single, sweepAngle As Single)
		DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub DrawBezier(pen As 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)
		SetStatus(GdipDrawBezier(nativeGraphics, pen.NativePen, x1, y1,x2, y2, x3, y3, x4, y4))
	End Sub

	Sub DrawBezier(pen As Pen, ByRef pt1 As PointF, ByRef pt2 As PointF, ByRef pt3 As PointF, ByRef pt4 As PointF)
		DrawBezier(pen, pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y)
	End Sub

	Sub DrawBeziers(pen As Pen, points As *PointF, count As Long)
		SetStatus(GdipDrawBeziers(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawBezier(pen As 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)
		SetStatus(GdipDrawBezierI(nativeGraphics, pen.NativePen, x1, y1, x2, y2, x3, y3, x4, y4))
	End Sub

	Sub DrawBezier(pen As Pen, ByRef pt1 As Point, ByRef pt2 As Point, ByRef pt3 As Point, ByRef pt4 As Point)
		DrawBezier(pen, pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X, pt4.Y)
	End Sub

	Sub DrawBeziers(pen As Pen, points As *Point, count As Long)
		SetStatus(GdipDrawBeziersI(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawRectangle(pen As Pen, ByRef rect As RectangleF)
		DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawRectangle(pen As Pen, x As Single, y As Single, width As Single, height As Single)
		SetStatus(GdipDrawRectangle(nativeGraphics, pen.NativePen, x, y, width, height))
	End Sub

	Sub DrawRectangles(pen As Pen, rects As *RectangleF, count As Long)
		SetStatus(GdipDrawRectangles(nativeGraphics, pen.NativePen, rects, count))
	End Sub

	Sub DrawRectangle(pen As Pen, ByRef rect As Rectangle)
		DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawRectangle(pen As Pen, x As Long, y As Long, width As Long, height As Long)
		SetStatus(GdipDrawRectangleI(nativeGraphics, pen.NativePen, x, y, width, height))
	End Sub

	Sub DrawRectangles(pen As Pen, rects As *Rectangle, count As Long)
		SetStatus(GdipDrawRectanglesI(nativeGraphics, pen.NativePen, rects, count))
	End Sub

	Sub DrawEllipse(pen As Pen, ByRef rect As RectangleF)
		DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawEllipse(pen As Pen, x As Single, y As Single, width As Single, height As Single)
		SetStatus(GdipDrawEllipse(nativeGraphics, pen.NativePen, x, y, width, height))
	End Sub

	Sub DrawEllipse(pen As Pen, ByRef rect As Rectangle)
		DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawEllipse(pen As Pen, x As Long, y As Long, width As Long, height As Long)
		SetStatus(GdipDrawEllipseI(nativeGraphics, pen.NativePen, x, y, width, height))
	End Sub

	Sub DrawPie(pen As Pen, ByRef rect As RectangleF, startAngle As Single, sweepAngle As Single)
		DrawPie(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub DrawPie(pen As Pen, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipDrawPie(nativeGraphics, pen.NativePen, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub DrawPie(pen As Pen, ByRef rect As Rectangle, startAngle As Single, sweepAngle As Single)
		DrawPie(pen, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub DrawPie(pen As Pen, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipDrawPieI(nativeGraphics, pen.NativePen, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub DrawPolygon(pen As Pen, points As *PointF, count As Long)
		SetStatus(GdipDrawPolygon(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawPolygon(pen As Pen, points As *Point, count As Long)
		SetStatus(GdipDrawPolygonI(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawPath(pen As Pen, path As GraphicsPath)
		If ActiveBasic.IsNothing(pen) Or ActiveBasic.IsNothing(path) Then
			Throw New ArgumentNullException("pen or path or both")
		End If
		SetStatus(GdipDrawPath(nativeGraphics, pen.NativePen, path.nativePath))
	End Sub

	Sub DrawCurve(pen As Pen, points As *PointF, count As Long)
		SetStatus(GdipDrawCurve(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawCurve(pen As Pen, points As *PointF, count As Long, tension As Single)
		SetStatus(GdipDrawCurve2(nativeGraphics, pen.NativePen, points,count, tension))
	End Sub

	Sub DrawCurve(pen As Pen, points As *PointF, count As Long, offset As Long, numberOfSegments As Long)
		SetStatus(GdipDrawCurve3(nativeGraphics, pen.NativePen, points, count, offset,numberOfSegments, 0.5))
	End Sub

	Sub DrawCurve(pen As Pen, points As *PointF, count As Long, offset As Long, numberOfSegments As Long, tension As Single)
		SetStatus(GdipDrawCurve3(nativeGraphics, pen.NativePen, points, count, offset,numberOfSegments, tension))
	End Sub

	Sub DrawCurve(pen As Pen, points As *Point, count As Long)
		SetStatus(GdipDrawCurveI(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawCurve(pen As Pen, points As *Point, count As Long, tension As Single)
		SetStatus(GdipDrawCurve2I(nativeGraphics, pen.NativePen, points, count, tension))
	End Sub

	Sub DrawCurve(pen As Pen, points As *Point, count As Long, offset As Long, numberOfSegments As Long)
		SetStatus(GdipDrawCurve3I(nativeGraphics, pen.NativePen, points, count, offset, numberOfSegments, 0.5))
	End Sub

	Sub DrawCurve(pen As Pen, points As *Point, count As Long, offset As Long, numberOfSegments As Long, tension As Single)
		SetStatus(GdipDrawCurve3I(nativeGraphics, pen.NativePen, points, count, offset, numberOfSegments, tension))
	End Sub

	Sub DrawClosedCurve(pen As Pen, points As *PointF, count As Long)
		SetStatus(GdipDrawClosedCurve(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawClosedCurve(pen As Pen, points As *PointF, count As Long, tension As Single)
		SetStatus(GdipDrawClosedCurve2(nativeGraphics, pen.NativePen, points, count, tension))
	End Sub

	Sub DrawClosedCurve(pen As Pen, points As *Point, count As Long)
		SetStatus(GdipDrawClosedCurveI(nativeGraphics, pen.NativePen, points, count))
	End Sub

	Sub DrawClosedCurve(pen As Pen, points As *Point, count As Long, tension As Single)
		SetStatus(GdipDrawClosedCurve2I(nativeGraphics, pen.NativePen, points, count, tension))
	End Sub

	Sub Clear(color As Color)
		SetStatus(GdipGraphicsClear(nativeGraphics, color))
	End Sub

	Sub FillRectangle(brush As Brush, ByRef rect As RectangleF)
		FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub FillRectangle(brush As Brush, x As Single, y As Single, width As Single, height As Single)
		SetStatus(GdipFillRectangle(nativeGraphics, brush.NativeBrush, x, y, width, height))
	End Sub

	Sub FillRectangles(brush As Brush, rects As *RectangleF, count As Long)
		SetStatus(GdipFillRectangles(nativeGraphics,brush.NativeBrush,rects, count))
	End Sub

	Sub FillRectangle(brush As Brush, ByRef rect As Rectangle)
		FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub FillRectangle(brush As Brush, x As Long, y As Long, width As Long, height As Long)
		SetStatus(GdipFillRectangleI(nativeGraphics, brush.NativeBrush, x, y, width, height))
	End Sub

	Sub FillRectangles(brush As Brush, rects As *Rectangle, count As Long)
		SetStatus(GdipFillRectanglesI(nativeGraphics, brush.NativeBrush, rects, count))
	End Sub

'	Sub FillPolygon(brush As Brush, points As *PointF, count As Long)
'		FillPolygon(brush, points, count, System.Drawing.Drawing2D.FillMode.Alternate)
'	End Sub

	Sub FillPolygon(brush As Brush, points As *PointF, count As Long, fillMode As Drawing2D.FillMode)
		SetStatus(GdipFillPolygon(nativeGraphics, brush.NativeBrush, points, count, fillMode))
	End Sub

'	Sub FillPolygon(brush As Brush, points As *Point, count As Long)
'		FillPolygon(brush, points, count, System.Drawing.Drawing2D.FillMode.Alternate)
'	End Sub

	Sub FillPolygon(brush As Brush, points As *Point, count As Long, fillMode As Drawing2D.FillMode)
		SetStatus(GdipFillPolygonI(nativeGraphics, brush.NativeBrush, points, count, fillMode))
	End Sub

	Sub FillEllipse(brush As Brush, ByRef rect As RectangleF)
		FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub FillEllipse(brush As Brush, x As Single, y As Single, width As Single, height As Single)
		SetStatus(GdipFillEllipse(nativeGraphics, brush.NativeBrush, x, y, width, height))
	End Sub

	Sub FillEllipse(brush As Brush, ByRef rect As Rectangle)
		FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub FillEllipse(brush As Brush, x As Long, y As Long, width As Long, height As Long)
		SetStatus(GdipFillEllipseI(nativeGraphics, brush.NativeBrush, x, y, width, height))
	End Sub

	Sub FillPie(brush As Brush, ByRef rect As RectangleF, startAngle As Single, sweepAngle As Single)
		FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub FillPie(brush As Brush, x As Single, y As Single, width As Single, height As Single, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipFillPie(nativeGraphics, brush.NativeBrush, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub FillPie(brush As Brush, ByRef rect As Rectangle, startAngle As Single, sweepAngle As Single)
		FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height, startAngle, sweepAngle)
	End Sub

	Sub FillPie(brush As Brush, x As Long, y As Long, width As Long, height As Long, startAngle As Single, sweepAngle As Single)
		SetStatus(GdipFillPieI(nativeGraphics, brush.NativeBrush, x, y, width, height, startAngle, sweepAngle))
	End Sub

	Sub FillPath(brush As Brush, path As GraphicsPath)
		If ActiveBasic.IsNothing(brush) Or ActiveBasic.IsNothing(path) Then
			Throw New ArgumentNullException("brush or path or both")
		End If
		SetStatus(GdipFillPath(nativeGraphics, brush.NativeBrush, path.nativePath))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *PointF, count As Long)
		SetStatus(GdipFillClosedCurve(nativeGraphics, brush.NativeBrush, points, count))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *PointF, count As Long, fillMode As Drawing2D.FillMode)
		SetStatus(GdipFillClosedCurve2(nativeGraphics, brush.NativeBrush, points, count, 0.5, fillMode))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *PointF, count As Long, fillMode As Drawing2D.FillMode, tension As Single)
		SetStatus(GdipFillClosedCurve2(nativeGraphics, brush.NativeBrush, points, count, tension, fillMode))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *Point, count As Long)
		SetStatus(GdipFillClosedCurveI(nativeGraphics, brush.NativeBrush, points, count))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *Point, count As Long, fillMode As Drawing2D.FillMode)
		SetStatus(GdipFillClosedCurve2I(nativeGraphics, brush.NativeBrush, points, count, 0.5, fillMode))
	End Sub

	Sub FillClosedCurve(brush As Brush, points As *Point, count As Long, fillMode As Drawing2D.FillMode, tension As Single)
		SetStatus(GdipFillClosedCurve2I(nativeGraphics, brush.NativeBrush, points, count, tension, fillMode))
	End Sub

	Sub FillRegion(brush As Brush, region As Region)
		SetStatus(GdipFillRegion(nativeGraphics, brush.NativeBrush, region.nativeRegion))
	End Sub

'DrawStringは次の組み合わせからなる。
'(PCWSTR, Long) or String
'PointF or (Single, Single) or Rectangle
'StringFormatの有無
	Sub DrawString(str As PCWSTR, length As Long, font As Font, brush As Brush, ByRef origin As PointF, stringFormat = Nothing As StringFormat)
		DrawString(str, length, font, brush, origin.X, origin.Y, stringFormat)
	End Sub

	Sub DrawString(str As PCWSTR, length As Long, font As Font, brush As Brush, x As Single, y As Single, stringFormat = Nothing As StringFormat)
		Dim rc As RectangleF
		rc.X = x
		rc.Y = y
		rc.Width = 0
		rc.Height = 0
		DrawString(str, length, font, brush, rc, stringFormat)
	End Sub

	Sub DrawString(str As PCWSTR, length As Long, font As Font, brush As Brush, ByRef layoutRect As RectangleF, stringFormat = Nothing As StringFormat)
		Dim nativeFont = getNativeFont(font)
		Dim nativeFormat = GetNativeStringFormat(stringFormat)
		Dim nativeBrush = getNativeBrush(brush)
		SetStatus(GdipDrawString(nativeGraphics, str, length, nativeFont, layoutRect, nativeFormat, nativeBrush))
	End Sub

	Sub DrawString(s As String, font As Font, brush As Brush, ByRef origin As PointF, stringFormat = Nothing As StringFormat)
		DrawString(s, font, brush, origin.X, origin.Y, stringFormat)
	End Sub

	Sub DrawString(s As String, font As Font, brush As Brush, x As Single, y As Single, stringFormat = Nothing As StringFormat)
		Dim rc As RectangleF
		rc.X = x
		rc.Y = y
		rc.Width = 0
		rc.Height = 0
		DrawString(s, font, brush, rc, stringFormat)
	End Sub

	Sub DrawString(s As String, font As Font, brush As Brush, ByRef layoutRect As RectangleF, stringFormat = Nothing As StringFormat)
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs) As Long
		DrawString(wcs, len As Long, font, brush, layoutRect, stringFormat)
	End Sub

	Function MeasureString(s As String, font As Font) As SizeF
		Dim pt As PointF
		MeasureString = MeasureString(s, font, pt, Nothing)
	End Function

	Function MeasureString(s As String, font As Font, ByRef layoutRectSize As SizeF) As SizeF
		MeasureString = MeasureString(s, font, layoutRectSize, Nothing)
	End Function

	Function MeasureString(s As String, font As Font, ByRef layoutRectSize As SizeF, stringFormat As StringFormat) As SizeF
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs) As Long
		MeasureString = MeasureString(wcs, len, font, layoutRectSize, stringFormat)
	End Function

	Function MeasureString(s As String, font As Font, ByRef origin As PointF, stringFormat As StringFormat) As SizeF
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs) As Long
		MeasureString = MeasureString(wcs, len, font, origin, stringFormat)
	End Function

	Function MeasureString(s As String, font As Font, width As Long, stringFormat As StringFormat) As SizeF
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs) As Long
		MeasureString = MeasureString(wcs, len, font, width, stringFormat)
	End Function

	Function MeasureString(s As String, font As Font, ByRef layoutRectSize As SizeF, stringFormat As StringFormat, ByRef codepointsFitted As Long, ByRef linesFilled As Long) As SizeF
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs) As Long
		MeasureString = MeasureString(wcs, len, font, layoutRectSize, stringFormat, codepointsFitted, linesFilled)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font) As SizeF
		Dim pt As PointF
		MeasureString = MeasureString(str, length, font, pt, Nothing)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font, ByRef layoutRectSize As SizeF) As SizeF
		MeasureString = MeasureString(str, length, font, layoutRectSize, Nothing)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font, ByRef layoutRectSize As SizeF, stringFormat As StringFormat) As SizeF
		MeasureString = measureStringPt(str, length, font, layoutRectSize, stringFormat, 0, 0)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font, ByRef origin As PointF, stringFormat As StringFormat) As SizeF
		Dim layoutRect As RectangleF
		With layoutRect
			.X = origin.X
			.Y = origin.Y
			.Width = 0
			.Height = 0
		End With
		MeasureString = measureString(str, length, font, layoutRect, stringFormat, 0, 0)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font, width As Long, stringFormat As StringFormat) As SizeF
		Dim layoutRect As RectangleF
		With layoutRect
			.X = 0
			.Y = 0
			.Width = width
			.Height = 0
		End With
		MeasureString = measureString(str, length, font, layoutRect, stringFormat, 0, 0)
	End Function

	Function MeasureString(str As PCWSTR, length As Long, font As Font, ByRef layoutRectSize As SizeF, stringFormat As StringFormat, ByRef codepointsFitted As Long, ByRef linesFilled As Long) As SizeF
		MeasureString = measureStringPt(str, length, font, layoutRectSize, stringFormat, VarPtr(codepointsFitted), VarPtr(linesFilled))
	End Function

Private
	Function measureStringPt(str As PCWSTR, length As Long, font As Font, ByRef layoutRectSize As SizeF, stringFormat As StringFormat, codepointsFitted As *Long, linesFilled As *Long) As SizeF
		Dim layoutRect As RectangleF
		With layoutRect
			.X = 0
			.Y = 0
			.Width = layoutRectSize.Width
			.Height = layoutRectSize.Height
		End With
		measureStringPt = measureString(str, length, font, layoutRect, stringFormat, codepointsFitted, linesFilled)
	End Function

	Function measureString(str As PCWSTR, length As Long, font As Font, ByRef layoutRect As RectangleF, stringFormat As StringFormat, codepointsFitted As *Long, linesFilled As *Long) As SizeF
		Dim nativeFont = getNativeFont(font)
		Dim nativeFormat = GetNativeStringFormat(stringFormat)
		Dim boundingBox As RectangleF
		SetStatus(GdipMeasureString(nativeGraphics, str, length, nativeFont, layoutRect, nativeFormat, boundingBox, codepointsFitted, linesFilled))
		measureString.Width = boundingBox.Width
		measureString.Height = boundingBox.Height
	End Function

Public

	Function MeasureCharacterRanges(s As String, font As Font, ByRef layoutRect As RectangleF, stringFormat As StringFormat) As System.Collections.Generic.IList<Region>
		Dim wcs As PCWSTR
		Dim len = GetStr(s, wcs)
		MeasureCharacterRanges = MeasureCharacterRanges(wcs, len, font, layoutRect, stringFormat)
	End Function

	Function MeasureCharacterRanges(str As PCWSTR, length As Long, font As Font, ByRef layoutRect As RectangleF, stringFormat As StringFormat) As System.Collections.Generic.IList<Region>
		If ActiveBasic.IsNothing(stringFormat) Then
			stringFormat = New StringFormat
		End If
		Dim count As Long
        SetStatus(GdipGetStringFormatMeasurableCharacterRangeCount(stringFormat.NativeFormat, count))
		Dim nativeRegions As **GpRegion 'ここで = GC_mallocとすると、エラーになる。
		nativeRegions = GC_malloc(count * SizeOf(*GpRegion))
		Dim regions = New System.Collections.Generic.List<Region>(count)
		MeasureCharacterRanges = regions

		Dim i As Long
		For i = 0 To ELM(count)
			Dim t = regions[i]
			nativeRegions[i] = t.nativeRegion
		Next
		Dim nativeFont = getNativeFont(font)
		SetStatus(GdipMeasureCharacterRanges(nativeGraphics, str, length, nativeFont, layoutRect, stringFormat.NativeFormat, count, nativeRegions))
	End Function

	'DrawDriverString
	'MeasureDriverString

	Sub DrawCachedBitmap(cb As CachedBitmap, x As Long, y As Long)
		SetStatus(GdipDrawCachedBitmap(nativeGraphics, cb.nativeCachedBitmap, x, y))
	End Sub

	Sub DrawImage(image As Image, ByRef point As PointF)
		DrawImage(image, point.X, point.Y)
	End Sub

	Sub DrawImage(image As Image, x As Single, y As Single)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImage(nativeGraphics, nativeImage, x, y))
	End Sub

	Sub DrawImage(image As Image, ByRef rect As RectangleF)
		DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawImage(image As Image, x As Single, y As Single, width As Single, height As Single)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImageRect(nativeGraphics, nativeImage, x, y, width, height))
	End Sub

	Sub DrawImage(image As Image, ByRef point As Point)
		DrawImage(image, point.X, point.Y)
	End Sub

	Sub DrawImage(image As Image, x As Long, y As Long)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImageI(nativeGraphics, nativeImage, x, y))
	End Sub

	Sub DrawImage(image As Image, ByRef rect As Rectangle)
		DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height)
	End Sub

	Sub DrawImage(image As Image, x As Long, y As Long, width As Long, height As Long)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImageRectI(nativeGraphics, nativeImage, x, y, width, height))
	End Sub

	' 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

	Sub DrawImage(image As Image, destPoints As *PointF, count As Long)
		If count <> 3 And count <> 4 Then
			SetStatus(InvalidParameter)
		End If

		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImagePoints(nativeGraphics, nativeImage, destPoints, count))
	End Sub

	Sub DrawImage(image As Image, destPoints As *Point, count As Long)
		If count <> 3 And count <> 4 Then
			SetStatus(InvalidParameter)
		End If

		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImagePointsI(nativeGraphics, nativeImage, destPoints, count))
	End Sub

	Sub DrawImage(image As Image, ByRef destRect As Rectangle, ByRef src As Rectangle, srcUnit As GraphicsUnit)
		DrawImage(image, destRect, src.X, src.Y, src.Width, src.Height, srcUnit)
	End Sub

	Sub DrawImage(image As Image, ByRef destRect As RectangleF, ByRef src As RectangleF, srcUnit As GraphicsUnit)
		DrawImage(image, destRect, src.X, src.Y, src.Width, src.Height, srcUnit)
	End Sub

	Sub DrawImage(image As Image, x As Long, y As Long, ByRef src As Rectangle, srcUnit As GraphicsUnit)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImagePointRectI(nativeGraphics, nativeImage, x, y, src.X, src.Y, src.Width, src.Height, srcUnit))
	End Sub

	Sub DrawImage(image As Image, x As Single, y As Single, ByRef src As RectangleF, srcUnit As GraphicsUnit)
		Dim nativeImage = getNativeImage(image)
		SetStatus(GdipDrawImagePointRect(nativeGraphics, nativeImage, x, y, src.X, src.Y, src.Width, src.Height, srcUnit))
	End Sub

	Sub DrawImage(image As Image, destPoints As *Point, count As Long, ByRef src As Rectangle, srcUnit As GraphicsUnit, _
		imageAttr = Nothing As ImageAttributes, callback = Nothing As DrawImageAbort, callbackData = 0 As VoidPtr)

		Dim nativeImage = getNativeImage(image)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		SetStatus(GdipDrawImagePointsRectI(nativeGraphics, nativeImage, destPoints, count,
			src.X, src.Y, src.Width, src.Height, srcUnit, nativeImageAttr, callback, callbackData))
	End Sub

	Sub DrawImage(image As Image, destPoints As *PointF, count As Long, ByRef src As RectangleF, srcUnit As GraphicsUnit,
		imageAttr = Nothing As ImageAttributes, callback = Nothing As DrawImageAbort, callbackData = 0 As VoidPtr)

		Dim nativeImage = getNativeImage(image)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		SetStatus(GdipDrawImagePointsRect(nativeGraphics, nativeImage, destPoints, count,
			src.X, src.Y, src.Width, src.Height, srcUnit, nativeImageAttr, callback, callbackData))
	End Sub

	Sub DrawImage(image As Image, ByRef destRect As RectangleF,
		srcx As Single, srcy As Single, srcwidth As Single, srcheight As Single, srcUnit As GraphicsUnit,
		imageAttr = Nothing As ImageAttributes, callback = Nothing As DrawImageAbort, callbackData = 0 As VoidPtr)

		Dim nativeImage = getNativeImage(image)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		SetStatus(GdipDrawImageRectRect(nativeGraphics, nativeImageAttr,
			destRect.X, destRect.Y, destRect.Width, destRect.Height, srcx, srcy, srcwidth, srcheight,
			srcUnit, nativeImageAttr, callback, callbackData))
	End Sub

	Sub DrawImage(image As Image, ByRef destRect As Rectangle,
		srcx As Long, srcy As Long, srcwidth As Long, srcheight As Long, srcUnit As GraphicsUnit,
		imageAttr = Nothing As ImageAttributes, callback = Nothing As DrawImageAbort, callbackData = 0 As VoidPtr)

		Dim nativeImage = getNativeImage(image)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		SetStatus(GdipDrawImageRectRectI(nativeGraphics, nativeImage,
			destRect.X, destRect.Y, destRect.Width, destRect.Height,
			srcx, srcy, srcwidth, srcheight, srcUnit, nativeImageAttr, callback, callbackData))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, ByRef destPoint As PointF,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestPoint(nativeGraphics,
			nativeImage, destPoint, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, ByRef destPoint As Point,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestPointI(nativeGraphics,
			nativeImage, destPoint, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, ByRef destRect As RectangleF,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestRect(nativeGraphics,
			nativeImage, destRect, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, ByRef destRect As Rectangle,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestRectI(nativeGraphics,
			nativeImage, destRect, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, destPoints As *PointF, count As Long,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestPoints(nativeGraphics,
			nativeImage,destPoints, count, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile, destPoints As *Point, count As Long,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileDestPointsI(nativeGraphics,
			nativeImage,destPoints, count, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		ByRef destPoint As PointF, ByRef srcRect As RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestPoint(nativeGraphics,
			nativeImage, destPoint, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		ByRef destPoint As Point, ByRef srcRect As Rectangle, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestPointI(nativeGraphics,
			nativeImage, destPoint, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		ByRef destRect As RectangleF, ByRef srcRect As RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestRect(nativeGraphics,
			nativeImage, destRect, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		ByRef destRect As Rectangle, ByRef srcRect As Rectangle, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestRectI(nativeGraphics,
			nativeImage, destRect, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		destPoints As *PointF, count As Long, ByRef srcRect As RectangleF, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestPoints(nativeGraphics,
			nativeImage, destPoints, count, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub EnumerateMetafile(metafile As Metafile,
		destPoints As *Point, count As Long, ByRef srcRect As Rectangle, srcUnit As GraphicsUnit,
		callback As EnumerateMetafileProc, callbackData = 0 As VoidPtr, imageAttr = Nothing As ImageAttributes)

		Dim nativeImage = getNativeImage(metafile)
		Dim nativeImageAttr = getNativeImageAttributes(imageAttr)
		Dim procData As Detail.EnumerateMetafileProcData
		procData.Proc = callback
		procData.Data = callbackData
		SetStatus(GdipEnumerateMetafileSrcRectDestPointsI(nativeGraphics, nativeImage,
			destPoints, count, srcRect, srcUnit, AddressOf(Detail.NativeEnumerateMetafileProcEntry), VarPtr(procData), nativeImageAttr))
	End Sub

	Sub SetClip(g As Graphics)
		SetClip(g, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(g As Graphics, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipGraphics(nativeGraphics, g.nativeGraphics, combineMode))
	End Sub

	Sub SetClip(ByRef rc As RectangleF)
		SetClip(rc, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(ByRef rc As RectangleF, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, combineMode))
	End Sub

	Sub SetClip(ByRef rc As Rectangle)
		SetClip(rc, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(ByRef rc As Rectangle, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, combineMode))
	End Sub

	Sub SetClip(path As GraphicsPath)
		SetClip(path, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(path As GraphicsPath, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipPath(nativeGraphics, path.nativePath, combineMode))
	End Sub

	Sub SetClip(region As Region)
		SetClip(region, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(region As Region, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipRegion(nativeGraphics, region.nativeRegion, combineMode))
	End Sub

	Sub SetClip(hrgn As HRGN)
		SetClip(hrgn, System.Drawing.Drawing2D.CombineMode.Replace)
	End Sub

	Sub SetClip(hrgn As HRGN, combineMode As Drawing2D.CombineMode)
		SetStatus(GdipSetClipHrgn(nativeGraphics, hrgn, combineMode))
	End Sub

	Sub IntersectClip(ByRef rc As RectangleF)
		SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, System.Drawing.Drawing2D.CombineMode.Intersect))
	End Sub

	Sub IntersectClip(ByRef rc As Rectangle)
		SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, System.Drawing.Drawing2D.CombineMode.Intersect))
	End Sub

	Sub IntersectClip(region As Region)
		SetStatus(GdipSetClipRegion(nativeGraphics, region.nativeRegion, System.Drawing.Drawing2D.CombineMode.Intersect))
	End Sub

	Sub ExcludeClip(ByRef rc As RectangleF)
		SetStatus(GdipSetClipRect(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, System.Drawing.Drawing2D.CombineMode.Exclude))
	End Sub

	Sub ExcludeClip(ByRef rc As Rectangle)
		SetStatus(GdipSetClipRectI(nativeGraphics, rc.X, rc.Y, rc.Width, rc.Height, System.Drawing.Drawing2D.CombineMode.Exclude))
	End Sub

	Sub ExcludeClip(region As Region)
		SetStatus(GdipSetClipRegion(nativeGraphics, region.nativeRegion, System.Drawing.Drawing2D.CombineMode.Exclude))
	End Sub

	Sub ResetClip()
		SetStatus(GdipResetClip(nativeGraphics))
	End Sub

	Sub TranslateClip(dx As Single, dy As Single)
		SetStatus(GdipTranslateClip(nativeGraphics, dx, dy))
	End Sub

	Sub TranslateClip(dx As Long, dy As Long)
		SetStatus(GdipTranslateClipI(nativeGraphics, dx, dy))
	End Sub

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

	Const Function IsVisible(ByRef pt As Point) As Boolean
		IsVisible(pt.X, pt.Y)
	End Function

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

	Const Function IsVisible(ByRef rc As Rectangle) As Boolean
		IsVisible = IsVisible(rc.X, rc.Y, rc.Width, rc.Height)
	End Function

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

	Const Function IsVisible(ByRef pt As PointF) As Boolean
		IsVisible = IsVisible(pt.X, pt.Y)
	End Function

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

	Const Function IsVisible(ByRef rc As RectangleF) As Boolean
		IsVisible = IsVisible(rc.X, rc.Y, rc.Width, rc.Height)
	End Function

	Const Function Save() As Drawing2D.GraphicsState
		SetStatus(GdipSaveGraphics(nativeGraphics, Save))
	End Function

	Sub Restore(gstate As Drawing2D.GraphicsState)
		SetStatus(GdipRestoreGraphics(nativeGraphics, gstate))
	End Sub

	Function BeginContainer(ByRef dstrect As RectangleF, ByRef srcrect As RectangleF, unit As GraphicsUnit) As Drawing2D.GraphicsContainer
		SetStatus(GdipBeginContainer(nativeGraphics, dstrect, srcrect, unit, BeginContainer))
	End Function

	Function BeginContainer(ByRef dstrect As Rectangle, ByRef srcrect As Rectangle, unit As GraphicsUnit) As Drawing2D.GraphicsContainer
		SetStatus(GdipBeginContainerI(nativeGraphics, dstrect, srcrect, unit, BeginContainer))
	End Function

	Function BeginContainer() As Drawing2D.GraphicsContainer
		SetStatus(GdipBeginContainer2(nativeGraphics, BeginContainer))
	End Function

	Sub EndContainer(state As Drawing2D.GraphicsContainer)
		SetStatus(GdipEndContainer(nativeGraphics, state))
	End Sub

	Sub AddMetafileComment(data As *Byte, sizeData As DWord)
		SetStatus(GdipComment(nativeGraphics, sizeData, data))
	End Sub

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

	Function NativeGraphics() As *GpGraphics
		NativeGraphics = nativeGraphics
	End Function

	Sub Graphics(graphics As *GpGraphics)
		nativeGraphics = graphics
	End Sub

Private
	Static Function getNativePen(pen As Pen) As *GpPen
		If ActiveBasic.IsNothing(pen) Then
			getNativePen = 0
		Else
			getNativePen = pen.NativePen
		End If
	End Function

	Static Function getNativeBrush(br As Brush) As *GpBrush
		If ActiveBasic.IsNothing(br) Then
			getNativeBrush = 0
		Else
			getNativeBrush = br.NativeBrush
		End If
	End Function

	Static Function getNativeFont(font As Font) As *GpFont
		If ActiveBasic.IsNothing(font) Then
			getNativeFont = 0
		Else
			getNativeFont = font.NativeFont
		End If
	End Function

	Static Function getNativeImage(image As Image) As *GpImage
		If ActiveBasic.IsNothing(image) Then
			getNativeImage = 0
		Else
			getNativeImage = image.nativeImage
		End If
	End Function

	Static Function getNativeImageAttributes(imageAttr As ImageAttributes) As *GpImageAttributes
		If ActiveBasic.IsNothing(imageAttr) Then
			getNativeImageAttributes = 0
		Else
			getNativeImageAttributes = imageAttr.nativeImage
		End If
	End Function

	nativeGraphics As *GpGraphics
End Class

End Namespace
End Namespace
