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.
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_Cleanup(PVOID ObjectBody
)
37 PGDIBRUSHOBJ pBrush
= (PGDIBRUSHOBJ
)ObjectBody
;
38 if(pBrush
->flAttrs
& (GDIBRUSH_IS_HATCH
| GDIBRUSH_IS_BITMAP
))
40 ASSERT(pBrush
->hbmPattern
);
41 GDIOBJ_SetOwnership(pBrush
->hbmPattern
, PsGetCurrentProcess());
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
)
88 if (BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
)
89 BrushInst
->BrushObject
.iSolidColor
= 0;
90 else if (BrushObj
->flAttrs
& GDIBRUSH_IS_SOLID
)
91 BrushInst
->BrushObject
.iSolidColor
= XLATEOBJ_iXlate(XlateObj
, BrushObj
->BrushAttr
.lbColor
);
93 BrushInst
->BrushObject
.iSolidColor
= 0xFFFFFFFF;
94 BrushInst
->BrushObject
.pvRbrush
= BrushObj
->ulRealization
;
95 BrushInst
->BrushObject
.flColorType
= 0;
96 BrushInst
->GdiBrushObject
= BrushObj
;
97 BrushInst
->XlateObject
= XlateObj
;
101 IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush
)
103 PGDIBRUSHOBJ BrushObject
;
105 HBITMAP hPattern
= 0;
107 switch (LogBrush
->lbStyle
)
110 hPattern
= NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes
[LogBrush
->lbHatch
]);
111 if (hPattern
== NULL
)
113 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
119 hPattern
= BITMAPOBJ_CopyBitmap((HBITMAP
)LogBrush
->lbHatch
);
120 if (hPattern
== NULL
)
122 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
128 hBrush
= BRUSHOBJ_AllocBrush();
131 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
135 BrushObject
= BRUSHOBJ_LockBrush(hBrush
);
136 if(BrushObject
!= NULL
)
138 switch (LogBrush
->lbStyle
)
141 BrushObject
->flAttrs
|= GDIBRUSH_IS_NULL
;
145 BrushObject
->flAttrs
|= GDIBRUSH_IS_SOLID
;
146 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
147 /* FIXME: Fill in the rest of fields!!! */
151 BrushObject
->flAttrs
|= GDIBRUSH_IS_HATCH
;
152 BrushObject
->hbmPattern
= hPattern
;
153 BrushObject
->BrushAttr
.lbColor
= LogBrush
->lbColor
& 0xFFFFFF;
157 BrushObject
->flAttrs
|= GDIBRUSH_IS_BITMAP
;
158 BrushObject
->hbmPattern
= hPattern
;
159 /* FIXME: Fill in the rest of fields!!! */
163 DPRINT1("Brush Style: %d\n", LogBrush
->lbStyle
);
168 BRUSHOBJ_UnlockBrush(hBrush
);
172 GDIOBJ_SetOwnership(hPattern
, NULL
);
185 PGDIBRUSHOBJ BrushObj
)
188 BITMAPOBJ
*BitmapObj
;
189 GDIBRUSHINST BrushInst
;
195 BitmapObj
= BITMAPOBJ_LockBitmap(dc
->w
.hBitmap
);
196 if (BitmapObj
== NULL
)
198 SetLastWin32Error(ERROR_INVALID_HANDLE
);
202 if (!(BrushObj
->flAttrs
& GDIBRUSH_IS_NULL
))
206 DestRect
.left
= XLeft
+ dc
->w
.DCOrgX
;
207 DestRect
.right
= XLeft
+ Width
+ dc
->w
.DCOrgX
;
211 DestRect
.left
= XLeft
+ Width
+ 1 + dc
->w
.DCOrgX
;
212 DestRect
.right
= XLeft
+ dc
->w
.DCOrgX
+ 1;
217 DestRect
.top
= YLeft
+ dc
->w
.DCOrgY
;
218 DestRect
.bottom
= YLeft
+ Height
+ dc
->w
.DCOrgY
;
222 DestRect
.top
= YLeft
+ Height
+ dc
->w
.DCOrgY
+ 1;
223 DestRect
.bottom
= YLeft
+ dc
->w
.DCOrgY
+ 1;
226 BrushOrigin
.x
= BrushObj
->ptOrigin
.x
+ dc
->w
.DCOrgX
;
227 BrushOrigin
.y
= BrushObj
->ptOrigin
.y
+ dc
->w
.DCOrgY
;
229 IntGdiInitBrushInstance(&BrushInst
, BrushObj
, dc
->XlateBrush
);
240 &BrushInst
.BrushObject
,
245 BITMAPOBJ_UnlockBitmap(dc
->w
.hBitmap
);
260 PGDIBRUSHOBJ BrushObj
;
266 SetLastWin32Error(ERROR_INVALID_HANDLE
);
270 for (r
= pRects
, i
= 0; i
< cRects
; i
++)
272 BrushObj
= BRUSHOBJ_LockBrush(r
->hBrush
);
283 BRUSHOBJ_UnlockBrush(r
->hBrush
);
293 /* PUBLIC FUNCTIONS ***********************************************************/
296 NtGdiCreateBrushIndirect(CONST LOGBRUSH
*LogBrush
)
298 LOGBRUSH SafeLogBrush
;
301 Status
= MmCopyFromCaller(&SafeLogBrush
, LogBrush
, sizeof(LOGBRUSH
));
302 if (!NT_SUCCESS(Status
))
304 SetLastNtError(Status
);
308 return IntGdiCreateBrushIndirect(&SafeLogBrush
);
312 NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked
, UINT ColorSpec
)
319 NtGdiCreateDIBPatternBrushPt(CONST VOID
*PackedDIB
, UINT Usage
)
326 NtGdiCreateHatchBrush(INT Style
, COLORREF Color
)
330 if (Style
< 0 || Style
>= NB_HATCH_STYLES
)
335 LogBrush
.lbStyle
= BS_HATCHED
;
336 LogBrush
.lbColor
= Color
;
337 LogBrush
.lbHatch
= Style
;
339 return IntGdiCreateBrushIndirect(&LogBrush
);
343 NtGdiCreatePatternBrush(HBITMAP hBitmap
)
347 LogBrush
.lbStyle
= BS_PATTERN
;
348 LogBrush
.lbColor
= 0;
349 LogBrush
.lbHatch
= (ULONG
)hBitmap
;
351 return IntGdiCreateBrushIndirect(&LogBrush
);
355 NtGdiCreateSolidBrush(COLORREF Color
)
359 LogBrush
.lbStyle
= BS_SOLID
;
360 LogBrush
.lbColor
= Color
;
361 LogBrush
.lbHatch
= 0;
363 return IntGdiCreateBrushIndirect(&LogBrush
);
367 NtGdiFixBrushOrgEx(VOID
)
375 * The NtGdiSetBrushOrgEx function sets the brush origin that GDI assigns to
376 * the next brush an application selects into the specified device context.
383 NtGdiSetBrushOrgEx(HDC hDC
, INT XOrg
, INT YOrg
, LPPOINT Point
)
385 PDC dc
= DC_LockDc(hDC
);
388 SetLastWin32Error(ERROR_INVALID_HANDLE
);
396 SafePoint
.x
= dc
->w
.brushOrgX
;
397 SafePoint
.y
= dc
->w
.brushOrgY
;
398 Status
= MmCopyToCaller(Point
, &SafePoint
, sizeof(POINT
));
399 if(!NT_SUCCESS(Status
))
402 SetLastNtError(Status
);
407 dc
->w
.brushOrgX
= XOrg
;
408 dc
->w
.brushOrgY
= YOrg
;
428 rb
= ExAllocatePoolWithTag(PagedPool
, sizeof(PATRECT
) * cRects
, TAG_PATBLT
);
431 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
434 Status
= MmCopyFromCaller(rb
, pRects
, sizeof(PATRECT
) * cRects
);
435 if (!NT_SUCCESS(Status
))
438 SetLastNtError(Status
);
443 Ret
= IntGdiPolyPatBlt(hDC
, dwRop
, pRects
, cRects
, Reserved
);
460 PGDIBRUSHOBJ BrushObj
;
461 DC
*dc
= DC_LockDc(hDC
);
466 SetLastWin32Error(ERROR_INVALID_HANDLE
);
470 BrushObj
= BRUSHOBJ_LockBrush(dc
->w
.hBrush
);
471 if (BrushObj
== NULL
)
473 SetLastWin32Error(ERROR_INVALID_HANDLE
);
487 BRUSHOBJ_UnlockBrush(dc
->w
.hBrush
);