Interlisp-D Color Graphics Revised: 21 Dec. 1982 by Richard R. Burton (Burton.pa) Copyright (c) 1982 by Xerox Corporation Preface This document describes the Interlisp-D facilities for using the color display. Users are encouraged to make comments and suggestions. The color graphics code is stored on the files <lispcore>color> LLCOLOR.DCOM and COLOR.DCOM. To use it you need to have a Dolphin or a Dorado with a color display attached and be running in the `wind' release of Interlisp-D. Introduction The color boards on the Dolphin and the Dorado differ in design. The Dolphin board supports 4 bits per pixel color. The Dorado supports 4 or 8 bits per pixel. (Actually the board supports 24 bpp also but Interlisp-D doesn't yet.) All of the users code should be written in higher level machine independent functions. Both color boards produce an image that is 640 pixels wide by 480 pixels high. The image can be thought of as a paint-by-number painting where the number of a pixel is its value. The number of bits per pixel (4 on the dolphin, 4 or 8 on the dorado) determines the number of difference colors that can be displayed at one time. When there are 4 bpp, 16 colors can be displayed at once. When there are 8 bpp, 256 colors can be displayed at once. A mapping table called a "color map" determines what color actually appears for each pixel value. A color map gives the color in terms of how much of the three primary colors (red, green and blue) displayed on the screen for each possible pixel value. In the following sections, the notions of "color map", and "color" are described. Color Bitmaps A "color bitmap" is actually a bitmap that allows more than one bit per pixel. The datatype BITMAP has been extended to include a number of bits per pixel field named BITMAPBITSPERPIXEL. Thus to test whether a bitmap is a "color bitmap" the following form can be used: (NEQ (fetch (BITMAP BITMAPBITSPERPIXEL) of Var) 1). In multiple bit per pixel bitmaps, the bits which represent a pixel are stored contiguously. BITMAPCREATE was extended to create multiple bit per pixel bitmaps. (BITMAPCREATE Width Height BitsPerPixel) [function] This creates a COLORBITMAP that is Width pixels wide by Height pixels high allowing BitsPerPixel bits per pixel. Currently any value of BitsPerPixel except 1, 4, 8 or NIL (defaults to 1) will cause an error. A 4 bit per pixel color screen bitmap uses approximately 76k of storage. There is only one such bitmap. The following function provides access to it. (COLORSCREENBITMAP) Returns the COLORBITMAP that is being or will be displayed on the color display. This will be NIL if the color display has never been turned on (see COLORDISPLAY below). WHOLECOLORDISPLAY is a global variable set to a REGION that covers the entire color display screen. Currently this is (0 0 640 480). COLORSCREENWIDTH (640) and COLORSCREENHEIGHT (480) are global variables whose values are the dimensions of the color display. Color representations A color map maps a color number ([0 -> 2↑nbits-1]) into the intensities of the three color guns (primary colors red, green and blue). Each entry in the color map has 8 bits for each of the primary colors allowing 256 levels per primary or 2↑24 possible colors (not all of which are distinct to the human eye). Within Interlisp-D programs, colors can be manipulated as numbers, red-green-blue triples, names, or hue-lightness-saturation triples. Any function that takes a color will accept any of the different representations. If a number is given, it will be the color number used in the operation. It must be valid for the color bitmap used in the operation. (Since all of the routines that use a color need to determine its number, it is fastest to use numbers for colors. COLORNUMBERP described below provides a way to translate into numbers from the other representations.) A red-green-blue (RGB) triple is a list of three numbers between 0 and 255. The first element gives the intensity for RED, the second for GREEN and the third for BLUE. When an RGB triple is used, the current color map is searched to find the color with the correct intensities. If none is found, an error is generated. (That is, no attempt is made by the system to assign color numbers to intensities automatically.) Example of an RGB triple is (255 255 255) which gives the color white. The record RGB defined as (RED GREEN BLUE) is provided to manipulate RGB triples. A color name is an atom that is on the A-list COLORNAMES. The CDR of the color name's entry will be used as the color corresponding to the color name. This can be any of the other representations. (Note: It can even be another color name. Loops in the name space such as would be caused by putting '(RED . CRIMSON) and '(CRIMSON . RED) on COLORNAMES are NOT checked for by the system.) Several color names are available in the initial system and are intended to allow color programs written by different users to coexist. These are: name RGB number in default color map BLACK (0 0 0) 0 BLUE (0 0 255) 1 GREEN (0 255 0) 2 CYAN (0 255 255) 3 RED (255 0 0) 4 MAGENTA (255 0 255) 5 YELLOW (255 255 0) 6 WHITE (255 255 255) 7 A hue-lightness-saturation triple is a list of three numbers. The first number (HUE) is between 0 and 355 and indicates a position in degrees on a color wheel (blue at 0, red at 120 and green at 240). The second (LIGHTNESS) is a FLOATP between 0 and 1 which indicates how much total intensity is in the color. The third (SATURATION) is a FLOATP between 0 and 1 which indicates how disparate the three primary levels are. The record HLS defined as (HUE LIGHTNESS SATURATION) is provided to manipulate HLS triples. Example: the color blue is represented in HLS notation by (0 .5 1.0). (COLORNUMBERP Color BitsPerPixel NOERRFLG) Returns the color number (offset into the screen color map) of Color. Color is one of the following: A positive number less than the maximum number of colors. A color name. A RGB triple. A HLS triple. If Color is one of the above and is found in the screen colormap, its color number in the screen color map is returned. If not, an error is generated unless NOERRFLG is non-NIL, in which case NIL is returned. (RGBP X) Returns X if X is an RGB triple; NIL otherwise. (HLSP X) Returns X if X is an HLS triple; NIL otherwise. Color maps The screen color map holds the information about what color is displayed on the color screen for each pixel value in the color screen bitmap. The values in the current screen color map may be changed and this change will be reflected in the colors being displayed at the next vertical retrace (approximately 1/30 of a second). Changing the colormap can be used to get dramatic effects. (COLORMAPCREATE Intensities BitsPerPixel) Creates a color map for a screen that has BitsPerPixel bits per pixel. If BitsPerPixel is NIL, the number of bits per pixel is taken from the current color display setting. Intensities specifies the initial colors that should be in the map. If Intensities is not NIL, it should be a list of color specifications (other than color numbers). e.g. the list of RGB triples returned by the function INTENSITIESFROMCOLORMAP. If Intensities is NIL, the value of the variable \DEFAULTCOLORINTENSITIES is used if BitsPerPixel is 4; the value of the variable \DEFAULT8BITCOLORINTENSITIES if BitsPerPixel is 8. (COLORMAPP ColorMap? BitsPerPixel) Returns ColorMap? if it is a color map that has BitsPerPixel bits per pixel; NIL otherwise. If BitsPerPixel is NIL, it returns ColorMap? if it is either a 4 bpp or an 8 bpp colormap. (INTENSITIESFROMCOLORMAP ColorMap) Returns a list of the intensity levels of ColorMap (default is (SCREENCOLORMAP)) in a form accepted by COLORMAPCREATE. This list can be written on file and thus provides a way of saving color map specifications. (COLORMAPCOPY ColorMap BitsPerPixel) If ColorMap is a color map, it returns a color map that contains the same color intensities as ColorMap; otherwise it returns a color map with default color values. (SCREENCOLORMAP NewColorMap) Reads and sets the color map that is used by the color display. If NewColorMap is non-NIL, it should be a color map and SCREENCOLORMAP sets the system color map to be that color map. The value returned is the value of the screen color map before SCREENCOLORMAP was called. If NewColorMap is NIL, the current screen color map is returned without change. (MAPOFACOLOR Primaries) Returns a color map which is different shades of one or more of the primary colors. For example, (MAPOFACOLOR '(RED GREEN BLUE)) gives a color map of different shades of gray; (MAPOFACOLOR 'RED) gives different shades of red. Changing color maps The following functions are provided to access and change the intensity levels in a color map. (SETCOLORINTENSITY ColorMap ColorNumber ColorSpec) Sets the primary intensities of color number ColorNumber in the color map ColorMap to the ones specified by ColorSpec. ColorSpec can be either an RGB triple, an HLS triple or a color name. The value returned is NIL. (COLORLEVEL ColorMap ColorNumber PrimaryColor NewLevel) Sets and reads the intensity level of the primary color PrimaryColor (RED, GREEN or BLUE) for the color number ColorNumber in the color map ColorMap. If NewLevel is a number between 0 and 255, it is set. The previous value of the intensity of PrimaryColor is returned. (ADJUSTCOLORMAP Primary Delta ColorMap) Adds Delta to the intensity of the Primary color value (RED, GREEN or BLUE) for every color number in ColorMap. (ROTATECOLORMAP ColorMap StartColor ThruColor) Rotates a sequence of colors in ColorMap. The rotation moves the intensity values of color number StartColor into color number StartColor+1, the intensity values of color number StartColor+1 into color number StartColor+2, etc. and ThruColor's values into StartColor. (EDITCOLORMAP Var NoQFlg) Allows interactive editting of a COLORMAPP. If Var is an atom whose value is a COLORMAPP, its value is editted. Otherwise a new color map is created and editted. The color map being editted is made the screen color map while the editting is taking place so that its effects can be observed. The editted color map is returned as the value. If NoQFlg is NIL and the color display is on, the user is asked if they want a test pattern of colors. A yes response will cause the function SHOWCOLORTESTPATTERN to be called which will display a test pattern with blocks of each of the possible colors. The user is prompted for the location of a color control window to be placed on the black and white display. This window allows the value of any of the colors to be changed. The color number of the color being editted is in the upper left part of the window. Six bars are displayed. The right three bars give the color intensities for the three primary colors of the current color number. The left three bars give the value of the color's Hue, Lightness and Saturation parameters. These levels can be changed by positioning the cursor in one of the bars and pressing the LEFT button. While the LEFT button is down, the value of that parameter will track the Y position of the cursor. When the LEFT button is released, the color tracking stops. The color being editted is changed by pressing the MIDDLE button while the cursor is in the interior of the edit window. This will bring up a menu of color numbers. Selecting one sets the current color to the selected color. The color being editted can also be changed by selecting the menu item "PickPt". This will switch the cursor onto the color screen and allow the user to select a point from the color screen. It will then edit the color of the selected point. To stop the editting, move the cursor into the title of the editting window and press the MIDDLE button. This will bring up a menu. Select STOP to quit. Turning the color display on and off The color display can be turned on and off. While the color display is on, the memory used for the color display screen bitmap is locked down and a significant amount of processing time (35% on the dolphin) is used to drive the color display. (COLORDISPLAYP) Returns the current color map if the color display is on; otherwise return NIL. (COLORDISPLAY ColorMapIfOn BitsPerPixel ClearScreenFlg) If ColorMapIfOn is NIL, it turns off the color display. If ColorMapIfOn is non-NIL, it turns on the color display allocating BitsPerPixel bits per pixel. If ColorMapIfOn is of type COLORMAPP or 8BITCOLORMAP, it is used as the screen color map. If ClearScreenFlg is non-NIL, all of the bits in the color screen are set to 0 Turning on the color display requires allocating and locking down the memory necessary to hold the color display screen bitmap and the system color map. Turning the color display off frees this memory. USING COLOR The current color implementation allows display streams to operate on color bitmaps. There are two new functions (DSPCOLOR and DSPBACKCOLOR) which set the color in which a display stream prints or draws. (DSPCOLOR Color DisplayStream) Sets the foreground color of a displaystream. Returns the previous foreground color. If Color is NIL, it returns the current foreground color without changing anything. The default foreground color is 7 which is white in the default color map. (DSPBACKCOLOR Color DisplayStream) Sets the background color of a displaystream. Returns the previous background color. If Color is NIL, it returns the current background color without changing anything. The default background color is 0 which is black in the default color map. The BITBLT, the line and curve drawing routines and the printing routines know how to operate on a display stream that has a color bitmap as their destination. Following are some notes about them. BITBLT If blting from a color bitmap onto another color bitmap of the same bpp, the operations PAINT, INVERT and ERASE are done on a bit level; not on a pixel level. Thus painting color 3 onto color 10 will result in color 11. If blting from a black and white bitmap onto a color bitmap, the 1 bits will appear in the DSPCOLOR and the 0 bits in DSPBACKCOLOR. Currently, REPLACE is the only operation that is supported blting from black and white to color. This operation is fairly expensive; if the same bitmap is going to be put up several times in the same color it is faster to create a color copy then blt the color copy. If the SourceType is TEXTURE and the DestinationBitmap is a color bitmap, the Texture argument is taken to be a color. Thus to fill an area with the color BLUE assuming COLORDS is a display stream whose destination is a color bitmap such as the color screen: (BITBLT NIL NIL NIL COLORDS 50 75 100 200 'TEXTURE 'REPLACE 'BLUE). Curve drawing For the function DRAWCIRCLE, DRAWELLIPSE and DRAWCURVE, the notion of a brush has been extended to include a color. A BRUSH is now (BRUSHSHAPE BRUSHSIZE BRUSHCOLOR). Also the brush can be a bitmap which can be color bitmap. Line drawing The line drawing routines have been extended to take another argument which is the color the line is to appear in if the destination of the display stream is a color bitmap. (DRAWLINE X1 Y1 X2 Y2 WIDTH OPERATION DISPLAYSTREAM COLOR) (DRAWTO X Y WIDTH OPERATION DISPLAYSTREAM COLOR) (RELDRAWTO X Y WIDTH OPERATION DISPLAYSTREAM COLOR) (DRAWBETWEEN POS1 POS2 WIDTH OPERATION DISPLAYSTREAM COLOR) If the COLOR argument is NIL, the DSPFOREGROUNDCOLOR of the display stream is used. Printing Printing only works (currently) in REPLACE mode. The characters will have a background of DSPBACKCOLOR and a foreground color of DSPCOLOR. The first time a character is printed in a new color, the color images corresponding to the current font are calculated and cached. Thus the first character may take a while to appear but succeeding characters print quickly. Example of printing to the color screen. (COLORDISPLAY T 4) ; turn the display on in 4 bpp mode. (SETQ FOO (DSPCREATE (COLORSCREENBITMAP)) ; create a displaystream whose destination is the color screen. (DSPCOLOR 'RED FOO) (PRINT 'HELLO FOO) ;will print in red. Cursor on the color screen The cursor can be moved to the color screen. While on the color screen, the cursor is placed using XOR mode, thus with some color maps it may be hard to see. It is automatically taken down whenever an operation is performed that changes any bits on the color screen. While the cursor is on the color screen, the black and white cursor is cleared. (CHANGECURSORSCREEN ScreenBitmap) ScreenBitmap must be the value of either (COLORSCREENBITMAP) or (SCREENBITMAP). CHANGECURSORSCREEN moves the cursor onto the specified screen. The value returned is the screen bitmap that the cursor was on before CHANGECURSORSCREEN was called. Miscellaneous color functions The following functions provide some common operations on color bitmaps and display streams. (COLORFILL Region ColorNumber ColorDisplayStream Operation) Fills a region in the color bitmap with a color. (COLORFILLAREA Left Bottom Width Height ColorNumber ColorDisplayStream Operation) Fills an area in the color bitmap with a color. (COLORIZEBITMAP BitMap 0Color 1Color NBits) Creates a COLORBITMAP from a BITMAP. The returned COLORBITMAP will have color number 1Color in those pixel of BitMap that were 1 and 0Color in those pixel of BitMap that were 0. This provides a way of producing a color bitmap from a black and white bitmap. Note: this is a fairly expensive operation in terms of both time and space. Demonstration programs (on file COLORDEMO.DCOM) (COLORDEMO) Brings up a menu of color demonstration programs. The system will cycle through the entries on the menu automatically, allowing each to run for a small fixed amount of time (typically 40 seconds). Selecting one of the entries in the menu will cause it to start that program. (COLORDEMO1) Runs the Interlisp-D logo demonstration until a button is pressed then adds color kinetic. The middle button will bring up a menu that allows changing the speed of rotation or editting the color map. The left button will rotate the color map in the kinetic area. (COLORDEMO2 Size) Puts up a test pattern of size Size then rotates the color map. The speed of rotation of the color map is determined by the Y position of the cursor. The middle button will bring up a menu that allows editting of the color map or changing the color map to a map of different shades of one color. (COLORKINETIC Region FirstColor LastColor) Runs color kinetic in a region of the color display using colors FirstColor through LastColor. (TUNNEL Speed) Draws a series of concentric rectangles of increasing size in increasing color numbers. Speed determines the size of the rectangles. This can then be "run" by calling ROTATEIT described below. (MINESHAFT N OutFlg) Draws a series of concentric rectangles of size N in increasing color numbers. OutFlg determines whether the color numbers increase or decrease. This can then be "run" by calling ROTATEIT described below. (WELL N) Draws a series of concentric circles on the color screen in increasing color numbers. The circles will be of size N. This can then be "run" by calling ROTATEIT described below. (SHOWCOLORTESTPATTERN BarSize) Displays a pattern of colors on the color display. This is useful when editting a color map. The pattern has squares of the 16 possible colors layed out in two rows at the top of the screen. Colors 0 through 7 in the top row. Colors 8 through 15 in the next row. The bottom part of the screen is then layered with bars of BarSize width with the consecutive color numbers. The pattern is design so that every color has a border with every other color (unless BarSize is too large to allow room for every color - about 20). (ROTATEIT BeginColor EndColor Wait) Goes into an infinite loop rotating the screen color map. The colors between BeginColor (default 0) and EndColor (default maximum color) are rotated. If Wait is given, (DISMISS Wait) is called each time the color map is changed. This provides an easy way of "animating" screen images. (COLORPOLYDEMO ColorDS) {on the file COLORPOLYGONS.DCOM} Runs a version of the Polygons program on the color screen. Appendix A Format of the Dolphin color maps The form of a color map as desired by the hardware should be of no interest to users but is documented here because as far as I know it is documented no where else. The hardware expects a pointer to a 60 word table whose base must be 16 word aligned. The first two words must be 0. Words 2 thru 49 give the color intensity levels. Each word can be used to set any primary color of any color number but the Interlisp-D implementation (and all others that I know of) use words 2-4 for color 0, words 5-7 for color 1, etc. The format of each word is as follows: bits 0-3 (leftmost): color number indicating which color this sets. bit 4: set if this entry is for RED gun. bit 5: set if this entry is for GREEN gun. bit 6: set if this entry is for BLUE gun. bit 7: ignored bits 8-15 (right byte): Intensity level for the primary gun. Words 50 thru 59 must be 0. In Interlisp-D, 4 additional words are set aside in each color map to insure the 16 word alignment.