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