mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +00:00
- Moved SelectBitmap/Font to their proper places.
- Correct CreateCompatibleBitmap issues, finding more bugs and noted them. - DibObj.c is a work in progress, needing more love. Managing SEH in a proper manner, fixing the SEH abuse. - Wine gdi bitmap cross tests looking better, 16 bpp down to 50 faults. - Need full spectrum testing, I exhausted my test suite so anything will do. svn path=/trunk/; revision=37784
This commit is contained in:
parent
1af0b46120
commit
27204c5847
4 changed files with 721 additions and 433 deletions
|
@ -171,7 +171,7 @@ IntCreateCompatibleBitmap(
|
|||
INT Width,
|
||||
INT Height)
|
||||
{
|
||||
HBITMAP Bmp;
|
||||
HBITMAP Bmp = NULL;
|
||||
|
||||
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
||||
if (0 == Width || 0 == Height)
|
||||
|
@ -180,9 +180,120 @@ IntCreateCompatibleBitmap(
|
|||
}
|
||||
else
|
||||
{
|
||||
Bmp = IntGdiCreateBitmap(abs(Width), abs(Height), 1, Dc->w.bitsPerPixel, NULL);
|
||||
if (Dc->DC_Type != DC_TYPE_MEMORY)
|
||||
{
|
||||
Bmp = IntGdiCreateBitmap( abs(Width),
|
||||
abs(Height),
|
||||
IntGdiGetDeviceCaps(Dc,PLANES),
|
||||
IntGdiGetDeviceCaps(Dc,BITSPIXEL),
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DIBSECTION dibs;
|
||||
INT Count;
|
||||
PBITMAPOBJ BitmapObj = BITMAPOBJ_LockBitmap( Dc->w.hBitmap );
|
||||
Count = BITMAP_GetObject(BitmapObj, sizeof(dibs), &dibs);
|
||||
|
||||
if (Count)
|
||||
{
|
||||
if (Count == sizeof(BITMAP))
|
||||
{
|
||||
|
||||
/* We have a bitmap bug!!! W/O the HACK, we have white icons.
|
||||
|
||||
MSDN Note: When a memory device context is created, it initially
|
||||
has a 1-by-1 monochrome bitmap selected into it. If this memory
|
||||
device context is used in CreateCompatibleBitmap, the bitmap that
|
||||
is created is a monochrome bitmap. To create a color bitmap, use
|
||||
the hDC that was used to create the memory device context, as
|
||||
shown in the following code:
|
||||
|
||||
HDC memDC = CreateCompatibleDC ( hDC );
|
||||
HBITMAP memBM = CreateCompatibleBitmap ( hDC, nWidth, nHeight );
|
||||
SelectObject ( memDC, memBM );
|
||||
*/
|
||||
Bmp = IntGdiCreateBitmap( abs(Width),
|
||||
abs(Height),
|
||||
dibs.dsBm.bmPlanes,
|
||||
IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct!
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
/* A DIB section is selected in the DC */
|
||||
BITMAPINFO *bi;
|
||||
PVOID Bits;
|
||||
|
||||
/* Allocate memory for a BITMAPINFOHEADER structure and a
|
||||
color table. The maximum number of colors in a color table
|
||||
is 256 which corresponds to a bitmap with depth 8.
|
||||
Bitmaps with higher depths don't have color tables. */
|
||||
bi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD), TAG_TEMP);
|
||||
|
||||
if (bi)
|
||||
{
|
||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||
bi->bmiHeader.biWidth = Width;
|
||||
bi->bmiHeader.biHeight = Height;
|
||||
bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes;
|
||||
bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount;
|
||||
bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
|
||||
bi->bmiHeader.biSizeImage = 0;
|
||||
bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
|
||||
bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
|
||||
bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
|
||||
bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
|
||||
|
||||
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
/* Copy the color masks */
|
||||
RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD));
|
||||
}
|
||||
else if (bi->bmiHeader.biBitCount <= 8)
|
||||
{
|
||||
/* Copy the color table */
|
||||
UINT Index;
|
||||
PPALGDI PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
|
||||
|
||||
if (!PalGDI)
|
||||
{
|
||||
ExFreePoolWithTag(bi, TAG_TEMP);
|
||||
BITMAPOBJ_UnlockBitmap( BitmapObj );
|
||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (Index = 0;
|
||||
Index < 256 && Index < PalGDI->NumColors;
|
||||
Index++)
|
||||
{
|
||||
bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
|
||||
bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
|
||||
bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
|
||||
bi->bmiColors[Index].rgbReserved = 0;
|
||||
}
|
||||
PALETTE_UnlockPalette(PalGDI);
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap( BitmapObj );
|
||||
|
||||
Bmp = DIB_CreateDIBSection ( Dc,
|
||||
bi,
|
||||
DIB_RGB_COLORS,
|
||||
&Bits,
|
||||
NULL,
|
||||
0,
|
||||
0);
|
||||
|
||||
ExFreePoolWithTag(bi, TAG_TEMP);
|
||||
return Bmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap( BitmapObj );
|
||||
}
|
||||
}
|
||||
return Bmp;
|
||||
}
|
||||
|
||||
|
@ -201,9 +312,12 @@ NtGdiCreateCompatibleBitmap(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!hDC)
|
||||
return IntGdiCreateBitmap(Width, Height, 1, 1, 0);
|
||||
|
||||
Dc = DC_LockDc(hDC);
|
||||
|
||||
DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, Dc->w.bitsPerPixel);
|
||||
DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, ((PGDIDEVICE)Dc->pPDev)->GDIInfo.cBitsPixel);
|
||||
|
||||
if (NULL == Dc)
|
||||
{
|
||||
|
@ -343,6 +457,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
|
|||
bmpobj = BITMAPOBJ_LockBitmap ( hBmpTmp );
|
||||
if ( bmpobj )
|
||||
{
|
||||
// Dont you need to convert something here?
|
||||
Result = *(COLORREF*)bmpobj->SurfObj.pvScan0;
|
||||
BITMAPOBJ_UnlockBitmap ( bmpobj );
|
||||
}
|
||||
|
@ -785,5 +900,101 @@ NtGdiGetDCforBitmap(
|
|||
return hDC;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HBITMAP
|
||||
APIENTRY
|
||||
NtGdiSelectBitmap(
|
||||
IN HDC hDC,
|
||||
IN HBITMAP hBmp)
|
||||
{
|
||||
PDC pDC;
|
||||
PDC_ATTR pDc_Attr;
|
||||
HBITMAP hOrgBmp;
|
||||
PBITMAPOBJ pBmp;
|
||||
HRGN hVisRgn;
|
||||
BOOLEAN bFailed;
|
||||
PGDIBRUSHOBJ pBrush;
|
||||
|
||||
if (hDC == NULL || hBmp == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDc_Attr = pDC->pDc_Attr;
|
||||
if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
|
||||
|
||||
/* must be memory dc to select bitmap */
|
||||
if (pDC->DC_Type != DC_TYPE_MEMORY)
|
||||
{
|
||||
DC_UnlockDc(pDC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pBmp = BITMAPOBJ_LockBitmap(hBmp);
|
||||
if (!pBmp)
|
||||
{
|
||||
DC_UnlockDc(pDC);
|
||||
return NULL;
|
||||
}
|
||||
hOrgBmp = pDC->w.hBitmap;
|
||||
|
||||
/* Release the old bitmap, lock the new one and convert it to a SURF */
|
||||
pDC->w.hBitmap = hBmp;
|
||||
|
||||
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
|
||||
pDC->DcLevel.pSurface = pBmp;
|
||||
pBmp->hDC = hDC;
|
||||
|
||||
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
|
||||
if(pBmp->dib)
|
||||
{
|
||||
pDC->w.bitsPerPixel = pBmp->dib->dsBmih.biBitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDC->w.bitsPerPixel = BitsPerFormat(pBmp->SurfObj.iBitmapFormat);
|
||||
}
|
||||
|
||||
hVisRgn = NtGdiCreateRectRgn(0, 0, pBmp->SurfObj.sizlBitmap.cx, pBmp->SurfObj.sizlBitmap.cy);
|
||||
BITMAPOBJ_UnlockBitmap(pBmp);
|
||||
|
||||
/* Regenerate the XLATEOBJs. */
|
||||
pBrush = BRUSHOBJ_LockBrush(pDc_Attr->hbrush);
|
||||
if (pBrush)
|
||||
{
|
||||
if (pDC->XlateBrush)
|
||||
{
|
||||
EngDeleteXlate(pDC->XlateBrush);
|
||||
}
|
||||
pDC->XlateBrush = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
|
||||
BRUSHOBJ_UnlockBrush(pBrush);
|
||||
}
|
||||
|
||||
pBrush = PENOBJ_LockPen(pDc_Attr->hpen);
|
||||
if (pBrush)
|
||||
{
|
||||
if (pDC->XlatePen)
|
||||
{
|
||||
EngDeleteXlate(pDC->XlatePen);
|
||||
}
|
||||
pDC->XlatePen = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
|
||||
PENOBJ_UnlockPen(pBrush);
|
||||
}
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
if (hVisRgn)
|
||||
{
|
||||
GdiSelectVisRgn(hDC, hVisRgn);
|
||||
NtGdiDeleteObject(hVisRgn);
|
||||
}
|
||||
|
||||
return hOrgBmp;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -2064,138 +2064,6 @@ NtGdiSaveDC(HDC hDC)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HBITMAP
|
||||
APIENTRY
|
||||
NtGdiSelectBitmap(
|
||||
IN HDC hDC,
|
||||
IN HBITMAP hBmp)
|
||||
{
|
||||
PDC pDC;
|
||||
PDC_ATTR pDc_Attr;
|
||||
HBITMAP hOrgBmp;
|
||||
PBITMAPOBJ pBmp;
|
||||
HRGN hVisRgn;
|
||||
BOOLEAN bFailed;
|
||||
PGDIBRUSHOBJ pBrush;
|
||||
|
||||
if (hDC == NULL || hBmp == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDc_Attr = pDC->pDc_Attr;
|
||||
if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
|
||||
|
||||
/* must be memory dc to select bitmap */
|
||||
if (pDC->DC_Type != DC_TYPE_MEMORY)
|
||||
{
|
||||
DC_UnlockDc(pDC);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pBmp = BITMAPOBJ_LockBitmap(hBmp);
|
||||
if (!pBmp)
|
||||
{
|
||||
DC_UnlockDc(pDC);
|
||||
return NULL;
|
||||
}
|
||||
hOrgBmp = pDC->w.hBitmap;
|
||||
|
||||
/* Release the old bitmap, lock the new one and convert it to a SURF */
|
||||
pDC->w.hBitmap = hBmp;
|
||||
|
||||
// If Info DC this is zero and pSurface is moved to DC->pSurfInfo.
|
||||
pDC->DcLevel.pSurface = pBmp;
|
||||
pBmp->hDC = hDC;
|
||||
|
||||
// if we're working with a DIB, get the palette [fixme: only create if the selected palette is null]
|
||||
if(pBmp->dib)
|
||||
{
|
||||
pDC->w.bitsPerPixel = pBmp->dib->dsBmih.biBitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
pDC->w.bitsPerPixel = BitsPerFormat(pBmp->SurfObj.iBitmapFormat);
|
||||
}
|
||||
|
||||
hVisRgn = NtGdiCreateRectRgn(0, 0, pBmp->SurfObj.sizlBitmap.cx, pBmp->SurfObj.sizlBitmap.cy);
|
||||
BITMAPOBJ_UnlockBitmap(pBmp);
|
||||
|
||||
/* Regenerate the XLATEOBJs. */
|
||||
pBrush = BRUSHOBJ_LockBrush(pDc_Attr->hbrush);
|
||||
if (pBrush)
|
||||
{
|
||||
if (pDC->XlateBrush)
|
||||
{
|
||||
EngDeleteXlate(pDC->XlateBrush);
|
||||
}
|
||||
pDC->XlateBrush = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
|
||||
BRUSHOBJ_UnlockBrush(pBrush);
|
||||
}
|
||||
|
||||
pBrush = PENOBJ_LockPen(pDc_Attr->hpen);
|
||||
if (pBrush)
|
||||
{
|
||||
if (pDC->XlatePen)
|
||||
{
|
||||
EngDeleteXlate(pDC->XlatePen);
|
||||
}
|
||||
pDC->XlatePen = IntGdiCreateBrushXlate(pDC, pBrush, &bFailed);
|
||||
PENOBJ_UnlockPen(pBrush);
|
||||
}
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
if (hVisRgn)
|
||||
{
|
||||
GdiSelectVisRgn(hDC, hVisRgn);
|
||||
NtGdiDeleteObject(hVisRgn);
|
||||
}
|
||||
|
||||
return hOrgBmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HFONT
|
||||
APIENTRY
|
||||
NtGdiSelectFont(
|
||||
IN HDC hDC,
|
||||
IN HFONT hFont)
|
||||
{
|
||||
PDC pDC;
|
||||
PDC_ATTR pDc_Attr;
|
||||
HFONT hOrgFont = NULL;
|
||||
|
||||
if (hDC == NULL || hFont == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDc_Attr = pDC->pDc_Attr;
|
||||
if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
|
||||
|
||||
/* FIXME: what if not successful? */
|
||||
if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
|
||||
{
|
||||
hOrgFont = pDc_Attr->hlfntNew;
|
||||
pDc_Attr->hlfntNew = hFont;
|
||||
}
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
return hOrgFont;
|
||||
}
|
||||
|
||||
HPALETTE
|
||||
FASTCALL
|
||||
|
|
|
@ -24,6 +24,51 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static const RGBQUAD EGAColorsQuads[16] = {
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
|
||||
{ 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x00, 0x00 },
|
||||
{ 0x00, 0x80, 0x80, 0x00 },
|
||||
{ 0x80, 0x00, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x80, 0x00 },
|
||||
{ 0x80, 0x80, 0x00, 0x00 },
|
||||
{ 0x80, 0x80, 0x80, 0x00 },
|
||||
{ 0xc0, 0xc0, 0xc0, 0x00 },
|
||||
{ 0x00, 0x00, 0xff, 0x00 },
|
||||
{ 0x00, 0xff, 0x00, 0x00 },
|
||||
{ 0x00, 0xff, 0xff, 0x00 },
|
||||
{ 0xff, 0x00, 0x00, 0x00 },
|
||||
{ 0xff, 0x00, 0xff, 0x00 },
|
||||
{ 0xff, 0xff, 0x00, 0x00 },
|
||||
{ 0xff, 0xff, 0xff, 0x00 }
|
||||
};
|
||||
|
||||
static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
|
||||
{ 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x00, 0x00 },
|
||||
{ 0x00, 0x80, 0x80, 0x00 },
|
||||
{ 0x80, 0x00, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x80, 0x00 },
|
||||
{ 0x80, 0x80, 0x00, 0x00 },
|
||||
{ 0xc0, 0xc0, 0xc0, 0x00 },
|
||||
{ 0xc0, 0xdc, 0xc0, 0x00 },
|
||||
{ 0xf0, 0xca, 0xa6, 0x00 },
|
||||
{ 0xf0, 0xfb, 0xff, 0x00 },
|
||||
{ 0xa4, 0xa0, 0xa0, 0x00 },
|
||||
{ 0x80, 0x80, 0x80, 0x00 },
|
||||
{ 0x00, 0x00, 0xf0, 0x00 },
|
||||
{ 0x00, 0xff, 0x00, 0x00 },
|
||||
{ 0x00, 0xff, 0xff, 0x00 },
|
||||
{ 0xff, 0x00, 0x00, 0x00 },
|
||||
{ 0xff, 0x00, 0xff, 0x00 },
|
||||
{ 0xff, 0xff, 0x00, 0x00 },
|
||||
{ 0xff, 0xff, 0xff, 0x00 }
|
||||
};
|
||||
|
||||
|
||||
UINT APIENTRY
|
||||
IntSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors)
|
||||
{
|
||||
|
@ -294,6 +339,8 @@ IntSetDIBits(
|
|||
return result;
|
||||
}
|
||||
|
||||
// FIXME by Removing NtGdiSetDIBits!!!
|
||||
// This is a victim of the Win32k Initialization BUG!!!!!
|
||||
// Converts a DIB to a device-dependent bitmap
|
||||
INT APIENTRY
|
||||
NtGdiSetDIBits(
|
||||
|
@ -307,6 +354,29 @@ NtGdiSetDIBits(
|
|||
{
|
||||
PDC Dc;
|
||||
INT Ret;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
UINT cjBits;
|
||||
|
||||
if (!Bits) return 0;
|
||||
|
||||
_SEH2_TRY
|
||||
{ // FYI: We converted from CORE in gdi.
|
||||
ProbeForRead(bmi, sizeof(BITMAPINFO), 1);
|
||||
cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes * bmi->bmiHeader.biWidth;
|
||||
cjBits = ((cjBits + 31) & ~31 ) / 8;
|
||||
cjBits *= ScanLines;
|
||||
ProbeForRead(Bits, cjBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Dc = DC_LockDc(hDC);
|
||||
if (NULL == Dc)
|
||||
|
@ -319,7 +389,7 @@ NtGdiSetDIBits(
|
|||
DC_UnlockDc(Dc);
|
||||
return 0;
|
||||
}
|
||||
// Need SEH to check Bits and bmi. BTW bmi was converted in gdi.
|
||||
|
||||
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
||||
|
||||
DC_UnlockDc(Dc);
|
||||
|
@ -367,6 +437,22 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
|
||||
if (!Bits) return 0;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(bmi, cjMaxInfo , 1);
|
||||
ProbeForRead(Bits, cjMaxBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
|
@ -400,14 +486,11 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
ptSource.x = XSrc;
|
||||
ptSource.y = YSrc;
|
||||
|
||||
/* Enter SEH, as the bits are user mode */
|
||||
_SEH2_TRY // Look at NtGdiStretchDIBitsInternal
|
||||
{
|
||||
|
||||
SourceSize.cx = bmi->bmiHeader.biWidth;
|
||||
SourceSize.cy = ScanLines; // this one --> abs(bmi->bmiHeader.biHeight) - StartScan
|
||||
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
|
||||
|
||||
ProbeForRead(Bits, DIBWidth * abs(bmi->bmiHeader.biHeight), 1);
|
||||
hSourceBitmap = EngCreateBitmap(SourceSize,
|
||||
DIBWidth,
|
||||
BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
|
||||
|
@ -417,25 +500,25 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
{
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
Status = STATUS_NO_MEMORY;
|
||||
_SEH2_LEAVE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
pSourceSurf = EngLockSurface((HSURF)hSourceBitmap);
|
||||
if (!pSourceSurf)
|
||||
{
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
_SEH2_LEAVE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
||||
/* Obtain destination palette from the DC */
|
||||
pDCPalette = PALETTE_LockPalette(((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault);
|
||||
if (!pDCPalette)
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
_SEH2_LEAVE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
DDBPaletteType = pDCPalette->Mode;
|
||||
DDBPalette = ((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault;
|
||||
PALETTE_UnlockPalette(pDCPalette);
|
||||
|
@ -445,7 +528,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
{
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
Status = STATUS_NO_MEMORY;
|
||||
_SEH2_LEAVE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Determine XlateObj */
|
||||
|
@ -454,7 +537,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
{
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
Status = STATUS_NO_MEMORY;
|
||||
_SEH2_LEAVE;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Copy the bits */
|
||||
|
@ -469,14 +552,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
NULL,
|
||||
NULL,
|
||||
ROP3_TO_ROP4(SRCCOPY));
|
||||
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
Exit:
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* FIXME: Should probably be only the number of lines actually copied */
|
||||
|
@ -516,9 +592,36 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG Result = 0;
|
||||
BOOL bPaletteMatch = FALSE;
|
||||
PBYTE ChkBits = Bits;
|
||||
PVOID ColorPtr;
|
||||
RGBQUAD *rgbQuads;
|
||||
|
||||
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
|
||||
|
||||
if ( (Usage && Usage != DIB_PAL_COLORS) ||
|
||||
!Info ||
|
||||
!hBitmap )
|
||||
return 0;
|
||||
|
||||
// if ScanLines == 0, no need to copy Bits.
|
||||
if (!ScanLines) ChkBits = NULL;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
|
||||
if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get handle for the palette in DC. */
|
||||
Dc = DC_LockDc(hDC);
|
||||
if (Dc == NULL) return 0;
|
||||
|
@ -531,47 +634,38 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
hSourcePalette = Dc->DcLevel.hpal;
|
||||
DC_UnlockDc(Dc);
|
||||
|
||||
/* don't do anything if we fail this */
|
||||
if (Usage != DIB_RGB_COLORS && Usage != DIB_PAL_COLORS)
|
||||
return 0;
|
||||
|
||||
/* Get a pointer to the source bitmap object */
|
||||
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
|
||||
if (BitmapObj == NULL)
|
||||
return 0;
|
||||
|
||||
ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize);
|
||||
rgbQuads = (RGBQUAD *)ColorPtr;
|
||||
|
||||
/* fill out the BITMAPINFO struct */
|
||||
if (Bits == NULL)
|
||||
{
|
||||
_SEH2_TRY // Look at NtGdiStretchDIBitsInternal
|
||||
{ // Why check for anything, we converted in gdi!
|
||||
if (!ChkBits)
|
||||
{ // Core or not to Core? We have converted from Core in Gdi~ so?
|
||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||
|
||||
ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
|
||||
|
||||
coreheader = (BITMAPCOREHEADER*) Info;
|
||||
coreheader->bcWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||
coreheader->bcPlanes = 1;
|
||||
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
||||
/* Resulting height may be smaller than original height */ // You think!
|
||||
coreheader->bcHeight = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
||||
/* Resulting height may be smaller than original height */
|
||||
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||
coreheader->bcSize = DIB_GetDIBWidthBytes(coreheader->bcWidth,
|
||||
coreheader->bcBitCount) * coreheader->bcHeight;
|
||||
if (BitmapObj->SurfObj.lDelta > 0)
|
||||
coreheader->bcHeight = -coreheader->bcHeight;
|
||||
}
|
||||
|
||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||
if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
|
||||
{
|
||||
ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
|
||||
|
||||
if (!ScanLines) ScanLines = abs(Info->bmiHeader.biHeight) - StartScan;
|
||||
|
||||
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||
/* Resulting height may be smaller than original height */
|
||||
Info->bmiHeader.biHeight = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
||||
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||
Info->bmiHeader.biPlanes = 1;
|
||||
Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
||||
switch (BitmapObj->SurfObj.iBitmapFormat)
|
||||
|
@ -608,18 +702,8 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
if (BitmapObj->SurfObj.lDelta > 0)
|
||||
Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SIZEL DestSize;
|
||||
|
@ -628,10 +712,6 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
POINTL SourcePoint;
|
||||
ULONG Index;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(Info, sizeof(BITMAPINFO), 1);
|
||||
|
||||
if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat))
|
||||
{
|
||||
hDestPalette = hSourcePalette;
|
||||
|
@ -660,10 +740,53 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
}
|
||||
|
||||
/* Copy palette. */
|
||||
/* FIXME: This is largely incomplete. */
|
||||
if (Info->bmiHeader.biBitCount <= 8)
|
||||
/* FIXME: This is largely incomplete. ATM no Core!*/
|
||||
switch(Info->bmiHeader.biBitCount)
|
||||
{
|
||||
case 1:
|
||||
case 4:
|
||||
case 8:
|
||||
Info->bmiHeader.biClrUsed = 0;
|
||||
if ( BitmapObj->dib && BitmapObj->dib->dsBm.bmBitsPixel == Info->bmiHeader.biBitCount)
|
||||
{
|
||||
if (Usage == DIB_RGB_COLORS)
|
||||
{
|
||||
if (DestPalette->NumColors != 1 << Info->bmiHeader.biBitCount)
|
||||
Info->bmiHeader.biClrUsed = DestPalette->NumColors;
|
||||
for (Index = 0;
|
||||
Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors;
|
||||
Index++)
|
||||
{
|
||||
rgbQuads[Index].rgbRed = DestPalette->IndexedColors[Index].peRed;
|
||||
rgbQuads[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen;
|
||||
rgbQuads[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue;
|
||||
rgbQuads[Index].rgbReserved = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PWORD Ptr = ColorPtr;
|
||||
for (Index = 0;
|
||||
Index < (1 << Info->bmiHeader.biBitCount);
|
||||
Index++)
|
||||
{
|
||||
Ptr[Index] = (WORD)Index;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Usage == DIB_PAL_COLORS)
|
||||
{
|
||||
PWORD Ptr = ColorPtr;
|
||||
for (Index = 0;
|
||||
Index < (1 << Info->bmiHeader.biBitCount);
|
||||
Index++)
|
||||
{
|
||||
Ptr[Index] = (WORD)Index;
|
||||
}
|
||||
}
|
||||
else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
|
||||
{
|
||||
for (Index = 0;
|
||||
Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors;
|
||||
|
@ -675,33 +798,90 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
Info->bmiColors[Index].rgbReserved = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (Usage == DIB_PAL_COLORS)
|
||||
else
|
||||
{
|
||||
DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet\n");
|
||||
switch(Info->bmiHeader.biBitCount)
|
||||
{
|
||||
case 1:
|
||||
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0;
|
||||
rgbQuads[0].rgbReserved = 0;
|
||||
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff;
|
||||
rgbQuads[1].rgbReserved = 0;
|
||||
break;
|
||||
case 4:
|
||||
RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
|
||||
break;
|
||||
case 8:
|
||||
{
|
||||
INT r, g, b;
|
||||
RGBQUAD *color;
|
||||
|
||||
RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD));
|
||||
RtlCopyMemory(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD));
|
||||
color = rgbQuads + 10;
|
||||
for(r = 0; r <= 5; r++) /* FIXME */
|
||||
for(g = 0; g <= 5; g++)
|
||||
for(b = 0; b <= 5; b++)
|
||||
{
|
||||
color->rgbRed = (r * 0xff) / 5;
|
||||
color->rgbGreen = (g * 0xff) / 5;
|
||||
color->rgbBlue = (b * 0xff) / 5;
|
||||
color->rgbReserved = 0;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case 15:
|
||||
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
((PDWORD)Info->bmiColors)[0] = 0x7c00;
|
||||
((PDWORD)Info->bmiColors)[1] = 0x03e0;
|
||||
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
((PDWORD)Info->bmiColors)[0] = 0xf800;
|
||||
((PDWORD)Info->bmiColors)[1] = 0x07e0;
|
||||
((PDWORD)Info->bmiColors)[2] = 0x001f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
if (Info->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
((PDWORD)Info->bmiColors)[0] = 0xff0000;
|
||||
((PDWORD)Info->bmiColors)[1] = 0x00ff00;
|
||||
((PDWORD)Info->bmiColors)[2] = 0x0000ff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (bPaletteMatch)
|
||||
PALETTE_UnlockPalette(DestPalette);
|
||||
|
||||
if (!ScanLines) ScanLines = abs(Info->bmiHeader.biHeight) - StartScan;
|
||||
|
||||
/* Create the destination bitmap to for the copy operation */
|
||||
//
|
||||
// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them.
|
||||
//
|
||||
/* Create the destination bitmap too for the copy operation */
|
||||
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
|
||||
{
|
||||
_SEH2_YIELD(goto cleanup);
|
||||
goto cleanup;
|
||||
}
|
||||
else
|
||||
{ // Here again! ScanLine can be zero!
|
||||
{
|
||||
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
||||
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||
DestSize.cy = ScanLines; // this one ---> abs(Info->bmiHeader.biHeight) - StartScan;
|
||||
DestSize.cy = ScanLines;
|
||||
|
||||
hDestBitmap = NULL;
|
||||
|
||||
ProbeForWrite(Bits, BitmapObj->SurfObj.cjBits, 1);
|
||||
|
||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||
|
@ -715,7 +895,7 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
Bits);
|
||||
}
|
||||
|
||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||
if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER))
|
||||
{
|
||||
Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx,
|
||||
Info->bmiHeader.biBitCount) * DestSize.cy;
|
||||
|
@ -728,14 +908,8 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
}
|
||||
|
||||
if (hDestBitmap == NULL)
|
||||
_SEH2_YIELD(goto cleanup);
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -767,7 +941,6 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
&SourcePoint))
|
||||
{
|
||||
DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan);
|
||||
// Result = abs(Info->bmiHeader.biHeight) - StartScan;
|
||||
Result = ScanLines;
|
||||
}
|
||||
|
||||
|
@ -775,7 +948,6 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
EngUnlockSurface(DestSurfObj);
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (hDestBitmap != NULL)
|
||||
EngDeleteSurface((HSURF)hDestBitmap);
|
||||
|
@ -1207,6 +1379,7 @@ DIB_CreateDIBSection(
|
|||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -772,5 +772,41 @@ NtGdiHfontCreate(
|
|||
return hNewFont;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HFONT
|
||||
APIENTRY
|
||||
NtGdiSelectFont(
|
||||
IN HDC hDC,
|
||||
IN HFONT hFont)
|
||||
{
|
||||
PDC pDC;
|
||||
PDC_ATTR pDc_Attr;
|
||||
HFONT hOrgFont = NULL;
|
||||
|
||||
if (hDC == NULL || hFont == NULL) return NULL;
|
||||
|
||||
pDC = DC_LockDc(hDC);
|
||||
if (!pDC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pDc_Attr = pDC->pDc_Attr;
|
||||
if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
|
||||
|
||||
/* FIXME: what if not successful? */
|
||||
if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
|
||||
{
|
||||
hOrgFont = pDc_Attr->hlfntNew;
|
||||
pDc_Attr->hlfntNew = hFont;
|
||||
}
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
|
||||
return hOrgFont;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue