From 351632de29b3ed554381987eb668ea7b7e4fe24c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Tue, 4 Aug 2009 20:37:10 +0000 Subject: [PATCH] XLATEOBJ rewrite. The new XLATEOBJ is not allocated from paged pool anymore, but instead allocated on the stack and Initialized. Only when we habe more than a color table with more than 6 entries, we need to allocate an additional buffer. The new interface: EXLATEOBJ_vInitialize is the main init function. It takes a source and destination palette and back and fore colors for monochome surfaces. EXLATEOBJ_vInitXlateFromDCs takes the source and dest DC and is for color translation between 2 surfaces represented by 2 DCs. EXLATEOBJ_vInitBrushXlate initializes an XLATEOBJ for a pattern brush. Finally EXLATEOBJ_vCleanup needs to be called when the XLATEOBJ is not needed anymore. Implement individual iXlate functions for certain cases and store a function pointer in the EXLATEOBJ structure for quick access. Change the usage of the PALETTE.Mode member to be a flag instead of an enum, add usage of PAL_MONOCHOME, PAL_RGB16_555 and PAL_RGB16_565. Add gpalMono, which *should* be used as palette for 1bpp DDBs. Currently there's a hack in the XLATEOBJ init code, to hack around the fact that this is missing. Fix the Hatch brush patterns, as they were inverted. Implement PALETTE_ulGetNearestBitFieldsIndex and PALETTE_ulGetNearestIndex. Get rid of the XLATEOBJ for the mouse pointer instead realize the pointer before usage. Get rid of logicalToSystem PALETTE member. NtGdiGetDIBitsInternal: Don't create a DIBBrush from the BITMAPINFO, when pvBits is NULL, as the function might be uninitualized. This fixes a crash of gdi_regtest. The whole function is quite ugly and needs to be rewritten (like probably the rest of the DIB code). This fixes the problem of artifacts in the selected desktop icons and some color problems. svn path=/trunk/; revision=42391 --- .../subsystems/win32/win32k/dib/dib16bpp.c | 20 +- reactos/subsystems/win32/win32k/dib/dib8bpp.c | 19 +- .../win32k/dib/i386/dib32bpp_colorfill.s | 2 +- .../subsystems/win32/win32k/eng/engbrush.c | 104 +- reactos/subsystems/win32/win32k/eng/mouse.c | 151 +- reactos/subsystems/win32/win32k/eng/xlate.c | 1532 +++++++++-------- .../subsystems/win32/win32k/include/brush.h | 4 +- .../win32/win32k/include/engobjects.h | 21 - .../subsystems/win32/win32k/include/palette.h | 18 +- .../subsystems/win32/win32k/include/win32k.h | 1 + .../win32/win32k/include/xlateobj.h | 52 + reactos/subsystems/win32/win32k/misc/file.c | 14 +- .../subsystems/win32/win32k/ntuser/windc.c | 2 +- .../subsystems/win32/win32k/objects/bitblt.c | 94 +- .../subsystems/win32/win32k/objects/bitmaps.c | 49 +- .../subsystems/win32/win32k/objects/brush.c | 12 +- .../subsystems/win32/win32k/objects/dclife.c | 12 +- .../subsystems/win32/win32k/objects/dcobjs.c | 75 +- .../subsystems/win32/win32k/objects/dibobj.c | 136 +- .../win32/win32k/objects/fillshap.c | 48 +- .../win32/win32k/objects/freetype.c | 51 +- .../subsystems/win32/win32k/objects/palette.c | 134 +- 22 files changed, 1336 insertions(+), 1215 deletions(-) create mode 100644 reactos/subsystems/win32/win32k/include/xlateobj.h 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;