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;