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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/wingdi16.h"
31 #include "gdi_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(gdi
);
36 /* GDI logical brush object */
43 #define NB_HATCH_STYLES 6
45 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
);
46 static INT
BRUSH_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
47 static INT
BRUSH_GetObject( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
);
48 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
, void *obj
);
50 static const struct gdi_obj_funcs brush_funcs
=
52 BRUSH_SelectObject
, /* pSelectObject */
53 BRUSH_GetObject16
, /* pGetObject16 */
54 BRUSH_GetObject
, /* pGetObjectA */
55 BRUSH_GetObject
, /* pGetObjectW */
56 NULL
, /* pUnrealizeObject */
57 BRUSH_DeleteObject
/* pDeleteObject */
60 static HGLOBAL16
dib_copy(const BITMAPINFO
*info
, UINT coloruse
)
66 if (info
->bmiHeader
.biCompression
)
67 size
= info
->bmiHeader
.biSizeImage
;
69 size
= DIB_GetDIBImageBytes(info
->bmiHeader
.biWidth
,
70 info
->bmiHeader
.biHeight
,
71 info
->bmiHeader
.biBitCount
);
72 size
+= DIB_BitmapInfoSize( info
, coloruse
);
74 if (!(hmem
= GlobalAlloc16( GMEM_MOVEABLE
, size
)))
78 newInfo
= (BITMAPINFO
*) GlobalLock16( hmem
);
79 memcpy( newInfo
, info
, size
);
80 GlobalUnlock16( hmem
);
85 /***********************************************************************
86 * CreateBrushIndirect (GDI32.@)
88 * Create a logical brush with a given style, color or pattern.
91 * brush [I] Pointer to a LOGBRUSH structure describing the desired brush.
94 * A handle to the created brush, or a NULL handle if the brush cannot be
98 * - The brush returned should be freed by the caller using DeleteObject()
99 * when it is no longer required.
100 * - Windows 95 and earlier cannot create brushes from bitmaps or DIBs larger
101 * than 8x8 pixels. If a larger bitmap is given, only a portion of the bitmap
104 HBRUSH WINAPI
CreateBrushIndirect( const LOGBRUSH
* brush
)
109 if (!(ptr
= GDI_AllocObject( sizeof(BRUSHOBJ
), BRUSH_MAGIC
,
110 (HGDIOBJ
*)&hbrush
, &brush_funcs
))) return 0;
111 ptr
->logbrush
.lbStyle
= brush
->lbStyle
;
112 ptr
->logbrush
.lbColor
= brush
->lbColor
;
113 ptr
->logbrush
.lbHatch
= brush
->lbHatch
;
115 switch (ptr
->logbrush
.lbStyle
)
118 ptr
->logbrush
.lbStyle
= BS_PATTERN
;
121 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)BITMAP_CopyBitmap( (HBITMAP
) ptr
->logbrush
.lbHatch
);
122 if (!ptr
->logbrush
.lbHatch
) goto error
;
125 case BS_DIBPATTERNPT
:
126 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
127 ptr
->logbrush
.lbHatch
= (ULONG_PTR
)dib_copy( (BITMAPINFO
*) ptr
->logbrush
.lbHatch
,
128 ptr
->logbrush
.lbColor
);
129 if (!ptr
->logbrush
.lbHatch
) goto error
;
132 case BS_DIBPATTERN8X8
:
136 HGLOBAL h
= (HGLOBAL
)ptr
->logbrush
.lbHatch
;
138 ptr
->logbrush
.lbStyle
= BS_DIBPATTERN
;
139 if (!(bmi
= (BITMAPINFO
*)GlobalLock( h
))) goto error
;
140 ptr
->logbrush
.lbHatch
= dib_copy( bmi
, ptr
->logbrush
.lbColor
);
142 if (!ptr
->logbrush
.lbHatch
) goto error
;
147 if(ptr
->logbrush
.lbStyle
> BS_MONOPATTERN
) goto error
;
151 GDI_ReleaseObj( hbrush
);
152 TRACE("%p\n", hbrush
);
156 GDI_FreeObject( hbrush
, ptr
);
161 /***********************************************************************
162 * CreateHatchBrush (GDI32.@)
164 * Create a logical brush with a hatched pattern.
167 * style [I] Direction of lines for the hatch pattern (HS_* values from "wingdi.h")
168 * color [I] Colour of the hatched pattern
171 * A handle to the created brush, or a NULL handle if the brush cannot
175 * - This function uses CreateBrushIndirect() to create the brush.
176 * - The brush returned should be freed by the caller using DeleteObject()
177 * when it is no longer required.
179 HBRUSH WINAPI
CreateHatchBrush( INT style
, COLORREF color
)
183 TRACE("%d %06x\n", style
, color
);
185 logbrush
.lbStyle
= BS_HATCHED
;
186 logbrush
.lbColor
= color
;
187 logbrush
.lbHatch
= style
;
189 return CreateBrushIndirect( &logbrush
);
193 /***********************************************************************
194 * CreatePatternBrush (GDI32.@)
196 * Create a logical brush with a pattern from a bitmap.
199 * hbitmap [I] Bitmap containing pattern for the brush
202 * A handle to the created brush, or a NULL handle if the brush cannot
206 * - This function uses CreateBrushIndirect() to create the brush.
207 * - The brush returned should be freed by the caller using DeleteObject()
208 * when it is no longer required.
210 HBRUSH WINAPI
CreatePatternBrush( HBITMAP hbitmap
)
212 LOGBRUSH logbrush
= { BS_PATTERN
, 0, 0 };
213 TRACE("%p\n", hbitmap
);
215 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
216 return CreateBrushIndirect( &logbrush
);
220 /***********************************************************************
221 * CreateDIBPatternBrush (GDI32.@)
223 * Create a logical brush with a pattern from a DIB.
226 * hbitmap [I] Global object containing BITMAPINFO structure for the pattern
227 * coloruse [I] Specifies color format, if provided
230 * A handle to the created brush, or a NULL handle if the brush cannot
234 * - This function uses CreateBrushIndirect() to create the brush.
235 * - The brush returned should be freed by the caller using DeleteObject()
236 * when it is no longer required.
237 * - This function is for compatibility only. CreateDIBPatternBrushPt() should
240 HBRUSH WINAPI
CreateDIBPatternBrush( HGLOBAL hbitmap
, UINT coloruse
)
244 TRACE("%p\n", hbitmap
);
246 logbrush
.lbStyle
= BS_DIBPATTERN
;
247 logbrush
.lbColor
= coloruse
;
249 logbrush
.lbHatch
= (ULONG_PTR
)hbitmap
;
251 return CreateBrushIndirect( &logbrush
);
255 /***********************************************************************
256 * CreateDIBPatternBrushPt (GDI32.@)
258 * Create a logical brush with a pattern from a DIB.
261 * data [I] Pointer to a BITMAPINFO structure and image data for the pattern
262 * coloruse [I] Specifies color format, if provided
265 * A handle to the created brush, or a NULL handle if the brush cannot
269 * - This function uses CreateBrushIndirect() to create the brush.
270 * - The brush returned should be freed by the caller using DeleteObject()
271 * when it is no longer required.
273 HBRUSH WINAPI
CreateDIBPatternBrushPt( const void* data
, UINT coloruse
)
275 const BITMAPINFO
*info
=(const BITMAPINFO
*)data
;
281 TRACE("%p %dx%d %dbpp\n", info
, info
->bmiHeader
.biWidth
,
282 info
->bmiHeader
.biHeight
, info
->bmiHeader
.biBitCount
);
284 logbrush
.lbStyle
= BS_DIBPATTERNPT
;
285 logbrush
.lbColor
= coloruse
;
286 logbrush
.lbHatch
= (ULONG_PTR
)data
;
288 return CreateBrushIndirect( &logbrush
);
292 /***********************************************************************
293 * CreateSolidBrush (GDI32.@)
295 * Create a logical brush consisting of a single colour.
298 * color [I] Colour to make the solid brush
301 * A handle to the newly created brush, or a NULL handle if the brush cannot
305 * - This function uses CreateBrushIndirect() to create the brush.
306 * - The brush returned should be freed by the caller using DeleteObject()
307 * when it is no longer required.
309 HBRUSH WINAPI
CreateSolidBrush( COLORREF color
)
313 TRACE("%06x\n", color
);
315 logbrush
.lbStyle
= BS_SOLID
;
316 logbrush
.lbColor
= color
;
317 logbrush
.lbHatch
= 0;
319 return CreateBrushIndirect( &logbrush
);
323 /***********************************************************************
324 * SetBrushOrgEx (GDI32.@)
326 * Set the brush origin for a device context.
329 * hdc [I] Device context to set the brush origin for
332 * oldorg [O] If non NULL, destination for previously set brush origin.
335 * Success: TRUE. The origin is set to (x,y), and oldorg is updated if given.
337 BOOL WINAPI
SetBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
339 DC
*dc
= DC_GetDCPtr( hdc
);
341 if (!dc
) return FALSE
;
344 oldorg
->x
= dc
->brushOrgX
;
345 oldorg
->y
= dc
->brushOrgY
;
349 DC_ReleaseDCPtr( dc
);
353 /***********************************************************************
354 * FixBrushOrgEx (GDI32.@)
359 * This function is no longer documented by MSDN, but in Win95 GDI32 it
360 * is the same as SetBrushOrgEx().
362 BOOL WINAPI
FixBrushOrgEx( HDC hdc
, INT x
, INT y
, LPPOINT oldorg
)
364 return SetBrushOrgEx(hdc
,x
,y
,oldorg
);
368 /***********************************************************************
371 static HGDIOBJ
BRUSH_SelectObject( HGDIOBJ handle
, HDC hdc
)
375 DC
*dc
= get_dc_ptr( hdc
);
379 if ((brush
= GDI_GetObjPtr( handle
, BRUSH_MAGIC
)))
381 if (brush
->logbrush
.lbStyle
== BS_PATTERN
)
382 BITMAP_SetOwnerDC( (HBITMAP
)brush
->logbrush
.lbHatch
, dc
);
384 if (dc
->funcs
->pSelectBrush
) handle
= dc
->funcs
->pSelectBrush( dc
->physDev
, handle
);
389 GDI_inc_ref_count( handle
);
390 GDI_dec_ref_count( ret
);
392 GDI_ReleaseObj( handle
);
394 release_dc_ptr( dc
);
399 /***********************************************************************
402 static BOOL
BRUSH_DeleteObject( HGDIOBJ handle
, void *obj
)
404 BRUSHOBJ
*brush
= obj
;
406 switch(brush
->logbrush
.lbStyle
)
409 DeleteObject( (HGDIOBJ
)brush
->logbrush
.lbHatch
);
412 GlobalFree16( (HGLOBAL16
)brush
->logbrush
.lbHatch
);
415 return GDI_FreeObject( handle
, obj
);
419 /***********************************************************************
422 static INT
BRUSH_GetObject16( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
424 BRUSHOBJ
*brush
= obj
;
427 logbrush
.lbStyle
= brush
->logbrush
.lbStyle
;
428 logbrush
.lbColor
= brush
->logbrush
.lbColor
;
429 logbrush
.lbHatch
= brush
->logbrush
.lbHatch
;
430 if (count
> sizeof(logbrush
)) count
= sizeof(logbrush
);
431 memcpy( buffer
, &logbrush
, count
);
436 /***********************************************************************
439 static INT
BRUSH_GetObject( HGDIOBJ handle
, void *obj
, INT count
, LPVOID buffer
)
441 BRUSHOBJ
*brush
= obj
;
444 return sizeof(brush
->logbrush
);
446 if (count
> sizeof(brush
->logbrush
)) count
= sizeof(brush
->logbrush
);
447 memcpy( buffer
, &brush
->logbrush
, count
);
452 /***********************************************************************
453 * SetSolidBrush (GDI.604)
455 * Change the color of a solid brush.
458 * hBrush [I] Brush to change the color of
459 * newColor [I] New color for hBrush
462 * Success: TRUE. The color of hBrush is set to newColor.
466 * This function is undocumented and untested. The implementation may
469 BOOL16 WINAPI
SetSolidBrush16(HBRUSH16 hBrush
, COLORREF newColor
)
474 TRACE("(hBrush %04x, newColor %08x)\n", hBrush
, newColor
);
475 if (!(brushPtr
= (BRUSHOBJ
*) GDI_GetObjPtr( HBRUSH_32(hBrush
), BRUSH_MAGIC
)))
478 if (brushPtr
->logbrush
.lbStyle
== BS_SOLID
)
480 brushPtr
->logbrush
.lbColor
= newColor
;
484 GDI_ReleaseObj( HBRUSH_32(hBrush
) );