Alexandre Julliard : gdi32: Use GetImage to retrieve the brush bits in enhanced metafiles.
Alexandre Julliard
julliard at winehq.org
Wed Aug 3 12:48:10 CDT 2011
Module: wine
Branch: master
Commit: 1aa35bea9a7ffdd087d2a5aebb25525a69a1e3ba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1aa35bea9a7ffdd087d2a5aebb25525a69a1e3ba
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Aug 3 13:08:34 2011 +0200
gdi32: Use GetImage to retrieve the brush bits in enhanced metafiles.
---
dlls/gdi32/enhmfdrv/objects.c | 84 +++++++++++------------------------------
1 files changed, 22 insertions(+), 62 deletions(-)
diff --git a/dlls/gdi32/enhmfdrv/objects.c b/dlls/gdi32/enhmfdrv/objects.c
index fca6f63..454c6cb 100644
--- a/dlls/gdi32/enhmfdrv/objects.c
+++ b/dlls/gdi32/enhmfdrv/objects.c
@@ -105,36 +105,6 @@ HBITMAP EMFDRV_SelectBitmap( PHYSDEV dev, HBITMAP hbitmap )
}
-/* Internal helper for EMFDRV_CreateBrushIndirect():
- * Change the padding of a bitmap from 16 (BMP) to 32 (DIB) bits.
- */
-static inline void EMFDRV_PadTo32(LPBYTE lpRows, int height, int width)
-{
- int bytes16 = 2 * ((width + 15) / 16);
- int bytes32 = 4 * ((width + 31) / 32);
- LPBYTE lpSrc, lpDst;
- int i;
-
- if (!height)
- return;
-
- height = abs(height) - 1;
- lpSrc = lpRows + height * bytes16;
- lpDst = lpRows + height * bytes32;
-
- /* Note that we work backwards so we can re-pad in place */
- while (height >= 0)
- {
- for (i = bytes32; i > bytes16; i--)
- lpDst[i - 1] = 0; /* Zero the padding bytes */
- for (; i > 0; i--)
- lpDst[i - 1] = lpSrc[i - 1]; /* Move image bytes into alignment */
- lpSrc -= bytes16;
- lpDst -= bytes32;
- height--;
- }
-}
-
/***********************************************************************
* EMFDRV_CreateBrushIndirect
*/
@@ -197,46 +167,36 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
case BS_PATTERN:
{
EMRCREATEDIBPATTERNBRUSHPT *emr;
- BITMAPINFOHEADER *info;
- BITMAP bm;
- DWORD bmSize, biSize, size;
+ char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+ BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
+ struct gdi_image_bits bits;
+ DWORD size;
- GetObjectA((HANDLE)logbrush.lbHatch, sizeof(bm), &bm);
-
- if (bm.bmBitsPixel != 1 || bm.bmPlanes != 1)
+ if (!get_bitmap_image( (HANDLE)logbrush.lbHatch, src_info, &bits )) break;
+ if (src_info->bmiHeader.biBitCount != 1)
{
FIXME("Trying to create a color pattern brush\n");
+ if (bits.free) bits.free( &bits );
break;
}
- /* BMP will be aligned to 32 bits, not 16 */
- bmSize = get_dib_stride(bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight;
-
- biSize = sizeof(BITMAPINFOHEADER);
/* FIXME: There is an extra DWORD written by native before the BMI.
* Not sure what its meant to contain.
*/
- size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize + sizeof(DWORD);
+ size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + sizeof(DWORD) +
+ sizeof(BITMAPINFOHEADER) + src_info->bmiHeader.biSizeImage;
emr = HeapAlloc( GetProcessHeap(), 0, size );
if(!emr)
- break;
-
- info = (BITMAPINFOHEADER *)((LPBYTE)emr +
- sizeof(EMRCREATEDIBPATTERNBRUSHPT) + sizeof(DWORD));
- info->biSize = sizeof(BITMAPINFOHEADER);
- info->biWidth = bm.bmWidth;
- info->biHeight = bm.bmHeight;
- info->biPlanes = bm.bmPlanes;
- info->biBitCount = bm.bmBitsPixel;
- info->biSizeImage = bmSize;
- GetBitmapBits((HANDLE)logbrush.lbHatch,
- bm.bmHeight * get_bitmap_stride(bm.bmWidth, bm.bmBitsPixel),
- (LPBYTE)info + sizeof(BITMAPINFOHEADER));
-
- /* Change the padding to be DIB compatible if needed */
- if (bm.bmWidth & 31)
- EMFDRV_PadTo32((LPBYTE)info + sizeof(BITMAPINFOHEADER), bm.bmWidth, bm.bmHeight);
+ {
+ if (bits.free) bits.free( &bits );
+ break;
+ }
+
+ dst_info = (BITMAPINFO *)((LPBYTE)(emr + 1) + sizeof(DWORD));
+ dst_info->bmiHeader = src_info->bmiHeader;
+ memcpy( &dst_info->bmiHeader + 1, bits.ptr, dst_info->bmiHeader.biSizeImage );
+ if (bits.free) bits.free( &bits );
emr->emr.iType = EMR_CREATEMONOBRUSH;
emr->emr.nSize = size;
@@ -249,10 +209,10 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
* FIXME: It may be that the DIB functions themselves accept this value.
*/
emr->iUsage = DIB_PAL_MONO;
- emr->offBmi = (LPBYTE)info - (LPBYTE)emr;
- emr->cbBmi = biSize;
- emr->offBits = emr->offBmi + biSize;
- emr->cbBits = bmSize;
+ emr->offBmi = (LPBYTE)dst_info - (LPBYTE)emr;
+ emr->cbBmi = sizeof( BITMAPINFOHEADER );
+ emr->offBits = emr->offBmi + emr->cbBmi;
+ emr->cbBits = dst_info->bmiHeader.biSizeImage;
if(!EMFDRV_WriteRecord( dev, &emr->emr ))
index = 0;
More information about the wine-cvs
mailing list