reactos/win32ss/gdi/ntgdi/dcutil.c
jimtabor 94b4b5c127 [NtGDI] Fix ExtSelectClipRgn Tests
Fix results from tests, add (last one) gdi batch support for
ExtSelectClipRgn. Left commented out test code in tree this time.
Pass Katayama Hirofumi MZ SelectClipRgn tests. After commit will plug in
the last batch. After 12 years.

See CORE-13817 and CORE-15906.
2019-05-09 12:33:21 -05:00

939 lines
21 KiB
C

#include <win32k.h>
#define NDEBUG
#include <debug.h>
BOOL FASTCALL
GreDPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
{
PDC dc;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
IntDPtoLP(dc, lpPoints, nCount);
DC_UnlockDc(dc);
return TRUE;
}
BOOL FASTCALL
GreLPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount)
{
PDC dc;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
IntLPtoDP(dc, lpPoints, nCount);
DC_UnlockDc(dc);
return TRUE;
}
int FASTCALL
GreGetBkMode(HDC hdc)
{
PDC dc;
LONG lBkMode;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
lBkMode = dc->pdcattr->lBkMode;
DC_UnlockDc(dc);
return lBkMode;
}
COLORREF FASTCALL
GreGetBkColor(HDC hdc)
{
PDC dc;
COLORREF crBk;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
crBk = dc->pdcattr->ulBackgroundClr;
DC_UnlockDc(dc);
return crBk;
}
int FASTCALL
GreGetMapMode(HDC hdc)
{
PDC dc;
INT iMapMode;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
iMapMode = dc->pdcattr->iMapMode;
DC_UnlockDc(dc);
return iMapMode;
}
COLORREF FASTCALL
GreGetTextColor(HDC hdc)
{
PDC dc;
ULONG ulForegroundClr;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
ulForegroundClr = dc->pdcattr->ulForegroundClr;
DC_UnlockDc(dc);
return ulForegroundClr;
}
COLORREF FASTCALL
IntGdiSetBkColor(HDC hDC, COLORREF color)
{
COLORREF oldColor;
PDC dc;
PDC_ATTR pdcattr;
HBRUSH hBrush;
if (!(dc = DC_LockDc(hDC)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = dc->pdcattr;
oldColor = pdcattr->ulBackgroundClr;
pdcattr->ulBackgroundClr = color;
if (pdcattr->crBackgroundClr != color)
{
pdcattr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL); // Clear Flag if set.
pdcattr->crBackgroundClr = color;
}
hBrush = pdcattr->hbrush;
DC_UnlockDc(dc);
NtGdiSelectBrush(hDC, hBrush);
return oldColor;
}
INT FASTCALL
IntGdiSetBkMode(HDC hDC, INT Mode)
{
COLORREF oldMode;
PDC dc;
PDC_ATTR pdcattr;
if (!(dc = DC_LockDc(hDC)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = dc->pdcattr;
oldMode = pdcattr->lBkMode;
pdcattr->jBkMode = Mode;
pdcattr->lBkMode = Mode;
DC_UnlockDc(dc);
return oldMode;
}
UINT
FASTCALL
IntGdiSetTextAlign(HDC hDC,
UINT Mode)
{
UINT prevAlign;
DC *dc;
PDC_ATTR pdcattr;
dc = DC_LockDc(hDC);
if (!dc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
pdcattr = dc->pdcattr;
prevAlign = pdcattr->lTextAlign;
pdcattr->lTextAlign = Mode;
if (pdcattr->dwLayout & LAYOUT_RTL)
{
if ((Mode & TA_CENTER) != TA_CENTER) Mode ^= TA_RIGHT;
}
pdcattr->flTextAlign = Mode & TA_MASK;
DC_UnlockDc(dc);
return prevAlign;
}
COLORREF
FASTCALL
IntGdiSetTextColor(HDC hDC,
COLORREF color)
{
COLORREF crOldColor;
PDC pdc;
PDC_ATTR pdcattr;
pdc = DC_LockDc(hDC);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
pdcattr = pdc->pdcattr;
crOldColor = (COLORREF) pdcattr->ulForegroundClr;
pdcattr->ulForegroundClr = (ULONG)color;
if (pdcattr->crForegroundClr != color)
{
pdcattr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
pdcattr->crForegroundClr = color;
}
DC_vUpdateTextBrush(pdc);
DC_vUpdateLineBrush(pdc);
DC_vUpdateFillBrush(pdc);
DC_UnlockDc(pdc);
return crOldColor;
}
COLORREF FASTCALL
IntSetDCBrushColor(HDC hdc, COLORREF crColor)
{
COLORREF OldColor = CLR_INVALID;
PDC dc;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
else
{
OldColor = (COLORREF) dc->pdcattr->ulBrushClr;
dc->pdcattr->ulBrushClr = (ULONG) crColor;
if ( dc->pdcattr->crBrushClr != crColor )
{
dc->pdcattr->ulDirty_ |= DIRTY_FILL;
dc->pdcattr->crBrushClr = crColor;
}
}
DC_UnlockDc(dc);
return OldColor;
}
BOOL FASTCALL
GreSetBrushOrg(
HDC hdc,
INT x,
INT y,
LPPOINT pptOut)
{
PDC pdc = DC_LockDc(hdc);
if (pdc == NULL)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if (pptOut != NULL)
{
*pptOut = pdc->pdcattr->ptlBrushOrigin;
}
pdc->pdcattr->ptlBrushOrigin.x = x;
pdc->pdcattr->ptlBrushOrigin.y = y;
DC_vSetBrushOrigin(pdc, x, y);
DC_UnlockDc(pdc);
return TRUE;
}
COLORREF FASTCALL
IntSetDCPenColor(HDC hdc, COLORREF crColor)
{
COLORREF OldColor;
PDC dc;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return CLR_INVALID;
}
OldColor = (COLORREF)dc->pdcattr->ulPenClr;
dc->pdcattr->ulPenClr = (ULONG)crColor;
if (dc->pdcattr->crPenClr != crColor)
{
dc->pdcattr->ulDirty_ |= DIRTY_LINE;
dc->pdcattr->crPenClr = crColor;
}
DC_UnlockDc(dc);
return OldColor;
}
int
FASTCALL
GreSetStretchBltMode(HDC hDC, int iStretchMode)
{
PDC pdc;
PDC_ATTR pdcattr;
INT oSMode = 0;
pdc = DC_LockDc(hDC);
if (pdc)
{
pdcattr = pdc->pdcattr;
oSMode = pdcattr->lStretchBltMode;
pdcattr->lStretchBltMode = iStretchMode;
// Wine returns an error here. We set the default.
if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
pdcattr->jStretchBltMode = iStretchMode;
DC_UnlockDc(pdc);
}
return oSMode;
}
int FASTCALL
GreGetGraphicsMode(HDC hdc)
{
PDC dc;
int GraphicsMode;
if (!(dc = DC_LockDc(hdc)))
{
EngSetLastError(ERROR_INVALID_HANDLE);
return CLR_INVALID;
}
GraphicsMode = dc->pdcattr->iGraphicsMode;
DC_UnlockDc(dc);
return GraphicsMode;
}
VOID
FASTCALL
DCU_SetDcUndeletable(HDC hDC)
{
PDC dc = DC_LockDc(hDC);
if (!dc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return;
}
dc->fs |= DC_FLAG_PERMANENT;
DC_UnlockDc(dc);
return;
}
#if 0
BOOL FASTCALL
IntIsPrimarySurface(SURFOBJ *SurfObj)
{
if (PrimarySurface.pSurface == NULL)
{
return FALSE;
}
return SurfObj->hsurf == PrimarySurface.pSurface; // <- FIXME: WTF?
}
#endif
BOOL
FASTCALL
IntSetDefaultRegion(PDC pdc)
{
PSURFACE pSurface;
PREGION prgn;
RECTL rclWnd, rclClip;
IntGdiReleaseRaoRgn(pdc);
rclWnd.left = 0;
rclWnd.top = 0;
rclWnd.right = pdc->dclevel.sizl.cx;
rclWnd.bottom = pdc->dclevel.sizl.cy;
rclClip = rclWnd;
//EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
if (pdc->ppdev->flFlags & PDEV_META_DEVICE)
{
pSurface = pdc->dclevel.pSurface;
if (pSurface && pSurface->flags & PDEV_SURFACE)
{
rclClip.left += pdc->ppdev->ptlOrigion.x;
rclClip.top += pdc->ppdev->ptlOrigion.y;
rclClip.right += pdc->ppdev->ptlOrigion.x;
rclClip.bottom += pdc->ppdev->ptlOrigion.y;
}
}
//EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
prgn = pdc->prgnVis;
if (prgn && prgn != prgnDefault)
{
REGION_SetRectRgn( prgn,
rclClip.left,
rclClip.top,
rclClip.right ,
rclClip.bottom );
}
else
{
prgn = IntSysCreateRectpRgn( rclClip.left,
rclClip.top,
rclClip.right ,
rclClip.bottom );
pdc->prgnVis = prgn;
}
if (prgn)
{
pdc->ptlDCOrig.x = 0;
pdc->ptlDCOrig.y = 0;
pdc->erclWindow = rclWnd;
pdc->erclClip = rclClip;
/* Might be an InitDC or DCE... */
pdc->ptlFillOrigin = pdc->dcattr.ptlBrushOrigin;
return TRUE;
}
// No Vis use the Default System Region.
pdc->prgnVis = prgnDefault;
return FALSE;
}
BOOL APIENTRY
NtGdiCancelDC(HDC hDC)
{
UNIMPLEMENTED;
return FALSE;
}
WORD APIENTRY
IntGdiSetHookFlags(HDC hDC, WORD Flags)
{
WORD wRet;
DC *dc = DC_LockDc(hDC);
if (NULL == dc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
wRet = dc->fs & DC_FLAG_DIRTY_RAO; // FIXME: Wrong flag!
/* Info in "Undocumented Windows" is slightly confusing. */
DPRINT("DC %p, Flags %04x\n", hDC, Flags);
if (Flags & DCHF_INVALIDATEVISRGN)
{
/* hVisRgn has to be updated */
dc->fs |= DC_FLAG_DIRTY_RAO;
}
else if (Flags & DCHF_VALIDATEVISRGN || 0 == Flags)
{
//dc->fs &= ~DC_FLAG_DIRTY_RAO;
}
DC_UnlockDc(dc);
return wRet;
}
BOOL
APIENTRY
NtGdiGetDCDword(
HDC hDC,
UINT u,
DWORD *Result)
{
BOOL Ret = TRUE;
PDC pdc;
PDC_ATTR pdcattr;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (!Result)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdc = DC_LockDc(hDC);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
pdcattr = pdc->pdcattr;
switch (u)
{
case GdiGetJournal:
break;
case GdiGetRelAbs:
SafeResult = pdcattr->lRelAbs;
break;
case GdiGetBreakExtra:
SafeResult = pdcattr->lBreakExtra;
break;
case GdiGerCharBreak:
SafeResult = pdcattr->cBreak;
break;
case GdiGetArcDirection:
if (pdcattr->dwLayout & LAYOUT_RTL)
SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
else
SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) + AD_COUNTERCLOCKWISE;
break;
case GdiGetEMFRestorDc:
SafeResult = pdc->dclevel.lSaveDepth;
break;
case GdiGetFontLanguageInfo:
SafeResult = IntGetFontLanguageInfo(pdc);
break;
case GdiGetIsMemDc:
SafeResult = pdc->dctype;
break;
case GdiGetMapMode:
SafeResult = pdcattr->iMapMode;
break;
case GdiGetTextCharExtra:
SafeResult = pdcattr->lTextExtra;
break;
default:
EngSetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH2_TRY
{
ProbeForWrite(Result, sizeof(DWORD), 1);
*Result = SafeResult;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
Ret = FALSE;
}
}
DC_UnlockDc(pdc);
return Ret;
}
_Success_(return != FALSE)
BOOL
APIENTRY
NtGdiGetAndSetDCDword(
_In_ HDC hdc,
_In_ UINT u,
_In_ DWORD dwIn,
_Out_ DWORD *pdwResult)
{
BOOL Ret = TRUE;
PDC pdc;
PDC_ATTR pdcattr;
DWORD SafeResult = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (!pdwResult)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pdc = DC_LockDc(hdc);
if (!pdc)
{
EngSetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
pdcattr = pdc->pdcattr;
switch (u)
{
case GdiGetSetCopyCount:
SafeResult = pdc->ulCopyCount;
pdc->ulCopyCount = dwIn;
break;
case GdiGetSetTextAlign:
SafeResult = pdcattr->lTextAlign;
pdcattr->lTextAlign = dwIn;
// pdcattr->flTextAlign = dwIn; // Flags!
break;
case GdiGetSetRelAbs:
SafeResult = pdcattr->lRelAbs;
pdcattr->lRelAbs = dwIn;
break;
case GdiGetSetTextCharExtra:
SafeResult = pdcattr->lTextExtra;
pdcattr->lTextExtra = dwIn;
break;
case GdiGetSetSelectFont:
break;
case GdiGetSetMapperFlagsInternal:
if (dwIn & ~1)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
SafeResult = pdcattr->flFontMapper;
pdcattr->flFontMapper = dwIn;
break;
case GdiGetSetMapMode:
SafeResult = IntGdiSetMapMode(pdc, dwIn);
break;
case GdiGetSetArcDirection:
if (dwIn != AD_COUNTERCLOCKWISE && dwIn != AD_CLOCKWISE)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (pdcattr->dwLayout & LAYOUT_RTL) // Right to Left
{
SafeResult = AD_CLOCKWISE - ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
if (dwIn == AD_CLOCKWISE)
{
pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
break;
}
pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
}
else // Left to Right
{
SafeResult = ((pdc->dclevel.flPath & DCPATH_CLOCKWISE) != 0) +
AD_COUNTERCLOCKWISE;
if (dwIn == AD_COUNTERCLOCKWISE)
{
pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
break;
}
pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
}
break;
default:
EngSetLastError(ERROR_INVALID_PARAMETER);
Ret = FALSE;
break;
}
if (Ret)
{
_SEH2_TRY
{
ProbeForWrite(pdwResult, sizeof(DWORD), 1);
*pdwResult = SafeResult;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
Ret = FALSE;
}
}
DC_UnlockDc(pdc);
return Ret;
}
VOID
FASTCALL
IntUpdateBoundsRect(PDC pdc, PRECTL pRect)
{
if (pdc->fs & DC_ACCUM_APP)
{
RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, pRect);
}
if (pdc->fs & DC_ACCUM_WMGR)
{
RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, pRect);
}
}
DWORD
APIENTRY
NtGdiGetBoundsRect(
IN HDC hdc,
OUT LPRECT prc,
IN DWORD flags)
{
DWORD ret;
PDC pdc;
RECT rc;
/* Lock the DC */
if (!(pdc = DC_LockDc(hdc))) return 0;
if (!(flags & DCB_WINDOWMGR))
{
rc = pdc->erclBoundsApp;
if (RECTL_bIsEmptyRect(&rc))
{
rc.left = rc.top = rc.right = rc.bottom = 0;
ret = DCB_RESET;
}
else
{
RECTL rcRgn;
if (pdc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(pdc);
if(!REGION_GetRgnBox(pdc->prgnRao, &rcRgn))
{
REGION_GetRgnBox(pdc->prgnVis, &rcRgn);
}
rc.left = max( rc.left, 0 );
rc.top = max( rc.top, 0 );
rc.right = min( rc.right, rcRgn.right - rcRgn.left );
rc.bottom = min( rc.bottom, rcRgn.bottom - rcRgn.top );
DPRINT("Rao dc %p r %d b %d\n",pdc,rcRgn.right - rcRgn.left, rcRgn.bottom - rcRgn.top);
DPRINT("rc l %d t %d\n",rc.left,rc.top);
DPRINT(" r %d b %d\n",rc.right,rc.bottom);
ret = DCB_SET;
}
IntDPtoLP( pdc, &rc, 2 );
DPRINT("rc1 l %d t %d\n",rc.left,rc.top);
DPRINT(" r %d b %d\n",rc.right,rc.bottom);
}
else
{
rc = pdc->erclBounds;
ret = DCB_SET;
}
/* Copy the rect to the caller */
_SEH2_TRY
{
ProbeForWrite(prc, sizeof(RECT), 1);
*prc = rc;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = 0;
}
_SEH2_END;
if (flags & DCB_RESET)
{
if (!(flags & DCB_WINDOWMGR))
{
pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
}
else
{
pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
}
}
DC_UnlockDc(pdc);
return ret;
}
DWORD
APIENTRY
NtGdiSetBoundsRect(
IN HDC hdc,
IN LPRECT prc,
IN DWORD flags)
{
DWORD ret;
PDC pdc;
RECTL rcl;
/* Verify arguments */
if ((flags & DCB_ENABLE) && (flags & DCB_DISABLE)) return 0;
/* Lock the DC */
if (!(pdc = DC_LockDc(hdc))) return 0;
/* Get the return value */
ret = DCB_RESET; /* we don't have device-specific bounds */
ret = (pdc->fs & (DC_ACCUM_APP|DC_ACCUM_WMGR) ? DCB_ENABLE : DCB_DISABLE) |
(RECTL_bIsEmptyRect(&pdc->erclBoundsApp) ? ret & DCB_SET : DCB_SET );
ret |= (flags & DCB_WINDOWMGR);
if (flags & DCB_RESET)
{
if (!(flags & DCB_WINDOWMGR))
{
pdc->erclBoundsApp.left = pdc->erclBoundsApp.top = INT_MAX;
pdc->erclBoundsApp.right = pdc->erclBoundsApp.bottom = INT_MIN;
}
else
{
pdc->erclBounds.left = pdc->erclBounds.top = INT_MAX;
pdc->erclBounds.right = pdc->erclBounds.bottom = INT_MIN;
}
}
if (flags & DCB_ACCUMULATE && prc != NULL)
{
/* Capture the rect */
_SEH2_TRY
{
ProbeForRead(prc, sizeof(RECT), 1);
rcl = *prc;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DC_UnlockDc(pdc);
_SEH2_YIELD(return 0;)
}
_SEH2_END;
RECTL_vMakeWellOrdered(&rcl);
if (!(flags & DCB_WINDOWMGR))
{
IntLPtoDP( pdc, (POINT *)&rcl, 2 );
RECTL_bUnionRect(&pdc->erclBoundsApp, &pdc->erclBoundsApp, &rcl);
}
else
RECTL_bUnionRect(&pdc->erclBounds, &pdc->erclBounds, &rcl);
}
if (flags & DCB_ENABLE)
{
if (!(flags & DCB_WINDOWMGR))
pdc->fs |= DC_ACCUM_APP;
else
pdc->fs |= DC_ACCUM_WMGR;
}
if (flags & DCB_DISABLE)
{
if (!(flags & DCB_WINDOWMGR))
pdc->fs &= ~DC_ACCUM_APP;
else
pdc->fs &= ~DC_ACCUM_WMGR;
}
DC_UnlockDc(pdc);
return ret;
}
/* Translates a COLORREF to the right color in the specified DC color space */
ULONG
TranslateCOLORREF(PDC pdc, COLORREF crColor)
{
PSURFACE psurfDC;
PPALETTE ppalDC;
ULONG index, ulColor, iBitmapFormat;
EXLATEOBJ exlo;
/* Get the DC surface */
psurfDC = pdc->dclevel.pSurface;
/* If no surface is selected, use the default bitmap */
if (!psurfDC)
psurfDC = psurfDefaultBitmap;
/* Check what color type this is */
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 = psurfDC->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 */
EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurfDC->ppal, 0xFFFFFF, 0, 0);
/* Translate the color to the target format */
ulColor = XLATEOBJ_iXlate(&exlo.xlo, crColor);
/* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);
return ulColor;
}