The Implementation of Device-Independent Graphics Through Imagestreams filed as {Eris}Internal>Doc>DIGguide.TEdit written by Herb Jellinek on 2 November 1984 last revision on 26 February 1985 The Interlisp-D system does all image creation through a set of functions and data structures for device-independent graphics, known popularly as DIG. DIG is achieved throught the use of a special flavor of stream, known as an imagestream. An imagestream, by convention, is any stream that has its IMAGEOPS field (described in detail below) set to a vector of meaningful graphical operations. Using imagestreams, we can write programs that draw and print on an output stream without regard to the underlying device, be it window, disk, Dover, 8044 or Diablo printers. For example, the following have imagestreams backing them: windows, Press streams, Interpress streams, and Iris streams. Imagestream structure As indicated above, imagestreams use a field that no other stream does: IMAGEOPS. IMAGEOPS is an instance of the IMAGEOPS datatype, and contains a vector of the stream's graphical methods. The methods contained in the IMAGEOPS can make arbitrary use of the stream's IMAGEDATA field, which is provided for their use, and may contain any data needed. IMAGEOPS [Datatype] The IMAGEOPS datatype has the following fields: IMAGETYPE The name of image type. Monochrome display streams have an IMAGETYPE of DISPLAY; color display streams are identified as (COLOR DISPLAY). The IMAGETYPE is informational, and can be set to anything the implementor chooses. IMFONTCREATE The device name to pass to FONTCREATE when fonts are created for the stream. The following fields are all stream methods, and are presented with their arguments, in the manner of a function definition. With the exception of IMCLOSEFN, each method that follows has a corresponding function that consists of the method's name with the "IM" prefix removed. All coordinates that refer to points in a display device's space are measured in the device's units. (The IMSCALE method provides access to a device's scale.) (IMCLOSEFN STREAM) What to do before stream is CLOSEFed, e.g. flush buffers, write header or trailer information, etc. (IMDRAWLINE STREAM X1 Y1 X2 Y2 WIDTH OPERATION COLOR) Draws a line of width WIDTH from (X1, Y1) to (X2, Y2). (Dashing is currently handled at a higher level, and thus is not an argument). (IMDRAWCURVE STREAM KNOTS CLOSED BRUSH DASHING) Draws a curve through KNOTS. (IMDRAWCIRCLE STREAM CENTERX CENTERY RADIUS BRUSH DASHING) Draws a circle of radius RADIUS around (CENTERX, CENTERY). (IMDRAWELLIPSE STREAM CENTERX CENTERY SEMIMINORRADIUS SEMIMAJORRADIUS ORIENTATION BRUSH DASHING) Draws an ellipse around (CENTERX, CENTERY). (IMFILLCIRCLE STREAM CENTERX CENTERY RADIUS TEXTURE) Draws a circle filled with texture TEXTURE around (CENTERX, CENTERY). (IMBLTSHADE TEXTURE STREAM DESTINATIONLEFT DESTINATIONBOTTOM WIDTH HEIGHT OPERATION CLIPPINGREGION) The texture-source case of BITBLT. DESTINATIONLEFT, DESTINATIONBOTTOM, WIDTH, HEIGHT, and CLIPPINGREGION are measured in STREAM's units. This method is invoked by the functions BITBLT and BLTSHADE. (IMBITBLT SOURCEBITMAP SOURCELEFT SOURCEBOTTOM STREAM DESTINATIONLEFT DESTINATIONBOTTOM WIDTH HEIGHT SOURCETYPE OPERATION TEXTURE CLIPPINGREGION CLIPPEDSOURCELEFT CLIPPEDSOURCEBOTTOM) The bitmap-source cases of BITBLT. SOURCELEFT, SOURCEBOTTOM, CLIPPEDSOURCELEFT, CLIPPEDSOURCEBOTTOM, WIDTH, and HEIGHT are measured in pixels; DESTINATIONLEFT, DESTINATIONBOTTOM, and CLIPPINGREGION are in the units of the destination stream. (IMSCALEDBITBLT SOURCEBITMAP SOURCELEFT SOURCEBOTTOM STREAM DESTINATIONLEFT DESTINATIONBOTTOM WIDTH HEIGHT SOURCETYPE OPERATION TEXTURE CLIPPINGREGION CLIPPEDSOURCELEFT CLIPPEDSOURCEBOTTOM SCALE ) A scaled version of IMBITBLT. Each pixel in SOURCEBITMAP is replicated SCALE times in the X and Y directions; currently, SCALE must be an integer. (IMMOVETO STREAM X Y) Move to (X,Y). This method is invoked by the functions MOVETO and RELMOVETO. If it is not supplied, a default method composed of calls to the IMXPOSITION and IMYPOSITION methods is used. (IMTERPRI STREAM) (As yet unused.) Issue a newline. When implemented, this method will be invoked by the function TERPRI. It defaults to (\OUTCHAR STREAM (CHARCODE EOL)). (IMSTRINGWIDTH STREAM STR RDTBL) Returns the width of string STR in STREAM's units, using STREAM's current font. If this method is not supplied, it defaults to calling \STRINGWIDTH.GENERIC. (IMCHARWIDTH STREAM CHARCODE) Returns the width of character CHARCODE in STREAM's units. If this method is not supplied, it defaults to calling \STRINGWIDTH.GENERIC. The following methods all have corresponding DSPxx functions (e.g. IMYPOSITION corresponds to DSPYPOSITION) that invoke them. They also have the property that they return their previous value; when called with NIL they return the old value without changing it. (IMXPOSITION STREAM XPOSITION) Sets new x-position on STREAM. (IMYPOSITION STREAM YPOSITION) Sets new y-position on STREAM. (IMFONT STREAM FONT) Sets STREAM's font to be FONT. (IMLEFTMARGIN STREAM LEFTMARGIN) Sets STREAM's left margin to be LEFTMARGIN. The left margin is defined as the x position set after newline. (IMRIGHTMARGIN STREAM RIGHTMARGIN) Sets STREAM's right margin to be RIGHTMARGIN. The right margin is defined as the maximum x position at which characters will be printed; printing beyond it causes a newline. (IMLINEFEED STREAM DELTA) Sets STREAM's linefeed distance (distance to move vertically after a newline) to be DELTA. (IMNEWPAGE STREAM) Causes a new page to be started; the position is set to (DSPLEFTMARGIN, DSPTOPMARGIN). If not supplied, defaults to (\OUTCHAR STREAM (CHARCODE ^L)). (IMSCALE STREAM SCALE) Returns the number of device points per screen point (a screen point being ~1/72 inch). In a later release of Interlisp-D the conversion factor will be specifiable. (I.e. right now SCALE is ignored.) (IMTOPMARGIN STREAM YPOSITION) Sets STREAM's top margin (the y-position of the tops of characters that is set after newpage) to be YPOSITION. (IMBOTTOMMARGIN STREAM YPOSITION) Sets STREAM's bottom margin (the y-position beyond which any printing causes a newpage) to be YPOSITION. (IMSPACEFACTOR STREAM FACTOR) Sets the amount by which to multiply the natural width of all following space characters on STREAM: used for justification of text. The default value is 1. For example, if the natural width of a space in STREAM's current font is 12 units, and the spacefactor is set to 2, spaces will appear 24 units wide. The values returned by STRINGWIDTH and CHARWIDTH will also be affected. (IMOPERATION STREAM OPERATION) Sets the default BITBLT OPERATION argument. See the DSPOPERATION and BITBLT documentation for more information. (IMBACKCOLOR STREAM COLOR) Sets the background color of STREAM. (IMCOLOR STREAM COLOR) Sets the default color of STREAM. In addition to the IMAGEOPS-borne methods described above, there are two other important methods, which are contained in the stream itself. STRMBOUTFN [Stream Method] Function called by BOUT. You can install a STRMBOUTFN in a stream STREAM using the form (replace (STREAM STRMBOUTFN) of STREAM with (FUNCTION MYBOUTFN)). OUTCHARFN [Stream Method] This is the function that is called to output a single byte. This is like STRMBOUTFN, except for being one level higher: it is intended for text output. Hence, this function should convert (CHARCODE EOL) into the stream's actual end of line sequence, and should adjust the stream's CHARPOSITION appropriately before invoking the stream's STRMBOUTFN (by calling BOUT) to actually put the character. Defaults to \FILEOUTCHARFN, which is definitely NOT what you want. OUTCHARFNs are installed using a form like (replace (STREAM OUTCHARFN) of STREAM with (FUNCTION MYOUTCHARFN)). IMAGEDATA [Record field] Used to hold data pertaining to this type of imagestream; the content is completely up to the implementor. For Interpress devices, this is an instance of the datatype INTERPRESSDATA; for Press, PRESSDATA; for the display, \DISPLAYDATA. Creating imagestreams (OPENIMAGESTREAM FILE IMAGETYPE OPTIONS) [function] Opens and returns an output stream of type IMAGETYPE (PRESS, INTERPRESS, DISPLAY or other types) on a destination specified by FILE. FILE can name a file either on a normal storage device or on a printer device. In the latter case, the file is sent to the printer when the stream is closed. Because of the way that defaulted arguments are interpreted, OPENIMAGESTREAM provides a convenient and standard interface for interpreting user output-destination specifications. If IMAGETYPE is NIL, the image type is inferred from the extension field of FILE and the EXTENSIONS properties in the list PRINTFILETYPES. Thus, a PRESS extension denotes a Press-format stream, while IP, IPR, and INTERPRESS indicate Interpress format. If FILE has no extension but is a file on the printer device {LPT}, then IMAGETYPE will be the type that the indicated printer can print. If FILE has no extension but is not on the printer device, then IMAGETYPE will default to the type accepted by the first printer on DEFAULTPRINTINGHOST. FILE = NIL is equivalent to FILE = {LPT}. Names for printer files are of the form {LPT}PRINTERNAME.TYPE, where PRINTERNAME, TYPE, or both may be omitted. PRINTERNAME is the name of the particular printer to which the file will be transmitted on closing; it defaults to the first printer on DEFAULTPRINTINGHOST that can print IMAGETYPE files. As just described, the TYPE extension supplies the IMAGETYPE when it is defaulted. OPENIMAGESTREAM will generate an error if the specified printer does not accept the kind of file specified by IMAGETYPE. Examples assuming IP: is an Interpress printer, P is a Press printer, and DEFAULTPRINTINGHOST is (IP: P): (OPENIMAGESTREAM) returns an Interpress image stream on printer IP: (OPENIMAGESTREAM NIL 'PRESS) returns a Press stream on P (OPENIMAGESTREAM '{LPT}.INTERPRESS) returns an Interpress stream on IP: (OPENIMAGESTREAM '{CORE}FOO.PRESS) returns a Press stream on the file {CORE}FOO.PRESS For completeness and consistency, if IMAGETYPE is inferred to be DISPLAY, then the user is prompted for a window to open. The file name in this case will be used as the title of the window. OPTIONS is a list in property list format that may be used to specify certain attributes of the image stream; not all attributes are meaningful or interpreted by all types of streams. Among the properties are: REGION value is the region on the page (in stream scale units, 0,0 being the lower-left corner of the page) that text will fill up. It establishes the initial values for DSPLEFTMARGIN, DSPRIGHTMARGIN, DSPBOTTOMMARGIN and DSPTOPMARGIN. FONTS value is a list of fonts that are expected to be used in the stream. Some streams (e.g. Interpress) are more efficient if the expected fonts are called out in advance, but this is not necessary. The first font in this list will be the initial font of the stream, otherwise the DEFAULTFONT for that image type will be used. HEADING the heading to be placed automatically on each page, NIL means no heading. IMAGESTREAMTYPES [a-list] Describes how to create a stream for a given image type. Contains OPENSTREAM, FONTCREATE, FONTSAVAILABLE methods. The main a-list is indexed by the image-stream type name (e.g., DISPLAY, PRESS, or INTERPRESS) to get another a-list that associates device-dependent functions with generic operation names. Format of a single a-list entry: (imagetype (OPENSTREAM function-to-open-the-stream) (FONTCREATE function-to-create-a-fontdescriptor) (FONTSAVAILABLE function-to-return-available-fonts)) For example, for Interpress, the a-list entry is: (INTERPRESS (OPENSTREAM OPENIPSTREAM) (FONTCREATE \CREATEINTERPRESSFONT) (FONTSAVAILABLE \SEARCHINTERPRESSFONTS)) The OPENSTREAM function is called with arguments: (openstreamfn FILE OPTIONS) FILE is the file name as it was passed to OPENIMAGESTREAM, and OPTIONS is the OPTIONS property list passed to OPENIMAGESTREAM. The result must be a stream of the appropriate imagetype. The FONTCREATE function is called with arguments: (fontcreatefn FAMILY SIZE FACE ROTATION DEVICE) FAMILY is the family name for the font, e.g. MODERN. SIZE is the body size of the font, in printer's points. FACE is a 3-element list describing the weight, slope, and expansion of the face desired, e.g. (MEDIUM ITALIC EXPANDED). ROTATION is how much the font is to be rotated from the normal orientation, in minutes of arc. For example, to print a landscape page, fonts would have rotation 5400 (=90 degrees). The function's result must be a FONTDESCRIPTOR with the fields filled in appropriately. The FONTSAVAILABLE function is called with arguments: (fontsavailablefn FAMILY SIZE FACE ROTATION DEVICE) This function returns a list of all fonts agreeing with the FAMILY, SIZE, FACE, and ROTATION arguments; any of them may be wildcarded (i.e. equal to '*, which means "any"). Each element of the list should be a 5-tuple of the form (FAMILY SIZE FACE ROTATION DEVICE). Where the function looks is an implementation decision: the fontsavailablefn for the display device looks at DISPLAYFONTDIRECTORIES, the Interpress code looks on INTERPRESSFONTDIRECTORIES, and implementors of new devices should feel free to introduce new search path variables. Imagestream predicates (IMAGESTREAMP X IMAGETYPE) [function] Returns X (possibly coerced to a stream) if it is an output image stream of type IMAGETYPE (or of any type if IMAGETYPE = NIL), otherwise NIL. (IMAGESTREAMTYPE STREAM) [function] Returns the image type of STREAM. (IMAGESTREAMTYPEP STREAM TYPE) [function] Returns T if STREAM is an imagestream of type TYPE. Creating your own flavor of imagestream In accomplishing a task as complex as building a new flavor of imagestream, no document can contain all of the answers, tricks, or shortcuts. There is no substitute for studying a working implementation in doing your own. Therefore, we recommend you look at the FX80STREAM package as an example of how to create a new imaging device. FX80STREAM is a DIG interface for the Epson FX-80 printer - a device simple enough to drive that its details will not obscure the fundamentals of how its imagestream works.xx``````xx`````  GACHA  TIMESROMAN GACHA TIMESROMAN  TIMESROMAN TIMESROMAN GACHA TIMESROMAN  TIMESROMAN TIMESROMAN TIMESROMAN TIMESROMAN     5 +  !   b     V  :    H   D  ( J      $   <  *  F    '   e ~ .        B    (      U     !        +          P          %   $       V          3                    -           -            ,  D        c          J        C    -   i 0                                        C                 I         :  !                   Y         S       ] l x            %                      q         K jO ,  .* "              +    /   h     9    0   ! 6  < 9 ;       +    }     _           /      #!   "$    &  w               #   7      D   K   a    "        3     j  $     &    =    $       '  5 [   *     $         =    9 P   = !  [       H                    (   ?   8z