Commit d5fe87e2 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Select the pattern brush only when first used.

parent d353c95d
...@@ -167,20 +167,6 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD ...@@ -167,20 +167,6 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
return TRUE; 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) 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, return init_dib_info( dib, &info->bmiHeader, (const DWORD *)info->bmiColors,
......
...@@ -103,6 +103,7 @@ typedef struct dibdrv_physdev ...@@ -103,6 +103,7 @@ typedef struct dibdrv_physdev
const BITMAPINFO *brush_pattern_info; const BITMAPINFO *brush_pattern_info;
void *brush_pattern_bits; void *brush_pattern_bits;
UINT brush_pattern_usage; 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); BOOL (* brush_rects)(struct dibdrv_physdev *pdev, dib_info *dib, int num, const RECT *rects, HRGN clip);
/* background */ /* background */
...@@ -226,7 +227,6 @@ extern void get_rop_codes(INT rop, struct rop_codes *codes) DECLSPEC_HIDDEN; ...@@ -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 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 update_brush_rop( dibdrv_physdev *pdev, INT rop ) DECLSPEC_HIDDEN;
extern void reset_dash_origin(dibdrv_physdev *pdev) 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, extern BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits,
enum dib_info_flags flags) DECLSPEC_HIDDEN; 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; extern BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) DECLSPEC_HIDDEN;
......
...@@ -1468,35 +1468,62 @@ static BOOL matching_pattern_format( dib_info *dib, dib_info *pattern ) ...@@ -1468,35 +1468,62 @@ static BOOL matching_pattern_format( dib_info *dib, dib_info *pattern )
return TRUE; 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; 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); copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
pdev->brush_dib.height = pattern->height; pdev->brush_dib.height = pattern.height;
pdev->brush_dib.width = pattern->width; 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.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.is_copy = FALSE;
pdev->brush_dib.bits.free = NULL; 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, rect.left = rect.top = 0;
pdev->brush_dib.height * pdev->brush_dib.stride ); rect.right = pattern.width;
pdev->brush_dib.bits.is_copy = TRUE; rect.bottom = pattern.height;
pdev->brush_dib.bits.free = free_heap_bits;
rect.left = rect.top = 0; pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, &pattern, &rect);
rect.right = pattern->width; }
rect.bottom = pattern->height;
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 ...@@ -1516,15 +1543,8 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE
switch(pdev->brush_style) switch(pdev->brush_style)
{ {
case BS_DIBPATTERN: case BS_DIBPATTERN:
if (pdev->brush_pattern_usage == DIB_PAL_COLORS) if (!pdev->brush_dib.bits.ptr && !select_pattern_brush( pdev ))
{ return FALSE;
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(!create_pattern_brush_bits(pdev)) if(!create_pattern_brush_bits(pdev))
return FALSE; return FALSE;
break; break;
...@@ -1582,7 +1602,7 @@ static BOOL pattern_brush(dibdrv_physdev *pdev, dib_info *dib, int num, const RE ...@@ -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 */ /* 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) if (pdev->brush_style == BS_DIBPATTERN && pdev->brush_pattern_usage == DIB_PAL_COLORS)
free_pattern_brush_bits( pdev ); free_pattern_brush( pdev );
return TRUE; return TRUE;
} }
...@@ -1614,38 +1634,14 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap, ...@@ -1614,38 +1634,14 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush, HBITMAP bitmap,
if (bitmap || info) /* pattern brush */ 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_rects = pattern_brush;
pdev->brush_style = BS_DIBPATTERN; pdev->brush_style = BS_DIBPATTERN;
pdev->brush_pattern_info = info; pdev->brush_pattern_info = info;
pdev->brush_pattern_bits = bits; pdev->brush_pattern_bits = bits;
pdev->brush_pattern_usage = usage; pdev->brush_pattern_usage = usage;
pdev->brush_pattern_bitmap = bitmap;
pdev->defer &= ~DEFER_BRUSH; 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 ); return next->funcs->pSelectBrush( next, hbrush, bitmap, info, bits, usage );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment