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
This commit is contained in:
Timo Kreuzer 2009-08-04 20:37:10 +00:00
parent ba959a4eaa
commit 351632de29
22 changed files with 1336 additions and 1215 deletions

View file

@ -580,8 +580,8 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
register NICEPIXEL32 SrcPixel32; register NICEPIXEL32 SrcPixel32;
register NICEPIXEL32 DstPixel32; register NICEPIXEL32 DstPixel32;
UCHAR Alpha, SrcBpp; UCHAR Alpha, SrcBpp;
XLATEGDI* XlateGDI; EXLATEOBJ *pexlo;
XLATEOBJ* SrcXlateObj; EXLATEOBJ exloDst2Src;
DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
@ -619,14 +619,8 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
return FALSE; return FALSE;
} }
XlateGDI = ObjToGDI(ColorTranslation, XLATE); pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
if (!SrcXlateObj)
{
DPRINT1("IntEngCreateXlate failed\n");
return FALSE;
}
Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left << 1)); (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.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
SrcPixel32.col.alpha = (SrcBpp == 32) ? SrcPixel32.col.alpha = (SrcBpp == 32) ?
(SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
BlendFunc.SourceConstantAlpha; BlendFunc.SourceConstantAlpha;
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; 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.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.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); 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++; SrcY++;
} }
if (SrcXlateObj) EngDeleteXlate(SrcXlateObj); EXLATEOBJ_vCleanup(&exloDst2Src);
return TRUE; return TRUE;
} }

View file

@ -401,8 +401,8 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
register NICEPIXEL32 SrcPixel32; register NICEPIXEL32 SrcPixel32;
register NICEPIXEL16 SrcPixel16; register NICEPIXEL16 SrcPixel16;
UCHAR Alpha, SrcBpp; UCHAR Alpha, SrcBpp;
XLATEGDI* XlateGDI; EXLATEOBJ exloDst2Src;
XLATEOBJ* SrcXlateObj; EXLATEOBJ* pexlo;
DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
@ -439,14 +439,8 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
return FALSE; return FALSE;
} }
XlateGDI = ObjToGDI(ColorTranslation, XLATE); pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo);
SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal); EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0);
if (!SrcXlateObj)
{
DPRINT1("IntEngCreateXlate failed\n");
return FALSE;
}
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
DestRect->left); DestRect->left);
@ -480,7 +474,7 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; 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.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.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); 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++; SrcY++;
} }
if (SrcXlateObj) EXLATEOBJ_vCleanup(&exloDst2Src);
EngDeleteXlate(SrcXlateObj);
return TRUE; return TRUE;
} }

View file

@ -4,7 +4,7 @@
* FILE: subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.c * FILE: subsystems/win32/win32k/dib/i386/dib32bpp_colorfill.c
* PURPOSE: ASM optimised 32bpp ColorFill * PURPOSE: ASM optimised 32bpp ColorFill
* PROGRAMMERS: Magnus Olsen * PROGRAMMERS: Magnus Olsen
* Timo Kreuzer (timo.kreuzer@rectos.org) * Timo Kreuzer (timo.kreuzer@reactos.org)
*/ */
.intel_syntax noprefix .intel_syntax noprefix

View file

@ -18,54 +18,59 @@ VOID
NTAPI NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
{ {
ULONG iSolidColor; HPALETTE hpal = NULL;
XLATEOBJ *pxlo;
PSURFACE psurfTrg;
ASSERT(pebo); ASSERT(pebo);
ASSERT(pbrush); ASSERT(pbrush);
ASSERT(pdc); ASSERT(pdc);
psurfTrg = pdc->dclevel.pSurface;
pebo->psurfTrg = psurfTrg;
pebo->BrushObject.flColorType = 0; 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->BrushObject.pvRbrush = NULL;
pebo->pbrush = pbrush;
pebo->pengbrush = NULL; 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) if (pbrush->flAttrs & GDIBRUSH_IS_NULL)
{ {
/* NULL brushes don't need a color */
pebo->BrushObject.iSolidColor = 0; pebo->BrushObject.iSolidColor = 0;
} }
else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID) else if (pbrush->flAttrs & GDIBRUSH_IS_SOLID)
{ {
/* Set the RGB color */ /* Set the RGB color */
pebo->crRealize = pbrush->BrushAttr.lbColor; EBRUSHOBJ_vSetSolidBrushColor(pebo, 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);
} }
else else
{ {
/* This is a pattern brush that needs realization */ /* This is a pattern brush that needs realization */
pebo->BrushObject.iSolidColor = 0xFFFFFFFF; pebo->BrushObject.iSolidColor = 0xFFFFFFFF;
/* Use foreground color of hatch brushes */
if (pbrush->flAttrs & GDIBRUSH_IS_HATCH)
pebo->crCurrentText = pbrush->BrushAttr.lbColor;
} }
} }
VOID VOID
FASTCALL FASTCALL
EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo) EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor)
{ {
ULONG iSolidColor; ULONG iSolidColor;
EXLATEOBJ exlo;
/* Never use with non-solid brushes */ /* Never use with non-solid brushes */
ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID); ASSERT(pebo->flattrs & GDIBRUSH_IS_SOLID);
@ -74,11 +79,15 @@ EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo)
pebo->crRealize = crColor; pebo->crRealize = crColor;
pebo->ulRGBColor = 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 */ /* 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;
pebo->BrushObject.iSolidColor = iSolidColor; /* Clean up the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
} }
VOID VOID
@ -99,6 +108,9 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
EngFreeMem(pebo->BrushObject.pvRbrush); EngFreeMem(pebo->BrushObject.pvRbrush);
pebo->BrushObject.pvRbrush = NULL; pebo->BrushObject.pvRbrush = NULL;
} }
if (pebo->ppalSurf != &gpalRGB)
PALETTE_ShareUnlockPalette(pebo->ppalSurf);
} }
VOID VOID
@ -176,53 +188,55 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
{ {
BOOL bResult; BOOL bResult;
PFN_DrvRealizeBrush pfnRealzizeBrush = NULL; PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
PSURFACE psurfTrg, psurfPattern, psurfMask; PSURFACE psurfPattern, psurfMask;
PPDEVOBJ ppdev = NULL; PPDEVOBJ ppdev = NULL;
XLATEOBJ *pxlo; EXLATEOBJ exlo;
psurfTrg = pebo->psurfTrg; // FIXME: all EBRUSHOBJs need a surface // FIXME: all EBRUSHOBJs need a surface, see EBRUSHOBJ_vInit
if (!psurfTrg) if (!pebo->psurfTrg)
{ {
DPRINT1("Pattern brush has no target surface!\n"); DPRINT1("Pattern brush has no target surface!\n");
return FALSE; 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) if (ppdev && bCallDriver)
pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush; pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
if (!pfnRealzizeBrush)
{
pfnRealzizeBrush = EngRealizeBrush;
}
psurfPattern = SURFACE_LockSurface(pebo->pbrush->hbmPattern); if (!pfnRealzizeBrush)
if (!psurfPattern) pfnRealzizeBrush = EngRealizeBrush;
{
DPRINT1("No pattern, nothing to realize!\n"); psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
return FALSE; ASSERT(psurfPattern);
}
/* FIXME: implement mask */ /* FIXME: implement mask */
psurfMask = NULL; psurfMask = NULL;
/* Create xlateobj for the brush */ /* Initialize XLATEOBJ for the brush */
pxlo = IntCreateBrushXlate(pebo->pbrush, psurfTrg, pebo->crCurrentBack); EXLATEOBJ_vInitBrushXlate(&exlo,
pebo->pbrush,
pebo->psurfTrg,
pebo->crCurrentText,
pebo->crCurrentBack);
/* Perform the realization */ /* Create the realization */
bResult = pfnRealzizeBrush(&pebo->BrushObject, bResult = pfnRealzizeBrush(&pebo->BrushObject,
&pebo->psurfTrg->SurfObj, &pebo->psurfTrg->SurfObj,
&psurfPattern->SurfObj, &psurfPattern->SurfObj,
psurfMask ? &psurfMask->SurfObj : NULL, psurfMask ? &psurfMask->SurfObj : NULL,
pxlo, &exlo.xlo,
-1); // FIXME: what about hatch brushes? -1); // FIXME: what about hatch brushes?
EngDeleteXlate(pxlo); /* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
/* Unlock surfaces */
if (psurfPattern) if (psurfPattern)
SURFACE_UnlockSurface(psurfPattern); SURFACE_ShareUnlockSurface(psurfPattern);
if (psurfMask) if (psurfMask)
SURFACE_UnlockSurface(psurfMask); SURFACE_ShareUnlockSurface(psurfMask);
return bResult; return bResult;
} }

View file

@ -243,7 +243,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
&pgp->psurfColor->SurfObj, &pgp->psurfColor->SurfObj,
&pgp->psurfMask->SurfObj, &pgp->psurfMask->SurfObj,
NULL, NULL,
pgp->XlateObject, NULL,
&rclSurf, &rclSurf,
(POINTL*)&rclPointer, (POINTL*)&rclPointer,
(POINTL*)&rclPointer, (POINTL*)&rclPointer,
@ -258,7 +258,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
&pgp->psurfMask->SurfObj, &pgp->psurfMask->SurfObj,
NULL, NULL,
NULL, NULL,
pgp->XlateObject, NULL,
&rclSurf, &rclSurf,
(POINTL*)&rclPointer, (POINTL*)&rclPointer,
NULL, NULL,
@ -273,7 +273,7 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
&pgp->psurfMask->SurfObj, &pgp->psurfMask->SurfObj,
NULL, NULL,
NULL, NULL,
pgp->XlateObject, NULL,
&rclSurf, &rclSurf,
(POINTL*)&rclPointer, (POINTL*)&rclPointer,
NULL, NULL,
@ -302,10 +302,10 @@ EngSetPointerShape(
{ {
PDEVOBJ *ppdev; PDEVOBJ *ppdev;
GDIPOINTER *pgp; GDIPOINTER *pgp;
PBYTE Bits;
SIZEL Size; SIZEL Size;
LONG lDelta; LONG lDelta;
HBITMAP hbmp; HBITMAP hbmp;
RECTL rcl;
ASSERT(pso); ASSERT(pso);
@ -316,10 +316,6 @@ EngSetPointerShape(
if (pgp->psurfColor) if (pgp->psurfColor)
{ {
/* FIXME: let GDI allocate/free memory */
EngFreeMem(pgp->psurfColor->SurfObj.pvBits);
pgp->psurfColor->SurfObj.pvBits = 0;
EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr); EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
SURFACE_ShareUnlockSurface(pgp->psurfColor); SURFACE_ShareUnlockSurface(pgp->psurfColor);
pgp->psurfColor = NULL; pgp->psurfColor = NULL;
@ -327,10 +323,6 @@ EngSetPointerShape(
if (pgp->psurfMask) if (pgp->psurfMask)
{ {
/* FIXME: let GDI allocate/free memory */
EngFreeMem(pgp->psurfMask->SurfObj.pvBits);
pgp->psurfMask->SurfObj.pvBits = 0;
EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr); EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
SURFACE_ShareUnlockSurface(pgp->psurfMask); SURFACE_ShareUnlockSurface(pgp->psurfMask);
pgp->psurfMask = NULL; pgp->psurfMask = NULL;
@ -343,12 +335,6 @@ EngSetPointerShape(
pgp->psurfSave = NULL; pgp->psurfSave = NULL;
} }
if (pgp->XlateObject != NULL)
{
EngDeleteXlate(pgp->XlateObject);
pgp->XlateObject = NULL;
}
/* See if we are being asked to hide the pointer. */ /* See if we are being asked to hide the pointer. */
if (psoMask == NULL) if (psoMask == NULL)
{ {
@ -367,70 +353,15 @@ EngSetPointerShape(
pgp->Size.cx = abs(psoMask->lDelta) << 3; pgp->Size.cx = abs(psoMask->lDelta) << 3;
pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1; 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.cx = pgp->Size.cx;
Size.cy = pgp->Size.cy << 1; 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, /* Calculate lDelta for our surfaces. */
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. */
switch (pso->iBitmapFormat) switch (pso->iBitmapFormat)
{ {
case BMF_1BPP: case BMF_1BPP:
@ -456,14 +387,71 @@ EngSetPointerShape(
break; break;
} }
/* Create surface for saving the pixels under the cursor. */
hbmp = EngCreateBitmap(pgp->Size, hbmp = EngCreateBitmap(pgp->Size,
lDelta, lDelta,
pso->iBitmapFormat, pso->iBitmapFormat,
BMF_TOPDOWN | BMF_NOZEROINIT, BMF_TOPDOWN | BMF_NOZEROINIT,
NULL); NULL);
pgp->psurfSave = SURFACE_ShareLockSurface(hbmp); 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) if (x != -1)
{ {
IntShowMousePointer(ppdev, pso); IntShowMousePointer(ppdev, pso);
@ -475,8 +463,11 @@ EngSetPointerShape(
prcl->right = prcl->left + pgp->Size.cx; prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy; prcl->bottom = prcl->top + pgp->Size.cy;
} }
} else if (prcl != NULL) }
else if (prcl != NULL)
{
prcl->left = prcl->top = prcl->right = prcl->bottom = -1; prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
}
return SPS_ACCEPT_NOEXCLUDE; return SPS_ACCEPT_NOEXCLUDE;
} }

File diff suppressed because it is too large Load diff

View file

@ -58,7 +58,7 @@ typedef struct _EBRUSHOBJ
// DWORD dwUnknown2c; // DWORD dwUnknown2c;
// DWORD dwUnknown30; // DWORD dwUnknown30;
SURFACE * psurfTrg; SURFACE * psurfTrg;
// PALETTE * ppalSurf; struct _PALETTE * ppalSurf;
// PALETTE * ppalDC; // PALETTE * ppalDC;
// PALETTE * ppal3; // PALETTE * ppal3;
// DWORD dwUnknown44; // DWORD dwUnknown44;
@ -110,7 +110,7 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);
VOID VOID
FASTCALL FASTCALL
EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor, XLATEOBJ *pxlo); EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor);
VOID VOID
NTAPI NTAPI

View file

@ -102,27 +102,6 @@ typedef struct _XFORMGDI {
/* XFORMOBJ has no public members */ /* XFORMOBJ has no public members */
} XFORMGDI; } 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 /* as the *OBJ structures are located at the beginning of the *GDI structures
we can simply typecast the pointer */ we can simply typecast the pointer */
#define ObjToGDI(ClipObj, Type) (Type##GDI *)(ClipObj) #define ObjToGDI(ClipObj, Type) (Type##GDI *)(ClipObj)

View file

@ -49,10 +49,13 @@ typedef struct _PALETTE
ULONG RedMask; ULONG RedMask;
ULONG GreenMask; ULONG GreenMask;
ULONG BlueMask; ULONG BlueMask;
ULONG ulRedShift;
ULONG ulGreenShift;
ULONG ulBlueShift;
HDEV hPDev; HDEV hPDev;
} PALETTE, *PPALETTE; } PALETTE, *PPALETTE;
extern PALETTE gpalRGB, gpalBGR; extern PALETTE gpalRGB, gpalBGR, gpalMono;
HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, 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); INT FASTCALL PALETTE_GetObject(PPALETTE pGdiObject, INT cbCount, LPLOGBRUSH lpBuffer);
ULONG NTAPI PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor); ULONG NTAPI PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor);
ULONG NTAPI PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG iColor);
VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors); VOID NTAPI PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors);
PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID); PPALETTEENTRY FASTCALL ReturnSystemPalette (VOID);
HPALETTE FASTCALL GdiSelectPalette(HDC, HPALETTE, BOOL); 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 FORCEINLINE
ULONG ULONG
PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex) PALETTE_ulGetRGBColorFromIndex(PPALETTE ppal, ULONG ulIndex)

