1/*
2 * gdiplusgraphics.h
3 *
4 * GDI+ Graphics class
5 *
6 * This file is part of the w32api package.
7 *
8 * Contributors:
9 *   Created by Markus Koenig <markus@stber-koenig.de>
10 *
11 * THIS SOFTWARE IS NOT COPYRIGHTED
12 *
13 * This source code is offered for use in the public domain. You may
14 * use, modify or distribute it freely.
15 *
16 * This code is distributed in the hope that it will be useful but
17 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18 * DISCLAIMED. This includes but is not limited to warranties of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 */
22
23#ifndef __GDIPLUS_GRAPHICS_H
24#define __GDIPLUS_GRAPHICS_H
25#if __GNUC__ >=3
26#pragma GCC system_header
27#endif
28
29#ifndef __cplusplus
30#error "A C++ compiler is required to include gdiplusgraphics.h."
31#endif
32
33class Graphics: public GdiplusBase
34{
35	friend class Bitmap;
36	friend class CachedBitmap;
37	friend class Font;
38	friend class GraphicsPath;
39	friend class Metafile;
40	friend class Region;
41
42public:
43	static Graphics* FromHDC(HDC hdc)
44	{
45		return new Graphics(hdc);
46	}
47	static Graphics* FromHDC(HDC hdc, HANDLE hdevice)
48	{
49		return new Graphics(hdc, hdevice);
50	}
51	static Graphics* FromHWND(HWND hwnd, BOOL icm = FALSE)
52	{
53		return new Graphics(hwnd, icm);
54	}
55	static Graphics* FromImage(Image *image)
56	{
57		return new Graphics(image);
58	}
59	static HPALETTE GetHalftonePalette()
60	{
61		return DllExports::GdipCreateHalftonePalette();
62	}
63
64	Graphics(Image *image): nativeGraphics(NULL), lastStatus(Ok)
65	{
66		lastStatus = DllExports::GdipGetImageGraphicsContext(
67				image ? image->nativeImage : NULL,
68				&nativeGraphics);
69	}
70	Graphics(HDC hdc): nativeGraphics(NULL), lastStatus(Ok)
71	{
72		lastStatus = DllExports::GdipCreateFromHDC(
73				hdc, &nativeGraphics);
74	}
75	Graphics(HDC hdc, HANDLE hdevice): nativeGraphics(NULL), lastStatus(Ok)
76	{
77		lastStatus = DllExports::GdipCreateFromHDC2(
78				hdc, hdevice, &nativeGraphics);
79	}
80	Graphics(HWND hwnd, BOOL icm = FALSE):
81		nativeGraphics(NULL), lastStatus(Ok)
82	{
83		if (icm) {
84			lastStatus = DllExports::GdipCreateFromHWNDICM(
85					hwnd, &nativeGraphics);
86		} else {
87			lastStatus = DllExports::GdipCreateFromHWND(
88					hwnd, &nativeGraphics);
89		}
90	}
91	~Graphics()
92	{
93		DllExports::GdipDeleteGraphics(nativeGraphics);
94	}
95
96	Status AddMetafileComment(const BYTE *data, UINT sizeData)
97	{
98		return updateStatus(DllExports::GdipComment(
99				nativeGraphics, sizeData, data));
100	}
101	GraphicsContainer BeginContainer()
102	{
103		GraphicsContainer result = 0;
104		updateStatus(DllExports::GdipBeginContainer2(
105				nativeGraphics, &result));
106		return result;
107	}
108	GraphicsContainer BeginContainer(const RectF& dstrect,
109			const RectF& srcrect, Unit unit)
110	{
111		GraphicsContainer result = 0;
112		updateStatus(DllExports::GdipBeginContainer(
113				nativeGraphics, &dstrect, &srcrect, unit,
114				&result));
115		return result;
116	}
117	GraphicsContainer BeginContainer(const Rect& dstrect,
118			const Rect& srcrect, Unit unit)
119	{
120		GraphicsContainer result = 0;
121		updateStatus(DllExports::GdipBeginContainerI(
122				nativeGraphics, &dstrect, &srcrect, unit,
123				&result));
124		return result;
125	}
126	Status Clear(const Color& color)
127	{
128		return updateStatus(DllExports::GdipGraphicsClear(
129				nativeGraphics, color.GetValue()));
130	}
131	Status DrawArc(const Pen *pen, REAL x, REAL y, REAL width, REAL height,
132			REAL startAngle, REAL sweepAngle)
133	{
134		return updateStatus(DllExports::GdipDrawArc(
135				nativeGraphics, pen ? pen->nativePen : NULL,
136				x, y, width, height, startAngle, sweepAngle));
137	}
138	Status DrawArc(const Pen *pen, INT x, INT y, INT width, INT height,
139			REAL startAngle, REAL sweepAngle)
140	{
141		return updateStatus(DllExports::GdipDrawArcI(
142				nativeGraphics, pen ? pen->nativePen : NULL,
143				x, y, width, height, startAngle, sweepAngle));
144	}
145	Status DrawArc(const Pen *pen, const RectF& rect,
146			REAL startAngle, REAL sweepAngle)
147	{
148		return updateStatus(DllExports::GdipDrawArc(
149				nativeGraphics, pen ? pen->nativePen : NULL,
150				rect.X, rect.Y, rect.Width, rect.Height,
151				startAngle, sweepAngle));
152	}
153	Status DrawArc(const Pen *pen, const Rect& rect,
154			REAL startAngle, REAL sweepAngle)
155	{
156		return updateStatus(DllExports::GdipDrawArcI(
157				nativeGraphics, pen ? pen->nativePen : NULL,
158				rect.X, rect.Y, rect.Width, rect.Height,
159				startAngle, sweepAngle));
160	}
161	Status DrawBezier(const Pen *pen,
162			REAL x1, REAL y1, REAL x2, REAL y2,
163			REAL x3, REAL y3, REAL x4, REAL y4)
164	{
165		return updateStatus(DllExports::GdipDrawBezier(
166				nativeGraphics, pen ? pen->nativePen : NULL,
167				x1, y1, x2, y2, x3, y3, x4, y4));
168	}
169	Status DrawBezier(const Pen *pen,
170			INT x1, INT y1, INT x2, INT y2,
171			INT x3, INT y3, INT x4, INT y4)
172	{
173		return updateStatus(DllExports::GdipDrawBezierI(
174				nativeGraphics, pen ? pen->nativePen : NULL,
175				x1, y1, x2, y2, x3, y3, x4, y4));
176	}
177	Status DrawBezier(const Pen *pen,
178			const PointF& pt1, const PointF& pt2,
179			const PointF& pt3, const PointF& pt4)
180	{
181		return updateStatus(DllExports::GdipDrawBezier(
182				nativeGraphics, pen ? pen->nativePen : NULL,
183				pt1.X, pt1.Y, pt2.X, pt2.Y,
184				pt3.X, pt3.Y, pt4.X, pt4.Y));
185	}
186	Status DrawBezier(const Pen *pen,
187			const Point& pt1, const Point& pt2,
188			const Point& pt3, const Point& pt4)
189	{
190		return updateStatus(DllExports::GdipDrawBezierI(
191				nativeGraphics, pen ? pen->nativePen : NULL,
192				pt1.X, pt1.Y, pt2.X, pt2.Y,
193				pt3.X, pt3.Y, pt4.X, pt4.Y));
194	}
195	Status DrawBeziers(const Pen *pen, const PointF *points, INT count)
196	{
197		return updateStatus(DllExports::GdipDrawBeziers(
198				nativeGraphics, pen ? pen->nativePen : NULL,
199				points, count));
200	}
201	Status DrawBeziers(const Pen *pen, const Point *points, INT count)
202	{
203		return updateStatus(DllExports::GdipDrawBeziersI(
204				nativeGraphics, pen ? pen->nativePen : NULL,
205				points, count));
206	}
207	Status DrawCachedBitmap(CachedBitmap *cb, INT x, INT y)
208	{
209		return updateStatus(DllExports::GdipDrawCachedBitmap(
210				nativeGraphics,
211				cb ? cb->nativeCachedBitmap : NULL,
212				x, y));
213	}
214	Status DrawClosedCurve(const Pen *pen, const PointF *points, INT count)
215	{
216		return updateStatus(DllExports::GdipDrawClosedCurve(
217				nativeGraphics, pen ? pen->nativePen : NULL,
218				points, count));
219	}
220	Status DrawClosedCurve(const Pen *pen, const Point *points, INT count)
221	{
222		return updateStatus(DllExports::GdipDrawClosedCurveI(
223				nativeGraphics, pen ? pen->nativePen : NULL,
224				points, count));
225	}
226	Status DrawClosedCurve(const Pen *pen, const PointF *points, INT count,
227			REAL tension)
228	{
229		return updateStatus(DllExports::GdipDrawClosedCurve2(
230				nativeGraphics, pen ? pen->nativePen : NULL,
231				points, count, tension));
232	}
233	Status DrawClosedCurve(const Pen *pen, const Point *points, INT count,
234			REAL tension)
235	{
236		return updateStatus(DllExports::GdipDrawClosedCurve2I(
237				nativeGraphics, pen ? pen->nativePen : NULL,
238				points, count, tension));
239	}
240	Status DrawCurve(const Pen *pen, const PointF *points, INT count)
241	{
242		return updateStatus(DllExports::GdipDrawCurve(
243				nativeGraphics, pen ? pen->nativePen : NULL,
244				points, count));
245	}
246	Status DrawCurve(const Pen *pen, const Point *points, INT count)
247	{
248		return updateStatus(DllExports::GdipDrawCurveI(
249				nativeGraphics, pen ? pen->nativePen : NULL,
250				points, count));
251	}
252	Status DrawCurve(const Pen *pen, const PointF *points, INT count,
253			REAL tension)
254	{
255		return updateStatus(DllExports::GdipDrawCurve2(
256				nativeGraphics, pen ? pen->nativePen : NULL,
257				points, count, tension));
258	}
259	Status DrawCurve(const Pen *pen, const Point *points, INT count,
260			REAL tension)
261	{
262		return updateStatus(DllExports::GdipDrawCurve2I(
263				nativeGraphics, pen ? pen->nativePen : NULL,
264				points, count, tension));
265	}
266	Status DrawCurve(const Pen *pen, const PointF *points, INT count,
267			INT offset, INT numberOfSegments, REAL tension)
268	{
269		return updateStatus(DllExports::GdipDrawCurve3(
270				nativeGraphics, pen ? pen->nativePen : NULL,
271				points, count, offset,
272				numberOfSegments, tension));
273	}
274	Status DrawCurve(const Pen *pen, const Point *points, INT count,
275			INT offset, INT numberOfSegments, REAL tension)
276	{
277		return updateStatus(DllExports::GdipDrawCurve3I(
278				nativeGraphics, pen ? pen->nativePen : NULL,
279				points, count, offset,
280				numberOfSegments, tension));
281	}
282	Status DrawDriverString(const UINT16 *text, INT length,
283			const Font *font, const Brush *brush,
284			const PointF *positions, INT flags,
285			const Matrix *matrix)
286	{
287		return updateStatus(DllExports::GdipDrawDriverString(
288				nativeGraphics, text, length,
289				font ? font->nativeFont : NULL,
290				brush ? brush->nativeBrush : NULL,
291				positions, flags,
292				matrix ? matrix->nativeMatrix : NULL));
293	}
294	Status DrawEllipse(const Pen *pen,
295			REAL x, REAL y, REAL width, REAL height)
296	{
297		return updateStatus(DllExports::GdipDrawEllipse(
298				nativeGraphics, pen ? pen->nativePen : NULL,
299				x, y, width, height));
300	}
301	Status DrawEllipse(const Pen *pen, INT x, INT y, INT width, INT height)
302	{
303		return updateStatus(DllExports::GdipDrawEllipseI(
304				nativeGraphics, pen ? pen->nativePen : NULL,
305				x, y, width, height));
306	}
307	Status DrawEllipse(const Pen *pen, const RectF& rect)
308	{
309		return updateStatus(DllExports::GdipDrawEllipse(
310				nativeGraphics, pen ? pen->nativePen : NULL,
311				rect.X, rect.Y, rect.Width, rect.Height));
312	}
313	Status DrawEllipse(const Pen *pen, const Rect& rect)
314	{
315		return updateStatus(DllExports::GdipDrawEllipseI(
316				nativeGraphics, pen ? pen->nativePen : NULL,
317				rect.X, rect.Y, rect.Width, rect.Height));
318	}
319	Status DrawImage(Image *image, REAL x, REAL y)
320	{
321		return updateStatus(DllExports::GdipDrawImage(
322				nativeGraphics,
323				image ? image->nativeImage : NULL,
324				x, y));
325	}
326	Status DrawImage(Image *image, INT x, INT y)
327	{
328		return updateStatus(DllExports::GdipDrawImageI(
329				nativeGraphics,
330				image ? image->nativeImage : NULL,
331				x, y));
332	}
333	Status DrawImage(Image *image, const PointF& point)
334	{
335		return updateStatus(DllExports::GdipDrawImage(
336				nativeGraphics,
337				image ? image->nativeImage : NULL,
338				point.X, point.Y));
339	}
340	Status DrawImage(Image *image, const Point& point)
341	{
342		return updateStatus(DllExports::GdipDrawImageI(
343				nativeGraphics,
344				image ? image->nativeImage : NULL,
345				point.X, point.Y));
346	}
347	Status DrawImage(Image *image, REAL x, REAL y, REAL width, REAL height)
348	{
349		return updateStatus(DllExports::GdipDrawImageRect(
350				nativeGraphics,
351				image ? image->nativeImage : NULL,
352				x, y, width, height));
353	}
354	Status DrawImage(Image *image, INT x, INT y, INT width, INT height)
355	{
356		return updateStatus(DllExports::GdipDrawImageRectI(
357				nativeGraphics,
358				image ? image->nativeImage : NULL,
359				x, y, width, height));
360	}
361	Status DrawImage(Image *image, const RectF& rect)
362	{
363		return updateStatus(DllExports::GdipDrawImageRect(
364				nativeGraphics,
365				image ? image->nativeImage : NULL,
366				rect.X, rect.Y, rect.Width, rect.Height));
367	}
368	Status DrawImage(Image *image, const Rect& rect)
369	{
370		return updateStatus(DllExports::GdipDrawImageRectI(
371				nativeGraphics,
372				image ? image->nativeImage : NULL,
373				rect.X, rect.Y, rect.Width, rect.Height));
374	}
375	Status DrawImage(Image *image, const PointF *destPoints, INT count)
376	{
377		return updateStatus(DllExports::GdipDrawImagePoints(
378				nativeGraphics,
379				image ? image->nativeImage : NULL,
380				destPoints, count));
381	}
382	Status DrawImage(Image *image, const Point *destPoints, INT count)
383	{
384		return updateStatus(DllExports::GdipDrawImagePointsI(
385				nativeGraphics,
386				image ? image->nativeImage : NULL,
387				destPoints, count));
388	}
389	Status DrawImage(Image *image, REAL x, REAL y, REAL srcx, REAL srcy,
390			REAL srcwidth, REAL srcheight, Unit srcUnit)
391	{
392		return updateStatus(DllExports::GdipDrawImagePointRect(
393				nativeGraphics,
394				image ? image->nativeImage : NULL,
395				x, y, srcx, srcy, srcwidth, srcheight,
396				srcUnit));
397	}
398	Status DrawImage(Image *image, INT x, INT y, INT srcx, INT srcy,
399			INT srcwidth, INT srcheight, Unit srcUnit)
400	{
401		return updateStatus(DllExports::GdipDrawImagePointRectI(
402				nativeGraphics,
403				image ? image->nativeImage : NULL,
404				x, y, srcx, srcy, srcwidth, srcheight,
405				srcUnit));
406	}
407	Status DrawImage(Image *image, const RectF& destRect,
408			REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
409			Unit srcUnit,
410			const ImageAttributes *imageAttributes = NULL,
411			DrawImageAbort callback = NULL,
412			VOID *callbackData = NULL)
413	{
414		return updateStatus(DllExports::GdipDrawImageRectRect(
415				nativeGraphics,
416				image ? image->nativeImage : NULL,
417				destRect.X, destRect.Y,
418				destRect.Width, destRect.Height,
419				srcx, srcy, srcwidth, srcheight, srcUnit,
420				imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
421				callback, callbackData));
422	}
423	Status DrawImage(Image *image, const Rect& destRect,
424			INT srcx, INT srcy, INT srcwidth, INT srcheight,
425			Unit srcUnit,
426			const ImageAttributes *imageAttributes = NULL,
427			DrawImageAbort callback = NULL,
428			VOID *callbackData = NULL)
429	{
430		return updateStatus(DllExports::GdipDrawImageRectRectI(
431				nativeGraphics,
432				image ? image->nativeImage : NULL,
433				destRect.X, destRect.Y,
434				destRect.Width, destRect.Height,
435				srcx, srcy, srcwidth, srcheight, srcUnit,
436				imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
437				callback, callbackData));
438	}
439	Status DrawImage(Image *image, const RectF& destRect,
440			const RectF& sourceRect, Unit srcUnit,
441			const ImageAttributes *imageAttributes = NULL)
442	{
443		return updateStatus(DllExports::GdipDrawImageRectRectI(
444				nativeGraphics,
445				image ? image->nativeImage : NULL,
446				destRect.X, destRect.Y,
447				destRect.Width, destRect.Height,
448				sourceRect.X, sourceRect.Y,
449				sourceRect.Width, sourceRect.Height, srcUnit,
450				imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
451				NULL, NULL));
452	}
453	Status DrawImage(Image *image, const PointF *destPoints, INT count,
454			REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
455			Unit srcUnit,
456			const ImageAttributes *imageAttributes = NULL,
457			DrawImageAbort callback = NULL,
458			VOID *callbackData = NULL)
459	{
460		return updateStatus(DllExports::GdipDrawImagePointsRect(
461				nativeGraphics,
462				image ? image->nativeImage : NULL,
463				destPoints, count,
464				srcx, srcy, srcwidth, srcheight, srcUnit,
465				imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
466				callback, callbackData));
467	}
468	Status DrawImage(Image *image, const Point *destPoints, INT count,
469			INT srcx, INT srcy, INT srcwidth, INT srcheight,
470			Unit srcUnit,
471			const ImageAttributes *imageAttributes = NULL,
472			DrawImageAbort callback = NULL,
473			VOID *callbackData = NULL)
474	{
475		return updateStatus(DllExports::GdipDrawImagePointsRectI(
476				nativeGraphics,
477				image ? image->nativeImage : NULL,
478				destPoints, count,
479				srcx, srcy, srcwidth, srcheight, srcUnit,
480				imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
481				callback, callbackData));
482	}
483	// TODO: [GDI+ 1.1] Graphics::DrawImage(..Effect..)
484	//Status DrawImage(Image *image, RectF *sourceRect, Matrix *matrix,
485	//		Effect *effect, ImageAttributes *imageAttributes,
486	//		Unit srcUnit)
487	//{
488	//	return updateStatus(DllExports::GdipDrawImageFX(
489	//			nativeGraphics,
490	//			image ? image->nativeImage : NULL,
491	//			sourceRect,
492	//			matrix ? matrix->nativeMatrix : NULL,
493	//			effect ? effect->nativeEffect : NULL,
494	//			imageAttributes ? imageAttributes->nativeImageAttributes : NULL,
495	//			srcUnit));
496	//}
497	Status DrawLine(const Pen *pen, REAL x1, REAL y1, REAL x2, REAL y2)
498	{
499		return updateStatus(DllExports::GdipDrawLine(
500				nativeGraphics, pen ? pen->nativePen : NULL,
501				x1, y1, x2, y2));
502	}
503	Status DrawLine(const Pen *pen, INT x1, INT y1, INT x2, INT y2)
504	{
505		return updateStatus(DllExports::GdipDrawLineI(
506				nativeGraphics, pen ? pen->nativePen : NULL,
507				x1, y1, x2, y2));
508	}
509	Status DrawLine(const Pen *pen, const PointF& pt1, const PointF& pt2)
510	{
511		return updateStatus(DllExports::GdipDrawLine(
512				nativeGraphics, pen ? pen->nativePen : NULL,
513				pt1.X, pt1.Y, pt2.X, pt2.Y));
514	}
515	Status DrawLine(const Pen *pen, const Point& pt1, const Point& pt2)
516	{
517		return updateStatus(DllExports::GdipDrawLineI(
518				nativeGraphics, pen ? pen->nativePen : NULL,
519				pt1.X, pt1.Y, pt2.X, pt2.Y));
520	}
521	Status DrawLines(const Pen *pen, const PointF *points, INT count)
522	{
523		return updateStatus(DllExports::GdipDrawLines(
524				nativeGraphics, pen ? pen->nativePen : NULL,
525				points, count));
526	}
527	Status DrawLines(const Pen *pen, const Point *points, INT count)
528	{
529		return updateStatus(DllExports::GdipDrawLinesI(
530				nativeGraphics, pen ? pen->nativePen : NULL,
531				points, count));
532	}
533	Status DrawPath(const Pen *pen, const GraphicsPath *path)
534	{
535		return updateStatus(DllExports::GdipDrawPath(
536				nativeGraphics, pen ? pen->nativePen : NULL,
537				path ? path->nativePath : NULL));
538	}
539	Status DrawPie(const Pen *pen, REAL x, REAL y, REAL width, REAL height,
540			REAL startAngle, REAL sweepAngle)
541	{
542		return updateStatus(DllExports::GdipDrawPie(
543				nativeGraphics, pen ? pen->nativePen : NULL,
544				x, y, width, height, startAngle, sweepAngle));
545	}
546	Status DrawPie(const Pen *pen, INT x, INT y, INT width, INT height,
547			REAL startAngle, REAL sweepAngle)
548	{
549		return updateStatus(DllExports::GdipDrawPieI(
550				nativeGraphics, pen ? pen->nativePen : NULL,
551				x, y, width, height, startAngle, sweepAngle));
552	}
553	Status DrawPie(const Pen *pen, const RectF& rect,
554			REAL startAngle, REAL sweepAngle)
555	{
556		return updateStatus(DllExports::GdipDrawPie(
557				nativeGraphics, pen ? pen->nativePen : NULL,
558				rect.X, rect.Y, rect.Width, rect.Height,
559				startAngle, sweepAngle));
560	}
561	Status DrawPie(const Pen *pen, const Rect& rect,
562			REAL startAngle, REAL sweepAngle)
563	{
564		return updateStatus(DllExports::GdipDrawPieI(
565				nativeGraphics, pen ? pen->nativePen : NULL,
566				rect.X, rect.Y, rect.Width, rect.Height,
567				startAngle, sweepAngle));
568	}
569	Status DrawPolygon(const Pen *pen, const PointF *points, INT count)
570	{
571		return updateStatus(DllExports::GdipDrawPolygon(
572				nativeGraphics, pen ? pen->nativePen : NULL,
573				points, count));
574	}
575	Status DrawPolygon(const Pen *pen, const Point *points, INT count)
576	{
577		return updateStatus(DllExports::GdipDrawPolygonI(
578				nativeGraphics, pen ? pen->nativePen : NULL,
579				points, count));
580	}
581	Status DrawRectangle(const Pen *pen,
582			REAL x, REAL y, REAL width, REAL height)
583	{
584		return updateStatus(DllExports::GdipDrawRectangle(
585				nativeGraphics, pen ? pen->nativePen : NULL,
586				x, y, width, height));
587	}
588	Status DrawRectangle(const Pen *pen,
589			INT x, INT y, INT width, INT height)
590	{
591		return updateStatus(DllExports::GdipDrawRectangleI(
592				nativeGraphics, pen ? pen->nativePen : NULL,
593				x, y, width, height));
594	}
595	Status DrawRectangle(const Pen *pen, const RectF& rect)
596	{
597		return updateStatus(DllExports::GdipDrawRectangle(
598				nativeGraphics, pen ? pen->nativePen : NULL,
599				rect.X, rect.Y, rect.Width, rect.Height));
600	}
601	Status DrawRectangle(const Pen *pen, const Rect& rect)
602	{
603		return updateStatus(DllExports::GdipDrawRectangleI(
604				nativeGraphics, pen ? pen->nativePen : NULL,
605				rect.X, rect.Y, rect.Width, rect.Height));
606	}
607	Status DrawRectangles(const Pen *pen, const RectF *rects, INT count)
608	{
609		return updateStatus(DllExports::GdipDrawRectangles(
610				nativeGraphics, pen ? pen->nativePen : NULL,
611				rects, count));
612	}
613	Status DrawRectangles(const Pen *pen, const Rect *rects, INT count)
614	{
615		return updateStatus(DllExports::GdipDrawRectanglesI(
616				nativeGraphics, pen ? pen->nativePen : NULL,
617				rects, count));
618	}
619	Status DrawString(const WCHAR *string, INT length, const Font *font,
620			const PointF& origin, const Brush *brush)
621	{
622		RectF layoutRect(origin.X, origin.Y, 0.0f, 0.0f);
623		return updateStatus(DllExports::GdipDrawString(
624				nativeGraphics, string, length,
625				font ? font->nativeFont : NULL,
626				&layoutRect, NULL,
627				brush ? brush->nativeBrush : NULL));
628	}
629	Status DrawString(const WCHAR *string, INT length,
630			const Font *font, const PointF& origin,
631			const StringFormat *stringFormat, const Brush *brush)
632	{
633		RectF layoutRect(origin.X, origin.Y, 0.0f, 0.0f);
634		return updateStatus(DllExports::GdipDrawString(
635				nativeGraphics, string, length,
636				font ? font->nativeFont : NULL,
637				&layoutRect,
638				stringFormat ? stringFormat->nativeStringFormat : NULL,
639				brush ? brush->nativeBrush : NULL));
640	}
641	Status DrawString(const WCHAR *string, INT length,
642			const Font *font, const RectF& layoutRect,
643			const StringFormat *stringFormat, const Brush *brush)
644	{
645		return updateStatus(DllExports::GdipDrawString(
646				nativeGraphics, string, length,
647				font ? font->nativeFont : NULL,
648				&layoutRect,
649				stringFormat ? stringFormat->nativeStringFormat : NULL,
650				brush ? brush->nativeBrush : NULL));
651	}
652	Status EndContainer(GraphicsContainer state)
653	{
654		return updateStatus(DllExports::GdipEndContainer(
655				nativeGraphics, state));
656	}
657	Status EnumerateMetafile(const Metafile *metafile,
658			const PointF& destPoint,
659			EnumerateMetafileProc callback,
660			VOID *callbackData = NULL,
661			ImageAttributes *imageAttributes = NULL)
662	{
663		return updateStatus(DllExports::GdipEnumerateMetafileDestPoint(
664				nativeGraphics,
665				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
666				destPoint, callback, callbackData,
667				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
668	}
669	Status EnumerateMetafile(const Metafile *metafile,
670			const Point& destPoint,
671			EnumerateMetafileProc callback,
672			VOID *callbackData = NULL,
673			ImageAttributes *imageAttributes = NULL)
674	{
675		return updateStatus(DllExports::GdipEnumerateMetafileDestPointI(
676				nativeGraphics,
677				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
678				destPoint, callback, callbackData,
679				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
680	}
681	Status EnumerateMetafile(const Metafile *metafile,
682			const RectF& destRect,
683			EnumerateMetafileProc callback,
684			VOID *callbackData = NULL,
685			ImageAttributes *imageAttributes = NULL)
686	{
687		return updateStatus(DllExports::GdipEnumerateMetafileDestRect(
688				nativeGraphics,
689				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
690				destRect, callback, callbackData,
691				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
692	}
693	Status EnumerateMetafile(const Metafile *metafile,
694			const Rect& destRect,
695			EnumerateMetafileProc callback,
696			VOID *callbackData = NULL,
697			ImageAttributes *imageAttributes = NULL)
698	{
699		return updateStatus(DllExports::GdipEnumerateMetafileDestRectI(
700				nativeGraphics,
701				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
702				destRect, callback, callbackData,
703				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
704	}
705	Status EnumerateMetafile(const Metafile *metafile,
706			const PointF *destPoints, INT count,
707			EnumerateMetafileProc callback,
708			VOID *callbackData = NULL,
709			ImageAttributes *imageAttributes = NULL)
710	{
711		return updateStatus(DllExports::GdipEnumerateMetafileDestPoints(
712				nativeGraphics,
713				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
714				destPoints, count, callback, callbackData,
715				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
716	}
717	Status EnumerateMetafile(const Metafile *metafile,
718			const Point *destPoints, INT count,
719			EnumerateMetafileProc callback,
720			VOID *callbackData = NULL,
721			ImageAttributes *imageAttributes = NULL)
722	{
723		return updateStatus(DllExports::GdipEnumerateMetafileDestPointsI(
724				nativeGraphics,
725				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
726				destPoints, count, callback, callbackData,
727				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
728	}
729	Status EnumerateMetafile(const Metafile *metafile,
730			const PointF& destPoint,
731			const RectF& srcRect, Unit srcUnit,
732			EnumerateMetafileProc callback,
733			VOID *callbackData = NULL,
734			ImageAttributes *imageAttributes = NULL)
735	{
736		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoint(
737				nativeGraphics,
738				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
739				destPoint, srcRect, srcUnit,
740				callback, callbackData,
741				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
742	}
743	Status EnumerateMetafile(const Metafile *metafile,
744			const Point& destPoint,
745			const Rect& srcRect, Unit srcUnit,
746			EnumerateMetafileProc callback,
747			VOID *callbackData = NULL,
748			ImageAttributes *imageAttributes = NULL)
749	{
750		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointI(
751				nativeGraphics,
752				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
753				destPoint, srcRect, srcUnit,
754				callback, callbackData,
755				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
756	}
757	Status EnumerateMetafile(const Metafile *metafile,
758			const RectF& destRect,
759			const RectF& srcRect, Unit srcUnit,
760			EnumerateMetafileProc callback,
761			VOID *callbackData = NULL,
762			ImageAttributes *imageAttributes = NULL)
763	{
764		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestRect(
765				nativeGraphics,
766				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
767				destRect, srcRect, srcUnit,
768				callback, callbackData,
769				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
770	}
771	Status EnumerateMetafile(const Metafile *metafile,
772			const Rect& destRect,
773			const Rect& srcRect, Unit srcUnit,
774			EnumerateMetafileProc callback,
775			VOID *callbackData = NULL,
776			ImageAttributes *imageAttributes = NULL)
777	{
778		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestRectI(
779				nativeGraphics,
780				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
781				destRect, srcRect, srcUnit,
782				callback, callbackData,
783				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
784	}
785	Status EnumerateMetafile(const Metafile *metafile,
786			const PointF* destPoints, INT count,
787			const RectF& srcRect, Unit srcUnit,
788			EnumerateMetafileProc callback,
789			VOID *callbackData = NULL,
790			ImageAttributes *imageAttributes = NULL)
791	{
792		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoints(
793				nativeGraphics,
794				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
795				destPoints, count, srcRect, srcUnit,
796				callback, callbackData,
797				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
798	}
799	Status EnumerateMetafile(const Metafile *metafile,
800			const Point* destPoints, INT count,
801			const Rect& srcRect, Unit srcUnit,
802			EnumerateMetafileProc callback,
803			VOID *callbackData = NULL,
804			ImageAttributes *imageAttributes = NULL)
805	{
806		return updateStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointsI(
807				nativeGraphics,
808				metafile ? ((GpMetafile*) metafile->nativeImage) : NULL,
809				destPoints, count, srcRect, srcUnit,
810				callback, callbackData,
811				imageAttributes ? imageAttributes->nativeImageAttributes : NULL));
812	}
813	Status ExcludeClip(const RectF& rect)
814	{
815		return updateStatus(DllExports::GdipSetClipRect(
816				nativeGraphics,
817				rect.X, rect.Y, rect.Width, rect.Height,
818				CombineModeExclude));
819	}
820	Status ExcludeClip(const Rect& rect)
821	{
822		return updateStatus(DllExports::GdipSetClipRectI(
823				nativeGraphics,
824				rect.X, rect.Y, rect.Width, rect.Height,
825				CombineModeExclude));
826	}
827	Status ExcludeClip(const Region *region)
828	{
829		return updateStatus(DllExports::GdipSetClipRegion(
830				nativeGraphics,
831				region ? region->nativeRegion : NULL,
832				CombineModeExclude));
833	}
834	Status FillClosedCurve(const Brush *brush,
835			const PointF *points, INT count)
836	{
837		return updateStatus(DllExports::GdipFillClosedCurve(
838				nativeGraphics,
839				brush ? brush->nativeBrush : NULL,
840				points, count));
841	}
842	Status FillClosedCurve(const Brush *brush,
843			const Point *points, INT count)
844	{
845		return updateStatus(DllExports::GdipFillClosedCurveI(
846				nativeGraphics,
847				brush ? brush->nativeBrush : NULL,
848				points, count));
849	}
850	Status FillClosedCurve(const Brush *brush,
851			const PointF *points, INT count,
852			FillMode fillMode, REAL tension = 0.5f)
853	{
854		return updateStatus(DllExports::GdipFillClosedCurve2(
855				nativeGraphics,
856				brush ? brush->nativeBrush : NULL,
857				points, count, tension, fillMode));
858	}
859	Status FillClosedCurve(const Brush *brush,
860			const Point *points, INT count,
861			FillMode fillMode, REAL tension = 0.5f)
862	{
863		return updateStatus(DllExports::GdipFillClosedCurve2I(
864				nativeGraphics,
865				brush ? brush->nativeBrush : NULL,
866				points, count, tension, fillMode));
867	}
868	Status FillEllipse(const Brush *brush,
869			REAL x, REAL y, REAL width, REAL height)
870	{
871		return updateStatus(DllExports::GdipFillEllipse(
872				nativeGraphics,
873				brush ? brush->nativeBrush : NULL,
874				x, y, width, height));
875	}
876	Status FillEllipse(const Brush *brush,
877			INT x, INT y, INT width, INT height)
878	{
879		return updateStatus(DllExports::GdipFillEllipseI(
880				nativeGraphics,
881				brush ? brush->nativeBrush : NULL,
882				x, y, width, height));
883	}
884	Status FillEllipse(const Brush *brush, const RectF& rect)
885	{
886		return updateStatus(DllExports::GdipFillEllipse(
887				nativeGraphics,
888				brush ? brush->nativeBrush : NULL,
889				rect.X, rect.Y, rect.Width, rect.Height));
890	}
891	Status FillEllipse(const Brush *brush, const Rect& rect)
892	{
893		return updateStatus(DllExports::GdipFillEllipseI(
894				nativeGraphics,
895				brush ? brush->nativeBrush : NULL,
896				rect.X, rect.Y, rect.Width, rect.Height));
897	}
898	Status FillPath(const Brush *brush, const GraphicsPath *path)
899	{
900		return updateStatus(DllExports::GdipFillPath(
901				nativeGraphics,
902				brush ? brush->nativeBrush : NULL,
903				path ? path->nativePath : NULL));
904	}
905	Status FillPie(const Brush *brush,
906			REAL x, REAL y, REAL width, REAL height,
907			REAL startAngle, REAL sweepAngle)
908	{
909		return updateStatus(DllExports::GdipFillPie(
910				nativeGraphics,
911				brush ? brush->nativeBrush : NULL,
912				x, y, width, height, startAngle, sweepAngle));
913	}
914	Status FillPie(const Brush *brush, INT x, INT y, INT width, INT height,
915			REAL startAngle, REAL sweepAngle)
916	{
917		return updateStatus(DllExports::GdipFillPieI(
918				nativeGraphics,
919				brush ? brush->nativeBrush : NULL,
920				x, y, width, height, startAngle, sweepAngle));
921	}
922	Status FillPie(const Brush *brush, const RectF& rect,
923			REAL startAngle, REAL sweepAngle)
924	{
925		return updateStatus(DllExports::GdipFillPie(
926				nativeGraphics,
927				brush ? brush->nativeBrush : NULL,
928				rect.X, rect.Y, rect.Width, rect.Height,
929				startAngle, sweepAngle));
930	}
931	Status FillPie(const Brush *brush, const Rect& rect,
932			REAL startAngle, REAL sweepAngle)
933	{
934		return updateStatus(DllExports::GdipFillPieI(
935				nativeGraphics,
936				brush ? brush->nativeBrush : NULL,
937				rect.X, rect.Y, rect.Width, rect.Height,
938				startAngle, sweepAngle));
939	}
940	Status FillPolygon(const Brush *brush, const PointF *points, INT count)
941	{
942		return updateStatus(DllExports::GdipFillPolygon(
943				nativeGraphics,
944				brush ? brush->nativeBrush : NULL,
945				points, count, FillModeAlternate));
946	}
947	Status FillPolygon(const Brush *brush, const Point *points, INT count)
948	{
949		return updateStatus(DllExports::GdipFillPolygonI(
950				nativeGraphics,
951				brush ? brush->nativeBrush : NULL,
952				points, count, FillModeAlternate));
953	}
954	Status FillPolygon(const Brush *brush, const PointF *points, INT count,
955			FillMode fillMode)
956	{
957		return updateStatus(DllExports::GdipFillPolygon(
958				nativeGraphics,
959				brush ? brush->nativeBrush : NULL,
960				points, count, fillMode));
961	}
962	Status FillPolygon(const Brush *brush, const Point *points, INT count,
963			FillMode fillMode)
964	{
965		return updateStatus(DllExports::GdipFillPolygonI(
966				nativeGraphics,
967				brush ? brush->nativeBrush : NULL,
968				points, count, fillMode));
969	}
970	Status FillRectangle(const Brush *brush,
971			REAL x, REAL y, REAL width, REAL height)
972	{
973		return updateStatus(DllExports::GdipFillRectangle(
974				nativeGraphics,
975				brush ? brush->nativeBrush : NULL,
976				x, y, width, height));
977	}
978	Status FillRectangle(const Brush *brush,
979			INT x, INT y, INT width, INT height)
980	{
981		return updateStatus(DllExports::GdipFillRectangleI(
982				nativeGraphics,
983				brush ? brush->nativeBrush : NULL,
984				x, y, width, height));
985	}
986	Status FillRectangle(const Brush *brush, const RectF& rect)
987	{
988		return updateStatus(DllExports::GdipFillRectangle(
989				nativeGraphics,
990				brush ? brush->nativeBrush : NULL,
991				rect.X, rect.Y, rect.Width, rect.Height));
992	}
993	Status FillRectangle(const Brush *brush, const Rect& rect)
994	{
995		return updateStatus(DllExports::GdipFillRectangleI(
996				nativeGraphics,
997				brush ? brush->nativeBrush : NULL,
998				rect.X, rect.Y, rect.Width, rect.Height));
999	}
1000	Status FillRectangles(const Brush *brush, const RectF *rects, INT count)
1001	{
1002		return updateStatus(DllExports::GdipFillRectangles(
1003				nativeGraphics,
1004				brush ? brush->nativeBrush : NULL,
1005				rects, count));
1006	}
1007	Status FillRectangles(const Brush *brush, const Rect *rects, INT count)
1008	{
1009		return updateStatus(DllExports::GdipFillRectanglesI(
1010				nativeGraphics,
1011				brush ? brush->nativeBrush : NULL,
1012				rects, count));
1013	}
1014	Status FillRegion(const Brush *brush, const Region *region)
1015	{
1016		return updateStatus(DllExports::GdipFillRegion(
1017				nativeGraphics,
1018				brush ? brush->nativeBrush : NULL,
1019				region ? region->nativeRegion : NULL));
1020	}
1021	VOID Flush(FlushIntention intention = FlushIntentionFlush)
1022	{
1023		updateStatus(DllExports::GdipFlush(nativeGraphics, intention));
1024	}
1025	Status GetClip(Region *region) const
1026	{
1027		return updateStatus(DllExports::GdipGetClip(
1028				nativeGraphics,
1029				region ? region->nativeRegion : NULL));
1030	}
1031	Status GetClipBounds(RectF *rect) const
1032	{
1033		return updateStatus(DllExports::GdipGetClipBounds(
1034				nativeGraphics, rect));
1035	}
1036	Status GetClipBounds(Rect *rect) const
1037	{
1038		return updateStatus(DllExports::GdipGetClipBoundsI(
1039				nativeGraphics, rect));
1040	}
1041	CompositingMode GetCompositingMode() const
1042	{
1043		CompositingMode result = CompositingModeSourceOver;
1044		updateStatus(DllExports::GdipGetCompositingMode(
1045				nativeGraphics, &result));
1046		return result;
1047	}
1048	CompositingQuality GetCompositingQuality() const
1049	{
1050		CompositingQuality result = CompositingQualityDefault;
1051		updateStatus(DllExports::GdipGetCompositingQuality(
1052				nativeGraphics, &result));
1053		return result;
1054	}
1055	REAL GetDpiX() const
1056	{
1057		REAL result = 0.0f;
1058		updateStatus(DllExports::GdipGetDpiX(nativeGraphics, &result));
1059		return result;
1060	}
1061	REAL GetDpiY() const
1062	{
1063		REAL result = 0.0f;
1064		updateStatus(DllExports::GdipGetDpiY(nativeGraphics, &result));
1065		return result;
1066	}
1067	HDC GetHDC()
1068	{
1069		HDC result = NULL;
1070		updateStatus(DllExports::GdipGetDC(nativeGraphics, &result));
1071		return result;
1072	}
1073	InterpolationMode GetInterpolationMode() const
1074	{
1075		InterpolationMode result = InterpolationModeDefault;
1076		updateStatus(DllExports::GdipGetInterpolationMode(
1077				nativeGraphics, &result));
1078		return result;
1079	}
1080	Status GetLastStatus() const
1081	{
1082		Status result = lastStatus;
1083		lastStatus = Ok;
1084		return result;
1085	}
1086	Status GetNearestColor(Color *color) const
1087	{
1088		return updateStatus(DllExports::GdipGetNearestColor(
1089				nativeGraphics, color ? &color->Value : NULL));
1090	}
1091	REAL GetPageScale() const
1092	{
1093		REAL result = 0.0f;
1094		updateStatus(DllExports::GdipGetPageScale(
1095				nativeGraphics, &result));
1096		return result;
1097	}
1098	Unit GetPageUnit() const
1099	{
1100		Unit result = UnitWorld;
1101		updateStatus(DllExports::GdipGetPageUnit(
1102				nativeGraphics, &result));
1103		return result;
1104	}
1105	PixelOffsetMode GetPixelOffsetMode() const
1106	{
1107		PixelOffsetMode result = PixelOffsetModeDefault;
1108		updateStatus(DllExports::GdipGetPixelOffsetMode(
1109				nativeGraphics, &result));
1110		return result;
1111	}
1112	Status GetRenderingOrigin(INT *x, INT *y) const
1113	{
1114		return updateStatus(DllExports::GdipGetRenderingOrigin(
1115				nativeGraphics, x, y));
1116	}
1117	SmoothingMode GetSmoothingMode() const
1118	{
1119		SmoothingMode result = SmoothingModeDefault;
1120		updateStatus(DllExports::GdipGetSmoothingMode(
1121				nativeGraphics, &result));
1122		return result;
1123	}
1124	UINT GetTextContrast() const
1125	{
1126		UINT result = 0;
1127		updateStatus(DllExports::GdipGetTextContrast(
1128				nativeGraphics, &result));
1129		return result;
1130	}
1131	TextRenderingHint GetTextRenderingHint() const
1132	{
1133		TextRenderingHint result = TextRenderingHintSystemDefault;
1134		updateStatus(DllExports::GdipGetTextRenderingHint(
1135				nativeGraphics, &result));
1136		return result;
1137	}
1138	Status GetTransform(Matrix *matrix) const
1139	{
1140		return updateStatus(DllExports::GdipGetWorldTransform(
1141				nativeGraphics,
1142				matrix ? matrix->nativeMatrix : NULL));
1143	}
1144	Status GetVisibleClipBounds(RectF *rect) const
1145	{
1146		return updateStatus(DllExports::GdipGetVisibleClipBounds(
1147				nativeGraphics, rect));
1148	}
1149	Status GetVisibleClipBounds(Rect *rect) const
1150	{
1151		return updateStatus(DllExports::GdipGetVisibleClipBoundsI(
1152				nativeGraphics, rect));
1153	}
1154	Status IntersectClip(const RectF& rect)
1155	{
1156		return updateStatus(DllExports::GdipSetClipRect(
1157				nativeGraphics,
1158				rect.X, rect.Y, rect.Width, rect.Height,
1159				CombineModeIntersect));
1160	}
1161	Status IntersectClip(const Rect& rect)
1162	{
1163		return updateStatus(DllExports::GdipSetClipRectI(
1164				nativeGraphics,
1165				rect.X, rect.Y, rect.Width, rect.Height,
1166				CombineModeIntersect));
1167	}
1168	Status IntersectClip(const Region *region)
1169	{
1170		return updateStatus(DllExports::GdipSetClipRegion(
1171				nativeGraphics,
1172				region ? region->nativeRegion : NULL,
1173				CombineModeIntersect));
1174	}
1175	BOOL IsClipEmpty() const
1176	{
1177		BOOL result = FALSE;
1178		updateStatus(DllExports::GdipIsClipEmpty(
1179				nativeGraphics, &result));
1180		return result;
1181	}
1182	BOOL IsVisible(REAL x, REAL y) const
1183	{
1184		BOOL result = FALSE;
1185		updateStatus(DllExports::GdipIsVisiblePoint(
1186				nativeGraphics, x, y, &result));
1187		return result;
1188	}
1189	BOOL IsVisible(INT x, INT y) const
1190	{
1191		BOOL result = FALSE;
1192		updateStatus(DllExports::GdipIsVisiblePointI(
1193				nativeGraphics, x, y, &result));
1194		return result;
1195	}
1196	BOOL IsVisible(const PointF& point) const
1197	{
1198		BOOL result = FALSE;
1199		updateStatus(DllExports::GdipIsVisiblePoint(
1200				nativeGraphics, point.X, point.Y, &result));
1201		return result;
1202	}
1203	BOOL IsVisible(const Point& point) const
1204	{
1205		BOOL result = FALSE;
1206		updateStatus(DllExports::GdipIsVisiblePointI(
1207				nativeGraphics, point.X, point.Y, &result));
1208		return result;
1209	}
1210	BOOL IsVisible(REAL x, REAL y, REAL width, REAL height) const
1211	{
1212		BOOL result = FALSE;
1213		updateStatus(DllExports::GdipIsVisibleRect(
1214				nativeGraphics, x, y, width, height, &result));
1215		return result;
1216	}
1217	BOOL IsVisible(INT x, INT y, INT width, INT height) const
1218	{
1219		BOOL result = FALSE;
1220		updateStatus(DllExports::GdipIsVisibleRectI(
1221				nativeGraphics, x, y, width, height, &result));
1222		return result;
1223	}
1224	BOOL IsVisible(const RectF& rect) const
1225	{
1226		BOOL result = FALSE;
1227		updateStatus(DllExports::GdipIsVisibleRect(
1228				nativeGraphics, rect.X, rect.Y,
1229				rect.Width, rect.Height, &result));
1230		return result;
1231	}
1232	BOOL IsVisible(const Rect& rect) const
1233	{
1234		BOOL result = FALSE;
1235		updateStatus(DllExports::GdipIsVisibleRectI(
1236				nativeGraphics, rect.X, rect.Y,
1237				rect.Width, rect.Height, &result));
1238		return result;
1239	}
1240	BOOL IsVisibleClipEmpty() const
1241	{
1242		BOOL result = FALSE;
1243		updateStatus(DllExports::GdipIsVisibleClipEmpty(
1244				nativeGraphics, &result));
1245		return result;
1246	}
1247	Status MeasureCharacterRanges(const WCHAR *string, INT length,
1248			const Font *font, const RectF& layoutRect,
1249			const StringFormat *stringFormat,
1250			INT regionCount, Region *regions) const
1251	{
1252		if (regionCount <= 0 || !regions)
1253			return lastStatus = InvalidParameter;
1254
1255		GpRegion **nativeRegionArray = (GpRegion**)
1256			DllExports::GdipAlloc(regionCount * sizeof(GpRegion*));
1257		if (!nativeRegionArray)
1258			return lastStatus = OutOfMemory;
1259		for (int i = 0; i < regionCount; ++i) {
1260			nativeRegionArray[i] = regions[i].nativeRegion;
1261		}
1262		Status status = updateStatus(DllExports::GdipMeasureCharacterRanges(
1263				nativeGraphics, string, length,
1264				font ? font->nativeFont : NULL,
1265				layoutRect,
1266				stringFormat ? stringFormat->nativeStringFormat : NULL,
1267				regionCount, nativeRegionArray));
1268		DllExports::GdipFree(nativeRegionArray);
1269		return status;
1270	}
1271	Status MeasureDriverString(const UINT16 *text, INT length,
1272			const Font *font, const PointF *positions, INT flags,
1273			const Matrix *matrix, RectF *boundingBox) const
1274	{
1275		return updateStatus(DllExports::GdipMeasureDriverString(
1276				nativeGraphics, text, length,
1277				font ? font->nativeFont : NULL,
1278				positions, flags,
1279				matrix ? matrix->nativeMatrix : NULL,
1280				boundingBox));
1281	}
1282	Status MeasureString(const WCHAR *string, INT length,
1283			const Font *font, const RectF& layoutRect,
1284			RectF *boundingBox) const
1285	{
1286		return updateStatus(DllExports::GdipMeasureString(
1287				nativeGraphics, string, length,
1288				font ? font->nativeFont : NULL,
1289				&layoutRect, NULL, boundingBox, NULL, NULL));
1290	}
1291	Status MeasureString(const WCHAR *string, INT length,
1292			const Font *font, const RectF& layoutRect,
1293			const StringFormat *stringFormat, RectF *boundingBox,
1294			INT *codepointsFitted = NULL,
1295			INT *linesFitted = NULL) const
1296	{
1297		return updateStatus(DllExports::GdipMeasureString(
1298				nativeGraphics, string, length,
1299				font ? font->nativeFont : NULL,
1300				&layoutRect,
1301				stringFormat ? stringFormat->nativeStringFormat : NULL,
1302				boundingBox, codepointsFitted, linesFitted));
1303	}
1304	Status MeasureString(const WCHAR *string, INT length,
1305			const Font *font, const SizeF& layoutRectSize,
1306			const StringFormat *stringFormat, SizeF *size,
1307			INT *codepointsFitted = NULL,
1308			INT *linesFitted = NULL) const
1309	{
1310		if (!size) return lastStatus = InvalidParameter;
1311		RectF layoutRect(PointF(0.0f, 0.0f), layoutRectSize);
1312		RectF boundingBox;
1313		Status status = updateStatus(DllExports::GdipMeasureString(
1314				nativeGraphics, string, length,
1315				font ? font->nativeFont : NULL,
1316				&layoutRect,
1317				stringFormat ? stringFormat->nativeStringFormat : NULL,
1318				&boundingBox, codepointsFitted, linesFitted));
1319		boundingBox.GetSize(size);
1320		return status;
1321	}
1322	Status MeasureString(const WCHAR *string, INT length,
1323			const Font *font, const PointF& origin,
1324			RectF *boundingBox) const
1325	{
1326		RectF layoutRect(origin, SizeF(0.0f, 0.0f));
1327		return updateStatus(DllExports::GdipMeasureString(
1328				nativeGraphics, string, length,
1329				font ? font->nativeFont : NULL,
1330				&layoutRect, NULL, boundingBox, NULL, NULL));
1331	}
1332	Status MeasureString(const WCHAR *string, INT length,
1333			const Font *font, const PointF& origin,
1334			const StringFormat *stringFormat,
1335			RectF *boundingBox) const
1336	{
1337		RectF layoutRect(origin, SizeF(0.0f, 0.0f));
1338		return updateStatus(DllExports::GdipMeasureString(
1339				nativeGraphics, string, length,
1340				font ? font->nativeFont : NULL,
1341				&layoutRect,
1342				stringFormat ? stringFormat->nativeStringFormat : NULL,
1343				boundingBox, NULL, NULL));
1344	}
1345	Status MultiplyTransform(const Matrix *matrix,
1346			MatrixOrder order = MatrixOrderPrepend)
1347	{
1348		return updateStatus(DllExports::GdipMultiplyWorldTransform(
1349				nativeGraphics,
1350				matrix ? matrix->nativeMatrix : NULL, order));
1351	}
1352	VOID ReleaseHDC(HDC hdc)
1353	{
1354		updateStatus(DllExports::GdipReleaseDC(nativeGraphics, hdc));
1355	}
1356	Status ResetClip()
1357	{
1358		return updateStatus(DllExports::GdipResetClip(nativeGraphics));
1359	}
1360	Status ResetTransform()
1361	{
1362		return updateStatus(DllExports::GdipResetWorldTransform(
1363				nativeGraphics));
1364	}
1365	Status Restore(GraphicsState state)
1366	{
1367		return updateStatus(DllExports::GdipRestoreGraphics(
1368				nativeGraphics, state));
1369	}
1370	Status RotateTransform(REAL angle,
1371			MatrixOrder order = MatrixOrderPrepend)
1372	{
1373		return updateStatus(DllExports::GdipRotateWorldTransform(
1374				nativeGraphics, angle, order));
1375	}
1376	GraphicsState Save() const
1377	{
1378		GraphicsState result = 0;
1379		updateStatus(DllExports::GdipSaveGraphics(
1380				nativeGraphics, &result));
1381		return result;
1382	}
1383	Status ScaleTransform(REAL sx, REAL sy,
1384			MatrixOrder order = MatrixOrderPrepend)
1385	{
1386		return updateStatus(DllExports::GdipScaleWorldTransform(
1387				nativeGraphics, sx, sy, order));
1388	}
1389	VOID SetAbort()
1390	{
1391		updateStatus(NotImplemented);
1392	}
1393	Status SetClip(const Graphics *g,
1394			CombineMode combineMode = CombineModeReplace)
1395	{
1396		return updateStatus(DllExports::GdipSetClipGraphics(
1397				nativeGraphics, g ? g->nativeGraphics : NULL,
1398				combineMode));
1399	}
1400	Status SetClip(const RectF& rect,
1401			CombineMode combineMode = CombineModeReplace)
1402	{
1403		return updateStatus(DllExports::GdipSetClipRect(
1404				nativeGraphics,
1405				rect.X, rect.Y, rect.Width, rect.Height,
1406				combineMode));
1407	}
1408	Status SetClip(const Rect& rect,
1409			CombineMode combineMode = CombineModeReplace)
1410	{
1411		return updateStatus(DllExports::GdipSetClipRectI(
1412				nativeGraphics,
1413				rect.X, rect.Y, rect.Width, rect.Height,
1414				combineMode));
1415	}
1416	Status SetClip(const GraphicsPath *path,
1417			CombineMode combineMode = CombineModeReplace)
1418	{
1419		return updateStatus(DllExports::GdipSetClipPath(
1420				nativeGraphics,
1421				path ? path->nativePath : NULL,
1422				combineMode));
1423	}
1424	Status SetClip(const Region *region,
1425			CombineMode combineMode = CombineModeReplace)
1426	{
1427		return updateStatus(DllExports::GdipSetClipRegion(
1428				nativeGraphics,
1429				region ? region->nativeRegion : NULL,
1430				combineMode));
1431	}
1432	Status SetClip(HRGN hRgn, CombineMode combineMode = CombineModeReplace)
1433	{
1434		return updateStatus(DllExports::GdipSetClipHrgn(
1435				nativeGraphics, hRgn, combineMode));
1436	}
1437	Status SetCompositingMode(CompositingMode compositingMode)
1438	{
1439		return updateStatus(DllExports::GdipSetCompositingMode(
1440				nativeGraphics, compositingMode));
1441	}
1442	Status SetCompositingQuality(CompositingQuality compositingQuality)
1443	{
1444		return updateStatus(DllExports::GdipSetCompositingQuality(
1445				nativeGraphics, compositingQuality));
1446	}
1447	Status SetInterpolationMode(InterpolationMode interpolationMode)
1448	{
1449		return updateStatus(DllExports::GdipSetInterpolationMode(
1450				nativeGraphics, interpolationMode));
1451	}
1452	Status SetPageScale(REAL scale)
1453	{
1454		return updateStatus(DllExports::GdipSetPageScale(
1455				nativeGraphics, scale));
1456	}
1457	Status SetPageUnit(Unit unit)
1458	{
1459		return updateStatus(DllExports::GdipSetPageUnit(
1460				nativeGraphics, unit));
1461	}
1462	Status SetPixelOffsetMode(PixelOffsetMode pixelOffsetMode)
1463	{
1464		return updateStatus(DllExports::GdipSetPixelOffsetMode(
1465				nativeGraphics, pixelOffsetMode));
1466	}
1467	Status SetRenderingOrigin(INT x, INT y)
1468	{
1469		return updateStatus(DllExports::GdipSetRenderingOrigin(
1470				nativeGraphics, x, y));
1471	}
1472	Status SetSmoothingMode(SmoothingMode smoothingMode)
1473	{
1474		return updateStatus(DllExports::GdipSetSmoothingMode(
1475				nativeGraphics, smoothingMode));
1476	}
1477	Status SetTextContrast(UINT contrast)
1478	{
1479		return updateStatus(DllExports::GdipSetTextContrast(
1480				nativeGraphics, contrast));
1481	}
1482	Status SetTextRenderingHint(TextRenderingHint textRenderingHint)
1483	{
1484		return updateStatus(DllExports::GdipSetTextRenderingHint(
1485				nativeGraphics, textRenderingHint));
1486	}
1487	Status SetTransform(const Matrix *matrix)
1488	{
1489		return updateStatus(DllExports::GdipSetWorldTransform(
1490				nativeGraphics,
1491				matrix ? matrix->nativeMatrix : NULL));
1492	}
1493	Status TransformPoints(CoordinateSpace destSpace,
1494			CoordinateSpace srcSpace,
1495			PointF *pts, INT count) const
1496	{
1497		return updateStatus(DllExports::GdipTransformPoints(
1498				nativeGraphics, destSpace, srcSpace,
1499				pts, count));
1500	}
1501	Status TransformPoints(CoordinateSpace destSpace,
1502			CoordinateSpace srcSpace,
1503			Point *pts, INT count) const
1504	{
1505		return updateStatus(DllExports::GdipTransformPointsI(
1506				nativeGraphics, destSpace, srcSpace,
1507				pts, count));
1508	}
1509	Status TranslateClip(REAL dx, REAL dy)
1510	{
1511		return updateStatus(DllExports::GdipTranslateClip(
1512				nativeGraphics, dx, dy));
1513	}
1514	Status TranslateClip(INT dx, INT dy)
1515	{
1516		return updateStatus(DllExports::GdipTranslateClipI(
1517				nativeGraphics, dx, dy));
1518	}
1519	Status TranslateTransform(REAL dx, REAL dy,
1520			MatrixOrder order = MatrixOrderPrepend)
1521	{
1522		return updateStatus(DllExports::GdipTranslateWorldTransform(
1523				nativeGraphics, dx, dy, order));
1524	}
1525
1526private:
1527	Graphics(const Graphics&);
1528	Graphics& operator=(const Graphics&);
1529
1530	Status updateStatus(Status newStatus) const
1531	{
1532		if (newStatus != Ok) lastStatus = newStatus;
1533		return newStatus;
1534	}
1535
1536	GpGraphics *nativeGraphics;
1537	mutable Status lastStatus;
1538};
1539
1540#endif /* __GDIPLUS_GRAPHICS_H */
1541