From 1ba1736238cfadcbd662471046d6b11ff38a258c Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 7 Sep 2021 14:10:44 +0200 Subject: [PATCH] gdi32: Copy brush bits in get_brush_bitmap_info. Signed-off-by: Jacek Caban Signed-off-by: Huw Davies Signed-off-by: Alexandre Julliard --- dlls/gdi32/brush.c | 35 +++++++++++++++++++++++++++++------ dlls/gdi32/emfdc.c | 5 ++--- dlls/gdi32/gdi_private.h | 3 +++ dlls/gdi32/metadc.c | 19 ++----------------- dlls/gdi32/ntgdi_private.h | 1 - 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c index 7c43df0dfcf..8ef902f60b9 100644 --- a/dlls/gdi32/brush.c +++ b/dlls/gdi32/brush.c @@ -140,7 +140,7 @@ void free_brush_pattern( struct brush_pattern *pattern ) HeapFree( GetProcessHeap(), 0, pattern->info ); } -BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) +BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void *bits, UINT *usage ) { BRUSHOBJ *brush; BOOL ret = FALSE; @@ -149,11 +149,34 @@ BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT * if (brush->pattern.info) { - memcpy( info, brush->pattern.info, get_dib_info_size( brush->pattern.info, brush->pattern.usage )); - if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed) - fill_default_color_table( info ); - *bits = brush->pattern.bits.ptr; - *usage = brush->pattern.usage; + if (info) + { + memcpy( info, brush->pattern.info, + get_dib_info_size( brush->pattern.info, brush->pattern.usage )); + if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed) + fill_default_color_table( info ); + if (info->bmiHeader.biHeight < 0) + info->bmiHeader.biHeight = -info->bmiHeader.biHeight; + } + if (bits) + { + /* always return a bottom-up DIB */ + if (brush->pattern.info->bmiHeader.biHeight < 0) + { + unsigned int i, width_bytes, height = -brush->pattern.info->bmiHeader.biHeight; + char *dst_ptr; + + width_bytes = get_dib_stride( brush->pattern.info->bmiHeader.biWidth, + brush->pattern.info->bmiHeader.biBitCount ); + dst_ptr = (char *)bits + (height - 1) * width_bytes; + for (i = 0; i < height; i++, dst_ptr -= width_bytes) + memcpy( dst_ptr, (char *)brush->pattern.bits.ptr + i * width_bytes, + width_bytes ); + } + else memcpy( bits, brush->pattern.bits.ptr, + brush->pattern.info->bmiHeader.biSizeImage ); + } + if (usage) *usage = brush->pattern.usage; ret = TRUE; } GDI_ReleaseObj( handle ); diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 6dc7229b574..300e2507852 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -190,10 +190,9 @@ static DWORD emfdc_create_brush( struct emf *emf, HBRUSH brush ) char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; DWORD info_size; - void *bits; UINT usage; - if (!get_brush_bitmap_info( brush, info, &bits, &usage )) break; + if (!get_brush_bitmap_info( brush, info, NULL, &usage )) break; info_size = get_dib_info_size( info, usage ); emr = HeapAlloc( GetProcessHeap(), 0, @@ -232,7 +231,7 @@ static DWORD emfdc_create_brush( struct emf *emf, HBRUSH brush ) emr->emr.nSize = emr->offBits + emr->cbBits; memcpy( (BYTE *)emr + emr->offBmi, info, emr->cbBmi ); - memcpy( (BYTE *)emr + emr->offBits, bits, emr->cbBits ); + get_brush_bitmap_info( brush, NULL, (char *)emr + emr->offBits, NULL ); if (!emfdc_record( emf, &emr->emr )) index = 0; HeapFree( GetProcessHeap(), 0, emr ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 675a2990215..7a4a8773f3f 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -224,4 +224,7 @@ extern BOOL EMFDC_StrokeAndFillPath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN; extern BOOL EMFDC_StrokePath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN; extern BOOL EMFDC_WidenPath( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN; +extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void *bits, + UINT *usage ) DECLSPEC_HIDDEN; + #endif /* __WINE_GDI_PRIVATE_H */ diff --git a/dlls/gdi32/metadc.c b/dlls/gdi32/metadc.c index 1f9d2f86b77..f4b313ba5db 100644 --- a/dlls/gdi32/metadc.c +++ b/dlls/gdi32/metadc.c @@ -546,11 +546,9 @@ static INT16 metadc_create_brush( struct metadc *metadc, HBRUSH brush ) char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer; DWORD info_size; - char *dst_ptr; - void *bits; UINT usage; - if (!get_brush_bitmap_info( brush, src_info, &bits, &usage )) goto done; + if (!get_brush_bitmap_info( brush, src_info, NULL, &usage )) goto done; info_size = get_dib_info_size( src_info, usage ); size = FIELD_OFFSET( METARECORD, rdParm[2] ) + @@ -562,22 +560,9 @@ static INT16 metadc_create_brush( struct metadc *metadc, HBRUSH brush ) mr->rdParm[0] = logbrush.lbStyle; mr->rdParm[1] = usage; dst_info = (BITMAPINFO *)(mr->rdParm + 2); - memcpy( dst_info, src_info, info_size ); + get_brush_bitmap_info( brush, dst_info, (char *)dst_info + info_size, NULL ); 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 ); - 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 + i * width_bytes, width_bytes ); - } - else memcpy( dst_ptr, bits, src_info->bmiHeader.biSizeImage ); break; } diff --git a/dlls/gdi32/ntgdi_private.h b/dlls/gdi32/ntgdi_private.h index ec3db21a2bd..b8273e8a405 100644 --- a/dlls/gdi32/ntgdi_private.h +++ b/dlls/gdi32/ntgdi_private.h @@ -170,7 +170,6 @@ extern void get_mono_dc_colors( DC *dc, int color_table_size, BITMAPINFO *info, extern HBRUSH create_brush( const LOGBRUSH *brush ); extern BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern ) DECLSPEC_HIDDEN; extern void free_brush_pattern( struct brush_pattern *pattern ) DECLSPEC_HIDDEN; -extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN; /* clipping.c */ extern BOOL clip_device_rect( DC *dc, RECT *dst, const RECT *src ) DECLSPEC_HIDDEN;