Alexandre Julliard : gdi32: Retrieve the brush pattern bits from the cache for metafiles.
Alexandre Julliard
julliard at winehq.org
Mon Nov 7 13:30:41 CST 2011
Module: wine
Branch: master
Commit: 7d0b65c4d1b4f070d2c18a7adbba6c6cdec082a0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7d0b65c4d1b4f070d2c18a7adbba6c6cdec082a0
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Nov 1 22:05:16 2011 +0100
gdi32: Retrieve the brush pattern bits from the cache for metafiles.
---
dlls/gdi32/brush.c | 29 +++++++++++++++++
dlls/gdi32/gdi_private.h | 2 +
dlls/gdi32/mfdrv/objects.c | 76 ++++++++++---------------------------------
3 files changed, 49 insertions(+), 58 deletions(-)
diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c
index 59d0bed..19372d1 100644
--- a/dlls/gdi32/brush.c
+++ b/dlls/gdi32/brush.c
@@ -90,6 +90,35 @@ static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
return TRUE;
}
+BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage )
+{
+ BRUSHOBJ *brush;
+ BOOL ret = FALSE;
+
+ if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE;
+
+ if (!brush->info)
+ {
+ BITMAPOBJ *bmp = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP );
+
+ if (bmp)
+ {
+ store_bitmap_bits( brush, bmp );
+ GDI_ReleaseObj( brush->bitmap );
+ }
+ }
+ if (brush->info)
+ {
+ memcpy( info, brush->info, bitmap_info_size( brush->info, brush->usage ));
+ *bits = brush->bits.ptr;
+ *usage = brush->usage;
+ ret = TRUE;
+ }
+ GDI_ReleaseObj( handle );
+ return ret;
+}
+
+
/***********************************************************************
* CreateBrushIndirect (GDI32.@)
*
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 0c73a9d..52fb318 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -233,6 +233,8 @@ extern BOOL get_bitmap_image( HBITMAP hbitmap, BITMAPINFO *info, struct gdi_imag
extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN;
+extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
+
/* clipping.c */
extern int get_clip_box( DC *dc, RECT *rect ) DECLSPEC_HIDDEN;
extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/mfdrv/objects.c b/dlls/gdi32/mfdrv/objects.c
index 599f226..3745ec7 100644
--- a/dlls/gdi32/mfdrv/objects.c
+++ b/dlls/gdi32/mfdrv/objects.c
@@ -174,86 +174,46 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
break;
}
case BS_PATTERN:
+ case BS_DIBPATTERN:
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
- struct gdi_image_bits bits;
- COLORREF cref;
+ DWORD info_size, image_size;
+ char *dst_ptr;
+ void *bits;
+ UINT usage;
- if (!get_bitmap_image( (HANDLE)logbrush.lbHatch, src_info, &bits )) goto done;
- if (src_info->bmiHeader.biBitCount != 1)
- {
- FIXME("Trying to store a colour pattern brush\n");
- if (bits.free) bits.free( &bits );
- goto done;
- }
+ if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;
- size = FIELD_OFFSET( METARECORD, rdParm[2] ) +
- FIELD_OFFSET( BITMAPINFO, bmiColors[2] ) + src_info->bmiHeader.biSizeImage;
+ info_size = bitmap_info_size( src_info, usage );
+ image_size = get_dib_image_size( src_info );
+ size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + image_size;
- if (!(mr = HeapAlloc( GetProcessHeap(), 0, size )))
- {
- if (bits.free) bits.free( &bits );
- goto done;
- }
+ if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
- mr->rdParm[0] = BS_PATTERN;
- mr->rdParm[1] = DIB_RGB_COLORS;
+ mr->rdParm[0] = logbrush.lbStyle;
+ mr->rdParm[1] = usage;
dst_info = (BITMAPINFO *)(mr->rdParm + 2);
- dst_info->bmiHeader = src_info->bmiHeader;
- dst_info->bmiHeader.biClrUsed = 0;
- cref = GetTextColor( dev->hdc );
- dst_info->bmiColors[0].rgbRed = GetRValue(cref);
- dst_info->bmiColors[0].rgbGreen = GetGValue(cref);
- dst_info->bmiColors[0].rgbBlue = GetBValue(cref);
- dst_info->bmiColors[0].rgbReserved = 0;
- cref = GetBkColor( dev->hdc );
- dst_info->bmiColors[1].rgbRed = GetRValue(cref);
- dst_info->bmiColors[1].rgbGreen = GetGValue(cref);
- dst_info->bmiColors[1].rgbBlue = GetBValue(cref);
- dst_info->bmiColors[1].rgbReserved = 0;
+ memcpy( dst_info, src_info, info_size );
+ if (dst_info->bmiHeader.biClrUsed == 1 << dst_info->bmiHeader.biBitCount)
+ dst_info->bmiHeader.biClrUsed = 0;
+ dst_ptr = (char *)dst_info + info_size;
/* always return a bottom-up DIB */
if (dst_info->bmiHeader.biHeight < 0)
{
int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth,
dst_info->bmiHeader.biBitCount );
- char *dst_ptr = (char *)&dst_info->bmiColors[2];
dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight;
dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes;
for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
- memcpy( dst_ptr, (char *)bits.ptr + i * width_bytes, width_bytes );
+ memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes );
}
- else memcpy( &dst_info->bmiColors[2], bits.ptr, dst_info->bmiHeader.biSizeImage );
- if (bits.free) bits.free( &bits );
+ else memcpy( dst_ptr, bits, image_size );
break;
}
- case BS_DIBPATTERN:
- {
- BITMAPINFO *info = (BITMAPINFO *)logbrush.lbHatch;
- DWORD bmSize, biSize;
-
- if (info->bmiHeader.biCompression)
- bmSize = info->bmiHeader.biSizeImage;
- else
- bmSize = get_dib_image_size( info );
- biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
- size = sizeof(METARECORD) + biSize + bmSize + 2;
- mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
- if (!mr)
- {
- GlobalUnlock( (HGLOBAL)logbrush.lbHatch );
- goto done;
- }
- mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
- mr->rdSize = size / 2;
- *(mr->rdParm) = logbrush.lbStyle;
- *(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
- memcpy(mr->rdParm + 2, info, biSize + bmSize);
- break;
- }
default:
FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
return 0;
More information about the wine-cvs
mailing list