diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 222ba42a07b..45874afbe45 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -53,21 +53,6 @@ static const struct gdi_obj_funcs brush_funcs = BRUSH_DeleteObject /* pDeleteObject */ }; -static void *dib_copy(const BITMAPINFO *info, UINT coloruse) -{ - BITMAPINFO *newInfo; - INT size; - - if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS) - size = info->bmiHeader.biSizeImage; - else - size = get_dib_image_size(info); - size += bitmap_info_size( info, coloruse ); - - if ((newInfo = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( newInfo, info, size ); - return newInfo; -} - /*********************************************************************** * CreateBrushIndirect (GDI32.@) @@ -117,8 +102,8 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) case BS_DIBPATTERNPT: ptr->logbrush.lbStyle = BS_DIBPATTERN; - ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch, - ptr->logbrush.lbColor); + ptr->logbrush.lbHatch = (ULONG_PTR)copy_packed_dib( (BITMAPINFO *) ptr->logbrush.lbHatch, + ptr->logbrush.lbColor ); if (!ptr->logbrush.lbHatch) goto error; break; @@ -129,7 +114,7 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) ptr->logbrush.lbStyle = BS_DIBPATTERN; if (!(bmi = GlobalLock( h ))) goto error; - ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor); + ptr->logbrush.lbHatch = (ULONG_PTR)copy_packed_dib( bmi, ptr->logbrush.lbColor ); GlobalUnlock( h ); if (!ptr->logbrush.lbHatch) goto error; break; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index 7cc24a64077..b9f9f3b52cc 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -1113,6 +1113,23 @@ void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) if (info->bmiHeader.biBitCount <= 8) fill_default_color_table( info ); } +BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) +{ + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *ret, *info = (BITMAPINFO *)buffer; + int info_size, image_size; + + if (!bitmapinfo_from_user_bitmapinfo( info, src_info, usage, FALSE )) return NULL; + + info_size = bitmap_info_size( info, usage ); + image_size = get_dib_image_size( info ); + if ((ret = HeapAlloc( GetProcessHeap(), 0, info_size + image_size ))) + { + memcpy( ret, info, info_size ); + memcpy( (char *)ret + info_size, (char *)src_info + bitmap_info_size(src_info,usage), image_size ); + } + return ret; +} /****************************************************************************** * GetDIBits [GDI32.@] diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 9ecb3b11a2d..ddeb0bd5dcd 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -230,6 +230,7 @@ extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src /* bitmap.c */ extern void get_ddb_bitmapinfo( BITMAPOBJ *bmp, BITMAPINFO *info ) DECLSPEC_HIDDEN; +extern BITMAPINFO *copy_packed_dib( const BITMAPINFO *src_info, UINT usage ) DECLSPEC_HIDDEN; extern BOOL get_bitmap_image( HBITMAP hbitmap, BITMAPINFO *info, struct gdi_image_bits *bits ) DECLSPEC_HIDDEN; extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN; extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN; diff --git a/dlls/gdi32/tests/brush.c b/dlls/gdi32/tests/brush.c index 3742608371e..a02209fadcc 100644 --- a/dlls/gdi32/tests/brush.c +++ b/dlls/gdi32/tests/brush.c @@ -192,6 +192,16 @@ static void test_pattern_brush(void) ret = GlobalFlags( mem ); ok( ret == 2, "wrong flags %x\n", ret ); + info->bmiHeader.biBitCount = 8; + info->bmiHeader.biCompression = BI_RLE8; + brush = CreateDIBPatternBrushPt( info, DIB_RGB_COLORS ); + ok( !brush, "CreateDIBPatternBrushPt succeeded\n" ); + + info->bmiHeader.biBitCount = 4; + info->bmiHeader.biCompression = BI_RLE4; + brush = CreateDIBPatternBrushPt( info, DIB_RGB_COLORS ); + ok( !brush, "CreateDIBPatternBrushPt succeeded\n" ); + br.lbStyle = BS_DIBPATTERN8X8; br.lbColor = DIB_RGB_COLORS; br.lbHatch = (ULONG_PTR)mem;