Alexandre Julliard : gdi32: Select the pattern brush only when first used.

Alexandre Julliard julliard at winehq.org
Mon Dec 12 12:25:54 CST 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Dec  8 12:12:54 2011 +0100

gdi32: Select the pattern brush only when first used.

---

 dlls/gdi32/dibdrv/dc.c      |   14 ------
 dlls/gdi32/dibdrv/dibdrv.h  |    2 +-
 dlls/gdi32/dibdrv/objects.c |   98 ++++++++++++++++++++----------------------
 3 files changed, 48 insertions(+), 66 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 6bcce26..ed7b0f7 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -167,20 +167,6 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
     return TRUE;
 }
 
-BOOL init_dib_info_from_brush(dib_info *dib, const BITMAPINFO *bi, void *bits, UINT usage, HDC hdc)
-{
-    if (bi->bmiHeader.biClrUsed && usage == DIB_PAL_COLORS)
-    {
-        char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
-        BITMAPINFO *info = (BITMAPINFO *)buffer;
-
-        copy_bitmapinfo( info, bi );
-        fill_color_table_from_pal_colors( info, hdc );
-        return init_dib_info_from_bitmapinfo( dib, info, bits, private_color_table );
-    }
-    return init_dib_info_from_bitmapinfo(dib, bi, bits, private_color_table );
-}
-
 BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags)
 {
     return init_dib_info( dib, &info->bmiHeader, (const DWORD *)info->bmiColors,
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 2aa672d..d388f91 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -103,6 +103,7 @@ typedef struct dibdrv_physdev
     const BITMAPINFO *brush_pattern_info;
     void *brush_pattern_bits;
     UINT brush_pattern_usage;
+    HBITMAP brush_pattern_bitmap;
     BOOL   (* brush_rects)(struct dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, HRGN clip);
 
     /* background */
@@ -226,7 +227,6 @@ extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN;
 extern void calc_and_xor_masks(INT rop, DWORD color, DWORD *and, DWORD *xor) DECLSPEC_HIDDEN;
 extern void update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
 extern void reset_dash_origin(dibdrv_physdev *pdev) DECLSPEC_HIDDEN;
-extern BOOL init_dib_info_from_brush(dib_info *dib, const BITMAPINFO *bi, void *bits, UINT usage, HDC hdc) DECLSPEC_HIDDEN;
 extern BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits,
                                           enum dib_info_flags flags) DECLSPEC_HIDDEN;
 extern BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 14f1260..9ab3bcd 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1468,35 +1468,62 @@ static BOOL matching_pattern_format( dib_info *dib, dib_info *pattern )
     return TRUE;
 }
 
-static void select_pattern_brush( dibdrv_physdev *pdev, dib_info *pattern )
+static BOOL select_pattern_brush( dibdrv_physdev *pdev )
 {
+    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
+    BITMAPINFO *info = (BITMAPINFO *)buffer;
     RECT rect;
+    dib_info pattern;
+
+    if (!pdev->brush_pattern_info)
+    {
+        BITMAPOBJ *bmp = GDI_GetObjPtr( pdev->brush_pattern_bitmap, OBJ_BITMAP );
+        BOOL ret;
+
+        if (!bmp) return FALSE;
+        ret = init_dib_info_from_bitmapobj( &pattern, bmp, 0 );
+        GDI_ReleaseObj( pdev->brush_pattern_bitmap );
+        if (!ret) return FALSE;
+    }
+    else if (pdev->brush_pattern_info->bmiHeader.biClrUsed && pdev->brush_pattern_usage == DIB_PAL_COLORS)
+    {
+        copy_bitmapinfo( info, pdev->brush_pattern_info );
+        fill_color_table_from_pal_colors( info, pdev->dev.hdc );
+        init_dib_info_from_bitmapinfo( &pattern, info, pdev->brush_pattern_bits, 0 );
+    }
+    else
+    {
+        init_dib_info_from_bitmapinfo( &pattern, pdev->brush_pattern_info, pdev->brush_pattern_bits, 0 );
+    }
 
-    free_pattern_brush( pdev );
     copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
 
-    pdev->brush_dib.height = pattern->height;
-    pdev->brush_dib.width  = pattern->width;
+    pdev->brush_dib.height = pattern.height;
+    pdev->brush_dib.width  = pattern.width;
     pdev->brush_dib.stride = get_dib_stride( pdev->brush_dib.width, pdev->brush_dib.bit_count );
 
-    if (matching_pattern_format( &pdev->brush_dib, pattern ))
+    if (matching_pattern_format( &pdev->brush_dib, &pattern ))
     {
-        pdev->brush_dib.bits.ptr     = pattern->bits.ptr;
+        pdev->brush_dib.bits.ptr     = pattern.bits.ptr;
         pdev->brush_dib.bits.is_copy = FALSE;
         pdev->brush_dib.bits.free    = NULL;
-        return;
     }
+    else
+    {
+        pdev->brush_dib.bits.ptr     = HeapAlloc( GetProcessHeap(), 0,
+                                                  pdev->brush_dib.height * pdev->brush_dib.stride );
+        pdev->brush_dib.bits.is_copy = TRUE;
+        pdev->brush_dib.bits.free    = free_heap_bits;
 
-    pdev->brush_dib.bits.ptr     = HeapAlloc( GetProcessHeap(), 0,
-                                              pdev->brush_dib.height * pdev->brush_dib.stride );
-    pdev->brush_dib.bits.is_copy = TRUE;
-    pdev->brush_dib.bits.free    = free_heap_bits;
+        rect.left = rect.top = 0;
+        rect.right = pattern.width;
+        rect.bottom = pattern.height;
 
-    rect.left = rect.top = 0;
-    rect.right = pattern->width;
-    rect.bottom = pattern->height;
+        pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, &pattern, &rect);
+    }
 
