4 * Copyright 1993, 1994 Alexandre Julliard
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.
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.
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
29 #include "wine/wingdi16.h"
32 #include "gdi_private.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
37 /* GDI logical brush object */
44 #define NB_HATCH_STYLES 6
46 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
);
47 static INT
BRUSH_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
48 static INT
BRUSH_GetObject( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
49 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
, void *obj
);
51 static const struct gdi_obj_funcs brush_funcs
=
53 BRUSH_SelectObject
, /* pSelectObject */
54 BRUSH_GetObject16
, /* pGetObject16 */
55 BRUSH_GetObject
, /* pGetObjectA */
56 BRUSH_GetObject
, /* pGetObjectW */
57 NULL
, /* pUnrealizeObject */
58 BRUSH_DeleteObject
/* pDeleteObject */
61 static HGLOBAL16
dib_copy(BITMAPINFO
*info
, UINT coloruse
)
67 if (info
->bmiHeader
.biCompression
)
68 size
= info
->bmiHeader
.biSizeImage
;
70 size
= DIB_GetDIBImageBytes(info
->bmiHeader
.biWidth
,
71 info
->bmiHeader
.biHeight
,
72 info
->bmiHeader
.biBitCount
);
73 size
+= DIB_BitmapInfoSize( info
, coloruse
);
75 if (!(hmem
= GlobalAlloc16( GMEM_MOVEABLE
, size
)))
79 newInfo
= (BITMAPINFO
*) GlobalLock16( hmem
);
80 memcpy( newInfo
, info
, size
);
81 GlobalUnlock16( hmem
);
86 /***********************************************************************
87 * CreateBrushIndirect (GDI32.@)
89 * Create a logical brush with a given style, color or pattern.
92 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
95 * A handle to the created brush, or a NULL handle if the brush cannot be
99 * - The brush returned should be freed by the caller using DeleteObject()
100 * when it is no longer required.
101 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
102 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
104 * - If the brush to be created matches a stock brush, a stock brush will be
105 * returned. This behaviour is undocumented.
107 HBRUSH WINAPI
CreateBrushIndirect( const LOGBRUSH
* brush
)
109 static const DWORD stockMap
[] = { /* Map of RGB colors of stock brushes */
110 RGB(255,255,255), WHITE_BRUSH
,
111 RGB(192,192,192), LTGRAY_BRUSH
,
112 RGB(128,128,128), GRAY_BRUSH
,
113 RGB(0,0,0), BLACK_BRUSH
118 if (brush
->lbStyle
== BS_SOLID
)
122 /* If a solid brush is created in a color matching one of the
123 * stock brushes, native returns the stock object (GDI heap
124 * optimisation). Some apps rely on this as they otherwise
125 * would leak their brushes.
127 for (i
= 0; i
< (sizeof(stockMap
)/sizeof(stockMap
[0])) / 2; i
+= 2)
129 if (brush
->lbColor
== stockMap
[i
])
131 HBRUSH hBr
= GetStockObject(stockMap
[i
+ 1]);
133 return hBr
; /* Return stock brush */
134 break; /* Being called to create a stock brush, fall through */
139 if (!(ptr
= GDI_AllocObject( sizeof(BRUSHOBJ
), BRUSH_MAGIC
,
140 (HGDIOBJ
*)&hbrush
, &brush_funcs
))) return 0;
141 ptr
->logbrush
.lbStyle
= brush
->lbStyle
;
142 ptr
->logbrush
.lbColor
= brush
->lbColor
;
143 ptr
->logbrush
.lbHatch
= brush
->lbHatch
;
145 switch (ptr
->logbrush
.lbStyle
)
148 ptr
->logbrush
.lbStyle
= BS_PATTERN
;
151 ptr
->logbrush
.lbHatch
= (LONG
)BITMAP_CopyBitmap( (HBITMAP
) ptr
->logbrush
.lbHatch
);
152 if (!ptr
->logbrush
.lbHatch
) goto error
;
155 case BS_DIBPATTERNPT
:
156 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
157 ptr
->logbrush
.lbHatch
= (LONG
)dib_copy( (BITMAPINFO
*) ptr
->logbrush
.lbHatch
,
158 ptr
->logbrush
.lbColor
);
159 if (!ptr
->logbrush
.lbHatch
) goto error
;
162 case BS_DIBPATTERN8X8
:
166 HGLOBAL h
= (HGLOBAL
)ptr
->logbrush
.lbHatch
;
168 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
169 if (!(bmi
= (BITMAPINFO
*)GlobalLock( h
))) goto error
;
170 ptr
->logbrush
.lbHatch
= dib_copy( bmi
, ptr
->logbrush
.lbColor
);
172 if (!ptr
->logbrush
.lbHatch
) goto error
;
177 if(ptr
->logbrush
.lbStyle
> BS_MONOPATTERN
) goto error
;
181 GDI_ReleaseObj( hbrush
);
182 TRACE("%p\n", hbrush
);
186 GDI_FreeObject( hbrush
, ptr
);
191 /***********************************************************************
192 * CreateHatchBrush (GDI32.@)
194 * Create a logical brush with a hatched pattern.
197 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
198 * color [I] Colour of the hatched pattern
201 * A handle to the created brush, or a NULL handle if the brush cannot
205 * - This function uses CreateBrushIndirect() to create the brush.
206 * - The brush returned should be freed by the caller using DeleteObject()
207 * when it is no longer required.
209 HBRUSH WINAPI
CreateHatchBrush( INT style
, COLORREF color
)
213 TRACE("%d %06lx\n", style
, color
);
215 logbrush
.lbStyle
= BS_HATCHED
;
216 logbrush
.lbColor
= color
;
217 logbrush
.lbHatch
= style
;
219 return CreateBrushIndirect( &logbrush
);
223 /***********************************************************************
224 * CreatePatternBrush (GDI32.@)
226 * Create a logical brush with a pattern from a bitmap.
229 * hbitmap [I] Bitmap containing pattern for the brush
232 * A handle to the created brush, or a NULL handle if the brush cannot
236 * - This function uses CreateBrushIndirect() to create the brush.
237 * - The brush returned should be freed by the caller using DeleteObject()
238 * when it is no longer required.
240 HBRUSH WINAPI
CreatePatternBrush( HBITMAP hbitmap
)
242 LOGBRUSH logbrush
= { BS_PATTERN
, 0, 0 };
243 TRACE("%p\n", hbitmap
);
245 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
246 return CreateBrushIndirect( &logbrush
);
250 /***********************************************************************
251 * CreateDIBPatternBrush (GDI32.@)
253 * Create a logical brush with a pattern from a DIB.
256 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
257 * coloruse [I] Specifies color format, if provided
260 * A handle to the created brush, or a NULL handle if the brush cannot
264 * - This function uses CreateBrushIndirect() to create the brush.
265 * - The brush returned should be freed by the caller using DeleteObject()
266 * when it is no longer required.
267 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
270 HBRUSH WINAPI
CreateDIBPatternBrush( HGLOBAL hbitmap
, UINT coloruse
)
274 TRACE("%p\n", hbitmap
);
276 logbrush
.lbStyle
= BS_DIBPATTERN
;
277 logbrush
.lbColor
= coloruse
;
279 logbrush
.lbHatch
= (LONG
)hbitmap
;
281 return CreateBrushIndirect( &logbrush
);
285 /***********************************************************************
286 * CreateDIBPatternBrushPt (GDI32.@)
288 * Create a logical brush with a pattern from a DIB.
291 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
292 * coloruse [I] Specifies color format, if provided
295 * A handle to the created brush, or a NULL handle if the brush cannot
299 * - This function uses CreateBrushIndirect() to create the brush.
300 * - The brush returned should be freed by the caller using DeleteObject()
301 * when it is no longer required.
303 HBRUSH WINAPI
CreateDIBPatternBrushPt( const void* data
, UINT coloruse
)
305 BITMAPINFO
*info
=(BITMAPINFO
*)data
;
311 TRACE("%p %ldx%ld %dbpp\n", info
, info
->bmiHeader
.biWidth
,
312 info
->bmiHeader
.biHeight
, info
->bmiHeader
.biBitCount
);
314 logbrush
.lbStyle
= BS_DIBPATTERNPT
;
315 logbrush
.lbColor
= coloruse
;
316 logbrush
.lbHatch
= (LONG
) data
;
318 return CreateBrushIndirect( &logbrush
);
322 /***********************************************************************
323 * CreateSolidBrush (GDI32.@)
325 * Create a logical brush consisting of a single colour.
328 * color [I] Colour to make the solid brush
331 * A handle to the newly created brush, or a NULL handle if the brush cannot
335 * - This function uses CreateBrushIndirect() to create the brush.
336 * - The brush returned should be freed by the caller using DeleteObject()
337 * when it is no longer required.
339 HBRUSH WINAPI
CreateSolidBrush( COLORREF color
)
343 TRACE("%06lx\n", color
);
345 logbrush
.lbStyle
= BS_SOLID
;
346 logbrush
.lbColor
= color
;
347 logbrush
.lbHatch
= 0;
349 return CreateBrushIndirect( &logbrush
);
353 /***********************************************************************
354 * SetBrushOrgEx (GDI32.@)
356 * Set the brush origin for a device context.
359 * hdc [I] Device context to set the brush origin for
362 * oldorg [O] If non NULL, destination for previously set brush origin.
365 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
367 BOOL WINAPI
SetBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
369 DC
*dc
= DC_GetDCPtr( hdc
);
371 if (!dc
) return FALSE
;
374 oldorg
->x
= dc
->brushOrgX
;
375 oldorg
->y
= dc
->brushOrgY
;
379 GDI_ReleaseObj( hdc
);
383 /***********************************************************************
384 * FixBrushOrgEx (GDI32.@)
389 * This function is no longer documented by MSDN, but in Win95 GDI32 it
390 * is the same as SetBrushOrgEx().
392 BOOL WINAPI
FixBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
394 return SetBrushOrgEx(hdc
,x
,y
,oldorg
);
398 /***********************************************************************
401 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, void *obj
, HDC hdc
)
403 BRUSHOBJ
*brush
= obj
;
405 DC
*dc
= DC_GetDCPtr( hdc
);
409 if (brush
->logbrush
.lbStyle
== BS_PATTERN
)
410 BITMAP_SetOwnerDC( (HBITMAP
)brush
->logbrush
.lbHatch
, dc
);
413 if (dc
->funcs
->pSelectBrush
) handle
= dc
->funcs
->pSelectBrush( dc
->physDev
, handle
);
414 if (handle
) dc
->hBrush
= handle
;
416 GDI_ReleaseObj( hdc
);
421 /***********************************************************************
424 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
, void *obj
)
426 BRUSHOBJ
*brush
= obj
;
428 switch(brush
->logbrush
.lbStyle
)
431 DeleteObject( (HGDIOBJ
)brush
->logbrush
.lbHatch
);
434 GlobalFree16( (HGLOBAL16
)brush
->logbrush
.lbHatch
);
437 return GDI_FreeObject( handle
, obj
);
441 /***********************************************************************
444 static INT
BRUSH_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
446 BRUSHOBJ
*brush
= obj
;
449 logbrush
.lbStyle
= brush
->logbrush
.lbStyle
;
450 logbrush
.lbColor
= brush
->logbrush
.lbColor
;
451 logbrush
.lbHatch
= brush
->logbrush
.lbHatch
;
452 if (count
> sizeof(logbrush
)) count
= sizeof(logbrush
);
453 memcpy( buffer
, &logbrush
, count
);
458 /***********************************************************************
461 static INT
BRUSH_GetObject( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
463 BRUSHOBJ
*brush
= obj
;
466 return sizeof(brush
->logbrush
);
468 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
469 memcpy( buffer
, &brush
->logbrush
, count
);
474 /***********************************************************************
475 * SetSolidBrush (GDI.604)
477 * Change the color of a solid brush.
480 * hBrush [I] Brush to change the color of
481 * newColor [I] New color for hBrush
484 * Success: TRUE. The color of hBrush is set to newColor.
488 * This function is undocumented and untested. The implementation may
491 BOOL16 WINAPI
SetSolidBrush16(HBRUSH16 hBrush
, COLORREF newColor
)
496 TRACE("(hBrush %04x, newColor %08lx)\n", hBrush
, (DWORD
)newColor
);
497 if (!(brushPtr
= (BRUSHOBJ
*) GDI_GetObjPtr( HBRUSH_32(hBrush
), BRUSH_MAGIC
)))
500 if (brushPtr
->logbrush
.lbStyle
== BS_SOLID
)
502 brushPtr
->logbrush
.lbColor
= newColor
;
506 GDI_ReleaseObj( HBRUSH_32(hBrush
) );