gdi32: Retrieve the brush pattern bits from the cache for metafiles.

oldstable
Alexandre Julliard 2011-11-01 22:05:16 +01:00
parent 199409a27b
commit 7d0b65c4d1
3 changed files with 49 additions and 58 deletions

View File

@ -90,6 +90,35 @@ static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
return TRUE;
}
BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage )
{
BRUSHOBJ *brush;
BOOL ret = FALSE;
if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE;
if (!brush->info)
{
BITMAPOBJ *bmp = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP );
if (bmp)
{
store_bitmap_bits( brush, bmp );
GDI_ReleaseObj( brush->bitmap );
}
}
if (brush->info)
{
memcpy( info, brush->info, bitmap_info_size( brush->info, brush->usage ));
*bits = brush->bits.ptr;
*usage = brush->usage;
ret = TRUE;
}
GDI_ReleaseObj( handle );
return ret;
}
/***********************************************************************
* CreateBrushIndirect (GDI32.@)
*

View File

@ -233,6 +233,8 @@ extern BOOL get_bitmap_image( HBITMAP hbitmap, BITMAPINFO *info, struct gdi_imag
extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap ) DECLSPEC_HIDDEN;
extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, PHYSDEV physdev ) DECLSPEC_HIDDEN;
extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
/* clipping.c */
extern int get_clip_box( DC *dc, RECT *rect ) DECLSPEC_HIDDEN;
extern void CLIPPING_UpdateGCRegion( DC * dc ) DECLSPEC_HIDDEN;

View File

@ -174,86 +174,46 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
break;
}
case BS_PATTERN:
case BS_DIBPATTERN:
{
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *dst_info, *src_info = (BITMAPINFO *)buffer;
struct gdi_image_bits bits;
COLORREF cref;
DWORD info_size, image_size;
char *dst_ptr;
void *bits;
UINT usage;
if (!get_bitmap_image( (HANDLE)logbrush.lbHatch, src_info, &bits )) goto done;
if (src_info->bmiHeader.biBitCount != 1)
{
FIXME("Trying to store a colour pattern brush\n");
if (bits.free) bits.free( &bits );
goto done;
}
if (!get_brush_bitmap_info( hBrush, src_info, &bits, &usage )) goto done;
size = FIELD_OFFSET( METARECORD, rdParm[2] ) +
FIELD_OFFSET( BITMAPINFO, bmiColors[2] ) + src_info->bmiHeader.biSizeImage;
info_size = bitmap_info_size( src_info, usage );
image_size = get_dib_image_size( src_info );
size = FIELD_OFFSET( METARECORD, rdParm[2] ) + info_size + image_size;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, size )))
{
if (bits.free) bits.free( &bits );
goto done;
}
if (!(mr = HeapAlloc( GetProcessHeap(), 0, size ))) goto done;
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
mr->rdParm[0] = BS_PATTERN;
mr->rdParm[1] = DIB_RGB_COLORS;
mr->rdParm[0] = logbrush.lbStyle;
mr->rdParm[1] = usage;
dst_info = (BITMAPINFO *)(mr->rdParm + 2);
dst_info->bmiHeader = src_info->bmiHeader;
dst_info->bmiHeader.biClrUsed = 0;
cref = GetTextColor( dev->hdc );
dst_info->bmiColors[0].rgbRed = GetRValue(cref);
dst_info->bmiColors[0].rgbGreen = GetGValue(cref);
dst_info->bmiColors[0].rgbBlue = GetBValue(cref);
dst_info->bmiColors[0].rgbReserved = 0;
cref = GetBkColor( dev->hdc );
dst_info->bmiColors[1].rgbRed = GetRValue(cref);
dst_info->bmiColors[1].rgbGreen = GetGValue(cref);
dst_info->bmiColors[1].rgbBlue = GetBValue(cref);
dst_info->bmiColors[1].rgbReserved = 0;
memcpy( dst_info, src_info, info_size );
if (dst_info->bmiHeader.biClrUsed == 1 << dst_info->bmiHeader.biBitCount)
dst_info->bmiHeader.biClrUsed = 0;
dst_ptr = (char *)dst_info + info_size;
/* always return a bottom-up DIB */
if (dst_info->bmiHeader.biHeight < 0)
{
int i, width_bytes = get_dib_stride( dst_info->bmiHeader.biWidth,
dst_info->bmiHeader.biBitCount );
char *dst_ptr = (char *)&dst_info->bmiColors[2];
dst_info->bmiHeader.biHeight = -dst_info->bmiHeader.biHeight;
dst_ptr += (dst_info->bmiHeader.biHeight - 1) * width_bytes;
for (i = 0; i < dst_info->bmiHeader.biHeight; i++, dst_ptr -= width_bytes)
memcpy( dst_ptr, (char *)bits.ptr + i * width_bytes, width_bytes );
memcpy( dst_ptr, (char *)bits + i * width_bytes, width_bytes );
}
else memcpy( &dst_info->bmiColors[2], bits.ptr, dst_info->bmiHeader.biSizeImage );
if (bits.free) bits.free( &bits );
else memcpy( dst_ptr, bits, image_size );
break;
}
case BS_DIBPATTERN:
{
BITMAPINFO *info = (BITMAPINFO *)logbrush.lbHatch;
DWORD bmSize, biSize;
if (info->bmiHeader.biCompression)
bmSize = info->bmiHeader.biSizeImage;
else
bmSize = get_dib_image_size( info );
biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
size = sizeof(METARECORD) + biSize + bmSize + 2;
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
if (!mr)
{
GlobalUnlock( (HGLOBAL)logbrush.lbHatch );
goto done;
}
mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
mr->rdSize = size / 2;
*(mr->rdParm) = logbrush.lbStyle;
*(mr->rdParm + 1) = LOWORD(logbrush.lbColor);
memcpy(mr->rdParm + 2, info, biSize + bmSize);
break;
}
default:
FIXME("Unkonwn brush style %x\n", logbrush.lbStyle);
return 0;