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
29 #include "gdi_private.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
34 /* GDI logical brush object */
41 #define NB_HATCH_STYLES 6
43 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
);
44 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
);
45 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
);
47 static const struct gdi_obj_funcs brush_funcs
=
49 BRUSH_SelectObject
, /* pSelectObject */
50 BRUSH_GetObject
, /* pGetObjectA */
51 BRUSH_GetObject
, /* pGetObjectW */
52 NULL
, /* pUnrealizeObject */
53 BRUSH_DeleteObject
/* pDeleteObject */
56 static HGLOBAL
dib_copy(const BITMAPINFO
*info
, UINT coloruse
)
62 if (info
->bmiHeader
.biCompression
!= BI_RGB
&& info
->bmiHeader
.biCompression
!= BI_BITFIELDS
)
63 size
= info
->bmiHeader
.biSizeImage
;
65 size
= get_dib_image_size(info
);
66 size
+= bitmap_info_size( info
, coloruse
);
68 if (!(hmem
= GlobalAlloc( GMEM_MOVEABLE
, size
)))
72 newInfo
= GlobalLock( hmem
);
73 memcpy( newInfo
, info
, size
);
79 /***********************************************************************
80 * CreateBrushIndirect (GDI32.@)
82 * Create a logical brush with a given style, color or pattern.
85 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
88 * A handle to the created brush, or a NULL handle if the brush cannot be
92 * - The brush returned should be freed by the caller using DeleteObject()
93 * when it is no longer required.
94 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
95 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
98 HBRUSH WINAPI
CreateBrushIndirect( const LOGBRUSH
* brush
)
103 if (!(ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr
) ))) return 0;
105 ptr
->logbrush
.lbStyle
= brush
->lbStyle
;
106 ptr
->logbrush
.lbColor
= brush
->lbColor
;
107 ptr
->logbrush
.lbHatch
= brush
->lbHatch
;
109 switch (ptr
->logbrush
.lbStyle
)
112 ptr
->logbrush
.lbStyle
= BS_PATTERN
;
115 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)BITMAP_CopyBitmap( (HBITMAP
) ptr
->logbrush
.lbHatch
);
116 if (!ptr
->logbrush
.lbHatch
) goto error
;
119 case BS_DIBPATTERNPT
:
120 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
121 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)dib_copy( (BITMAPINFO
*) ptr
->logbrush
.lbHatch
,
122 ptr
->logbrush
.lbColor
);
123 if (!ptr
->logbrush
.lbHatch
) goto error
;
126 case BS_DIBPATTERN8X8
:
130 HGLOBAL h
= (HGLOBAL
)ptr
->logbrush
.lbHatch
;
132 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
133 if (!(bmi
= GlobalLock( h
))) goto error
;
134 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)dib_copy( bmi
, ptr
->logbrush
.lbColor
);
136 if (!ptr
->logbrush
.lbHatch
) goto error
;
141 if(ptr
->logbrush
.lbStyle
> BS_MONOPATTERN
) goto error
;
145 if ((hbrush
= alloc_gdi_handle( &ptr
->header
, OBJ_BRUSH
, &brush_funcs
)))
147 TRACE("%p\n", hbrush
);
152 if (ptr
->logbrush
.lbHatch
)
154 if (ptr
->logbrush
.lbStyle
== BS_PATTERN
)
155 DeleteObject( (HGDIOBJ
)ptr
->logbrush
.lbHatch
);
156 else if (ptr
->logbrush
.lbStyle
== BS_DIBPATTERN
)
157 GlobalFree( (HGLOBAL
)ptr
->logbrush
.lbHatch
);
159 HeapFree( GetProcessHeap(), 0, ptr
);
164 /***********************************************************************
165 * CreateHatchBrush (GDI32.@)
167 * Create a logical brush with a hatched pattern.
170 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
171 * color [I] Colour of the hatched pattern
174 * A handle to the created brush, or a NULL handle if the brush cannot
178 * - This function uses CreateBrushIndirect() to create the brush.
179 * - The brush returned should be freed by the caller using DeleteObject()
180 * when it is no longer required.
182 HBRUSH WINAPI
CreateHatchBrush( INT style
, COLORREF color
)
186 TRACE("%d %06x\n", style
, color
);
188 logbrush
.lbStyle
= BS_HATCHED
;
189 logbrush
.lbColor
= color
;
190 logbrush
.lbHatch
= style
;
192 return CreateBrushIndirect( &logbrush
);
196 /***********************************************************************
197 * CreatePatternBrush (GDI32.@)
199 * Create a logical brush with a pattern from a bitmap.
202 * hbitmap [I] Bitmap containing pattern for the brush
205 * A handle to the created brush, or a NULL handle if the brush cannot
209 * - This function uses CreateBrushIndirect() to create the brush.
210 * - The brush returned should be freed by the caller using DeleteObject()
211 * when it is no longer required.
213 HBRUSH WINAPI
CreatePatternBrush( HBITMAP hbitmap
)
215 LOGBRUSH logbrush
= { BS_PATTERN
, 0, 0 };
216 TRACE("%p\n", hbitmap
);
218 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
219 return CreateBrushIndirect( &logbrush
);
223 /***********************************************************************
224 * CreateDIBPatternBrush (GDI32.@)
226 * Create a logical brush with a pattern from a DIB.
229 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
230 * coloruse [I] Specifies color format, if provided
233 * A handle to the created brush, or a NULL handle if the brush cannot
237 * - This function uses CreateBrushIndirect() to create the brush.
238 * - The brush returned should be freed by the caller using DeleteObject()
239 * when it is no longer required.
240 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
243 HBRUSH WINAPI
CreateDIBPatternBrush( HGLOBAL hbitmap
, UINT coloruse
)
247 TRACE("%p\n", hbitmap
);
249 logbrush
.lbStyle
= BS_DIBPATTERN
;
250 logbrush
.lbColor
= coloruse
;
252 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
254 return CreateBrushIndirect( &logbrush
);
258 /***********************************************************************
259 * CreateDIBPatternBrushPt (GDI32.@)
261 * Create a logical brush with a pattern from a DIB.
264 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
265 * coloruse [I] Specifies color format, if provided
268 * A handle to the created brush, or a NULL handle if the brush cannot
272 * - This function uses CreateBrushIndirect() to create the brush.
273 * - The brush returned should be freed by the caller using DeleteObject()
274 * when it is no longer required.
276 HBRUSH WINAPI
CreateDIBPatternBrushPt( const void* data
, UINT coloruse
)
278 const BITMAPINFO
*info
=data
;
284 TRACE("%p %dx%d %dbpp\n", info
, info
->bmiHeader
.biWidth
,
285 info
->bmiHeader
.biHeight
, info
->bmiHeader
.biBitCount
);
287 logbrush
.lbStyle
= BS_DIBPATTERNPT
;
288 logbrush
.lbColor
= coloruse
;
289 logbrush
.lbHatch
= (ULONG_PTR
)data
;
291 return CreateBrushIndirect( &logbrush
);
295 /***********************************************************************
296 * CreateSolidBrush (GDI32.@)
298 * Create a logical brush consisting of a single colour.
301 * color [I] Colour to make the solid brush
304 * A handle to the newly created brush, or a NULL handle if the brush cannot
308 * - This function uses CreateBrushIndirect() to create the brush.
309 * - The brush returned should be freed by the caller using DeleteObject()
310 * when it is no longer required.
312 HBRUSH WINAPI
CreateSolidBrush( COLORREF color
)
316 TRACE("%06x\n", color
);
318 logbrush
.lbStyle
= BS_SOLID
;
319 logbrush
.lbColor
= color
;
320 logbrush
.lbHatch
= 0;
322 return CreateBrushIndirect( &logbrush
);
326 /***********************************************************************
327 * SetBrushOrgEx (GDI32.@)
329 * Set the brush origin for a device context.
332 * hdc [I] Device context to set the brush origin for
335 * oldorg [O] If non NULL, destination for previously set brush origin.
338 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
340 BOOL WINAPI
SetBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
342 DC
*dc
= get_dc_ptr( hdc
);
344 if (!dc
) return FALSE
;
347 oldorg
->x
= dc
->brushOrgX
;
348 oldorg
->y
= dc
->brushOrgY
;
352 release_dc_ptr( dc
);
356 /***********************************************************************
357 * FixBrushOrgEx (GDI32.@)
362 * This function is no longer documented by MSDN, but in Win95 GDI32 it
363 * is the same as SetBrushOrgEx().
365 BOOL WINAPI
FixBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
367 return SetBrushOrgEx(hdc
,x
,y
,oldorg
);
371 /***********************************************************************
374 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
)
378 DC
*dc
= get_dc_ptr( hdc
);
382 SetLastError( ERROR_INVALID_HANDLE
);
386 if ((brush
= GDI_GetObjPtr( handle
, OBJ_BRUSH
)))
388 PHYSDEV physdev
= GET_DC_PHYSDEV( dc
, pSelectBrush
);
390 if (brush
->logbrush
.lbStyle
== BS_PATTERN
)
392 PHYSDEV pattern_dev
= physdev
;
393 /* FIXME: This will go away once the dib driver implements
395 if(pattern_dev
== dc
->dibdrv
)
396 pattern_dev
= GET_NEXT_PHYSDEV( physdev
, pSelectBrush
);
398 BITMAP_SetOwnerDC( (HBITMAP
)brush
->logbrush
.lbHatch
, pattern_dev
);
401 GDI_inc_ref_count( handle
);
402 GDI_ReleaseObj( handle
);
404 if (!physdev
->funcs
->pSelectBrush( physdev
, handle
))
406 GDI_dec_ref_count( handle
);
412 GDI_dec_ref_count( ret
);
415 release_dc_ptr( dc
);
420 /***********************************************************************
423 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
)
425 BRUSHOBJ
*brush
= free_gdi_handle( handle
);
427 if (!brush
) return FALSE
;
428 switch(brush
->logbrush
.lbStyle
)
431 DeleteObject( (HGDIOBJ
)brush
->logbrush
.lbHatch
);
434 GlobalFree( (HGLOBAL
)brush
->logbrush
.lbHatch
);
437 return HeapFree( GetProcessHeap(), 0, brush
);
441 /***********************************************************************
444 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
)
446 BRUSHOBJ
*brush
= GDI_GetObjPtr( handle
, OBJ_BRUSH
);
448 if (!brush
) return 0;
451 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
452 memcpy( buffer
, &brush
->logbrush
, count
);
454 else count
= sizeof(brush
->logbrush
);
455 GDI_ReleaseObj( handle
);