Modified: trunk/reactos/include/win32k/bitmaps.h
Modified: trunk/reactos/include/win32k/brush.h
Modified: trunk/reactos/lib/gdi32/gdi32.def
Modified: trunk/reactos/lib/gdi32/include/precomp.h
Modified: trunk/reactos/lib/gdi32/makefile
Modified: trunk/reactos/lib/gdi32/misc/stubs.c
Modified: trunk/reactos/lib/gdi32/objects/dc.c
Added: trunk/reactos/lib/gdi32/objects/utils.c
Modified: trunk/reactos/subsys/win32k/include/dib.h
Modified: trunk/reactos/subsys/win32k/include/intgdi.h
Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c
Modified: trunk/reactos/subsys/win32k/objects/bitmaps.c
Modified: trunk/reactos/subsys/win32k/objects/brush.c
Modified: trunk/reactos/subsys/win32k/objects/color.c
Modified: trunk/reactos/subsys/win32k/objects/dc.c
Modified: trunk/reactos/subsys/win32k/objects/dib.c
Modified: trunk/reactos/subsys/win32k/objects/stockobj.c
Modified: trunk/reactos/tools/nci/w32ksvc.db
Modified: trunk/reactos/w32api/include/wingdi.h
--- trunk/reactos/include/win32k/bitmaps.h 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/include/win32k/bitmaps.h 2005-03-19 22:15:02 UTC (rev 14203)
@@ -18,7 +18,7 @@
/* For device-independent bitmaps: */
DIBSECTION *dib;
- RGBQUAD *ColorMap;
+ HPALETTE hDIBPalette;
} BITMAPOBJ, *PBITMAPOBJ;
#define BITMAPOBJ_IS_APIBITMAP 0x1
--- trunk/reactos/include/win32k/brush.h 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/include/win32k/brush.h 2005-03-19 22:15:02 UTC (rev 14203)
@@ -86,16 +86,13 @@
CONST LOGBRUSH *LogBrush);
HBRUSH STDCALL
-NtGdiCreateDIBPatternBrush(
- HGLOBAL hDIBPacked,
- UINT ColorSpec);
+NtGdiCreateDIBBrush(
+ CONST BITMAPINFO *BitmapInfoAndData,
+ UINT ColorSpec,
+ UINT BitmapInfoSize,
+ CONST VOID *PackedDIB);
HBRUSH STDCALL
-NtGdiCreateDIBPatternBrushPt(
- CONST VOID *PackedDIB,
- UINT Usage);
-
-HBRUSH STDCALL
NtGdiCreateHatchBrush(
INT Style,
COLORREF Color);
--- trunk/reactos/lib/gdi32/gdi32.def 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/gdi32.def 2005-03-19 22:15:02 UTC (rev 14203)
@@ -49,7 +49,7 @@
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 @@
CreateDCA@16
CreateDCW@16
CreateDIBPatternBrush@8
-CreateDIBPatternBrushPt@8=NtGdiCreateDIBPatternBrushPt@8
+CreateDIBPatternBrushPt@8
CreateDIBSection@24=NtGdiCreateDIBSection@24
CreateDIBitmap@24=NtGdiCreateDIBitmap@24
CreateDiscardableBitmap@12=NtGdiCreateDiscardableBitmap@12
--- trunk/reactos/lib/gdi32/include/precomp.h 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/include/precomp.h 2005-03-19 22:15:02 UTC (rev 14203)
@@ -53,7 +53,13 @@
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 */
--- trunk/reactos/lib/gdi32/makefile 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/makefile 2005-03-19 22:15:02 UTC (rev 14203)
@@ -40,6 +40,8 @@
OBJECTS_OBJECTS = \
objects/bitblt.o \
+ objects/utils.o \
+ objects/brush.o \
objects/dc.o \
objects/font.o \
objects/linedda.o \
--- trunk/reactos/lib/gdi32/misc/stubs.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/misc/stubs.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -84,22 +84,7 @@
return 0;
}
-/*
- * @unimplemented
- */
-HBRUSH
-STDCALL
-CreateDIBPatternBrush(
- HGLOBAL a0,
- UINT a1
- )
-{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
/*
* @unimplemented
*/
--- trunk/reactos/lib/gdi32/objects/dc.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/objects/dc.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -290,26 +290,6 @@
/*
* @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
- */
COLORREF
STDCALL
GetDCBrushColor(
--- trunk/reactos/lib/gdi32/objects/utils.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/lib/gdi32/objects/utils.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -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)
+ * {
+ * <do something with the bitmap info>
+ * 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;
+}
--- trunk/reactos/subsys/win32k/include/dib.h 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/subsys/win32k/include/dib.h 2005-03-19 22:15:02 UTC (rev 14203)
@@ -17,6 +17,6 @@
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
HPALETTE FASTCALL
-BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType);
+BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
#endif /* _WIN32K_DIB_H */
--- trunk/reactos/subsys/win32k/include/intgdi.h 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/subsys/win32k/include/intgdi.h 2005-03-19 22:15:02 UTC (rev 14203)
@@ -9,17 +9,30 @@
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(
PDC dc,
--- trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -309,6 +309,13 @@
{
NTSTATUS Status;
+ if (WindowStation == NULL)
+ {
+// DPRINT1("Invalid window station handle\n");
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return STATUS_INVALID_HANDLE;
+ }
+
Status = ObReferenceObjectByHandle(
WindowStation,
DesiredAccess,
--- trunk/reactos/subsys/win32k/objects/bitmaps.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/subsys/win32k/objects/bitmaps.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -463,6 +463,10 @@
{
EngFreeUserMem(pBmp->SurfObj.pvBits);
}
+ if (pBmp->hDIBPalette)
+ {
+ NtGdiDeleteObject(pBmp->hDIBPalette);
+ }
}
return TRUE;
--- trunk/reactos/subsys/win32k/objects/brush.c 2005-03-19 21:48:33 UTC (rev 14202)
+++ trunk/reactos/subsys/win32k/objects/brush.c 2005-03-19 22:15:02 UTC (rev 14203)
@@ -72,6 +72,10 @@
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,83 +101,332 @@
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)
+ 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)
{
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
+ 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;
}
- break;
-
- case BS_PATTERN:
- hPattern = BITMAPOBJ_CopyBitmap((HBITMAP)LogBrush->lbHatch);
- if (hPattern == NULL)
+
+ case BI_RLE4:
+ if (BitCount == 4)
{
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
+ *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
+ return TRUE;
}
- break;
+ 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);
- if(BrushObject != NULL)
+ 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)
{
- switch (LogBrush->lbStyle)
- {
- case BS_NULL:
- BrushObject->flAttrs |= GDIBRUSH_IS_NULL;
- break;
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ hBrush = BRUSHOBJ_AllocBrush();
+ if (hBrush == NULL)
+ {
+ NtGdiDeleteObject(hPattern);
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
- case BS_SOLID:
- BrushObject->flAttrs |= GDIBRUSH_IS_SOLID;
- BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF;
- /* FIXME: Fill in the rest of fields!!! */
- break;
+ BrushObject = BRUSHOBJ_LockBrush(hBrush);
+ ASSERT(BrushObject != NULL);
- case BS_HATCHED:
- BrushObject->flAttrs |= GDIBRUSH_IS_HATCH;
- BrushObject->hbmPattern = hPattern;
- BrushObject->BrushAttr.lbColor = LogBrush->lbColor & 0xFFFFFF;
- break;
+ BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP;
+ BrushObject->hbmPattern = hPattern;
+ /* FIXME: Fill in the rest of fields!!! */
- case BS_PATTERN:
- BrushObject->flAttrs |= GDIBRUSH_IS_BITMAP;
- BrushObject->hbmPattern = hPattern;
- /* FIXME: Fill in the rest of fields!!! */
- break;
+ GDIOBJ_SetOwnership(hPattern, NULL);
- default:
- DPRINT1("Brush Style: %d\n", LogBrush->lbStyle);
- UNIMPLEMENTED;
- break;
- }
-
- BRUSHOBJ_UnlockBrush(hBrush);
+ BRUSHOBJ_UnlockBrush(hBrush);
+
+ return hBrush;
+}
+
+HBRUSH STDCALL
+IntGdiCreateSolidBrush(
+ COLORREF Color)
+{
+ HBRUSH hBrush;
+ PGDIBRUSHOBJ BrushObject;
+
+ hBrush = BRUSHOBJ_AllocBrush();
+ if (hBrush == NULL)
+ {
+ 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_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)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ BrushObject = BRUSHOBJ_LockBrush(hBrush);
+ ASSERT(BrushObject != NULL);
+ BrushObject->flAttrs |= GDIBRUSH_IS_NULL;
+ BRUSHOBJ_UnlockBrush(hBrush);
+
+ return hBrush;
+}
+
BOOL FASTCALL
IntPatBlt(
PDC dc,
@@ -299,82 +552,60 @@
/* 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,
[truncated at 1000 lines; 398 more skipped]