Copy bitmaps properly.
[wine.git] / objects / brush.c
blob0ea8dec44a6891733566984f3fb348149bbc7b5d
1 /*
2 * GDI brush objects
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <string.h>
8 #include "winbase.h"
9 #include "brush.h"
10 #include "bitmap.h"
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(gdi)
15 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
17 BITMAPINFO *newInfo;
18 HGLOBAL16 hmem;
19 INT size;
21 if (info->bmiHeader.biCompression)
22 size = info->bmiHeader.biSizeImage;
23 else
24 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
25 info->bmiHeader.biHeight,
26 info->bmiHeader.biBitCount);
27 size += DIB_BitmapInfoSize( info, coloruse );
29 if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
31 return 0;
33 newInfo = (BITMAPINFO *) GlobalLock16( hmem );
34 memcpy( newInfo, info, size );
35 GlobalUnlock16( hmem );
36 return hmem;
41 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
43 LOGBRUSH *brush = &brushPtr->logbrush;
45 switch (brush->lbStyle)
47 case BS_PATTERN8X8:
48 brush->lbStyle = BS_PATTERN;
49 case BS_PATTERN:
50 brush->lbHatch = (LONG)BITMAP_CopyBitmap( (HBITMAP) brush->lbHatch );
51 if (! brush->lbHatch)
52 break;
53 return TRUE;
55 case BS_DIBPATTERNPT:
56 brush->lbStyle = BS_DIBPATTERN;
57 brush->lbHatch = (LONG)dib_copy( (BITMAPINFO *) brush->lbHatch,
58 brush->lbColor);
59 if (! brush->lbHatch)
60 break;
61 return TRUE;
63 case BS_DIBPATTERN8X8:
64 case BS_DIBPATTERN:
66 BITMAPINFO* bmi;
67 HGLOBAL h = brush->lbHatch;
69 brush->lbStyle = BS_DIBPATTERN;
70 if (v16)
72 if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
73 break;
75 else
77 if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
78 break;
81 brush->lbHatch = dib_copy( bmi, brush->lbColor);
83 if (v16) GlobalUnlock16( h );
84 else GlobalUnlock( h );
86 if (!brush->lbHatch)
87 break;
89 return TRUE;
92 default:
93 if( brush->lbStyle <= BS_MONOPATTERN)
94 return TRUE;
97 return FALSE;
101 /***********************************************************************
102 * CreateBrushIndirect16 (GDI.50)
104 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
106 BOOL success;
107 BRUSHOBJ * brushPtr;
108 HBRUSH16 hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
109 if (!hbrush) return 0;
110 brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
111 brushPtr->logbrush.lbStyle = brush->lbStyle;
112 brushPtr->logbrush.lbColor = brush->lbColor;
113 brushPtr->logbrush.lbHatch = brush->lbHatch;
114 success = create_brush_indirect(brushPtr, TRUE);
115 GDI_HEAP_UNLOCK( hbrush );
116 if(!success)
118 GDI_FreeObject(hbrush);
119 hbrush = 0;
121 TRACE("%04x\n", hbrush);
122 return hbrush;
126 /***********************************************************************
127 * CreateBrushIndirect32 (GDI32.27)
129 * BUGS
130 * As for Windows 95 and Windows 98:
131 * Creating brushes from bitmaps or DIBs larger than 8x8 pixels
132 * is not supported. If a larger bitmap is given, only a portion
133 * of the bitmap is used.
135 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
137 BOOL success;
138 BRUSHOBJ * brushPtr;
139 HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
140 if (!hbrush) return 0;
141 brushPtr = (BRUSHOBJ *) GDI_HEAP_LOCK( hbrush );
142 brushPtr->logbrush.lbStyle = brush->lbStyle;
143 brushPtr->logbrush.lbColor = brush->lbColor;
144 brushPtr->logbrush.lbHatch = brush->lbHatch;
145 success = create_brush_indirect(brushPtr, FALSE);
146 GDI_HEAP_UNLOCK( hbrush );
147 if(!success)
149 GDI_FreeObject(hbrush);
150 hbrush = 0;
152 TRACE("%08x\n", hbrush);
153 return hbrush;
157 /***********************************************************************
158 * CreateHatchBrush16 (GDI.58)
160 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
162 return CreateHatchBrush( style, color );
166 /***********************************************************************
167 * CreateHatchBrush32 (GDI32.48)
169 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
171 LOGBRUSH logbrush;
173 TRACE("%d %06lx\n", style, color );
175 logbrush.lbStyle = BS_HATCHED;
176 logbrush.lbColor = color;
177 logbrush.lbHatch = style;
179 return CreateBrushIndirect( &logbrush );
183 /***********************************************************************
184 * CreatePatternBrush16 (GDI.60)
186 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
188 return (HBRUSH16)CreatePatternBrush( hbitmap );
192 /***********************************************************************
193 * CreatePatternBrush32 (GDI32.54)
195 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
197 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
198 TRACE("%04x\n", hbitmap );
200 logbrush.lbHatch = hbitmap;
201 return CreateBrushIndirect( &logbrush );
205 /***********************************************************************
206 * CreateDIBPatternBrush16 (GDI.445)
208 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
210 LOGBRUSH16 logbrush;
212 TRACE("%04x\n", hbitmap );
214 logbrush.lbStyle = BS_DIBPATTERN;
215 logbrush.lbColor = coloruse;
216 logbrush.lbHatch = hbitmap;
218 return CreateBrushIndirect16( &logbrush );
222 /***********************************************************************
223 * CreateDIBPatternBrush32 (GDI32.34)
225 * Create a logical brush which has the pattern specified by the DIB
227 * Function call is for compatability only. CreateDIBPatternBrushPt should be used.
229 * RETURNS
231 * Handle to a logical brush on success, NULL on failure.
233 * BUGS
236 HBRUSH WINAPI CreateDIBPatternBrush(
237 HGLOBAL hbitmap, /* Global object containg BITMAPINFO structure */
238 UINT coloruse /* Specifies color format, if provided */
241 LOGBRUSH logbrush;
243 TRACE("%04x\n", hbitmap );
245 logbrush.lbStyle = BS_DIBPATTERN;
246 logbrush.lbColor = coloruse;
248 logbrush.lbHatch = (LONG)hbitmap;
250 return CreateBrushIndirect( &logbrush );
254 /***********************************************************************
255 * CreateDIBPatternBrushPt (GDI32.35)
257 * Create a logical brush which has the pattern specified by the DIB
259 * RETURNS
261 * Handle to a logical brush on success, NULL on failure.
263 * BUGS
266 HBRUSH WINAPI CreateDIBPatternBrushPt(
267 const void* data, /* Pointer to a BITMAPINFO structure followed by more data */
268 UINT coloruse /* Specifies color format, if provided */
271 BITMAPINFO *info=(BITMAPINFO*)data;
272 LOGBRUSH logbrush;
274 TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
275 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
277 logbrush.lbStyle = BS_DIBPATTERNPT;
278 logbrush.lbColor = coloruse;
279 logbrush.lbHatch = (LONG) data;
281 return CreateBrushIndirect( &logbrush );
285 /***********************************************************************
286 * CreateSolidBrush (GDI.66)
288 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
290 return CreateSolidBrush( color );
294 /***********************************************************************
295 * CreateSolidBrush32 (GDI32.64)
297 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
299 LOGBRUSH logbrush;
301 TRACE("%06lx\n", color );
303 logbrush.lbStyle = BS_SOLID;
304 logbrush.lbColor = color;
305 logbrush.lbHatch = 0;
307 return CreateBrushIndirect( &logbrush );
311 /***********************************************************************
312 * SetBrushOrg (GDI.148)
314 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
316 DWORD retval;
317 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
318 if (!dc) return FALSE;
319 retval = dc->w.brushOrgX | (dc->w.brushOrgY << 16);
320 dc->w.brushOrgX = x;
321 dc->w.brushOrgY = y;
322 return retval;
326 /***********************************************************************
327 * SetBrushOrgEx (GDI32.308)
329 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
331 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
333 if (!dc) return FALSE;
334 if (oldorg)
336 oldorg->x = dc->w.brushOrgX;
337 oldorg->y = dc->w.brushOrgY;
339 dc->w.brushOrgX = x;
340 dc->w.brushOrgY = y;
341 return TRUE;
344 /***********************************************************************
345 * FixBrushOrgEx (GDI32.102)
346 * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
348 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
350 return SetBrushOrgEx(hdc,x,y,oldorg);
354 /***********************************************************************
355 * BRUSH_DeleteObject
357 BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
359 switch(brush->logbrush.lbStyle)
361 case BS_PATTERN:
362 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
363 break;
364 case BS_DIBPATTERN:
365 GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
366 break;
368 return GDI_FreeObject( hbrush );
372 /***********************************************************************
373 * BRUSH_GetObject16
375 INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
377 LOGBRUSH16 logbrush;
379 logbrush.lbStyle = brush->logbrush.lbStyle;
380 logbrush.lbColor = brush->logbrush.lbColor;
381 logbrush.lbHatch = brush->logbrush.lbHatch;
382 if (count > sizeof(logbrush)) count = sizeof(logbrush);
383 memcpy( buffer, &logbrush, count );
384 return count;
388 /***********************************************************************
389 * BRUSH_GetObject32
391 INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
393 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
394 memcpy( buffer, &brush->logbrush, count );
395 return count;
399 /***********************************************************************
400 * SetSolidBrush16 (GDI.604)
402 * If hBrush is a solid brush, change it's color to newColor.
404 * RETURNS
405 * TRUE on success, FALSE on failure.
406 * FIXME: not yet implemented!
408 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
410 FIXME("(hBrush %04x, newColor %04x): stub!\n", hBrush, (int)newColor);
412 return(FALSE);