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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "config.h"
22
23 #include <stdarg.h>
24 #include <string.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "gdi_private.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
33
34 /* GDI logical brush object */
35 typedef struct
36 {
37 GDIOBJHDR header;
38 LOGBRUSH logbrush;
39 } BRUSHOBJ;
40
41 #define NB_HATCH_STYLES 6
42
43 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc );
44 static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer );
45 static BOOL BRUSH_DeleteObject( HGDIOBJ handle );
46
47 static const struct gdi_obj_funcs brush_funcs =
48 {
49 BRUSH_SelectObject, /* pSelectObject */
50 BRUSH_GetObject, /* pGetObjectA */
51 BRUSH_GetObject, /* pGetObjectW */
52 NULL, /* pUnrealizeObject */
53 BRUSH_DeleteObject /* pDeleteObject */
54 };
55
56 static HGLOBAL dib_copy(const BITMAPINFO *info, UINT coloruse)
57 {
58 BITMAPINFO *newInfo;
59 HGLOBAL hmem;
60 INT size;
61
62 if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS)
63 size = info->bmiHeader.biSizeImage;
64 else
65 size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
66 info->bmiHeader.biHeight,
67 info->bmiHeader.biBitCount);
68 size += bitmap_info_size( info, coloruse );
69
70 if (!(hmem = GlobalAlloc( GMEM_MOVEABLE, size )))
71 {
72 return 0;
73 }
74 newInfo = GlobalLock( hmem );
75 memcpy( newInfo, info, size );
76 GlobalUnlock( hmem );
77 return hmem;
78 }
79
80
81 /***********************************************************************
82 * CreateBrushIndirect (GDI32.@)
83 *
84 * Create a logical brush with a given style, color or pattern.
85 *
86 * PARAMS
87 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
88 *
89 * RETURNS
90 * A handle to the created brush, or a NULL handle if the brush cannot be
91 * created.
92 *
93 * NOTES
94 * - The brush returned should be freed by the caller using DeleteObject()
95 * when it is no longer required.
96 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
97 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
98 * is used.
99 */
100 HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
101 {
102 BRUSHOBJ * ptr;
103 HBRUSH hbrush;
104
105 if (!(ptr = HeapAlloc( GetProcessHeap(), 0, sizeof(*ptr) ))) return 0;
106
107 ptr->logbrush.lbStyle = brush->lbStyle;
108 ptr->logbrush.lbColor = brush->lbColor;
109 ptr->logbrush.lbHatch = brush->lbHatch;
110
111 switch (ptr->logbrush.lbStyle)
112 {
113 case BS_PATTERN8X8:
114 ptr->logbrush.lbStyle = BS_PATTERN;
115 /* fall through */
116 case BS_PATTERN:
117 ptr->logbrush.lbHatch = (ULONG_PTR)BITMAP_CopyBitmap( (HBITMAP) ptr->logbrush.lbHatch );
118 if (!ptr->logbrush.lbHatch) goto error;
119 break;
120
121 case BS_DIBPATTERNPT:
122 ptr->logbrush.lbStyle = BS_DIBPATTERN;
123 ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( (BITMAPINFO *) ptr->logbrush.lbHatch,
124 ptr->logbrush.lbColor);
125 if (!ptr->logbrush.lbHatch) goto error;
126 break;
127
128 case BS_DIBPATTERN8X8:
129 case BS_DIBPATTERN:
130 {
131 BITMAPINFO* bmi;
132 HGLOBAL h = (HGLOBAL)ptr->logbrush.lbHatch;
133
134 ptr->logbrush.lbStyle = BS_DIBPATTERN;
135 if (!(bmi = GlobalLock( h ))) goto error;
136 ptr->logbrush.lbHatch = (ULONG_PTR)dib_copy( bmi, ptr->logbrush.lbColor);
137 GlobalUnlock( h );
138 if (!ptr->logbrush.lbHatch) goto error;
139 break;
140 }
141
142 default:
143 if(ptr->logbrush.lbStyle > BS_MONOPATTERN) goto error;
144 break;
145 }
146
147 if ((hbrush = alloc_gdi_handle( &ptr->header, OBJ_BRUSH, &brush_funcs )))
148 {
149 TRACE("%p\n", hbrush);
150 return hbrush;
151 }
152
153 error:
154 if (ptr->logbrush.lbHatch)
155 {
156 if (ptr->logbrush.lbStyle == BS_PATTERN)
157 DeleteObject( (HGDIOBJ)ptr->logbrush.lbHatch );
158 else if (ptr->logbrush.lbStyle == BS_DIBPATTERN)
159 GlobalFree( (HGLOBAL)ptr->logbrush.lbHatch );
160 }
161 HeapFree( GetProcessHeap(), 0, ptr );
162 return 0;
163 }
164
165
166 /***********************************************************************
167 * CreateHatchBrush (GDI32.@)
168 *
169 * Create a logical brush with a hatched pattern.
170 *
171 * PARAMS
172 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
173 * color [I] Colour of the hatched pattern
174 *
175 * RETURNS
176 * A handle to the created brush, or a NULL handle if the brush cannot
177 * be created.
178 *
179 * NOTES
180 * - This function uses CreateBrushIndirect() to create the brush.
181 * - The brush returned should be freed by the caller using DeleteObject()
182 * when it is no longer required.
183 */
184 HBRUSH WINAPI CreateHatchBrush( INT style, COLORREF color )
185 {
186 LOGBRUSH logbrush;
187
188 TRACE("%d %06x\n", style, color );
189
190 logbrush.lbStyle = BS_HATCHED;
191 logbrush.lbColor = color;
192 logbrush.lbHatch = style;
193
194 return CreateBrushIndirect( &logbrush );
195 }
196
197
198 /***********************************************************************
199 * CreatePatternBrush (GDI32.@)
200 *
201 * Create a logical brush with a pattern from a bitmap.
202 *
203 * PARAMS
204 * hbitmap [I] Bitmap containing pattern for the brush
205 *
206 * RETURNS
207 * A handle to the created brush, or a NULL handle if the brush cannot
208 * be created.
209 *
210 * NOTES
211 * - This function uses CreateBrushIndirect() to create the brush.
212 * - The brush returned should be freed by the caller using DeleteObject()
213 * when it is no longer required.
214 */
215 HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
216 {
217 LOGBRUSH logbrush = { BS_PATTERN, 0, 0 };
218 TRACE("%p\n", hbitmap );
219
220 logbrush.lbHatch = (ULONG_PTR)hbitmap;
221 return CreateBrushIndirect( &logbrush );
222 }
223
224
225 /***********************************************************************
226 * CreateDIBPatternBrush (GDI32.@)
227 *
228 * Create a logical brush with a pattern from a DIB.
229 *
230 * PARAMS
231 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
232 * coloruse [I] Specifies color format, if provided
233 *
234 * RETURNS
235 * A handle to the created brush, or a NULL handle if the brush cannot
236 * be created.
237 *
238 * NOTES
239 * - This function uses CreateBrushIndirect() to create the brush.
240 * - The brush returned should be freed by the caller using DeleteObject()
241 * when it is no longer required.
242 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
243 * be used instead.
244 */
245 HBRUSH WINAPI CreateDIBPatternBrush( HGLOBAL hbitmap, UINT coloruse )
246 {
247 LOGBRUSH logbrush;
248
249 TRACE("%p\n", hbitmap );
250
251 logbrush.lbStyle = BS_DIBPATTERN;
252 logbrush.lbColor = coloruse;
253
254 logbrush.lbHatch = (ULONG_PTR)hbitmap;
255
256 return CreateBrushIndirect( &logbrush );
257 }
258
259
260 /***********************************************************************
261 * CreateDIBPatternBrushPt (GDI32.@)
262 *
263 * Create a logical brush with a pattern from a DIB.
264 *
265 * PARAMS
266 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
267 * coloruse [I] Specifies color format, if provided
268 *
269 * RETURNS
270 * A handle to the created brush, or a NULL handle if the brush cannot
271 * be created.
272 *
273 * NOTES
274 * - This function uses CreateBrushIndirect() to create the brush.
275 * - The brush returned should be freed by the caller using DeleteObject()
276 * when it is no longer required.
277 */
278 HBRUSH WINAPI CreateDIBPatternBrushPt( const void* data, UINT coloruse )
279 {
280 const BITMAPINFO *info=data;
281 LOGBRUSH logbrush;
282
283 if (!data)
284 return NULL;
285
286 TRACE("%p %dx%d %dbpp\n", info, info->bmiHeader.biWidth,
287 info->bmiHeader.biHeight, info->bmiHeader.biBitCount);
288
289 logbrush.lbStyle = BS_DIBPATTERNPT;
290 logbrush.lbColor = coloruse;
291 logbrush.lbHatch = (ULONG_PTR)data;
292
293 return CreateBrushIndirect( &logbrush );
294 }
295
296
297 /***********************************************************************
298 * CreateSolidBrush (GDI32.@)
299 *
300 * Create a logical brush consisting of a single colour.
301 *
302 * PARAMS
303 * color [I] Colour to make the solid brush
304 *
305 * RETURNS
306 * A handle to the newly created brush, or a NULL handle if the brush cannot
307 * be created.
308 *
309 * NOTES
310 * - This function uses CreateBrushIndirect() to create the brush.
311 * - The brush returned should be freed by the caller using DeleteObject()
312 * when it is no longer required.
313 */
314 HBRUSH WINAPI CreateSolidBrush( COLORREF color )
315 {
316 LOGBRUSH logbrush;
317
318 TRACE("%06x\n", color );
319
320 logbrush.lbStyle = BS_SOLID;
321 logbrush.lbColor = color;
322 logbrush.lbHatch = 0;
323
324 return CreateBrushIndirect( &logbrush );
325 }
326
327
328 /***********************************************************************
329 * SetBrushOrgEx (GDI32.@)
330 *
331 * Set the brush origin for a device context.
332 *
333 * PARAMS
334 * hdc [I] Device context to set the brush origin for
335 * x [I] New x origin
336 * y [I] Ney y origin
337 * oldorg [O] If non NULL, destination for previously set brush origin.
338 *
339 * RETURNS
340 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
341 */
342 BOOL WINAPI SetBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
343 {
344 DC *dc = get_dc_ptr( hdc );
345
346 if (!dc) return FALSE;
347 if (oldorg)
348 {
349 oldorg->x = dc->brushOrgX;
350 oldorg->y = dc->brushOrgY;
351 }
352 dc->brushOrgX = x;
353 dc->brushOrgY = y;
354 release_dc_ptr( dc );
355 return TRUE;
356 }
357
358 /***********************************************************************
359 * FixBrushOrgEx (GDI32.@)
360 *
361 * See SetBrushOrgEx.
362 *
363 * NOTES
364 * This function is no longer documented by MSDN, but in Win95 GDI32 it
365 * is the same as SetBrushOrgEx().
366 */
367 BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
368 {
369 return SetBrushOrgEx(hdc,x,y,oldorg);
370 }
371
372
373 /***********************************************************************
374 * BRUSH_SelectObject
375 */
376 static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
377 {
378 BRUSHOBJ *brush;
379 HGDIOBJ ret = 0;
380 DC *dc = get_dc_ptr( hdc );
381
382 if (!dc)
383 {
384 SetLastError( ERROR_INVALID_HANDLE );
385 return 0;
386 }
387
388 if ((brush = GDI_GetObjPtr( handle, OBJ_BRUSH )))
389 {
390 if (brush->logbrush.lbStyle == BS_PATTERN)
391 BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
392
393 GDI_inc_ref_count( handle );
394 GDI_ReleaseObj( handle );
395
396 if (dc->funcs->pSelectBrush && !dc->funcs->pSelectBrush( dc->physDev, handle ))
397 {
398 GDI_dec_ref_count( handle );
399 }
400 else
401 {
402 ret = dc->hBrush;
403 dc->hBrush = handle;
404 GDI_dec_ref_count( ret );
405 }
406 }
407 release_dc_ptr( dc );
408 return ret;
409 }
410
411
412 /***********************************************************************
413 * BRUSH_DeleteObject
414 */
415 static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
416 {
417 BRUSHOBJ *brush = free_gdi_handle( handle );
418
419 if (!brush) return FALSE;
420 switch(brush->logbrush.lbStyle)
421 {
422 case BS_PATTERN:
423 DeleteObject( (HGDIOBJ)brush->logbrush.lbHatch );
424 break;
425 case BS_DIBPATTERN:
426 GlobalFree( (HGLOBAL)brush->logbrush.lbHatch );
427 break;
428 }
429 return HeapFree( GetProcessHeap(), 0, brush );
430 }
431
432
433 /***********************************************************************
434 * BRUSH_GetObject
435 */
436 static INT BRUSH_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
437 {
438 BRUSHOBJ *brush = GDI_GetObjPtr( handle, OBJ_BRUSH );
439
440 if (!brush) return 0;
441 if (buffer)
442 {
443 if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
444 memcpy( buffer, &brush->logbrush, count );
445 }
446 else count = sizeof(brush->logbrush);
447 GDI_ReleaseObj( handle );
448 return count;
449 }
450
451 /***********************************************************************
452 * BRUSH_SetSolid
453 */
454 BOOL BRUSH_SetSolid( HGDIOBJ handle, COLORREF new_color )
455 {
456 BRUSHOBJ * brushPtr;
457 BOOL res = FALSE;
458
459 if (!(brushPtr = GDI_GetObjPtr( handle, OBJ_BRUSH )))
460 return FALSE;
461
462 if (brushPtr->logbrush.lbStyle == BS_SOLID)
463 {
464 brushPtr->logbrush.lbColor = new_color;
465 res = TRUE;
466 }
467
468 GDI_ReleaseObj( handle );
469 return res;
470 }
471
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.