push f2fb4b43e6a5ad960b5745b9c70e0a8fefaca935
[wine/hacks.git] / dlls / gdi32 / brush.c
blobc713f746a909f891ca5ee8c988a4fdd054fb225b
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_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
47 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
48 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
50 static const struct gdi_obj_funcs brush_funcs =
52 BRUSH_SelectObject, /* pSelectObject */
53 BRUSH_GetObject16, /* pGetObject16 */
54 BRUSH_GetObject, /* pGetObjectA */
55 BRUSH_GetObject, /* pGetObjectW */
56 NULL, /* pUnrealizeObject */
57 BRUSH_DeleteObject /* pDeleteObject */
60 static HGLOBAL16 dib_copy(const BITMAPINFO *info, UINT coloruse)
62 BITMAPINFO *newInfo;
63 HGLOBAL16 hmem;
64 INT size;
66 if (info->bmiHeader.biCompression)
67 size = info->bmiHeader.biSizeImage;
68 else
69 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
70 info->bmiHeader.biHeight,
71 info->bmiHeader.biBitCount);
72 size += DIB_BitmapInfoSize( info, coloruse );
74 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
76 return 0;
78 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
79 memcpy( newInfo, info, size );
80 GlobalUnlock16( hmem );
81 return hmem;
85 /***********************************************************************
86 * CreateBrushIndirect (GDI32.@)
88 * Create a logical brush with a given style, color or pattern.
90 * PARAMS
91 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
93 * RETURNS
94 * A handle to the created brush, or a NULL handle if the brush cannot be
95 * created.
97 * NOTES
98 * - The brush returned should be freed by the caller using DeleteObject()
99 * when it is no longer required.
100 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
101 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
102 * is used.
104 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
106 BRUSHOBJ * ptr;
107 HBRUSH hbrush;
109 if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC,
110 (HGDIOBJ *)&hbrush, &brush_funcs ))) return 0;
111 ptr->logbrush.lbStyle = brush->lbStyle;
112 ptr->logbrush.lbColor = brush->lbColor;
113 ptr->logbrush.lbHatch = brush->lbHatch;
115 switch (ptr->logbrush.lbStyle)
117 case BS_PATTERN8X8:
118 ptr->logbrush.lbStyle = BS_PATTERN;
119 /* fall through */
120 case BS_PATTERN:
121 ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
122 if (!ptr->logbrush.lbHatch) goto error;
123 break;
125 case BS_DIBPATTERNPT:
126 ptr->logbrush.lbStyle = BS_DIBPATTERN;
127 ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
128 ptr->logbrush.lbColor);
129 if (!ptr->logbrush.lbHatch) goto error;
130 break;
132 case BS_DIBPATTERN8X8:
133 case BS_DIBPATTERN:
135 BITMAPINFO* bmi;
136 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
138 ptr->logbrush.lbStyle = BS_DIBPATTERN;
139 if (!(bmi = (BITMAPINFO *)GlobalLock( h ))) goto error;
140 ptr->logbrush.lbHatch = dib_copy( bmi, ptr->logbrush.lbColor);
141 GlobalUnlock( h );
142 if (!ptr->logbrush.lbHatch) goto error;
143 break;
146 default:
147 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
148 break;
151 GDI_ReleaseObj( hbrush );
152 TRACE("%p\n", hbrush);
153 return hbrush;
155 error:
156 GDI_FreeObject( hbrush, ptr );
157 return 0;
161 /***********************************************************************
162 * CreateHatchBrush (GDI32.@)
164 * Create a logical brush with a hatched pattern.
166 * PARAMS
167 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
168 * color [I] Colour of the hatched pattern
170 * RETURNS
171 * A handle to the created brush, or a NULL handle if the brush cannot
172 * be created.
174 * NOTES
175 * - This function uses CreateBrushIndirect() to create the brush.
176 * - The brush returned should be freed by the caller using DeleteObject()
177 * when it is no longer required.
179 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
181 LOGBRUSH logbrush;
183 TRACE("%d %06x\n", style, color );
185 logbrush.lbStyle = BS_HATCHED;
186 logbrush.lbColor = color;
187 logbrush.lbHatch = style;
189 return CreateBrushIndirect( &logbrush );
193 /***********************************************************************
194 * CreatePatternBrush (GDI32.@)
196 * Create a logical brush with a pattern from a bitmap.
198 * PARAMS
199 * hbitmap [I] Bitmap containing pattern for the brush
201 * RETURNS
202 * A handle to the created brush, or a NULL handle if the brush cannot
203 * be created.
205 * NOTES
206 * - This function uses CreateBrushIndirect() to create the brush.
207 * - The brush returned should be freed by the caller using DeleteObject()
208 * when it is no longer required.
210 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
212 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
213 TRACE("%p\n", hbitmap );
215 logbrush.lbHatch = (ULONG_PTR)hbitmap;
216 return CreateBrushIndirect( &logbrush );
220 /***********************************************************************
221 * CreateDIBPatternBrush (GDI32.@)
223 * Create a logical brush with a pattern from a DIB.
225 * PARAMS
226 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
227 * coloruse [I] Specifies color format, if provided
229 * RETURNS
230 * A handle to the created brush, or a NULL handle if the brush cannot
231 * be created.
233 * NOTES
234 * - This function uses CreateBrushIndirect() to create the brush.
235 * - The brush returned should be freed by the caller using DeleteObject()
236 * when it is no longer required.
237 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
238 * be used instead.
240 HBRUSH WINAPI CreateDIBPatternBrush( HGLOBAL hbitmap, UINT coloruse )
242 LOGBRUSH logbrush;
244 TRACE("%p\n", hbitmap );
246 logbrush.lbStyle = BS_DIBPATTERN;
247 logbrush.lbColor = coloruse;
249 logbrush.lbHatch = (ULONG_PTR)hbitmap;
251 return CreateBrushIndirect( &logbrush );
255 /***********************************************************************
256 * CreateDIBPatternBrushPt (GDI32.@)
258 * Create a logical brush with a pattern from a DIB.
260 * PARAMS
261 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
262 * coloruse [I] Specifies color format, if provided
264 * RETURNS
265 * A handle to the created brush, or a NULL handle if the brush cannot
266 * be created.
268 * NOTES
269 * - This function uses CreateBrushIndirect() to create the brush.
270 * - The brush returned should be freed by the caller using DeleteObject()
271 * when it is no longer required.
273 HBRUSH WINAPI CreateDIBPatternBrushPt( const void* data, UINT coloruse )
275 const BITMAPINFO *info=(const BITMAPINFO*)data;
276 LOGBRUSH logbrush;
278 if (!data)
279 return NULL;
281 TRACE("%p %dx%d %dbpp\n", info, info->bmiHeader.biWidth,
282 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
284 logbrush.lbStyle = BS_DIBPATTERNPT;
285 logbrush.lbColor = coloruse;
286 logbrush.lbHatch = (ULONG_PTR)data;
288 return CreateBrushIndirect( &logbrush );
292 /***********************************************************************
293 * CreateSolidBrush (GDI32.@)
295 * Create a logical brush consisting of a single colour.
297 * PARAMS
298 * color [I] Colour to make the solid brush
300 * RETURNS
301 * A handle to the newly created brush, or a NULL handle if the brush cannot
302 * be created.
304 * NOTES
305 * - This function uses CreateBrushIndirect() to create the brush.
306 * - The brush returned should be freed by the caller using DeleteObject()
307 * when it is no longer required.
309 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
311 LOGBRUSH logbrush;
313 TRACE("%06x\n", color );
315 logbrush.lbStyle = BS_SOLID;
316 logbrush.lbColor = color;
317 logbrush.lbHatch = 0;
319 return CreateBrushIndirect( &logbrush );
323 /***********************************************************************
324 * SetBrushOrgEx (GDI32.@)
326 * Set the brush origin for a device context.
328 * PARAMS
329 * hdc [I] Device context to set the brush origin for
330 * x [I] New x origin
331 * y [I] Ney y origin
332 * oldorg [O] If non NULL, destination for previously set brush origin.
334 * RETURNS
335 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
337 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
339 DC *dc = DC_GetDCPtr( hdc );
341 if (!dc) return FALSE;
342 if (oldorg)
344 oldorg->x = dc->brushOrgX;
345 oldorg->y = dc->brushOrgY;
347 dc->brushOrgX = x;
348 dc->brushOrgY = y;
349 DC_ReleaseDCPtr( dc );
350 return TRUE;
353 /***********************************************************************
354 * FixBrushOrgEx (GDI32.@)
356 * See SetBrushOrgEx.
358 * NOTES
359 * This function is no longer documented by MSDN, but in Win95 GDI32 it
360 * is the same as SetBrushOrgEx().
362 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
364 return SetBrushOrgEx(hdc,x,y,oldorg);
368 /***********************************************************************
369 * BRUSH_SelectObject
371 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
373 BRUSHOBJ *brush;
374 HGDIOBJ ret = 0;
375 DC *dc = get_dc_ptr( hdc );
377 if (!dc) return 0;
379 if ((brush = GDI_GetObjPtr( handle, BRUSH_MAGIC )))
381 if (brush->logbrush.lbStyle == BS_PATTERN)
382 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
384 if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
385 if (handle)
387 ret = dc->hBrush;
388 dc->hBrush = handle;
389 GDI_inc_ref_count( handle );
390 GDI_dec_ref_count( ret );
392 GDI_ReleaseObj( handle );
394 release_dc_ptr( dc );
395 return ret;
399 /***********************************************************************
400 * BRUSH_DeleteObject
402 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
404 BRUSHOBJ *brush = obj;
406 switch(brush->logbrush.lbStyle)
408 case BS_PATTERN:
409 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
410 break;
411 case BS_DIBPATTERN:
412 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
413 break;
415 return GDI_FreeObject( handle, obj );
419 /***********************************************************************
420 * BRUSH_GetObject16
422 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
424 BRUSHOBJ *brush = obj;
425 LOGBRUSH16 logbrush;
427 logbrush.lbStyle = brush->logbrush.lbStyle;
428 logbrush.lbColor = brush->logbrush.lbColor;
429 logbrush.lbHatch = brush->logbrush.lbHatch;
430 if (count > sizeof(logbrush)) count = sizeof(logbrush);
431 memcpy( buffer, &logbrush, count );
432 return count;
436 /***********************************************************************
437 * BRUSH_GetObject
439 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
441 BRUSHOBJ *brush = obj;
443 if( !buffer )
444 return sizeof(brush->logbrush);
446 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
447 memcpy( buffer, &brush->logbrush, count );
448 return count;
452 /***********************************************************************
453 * SetSolidBrush (GDI.604)
455 * Change the color of a solid brush.
457 * PARAMS
458 * hBrush [I] Brush to change the color of
459 * newColor [I] New color for hBrush
461 * RETURNS
462 * Success: TRUE. The color of hBrush is set to newColor.
463 * Failure: FALSE.
465 * FIXME
466 * This function is undocumented and untested. The implementation may
467 * not be correct.
469 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
471 BRUSHOBJ * brushPtr;
472 BOOL16 res = FALSE;
474 TRACE("(hBrush %04x, newColor %08x)\n", hBrush, newColor);
475 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( HBRUSH_32(hBrush), BRUSH_MAGIC )))
476 return FALSE;
478 if (brushPtr->logbrush.lbStyle == BS_SOLID)
480 brushPtr->logbrush.lbColor = newColor;
481 res = TRUE;
484 GDI_ReleaseObj( HBRUSH_32(hBrush) );
485 return res;