2 * ReactOS Win32 Subsystem
4 * Copyright (C) 1998 - 2004 ReactOS Team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * $Id: brush.c,v 1.41 2004/12/05 00:20:41 navaraf Exp $
24 static const USHORT HatchBrushes
[NB_HATCH_STYLES
][8] =
26 {0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00}, /* HS_HORIZONTAL */
27 {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, /* HS_VERTICAL */
28 {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, /* HS_FDIAGONAL */
29 {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, /* HS_BDIAGONAL */
30 {0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08}, /* HS_CROSS */
31 {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81} /* HS_DIAGCROSS */
35 Brush_InternalDelete( PGDIBRUSHOBJ pBrush
)
39 if(pBrush
->flAttrs
& (GDIBRUSH_IS_HATCH
| GDIBRUSH_IS_BITMAP
))
41 ASSERT(pBrush
->hbmPattern
);
42 GDIOBJ_SetOwnership(pBrush
->hbmPattern
, PsGetCurrentProcess());
43 NtGdiDeleteObject(pBrush
->hbmPattern
);
50 IntGdiCreateBrushXlate(PDC Dc
, GDIBRUSHOBJ
*BrushObj
, BOOLEAN
*Failed
)
52 XLATEOBJ
*Result
= NULL
;
54 if (BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
)
59 else if (BrushObj
->flAttrs
& GDIBRUSH_IS_SOLID
)
61 Result
= IntEngCreateXlate(0, PAL_RGB
, Dc
->w
.hPalette
, NULL
);
66 BITMAPOBJ
*Pattern
= BITMAPOBJ_LockBitmap(BrushObj
->hbmPattern
);
70 /* Special case: 1bpp pattern */
71 if (Pattern
->SurfObj
.iBitmapFormat
== BMF_1BPP
)
73 if (Dc
->w
.bitsPerPixel
!= 1)
74 Result
= IntEngCreateSrcMonoXlate(Dc
->w
.hPalette
, Dc
->w
.textColor
, Dc
->w
.backgroundColor
);
77 BITMAPOBJ_UnlockBitmap(BrushObj
->hbmPattern
);
85 IntGdiInitBrushInstance(GDIBRUSHINST
*BrushInst
, PGDIBRUSHOBJ BrushObj
, XLATEOBJ
*XlateObj
)
87 if (BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
)
88 BrushInst
->BrushObject
.iSolidColor
= 0;
89 else if (BrushObj
->flAttrs
& GDIBRUSH_IS_SOLID
)
90 BrushInst
->BrushObject
.iSolidColor
= XLATEOBJ_iXlate(XlateObj
, BrushObj
->BrushAttr
.lbColor
);
92 BrushInst
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
93 BrushInst
->BrushObject
.pvRbrush
= BrushObj
->ulRealization
;
94 BrushInst
->BrushObject
.flColorType
= 0;
95 BrushInst
->GdiBrushObject
= BrushObj
;
96 BrushInst
->XlateObject
= XlateObj
;
100 IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush
)
102 PGDIBRUSHOBJ BrushObject
;
104 HBITMAP hPattern
= 0;
106 switch (LogBrush
->lbStyle
)
109 hPattern
= NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes
[LogBrush
->lbHatch
]);
110 if (hPattern
== NULL
)
112 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
118 hPattern
= BITMAPOBJ_CopyBitmap((HBITMAP
)LogBrush
->lbHatch
);
119 if (hPattern
== NULL
)
121 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
127 hBrush
= BRUSHOBJ_AllocBrush();
130 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
134 BrushObject
= BRUSHOBJ_LockBrush(hBrush
);
136 switch (LogBrush
->lbStyle
)
139 BrushObject
->flAttrs
|= GDIBRUSH_IS_NULL
;
143 BrushObject
->flAttrs
|= GDIBRUSH_IS_SOLID
;
144 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
145 /* FIXME: Fill in the rest of fields!!! */
149 BrushObject
->flAttrs
|= GDIBRUSH_IS_HATCH
;
150 BrushObject
->hbmPattern
= hPattern
;
151 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
155 BrushObject
->flAttrs
|= GDIBRUSH_IS_BITMAP
;
156 BrushObject
->hbmPattern
= hPattern
;
157 /* FIXME: Fill in the rest of fields!!! */
161 DPRINT1("Brush Style: %d\n", LogBrush
->lbStyle
);
166 GDIOBJ_SetOwnership(hPattern
, NULL
);
168 BRUSHOBJ_UnlockBrush(hBrush
);
180 PGDIBRUSHOBJ BrushObj
)
183 BITMAPOBJ
*BitmapObj
;
184 GDIBRUSHINST BrushInst
;
188 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
189 if (BitmapObj
== NULL
)
191 SetLastWin32Error(ERROR_INVALID_HANDLE
);
196 if (!(BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
))
200 DestRect
.left
= XLeft
+ dc
->w
.DCOrgX
;
201 DestRect
.right
= XLeft
+ Width
+ dc
->w
.DCOrgX
;
205 DestRect
.left
= XLeft
+ Width
+ 1 + dc
->w
.DCOrgX
;
206 DestRect
.right
= XLeft
+ dc
->w
.DCOrgX
+ 1;
211 DestRect
.top
= YLeft
+ dc
->w
.DCOrgY
;
212 DestRect
.bottom
= YLeft
+ Height
+ dc
->w
.DCOrgY
;
216 DestRect
.top
= YLeft
+ Height
+ dc
->w
.DCOrgY
+ 1;
217 DestRect
.bottom
= YLeft
+ dc
->w
.DCOrgY
+ 1;
220 BrushOrigin
.x
= BrushObj
->ptOrigin
.x
+ dc
->w
.DCOrgX
;
221 BrushOrigin
.y
= BrushObj
->ptOrigin
.y
+ dc
->w
.DCOrgY
;
223 IntGdiInitBrushInstance(&BrushInst
, BrushObj
, dc
->XlateBrush
);
234 &BrushInst
.BrushObject
,
239 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
254 PGDIBRUSHOBJ BrushObj
;
260 SetLastWin32Error(ERROR_INVALID_HANDLE
);
264 for (r
= pRects
, i
= 0; i
< cRects
; i
++)
266 BrushObj
= BRUSHOBJ_LockBrush(r
->hBrush
);
275 BRUSHOBJ_UnlockBrush(r
->hBrush
);
284 /* PUBLIC FUNCTIONS ***********************************************************/
287 NtGdiCreateBrushIndirect(CONST LOGBRUSH
*LogBrush
)
289 LOGBRUSH SafeLogBrush
;
292 Status
= MmCopyFromCaller(&SafeLogBrush
, LogBrush
, sizeof(LOGBRUSH
));
293 if (!NT_SUCCESS(Status
))
295 SetLastNtError(Status
);
299 return IntGdiCreateBrushIndirect(&SafeLogBrush
);
303 NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked
, UINT ColorSpec
)
310 NtGdiCreateDIBPatternBrushPt(CONST VOID
*PackedDIB
, UINT Usage
)
317 NtGdiCreateHatchBrush(INT Style
, COLORREF Color
)
321 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
326 LogBrush
.lbStyle
= BS_HATCHED
;
327 LogBrush
.lbColor
= Color
;
328 LogBrush
.lbHatch
= Style
;
330 return IntGdiCreateBrushIndirect(&LogBrush
);
334 NtGdiCreatePatternBrush(HBITMAP hBitmap
)
338 LogBrush
.lbStyle
= BS_PATTERN
;
339 LogBrush
.lbColor
= 0;
340 LogBrush
.lbHatch
= (ULONG
)hBitmap
;
342 return IntGdiCreateBrushIndirect(&LogBrush
);
346 NtGdiCreateSolidBrush(COLORREF Color
)
350 LogBrush
.lbStyle
= BS_SOLID
;
351 LogBrush
.lbColor
= Color
;
352 LogBrush
.lbHatch
= 0;
354 return IntGdiCreateBrushIndirect(&LogBrush
);
358 NtGdiFixBrushOrgEx(VOID
)
366 * The NtGdiSetBrushOrgEx function sets the brush origin that GDI assigns to
367 * the next brush an application selects into the specified device context.
374 NtGdiSetBrushOrgEx(HDC hDC
, INT XOrg
, INT YOrg
, LPPOINT Point
)
376 PDC dc
= DC_LockDc(hDC
);
379 SetLastWin32Error(ERROR_INVALID_HANDLE
);
387 SafePoint
.x
= dc
->w
.brushOrgX
;
388 SafePoint
.y
= dc
->w
.brushOrgY
;
389 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
390 if(!NT_SUCCESS(Status
))
393 SetLastNtError(Status
);
398 dc
->w
.brushOrgX
= XOrg
;
399 dc
->w
.brushOrgY
= YOrg
;
419 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
422 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
425 Status
= MmCopyFromCaller(rb
, pRects
, sizeof(PATRECT
) * cRects
);
426 if (!NT_SUCCESS(Status
))
429 SetLastNtError(Status
);
434 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, pRects
, cRects
, Reserved
);
451 PGDIBRUSHOBJ BrushObj
;
452 DC
*dc
= DC_LockDc(hDC
);
457 SetLastWin32Error(ERROR_INVALID_HANDLE
);
461 BrushObj
= BRUSHOBJ_LockBrush(dc
->w
.hBrush
);
462 if (BrushObj
== NULL
)
464 SetLastWin32Error(ERROR_INVALID_HANDLE
);
478 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);