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