push 9bfdf186dc6a237cd7f58f0ee2ef677e81617b1d
[wine/hacks.git] / dlls / gdi32 / brush.c
blob1f81c0038b91ed6b9b5f419a79231cc6f8bf45ee
1 /*
2 * GDI brush objects
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
21 #include "config.h"
23 #include <stdarg.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "wine/wingdi16.h"
30 #include "wownt32.h"
31 #include "gdi_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
36 /* GDI logical brush object */
37 typedef struct
39 GDIOBJHDR header;
40 LOGBRUSH logbrush;
41 } BRUSHOBJ;
43 #define NB_HATCH_STYLES 6
45 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc );
46 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
47 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
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)
60 BITMAPINFO *newInfo;
61 HGLOBAL16 hmem;
62 INT size;
64 if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS)
65 size = info->bmiHeader.biSizeImage;
66 else
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 )))
74 return 0;
76 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
77 memcpy( newInfo, info, size );
78 GlobalUnlock16( hmem );
79 return hmem;
83 /***********************************************************************
84 * CreateBrushIndirect (GDI32.@)
86 * Create a logical brush with a given style, color or pattern.
88 * PARAMS
89 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
91 * RETURNS
92 * A handle to the created brush, or a NULL handle if the brush cannot be
93 * created.
95 * NOTES
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
100 * is used.
102 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
104 BRUSHOBJ * ptr;
105 HBRUSH hbrush;
107 if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC,
108 (HGDIOBJ *)&hbrush, &brush_funcs ))) 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)
115 case BS_PATTERN8X8:
116 ptr->logbrush.lbStyle = BS_PATTERN;
117 /* fall through */
118 case BS_PATTERN:
119 ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
120 if (!ptr->logbrush.lbHatch) goto error;
121 break;
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;
128 break;
130 case BS_DIBPATTERN8X8:
131 case BS_DIBPATTERN:
133 BITMAPINFO* bmi;
134 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
136 ptr->logbrush.lbStyle = BS_DIBPATTERN;
137 if (!(bmi = (BITMAPINFO *)GlobalLock( h ))) goto error;
138 ptr->logbrush.lbHatch = dib_copy( bmi, ptr->logbrush.lbColor);
139 GlobalUnlock( h );
140 if (!ptr->logbrush.lbHatch) goto error;
141 break;
144 default:
145 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
146 break;
149 GDI_ReleaseObj( hbrush );
150 TRACE("%p\n", hbrush);
151 return hbrush;
153 error:
154 GDI_FreeObject( hbrush, ptr );
155 return 0;
159 /***********************************************************************
160 * CreateHatchBrush (GDI32.@)
162 * Create a logical brush with a hatched pattern.
164 * PARAMS
165 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
166 * color [I] Colour of the hatched pattern
168 * RETURNS
169 * A handle to the created brush, or a NULL handle if the brush cannot
170 * be created.
172 * NOTES
173 * - This function uses CreateBrushIndirect() to create the brush.
174 * - The brush returned should be freed by the caller using DeleteObject()
175 * when it is no longer required.
177 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
179 LOGBRUSH logbrush;
181 TRACE("%d %06x\n", style, color );
183 logbrush.lbStyle = BS_HATCHED;
184 logbrush.lbColor = color;
185 logbrush.lbHatch = style;
187 return CreateBrushIndirect( &logbrush );
191 /***********************************************************************
192 * CreatePatternBrush (GDI32.@)
194 * Create a logical brush with a pattern from a bitmap.
196 * PARAMS
197 * hbitmap [I] Bitmap containing pattern for the brush
199 * RETURNS
200 * A handle to the created brush, or a NULL handle if the brush cannot
201 * be created.
203 * NOTES
204 * - This function uses CreateBrushIndirect() to create the brush.
205 * - The brush returned should be freed by the caller using DeleteObject()
206 * when it is no longer required.
208 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
210 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
211 TRACE("%p\n", hbitmap );
213 logbrush.lbHatch = (ULONG_PTR)hbitmap;
214 return CreateBrushIndirect( &logbrush );
218 /***********************************************************************
219 * CreateDIBPatternBrush (GDI32.@)
221 * Create a logical brush with a pattern from a DIB.
223 * PARAMS
224 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
225 * coloruse [I] Specifies color format, if provided
227 * RETURNS
228 * A handle to the created brush, or a NULL handle if the brush cannot
229 * be created.
231 * NOTES
232 * - This function uses CreateBrushIndirect() to create the brush.
233 * - The brush returned should be freed by the caller using DeleteObject()
234 * when it is no longer required.
235 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
236 * be used instead.
238 HBRUSH WINAPI CreateDIBPatternBrush( HGLOBAL hbitmap, UINT coloruse )
240 LOGBRUSH logbrush;
242 TRACE("%p\n", hbitmap );
244 logbrush.lbStyle = BS_DIBPATTERN;
245 logbrush.lbColor = coloruse;
247 logbrush.lbHatch = (ULONG_PTR)hbitmap;
249 return CreateBrushIndirect( &logbrush );
253 /***********************************************************************
254 * CreateDIBPatternBrushPt (GDI32.@)
256 * Create a logical brush with a pattern from a DIB.
258 * PARAMS
259 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
260 * coloruse [I] Specifies color format, if provided
262 * RETURNS
263 * A handle to the created brush, or a NULL handle if the brush cannot
264 * be created.
266 * NOTES
267 * - This function uses CreateBrushIndirect() to create the brush.
268 * - The brush returned should be freed by the caller using DeleteObject()
269 * when it is no longer required.
271 HBRUSH WINAPI CreateDIBPatternBrushPt( const void* data, UINT coloruse )
273 const BITMAPINFO *info=(const BITMAPINFO*)data;
274 LOGBRUSH logbrush;
276 if (!data)
277 return NULL;
279 TRACE("%p %dx%d %dbpp\n", info, info->bmiHeader.biWidth,
280 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
282 logbrush.lbStyle = BS_DIBPATTERNPT;
283 logbrush.lbColor = coloruse;
284 logbrush.lbHatch = (ULONG_PTR)data;
286 return CreateBrushIndirect( &logbrush );
290 /***********************************************************************
291 * CreateSolidBrush (GDI32.@)
293 * Create a logical brush consisting of a single colour.
295 * PARAMS
296 * color [I] Colour to make the solid brush
298 * RETURNS
299 * A handle to the newly created brush, or a NULL handle if the brush cannot
300 * be created.
302 * NOTES
303 * - This function uses CreateBrushIndirect() to create the brush.
304 * - The brush returned should be freed by the caller using DeleteObject()
305 * when it is no longer required.
307 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
309 LOGBRUSH logbrush;
311 TRACE("%06x\n", color );
313 logbrush.lbStyle = BS_SOLID;
314 logbrush.lbColor = color;
315 logbrush.lbHatch = 0;
317 return CreateBrushIndirect( &logbrush );
321 /***********************************************************************
322 * SetBrushOrgEx (GDI32.@)
324 * Set the brush origin for a device context.
326 * PARAMS
327 * hdc [I] Device context to set the brush origin for
328 * x [I] New x origin
329 * y [I] Ney y origin
330 * oldorg [O] If non NULL, destination for previously set brush origin.
332 * RETURNS
333 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
335 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
337 DC *dc = get_dc_ptr( hdc );
339 if (!dc) return FALSE;
340 if (oldorg)
342 oldorg->x = dc->brushOrgX;
343 oldorg->y = dc->brushOrgY;
345 dc->brushOrgX = x;
346 dc->brushOrgY = y;
347 release_dc_ptr( dc );
348 return TRUE;
351 /***********************************************************************
352 * FixBrushOrgEx (GDI32.@)
354 * See SetBrushOrgEx.
356 * NOTES
357 * This function is no longer documented by MSDN, but in Win95 GDI32 it
358 * is the same as SetBrushOrgEx().
360 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
362 return SetBrushOrgEx(hdc,x,y,oldorg);
366 /***********************************************************************
367 * BRUSH_SelectObject
369 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
371 BRUSHOBJ *brush;
372 HGDIOBJ ret = 0;
373 DC *dc = get_dc_ptr( hdc );
375 if (!dc)
377 SetLastError( ERROR_INVALID_HANDLE );
378 return 0;
381 if ((brush = GDI_GetObjPtr( handle, BRUSH_MAGIC )))
383 if (brush->logbrush.lbStyle == BS_PATTERN)
384 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
386 GDI_inc_ref_count( handle );
387 GDI_ReleaseObj( handle );
389 if (dc->funcs->pSelectBrush && !dc->funcs->pSelectBrush( dc->physDev, handle ))
391 GDI_dec_ref_count( handle );
393 else
395 ret = dc->hBrush;
396 dc->hBrush = handle;
397 GDI_dec_ref_count( ret );
400 release_dc_ptr( dc );
401 return ret;
405 /***********************************************************************
406 * BRUSH_DeleteObject
408 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
410 BRUSHOBJ *brush = obj;
412 switch(brush->logbrush.lbStyle)
414 case BS_PATTERN:
415 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
416 break;
417 case BS_DIBPATTERN:
418 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
419 break;
421 return GDI_FreeObject( handle, obj );
425 /***********************************************************************
426 * BRUSH_GetObject
428 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
430 BRUSHOBJ *brush = obj;
432 if( !buffer )
433 return sizeof(brush->logbrush);
435 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
436 memcpy( buffer, &brush->logbrush, count );
437 return count;
441 /***********************************************************************
442 * SetSolidBrush (GDI.604)
444 * Change the color of a solid brush.
446 * PARAMS
447 * hBrush [I] Brush to change the color of
448 * newColor [I] New color for hBrush
450 * RETURNS
451 * Success: TRUE. The color of hBrush is set to newColor.
452 * Failure: FALSE.
454 * FIXME
455 * This function is undocumented and untested. The implementation may
456 * not be correct.
458 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
460 BRUSHOBJ * brushPtr;
461 BOOL16 res = FALSE;
463 TRACE("(hBrush %04x, newColor %08x)\n", hBrush, newColor);
464 if (!(brushPtr = GDI_GetObjPtr( HBRUSH_32(hBrush), BRUSH_MAGIC )))
465 return FALSE;
467 if (brushPtr->logbrush.lbStyle == BS_SOLID)
469 brushPtr->logbrush.lbColor = newColor;
470 res = TRUE;
473 GDI_ReleaseObj( HBRUSH_32(hBrush) );
474 return res;