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