Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

897 lines
25 KiB

/******************************Module*Header*******************************\
* Module Name: paleng.cxx
*
* Palette support routines used by NT components.
*
* Created: 27-Nov-1990 12:28:40
* Author: Patrick Haluptzok patrickh
*
* Copyright (c) 1990-1999 Microsoft Corporation
\**************************************************************************/
#include "precomp.hxx"
/******************************Public*Routine******************************\
* GreSetPaletteOwner
*
* Sets the palette owner.
*
\**************************************************************************/
BOOL
GreSetPaletteOwner(
HPALETTE hpal,
W32PID lPid)
{
BOOL bRet = FALSE;
if (hpal==(HPALETTE)STOCKOBJ_PAL)
{
WARNING("GreSetPaletteOwner: Cannot set owner for the stock Palette\n");
}
else
{
bRet = HmgSetOwner((HOBJ)hpal,lPid,PAL_TYPE);
}
return (bRet);
}
/******************************Public*Routine******************************\
* CreateSurfacePal
*
* Turns a physical palette into a palette managed palette for a device.
*
* History:
* Tue 04-Dec-1990 -by- Patrick Haluptzok [patrickh]
* Wrote it.
\**************************************************************************/
BOOL CreateSurfacePal(XEPALOBJ palSrc, FLONG iPalType, ULONG ulNumReserved, ULONG ulNumPalReg)
{
ASSERTGDI(iPalType == PAL_MANAGED, "ERROR: CreateSurfacePalette passed bad iPalType\n");
ASSERTGDI(palSrc.bValid(), "ERROR CreateSurfacePal palSrc");
ASSERTGDI(palSrc.cEntries() != 0, "ERROR CreateSurfacePal");
//
// If it is a Palette managed surface we must keep an exact
// copy of it's origal state for certain functionality.
//
PALMEMOBJ pal;
BOOL b;
b = pal.bCreatePalette(palSrc.iPalMode(),
palSrc.cEntries(),
(PULONG) palSrc.apalColorGet(),
0,
0,
0,
iPalType);
if (b)
{
ASSERTGDI(pal.bIsIndexed(), "Creating a non-indexed managed surface ???");
ASSERTGDI(pal.bIsPalManaged(), "ERROR PAL_MANaged not pal managed");
//
// Now we have to set the type or the source to be PAL_MANAGED.
//
palSrc.flPalSet((palSrc.flPal() & ~(PAL_FIXED)) | PAL_MANAGED);
//
// Set the used and foreground flags on the reserved palette entries.
//
PAL_ULONG palTemp;
ASSERTGDI((ulNumReserved & 0x00001) == 0, "ERROR non multiple of 2 reserved colors");
palSrc.ulNumReserved(ulNumReserved);
pal.ulNumReserved(ulNumReserved);
ulNumReserved >>= 1;
ULONG iPalMode;
for (iPalMode = 0; iPalMode < ulNumReserved; iPalMode++)
{
palTemp.ul = pal.ulEntryGet(iPalMode);
palTemp.pal.peFlags = (PC_FOREGROUND | PC_USED);
pal.ulEntrySet(iPalMode, palTemp.ul);
palTemp.ul = pal.ulEntryGet(iPalMode + (ulNumPalReg - ulNumReserved));
palTemp.pal.peFlags = (PC_FOREGROUND | PC_USED);
pal.ulEntrySet(iPalMode + (ulNumPalReg - ulNumReserved), palTemp.ul);
}
//
// Ok the palette is in perfect initial shape, copy it.
//
palSrc.vCopyEntriesFrom(pal);
palSrc.ppalOriginal(pal.ppalGet());
pal.ulTime(palSrc.ulTime());
pal.vKeepIt();
}
return(b);
}
/******************************Public*Routine******************************\
* ulGetNearestIndexFromColorref
*
* Given the surface palette and the DC palette, this returns the index in
* palSurf that crColor maps to.
*
* Modifies: Nothing.
*
* Returns: Index in palSurf that crColor maps to.
*
* PALETTERGB puts a 2 in the high byte.
* PALETTEINDEX puts a 1 in the high byte.
*
* History:
* Mon 02-Sep-1991 -by- Patrick Haluptzok [patrickh]
* Wrote it.
\**************************************************************************/
ULONG
ulGetNearestIndexFromColorref(
XEPALOBJ palSurf,
XEPALOBJ palDC,
ULONG crColor,
ULONG seSearchExactFirst)
{
ASSERTGDI(palDC.bValid(), "ERROR invalid palDC");
PDEV *ppdev = (PDEV *)palDC.hdev();
PAL_ULONG palTemp;
palTemp.ul = crColor;
//
// Check if it's palette managed. If it's a device bitmap for a palette managed
// device it will have an invalid palette. If the palettes valid then it may be
// the palette managed device's palette.
//
if ((!palSurf.bValid()) || (palSurf.bIsPalManaged()))
{
//
// RGB: Match to default palette or dither
//
// PALETTERGB: Match RGB value to nearest entry in palette
//
// PALETTEINDEX: The low 16 bits is a direct index to a palette entry
//
//
// Check if it's a color forces us to access the xlate
//
if (palTemp.ul & 0x03000000)
{
if (palTemp.ul & 0x01000000)
{
//
// PALETTEINDEX:
//
// This means they have an explicit entry in the DC palette they want
//
palTemp.pal.peFlags = 0;
if (palTemp.ul >= palDC.cEntries())
{
palTemp.ul = 0;
}
}
else
{
//
// PALETTERGB:
//
// Get rid of the top byte first. It's 0x02 and we want to
// search with this being an RGB.
//
palTemp.pal.peFlags = 0;
palTemp.ul = palDC.ulGetNearestFromPalentry(
palTemp.pal,
seSearchExactFirst
);
}
//
// If the DC's palette is the default palette, adjust if this is in the
// top 10 colors, then we're done, because there's no translation of
// the default palette
//
if (palDC.bIsPalDefault())
{
if (palTemp.ul >= 10)
{
palTemp.ul = palTemp.ul + 236;
}
return(palTemp.ul);
}
//
// Now do the right thing based on whether we are on the device bitmap
// or the device surface.
//
if ((palSurf.bValid()) && (palDC.ptransCurrent() != NULL))
{
return(palDC.ulTranslateDCtoCurrent(palTemp.ul));
}
if ((!palSurf.bValid()) && (palDC.ptransFore() != NULL))
{
return(palDC.ulTranslateDCtoFore(palTemp.ul));
}
//
// App is in hosed state which is possible in multi-tasking system.
// Map as best we can into static colors, get the RGB from palDC.
//
palTemp.pal = palDC.palentryGet(palTemp.ul);
//
// If PC_EXPLICIT is set just return value modulo 256.
//
if (palTemp.pal.peFlags == PC_EXPLICIT)
{
return(palTemp.ul & 0x000000FF);
}
}
//
// check for DIBINDEX
//
if ((palTemp.ul & 0x10ff0000) == 0x10ff0000)
{
return(palTemp.ul & 0x000000FF);
}
//
// At this point palTemp is an RGB value
//
// Well we need to match against the default palette. We quickly
// check for black and white and pass the rest through.
//
palTemp.pal.peFlags = 0;
if (palTemp.ul == 0xFFFFFF)
{
palTemp.ul = 19;
}
else if (palTemp.ul != 0)
{
palTemp.ul =
((XEPALOBJ) ppalDefault).ulGetNearestFromPalentry(
palTemp.pal,
seSearchExactFirst
);
}
if (palTemp.ul >= 10)
{
palTemp.ul = palTemp.ul + 236;
}
return(palTemp.ul);
}
//
// This means they are not palette managed.
//
if (palTemp.ul & 0x01000000)
{
//
// PALETTEINDEX:
// This means they have an explicit entry in the DC palette they want.
//
palTemp.ul &= 0x0000FFFF;
if (palTemp.ul >= palDC.cEntries())
{
palTemp.ul = 0;
}
palTemp.pal = palDC.palentryGet(palTemp.ul);
}
else if ((palTemp.ul & 0x10ff0000) == 0x10ff0000)
{
//
// check for DIBINDEX
//
palTemp.ul &= 0x000000FF;
return((palTemp.ul >= palSurf.cEntries()) ? 0 : palTemp.ul);
}
else
{
//
// We just look for the closest RGB.
//
palTemp.pal.peFlags = 0;
}
//
// Now it is time to look in the surface palette for the matching color.
//
return(palSurf.ulGetNearestFromPalentry(palTemp.pal, seSearchExactFirst));
}
/******************************Public*Routine******************************\
* ulGetMatchingIndexFromColorref
*
* Given the surface palette and the DC palette, this returns the index in
* palSurf that crColor maps to exactly, or 0xFFFFFFFF if it doesn't map
* exactly to any color. Note that if the "find nearest in palette managed"
* bit (0x20000000) is set, the nearest color qualifies as a match, because
* that's what they're asking for. However, there is no guarantee that either
* of the special bits will result in a match, because the palette may be in
* an incorrect state or they could be asking for a direct index into the DC
* palette that produces a color that's not in the surface's palette (in the
* case of a non-palette-managed surface).
*
* Modifies: Nothing.
*
* Returns: Index in palSurf that crColor maps to.
*
* PALETTERGB puts a 2 in the high byte (find nearest)
* PALETTEINDEX puts a 1 in the high byte (find specified index)
*
* History:
* Sun 27-Dec-1992 -by- Michael Abrash [mikeab]
* Wrote it.
\**************************************************************************/
ULONG
ulGetMatchingIndexFromColorref(
XEPALOBJ palSurf,
XEPALOBJ palDC,
ULONG crColor
)
{
ASSERTGDI(palDC.bValid(), "ERROR invalid palDC");
PAL_ULONG palTemp;
PDEV *ppdev = (PDEV *)palDC.hdev();
palTemp.ul = crColor;
//
// Check if it's palette managed. If it's a device bitmap for a palette managed
// device it will have an invalid palette. If the palette's valid then it may be
// the palette managed device's palette.
//
if ((!palSurf.bValid()) || (palSurf.bIsPalManaged()))
{
//
// RGB: Match to default palette or dither
//
// PALETTERGB: Match RGB value to nearest entry in palette
//
// PALETTEINDEX: The low 16 bits is a direct index to a palette entry
//
//
// Check if it's a color forces us to access the xlate
//
if (palTemp.ul & 0x03000000)
{
if (palTemp.ul & 0x01000000)
{
//
// PALETTEINDEX:
//
// This means they have an explicit entry in the DC palette they
// want; only the lower byte is valid
//
palTemp.ul &= 0x0000FFFF;
if (palTemp.ul >= palDC.cEntries())
{
palTemp.ul = 0;
}
}
else // (palTemp.ul & 0x02000000)
{
//
// Get rid of the top byte first. It's 0x02 and we want to search
// the DC's palette for the nearest match with this being an RGB.
// Note that in this case the nearest match and exact match are
// logically equivalent
//
palTemp.pal.peFlags = 0;
palTemp.ul = palDC.ulGetNearestFromPalentry(palTemp.pal);
}
//
// If the DC's palette is the default palette, adjust if this is in the
// top 10 colors, then we're done, because there's no translation of
// the default palette
//
if (palDC.bIsPalDefault())
{
if (palTemp.ul >= 10)
{
palTemp.ul = palTemp.ul + 236;
}
return(palTemp.ul);
}
//
// Now do the right thing based on whether we are on the device bitmap
// or the device surface
//
if ((palSurf.bValid()) && (palDC.ptransCurrent() != NULL))
{
//
// We're drawing to a palette managed device surface, using the
// current translation (which may be either back or fore, depending
// on whether the application is in the foreground and owns the
// palette)
//
return(palDC.ulTranslateDCtoCurrent(palTemp.ul));
}
if ((!palSurf.bValid()) && (palDC.ptransFore() != NULL))
{
//
// We're drawing to a bitmap for a palette managed device, using
// the fore translation (always treat drawing to a bitmap as
// foreground drawing)
//
return(palDC.ulTranslateDCtoFore(palTemp.ul));
}
//
// App is in hosed state which is possible in multi-tasking system.
// Map as best we can into static colors, get the RGB from palDC and
// try to find that in the default palette
//
palTemp.pal = palDC.palentryGet(palTemp.ul);
//
// If PC_EXPLICIT is set just return value modulo 256.
//
if (palTemp.pal.peFlags == PC_EXPLICIT)
{
return(palTemp.ul & 0x000000FF);
}
}
//
// check for DIBINDEX
//
if ((palTemp.ul & 0x10ff0000) == 0x10ff0000)
{
return(palTemp.ul & 0x000000FF);
}
//
// Well, we're palette managed and have a plain old RGB (or failed to
// find the desired translation), so we need to match against the
// default palette. We quickly check for black and white and pass
// the rest through.
//
palTemp.pal.peFlags = 0;
if (palTemp.ul == 0xFFFFFF)
{
palTemp.ul = 19;
}
else if (palTemp.ul != 0)
{
palTemp.ul = ((XEPALOBJ) ppalDefault).ulGetMatchFromPalentry(palTemp.pal);
}
//
// If we're in the top half of the default palette, adjust to the high end
// of the 256-color palette, where the top half of the default palette
// actually resides
//
if ((palTemp.ul != 0xFFFFFFFF) && (palTemp.ul >= 10))
{
palTemp.ul = palTemp.ul + 236;
}
return(palTemp.ul);
}
//
// Not palette managed.
//
if (palTemp.ul & 0x01000000)
{
//
// This means they have an explicit entry in the DC palette they want.
// Limit the maximum explicit entry to 8 bits.
//
palTemp.ul &= 0x0000FFFF;
//
// If the index is off the end of the palette, wrap it modulo the palette
// length.
//
if (palTemp.ul >= palDC.cEntries())
{
palTemp.ul = 0;
}
//
// Search the palette for the color closest to the color selected from the
// DC palette by the specified index
//
palTemp.pal = palDC.palentryGet(palTemp.ul);
}
else if ((palTemp.ul & 0x10ff0000) == 0x10ff0000)
{
//
// check for DIBINDEX
//
palTemp.ul &= 0x000000FF;
return((palTemp.ul >= palSurf.cEntries()) ? 0 : palTemp.ul);
}
else
{
//
// We just look for the closest RGB; mask off the flags.
//
palTemp.pal.peFlags = 0;
}
//
// Now it is time to look in the surface palette for the matching color.
//
return(palSurf.ulGetMatchFromPalentry(palTemp.pal));
}
/******************************Public*Routine******************************\
* ulColorRefToRGB
*
* Given a color ref this returns the RGB it corresponds to.
*
* This is a helper function given a color ref that may contain
* DIBINDEX value, do the appropriate translation of the DIBINDEX.
*
* History:
* 19-Jan-2001 -by- Barton House bhouse
* Wrote it.
\**************************************************************************/
ULONG
ulColorRefToRGB(
XEPALOBJ palSurf,
XEPALOBJ palDC,
ULONG iColorRef
)
{
if((iColorRef & 0x10FF0000) == 0x10FF0000)
{
return ulIndexToRGB(palSurf, palDC, iColorRef & 0xFF);
}
else
{
return iColorRef;
}
}
/******************************Public*Routine******************************\
* ulIndexToRGB
*
* Given an index this returns the RGB it corresponds to.
*
* History:
* 21-Nov-1992 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
ULONG
ulIndexToRGB(
XEPALOBJ palSurf,
XEPALOBJ palDC,
ULONG iSolidColor
)
{
ASSERTGDI(palDC.bValid(), "ERROR invalid palDC");
PAL_ULONG palTemp;
if (palSurf.bValid())
{
return(palSurf.ulIndexToRGB(iSolidColor));
}
//
// It's a palette managed device bitmap.
//
if (iSolidColor < 10)
{
palTemp.pal = logDefaultPal.palPalEntry[iSolidColor];
return(palTemp.ul);
}
if (iSolidColor > 245)
{
palTemp.pal = logDefaultPal.palPalEntry[iSolidColor - 236];
return(palTemp.ul);
}
//
// Well it's the first entry in the logical palette that mapped here in the
// foreground xlate. If the foreground Xlate is invalid, who knows, return 0.
//
SEMOBJ semo(ghsemPalette);
if (palDC.ptransFore() != NULL)
{
PBYTE pjTemp = palDC.ptransFore()->ajVector;
palTemp.ul = palDC.cEntries();
for (palTemp.ul = 0; palTemp.ul < palDC.cEntries(); palTemp.ul++,pjTemp++)
{
if (*pjTemp == ((BYTE) iSolidColor))
return(palDC.ulEntryGet(palTemp.ul));
}
}
//
// Well we just don't know.
//
return(0);
}
/******************************Public*Routine******************************\
* bIsCompatible
*
* This returns TRUE if the bitmap can be selected into this PDEV's memory
* DC's based on "Can we determine the color information". It also returns
* the palette you could use for a reference for color information.
*
* History:
* 28-Jan-1993 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
BOOL bIsCompatible(PPALETTE *pppalReference, PPALETTE ppalBM, SURFACE *pSurfBM, HDEV hdev)
{
BOOL bRet = TRUE;
XEPALOBJ palBM(ppalBM);
PDEVOBJ po(hdev);
// We need to make sure this could be selected into this DC. If it is a device
// managed bitmap, it must be the same device.
if (((pSurfBM->iType() != STYPE_BITMAP) || (pSurfBM->dhsurf() != 0)) &&
(pSurfBM->hdev() != hdev))
{
WARNING1("bIsCompatible failed Device surface for another PDEV\n");
bRet = FALSE;
}
else if (palBM.bValid())
{
// No problem, we already have color information.
*pppalReference = palBM.ppalGet();
}
else if (pSurfBM->iFormat() != po.iDitherFormat())
{
// Check surface is compatible with PDEV for selection.
WARNING1("bIsCompatible: Bitmap not compatible with DC\n");
bRet = FALSE;
}
else
{
// If it's not palette managed set in palette for the device. Otherwise
// leave it NULL and the right stuff will happen.
if (!po.bIsPalManaged())
{
*pppalReference = po.ppalSurf();
}
else
{
*pppalReference = (PPALETTE) NULL;
ASSERTGDI(po.iDitherFormat() == BMF_8BPP, "ERROR GetDIBits no palette not 8BPP");
}
}
return(bRet);
}
/******************************Public*Routine******************************\
* rgbFromColorref
*
* Given the surface palette and the DC palette, this returns the rgb that
* this colorref represents.
*
* Returns: RGB that crColor maps to.
*
* PALETTERGB puts a 2 in the high byte (find nearest)
* PALETTEINDEX puts a 1 in the high byte (find specified index)
*
* History:
* Thu 18-Feb-1993 -by- Patrick Haluptzok [patrickh]
* Wrote it.
\**************************************************************************/
ULONG
rgbFromColorref(
XEPALOBJ palSurf,
XEPALOBJ palDC,
ULONG crColor
)
{
ASSERTGDI(palDC.bValid(), "ERROR invalid palDC");
PAL_ULONG palTemp;
palTemp.ul = crColor;
if (palTemp.ul & 0x01000000)
{
//
// This means they have an explicit entry in the DC palette they
// want. Only the lower byte is valid.
//
palTemp.ul &= 0x0000FFFF;
if (palTemp.ul >= palDC.cEntries())
{
palTemp.ul = 0;
}
palTemp.pal = palDC.palentryGet(palTemp.ul);
//
// If PC_EXPLICIT reach into the surface palette if possible.
//
if (palTemp.pal.peFlags == PC_EXPLICIT)
{
if (palSurf.bValid())
{
if (palSurf.cEntries())
{
palTemp.ul &= 0x000000FF;
if (palTemp.ul >= palSurf.cEntries())
{
palTemp.ul = palTemp.ul % palSurf.cEntries();
}
palTemp.pal = palSurf.palentryGet(palTemp.ul);
}
}
}
}
palTemp.pal.peFlags = 0;
return(palTemp.ul);
}
/******************************Public*Routine******************************\
* bEqualRGB_In_Palette
*
* This function determines if 2 palettes contain identical RGB entries and
* palette sizes and therefore have an identity xlate between them. This is
* need with DIBSECTIONS which may have duplicate palette entries but still
* should have identity xlates when blting between them.
*
* History:
* 10-Mar-1994 -by- Patrick Haluptzok patrickh
* Wrote it.
\**************************************************************************/
BOOL bEqualRGB_In_Palette(XEPALOBJ palSrc, XEPALOBJ palDst)
{
ASSERTGDI(palSrc.bValid(), "ERROR invalid SRC");
ASSERTGDI(palDst.bValid(), "ERROR invalid DST");
//
// Check for equal size palettes that are == to 256 in size.
// 256 is the size of our palette managed palettes.
//
if ((palSrc.cEntries() != palDst.cEntries()) ||
(palDst.cEntries() != 256))
{
return(FALSE);
}
//
// If the Dst is a DC palette make sure it contains an identity
// realization in it.
//
UINT uiIndex;
if (palDst.bIsPalDC())
{
//
// Check the translate for the current if it's the screen, otherwise
// check the translate for the foreground for a bitmap.
//
TRANSLATE *ptrans = palDst.ptransFore();
if (ptrans == NULL)
return(FALSE);
uiIndex = palDst.cEntries();
while(uiIndex--)
{
if (ptrans->ajVector[uiIndex] != uiIndex)
return(FALSE);
}
}
uiIndex = palDst.cEntries();
ULONG ulTemp;
while(uiIndex--)
{
ulTemp = palSrc.ulEntryGet(uiIndex) ^ palDst.ulEntryGet(uiIndex);
if (ulTemp & 0xFFFFFF)
{
return(FALSE);
}
}
return(TRUE);
}