diff --git a/reactos/subsystems/win32/win32k/dib/dib16bpp.c b/reactos/subsystems/win32/win32k/dib/dib16bpp.c index cdfd666d199..cbc0129903b 100644 --- a/reactos/subsystems/win32/win32k/dib/dib16bpp.c +++ b/reactos/subsystems/win32/win32k/dib/dib16bpp.c @@ -580,8 +580,8 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, register NICEPIXEL32 SrcPixel32; register NICEPIXEL32 DstPixel32; UCHAR Alpha, SrcBpp; - XLATEGDI* XlateGDI; - XLATEOBJ* SrcXlateObj; + EXLATEOBJ *pexlo; + EXLATEOBJ exloDst2Src; DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, @@ -619,14 +619,8 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, return FALSE; } - XlateGDI = ObjToGDI(ColorTranslation, XLATE); - SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); - - if (!SrcXlateObj) - { - DPRINT1("IntEngCreateXlate failed\n"); - return FALSE; - } + pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); + EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0); Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + (DestRect->left << 1)); @@ -679,12 +673,12 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; SrcPixel32.col.alpha = (SrcBpp == 32) ? (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : - BlendFunc.SourceConstantAlpha; + BlendFunc.SourceConstantAlpha; Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst); + DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst); SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); @@ -696,7 +690,7 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, SrcY++; } - if (SrcXlateObj) EngDeleteXlate(SrcXlateObj); + EXLATEOBJ_vCleanup(&exloDst2Src); return TRUE; } diff --git a/reactos/subsystems/win32/win32k/dib/dib8bpp.c b/reactos/subsystems/win32/win32k/dib/dib8bpp.c index 76d387b32ca..cfbdb0a2db8 100644 --- a/reactos/subsystems/win32/win32k/dib/dib8bpp.c +++ b/reactos/subsystems/win32/win32k/dib/dib8bpp.c @@ -401,8 +401,8 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, register NICEPIXEL32 SrcPixel32; register NICEPIXEL16 SrcPixel16; UCHAR Alpha, SrcBpp; - XLATEGDI* XlateGDI; - XLATEOBJ* SrcXlateObj; + EXLATEOBJ exloDst2Src; + EXLATEOBJ* pexlo; DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, @@ -439,14 +439,8 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, return FALSE; } - XlateGDI = ObjToGDI(ColorTranslation, XLATE); - SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); - - if (!SrcXlateObj) - { - DPRINT1("IntEngCreateXlate failed\n"); - return FALSE; - } + pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); + EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0); Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + DestRect->left); @@ -480,7 +474,7 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst); + DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst); SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); @@ -490,8 +484,7 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, SrcY++; } - if (SrcXlateObj) - EngDeleteXlate(SrcXlateObj); + EXLATEOBJ_vCleanup(&exloDst2Src); return TRUE; } diff --git a/reactos/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s b/reactos/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s index f2e08365d1f..fce9f7f84c0 100644 --- a/reactos/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s +++ b/reactos/subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.s @@ -4,7 +4,7 @@ * FILE: subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.c * PURPOSE: ASM optimised 32bpp ColorFill * PROGRAMMERS: Magnus Olsen - * Timo Kreuzer (timo.kreuzer@rectos.org) + * Timo Kreuzer (timo.kreuzer@reactos.org) */ .intel_syntax noprefix diff --git a/reactos/subsystems/win32/win32k/eng/engbrush.c b/reactos/subsystems/win32/win32k/eng/engbrush.c index b489bb509ed..8a4e04212f5 100644 --- a/reactos/subsystems/win32/win32k/eng/engbrush.c +++ b/reactos/subsystems/win32/win32k/eng/engbrush.c @@ -18,54 +18,59 @@ VOID NTAPI EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) { - ULONG iSolidColor; - XLATEOBJ *pxlo; - PSURFACE psurfTrg; + HPALETTE hpal = NULL; ASSERT(pebo); ASSERT(pbrush); ASSERT(pdc); - psurfTrg = pdc->dclevel.pSurface; - - pebo->psurfTrg = psurfTrg; pebo->BrushObject.flColorType = 0; - pebo->pbrush = pbrush; - pebo->flattrs = pbrush->flAttrs; - pebo->crCurrentText = pdc->pdcattr->crForegroundClr; - pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr; pebo->BrushObject.pvRbrush = NULL; + pebo->pbrush = pbrush; pebo->pengbrush = NULL; + pebo->flattrs = pbrush->flAttrs; + + /* Initialize 1 bpp fore and back colors */ + pebo->crCurrentBack = pdc->pdcattr->crBackgroundClr; + pebo->crCurrentText = pdc->pdcattr->crForegroundClr; + + pebo->psurfTrg = pdc->dclevel.pSurface; +// ASSERT(pebo->psurfTrg); // FIXME: some dcs don't have a surface + + if (pebo->psurfTrg) + hpal = pebo->psurfTrg->hDIBPalette; + if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault; + pebo->ppalSurf = PALETTE_ShareLockPalette(hpal); + if (!pebo->ppalSurf) + pebo->ppalSurf = &gpalRGB; if (pbrush->flAttrs & GDIBRUSH_IS_NULL) { + /* NULL brushes don't need a color */ pebo->BrushObject.iSolidColor = 0; } else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID) { /* Set the RGB color */ - pebo->crRealize = pbrush->BrushAttr.lbColor; - pebo->ulRGBColor = pbrush->BrushAttr.lbColor; - - /* Translate the brush color to the target format */ - pxlo = IntCreateBrushXlate(pbrush, psurfTrg, pebo->crCurrentBack); - iSolidColor = XLATEOBJ_iXlate(pxlo, pbrush->BrushAttr.lbColor); - pebo->BrushObject.iSolidColor = iSolidColor; - if (pxlo) - EngDeleteXlate(pxlo); + EBRUSHOBJ_vSetSolidBrushColor(pebo, pbrush->BrushAttr.lbColor); } else { /* This is a pattern brush that needs realization */ pebo->BrushObject.iSolidColor = 0xFFFFFFFF; + + /* Use foreground color of hatch brushes */ + if (pbrush->flAttrs & GDIBRUSH_IS_HATCH) + pebo->crCurrentText = pbrush->BrushAttr.lbColor; } } VOID FASTCALL -EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo) +EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor) { ULONG iSolidColor; + EXLATEOBJ exlo; /* Never use with non-solid brushes */ ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID); @@ -74,11 +79,15 @@ EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo) pebo->crRealize = crColor; pebo->ulRGBColor = crColor; + /* Initialize an XLATEOBJ RGB -> surface */ + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, pebo->ppalSurf, 0, 0, 0); + /* Translate the brush color to the target format */ - iSolidColor = XLATEOBJ_iXlate(pxlo, crColor); + iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); pebo->BrushObject.iSolidColor = iSolidColor; - pebo->BrushObject.iSolidColor = iSolidColor; + /* Clean up the XLATEOBJ */ + EXLATEOBJ_vCleanup(&exlo); } VOID @@ -99,6 +108,9 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo) EngFreeMem(pebo->BrushObject.pvRbrush); pebo->BrushObject.pvRbrush = NULL; } + + if (pebo->ppalSurf != &gpalRGB) + PALETTE_ShareUnlockPalette(pebo->ppalSurf); } VOID @@ -176,53 +188,55 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) { BOOL bResult; PFN_DrvRealizeBrush pfnRealzizeBrush = NULL; - PSURFACE psurfTrg, psurfPattern, psurfMask; + PSURFACE psurfPattern, psurfMask; PPDEVOBJ ppdev = NULL; - XLATEOBJ *pxlo; + EXLATEOBJ exlo; - psurfTrg = pebo->psurfTrg; // FIXME: all EBRUSHOBJs need a surface - if (!psurfTrg) + // FIXME: all EBRUSHOBJs need a surface, see EBRUSHOBJ_vInit + if (!pebo->psurfTrg) { DPRINT1("Pattern brush has no target surface!\n"); return FALSE; } - ppdev = (PPDEVOBJ)psurfTrg->SurfObj.hdev; // FIXME: all SURFACEs need a PDEV + ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev; + + // FIXME: all SURFACEs need a PDEV if (ppdev && bCallDriver) pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush; - if (!pfnRealzizeBrush) - { - pfnRealzizeBrush = EngRealizeBrush; - } - psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern); - if (!psurfPattern) - { - DPRINT1("No pattern, nothing to realize!\n"); - return FALSE; - } + if (!pfnRealzizeBrush) + pfnRealzizeBrush = EngRealizeBrush; + + psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern); + ASSERT(psurfPattern); /* FIXME: implement mask */ psurfMask = NULL; - /* Create xlateobj for the brush */ - pxlo = IntCreateBrushXlate(pebo->pbrush, psurfTrg, pebo->crCurrentBack); + /* Initialize XLATEOBJ for the brush */ + EXLATEOBJ_vInitBrushXlate(&exlo, + pebo->pbrush, + pebo->psurfTrg, + pebo->crCurrentText, + pebo->crCurrentBack); - /* Perform the realization */ + /* Create the realization */ bResult = pfnRealzizeBrush(&pebo->BrushObject, &pebo->psurfTrg->SurfObj, &psurfPattern->SurfObj, psurfMask ? &psurfMask->SurfObj : NULL, - pxlo, + &exlo.xlo, -1); // FIXME: what about hatch brushes? - EngDeleteXlate(pxlo); + /* Cleanup the XLATEOBJ */ + EXLATEOBJ_vCleanup(&exlo); + /* Unlock surfaces */ if (psurfPattern) - SURFACE_UnlockSurface(psurfPattern); - + SURFACE_ShareUnlockSurface(psurfPattern); if (psurfMask) - SURFACE_UnlockSurface(psurfMask); + SURFACE_ShareUnlockSurface(psurfMask); return bResult; } diff --git a/reactos/subsystems/win32/win32k/eng/mouse.c b/reactos/subsystems/win32/win32k/eng/mouse.c index d6c9df6457d..7ee6d3ea1f8 100644 --- a/reactos/subsystems/win32/win32k/eng/mouse.c +++ b/reactos/subsystems/win32/win32k/eng/mouse.c @@ -243,7 +243,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) &pgp->psurfColor->SurfObj, &pgp->psurfMask->SurfObj, NULL, - pgp->XlateObject, + NULL, &rclSurf, (POINTL*)&rclPointer, (POINTL*)&rclPointer, @@ -258,7 +258,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) &pgp->psurfMask->SurfObj, NULL, NULL, - pgp->XlateObject, + NULL, &rclSurf, (POINTL*)&rclPointer, NULL, @@ -273,7 +273,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) &pgp->psurfMask->SurfObj, NULL, NULL, - pgp->XlateObject, + NULL, &rclSurf, (POINTL*)&rclPointer, NULL, @@ -302,10 +302,10 @@ EngSetPointerShape( { PDEVOBJ *ppdev; GDIPOINTER *pgp; - PBYTE Bits; SIZEL Size; LONG lDelta; HBITMAP hbmp; + RECTL rcl; ASSERT(pso); @@ -316,10 +316,6 @@ EngSetPointerShape( if (pgp->psurfColor) { - /* FIXME: let GDI allocate/free memory */ - EngFreeMem(pgp->psurfColor->SurfObj.pvBits); - pgp->psurfColor->SurfObj.pvBits = 0; - EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfColor); pgp->psurfColor = NULL; @@ -327,10 +323,6 @@ EngSetPointerShape( if (pgp->psurfMask) { - /* FIXME: let GDI allocate/free memory */ - EngFreeMem(pgp->psurfMask->SurfObj.pvBits); - pgp->psurfMask->SurfObj.pvBits = 0; - EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); SURFACE_ShareUnlockSurface(pgp->psurfMask); pgp->psurfMask = NULL; @@ -343,12 +335,6 @@ EngSetPointerShape( pgp->psurfSave = NULL; } - if (pgp->XlateObject != NULL) - { - EngDeleteXlate(pgp->XlateObject); - pgp->XlateObject = NULL; - } - /* See if we are being asked to hide the pointer. */ if (psoMask == NULL) { @@ -367,70 +353,15 @@ EngSetPointerShape( pgp->Size.cx = abs(psoMask->lDelta) << 3; pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1; - if (psoColor != NULL) - { - /* FIXME: let GDI allocate/free memory */ - Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE); - if (Bits == NULL) - { - return SPS_ERROR; - } - - memcpy(Bits, psoColor->pvBits, psoColor->cjBits); - - hbmp = EngCreateBitmap(pgp->Size, - psoColor->lDelta, - psoColor->iBitmapFormat, - psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, - Bits); - - pgp->psurfColor = SURFACE_ShareLockSurface(hbmp); - } - else - { - pgp->psurfColor = NULL; - } - Size.cx = pgp->Size.cx; Size.cy = pgp->Size.cy << 1; - Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE); - if (Bits == NULL) - { - return SPS_ERROR; - } - memcpy(Bits, psoMask->pvBits, psoMask->cjBits); + rcl.left = 0; + rcl.top = 0; + rcl.right = Size.cx; + rcl.bottom = Size.cy; - hbmp = EngCreateBitmap(Size, - psoMask->lDelta, - psoMask->iBitmapFormat, - psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, - Bits); - - pgp->psurfMask = SURFACE_ShareLockSurface(hbmp); - - /* Create an XLATEOBJ that will be used for drawing masks. - * FIXME: We should get this in pxlo parameter! */ - if (pxlo == NULL) - { - HPALETTE BWPalette, DestPalette; - ULONG BWColors[] = {0, 0xFFFFFF}; - - BWPalette = EngCreatePalette(PAL_INDEXED, sizeof(BWColors) / sizeof(ULONG), - BWColors, 0, 0, 0); - - DestPalette = ppdev->DevInfo.hpalDefault; - pgp->XlateObject = IntEngCreateXlate(0, 0, - DestPalette, BWPalette); - EngDeletePalette(BWPalette); - } - else - { - pgp->XlateObject = EngAllocMem(0, sizeof(XLATEOBJ), TAG_XLATEOBJ); - memcpy(pgp->XlateObject, pxlo, sizeof(XLATEOBJ)); - } - - /* Create surface for saving the pixels under the cursor. */ + /* Calculate lDelta for our surfaces. */ switch (pso->iBitmapFormat) { case BMF_1BPP: @@ -456,14 +387,71 @@ EngSetPointerShape( break; } + /* Create surface for saving the pixels under the cursor. */ hbmp = EngCreateBitmap(pgp->Size, lDelta, pso->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); - pgp->psurfSave = SURFACE_ShareLockSurface(hbmp); + /* Create a mask surface */ + if (psoMask) + { + EXLATEOBJ exlo; + PPALETTE ppal; + + ppal = PALETTE_LockPalette(ppdev->DevInfo.hpalDefault); + EXLATEOBJ_vInitialize(&exlo, + &gpalMono, + ppal, + 0, + RGB(0xff,0xff,0xff), + RGB(0,0,0)); + + hbmp = EngCreateBitmap(Size, + lDelta, + pso->iBitmapFormat, + 0, + NULL); + pgp->psurfMask = SURFACE_ShareLockSurface(hbmp); + IntEngCopyBits(&pgp->psurfMask->SurfObj, + psoMask, + NULL, + &exlo.xlo, + &rcl, + (POINTL*)&rcl); + + EXLATEOBJ_vCleanup(&exlo); + if (ppal) + PALETTE_UnlockPalette(ppal); + } + else + { + pgp->psurfMask = NULL; + } + + /* Create a color surface */ + if (psoColor) + { + hbmp = EngCreateBitmap(pgp->Size, + lDelta, + pso->iBitmapFormat, + BMF_TOPDOWN | BMF_NOZEROINIT, + NULL); + pgp->psurfColor = SURFACE_ShareLockSurface(hbmp); + IntEngCopyBits(&pgp->psurfColor->SurfObj, + psoColor, + NULL, + pxlo, + &rcl, + (POINTL*)&rcl); + } + else + { + pgp->psurfColor = NULL; + } + if (x != -1) { IntShowMousePointer(ppdev, pso); @@ -475,8 +463,11 @@ EngSetPointerShape( prcl->right = prcl->left + pgp->Size.cx; prcl->bottom = prcl->top + pgp->Size.cy; } - } else if (prcl != NULL) + } + else if (prcl != NULL) + { prcl->left = prcl->top = prcl->right = prcl->bottom = -1; + } return SPS_ACCEPT_NOEXCLUDE; } diff --git a/reactos/subsystems/win32/win32k/eng/xlate.c b/reactos/subsystems/win32/win32k/eng/xlate.c index 11190f16f96..3dde6e231fc 100644 --- a/reactos/subsystems/win32/win32k/eng/xlate.c +++ b/reactos/subsystems/win32/win32k/eng/xlate.c @@ -1,736 +1,880 @@ /* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* $Id$ - * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: GDI Color Translation Functions - * FILE: subsys/win32k/eng/xlate.c - * PROGRAMER: Jason Filby - * REVISION HISTORY: - * 8/20/1999: Created + * FILE: subsystems/win32/win32k/eng/xlate.c + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */ #include +#include + #define NDEBUG #include + +/** Globals *******************************************************************/ + +ULONG giUniqueXlate = 0; +EXLATEOBJ gexloTrivial; +XLATEOBJ* gpxloTrivial = &gexloTrivial.xlo; + +const BYTE gajXlate5to8[32] = +{ 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99,107,115,123, + 132,140,148,156,165,173,181,189,197,206,214,222,231,239,247,255}; + +const BYTE gajXlate6to8[64] = +{ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 52, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, 97,101,105,109,113,117,121,125, +130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190, +194,198,202,207,210,215,219,223,227,231,235,239,243,247,251,255}; + + +/** iXlate functions **********************************************************/ + +ULONG +FASTCALL +EXLATEOBJ_iXlateTrivial(PEXLATEOBJ pexlo, ULONG iColor) +{ + return iColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateToMono(PEXLATEOBJ pexlo, ULONG iColor) +{ + return (iColor == pexlo->xlo.pulXlate[0]); +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateTable(PEXLATEOBJ pexlo, ULONG iColor) +{ + if (iColor >= pexlo->xlo.cEntries) + { + iColor %= pexlo->xlo.cEntries; + } + return pexlo->xlo.pulXlate[iColor]; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy green */ + iNewColor = iColor & 0x00ff00; + + /* Mask red and blue */ + iColor &= 0xff00ff; + + /* Shift and copy red and blue */ + iNewColor |= iColor >> 16; + iNewColor |= iColor << 16; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateRGBto555(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy red */ + iColor <<= 7; + iNewColor = iColor & 0x7C00; + + /* Copy green */ + iColor >>= 13; + iNewColor |= iColor & 0x3E0; + + /* Copy green */ + iColor >>= 13; + iNewColor |= iColor & 0x1F; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateBGRto555(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iColor >>= 3; + iNewColor = iColor & 0x1f; + + /* Copy green */ + iColor >>= 3; + iNewColor |= (iColor & 0x3E0); + + /* Copy red */ + iColor >>= 3; + iNewColor |= (iColor & 0x7C00); + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateRGBto565(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy red */ + iColor <<= 8; + iNewColor = iColor & 0xF800; + + /* Copy green */ + iColor >>= 13; + iNewColor |= iColor & 0x7E0; + + /* Copy green */ + iColor >>= 14; + iNewColor |= iColor & 0x1F; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateBGRto565(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iColor >>= 3; + iNewColor = iColor & 0x1f; + + /* Copy green */ + iColor >>= 2; + iNewColor |= (iColor & 0x7E0); + + /* Copy red */ + iColor >>= 3; + iNewColor |= (iColor & 0xF800); + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateRGBtoPal(PEXLATEOBJ pexlo, ULONG iColor) +{ + return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor); +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate555toRGB(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = gajXlate5to8[iColor & 0x1F] << 16; + + /* Copy green */ + iColor >>= 5; + iNewColor |= gajXlate5to8[iColor & 0x1F] << 8; + + /* Copy red */ + iColor >>= 5; + iNewColor |= gajXlate5to8[iColor & 0x1F]; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate555toBGR(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = gajXlate5to8[iColor & 0x1F]; + + /* Copy green */ + iColor >>= 5; + iNewColor |= gajXlate5to8[iColor & 0x1F] << 8; + + /* Copy red */ + iColor >>= 5; + iNewColor |= gajXlate5to8[iColor & 0x1F] << 16; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate555to565(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = iColor & 0x1f; + + /* Copy red and green */ + iColor <<= 1; + iNewColor |= iColor & 0xFFC0; + + /* Duplicate highest green bit */ + iColor >>= 5; + iNewColor |= (iColor & 0x20); + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate555toPal(PEXLATEOBJ pexlo, ULONG iColor) +{ + iColor = EXLATEOBJ_iXlate555toRGB(pexlo, iColor); + + return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor); +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate565to555(PEXLATEOBJ pxlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = iColor & 0x1f; + + /* Copy red and green */ + iColor >>= 1; + iNewColor |= iColor & 0x7FE0; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate565toRGB(PEXLATEOBJ pexlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = gajXlate5to8[iColor & 0x1F] << 16; + + /* Copy green */ + iColor >>= 5; + iNewColor |= gajXlate6to8[iColor & 0x3F] << 8; + + /* Copy red */ + iColor >>= 6; + iNewColor |= gajXlate5to8[iColor & 0x1F]; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate565toBGR(PEXLATEOBJ pexlo, ULONG iColor) +{ + ULONG iNewColor; + + /* Copy blue */ + iNewColor = gajXlate5to8[iColor & 0x1F]; + + /* Copy green */ + iColor >>= 5; + iNewColor |= gajXlate6to8[iColor & 0x3F] << 8; + + /* Copy blue */ + iColor >>= 6; + iNewColor |= gajXlate5to8[iColor & 0x1F] << 16; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlate565toPal(EXLATEOBJ *pexlo, ULONG iColor) +{ + iColor = EXLATEOBJ_iXlate565toRGB(pexlo, iColor); + + return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor); +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateShiftAndMask(PEXLATEOBJ pexlo, ULONG iColor) +{ + ULONG iNewColor; + + iNewColor = _rotl(iColor, pexlo->ulRedShift) & pexlo->ulRedMask; + iNewColor |= _rotl(iColor, pexlo->ulGreenShift) & pexlo->ulGreenMask; + iNewColor |= _rotl(iColor, pexlo->ulBlueShift) & pexlo->ulBlueMask; + + return iNewColor; +} + +ULONG +FASTCALL +EXLATEOBJ_iXlateBitfieldsToPal(PEXLATEOBJ pexlo, ULONG iColor) +{ + /* Convert bitfields to RGB */ + iColor = EXLATEOBJ_iXlateShiftAndMask(pexlo, iColor); + + /* Return nearest index */ + return PALETTE_ulGetNearestPaletteIndex(pexlo->ppalDst, iColor); +} + + +/** Private Functions *********************************************************/ + +VOID +NTAPI +EXLATEOBJ_vInitTrivial(PEXLATEOBJ pexlo) +{ + pexlo->xlo.iUniq = InterlockedIncrement((LONG*)&giUniqueXlate); + pexlo->xlo.flXlate = XO_TRIVIAL; + pexlo->xlo.iSrcType = PAL_RGB; + pexlo->xlo.iDstType = PAL_RGB; + pexlo->xlo.cEntries = 0; + pexlo->xlo.pulXlate = pexlo->aulXlate; + pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial; + pexlo->ppalSrc = &gpalRGB; + pexlo->ppalDst = &gpalRGB; + pexlo->ppalDstDc = &gpalRGB; + pexlo->hColorTransform = NULL; +} + +VOID +NTAPI +EXLATEOBJ_vInitialize( + PEXLATEOBJ pexlo, + PALETTE *ppalSrc, + PALETTE *ppalDst, + COLORREF crSrcBackColor, + COLORREF crDstBackColor, + COLORREF crDstForeColor) +{ + ULONG cEntries; + ULONG i, ulColor; + + EXLATEOBJ_vInitTrivial(pexlo); + + if (ppalDst == ppalSrc || !ppalSrc || !ppalDst || + ((ppalDst->Mode == PAL_RGB || ppalDst->Mode == PAL_BGR) && + ppalDst->Mode == ppalSrc->Mode)) + { + return; + } + + pexlo->ppalSrc = ppalSrc; + pexlo->ppalDst = ppalDst; + pexlo->xlo.iSrcType = ppalSrc->Mode; + pexlo->xlo.iDstType = ppalDst->Mode; + + /* Chack if both of the pallettes are indexed */ + if (!(ppalSrc->Mode & PAL_INDEXED) || !(ppalDst->Mode & PAL_INDEXED)) + { + /* At least one palette is not indexed, calculate shifts/masks */ + ULONG aulMasksSrc[3], aulMasksDst[3]; + + PALETTE_vGetBitMasks(ppalSrc, aulMasksSrc); + PALETTE_vGetBitMasks(ppalDst, aulMasksDst); + + pexlo->ulRedMask = aulMasksDst[0]; + pexlo->ulGreenMask = aulMasksDst[1]; + pexlo->ulBlueMask = aulMasksDst[2]; + + pexlo->ulRedShift = CalculateShift(aulMasksSrc[0], aulMasksDst[0]); + pexlo->ulGreenShift = CalculateShift(aulMasksSrc[1], aulMasksDst[1]); + pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]); + } + + if (ppalSrc->Mode & PAL_MONOCHROME) + { + /* This is a monochrome palette */ + if (!(ppalDst->Mode & PAL_MONOCHROME)) + { + /* Mono to color, use the dest DC's fore and back color */ + pexlo->pfnXlate = EXLATEOBJ_iXlateTable; + pexlo->xlo.flXlate |= XO_TABLE; + pexlo->xlo.cEntries = 2; + pexlo->xlo.pulXlate[0] = + PALETTE_ulGetNearestIndex(ppalDst, crDstForeColor); + pexlo->xlo.pulXlate[1] = + PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor); + } + } + else if (ppalDst->Mode & PAL_MONOCHROME) + { + pexlo->pfnXlate = EXLATEOBJ_iXlateToMono; + pexlo->xlo.flXlate |= XO_TO_MONO; + pexlo->xlo.cEntries = 1; + + if (ppalSrc->Mode & PAL_INDEXED) + { + pexlo->aulXlate[0] = + PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor); + } + else if (ppalSrc->Mode & PAL_BGR) + { + pexlo->aulXlate[0] = crSrcBackColor; + } + else if (ppalSrc->Mode & PAL_RGB) + { + pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor), + GetGValue(crSrcBackColor), + GetRValue(crSrcBackColor)); + } + else if (ppalSrc->Mode & PAL_BITFIELDS) + { + PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask); + pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask); + pexlo->ulGreenShift = CalculateShift(0xFF00, pexlo->ulGreenMask); + pexlo->ulBlueShift = CalculateShift(0xFF0000, pexlo->ulBlueMask); + + pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor); + } + } + else if (ppalSrc->Mode & PAL_INDEXED) + { + cEntries = ppalSrc->NumColors; + + /* Allocate buffer if needed */ + if (cEntries > 6) + { + pexlo->xlo.pulXlate = EngAllocMem(0, + cEntries * sizeof(ULONG), + TAG_XLATEOBJ); + if (!pexlo->xlo.pulXlate) + { + DPRINT1("Could not allocate pulXlate buffer.\n"); + pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial; + pexlo->xlo.flXlate = XO_TRIVIAL; + return; + } + } + pexlo->xlo.cEntries = cEntries; + + pexlo->pfnXlate = EXLATEOBJ_iXlateTable; + if (ppalDst->Mode & PAL_INDEXED) + { + pexlo->xlo.flXlate |= XO_TABLE; + + for (i = 0; i < cEntries; i++) + { + ulColor = RGB(ppalSrc->IndexedColors[i].peRed, + ppalSrc->IndexedColors[i].peGreen, + ppalSrc->IndexedColors[i].peBlue); + + pexlo->xlo.pulXlate[i] = + PALETTE_ulGetNearestPaletteIndex(ppalDst, ulColor); + + if (pexlo->xlo.pulXlate[i] != i) + pexlo->xlo.flXlate &= ~XO_TRIVIAL; + } + + if (pexlo->xlo.flXlate & XO_TRIVIAL) + { + if (pexlo->xlo.pulXlate != pexlo->aulXlate) + EngFreeMem(pexlo->xlo.pulXlate); + pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial; + pexlo->xlo.flXlate = XO_TRIVIAL; + return; + } + } + else + { + // FIXME: use PALETTE_ulGetNearest + EXLATEOBJ exloTmp = *pexlo; + exloTmp.xlo.pulXlate = exloTmp.aulXlate; + + pexlo->xlo.flXlate |= XO_TABLE; + for (i = 0; i < pexlo->xlo.cEntries; i++) + { + ulColor = RGB(ppalSrc->IndexedColors[i].peRed, + ppalSrc->IndexedColors[i].peGreen, + ppalSrc->IndexedColors[i].peBlue); + pexlo->xlo.pulXlate[i] = + EXLATEOBJ_iXlateShiftAndMask(&exloTmp, ulColor); + } + } + } + else if (ppalSrc->Mode & PAL_RGB) + { + if (ppalDst->Mode & PAL_INDEXED) + pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal; + + else if (ppalDst->Mode & PAL_BGR) + pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR; + + else if (ppalDst->Mode & PAL_RGB16_555) + pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555; + + else if (ppalDst->Mode & PAL_RGB16_565) + pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565; + + else if (ppalDst->Mode & PAL_BITFIELDS) + pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; + } + else if (ppalSrc->Mode & PAL_BGR) + { + if (ppalDst->Mode & PAL_INDEXED) + pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal; + + else if (ppalDst->Mode & PAL_RGB) + /* The inverse function works the same */ + pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR; + + else if (ppalDst->Mode & PAL_RGB16_555) + pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555; + + else if (ppalDst->Mode & PAL_RGB16_565) + pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565; + + else if (ppalDst->Mode & PAL_BITFIELDS) + pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; + } + else if (ppalSrc->Mode & PAL_RGB16_555) + { + if (ppalDst->Mode & PAL_INDEXED) + pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal; + + else if (ppalDst->Mode & PAL_RGB) + pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB; + + else if (ppalDst->Mode & PAL_BGR) + pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR; + + else if (ppalDst->Mode & PAL_RGB16_565) + pexlo->pfnXlate = EXLATEOBJ_iXlate555to565; + + else if (ppalDst->Mode & PAL_BITFIELDS) + pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; + } + else if (ppalSrc->Mode & PAL_RGB16_565) + { + if (ppalDst->Mode & PAL_INDEXED) + pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal; + + else if (ppalDst->Mode & PAL_RGB) + pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB; + + else if (ppalDst->Mode & PAL_BGR) + pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR; + + else if (ppalDst->Mode & PAL_RGB16_555) + pexlo->pfnXlate = EXLATEOBJ_iXlate565to555; + + else if (ppalDst->Mode & PAL_BITFIELDS) + pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; + } + else if (ppalSrc->Mode & PAL_BITFIELDS) + { + if (ppalDst->Mode & PAL_INDEXED) + pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal; + else + pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; + } + + /* Check for a trivial shift and mask operation */ + if (pexlo->pfnXlate == EXLATEOBJ_iXlateShiftAndMask && + !pexlo->ulRedShift && !pexlo->ulGreenShift && !pexlo->ulBlueShift) + { + pexlo->pfnXlate = EXLATEOBJ_iXlateTrivial; + } + + /* Check for trivial xlate */ + if (pexlo->pfnXlate == EXLATEOBJ_iXlateTrivial) + pexlo->xlo.flXlate = XO_TRIVIAL; + else + pexlo->xlo.flXlate &= ~XO_TRIVIAL; +} + +VOID +NTAPI +EXLATEOBJ_vInitXlateFromDCs( + EXLATEOBJ* pexlo, + PDC pdcSrc, + PDC pdcDst) +{ + PSURFACE psurfDst, psurfSrc; + HPALETTE hpalSrc, hpalDst; + PPALETTE ppalSrc, ppalDst, ppalDstDc; + + DPRINT("Enter EXLATEOBJ_vInitXlateFromDCs\n"); + + /* Do basic init */ + EXLATEOBJ_vInitTrivial(pexlo); + + psurfDst = pdcDst->dclevel.pSurface; + psurfSrc = pdcSrc->dclevel.pSurface; + + if (psurfDst == psurfSrc) + { + return; + } + + hpalSrc = psurfSrc->hDIBPalette; + if (!hpalSrc) + hpalSrc = pPrimarySurface->DevInfo.hpalDefault; + + ppalSrc = PALETTE_ShareLockPalette(hpalSrc); + if (!ppalSrc) + return; + + hpalDst = psurfDst->hDIBPalette; + if (!hpalDst) hpalDst = pPrimarySurface->DevInfo.hpalDefault; + + ppalDst = PALETTE_ShareLockPalette(hpalDst); + if (!ppalDst) + { + PALETTE_ShareUnlockPalette(ppalSrc); + return; + } + + ppalDstDc = pdcDst->dclevel.ppal; + ASSERT(ppalDstDc); + + /* KB41464 details how to convert between mono and color */ + if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP) + { + if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP) + { + // HACK!! FIXME: 1bpp DDBs should have gpalMono already! + EXLATEOBJ_vInitialize(pexlo, + ppalSrc, + &gpalMono, + pdcSrc->pdcattr->crBackgroundClr, + pdcDst->pdcattr->crBackgroundClr, + pdcDst->pdcattr->crForegroundClr); + } + } + else if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP && !psurfSrc->hSecure) + { + // HACK!! FIXME: 1bpp DDBs should have gpalMono already! + EXLATEOBJ_vInitialize(pexlo, + &gpalMono, + ppalDst, + 0, + pdcDst->pdcattr->crBackgroundClr, + pdcDst->pdcattr->crForegroundClr); + } + else + { + EXLATEOBJ_vInitialize(pexlo, ppalSrc, ppalDst, 0, 0, 0); + } + + PALETTE_ShareUnlockPalette(ppalDst); + PALETTE_ShareUnlockPalette(ppalSrc); +} + + +VOID +NTAPI +EXLATEOBJ_vInitBrushXlate( + PEXLATEOBJ pexlo, + BRUSH *pbrush, + SURFACE *psurfDst, + COLORREF crForegroundClr, + COLORREF crBackgroundClr) +{ + HPALETTE hpalDst = NULL; + PPALETTE ppalDst, ppalPattern; + + ASSERT(pexlo); + ASSERT(pbrush); + ASSERT(psurfDst); + ASSERT(!(pbrush->flAttrs & (GDIBRUSH_IS_SOLID | GDIBRUSH_IS_NULL))); + + EXLATEOBJ_vInitTrivial(pexlo); + + hpalDst = psurfDst->hDIBPalette; + if (!hpalDst) hpalDst = pPrimarySurface->DevInfo.hpalDefault; + ppalDst = PALETTE_ShareLockPalette(hpalDst); + if (!ppalDst) + { + DPRINT1("No ppalDst!\n"); + return; + } + + SURFACE *psurfPattern = SURFACE_ShareLockSurface(pbrush->hbmPattern); + if (!psurfPattern) + { + PALETTE_ShareUnlockPalette(ppalDst); + return; + } + +#if 0 + if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP) + { + if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP) + { + // HACK!! FIXME: 1bpp DDBs should have gpalMono already! + EXLATEOBJ_vInitialize(pexlo, + ppalSrc, + &gpalMono, + 0, + crBackgroundClr, + crForegroundClr); + } + } + else +#endif + if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP && + !(pbrush->flAttrs & GDIBRUSH_IS_DIB)) + { + /* Special case: 1 bpp pattern, not a DIB brush. */ + if (psurfDst->SurfObj.iBitmapFormat != BMF_1BPP) + { + // HACK!! FIXME: 1bpp DDBs should have gpalMono already! + EXLATEOBJ_vInitialize(pexlo, + &gpalMono, + ppalDst, + 0, + crBackgroundClr, + crForegroundClr); + } + } + else + { + /* Default: use the patterns' palette */ + ppalPattern = PALETTE_LockPalette(psurfPattern->hDIBPalette); + if (ppalPattern) + { + EXLATEOBJ_vInitialize(pexlo, &gpalRGB, ppalDst, 0, 0, 0); + PALETTE_UnlockPalette(ppalPattern); + } + } + + PALETTE_ShareUnlockPalette(ppalDst); + SURFACE_ShareUnlockSurface(psurfPattern); +} + +VOID +NTAPI +EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo) +{ + if (pexlo->xlo.pulXlate != pexlo->aulXlate) + { + EngFreeMem(pexlo->xlo.pulXlate); + } + pexlo->xlo.pulXlate = NULL; +} + VOID InitXlateImpl(VOID) { -} -static __inline ULONG -ShiftAndMask(XLATEGDI *XlateGDI, ULONG Color) -{ - ULONG TranslatedColor; - - if (XlateGDI->RedShift < 0) - TranslatedColor = (Color >> -(XlateGDI->RedShift)) & XlateGDI->RedMask; - else - TranslatedColor = (Color << XlateGDI->RedShift) & XlateGDI->RedMask; - if (XlateGDI->GreenShift < 0) - TranslatedColor |= (Color >> -(XlateGDI->GreenShift)) & XlateGDI->GreenMask; - else - TranslatedColor |= (Color << XlateGDI->GreenShift) & XlateGDI->GreenMask; - if (XlateGDI->BlueShift < 0) - TranslatedColor |= (Color >> -(XlateGDI->BlueShift)) & XlateGDI->BlueMask; - else - TranslatedColor |= (Color << XlateGDI->BlueShift) & XlateGDI->BlueMask; - - return TranslatedColor; + EXLATEOBJ_vInitTrivial(&gexloTrivial); } -static __inline ULONG -ClosestColorMatch(XLATEGDI *XlateGDI, LPPALETTEENTRY SourceColor, - PALETTEENTRY *DestColors, ULONG NumColors) +/** Public DDI Functions ******************************************************/ + +#undef XLATEOBJ_iXlate +ULONG +NTAPI +XLATEOBJ_iXlate(XLATEOBJ *pxlo, ULONG iColor) { - ULONG SourceRed, SourceGreen, SourceBlue; - ULONG cxRed, cxGreen, cxBlue, Rating, BestMatch = 0xFFFFFF; - ULONG CurrentIndex, BestIndex = 0; + PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo; - SourceRed = SourceColor->peRed; - SourceGreen = SourceColor->peGreen; - SourceBlue = SourceColor->peBlue; + if (!pxlo) + return iColor; - for (CurrentIndex = 0; CurrentIndex < NumColors; CurrentIndex++, DestColors++) - { - cxRed = abs((SHORT)SourceRed - (SHORT)DestColors->peRed); - cxRed *= cxRed; - cxGreen = abs((SHORT)SourceGreen - (SHORT)DestColors->peGreen); - cxGreen *= cxGreen; - cxBlue = abs((SHORT)SourceBlue - (SHORT)DestColors->peBlue); - cxBlue *= cxBlue; - - Rating = cxRed + cxGreen + cxBlue; - - if (Rating == 0) - { - /* Exact match */ - BestIndex = CurrentIndex; - break; - } - - if (Rating < BestMatch) - { - BestIndex = CurrentIndex; - BestMatch = Rating; - } - } - - return BestIndex; + /* Call the iXlate function */ + return pexlo->pfnXlate(pexlo, iColor); } -static __inline VOID -BitMasksFromPal(USHORT PalType, PPALETTE Palette, - PULONG RedMask, PULONG BlueMask, PULONG GreenMask) +ULONG +NTAPI +XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut) { - static const union { PALETTEENTRY Color; ULONG Mask; } Red = {{0xFF, 0x00, 0x00}}; - static const union { PALETTEENTRY Color; ULONG Mask; } Green = {{0x00, 0xFF, 0x00}}; - static const union { PALETTEENTRY Color; ULONG Mask; } Blue = {{0x00, 0x00, 0xFF}}; + PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo; + PPALETTE ppal; + INT i; - switch (PalType) - { - case PAL_RGB: - *RedMask = RGB(0xFF, 0x00, 0x00); - *GreenMask = RGB(0x00, 0xFF, 0x00); - *BlueMask = RGB(0x00, 0x00, 0xFF); - break; - case PAL_BGR: - *RedMask = RGB(0x00, 0x00, 0xFF); - *GreenMask = RGB(0x00, 0xFF, 0x00); - *BlueMask = RGB(0xFF, 0x00, 0x00); - break; - case PAL_BITFIELDS: - *RedMask = Palette->RedMask; - *GreenMask = Palette->GreenMask; - *BlueMask = Palette->BlueMask; - break; - case PAL_INDEXED: - *RedMask = Red.Mask; - *GreenMask = Green.Mask; - *BlueMask = Blue.Mask; - break; - } -} - -/* - * Calculate the number of bits Mask must be shift to the left to get a - * 1 in the most significant bit position - */ -static __inline INT -CalculateShift(ULONG Mask) -{ - ULONG Shift = 0; - ULONG LeftmostBit = 1 << (8 * sizeof(ULONG) - 1); - - while (0 == (Mask & LeftmostBit) && Shift < 8 * sizeof(ULONG)) - { - Mask = Mask << 1; - Shift++; - } - - return Shift; -} - -XLATEOBJ* FASTCALL -IntEngCreateXlate(USHORT DestPalType, USHORT SourcePalType, - HPALETTE PaletteDest, HPALETTE PaletteSource) -{ - XLATEOBJ *XlateObj; - XLATEGDI *XlateGDI; - PALETTE *SourcePalGDI = 0; - PALETTE *DestPalGDI = 0; - ULONG SourceRedMask = 0, SourceGreenMask = 0, SourceBlueMask = 0; - ULONG DestRedMask = 0, DestGreenMask = 0, DestBlueMask = 0; - ULONG i; - - ASSERT(SourcePalType || PaletteSource); - ASSERT(DestPalType || PaletteDest); - - XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); - if (XlateGDI == NULL) - { - DPRINT1("Failed to allocate memory for a XLATE structure!\n"); - return NULL; - } - XlateObj = GDIToObj(XlateGDI, XLATE); - - if (PaletteSource != NULL) - SourcePalGDI = PALETTE_LockPalette(PaletteSource); - if (PaletteDest == PaletteSource) - DestPalGDI = SourcePalGDI; - else if (PaletteDest != NULL) - DestPalGDI = PALETTE_LockPalette(PaletteDest); - - if (SourcePalType == 0) - { - if (!SourcePalGDI) - { - DPRINT1("Failed to lock source palette %p\n", PaletteSource); - return NULL; - } - SourcePalType = SourcePalGDI->Mode; - } - if (DestPalType == 0) - { - if (!DestPalGDI) - { - DPRINT1("Failed to lock dest palette %p\n", PaletteDest); - return NULL; - } - DestPalType = DestPalGDI->Mode; - } - - XlateObj->iSrcType = SourcePalType; - XlateObj->iDstType = DestPalType; - XlateObj->flXlate = 0; - XlateObj->cEntries = 0; - - /* Store handles of palettes in internal Xlate GDI object (or NULLs) */ - XlateGDI->SourcePal = PaletteSource; - XlateGDI->DestPal = PaletteDest; - - XlateGDI->UseShiftAndMask = FALSE; - - /* - * Compute bit fiddeling constants unless both palettes are indexed, then - * we don't need them. - */ - if (SourcePalType != PAL_INDEXED || DestPalType != PAL_INDEXED) - { - BitMasksFromPal(SourcePalType, SourcePalGDI, &SourceRedMask, - &SourceBlueMask, &SourceGreenMask); - BitMasksFromPal(DestPalType, DestPalGDI, &DestRedMask, - &DestBlueMask, &DestGreenMask); - XlateGDI->RedShift = CalculateShift(SourceRedMask) - CalculateShift(DestRedMask); - XlateGDI->RedMask = DestRedMask; - XlateGDI->GreenShift = CalculateShift(SourceGreenMask) - CalculateShift(DestGreenMask); - XlateGDI->GreenMask = DestGreenMask; - XlateGDI->BlueShift = CalculateShift(SourceBlueMask) - CalculateShift(DestBlueMask); - XlateGDI->BlueMask = DestBlueMask; - } - - /* If source and destination palettes are the same or if they're RGB/BGR */ - if (PaletteDest == PaletteSource || - (DestPalType == PAL_RGB && SourcePalType == PAL_RGB) || - (DestPalType == PAL_BGR && SourcePalType == PAL_BGR)) - { - XlateObj->flXlate |= XO_TRIVIAL; - goto end; - } - - /* - * If source and destination are bitfield based (RGB and BGR are just - * special bitfields) we can use simple shifting. - */ - if ((DestPalType == PAL_RGB || DestPalType == PAL_BGR || - DestPalType == PAL_BITFIELDS) && - (SourcePalType == PAL_RGB || SourcePalType == PAL_BGR || - SourcePalType == PAL_BITFIELDS)) - { - if (SourceRedMask == DestRedMask && - SourceBlueMask == DestBlueMask && - SourceGreenMask == DestGreenMask) - { - XlateObj->flXlate |= XO_TRIVIAL; - } - XlateGDI->UseShiftAndMask = TRUE; - goto end; - } - - /* Indexed -> Indexed */ - if (SourcePalType == PAL_INDEXED && DestPalType == PAL_INDEXED) - { - XlateObj->cEntries = SourcePalGDI->NumColors; - XlateObj->pulXlate = - EngAllocMem(0, sizeof(ULONG) * XlateObj->cEntries, TAG_XLATEOBJ); - - XlateObj->flXlate |= XO_TRIVIAL; - for (i = 0; i < XlateObj->cEntries; i++) - { - XlateObj->pulXlate[i] = ClosestColorMatch( - XlateGDI, SourcePalGDI->IndexedColors + i, - DestPalGDI->IndexedColors, DestPalGDI->NumColors); - if (XlateObj->pulXlate[i] != i) - XlateObj->flXlate &= ~XO_TRIVIAL; - } - - XlateObj->flXlate |= XO_TABLE; - goto end; - } - - /* Indexed -> Bitfields/RGB/BGR */ - if (SourcePalType == PAL_INDEXED) - { - XlateObj->cEntries = SourcePalGDI->NumColors; - XlateObj->pulXlate = - EngAllocMem(0, sizeof(ULONG) * XlateObj->cEntries, TAG_XLATEOBJ); - for (i = 0; i < XlateObj->cEntries; i++) - XlateObj->pulXlate[i] = - ShiftAndMask(XlateGDI, *((ULONG *)&SourcePalGDI->IndexedColors[i])); - XlateObj->flXlate |= XO_TABLE; - goto end; - } - - /* - * Last case: Bitfields/RGB/BGR -> Indexed - * isn't handled here yet and all the logic is in XLATEOBJ_iXlate now. - */ - -end: - if (PaletteDest != NULL) - if (PaletteDest != PaletteSource) - if (DestPalGDI != NULL) - PALETTE_UnlockPalette(DestPalGDI); - - - if (PaletteSource != NULL) - PALETTE_UnlockPalette(SourcePalGDI); - - return XlateObj; -} - -XLATEOBJ* FASTCALL -IntEngCreateMonoXlate( - USHORT SourcePalType, HPALETTE PaletteDest, HPALETTE PaletteSource, - ULONG BackgroundColor) -{ - XLATEOBJ *XlateObj; - XLATEGDI *XlateGDI; - PALETTE *SourcePalGDI; - - XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); - if (XlateGDI == NULL) - { - DPRINT1("Failed to allocate memory for a XLATE structure!\n"); - return NULL; - } - XlateObj = GDIToObj(XlateGDI, XLATE); - - SourcePalGDI = PALETTE_LockPalette(PaletteSource); - /* FIXME - SourcePalGDI can be NULL!!! Handle this case instead of ASSERT! */ - ASSERT(SourcePalGDI); - - if (SourcePalType == 0) - SourcePalType = SourcePalGDI->Mode; - - XlateObj->iSrcType = SourcePalType; - XlateObj->iDstType = PAL_INDEXED; - - /* Store handles of palettes in internal Xlate GDI object (or NULLs) */ - XlateGDI->DestPal = PaletteDest; - XlateGDI->SourcePal = PaletteSource; - - XlateObj->flXlate = XO_TO_MONO; - XlateObj->cEntries = 1; - XlateObj->pulXlate = &XlateGDI->BackgroundColor; - switch (SourcePalType) - { - case PAL_INDEXED: - XlateGDI->BackgroundColor = NtGdiGetNearestPaletteIndex( - PaletteSource, BackgroundColor); - break; - case PAL_BGR: - XlateGDI->BackgroundColor = BackgroundColor; - break; - case PAL_RGB: - XlateGDI->BackgroundColor = - ((BackgroundColor & 0xFF) << 16) | - ((BackgroundColor & 0xFF0000) >> 16) | - (BackgroundColor & 0xFF00); - break; - case PAL_BITFIELDS: - { - BitMasksFromPal(SourcePalType, SourcePalGDI, &XlateGDI->RedMask, - &XlateGDI->BlueMask, &XlateGDI->GreenMask); - XlateGDI->RedShift = CalculateShift(0xFF) - CalculateShift(XlateGDI->RedMask); - XlateGDI->GreenShift = CalculateShift(0xFF00) - CalculateShift(XlateGDI->GreenMask); - XlateGDI->BlueShift = CalculateShift(0xFF0000) - CalculateShift(XlateGDI->BlueMask); - XlateGDI->BackgroundColor = ShiftAndMask(XlateGDI, BackgroundColor); - } - break; - } - - PALETTE_UnlockPalette(SourcePalGDI); - - return XlateObj; -} - -XLATEOBJ* FASTCALL -IntEngCreateSrcMonoXlate(HPALETTE PaletteDest, - ULONG Color0, - ULONG Color1) -{ - XLATEOBJ *XlateObj; - XLATEGDI *XlateGDI; - PALETTE *DestPalGDI; - - DestPalGDI = PALETTE_LockPalette(PaletteDest); - if (DestPalGDI == NULL) - return NULL; - - XlateGDI = EngAllocMem(0, sizeof(XLATEGDI), TAG_XLATEOBJ); - if (XlateGDI == NULL) - { - PALETTE_UnlockPalette(DestPalGDI); - DPRINT1("Failed to allocate memory for a XLATE structure!\n"); - return NULL; - } - XlateObj = GDIToObj(XlateGDI, XLATE); - - XlateObj->cEntries = 2; - XlateObj->pulXlate = EngAllocMem(0, sizeof(ULONG) * XlateObj->cEntries, TAG_XLATEOBJ); - if (XlateObj->pulXlate == NULL) - { - PALETTE_UnlockPalette(DestPalGDI); - EngFreeMem(XlateGDI); - return NULL; - } - - XlateObj->iSrcType = PAL_INDEXED; - XlateObj->iDstType = DestPalGDI->Mode; - - /* Store handles of palettes in internal Xlate GDI object (or NULLs) */ - XlateGDI->SourcePal = NULL; - XlateGDI->DestPal = PaletteDest; - - XlateObj->flXlate = XO_TABLE; - - BitMasksFromPal(DestPalGDI->Mode, DestPalGDI, &XlateGDI->RedMask, - &XlateGDI->BlueMask, &XlateGDI->GreenMask); - - XlateGDI->RedShift = CalculateShift(RGB(0xFF, 0x00, 0x00)) - CalculateShift(XlateGDI->RedMask); - XlateGDI->GreenShift = CalculateShift(RGB(0x00, 0xFF, 0x00)) - CalculateShift(XlateGDI->GreenMask); - XlateGDI->BlueShift = CalculateShift(RGB(0x00, 0x00, 0xFF)) - CalculateShift(XlateGDI->BlueMask); - - /* Yes, that's how Windows works, ... */ - XlateObj->pulXlate[1] = ShiftAndMask(XlateGDI, Color1); - XlateObj->pulXlate[0] = ShiftAndMask(XlateGDI, Color0); - - if (XlateObj->iDstType == PAL_INDEXED) - { - XlateObj->pulXlate[0] = - ClosestColorMatch(XlateGDI, - (LPPALETTEENTRY)&XlateObj->pulXlate[0], - DestPalGDI->IndexedColors, - DestPalGDI->NumColors); - XlateObj->pulXlate[1] = - ClosestColorMatch(XlateGDI, - (LPPALETTEENTRY)&XlateObj->pulXlate[1], - DestPalGDI->IndexedColors, - DestPalGDI->NumColors); - } - - PALETTE_UnlockPalette(DestPalGDI); - - return XlateObj; -} - -HPALETTE FASTCALL -IntEngGetXlatePalette(XLATEOBJ *XlateObj, - ULONG Palette) -{ - XLATEGDI *XlateGDI = ObjToGDI(XlateObj, XLATE); - switch (Palette) - { - case XO_DESTPALETTE: - return XlateGDI->DestPal; - break; - - case XO_SRCPALETTE: - return XlateGDI->SourcePal; - break; - } - return 0; -} - -XLATEOBJ* -FASTCALL -IntCreateXlateForBlt(PDC pDCDest, PDC pDCSrc, SURFACE* psurfDest, SURFACE* psurfSrc) -{ - XLATEOBJ *XlateObj; - HPALETTE DestPalette, SourcePalette; - PDC_ATTR pdcattr; - - DPRINT("Enter IntCreateXlateFromDCs\n"); - - if (psurfDest == psurfSrc) - { - return NULL; - } - - DestPalette = psurfDest->hDIBPalette; - if (!DestPalette) DestPalette = pPrimarySurface->DevInfo.hpalDefault; - - SourcePalette = psurfSrc->hDIBPalette; - if (!SourcePalette) SourcePalette = pPrimarySurface->DevInfo.hpalDefault; - - DPRINT("DestPalette = %p, SourcePalette = %p, DefaultPatelle = %p\n", DestPalette, SourcePalette, NtGdiGetStockObject((INT)DEFAULT_PALETTE)); - - /* KB41464 details how to convert between mono and color */ - if (psurfDest->SurfObj.iBitmapFormat == BMF_1BPP) - { - if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP) - { - XlateObj = NULL; - } - else - { - pdcattr = pDCSrc->pdcattr; - XlateObj = IntEngCreateMonoXlate(0, DestPalette, SourcePalette, pdcattr->crBackgroundClr); - } - } - else - { - if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP) - { - /* DIB sections need special handling */ - if (psurfSrc->hSecure) - { - PPALETTE ppal = PALETTE_LockPalette(psurfSrc->hDIBPalette); - if (ppal) - { - XlateObj = IntEngCreateSrcMonoXlate(DestPalette, ((ULONG*)ppal->IndexedColors)[0], ((ULONG*)ppal->IndexedColors)[1]); - PALETTE_UnlockPalette(ppal); - } - else - XlateObj = NULL; - } - else - { - pdcattr = pDCDest->pdcattr; - XlateObj = IntEngCreateSrcMonoXlate(DestPalette, pdcattr->crForegroundClr, pdcattr->crBackgroundClr); - } - } - else - { - XlateObj = IntEngCreateXlate(0, 0, DestPalette, SourcePalette); - } - if (!XlateObj) - { - return (XLATEOBJ*)-1; - } - } - return XlateObj; -} - -/* PUBLIC FUNCTIONS ***********************************************************/ - -/* - * @implemented /// this is not a public function! - */ -VOID FASTCALL -EngDeleteXlate(XLATEOBJ *XlateObj) -{ - XLATEGDI *XlateGDI; - - if (XlateObj == NULL) - { - DPRINT1("Trying to delete NULL XLATEOBJ\n"); - return; - } - - XlateGDI = ObjToGDI(XlateObj, XLATE); - - if (!XlateGDI) return; - - if ((XlateObj->flXlate & XO_TABLE) && - XlateObj->pulXlate != NULL) - { - EngFreeMem(XlateObj->pulXlate); - } - - EngFreeMem(XlateGDI); -} - -/* - * @implemented - */ -PULONG APIENTRY -XLATEOBJ_piVector(XLATEOBJ *XlateObj) -{ - if (XlateObj->iSrcType == PAL_INDEXED) - { - return XlateObj->pulXlate; - } - - return NULL; -} - -/* - * @implemented - */ -ULONG APIENTRY -XLATEOBJ_iXlate(XLATEOBJ *XlateObj, ULONG Color) -{ - XLATEGDI *XlateGDI; - PALETTE *PalGDI; - ULONG Closest; - - /* Return the original color if there's no color translation object. */ - if (!XlateObj) - return Color; - - if (XlateObj->flXlate & XO_TRIVIAL) - return Color; - - if (XlateObj->flXlate & XO_TABLE) - { - if (Color >= XlateObj->cEntries) - Color %= XlateObj->cEntries; - - return XlateObj->pulXlate[Color]; - } - - - if (XlateObj->flXlate & XO_TO_MONO) - return Color == XlateObj->pulXlate[0]; - - XlateGDI = ObjToGDI(XlateObj, XLATE); - - if (XlateGDI->UseShiftAndMask) - return ShiftAndMask(XlateGDI, Color); - - if (XlateObj->iSrcType == PAL_RGB || XlateObj->iSrcType == PAL_BGR || - XlateObj->iSrcType == PAL_BITFIELDS) - { - /* FIXME: should we cache colors used often? */ - /* FIXME: won't work if destination isn't indexed */ - - /* Convert the source color to the palette RGB format. */ - Color = ShiftAndMask(XlateGDI, Color); - - /* Extract the destination palette. */ - PalGDI = PALETTE_LockPalette(XlateGDI->DestPal); - if(PalGDI != NULL) - { - /* Return closest match for the given color. */ - Closest = ClosestColorMatch(XlateGDI, (LPPALETTEENTRY)&Color, PalGDI->IndexedColors, PalGDI->NumColors); - PALETTE_UnlockPalette(PalGDI); - return Closest; - } - } - - return 0; -} - -/* - * @implemented - */ -ULONG APIENTRY -XLATEOBJ_cGetPalette(XLATEOBJ *XlateObj, ULONG PalOutType, ULONG cPal, - ULONG *OutPal) -{ - HPALETTE hPalette; - XLATEGDI *XlateGDI; - PALETTE *PalGDI; - ULONG *InPal; - - XlateGDI = ObjToGDI(XlateObj, XLATE); - if (PalOutType == XO_SRCPALETTE) - hPalette = XlateGDI->SourcePal; - else if (PalOutType == XO_DESTPALETTE) - hPalette = XlateGDI->DestPal; - else - { - UNIMPLEMENTED; - return 0; + if (!pxlo) + { + return 0; } - PalGDI = PALETTE_LockPalette(hPalette); - if(PalGDI != NULL) - { - /* copy the indexed colors into the buffer */ - - for(InPal = (ULONG*)PalGDI->IndexedColors; - cPal > 0; - cPal--, InPal++, OutPal++) - { - *OutPal = *InPal; - } - - PALETTE_UnlockPalette(PalGDI); - - return cPal; - } - - return 0; -} - -/* - * @unimplemented - */ -HANDLE APIENTRY -XLATEOBJ_hGetColorTransform( - IN XLATEOBJ *XlateObj) -{ - UNIMPLEMENTED; - return NULL; -} - -// HACK! -XLATEOBJ* -IntCreateBrushXlate(BRUSH *pbrush, SURFACE * psurf, COLORREF crBackgroundClr) -{ - XLATEOBJ *pxlo = NULL; - HPALETTE hPalette = NULL; - - if (psurf) + if (iPal > 5) { - hPalette = psurf->hDIBPalette; + DPRINT1("XLATEOBJ_cGetPalette called with wrong iPal: %d\n", iPal); + return 0; } - if (!hPalette) hPalette = pPrimarySurface->DevInfo.hpalDefault; - if (pbrush->flAttrs & GDIBRUSH_IS_NULL) + /* Get the requested palette */ + if (iPal == XO_DESTDCPALETTE) { - pxlo = NULL; + ppal = pexlo->ppalDstDc; } - else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID) + else if (iPal == XO_SRCPALETTE || iPal == XO_SRCBITFIELDS) { - pxlo = IntEngCreateXlate(0, PAL_RGB, hPalette, NULL); + ppal = pexlo->ppalSrc; } else { - SURFACE *psurfPattern = SURFACE_LockSurface(pbrush->hbmPattern); - if (psurfPattern == NULL) - return FALSE; - - /* Special case: 1bpp pattern */ - if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP) - { - pxlo = IntEngCreateSrcMonoXlate(hPalette, - crBackgroundClr, - pbrush->BrushAttr.lbColor); - } - else if (pbrush->flAttrs & GDIBRUSH_IS_DIB) - { - pxlo = IntEngCreateXlate(0, 0, hPalette, psurfPattern->hDIBPalette); - } - - SURFACE_UnlockSurface(psurfPattern); + ppal = pexlo->ppalDst; } - return pxlo; + /* Verify palette type match */ + if (!ppal || + ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE) + && !(ppal->Mode & PAL_INDEXED)) || + ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS) + && !(ppal->Mode & PAL_BITFIELDS))) + { + return 0; + } + + if(!pPalOut) + { + return ppal->NumColors; + } + + /* Copy the values into the buffer */ + if (ppal->Mode & PAL_INDEXED) + { + cPal = min(cPal, ppal->NumColors); + for (i = 0; i < cPal; i++) + { + pPalOut[i] = RGB(ppal->IndexedColors[i].peRed, + ppal->IndexedColors[i].peGreen, + ppal->IndexedColors[i].peBlue); + } + } + else + { + // FIXME: should use the above code + pPalOut[0] = ppal->RedMask; + pPalOut[1] = ppal->GreenMask; + pPalOut[2] = ppal->BlueMask; + } + + return cPal; } +HANDLE +NTAPI +XLATEOBJ_hGetColorTransform(XLATEOBJ *pxlo) +{ + PEXLATEOBJ pexlo = (PEXLATEOBJ)pxlo; + return pexlo->hColorTransform; +} + +PULONG +NTAPI +XLATEOBJ_piVector(XLATEOBJ *pxlo) +{ + if (pxlo->iSrcType == PAL_INDEXED) + { + return pxlo->pulXlate; + } + + return NULL; +} /* EOF */ diff --git a/reactos/subsystems/win32/win32k/include/brush.h b/reactos/subsystems/win32/win32k/include/brush.h index 6bb2ad30de0..2541fb9b23b 100644 --- a/reactos/subsystems/win32/win32k/include/brush.h +++ b/reactos/subsystems/win32/win32k/include/brush.h @@ -58,7 +58,7 @@ typedef struct _EBRUSHOBJ // DWORD dwUnknown2c; // DWORD dwUnknown30; SURFACE * psurfTrg; -// PALETTE * ppalSurf; + struct _PALETTE * ppalSurf; // PALETTE * ppalDC; // PALETTE * ppal3; // DWORD dwUnknown44; @@ -110,7 +110,7 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *); VOID FASTCALL -EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo); +EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor); VOID NTAPI diff --git a/reactos/subsystems/win32/win32k/include/engobjects.h b/reactos/subsystems/win32/win32k/include/engobjects.h index 8c92f1a0f30..a924fc1148d 100644 --- a/reactos/subsystems/win32/win32k/include/engobjects.h +++ b/reactos/subsystems/win32/win32k/include/engobjects.h @@ -102,27 +102,6 @@ typedef struct _XFORMGDI { /* XFORMOBJ has no public members */ } XFORMGDI; -typedef struct _XLATEGDI { - XLATEOBJ XlateObj; - HPALETTE DestPal; - HPALETTE SourcePal; - BOOL UseShiftAndMask; - -// union { -// struct { /* For Shift Translations */ - ULONG RedMask; - ULONG GreenMask; - ULONG BlueMask; - INT RedShift; - INT GreenShift; - INT BlueShift; -// }; -// struct { /* For Color -> Mono Translations */ - ULONG BackgroundColor; -// }; -// }; -} XLATEGDI; - /* as the *OBJ structures are located at the beginning of the *GDI structures we can simply typecast the pointer */ #define ObjToGDI(ClipObj, Type) (Type##GDI *)(ClipObj) diff --git a/reactos/subsystems/win32/win32k/include/palette.h b/reactos/subsystems/win32/win32k/include/palette.h index 0509c468dbe..102654573fe 100644 --- a/reactos/subsystems/win32/win32k/include/palette.h +++ b/reactos/subsystems/win32/win32k/include/palette.h @@ -49,10 +49,13 @@ typedef struct _PALETTE ULONG RedMask; ULONG GreenMask; ULONG BlueMask; + ULONG ulRedShift; + ULONG ulGreenShift; + ULONG ulBlueShift; HDEV hPDev; } PALETTE, *PPALETTE; -extern PALETTE gpalRGB, gpalBGR; +extern PALETTE gpalRGB, gpalBGR, gpalMono; HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, @@ -84,11 +87,24 @@ INT FASTCALL PALETTE_ToPhysical (PDC dc, COLORREF color); INT FASTCALL PALETTE_GetObject(PPALETTE pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer); ULONG NTAPI PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor); +ULONG NTAPI PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG iColor); VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors); PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); HPALETTE FASTCALL GdiSelectPalette(HDC, HPALETTE, BOOL); +ULONG +FORCEINLINE +CalculateShift(ULONG ulMask1, ULONG ulMask2) +{ + ULONG ulShift1, ulShift2; + BitScanReverse(&ulShift1, ulMask1); + BitScanReverse(&ulShift2, ulMask2); + ulShift2 -= ulShift1; + if ((INT)ulShift2 < 0) ulShift2 += 32; + return ulShift2; +} + FORCEINLINE ULONG PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex) diff --git a/reactos/subsystems/win32/win32k/include/win32k.h b/reactos/subsystems/win32/win32k/include/win32k.h index d924ba2abf2..4cd9e7b5720 100644 --- a/reactos/subsystems/win32/win32k/include/win32k.h +++ b/reactos/subsystems/win32/win32k/include/win32k.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/reactos/subsystems/win32/win32k/include/xlateobj.h b/reactos/subsystems/win32/win32k/include/xlateobj.h new file mode 100644 index 00000000000..a2ffedb7615 --- /dev/null +++ b/reactos/subsystems/win32/win32k/include/xlateobj.h @@ -0,0 +1,52 @@ + /* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: XLATEOBJ structures and functions + * FILE: subsystem/win32/win32k/eng/objects.h + * PROGRAMER: Timo Kreuzer + * + */ + +#include + +struct _EXLATEOBJ; + +typedef ULONG (FASTCALL *PFN_XLATE)(struct _EXLATEOBJ *pexlo, ULONG iColor); + +typedef struct _EXLATEOBJ +{ + XLATEOBJ xlo; + + PFN_XLATE pfnXlate; + + PPALETTE ppalSrc; + PPALETTE ppalDst; + PPALETTE ppalDstDc; + + HANDLE hColorTransform; + + union + { + ULONG aulXlate[6]; + struct + { + ULONG ulRedMask; + ULONG ulGreenMask; + ULONG ulBlueMask; + ULONG ulRedShift; + ULONG ulGreenShift; + ULONG ulBlueShift; + }; + }; +} EXLATEOBJ, *PEXLATEOBJ; + +void +DbgCmpXlate(XLATEOBJ *pxlo1, XLATEOBJ *pxlo2); + +VOID NTAPI EXLATEOBJ_vInitialize(PEXLATEOBJ pexlo, PALETTE *ppalSrc, PALETTE *ppalDst, ULONG, ULONG, ULONG); +VOID NTAPI EXLATEOBJ_vInitXlateFromDCs(PEXLATEOBJ pexlo, PDC pdcSrc, PDC pdcDst); +VOID NTAPI EXLATEOBJ_vInitBrushXlate(PEXLATEOBJ pexlo, BRUSH *pbrush, SURFACE *psurf, COLORREF crForegroundClr, COLORREF crBackgroundClr); +VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(PEXLATEOBJ pexlo, PPALETTE ppalDst, ULONG Color0, ULONG Color1); +VOID NTAPI EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo); + +//#define XLATEOBJ_iXlate(pxo, Color) ((EXLATEOBJ*)pxo)->pfnXlate(pxo, Color) diff --git a/reactos/subsystems/win32/win32k/misc/file.c b/reactos/subsystems/win32/win32k/misc/file.c index d21a735d658..263ed12e0b7 100644 --- a/reactos/subsystems/win32/win32k/misc/file.c +++ b/reactos/subsystems/win32/win32k/misc/file.c @@ -158,10 +158,11 @@ typedef struct tagBITMAPV5INFO // FIXME: this should go to dibobj.c NTSTATUS ProbeAndConvertBitmapInfo( - OUT PBITMAPV5INFO pbmiDst, + OUT BITMAPV5HEADER *pbmhDst, + OUT RGBQUAD *pbmiColorsDst, + ULONG cColors, IN PBITMAPINFO pbmiUnsafe) { - BITMAPV5HEADER *pbmhDst = (BITMAPV5HEADER*)&pbmiDst->bmiHeader; DWORD dwSize; RGBQUAD *pbmiColors; ULONG ulWidthBytes; @@ -280,6 +281,10 @@ ProbeAndConvertBitmapInfo( return STATUS_INVALID_PARAMETER; } + /* Copy Colors */ + cColors = min(cColors, pbmhDst->bV5ClrUsed); + memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD)); + return STATUS_SUCCESS; } @@ -320,7 +325,10 @@ UserLoadImage(PCWSTR pwszName) /* Create a normalized local BITMAPINFO */ _SEH2_TRY { - Status = ProbeAndConvertBitmapInfo(&bmiLocal, pbmi); + Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader, + bmiLocal.bmiColors, + 256, + pbmi); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { diff --git a/reactos/subsystems/win32/win32k/ntuser/windc.c b/reactos/subsystems/win32/win32k/ntuser/windc.c index fffe387d368..a78cdb20189 100644 --- a/reactos/subsystems/win32/win32k/ntuser/windc.c +++ b/reactos/subsystems/win32/win32k/ntuser/windc.c @@ -869,7 +869,7 @@ UserGetWindowDC(PWINDOW_OBJECT Wnd) HWND FASTCALL UserGethWnd( HDC hdc, PWNDOBJ *pwndo) { - PWNDGDI pWndgdi; + PWNDGDI pWndgdi = NULL; PWINDOW_OBJECT Wnd = NULL; HWND hWnd; BOOL Hit = FALSE; diff --git a/reactos/subsystems/win32/win32k/objects/bitblt.c b/reactos/subsystems/win32/win32k/objects/bitblt.c index 82b5c18443b..a0e04df124a 100644 --- a/reactos/subsystems/win32/win32k/objects/bitblt.c +++ b/reactos/subsystems/win32/win32k/objects/bitblt.c @@ -44,8 +44,8 @@ NtGdiAlphaBlend( PDC DCSrc; SURFACE *BitmapDest, *BitmapSrc; RECTL DestRect, SourceRect; - BOOL Status; - XLATEOBJ *XlateObj; + BOOL bResult; + EXLATEOBJ exlo; BLENDOBJ BlendObj; BlendObj.BlendFunction = BlendFunc; @@ -147,31 +147,23 @@ NtGdiAlphaBlend( } /* Create the XLATEOBJ. */ - XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); + EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); - if (XlateObj == (XLATEOBJ*)-1) - { - DPRINT1("couldn't create XlateObj\n"); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - XlateObj = NULL; - Status = FALSE; - } - else - { - /* Perform the alpha blend operation */ - Status = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, - DCDest->rosdc.CombinedClip, XlateObj, - &DestRect, &SourceRect, &BlendObj); - } - - if (XlateObj != NULL) - EngDeleteXlate(XlateObj); + /* Perform the alpha blend operation */ + bResult = IntEngAlphaBlend(&BitmapDest->SurfObj, + &BitmapSrc->SurfObj, + DCDest->rosdc.CombinedClip, + &exlo.xlo, + &DestRect, + &SourceRect, + &BlendObj); + EXLATEOBJ_vCleanup(&exlo); DC_UnlockDc(DCDest); if (hDCSrc != hDCDest) DC_UnlockDc(DCSrc); - return Status; + return bResult; } BOOL APIENTRY @@ -195,6 +187,7 @@ NtGdiBitBlt( RECTL DestRect; POINTL SourcePoint; BOOL Status = FALSE; + EXLATEOBJ exlo; XLATEOBJ *XlateObj = NULL; BOOL UsesSource = ROP3_USES_SOURCE(ROP); @@ -281,15 +274,8 @@ NtGdiBitBlt( /* Create the XLATEOBJ. */ if (UsesSource) { - XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); - - if (XlateObj == (XLATEOBJ*)-1) - { - DPRINT1("couldn't create XlateObj\n"); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - XlateObj = NULL; - goto cleanup; - } + EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); + XlateObj = &exlo.xlo; } /* Perform the bitblt operation */ @@ -306,9 +292,8 @@ NtGdiBitBlt( ROP3_TO_ROP4(ROP)); cleanup: - if (UsesSource && XlateObj != NULL) - EngDeleteXlate(XlateObj); - + if (UsesSource) + EXLATEOBJ_vCleanup(&exlo); if (UsesSource && hDCSrc != hDCDest) { DC_UnlockDc(DCSrc); @@ -335,12 +320,12 @@ NtGdiTransparentBlt( PDC DCDest, DCSrc; RECTL rcDest, rcSrc; SURFACE *BitmapDest, *BitmapSrc = NULL; - XLATEOBJ *XlateObj = NULL; HPALETTE SourcePalette = 0, DestPalette = 0; PPALETTE PalDestGDI, PalSourceGDI; USHORT PalDestMode, PalSrcMode; ULONG TransparentColor = 0; BOOL Ret = FALSE; + EXLATEOBJ exlo; if(!(DCDest = DC_LockDc(hdcDst))) { @@ -418,17 +403,15 @@ NtGdiTransparentBlt( else { PalDestMode = PalSrcMode; + PalDestGDI = PalSourceGDI; } /* Translate Transparent (RGB) Color to the source palette */ - if((XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalSrcMode, PAL_RGB, SourcePalette, NULL))) - { - TransparentColor = XLATEOBJ_iXlate(XlateObj, (ULONG)TransColor); - EngDeleteXlate(XlateObj); - } + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalSourceGDI, 0, 0, 0); + TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor); + EXLATEOBJ_vCleanup(&exlo); - /* Create the XLATE object to convert colors between source and destination */ - XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette); + EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0); rcDest.left = xDst; rcDest.top = yDst; @@ -453,7 +436,7 @@ NtGdiTransparentBlt( rcSrc.bottom += DCSrc->ptlDCOrig.y; Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, - DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc, + DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc, TransparentColor, 0); done: @@ -462,10 +445,7 @@ done: { DC_UnlockDc(DCDest); } - if(XlateObj) - { - EngDeleteXlate(XlateObj); - } + EXLATEOBJ_vCleanup(&exlo); return Ret; } @@ -734,6 +714,7 @@ GreStretchBltMask( RECTL DestRect; RECTL SourceRect; BOOL Status = FALSE; + EXLATEOBJ exlo; XLATEOBJ *XlateObj = NULL; POINTL BrushOrigin; BOOL UsesSource = ROP3_USES_SOURCE(ROP); @@ -825,20 +806,13 @@ GreStretchBltMask( goto failed; if (UsesSource) { - { - BitmapSrc = DCSrc->dclevel.pSurface; - if (BitmapSrc == NULL) - goto failed; - } + BitmapSrc = DCSrc->dclevel.pSurface; + if (BitmapSrc == NULL) + goto failed; /* Create the XLATEOBJ. */ - XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); - if (XlateObj == (XLATEOBJ*)-1) - { - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - XlateObj = NULL; - goto failed; - } + EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); + XlateObj = &exlo.xlo; } /* Offset the brush */ @@ -876,9 +850,9 @@ GreStretchBltMask( ROP3_TO_ROP4(ROP)); failed: - if (XlateObj) + if (UsesSource) { - EngDeleteXlate(XlateObj); + EXLATEOBJ_vCleanup(&exlo); } if (UsesSource && hDCSrc != hDCDest) { diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index 4302e10204e..1f65f999157 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -335,8 +335,9 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) BOOL bInRect = FALSE; SURFACE *psurf; SURFOBJ *pso; - HPALETTE Pal = 0; - XLATEOBJ *XlateObj; + HPALETTE hpal = 0; + PPALETTE ppal; + EXLATEOBJ exlo; HBITMAP hBmpTmp; dc = DC_LockDc(hDC); @@ -359,25 +360,33 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) { bInRect = TRUE; psurf = dc->dclevel.pSurface; - pso = &psurf->SurfObj; if (psurf) { - Pal = psurf->hDIBPalette; - if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault; + pso = &psurf->SurfObj; + hpal = psurf->hDIBPalette; + if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault; + ppal = PALETTE_ShareLockPalette(hpal); - /* FIXME: Verify if it shouldn't be PAL_BGR! */ - XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal); - if (XlateObj) + if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure) { - // check if this DC has a DIB behind it... - if (pso->pvScan0) // STYPE_BITMAP == pso->iType - { - ASSERT(pso->lDelta); - Result = XLATEOBJ_iXlate(XlateObj, - DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos)); - } - EngDeleteXlate(XlateObj); + /* FIXME: palette should be gpalMono already ! */ + EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0); } + else + { + EXLATEOBJ_vInitialize(&exlo, 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); + PALETTE_ShareUnlockPalette(ppal); } } DC_UnlockDc(dc); @@ -495,10 +504,10 @@ NtGdiGetBitmapBits( return 0; } - bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx, - BitsPerFormat(psurf->SurfObj.iBitmapFormat)) * + bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx, + BitsPerFormat(psurf->SurfObj.iBitmapFormat)) * abs(psurf->SurfObj.sizlBitmap.cy); - + /* If the bits vector is null, the function should return the read size */ if (pUnsafeBits == NULL) { @@ -545,7 +554,7 @@ IntSetBitmapBits( DPRINT("Calling device specific BitmapBits\n"); if (psurf->DDBitmap->funcs->pBitmapBits) { - ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap, + ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap, (void *)Bits, Bytes, DDB_SET); diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index 16d8a71bef4..07cb63e1bc2 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -13,12 +13,12 @@ static const USHORT HatchBrushes[NB_HATCH_STYLES][8] = { - {0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00}, /* HS_HORIZONTAL */ - {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, /* HS_VERTICAL */ - {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, /* HS_FDIAGONAL */ - {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, /* HS_BDIAGONAL */ - {0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08}, /* HS_CROSS */ - {0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81} /* HS_DIAGCROSS */ + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */ + {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */ + {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */ + {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */ + {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */ + {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */ }; BOOL diff --git a/reactos/subsystems/win32/win32k/objects/dclife.c b/reactos/subsystems/win32/win32k/objects/dclife.c index 889e748e1b9..ae96546dcf3 100644 --- a/reactos/subsystems/win32/win32k/objects/dclife.c +++ b/reactos/subsystems/win32/win32k/objects/dclife.c @@ -23,6 +23,7 @@ DC_AllocDC(PUNICODE_STRING Driver) PWSTR Buf = NULL; XFORM xformTemplate; PBRUSH pbrush; + HSURF hsurf; if (Driver != NULL) { @@ -128,6 +129,9 @@ DC_AllocDC(PUNICODE_STRING Driver) NewDC->dclevel.lSaveDepth = 1; + hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that? + NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); + return NewDC; } @@ -223,7 +227,6 @@ IntGdiCreateDC( HRGN hVisRgn; UNICODE_STRING StdDriver; BOOL calledFromUser; - HSURF hsurf; RtlInitUnicodeString(&StdDriver, L"DISPLAY"); @@ -296,8 +299,6 @@ IntGdiCreateDC( pdc->dhpdev = PrimarySurface.hPDev; if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device. pdc->ppdev = (PVOID)&PrimarySurface; - hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that? - pdc->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); // ATM we only have one display. pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY; @@ -344,7 +345,7 @@ IntGdiCreateDC( */ pdc->dctype = DC_TYPE_INFO; // pdc->pSurfInfo = - DC_vSelectSurface(pdc, NULL); +// DC_vSelectSurface(pdc, NULL); pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255); pdcattr->crForegroundClr = RGB(0, 0, 0); DC_UnlockDc(pdc); @@ -451,6 +452,7 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC) if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG! { // This is a cheesy way to do this. PDC dc = DC_LockDc(hDC); + HSURF hsurf; defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC); if (!defaultDCstate) { @@ -459,6 +461,8 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC) } RtlZeroMemory(defaultDCstate, sizeof(DC)); defaultDCstate->pdcattr = &defaultDCstate->dcattr; + hsurf = (HSURF)PrimarySurface.pSurface; // HAX˛ + defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); DC_vCopyState(dc, defaultDCstate); DC_UnlockDc(dc); } diff --git a/reactos/subsystems/win32/win32k/objects/dcobjs.c b/reactos/subsystems/win32/win32k/objects/dcobjs.c index 30c3c429efd..d45425b13d6 100644 --- a/reactos/subsystems/win32/win32k/objects/dcobjs.c +++ b/reactos/subsystems/win32/win32k/objects/dcobjs.c @@ -17,7 +17,6 @@ DC_vUpdateFillBrush(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; PBRUSH pbrFill; - XLATEOBJ *pxlo = NULL; /* Check if the brush handle has changed */ if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr) @@ -40,30 +39,19 @@ DC_vUpdateFillBrush(PDC pdc) } } - /* ROS HACK, should use surf xlate */ - pxlo = IntCreateBrushXlate(pdc->dclevel.pbrFill, - pdc->dclevel.pSurface, - pdc->pdcattr->crBackgroundClr); - /* Check if the EBRUSHOBJ needs update */ if (pdcattr->ulDirty_ & DIRTY_FILL) { - pbrFill = pdc->dclevel.pbrFill; - - /* Update eboFill, realizing it, if needed */ - EBRUSHOBJ_vUpdate(&pdc->eboFill, pbrFill, pdc); + /* Update eboFill */ + EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); } /* Check for DC brush */ if (pdcattr->hbrush == StockObjects[DC_BRUSH]) { + /* ROS HACK, should use surf xlate */ /* Update the eboFill's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr, pxlo); - } - - if (pxlo != NULL) - { - EngDeleteXlate(pxlo); + EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr); } /* Clear flags */ @@ -76,7 +64,6 @@ DC_vUpdateLineBrush(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; PBRUSH pbrLine; - XLATEOBJ *pxlo; /* Check if the pen handle has changed */ if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr) @@ -99,30 +86,18 @@ DC_vUpdateLineBrush(PDC pdc) } } - /* ROS HACK, should use surf xlate */ - pxlo = IntCreateBrushXlate(pdc->dclevel.pbrFill, - pdc->dclevel.pSurface, - pdc->pdcattr->crBackgroundClr); - /* Check if the EBRUSHOBJ needs update */ if (pdcattr->ulDirty_ & DIRTY_LINE) { - pbrLine = pdc->dclevel.pbrLine; - - /* Update eboLine, realizing it, if needed */ - EBRUSHOBJ_vUpdate(&pdc->eboLine, pbrLine, pdc); + /* Update eboLine */ + EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); } /* Check for DC pen */ if (pdcattr->hpen == StockObjects[DC_PEN]) { /* Update the eboLine's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr, pxlo); - } - - if (pxlo != NULL) - { - EngDeleteXlate(pxlo); + EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr); } /* Clear flags */ @@ -134,25 +109,9 @@ FASTCALL DC_vUpdateTextBrush(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; - XLATEOBJ *pxlo = NULL; - SURFACE *psurf; - HPALETTE hpal; - - psurf = pdc->dclevel.pSurface; - if (psurf) - { - hpal = psurf->hDIBPalette; - if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault; - pxlo = IntEngCreateXlate(0, PAL_RGB, hpal, NULL); - } /* Update the eboText's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr, pxlo); - - if (pxlo) - { - EngDeleteXlate(pxlo); - } + EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr); /* Clear flag */ pdcattr->ulDirty_ &= ~DIRTY_TEXT; @@ -163,25 +122,9 @@ FASTCALL DC_vUpdateBackgroundBrush(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; - XLATEOBJ *pxlo = NULL; - SURFACE *psurf; - HPALETTE hpal; - - psurf = pdc->dclevel.pSurface; - if (psurf) - { - hpal = psurf->hDIBPalette; - if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault; - pxlo = IntEngCreateXlate(0, PAL_RGB, hpal, NULL); - } /* Update the eboBackground's solid color */ - EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr, pxlo); - - if (pxlo) - { - EngDeleteXlate(pxlo); - } + EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr); /* Clear flag */ pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND; diff --git a/reactos/subsystems/win32/win32k/objects/dibobj.c b/reactos/subsystems/win32/win32k/objects/dibobj.c index 42ec533b6be..e5aac6035b7 100644 --- a/reactos/subsystems/win32/win32k/objects/dibobj.c +++ b/reactos/subsystems/win32/win32k/objects/dibobj.c @@ -230,11 +230,11 @@ IntSetDIBits( SIZEL SourceSize; POINTL ZeroPoint; RECTL DestRect; - XLATEOBJ *XlateObj; - PPALETTE hDCPalette; + EXLATEOBJ exlo; + PPALETTE ppalDDB, ppalDIB; //RGBQUAD *lpRGB; HPALETTE DDB_Palette, DIB_Palette; - ULONG DDB_Palette_Type, DIB_Palette_Type; + ULONG DIB_Palette_Type; INT DIBWidth; // Check parameters @@ -290,8 +290,8 @@ IntSetDIBits( DDB_Palette = DC->ppdev->DevInfo.hpalDefault; } - hDCPalette = PALETTE_LockPalette(DDB_Palette); - if (NULL == hDCPalette) + ppalDDB = PALETTE_LockPalette(DDB_Palette); + if (NULL == ppalDDB) { EngUnlockSurface(SourceSurf); EngDeleteSurface((HSURF)SourceBitmap); @@ -299,8 +299,6 @@ IntSetDIBits( SetLastWin32Error(ERROR_INVALID_HANDLE); return 0; } - DDB_Palette_Type = hDCPalette->Mode; - PALETTE_UnlockPalette(hDCPalette); // Source palette obtained from the BITMAPINFO DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type); @@ -313,17 +311,10 @@ IntSetDIBits( return 0; } - // Determine XLATEOBJ for color translation - XlateObj = IntEngCreateXlate(0, 0, DDB_Palette, DIB_Palette); - if (NULL == XlateObj) - { - PALETTE_FreePaletteByHandle(DIB_Palette); - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return 0; - } + ppalDIB = PALETTE_LockPalette(DIB_Palette); + + /* Initialize XLATEOBJ for color translation */ + EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0); // Zero point ZeroPoint.x = 0; @@ -335,7 +326,7 @@ IntSetDIBits( DestRect.right = SourceSize.cx; DestRect.bottom = DestRect.top + ScanLines; - copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint); + copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint); // If it succeeded, return number of scanlines copies if (copyBitsResult == TRUE) @@ -346,7 +337,9 @@ IntSetDIBits( } // Clean up - EngDeleteXlate(XlateObj); + EXLATEOBJ_vCleanup(&exlo); + PALETTE_UnlockPalette(ppalDIB); + PALETTE_UnlockPalette(ppalDDB); PALETTE_FreePaletteByHandle(DIB_Palette); EngUnlockSurface(SourceSurf); EngDeleteSurface((HSURF)SourceBitmap); @@ -449,10 +442,10 @@ NtGdiSetDIBitsToDeviceInternal( POINTL ptSource; INT DIBWidth; SIZEL SourceSize; - XLATEOBJ *XlateObj = NULL; - PPALETTE pDCPalette; + EXLATEOBJ exlo; + PPALETTE ppalDDB = NULL, ppalDIB = NULL; HPALETTE DDBPalette, DIBPalette = NULL; - ULONG DDBPaletteType, DIBPaletteType; + ULONG DIBPaletteType; if (!Bits) return 0; @@ -533,17 +526,14 @@ NtGdiSetDIBitsToDeviceInternal( } /* Obtain destination palette */ - pDCPalette = PALETTE_LockPalette(DDBPalette); - if (!pDCPalette) + ppalDDB = PALETTE_LockPalette(DDBPalette); + if (!ppalDDB) { SetLastWin32Error(ERROR_INVALID_HANDLE); Status = STATUS_UNSUCCESSFUL; goto Exit; } - DDBPaletteType = pDCPalette->Mode; - PALETTE_UnlockPalette(pDCPalette); - DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType); if (!DIBPalette) { @@ -552,27 +542,25 @@ NtGdiSetDIBitsToDeviceInternal( goto Exit; } - /* Determine XlateObj */ - XlateObj = IntEngCreateXlate(DDBPaletteType, DIBPaletteType, DDBPalette, DIBPalette); - if (!XlateObj) - { - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - Status = STATUS_NO_MEMORY; - goto Exit; - } + /* Initialize EXLATEOBJ */ + EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0); /* Copy the bits */ Status = IntEngBitBlt(pDestSurf, pSourceSurf, NULL, pDC->rosdc.CombinedClip, - XlateObj, + &exlo.xlo, &rcDest, &ptSource, NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY)); + + /* Cleanup EXLATEOBJ */ + EXLATEOBJ_vCleanup(&exlo); + Exit: if (NT_SUCCESS(Status)) { @@ -580,9 +568,11 @@ Exit: ret = ScanLines; // this one --> abs(Info->bmiHeader.biHeight) - StartScan; } + if (ppalDIB) PALETTE_UnlockPalette(ppalDIB); + if (ppalDDB) PALETTE_UnlockPalette(ppalDDB); + if (pSourceSurf) EngUnlockSurface(pSourceSurf); if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap); - if (XlateObj) EngDeleteXlate(XlateObj); if (DIBPalette) PALETTE_FreePaletteByHandle(DIBPalette); DC_UnlockDc(pDC); @@ -609,15 +599,14 @@ NtGdiGetDIBitsInternal( HBITMAP hDestBitmap = NULL; HPALETTE hSourcePalette = NULL; HPALETTE hDestPalette = NULL; - PPALETTE SourcePalette = NULL; - PPALETTE DestPalette = NULL; + PPALETTE ppalSrc = NULL; + PPALETTE ppalDst = NULL; NTSTATUS Status = STATUS_SUCCESS; ULONG Result = 0; BOOL bPaletteMatch = FALSE; PBYTE ChkBits = Bits; PVOID ColorPtr; RGBQUAD *rgbQuads; - ULONG SourcePaletteType = 0; ULONG DestPaletteType; ULONG Index; @@ -632,6 +621,8 @@ NtGdiGetDIBitsInternal( _SEH2_TRY { + ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core. if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1); } @@ -671,8 +662,9 @@ NtGdiGetDIBitsInternal( /* Copy palette information * Always create a palette for 15 & 16 bit. */ - if (Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) && - Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) + if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) && + Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) || + !ChkBits) { hDestPalette = hSourcePalette; bPaletteMatch = TRUE; @@ -680,23 +672,20 @@ NtGdiGetDIBitsInternal( 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); + ppalSrc = PALETTE_LockPalette(hSourcePalette); + /* FIXME - ppalSrc can be NULL!!! Don't assert here! */ + ASSERT(ppalSrc); - if (bPaletteMatch) + 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; + ppalDst = PALETTE_LockPalette(hDestPalette); + /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */ + DPRINT("ppalDst : %p\n", ppalDst); + ASSERT(ppalDst); } else { - DestPalette = SourcePalette; + ppalDst = ppalSrc; } /* Copy palette. */ @@ -712,15 +701,15 @@ NtGdiGetDIBitsInternal( { if (Usage == DIB_RGB_COLORS) { - if (DestPalette->NumColors != 1 << Info->bmiHeader.biBitCount) - Info->bmiHeader.biClrUsed = DestPalette->NumColors; + if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount) + Info->bmiHeader.biClrUsed = ppalDst->NumColors; for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors; + Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->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].rgbRed = ppalDst->IndexedColors[Index].peRed; + rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen; + rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue; rgbQuads[Index].rgbReserved = 0; } } @@ -750,12 +739,12 @@ NtGdiGetDIBitsInternal( else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch) { for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors; + Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->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].rgbRed = ppalDst->IndexedColors[Index].peRed; + Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen; + Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue; Info->bmiColors[Index].rgbReserved = 0; } } @@ -825,8 +814,8 @@ NtGdiGetDIBitsInternal( break; } - if (bPaletteMatch) - PALETTE_UnlockPalette(DestPalette); + if (!bPaletteMatch) + PALETTE_UnlockPalette(ppalDst); /* fill out the BITMAPINFO struct */ if (!ChkBits) @@ -934,14 +923,11 @@ NtGdiGetDIBitsInternal( if (NT_SUCCESS(Status)) { - XLATEOBJ *XlateObj; + EXLATEOBJ exlo; SURFOBJ *DestSurfObj; RECTL DestRect; - XlateObj = IntEngCreateXlate(DestPaletteType, - SourcePaletteType, - hDestPalette, - hSourcePalette); + EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0); SourcePoint.x = 0; SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines); @@ -957,7 +943,7 @@ NtGdiGetDIBitsInternal( if (IntEngCopyBits(DestSurfObj, &psurf->SurfObj, NULL, - XlateObj, + &exlo.xlo, &DestRect, &SourcePoint)) { @@ -965,11 +951,13 @@ NtGdiGetDIBitsInternal( Result = ScanLines; } - EngDeleteXlate(XlateObj); + EXLATEOBJ_vCleanup(&exlo); EngUnlockSurface(DestSurfObj); } } cleanup: + PALETTE_UnlockPalette(ppalSrc); + if (hDestBitmap != NULL) EngDeleteSurface((HSURF)hDestBitmap); diff --git a/reactos/subsystems/win32/win32k/objects/fillshap.c b/reactos/subsystems/win32/win32k/objects/fillshap.c index fc315e58f26..df4f8228cc3 100644 --- a/reactos/subsystems/win32/win32k/objects/fillshap.c +++ b/reactos/subsystems/win32/win32k/objects/fillshap.c @@ -44,7 +44,7 @@ IntGdiPolygon(PDC dc, POINTL BrushOrigin; // int Left; // int Top; - + ASSERT(dc); // caller's responsibility to pass a valid dc if (!Points || Count < 2 ) @@ -848,10 +848,10 @@ IntGdiGradientFill( { SURFACE *psurf; PPALETTE PalDestGDI; - XLATEOBJ *XlateObj; + EXLATEOBJ exlo; RECTL Extent; POINTL DitherOrg; - ULONG Mode, i; + ULONG i; BOOL Ret; HPALETTE hDestPalette; @@ -921,20 +921,11 @@ IntGdiGradientFill( if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault; PalDestGDI = PALETTE_LockPalette(hDestPalette); - if (PalDestGDI) - { - Mode = 0; - PALETTE_UnlockPalette(PalDestGDI); - } - else - Mode = PAL_RGB; - - XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, hDestPalette, NULL); - ASSERT(XlateObj); + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0); Ret = IntEngGradientFill(&psurf->SurfObj, dc->rosdc.CombinedClip, - XlateObj, + &exlo.xlo, pVertex, uVertex, pMesh, @@ -943,7 +934,10 @@ IntGdiGradientFill( &DitherOrg, ulMode); - EngDeleteXlate(XlateObj); + EXLATEOBJ_vCleanup(&exlo); + + if (PalDestGDI) + PALETTE_UnlockPalette(PalDestGDI); return Ret; } @@ -1072,8 +1066,9 @@ NtGdiExtFloodFill( PDC dc; PDC_ATTR pdcattr; SURFACE *psurf = NULL; - HPALETTE Pal = 0; - XLATEOBJ *XlateObj = NULL; + HPALETTE hpal; + PPALETTE ppal; + EXLATEOBJ exlo; BOOL Ret = FALSE; RECTL DestRect; POINTL Pt; @@ -1117,20 +1112,21 @@ NtGdiExtFloodFill( goto cleanup; } - Pal = dc->dclevel.pSurface->hDIBPalette; - if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault; - XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, PAL_RGB, Pal, NULL); + hpal = dc->dclevel.pSurface->hDIBPalette; + if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault; + ppal = PALETTE_ShareLockPalette(hpal); + + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0); /* Only solid fills supported for now * How to support pattern brushes and non standard surfaces (not offering dib functions): * Version a (most likely slow): call DrvPatBlt for every pixel * Version b: create a flood mask and let MaskBlt blit a masked brush */ - if (XlateObj != NULL) - { - ConvColor = XLATEOBJ_iXlate(XlateObj, Color); - Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType); - EngDeleteXlate(XlateObj); - } + ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color); + Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType); + + EXLATEOBJ_vCleanup(&exlo); + PALETTE_ShareUnlockPalette(ppal); cleanup: DC_UnlockDc(dc); diff --git a/reactos/subsystems/win32/win32k/objects/freetype.c b/reactos/subsystems/win32/win32k/objects/freetype.c index b53731c40a6..00158f9429a 100644 --- a/reactos/subsystems/win32/win32k/objects/freetype.c +++ b/reactos/subsystems/win32/win32k/objects/freetype.c @@ -3110,12 +3110,13 @@ GreExtTextOutW( FONTOBJ *FontObj; PFONTGDI FontGDI; PTEXTOBJ TextObj = NULL; - XLATEOBJ *XlateObj=NULL, *XlateObj2=NULL; + EXLATEOBJ exloRGB2Dst, exloDst2RGB; FT_Render_Mode RenderMode; BOOLEAN Render; POINT Start; BOOL DoBreak = FALSE; HPALETTE hDestPalette; + PPALETTE ppalDst; USHORT DxShift; // TODO: Write test-cases to exactly match real Windows in different @@ -3185,20 +3186,6 @@ GreExtTextOutW( RealXStart = (Start.x + dc->ptlDCOrig.x) << 6; YStart = Start.y + dc->ptlDCOrig.y; - /* Create the brushes */ - hDestPalette = psurf->hDIBPalette; - if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault; - XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, PAL_RGB, hDestPalette, NULL); - if ( !XlateObj ) - { - goto fail; - } - XlateObj2 = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, hDestPalette); - if ( !XlateObj2 ) - { - goto fail; - } - SourcePoint.x = 0; SourcePoint.y = 0; MaskRect.left = 0; @@ -3397,6 +3384,15 @@ GreExtTextOutW( TextTop = YStart; BackgroundLeft = (RealXStart + 32) >> 6; + /* Create the xlateobj */ + hDestPalette = psurf->hDIBPalette; + if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault; + ppalDst = PALETTE_LockPalette(hDestPalette); + EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0); + EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0); + PALETTE_UnlockPalette(ppalDst); + + /* * The main rendering loop. */ @@ -3416,7 +3412,7 @@ GreExtTextOutW( { DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index); IntUnLockFreeType; - goto fail; + goto fail2; } glyph = face->glyph; realglyph = ftGdiGlyphCacheSet(face, @@ -3428,7 +3424,7 @@ GreExtTextOutW( { DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index); IntUnLockFreeType; - goto fail; + goto fail2; } } @@ -3450,7 +3446,7 @@ GreExtTextOutW( if (error) { DPRINT1("WARNING: Failed to render glyph!\n"); - goto fail; + goto fail2; } } realglyph2 = (FT_BitmapGlyph)realglyph; @@ -3508,7 +3504,7 @@ GreExtTextOutW( DPRINT1("WARNING: EngLockSurface() failed!\n"); // FT_Done_Glyph(realglyph); IntUnLockFreeType; - goto fail; + goto fail2; } SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); if ( !SourceGlyphSurf ) @@ -3516,7 +3512,7 @@ GreExtTextOutW( EngDeleteSurface((HSURF)HSourceGlyph); DPRINT1("WARNING: EngLockSurface() failed!\n"); IntUnLockFreeType; - goto fail; + goto fail2; } /* @@ -3539,8 +3535,8 @@ GreExtTextOutW( SurfObj, SourceGlyphSurf, dc->rosdc.CombinedClip, - XlateObj, - XlateObj2, + &exloRGB2Dst.xlo, + &exloDst2RGB.xlo, &DestRect, (PPOINTL)&MaskRect, &dc->eboText.BrushObject, @@ -3577,8 +3573,8 @@ GreExtTextOutW( IntUnLockFreeType; - EngDeleteXlate(XlateObj); - EngDeleteXlate(XlateObj2); + EXLATEOBJ_vCleanup(&exloRGB2Dst); + EXLATEOBJ_vCleanup(&exloDst2RGB); if (TextObj != NULL) TEXTOBJ_UnlockText(TextObj); good: @@ -3586,11 +3582,10 @@ good: return TRUE; +fail2: + EXLATEOBJ_vCleanup(&exloRGB2Dst); + EXLATEOBJ_vCleanup(&exloDst2RGB); fail: - if ( XlateObj2 != NULL ) - EngDeleteXlate(XlateObj2); - if ( XlateObj != NULL ) - EngDeleteXlate(XlateObj); if (TextObj != NULL) TEXTOBJ_UnlockText(TextObj); DC_UnlockDc(dc); diff --git a/reactos/subsystems/win32/win32k/objects/palette.c b/reactos/subsystems/win32/win32k/objects/palette.c index 70c3a79775f..aab15442926 100644 --- a/reactos/subsystems/win32/win32k/objects/palette.c +++ b/reactos/subsystems/win32/win32k/objects/palette.c @@ -14,7 +14,7 @@ static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */ -PALETTE gpalRGB, gpalBGR; +PALETTE gpalRGB, gpalBGR, gpalMono; const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] = { @@ -110,6 +110,9 @@ HPALETTE FASTCALL PALETTE_Init(VOID) gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00); gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00); + memset(&gpalMono, 0, sizeof(PALETTE)); + gpalMono.Mode = PAL_MONOCHROME; + return hpalette; } @@ -166,6 +169,11 @@ PALETTE_AllocPalette(ULONG Mode, PalGDI->RedMask = Red; PalGDI->GreenMask = Green; PalGDI->BlueMask = Blue; + + if (Red == 0x7c00 && Green == 0x3E0 && Blue == 0x1F) + PalGDI->Mode |= PAL_RGB16_555; + else if (Red == 0xF800 && Green == 0x7E0 && Blue == 0x1F) + PalGDI->Mode |= PAL_RGB16_565; } PALETTE_UnlockPalette(PalGDI); @@ -273,32 +281,57 @@ PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor) return ulBestIndex; } +ULONG +NTAPI +PALETTE_ulGetNearestBitFieldsIndex(PALETTE* ppal, ULONG ulColor) +{ + ULONG ulNewColor; + + // FIXME: HACK, should be stored already + ppal->ulRedShift = CalculateShift(RGB(0xff,0,0), ppal->RedMask); + ppal->ulGreenShift = CalculateShift(RGB(0,0xff,0), ppal->GreenMask); + ppal->ulBlueShift = CalculateShift(RGB(0,0,0xff), ppal->BlueMask); + + ulNewColor = _rotl(ulColor, ppal->ulRedShift) & ppal->RedMask; + ulNewColor |= _rotl(ulColor, ppal->ulGreenShift) & ppal->GreenMask; + ulNewColor |= _rotl(ulColor, ppal->ulBlueShift) & ppal->BlueMask; + + return ulNewColor; +} + +ULONG +NTAPI +PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG ulColor) +{ + if (ppal->Mode & PAL_INDEXED) // use fl & PALINDEXED + return PALETTE_ulGetNearestPaletteIndex(ppal, ulColor); + else + return PALETTE_ulGetNearestBitFieldsIndex(ppal, ulColor); +} + VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors) { ASSERT(pulColors); - switch (ppal->Mode) + if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB) { - case PAL_INDEXED: - case PAL_RGB: - pulColors[0] = RGB(0xFF, 0x00, 0x00); - pulColors[1] = RGB(0x00, 0xFF, 0x00); - pulColors[2] = RGB(0x00, 0x00, 0xFF); - break; - - case PAL_BGR: - pulColors[0] = RGB(0x00, 0x00, 0xFF); - pulColors[1] = RGB(0x00, 0xFF, 0x00); - pulColors[2] = RGB(0xFF, 0x00, 0x00); - break; - - case PAL_BITFIELDS: - pulColors[0] = ppal->RedMask; - pulColors[1] = ppal->GreenMask; - pulColors[2] = ppal->BlueMask; - break; + pulColors[0] = RGB(0xFF, 0x00, 0x00); + pulColors[1] = RGB(0x00, 0xFF, 0x00); + pulColors[2] = RGB(0x00, 0x00, 0xFF); + } + else if (ppal->Mode & PAL_BGR) + { + pulColors[0] = RGB(0x00, 0x00, 0xFF); + pulColors[1] = RGB(0x00, 0xFF, 0x00); + pulColors[2] = RGB(0xFF, 0x00, 0x00); + } + else if (ppal->Mode & PAL_BITFIELDS) + { + pulColors[0] = ppal->RedMask; + pulColors[1] = ppal->GreenMask; + pulColors[2] = ppal->BlueMask; } } @@ -415,7 +448,6 @@ NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries ) if (PalGDI != NULL) { PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors); - PalGDI->logicalToSystem = NULL; PALETTE_UnlockPalette(PalGDI); } else @@ -614,28 +646,25 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color) return nearest; } - switch (palGDI->Mode) + if (palGDI->Mode & PAL_INDEXED) { - case PAL_INDEXED: - { - ULONG index; - index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color); - nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index); - break; - } - case PAL_BGR: - case PAL_RGB: - nearest = Color; - break; - case PAL_BITFIELDS: - RBits = 8 - GetNumberOfBits(palGDI->RedMask); - GBits = 8 - GetNumberOfBits(palGDI->GreenMask); - BBits = 8 - GetNumberOfBits(palGDI->BlueMask); - nearest = RGB( - (GetRValue(Color) >> RBits) << RBits, - (GetGValue(Color) >> GBits) << GBits, - (GetBValue(Color) >> BBits) << BBits); - break; + ULONG index; + index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color); + nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index); + } + else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR) + { + nearest = Color; + } + else if (palGDI->Mode & PAL_BITFIELDS) + { + RBits = 8 - GetNumberOfBits(palGDI->RedMask); + GBits = 8 - GetNumberOfBits(palGDI->GreenMask); + BBits = 8 - GetNumberOfBits(palGDI->BlueMask); + nearest = RGB( + (GetRValue(Color) >> RBits) << RBits, + (GetGValue(Color) >> GBits) << GBits, + (GetBValue(Color) >> BBits) << BBits); } PALETTE_UnlockPalette(palGDI); DC_UnlockDc(dc); @@ -655,8 +684,12 @@ NtGdiGetNearestPaletteIndex( if (ppal) { - /* Return closest match for the given RGB color */ - index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor); + if (ppal->Mode & PAL_INDEXED) + { + /* Return closest match for the given RGB color */ + index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor); + } + // else SetLastError ? PALETTE_UnlockPalette(ppal); } @@ -719,16 +752,6 @@ IntGdiRealizePalette(HDC hDC) PALETTE_UnlockPalette(sysGDI); PALETTE_UnlockPalette(palGDI); - // Create the XLATEOBJ for device managed DCs - if(dc->dctype != DC_TYPE_MEMORY) - { - if (palGDI->logicalToSystem != NULL) - { - EngDeleteXlate(palGDI->logicalToSystem); - } - palGDI->logicalToSystem = IntEngCreateXlate(sysMode, palMode, systemPalette, dc->dclevel.hpal); - } - DC_UnlockDc(dc); return realized; @@ -937,9 +960,6 @@ IntSetPaletteEntries( } memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY)); PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors); - if (palGDI->logicalToSystem) - ExFreePool(palGDI->logicalToSystem); - palGDI->logicalToSystem = NULL; PALETTE_UnlockPalette(palGDI); return Entries;