Home | History | Annotate | Download | only in gdiplus
      1 /*
      2  * gdiplusimpl.h
      3  *
      4  * GDI+ Bitmap, CachedBitmap, CustomLineCap, Font, FontCollection, FontFamily,
      5  *      Image, InstalledFontCollection, PrivateFontCollection, Region
      6  *      implementation.  Definitions of these classes are in gdiplusheaders.h.
      7  *
      8  * This file is part of the w32api package.
      9  *
     10  * Contributors:
     11  *   Created by Markus Koenig <markus (at) stber-koenig.de>
     12  *
     13  * THIS SOFTWARE IS NOT COPYRIGHTED
     14  *
     15  * This source code is offered for use in the public domain. You may
     16  * use, modify or distribute it freely.
     17  *
     18  * This code is distributed in the hope that it will be useful but
     19  * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
     20  * DISCLAIMED. This includes but is not limited to warranties of
     21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     22  *
     23  */
     24 
     25 #ifndef __GDIPLUS_IMPL_H
     26 #define __GDIPLUS_IMPL_H
     27 #if __GNUC__ >=3
     28 #pragma GCC system_header
     29 #endif
     30 
     31 #ifndef __cplusplus
     32 #error "A C++ compiler is required to include gdiplusimpl.h."
     33 #endif
     34 
     35 /*
     36  * FIXME: I called this file gdiplusimpl.h, but what should it really be called?
     37  * Or did Microsoft create separate files for each class implemented here?
     38  */
     39 
     40 
     41 // Image
     42 
     43 __inline__ Image* Image::FromFile(const WCHAR *filename,
     44 		BOOL useEmbeddedColorManagement)
     45 {
     46 	return new Image(filename, useEmbeddedColorManagement);
     47 }
     48 
     49 __inline__ Image* Image::FromStream(IStream *stream,
     50 		BOOL useEmbeddedColorManagement)
     51 {
     52 	return new Image(stream, useEmbeddedColorManagement);
     53 }
     54 
     55 __inline__ Image::Image(const WCHAR *filename, BOOL useEmbeddedColorManagement):
     56 	nativeImage(NULL), lastStatus(Ok)
     57 {
     58 	if (useEmbeddedColorManagement) {
     59 		lastStatus = DllExports::GdipLoadImageFromFileICM(
     60 				filename, &nativeImage);
     61 	} else {
     62 		lastStatus = DllExports::GdipLoadImageFromFile(
     63 				filename, &nativeImage);
     64 	}
     65 }
     66 
     67 __inline__ Image::Image(IStream *stream, BOOL useEmbeddedColorManagement):
     68 	nativeImage(NULL), lastStatus(Ok)
     69 {
     70 	if (useEmbeddedColorManagement) {
     71 		lastStatus = DllExports::GdipLoadImageFromStreamICM(
     72 				stream, &nativeImage);
     73 	} else {
     74 		lastStatus = DllExports::GdipLoadImageFromStream(
     75 				stream, &nativeImage);
     76 	}
     77 }
     78 
     79 __inline__ Status Image::FindFirstItem(ImageItemData *item)
     80 {
     81 	// FIXME: can't test GdipFindFirstImageItem b/c it isn't exported in 1.0
     82 	return updateStatus(DllExports::GdipFindFirstImageItem(
     83 			nativeImage, item));
     84 }
     85 
     86 __inline__ Status Image::FindNextItem(ImageItemData *item)
     87 {
     88 	// FIXME: can't test GdipFindFirstImageItem b/c it isn't exported in 1.0
     89 	return updateStatus(DllExports::GdipFindNextImageItem(
     90 			nativeImage, item));
     91 }
     92 
     93 __inline__ Status Image::GetAllPropertyItems(UINT totalBufferSize,
     94 		UINT numProperties, PropertyItem *allItems)
     95 {
     96 	return updateStatus(DllExports::GdipGetAllPropertyItems(
     97 			nativeImage, totalBufferSize, numProperties, allItems));
     98 }
     99 
    100 __inline__ Status Image::GetBounds(RectF *srcRect, Unit *srcUnit)
    101 {
    102 	return updateStatus(DllExports::GdipGetImageBounds(
    103 			nativeImage, srcRect, srcUnit));
    104 }
    105 
    106 __inline__ Status Image::GetEncoderParameterList(const CLSID *clsidEncoder,
    107 		UINT size, EncoderParameters *buffer)
    108 {
    109 	return updateStatus(DllExports::GdipGetEncoderParameterList(
    110 			nativeImage, clsidEncoder, size, buffer));
    111 }
    112 
    113 __inline__ UINT Image::GetEncoderParameterListSize(const CLSID *clsidEncoder)
    114 {
    115 	UINT result = 0;
    116 	updateStatus(DllExports::GdipGetEncoderParameterListSize(
    117 			nativeImage, clsidEncoder, &result));
    118 	return result;
    119 }
    120 
    121 __inline__ UINT Image::GetFlags()
    122 {
    123 	UINT result = 0;
    124 	updateStatus(DllExports::GdipGetImageFlags(nativeImage, &result));
    125 	return result;
    126 }
    127 
    128 __inline__ UINT Image::GetFrameCount(const GUID *dimensionID)
    129 {
    130 	UINT result = 0;
    131 	updateStatus(DllExports::GdipImageGetFrameCount(
    132 			nativeImage, dimensionID, &result));
    133 	return result;
    134 }
    135 
    136 __inline__ UINT Image::GetFrameDimensionsCount()
    137 {
    138 	UINT result = 0;
    139 	updateStatus(DllExports::GdipImageGetFrameDimensionsCount(
    140 			nativeImage, &result));
    141 	return result;
    142 }
    143 
    144 __inline__ Status Image::GetFrameDimensionsList(GUID *dimensionIDs, UINT count)
    145 {
    146 	return updateStatus(DllExports::GdipImageGetFrameDimensionsList(
    147 			nativeImage, dimensionIDs, count));
    148 }
    149 
    150 __inline__ UINT Image::GetHeight()
    151 {
    152 	UINT result = 0;
    153 	updateStatus(DllExports::GdipGetImageHeight(nativeImage, &result));
    154 	return result;
    155 }
    156 
    157 __inline__ REAL Image::GetHorizontalResolution()
    158 {
    159 	REAL result = 0.0f;
    160 	updateStatus(DllExports::GdipGetImageHorizontalResolution(
    161 			nativeImage, &result));
    162 	return result;
    163 }
    164 
    165 __inline__ Status Image::GetItemData(ImageItemData *item)
    166 {
    167 	// FIXME: can't test GdipGetImageItemData b/c it isn't exported in 1.0
    168 	return updateStatus(DllExports::GdipGetImageItemData(
    169 			nativeImage, item));
    170 }
    171 
    172 __inline__ Status Image::GetPalette(ColorPalette *palette, INT size)
    173 {
    174 	return updateStatus(DllExports::GdipGetImagePalette(
    175 			nativeImage, palette, size));
    176 }
    177 
    178 __inline__ INT Image::GetPaletteSize()
    179 {
    180 	INT result = 0;
    181 	updateStatus(DllExports::GdipGetImagePaletteSize(nativeImage, &result));
    182 	return result;
    183 }
    184 
    185 __inline__ Status Image::GetPhysicalDimension(SizeF *size)
    186 {
    187 	if (!size) return lastStatus = InvalidParameter;
    188 	return updateStatus(DllExports::GdipGetImageDimension(
    189 			nativeImage, &size->Width, &size->Height));
    190 }
    191 
    192 __inline__ PixelFormat Image::GetPixelFormat()
    193 {
    194 	PixelFormat result = (PixelFormat) 0;
    195 	updateStatus(DllExports::GdipGetImagePixelFormat(nativeImage, &result));
    196 	return result;
    197 }
    198 
    199 __inline__ UINT Image::GetPropertyCount()
    200 {
    201 	UINT result = 0;
    202 	updateStatus(DllExports::GdipGetPropertyCount(nativeImage, &result));
    203 	return result;
    204 }
    205 
    206 __inline__ Status Image::GetPropertyIdList(UINT numOfProperty, PROPID *list)
    207 {
    208 	return updateStatus(DllExports::GdipGetPropertyIdList(
    209 			nativeImage, numOfProperty, list));
    210 }
    211 
    212 __inline__ Status Image::GetPropertyItem(PROPID propId, UINT propSize,
    213 		PropertyItem *buffer)
    214 {
    215 	return updateStatus(DllExports::GdipGetPropertyItem(
    216 			nativeImage, propId, propSize, buffer));
    217 }
    218 
    219 __inline__ UINT Image::GetPropertyItemSize(PROPID propId)
    220 {
    221 	UINT result = 0;
    222 	updateStatus(DllExports::GdipGetPropertyItemSize(
    223 			nativeImage, propId, &result));
    224 	return result;
    225 }
    226 
    227 __inline__ Status Image::GetPropertySize(
    228 		UINT *totalBufferSize, UINT *numProperties)
    229 {
    230 	return updateStatus(DllExports::GdipGetPropertySize(
    231 			nativeImage, totalBufferSize, numProperties));
    232 }
    233 
    234 __inline__ Status Image::GetRawFormat(GUID *format)
    235 {
    236 	return updateStatus(DllExports::GdipGetImageRawFormat(
    237 			nativeImage, format));
    238 }
    239 
    240 __inline__ Image* Image::GetThumbnailImage(UINT thumbWidth, UINT thumbHeight,
    241 		GetThumbnailImageAbort callback, VOID *callbackData)
    242 {
    243 	GpImage *thumbImage = NULL;
    244 	Status status = updateStatus(DllExports::GdipGetImageThumbnail(
    245 			nativeImage, thumbWidth, thumbHeight, &thumbImage,
    246 			callback, callbackData));
    247 
    248 	if (status == Ok) {
    249 		Image *result = new Image(thumbImage, Ok);
    250 		if (!result) {
    251 			DllExports::GdipDisposeImage(thumbImage);
    252 			lastStatus = OutOfMemory;
    253 		}
    254 		return result;
    255 	} else {
    256 		return NULL;
    257 	}
    258 }
    259 
    260 __inline__ ImageType Image::GetType() const
    261 {
    262 	ImageType result = ImageTypeUnknown;
    263 	updateStatus(DllExports::GdipGetImageType(nativeImage, &result));
    264 	return result;
    265 }
    266 
    267 __inline__ REAL Image::GetVerticalResolution()
    268 {
    269 	REAL result = 0.0f;
    270 	updateStatus(DllExports::GdipGetImageVerticalResolution(
    271 			nativeImage, &result));
    272 	return result;
    273 }
    274 
    275 __inline__ UINT Image::GetWidth()
    276 {
    277 	UINT result = 0;
    278 	updateStatus(DllExports::GdipGetImageWidth(nativeImage, &result));
    279 	return result;
    280 }
    281 
    282 __inline__ Status Image::RemovePropertyItem(PROPID propId)
    283 {
    284 	return updateStatus(DllExports::GdipRemovePropertyItem(
    285 			nativeImage, propId));
    286 }
    287 
    288 __inline__ Status Image::RotateFlip(RotateFlipType rotateFlipType)
    289 {
    290 	return updateStatus(DllExports::GdipImageRotateFlip(
    291 			nativeImage, rotateFlipType));
    292 }
    293 
    294 __inline__ Status Image::Save(const WCHAR *filename, const CLSID *clsidEncoder,
    295 		const EncoderParameters *encoderParams)
    296 {
    297 	return updateStatus(DllExports::GdipSaveImageToFile(
    298 			nativeImage, filename, clsidEncoder, encoderParams));
    299 }
    300 
    301 __inline__ Status Image::Save(IStream *stream, const CLSID *clsidEncoder,
    302 		const EncoderParameters *encoderParams)
    303 {
    304 	return updateStatus(DllExports::GdipSaveImageToStream(
    305 			nativeImage, stream, clsidEncoder, encoderParams));
    306 }
    307 
    308 __inline__ Status Image::SaveAdd(const EncoderParameters *encoderParams)
    309 {
    310 	return updateStatus(DllExports::GdipSaveAdd(
    311 			nativeImage, encoderParams));
    312 }
    313 
    314 __inline__ Status Image::SaveAdd(Image *newImage,
    315 		const EncoderParameters *encoderParams)
    316 {
    317 	return updateStatus(DllExports::GdipSaveAddImage(
    318 			nativeImage,
    319 			newImage ? newImage->nativeImage : NULL,
    320 			encoderParams));
    321 }
    322 
    323 __inline__ Status Image::SelectActiveFrame(
    324 		const GUID *dimensionID, UINT frameIndex)
    325 {
    326 	return updateStatus(DllExports::GdipImageSelectActiveFrame(
    327 			nativeImage, dimensionID, frameIndex));
    328 }
    329 
    330 __inline__ Status Image::SetAbort(GdiplusAbort *pIAbort)
    331 {
    332 	// FIXME: can't test GdipImageSetAbort because it isn't exported in 1.0
    333 	return updateStatus(DllExports::GdipImageSetAbort(
    334 			nativeImage, pIAbort));
    335 }
    336 
    337 __inline__ Status Image::SetPalette(const ColorPalette *palette)
    338 {
    339 	return updateStatus(DllExports::GdipSetImagePalette(
    340 			nativeImage, palette));
    341 }
    342 
    343 __inline__ Status Image::SetPropertyItem(const PropertyItem *item)
    344 {
    345 	return updateStatus(DllExports::GdipSetPropertyItem(nativeImage, item));
    346 }
    347 
    348 
    349 // Bitmap
    350 
    351 __inline__ Bitmap* Bitmap::FromBITMAPINFO(const BITMAPINFO *gdiBitmapInfo,
    352 		VOID *gdiBitmapData)
    353 {
    354 	return new Bitmap(gdiBitmapInfo, gdiBitmapData);
    355 }
    356 
    357 __inline__ Bitmap* Bitmap::FromDirectDrawSurface7(IDirectDrawSurface7 *surface)
    358 {
    359 	return new Bitmap(surface);
    360 }
    361 
    362 __inline__ Bitmap* Bitmap::FromFile(const WCHAR *filename,
    363 		BOOL useEmbeddedColorManagement)
    364 {
    365 	return new Bitmap(filename, useEmbeddedColorManagement);
    366 }
    367 
    368 __inline__ Bitmap* Bitmap::FromHBITMAP(HBITMAP hbm, HPALETTE hpal)
    369 {
    370 	return new Bitmap(hbm, hpal);
    371 }
    372 
    373 __inline__ Bitmap* Bitmap::FromHICON(HICON icon)
    374 {
    375 	return new Bitmap(icon);
    376 }
    377 
    378 __inline__ Bitmap* Bitmap::FromResource(
    379 		HINSTANCE hInstance, const WCHAR *bitmapName)
    380 {
    381 	return new Bitmap(hInstance, bitmapName);
    382 }
    383 
    384 __inline__ Bitmap* Bitmap::FromStream(IStream *stream,
    385 		BOOL useEmbeddedColorManagement)
    386 {
    387 	return new Bitmap(stream, useEmbeddedColorManagement);
    388 }
    389 
    390 //TODO: [GDI+ 1.1] Bitmap::ApplyEffect
    391 //__inline__ Status Bitmap::ApplyEffect(Bitmap **inputs, INT numInputs,
    392 //		Effect *effect, RECT *ROI, RECT *outputRect, Bitmap **output)
    393 //{
    394 //	return NotImplemented;
    395 //}
    396 
    397 __inline__ Status Bitmap::InitializePalette(ColorPalette *palette,
    398 		PaletteType paletteType, INT optimalColors,
    399 		BOOL useTransparentColor, Bitmap *bitmap)
    400 {
    401 	// FIXME: can't test GdipInitializePalette b/c it isn't exported in 1.0
    402 	return DllExports::GdipInitializePalette(palette, paletteType,
    403 			optimalColors, useTransparentColor,
    404 			bitmap ? (GpBitmap*) bitmap->nativeImage : NULL);
    405 }
    406 
    407 __inline__ Bitmap::Bitmap(const BITMAPINFO *gdiBitmapInfo, VOID *gdiBitmapData):
    408 	Image(NULL, Ok)
    409 {
    410 	GpBitmap *nativeBitmap = NULL;
    411 	lastStatus = DllExports::GdipCreateBitmapFromGdiDib(
    412 			gdiBitmapInfo, gdiBitmapData, &nativeBitmap);
    413 	nativeImage = nativeBitmap;
    414 }
    415 
    416 __inline__ Bitmap::Bitmap(IDirectDrawSurface7 *surface): Image(NULL, Ok)
    417 {
    418 	GpBitmap *nativeBitmap = NULL;
    419 	lastStatus = DllExports::GdipCreateBitmapFromDirectDrawSurface(
    420 			surface, &nativeBitmap);
    421 	nativeImage = nativeBitmap;
    422 }
    423 
    424 __inline__ Bitmap::Bitmap(const WCHAR *filename,
    425 		BOOL useEmbeddedColorManagement): Image(NULL, Ok)
    426 {
    427 	GpBitmap *nativeBitmap = NULL;
    428 	if (useEmbeddedColorManagement) {
    429 		lastStatus = DllExports::GdipCreateBitmapFromFileICM(
    430 				filename, &nativeBitmap);
    431 	} else {
    432 		lastStatus = DllExports::GdipCreateBitmapFromFile(
    433 				filename, &nativeBitmap);
    434 	}
    435 	nativeImage = nativeBitmap;
    436 }
    437 
    438 __inline__ Bitmap::Bitmap(HBITMAP hbm, HPALETTE hpal):
    439 	Image(NULL, Ok)
    440 {
    441 	GpBitmap *nativeBitmap = NULL;
    442 	lastStatus = DllExports::GdipCreateBitmapFromHBITMAP(
    443 			hbm, hpal, &nativeBitmap);
    444 	nativeImage = nativeBitmap;
    445 }
    446 
    447 __inline__ Bitmap::Bitmap(HICON hicon):
    448 	Image(NULL, Ok)
    449 {
    450 	GpBitmap *nativeBitmap = NULL;
    451 	lastStatus = DllExports::GdipCreateBitmapFromHICON(hicon, &nativeBitmap);
    452 	nativeImage = nativeBitmap;
    453 }
    454 
    455 __inline__ Bitmap::Bitmap(HINSTANCE hInstance, const WCHAR *bitmapName):
    456 	Image(NULL, Ok)
    457 {
    458 	GpBitmap *nativeBitmap = NULL;
    459 	lastStatus = DllExports::GdipCreateBitmapFromResource(
    460 			hInstance, bitmapName, &nativeBitmap);
    461 	nativeImage = nativeBitmap;
    462 }
    463 
    464 __inline__ Bitmap::Bitmap(IStream *stream, BOOL useEmbeddedColorManagement):
    465 	Image(NULL, Ok)
    466 {
    467 	GpBitmap *nativeBitmap = NULL;
    468 	if (useEmbeddedColorManagement) {
    469 		lastStatus = DllExports::GdipCreateBitmapFromStreamICM(
    470 				stream, &nativeBitmap);
    471 	} else {
    472 		lastStatus = DllExports::GdipCreateBitmapFromStream(
    473 				stream, &nativeBitmap);
    474 	}
    475 	nativeImage = nativeBitmap;
    476 }
    477 
    478 __inline__ Bitmap::Bitmap(INT width, INT height, Graphics *target):
    479 	Image(NULL, Ok)
    480 {
    481 	GpBitmap *nativeBitmap = NULL;
    482 	lastStatus = DllExports::GdipCreateBitmapFromGraphics(
    483 			width, height, target ? target->nativeGraphics : NULL,
    484 			&nativeBitmap);
    485 	nativeImage = nativeBitmap;
    486 }
    487 
    488 __inline__ Bitmap::Bitmap(INT width, INT height, PixelFormat format):
    489 	Image(NULL, Ok)
    490 {
    491 	GpBitmap *nativeBitmap = NULL;
    492 	lastStatus = DllExports::GdipCreateBitmapFromScan0(
    493 			width, height, 0, format, NULL, &nativeBitmap);
    494 	nativeImage = nativeBitmap;
    495 }
    496 
    497 __inline__ Bitmap::Bitmap(INT width, INT height, INT stride,
    498 		PixelFormat format, BYTE *scan0): Image(NULL, Ok)
    499 {
    500 	GpBitmap *nativeBitmap = NULL;
    501 	lastStatus = DllExports::GdipCreateBitmapFromScan0(
    502 			width, height, stride, format, scan0, &nativeBitmap);
    503 	nativeImage = nativeBitmap;
    504 }
    505 
    506 __inline__ Bitmap* Bitmap::Clone(const RectF& rect, PixelFormat format) const
    507 {
    508 	return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
    509 }
    510 
    511 __inline__ Bitmap* Bitmap::Clone(const Rect& rect, PixelFormat format) const
    512 {
    513 	return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
    514 }
    515 
    516 __inline__ Bitmap* Bitmap::Clone(REAL x, REAL y, REAL width, REAL height,
    517 		PixelFormat format) const
    518 {
    519 	GpBitmap *cloneBitmap = NULL;
    520 	Status status = updateStatus(DllExports::GdipCloneBitmapArea(
    521 			x, y, width, height, format,
    522 			(GpBitmap*) nativeImage, &cloneBitmap));
    523 	if (status == Ok) {
    524 		Bitmap *result = new Bitmap(cloneBitmap, lastStatus);
    525 		if (!result) {
    526 			DllExports::GdipDisposeImage(cloneBitmap);
    527 			lastStatus = OutOfMemory;
    528 		}
    529 		return result;
    530 	} else {
    531 		return NULL;
    532 	}
    533 }
    534 
    535 __inline__ Bitmap* Bitmap::Clone(INT x, INT y, INT width, INT height,
    536 		PixelFormat format) const
    537 {
    538 	GpBitmap *cloneBitmap = NULL;
    539 	Status status = updateStatus(DllExports::GdipCloneBitmapAreaI(
    540 			x, y, width, height, format,
    541 			(GpBitmap*) nativeImage, &cloneBitmap));
    542 	if (status == Ok) {
    543 		Bitmap *result = new Bitmap(cloneBitmap, lastStatus);
    544 		if (!result) {
    545 			DllExports::GdipDisposeImage(cloneBitmap);
    546 			lastStatus = OutOfMemory;
    547 		}
    548 		return result;
    549 	} else {
    550 		return NULL;
    551 	}
    552 }
    553 
    554 //TODO: [GDI+ 1.1] Bitmap::ApplyEffect
    555 //__inline__ Status Bitmap::ApplyEffect(Effect *effect, RECT *ROI)
    556 //{
    557 //	return NotImplemented;
    558 //}
    559 
    560 __inline__ Status Bitmap::ConvertFormat(PixelFormat format,
    561 		DitherType ditherType, PaletteType paletteType,
    562 		ColorPalette *palette, REAL alphaThresholdPercent)
    563 {
    564 	// FIXME: can't test GdipBitmapConvertFormat b/c it isn't exported in 1.0
    565 	return updateStatus(DllExports::GdipBitmapConvertFormat(
    566 			(GpBitmap*) nativeImage, format, ditherType,
    567 			paletteType, palette, alphaThresholdPercent));
    568 }
    569 
    570 __inline__ Status Bitmap::GetHBITMAP(
    571 		const Color& colorBackground, HBITMAP *hbmReturn) const
    572 {
    573 	return updateStatus(DllExports::GdipCreateHBITMAPFromBitmap(
    574 			(GpBitmap*) nativeImage, hbmReturn,
    575 			colorBackground.GetValue()));
    576 }
    577 
    578 __inline__ Status Bitmap::GetHICON(HICON *icon) const
    579 {
    580 	return updateStatus(DllExports::GdipCreateHICONFromBitmap(
    581 			(GpBitmap*) nativeImage, icon));
    582 }
    583 
    584 __inline__ Status Bitmap::GetHistogram(HistogramFormat format,
    585 		UINT numberOfEntries,
    586 		UINT *channel0, UINT *channel1,
    587 		UINT *channel2, UINT *channel3) const
    588 {
    589 	return updateStatus(DllExports::GdipBitmapGetHistogram(
    590 			(GpBitmap*) nativeImage, format, numberOfEntries,
    591 			channel0, channel1, channel2, channel3));
    592 }
    593 
    594 __inline__ Status Bitmap::GetHistogramSize(HistogramFormat format,
    595 		UINT *numberOfEntries) const
    596 {
    597 	return updateStatus(DllExports::GdipBitmapGetHistogramSize(
    598 			format, numberOfEntries));
    599 }
    600 
    601 __inline__ Status Bitmap::GetPixel(INT x, INT y, Color *color) const
    602 {
    603 	return updateStatus(DllExports::GdipBitmapGetPixel(
    604 			(GpBitmap*) nativeImage, x, y,
    605 			color ? &color->Value : NULL));
    606 }
    607 
    608 __inline__ Status Bitmap::LockBits(const Rect *rect, UINT flags,
    609 		PixelFormat format, BitmapData *lockedBitmapData)
    610 {
    611 	return updateStatus(DllExports::GdipBitmapLockBits(
    612 			(GpBitmap*) nativeImage, rect, flags, format,
    613 			lockedBitmapData));
    614 }
    615 
    616 __inline__ Status Bitmap::SetPixel(INT x, INT y, const Color& color)
    617 {
    618 	return updateStatus(DllExports::GdipBitmapSetPixel(
    619 			(GpBitmap*) nativeImage, x, y, color.GetValue()));
    620 }
    621 
    622 __inline__ Status Bitmap::SetResolution(REAL xdpi, REAL ydpi)
    623 {
    624 	return updateStatus(DllExports::GdipBitmapSetResolution(
    625 			(GpBitmap*) nativeImage, xdpi, ydpi));
    626 }
    627 
    628 __inline__ Status Bitmap::UnlockBits(BitmapData *lockedBitmapData)
    629 {
    630 	return updateStatus(DllExports::GdipBitmapUnlockBits(
    631 			(GpBitmap*) nativeImage, lockedBitmapData));
    632 }
    633 
    634 
    635 // CachedBitmap
    636 
    637 __inline__ CachedBitmap::CachedBitmap(Bitmap *bitmap, Graphics *graphics):
    638 	nativeCachedBitmap(NULL), lastStatus(Ok)
    639 {
    640 	lastStatus = DllExports::GdipCreateCachedBitmap(
    641 			bitmap ? ((GpBitmap*) bitmap->nativeImage) : NULL,
    642 			graphics ? graphics->nativeGraphics : NULL,
    643 			&nativeCachedBitmap);
    644 }
    645 
    646 __inline__ CachedBitmap::~CachedBitmap()
    647 {
    648 	DllExports::GdipDeleteCachedBitmap(nativeCachedBitmap);
    649 }
    650 
    651 
    652 // CustomLineCap
    653 
    654 __inline__ CustomLineCap::CustomLineCap(
    655 		const GraphicsPath *fillPath,
    656 		const GraphicsPath *strokePath,
    657 		LineCap baseCap, REAL baseInset):
    658 		nativeCustomLineCap(NULL), lastStatus(Ok)
    659 {
    660 	lastStatus = DllExports::GdipCreateCustomLineCap(
    661 			fillPath ? fillPath->nativePath : NULL,
    662 			strokePath ? strokePath->nativePath : NULL,
    663 			baseCap, baseInset, &nativeCustomLineCap);
    664 }
    665 
    666 __inline__ LineCap CustomLineCap::GetBaseCap() const
    667 {
    668 	LineCap result = LineCapFlat;
    669 	updateStatus(DllExports::GdipGetCustomLineCapBaseCap(
    670 			nativeCustomLineCap, &result));
    671 	return result;
    672 }
    673 
    674 __inline__ REAL CustomLineCap::GetBaseInset() const
    675 {
    676 	REAL result = 0.0f;
    677 	updateStatus(DllExports::GdipGetCustomLineCapBaseInset(
    678 			nativeCustomLineCap, &result));
    679 	return result;
    680 }
    681 
    682 __inline__ Status CustomLineCap::GetStrokeCaps(LineCap *startCap,
    683 		LineCap *endCap) const
    684 {
    685 	return updateStatus(DllExports::GdipGetCustomLineCapStrokeCaps(
    686 			nativeCustomLineCap, startCap, endCap));
    687 }
    688 
    689 __inline__ LineJoin CustomLineCap::GetStrokeJoin() const
    690 {
    691 	LineJoin result = LineJoinMiter;
    692 	updateStatus(DllExports::GdipGetCustomLineCapStrokeJoin(
    693 			nativeCustomLineCap, &result));
    694 	return result;
    695 }
    696 
    697 __inline__ REAL CustomLineCap::GetWidthScale() const
    698 {
    699 	REAL result = 0.0f;
    700 	updateStatus(DllExports::GdipGetCustomLineCapWidthScale(
    701 			nativeCustomLineCap, &result));
    702 	return result;
    703 }
    704 
    705 __inline__ Status CustomLineCap::SetBaseCap(LineCap baseCap)
    706 {
    707 	return updateStatus(DllExports::GdipSetCustomLineCapBaseCap(
    708 			nativeCustomLineCap, baseCap));
    709 }
    710 
    711 __inline__ Status CustomLineCap::SetBaseInset(REAL inset)
    712 {
    713 	return updateStatus(DllExports::GdipSetCustomLineCapBaseInset(
    714 			nativeCustomLineCap, inset));
    715 }
    716 
    717 __inline__ Status CustomLineCap::SetStrokeCap(LineCap strokeCap)
    718 {
    719 	return updateStatus(DllExports::GdipSetCustomLineCapStrokeCaps(
    720 			nativeCustomLineCap, strokeCap, strokeCap));
    721 }
    722 
    723 __inline__ Status CustomLineCap::SetStrokeCaps(LineCap startCap, LineCap endCap)
    724 {
    725 	return updateStatus(DllExports::GdipSetCustomLineCapStrokeCaps(
    726 			nativeCustomLineCap, startCap, endCap));
    727 }
    728 
    729 __inline__ Status CustomLineCap::SetStrokeJoin(LineJoin lineJoin)
    730 {
    731 	return updateStatus(DllExports::GdipSetCustomLineCapStrokeJoin(
    732 			nativeCustomLineCap, lineJoin));
    733 }
    734 
    735 __inline__ Status CustomLineCap::SetWidthScale(REAL widthScale)
    736 {
    737 	return updateStatus(DllExports::GdipSetCustomLineCapWidthScale(
    738 			nativeCustomLineCap, widthScale));
    739 }
    740 
    741 
    742 // Font
    743 
    744 __inline__ Font::Font(const FontFamily *family,
    745 		REAL emSize, INT style, Unit unit):
    746 		nativeFont(NULL), lastStatus(Ok)
    747 {
    748 	lastStatus = DllExports::GdipCreateFont(
    749 			family ? family->nativeFontFamily : NULL,
    750 			emSize, style, unit, &nativeFont);
    751 }
    752 
    753 __inline__ Font::Font(HDC hdc, HFONT hfont):
    754 	nativeFont(NULL), lastStatus(Ok)
    755 {
    756 	LOGFONTW logfont;
    757 	if (GetObject(hfont, sizeof logfont, &logfont)) {
    758 		lastStatus = DllExports::GdipCreateFontFromLogfontW(
    759 				hdc, &logfont, &nativeFont);
    760 	} else {
    761 		lastStatus = DllExports::GdipCreateFontFromDC(
    762 				hdc, &nativeFont);
    763 	}
    764 }
    765 
    766 __inline__ Font::Font(HDC hdc, const LOGFONTA *logfont):
    767 	nativeFont(NULL), lastStatus(Ok)
    768 {
    769 	lastStatus = DllExports::GdipCreateFontFromLogfontA(
    770 			hdc, logfont, &nativeFont);
    771 }
    772 
    773 __inline__ Font::Font(HDC hdc, const LOGFONTW *logfont):
    774 	nativeFont(NULL), lastStatus(Ok)
    775 {
    776 	lastStatus = DllExports::GdipCreateFontFromLogfontW(
    777 			hdc, logfont, &nativeFont);
    778 }
    779 
    780 __inline__ Font::Font(HDC hdc):
    781 	nativeFont(NULL), lastStatus(Ok)
    782 {
    783 	lastStatus = DllExports::GdipCreateFontFromDC(hdc, &nativeFont);
    784 }
    785 
    786 __inline__ Font::Font(const WCHAR *familyName, REAL emSize, INT style,
    787 		Unit unit, const FontCollection *fontCollection):
    788 		nativeFont(NULL), lastStatus(Ok)
    789 {
    790 	GpFontFamily *nativeFamily = NULL;
    791 	lastStatus = DllExports::GdipCreateFontFamilyFromName(
    792 			familyName,
    793 			fontCollection ? fontCollection->nativeFontCollection : NULL,
    794 			&nativeFamily);
    795 
    796 	if (nativeFamily) {
    797 		lastStatus = DllExports::GdipCreateFont(
    798 				nativeFamily, emSize, style, unit, &nativeFont);
    799 		DllExports::GdipDeleteFontFamily(nativeFamily);
    800 	}
    801 }
    802 
    803 __inline__ Font::~Font()
    804 {
    805 	DllExports::GdipDeleteFont(nativeFont);
    806 }
    807 
    808 __inline__ Font* Font::Clone() const
    809 {
    810 	GpFont *cloneFont = NULL;
    811 	Status status = updateStatus(DllExports::GdipCloneFont(
    812 			nativeFont, &cloneFont));
    813 	if (status == Ok) {
    814 		Font *result = new Font(cloneFont, lastStatus);
    815 		if (!result) {
    816 			DllExports::GdipDeleteFont(cloneFont);
    817 			lastStatus = OutOfMemory;
    818 		}
    819 		return result;
    820 	} else {
    821 		return NULL;
    822 	}
    823 }
    824 
    825 __inline__ Status Font::GetFamily(FontFamily *family) const
    826 {
    827 	if (!family) return lastStatus = InvalidParameter;
    828 	// FIXME: do we need to call GdipDeleteFontFamily first?
    829 	return family->lastStatus = updateStatus(DllExports::GdipGetFamily(
    830 			nativeFont, &family->nativeFontFamily));
    831 }
    832 
    833 __inline__ REAL Font::GetHeight(const Graphics *graphics) const
    834 {
    835 	REAL result = 0.0f;
    836 	updateStatus(DllExports::GdipGetFontHeight(
    837 			nativeFont, graphics ? graphics->nativeGraphics : NULL,
    838 			&result));
    839 	return result;
    840 }
    841 
    842 __inline__ REAL Font::GetHeight(REAL dpi) const
    843 {
    844 	REAL result = 0.0f;
    845 	updateStatus(DllExports::GdipGetFontHeightGivenDPI(
    846 			nativeFont, dpi, &result));
    847 	return result;
    848 }
    849 
    850 __inline__ Status Font::GetLogFontA(const Graphics *graphics, LOGFONTA *logfontA)
    851 const
    852 {
    853 	return updateStatus(DllExports::GdipGetLogFontA(
    854 			nativeFont, graphics ? graphics->nativeGraphics : NULL,
    855 			logfontA));
    856 }
    857 
    858 __inline__ Status Font::GetLogFontW(const Graphics *graphics, LOGFONTW *logfontW)
    859 const
    860 {
    861 	return updateStatus(DllExports::GdipGetLogFontW(
    862 			nativeFont, graphics ? graphics->nativeGraphics : NULL,
    863 			logfontW));
    864 }
    865 
    866 __inline__ REAL Font::GetSize() const
    867 {
    868 	REAL result = 0.0;
    869 	updateStatus(DllExports::GdipGetFontSize(nativeFont, &result));
    870 	return result;
    871 }
    872 
    873 __inline__ INT Font::GetStyle() const
    874 {
    875 	INT result = FontStyleRegular;
    876 	updateStatus(DllExports::GdipGetFontStyle(nativeFont, &result));
    877 	return result;
    878 }
    879 
    880 __inline__ Unit Font::GetUnit() const
    881 {
    882 	Unit result = UnitPoint;
    883 	updateStatus(DllExports::GdipGetFontUnit(nativeFont, &result));
    884 	return result;
    885 }
    886 
    887 
    888 // FontCollection
    889 
    890 __inline__ FontCollection::FontCollection():
    891 	nativeFontCollection(NULL), lastStatus(Ok)
    892 {
    893 }
    894 
    895 __inline__ Status FontCollection::GetFamilies(INT numSought,
    896 		FontFamily *families, INT *numFound) const
    897 {
    898 	if (numSought <= 0 || !families || !numFound)
    899 		return lastStatus = InvalidParameter;
    900 
    901 	for (int i = 0; i < numSought; ++i) {
    902 		families[i].nativeFontFamily = NULL;
    903 		families[i].lastStatus = FontFamilyNotFound;
    904 	}
    905 	*numFound = 0;
    906 
    907 	GpFontFamily **nativeFamilyArray = (GpFontFamily**)
    908 		DllExports::GdipAlloc(numSought * sizeof (GpFontFamily*));
    909 	if (!nativeFamilyArray)
    910 		return lastStatus = OutOfMemory;
    911 
    912 	Status status = updateStatus(DllExports::GdipGetFontCollectionFamilyList(
    913 			nativeFontCollection, numSought, nativeFamilyArray,
    914 			numFound));
    915 
    916 	// FIXME: must the native GpFontFamily objects be cloned? Seems so.
    917 	// (if this is not done, the "Creating a Private Font Collection"
    918 	// example crashes on "delete[] pFontFamily")
    919 
    920 	if (status == Ok) {
    921 		for (int i = 0; i < *numFound; ++i) {
    922 			families[i].lastStatus =
    923 				updateStatus(DllExports::GdipCloneFontFamily(
    924 					nativeFamilyArray[i],
    925 					&families[i].nativeFontFamily));
    926 		}
    927 	}
    928 
    929 	DllExports::GdipFree(nativeFamilyArray);
    930 	return status;
    931 }
    932 
    933 __inline__ INT FontCollection::GetFamilyCount() const
    934 {
    935 	INT result = 0;
    936 	updateStatus(DllExports::GdipGetFontCollectionFamilyCount(
    937 			nativeFontCollection, &result));
    938 	return result;
    939 }
    940 
    941 
    942 // FontFamily
    943 
    944 // FIXME: do FontFamily::GenericMonospace() et al. need to be thread safe?
    945 // FIXME: maybe put parts of this in gdiplus.c
    946 
    947 extern "C" void *_GdipFontFamilyCachedGenericMonospace;
    948 extern "C" void *_GdipFontFamilyCachedGenericSansSerif;
    949 extern "C" void *_GdipFontFamilyCachedGenericSerif;
    950 
    951 __inline__ const FontFamily* FontFamily::GenericMonospace()
    952 {
    953 	if (!_GdipFontFamilyCachedGenericMonospace) {
    954 		GpFontFamily *nativeFontFamily = 0;
    955 		Status status = DllExports::GdipGetGenericFontFamilyMonospace(
    956 				&nativeFontFamily);
    957 		if (status == Ok && nativeFontFamily) {
    958 			_GdipFontFamilyCachedGenericMonospace = (void*)
    959 				new FontFamily(nativeFontFamily, Ok);
    960 		}
    961 	}
    962 	return (FontFamily*) _GdipFontFamilyCachedGenericMonospace;
    963 }
    964 
    965 __inline__ const FontFamily* FontFamily::GenericSansSerif()
    966 {
    967 	if (!_GdipFontFamilyCachedGenericSansSerif) {
    968 		GpFontFamily *nativeFontFamily = 0;
    969 		Status status = DllExports::GdipGetGenericFontFamilySansSerif(
    970 				&nativeFontFamily);
    971 		if (status == Ok && nativeFontFamily) {
    972 			_GdipFontFamilyCachedGenericSansSerif = (void*)
    973 				new FontFamily(nativeFontFamily, Ok);
    974 		}
    975 	}
    976 	return (FontFamily*) _GdipFontFamilyCachedGenericSansSerif;
    977 }
    978 
    979 __inline__ const FontFamily* FontFamily::GenericSerif()
    980 {
    981 	if (!_GdipFontFamilyCachedGenericSerif) {
    982 		GpFontFamily *nativeFontFamily = 0;
    983 		Status status = DllExports::GdipGetGenericFontFamilySerif(
    984 				&nativeFontFamily);
    985 		if (status == Ok && nativeFontFamily) {
    986 			_GdipFontFamilyCachedGenericSerif = (void*)
    987 				new FontFamily(nativeFontFamily, Ok);
    988 		}
    989 	}
    990 	return (FontFamily*) _GdipFontFamilyCachedGenericSerif;
    991 }
    992 
    993 __inline__ FontFamily::FontFamily():
    994 	nativeFontFamily(NULL), lastStatus(Ok)
    995 {
    996 }
    997 
    998 __inline__ FontFamily::FontFamily(const WCHAR *name,
    999 		const FontCollection *fontCollection):
   1000 		nativeFontFamily(NULL), lastStatus(Ok)
   1001 {
   1002 	lastStatus = DllExports::GdipCreateFontFamilyFromName(name,
   1003 			fontCollection ? fontCollection->nativeFontCollection : NULL,
   1004 			&nativeFontFamily);
   1005 }
   1006 
   1007 __inline__ FontFamily::~FontFamily()
   1008 {
   1009 	DllExports::GdipDeleteFontFamily(nativeFontFamily);
   1010 }
   1011 
   1012 __inline__ FontFamily* FontFamily::Clone() const
   1013 {
   1014 	GpFontFamily *cloneFontFamily = NULL;
   1015 	Status status = updateStatus(DllExports::GdipCloneFontFamily(
   1016 			nativeFontFamily, &cloneFontFamily));
   1017 	if (status == Ok) {
   1018 		FontFamily *result = new FontFamily(cloneFontFamily, lastStatus);
   1019 		if (!result) {
   1020 			DllExports::GdipDeleteFontFamily(cloneFontFamily);
   1021 			lastStatus = OutOfMemory;
   1022 		}
   1023 		return result;
   1024 	} else {
   1025 		return NULL;
   1026 	}
   1027 }
   1028 
   1029 __inline__ UINT16 FontFamily::GetCellAscent(INT style) const
   1030 {
   1031 	UINT16 result = 0;
   1032 	updateStatus(DllExports::GdipGetCellAscent(
   1033 			nativeFontFamily, style, &result));
   1034 	return result;
   1035 }
   1036 
   1037 __inline__ UINT16 FontFamily::GetCellDescent(INT style) const
   1038 {
   1039 	UINT16 result = 0;
   1040 	updateStatus(DllExports::GdipGetCellDescent(
   1041 			nativeFontFamily, style, &result));
   1042 	return result;
   1043 }
   1044 
   1045 __inline__ UINT16 FontFamily::GetEmHeight(INT style) const
   1046 {
   1047 	UINT16 result = 0;
   1048 	updateStatus(DllExports::GdipGetEmHeight(
   1049 			nativeFontFamily, style, &result));
   1050 	return result;
   1051 }
   1052 
   1053 __inline__ Status FontFamily::GetFamilyName(WCHAR name[LF_FACESIZE],
   1054 		LANGID language) const
   1055 {
   1056 	return updateStatus(DllExports::GdipGetFamilyName(
   1057 			nativeFontFamily, name, language));
   1058 }
   1059 
   1060 __inline__ UINT16 FontFamily::GetLineSpacing(INT style) const
   1061 {
   1062 	UINT16 result = 0;
   1063 	updateStatus(DllExports::GdipGetLineSpacing(
   1064 			nativeFontFamily, style, &result));
   1065 	return result;
   1066 }
   1067 
   1068 __inline__ BOOL FontFamily::IsStyleAvailable(INT style) const
   1069 {
   1070 	BOOL result = FALSE;
   1071 	updateStatus(DllExports::GdipIsStyleAvailable(
   1072 			nativeFontFamily, style, &result));
   1073 	return result;
   1074 }
   1075 
   1076 
   1077 // InstalledFontCollection
   1078 
   1079 __inline__ InstalledFontCollection::InstalledFontCollection()
   1080 {
   1081 	lastStatus = DllExports::GdipNewInstalledFontCollection(
   1082 			&nativeFontCollection);
   1083 }
   1084 
   1085 
   1086 // PrivateFontCollection
   1087 
   1088 __inline__ PrivateFontCollection::PrivateFontCollection()
   1089 {
   1090 	lastStatus = DllExports::GdipNewPrivateFontCollection(
   1091 			&nativeFontCollection);
   1092 }
   1093 
   1094 __inline__ Status PrivateFontCollection::AddFontFile(const WCHAR *filename)
   1095 {
   1096 	return updateStatus(DllExports::GdipPrivateAddFontFile(
   1097 			nativeFontCollection, filename));
   1098 }
   1099 
   1100 __inline__ Status PrivateFontCollection::AddMemoryFont(
   1101 		const VOID *memory, INT length)
   1102 {
   1103 	return updateStatus(DllExports::GdipPrivateAddMemoryFont(
   1104 			nativeFontCollection, memory, length));
   1105 }
   1106 
   1107 
   1108 // Region
   1109 
   1110 __inline__ Region* Region::FromHRGN(HRGN hrgn)
   1111 {
   1112 	return new Region(hrgn);
   1113 }
   1114 
   1115 __inline__ Region::Region(): nativeRegion(NULL), lastStatus(Ok)
   1116 {
   1117 	lastStatus = DllExports::GdipCreateRegion(&nativeRegion);
   1118 }
   1119 
   1120 __inline__ Region::Region(const RectF& rect): nativeRegion(NULL), lastStatus(Ok)
   1121 {
   1122 	lastStatus = DllExports::GdipCreateRegionRect(&rect, &nativeRegion);
   1123 }
   1124 
   1125 __inline__ Region::Region(const Rect& rect): nativeRegion(NULL), lastStatus(Ok)
   1126 {
   1127 	lastStatus = DllExports::GdipCreateRegionRectI(&rect, &nativeRegion);
   1128 }
   1129 
   1130 __inline__ Region::Region(const GraphicsPath *path):
   1131 	nativeRegion(NULL), lastStatus(Ok)
   1132 {
   1133 	lastStatus = DllExports::GdipCreateRegionPath(
   1134 			path ? path->nativePath : NULL, &nativeRegion);
   1135 }
   1136 
   1137 __inline__ Region::Region(const BYTE *regionData, INT size):
   1138 	nativeRegion(NULL), lastStatus(Ok)
   1139 {
   1140 	lastStatus = DllExports::GdipCreateRegionRgnData(
   1141 			regionData, size, &nativeRegion);
   1142 }
   1143 
   1144 __inline__ Region::Region(HRGN hrgn): nativeRegion(NULL), lastStatus(Ok)
   1145 {
   1146 	lastStatus = DllExports::GdipCreateRegionHrgn(hrgn, &nativeRegion);
   1147 }
   1148 
   1149 __inline__ Region::~Region()
   1150 {
   1151 	DllExports::GdipDeleteRegion(nativeRegion);
   1152 }
   1153 
   1154 __inline__ Region* Region::Clone() const
   1155 {
   1156 	GpRegion *cloneRegion = NULL;
   1157 	Status status = updateStatus(DllExports::GdipCloneRegion(
   1158 			nativeRegion, &cloneRegion));
   1159 	if (status == Ok) {
   1160 		Region *result = new Region(cloneRegion, lastStatus);
   1161 		if (!result) {
   1162 			DllExports::GdipDeleteRegion(cloneRegion);
   1163 			lastStatus = OutOfMemory;
   1164 		}
   1165 		return result;
   1166 	} else {
   1167 		return NULL;
   1168 	}
   1169 }
   1170 
   1171 __inline__ Status Region::Complement(const RectF& rect)
   1172 {
   1173 	return updateStatus(DllExports::GdipCombineRegionRect(
   1174 			nativeRegion, &rect, CombineModeComplement));
   1175 }
   1176 
   1177 __inline__ Status Region::Complement(const Rect& rect)
   1178 {
   1179 	return updateStatus(DllExports::GdipCombineRegionRectI(
   1180 			nativeRegion, &rect, CombineModeComplement));
   1181 }
   1182 
   1183 __inline__ Status Region::Complement(const Region *region)
   1184 {
   1185 	return updateStatus(DllExports::GdipCombineRegionRegion(
   1186 			nativeRegion, region ? region->nativeRegion : NULL,
   1187 			CombineModeComplement));
   1188 }
   1189 
   1190 __inline__ Status Region::Complement(const GraphicsPath *path)
   1191 {
   1192 	return updateStatus(DllExports::GdipCombineRegionPath(
   1193 			nativeRegion, path ? path->nativePath : NULL,
   1194 			CombineModeComplement));
   1195 }
   1196 
   1197 __inline__ BOOL Region::Equals(const Region *region, const Graphics *graphics)
   1198 const
   1199 {
   1200 	BOOL result = FALSE;
   1201 	updateStatus(DllExports::GdipIsEqualRegion(
   1202 			nativeRegion, region ? region->nativeRegion : NULL,
   1203 			graphics ? graphics->nativeGraphics : NULL, &result));
   1204 	return result;
   1205 }
   1206 
   1207 __inline__ Status Region::Exclude(const RectF& rect)
   1208 {
   1209 	return updateStatus(DllExports::GdipCombineRegionRect(
   1210 			nativeRegion, &rect, CombineModeExclude));
   1211 }
   1212 
   1213 __inline__ Status Region::Exclude(const Rect& rect)
   1214 {
   1215 	return updateStatus(DllExports::GdipCombineRegionRectI(
   1216 			nativeRegion, &rect, CombineModeExclude));
   1217 }
   1218 
   1219 __inline__ Status Region::Exclude(const Region *region)
   1220 {
   1221 	return updateStatus(DllExports::GdipCombineRegionRegion(
   1222 			nativeRegion, region ? region->nativeRegion : NULL,
   1223 			CombineModeExclude));
   1224 }
   1225 
   1226 __inline__ Status Region::Exclude(const GraphicsPath *path)
   1227 {
   1228 	return updateStatus(DllExports::GdipCombineRegionPath(
   1229 			nativeRegion, path ? path->nativePath : NULL,
   1230 			CombineModeExclude));
   1231 }
   1232 
   1233 __inline__ Status Region::GetBounds(RectF *rect, const Graphics *graphics) const
   1234 {
   1235 	return updateStatus(DllExports::GdipGetRegionBounds(nativeRegion,
   1236 			graphics ? graphics->nativeGraphics : NULL, rect));
   1237 }
   1238 
   1239 __inline__ Status Region::GetBounds(Rect *rect, const Graphics *graphics) const
   1240 {
   1241 	return updateStatus(DllExports::GdipGetRegionBoundsI(nativeRegion,
   1242 			graphics ? graphics->nativeGraphics : NULL, rect));
   1243 }
   1244 
   1245 __inline__ Status Region::GetData(BYTE *buffer, UINT bufferSize,
   1246 		UINT *sizeFilled) const
   1247 {
   1248 	return updateStatus(DllExports::GdipGetRegionData(
   1249 			nativeRegion, buffer, bufferSize, sizeFilled));
   1250 }
   1251 
   1252 __inline__ UINT Region::GetDataSize() const
   1253 {
   1254 	UINT result = 0;
   1255 	updateStatus(DllExports::GdipGetRegionDataSize(nativeRegion, &result));
   1256 	return result;
   1257 }
   1258 
   1259 __inline__ HRGN Region::GetHRGN(const Graphics *graphics) const
   1260 {
   1261 	HRGN result = NULL;
   1262 	updateStatus(DllExports::GdipGetRegionHRgn(nativeRegion,
   1263 			graphics ? graphics->nativeGraphics : NULL, &result));
   1264 	return result;
   1265 }
   1266 
   1267 __inline__ Status Region::GetRegionScans(const Matrix *matrix,
   1268 		RectF *rects, INT *count) const
   1269 {
   1270 	return updateStatus(DllExports::GdipGetRegionScans(
   1271 			nativeRegion, rects, count,
   1272 			matrix ? matrix->nativeMatrix : NULL));
   1273 }
   1274 
   1275 __inline__ Status Region::GetRegionScans(const Matrix *matrix,
   1276 		Rect *rects, INT *count) const
   1277 {
   1278 	return updateStatus(DllExports::GdipGetRegionScansI(
   1279 			nativeRegion, rects, count,
   1280 			matrix ? matrix->nativeMatrix : NULL));
   1281 }
   1282 
   1283 __inline__ UINT Region::GetRegionScansCount(const Matrix *matrix) const
   1284 {
   1285 	UINT result = 0;
   1286 	updateStatus(DllExports::GdipGetRegionScansCount(
   1287 			nativeRegion, &result,
   1288 			matrix ? matrix->nativeMatrix : NULL));
   1289 	return result;
   1290 }
   1291 
   1292 __inline__ Status Region::Intersect(const RectF& rect)
   1293 {
   1294 	return updateStatus(DllExports::GdipCombineRegionRect(
   1295 			nativeRegion, &rect, CombineModeIntersect));
   1296 }
   1297 
   1298 __inline__ Status Region::Intersect(const Rect& rect)
   1299 {
   1300 	return updateStatus(DllExports::GdipCombineRegionRectI(
   1301 			nativeRegion, &rect, CombineModeIntersect));
   1302 }
   1303 
   1304 __inline__ Status Region::Intersect(const Region *region)
   1305 {
   1306 	return updateStatus(DllExports::GdipCombineRegionRegion(
   1307 			nativeRegion, region ? region->nativeRegion : NULL,
   1308 			CombineModeIntersect));
   1309 }
   1310 
   1311 __inline__ Status Region::Intersect(const GraphicsPath *path)
   1312 {
   1313 	return updateStatus(DllExports::GdipCombineRegionPath(
   1314 			nativeRegion, path ? path->nativePath : NULL,
   1315 			CombineModeIntersect));
   1316 }
   1317 
   1318 __inline__ BOOL Region::IsEmpty(const Graphics *graphics) const
   1319 {
   1320 	BOOL result = FALSE;
   1321 	updateStatus(DllExports::GdipIsEmptyRegion(nativeRegion,
   1322 			graphics ? graphics->nativeGraphics : NULL, &result));
   1323 	return result;
   1324 }
   1325 
   1326 __inline__ BOOL Region::IsInfinite(const Graphics *graphics) const
   1327 {
   1328 	BOOL result = FALSE;
   1329 	updateStatus(DllExports::GdipIsInfiniteRegion(nativeRegion,
   1330 			graphics ? graphics->nativeGraphics : NULL, &result));
   1331 	return result;
   1332 }
   1333 
   1334 __inline__ BOOL Region::IsVisible(REAL x, REAL y,
   1335 		const Graphics *graphics) const
   1336 {
   1337 	BOOL result = FALSE;
   1338 	updateStatus(DllExports::GdipIsVisibleRegionPoint(
   1339 			nativeRegion, x, y,
   1340 			graphics ? graphics->nativeGraphics : NULL, &result));
   1341 	return result;
   1342 }
   1343 
   1344 __inline__ BOOL Region::IsVisible(INT x, INT y,
   1345 		const Graphics *graphics) const
   1346 {
   1347 	BOOL result = FALSE;
   1348 	updateStatus(DllExports::GdipIsVisibleRegionPointI(
   1349 			nativeRegion, x, y,
   1350 			graphics ? graphics->nativeGraphics : NULL, &result));
   1351 	return result;
   1352 }
   1353 
   1354 __inline__ BOOL Region::IsVisible(const PointF& point,
   1355 		const Graphics *graphics) const
   1356 {
   1357 	BOOL result = FALSE;
   1358 	updateStatus(DllExports::GdipIsVisibleRegionPoint(
   1359 			nativeRegion, point.X, point.Y,
   1360 			graphics ? graphics->nativeGraphics : NULL, &result));
   1361 	return result;
   1362 }
   1363 
   1364 __inline__ BOOL Region::IsVisible(const Point& point,
   1365 		const Graphics *graphics) const
   1366 {
   1367 	BOOL result = FALSE;
   1368 	updateStatus(DllExports::GdipIsVisibleRegionPointI(
   1369 			nativeRegion, point.X, point.Y,
   1370 			graphics ? graphics->nativeGraphics : NULL, &result));
   1371 	return result;
   1372 }
   1373 
   1374 __inline__ BOOL Region::IsVisible(REAL x, REAL y, REAL width, REAL height,
   1375 		const Graphics *graphics) const
   1376 {
   1377 	BOOL result = FALSE;
   1378 	updateStatus(DllExports::GdipIsVisibleRegionRect(
   1379 			nativeRegion, x, y, width, height,
   1380 			graphics ? graphics->nativeGraphics : NULL, &result));
   1381 	return result;
   1382 }
   1383 
   1384 __inline__ BOOL Region::IsVisible(INT x, INT y, INT width, INT height,
   1385 		const Graphics *graphics) const
   1386 {
   1387 	BOOL result = FALSE;
   1388 	updateStatus(DllExports::GdipIsVisibleRegionRectI(
   1389 			nativeRegion, x, y, width, height,
   1390 			graphics ? graphics->nativeGraphics : NULL, &result));
   1391 	return result;
   1392 }
   1393 
   1394 __inline__ BOOL Region::IsVisible(const RectF& rect,
   1395 		const Graphics *graphics) const
   1396 {
   1397 	BOOL result = FALSE;
   1398 	updateStatus(DllExports::GdipIsVisibleRegionRect(
   1399 			nativeRegion, rect.X, rect.Y, rect.Width, rect.Height,
   1400 			graphics ? graphics->nativeGraphics : NULL, &result));
   1401 	return result;
   1402 }
   1403 
   1404 __inline__ BOOL Region::IsVisible(const Rect& rect,
   1405 		const Graphics *graphics) const
   1406 {
   1407 	BOOL result = FALSE;
   1408 	updateStatus(DllExports::GdipIsVisibleRegionRectI(
   1409 			nativeRegion, rect.X, rect.Y, rect.Width, rect.Height,
   1410 			graphics ? graphics->nativeGraphics : NULL, &result));
   1411 	return result;
   1412 }
   1413 
   1414 __inline__ Status Region::MakeEmpty()
   1415 {
   1416 	return updateStatus(DllExports::GdipSetEmpty(nativeRegion));
   1417 }
   1418 
   1419 __inline__ Status Region::MakeInfinite()
   1420 {
   1421 	return updateStatus(DllExports::GdipSetInfinite(nativeRegion));
   1422 }
   1423 
   1424 __inline__ Status Region::Transform(const Matrix *matrix)
   1425 {
   1426 	return updateStatus(DllExports::GdipTransformRegion(
   1427 			nativeRegion, matrix ? matrix->nativeMatrix : NULL));
   1428 }
   1429 
   1430 __inline__ Status Region::Translate(REAL dx, REAL dy)
   1431 {
   1432 	return updateStatus(DllExports::GdipTranslateRegion(
   1433 			nativeRegion, dx, dy));
   1434 }
   1435 
   1436 __inline__ Status Region::Translate(INT dx, INT dy)
   1437 {
   1438 	return updateStatus(DllExports::GdipTranslateRegionI(
   1439 			nativeRegion, dx, dy));
   1440 }
   1441 
   1442 __inline__ Status Region::Union(const RectF& rect)
   1443 {
   1444 	return updateStatus(DllExports::GdipCombineRegionRect(
   1445 			nativeRegion, &rect, CombineModeUnion));
   1446 }
   1447 
   1448 __inline__ Status Region::Union(const Rect& rect)
   1449 {
   1450 	return updateStatus(DllExports::GdipCombineRegionRectI(
   1451 			nativeRegion, &rect, CombineModeUnion));
   1452 }
   1453 
   1454 __inline__ Status Region::Union(const Region *region)
   1455 {
   1456 	return updateStatus(DllExports::GdipCombineRegionRegion(
   1457 			nativeRegion, region ? region->nativeRegion : NULL,
   1458 			CombineModeUnion));
   1459 }
   1460 
   1461 __inline__ Status Region::Union(const GraphicsPath *path)
   1462 {
   1463 	return updateStatus(DllExports::GdipCombineRegionPath(
   1464 			nativeRegion, path ? path->nativePath : NULL,
   1465 			CombineModeUnion));
   1466 }
   1467 
   1468 __inline__ Status Region::Xor(const RectF& rect)
   1469 {
   1470 	return updateStatus(DllExports::GdipCombineRegionRect(
   1471 			nativeRegion, &rect, CombineModeXor));
   1472 }
   1473 
   1474 __inline__ Status Region::Xor(const Rect& rect)
   1475 {
   1476 	return updateStatus(DllExports::GdipCombineRegionRectI(
   1477 			nativeRegion, &rect, CombineModeXor));
   1478 }
   1479 
   1480 __inline__ Status Region::Xor(const Region *region)
   1481 {
   1482 	return updateStatus(DllExports::GdipCombineRegionRegion(
   1483 			nativeRegion, region ? region->nativeRegion : NULL,
   1484 			CombineModeXor));
   1485 }
   1486 
   1487 __inline__ Status Region::Xor(const GraphicsPath *path)
   1488 {
   1489 	return updateStatus(DllExports::GdipCombineRegionPath(
   1490 			nativeRegion, path ? path->nativePath : NULL,
   1491 			CombineModeXor));
   1492 }
   1493 
   1494 
   1495 // GraphicsPath
   1496 
   1497 __inline__ BOOL GraphicsPath::IsOutlineVisible(REAL x, REAL y, const Pen *pen,
   1498 		const Graphics *g) const
   1499 {
   1500 	BOOL result = FALSE;
   1501 	updateStatus(DllExports::GdipIsOutlineVisiblePathPoint(
   1502 			nativePath, x, y, pen ? pen->nativePen : NULL,
   1503 			g ? g->nativeGraphics : NULL, &result));
   1504 	return result;
   1505 }
   1506 
   1507 __inline__ BOOL GraphicsPath::IsOutlineVisible(INT x, INT y, const Pen *pen,
   1508 		const Graphics *g) const
   1509 {
   1510 	BOOL result = FALSE;
   1511 	updateStatus(DllExports::GdipIsOutlineVisiblePathPointI(
   1512 			nativePath, x, y, pen ? pen->nativePen : NULL,
   1513 			g ? g->nativeGraphics : NULL, &result));
   1514 	return result;
   1515 }
   1516 
   1517 __inline__ BOOL GraphicsPath::IsOutlineVisible(const PointF& point, const Pen *pen,
   1518 		const Graphics *g) const
   1519 {
   1520 	BOOL result = FALSE;
   1521 	updateStatus(DllExports::GdipIsOutlineVisiblePathPoint(
   1522 			nativePath, point.X, point.Y,
   1523 			pen ? pen->nativePen : NULL,
   1524 			g ? g->nativeGraphics : NULL, &result));
   1525 	return result;
   1526 }
   1527 
   1528 __inline__ BOOL GraphicsPath::IsOutlineVisible(const Point& point, const Pen *pen,
   1529 		const Graphics *g) const
   1530 {
   1531 	BOOL result = FALSE;
   1532 	updateStatus(DllExports::GdipIsOutlineVisiblePathPointI(
   1533 			nativePath, point.X, point.Y,
   1534 			pen ? pen->nativePen : NULL,
   1535 			g ? g->nativeGraphics : NULL, &result));
   1536 	return result;
   1537 }
   1538 
   1539 __inline__ BOOL GraphicsPath::IsVisible(REAL x, REAL y, const Graphics *g) const
   1540 {
   1541 	BOOL result = FALSE;
   1542 	updateStatus(DllExports::GdipIsVisiblePathPoint(
   1543 			nativePath, x, y,
   1544 			g ? g->nativeGraphics : NULL, &result));
   1545 	return result;
   1546 }
   1547 __inline__ BOOL GraphicsPath::IsVisible(INT x, INT y, const Graphics *g) const
   1548 {
   1549 	BOOL result = FALSE;
   1550 	updateStatus(DllExports::GdipIsVisiblePathPointI(
   1551 			nativePath, x, y,
   1552 			g ? g->nativeGraphics : NULL, &result));
   1553 	return result;
   1554 }
   1555 
   1556 __inline__ BOOL GraphicsPath::IsVisible(const PointF& point,
   1557 		const Graphics *g) const
   1558 {
   1559 	BOOL result = FALSE;
   1560 	updateStatus(DllExports::GdipIsVisiblePathPoint(
   1561 			nativePath, point.X, point.Y,
   1562 			g ? g->nativeGraphics : NULL, &result));
   1563 	return result;
   1564 }
   1565 
   1566 __inline__ BOOL GraphicsPath::IsVisible(const Point& point, const Graphics *g) const
   1567 {
   1568 	BOOL result = FALSE;
   1569 	updateStatus(DllExports::GdipIsVisiblePathPointI(
   1570 			nativePath, point.X, point.Y,
   1571 			g ? g->nativeGraphics : NULL, &result));
   1572 	return result;
   1573 }
   1574 
   1575 
   1576 // PathData
   1577 
   1578 __inline__ Status PathData::AllocateArrays(INT capacity)
   1579 {
   1580 	if (capacity < 0) {
   1581 		return InvalidParameter;
   1582 	} else if (Count < capacity) {
   1583 		FreeArrays();
   1584 
   1585 		PointF *pointArray = (PointF*)
   1586 			DllExports::GdipAlloc(capacity * sizeof(PointF));
   1587 		if (!pointArray)
   1588 			return OutOfMemory;
   1589 
   1590 		BYTE *typeArray = (BYTE*)
   1591 			DllExports::GdipAlloc(capacity * sizeof(BYTE));
   1592 		if (!typeArray) {
   1593 			DllExports::GdipFree(pointArray);
   1594 			return OutOfMemory;
   1595 		}
   1596 
   1597 		Count = capacity;
   1598 		Points = pointArray;
   1599 		Types = typeArray;
   1600 	}
   1601 	return Ok;
   1602 }
   1603 
   1604 __inline__ VOID PathData::FreeArrays()
   1605 {
   1606 	if (Points) DllExports::GdipFree(Points);
   1607 	if (Types) DllExports::GdipFree(Types);
   1608 	Count = 0;
   1609 	Points = NULL;
   1610 	Types = NULL;
   1611 }
   1612 
   1613 #endif /* __GDIPLUS_IMPL_H */
   1614