Author: tkreuzer Date: Thu Apr 26 16:19:22 2012 New Revision: 56429
URL: http://svn.reactos.org/svn/reactos?rev=56429&view=rev Log: [WIN32K] - Implement TranslateCOLORREF, based on IntHandleSpecialColorType, but now returning both the translated color and the resulting RGB color, correctly handling DIBINDEX, which will use the given value without translation. - Rewrite NtGdiSetPixel using IntPatBlt - Rewrite NtGdiGetPixel using IntEngCopyBits - Fix EXLATEOBJ_iXlateTable to return 0, when the palette index is too big, instead of wrapping around - Remove old debugcode
Added: trunk/reactos/win32ss/gdi/ntgdi/patblt.c - copied, changed from r56411, trunk/reactos/win32ss/gdi/ntgdi/bitblt.c Modified: trunk/reactos/win32ss/gdi/eng/engbrush.c trunk/reactos/win32ss/gdi/eng/xlate.c trunk/reactos/win32ss/gdi/ntgdi/bitblt.c trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c trunk/reactos/win32ss/gdi/ntgdi/brush.h trunk/reactos/win32ss/gdi/ntgdi/dcobjs.c
Modified: trunk/reactos/win32ss/gdi/eng/engbrush.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/engbrush.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/eng/engbrush.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/eng/engbrush.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -47,7 +47,7 @@ else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID) { /* Set the RGB color */ - EBRUSHOBJ_vSetSolidBrushColor(pebo, pbrush->BrushAttr.lbColor); + EBRUSHOBJ_vSetSolidRGBColor(pebo, pbrush->BrushAttr.lbColor); } else { @@ -62,7 +62,7 @@
VOID FASTCALL -EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor) +EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor) { ULONG iSolidColor; EXLATEOBJ exlo;
Modified: trunk/reactos/win32ss/gdi/eng/xlate.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/xlate.c?rev... ============================================================================== --- trunk/reactos/win32ss/gdi/eng/xlate.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/eng/xlate.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -49,10 +49,7 @@ FASTCALL EXLATEOBJ_iXlateTable(PEXLATEOBJ pexlo, ULONG iColor) { - if (iColor >= pexlo->xlo.cEntries) - { - iColor %= pexlo->xlo.cEntries; - } + if (iColor >= pexlo->xlo.cEntries) return 0; return pexlo->xlo.pulXlate[iColor]; }
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitblt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitblt.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -16,6 +16,79 @@
#define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop)) #define ROP_TO_ROP4(Rop) ((Rop) >> 16) + +ULONG +TranslateCOLORREF(PDC pdc, COLORREF *pcrColor) +{ + PPALETTE ppalDC, ppalSurface; + ULONG index, ulColor, iBitmapFormat; + COLORREF crColor = *pcrColor; + EXLATEOBJ exlo; + + switch (crColor >> 24) + { + case 0x00: /* RGB color */ + break; + + case 0x01: /* PALETTEINDEX */ + index = crColor & 0xFFFFFF; + ppalDC = pdc->dclevel.ppal; + if (index >= ppalDC->NumColors) index = 0; + + /* Get the RGB value */ + crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); + *pcrColor = crColor; + break; + + case 0x02: /* PALETTERGB */ + + /* First find the nearest index in the dc palette */ + ppalDC = pdc->dclevel.ppal; + index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF); + + /* Get the RGB value */ + crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index); + *pcrColor = crColor; + break; + + case 0x10: /* DIBINDEX */ + /* Mask the value to match the target bpp */ + iBitmapFormat = pdc->dclevel.pSurface->SurfObj.iBitmapFormat; + if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1; + else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf; + else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF; + else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF; + else index = crColor & 0xFFFFFF; + + /* Translate the color to RGB for the caller */ + ppalSurface = pdc->dclevel.pSurface->ppal; + if (index < ppalSurface->NumColors) + *pcrColor = PALETTE_ulGetRGBColorFromIndex(ppalSurface, index); + else + *pcrColor = 0; + return index; + + default: + DPRINT("Unsupported color type %d passed\n", crColor >> 24); + return 0; + } + + /* Initialize an XLATEOBJ from RGB to the target surface */ + EXLATEOBJ_vInitialize(&exlo, + &gpalRGB, + pdc->dclevel.pSurface->ppal, + 0, + pdc->pdcattr->crBackgroundClr, + pdc->pdcattr->crForegroundClr); + + /* Translate the color to the target format */ + ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); + + /* Cleanup and return the RGB value */ + EXLATEOBJ_vCleanup(&exlo); + return ulColor; +} +
BOOL APIENTRY NtGdiAlphaBlend( @@ -874,17 +947,17 @@ _In_ INT y, _In_ INT cx, _In_ INT cy, - _In_ DWORD rop4) + _In_ DWORD dwRop) { BOOL bResult; PDC pdc;
/* Mask away everything except foreground rop index */ - rop4 = rop4 & 0x00FF0000; - rop4 |= rop4 << 8; + dwRop = dwRop & 0x00FF0000; + dwRop |= dwRop << 8;
/* Check if the rop uses a source */ - if (ROP_USES_SOURCE(rop4)) + if (ROP_USES_SOURCE(dwRop)) { /* This is not possible */ return 0; @@ -911,7 +984,7 @@ DC_vUpdateFillBrush(pdc);
/* Call the internal function */ - bResult = IntPatBlt(pdc, x, y, cx, cy, rop4, &pdc->eboFill); + bResult = IntPatBlt(pdc, x, y, cx, cy, dwRop, &pdc->eboFill);
/* Unlock the DC and return the result */ DC_UnlockDc(pdc); @@ -969,3 +1042,137 @@
return Ret; } + + +COLORREF +APIENTRY +NtGdiSetPixel( + _In_ HDC hdc, + _In_ INT x, + _In_ INT y, + _In_ COLORREF crColor) +{ + PDC pdc; + ULONG iOldColor, iSolidColor; + BOOL bResult; + PEBRUSHOBJ pebo; + ULONG ulDirty; + + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return -1; + } + + /* Check if the DC has no surface (empty mem or info DC) */ + if (pdc->dclevel.pSurface == NULL) + { + /* Fail! */ + DC_UnlockDc(pdc); + return -1; + } + + /* Translate the color to the target format and get the RGB value */ + iSolidColor = TranslateCOLORREF(pdc, &crColor); + + /* Use the DC's text brush, which is always a solid brush */ + pebo = &pdc->eboText; + + /* Save the old solid color and set the one for the pixel */ + iOldColor = EBRUSHOBJ_iSetSolidColor(pebo, iSolidColor); + + /* Save dirty flags and reset dirty text brush flag */ + ulDirty = pdc->pdcattr->ulDirty_; + pdc->pdcattr->ulDirty_ &= ~DIRTY_TEXT; + + /* Call the internal function */ + bResult = IntPatBlt(pdc, x, y, 1, 1, PATCOPY, pebo); + + /* Restore old text brush color and dirty flags */ + EBRUSHOBJ_iSetSolidColor(pebo, iOldColor); + pdc->pdcattr->ulDirty_ = ulDirty; + + /* Unlock the DC */ + DC_UnlockDc(pdc); + + /* Return the new RGB color or -1 on failure */ + return bResult ? crColor : -1; +} + +COLORREF +APIENTRY +NtGdiGetPixel( + _In_ HDC hdc, + _In_ INT x, + _In_ INT y) +{ + PDC pdc; + ULONG ulRGBColor; + BOOL bResult = FALSE; + POINTL ptlSrc; + PSURFACE psurfSrc, psurfDest; + + /* Lock the DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return -1; + } + + /* Check if the DC has no surface (empty mem or info DC) */ + psurfSrc = pdc->dclevel.pSurface; + if (psurfSrc == NULL) + { + /* Fail! */ + DC_UnlockDc(pdc); + return -1; + } + + /* Get the logical coordinates */ + ptlSrc.x = x; + ptlSrc.y = y; + + /* Translate coordinates to device coordinates */ + IntLPtoDP(pdc, &ptlSrc, 1); + ptlSrc.x += pdc->ptlDCOrig.x; + ptlSrc.y += pdc->ptlDCOrig.y; + + /* Allocate a surface */ + psurfDest = SURFACE_AllocSurface(STYPE_BITMAP, 1, 1, BMF_32BPP); + if (psurfDest) + { + /* Set the bitmap bits */ + if (SURFACE_bSetBitmapBits(psurfDest, 0, 0, &ulRGBColor)) + { + RECTL rclDest = {0, 0, 1, 1}; + EXLATEOBJ exlo; + + /* Translate from the source palette to RGB color */ + EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, &gpalRGB, 0, 0, 0); + + /* Call the copy bits function */ + bResult = IntEngCopyBits(&psurfDest->SurfObj, + &psurfSrc->SurfObj, + pdc->rosdc.CombinedClip, + &exlo.xlo, + &rclDest, + &ptlSrc); + + /* Cleanup the XLATEOBJ */ + EXLATEOBJ_vCleanup(&exlo); + } + + /* Delete the surface */ + GDIOBJ_vDeleteObject(&psurfDest->BaseObject); + } + + /* Unlock the DC */ + DC_UnlockDc(pdc); + + /* Return the new RGB color or -1 on failure */ + return bResult ? ulRGBColor : -1; +} +
Modified: trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/bitmaps.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -385,103 +385,6 @@ return Ret; }
-COLORREF APIENTRY -NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) -{ - PDC dc = NULL; - COLORREF Result = (COLORREF)CLR_INVALID; // Default to failure - BOOL bInRect = FALSE; - SURFACE *psurf; - SURFOBJ *pso; - EXLATEOBJ exlo; - HBITMAP hBmpTmp; - - dc = DC_LockDc(hDC); - - if (!dc) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return Result; - } - - if (dc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(dc); - return Result; - } - - XPos += dc->ptlDCOrig.x; - YPos += dc->ptlDCOrig.y; - if ((dc->rosdc.CombinedClip == NULL) || - (RECTL_bPointInRect(&dc->rosdc.CombinedClip->rclBounds, XPos, YPos))) - { - bInRect = TRUE; - psurf = dc->dclevel.pSurface; - if (psurf) - { - pso = &psurf->SurfObj; - EXLATEOBJ_vInitialize(&exlo, psurf->ppal, &gpalRGB, 0, 0xffffff, 0); - // Check if this DC has a DIB behind it... - if (pso->pvScan0) // STYPE_BITMAP == pso->iType - { - ASSERT(pso->lDelta); - Result = XLATEOBJ_iXlate(&exlo.xlo, - DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos)); - } - - EXLATEOBJ_vCleanup(&exlo); - } - } - DC_UnlockDc(dc); - - // If Result is still CLR_INVALID, then the "quick" method above didn't work - if (bInRect && Result == CLR_INVALID) - { - // FIXME: create a 1x1 32BPP DIB, and blit to it - HDC hDCTmp = NtGdiCreateCompatibleDC(hDC); - if (hDCTmp) - { - static const BITMAPINFOHEADER bih = { sizeof(BITMAPINFOHEADER), 1, 1, 1, 32, BI_RGB, 0, 0, 0, 0, 0 }; - BITMAPINFO bi; - RtlMoveMemory(&(bi.bmiHeader), &bih, sizeof(bih)); - hBmpTmp = NtGdiCreateDIBitmapInternal(hDC, - bi.bmiHeader.biWidth, - bi.bmiHeader.biHeight, - 0, - NULL, - &bi, - DIB_RGB_COLORS, - bi.bmiHeader.biBitCount, - bi.bmiHeader.biSizeImage, - 0, - 0); - - //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL); - if (hBmpTmp) - { - HBITMAP hBmpOld = (HBITMAP)NtGdiSelectBitmap(hDCTmp, hBmpTmp); - if (hBmpOld) - { - NtGdiBitBlt(hDCTmp, 0, 0, 1, 1, hDC, XPos, YPos, SRCCOPY, 0, 0); - NtGdiSelectBitmap(hDCTmp, hBmpOld); - - // Our bitmap is no longer selected, so we can access it's stuff... - psurf = SURFACE_ShareLockSurface(hBmpTmp); - if (psurf) - { - // Dont you need to convert something here? - Result = *(COLORREF*)psurf->SurfObj.pvScan0; - SURFACE_ShareUnlockSurface(psurf); - } - } - GreDeleteObject(hBmpTmp); - } - NtGdiDeleteObjectApp(hDCTmp); - } - } - - return Result; -}
VOID FASTCALL @@ -652,116 +555,6 @@
return Ret; } - -VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color) -{ - PDC pdc = NULL; - RGBQUAD quad; - PALETTEENTRY palEntry; - UINT index; - - switch (*Color >> 24) - { - case 0x10: /* DIBINDEX */ - if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1) - { - *Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue); - } - else - { - /* Out of color table bounds - use black */ - *Color = RGB(0, 0, 0); - } - break; - case 0x02: /* PALETTERGB */ - pdc = DC_LockDc(hDC); - if (pdc->dclevel.hpal != NtGdiGetStockObject(DEFAULT_PALETTE)) - { - index = NtGdiGetNearestPaletteIndex(pdc->dclevel.hpal, *Color); - IntGetPaletteEntries(pdc->dclevel.hpal, index, 1, &palEntry); - *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue); - } - else - { - /* Use the pure color */ - *Color = *Color & 0x00FFFFFF; - } - DC_UnlockDc(pdc); - break; - case 0x01: /* PALETTEINDEX */ - pdc = DC_LockDc(hDC); - if (IntGetPaletteEntries(pdc->dclevel.hpal, LOWORD(*Color), 1, &palEntry) == 1) - { - *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue); - } - else - { - /* Index does not exist, use zero index */ - IntGetPaletteEntries(pdc->dclevel.hpal, 0, 1, &palEntry); - *Color = RGB(palEntry.peRed, palEntry.peGreen, palEntry.peBlue); - } - DC_UnlockDc(pdc); - break; - default: - DPRINT("Unsupported color type %d passed\n", *Color >> 24); - break; - } -} - -BOOL APIENTRY -GdiSetPixelV( - HDC hDC, - INT X, - INT Y, - COLORREF Color) -{ - HBRUSH hBrush; - HGDIOBJ OldBrush; - - if ((Color & 0xFF000000) != 0) - { - IntHandleSpecialColorType(hDC, &Color); - } - - hBrush = NtGdiCreateSolidBrush(Color, NULL); - if (hBrush == NULL) - return FALSE; - - OldBrush = NtGdiSelectBrush(hDC, hBrush); - if (OldBrush == NULL) - { - GreDeleteObject(hBrush); - return FALSE; - } - - NtGdiPatBlt(hDC, X, Y, 1, 1, PATCOPY); - NtGdiSelectBrush(hDC, OldBrush); - GreDeleteObject(hBrush); - - return TRUE; -} - -COLORREF APIENTRY -NtGdiSetPixel( - HDC hDC, - INT X, - INT Y, - COLORREF Color) -{ - DPRINT("0 NtGdiSetPixel X %ld Y %ld C %ld\n", X, Y, Color); - - if (GdiSetPixelV(hDC,X,Y,Color)) - { - Color = NtGdiGetPixel(hDC,X,Y); - DPRINT("1 NtGdiSetPixel X %ld Y %ld C %ld\n", X, Y, Color); - return Color; - } - - Color = (COLORREF)CLR_INVALID; - DPRINT("2 NtGdiSetPixel X %ld Y %ld C %ld\n", X, Y, Color); - return Color; -} -
/* Internal Functions */
Modified: trunk/reactos/win32ss/gdi/ntgdi/brush.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/brush.h?r... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/brush.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/brush.h [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -104,7 +104,7 @@
VOID FASTCALL -EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor); +EBRUSHOBJ_vSetSolidRGBColor(EBRUSHOBJ *pebo, COLORREF crColor);
VOID NTAPI @@ -129,6 +129,15 @@ #define BRUSHOBJ_psoPattern(pbo) \ EBRUSHOBJ_psoPattern(CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject))
+ULONG +FORCEINLINE +EBRUSHOBJ_iSetSolidColor(EBRUSHOBJ *pebo, ULONG iSolidColor) +{ + ULONG iOldColor = pebo->BrushObject.iSolidColor; + pebo->BrushObject.iSolidColor = iSolidColor; + return iOldColor; +} + BOOL FASTCALL IntGdiSetBrushOwner(PBRUSH,DWORD); BOOL FASTCALL GreSetBrushOwner(HBRUSH,DWORD);
Modified: trunk/reactos/win32ss/gdi/ntgdi/dcobjs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/dcobjs.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/dcobjs.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/dcobjs.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -51,7 +51,7 @@ { /* ROS HACK, should use surf xlate */ /* Update the eboFill's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr); + EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboFill, pdcattr->crPenClr); }
/* Clear flags */ @@ -97,7 +97,7 @@ if (pdcattr->hpen == StockObjects[DC_PEN]) { /* Update the eboLine's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr); + EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboLine, pdcattr->crPenClr); }
/* Clear flags */ @@ -116,7 +116,7 @@ EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc);
/* Update the eboText's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr); + EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboText, pdcattr->crForegroundClr);
/* Clear flag */ pdcattr->ulDirty_ &= ~DIRTY_TEXT; @@ -132,7 +132,7 @@ EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc);
/* Update the eboBackground's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr); + EBRUSHOBJ_vSetSolidRGBColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
/* Clear flag */ pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;
Copied: trunk/reactos/win32ss/gdi/ntgdi/patblt.c (from r56411, trunk/reactos/win32ss/gdi/ntgdi/bitblt.c) URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/patblt.c?... ============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/patblt.c [iso-8859-1] Thu Apr 26 16:19:22 2012 @@ -885,8 +885,6 @@ return NtGdiMaskBlt(hDC, XLeft, YLeft, Width, Height, 0,0,0,0,0,0,ROP,0); }
-if ((XLeft == 0) && (YLeft == 0) && (Width == 592) && (Height == 362)) __debugbreak(); - dc = DC_LockDc(hDC); if (dc == NULL) {