Added function table to GDI objects for better encapsulation.
[wine.git] / objects / brush.c
blob16e107b3533b4d66e1951e1f85ee7bd56d084ae5
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;
83 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
85 LOGBRUSH *brush = &brushPtr->logbrush;
87 switch (brush->lbStyle)
89 case BS_PATTERN8X8:
90 brush->lbStyle = BS_PATTERN;
91 case BS_PATTERN:
92 brush->lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) brush->lbHatch );
93 if (! brush->lbHatch)
94 break;
95 return TRUE;
97 case BS_DIBPATTERNPT:
98 brush->lbStyle = BS_DIBPATTERN;
99 brush->lbHatch = (LONG)dib_copy( (BITMAPINFO *) brush->lbHatch,
100 brush->lbColor);
101 if (! brush->lbHatch)
102 break;
103 return TRUE;
105 case BS_DIBPATTERN8X8:
106 case BS_DIBPATTERN:
108 BITMAPINFO* bmi;
109 HGLOBAL h = brush->lbHatch;
111 brush->lbStyle = BS_DIBPATTERN;
112 if (v16)
114 if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
115 break;
117 else
119 if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
120 break;
123 brush->lbHatch = dib_copy( bmi, brush->lbColor);
125 if (v16) GlobalUnlock16( h );
126 else GlobalUnlock( h );
128 if (!brush->lbHatch)
129 break;
131 return TRUE;
134 default:
135 if( brush->lbStyle <= BS_MONOPATTERN)
136 return TRUE;
139 return FALSE;
143 /***********************************************************************
144 * CreateBrushIndirect (GDI.50)
146 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
148 BOOL success;
149 BRUSHOBJ * brushPtr;
150 HBRUSH hbrush;
152 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush, &brush_funcs )))
153 return 0;
154 brushPtr->logbrush.lbStyle = brush->lbStyle;
155 brushPtr->logbrush.lbColor = brush->lbColor;
156 brushPtr->logbrush.lbHatch = brush->lbHatch;
157 success = create_brush_indirect(brushPtr, TRUE);
158 if(!success)
160 GDI_FreeObject( hbrush, brushPtr );
161 hbrush = 0;
163 else GDI_ReleaseObj( hbrush );
164 TRACE("%04x\n", hbrush);
165 return hbrush;
169 /***********************************************************************
170 * CreateBrushIndirect (GDI32.@)
172 * BUGS
173 * As for Windows 95 and Windows 98:
174 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
175 * is not supported. If a larger bitmap is given, only a portion
176 * of the bitmap is used.
178 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
180 BOOL success;
181 BRUSHOBJ * brushPtr;
182 HBRUSH hbrush;
183 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush, &brush_funcs )))
184 return 0;
185 brushPtr->logbrush.lbStyle = brush->lbStyle;
186 brushPtr->logbrush.lbColor = brush->lbColor;
187 brushPtr->logbrush.lbHatch = brush->lbHatch;
188 success = create_brush_indirect(brushPtr, FALSE);
189 if(!success)
191 GDI_FreeObject( hbrush, brushPtr );
192 hbrush = 0;
194 else GDI_ReleaseObj( hbrush );
195 TRACE("%08x\n", hbrush);
196 return hbrush;
200 /***********************************************************************
201 * CreateHatchBrush (GDI.58)
203 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
205 return CreateHatchBrush( style, color );
209 /***********************************************************************
210 * CreateHatchBrush (GDI32.@)
212 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
214 LOGBRUSH logbrush;
216 TRACE("%d %06lx\n", style, color );
218 logbrush.lbStyle = BS_HATCHED;
219 logbrush.lbColor = color;
220 logbrush.lbHatch = style;
222 return CreateBrushIndirect( &logbrush );
226 /***********************************************************************
227 * CreatePatternBrush (GDI.60)
229 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
231 return (HBRUSH16)CreatePatternBrush( hbitmap );
235 /***********************************************************************
236 * CreatePatternBrush (GDI32.@)
238 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
240 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
241 TRACE("%04x\n", hbitmap );
243 logbrush.lbHatch = hbitmap;
244 return CreateBrushIndirect( &logbrush );
248 /***********************************************************************
249 * CreateDIBPatternBrush (GDI.445)
251 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
253 LOGBRUSH16 logbrush;
255 TRACE("%04x\n", hbitmap );
257 logbrush.lbStyle = BS_DIBPATTERN;
258 logbrush.lbColor = coloruse;
259 logbrush.lbHatch = hbitmap;
261 return CreateBrushIndirect16( &logbrush );
265 /***********************************************************************
266 * CreateDIBPatternBrush (GDI32.@)
268 * Create a logical brush which has the pattern specified by the DIB
270 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
272 * RETURNS
274 * Handle to a logical brush on success, NULL on failure.
276 * BUGS
279 HBRUSH WINAPI CreateDIBPatternBrush(
280 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
281 UINT coloruse /* [in] Specifies color format, if provided */
284 LOGBRUSH logbrush;
286 TRACE("%04x\n", hbitmap );
288 logbrush.lbStyle = BS_DIBPATTERN;
289 logbrush.lbColor = coloruse;
291 logbrush.lbHatch = (LONG)hbitmap;
293 return CreateBrushIndirect( &logbrush );
297 /***********************************************************************
298 * CreateDIBPatternBrushPt (GDI32.@)
300 * Create a logical brush which has the pattern specified by the DIB
302 * RETURNS
304 * Handle to a logical brush on success, NULL on failure.
306 * BUGS
309 HBRUSH WINAPI CreateDIBPatternBrushPt(
310 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
311 UINT coloruse /* [in] Specifies color format, if provided */
314 BITMAPINFO *info=(BITMAPINFO*)data;
315 LOGBRUSH logbrush;
317 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
318 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
320 logbrush.lbStyle = BS_DIBPATTERNPT;
321 logbrush.lbColor = coloruse;
322 logbrush.lbHatch = (LONG) data;
324 return CreateBrushIndirect( &logbrush );
328 /***********************************************************************
329 * CreateSolidBrush (GDI.66)
331 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
333 return CreateSolidBrush( color );
337 /***********************************************************************
338 * CreateSolidBrush (GDI32.@)
340 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
342 LOGBRUSH logbrush;
344 TRACE("%06lx\n", color );
346 logbrush.lbStyle = BS_SOLID;
347 logbrush.lbColor = color;
348 logbrush.lbHatch = 0;
350 return CreateBrushIndirect( &logbrush );
354 /***********************************************************************
355 * SetBrushOrg (GDI.148)
357 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
359 DWORD retval;
360 DC *dc = DC_GetDCPtr( hdc );
361 if (!dc) return FALSE;
362 retval = dc->brushOrgX | (dc->brushOrgY << 16);
363 dc->brushOrgX = x;
364 dc->brushOrgY = y;
365 GDI_ReleaseObj( hdc );
366 return retval;
370 /***********************************************************************
371 * SetBrushOrgEx (GDI32.@)
373 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
375 DC *dc = DC_GetDCPtr( hdc );
377 if (!dc) return FALSE;
378 if (oldorg)
380 oldorg->x = dc->brushOrgX;
381 oldorg->y = dc->brushOrgY;
383 dc->brushOrgX = x;
384 dc->brushOrgY = y;
385 GDI_ReleaseObj( hdc );
386 return TRUE;
389 /***********************************************************************
390 * FixBrushOrgEx (GDI32.@)
391 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
393 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
395 return SetBrushOrgEx(hdc,x,y,oldorg);
399 /***********************************************************************
400 * BRUSH_SelectObject
402 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
404 BRUSHOBJ *brush = obj;
405 HGDIOBJ ret;
406 DC *dc = DC_GetDCPtr( hdc );
408 if (!dc) return 0;
410 if (brush->logbrush.lbStyle == BS_PATTERN)
411 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
413 ret = dc->hBrush;
414 if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
415 if (handle) dc->hBrush = handle;
416 else ret = 0;
417 GDI_ReleaseObj( hdc );
418 return ret;
422 /***********************************************************************
423 * BRUSH_DeleteObject
425 static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
427 BRUSHOBJ *brush = obj;
429 switch(brush->logbrush.lbStyle)
431 case BS_PATTERN:
432 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
433 break;
434 case BS_DIBPATTERN:
435 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
436 break;
438 return GDI_FreeObject( handle, obj );
442 /***********************************************************************
443 * BRUSH_GetObject16
445 static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
447 BRUSHOBJ *brush = obj;
448 LOGBRUSH16 logbrush;
450 logbrush.lbStyle = brush->logbrush.lbStyle;
451 logbrush.lbColor = brush->logbrush.lbColor;
452 logbrush.lbHatch = brush->logbrush.lbHatch;
453 if (count > sizeof(logbrush)) count = sizeof(logbrush);
454 memcpy( buffer, &logbrush, count );
455 return count;
459 /***********************************************************************
460 * BRUSH_GetObject
462 static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
464 BRUSHOBJ *brush = obj;
466 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
467 memcpy( buffer, &brush->logbrush, count );
468 return count;
472 /***********************************************************************
473 * SetSolidBrush (GDI.604)
475 * If hBrush is a solid brush, change its color to newColor.
477 * RETURNS
478 * TRUE on success, FALSE on failure.
480 * FIXME: untested, not sure if correct.
482 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
484 BRUSHOBJ * brushPtr;
485 BOOL16 res = FALSE;
487 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
488 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( hBrush, BRUSH_MAGIC )))
489 return FALSE;
491 if (brushPtr->logbrush.lbStyle == BS_SOLID)
493 brushPtr->logbrush.lbColor = newColor;
494 res = TRUE;
497 GDI_ReleaseObj( hBrush );
498 return res;