[WIN32SS]

* Properly implement GetNearestColor

svn path=/trunk/; revision=57293
This commit is contained in:
Jérôme Gardou 2012-09-13 21:49:32 +00:00
parent 534a4aec24
commit 86ab0232e3
4 changed files with 121 additions and 112 deletions

View file

@ -17,74 +17,6 @@
#define FIXUP_ROP(Rop) if(((Rop) & 0xFF000000) == 0) Rop = MAKEROP4((Rop), (Rop))
#define ROP_TO_ROP4(Rop) ((Rop) >> 16)
ULONG
TranslateCOLORREF(PDC pdc, COLORREF crColor)
{
PPALETTE ppalDC, ppalSurface;
ULONG index, ulColor, iBitmapFormat;
EXLATEOBJ exlo;
switch (crColor >> 24)
{
case 0x00: /* RGB color */
break;
case 0x01: /* PALETTEINDEX */
index = crColor & 0xFFFFFF;
ppalDC = pdc->dclevel.ppal;
if (index >= ppalDC->NumColors) index = 0;
/* Get the RGB value */
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
break;
case 0x02: /* PALETTERGB */
if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
{
/* First find the nearest index in the dc palette */
ppalDC = pdc->dclevel.ppal;
index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
/* Get the RGB value */
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
}
else
{
/* Use the pure color */
crColor = crColor & 0x00FFFFFF;
}
break;
case 0x10: /* DIBINDEX */
/* Mask the value to match the target bpp */
iBitmapFormat = pdc->dclevel.pSurface->SurfObj.iBitmapFormat;
if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
else index = crColor & 0xFFFFFF;
return index;
default:
DPRINT("Unsupported color type %u passed\n", crColor >> 24);
crColor &= 0xFFFFFF;
}
/* Initialize an XLATEOBJ from RGB to the target surface */
ppalSurface = pdc->dclevel.pSurface->ppal;
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppalSurface, 0xFFFFFF, 0, 0);
/* Translate the color to the target format */
ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
/* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
return ulColor;
}
BOOL APIENTRY
NtGdiAlphaBlend(
HDC hDCDest,

View file

@ -162,6 +162,18 @@ GdiSelectPalette(
HPALETTE hpal,
BOOL ForceBackground);
/* dcutil.c */
COLORREF
FASTCALL
IntGdiSetBkColor (HDC hDC, COLORREF Color);
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color);
UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
BOOL FASTCALL IntSetDefaultRegion(PDC);
ULONG TranslateCOLORREF(PDC pdc, COLORREF crColor);
INIT_FUNCTION NTSTATUS NTAPI InitDcImpl(VOID);
@ -179,20 +191,15 @@ VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2);
VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel);
VOID FASTCALL DCU_SetDcUndeletable(HDC);
VOID NTAPI DC_vFreeDcAttr(PDC pdc);
VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev);
COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color);
INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode);
COLORREF FASTCALL IntGdiSetTextColor(HDC hDC, COLORREF color);
UINT FASTCALL IntGdiSetTextAlign(HDC hDC, UINT Mode);
VOID FASTCALL IntGdiReferencePdev(PPDEVOBJ pPDev);
VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType);
HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC);
BOOL FASTCALL IntGdiCleanDC(HDC hDC);
VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS);
BOOL FASTCALL IntSetDefaultRegion(PDC);
BOOL NTAPI GreSetDCOwner(HDC hdc, ULONG ulOwner);
VOID

View file

@ -551,3 +551,73 @@ NtGdiSetBoundsRect(
DC_UnlockDc(pdc);
return ret;
}
/* Translates a COLORREF to the right color in the specified DC color space */
ULONG
TranslateCOLORREF(PDC pdc, COLORREF crColor)
{
PPALETTE ppalDC, ppalSurface;
ULONG index, ulColor, iBitmapFormat;
EXLATEOBJ exlo;
switch (crColor >> 24)
{
case 0x00: /* RGB color */
break;
case 0x01: /* PALETTEINDEX */
index = crColor & 0xFFFFFF;
ppalDC = pdc->dclevel.ppal;
if (index >= ppalDC->NumColors) index = 0;
/* Get the RGB value */
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
break;
case 0x02: /* PALETTERGB */
if (pdc->dclevel.hpal != StockObjects[DEFAULT_PALETTE])
{
/* First find the nearest index in the dc palette */
ppalDC = pdc->dclevel.ppal;
index = PALETTE_ulGetNearestIndex(ppalDC, crColor & 0xFFFFFF);
/* Get the RGB value */
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, index);
}
else
{
/* Use the pure color */
crColor = crColor & 0x00FFFFFF;
}
break;
case 0x10: /* DIBINDEX */
/* Mask the value to match the target bpp */
iBitmapFormat = pdc->dclevel.pSurface->SurfObj.iBitmapFormat;
if (iBitmapFormat == BMF_1BPP) index = crColor & 0x1;
else if (iBitmapFormat == BMF_4BPP) index = crColor & 0xf;
else if (iBitmapFormat == BMF_8BPP) index = crColor & 0xFF;
else if (iBitmapFormat == BMF_16BPP) index = crColor & 0xFFFF;
else index = crColor & 0xFFFFFF;
return index;
default:
DPRINT("Unsupported color type %u passed\n", crColor >> 24);
crColor &= 0xFFFFFF;
}
/* Initialize an XLATEOBJ from RGB to the target surface */
ppalSurface = pdc->dclevel.pSurface->ppal;
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppalSurface, 0xFFFFFF, 0, 0);
/* Translate the color to the target format */
ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
/* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
return ulColor;
}

View file

@ -684,47 +684,47 @@ NtGdiSetColorAdjustment(
return FALSE;
}
COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color)
COLORREF
APIENTRY
NtGdiGetNearestColor(
_In_ HDC hDC,
_In_ COLORREF Color)
{
COLORREF nearest = CLR_INVALID;
PDC dc;
PPALETTE palGDI;
LONG RBits, GBits, BBits;
COLORREF nearest = CLR_INVALID;
PDC dc;
EXLATEOBJ exlo;
PPALETTE ppal;
dc = DC_LockDc(hDC);
if (NULL != dc)
{
HPALETTE hpal = dc->dclevel.hpal;
palGDI = PALETTE_ShareLockPalette(hpal);
if (!palGDI)
{
DC_UnlockDc(dc);
return nearest;
}
dc = DC_LockDc(hDC);
if (palGDI->flFlags & PAL_INDEXED)
{
ULONG index;
index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color);
nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index);
}
else if (palGDI->flFlags & PAL_RGB || palGDI->flFlags & PAL_BGR)
{
nearest = Color;
}
else if (palGDI->flFlags & 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_ShareUnlockPalette(palGDI);
DC_UnlockDc(dc);
}
if(dc == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
if(dc->dclevel.pSurface == NULL)
ppal = gppalMono;
else
ppal = dc->dclevel.pSurface->ppal;
/* Translate the color to the DC format */
Color = TranslateCOLORREF(dc, Color);
/* XLATE it back to RGB color space */
EXLATEOBJ_vInitialize(&exlo,
ppal,
&gpalRGB,
0,
RGB(0xff, 0xff, 0xff),
RGB(0, 0, 0));
nearest = XLATEOBJ_iXlate(&exlo.xlo, Color);
EXLATEOBJ_vCleanup(&exlo);
/* We're done */
DC_UnlockDc(dc);
return nearest;
}