Jacek Caban : gdi32: Copy brush bits in get_brush_bitmap_info.

Alexandre Julliard julliard at winehq.org
Tue Sep 7 16:25:19 CDT 2021


Module: wine
Branch: master
Commit: 1ba1736238cfadcbd662471046d6b11ff38a258c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1ba1736238cfadcbd662471046d6b11ff38a258c

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Sep  7 14:10:44 2021 +0200

gdi32: Copy brush bits in get_brush_bitmap_info.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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;




More information about the wine-cvs mailing list