mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
[WIN32K]
- DDB are 16 bits aligned. - Reset hdc field of the unselected bitmap. - Lock it too, so it's not messed with when we unselect it. - Move Pattern creation of IntGdiCreateDIBBrush to DIB_CreateDIBSection. svn path=/branches/reactos-yarotows/; revision=48406
This commit is contained in:
parent
7d7d9eba48
commit
a0d32e2d0b
6 changed files with 82 additions and 77 deletions
|
@ -200,16 +200,21 @@ SURFACE_bSetBitmapBits(
|
||||||
cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
|
cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
|
||||||
|
|
||||||
/* Is a width in bytes given? */
|
/* Is a width in bytes given? */
|
||||||
if (ulWidth)
|
if (!ulWidth)
|
||||||
{
|
{
|
||||||
/* Align the width (Windows compatibility) */
|
/* Align the width (windows compatibility) */
|
||||||
ulWidth = ((((ulWidth << 3) / cBitsPixel) * cBitsPixel + 31) & ~31) >> 3;
|
if(psurf->flags & DDB_SURFACE)
|
||||||
}
|
{
|
||||||
else
|
/* DDB are 16 bits aligned */
|
||||||
{
|
ulWidth = BITMAP_GetWidthBytes(pso->sizlBitmap.cx, cBitsPixel);
|
||||||
/* Calculate width from the bitmap width in pixels */
|
}
|
||||||
ulWidth = ((pso->sizlBitmap.cx * cBitsPixel + 31) & ~31) >> 3;
|
else
|
||||||
}
|
{
|
||||||
|
/* Others are 32 bits aligned */
|
||||||
|
ulWidth = DIB_GetDIBWidthBytes(pso->sizlBitmap.cx, cBitsPixel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculate the bitmap size in bytes */
|
/* Calculate the bitmap size in bytes */
|
||||||
pso->cjBits = ulWidth * pso->sizlBitmap.cy;
|
pso->cjBits = ulWidth * pso->sizlBitmap.cy;
|
||||||
|
|
|
@ -32,7 +32,8 @@ GreCreateBitmapEx(
|
||||||
IN ULONG iFormat,
|
IN ULONG iFormat,
|
||||||
IN USHORT fjBitmap,
|
IN USHORT fjBitmap,
|
||||||
IN ULONG cjBits,
|
IN ULONG cjBits,
|
||||||
IN OPTIONAL PVOID pvBits);
|
IN OPTIONAL PVOID pvBits,
|
||||||
|
IN FLONG flags);
|
||||||
|
|
||||||
HBITMAP
|
HBITMAP
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
|
|
@ -76,14 +76,14 @@ GreCreateBitmapEx(
|
||||||
IN ULONG iFormat,
|
IN ULONG iFormat,
|
||||||
IN USHORT fjBitmap,
|
IN USHORT fjBitmap,
|
||||||
IN ULONG cjSizeImage,
|
IN ULONG cjSizeImage,
|
||||||
IN OPTIONAL PVOID pvBits)
|
IN OPTIONAL PVOID pvBits,
|
||||||
|
IN FLONG flags)
|
||||||
{
|
{
|
||||||
PSURFACE psurf;
|
PSURFACE psurf;
|
||||||
SURFOBJ *pso;
|
SURFOBJ *pso;
|
||||||
HBITMAP hbmp;
|
HBITMAP hbmp;
|
||||||
PVOID pvCompressedBits;
|
PVOID pvCompressedBits;
|
||||||
SIZEL sizl;
|
SIZEL sizl;
|
||||||
FLONG fl = 0;
|
|
||||||
|
|
||||||
/* Verify format */
|
/* Verify format */
|
||||||
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
|
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
|
||||||
|
@ -107,7 +107,7 @@ GreCreateBitmapEx(
|
||||||
pvCompressedBits = pvBits;
|
pvCompressedBits = pvBits;
|
||||||
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
Decompress4bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
|
Decompress4bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
|
||||||
fl |= BMF_RLE_HACK;
|
fjBitmap |= BMF_RLE_HACK;
|
||||||
}
|
}
|
||||||
else if (iFormat == BMF_8RLE)
|
else if (iFormat == BMF_8RLE)
|
||||||
{
|
{
|
||||||
|
@ -115,9 +115,12 @@ GreCreateBitmapEx(
|
||||||
pvCompressedBits = pvBits;
|
pvCompressedBits = pvBits;
|
||||||
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
Decompress8bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
|
Decompress8bpp(sizl, pvCompressedBits, pvBits, pso->lDelta);
|
||||||
fl |= BMF_RLE_HACK;
|
fjBitmap |= BMF_RLE_HACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark as API bitmap */
|
||||||
|
psurf->flags |= (flags | API_BITMAP);
|
||||||
|
|
||||||
/* Set the bitmap bits */
|
/* Set the bitmap bits */
|
||||||
if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
|
if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
|
||||||
{
|
{
|
||||||
|
@ -127,14 +130,14 @@ GreCreateBitmapEx(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark as API bitmap */
|
|
||||||
psurf->flags |= API_BITMAP;
|
|
||||||
|
|
||||||
/* Unlock the surface and return */
|
/* Unlock the surface and return */
|
||||||
SURFACE_UnlockSurface(psurf);
|
SURFACE_UnlockSurface(psurf);
|
||||||
return hbmp;
|
return hbmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Creates a DDB surface,
|
||||||
|
* as in CreateCompatibleBitmap or CreateBitmap.
|
||||||
|
*/
|
||||||
HBITMAP
|
HBITMAP
|
||||||
APIENTRY
|
APIENTRY
|
||||||
GreCreateBitmap(
|
GreCreateBitmap(
|
||||||
|
@ -151,7 +154,8 @@ GreCreateBitmap(
|
||||||
BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
|
BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
|
||||||
0, /* no bitmap flags */
|
0, /* no bitmap flags */
|
||||||
0, /* auto size */
|
0, /* auto size */
|
||||||
pvBits);
|
pvBits,
|
||||||
|
DDB_SURFACE /* DDB */);
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP
|
HBITMAP
|
||||||
|
@ -163,10 +167,7 @@ NtGdiCreateBitmap(
|
||||||
IN UINT cBitsPixel,
|
IN UINT cBitsPixel,
|
||||||
IN OPTIONAL LPBYTE pUnsafeBits)
|
IN OPTIONAL LPBYTE pUnsafeBits)
|
||||||
{
|
{
|
||||||
PSURFACE psurf;
|
|
||||||
SURFOBJ *pso;
|
|
||||||
HBITMAP hbmp;
|
HBITMAP hbmp;
|
||||||
FLONG fl = 0;
|
|
||||||
ULONG cjWidthBytes, iFormat;
|
ULONG cjWidthBytes, iFormat;
|
||||||
|
|
||||||
/* NOTE: Windows also doesn't store nr. of planes separately! */
|
/* NOTE: Windows also doesn't store nr. of planes separately! */
|
||||||
|
@ -185,7 +186,7 @@ NtGdiCreateBitmap(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure that cjBits will not overflow */
|
/* Make sure that cjBits will not overflow */
|
||||||
cjWidthBytes = DIB_GetDIBWidthBytes(nWidth, cBitsPixel);
|
cjWidthBytes = BITMAP_GetWidthBytes(nWidth, cBitsPixel);
|
||||||
if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
|
if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
|
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
|
||||||
|
@ -194,30 +195,12 @@ NtGdiCreateBitmap(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a surface */
|
/* cBitsPixel = cBitsPixel * cPlanes now! */
|
||||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
|
hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL);
|
||||||
if (!psurf)
|
|
||||||
{
|
|
||||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
|
||||||
EngSetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the handle for the bitmap and the surfobj */
|
|
||||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
|
||||||
pso = &psurf->SurfObj;
|
|
||||||
|
|
||||||
/* Allocate the bitmap bits */
|
|
||||||
if (!SURFACE_bSetBitmapBits(psurf, fl, 0, NULL))
|
|
||||||
{
|
|
||||||
/* Bail out if that failed */
|
|
||||||
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
|
||||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pUnsafeBits)
|
if (pUnsafeBits)
|
||||||
{
|
{
|
||||||
|
PSURFACE psurf = SURFACE_LockSurface(hbmp);
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
|
ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
|
||||||
|
@ -225,17 +208,15 @@ NtGdiCreateBitmap(
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
|
SURFACE_UnlockSurface(psurf);
|
||||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||||
_SEH2_YIELD(return NULL;)
|
_SEH2_YIELD(return NULL;)
|
||||||
}
|
}
|
||||||
_SEH2_END
|
_SEH2_END
|
||||||
|
|
||||||
|
SURFACE_UnlockSurface(psurf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark as API bitmap */
|
|
||||||
psurf->flags |= API_BITMAP;
|
|
||||||
|
|
||||||
/* Unlock the surface and return */
|
|
||||||
SURFACE_UnlockSurface(psurf);
|
|
||||||
return hbmp;
|
return hbmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +912,8 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
|
||||||
Bitmap->SurfObj.iBitmapFormat,
|
Bitmap->SurfObj.iBitmapFormat,
|
||||||
Bitmap->SurfObj.fjBitmap,
|
Bitmap->SurfObj.fjBitmap,
|
||||||
Bitmap->SurfObj.cjBits,
|
Bitmap->SurfObj.cjBits,
|
||||||
NULL);
|
NULL,
|
||||||
|
Bitmap->flags);
|
||||||
|
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -1052,4 +1034,5 @@ NtGdiGetDCforBitmap(
|
||||||
return hdc;
|
return hdc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -25,7 +25,7 @@ typedef struct _GDI_OBJ_ATTR_ENTRY
|
||||||
RGN_ATTR Attr[GDIOBJATTRFREE];
|
RGN_ATTR Attr[GDIOBJATTRFREE];
|
||||||
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
|
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
|
||||||
|
|
||||||
static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
|
static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
|
||||||
{
|
{
|
||||||
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
|
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
|
||||||
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
|
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
|
||||||
|
@ -256,8 +256,7 @@ IntGdiCreateDIBBrush(
|
||||||
PBRUSH pbrush;
|
PBRUSH pbrush;
|
||||||
HBITMAP hPattern;
|
HBITMAP hPattern;
|
||||||
ULONG_PTR DataPtr;
|
ULONG_PTR DataPtr;
|
||||||
PSURFACE psurfPattern;
|
PVOID pvDIBits;
|
||||||
HPALETTE hpal ;
|
|
||||||
|
|
||||||
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
||||||
{
|
{
|
||||||
|
@ -267,25 +266,17 @@ IntGdiCreateDIBBrush(
|
||||||
|
|
||||||
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
|
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
|
||||||
|
|
||||||
hPattern = GreCreateBitmap(BitmapInfo->bmiHeader.biWidth,
|
hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0);
|
||||||
BitmapInfo->bmiHeader.biHeight,
|
|
||||||
BitmapInfo->bmiHeader.biPlanes,
|
|
||||||
BitmapInfo->bmiHeader.biBitCount,
|
|
||||||
(PVOID)DataPtr);
|
|
||||||
if (hPattern == NULL)
|
if (hPattern == NULL)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
RtlCopyMemory(pvDIBits,
|
||||||
psurfPattern = SURFACE_LockSurface(hPattern);
|
(PVOID)DataPtr,
|
||||||
ASSERT(psurfPattern != NULL);
|
DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth,
|
||||||
if(ColorSpec == DIB_PAL_COLORS) DPRINT1("FIXME, unsupported color spec!\n");
|
BitmapInfo->bmiHeader.biHeight,
|
||||||
hpal = BuildDIBPalette(BitmapInfo);
|
BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes));
|
||||||
psurfPattern->ppal = PALETTE_ShareLockPalette(hpal);
|
|
||||||
/* Lazy delete palette, it will be freed when its shared reference is zeroed */
|
|
||||||
GreDeleteObject(hpal);
|
|
||||||
SURFACE_UnlockSurface(psurfPattern);
|
|
||||||
|
|
||||||
pbrush = BRUSH_AllocBrushWithHandle();
|
pbrush = BRUSH_AllocBrushWithHandle();
|
||||||
if (pbrush == NULL)
|
if (pbrush == NULL)
|
||||||
|
|
|
@ -284,15 +284,25 @@ NtGdiSelectBitmap(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the handle for the old bitmap */
|
/* Get the handle for the old bitmap */
|
||||||
psurfOld = pDC->dclevel.pSurface;
|
ASSERT(pDC->dclevel.pSurface);
|
||||||
hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL;
|
hOrgBmp = pDC->dclevel.pSurface->BaseObject.hHmgr;
|
||||||
|
|
||||||
|
/* Lock it, to be sure while we mess with it*/
|
||||||
|
psurfOld = SURFACE_LockSurface(hOrgBmp);
|
||||||
|
|
||||||
|
/* Reset hdc, this surface isn't selected anymore */
|
||||||
|
psurfOld->hdc = NULL;
|
||||||
|
|
||||||
/* Release the old bitmap, reference the new */
|
/* Release the old bitmap, reference the new */
|
||||||
DC_vSelectSurface(pDC, psurfBmp);
|
DC_vSelectSurface(pDC, psurfBmp);
|
||||||
|
|
||||||
|
/* And unlock it, now we're done */
|
||||||
|
SURFACE_UnlockSurface(psurfOld);
|
||||||
|
|
||||||
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
|
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
|
||||||
psurfBmp->hdc = hDC;
|
psurfBmp->hdc = hDC;
|
||||||
|
|
||||||
|
|
||||||
/* FIXME; improve by using a region without a handle and selecting it */
|
/* FIXME; improve by using a region without a handle and selecting it */
|
||||||
hVisRgn = IntSysCreateRectRgn( 0,
|
hVisRgn = IntSysCreateRectRgn( 0,
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -1463,10 +1463,20 @@ DIB_CreateDIBSection(
|
||||||
|
|
||||||
if (usage == DIB_PAL_COLORS)
|
if (usage == DIB_PAL_COLORS)
|
||||||
{
|
{
|
||||||
PPALETTE pdcPal ;
|
if(dc)
|
||||||
pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
|
{
|
||||||
hpal = DIB_MapPaletteColors(pdcPal, bmi);
|
PPALETTE pdcPal ;
|
||||||
PALETTE_UnlockPalette(pdcPal);
|
pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
|
||||||
|
hpal = DIB_MapPaletteColors(pdcPal, bmi);
|
||||||
|
PALETTE_UnlockPalette(pdcPal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* For DIB Brushes */
|
||||||
|
DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n");
|
||||||
|
/* HACK */
|
||||||
|
hpal = (HPALETTE) 0xFFFFFFFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1475,7 +1485,7 @@ DIB_CreateDIBSection(
|
||||||
|
|
||||||
if(!hpal)
|
if(!hpal)
|
||||||
{
|
{
|
||||||
DPRINT1("Error : Could not create a aplette for the DIB.\n");
|
DPRINT1("Error : Could not create a palette for the DIB.\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1489,7 +1499,8 @@ DIB_CreateDIBSection(
|
||||||
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
|
BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |
|
||||||
(bi->biHeight < 0 ? BMF_TOPDOWN : 0),
|
(bi->biHeight < 0 ? BMF_TOPDOWN : 0),
|
||||||
bi->biSizeImage,
|
bi->biSizeImage,
|
||||||
bm.bmBits);
|
bm.bmBits,
|
||||||
|
0);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||||
|
@ -1512,9 +1523,13 @@ DIB_CreateDIBSection(
|
||||||
bmp->flags = API_BITMAP;
|
bmp->flags = API_BITMAP;
|
||||||
bmp->biClrImportant = bi->biClrImportant;
|
bmp->biClrImportant = bi->biClrImportant;
|
||||||
|
|
||||||
bmp->ppal = PALETTE_ShareLockPalette(hpal);
|
/* HACK */
|
||||||
/* Lazy delete hpal, it will be freed at surface release */
|
if(hpal != (HPALETTE)0xFFFFFFFF)
|
||||||
GreDeleteObject(hpal);
|
{
|
||||||
|
bmp->ppal = PALETTE_ShareLockPalette(hpal);
|
||||||
|
/* Lazy delete hpal, it will be freed at surface release */
|
||||||
|
GreDeleteObject(hpal);
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up in case of errors
|
// Clean up in case of errors
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
Loading…
Reference in a new issue