898 lines
25 KiB
C++
898 lines
25 KiB
C++
/******************************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);
|
||
}
|