Alexandre Julliard : gdi32: Reselect the pattern brush on every use if it' s mapped with DIB_PAL_COLORS.

Alexandre Julliard julliard at winehq.org
Tue Nov 8 12:23:10 CST 2011


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Nov  8 13:18:01 2011 +0100

gdi32: Reselect the pattern brush on every use if it's mapped with DIB_PAL_COLORS.

---

 dlls/gdi32/dibdrv/dibdrv.h  |    3 +
 dlls/gdi32/dibdrv/objects.c |   86 +++++++++++++++++++++++++++++--------------
 dlls/gdi32/tests/brush.c    |    2 +-
 3 files changed, 62 insertions(+), 29 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index 0650e08..6ef0d94 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -90,6 +90,9 @@ typedef struct dibdrv_physdev
     DWORD brush_color, brush_and, brush_xor;
     dib_info brush_dib;
     void *brush_and_bits, *brush_xor_bits;
+    const BITMAPINFO *brush_pattern_info;
+    void *brush_pattern_bits;
+    UINT brush_pattern_usage;
     BOOL   (* brush_rects)(struct dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, HRGN clip);
 
     /* background */
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index 3418dc8..cf714b5 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1246,6 +1246,30 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev)
     return ret;
 }
 
+static void select_pattern_brush( dibdrv_physdev *pdev, dib_info *pattern )
+{
+    RECT rect;
+
+    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.stride = get_dib_stride( pdev->brush_dib.width, pdev->brush_dib.bit_count );
+
+    pdev->brush_dib.bits.param   = NULL;
+    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;
+
+    pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, pattern, &rect);
+}
+
 /**********************************************************************
  *             pattern_brush
  *
@@ -1263,6 +1287,16 @@ 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;
+                HPALETTE pal = GetCurrentObject( pdev->dev.hdc, OBJ_PAL );
+                if (!init_dib_info_from_brush( &pattern, pdev->brush_pattern_info,
+                                               pdev->brush_pattern_bits, DIB_PAL_COLORS, pal ))
+                    return FALSE;
+                select_pattern_brush( pdev, &pattern );
+                free_dib_info( &pattern );
+            }
             if(!create_pattern_brush_bits(pdev))
                 return FALSE;
             break;
@@ -1317,6 +1351,11 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
         }
     }
     release_wine_region( region );
+
+    /* 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 );
+
     return TRUE;
 }
 
@@ -1347,9 +1386,7 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
 
     if (bitmap || info)  /* pattern brush */
     {
-        dib_info orig_dib;
-        HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL;
-        RECT rect;
+        dib_info pattern;
         BOOL ret;
 
         if (!info)
@@ -1357,37 +1394,30 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
             BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
 
             if (!bmp) return 0;
-            ret = init_dib_info_from_bitmapobj( &orig_dib, bmp, 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 );
         }
-        else ret = init_dib_info_from_brush( &orig_dib, info, bits, usage, pal );
-
-        if (!ret) return 0;
-
-        if (usage == DIB_PAL_COLORS) FIXME( "DIB_PAL_COLORS brush not handled correctly\n");
-
-        free_pattern_brush( pdev );
-        copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
-
-        pdev->brush_dib.height = orig_dib.height;
-        pdev->brush_dib.width  = orig_dib.width;
-        pdev->brush_dib.stride = get_dib_stride( pdev->brush_dib.width, pdev->brush_dib.bit_count );
-
-        pdev->brush_dib.bits.param   = NULL;
-        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 = orig_dib.width;
-        rect.bottom = orig_dib.height;
 
-        pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, &orig_dib, &rect);
         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->defer &= ~DEFER_BRUSH;
-        free_dib_info(&orig_dib);
 
         return next->funcs->pSelectBrush( next, hbrush, bitmap, info, bits, usage );
     }
diff --git a/dlls/gdi32/tests/brush.c b/dlls/gdi32/tests/brush.c
index f0ef2df..c6c7678 100644
--- a/dlls/gdi32/tests/brush.c
+++ b/dlls/gdi32/tests/brush.c
@@ -288,7 +288,7 @@ static void test_palette_brush(void)
                         pal->palPalEntry[255 - i].peGreen << 8 |
                         pal->palPalEntry[255 - i].peBlue);
         if (expect)
-            todo_wine ok( dib_bits[i] == expect, "wrong bits %x/%x at %u,%u\n", dib_bits[i], expect, i % 16, i / 16 );
+            ok( dib_bits[i] == expect, "wrong bits %x/%x at %u,%u\n", dib_bits[i], expect, i % 16, i / 16 );
         else
             ok( dib_bits[i] == expect, "wrong bits %x/%x at %u,%u\n", dib_bits[i], expect, i % 16, i / 16 );
     }




More information about the wine-cvs mailing list