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 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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -40,6 +40,7 @@
#include <include/window.h>
#include <include/winsta.h>
#include <include/xformobj.h>
#include <include/xlateobj.h>
#include <include/region.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
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)
{

View file

@ -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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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;