Hi, attached to this mail the second part, color management. Coments will be welcome (really I don't know GRX internals a lot).
M.Alvarez
Color management
GRX defines the type 'GrColor' for color variables. 'GrColor' it's a 32 bits integer. The 8 left bits are reserved for the write mode (see below). The 24 bits right are the color value.
The library supports two models for color management. In the 'indirect' (or color table) mode, color values are indices to a color table. The color table slots will be allocated with the highest resolution supported by the hardware (EGA: 2 bits, VGA: 6 bits) with respect to the component color intensities. In the 'direct' (or RGB) mode, color values map directly into component color intensities with non-overlapping bitfields of the color index representing the component colors.
Color table model is supported until 256 color modes. The RGB model is supported in 256 color and up color modes.
In RGB mode the color index map to component color intensities depend on the video mode set, so it can't be assumed the component color bitfields (but if you are curious check the GrColorInfo global structure in "grx20.h").
After the first 'GrSetMode' call two colors are always defined: black and white. The color values of these two colors are returned by the functions:
GrColor GrBlack(void); GrColor GrWhite(void);
GrBlack() is guaranteed to be 0.
The library supports five write modes (a write mode descibes the operation between the actual bit color and the one to be set): write, XOR, logical OR, logical AND and IMAGE. These can be selected with OR-ing the color value with one of the following constants declared in "grx20.h":
#define GrWRITE 0UL /* write color */ #define GrXOR 0x01000000UL /* to "XOR" any color to the screen */ #define GrOR 0x02000000UL /* to "OR" to the screen */ #define GrAND 0x03000000UL /* to "AND" to the screen */ #define GrIMAGE 0x04000000UL /* BLIT: write, except given color */
The 'GrIMAGE' write mode only works with the 'bitblt' function.
By convention, the no-op color is obtained by combining color value 0 (black) with the XOR operation. This no-op color has been defined in "grx20.h" as:
#define GrNOCOLOR (GrXOR | 0) /* GrNOCOLOR is used for "no" color */
The write mode part and the color value part of a 'GrColor' variable can be obtained OR-ing it with one of the following constants declared in "grx20.h":
#define GrCVALUEMASK 0x00ffffffUL /* color value mask */ #define GrCMODEMASK 0xff000000UL /* color operation mask */
The number of colors in the current graphics mode is returned by the:
GrColor GrNumColors(void);
function, while the number of unused, available color can be obtained by calling:
GrColor GrNumFreeColors(void);
Colors can be allocated with the:
GrColor GrAllocColor(int r,int g,int b);
function (component intensities can range from 0 to 255), or with the:
GrColor GrAllocCell(void);
function. In the second case the component intensities of the returned color can be set with:
void GrSetColor(GrColor color,int r,int g,int b);
In the color table model both 'Alloc' functions return 'GrNOCOLOR' if there are no more free colors available. In the RGB model 'GrNumFreeColors' returns 0 and 'GrAllocCell' always returns 'GrNOCOLOR', as colors returned by 'GrAllocCell' are meant to be changed -- what is not supposed to be done in RGB mode. Also note that 'GrAllocColor' operates much more efficiently in RGB mode, and that it never returns 'GrNOCOLOR' in this case.
Color table entries can be freed (when not in RGB mode) by calling:
void GrFreeColor(GrColor color);
The component intensities of any color can be queried using the function:
void GrQueryColor(GrColor c,int *r,int *g,int *b);
Initially the color system is in color table (indirect) model if there are 256 or less colors. 256 color modes can be put into the RGB model by calling:
void GrSetRGBcolorMode(void);
The color system can be reset (i.e. put back into color table model if possible, all colors freed except for black and white) by calling:
void GrResetColors(void);
The function:
void GrRefreshColors(void);
reloads the currently allocated color values into the video hardware. This function is not needed in typical applications, unless the display adapter is programmed directly by the application.
This functions:
GrColor GrAllocColorID(int r,int g,int b); void GrQueryColorID(GrColor c,int *r,int *g,int *b);
are inlined versions (except if you compile GRX with 'GRX_SKIP_INLINES' defined) to be used in the RGB model (in the color table model they call the normal routines).
Portable use of a few colors
People that only want to use a few colors find the GRX color handling a bit confusing, but it gives the power to manage a lot of color deeps and two color models. Here are some guidelines to easily use the famous 16 ega colors in GRX programs. We need this GRX function:
GrColor *GrAllocEgaColors(void);
it returns a 16 GrColor array with the 16 ega colors alloced (really it's a trivial function, read the source "src/setup/colorega.c"). We can use a construction like that:
First, in your C code make a global pointer, and init it after set the graphics mode:
GrColor *egacolors; .... int your_setup_function( ... ) { ... GrSetMode( ... ) ... egacolors = GrAllocEgaColors(); ... }
Next, add this to your main include file:
extern GrColor *egacolors; #define BLACK egacolors[0] #define BLUE egacolors[1] #define GREEN egacolors[2] #define CYAN egacolors[3] #define RED egacolors[4] #define MAGENTA egacolors[5] #define BROWN egacolors[6] #define LIGHTGRAY egacolors[7] #define DARKGRAY egacolors[8] #define LIGHTBLUE egacolors[9] #define LIGHTGREEN egacolors[10] #define LIGHTCYAN egacolors[11] #define LIGHTRED egacolors[12] #define LIGHTMAGENTA egacolors[13] #define YELLOW egacolors[14] #define WHITE egacolors[15]
Now you can use the defined colors in your code. Note that if you are in color table model in a 16 color mode, you have exhausted the color table. Note too that this don't work to initialize static variables with a color, because 'egacolors' is not initialized.