- removed next & prev fields from WINE_MODREF and implement instead
[wine.git] / objects / brush.c
blobd4a881ded2c22f3f4c46168853d91ae27ae554f6
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 "wownt32.h"
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
34 /* GDI logical brush object */
35 typedef struct
37 GDIOBJHDR header;
38 LOGBRUSH logbrush;
39 } BRUSHOBJ;
41 #define NB_HATCH_STYLES 6
43 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
44 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
45 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
46 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
48 static const struct gdi_obj_funcs brush_funcs =
50 BRUSH_SelectObject, /* pSelectObject */
51 BRUSH_GetObject16, /* pGetObject16 */
52 BRUSH_GetObject, /* pGetObjectA */
53 BRUSH_GetObject, /* pGetObjectW */
54 NULL, /* pUnrealizeObject */
55 BRUSH_DeleteObject /* pDeleteObject */
58 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
60 BITMAPINFO *newInfo;
61 HGLOBAL16 hmem;
62 INT size;
64 if (info->bmiHeader.biCompression)
65 size = info->bmiHeader.biSizeImage;
66 else
67 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
68 info->bmiHeader.biHeight,
69 info->bmiHeader.biBitCount);
70 size += DIB_BitmapInfoSize( 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 * BUGS
87 * As for Windows 95 and Windows 98:
88 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
89 * is not supported. If a larger bitmap is given, only a portion
90 * of the bitmap is used.
92 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
94 BRUSHOBJ * ptr;
95 HBRUSH hbrush;
97 if (!(ptr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC,
98 (HGDIOBJ *)&hbrush, &brush_funcs ))) return 0;
99 ptr->logbrush.lbStyle = brush->lbStyle;
100 ptr->logbrush.lbColor = brush->lbColor;
101 ptr->logbrush.lbHatch = brush->lbHatch;
103 switch (ptr->logbrush.lbStyle)
105 case BS_PATTERN8X8:
106 ptr->logbrush.lbStyle = BS_PATTERN;
107 /* fall through */
108 case BS_PATTERN:
109 ptr->logbrush.lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
110 if (!ptr->logbrush.lbHatch) goto error;
111 break;
113 case BS_DIBPATTERNPT:
114 ptr->logbrush.lbStyle = BS_DIBPATTERN;
115 ptr->logbrush.lbHatch = (LONG)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
116 ptr->logbrush.lbColor);
117 if (!ptr->logbrush.lbHatch) goto error;
118 break;
120 case BS_DIBPATTERN8X8:
121 case BS_DIBPATTERN:
123 BITMAPINFO* bmi;
124 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
126 ptr->logbrush.lbStyle = BS_DIBPATTERN;
127 if (!(bmi = (BITMAPINFO *)GlobalLock( h ))) goto error;
128 ptr->logbrush.lbHatch = dib_copy( bmi, ptr->logbrush.lbColor);
129 GlobalUnlock( h );
130 if (!ptr->logbrush.lbHatch) goto error;
131 break;
134 default:
135 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
136 break;
139 GDI_ReleaseObj( hbrush );
140 TRACE("%p\n", hbrush);
141 return hbrush;
143 error:
144 GDI_FreeObject( hbrush, ptr );
145 return 0;
149 /***********************************************************************
150 * CreateHatchBrush (GDI32.@)
152 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
154 LOGBRUSH logbrush;
156 TRACE("%d %06lx\n", style, color );
158 logbrush.lbStyle = BS_HATCHED;
159 logbrush.lbColor = color;
160 logbrush.lbHatch = style;
162 return CreateBrushIndirect( &logbrush );
166 /***********************************************************************
167 * CreatePatternBrush (GDI32.@)
169 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
171 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
172 TRACE("%p\n", hbitmap );
174 logbrush.lbHatch = (ULONG_PTR)hbitmap;
175 return CreateBrushIndirect( &logbrush );
179 /***********************************************************************
180 * CreateDIBPatternBrush (GDI32.@)
182 * Create a logical brush which has the pattern specified by the DIB
184 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
186 * RETURNS
188 * Handle to a logical brush on success, NULL on failure.
190 * BUGS
193 HBRUSH WINAPI CreateDIBPatternBrush(
194 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
195 UINT coloruse /* [in] Specifies color format, if provided */
198 LOGBRUSH logbrush;
200 TRACE("%p\n", hbitmap );
202 logbrush.lbStyle = BS_DIBPATTERN;
203 logbrush.lbColor = coloruse;
205 logbrush.lbHatch = (LONG)hbitmap;
207 return CreateBrushIndirect( &logbrush );
211 /***********************************************************************
212 * CreateDIBPatternBrushPt (GDI32.@)
214 * Create a logical brush which has the pattern specified by the DIB
216 * RETURNS
218 * Handle to a logical brush on success, NULL on failure.
220 * BUGS
223 HBRUSH WINAPI CreateDIBPatternBrushPt(
224 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
225 UINT coloruse /* [in] Specifies color format, if provided */
228 BITMAPINFO *info=(BITMAPINFO*)data;
229 LOGBRUSH logbrush;
231 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
232 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
234 logbrush.lbStyle = BS_DIBPATTERNPT;
235 logbrush.lbColor = coloruse;
236 logbrush.lbHatch = (LONG) data;
238 return CreateBrushIndirect( &logbrush );
242 /***********************************************************************
243 * CreateSolidBrush (GDI32.@)
245 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
247 LOGBRUSH logbrush;
249 TRACE("%06lx\n", color );
251 logbrush.lbStyle = BS_SOLID;
252 logbrush.lbColor = color;
253 logbrush.lbHatch = 0;
255 return CreateBrushIndirect( &logbrush );
259 /***********************************************************************
260 * SetBrushOrgEx (GDI32.@)
262 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
264 DC *dc = DC_GetDCPtr( hdc );
266 if (!dc) return FALSE;
267 if (oldorg)
269 oldorg->x = dc->brushOrgX;
270 oldorg->y = dc->brushOrgY;
272 dc->brushOrgX = x;
273 dc->brushOrgY = y;
274 GDI_ReleaseObj( hdc );
275 return TRUE;
278 /***********************************************************************
279 * FixBrushOrgEx (GDI32.@)
280 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
282 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
284 return SetBrushOrgEx(hdc,x,y,oldorg);
288 /***********************************************************************
289 * BRUSH_SelectObject
291 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
293 BRUSHOBJ *brush = obj;
294 HGDIOBJ ret;
295 DC *dc = DC_GetDCPtr( hdc );
297 if (!dc) return 0;
299 if (brush->logbrush.lbStyle == BS_PATTERN)
300 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
302 ret = dc->hBrush;
303 if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
304 if (handle) dc->hBrush = handle;
305 else ret = 0;
306 GDI_ReleaseObj( hdc );
307 return ret;
311 /***********************************************************************
312 * BRUSH_DeleteObject
314 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
316 BRUSHOBJ *brush = obj;
318 switch(brush->logbrush.lbStyle)
320 case BS_PATTERN:
321 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
322 break;
323 case BS_DIBPATTERN:
324 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
325 break;
327 return GDI_FreeObject( handle, obj );
331 /***********************************************************************
332 * BRUSH_GetObject16
334 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
336 BRUSHOBJ *brush = obj;
337 LOGBRUSH16 logbrush;
339 logbrush.lbStyle = brush->logbrush.lbStyle;
340 logbrush.lbColor = brush->logbrush.lbColor;
341 logbrush.lbHatch = brush->logbrush.lbHatch;
342 if (count > sizeof(logbrush)) count = sizeof(logbrush);
343 memcpy( buffer, &logbrush, count );
344 return count;
348 /***********************************************************************
349 * BRUSH_GetObject
351 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
353 BRUSHOBJ *brush = obj;
355 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
356 memcpy( buffer, &brush->logbrush, count );
357 return count;
361 /***********************************************************************
362 * SetSolidBrush (GDI.604)
364 * If hBrush is a solid brush, change its color to newColor.
366 * RETURNS
367 * TRUE on success, FALSE on failure.
369 * FIXME: untested, not sure if correct.
371 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
373 BRUSHOBJ * brushPtr;
374 BOOL16 res = FALSE;
376 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
377 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( HBRUSH_32(hBrush), BRUSH_MAGIC )))
378 return FALSE;
380 if (brushPtr->logbrush.lbStyle == BS_SOLID)
382 brushPtr->logbrush.lbColor = newColor;
383 res = TRUE;
386 GDI_ReleaseObj( HBRUSH_32(hBrush) );
387 return res;