Author: jimtabor Date: Sun Nov 30 18:13:45 2008 New Revision: 37784
URL: http://svn.reactos.org/svn/reactos?rev=37784&view=rev Log: - 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.
Modified: trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c trunk/reactos/subsystems/win32/win32k/objects/dc.c trunk/reactos/subsystems/win32/win32k/objects/dibobj.c trunk/reactos/subsystems/win32/win32k/objects/font.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] Sun Nov 30 18:13:45 2008 @@ -171,19 +171,130 @@ INT Width, INT Height) { - HBITMAP Bmp; - - /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */ - if (0 == Width || 0 == Height) - { - Bmp = NtGdiGetStockObject(DEFAULT_BITMAP); - } - else - { - Bmp = IntGdiCreateBitmap(abs(Width), abs(Height), 1, Dc->w.bitsPerPixel, NULL); - } - - return 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) + { + Bmp = NtGdiGetStockObject(DEFAULT_BITMAP); + } + else + { + 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; }
HBITMAP APIENTRY @@ -201,9 +312,12 @@ 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 @@ 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 @@ 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 */
Modified: trunk/reactos/subsystems/win32/win32k/objects/dc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/dc.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/dc.c [iso-8859-1] Sun Nov 30 18:13:45 2008 @@ -2064,138 +2064,6 @@ 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
Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Sun Nov 30 18:13:45 2008 @@ -23,6 +23,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 @@ 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,19 +354,42 @@ { 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) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return 0; - } + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return 0; + } if (Dc->DC_Type == DC_TYPE_INFO) - { - DC_UnlockDc(Dc); - return 0; - } - // Need SEH to check Bits and bmi. BTW bmi was converted in gdi. + { + DC_UnlockDc(Dc); + return 0; + } + Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc); @@ -367,6 +437,22 @@
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,83 +486,73 @@ 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), - bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, - (PVOID) Bits); - if (!hSourceBitmap) - { - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - Status = STATUS_NO_MEMORY; - _SEH2_LEAVE; - } - - pSourceSurf = EngLockSurface((HSURF)hSourceBitmap); - if (!pSourceSurf) - { - Status = STATUS_UNSUCCESSFUL; - _SEH2_LEAVE; - } - - - /* 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; - } - DDBPaletteType = pDCPalette->Mode; - DDBPalette = ((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault; - PALETTE_UnlockPalette(pDCPalette); - - DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType); - if (!DIBPalette) - { - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - Status = STATUS_NO_MEMORY; - _SEH2_LEAVE; - } - - /* Determine XlateObj */ - XlateObj = IntEngCreateXlate(DDBPaletteType, DIBPaletteType, DDBPalette, DIBPalette); - if (!XlateObj) - { - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - Status = STATUS_NO_MEMORY; - _SEH2_LEAVE; - } - - /* Copy the bits */ - Status = IntEngBitBlt(pDestSurf, - pSourceSurf, - NULL, - pDC->CombinedClip, - XlateObj, - &rcDest, - &ptSource, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCCOPY)); - - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END - + + SourceSize.cx = bmi->bmiHeader.biWidth; + SourceSize.cy = ScanLines; // this one --> abs(bmi->bmiHeader.biHeight) - StartScan + DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount); + + hSourceBitmap = EngCreateBitmap(SourceSize, + DIBWidth, + BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), + bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, + (PVOID) Bits); + if (!hSourceBitmap) + { + SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); + Status = STATUS_NO_MEMORY; + goto Exit; + } + + pSourceSurf = EngLockSurface((HSURF)hSourceBitmap); + if (!pSourceSurf) + { + Status = STATUS_UNSUCCESSFUL; + 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; + goto Exit; + } + + DDBPaletteType = pDCPalette->Mode; + DDBPalette = ((GDIDEVICE *)pDC->pPDev)->DevInfo.hpalDefault; + PALETTE_UnlockPalette(pDCPalette); + + DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType); + if (!DIBPalette) + { + SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); + Status = STATUS_NO_MEMORY; + goto Exit; + } + + /* Determine XlateObj */ + XlateObj = IntEngCreateXlate(DDBPaletteType, DIBPaletteType, DDBPalette, DIBPalette); + if (!XlateObj) + { + SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); + Status = STATUS_NO_MEMORY; + goto Exit; + } + + /* Copy the bits */ + Status = IntEngBitBlt(pDestSurf, + pSourceSurf, + NULL, + pDC->CombinedClip, + XlateObj, + &rcDest, + &ptSource, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCCOPY)); +Exit: if (NT_SUCCESS(Status)) { /* FIXME: Should probably be only the number of lines actually copied */ @@ -516,8 +592,35 @@ 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); @@ -531,251 +634,320 @@ 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; + 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 (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); - 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)) - { - 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.biPlanes = 1; - Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat); - switch (BitmapObj->SurfObj.iBitmapFormat) - { - case BMF_1BPP: - case BMF_4BPP: - case BMF_8BPP: - case BMF_16BPP: - case BMF_24BPP: - case BMF_32BPP: - Info->bmiHeader.biCompression = BI_RGB; - break; - case BMF_4RLE: - Info->bmiHeader.biCompression = BI_RLE4; - break; - case BMF_8RLE: - Info->bmiHeader.biCompression = BI_RLE8; - break; - case BMF_JPEG: - Info->bmiHeader.biCompression = BI_JPEG; - break; - case BMF_PNG: - Info->bmiHeader.biCompression = BI_PNG; - break; - } - /* Image size has to be calculated */ - Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth, - Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight; - Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */ - Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */ - Info->bmiHeader.biClrUsed = 0; - Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */ - /* Report negtive height for top-down bitmaps. */ - 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; - } + 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; + + 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 */ + 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)) + { + Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx; + /* Resulting height may be smaller than original height */ + Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy; + Info->bmiHeader.biPlanes = 1; + Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat); + switch (BitmapObj->SurfObj.iBitmapFormat) + { + case BMF_1BPP: + case BMF_4BPP: + case BMF_8BPP: + case BMF_16BPP: + case BMF_24BPP: + case BMF_32BPP: + Info->bmiHeader.biCompression = BI_RGB; + break; + case BMF_4RLE: + Info->bmiHeader.biCompression = BI_RLE4; + break; + case BMF_8RLE: + Info->bmiHeader.biCompression = BI_RLE8; + break; + case BMF_JPEG: + Info->bmiHeader.biCompression = BI_JPEG; + break; + case BMF_PNG: + Info->bmiHeader.biCompression = BI_PNG; + break; + } + /* Image size has to be calculated */ + Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth, + Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight; + Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */ + Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */ + Info->bmiHeader.biClrUsed = 0; + Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */ + /* Report negtive height for top-down bitmaps. */ + if (BitmapObj->SurfObj.lDelta > 0) + Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight; + } + Result = BitmapObj->SurfObj.sizlBitmap.cy; } else { - SIZEL DestSize; - ULONG SourcePaletteType = 0; - ULONG DestPaletteType; - POINTL SourcePoint; - ULONG Index; - - _SEH2_TRY - { - ProbeForRead(Info, sizeof(BITMAPINFO), 1); - - if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat)) - { - hDestPalette = hSourcePalette; - bPaletteMatch = TRUE; - } - else - hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault; - - SourcePalette = PALETTE_LockPalette(hSourcePalette); - /* FIXME - SourcePalette can be NULL!!! Don't assert here! */ - ASSERT(SourcePalette); - SourcePaletteType = SourcePalette->Mode; - PALETTE_UnlockPalette(SourcePalette); - - if (bPaletteMatch) - { - DestPalette = PALETTE_LockPalette(hDestPalette); - /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */ - DPRINT("DestPalette : %p\n", DestPalette); - ASSERT(DestPalette); - DestPaletteType = DestPalette->Mode; - } - else - { - DestPalette = SourcePalette; - } - - /* Copy palette. */ - /* FIXME: This is largely incomplete. */ - if (Info->bmiHeader.biBitCount <= 8) - { + SIZEL DestSize; + ULONG SourcePaletteType = 0; + ULONG DestPaletteType; + POINTL SourcePoint; + ULONG Index; + + if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat)) + { + hDestPalette = hSourcePalette; + bPaletteMatch = TRUE; + } + else + hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault; + + SourcePalette = PALETTE_LockPalette(hSourcePalette); + /* FIXME - SourcePalette can be NULL!!! Don't assert here! */ + ASSERT(SourcePalette); + SourcePaletteType = SourcePalette->Mode; + PALETTE_UnlockPalette(SourcePalette); + + if (bPaletteMatch) + { + DestPalette = PALETTE_LockPalette(hDestPalette); + /* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */ + DPRINT("DestPalette : %p\n", DestPalette); + ASSERT(DestPalette); + DestPaletteType = DestPalette->Mode; + } + else + { + DestPalette = SourcePalette; + } + + /* Copy palette. */ + /* 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; Index++) - { - Info->bmiColors[Index].rgbRed = DestPalette->IndexedColors[Index].peRed; - Info->bmiColors[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen; - Info->bmiColors[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue; - Info->bmiColors[Index].rgbReserved = 0; - } + { + Info->bmiColors[Index].rgbRed = DestPalette->IndexedColors[Index].peRed; + Info->bmiColors[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen; + Info->bmiColors[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue; + 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; + } } - } - - if (bPaletteMatch) - PALETTE_UnlockPalette(DestPalette); - - if (!ScanLines) ScanLines = abs(Info->bmiHeader.biHeight) - StartScan; - - /* Create the destination bitmap to for the copy operation */ - if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy) - { - _SEH2_YIELD(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; - - hDestBitmap = NULL; - - ProbeForWrite(Bits, BitmapObj->SurfObj.cjBits, 1); - - if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) - { - BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info; - coreheader->bcSize = DIB_GetDIBWidthBytes(DestSize.cx, - coreheader->bcBitCount) * DestSize.cy; - - hDestBitmap = EngCreateBitmap(DestSize, - DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount), - BitmapFormat(coreheader->bcBitCount, BI_RGB), - 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN, - Bits); - } - - if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) - { - Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx, - Info->bmiHeader.biBitCount) * DestSize.cy; - - hDestBitmap = EngCreateBitmap(DestSize, - DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), - BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression), - 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN, - Bits); - } - - if (hDestBitmap == NULL) - _SEH2_YIELD(goto cleanup); - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END - - if (NT_SUCCESS(Status)) - { - XLATEOBJ *XlateObj; - SURFOBJ *DestSurfObj; - RECTL DestRect; - - XlateObj = IntEngCreateXlate(DestPaletteType, - SourcePaletteType, - hDestPalette, - hSourcePalette); - - SourcePoint.x = 0; - SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines); - - /* Determine destination rectangle */ - DestRect.top = 0; - DestRect.left = 0; - DestRect.right = DestSize.cx; - DestRect.bottom = DestSize.cy; - - DestSurfObj = EngLockSurface((HSURF)hDestBitmap); - - if (EngCopyBits(DestSurfObj, - &BitmapObj->SurfObj, - NULL, - XlateObj, - &DestRect, - &SourcePoint)) - { - DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan); -// Result = abs(Info->bmiHeader.biHeight) - StartScan; - Result = ScanLines; - } - - EngDeleteXlate(XlateObj); - EngUnlockSurface(DestSurfObj); - } - } - + } + + 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 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) + { + goto cleanup; + } + else + { + ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan); + DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx; + DestSize.cy = ScanLines; + + hDestBitmap = NULL; + + if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info; + coreheader->bcSize = DIB_GetDIBWidthBytes(DestSize.cx, + coreheader->bcBitCount) * DestSize.cy; + + hDestBitmap = EngCreateBitmap(DestSize, + DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount), + BitmapFormat(coreheader->bcBitCount, BI_RGB), + 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN, + Bits); + } + + if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) + { + Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx, + Info->bmiHeader.biBitCount) * DestSize.cy; + + hDestBitmap = EngCreateBitmap(DestSize, + DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), + BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression), + 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN, + Bits); + } + + if (hDestBitmap == NULL) + goto cleanup; + } + + if (NT_SUCCESS(Status)) + { + XLATEOBJ *XlateObj; + SURFOBJ *DestSurfObj; + RECTL DestRect; + + XlateObj = IntEngCreateXlate(DestPaletteType, + SourcePaletteType, + hDestPalette, + hSourcePalette); + + SourcePoint.x = 0; + SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines); + + /* Determine destination rectangle */ + DestRect.top = 0; + DestRect.left = 0; + DestRect.right = DestSize.cx; + DestRect.bottom = DestSize.cy; + + DestSurfObj = EngLockSurface((HSURF)hDestBitmap); + + if (EngCopyBits( DestSurfObj, + &BitmapObj->SurfObj, + NULL, + XlateObj, + &DestRect, + &SourcePoint)) + { + DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan); + Result = ScanLines; + } + + EngDeleteXlate(XlateObj); + EngUnlockSurface(DestSurfObj); + } + } cleanup: if (hDestBitmap != NULL) EngDeleteSurface((HSURF)hDestBitmap); @@ -1207,6 +1379,7 @@ PAGE_READWRITE); if (!NT_SUCCESS(Status)) { + SetLastWin32Error(ERROR_INVALID_PARAMETER); return NULL; }
Modified: trunk/reactos/subsystems/win32/win32k/objects/font.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/font.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/font.c [iso-8859-1] Sun Nov 30 18:13:45 2008 @@ -772,5 +772,41 @@ 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 */