Alexandre Julliard : gdi32: Always store a copy of the bitmap bits for pattern brushes.

Alexandre Julliard julliard at winehq.org
Thu May 24 14:58:12 CDT 2012


Module: wine
Branch: master
Commit: a196ad8fc1687e3814c978ecf6224dbf7db18c86
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a196ad8fc1687e3814c978ecf6224dbf7db18c86

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed May 23 21:12:04 2012 +0200

gdi32: Always store a copy of the bitmap bits for pattern brushes.

---

 dlls/gdi32/brush.c          |   90 ++++++++-----------------------------------
 dlls/gdi32/dibdrv/objects.c |   12 +-----
 dlls/gdi32/gdi_private.h    |    1 -
 dlls/gdi32/pen.c            |    6 +--
 4 files changed, 18 insertions(+), 91 deletions(-)

diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c
index cb5a163..e0dd599 100644
--- a/dlls/gdi32/brush.c
+++ b/dlls/gdi32/brush.c
@@ -55,88 +55,37 @@ static const struct gdi_obj_funcs brush_funcs =
 };
 
 
-/* fetch the contents of the brush bitmap and cache them in the brush pattern */
-void cache_pattern_bits( PHYSDEV physdev, struct brush_pattern *pattern )
+static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
 {
+    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256])];
+    BITMAPINFO *info = (BITMAPINFO *)buffer;
     struct gdi_image_bits bits;
     struct bitblt_coords src;
-    BITMAPINFO *info;
-    BITMAPOBJ *bmp;
-
-    if (pattern->info) return;  /* already cached */
-    if (!(bmp = GDI_GetObjPtr( pattern->bitmap, OBJ_BITMAP ))) return;
-
-    /* we don't need to cache if we are selecting into the same type of DC */
-    if (physdev && bmp->funcs == physdev->funcs) goto done;
+    BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
 
-    if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) goto done;
+    if (!bmp) return FALSE;
 
     src.visrect.left   = src.x = 0;
     src.visrect.top    = src.y = 0;
     src.visrect.right  = src.width = bmp->dib.dsBm.bmWidth;
     src.visrect.bottom = src.height = bmp->dib.dsBm.bmHeight;
-    if (bmp->funcs->pGetImage( NULL, pattern->bitmap, info, &bits, &src ))
-    {
-        HeapFree( GetProcessHeap(), 0, info );
-        goto done;
-    }
-
-    /* release the unneeded space */
-    HeapReAlloc( GetProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, info,
-                 get_dib_info_size( info, DIB_RGB_COLORS ));
-    pattern->info  = info;
-    pattern->bits  = bits;
-    pattern->usage = DIB_RGB_COLORS;
-
-done:
-    GDI_ReleaseObj( pattern->bitmap );
-}
+    if (bmp->funcs->pGetImage( NULL, bitmap, info, &bits, &src )) goto done;
 
-static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
-{
-    BITMAPINFO *info;
-    BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
-
-    if (!bmp) return FALSE;
-
-    if (!is_bitmapobj_dib( bmp ))
+    brush->bits = bits;
+    if (!bits.free)
     {
-        if ((brush->bitmap = CreateBitmap( bmp->dib.dsBm.bmWidth, bmp->dib.dsBm.bmHeight,
-                                           bmp->dib.dsBm.bmPlanes, bmp->dib.dsBm.bmBitsPixel, NULL )))
-        {
-            if (bmp->funcs->pCopyBitmap( bitmap, brush->bitmap ))
-            {
-                BITMAPOBJ *copy = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP );
-                copy->funcs = bmp->funcs;
-                GDI_ReleaseObj( copy );
-            }
-            else
-            {
-                DeleteObject( brush->bitmap );
-                brush->bitmap = 0;
-            }
-        }
-        GDI_ReleaseObj( bitmap );
-        return brush->bitmap != 0;
+        if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) goto done;
+        memcpy( brush->bits.ptr, bits.ptr, info->bmiHeader.biSizeImage );
+        brush->bits.free = free_heap_bits;
     }
 
-    info = HeapAlloc( GetProcessHeap(), 0,
-                      get_dib_info_size( (BITMAPINFO *)&bmp->dib.dsBmih, DIB_RGB_COLORS ));
-    if (!info) goto done;
-    info->bmiHeader = bmp->dib.dsBmih;
-    if (info->bmiHeader.biCompression == BI_BITFIELDS)
-        memcpy( &info->bmiHeader + 1, bmp->dib.dsBitfields, sizeof(bmp->dib.dsBitfields) );
-    else if (info->bmiHeader.biClrUsed)
-        memcpy( &info->bmiHeader + 1, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) );
-    if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage )))
+    if (!(brush->info = HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( info, DIB_RGB_COLORS ))))
     {
-        HeapFree( GetProcessHeap(), 0, info );
+        if (brush->bits.free) brush->bits.free( &brush->bits );
         goto done;
     }
-    memcpy( brush->bits.ptr, bmp->dib.dsBm.bmBits, info->bmiHeader.biSizeImage );
-    brush->bits.is_copy = TRUE;
-    brush->bits.free = free_heap_bits;
-    brush->info = info;
+    memcpy( brush->info, info, get_dib_info_size( info, DIB_RGB_COLORS ));
+    brush->bits.is_copy = FALSE;  /* the bits can't be modified */
     brush->usage = DIB_RGB_COLORS;
 
 done:
@@ -200,7 +149,6 @@ BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern )
 void free_brush_pattern( struct brush_pattern *pattern )
 {
     if (pattern->bits.free) pattern->bits.free( &pattern->bits );
-    if (pattern->bitmap) DeleteObject( pattern->bitmap );
     HeapFree( GetProcessHeap(), 0, pattern->info );
 }
 
@@ -211,8 +159,6 @@ BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *
 
     if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE;
 
-    if (!brush->pattern.info) cache_pattern_bits( NULL, &brush->pattern );
-
     if (brush->pattern.info)
     {
         memcpy( info, brush->pattern.info, get_dib_info_size( brush->pattern.info, brush->pattern.usage ));
@@ -495,11 +441,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
         PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush );
         struct brush_pattern *pattern = &brush->pattern;
 
-        if (!pattern->info)
-        {
-            if (pattern->bitmap) cache_pattern_bits( physdev, pattern );
-            else pattern = NULL;
-        }
+        if (!pattern->info) pattern = NULL;
 
         GDI_inc_ref_count( handle );
         GDI_ReleaseObj( handle );
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index dd47ee1..35164e6 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1873,17 +1873,7 @@ static BOOL select_pattern_brush( dibdrv_physdev *pdev, dib_brush *brush, BOOL *
     if (pattern.bit_count == 1 && !pattern.color_table)
         dither = FALSE;  /* monochrome DDB pattern brushes don't get dithered */
 
-    if (!brush->pattern.info)
-    {
-        BITMAPOBJ *bmp = GDI_GetObjPtr( brush->pattern.bitmap, OBJ_BITMAP );
-        BOOL ret;
-
-        if (!bmp) return FALSE;
-        ret = init_dib_info_from_bitmapobj( &pattern, bmp );
-        GDI_ReleaseObj( brush->pattern.bitmap );
-        if (!ret) return FALSE;
-    }
-    else if (brush->pattern.info->bmiHeader.biClrUsed && brush->pattern.usage == DIB_PAL_COLORS)
+    if (brush->pattern.info->bmiHeader.biClrUsed && brush->pattern.usage == DIB_PAL_COLORS)
     {
         copy_bitmapinfo( info, brush->pattern.info );
         fill_color_table_from_pal_colors( info, pdev->dev.hdc );
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index db8fd24..36d0131 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -221,7 +221,6 @@ extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src
                            struct gdi_image_bits *bits, int mode ) DECLSPEC_HIDDEN;
 
 /* brush.c */
-extern void cache_pattern_bits( PHYSDEV physdev, struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
 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;
diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c
index 1d04dae..6695ee9 100644
--- a/dlls/gdi32/pen.c
+++ b/dlls/gdi32/pen.c
@@ -243,11 +243,7 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
             break;
         case OBJ_EXTPEN:
             pattern = &pen->pattern;
-            if (!pattern->info)
-            {
-                if (pattern->bitmap) cache_pattern_bits( physdev, pattern );
-                else pattern = NULL;
-            }
+            if (!pattern->info) pattern = NULL;
             break;
         default:
             GDI_ReleaseObj( handle );




More information about the wine-cvs mailing list