-    pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, pattern, &rect);
+    free_dib_info( &pattern );
+    return TRUE;
 }
 
 /**********************************************************************
@@ -1516,15 +1543,8 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
         switch(pdev->brush_style)
         {
         case BS_DIBPATTERN:
-            if (pdev->brush_pattern_usage == DIB_PAL_COLORS)
-            {
-                dib_info pattern;
-                if (!init_dib_info_from_brush( &pattern, pdev->brush_pattern_info,
-                                               pdev->brush_pattern_bits, DIB_PAL_COLORS, pdev->dev.hdc ))
-                    return FALSE;
-                select_pattern_brush( pdev, &pattern );
-                free_dib_info( &pattern );
-            }
+            if (!pdev->brush_dib.bits.ptr && !select_pattern_brush( pdev ))
+                return FALSE;
             if(!create_pattern_brush_bits(pdev))
                 return FALSE;
             break;
@@ -1582,7 +1602,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
 
     /* we need to recompute the bits each time for DIB_PAL_COLORS */
     if (pdev->brush_style == BS_DIBPATTERN && pdev->brush_pattern_usage == DIB_PAL_COLORS)
-        free_pattern_brush_bits( pdev );
+        free_pattern_brush( pdev );
 
     return TRUE;
 }
@@ -1614,38 +1634,14 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
 
     if (bitmap || info)  /* pattern brush */
     {
-        dib_info pattern;
-        BOOL ret;
-
-        if (!info)
-        {
-            BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
-
-            if (!bmp) return 0;
-            ret = init_dib_info_from_bitmapobj( &pattern, bmp, 0 );
-            GDI_ReleaseObj( bitmap );
-            if (!ret) return 0;
-            select_pattern_brush( pdev, &pattern );
-            free_dib_info( &pattern );
-        }
-        else if (usage != DIB_PAL_COLORS)
-        {
-            if (!init_dib_info_from_brush( &pattern, info, bits, DIB_RGB_COLORS, 0 )) return 0;
-            select_pattern_brush( pdev, &pattern );
-            free_dib_info( &pattern );
-        }
-        else
-        {
-            /* brush is actually selected only when it's used */
-            free_pattern_brush( pdev );
-        }
-
         pdev->brush_rects = pattern_brush;
         pdev->brush_style = BS_DIBPATTERN;
         pdev->brush_pattern_info = info;
         pdev->brush_pattern_bits = bits;
         pdev->brush_pattern_usage = usage;
+        pdev->brush_pattern_bitmap = bitmap;
         pdev->defer &= ~DEFER_BRUSH;
+        free_pattern_brush( pdev ); /* brush is actually selected only when it's used */
 
         return next->funcs->pSelectBrush( next, hbrush, bitmap, info, bits, usage );
     }




More information about the wine-cvs mailing list