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 "wine/wingdi16.h"
31 #include "gdi_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
36 /* GDI logical brush object */
43 #define NB_HATCH_STYLES 6
45 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
);
46 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
);
47 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
);
49 static const struct gdi_obj_funcs brush_funcs
=
51 BRUSH_SelectObject
, /* pSelectObject */
52 BRUSH_GetObject
, /* pGetObjectA */
53 BRUSH_GetObject
, /* pGetObjectW */
54 NULL
, /* pUnrealizeObject */
55 BRUSH_DeleteObject
/* pDeleteObject */
58 static HGLOBAL16
dib_copy(const BITMAPINFO
*info
, UINT coloruse
)
64 if (info
->bmiHeader
.biCompression
!= BI_RGB
&& info
->bmiHeader
.biCompression
!= BI_BITFIELDS
)
65 size
= info
->bmiHeader
.biSizeImage
;
67 size
= DIB_GetDIBImageBytes(info
->bmiHeader
.biWidth
,
68 info
->bmiHeader
.biHeight
,
69 info
->bmiHeader
.biBitCount
);
70 size
+= bitmap_info_size( info
, coloruse
);
72 if (!(hmem
= GlobalAlloc16( GMEM_MOVEABLE
, size
)))
76 newInfo
= GlobalLock16( hmem
);
77 memcpy( newInfo
, info
, size
);
78 GlobalUnlock16( hmem
);
83 /***********************************************************************
84 * CreateBrushIndirect (GDI32.@)
86 * Create a logical brush with a given style, color or pattern.
89 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
92 * A handle to the created brush, or a NULL handle if the brush cannot be
96 * - The brush returned should be freed by the caller using DeleteObject()
97 * when it is no longer required.
98 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
99 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
102 HBRUSH WINAPI
CreateBrushIndirect( const LOGBRUSH
* brush
)
107 if (!(ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr
) ))) return 0;
109 ptr
->logbrush
.lbStyle
= brush
->lbStyle
;
110 ptr
->logbrush
.lbColor
= brush
->lbColor
;
111 ptr
->logbrush
.lbHatch
= brush
->lbHatch
;
113 switch (ptr
->logbrush
.lbStyle
)
116 ptr
->logbrush
.lbStyle
= BS_PATTERN
;
119 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)BITMAP_CopyBitmap( (HBITMAP
) ptr
->logbrush
.lbHatch
);
120 if (!ptr
->logbrush
.lbHatch
) goto error
;
123 case BS_DIBPATTERNPT
:
124 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
125 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)dib_copy( (BITMAPINFO
*) ptr
->logbrush
.lbHatch
,
126 ptr
->logbrush
.lbColor
);
127 if (!ptr
->logbrush
.lbHatch
) goto error
;
130 case BS_DIBPATTERN8X8
:
134 HGLOBAL h
= (HGLOBAL
)ptr
->logbrush
.lbHatch
;
136 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
137 if (!(bmi
= GlobalLock( h
))) goto error
;
138 ptr
->logbrush
.lbHatch
= dib_copy( bmi
, ptr
->logbrush
.lbColor
);
140 if (!ptr
->logbrush
.lbHatch
) goto error
;
145 if(ptr
->logbrush
.lbStyle
> BS_MONOPATTERN
) goto error
;
149 if ((hbrush
= alloc_gdi_handle( &ptr
->header
, OBJ_BRUSH
, &brush_funcs
)))
151 TRACE("%p\n", hbrush
);
156 if (ptr
->logbrush
.lbHatch
)
158 if (ptr
->logbrush
.lbStyle
== BS_PATTERN
)
159 DeleteObject( (HGDIOBJ
)ptr
->logbrush
.lbHatch
);
160 else if (ptr
->logbrush
.lbStyle
== BS_DIBPATTERN
)
161 GlobalFree16( (HGLOBAL16
)ptr
->logbrush
.lbHatch
);
163 HeapFree( GetProcessHeap(), 0, ptr
);
168 /***********************************************************************
169 * CreateHatchBrush (GDI32.@)
171 * Create a logical brush with a hatched pattern.
174 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
175 * color [I] Colour of the hatched pattern
178 * A handle to the created brush, or a NULL handle if the brush cannot
182 * - This function uses CreateBrushIndirect() to create the brush.
183 * - The brush returned should be freed by the caller using DeleteObject()
184 * when it is no longer required.
186 HBRUSH WINAPI
CreateHatchBrush( INT style
, COLORREF color
)
190 TRACE("%d %06x\n", style
, color
);
192 logbrush
.lbStyle
= BS_HATCHED
;
193 logbrush
.lbColor
= color
;
194 logbrush
.lbHatch
= style
;
196 return CreateBrushIndirect( &logbrush
);
200 /***********************************************************************
201 * CreatePatternBrush (GDI32.@)
203 * Create a logical brush with a pattern from a bitmap.
206 * hbitmap [I] Bitmap containing pattern for the brush
209 * A handle to the created brush, or a NULL handle if the brush cannot
213 * - This function uses CreateBrushIndirect() to create the brush.
214 * - The brush returned should be freed by the caller using DeleteObject()
215 * when it is no longer required.
217 HBRUSH WINAPI
CreatePatternBrush( HBITMAP hbitmap
)
219 LOGBRUSH logbrush
= { BS_PATTERN
, 0, 0 };
220 TRACE("%p\n", hbitmap
);
222 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
223 return CreateBrushIndirect( &logbrush
);
227 /***********************************************************************
228 * CreateDIBPatternBrush (GDI32.@)
230 * Create a logical brush with a pattern from a DIB.
233 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
234 * coloruse [I] Specifies color format, if provided
237 * A handle to the created brush, or a NULL handle if the brush cannot
241 * - This function uses CreateBrushIndirect() to create the brush.
242 * - The brush returned should be freed by the caller using DeleteObject()
243 * when it is no longer required.
244 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
247 HBRUSH WINAPI
CreateDIBPatternBrush( HGLOBAL hbitmap
, UINT coloruse
)
251 TRACE("%p\n", hbitmap
);
253 logbrush
.lbStyle
= BS_DIBPATTERN
;
254 logbrush
.lbColor
= coloruse
;
256 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
258 return CreateBrushIndirect( &logbrush
);
262 /***********************************************************************
263 * CreateDIBPatternBrushPt (GDI32.@)
265 * Create a logical brush with a pattern from a DIB.
268 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
269 * coloruse [I] Specifies color format, if provided
272 * A handle to the created brush, or a NULL handle if the brush cannot
276 * - This function uses CreateBrushIndirect() to create the brush.
277 * - The brush returned should be freed by the caller using DeleteObject()
278 * when it is no longer required.
280 HBRUSH WINAPI
CreateDIBPatternBrushPt( const void* data
, UINT coloruse
)
282 const BITMAPINFO
*info
=data
;
288 TRACE("%p %dx%d %dbpp\n", info
, info
->bmiHeader
.biWidth
,
289 info
->bmiHeader
.biHeight
, info
->bmiHeader
.biBitCount
);
291 logbrush
.lbStyle
= BS_DIBPATTERNPT
;
292 logbrush
.lbColor
= coloruse
;
293 logbrush
.lbHatch
= (ULONG_PTR
)data
;
295 return CreateBrushIndirect( &logbrush
);
299 /***********************************************************************
300 * CreateSolidBrush (GDI32.@)
302 * Create a logical brush consisting of a single colour.
305 * color [I] Colour to make the solid brush
308 * A handle to the newly created brush, or a NULL handle if the brush cannot
312 * - This function uses CreateBrushIndirect() to create the brush.
313 * - The brush returned should be freed by the caller using DeleteObject()
314 * when it is no longer required.
316 HBRUSH WINAPI
CreateSolidBrush( COLORREF color
)
320 TRACE("%06x\n", color
);
322 logbrush
.lbStyle
= BS_SOLID
;
323 logbrush
.lbColor
= color
;
324 logbrush
.lbHatch
= 0;
326 return CreateBrushIndirect( &logbrush
);
330 /***********************************************************************
331 * SetBrushOrgEx (GDI32.@)
333 * Set the brush origin for a device context.
336 * hdc [I] Device context to set the brush origin for
339 * oldorg [O] If non NULL, destination for previously set brush origin.
342 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
344 BOOL WINAPI
SetBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
346 DC
*dc
= get_dc_ptr( hdc
);
348 if (!dc
) return FALSE
;
351 oldorg
->x
= dc
->brushOrgX
;
352 oldorg
->y
= dc
->brushOrgY
;
356 release_dc_ptr( dc
);
360 /***********************************************************************
361 * FixBrushOrgEx (GDI32.@)
366 * This function is no longer documented by MSDN, but in Win95 GDI32 it
367 * is the same as SetBrushOrgEx().
369 BOOL WINAPI
FixBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
371 return SetBrushOrgEx(hdc
,x
,y
,oldorg
);
375 /***********************************************************************
378 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
)
382 DC
*dc
= get_dc_ptr( hdc
);
386 SetLastError( ERROR_INVALID_HANDLE
);
390 if ((brush
= GDI_GetObjPtr( handle
, OBJ_BRUSH
)))
392 if (brush
->logbrush
.lbStyle
== BS_PATTERN
)
393 BITMAP_SetOwnerDC( (HBITMAP
)brush
->logbrush
.lbHatch
, dc
);
395 GDI_inc_ref_count( handle
);
396 GDI_ReleaseObj( handle
);
398 if (dc
->funcs
->pSelectBrush
&& !dc
->funcs
->pSelectBrush( dc
->physDev
, handle
))
400 GDI_dec_ref_count( handle
);
406 GDI_dec_ref_count( ret
);
409 release_dc_ptr( dc
);
414 /***********************************************************************
417 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
)
419 BRUSHOBJ
*brush
= free_gdi_handle( handle
);
421 if (!brush
) return FALSE
;
422 switch(brush
->logbrush
.lbStyle
)
425 DeleteObject( (HGDIOBJ
)brush
->logbrush
.lbHatch
);
428 GlobalFree16( (HGLOBAL16
)brush
->logbrush
.lbHatch
);
431 return HeapFree( GetProcessHeap(), 0, brush
);
435 /***********************************************************************
438 static INT
BRUSH_GetObject( HGDIOBJ handle
, INT count
, LPVOID buffer
)
440 BRUSHOBJ
*brush
= GDI_GetObjPtr( handle
, OBJ_BRUSH
);
442 if (!brush
) return 0;
445 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
446 memcpy( buffer
, &brush
->logbrush
, count
);
448 else count
= sizeof(brush
->logbrush
);
449 GDI_ReleaseObj( handle
);
454 /***********************************************************************
455 * SetSolidBrush (GDI.604)
457 * Change the color of a solid brush.
460 * hBrush [I] Brush to change the color of
461 * newColor [I] New color for hBrush
464 * Success: TRUE. The color of hBrush is set to newColor.
468 * This function is undocumented and untested. The implementation may
471 BOOL16 WINAPI
SetSolidBrush16(HBRUSH16 hBrush
, COLORREF newColor
)
476 TRACE("(hBrush %04x, newColor %08x)\n", hBrush
, newColor
);
477 if (!(brushPtr
= GDI_GetObjPtr( HBRUSH_32(hBrush
), OBJ_BRUSH
)))
480 if (brushPtr
->logbrush
.lbStyle
== BS_SOLID
)
482 brushPtr
->logbrush
.lbColor
= newColor
;
486 GDI_ReleaseObj( HBRUSH_32(hBrush
) );