Added some more tests.
[wine.git] / objects / brush.c
blobac747f7274b545f91aa6c938aaabef7dde16d562
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"
28 #include "wine/wingdi16.h"
29 #include "bitmap.h"
30 #include "brush.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
36 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
38 BITMAPINFO *newInfo;
39 HGLOBAL16 hmem;
40 INT size;
42 if (info->bmiHeader.biCompression)
43 size = info->bmiHeader.biSizeImage;
44 else
45 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
46 info->bmiHeader.biHeight,
47 info->bmiHeader.biBitCount);
48 size += DIB_BitmapInfoSize( info, coloruse );
50 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
52 return 0;
54 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
55 memcpy( newInfo, info, size );
56 GlobalUnlock16( hmem );
57 return hmem;
62 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
64 LOGBRUSH *brush = &brushPtr->logbrush;
66 switch (brush->lbStyle)
68 case BS_PATTERN8X8:
69 brush->lbStyle = BS_PATTERN;
70 case BS_PATTERN:
71 brush->lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) brush->lbHatch );
72 if (! brush->lbHatch)
73 break;
74 return TRUE;
76 case BS_DIBPATTERNPT:
77 brush->lbStyle = BS_DIBPATTERN;
78 brush->lbHatch = (LONG)dib_copy( (BITMAPINFO *) brush->lbHatch,
79 brush->lbColor);
80 if (! brush->lbHatch)
81 break;
82 return TRUE;
84 case BS_DIBPATTERN8X8:
85 case BS_DIBPATTERN:
87 BITMAPINFO* bmi;
88 HGLOBAL h = brush->lbHatch;
90 brush->lbStyle = BS_DIBPATTERN;
91 if (v16)
93 if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
94 break;
96 else
98 if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
99 break;
102 brush->lbHatch = dib_copy( bmi, brush->lbColor);
104 if (v16) GlobalUnlock16( h );
105 else GlobalUnlock( h );
107 if (!brush->lbHatch)
108 break;
110 return TRUE;
113 default:
114 if( brush->lbStyle <= BS_MONOPATTERN)
115 return TRUE;
118 return FALSE;
122 /***********************************************************************
123 * CreateBrushIndirect (GDI.50)
125 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
127 BOOL success;
128 BRUSHOBJ * brushPtr;
129 HBRUSH hbrush;
131 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
132 brushPtr->logbrush.lbStyle = brush->lbStyle;
133 brushPtr->logbrush.lbColor = brush->lbColor;
134 brushPtr->logbrush.lbHatch = brush->lbHatch;
135 success = create_brush_indirect(brushPtr, TRUE);
136 if(!success)
138 GDI_FreeObject( hbrush, brushPtr );
139 hbrush = 0;
141 else GDI_ReleaseObj( hbrush );
142 TRACE("%04x\n", hbrush);
143 return hbrush;
147 /***********************************************************************
148 * CreateBrushIndirect (GDI32.@)
150 * BUGS
151 * As for Windows 95 and Windows 98:
152 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
153 * is not supported. If a larger bitmap is given, only a portion
154 * of the bitmap is used.
156 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
158 BOOL success;
159 BRUSHOBJ * brushPtr;
160 HBRUSH hbrush;
161 if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
162 brushPtr->logbrush.lbStyle = brush->lbStyle;
163 brushPtr->logbrush.lbColor = brush->lbColor;
164 brushPtr->logbrush.lbHatch = brush->lbHatch;
165 success = create_brush_indirect(brushPtr, FALSE);
166 if(!success)
168 GDI_FreeObject( hbrush, brushPtr );
169 hbrush = 0;
171 else GDI_ReleaseObj( hbrush );
172 TRACE("%08x\n", hbrush);
173 return hbrush;
177 /***********************************************************************
178 * CreateHatchBrush (GDI.58)
180 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
182 return CreateHatchBrush( style, color );
186 /***********************************************************************
187 * CreateHatchBrush (GDI32.@)
189 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
191 LOGBRUSH logbrush;
193 TRACE("%d %06lx\n", style, color );
195 logbrush.lbStyle = BS_HATCHED;
196 logbrush.lbColor = color;
197 logbrush.lbHatch = style;
199 return CreateBrushIndirect( &logbrush );
203 /***********************************************************************
204 * CreatePatternBrush (GDI.60)
206 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
208 return (HBRUSH16)CreatePatternBrush( hbitmap );
212 /***********************************************************************
213 * CreatePatternBrush (GDI32.@)
215 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
217 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
218 TRACE("%04x\n", hbitmap );
220 logbrush.lbHatch = hbitmap;
221 return CreateBrushIndirect( &logbrush );
225 /***********************************************************************
226 * CreateDIBPatternBrush (GDI.445)
228 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
230 LOGBRUSH16 logbrush;
232 TRACE("%04x\n", hbitmap );
234 logbrush.lbStyle = BS_DIBPATTERN;
235 logbrush.lbColor = coloruse;
236 logbrush.lbHatch = hbitmap;
238 return CreateBrushIndirect16( &logbrush );
242 /***********************************************************************
243 * CreateDIBPatternBrush (GDI32.@)
245 * Create a logical brush which has the pattern specified by the DIB
247 * Function call is for compatibility only. CreateDIBPatternBrushPt should be used.
249 * RETURNS
251 * Handle to a logical brush on success, NULL on failure.
253 * BUGS
256 HBRUSH WINAPI CreateDIBPatternBrush(
257 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
258 UINT coloruse /* [in] Specifies color format, if provided */
261 LOGBRUSH logbrush;
263 TRACE("%04x\n", hbitmap );
265 logbrush.lbStyle = BS_DIBPATTERN;
266 logbrush.lbColor = coloruse;
268 logbrush.lbHatch = (LONG)hbitmap;
270 return CreateBrushIndirect( &logbrush );
274 /***********************************************************************
275 * CreateDIBPatternBrushPt (GDI32.@)
277 * Create a logical brush which has the pattern specified by the DIB
279 * RETURNS
281 * Handle to a logical brush on success, NULL on failure.
283 * BUGS
286 HBRUSH WINAPI CreateDIBPatternBrushPt(
287 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */
288 UINT coloruse /* [in] Specifies color format, if provided */
291 BITMAPINFO *info=(BITMAPINFO*)data;
292 LOGBRUSH logbrush;
294 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
295 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
297 logbrush.lbStyle = BS_DIBPATTERNPT;
298 logbrush.lbColor = coloruse;
299 logbrush.lbHatch = (LONG) data;
301 return CreateBrushIndirect( &logbrush );
305 /***********************************************************************
306 * CreateSolidBrush (GDI.66)
308 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
310 return CreateSolidBrush( color );
314 /***********************************************************************
315 * CreateSolidBrush (GDI32.@)
317 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
319 LOGBRUSH logbrush;
321 TRACE("%06lx\n", color );
323 logbrush.lbStyle = BS_SOLID;
324 logbrush.lbColor = color;
325 logbrush.lbHatch = 0;
327 return CreateBrushIndirect( &logbrush );
331 /***********************************************************************
332 * SetBrushOrg (GDI.148)
334 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
336 DWORD retval;
337 DC *dc = DC_GetDCPtr( hdc );
338 if (!dc) return FALSE;
339 retval = dc->brushOrgX | (dc->brushOrgY << 16);
340 dc->brushOrgX = x;
341 dc->brushOrgY = y;
342 GDI_ReleaseObj( hdc );
343 return retval;
347 /***********************************************************************
348 * SetBrushOrgEx (GDI32.@)
350 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
352 DC *dc = DC_GetDCPtr( hdc );
354 if (!dc) return FALSE;
355 if (oldorg)
357 oldorg->x = dc->brushOrgX;
358 oldorg->y = dc->brushOrgY;
360 dc->brushOrgX = x;
361 dc->brushOrgY = y;
362 GDI_ReleaseObj( hdc );
363 return TRUE;
366 /***********************************************************************
367 * FixBrushOrgEx (GDI32.@)
368 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
370 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
372 return SetBrushOrgEx(hdc,x,y,oldorg);
376 /***********************************************************************
377 * BRUSH_DeleteObject
379 BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
381 switch(brush->logbrush.lbStyle)
383 case BS_PATTERN:
384 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
385 break;
386 case BS_DIBPATTERN:
387 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
388 break;
390 return GDI_FreeObject( hbrush, brush );
394 /***********************************************************************
395 * BRUSH_GetObject16
397 INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
399 LOGBRUSH16 logbrush;
401 logbrush.lbStyle = brush->logbrush.lbStyle;
402 logbrush.lbColor = brush->logbrush.lbColor;
403 logbrush.lbHatch = brush->logbrush.lbHatch;
404 if (count > sizeof(logbrush)) count = sizeof(logbrush);
405 memcpy( buffer, &logbrush, count );
406 return count;
410 /***********************************************************************
411 * BRUSH_GetObject
413 INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
415 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
416 memcpy( buffer, &brush->logbrush, count );
417 return count;
421 /***********************************************************************
422 * SetSolidBrush (GDI.604)
424 * If hBrush is a solid brush, change its color to newColor.
426 * RETURNS
427 * TRUE on success, FALSE on failure.
429 * FIXME: untested, not sure if correct.
431 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
433 BRUSHOBJ * brushPtr;
434 BOOL16 res = FALSE;
436 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
437 if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( hBrush, BRUSH_MAGIC )))
438 return FALSE;
440 if (brushPtr->logbrush.lbStyle == BS_SOLID)
442 brushPtr->logbrush.lbColor = newColor;
443 res = TRUE;
446 GDI_ReleaseObj( hBrush );
447 return res;