/*********************************************************************** * CreateBrushIndirect (GDI32.@) * * Create a logical brush with a given style, color or pattern. * * PARAMS * brush [I] Pointer to a LOGBRUSH structure describing the desired brush. * * RETURNS * A handle to the created brush, or a NULL handle if the brush cannot be * created. * * NOTES * - The brush returned should be freed by the caller using DeleteObject() * when it is no longer required. * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap * is used. */ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * ptr; HBRUSH hbrush; HGLOBAL hmem = 0; if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) return 0; ptr->logbrush = *brush; switch (ptr->logbrush.lbStyle) { 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); return hbrush; } error: if (ptr->bitmap) DeleteObject( ptr->bitmap ); HeapFree( GetProcessHeap(), 0, ptr->info ); HeapFree( GetProcessHeap(), 0, ptr ); return 0; }
BOOL store_brush_pattern( LOGBRUSH *brush, struct brush_pattern *pattern ) { HGLOBAL hmem = 0; pattern->info = NULL; pattern->bits.free = NULL; switch (brush->lbStyle) { case BS_SOLID: case BS_HOLLOW: return TRUE; case BS_HATCHED: if (brush->lbHatch > HS_DIAGCROSS) { if (brush->lbHatch >= HS_API_MAX) return FALSE; brush->lbStyle = BS_SOLID; brush->lbHatch = 0; } 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; } }