gdi32: Add a structure to store all the extra information needed for a pattern brush.
This commit is contained in:
parent
5a67227078
commit
8bf48557ef
|
@ -36,10 +36,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
GDIOBJHDR header;
|
GDIOBJHDR header;
|
||||||
LOGBRUSH logbrush;
|
LOGBRUSH logbrush;
|
||||||
HBITMAP bitmap; /* bitmap handle for DDB pattern brushes */
|
struct brush_pattern pattern;
|
||||||
BITMAPINFO *info; /* DIB info for pattern brushes */
|
|
||||||
struct gdi_image_bits bits; /* DIB bits for pattern brushes */
|
|
||||||
UINT usage; /* color usage for DIB info */
|
|
||||||
} BRUSHOBJ;
|
} BRUSHOBJ;
|
||||||
|
|
||||||
#define NB_HATCH_STYLES 6
|
#define NB_HATCH_STYLES 6
|
||||||
|
@ -58,8 +55,8 @@ static const struct gdi_obj_funcs brush_funcs =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* fetch the contents of the brush bitmap and cache them in the brush object */
|
/* fetch the contents of the brush bitmap and cache them in the brush pattern */
|
||||||
static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
|
static BOOL store_bitmap_bits( struct brush_pattern *brush, BITMAPOBJ *bmp )
|
||||||
{
|
{
|
||||||
const struct gdi_dc_funcs *funcs = get_bitmap_funcs( bmp );
|
const struct gdi_dc_funcs *funcs = get_bitmap_funcs( bmp );
|
||||||
struct gdi_image_bits bits;
|
struct gdi_image_bits bits;
|
||||||
|
@ -88,7 +85,7 @@ static BOOL store_bitmap_bits( BRUSHOBJ *brush, BITMAPOBJ *bmp )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL copy_bitmap( BRUSHOBJ *brush, HBITMAP bitmap )
|
static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
|
||||||
{
|
{
|
||||||
BITMAPINFO *info;
|
BITMAPINFO *info;
|
||||||
BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
|
BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
|
||||||
|
@ -140,6 +137,58 @@ done:
|
||||||
return brush->info != NULL;
|
return brush->info != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern )
|
||||||
|
{
|
||||||
|
HGLOBAL hmem = 0;
|
||||||
|
|
||||||
|
pattern->bitmap = 0;
|
||||||
|
pattern->info = NULL;
|
||||||
|
pattern->bits.free = NULL;
|
||||||
|
|
||||||
|
switch (brush->lbStyle)
|
||||||
|
{
|
||||||
|
case BS_SOLID:
|
||||||
|
case BS_HOLLOW:
|
||||||
|
case BS_HATCHED:
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case BS_PATTERN8X8:
|
||||||
|
brush->lbStyle = BS_PATTERN;
|
||||||
|
/* fall through */
|
||||||
|
case BS_PATTERN:
|
||||||
|
brush->lbColor = 0;
|
||||||
|
return copy_bitmap( pattern, (HBITMAP)brush->lbHatch );
|
||||||
|
|
||||||
|
case BS_DIBPATTERN:
|
||||||
|
hmem = (HGLOBAL)brush->lbHatch;
|
||||||
|
if (!(brush->lbHatch = (ULONG_PTR)GlobalLock( hmem ))) return FALSE;
|
||||||
|
/* fall through */
|
||||||
|
case BS_DIBPATTERNPT:
|
||||||
|
pattern->usage = brush->lbColor;
|
||||||
|
pattern->info = copy_packed_dib( (BITMAPINFO *)brush->lbHatch, pattern->usage );
|
||||||
|
if (hmem) GlobalUnlock( hmem );
|
||||||
|
if (!pattern->info) return FALSE;
|
||||||
|
pattern->bits.ptr = (char *)pattern->info + get_dib_info_size( pattern->info, pattern->usage );
|
||||||
|
brush->lbStyle = BS_DIBPATTERN;
|
||||||
|
brush->lbColor = 0;
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case BS_DIBPATTERN8X8:
|
||||||
|
case BS_MONOPATTERN:
|
||||||
|
case BS_INDEXED:
|
||||||
|
default:
|
||||||
|
WARN( "invalid brush style %u\n", brush->lbStyle );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_brush_pattern( struct brush_pattern *pattern )
|
||||||
|
{
|
||||||
|
if (pattern->bits.free) pattern->bits.free( &pattern->bits );
|
||||||
|
if (pattern->bitmap) DeleteObject( pattern->bitmap );
|
||||||
|
HeapFree( GetProcessHeap(), 0, pattern->info );
|
||||||
|
}
|
||||||
|
|
||||||
BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage )
|
BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage )
|
||||||
{
|
{
|
||||||
BRUSHOBJ *brush;
|
BRUSHOBJ *brush;
|
||||||
|
@ -147,23 +196,23 @@ BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *
|
||||||
|
|
||||||
if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE;
|
if (!(brush = GDI_GetObjPtr( handle, OBJ_BRUSH ))) return FALSE;
|
||||||
|
|
||||||
if (!brush->info)
|
if (!brush->pattern.info)
|
||||||
{
|
{
|
||||||
BITMAPOBJ *bmp = GDI_GetObjPtr( brush->bitmap, OBJ_BITMAP );
|
BITMAPOBJ *bmp = GDI_GetObjPtr( brush->pattern.bitmap, OBJ_BITMAP );
|
||||||
|
|
||||||
if (bmp)
|
if (bmp)
|
||||||
{
|
{
|
||||||
store_bitmap_bits( brush, bmp );
|
store_bitmap_bits( &brush->pattern, bmp );
|
||||||
GDI_ReleaseObj( brush->bitmap );
|
GDI_ReleaseObj( brush->pattern.bitmap );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (brush->info)
|
if (brush->pattern.info)
|
||||||
{
|
{
|
||||||
memcpy( info, brush->info, get_dib_info_size( brush->info, brush->usage ));
|
memcpy( info, brush->pattern.info, get_dib_info_size( brush->pattern.info, brush->pattern.usage ));
|
||||||
if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed)
|
if (info->bmiHeader.biBitCount <= 8 && !info->bmiHeader.biClrUsed)
|
||||||
fill_default_color_table( info );
|
fill_default_color_table( info );
|
||||||
*bits = brush->bits.ptr;
|
*bits = brush->pattern.bits.ptr;
|
||||||
*usage = brush->usage;
|
*usage = brush->pattern.usage;
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
GDI_ReleaseObj( handle );
|
GDI_ReleaseObj( handle );
|
||||||
|
@ -194,58 +243,19 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
|
||||||
{
|
{
|
||||||
BRUSHOBJ * ptr;
|
BRUSHOBJ * ptr;
|
||||||
HBRUSH hbrush;
|
HBRUSH hbrush;
|
||||||
HGLOBAL hmem = 0;
|
|
||||||
|
|
||||||
if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) return 0;
|
if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0;
|
||||||
|
|
||||||
ptr->logbrush = *brush;
|
ptr->logbrush = *brush;
|
||||||
|
|
||||||
switch (ptr->logbrush.lbStyle)
|
if (store_brush_pattern( &ptr->logbrush, &ptr->pattern ) &&
|
||||||
{
|
(hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
|
||||||
case BS_SOLID:
|
|
||||||
case BS_HOLLOW:
|
|
||||||
case BS_HATCHED:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BS_PATTERN8X8:
|
|
||||||
ptr->logbrush.lbStyle = BS_PATTERN;
|
|
||||||
/* fall through */
|
|
||||||
case BS_PATTERN:
|
|
||||||
if (!copy_bitmap( ptr, (HBITMAP)ptr->logbrush.lbHatch )) goto error;
|
|
||||||
ptr->logbrush.lbColor = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BS_DIBPATTERN:
|
|
||||||
hmem = (HGLOBAL)ptr->logbrush.lbHatch;
|
|
||||||
if (!(ptr->logbrush.lbHatch = (ULONG_PTR)GlobalLock( hmem ))) goto error;
|
|
||||||
/* fall through */
|
|
||||||
case BS_DIBPATTERNPT:
|
|
||||||
ptr->usage = ptr->logbrush.lbColor;
|
|
||||||
ptr->info = copy_packed_dib( (BITMAPINFO *)ptr->logbrush.lbHatch, ptr->usage );
|
|
||||||
if (hmem) GlobalUnlock( hmem );
|
|
||||||
if (!ptr->info) goto error;
|
|
||||||
ptr->bits.ptr = (char *)ptr->info + get_dib_info_size( ptr->info, ptr->usage );
|
|
||||||
ptr->logbrush.lbStyle = BS_DIBPATTERN;
|
|
||||||
ptr->logbrush.lbColor = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BS_DIBPATTERN8X8:
|
|
||||||
case BS_MONOPATTERN:
|
|
||||||
case BS_INDEXED:
|
|
||||||
default:
|
|
||||||
WARN( "invalid brush style %u\n", ptr->logbrush.lbStyle );
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
|
|
||||||
{
|
{
|
||||||
TRACE("%p\n", hbrush);
|
TRACE("%p\n", hbrush);
|
||||||
return hbrush;
|
return hbrush;
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
free_brush_pattern( &ptr->pattern );
|
||||||
if (ptr->bitmap) DeleteObject( ptr->bitmap );
|
|
||||||
HeapFree( GetProcessHeap(), 0, ptr->info );
|
|
||||||
HeapFree( GetProcessHeap(), 0, ptr );
|
HeapFree( GetProcessHeap(), 0, ptr );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -476,22 +486,22 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
|
||||||
if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH )))
|
if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH )))
|
||||||
{
|
{
|
||||||
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush );
|
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSelectBrush );
|
||||||
HBITMAP bitmap = brush->bitmap;
|
HBITMAP bitmap = brush->pattern.bitmap;
|
||||||
BITMAPINFO *info;
|
BITMAPINFO *info;
|
||||||
void *bits;
|
void *bits;
|
||||||
UINT usage;
|
UINT usage;
|
||||||
|
|
||||||
if (bitmap && !brush->info)
|
if (bitmap && !brush->pattern.info)
|
||||||
{
|
{
|
||||||
BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
|
BITMAPOBJ *bmp = GDI_GetObjPtr( bitmap, OBJ_BITMAP );
|
||||||
/* fetch the bitmap bits if we are selecting into a different type of DC */
|
/* fetch the bitmap bits if we are selecting into a different type of DC */
|
||||||
if (bmp && bmp->funcs != physdev->funcs) store_bitmap_bits( brush, bmp );
|
if (bmp && bmp->funcs != physdev->funcs) store_bitmap_bits( &brush->pattern, bmp );
|
||||||
GDI_ReleaseObj( bitmap );
|
GDI_ReleaseObj( bitmap );
|
||||||
}
|
}
|
||||||
|
|
||||||
info = brush->info;
|
info = brush->pattern.info;
|
||||||
bits = brush->bits.ptr;
|
bits = brush->pattern.bits.ptr;
|
||||||
usage = brush->usage;
|
usage = brush->pattern.usage;
|
||||||
GDI_inc_ref_count( handle );
|
GDI_inc_ref_count( handle );
|
||||||
GDI_ReleaseObj( handle );
|
GDI_ReleaseObj( handle );
|
||||||
|
|
||||||
|
@ -519,9 +529,7 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
|
||||||
BRUSHOBJ *brush = free_gdi_handle( handle );
|
BRUSHOBJ *brush = free_gdi_handle( handle );
|
||||||
|
|
||||||
if (!brush) return FALSE;
|
if (!brush) return FALSE;
|
||||||
if (brush->bits.free) brush->bits.free( &brush->bits );
|
free_brush_pattern( &brush->pattern );
|
||||||
if (brush->bitmap) DeleteObject( brush->bitmap );
|
|
||||||
HeapFree( GetProcessHeap(), 0, brush->info );
|
|
||||||
return HeapFree( GetProcessHeap(), 0, brush );
|
return HeapFree( GetProcessHeap(), 0, brush );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,14 @@ typedef struct tagBITMAPOBJ
|
||||||
RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */
|
RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */
|
||||||
} BITMAPOBJ;
|
} BITMAPOBJ;
|
||||||
|
|
||||||
|
struct brush_pattern
|
||||||
|
{
|
||||||
|
HBITMAP bitmap; /* bitmap handle for DDB patterns */
|
||||||
|
BITMAPINFO *info; /* DIB info */
|
||||||
|
struct gdi_image_bits bits; /* DIB bits */
|
||||||
|
UINT usage; /* color usage for DIB info */
|
||||||
|
};
|
||||||
|
|
||||||
/* bidi.c */
|
/* bidi.c */
|
||||||
|
|
||||||
/* Wine_GCPW Flags */
|
/* Wine_GCPW Flags */
|
||||||
|
@ -208,6 +216,8 @@ extern DWORD stretch_bits( const BITMAPINFO *src_info, struct bitblt_coords *src
|
||||||
struct gdi_image_bits *bits, int mode ) DECLSPEC_HIDDEN;
|
struct gdi_image_bits *bits, int mode ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* brush.c */
|
/* brush.c */
|
||||||
|
extern BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
|
||||||
|
extern void free_brush_pattern( struct brush_pattern *pattern ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
|
extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
/* clipping.c */
|
/* clipping.c */
|
||||||
|
|
Loading…
Reference in New Issue