Module: wine Branch: master Commit: d5fe87e2e89ed485c9a2c481eb7c43b391047b1f URL: http://source.winehq.org/git/wine.git/?a=commit;h=d5fe87e2e89ed485c9a2c481eb...
Author: Alexandre Julliard julliard@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 ); }