From 1e7a5224aa7f37bb7eb8cb3664fbc5de55bd51a8 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 19 Mar 2005 22:15:02 +0000 Subject: [PATCH] - Replace the ColorMap pointer in BITMAPOBJ with palette handle and correctly free it when the bitmap is about to be destroyed. Also get rid of some palette leaks when DIBs were selected into device context. - Refine GDI32 -> Win32k interface for creating and managing brushes. Remove NtGdiCreateBrushIndirect, NtGdiCreateDIBPatternBrush, NtGdiCreateDIBPatternBrushPt and NtGdiFixBrushOrgEx syscalls and add NtGdiCreateDIBBrush. - Implement basic support for DIB pattern brushes. - Add user mode helper routine for "normalizing" BITMAPINFO structure. - Add definition for BITMAPV5HEADER. svn path=/trunk/; revision=14203 --- reactos/include/win32k/bitmaps.h | 2 +- reactos/include/win32k/brush.h | 13 +- reactos/lib/gdi32/gdi32.def | 4 +- reactos/lib/gdi32/include/precomp.h | 6 + reactos/lib/gdi32/makefile | 2 + reactos/lib/gdi32/misc/stubs.c | 15 - reactos/lib/gdi32/objects/dc.c | 20 - reactos/lib/gdi32/objects/utils.c | 333 +++++++++++++++++ reactos/subsys/win32k/include/dib.h | 2 +- reactos/subsys/win32k/include/intgdi.h | 29 +- reactos/subsys/win32k/ntuser/winsta.c | 7 + reactos/subsys/win32k/objects/bitmaps.c | 4 + reactos/subsys/win32k/objects/brush.c | 455 +++++++++++++++++------ reactos/subsys/win32k/objects/color.c | 2 +- reactos/subsys/win32k/objects/dc.c | 17 +- reactos/subsys/win32k/objects/dib.c | 64 +++- reactos/subsys/win32k/objects/stockobj.c | 40 +- reactos/tools/nci/w32ksvc.db | 5 +- reactos/w32api/include/wingdi.h | 28 ++ 19 files changed, 811 insertions(+), 237 deletions(-) create mode 100644 reactos/lib/gdi32/objects/utils.c diff --git a/reactos/include/win32k/bitmaps.h b/reactos/include/win32k/bitmaps.h index a438eba6cd8..4382f46d011 100644 --- a/reactos/include/win32k/bitmaps.h +++ b/reactos/include/win32k/bitmaps.h @@ -18,7 +18,7 @@ typedef struct _BITMAPOBJ /* For device-independent bitmaps: */ DIBSECTION *dib; - RGBQUAD *ColorMap; + HPALETTE hDIBPalette; } BITMAPOBJ, *PBITMAPOBJ; #define BITMAPOBJ_IS_APIBITMAP 0x1 diff --git a/reactos/include/win32k/brush.h b/reactos/include/win32k/brush.h index 3f39a5ffe46..9d44112e3e4 100644 --- a/reactos/include/win32k/brush.h +++ b/reactos/include/win32k/brush.h @@ -86,14 +86,11 @@ NtGdiCreateBrushIndirect( CONST LOGBRUSH *LogBrush); HBRUSH STDCALL -NtGdiCreateDIBPatternBrush( - HGLOBAL hDIBPacked, - UINT ColorSpec); - -HBRUSH STDCALL -NtGdiCreateDIBPatternBrushPt( - CONST VOID *PackedDIB, - UINT Usage); +NtGdiCreateDIBBrush( + CONST BITMAPINFO *BitmapInfoAndData, + UINT ColorSpec, + UINT BitmapInfoSize, + CONST VOID *PackedDIB); HBRUSH STDCALL NtGdiCreateHatchBrush( diff --git a/reactos/lib/gdi32/gdi32.def b/reactos/lib/gdi32/gdi32.def index fcf7a82aa6d..d6a9f07c126 100644 --- a/reactos/lib/gdi32/gdi32.def +++ b/reactos/lib/gdi32/gdi32.def @@ -49,7 +49,7 @@ CopyMetaFileA@8 CopyMetaFileW@8 CreateBitmap@20=NtGdiCreateBitmap@20 CreateBitmapIndirect@4=NtGdiCreateBitmapIndirect@4 -CreateBrushIndirect@4=NtGdiCreateBrushIndirect@4 +CreateBrushIndirect@4 CreateColorSpaceA@4 CreateColorSpaceW@4 CreateCompatibleBitmap@12=NtGdiCreateCompatibleBitmap@12 @@ -57,7 +57,7 @@ CreateCompatibleDC@4=NtGdiCreateCompatableDC@4 CreateDCA@16 CreateDCW@16 CreateDIBPatternBrush@8 -CreateDIBPatternBrushPt@8=NtGdiCreateDIBPatternBrushPt@8 +CreateDIBPatternBrushPt@8 CreateDIBSection@24=NtGdiCreateDIBSection@24 CreateDIBitmap@24=NtGdiCreateDIBitmap@24 CreateDiscardableBitmap@12=NtGdiCreateDiscardableBitmap@12 diff --git a/reactos/lib/gdi32/include/precomp.h b/reactos/lib/gdi32/include/precomp.h index 1accfed4187..750318e21f2 100644 --- a/reactos/lib/gdi32/include/precomp.h +++ b/reactos/lib/gdi32/include/precomp.h @@ -53,7 +53,13 @@ BOOL FASTCALL NewTextMetricW2A(NEWTEXTMETRICA *tma, NEWTEXTMETRICW *tmw); BOOL FASTCALL NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw); /* == GDI HANDLES =========================================================== */ + BOOL GdiIsHandleValid(HGDIOBJ hGdiObj); BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, PVOID *UserData); +/* == BITMAP UTILITY FUNCTIONS ============================================== */ + +BOOL STDCALL CalculateColorTableSize(LPBITMAPINFOHEADER BitmapInfoHeader, UINT *ColorSpec, UINT *ColorTableSize); +LPBITMAPINFO STDCALL ConvertBitmapInfo(LPBITMAPINFO BitmapInfo, UINT ColorSpec, UINT *BitmapInfoSize, BOOL FollowedByData); + /* EOF */ diff --git a/reactos/lib/gdi32/makefile b/reactos/lib/gdi32/makefile index 686e958e4c4..7e5ad362ad5 100644 --- a/reactos/lib/gdi32/makefile +++ b/reactos/lib/gdi32/makefile @@ -40,6 +40,8 @@ MISC_OBJECTS = \ OBJECTS_OBJECTS = \ objects/bitblt.o \ + objects/utils.o \ + objects/brush.o \ objects/dc.o \ objects/font.o \ objects/linedda.o \ diff --git a/reactos/lib/gdi32/misc/stubs.c b/reactos/lib/gdi32/misc/stubs.c index 9689b8592d2..af2b41da213 100644 --- a/reactos/lib/gdi32/misc/stubs.c +++ b/reactos/lib/gdi32/misc/stubs.c @@ -84,21 +84,6 @@ CloseMetaFile( return 0; } -/* - * @unimplemented - */ -HBRUSH -STDCALL -CreateDIBPatternBrush( - HGLOBAL a0, - UINT a1 - ) -{ - UNIMPLEMENTED; - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - /* * @unimplemented diff --git a/reactos/lib/gdi32/objects/dc.c b/reactos/lib/gdi32/objects/dc.c index 476aa3ad9e2..c3f9cba0714 100644 --- a/reactos/lib/gdi32/objects/dc.c +++ b/reactos/lib/gdi32/objects/dc.c @@ -287,26 +287,6 @@ GetObjectW(HGDIOBJ Handle, int Size, LPVOID Buffer) } -/* - * @implemented - */ -BOOL -STDCALL -FixBrushOrgEx( - HDC hdc, - int nXOrg, - int nYOrg, - LPPOINT lppt - ) -{ - #if 0 - /* FIXME - Check if we're emulating win95, if so, forward to SetBrushOrgEx() */ - return SetBrushOrgEx(hdc, nXOrg, nYOrg, lppt); - #endif - - return FALSE; -} - /* * @implemented */ diff --git a/reactos/lib/gdi32/objects/utils.c b/reactos/lib/gdi32/objects/utils.c new file mode 100644 index 00000000000..d0c98609751 --- /dev/null +++ b/reactos/lib/gdi32/objects/utils.c @@ -0,0 +1,333 @@ +#include "precomp.h" + +/** + * @name CalculateColorTableSize + * + * Internal routine to calculate the number of color table entries. + * + * @param BitmapInfoHeader + * Input bitmap information header, can be any version of + * BITMAPINFOHEADER or BITMAPCOREHEADER. + * + * @param ColorSpec + * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS + * or DIB_RGB_COLORS). On successful return this value is normalized + * according to the bitmap info. + * + * @param ColorTableSize + * On successful return this variable is filled with number of + * entries in color table for the image with specified parameters. + * + * @return + * TRUE if the input values together form a valid image, FALSE otherwise. + */ + +BOOL STDCALL +CalculateColorTableSize( + LPBITMAPINFOHEADER BitmapInfoHeader, + UINT *ColorSpec, + UINT *ColorTableSize) +{ + WORD BitCount; + DWORD ClrUsed; + DWORD Compression; + + /* + * At first get some basic parameters from the passed BitmapInfoHeader + * structure. It can have one of the following formats: + * - BITMAPCOREHEADER (the oldest one with totally different layout + * from the others) + * - BITMAPINFOHEADER (the standard and most common header) + * - BITMAPV4HEADER (extension of BITMAPINFOHEADER) + * - BITMAPV5HEADER (extension of BITMAPV4HEADER) + */ + + if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER)) + { + BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount; + ClrUsed = 0; + Compression = BI_RGB; + } + else + { + BitCount = BitmapInfoHeader->biBitCount; + ClrUsed = BitmapInfoHeader->biClrUsed; + Compression = BitmapInfoHeader->biCompression; + } + + switch (Compression) + { + case BI_BITFIELDS: + if (*ColorSpec == DIB_PAL_COLORS) + *ColorSpec = DIB_RGB_COLORS; + + if (BitCount != 16 && BitCount != 32) + return FALSE; + + /* + * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in + * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask). + * For BITMAPINFOHEADER the color masks are stored in the palette. + */ + + if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER)) + *ColorTableSize = 0; + else + *ColorTableSize = 3; + + return TRUE; + + case BI_RGB: + switch (BitCount) + { + case 1: + *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2; + return TRUE; + + case 4: + *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; + return TRUE; + + case 8: + *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; + return TRUE; + + default: + if (*ColorSpec == DIB_PAL_COLORS) + *ColorSpec = DIB_RGB_COLORS; + if (BitCount != 16 && BitCount != 24 && BitCount != 32) + return FALSE; + *ColorTableSize = ClrUsed; + return TRUE; + } + + case BI_RLE4: + if (BitCount == 4) + { + *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; + return TRUE; + } + return FALSE; + + case BI_RLE8: + if (BitCount == 8) + { + *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; + return TRUE; + } + return FALSE; + + case BI_JPEG: + case BI_PNG: + *ColorTableSize = ClrUsed; + return TRUE; + + default: + return FALSE; + } +} + +/** + * @name ConvertBitmapInfo + * + * Internal routine to convert a user-passed BITMAPINFO structure into + * unified BITMAPINFO structure. + * + * @param BitmapInfo + * Input bitmap info, can be any version of BITMAPINFO or + * BITMAPCOREINFO. + * @param ColorSpec + * Specifies whether the bmiColors member of the BITMAPINFO structure + * contains a valid color table and, if so, whether the entries in + * this color table contain explicit red, green, blue (DIB_RGB_COLORS) + * values or palette indexes (DIB_PAL_COLORS). + * @param BitmapInfoSize + * On successful return contains the size of the returned BITMAPINFO + * structure. If FollowedByData is TRUE the size includes the number + * of bytes occupied by the image data. + * @param FollowedByData + * Specifies if the BITMAPINFO header is immediately followed + * by the actual bitmap data (eg. as passed to CreateDIBPatternBrush). + * + * @return + * Either the original BitmapInfo or newly allocated structure is + * returned. For the later case the caller is responsible for freeing the + * memory using RtlFreeHeap with the current process heap. + * + * @example + * PBITMAPINFO NewBitmapInfo; + * UINT NewBitmapInfoSize; + * + * NewBitmapInfo = ConvertBitmapInfo(OldBitmapInfo, DIB_RGB_COLORS, + * &NewBitmapInfoSize, FALSE); + * if (NewBitmapInfo) + * { + * + * if (NewBitmapInfo != OldBitmapInfo) + * RtlFreeHeap(RtlGetProcessHeap(), 0, NewBitmapInfo); + * } + */ + +LPBITMAPINFO STDCALL +ConvertBitmapInfo( + LPBITMAPINFO BitmapInfo, + UINT ColorSpec, + UINT *BitmapInfoSize, + BOOL FollowedByData) +{ + LPBITMAPINFO NewBitmapInfo = BitmapInfo; + LPBITMAPCOREINFO CoreBitmapInfo = (LPBITMAPCOREINFO)BitmapInfo; + DWORD Size = 0; + ULONG DataSize = 0; + UINT PaletteEntryCount = 0; + + /* + * At first check if the passed BitmapInfo structure has valid size. It + * can have one of these headers: BITMAPCOREHEADER, BITMAPINFOHEADER, + * BITMAPV4HEADER or BITMAPV5HEADER (see CalculateColorTableSize for + * description). + */ + + if (BitmapInfo->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) && + (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER) || + BitmapInfo->bmiHeader.biSize > sizeof(BITMAPV5HEADER))) + { + return NULL; + } + + /* + * Now calculate the color table size. Also if the bitmap info contains + * invalid color information it's rejected here. + */ + + if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, &ColorSpec, + &PaletteEntryCount)) + { + return NULL; + } + + /* + * Calculate the size of image data if applicable. We must be careful + * to do proper aligning on line ends. + */ + + if (FollowedByData) + { + if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + DataSize = + CoreBitmapInfo->bmciHeader.bcHeight * + CoreBitmapInfo->bmciHeader.bcWidth * + CoreBitmapInfo->bmciHeader.bcBitCount; + DataSize = ((DataSize + 31) & ~31) / 8; + DataSize *= CoreBitmapInfo->bmciHeader.bcPlanes; + } + else + { + if (BitmapInfo->bmiHeader.biCompression == BI_RGB || + BitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) + { + DataSize = + abs(BitmapInfo->bmiHeader.biHeight) * + BitmapInfo->bmiHeader.biWidth * + BitmapInfo->bmiHeader.biBitCount; + DataSize = ((DataSize + 31) & ~31) / 8; + DataSize *= BitmapInfo->bmiHeader.biPlanes; + } + else + { + DataSize = BitmapInfo->bmiHeader.biSizeImage; + } + } + } + + /* + * If BitmapInfo was originally BITMAPCOREINFO then we need to convert + * it to the standard BITMAPINFO layout. + */ + + if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + Size = sizeof(BITMAPINFOHEADER); + if (ColorSpec == DIB_RGB_COLORS) + Size += PaletteEntryCount * sizeof(RGBQUAD); + else + Size += PaletteEntryCount * sizeof(USHORT); + Size += DataSize; + + NewBitmapInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size); + if (NewBitmapInfo == NULL) + { + return NULL; + } + + NewBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + NewBitmapInfo->bmiHeader.biWidth = CoreBitmapInfo->bmciHeader.bcWidth; + NewBitmapInfo->bmiHeader.biHeight = CoreBitmapInfo->bmciHeader.bcHeight; + NewBitmapInfo->bmiHeader.biPlanes = CoreBitmapInfo->bmciHeader.bcPlanes; + NewBitmapInfo->bmiHeader.biBitCount = CoreBitmapInfo->bmciHeader.bcBitCount; + NewBitmapInfo->bmiHeader.biCompression = BI_RGB; + NewBitmapInfo->bmiHeader.biSizeImage = 0; + NewBitmapInfo->bmiHeader.biXPelsPerMeter = 0; + NewBitmapInfo->bmiHeader.biYPelsPerMeter = 0; + NewBitmapInfo->bmiHeader.biClrUsed = 0; + NewBitmapInfo->bmiHeader.biClrImportant = 0; + + if (PaletteEntryCount != 0) + { + if (ColorSpec == DIB_RGB_COLORS) + { + ULONG Index; + + for (Index = 0; Index < PaletteEntryCount; Index++) + { + NewBitmapInfo->bmiColors[Index].rgbRed = + CoreBitmapInfo->bmciColors[Index].rgbtRed; + NewBitmapInfo->bmiColors[Index].rgbGreen = + CoreBitmapInfo->bmciColors[Index].rgbtGreen; + NewBitmapInfo->bmiColors[Index].rgbBlue = + CoreBitmapInfo->bmciColors[Index].rgbtBlue; + NewBitmapInfo->bmiColors[Index].rgbReserved = 0; + } + } + else + { + RtlCopyMemory(NewBitmapInfo->bmiColors, + CoreBitmapInfo->bmciColors, + PaletteEntryCount * sizeof(USHORT)); + } + } + + if (FollowedByData) + { + ULONG_PTR NewDataPtr, OldDataPtr; + + if (ColorSpec == DIB_RGB_COLORS) + { + NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors + + PaletteEntryCount); + OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors + + PaletteEntryCount); + } + else + { + NewDataPtr = (ULONG_PTR)(NewBitmapInfo->bmiColors) + + PaletteEntryCount * sizeof(USHORT); + OldDataPtr = (ULONG_PTR)(CoreBitmapInfo->bmciColors) + + PaletteEntryCount * sizeof(USHORT); + } + + RtlCopyMemory((PVOID)NewDataPtr, (PVOID)OldDataPtr, DataSize); + } + } + + Size = NewBitmapInfo->bmiHeader.biSize; + if (ColorSpec == DIB_RGB_COLORS) + Size += PaletteEntryCount * sizeof(RGBQUAD); + else + Size += PaletteEntryCount * sizeof(USHORT); + Size += DataSize; + *BitmapInfoSize = Size; + + return NewBitmapInfo; +} diff --git a/reactos/subsys/win32k/include/dib.h b/reactos/subsys/win32k/include/dib.h index 80a2fc4d7a3..49a13af6256 100644 --- a/reactos/subsys/win32k/include/dib.h +++ b/reactos/subsys/win32k/include/dib.h @@ -17,6 +17,6 @@ RGBQUAD * FASTCALL DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi); HPALETTE FASTCALL -BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType); +BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType); #endif /* _WIN32K_DIB_H */ diff --git a/reactos/subsys/win32k/include/intgdi.h b/reactos/subsys/win32k/include/intgdi.h index 66c422977ba..9d609313b69 100644 --- a/reactos/subsys/win32k/include/intgdi.h +++ b/reactos/subsys/win32k/include/intgdi.h @@ -9,16 +9,29 @@ IntGdiCreateBrushXlate(PDC Dc, GDIBRUSHOBJ *BrushObj, BOOLEAN *Failed); VOID FASTCALL IntGdiInitBrushInstance(GDIBRUSHINST *BrushInst, PGDIBRUSHOBJ BrushObj, XLATEOBJ *XlateObj); -HBRUSH FASTCALL -IntGdiCreateBrushIndirect(PLOGBRUSH lb); -HBRUSH FASTCALL -IntGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked, - UINT ColorSpec); +HBRUSH STDCALL +IntGdiCreateDIBBrush( + CONST BITMAPINFO *BitmapInfo, + UINT ColorSpec, + UINT BitmapInfoSize, + CONST VOID *PackedDIB); -HBRUSH FASTCALL -IntGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB, - UINT Usage); +HBRUSH STDCALL +IntGdiCreateHatchBrush( + INT Style, + COLORREF Color); + +HBRUSH STDCALL +IntGdiCreatePatternBrush( + HBITMAP hBitmap); + +HBRUSH STDCALL +IntGdiCreateSolidBrush( + COLORREF Color); + +HBRUSH STDCALL +IntGdiCreateNullBrush(VOID); BOOL FASTCALL IntPatBlt( diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index e2f3b1dc6f0..afa60e2dfa9 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -309,6 +309,13 @@ IntValidateWindowStationHandle( { NTSTATUS Status; + if (WindowStation == NULL) + { +// DPRINT1("Invalid window station handle\n"); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return STATUS_INVALID_HANDLE; + } + Status = ObReferenceObjectByHandle( WindowStation, DesiredAccess, diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index be145c84cb9..be7c92fa807 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.c @@ -463,6 +463,10 @@ BITMAP_Cleanup(PVOID ObjectBody) { EngFreeUserMem(pBmp->SurfObj.pvBits); } + if (pBmp->hDIBPalette) + { + NtGdiDeleteObject(pBmp->hDIBPalette); + } } return TRUE; diff --git a/reactos/subsys/win32k/objects/brush.c b/reactos/subsys/win32k/objects/brush.c index 0515507c617..9dee1e9e884 100644 --- a/reactos/subsys/win32k/objects/brush.c +++ b/reactos/subsys/win32k/objects/brush.c @@ -72,6 +72,10 @@ IntGdiCreateBrushXlate(PDC Dc, GDIBRUSHOBJ *BrushObj, BOOLEAN *Failed) if (Dc->w.bitsPerPixel != 1) Result = IntEngCreateSrcMonoXlate(Dc->w.hPalette, Dc->w.textColor, Dc->w.backgroundColor); } + else if (BrushObj->flAttrs & GDIBRUSH_IS_DIB) + { + Result = IntEngCreateXlate(0, 0, Dc->w.hPalette, Pattern->hDIBPalette); + } BITMAPOBJ_UnlockBitmap(BrushObj->hbmPattern); *Failed = FALSE; @@ -97,33 +101,291 @@ IntGdiInitBrushInstance(GDIBRUSHINST *BrushInst, PGDIBRUSHOBJ BrushObj, XLATEOBJ BrushInst->XlateObject = XlateObj; } -HBRUSH FASTCALL -IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush) +/** + * @name CalculateColorTableSize + * + * Internal routine to calculate the number of color table entries. + * + * @param BitmapInfoHeader + * Input bitmap information header, can be any version of + * BITMAPINFOHEADER or BITMAPCOREHEADER. + * + * @param ColorSpec + * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS + * or DIB_RGB_COLORS). On successful return this value is normalized + * according to the bitmap info. + * + * @param ColorTableSize + * On successful return this variable is filled with number of + * entries in color table for the image with specified parameters. + * + * @return + * TRUE if the input values together form a valid image, FALSE otherwise. + */ + +BOOL STDCALL +CalculateColorTableSize( + CONST BITMAPINFOHEADER *BitmapInfoHeader, + UINT *ColorSpec, + UINT *ColorTableSize) { - PGDIBRUSHOBJ BrushObject; - HBRUSH hBrush; - HBITMAP hPattern = 0; - - switch (LogBrush->lbStyle) + WORD BitCount; + DWORD ClrUsed; + DWORD Compression; + + /* + * At first get some basic parameters from the passed BitmapInfoHeader + * structure. It can have one of the following formats: + * - BITMAPCOREHEADER (the oldest one with totally different layout + * from the others) + * - BITMAPINFOHEADER (the standard and most common header) + * - BITMAPV4HEADER (extension of BITMAPINFOHEADER) + * - BITMAPV5HEADER (extension of BITMAPV4HEADER) + */ + + if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER)) { - case BS_HATCHED: - hPattern = NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes[LogBrush->lbHatch]); - if (hPattern == NULL) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - break; - - case BS_PATTERN: - hPattern = BITMAPOBJ_CopyBitmap((HBITMAP)LogBrush->lbHatch); - if (hPattern == NULL) - { - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } - break; + BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount; + ClrUsed = 0; + Compression = BI_RGB; } + else + { + BitCount = BitmapInfoHeader->biBitCount; + ClrUsed = BitmapInfoHeader->biClrUsed; + Compression = BitmapInfoHeader->biCompression; + } + + switch (Compression) + { + case BI_BITFIELDS: + if (*ColorSpec == DIB_PAL_COLORS) + *ColorSpec = DIB_RGB_COLORS; + + if (BitCount != 16 && BitCount != 32) + return FALSE; + + /* + * For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in + * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask). + * For BITMAPINFOHEADER the color masks are stored in the palette. + */ + + if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER)) + *ColorTableSize = 0; + else + *ColorTableSize = 3; + + return TRUE; + + case BI_RGB: + switch (BitCount) + { + case 1: + *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2; + return TRUE; + + case 4: + *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; + return TRUE; + + case 8: + *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; + return TRUE; + + default: + if (*ColorSpec == DIB_PAL_COLORS) + *ColorSpec = DIB_RGB_COLORS; + if (BitCount != 16 && BitCount != 24 && BitCount != 32) + return FALSE; + *ColorTableSize = ClrUsed; + return TRUE; + } + + case BI_RLE4: + if (BitCount == 4) + { + *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; + return TRUE; + } + return FALSE; + + case BI_RLE8: + if (BitCount == 8) + { + *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; + return TRUE; + } + return FALSE; + + case BI_JPEG: + case BI_PNG: + *ColorTableSize = ClrUsed; + return TRUE; + + default: + return FALSE; + } +} + +HBRUSH STDCALL +IntGdiCreateDIBBrush( + CONST BITMAPINFO *BitmapInfo, + UINT ColorSpec, + UINT BitmapInfoSize, + CONST VOID *PackedDIB) +{ + HBRUSH hBrush; + PGDIBRUSHOBJ BrushObject; + HBITMAP hPattern; + ULONG_PTR DataPtr; + UINT PaletteEntryCount; + PBITMAPOBJ BitmapObject; + UINT PaletteType; + + if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, &ColorSpec, + &PaletteEntryCount)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return NULL; + } + + DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize; + if (ColorSpec == DIB_RGB_COLORS) + DataPtr += PaletteEntryCount * sizeof(RGBQUAD); + else + DataPtr += PaletteEntryCount * sizeof(USHORT); + + hPattern = NtGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth, + BitmapInfo->bmiHeader.biHeight, + BitmapInfo->bmiHeader.biPlanes, + BitmapInfo->bmiHeader.biBitCount, + (PVOID)DataPtr); + if (hPattern == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + BitmapObject = BITMAPOBJ_LockBitmap(hPattern); + ASSERT(BitmapObject != NULL); + BitmapObject->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType); + BITMAPOBJ_UnlockBitmap(hPattern); + + hBrush = BRUSHOBJ_AllocBrush(); + if (hBrush == NULL) + { + NtGdiDeleteObject(hPattern); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + BrushObject = BRUSHOBJ_LockBrush(hBrush); + ASSERT(BrushObject != NULL); + + BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP | GDIBRUSH_IS_DIB; + BrushObject->hbmPattern = hPattern; + /* FIXME: Fill in the rest of fields!!! */ + + GDIOBJ_SetOwnership(hPattern, NULL); + + BRUSHOBJ_UnlockBrush(hBrush); + + return hBrush; +} + +HBRUSH STDCALL +IntGdiCreateHatchBrush( + INT Style, + COLORREF Color) +{ + HBRUSH hBrush; + PGDIBRUSHOBJ BrushObject; + HBITMAP hPattern; + + if (Style < 0 || Style >= NB_HATCH_STYLES) + { + return 0; + } + + hPattern = NtGdiCreateBitmap(8, 8, 1, 1, HatchBrushes[Style]); + if (hPattern == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + hBrush = BRUSHOBJ_AllocBrush(); + if (hBrush == NULL) + { + NtGdiDeleteObject(hPattern); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + BrushObject = BRUSHOBJ_LockBrush(hBrush); + ASSERT(BrushObject != NULL); + + BrushObject->flAttrs |= GDIBRUSH_IS_HATCH; + BrushObject->hbmPattern = hPattern; + BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF; + + GDIOBJ_SetOwnership(hPattern, NULL); + + BRUSHOBJ_UnlockBrush(hBrush); + + return hBrush; +} + +HBRUSH STDCALL +IntGdiCreatePatternBrush( + HBITMAP hBitmap) +{ + HBRUSH hBrush; + PGDIBRUSHOBJ BrushObject; + HBITMAP hPattern; + + hPattern = BITMAPOBJ_CopyBitmap(hBitmap); + if (hPattern == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + hBrush = BRUSHOBJ_AllocBrush(); + if (hBrush == NULL) + { + NtGdiDeleteObject(hPattern); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + BrushObject = BRUSHOBJ_LockBrush(hBrush); + ASSERT(BrushObject != NULL); + + BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP; + BrushObject->hbmPattern = hPattern; + /* FIXME: Fill in the rest of fields!!! */ + + GDIOBJ_SetOwnership(hPattern, NULL); + + BRUSHOBJ_UnlockBrush(hBrush); + + return hBrush; +} + +HBRUSH STDCALL +IntGdiCreateSolidBrush( + COLORREF Color) +{ + HBRUSH hBrush; + PGDIBRUSHOBJ BrushObject; hBrush = BRUSHOBJ_AllocBrush(); if (hBrush == NULL) @@ -133,43 +395,34 @@ IntGdiCreateBrushIndirect(PLOGBRUSH LogBrush) } BrushObject = BRUSHOBJ_LockBrush(hBrush); - if(BrushObject != NULL) + ASSERT(BrushObject != NULL); + + BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; + BrushObject->BrushAttr.lbColor = Color & 0xFFFFFF; + /* FIXME: Fill in the rest of fields!!! */ + + BRUSHOBJ_UnlockBrush(hBrush); + + return hBrush; +} + +HBRUSH STDCALL +IntGdiCreateNullBrush(VOID) +{ + HBRUSH hBrush; + PGDIBRUSHOBJ BrushObject; + + hBrush = BRUSHOBJ_AllocBrush(); + if (hBrush == NULL) { - switch (LogBrush->lbStyle) - { - case BS_NULL: - BrushObject->flAttrs |= GDIBRUSH_IS_NULL; - break; - - case BS_SOLID: - BrushObject->flAttrs |= GDIBRUSH_IS_SOLID; - BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; - /* FIXME: Fill in the rest of fields!!! */ - break; - - case BS_HATCHED: - BrushObject->flAttrs |= GDIBRUSH_IS_HATCH; - BrushObject->hbmPattern = hPattern; - BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF; - break; - - case BS_PATTERN: - BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP; - BrushObject->hbmPattern = hPattern; - /* FIXME: Fill in the rest of fields!!! */ - break; - - default: - DPRINT1("Brush Style: %d\n", LogBrush->lbStyle); - UNIMPLEMENTED; - break; - } - - BRUSHOBJ_UnlockBrush(hBrush); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; } - if (hPattern != 0) - GDIOBJ_SetOwnership(hPattern, NULL); + BrushObject = BRUSHOBJ_LockBrush(hBrush); + ASSERT(BrushObject != NULL); + BrushObject->flAttrs |= GDIBRUSH_IS_NULL; + BRUSHOBJ_UnlockBrush(hBrush); return hBrush; } @@ -299,80 +552,58 @@ IntGdiPolyPatBlt( /* PUBLIC FUNCTIONS ***********************************************************/ HBRUSH STDCALL -NtGdiCreateBrushIndirect(CONST LOGBRUSH *LogBrush) +NtGdiCreateDIBBrush( + CONST BITMAPINFO *BitmapInfoAndData, + UINT ColorSpec, + UINT BitmapInfoSize, + CONST VOID *PackedDIB) { - LOGBRUSH SafeLogBrush; + BITMAPINFO *SafeBitmapInfoAndData; NTSTATUS Status; - - Status = MmCopyFromCaller(&SafeLogBrush, LogBrush, sizeof(LOGBRUSH)); + HBRUSH hBrush; + + SafeBitmapInfoAndData = EngAllocMem(0, BitmapInfoSize, 0); + if (SafeBitmapInfoAndData == NULL) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + + Status = MmCopyFromCaller(SafeBitmapInfoAndData, BitmapInfoAndData, + BitmapInfoSize); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); return 0; } - - return IntGdiCreateBrushIndirect(&SafeLogBrush); + + hBrush = IntGdiCreateDIBBrush(SafeBitmapInfoAndData, ColorSpec, + BitmapInfoSize, PackedDIB); + + EngFreeMem(SafeBitmapInfoAndData); + + return hBrush; } HBRUSH STDCALL -NtGdiCreateDIBPatternBrush(HGLOBAL hDIBPacked, UINT ColorSpec) +NtGdiCreateHatchBrush( + INT Style, + COLORREF Color) { - UNIMPLEMENTED; - return 0; + return IntGdiCreateHatchBrush(Style, Color); } HBRUSH STDCALL -NtGdiCreateDIBPatternBrushPt(CONST VOID *PackedDIB, UINT Usage) +NtGdiCreatePatternBrush( + HBITMAP hBitmap) { - UNIMPLEMENTED; - return 0; -} - -HBRUSH STDCALL -NtGdiCreateHatchBrush(INT Style, COLORREF Color) -{ - LOGBRUSH LogBrush; - - if (Style < 0 || Style >= NB_HATCH_STYLES) - { - return 0; - } - - LogBrush.lbStyle = BS_HATCHED; - LogBrush.lbColor = Color; - LogBrush.lbHatch = Style; - - return IntGdiCreateBrushIndirect(&LogBrush); -} - -HBRUSH STDCALL -NtGdiCreatePatternBrush(HBITMAP hBitmap) -{ - LOGBRUSH LogBrush; - - LogBrush.lbStyle = BS_PATTERN; - LogBrush.lbColor = 0; - LogBrush.lbHatch = (ULONG)hBitmap; - - return IntGdiCreateBrushIndirect(&LogBrush); + return IntGdiCreatePatternBrush(hBitmap); } HBRUSH STDCALL NtGdiCreateSolidBrush(COLORREF Color) { - LOGBRUSH LogBrush; - - LogBrush.lbStyle = BS_SOLID; - LogBrush.lbColor = Color; - LogBrush.lbHatch = 0; - - return IntGdiCreateBrushIndirect(&LogBrush); -} - -BOOL STDCALL -NtGdiFixBrushOrgEx(VOID) -{ - return FALSE; + return IntGdiCreateSolidBrush(Color); } /* diff --git a/reactos/subsys/win32k/objects/color.c b/reactos/subsys/win32k/objects/color.c index 919238add2a..cbeaf8967a2 100644 --- a/reactos/subsys/win32k/objects/color.c +++ b/reactos/subsys/win32k/objects/color.c @@ -287,7 +287,7 @@ UINT STDCALL NtGdiGetSystemPaletteEntries(HDC hDC, UINT STDCALL NtGdiGetSystemPaletteUse(HDC hDC) { - UNIMPLEMENTED; + DPRINT1("NtGdiGetSystemPaletteUse is unimplemented\n"); return 0; } diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 07164a7a6ba..03981225660 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -1868,7 +1868,6 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) PGDIBRUSHOBJ brush; XLATEOBJ *XlateObj; DWORD objectType; - ULONG NumColors = 0; HRGN hVisRgn; BOOLEAN Failed; @@ -1962,21 +1961,7 @@ NtGdiSelectObject(HDC hDC, HGDIOBJ hGDIObj) if(pb->dib) { dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount; - - if(pb->dib->dsBmih.biBitCount <= 8) - { - if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else - if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else - if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; } - dc->w.hPalette = PALETTE_AllocPaletteIndexedRGB(NumColors, pb->ColorMap); - } - else - { - dc->w.hPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL, - pb->dib->dsBitfields[0], - pb->dib->dsBitfields[1], - pb->dib->dsBitfields[2]); - } + dc->w.hPalette = pb->hDIBPalette; } else { diff --git a/reactos/subsys/win32k/objects/dib.c b/reactos/subsys/win32k/objects/dib.c index 1d1285b3ba9..f203cb212d3 100644 --- a/reactos/subsys/win32k/objects/dib.c +++ b/reactos/subsys/win32k/objects/dib.c @@ -19,12 +19,15 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include +#include UINT STDCALL NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors) { PDC dc; PBITMAPOBJ BitmapObj; + PPALGDI PalGDI; + UINT Index; if (!(dc = DC_LockDc(hDC))) return 0; if (dc->IsIC) @@ -55,12 +58,24 @@ NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Col if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount)) Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex; - MmCopyFromCaller(BitmapObj->ColorMap + StartIndex, Colors, Entries * sizeof(RGBQUAD)); - - /* Rebuild the palette. */ - NtGdiDeleteObject(dc->w.hPalette); - dc->w.hPalette = PALETTE_AllocPaletteIndexedRGB(1 << BitmapObj->dib->dsBmih.biBitCount, - BitmapObj->ColorMap); + PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette); + _SEH_TRY + { + for (Index = StartIndex; + Index < StartIndex + Entries && Index < PalGDI->NumColors; + Index++) + { + PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed; + PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen; + PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue; + } + } + _SEH_HANDLE + { + Entries = 0; + } + _SEH_END + PALETTE_UnlockPalette(BitmapObj->hDIBPalette); } else Entries = 0; @@ -76,6 +91,8 @@ NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors) { PDC dc; PBITMAPOBJ BitmapObj; + PPALGDI PalGDI; + UINT Index; if (!(dc = DC_LockDc(hDC))) return 0; if (dc->IsIC) @@ -106,7 +123,24 @@ NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors) if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount)) Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex; - MmCopyToCaller(Colors, BitmapObj->ColorMap + StartIndex, Entries * sizeof(RGBQUAD)); + PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette); + _SEH_TRY + { + for (Index = StartIndex; + Index < StartIndex + Entries && Index < PalGDI->NumColors; + Index++) + { + Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed; + Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen; + Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue; + } + } + _SEH_HANDLE + { + Entries = 0; + } + _SEH_END + PALETTE_UnlockPalette(BitmapObj->hDIBPalette); } else Entries = 0; @@ -619,7 +653,7 @@ LONG STDCALL NtGdiGetBitmapBits(HBITMAP hBitmap, return ret; } -static HBITMAP FASTCALL +HBITMAP FASTCALL IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header, DWORD init, LPCVOID bits, const BITMAPINFO *data, UINT coloruse) @@ -884,14 +918,12 @@ DIB_CreateDIBSection( if(bi->biBitCount == 8) { Entries = 256; } if (Entries) - { - bmp->ColorMap = ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD)*Entries, TAG_COLORMAP); - RtlCopyMemory(bmp->ColorMap, bmi->bmiColors, sizeof(RGBQUAD)*Entries); - } + bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(Entries, bmi->bmiColors); else - { - bmp->ColorMap = NULL; - } + bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL, + dib->dsBitfields[0], + dib->dsBitfields[1], + dib->dsBitfields[2]); } // Clean up in case of errors @@ -1085,7 +1117,7 @@ DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi) } HPALETTE FASTCALL -BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType) +BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType) { BYTE bits; ULONG ColorCount; diff --git a/reactos/subsys/win32k/objects/stockobj.c b/reactos/subsys/win32k/objects/stockobj.c index c36e414ce87..59a8a3e42b5 100644 --- a/reactos/subsys/win32k/objects/stockobj.c +++ b/reactos/subsys/win32k/objects/stockobj.c @@ -68,28 +68,6 @@ static HBRUSH SysColorBrushes[NUM_SYSCOLORS]; /* GDI stock objects */ -static LOGBRUSH WhiteBrush = -{ BS_SOLID, RGB(255,255,255), 0 }; - -static LOGBRUSH LtGrayBrush = -/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ -{ BS_SOLID, RGB(192,192,192), 0 }; - -static LOGBRUSH GrayBrush = -/* FIXME : this should perhaps be BS_HATCHED, at least for 1 bitperpixel */ -{ BS_SOLID, RGB(128,128,128), 0 }; - -static LOGBRUSH DkGrayBrush = -/* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */ -/* NB_HATCH_STYLES is an index into HatchBrushes */ -{ BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES }; - -static LOGBRUSH BlackBrush = -{ BS_SOLID, RGB(0,0,0), 0 }; - -static LOGBRUSH NullBrush = -{ BS_NULL, 0, 0 }; - static LOGPEN WhitePen = { PS_SOLID, { 0, 0 }, RGB(255,255,255) }; @@ -144,12 +122,12 @@ CreateStockObjects(void) /* Create GDI Stock Objects from the logical structures we've defined */ - StockObjects[WHITE_BRUSH] = IntGdiCreateBrushIndirect(&WhiteBrush); - StockObjects[LTGRAY_BRUSH] = IntGdiCreateBrushIndirect(&LtGrayBrush); - StockObjects[GRAY_BRUSH] = IntGdiCreateBrushIndirect(&GrayBrush); - StockObjects[DKGRAY_BRUSH] = IntGdiCreateBrushIndirect(&DkGrayBrush); - StockObjects[BLACK_BRUSH] = IntGdiCreateBrushIndirect(&BlackBrush); - StockObjects[NULL_BRUSH] = IntGdiCreateBrushIndirect(&NullBrush); + StockObjects[WHITE_BRUSH] = IntGdiCreateSolidBrush(RGB(255,255,255)); + StockObjects[LTGRAY_BRUSH] = IntGdiCreateSolidBrush(RGB(192,192,192)); + StockObjects[GRAY_BRUSH] = IntGdiCreateSolidBrush(RGB(128,128,128)); + StockObjects[DKGRAY_BRUSH] = IntGdiCreateSolidBrush(RGB(64,64,64)); + StockObjects[BLACK_BRUSH] = IntGdiCreateSolidBrush(RGB(0,0,0)); + StockObjects[NULL_BRUSH] = IntGdiCreateNullBrush(); StockObjects[WHITE_PEN] = IntGdiCreatePenIndirect(&WhitePen); StockObjects[BLACK_PEN] = IntGdiCreatePenIndirect(&BlackPen); @@ -279,18 +257,14 @@ VOID FASTCALL CreateSysColorObjects(VOID) { UINT i; - LOGBRUSH Brush; LOGPEN Pen; /* Create the syscolor brushes */ - Brush.lbStyle = BS_SOLID; - Brush.lbHatch = 0; for(i = 0; i < NUM_SYSCOLORS; i++) { if(SysColorBrushes[i] == NULL) { - Brush.lbColor = SysColors[i]; - SysColorBrushes[i] = IntGdiCreateBrushIndirect(&Brush); + SysColorBrushes[i] = IntGdiCreateSolidBrush(SysColors[i]); if(SysColorBrushes[i] != NULL) { GDIOBJ_ConvertToStockObj((HGDIOBJ*)&SysColorBrushes[i]); diff --git a/reactos/tools/nci/w32ksvc.db b/reactos/tools/nci/w32ksvc.db index f821cb711bf..85212cee508 100644 --- a/reactos/tools/nci/w32ksvc.db +++ b/reactos/tools/nci/w32ksvc.db @@ -22,14 +22,12 @@ NtGdiCopyEnhMetaFile 2 NtGdiCopyMetaFile 2 NtGdiCreateBitmap 5 NtGdiCreateBitmapIndirect 1 -NtGdiCreateBrushIndirect 1 NtGdiCreateColorSpace 1 NtGdiCreateCompatibleBitmap 3 NtGdiCreateCompatableDC 1 NtGdiCreateDC 4 NtGdiCreateDIBitmap 6 -NtGdiCreateDIBPatternBrush 2 -NtGdiCreateDIBPatternBrushPt 2 +NtGdiCreateDIBBrush 4 NtGdiCreateDIBSection 6 NtGdiCreateDiscardableBitmap 3 NtGdiCreateEllipticRgn 4 @@ -81,7 +79,6 @@ NtGdiExtSelectClipRgn 3 NtGdiExtTextOut 8 NtGdiFillPath 1 NtGdiFillRgn 3 -NtGdiFixBrushOrgEx 0 NtGdiFlattenPath 1 NtGdiFloodFill 4 NtGdiFrameRgn 5 diff --git a/reactos/w32api/include/wingdi.h b/reactos/w32api/include/wingdi.h index c4f6290b340..bf25f1f19bc 100644 --- a/reactos/w32api/include/wingdi.h +++ b/reactos/w32api/include/wingdi.h @@ -1293,6 +1293,34 @@ typedef struct { DWORD bV4GammaGreen; DWORD bV4GammaBlue; } BITMAPV4HEADER,*LPBITMAPV4HEADER,*PBITMAPV4HEADER; +#if (WINVER >= 0x500) +typedef struct { + DWORD bV5Size; + LONG bV5Width; + LONG bV5Height; + WORD bV5Planes; + WORD bV5BitCount; + DWORD bV5Compression; + DWORD bV5SizeImage; + LONG bV5XPelsPerMeter; + LONG bV5YPelsPerMeter; + DWORD bV5ClrUsed; + DWORD bV5ClrImportant; + DWORD bV5RedMask; + DWORD bV5GreenMask; + DWORD bV5BlueMask; + DWORD bV5AlphaMask; + DWORD bV5CSType; + CIEXYZTRIPLE bV5Endpoints; + DWORD bV5GammaRed; + DWORD bV5GammaGreen; + DWORD bV5GammaBlue; + DWORD bV5Intent; + DWORD bV5ProfileData; + DWORD bV5ProfileSize; + DWORD bV5Reserved; +} BITMAPV5HEADER,*LPBITMAPV5HEADER,*PBITMAPV5HEADER; +#endif typedef struct tagFONTSIGNATURE { DWORD fsUsb[4]; DWORD fsCsb[2];