Changed typo va_list to valist.
[wine] / objects / brush.c
1 /*
2  * GDI brush objects
3  *
4  * Copyright 1993, 1994  Alexandre Julliard
5  */
6
7 #include <string.h>
8 #include "winbase.h"
9 #include "brush.h"
10 #include "bitmap.h"
11 #include "debugtools.h"
12
13 DEFAULT_DEBUG_CHANNEL(gdi);
14
15 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
16 {
17     BITMAPINFO  *newInfo;
18     HGLOBAL16   hmem;
19     INT         size;
20
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 );
28
29     if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
30     {
31         return 0;
32     }
33     newInfo = (BITMAPINFO *) GlobalLock16( hmem );
34     memcpy( newInfo, info, size );
35     GlobalUnlock16( hmem );
36     return hmem;
37 }
38
39
40
41 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
42 {
43     LOGBRUSH *brush = &brushPtr->logbrush;
44
45     switch (brush->lbStyle)
46     {
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;
54
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;
62
63        case BS_DIBPATTERN8X8:
64        case BS_DIBPATTERN:
65        {
66             BITMAPINFO* bmi;
67             HGLOBAL     h = brush->lbHatch;
68
69             brush->lbStyle = BS_DIBPATTERN;
70             if (v16)
71             {
72                if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
73                   break;
74             }
75             else
76             {
77                if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
78                   break;
79             }
80
81             brush->lbHatch = dib_copy( bmi, brush->lbColor);
82
83             if (v16)  GlobalUnlock16( h );
84             else      GlobalUnlock( h );
85
86             if (!brush->lbHatch)
87                break;
88
89             return TRUE;
90        }
91
92        default:
93           if( brush->lbStyle <= BS_MONOPATTERN)
94              return TRUE;
95     }
96
97     return FALSE;
98 }
99
100
101 /***********************************************************************
102  *           CreateBrushIndirect16    (GDI.50)
103  */
104 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
105 {
106     BOOL success;
107     BRUSHOBJ * brushPtr;
108     HBRUSH hbrush;
109
110     if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
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     if(!success)
116     {
117        GDI_FreeObject( hbrush, brushPtr );
118        hbrush = 0;
119     }
120     else GDI_ReleaseObj( hbrush );
121     TRACE("%04x\n", hbrush);
122     return hbrush;
123 }
124
125
126 /***********************************************************************
127  *           CreateBrushIndirect    (GDI32.27)
128  *
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.
134  */
135 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
136 {
137     BOOL success;
138     BRUSHOBJ * brushPtr;
139     HBRUSH hbrush;
140     if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
141     brushPtr->logbrush.lbStyle = brush->lbStyle;
142     brushPtr->logbrush.lbColor = brush->lbColor;
143     brushPtr->logbrush.lbHatch = brush->lbHatch;
144     success = create_brush_indirect(brushPtr, FALSE);
145     if(!success)
146     {
147        GDI_FreeObject( hbrush, brushPtr );
148        hbrush = 0;
149     }
150     else GDI_ReleaseObj( hbrush );
151     TRACE("%08x\n", hbrush);
152     return hbrush;
153 }
154
155
156 /***********************************************************************
157  *           CreateHatchBrush16    (GDI.58)
158  */
159 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
160 {
161     return CreateHatchBrush( style, color );
162 }
163
164
165 /***********************************************************************
166  *           CreateHatchBrush    (GDI32.48)
167  */
168 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
169 {
170     LOGBRUSH logbrush;
171
172     TRACE("%d %06lx\n", style, color );
173
174     logbrush.lbStyle = BS_HATCHED;
175     logbrush.lbColor = color;
176     logbrush.lbHatch = style;
177
178     return CreateBrushIndirect( &logbrush );
179 }
180
181
182 /***********************************************************************
183  *           CreatePatternBrush16    (GDI.60)
184  */
185 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
186 {
187     return (HBRUSH16)CreatePatternBrush( hbitmap );
188 }
189
190
191 /***********************************************************************
192  *           CreatePatternBrush    (GDI32.54)
193  */
194 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
195 {
196     LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
197     TRACE("%04x\n", hbitmap );
198
199     logbrush.lbHatch = hbitmap;
200         return CreateBrushIndirect( &logbrush );
201 }
202
203
204 /***********************************************************************
205  *           CreateDIBPatternBrush16    (GDI.445)
206  */
207 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
208 {
209     LOGBRUSH16 logbrush;
210
211     TRACE("%04x\n", hbitmap );
212
213     logbrush.lbStyle = BS_DIBPATTERN;
214     logbrush.lbColor = coloruse;
215     logbrush.lbHatch = hbitmap;
216
217     return CreateBrushIndirect16( &logbrush );
218     }
219
220
221 /***********************************************************************
222  *           CreateDIBPatternBrush    (GDI32.34)
223  *
224  *      Create a logical brush which has the pattern specified by the DIB
225  *
226  *      Function call is for compatibility only.  CreateDIBPatternBrushPt should be used.   
227  *
228  * RETURNS
229  *
230  *      Handle to a logical brush on success, NULL on failure.
231  *
232  * BUGS
233  *      
234  */
235 HBRUSH WINAPI CreateDIBPatternBrush( 
236                 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
237                 UINT coloruse    /* [in] Specifies color format, if provided */
238 )
239 {
240     LOGBRUSH logbrush;
241     
242     TRACE("%04x\n", hbitmap );
243
244     logbrush.lbStyle = BS_DIBPATTERN;
245     logbrush.lbColor = coloruse;
246
247     logbrush.lbHatch = (LONG)hbitmap;
248
249     return CreateBrushIndirect( &logbrush );
250 }
251
252
253 /***********************************************************************
254  *           CreateDIBPatternBrushPt    (GDI32.35)
255  *
256  *      Create a logical brush which has the pattern specified by the DIB
257  *
258  * RETURNS
259  *
260  *      Handle to a logical brush on success, NULL on failure.
261  *
262  * BUGS
263  *      
264  */
265 HBRUSH WINAPI CreateDIBPatternBrushPt(
266                 const void* data, /* [in] Pointer to a BITMAPINFO structure followed by more data */ 
267                 UINT coloruse     /* [in] Specifies color format, if provided */
268 )
269 {
270     BITMAPINFO *info=(BITMAPINFO*)data;
271     LOGBRUSH logbrush;
272     
273     TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
274           info->bmiHeader.biHeight,  info->bmiHeader.biBitCount);
275
276     logbrush.lbStyle = BS_DIBPATTERNPT;
277     logbrush.lbColor = coloruse;
278     logbrush.lbHatch = (LONG) data;
279
280     return CreateBrushIndirect( &logbrush );
281 }
282
283
284 /***********************************************************************
285  *           CreateSolidBrush    (GDI.66)
286  */
287 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
288 {
289     return CreateSolidBrush( color );
290 }
291
292
293 /***********************************************************************
294  *           CreateSolidBrush    (GDI32.64)
295  */
296 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
297 {
298     LOGBRUSH logbrush;
299
300     TRACE("%06lx\n", color );
301
302     logbrush.lbStyle = BS_SOLID;
303     logbrush.lbColor = color;
304     logbrush.lbHatch = 0;
305
306     return CreateBrushIndirect( &logbrush );
307 }
308
309
310 /***********************************************************************
311  *           SetBrushOrg    (GDI.148)
312  */
313 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
314 {
315     DWORD retval;
316     DC *dc = DC_GetDCPtr( hdc );
317     if (!dc) return FALSE;
318     retval = dc->brushOrgX | (dc->brushOrgY << 16);
319     dc->brushOrgX = x;
320     dc->brushOrgY = y;
321     GDI_ReleaseObj( hdc );
322     return retval;
323 }
324
325
326 /***********************************************************************
327  *           SetBrushOrgEx    (GDI32.308)
328  */
329 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
330 {
331     DC *dc = DC_GetDCPtr( hdc );
332
333     if (!dc) return FALSE;
334     if (oldorg)
335     {
336         oldorg->x = dc->brushOrgX;
337         oldorg->y = dc->brushOrgY;
338     }
339     dc->brushOrgX = x;
340     dc->brushOrgY = y;
341     GDI_ReleaseObj( hdc );
342     return TRUE;
343 }
344
345 /***********************************************************************
346  *           FixBrushOrgEx    (GDI32.102)
347  * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
348  */
349 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
350 {
351     return SetBrushOrgEx(hdc,x,y,oldorg);
352 }
353
354
355 /***********************************************************************
356  *           BRUSH_DeleteObject
357  */
358 BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
359 {
360     switch(brush->logbrush.lbStyle)
361     {
362       case BS_PATTERN:
363           DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
364           break;
365       case BS_DIBPATTERN:
366           GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
367           break;
368     }
369     return GDI_FreeObject( hbrush, brush );
370 }
371
372
373 /***********************************************************************
374  *           BRUSH_GetObject16
375  */
376 INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
377 {
378     LOGBRUSH16 logbrush;
379
380     logbrush.lbStyle = brush->logbrush.lbStyle;
381     logbrush.lbColor = brush->logbrush.lbColor;
382     logbrush.lbHatch = brush->logbrush.lbHatch;
383     if (count > sizeof(logbrush)) count = sizeof(logbrush);
384     memcpy( buffer, &logbrush, count );
385     return count;
386 }
387
388
389 /***********************************************************************
390  *           BRUSH_GetObject
391  */
392 INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
393 {
394     if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
395     memcpy( buffer, &brush->logbrush, count );
396     return count;
397 }
398
399
400 /***********************************************************************
401  *           SetSolidBrush16   (GDI.604)
402  *
403  *  If hBrush is a solid brush, change it's color to newColor.
404  *
405  *  RETURNS
406  *           TRUE on success, FALSE on failure.
407  *   FIXME: not yet implemented!
408  */
409 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
410 {
411      FIXME("(hBrush %04x, newColor %04x): stub!\n", hBrush, (int)newColor);
412
413      return(FALSE);
414 }
415