2010-05-12 22:56:24 +00:00
|
|
|
/*
|
2009-04-08 14:18:23 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS win32 subsystem
|
|
|
|
* PURPOSE: Functions for brushes
|
|
|
|
* FILE: subsystem/win32/win32k/objects/brush.c
|
2010-05-12 22:56:24 +00:00
|
|
|
* PROGRAMER:
|
1999-07-17 23:10:31 +00:00
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
1999-07-12 23:26:57 +00:00
|
|
|
|
2005-06-29 07:09:25 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
#define GDIOBJATTRFREE 170
|
|
|
|
|
|
|
|
typedef struct _GDI_OBJ_ATTR_FREELIST
|
|
|
|
{
|
|
|
|
LIST_ENTRY Entry;
|
|
|
|
DWORD nEntries;
|
|
|
|
PVOID AttrList[GDIOBJATTRFREE];
|
|
|
|
} GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST;
|
2010-05-12 22:56:24 +00:00
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
typedef struct _GDI_OBJ_ATTR_ENTRY
|
|
|
|
{
|
|
|
|
RGN_ATTR Attr[GDIOBJATTRFREE];
|
|
|
|
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
|
|
|
|
|
2010-08-02 01:41:16 +00:00
|
|
|
static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
|
2004-04-25 11:34:13 +00:00
|
|
|
{
|
2009-08-04 20:37:10 +00:00
|
|
|
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
|
|
|
|
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
|
|
|
|
{0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
|
|
|
|
{0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
|
|
|
|
{0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
|
|
|
|
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
|
2004-04-25 11:34:13 +00:00
|
|
|
};
|
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
|
|
|
|
PVOID
|
|
|
|
FASTCALL
|
|
|
|
AllocateObjectAttr(VOID)
|
|
|
|
{
|
|
|
|
PTHREADINFO pti;
|
|
|
|
PPROCESSINFO ppi;
|
|
|
|
PVOID pAttr;
|
|
|
|
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
|
|
|
|
PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry;
|
|
|
|
int i;
|
2010-05-12 22:56:24 +00:00
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
pti = PsGetCurrentThreadWin32Thread();
|
|
|
|
if (pti->pgdiBrushAttr)
|
|
|
|
{
|
|
|
|
pAttr = pti->pgdiBrushAttr; // Get the free one.
|
|
|
|
pti->pgdiBrushAttr = NULL;
|
|
|
|
return pAttr;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppi = PsGetCurrentProcessWin32Process();
|
|
|
|
|
|
|
|
if (!ppi->pBrushAttrList) // If set point is null, allocate new group.
|
|
|
|
{
|
|
|
|
pGdiObjAttrEntry = EngAllocUserMem(sizeof(GDI_OBJ_ATTR_ENTRY), 0);
|
|
|
|
|
|
|
|
if (!pGdiObjAttrEntry)
|
|
|
|
{
|
|
|
|
DPRINT1("Attr Failed User Allocation!\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("AllocObjectAttr User 0x%x\n",pGdiObjAttrEntry);
|
|
|
|
|
|
|
|
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
|
|
|
|
sizeof(GDI_OBJ_ATTR_FREELIST),
|
|
|
|
GDITAG_BRUSH_FREELIST);
|
|
|
|
if ( !pGdiObjAttrFreeList )
|
|
|
|
{
|
|
|
|
EngFreeUserMem(pGdiObjAttrEntry);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
RtlZeroMemory(pGdiObjAttrFreeList, sizeof(GDI_OBJ_ATTR_FREELIST));
|
|
|
|
|
|
|
|
DPRINT("AllocObjectAttr Ex 0x%x\n",pGdiObjAttrFreeList);
|
|
|
|
|
|
|
|
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
|
|
|
|
|
|
|
|
pGdiObjAttrFreeList->nEntries = GDIOBJATTRFREE;
|
|
|
|
// Start at the bottom up and set end of free list point.
|
|
|
|
ppi->pBrushAttrList = &pGdiObjAttrEntry->Attr[GDIOBJATTRFREE-1];
|
|
|
|
// Build the free attr list.
|
|
|
|
for ( i = 0; i < GDIOBJATTRFREE; i++)
|
|
|
|
{
|
|
|
|
pGdiObjAttrFreeList->AttrList[i] = &pGdiObjAttrEntry->Attr[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pAttr = ppi->pBrushAttrList;
|
|
|
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
|
|
|
|
|
|
|
// Free the list when it is full!
|
|
|
|
if ( pGdiObjAttrFreeList->nEntries-- == 1)
|
|
|
|
{ // No more free entries, so yank the list.
|
|
|
|
RemoveEntryList( &pGdiObjAttrFreeList->Entry );
|
|
|
|
|
|
|
|
ExFreePoolWithTag( pGdiObjAttrFreeList, GDITAG_BRUSH_FREELIST );
|
|
|
|
|
|
|
|
if ( IsListEmpty( &ppi->GDIBrushAttrFreeList ) )
|
|
|
|
{
|
|
|
|
ppi->pBrushAttrList = NULL;
|
|
|
|
return pAttr;
|
|
|
|
}
|
|
|
|
|
|
|
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppi->pBrushAttrList = pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1];
|
|
|
|
|
|
|
|
return pAttr;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
FreeObjectAttr(PVOID pAttr)
|
|
|
|
{
|
|
|
|
PTHREADINFO pti;
|
|
|
|
PPROCESSINFO ppi;
|
|
|
|
PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList;
|
|
|
|
|
|
|
|
pti = PsGetCurrentThreadWin32Thread();
|
2010-05-12 22:56:24 +00:00
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
if (!pti) return;
|
2010-05-12 22:56:24 +00:00
|
|
|
|
2009-12-28 18:10:03 +00:00
|
|
|
if (!pti->pgdiBrushAttr)
|
|
|
|
{ // If it is null, just cache it for the next time.
|
|
|
|
pti->pgdiBrushAttr = pAttr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppi = PsGetCurrentProcessWin32Process();
|
|
|
|
|
|
|
|
pGdiObjAttrFreeList = (PGDI_OBJ_ATTR_FREELIST)ppi->GDIBrushAttrFreeList.Flink;
|
|
|
|
|
|
|
|
// We add to the list of free entries, so this will grows!
|
|
|
|
if ( IsListEmpty(&ppi->GDIBrushAttrFreeList) ||
|
|
|
|
pGdiObjAttrFreeList->nEntries == GDIOBJATTRFREE )
|
|
|
|
{
|
|
|
|
pGdiObjAttrFreeList = ExAllocatePoolWithTag( PagedPool,
|
|
|
|
sizeof(GDI_OBJ_ATTR_FREELIST),
|
|
|
|
GDITAG_BRUSH_FREELIST);
|
|
|
|
if ( !pGdiObjAttrFreeList )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
InsertHeadList( &ppi->GDIBrushAttrFreeList, &pGdiObjAttrFreeList->Entry);
|
|
|
|
pGdiObjAttrFreeList->nEntries = 0;
|
|
|
|
}
|
|
|
|
// Up count, save the entry and set end of free list point.
|
|
|
|
++pGdiObjAttrFreeList->nEntries; // Top Down...
|
|
|
|
pGdiObjAttrFreeList->AttrList[pGdiObjAttrFreeList->nEntries-1] = pAttr;
|
|
|
|
ppi->pBrushAttrList = pAttr;
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
BOOL
|
|
|
|
INTERNAL_CALL
|
2004-12-12 01:40:39 +00:00
|
|
|
BRUSH_Cleanup(PVOID ObjectBody)
|
2004-04-25 11:34:13 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
PBRUSH pbrush = (PBRUSH)ObjectBody;
|
|
|
|
if (pbrush->flAttrs & (GDIBRUSH_IS_HATCH | GDIBRUSH_IS_BITMAP))
|
|
|
|
{
|
|
|
|
ASSERT(pbrush->hbmPattern);
|
|
|
|
GDIOBJ_SetOwnership(pbrush->hbmPattern, PsGetCurrentProcess());
|
|
|
|
GreDeleteObject(pbrush->hbmPattern);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the kmode styles array of EXTPENS */
|
|
|
|
if (pbrush->pStyle)
|
|
|
|
{
|
|
|
|
ExFreePool(pbrush->pStyle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2004-04-25 11:34:13 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
INT
|
|
|
|
FASTCALL
|
|
|
|
BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
if (Buffer == NULL) return sizeof(LOGBRUSH);
|
|
|
|
if (Count == 0) return 0;
|
2007-03-01 19:13:29 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
/* Set colour */
|
2009-03-20 22:40:14 +00:00
|
|
|
Buffer->lbColor = pbrush->BrushAttr.lbColor;
|
2006-09-24 08:36:56 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
/* Set Hatch */
|
2009-03-20 22:40:14 +00:00
|
|
|
if ((pbrush->flAttrs & GDIBRUSH_IS_HATCH)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
2008-11-09 22:02:46 +00:00
|
|
|
/* FIXME : this is not the right value */
|
2009-03-20 22:40:14 +00:00
|
|
|
Buffer->lbHatch = (LONG)pbrush->hbmPattern;
|
2007-03-01 19:13:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Buffer->lbHatch = 0;
|
|
|
|
}
|
2006-09-24 08:36:56 +00:00
|
|
|
|
2007-03-01 19:13:29 +00:00
|
|
|
Buffer->lbStyle = 0;
|
2006-09-24 08:36:56 +00:00
|
|
|
|
2007-03-01 19:13:29 +00:00
|
|
|
/* Get the type of style */
|
2009-03-20 22:40:14 +00:00
|
|
|
if ((pbrush->flAttrs & GDIBRUSH_IS_SOLID)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_SOLID;
|
|
|
|
}
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & GDIBRUSH_IS_NULL)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_NULL; // BS_HOLLOW
|
|
|
|
}
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & GDIBRUSH_IS_HATCH)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_HATCHED;
|
|
|
|
}
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & GDIBRUSH_IS_BITMAP)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_PATTERN;
|
|
|
|
}
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & GDIBRUSH_IS_DIB)!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
2007-10-19 23:21:45 +00:00
|
|
|
Buffer->lbStyle = BS_DIBPATTERN;
|
2007-03-01 19:13:29 +00:00
|
|
|
}
|
2006-09-24 08:36:56 +00:00
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
/* FIXME
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & )!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_INDEXED;
|
|
|
|
}
|
2009-03-20 22:40:14 +00:00
|
|
|
else if ((pbrush->flAttrs & )!=0)
|
2007-03-01 19:13:29 +00:00
|
|
|
{
|
|
|
|
Buffer->lbStyle = BS_DIBPATTERNPT;
|
|
|
|
}
|
|
|
|
*/
|
2006-09-24 08:36:56 +00:00
|
|
|
|
2007-03-01 19:13:29 +00:00
|
|
|
/* FIXME */
|
2007-04-28 21:53:06 +00:00
|
|
|
return sizeof(LOGBRUSH);
|
2006-09-22 20:19:49 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
IntGdiCreateDIBBrush(
|
2009-04-08 14:18:23 +00:00
|
|
|
CONST BITMAPINFO *BitmapInfo,
|
|
|
|
UINT ColorSpec,
|
|
|
|
UINT BitmapInfoSize,
|
|
|
|
CONST VOID *PackedDIB)
|
2005-03-19 22:15:02 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH hBrush;
|
|
|
|
PBRUSH pbrush;
|
|
|
|
HBITMAP hPattern;
|
|
|
|
ULONG_PTR DataPtr;
|
2010-08-02 00:53:25 +00:00
|
|
|
PVOID pvDIBits;
|
2009-04-08 14:18:23 +00:00
|
|
|
|
|
|
|
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-08-01 12:17:35 +00:00
|
|
|
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
|
2009-04-08 14:18:23 +00:00
|
|
|
|
2010-08-02 00:53:25 +00:00
|
|
|
hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
|
2009-04-08 14:18:23 +00:00
|
|
|
if (hPattern == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-08-02 00:53:25 +00:00
|
|
|
RtlCopyMemory(pvDIBits,
|
|
|
|
(PVOID)DataPtr,
|
|
|
|
DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
|
|
|
|
BitmapInfo->bmiHeader.biHeight,
|
|
|
|
BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
|
2009-04-08 14:18:23 +00:00
|
|
|
|
|
|
|
pbrush = BRUSH_AllocBrushWithHandle();
|
|
|
|
if (pbrush == NULL)
|
|
|
|
{
|
|
|
|
GreDeleteObject(hPattern);
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
hBrush = pbrush->BaseObject.hHmgr;
|
|
|
|
|
|
|
|
pbrush->flAttrs |= GDIBRUSH_IS_BITMAP | GDIBRUSH_IS_DIB;
|
|
|
|
pbrush->hbmPattern = hPattern;
|
|
|
|
/* FIXME: Fill in the rest of fields!!! */
|
|
|
|
|
|
|
|
GDIOBJ_SetOwnership(hPattern, NULL);
|
|
|
|
|
|
|
|
BRUSH_UnlockBrush(pbrush);
|
|
|
|
|
|
|
|
return hBrush;
|
2005-03-19 22:15:02 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
IntGdiCreateHatchBrush(
|
2009-04-08 14:18:23 +00:00
|
|
|
INT Style,
|
|
|
|
COLORREF Color)
|
2005-03-19 22:15:02 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH hBrush;
|
|
|
|
PBRUSH pbrush;
|
|
|
|
HBITMAP hPattern;
|
|
|
|
|
|
|
|
if (Style < 0 || Style >= NB_HATCH_STYLES)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
|
2009-04-08 14:18:23 +00:00
|
|
|
if (hPattern == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pbrush = BRUSH_AllocBrushWithHandle();
|
|
|
|
if (pbrush == NULL)
|
|
|
|
{
|
|
|
|
GreDeleteObject(hPattern);
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
hBrush = pbrush->BaseObject.hHmgr;
|
|
|
|
|
|
|
|
pbrush->flAttrs |= GDIBRUSH_IS_HATCH;
|
|
|
|
pbrush->hbmPattern = hPattern;
|
|
|
|
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
|
|
|
|
|
|
|
|
GDIOBJ_SetOwnership(hPattern, NULL);
|
|
|
|
|
|
|
|
BRUSH_UnlockBrush(pbrush);
|
|
|
|
|
|
|
|
return hBrush;
|
2005-03-19 22:15:02 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
IntGdiCreatePatternBrush(
|
2009-04-08 14:18:23 +00:00
|
|
|
HBITMAP hBitmap)
|
2005-03-19 22:15:02 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH hBrush;
|
|
|
|
PBRUSH pbrush;
|
|
|
|
HBITMAP hPattern;
|
|
|
|
|
|
|
|
hPattern = BITMAP_CopyBitmap(hBitmap);
|
|
|
|
if (hPattern == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pbrush = BRUSH_AllocBrushWithHandle();
|
|
|
|
if (pbrush == NULL)
|
|
|
|
{
|
|
|
|
GreDeleteObject(hPattern);
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
hBrush = pbrush->BaseObject.hHmgr;
|
|
|
|
|
|
|
|
pbrush->flAttrs |= GDIBRUSH_IS_BITMAP;
|
|
|
|
pbrush->hbmPattern = hPattern;
|
|
|
|
/* FIXME: Fill in the rest of fields!!! */
|
|
|
|
|
|
|
|
GDIOBJ_SetOwnership(hPattern, NULL);
|
|
|
|
|
|
|
|
BRUSH_UnlockBrush(pbrush);
|
|
|
|
|
|
|
|
return hBrush;
|
2005-03-19 22:15:02 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
IntGdiCreateSolidBrush(
|
2009-04-08 14:18:23 +00:00
|
|
|
COLORREF Color)
|
2005-03-19 22:15:02 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH hBrush;
|
|
|
|
PBRUSH pbrush;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
pbrush = BRUSH_AllocBrushWithHandle();
|
|
|
|
if (pbrush == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
hBrush = pbrush->BaseObject.hHmgr;
|
2005-03-19 22:15:02 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
pbrush->flAttrs |= GDIBRUSH_IS_SOLID;
|
2006-09-23 12:33:54 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
pbrush->BrushAttr.lbColor = Color;
|
|
|
|
/* FIXME: Fill in the rest of fields!!! */
|
2005-03-19 22:15:02 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
BRUSH_UnlockBrush(pbrush);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
return hBrush;
|
2005-03-19 22:15:02 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
IntGdiCreateNullBrush(VOID)
|
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH hBrush;
|
|
|
|
PBRUSH pbrush;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
pbrush = BRUSH_AllocBrushWithHandle();
|
|
|
|
if (pbrush == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
hBrush = pbrush->BaseObject.hHmgr;
|
2004-04-05 21:26:25 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
pbrush->flAttrs |= GDIBRUSH_IS_NULL;
|
|
|
|
BRUSH_UnlockBrush(pbrush);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
return hBrush;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
IntGdiSetSolidBrushColor(HBRUSH hBrush, COLORREF Color)
|
|
|
|
{
|
|
|
|
PBRUSH pbrush;
|
|
|
|
|
|
|
|
pbrush = BRUSH_LockBrush(hBrush);
|
|
|
|
if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
|
|
|
|
{
|
|
|
|
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
|
|
|
|
}
|
|
|
|
BRUSH_UnlockBrush(pbrush);
|
1999-07-02 02:33:59 +00:00
|
|
|
}
|
|
|
|
|
2008-11-13 23:12:42 +00:00
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
2003-12-12 15:47:37 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-03-19 22:15:02 +00:00
|
|
|
NtGdiCreateDIBBrush(
|
2009-04-08 14:18:23 +00:00
|
|
|
IN PVOID BitmapInfoAndData,
|
|
|
|
IN FLONG ColorSpec,
|
|
|
|
IN UINT BitmapInfoSize,
|
|
|
|
IN BOOL b8X8,
|
|
|
|
IN BOOL bPen,
|
|
|
|
IN PVOID PackedDIB)
|
2003-12-12 15:47:37 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
BITMAPINFO *SafeBitmapInfoAndData;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
HBRUSH hBrush;
|
|
|
|
|
|
|
|
SafeBitmapInfoAndData = EngAllocMem(FL_ZERO_MEMORY, BitmapInfoSize, TAG_DIB);
|
|
|
|
if (SafeBitmapInfoAndData == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead(BitmapInfoAndData, BitmapInfoSize, 1);
|
|
|
|
RtlCopyMemory(SafeBitmapInfoAndData, BitmapInfoAndData, BitmapInfoSize);
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
EngFreeMem(SafeBitmapInfoAndData);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
hBrush = IntGdiCreateDIBBrush(SafeBitmapInfoAndData,
|
|
|
|
ColorSpec,
|
|
|
|
BitmapInfoSize,
|
|
|
|
PackedDIB);
|
|
|
|
|
|
|
|
EngFreeMem(SafeBitmapInfoAndData);
|
|
|
|
|
|
|
|
return hBrush;
|
2003-12-12 15:47:37 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2006-01-08 20:08:38 +00:00
|
|
|
NtGdiCreateHatchBrushInternal(
|
2009-04-08 14:18:23 +00:00
|
|
|
ULONG Style,
|
|
|
|
COLORREF Color,
|
|
|
|
BOOL bPen)
|
2003-12-12 15:47:37 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
return IntGdiCreateHatchBrush(Style, Color);
|
2003-12-12 15:47:37 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2006-01-08 20:08:38 +00:00
|
|
|
NtGdiCreatePatternBrushInternal(
|
2009-04-08 14:18:23 +00:00
|
|
|
HBITMAP hBitmap,
|
|
|
|
BOOL bPen,
|
|
|
|
BOOL b8x8)
|
2003-12-12 15:47:37 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
return IntGdiCreatePatternBrush(hBitmap);
|
2003-12-12 15:47:37 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
HBRUSH
|
|
|
|
APIENTRY
|
2005-12-28 20:31:44 +00:00
|
|
|
NtGdiCreateSolidBrush(COLORREF Color,
|
|
|
|
IN OPTIONAL HBRUSH hbr)
|
2003-12-12 15:47:37 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
return IntGdiCreateSolidBrush(Color);
|
2003-12-12 15:47:37 +00:00
|
|
|
}
|
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
/**
|
|
|
|
* \name NtGdiSetBrushOrg
|
2004-04-05 21:26:25 +00:00
|
|
|
*
|
2009-04-08 14:18:23 +00:00
|
|
|
* \brief Sets the brush origin that GDI assigns to
|
2005-05-08 02:11:54 +00:00
|
|
|
* the next brush an application selects into the specified device context.
|
2004-04-05 21:26:25 +00:00
|
|
|
*
|
2009-04-08 14:18:23 +00:00
|
|
|
* @implemented
|
2004-04-05 21:26:25 +00:00
|
|
|
*/
|
2009-04-08 14:18:23 +00:00
|
|
|
BOOL
|
|
|
|
APIENTRY
|
2007-08-11 06:29:31 +00:00
|
|
|
NtGdiSetBrushOrg(HDC hDC, INT XOrg, INT YOrg, LPPOINT Point)
|
2003-08-19 11:48:50 +00:00
|
|
|
{
|
2009-04-08 14:18:23 +00:00
|
|
|
PDC dc;
|
|
|
|
PDC_ATTR pdcattr;
|
|
|
|
|
|
|
|
dc = DC_LockDc(hDC);
|
|
|
|
if (dc == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2004-04-25 14:46:54 +00:00
|
|
|
return FALSE;
|
2009-04-08 14:18:23 +00:00
|
|
|
}
|
|
|
|
pdcattr = dc->pdcattr;
|
2004-04-05 21:26:25 +00:00
|
|
|
|
2009-04-08 14:18:23 +00:00
|
|
|
if (Point != NULL)
|
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
POINT SafePoint;
|
|
|
|
SafePoint.x = pdcattr->ptlBrushOrigin.x;
|
|
|
|
SafePoint.y = pdcattr->ptlBrushOrigin.y;
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite(Point, sizeof(POINT), 1);
|
|
|
|
*Point = SafePoint;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DC_UnlockDc(dc);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pdcattr->ptlBrushOrigin.x = XOrg;
|
|
|
|
pdcattr->ptlBrushOrigin.y = YOrg;
|
2010-04-07 00:46:16 +00:00
|
|
|
IntptlBrushOrigin(dc, XOrg, YOrg );
|
2009-04-08 14:18:23 +00:00
|
|
|
DC_UnlockDc(dc);
|
|
|
|
|
|
|
|
return TRUE;
|
2007-04-06 22:50:19 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|