4 * Copyright 1993, 1994 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "ntgdi_private.h"
28 #include "wine/debug.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
32 /* GDI logical brush object */
35 struct gdi_obj_header obj
;
37 struct brush_pattern pattern
;
40 #define NB_HATCH_STYLES 6
42 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
);
43 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
);
45 static const struct gdi_obj_funcs brush_funcs
=
47 BRUSH_GetObject
, /* pGetObjectW */
48 NULL
, /* pUnrealizeObject */
49 BRUSH_DeleteObject
/* pDeleteObject */
53 static BOOL
copy_bitmap( struct brush_pattern
*brush
, HBITMAP bitmap
)
55 char buffer
[FIELD_OFFSET( BITMAPINFO
, bmiColors
[256])];
56 BITMAPINFO
*info
= (BITMAPINFO
*)buffer
;
57 struct gdi_image_bits bits
;
58 struct bitblt_coords src
;
59 BITMAPOBJ
*bmp
= GDI_GetObjPtr( bitmap
, NTGDI_OBJ_BITMAP
);
61 if (!bmp
) return FALSE
;
63 src
.visrect
.left
= src
.x
= 0;
64 src
.visrect
.top
= src
.y
= 0;
65 src
.visrect
.right
= src
.width
= bmp
->dib
.dsBm
.bmWidth
;
66 src
.visrect
.bottom
= src
.height
= bmp
->dib
.dsBm
.bmHeight
;
67 if (get_image_from_bitmap( bmp
, info
, &bits
, &src
)) goto done
;
72 if (!(brush
->bits
.ptr
= HeapAlloc( GetProcessHeap(), 0, info
->bmiHeader
.biSizeImage
))) goto done
;
73 memcpy( brush
->bits
.ptr
, bits
.ptr
, info
->bmiHeader
.biSizeImage
);
74 brush
->bits
.free
= free_heap_bits
;
77 if (!(brush
->info
= HeapAlloc( GetProcessHeap(), 0, get_dib_info_size( info
, DIB_RGB_COLORS
))))
79 if (brush
->bits
.free
) brush
->bits
.free( &brush
->bits
);
82 memcpy( brush
->info
, info
, get_dib_info_size( info
, DIB_RGB_COLORS
));
83 brush
->bits
.is_copy
= FALSE
; /* the bits can't be modified */
84 brush
->usage
= DIB_RGB_COLORS
;
87 GDI_ReleaseObj( bitmap
);
88 return brush
->info
!= NULL
;
91 BOOL
store_brush_pattern( LOGBRUSH
*brush
, struct brush_pattern
*pattern
)
96 pattern
->bits
.free
= NULL
;
98 switch (brush
->lbStyle
)
105 if (brush
->lbHatch
> HS_DIAGCROSS
)
107 if (brush
->lbHatch
>= HS_API_MAX
) return FALSE
;
108 brush
->lbStyle
= BS_SOLID
;
114 brush
->lbStyle
= BS_PATTERN
;
118 return copy_bitmap( pattern
, (HBITMAP
)brush
->lbHatch
);
121 hmem
= (HGLOBAL
)brush
->lbHatch
;
122 if (!(brush
->lbHatch
= (ULONG_PTR
)GlobalLock( hmem
))) return FALSE
;
124 case BS_DIBPATTERNPT
:
125 pattern
->usage
= brush
->lbColor
;
126 pattern
->info
= copy_packed_dib( (BITMAPINFO
*)brush
->lbHatch
, pattern
->usage
);
127 if (hmem
) GlobalUnlock( hmem
);
128 if (!pattern
->info
) return FALSE
;
129 pattern
->bits
.ptr
= (char *)pattern
->info
+ get_dib_info_size( pattern
->info
, pattern
->usage
);
130 brush
->lbStyle
= BS_DIBPATTERN
;
134 case BS_DIBPATTERN8X8
:
138 WARN( "invalid brush style %u\n", brush
->lbStyle
);
143 void free_brush_pattern( struct brush_pattern
*pattern
)
145 if (pattern
->bits
.free
) pattern
->bits
.free( &pattern
->bits
);
146 HeapFree( GetProcessHeap(), 0, pattern
->info
);
149 BOOL
get_brush_bitmap_info( HBRUSH handle
, BITMAPINFO
*info
, void **bits
, UINT
*usage
)
154 if (!(brush
= GDI_GetObjPtr( handle
, NTGDI_OBJ_BRUSH
))) return FALSE
;
156 if (brush
->pattern
.info
)
158 memcpy( info
, brush
->pattern
.info
, get_dib_info_size( brush
->pattern
.info
, brush
->pattern
.usage
));
159 if (info
->bmiHeader
.biBitCount
<= 8 && !info
->bmiHeader
.biClrUsed
)
160 fill_default_color_table( info
);
161 *bits
= brush
->pattern
.bits
.ptr
;
162 *usage
= brush
->pattern
.usage
;
165 GDI_ReleaseObj( handle
);
170 /***********************************************************************
171 * CreateBrushIndirect (GDI32.@)
173 * Create a logical brush with a given style, color or pattern.
176 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
179 * A handle to the created brush, or a NULL handle if the brush cannot be
183 * - The brush returned should be freed by the caller using DeleteObject()
184 * when it is no longer required.
185 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
186 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
189 HBRUSH WINAPI
CreateBrushIndirect( const LOGBRUSH
* brush
)
194 if (!(ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr
) ))) return 0;
196 ptr
->logbrush
= *brush
;
198 if (store_brush_pattern( &ptr
->logbrush
, &ptr
->pattern
) &&
199 (hbrush
= alloc_gdi_handle( &ptr
->obj
, NTGDI_OBJ_BRUSH
, &brush_funcs
)))
201 TRACE("%p\n", hbrush
);
205 free_brush_pattern( &ptr
->pattern
);
206 HeapFree( GetProcessHeap(), 0, ptr
);
211 /***********************************************************************
212 * CreateHatchBrush (GDI32.@)
214 * Create a logical brush with a hatched pattern.
217 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
218 * color [I] Colour of the hatched pattern
221 * A handle to the created brush, or a NULL handle if the brush cannot
225 * - This function uses CreateBrushIndirect() to create the brush.
226 * - The brush returned should be freed by the caller using DeleteObject()
227 * when it is no longer required.
229 HBRUSH WINAPI
CreateHatchBrush( INT style
, COLORREF color
)
233 TRACE("%d %06x\n", style
, color
);
235 logbrush
.lbStyle
= BS_HATCHED
;
236 logbrush
.lbColor
= color
;
237 logbrush
.lbHatch
= style
;
239 return CreateBrushIndirect( &logbrush
);
243 /***********************************************************************
244 * CreatePatternBrush (GDI32.@)
246 * Create a logical brush with a pattern from a bitmap.
249 * hbitmap [I] Bitmap containing pattern for the brush
252 * A handle to the created brush, or a NULL handle if the brush cannot
256 * - This function uses CreateBrushIndirect() to create the brush.
257 * - The brush returned should be freed by the caller using DeleteObject()
258 * when it is no longer required.
260 HBRUSH WINAPI
CreatePatternBrush( HBITMAP hbitmap
)
262 LOGBRUSH logbrush
= { BS_PATTERN
, 0, 0 };
263 TRACE("%p\n", hbitmap
);
265 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
266 return CreateBrushIndirect( &logbrush
);
270 /***********************************************************************
271 * CreateDIBPatternBrush (GDI32.@)
273 * Create a logical brush with a pattern from a DIB.
276 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
277 * coloruse [I] Specifies color format, if provided
280 * A handle to the created brush, or a NULL handle if the brush cannot
284 * - This function uses CreateBrushIndirect() to create the brush.
285 * - The brush returned should be freed by the caller using DeleteObject()
286 * when it is no longer required.
287 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
290 HBRUSH WINAPI
CreateDIBPatternBrush( HGLOBAL hbitmap
, UINT coloruse
)
294 TRACE("%p\n", hbitmap
);
296 logbrush
.lbStyle
= BS_DIBPATTERN
;
297 logbrush
.lbColor
= coloruse
;
299 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
301 return CreateBrushIndirect( &logbrush
);
305 /***********************************************************************
306 * CreateDIBPatternBrushPt (GDI32.@)
308 * Create a logical brush with a pattern from a DIB.
311 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
312 * coloruse [I] Specifies color format, if provided
315 * A handle to the created brush, or a NULL handle if the brush cannot
319 * - This function uses CreateBrushIndirect() to create the brush.
320 * - The brush returned should be freed by the caller using DeleteObject()
321 * when it is no longer required.
323 HBRUSH WINAPI
CreateDIBPatternBrushPt( const void* data
, UINT coloruse
)
325 const BITMAPINFO
*info
=data
;
331 TRACE("%p %dx%d %dbpp\n", info
, info
->bmiHeader
.biWidth
,
332 info
->bmiHeader
.biHeight
, info
->bmiHeader
.biBitCount
);
334 logbrush
.lbStyle
= BS_DIBPATTERNPT
;
335 logbrush
.lbColor
= coloruse
;
336 logbrush
.lbHatch
= (ULONG_PTR
)data
;
338 return CreateBrushIndirect( &logbrush
);
342 /***********************************************************************
343 * CreateSolidBrush (GDI32.@)
345 * Create a logical brush consisting of a single colour.
348 * color [I] Colour to make the solid brush
351 * A handle to the newly created brush, or a NULL handle if the brush cannot
355 * - This function uses CreateBrushIndirect() to create the brush.
356 * - The brush returned should be freed by the caller using DeleteObject()
357 * when it is no longer required.
359 HBRUSH WINAPI
CreateSolidBrush( COLORREF color
)
363 TRACE("%06x\n", color
);
365 logbrush
.lbStyle
= BS_SOLID
;
366 logbrush
.lbColor
= color
;
367 logbrush
.lbHatch
= 0;
369 return CreateBrushIndirect( &logbrush
);
373 /***********************************************************************
374 * SetBrushOrgEx (GDI32.@)
376 * Set the brush origin for a device context.
379 * hdc [I] Device context to set the brush origin for
382 * oldorg [O] If non NULL, destination for previously set brush origin.
385 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
387 BOOL WINAPI
SetBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
389 DC
*dc
= get_dc_ptr( hdc
);
391 if (!dc
) return FALSE
;
393 *oldorg
= dc
->attr
->brush_org
;
395 dc
->attr
->brush_org
.x
= x
;
396 dc
->attr
->brush_org
.y
= y
;
397 release_dc_ptr( dc
);
401 /***********************************************************************
402 * FixBrushOrgEx (GDI32.@)
407 * This function is no longer documented by MSDN, but in Win95 GDI32 it
408 * is the same as SetBrushOrgEx().
410 BOOL WINAPI
FixBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
412 return SetBrushOrgEx(hdc
,x
,y
,oldorg
);
416 /***********************************************************************
417 * NtGdiSelectBrush (win32u.@)
419 HGDIOBJ WINAPI
NtGdiSelectBrush( HDC hdc
, HGDIOBJ handle
)
425 if (!(dc
= get_dc_ptr( hdc
))) return 0;
427 if ((brush
= GDI_GetObjPtr( handle
, NTGDI_OBJ_BRUSH
)))
429 PHYSDEV physdev
= GET_DC_PHYSDEV( dc
, pSelectBrush
);
430 struct brush_pattern
*pattern
= &brush
->pattern
;
432 if (!pattern
->info
) pattern
= NULL
;
434 GDI_inc_ref_count( handle
);
435 GDI_ReleaseObj( handle
);
437 if (!physdev
->funcs
->pSelectBrush( physdev
, handle
, pattern
))
439 GDI_dec_ref_count( handle
);
445 GDI_dec_ref_count( ret
);
448 release_dc_ptr( dc
);
453 /***********************************************************************
456 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
)
458 BRUSHOBJ
*brush
= free_gdi_handle( handle
);
460 if (!brush
) return FALSE
;
461 free_brush_pattern( &brush
->pattern
);
462 HeapFree( GetProcessHeap(), 0, brush
);
467 /***********************************************************************
470 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
)
472 BRUSHOBJ
*brush
= GDI_GetObjPtr( handle
, NTGDI_OBJ_BRUSH
);
474 if (!brush
) return 0;
477 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
478 memcpy( buffer
, &brush
->logbrush
, count
);
480 else count
= sizeof(brush
->logbrush
);
481 GDI_ReleaseObj( handle
);