Added missing header.
[wine] / objects / brush.c
1 /*
2  * GDI brush objects
3  *
4  * Copyright 1993, 1994  Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include <string.h>
24
25 #include "winbase.h"
26 #include "wingdi.h"
27
28 #include "wine/wingdi16.h"
29 #include "bitmap.h"
30 #include "brush.h"
31
32 #include "wine/debug.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
35
36 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
37 {
38     BITMAPINFO  *newInfo;
39     HGLOBAL16   hmem;
40     INT         size;
41
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 );
49
50     if (!(hmem = GlobalAlloc16( GMEM_MOVEABLE, size )))
51     {
52         return 0;
53     }
54     newInfo = (BITMAPINFO *) GlobalLock16( hmem );
55     memcpy( newInfo, info, size );
56     GlobalUnlock16( hmem );
57     return hmem;
58 }
59
60
61
62 static BOOL create_brush_indirect(BRUSHOBJ *brushPtr, BOOL v16)
63 {
64     LOGBRUSH *brush = &brushPtr->logbrush;
65
66     switch (brush->lbStyle)
67     {
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;
75
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;
83
84        case BS_DIBPATTERN8X8:
85        case BS_DIBPATTERN:
86        {
87             BITMAPINFO* bmi;
88             HGLOBAL     h = brush->lbHatch;
89
90             brush->lbStyle = BS_DIBPATTERN;
91             if (v16)
92             {
93                if (!(bmi = (BITMAPINFO *)GlobalLock16( h )))
94                   break;
95             }
96             else
97             {
98                if (!(bmi = (BITMAPINFO *)GlobalLock( h )))
99                   break;
100             }
101
102             brush->lbHatch = dib_copy( bmi, brush->lbColor);
103
104             if (v16)  GlobalUnlock16( h );
105             else      GlobalUnlock( h );
106
107             if (!brush->lbHatch)
108                break;
109
110             return TRUE;
111        }
112
113        default:
114           if( brush->lbStyle <= BS_MONOPATTERN)
115              return TRUE;
116     }
117
118     return FALSE;
119 }
120
121
122 /***********************************************************************
123  *           CreateBrushIndirect    (GDI.50)
124  */
125 HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
126 {
127     BOOL success;
128     BRUSHOBJ * brushPtr;
129     HBRUSH hbrush;
130
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)
137     {
138        GDI_FreeObject( hbrush, brushPtr );
139        hbrush = 0;
140     }
141     else GDI_ReleaseObj( hbrush );
142     TRACE("%04x\n", hbrush);
143     return hbrush;
144 }
145
146
147 /***********************************************************************
148  *           CreateBrushIndirect    (GDI32.@)
149  *
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.
155  */
156 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
157 {
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)
167     {
168        GDI_FreeObject( hbrush, brushPtr );
169        hbrush = 0;
170     }
171     else GDI_ReleaseObj( hbrush );
172     TRACE("%08x\n", hbrush);
173     return hbrush;
174 }
175
176
177 /***********************************************************************
178  *           CreateHatchBrush    (GDI.58)
179  */
180 HBRUSH16 WINAPI CreateHatchBrush16( INT16 style, COLORREF color )
181 {
182     return CreateHatchBrush( style, color );
183 }
184
185
186 /***********************************************************************
187  *           CreateHatchBrush    (GDI32.@)
188  */
189 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
190 {
191     LOGBRUSH logbrush;
192
193     TRACE("%d %06lx\n", style, color );
194
195     logbrush.lbStyle = BS_HATCHED;
196     logbrush.lbColor = color;
197     logbrush.lbHatch = style;
198
199     return CreateBrushIndirect( &logbrush );
200 }
201
202
203 /***********************************************************************
204  *           CreatePatternBrush    (GDI.60)
205  */
206 HBRUSH16 WINAPI CreatePatternBrush16( HBITMAP16 hbitmap )
207 {
208     return (HBRUSH16)CreatePatternBrush( hbitmap );
209 }
210
211
212 /***********************************************************************
213  *           CreatePatternBrush    (GDI32.@)
214  */
215 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
216 {
217     LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
218     TRACE("%04x\n", hbitmap );
219
220     logbrush.lbHatch = hbitmap;
221         return CreateBrushIndirect( &logbrush );
222 }
223
224
225 /***********************************************************************
226  *           CreateDIBPatternBrush    (GDI.445)
227  */
228 HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
229 {
230     LOGBRUSH16 logbrush;
231
232     TRACE("%04x\n", hbitmap );
233
234     logbrush.lbStyle = BS_DIBPATTERN;
235     logbrush.lbColor = coloruse;
236     logbrush.lbHatch = hbitmap;
237
238     return CreateBrushIndirect16( &logbrush );
239     }
240
241
242 /***********************************************************************
243  *           CreateDIBPatternBrush    (GDI32.@)
244  *
245  *      Create a logical brush which has the pattern specified by the DIB
246  *
247  *      Function call is for compatibility only.  CreateDIBPatternBrushPt should be used.   
248  *
249  * RETURNS
250  *
251  *      Handle to a logical brush on success, NULL on failure.
252  *
253  * BUGS
254  *      
255  */
256 HBRUSH WINAPI CreateDIBPatternBrush( 
257                 HGLOBAL hbitmap, /* [in] Global object containg BITMAPINFO structure */
258                 UINT coloruse    /* [in] Specifies color format, if provided */
259 )
260 {
261     LOGBRUSH logbrush;
262     
263     TRACE("%04x\n", hbitmap );
264
265     logbrush.lbStyle = BS_DIBPATTERN;
266     logbrush.lbColor = coloruse;
267
268     logbrush.lbHatch = (LONG)hbitmap;
269
270     return CreateBrushIndirect( &logbrush );
271 }
272
273
274 /***********************************************************************
275  *           CreateDIBPatternBrushPt    (GDI32.@)
276  *
277  *      Create a logical brush which has the pattern specified by the DIB
278  *
279  * RETURNS
280  *
281  *      Handle to a logical brush on success, NULL on failure.
282  *
283  * BUGS
284  *      
285  */
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 */
289 )
290 {
291     BITMAPINFO *info=(BITMAPINFO*)data;
292     LOGBRUSH logbrush;
293     
294     TRACE("%p %ldx%ld %dbpp\n", info, info->bmiHeader.biWidth,
295           info->bmiHeader.biHeight,  info->bmiHeader.biBitCount);
296
297     logbrush.lbStyle = BS_DIBPATTERNPT;
298     logbrush.lbColor = coloruse;
299     logbrush.lbHatch = (LONG) data;
300
301     return CreateBrushIndirect( &logbrush );
302 }
303
304
305 /***********************************************************************
306  *           CreateSolidBrush    (GDI.66)
307  */
308 HBRUSH16 WINAPI CreateSolidBrush16( COLORREF color )
309 {
310     return CreateSolidBrush( color );
311 }
312
313
314 /***********************************************************************
315  *           CreateSolidBrush    (GDI32.@)
316  */
317 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
318 {
319     LOGBRUSH logbrush;
320
321     TRACE("%06lx\n", color );
322
323     logbrush.lbStyle = BS_SOLID;
324     logbrush.lbColor = color;
325     logbrush.lbHatch = 0;
326
327     return CreateBrushIndirect( &logbrush );
328 }
329
330
331 /***********************************************************************
332  *           SetBrushOrg    (GDI.148)
333  */
334 DWORD WINAPI SetBrushOrg16( HDC16 hdc, INT16 x, INT16 y )
335 {
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;
344 }
345
346
347 /***********************************************************************
348  *           SetBrushOrgEx    (GDI32.@)
349  */
350 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
351 {
352     DC *dc = DC_GetDCPtr( hdc );
353
354     if (!dc) return FALSE;
355     if (oldorg)
356     {
357         oldorg->x = dc->brushOrgX;
358         oldorg->y = dc->brushOrgY;
359     }
360     dc->brushOrgX = x;
361     dc->brushOrgY = y;
362     GDI_ReleaseObj( hdc );
363     return TRUE;
364 }
365
366 /***********************************************************************
367  *           FixBrushOrgEx    (GDI32.@)
368  * SDK says discontinued, but in Win95 GDI32 this is the same as SetBrushOrgEx
369  */
370 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
371 {
372     return SetBrushOrgEx(hdc,x,y,oldorg);
373 }
374
375
376 /***********************************************************************
377  *           BRUSH_DeleteObject
378  */
379 BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
380 {
381     switch(brush->logbrush.lbStyle)
382     {
383       case BS_PATTERN:
384           DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
385           break;
386       case BS_DIBPATTERN:
387           GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
388           break;
389     }
390     return GDI_FreeObject( hbrush, brush );
391 }
392
393
394 /***********************************************************************
395  *           BRUSH_GetObject16
396  */
397 INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
398 {
399     LOGBRUSH16 logbrush;
400
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;
407 }
408
409
410 /***********************************************************************
411  *           BRUSH_GetObject
412  */
413 INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
414 {
415     if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
416     memcpy( buffer, &brush->logbrush, count );
417     return count;
418 }
419
420
421 /***********************************************************************
422  *           SetSolidBrush   (GDI.604)
423  *
424  *  If hBrush is a solid brush, change its color to newColor.
425  *
426  *  RETURNS
427  *           TRUE on success, FALSE on failure.
428  *
429  *  FIXME: untested, not sure if correct.
430  */
431 BOOL16 WINAPI SetSolidBrush16(HBRUSH16 hBrush, COLORREF newColor )
432 {
433     BRUSHOBJ * brushPtr;
434     BOOL16 res = FALSE;
435
436     TRACE("(hBrush %04x, newColor %08lx)\n", hBrush, (DWORD)newColor);
437     if (!(brushPtr = (BRUSHOBJ *) GDI_GetObjPtr( hBrush, BRUSH_MAGIC )))
438         return FALSE;
439
440     if (brushPtr->logbrush.lbStyle == BS_SOLID)
441     {
442         brushPtr->logbrush.lbColor = newColor;
443         res = TRUE;
444     }
445
446      GDI_ReleaseObj( hBrush );
447      return res;
448 }
449