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.40 2004/07/14 20:48:57 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 NtGdiDeleteObject(pBrush
->hbmPattern
);
49 IntGdiCreateBrushXlate(PDC Dc
, GDIBRUSHOBJ
*BrushObj
, BOOLEAN
*Failed
)
51 XLATEOBJ
*Result
= NULL
;
53 if (BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
)
58 else if (BrushObj
->flAttrs
& GDIBRUSH_IS_SOLID
)
60 Result
= IntEngCreateXlate(0, PAL_RGB
, Dc
->w
.hPalette
, NULL
);
65 BITMAPOBJ
*Pattern
= BITMAPOBJ_LockBitmap(BrushObj
->hbmPattern
);
69 /* Special case: 1bpp pattern */
70 if (Pattern
->SurfObj
.iBitmapFormat
== BMF_1BPP
)
72 if (Dc
->w
.bitsPerPixel
!= 1)
73 Result
= IntEngCreateSrcMonoXlate(Dc
->w
.hPalette
, Dc
->w
.textColor
, Dc
->w
.backgroundColor
);
76 BITMAPOBJ_UnlockBitmap(BrushObj
->hbmPattern
);
84 IntGdiInitBrushInstance(GDIBRUSHINST
*BrushInst
, PGDIBRUSHOBJ BrushObj
, XLATEOBJ
*XlateObj
)
86 if (BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
)
87 BrushInst
->BrushObject
.iSolidColor
= 0;
88 else if (BrushObj
->flAttrs
& GDIBRUSH_IS_SOLID
)
89 BrushInst
->BrushObject
.iSolidColor
= XLATEOBJ_iXlate(XlateObj
, BrushObj
->BrushAttr
.lbColor
);
91 BrushInst
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
92 BrushInst
->BrushObject
.pvRbrush
= BrushObj
->ulRealization
;
93 BrushInst
->BrushObject
.flColorType
= 0;
94 BrushInst
->GdiBrushObject
= BrushObj
;
95 BrushInst
->XlateObject
= XlateObj
;
99 IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush
)
101 PGDIBRUSHOBJ BrushObject
;
103 HBITMAP hPattern
= 0;
105 switch (LogBrush
->lbStyle
)
108 hPattern
= NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes
[LogBrush
->lbHatch
]);
109 if (hPattern
== NULL
)
111 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
117 hPattern
= BITMAPOBJ_CopyBitmap((HBITMAP
)LogBrush
->lbHatch
);
118 if (hPattern
== NULL
)
120 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
126 hBrush
= BRUSHOBJ_AllocBrush();
129 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
133 BrushObject
= BRUSHOBJ_LockBrush(hBrush
);
135 switch (LogBrush
->lbStyle
)
138 BrushObject
->flAttrs
|= GDIBRUSH_IS_NULL
;
142 BrushObject
->flAttrs
|= GDIBRUSH_IS_SOLID
;
143 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
144 /* FIXME: Fill in the rest of fields!!! */
148 BrushObject
->flAttrs
|= GDIBRUSH_IS_HATCH
;
149 BrushObject
->hbmPattern
= hPattern
;
150 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
154 BrushObject
->flAttrs
|= GDIBRUSH_IS_BITMAP
;
155 BrushObject
->hbmPattern
= hPattern
;
156 /* FIXME: Fill in the rest of fields!!! */
160 DPRINT1("Brush Style: %d\n", LogBrush
->lbStyle
);
164 BRUSHOBJ_UnlockBrush(hBrush
);
176 PGDIBRUSHOBJ BrushObj
)
179 BITMAPOBJ
*BitmapObj
;
180 GDIBRUSHINST BrushInst
;
184 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
185 if (BitmapObj
== NULL
)
187 SetLastWin32Error(ERROR_INVALID_HANDLE
);
192 if (!(BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
))
196 DestRect
.left
= XLeft
+ dc
->w
.DCOrgX
;
197 DestRect
.right
= XLeft
+ Width
+ dc
->w
.DCOrgX
;
201 DestRect
.left
= XLeft
+ Width
+ 1 + dc
->w
.DCOrgX
;
202 DestRect
.right
= XLeft
+ dc
->w
.DCOrgX
+ 1;
207 DestRect
.top
= YLeft
+ dc
->w
.DCOrgY
;
208 DestRect
.bottom
= YLeft
+ Height
+ dc
->w
.DCOrgY
;
212 DestRect
.top
= YLeft
+ Height
+ dc
->w
.DCOrgY
+ 1;
213 DestRect
.bottom
= YLeft
+ dc
->w
.DCOrgY
+ 1;
216 BrushOrigin
.x
= BrushObj
->ptOrigin
.x
+ dc
->w
.DCOrgX
;
217 BrushOrigin
.y
= BrushObj
->ptOrigin
.y
+ dc
->w
.DCOrgY
;
219 IntGdiInitBrushInstance(&BrushInst
, BrushObj
, dc
->XlateBrush
);
230 &BrushInst
.BrushObject
,
235 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
250 PGDIBRUSHOBJ BrushObj
;
256 SetLastWin32Error(ERROR_INVALID_HANDLE
);
260 for (r
= pRects
, i
= 0; i
< cRects
; i
++)
262 BrushObj
= BRUSHOBJ_LockBrush(r
->hBrush
);
271 BRUSHOBJ_UnlockBrush(r
->hBrush
);
280 /* PUBLIC FUNCTIONS ***********************************************************/
283 NtGdiCreateBrushIndirect(CONST LOGBRUSH
*LogBrush
)
285 LOGBRUSH SafeLogBrush
;
288 Status
= MmCopyFromCaller(&SafeLogBrush
, LogBrush
, sizeof(LOGBRUSH
));
289 if (!NT_SUCCESS(Status
))
291 SetLastNtError(Status
);
295 return IntGdiCreateBrushIndirect(&SafeLogBrush
);
299 NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked
, UINT ColorSpec
)
306 NtGdiCreateDIBPatternBrushPt(CONST VOID
*PackedDIB
, UINT Usage
)
313 NtGdiCreateHatchBrush(INT Style
, COLORREF Color
)
317 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
322 LogBrush
.lbStyle
= BS_HATCHED
;
323 LogBrush
.lbColor
= Color
;
324 LogBrush
.lbHatch
= Style
;
326 return IntGdiCreateBrushIndirect(&LogBrush
);
330 NtGdiCreatePatternBrush(HBITMAP hBitmap
)
334 LogBrush
.lbStyle
= BS_PATTERN
;
335 LogBrush
.lbColor
= 0;
336 LogBrush
.lbHatch
= (ULONG
)hBitmap
;
338 return IntGdiCreateBrushIndirect(&LogBrush
);
342 NtGdiCreateSolidBrush(COLORREF Color
)
346 LogBrush
.lbStyle
= BS_SOLID
;
347 LogBrush
.lbColor
= Color
;
348 LogBrush
.lbHatch
= 0;
350 return IntGdiCreateBrushIndirect(&LogBrush
);
354 NtGdiFixBrushOrgEx(VOID
)
362 * The NtGdiSetBrushOrgEx function sets the brush origin that GDI assigns to
363 * the next brush an application selects into the specified device context.
370 NtGdiSetBrushOrgEx(HDC hDC
, INT XOrg
, INT YOrg
, LPPOINT Point
)
372 PDC dc
= DC_LockDc(hDC
);
375 SetLastWin32Error(ERROR_INVALID_HANDLE
);
383 SafePoint
.x
= dc
->w
.brushOrgX
;
384 SafePoint
.y
= dc
->w
.brushOrgY
;
385 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
386 if(!NT_SUCCESS(Status
))
389 SetLastNtError(Status
);
394 dc
->w
.brushOrgX
= XOrg
;
395 dc
->w
.brushOrgY
= YOrg
;
415 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
418 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
421 Status
= MmCopyFromCaller(rb
, pRects
, sizeof(PATRECT
) * cRects
);
422 if (!NT_SUCCESS(Status
))
425 SetLastNtError(Status
);
430 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, pRects
, cRects
, Reserved
);
447 PGDIBRUSHOBJ BrushObj
;
448 DC
*dc
= DC_LockDc(hDC
);
453 SetLastWin32Error(ERROR_INVALID_HANDLE
);
457 BrushObj
= BRUSHOBJ_LockBrush(dc
->w
.hBrush
);
458 if (BrushObj
== NULL
)
460 SetLastWin32Error(ERROR_INVALID_HANDLE
);
474 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);