Appendix B: Colors
Colors are always saved as four-byte LONG values. If the high byte is zero, then the low three bytes contain a normal RGB COLORREF. Otherwise, the value of the high byte is used as a bitfield of flags (notice that the values below are the indices of the bits that are set).
typedef enum
{
msocolorFlagPaletteIndex, // PALETTEINDEX macro
msocolorFlagPaletteRGB, // PALETTERGB macro
msocolorFlagSystemRGB, // MSOSYSTEMRGB
msocolorFlagSchemeIndex, // MSOSCHEMECOLOR
msocolorFlagSysIndex, // MSOSYSCOLOR
} MSOCOLORINDEX;
Windows defines the first two. The third (SystemRGB) is a flag that it set on an otherwise normal RGB value to indicate to the rendering engine to bypass its normal halftone dithering process and just render the color directly using Windows.
The presence of either of the last two flags indicates that the low three bytes are an index into a predefined array of colors. For SchemeIndex colors, the host application provides the translation to RGB colors when necessary (PowerPoint and Excel both use this). SysIndex colors are indices into colors tracked by Escher itself:
typedef enum
{
msosyscolorButtonFace, // COLOR_BTNFACE
msosyscolorWindowText, // COLOR_WINDOWTEXT
msosyscolorMenu, // COLOR_MENU
msosyscolorHighlight, // COLOR_HIGHLIGHT
msosyscolorHighlightText, // COLOR_HIGHLIGHTTEXT
msosyscolorCaptionText, // COLOR_CAPTIONTEXT
msosyscolorActiveCaption, // COLOR_ACTIVECAPTION
msosyscolorButtonHighlight, // COLOR_BTNHIGHLIGHT
msosyscolorButtonShadow, // COLOR_BTNSHADOW
msosyscolorButtonText, // COLOR_BTNTEXT
msosyscolorGrayText, // COLOR_GRAYTEXT
msosyscolorInactiveCaption, // COLOR_INACTIVECAPTION
msosyscolorInactiveCaptionText, // COLOR_INACTIVECAPTIONTEXT
msosyscolorInfoBackground, // COLOR_INFOBK
msosyscolorInfoText, // COLOR_INFOTEXT
msosyscolorMenuText, // COLOR_MENUTEXT
msosyscolorScrollbar, // COLOR_SCROLLBAR
msosyscolorWindow, // COLOR_WINDOW
msosyscolorWindowFrame, // COLOR_WINDOWFRAME
msosyscolor3DLight, // COLOR_3DLIGHT
msosyscolorMax, // Count of system colors
msocolorFillColor =0xF0, // Use the fillColor property
msocolorLineOrFillColor, // Use the line color only if there is a line
msocolorLineColor, // Use the lineColor property
msocolorShadowColor, // Use the shadow color
msocolorThis, // Use this color (only valid as described below)
msocolorFillBackColor, // Use the fillBackColor property
msocolorLineBackColor, // Use the lineBackColor property
msocolorFillThenLine, // Use the fillColor unless no fill and line
msocolorIndexMask =0xFF, // Extract the color index
msocolorProcessMask =0xFFFF00, // All the processing bits
msocolorModificationMask =0x0F00, // Just the function
msocolorModFlagMask =0xF000, // Just the additional flags
msocolorDarken =0x0100, // Darken color by parameter/255
msocolorLighten =0x0200, // Lighten color by parameter/255
msocolorAdd =0x0300, // Add grey level RGB(param,param,param)
msocolorSubtract =0x0400, // Subtract grey level RGB(p,p,p)
msocolorReverseSubtract =0x0500, // Subtract from grey level RGB(p,p,p)
/* In the following "black" means maximum component value, white minimum.
The operation is per component, to guarantee white combine with
msocolorGray */
msocolorBlackWhite =0x0600, // Black if < uParam, else white (>=)
msocolorInvert =0x2000, // Invert color (at the *end*)
msocolorInvert128 =0x4000, // Invert by toggling the top bit
msocolorGray =0x8000, // Make the color gray (before the above!)
msocolorBParamMask =0xFF0000, // Parameter used as above
msocolorBParamShift =16, // To extract the parameter value
}
MSOSYSCOLORINDEX;