View file

@ -40,6 +40,7 @@
#include <include/window.h> #include <include/window.h>
#include <include/winsta.h> #include <include/winsta.h>
#include <include/xformobj.h> #include <include/xformobj.h>
#include <include/xlateobj.h>
#include <include/region.h> #include <include/region.h>
#include <include/ntuser.h> #include <include/ntuser.h>

View file

@ -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 <include/palette.h>
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)

View file

@ -158,10 +158,11 @@ typedef struct tagBITMAPV5INFO
// FIXME: this should go to dibobj.c // FIXME: this should go to dibobj.c
NTSTATUS NTSTATUS
ProbeAndConvertBitmapInfo( ProbeAndConvertBitmapInfo(
OUT PBITMAPV5INFO pbmiDst, OUT BITMAPV5HEADER *pbmhDst,
OUT RGBQUAD *pbmiColorsDst,
ULONG cColors,
IN PBITMAPINFO pbmiUnsafe) IN PBITMAPINFO pbmiUnsafe)
{ {
BITMAPV5HEADER *pbmhDst = (BITMAPV5HEADER*)&pbmiDst->bmiHeader;
DWORD dwSize; DWORD dwSize;
RGBQUAD *pbmiColors; RGBQUAD *pbmiColors;
ULONG ulWidthBytes; ULONG ulWidthBytes;
@ -280,6 +281,10 @@ ProbeAndConvertBitmapInfo(
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* Copy Colors */
cColors = min(cColors, pbmhDst->bV5ClrUsed);
memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD));
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -320,7 +325,10 @@ UserLoadImage(PCWSTR pwszName)
/* Create a normalized local BITMAPINFO */ /* Create a normalized local BITMAPINFO */
_SEH2_TRY _SEH2_TRY
{ {
Status = ProbeAndConvertBitmapInfo(&bmiLocal, pbmi); Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader,
bmiLocal.bmiColors,
256,
pbmi);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {

View file

@ -869,7 +869,7 @@ UserGetWindowDC(PWINDOW_OBJECT Wnd)
HWND FASTCALL HWND FASTCALL
UserGethWnd( HDC hdc, PWNDOBJ *pwndo) UserGethWnd( HDC hdc, PWNDOBJ *pwndo)
{ {
PWNDGDI pWndgdi; PWNDGDI pWndgdi = NULL;
PWINDOW_OBJECT Wnd = NULL; PWINDOW_OBJECT Wnd = NULL;
HWND hWnd; HWND hWnd;
BOOL Hit = FALSE; BOOL Hit = FALSE;

View file

@ -44,8 +44,8 @@ NtGdiAlphaBlend(
PDC DCSrc; PDC DCSrc;
SURFACE *BitmapDest, *BitmapSrc; SURFACE *BitmapDest, *BitmapSrc;
RECTL DestRect, SourceRect; RECTL DestRect, SourceRect;
BOOL Status; BOOL bResult;
XLATEOBJ *XlateObj; EXLATEOBJ exlo;
BLENDOBJ BlendObj; BLENDOBJ BlendObj;
BlendObj.BlendFunction = BlendFunc; BlendObj.BlendFunction = BlendFunc;
@ -147,31 +147,23 @@ NtGdiAlphaBlend(
} }
/* Create the XLATEOBJ. */ /* Create the XLATEOBJ. */
XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
if (XlateObj == (XLATEOBJ*)-1) /* Perform the alpha blend operation */
{ bResult = IntEngAlphaBlend(&BitmapDest->SurfObj,
DPRINT1("couldn't create XlateObj\n"); &BitmapSrc->SurfObj,
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); DCDest->rosdc.CombinedClip,
XlateObj = NULL; &exlo.xlo,
Status = FALSE; &DestRect,
} &SourceRect,
else &BlendObj);
{
/* Perform the alpha blend operation */
Status = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, XlateObj,
&DestRect, &SourceRect, &BlendObj);
}
if (XlateObj != NULL)
EngDeleteXlate(XlateObj);
EXLATEOBJ_vCleanup(&exlo);
DC_UnlockDc(DCDest); DC_UnlockDc(DCDest);
if (hDCSrc != hDCDest) if (hDCSrc != hDCDest)
DC_UnlockDc(DCSrc); DC_UnlockDc(DCSrc);
return Status; return bResult;
} }
BOOL APIENTRY BOOL APIENTRY
@ -195,6 +187,7 @@ NtGdiBitBlt(
RECTL DestRect; RECTL DestRect;
POINTL SourcePoint; POINTL SourcePoint;
BOOL Status = FALSE; BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL; XLATEOBJ *XlateObj = NULL;
BOOL UsesSource = ROP3_USES_SOURCE(ROP); BOOL UsesSource = ROP3_USES_SOURCE(ROP);
@ -281,15 +274,8 @@ NtGdiBitBlt(
/* Create the XLATEOBJ. */ /* Create the XLATEOBJ. */
if (UsesSource) if (UsesSource)
{ {
XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
XlateObj = &exlo.xlo;
if (XlateObj == (XLATEOBJ*)-1)
{
DPRINT1("couldn't create XlateObj\n");
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
XlateObj = NULL;
goto cleanup;
}
} }
/* Perform the bitblt operation */ /* Perform the bitblt operation */
@ -306,9 +292,8 @@ NtGdiBitBlt(
ROP3_TO_ROP4(ROP)); ROP3_TO_ROP4(ROP));
cleanup: cleanup:
if (UsesSource && XlateObj != NULL) if (UsesSource)
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exlo);
if (UsesSource && hDCSrc != hDCDest) if (UsesSource && hDCSrc != hDCDest)
{ {
DC_UnlockDc(DCSrc); DC_UnlockDc(DCSrc);
@ -335,12 +320,12 @@ NtGdiTransparentBlt(
PDC DCDest, DCSrc; PDC DCDest, DCSrc;
RECTL rcDest, rcSrc; RECTL rcDest, rcSrc;
SURFACE *BitmapDest, *BitmapSrc = NULL; SURFACE *BitmapDest, *BitmapSrc = NULL;
XLATEOBJ *XlateObj = NULL;
HPALETTE SourcePalette = 0, DestPalette = 0; HPALETTE SourcePalette = 0, DestPalette = 0;
PPALETTE PalDestGDI, PalSourceGDI; PPALETTE PalDestGDI, PalSourceGDI;
USHORT PalDestMode, PalSrcMode; USHORT PalDestMode, PalSrcMode;
ULONG TransparentColor = 0; ULONG TransparentColor = 0;
BOOL Ret = FALSE; BOOL Ret = FALSE;
EXLATEOBJ exlo;
if(!(DCDest = DC_LockDc(hdcDst))) if(!(DCDest = DC_LockDc(hdcDst)))
{ {
@ -418,17 +403,15 @@ NtGdiTransparentBlt(
else else
{ {
PalDestMode = PalSrcMode; PalDestMode = PalSrcMode;
PalDestGDI = PalSourceGDI;
} }
/* Translate Transparent (RGB) Color to the source palette */ /* Translate Transparent (RGB) Color to the source palette */
if((XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalSrcMode, PAL_RGB, SourcePalette, NULL))) EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalSourceGDI, 0, 0, 0);
{ TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor);
TransparentColor = XLATEOBJ_iXlate(XlateObj, (ULONG)TransColor); EXLATEOBJ_vCleanup(&exlo);
EngDeleteXlate(XlateObj);
}
/* Create the XLATE object to convert colors between source and destination */ EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0);
XlateObj = (XLATEOBJ*)IntEngCreateXlate(PalDestMode, PalSrcMode, DestPalette, SourcePalette);
rcDest.left = xDst; rcDest.left = xDst;
rcDest.top = yDst; rcDest.top = yDst;
@ -453,7 +436,7 @@ NtGdiTransparentBlt(
rcSrc.bottom += DCSrc->ptlDCOrig.y; rcSrc.bottom += DCSrc->ptlDCOrig.y;
Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
DCDest->rosdc.CombinedClip, XlateObj, &rcDest, &rcSrc, DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc,
TransparentColor, 0); TransparentColor, 0);
done: done:
@ -462,10 +445,7 @@ done:
{ {
DC_UnlockDc(DCDest); DC_UnlockDc(DCDest);
} }
if(XlateObj) EXLATEOBJ_vCleanup(&exlo);
{
EngDeleteXlate(XlateObj);
}
return Ret; return Ret;
} }
@ -734,6 +714,7 @@ GreStretchBltMask(
RECTL DestRect; RECTL DestRect;
RECTL SourceRect; RECTL SourceRect;
BOOL Status = FALSE; BOOL Status = FALSE;
EXLATEOBJ exlo;
XLATEOBJ *XlateObj = NULL; XLATEOBJ *XlateObj = NULL;
POINTL BrushOrigin; POINTL BrushOrigin;
BOOL UsesSource = ROP3_USES_SOURCE(ROP); BOOL UsesSource = ROP3_USES_SOURCE(ROP);
@ -825,20 +806,13 @@ GreStretchBltMask(
goto failed; goto failed;
if (UsesSource) if (UsesSource)
{ {
{ BitmapSrc = DCSrc->dclevel.pSurface;
BitmapSrc = DCSrc->dclevel.pSurface; if (BitmapSrc == NULL)
if (BitmapSrc == NULL) goto failed;
goto failed;
}
/* Create the XLATEOBJ. */ /* Create the XLATEOBJ. */
XlateObj = IntCreateXlateForBlt(DCDest, DCSrc, BitmapDest, BitmapSrc); EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest);
if (XlateObj == (XLATEOBJ*)-1) XlateObj = &exlo.xlo;
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
XlateObj = NULL;
goto failed;
}
} }
/* Offset the brush */ /* Offset the brush */
@ -876,9 +850,9 @@ GreStretchBltMask(
ROP3_TO_ROP4(ROP)); ROP3_TO_ROP4(ROP));
failed: failed:
if (XlateObj) if (UsesSource)
{ {
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exlo);
} }
if (UsesSource && hDCSrc != hDCDest) if (UsesSource && hDCSrc != hDCDest)
{ {

View file

@ -335,8 +335,9 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
BOOL bInRect = FALSE; BOOL bInRect = FALSE;
SURFACE *psurf; SURFACE *psurf;
SURFOBJ *pso; SURFOBJ *pso;
HPALETTE Pal = 0; HPALETTE hpal = 0;
XLATEOBJ *XlateObj; PPALETTE ppal;
EXLATEOBJ exlo;
HBITMAP hBmpTmp; HBITMAP hBmpTmp;
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
@ -359,25 +360,33 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
{ {
bInRect = TRUE; bInRect = TRUE;
psurf = dc->dclevel.pSurface; psurf = dc->dclevel.pSurface;
pso = &psurf->SurfObj;
if (psurf) if (psurf)
{ {
Pal = psurf->hDIBPalette; pso = &psurf->SurfObj;
if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault; hpal = psurf->hDIBPalette;
if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault;
ppal = PALETTE_ShareLockPalette(hpal);
/* FIXME: Verify if it shouldn't be PAL_BGR! */ if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure)
XlateObj = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, 0, NULL, Pal);
if (XlateObj)
{ {
// check if this DC has a DIB behind it... /* FIXME: palette should be gpalMono already ! */
if (pso->pvScan0) // STYPE_BITMAP == pso->iType EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0);
{
ASSERT(pso->lDelta);
Result = XLATEOBJ_iXlate(XlateObj,
DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_GetPixel(pso, XPos, YPos));
}
EngDeleteXlate(XlateObj);
} }
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); DC_UnlockDc(dc);
@ -495,10 +504,10 @@ NtGdiGetBitmapBits(
return 0; return 0;
} }
bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx, bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx,
BitsPerFormat(psurf->SurfObj.iBitmapFormat)) * BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
abs(psurf->SurfObj.sizlBitmap.cy); abs(psurf->SurfObj.sizlBitmap.cy);
/* If the bits vector is null, the function should return the read size */ /* If the bits vector is null, the function should return the read size */
if (pUnsafeBits == NULL) if (pUnsafeBits == NULL)
{ {
@ -545,7 +554,7 @@ IntSetBitmapBits(
DPRINT("Calling device specific BitmapBits\n"); DPRINT("Calling device specific BitmapBits\n");
if (psurf->DDBitmap->funcs->pBitmapBits) if (psurf->DDBitmap->funcs->pBitmapBits)
{ {
ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap, ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap,
(void *)Bits, (void *)Bits,
Bytes, Bytes,
DDB_SET); DDB_SET);

View file

@ -13,12 +13,12 @@
static const USHORT HatchBrushes[NB_HATCH_STYLES][8] = static const USHORT HatchBrushes[NB_HATCH_STYLES][8] =
{ {
{0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00}, /* HS_HORIZONTAL */ {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
{0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, /* HS_VERTICAL */ {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
{0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}, /* HS_FDIAGONAL */ {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}, /* HS_BDIAGONAL */ {0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
{0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08}, /* HS_CROSS */ {0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
{0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81} /* HS_DIAGCROSS */ {0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
}; };
BOOL BOOL

View file

@ -23,6 +23,7 @@ DC_AllocDC(PUNICODE_STRING Driver)
PWSTR Buf = NULL; PWSTR Buf = NULL;
XFORM xformTemplate; XFORM xformTemplate;
PBRUSH pbrush; PBRUSH pbrush;
HSURF hsurf;
if (Driver != NULL) if (Driver != NULL)
{ {
@ -128,6 +129,9 @@ DC_AllocDC(PUNICODE_STRING Driver)
NewDC->dclevel.lSaveDepth = 1; NewDC->dclevel.lSaveDepth = 1;
hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that?
NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
return NewDC; return NewDC;
} }
@ -223,7 +227,6 @@ IntGdiCreateDC(
HRGN hVisRgn; HRGN hVisRgn;
UNICODE_STRING StdDriver; UNICODE_STRING StdDriver;
BOOL calledFromUser; BOOL calledFromUser;
HSURF hsurf;
RtlInitUnicodeString(&StdDriver, L"DISPLAY"); RtlInitUnicodeString(&StdDriver, L"DISPLAY");
@ -296,8 +299,6 @@ IntGdiCreateDC(
pdc->dhpdev = PrimarySurface.hPDev; pdc->dhpdev = PrimarySurface.hPDev;
if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device. if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device.
pdc->ppdev = (PVOID)&PrimarySurface; 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. // ATM we only have one display.
pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY; pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY;
@ -344,7 +345,7 @@ IntGdiCreateDC(
*/ */
pdc->dctype = DC_TYPE_INFO; pdc->dctype = DC_TYPE_INFO;
// pdc->pSurfInfo = // pdc->pSurfInfo =
DC_vSelectSurface(pdc, NULL); // DC_vSelectSurface(pdc, NULL);
pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255); pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255);
pdcattr->crForegroundClr = RGB(0, 0, 0); pdcattr->crForegroundClr = RGB(0, 0, 0);
DC_UnlockDc(pdc); DC_UnlockDc(pdc);
@ -451,6 +452,7 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG! if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG!
{ // This is a cheesy way to do this. { // This is a cheesy way to do this.
PDC dc = DC_LockDc(hDC); PDC dc = DC_LockDc(hDC);
HSURF hsurf;
defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC); defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC);
if (!defaultDCstate) if (!defaultDCstate)
{ {
@ -459,6 +461,8 @@ IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC)
} }
RtlZeroMemory(defaultDCstate, sizeof(DC)); RtlZeroMemory(defaultDCstate, sizeof(DC));
defaultDCstate->pdcattr = &defaultDCstate->dcattr; defaultDCstate->pdcattr = &defaultDCstate->dcattr;
hsurf = (HSURF)PrimarySurface.pSurface; // HAX²
defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf);
DC_vCopyState(dc, defaultDCstate); DC_vCopyState(dc, defaultDCstate);
DC_UnlockDc(dc); DC_UnlockDc(dc);
} }

View file

@ -17,7 +17,6 @@ DC_vUpdateFillBrush(PDC pdc)
{ {
PDC_ATTR pdcattr = pdc->pdcattr; PDC_ATTR pdcattr = pdc->pdcattr;
PBRUSH pbrFill; PBRUSH pbrFill;
XLATEOBJ *pxlo = NULL;
/* Check if the brush handle has changed */ /* Check if the brush handle has changed */
if (pdcattr->hbrush != pdc->dclevel.pbrFill->BaseObject.hHmgr) 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 */ /* Check if the EBRUSHOBJ needs update */
if (pdcattr->ulDirty_ & DIRTY_FILL) if (pdcattr->ulDirty_ & DIRTY_FILL)
{ {
pbrFill = pdc->dclevel.pbrFill; /* Update eboFill */
EBRUSHOBJ_vUpdate(&pdc->eboFill, pdc->dclevel.pbrFill, pdc);
/* Update eboFill, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboFill, pbrFill, pdc);
} }
/* Check for DC brush */ /* Check for DC brush */
if (pdcattr->hbrush == StockObjects[DC_BRUSH]) if (pdcattr->hbrush == StockObjects[DC_BRUSH])
{ {
/* ROS HACK, should use surf xlate */
/* Update the eboFill's solid color */ /* Update the eboFill's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr, pxlo); EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboFill, pdcattr->crPenClr);
}
if (pxlo != NULL)
{
EngDeleteXlate(pxlo);
} }
/* Clear flags */ /* Clear flags */
@ -76,7 +64,6 @@ DC_vUpdateLineBrush(PDC pdc)
{ {
PDC_ATTR pdcattr = pdc->pdcattr; PDC_ATTR pdcattr = pdc->pdcattr;
PBRUSH pbrLine; PBRUSH pbrLine;
XLATEOBJ *pxlo;
/* Check if the pen handle has changed */ /* Check if the pen handle has changed */
if (pdcattr->hpen != pdc->dclevel.pbrLine->BaseObject.hHmgr) 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 */ /* Check if the EBRUSHOBJ needs update */
if (pdcattr->ulDirty_ & DIRTY_LINE) if (pdcattr->ulDirty_ & DIRTY_LINE)
{ {
pbrLine = pdc->dclevel.pbrLine; /* Update eboLine */
EBRUSHOBJ_vUpdate(&pdc->eboLine, pdc->dclevel.pbrLine, pdc);
/* Update eboLine, realizing it, if needed */
EBRUSHOBJ_vUpdate(&pdc->eboLine, pbrLine, pdc);
} }
/* Check for DC pen */ /* Check for DC pen */
if (pdcattr->hpen == StockObjects[DC_PEN]) if (pdcattr->hpen == StockObjects[DC_PEN])
{ {
/* Update the eboLine's solid color */ /* Update the eboLine's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr, pxlo); EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboLine, pdcattr->crPenClr);
}
if (pxlo != NULL)
{
EngDeleteXlate(pxlo);
} }
/* Clear flags */ /* Clear flags */
@ -134,25 +109,9 @@ FASTCALL
DC_vUpdateTextBrush(PDC pdc) DC_vUpdateTextBrush(PDC pdc)
{ {
PDC_ATTR pdcattr = pdc->pdcattr; 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 */ /* Update the eboText's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr, pxlo); EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr);
if (pxlo)
{
EngDeleteXlate(pxlo);
}
/* Clear flag */ /* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_TEXT; pdcattr->ulDirty_ &= ~DIRTY_TEXT;
@ -163,25 +122,9 @@ FASTCALL
DC_vUpdateBackgroundBrush(PDC pdc) DC_vUpdateBackgroundBrush(PDC pdc)
{ {
PDC_ATTR pdcattr = pdc->pdcattr; 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 */ /* Update the eboBackground's solid color */
EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr, pxlo); EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr);
if (pxlo)
{
EngDeleteXlate(pxlo);
}
/* Clear flag */ /* Clear flag */
pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND; pdcattr->ulDirty_ &= ~DIRTY_BACKGROUND;

View file

@ -230,11 +230,11 @@ IntSetDIBits(
SIZEL SourceSize; SIZEL SourceSize;
POINTL ZeroPoint; POINTL ZeroPoint;
RECTL DestRect; RECTL DestRect;
XLATEOBJ *XlateObj; EXLATEOBJ exlo;
PPALETTE hDCPalette; PPALETTE ppalDDB, ppalDIB;
//RGBQUAD *lpRGB; //RGBQUAD *lpRGB;
HPALETTE DDB_Palette, DIB_Palette; HPALETTE DDB_Palette, DIB_Palette;
ULONG DDB_Palette_Type, DIB_Palette_Type; ULONG DIB_Palette_Type;
INT DIBWidth; INT DIBWidth;
// Check parameters // Check parameters
@ -290,8 +290,8 @@ IntSetDIBits(
DDB_Palette = DC->ppdev->DevInfo.hpalDefault; DDB_Palette = DC->ppdev->DevInfo.hpalDefault;
} }
hDCPalette = PALETTE_LockPalette(DDB_Palette); ppalDDB = PALETTE_LockPalette(DDB_Palette);
if (NULL == hDCPalette) if (NULL == ppalDDB)
{ {
EngUnlockSurface(SourceSurf); EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap); EngDeleteSurface((HSURF)SourceBitmap);
@ -299,8 +299,6 @@ IntSetDIBits(
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
DDB_Palette_Type = hDCPalette->Mode;
PALETTE_UnlockPalette(hDCPalette);
// Source palette obtained from the BITMAPINFO // Source palette obtained from the BITMAPINFO
DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type); DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type);
@ -313,17 +311,10 @@ IntSetDIBits(
return 0; return 0;
} }
// Determine XLATEOBJ for color translation ppalDIB = PALETTE_LockPalette(DIB_Palette);
XlateObj = IntEngCreateXlate(0, 0, DDB_Palette, DIB_Palette);
if (NULL == XlateObj) /* Initialize XLATEOBJ for color translation */
{ EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
PALETTE_FreePaletteByHandle(DIB_Palette);
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
SURFACE_UnlockSurface(bitmap);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
// Zero point // Zero point
ZeroPoint.x = 0; ZeroPoint.x = 0;
@ -335,7 +326,7 @@ IntSetDIBits(
DestRect.right = SourceSize.cx; DestRect.right = SourceSize.cx;
DestRect.bottom = DestRect.top + ScanLines; 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 it succeeded, return number of scanlines copies
if (copyBitsResult == TRUE) if (copyBitsResult == TRUE)
@ -346,7 +337,9 @@ IntSetDIBits(
} }
// Clean up // Clean up
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exlo);
PALETTE_UnlockPalette(ppalDIB);
PALETTE_UnlockPalette(ppalDDB);
PALETTE_FreePaletteByHandle(DIB_Palette); PALETTE_FreePaletteByHandle(DIB_Palette);
EngUnlockSurface(SourceSurf); EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap); EngDeleteSurface((HSURF)SourceBitmap);
@ -449,10 +442,10 @@ NtGdiSetDIBitsToDeviceInternal(
POINTL ptSource; POINTL ptSource;
INT DIBWidth; INT DIBWidth;
SIZEL SourceSize; SIZEL SourceSize;
XLATEOBJ *XlateObj = NULL; EXLATEOBJ exlo;
PPALETTE pDCPalette; PPALETTE ppalDDB = NULL, ppalDIB = NULL;
HPALETTE DDBPalette, DIBPalette = NULL; HPALETTE DDBPalette, DIBPalette = NULL;
ULONG DDBPaletteType, DIBPaletteType; ULONG DIBPaletteType;
if (!Bits) return 0; if (!Bits) return 0;
@ -533,17 +526,14 @@ NtGdiSetDIBitsToDeviceInternal(
} }
/* Obtain destination palette */ /* Obtain destination palette */
pDCPalette = PALETTE_LockPalette(DDBPalette); ppalDDB = PALETTE_LockPalette(DDBPalette);
if (!pDCPalette) if (!ppalDDB)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE); SetLastWin32Error(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
goto Exit; goto Exit;
} }
DDBPaletteType = pDCPalette->Mode;
PALETTE_UnlockPalette(pDCPalette);
DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType); DIBPalette = BuildDIBPalette(bmi, (PINT)&DIBPaletteType);
if (!DIBPalette) if (!DIBPalette)
{ {
@ -552,27 +542,25 @@ NtGdiSetDIBitsToDeviceInternal(
goto Exit; goto Exit;
} }
/* Determine XlateObj */ /* Initialize EXLATEOBJ */
XlateObj = IntEngCreateXlate(DDBPaletteType, DIBPaletteType, DDBPalette, DIBPalette); EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0);
if (!XlateObj)
{
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
/* Copy the bits */ /* Copy the bits */
Status = IntEngBitBlt(pDestSurf, Status = IntEngBitBlt(pDestSurf,
pSourceSurf, pSourceSurf,
NULL, NULL,
pDC->rosdc.CombinedClip, pDC->rosdc.CombinedClip,
XlateObj, &exlo.xlo,
&rcDest, &rcDest,
&ptSource, &ptSource,
NULL, NULL,
NULL, NULL,
NULL, NULL,
ROP3_TO_ROP4(SRCCOPY)); ROP3_TO_ROP4(SRCCOPY));
/* Cleanup EXLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
Exit: Exit:
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
@ -580,9 +568,11 @@ Exit:
ret = ScanLines; // this one --> abs(Info->bmiHeader.biHeight) - StartScan; ret = ScanLines; // this one --> abs(Info->bmiHeader.biHeight) - StartScan;
} }
if (ppalDIB) PALETTE_UnlockPalette(ppalDIB);
if (ppalDDB) PALETTE_UnlockPalette(ppalDDB);
if (pSourceSurf) EngUnlockSurface(pSourceSurf); if (pSourceSurf) EngUnlockSurface(pSourceSurf);
if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap); if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap);
if (XlateObj) EngDeleteXlate(XlateObj);
if (DIBPalette) PALETTE_FreePaletteByHandle(DIBPalette); if (DIBPalette) PALETTE_FreePaletteByHandle(DIBPalette);
DC_UnlockDc(pDC); DC_UnlockDc(pDC);
@ -609,15 +599,14 @@ NtGdiGetDIBitsInternal(
HBITMAP hDestBitmap = NULL; HBITMAP hDestBitmap = NULL;
HPALETTE hSourcePalette = NULL; HPALETTE hSourcePalette = NULL;
HPALETTE hDestPalette = NULL; HPALETTE hDestPalette = NULL;
PPALETTE SourcePalette = NULL; PPALETTE ppalSrc = NULL;
PPALETTE DestPalette = NULL; PPALETTE ppalDst = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ULONG Result = 0; ULONG Result = 0;
BOOL bPaletteMatch = FALSE; BOOL bPaletteMatch = FALSE;
PBYTE ChkBits = Bits; PBYTE ChkBits = Bits;
PVOID ColorPtr; PVOID ColorPtr;
RGBQUAD *rgbQuads; RGBQUAD *rgbQuads;
ULONG SourcePaletteType = 0;
ULONG DestPaletteType; ULONG DestPaletteType;
ULONG Index; ULONG Index;
@ -632,6 +621,8 @@ NtGdiGetDIBitsInternal(
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1);
ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core. ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core.
if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1); if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1);
} }
@ -671,8 +662,9 @@ NtGdiGetDIBitsInternal(
/* Copy palette information /* Copy palette information
* Always create a palette for 15 & 16 bit. */ * Always create a palette for 15 & 16 bit. */
if (Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) && if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) &&
Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) ||
!ChkBits)
{ {
hDestPalette = hSourcePalette; hDestPalette = hSourcePalette;
bPaletteMatch = TRUE; bPaletteMatch = TRUE;
@ -680,23 +672,20 @@ NtGdiGetDIBitsInternal(
else else
hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault; hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
SourcePalette = PALETTE_LockPalette(hSourcePalette); ppalSrc = PALETTE_LockPalette(hSourcePalette);
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */ /* FIXME - ppalSrc can be NULL!!! Don't assert here! */
ASSERT(SourcePalette); ASSERT(ppalSrc);
SourcePaletteType = SourcePalette->Mode;
PALETTE_UnlockPalette(SourcePalette);
if (bPaletteMatch) if (!bPaletteMatch)
{ {
DestPalette = PALETTE_LockPalette(hDestPalette); ppalDst = PALETTE_LockPalette(hDestPalette);
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */ /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */
DPRINT("DestPalette : %p\n", DestPalette); DPRINT("ppalDst : %p\n", ppalDst);
ASSERT(DestPalette); ASSERT(ppalDst);
DestPaletteType = DestPalette->Mode;
} }
else else
{ {
DestPalette = SourcePalette; ppalDst = ppalSrc;
} }
/* Copy palette. */ /* Copy palette. */
@ -712,15 +701,15 @@ NtGdiGetDIBitsInternal(
{ {
if (Usage == DIB_RGB_COLORS) if (Usage == DIB_RGB_COLORS)
{ {
if (DestPalette->NumColors != 1 << Info->bmiHeader.biBitCount) if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount)
Info->bmiHeader.biClrUsed = DestPalette->NumColors; Info->bmiHeader.biClrUsed = ppalDst->NumColors;
for (Index = 0; for (Index = 0;
Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors; Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
Index++) Index++)
{ {
rgbQuads[Index].rgbRed = DestPalette->IndexedColors[Index].peRed; rgbQuads[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
rgbQuads[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen; rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
rgbQuads[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue; rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
rgbQuads[Index].rgbReserved = 0; rgbQuads[Index].rgbReserved = 0;
} }
} }
@ -750,12 +739,12 @@ NtGdiGetDIBitsInternal(
else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch) else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch)
{ {
for (Index = 0; for (Index = 0;
Index < (1 << Info->bmiHeader.biBitCount) && Index < DestPalette->NumColors; Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors;
Index++) Index++)
{ {
Info->bmiColors[Index].rgbRed = DestPalette->IndexedColors[Index].peRed; Info->bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed;
Info->bmiColors[Index].rgbGreen = DestPalette->IndexedColors[Index].peGreen; Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen;
Info->bmiColors[Index].rgbBlue = DestPalette->IndexedColors[Index].peBlue; Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue;
Info->bmiColors[Index].rgbReserved = 0; Info->bmiColors[Index].rgbReserved = 0;
} }
} }
@ -825,8 +814,8 @@ NtGdiGetDIBitsInternal(
break; break;
} }
if (bPaletteMatch) if (!bPaletteMatch)
PALETTE_UnlockPalette(DestPalette); PALETTE_UnlockPalette(ppalDst);
/* fill out the BITMAPINFO struct */ /* fill out the BITMAPINFO struct */
if (!ChkBits) if (!ChkBits)
@ -934,14 +923,11 @@ NtGdiGetDIBitsInternal(
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
XLATEOBJ *XlateObj; EXLATEOBJ exlo;
SURFOBJ *DestSurfObj; SURFOBJ *DestSurfObj;
RECTL DestRect; RECTL DestRect;
XlateObj = IntEngCreateXlate(DestPaletteType, EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0);
SourcePaletteType,
hDestPalette,
hSourcePalette);
SourcePoint.x = 0; SourcePoint.x = 0;
SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines); SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
@ -957,7 +943,7 @@ NtGdiGetDIBitsInternal(
if (IntEngCopyBits(DestSurfObj, if (IntEngCopyBits(DestSurfObj,
&psurf->SurfObj, &psurf->SurfObj,
NULL, NULL,
XlateObj, &exlo.xlo,
&DestRect, &DestRect,
&SourcePoint)) &SourcePoint))
{ {
@ -965,11 +951,13 @@ NtGdiGetDIBitsInternal(
Result = ScanLines; Result = ScanLines;
} }
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exlo);
EngUnlockSurface(DestSurfObj); EngUnlockSurface(DestSurfObj);
} }
} }
cleanup: cleanup:
PALETTE_UnlockPalette(ppalSrc);
if (hDestBitmap != NULL) if (hDestBitmap != NULL)
EngDeleteSurface((HSURF)hDestBitmap); EngDeleteSurface((HSURF)hDestBitmap);

View file

@ -44,7 +44,7 @@ IntGdiPolygon(PDC dc,
POINTL BrushOrigin; POINTL BrushOrigin;
// int Left; // int Left;
// int Top; // int Top;
ASSERT(dc); // caller's responsibility to pass a valid dc ASSERT(dc); // caller's responsibility to pass a valid dc
if (!Points || Count < 2 ) if (!Points || Count < 2 )
@ -848,10 +848,10 @@ IntGdiGradientFill(
{ {
SURFACE *psurf; SURFACE *psurf;
PPALETTE PalDestGDI; PPALETTE PalDestGDI;
XLATEOBJ *XlateObj; EXLATEOBJ exlo;
RECTL Extent; RECTL Extent;
POINTL DitherOrg; POINTL DitherOrg;
ULONG Mode, i; ULONG i;
BOOL Ret; BOOL Ret;
HPALETTE hDestPalette; HPALETTE hDestPalette;
@ -921,20 +921,11 @@ IntGdiGradientFill(
if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault; if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault;
PalDestGDI = PALETTE_LockPalette(hDestPalette); PalDestGDI = PALETTE_LockPalette(hDestPalette);
if (PalDestGDI) EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalDestGDI, 0, 0, 0);
{
Mode = 0;
PALETTE_UnlockPalette(PalDestGDI);
}
else
Mode = PAL_RGB;
XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, hDestPalette, NULL);
ASSERT(XlateObj);
Ret = IntEngGradientFill(&psurf->SurfObj, Ret = IntEngGradientFill(&psurf->SurfObj,
dc->rosdc.CombinedClip, dc->rosdc.CombinedClip,
XlateObj, &exlo.xlo,
pVertex, pVertex,
uVertex, uVertex,
pMesh, pMesh,
@ -943,7 +934,10 @@ IntGdiGradientFill(
&DitherOrg, &DitherOrg,
ulMode); ulMode);
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exlo);
if (PalDestGDI)
PALETTE_UnlockPalette(PalDestGDI);
return Ret; return Ret;
} }
@ -1072,8 +1066,9 @@ NtGdiExtFloodFill(
PDC dc; PDC dc;
PDC_ATTR pdcattr; PDC_ATTR pdcattr;
SURFACE *psurf = NULL; SURFACE *psurf = NULL;
HPALETTE Pal = 0; HPALETTE hpal;
XLATEOBJ *XlateObj = NULL; PPALETTE ppal;
EXLATEOBJ exlo;
BOOL Ret = FALSE; BOOL Ret = FALSE;
RECTL DestRect; RECTL DestRect;
POINTL Pt; POINTL Pt;
@ -1117,20 +1112,21 @@ NtGdiExtFloodFill(
goto cleanup; goto cleanup;
} }
Pal = dc->dclevel.pSurface->hDIBPalette; hpal = dc->dclevel.pSurface->hDIBPalette;
if (!Pal) Pal = pPrimarySurface->DevInfo.hpalDefault; if (!hpal) hpal = pPrimarySurface->DevInfo.hpalDefault;
XlateObj = (XLATEOBJ*)IntEngCreateXlate(0, PAL_RGB, Pal, NULL); ppal = PALETTE_ShareLockPalette(hpal);
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0);
/* Only solid fills supported for now /* Only solid fills supported for now
* How to support pattern brushes and non standard surfaces (not offering dib functions): * How to support pattern brushes and non standard surfaces (not offering dib functions):
* Version a (most likely slow): call DrvPatBlt for every pixel * Version a (most likely slow): call DrvPatBlt for every pixel
* Version b: create a flood mask and let MaskBlt blit a masked brush */ * Version b: create a flood mask and let MaskBlt blit a masked brush */
if (XlateObj != NULL) ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
{ Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
ConvColor = XLATEOBJ_iXlate(XlateObj, Color);
Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType); EXLATEOBJ_vCleanup(&exlo);
EngDeleteXlate(XlateObj); PALETTE_ShareUnlockPalette(ppal);
}
cleanup: cleanup:
DC_UnlockDc(dc); DC_UnlockDc(dc);

View file

@ -3110,12 +3110,13 @@ GreExtTextOutW(
FONTOBJ *FontObj; FONTOBJ *FontObj;
PFONTGDI FontGDI; PFONTGDI FontGDI;
PTEXTOBJ TextObj = NULL; PTEXTOBJ TextObj = NULL;
XLATEOBJ *XlateObj=NULL, *XlateObj2=NULL; EXLATEOBJ exloRGB2Dst, exloDst2RGB;
FT_Render_Mode RenderMode; FT_Render_Mode RenderMode;
BOOLEAN Render; BOOLEAN Render;
POINT Start; POINT Start;
BOOL DoBreak = FALSE; BOOL DoBreak = FALSE;
HPALETTE hDestPalette; HPALETTE hDestPalette;
PPALETTE ppalDst;
USHORT DxShift; USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different // TODO: Write test-cases to exactly match real Windows in different
@ -3185,20 +3186,6 @@ GreExtTextOutW(
RealXStart = (Start.x + dc->ptlDCOrig.x) << 6; RealXStart = (Start.x + dc->ptlDCOrig.x) << 6;
YStart = Start.y + dc->ptlDCOrig.y; 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.x = 0;
SourcePoint.y = 0; SourcePoint.y = 0;
MaskRect.left = 0; MaskRect.left = 0;
@ -3397,6 +3384,15 @@ GreExtTextOutW(
TextTop = YStart; TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6; 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. * The main rendering loop.
*/ */
@ -3416,7 +3412,7 @@ GreExtTextOutW(
{ {
DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index); DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index);
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto fail2;
} }
glyph = face->glyph; glyph = face->glyph;
realglyph = ftGdiGlyphCacheSet(face, realglyph = ftGdiGlyphCacheSet(face,
@ -3428,7 +3424,7 @@ GreExtTextOutW(
{ {
DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index); DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index);
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto fail2;
} }
} }
@ -3450,7 +3446,7 @@ GreExtTextOutW(
if (error) if (error)
{ {
DPRINT1("WARNING: Failed to render glyph!\n"); DPRINT1("WARNING: Failed to render glyph!\n");
goto fail; goto fail2;
} }
} }
realglyph2 = (FT_BitmapGlyph)realglyph; realglyph2 = (FT_BitmapGlyph)realglyph;
@ -3508,7 +3504,7 @@ GreExtTextOutW(
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
// FT_Done_Glyph(realglyph); // FT_Done_Glyph(realglyph);
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto fail2;
} }
SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
if ( !SourceGlyphSurf ) if ( !SourceGlyphSurf )
@ -3516,7 +3512,7 @@ GreExtTextOutW(
EngDeleteSurface((HSURF)HSourceGlyph); EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n"); DPRINT1("WARNING: EngLockSurface() failed!\n");
IntUnLockFreeType; IntUnLockFreeType;
goto fail; goto fail2;
} }
/* /*
@ -3539,8 +3535,8 @@ GreExtTextOutW(
SurfObj, SurfObj,
SourceGlyphSurf, SourceGlyphSurf,
dc->rosdc.CombinedClip, dc->rosdc.CombinedClip,
XlateObj, &exloRGB2Dst.xlo,
XlateObj2, &exloDst2RGB.xlo,
&DestRect, &DestRect,
(PPOINTL)&MaskRect, (PPOINTL)&MaskRect,
&dc->eboText.BrushObject, &dc->eboText.BrushObject,
@ -3577,8 +3573,8 @@ GreExtTextOutW(
IntUnLockFreeType; IntUnLockFreeType;
EngDeleteXlate(XlateObj); EXLATEOBJ_vCleanup(&exloRGB2Dst);
EngDeleteXlate(XlateObj2); EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL) if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj); TEXTOBJ_UnlockText(TextObj);
good: good:
@ -3586,11 +3582,10 @@ good:
return TRUE; return TRUE;
fail2:
EXLATEOBJ_vCleanup(&exloRGB2Dst);
EXLATEOBJ_vCleanup(&exloDst2RGB);
fail: fail:
if ( XlateObj2 != NULL )
EngDeleteXlate(XlateObj2);
if ( XlateObj != NULL )
EngDeleteXlate(XlateObj);
if (TextObj != NULL) if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj); TEXTOBJ_UnlockText(TextObj);
DC_UnlockDc(dc); DC_UnlockDc(dc);

View file

@ -14,7 +14,7 @@
static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */ 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] = const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] =
{ {
@ -110,6 +110,9 @@ HPALETTE FASTCALL PALETTE_Init(VOID)
gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00); gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00);
gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00); gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00);
memset(&gpalMono, 0, sizeof(PALETTE));
gpalMono.Mode = PAL_MONOCHROME;
return hpalette; return hpalette;
} }
@ -166,6 +169,11 @@ PALETTE_AllocPalette(ULONG Mode,
PalGDI->RedMask = Red; PalGDI->RedMask = Red;
PalGDI->GreenMask = Green; PalGDI->GreenMask = Green;
PalGDI->BlueMask = Blue; 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); PALETTE_UnlockPalette(PalGDI);
@ -273,32 +281,57 @@ PALETTE_ulGetNearestPaletteIndex(PALETTE* ppal, ULONG iColor)
return ulBestIndex; 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 VOID
NTAPI NTAPI
PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors) PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors)
{ {
ASSERT(pulColors); ASSERT(pulColors);
switch (ppal->Mode) if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB)
{ {
case PAL_INDEXED: pulColors[0] = RGB(0xFF, 0x00, 0x00);
case PAL_RGB: pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[0] = RGB(0xFF, 0x00, 0x00); pulColors[2] = RGB(0x00, 0x00, 0xFF);
pulColors[1] = RGB(0x00, 0xFF, 0x00); }
pulColors[2] = RGB(0x00, 0x00, 0xFF); else if (ppal->Mode & PAL_BGR)
break; {
pulColors[0] = RGB(0x00, 0x00, 0xFF);
case PAL_BGR: pulColors[1] = RGB(0x00, 0xFF, 0x00);
pulColors[0] = RGB(0x00, 0x00, 0xFF); pulColors[2] = RGB(0xFF, 0x00, 0x00);
pulColors[1] = RGB(0x00, 0xFF, 0x00); }
pulColors[2] = RGB(0xFF, 0x00, 0x00); else if (ppal->Mode & PAL_BITFIELDS)
break; {
pulColors[0] = ppal->RedMask;
case PAL_BITFIELDS: pulColors[1] = ppal->GreenMask;
pulColors[0] = ppal->RedMask; pulColors[2] = ppal->BlueMask;
pulColors[1] = ppal->GreenMask;
pulColors[2] = ppal->BlueMask;
break;
} }
} }
@ -415,7 +448,6 @@ NtGdiCreatePaletteInternal ( IN LPLOGPALETTE pLogPal, IN UINT cEntries )
if (PalGDI != NULL) if (PalGDI != NULL)
{ {
PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors); PALETTE_ValidateFlags(PalGDI->IndexedColors, PalGDI->NumColors);
PalGDI->logicalToSystem = NULL;
PALETTE_UnlockPalette(PalGDI); PALETTE_UnlockPalette(PalGDI);
} }
else else
@ -614,28 +646,25 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color)
return nearest; return nearest;
} }
switch (palGDI->Mode) if (palGDI->Mode & PAL_INDEXED)
{ {
case PAL_INDEXED: ULONG index;
{ index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color);
ULONG index; nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index);
index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color); }
nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index); else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR)
break; {
} nearest = Color;
case PAL_BGR: }
case PAL_RGB: else if (palGDI->Mode & PAL_BITFIELDS)
nearest = Color; {
break; RBits = 8 - GetNumberOfBits(palGDI->RedMask);
case PAL_BITFIELDS: GBits = 8 - GetNumberOfBits(palGDI->GreenMask);
RBits = 8 - GetNumberOfBits(palGDI->RedMask); BBits = 8 - GetNumberOfBits(palGDI->BlueMask);
GBits = 8 - GetNumberOfBits(palGDI->GreenMask); nearest = RGB(
BBits = 8 - GetNumberOfBits(palGDI->BlueMask); (GetRValue(Color) >> RBits) << RBits,
nearest = RGB( (GetGValue(Color) >> GBits) << GBits,
(GetRValue(Color) >> RBits) << RBits, (GetBValue(Color) >> BBits) << BBits);
(GetGValue(Color) >> GBits) << GBits,
(GetBValue(Color) >> BBits) << BBits);
break;
} }
PALETTE_UnlockPalette(palGDI); PALETTE_UnlockPalette(palGDI);
DC_UnlockDc(dc); DC_UnlockDc(dc);
@ -655,8 +684,12 @@ NtGdiGetNearestPaletteIndex(
if (ppal) if (ppal)
{ {
/* Return closest match for the given RGB color */ if (ppal->Mode & PAL_INDEXED)
index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor); {
/* Return closest match for the given RGB color */
index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor);
}
// else SetLastError ?
PALETTE_UnlockPalette(ppal); PALETTE_UnlockPalette(ppal);
} }
@ -719,16 +752,6 @@ IntGdiRealizePalette(HDC hDC)
PALETTE_UnlockPalette(sysGDI); PALETTE_UnlockPalette(sysGDI);
PALETTE_UnlockPalette(palGDI); 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); DC_UnlockDc(dc);
return realized; return realized;
@ -937,9 +960,6 @@ IntSetPaletteEntries(
} }
memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY)); memcpy(palGDI->IndexedColors + Start, pe, Entries * sizeof(PALETTEENTRY));
PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors); PALETTE_ValidateFlags(palGDI->IndexedColors, palGDI->NumColors);
if (palGDI->logicalToSystem)
ExFreePool(palGDI->logicalToSystem);
palGDI->logicalToSystem = NULL;
PALETTE_UnlockPalette(palGDI); PALETTE_UnlockPalette(palGDI);
return Entries; return Entries;