- Clean up and add some comments.
[wine/multimedia.git] / objects / brush.c
blob4f268fda16d7b3055be37dce24f3a55e80670ced
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
23 #include <string.h>
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "wine/wingdi16.h"
28 #include "bitmap.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
33 /* GDI logical brush object */
34 typedef struct
36 GDIOBJHDR header;
37 LOGBRUSH logbrush;
38 } BRUSHOBJ;
40 #define NB_HATCH_STYLES 6
42 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
43 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
44 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
45 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
47 static const struct gdi_obj_funcs brush_funcs =
49 BRUSH_SelectObject, /* pSelectObject */
50 BRUSH_GetObject16, /* pGetObject16 */
51 BRUSH_GetObject, /* pGetObjectA */
52 BRUSH_GetObject, /* pGetObjectW */
53 NULL, /* pUnrealizeObject */
54 BRUSH_DeleteObject /* pDeleteObject */
57 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
59 BITMAPINFO *newInfo;
60 HGLOBAL16 hmem;
61 INT size;
63 if (info->bmiHeader.biCompression)
64 size = info->bmiHeader.biSizeImage;
65 else
66 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
67 info->bmiHeader.biHeight,
68 info->bmiHeader.biBitCount);
69 size += DIB_BitmapInfoSize( info, coloruse );
71 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
73 return 0;
75 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
76 memcpy( newInfo, info, size );
77 GlobalUnlock16( hmem );
78 return hmem;
82 /***********************************************************************
83 * CreateBrushIndirect (GDI32.@)
85 * BUGS
86 * As for Windows 95 and Windows 98:
87 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
88 * is not supported. If a larger bitmap is given, only a portion
89 * of the bitmap is used.
91 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
93 BRUSHOBJ * ptr;
94 HBRUSH hbrush;
96 if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush, &brush_funcs ))) return 0;
97 ptr->logbrush.lbStyle = brush->lbStyle;
98 ptr->logbrush.lbColor = brush->lbColor;
99 ptr->logbrush.lbHatch = brush->lbHatch;
101 switch (ptr->logbrush.lbStyle)
103 case BS_PATTERN8X8:
104 ptr->logbrush.lbStyle = BS_PATTERN;
105 /* fall through */
106 case BS_PATTERN:
107 ptr->logbrush.lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
108 if (!ptr->logbrush.lbHatch) goto error;
109 break;
111 case BS_DIBPATTERNPT:
112 ptr->logbrush.lbStyle = BS_DIBPATTERN;
113 ptr->logbrush.lbHatch = (LONG)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
114 ptr->logbrush.lbColor);
115 if (!ptr->logbrush.lbHatch) goto error;
116 break;
118 case BS_DIBPATTERN8X8:
119 case BS_DIBPATTERN:
121 BITMAPINFO* bmi;
122 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
124 ptr->logbrush.lbStyle = BS_DIBPATTERN;
125 if (!(bmi = (BITMAPINFO *)GlobalLock( h ))) goto error;
126 ptr->logbrush.lbHatch = dib_copy( bmi, ptr->logbrush.lbColor);
127 GlobalUnlock( h );
128 if (!ptr->logbrush.lbHatch) goto error;
129 break;
132 default:
133 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
134 break;
137 GDI_ReleaseObj( hbrush );
138 TRACE("%08x\n", hbrush);
139 return hbrush;
141 error:
142 GDI_FreeObject( hbrush, ptr );
143 return 0;
147 /***********************************************************************
148 * CreateHatchBrush (GDI32.@)
150 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
152 LOGBRUSH logbrush;
154 TRACE("%d %06lx\n", style, color );
156 logbrush.lbStyle = BS_HATCHED;
157 logbrush.lbColor = color;
158 logbrush.lbHatch = style;
160 return CreateBrushIndirect( &logbrush );
164 /***********************************************************************
165 * CreatePatternBrush (GDI32.@)
167 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
169 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
170 TRACE("%04x\n", hbitmap );
172 logbrush.lbHatch = (ULONG_PTR)hbitmap;
173 return CreateBrushIndirect( &logbrush );
177 /***********************************************************************
178 * CreateDIBPatternBrush (GDI32.@)
180 * Create a logical brush which has the pattern specified by the DIB
182 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
184 * RETURNS
186 * Handle to a logical brush on success, NULL on failure.
188 * BUGS
191 HBRUSH WINAPI CreateDIBPatternBrush(
192 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
193 UINT coloruse /* [in] Specifies color format, if provided */
196 LOGBRUSH logbrush;
198 TRACE("%04x\n", hbitmap );
200 logbrush.lbStyle = BS_DIBPATTERN;
201 logbrush.lbColor = coloruse;
203 logbrush.lbHatch = (LONG)hbitmap;
205 return CreateBrushIndirect( &logbrush );
209 /***********************************************************************
210 * CreateDIBPatternBrushPt (GDI32.@)
212 * Create a logical brush which has the pattern specified by the DIB
214 * RETURNS
216 * Handle to a logical brush on success, NULL on failure.
218 * BUGS
221 HBRUSH WINAPI CreateDIBPatternBrushPt(
222 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
223 UINT coloruse /* [in] Specifies color format, if provided */
226 BITMAPINFO *info=(BITMAPINFO*)data;
227 LOGBRUSH logbrush;
229 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
230 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
232 logbrush.lbStyle = BS_DIBPATTERNPT;
233 logbrush.lbColor = coloruse;
234 logbrush.lbHatch = (LONG) data;
236 return CreateBrushIndirect( &logbrush );
240 /***********************************************************************
241 * CreateSolidBrush (GDI32.@)
243 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
245 LOGBRUSH logbrush;
247 TRACE("%06lx\n", color );
249 logbrush.lbStyle = BS_SOLID;
250 logbrush.lbColor = color;
251 logbrush.lbHatch = 0;
253 return CreateBrushIndirect( &logbrush );
257 /***********************************************************************
258 * SetBrushOrgEx (GDI32.@)
260 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
262 DC *dc = DC_GetDCPtr( hdc );
264 if (!dc) return FALSE;
265 if (oldorg)
267 oldorg->x = dc->brushOrgX;
268 oldorg->y = dc->brushOrgY;
270 dc->brushOrgX = x;
271 dc->brushOrgY = y;
272 GDI_ReleaseObj( hdc );
273 return TRUE;
276 /***********************************************************************
277 * FixBrushOrgEx (GDI32.@)
278 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
280 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
282 return SetBrushOrgEx(hdc,x,y,oldorg);
286 /***********************************************************************
287 * BRUSH_SelectObject
289 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
291 BRUSHOBJ *brush = obj;
292 HGDIOBJ ret;
293 DC *dc = DC_GetDCPtr( hdc );
295 if (!dc) return 0;
297 if (brush->logbrush.lbStyle == BS_PATTERN)
298 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
300 ret = dc->hBrush;
301 if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
302 if (handle) dc->hBrush = handle;
303 else ret = 0;
304 GDI_ReleaseObj( hdc );
305 return ret;
309 /***********************************************************************
310 * BRUSH_DeleteObject
312 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
314 BRUSHOBJ *brush = obj;
316 switch(brush->logbrush.lbStyle)
318 case BS_PATTERN:
319 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
320 break;
321 case BS_DIBPATTERN:
322 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
323 break;
325 return GDI_FreeObject( handle, obj );
329 /***********************************************************************
330 * BRUSH_GetObject16
332 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
334 BRUSHOBJ *brush = obj;
335 LOGBRUSH16 logbrush;
337 logbrush.lbStyle = brush->logbrush.lbStyle;
338 logbrush.lbColor = brush->logbrush.lbColor;
339 logbrush.lbHatch = brush->logbrush.lbHatch;
340 if (count > sizeof(logbrush)) count = sizeof(logbrush);
341 memcpy( buffer, &logbrush, count );
342 return count;
346 /***********************************************************************
347 * BRUSH_GetObject
349 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
351 BRUSHOBJ *brush = obj;
353 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
354 memcpy( buffer, &brush->logbrush, count );
355 return count;
359 /***********************************************************************
360 * SetSolidBrush (GDI.604)
362 * If hBrush is a solid brush, change its color to newColor.
364 * RETURNS
365 * TRUE on success, FALSE on failure.
367 * FIXME: untested, not sure if correct.
369 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
371 BRUSHOBJ * brushPtr;
372 BOOL16 res = FALSE;
374 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
375 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( hBrush, BRUSH_MAGIC )))
376 return FALSE;
378 if (brushPtr->logbrush.lbStyle == BS_SOLID)
380 brushPtr->logbrush.lbColor = newColor;
381 res = TRUE;
384 GDI_ReleaseObj( hBrush );
385 return res;