C Language Implementation of the Core System - CLICS Project Description and Current Documentation Outline 1. Project Origin and Resources 2. Philosophy and Goals 3. User Manual 3.1. Naming Conventions 3.2. Error Handling 4. Internal Design 4.1. Major Structures 4.1.1 Segment Structure 4.1.2. View Surface Structure 4.1.3. DD Argument Structure 4.1.4. Software Character Storage Format 4.1.5. Other Structures 4.2. Major Modules 4.2.1. Output Primitive Functions 4.2.2. Dynamic Segment Attribute Setting Functions 4.2.3. The Repaint Subfunction 4.2.4. The Segdraw Subfunction 4.2.5. The Setmatrix Subfunction 4.2.6. The Reopen Subfunction 4.3. Device Driver Specifications 4.3.1. Device Property Flags 4.3.2. DI-DD Communication Structure 4.3.3. DI-DD Opcodes 5. Known Flaws 5.1. Hardware Clipping and Transformation 5.2. Use of Segment Type by DD 5.3. Internal Segment ID's 5.4. Batching of Primitives 5.5. Limited Number of Segments 5.6. No Garbage Collection 6. Efficiency Improvements 6.1. Restructuring Data Structures 6.2. In-line versus Function 6.3. Optimization 6.4. Restrictions 7. Completion 7.1. Input Functions 7.2. Nice Functions 7.3. Special Interfaces 8. Extension 8.1. Dynamic Loading of DD's 8.2. Sharable DI 8.3. Unlimited Number of Segments 8.4. Dynamic View Surface List 8.5. Raster Extensions 8.6. Extending, Copying, and Saving Segments C Language Implementation of the Core System - CLICS Project Description and Current Documentation 1. Project Origin and Resources In February of 1978, Mike Garrett, who was doing research in graphical interfaces to data base management systems, recruited Drew Greenholt, a data systems intern, to assist in the project for one year. There was a need for a device independent graphics package on a UNIX based PDP 11/70 and interest had been shown in the Core Graphics System by other elements of the agency involved. So, it was decided that Drew was to do an implementation of the Core with the assistance of Mike Garrett (approximately quarter time) and the consultation of Jim Foley and other members of the Graphics Standards Planning Committee. Drew subsequently took a course in the C language, and audited a course in computer graphics, before beginning work on the project. Thus, the work discussed here amounts to less than one man year. The product was not intended for a production environment and will hathat the most that could be done was to design for ease of eventual implementation of level four but implement only level two capabilities. We would then document fully, and hope that other resources for optimization, completion, extension, and evaluation could be found. Most of the burden of graphics processing was to be performed by the device independent (DI) part of the system. Thus the specifications for device drivers (DD) were to be very simple so that new devices could be added easily, this at the expense of not making use of all of the hardware capabilities of high performance graphics devices, which are not expected to be attached to PDP 11/70's under UNIX, anyway. The DD specifications are discussed later (section 4.3). Original intentions were for the DD's to be dynamically loaded at execution time, but sufficient UNIX system expertese was not available to determine how to do this efficiently. The system as it stands now requires declaration at compile time of DD's to be used. It would also be desirable to have the DI sharable among tasks, but again the present system does not allow this. 3. User Manual The user manual for CLICS has not been completed. It will consist of a modified and amended GSPC Status Report which we have available on line. (The GSPC Status Report may be obtained from the University of Colorado.) The modifications will be minor, consisting of deletion of some of the detail in the report, explanation of the CLICS-dependent features, function name revision, parameter conventions, and error handling. The function name and error handling conventions are discussed here. 3.1. Function Naming Conventions Objectives (in order): 1. uniqueness - all mnemonics must be unique in the first 7 characters although additional characters may be used to clarify the purpose of the function 2. recallability - ability to remember mnemonics without looking them up 3. consistency - similar names should convert to similar mnemonics 4. minimality - minimum number of rules for conversion 5. pronouncability - esthetically appealing mnemonics The following substitution conventions come close to achieving the above objectives and, after considering several other schemes, including some transposition schemes, have been adopted: _ -> {i.e. delete it} -> char -> ch disable -> disabl disassoc -> disass echo -> eco image -> initialize -> init input -> in inquire -> inq line -> lin marker -> mrk move -> mov output -> out polyline -> ply position -> pos rotate -> ro scale -> sc segment -> seg space -> spc terminate -> term translate -> tr view -> vw viewing -> vw This occasionally results in mnemonics with fewer than 7 characters which is fine. In some cases using only the first 7 characters results in termination of the mnemonic in the middle of a word. Users will probably want at least to complete the word but it is not necessary. (NOTE: set_button_all is inconsistent with other names which follow the pattern of verb_all_object and was changed to set_all_button before conversion) The names resulting from application of these rules are listed in appendix A. 3.2. Error Handling When an error occurs in a Core function, an error handling function is called which sends an error message to the operator's standard output, usually a terminal. The message consists of the function name in which the error occurred, and a synopsis of the error, which is usually identical to the synopsis in the GSPC Status Report. In addition, the error number is returned as the functional value of the Core function, so that the user can handle it programmatically. A value of 0 is returned if no error occurs. All errors are treated as non-fatal and no fancy error handling is done. Programmers are expected to use standard interactive debugging tools available on UNIX systems. 4. Internal Design The internal design of CLICS is based on the "Internal Design of the GSPC Core Graphics System, Final Report"[2]. There are exceptions, however. The minor ones are documented in the code. Major exceptions are covered here. First of all, only functions mentioned in the GSPC report[4] are included in our system. Second, the DI-DD interface is not the same. Ours is discussed in section 4.3. In the following, specific exceptions are discussed in the context of the functions affected. 4.1. Major Structures Here we discuss the more important data structures used in CLICS. The limitied C language data structuring capability[3] was used to build a fairly clean structure. 4.1.1 Segment Structure The segment structure in CLICS consists of a fixed length array of segment descriptor frames and a variable set of segment display records which together form what we refer to as the pseudo display file. The segment descriptor frames may each contain a description of a segment, including name, type, dynamic segment attributes, a view surface list, control flags, and a pointer to the segment display record (SDR) in the PDF for the segment. The segment structure used in CLICS at present is inefficient in space and has been redesigned but not reimplemented. The new design is discussed in section 6.1. The pdfptr is the byte number in the file at which the primitives and primitive attributes for the segment begin. Each such entity begins with a byte which indicates what primitive or attribute it is. If the entity requires a variable number of arguments, i.e. text and polyline, the next two bytes form an integer which is that number. Following that, if present, are the arguments: one byte per character, two bytes per integer, four bytes per floating point number or one byte per short integer. Coordinates are stored as floating point, two dimensional, normalized device coordinates. No viewing transformation information is kept in the file; all such transformations will have already been done. 2D image transformations can, of course, be applied, with unspecified results if partially off the view surface. The effect of image transformations on text is expressed in terms of effects on the text attributes. The position is of course multiplied by the image transformation directly. The character spacing is also multiplied by the transformation. However, it is assumed that if users really want distorted characters they will use high quality text. Thus the height and width parameters are each scaled by the average of the x and y scale factors of the image transformation, preserving the aspect ratio. The angle of the text extent is computed from the transformed character spacing and supplied to the DD so characters can be angled to conform to the extent. In low quality text mode, character spacing is ignored, but the angle may still be used by the DD. For medium quality, character spacing has been computed for each character individually, so character spacing information is never needed directly; it is only used to compute the angle. Nevertheless, it must be kept for multiplication by the image transformation. Finally each segment's set of entities is terminated by a null byte. The following table shows the indicator bytes and the corresponding arguments: Code Mnemonic Arguments # name type description 0 end_segment 0 1 move 2 x,y float adjust current position 2 line 2 x,y float draw line from current position 3 polyline n (xi,yi) float draw sequence of lines 4 text n (ci) char draw sequence of characters 6 marker 1 c char draw corresponding marker centered 11 color 3 r,g,b float change color mode 12 intensity 1 i float change intensity mode 13 linestyle 1 l short change linestyle mode 14 linewidth 1 l float change linewidth (expressed as multiple of standard linewidth) 15 font 1 f short change font mode 16 charsize 2 h,w float change character size 17 charspace 2 x,y float change character spacing 18 charquality 1 q short change character quality 20 pick_id 1,4 i,xm,ym, short, change pick_id and corresponding extent 4.1.2. View Surface Structure The view surface structure, again with hindsight, could use restructuring. It consists of an array of surface descriptor frames, each of which can hold a description of a view surface, including the name, some control flags, some property flags, and a pointer to the device driver of the view surface. The original plan called for loading DD's dynamically and filling the descriptor with this information. This is not implemented. The meaning of the control flags is explained in in-code comments. The meaning of the property flags is discussed in the DD specifications, section 4.3. These are used in the functions to determine how a particular function is to be handled for each device. 4.1.3. DD Argument Structure The DD arguments are passed by means of a pointer to a structure which can hold the opcode and each possible set of arguments for that opcode. This type of arrangement would probably have to be modified if the DD's were dynamically loaded. This structure is discussed in section 4.3. 4.1.4. Software Character Storage Format Each printable ascii character plus each of a selection of markers is stored as 16 command instances each chosen from the following commands of which there also happen to be 16: UP UP_LEFT UP_2 DOWN_4 DOWN UP_RIGHT DOWN_2 UP_PEN LEFT DOWN_LEFT LEFT_2 DOWN_PEN RIGHT DOWN_RIGHT RIGHT_2 STOP Thus all characters are drawn limited to vertical, horizontal, and diagonal strokes. An "M" is 4 strokes high by 4 strokes wide and all command sequences assume pen up and lower left corner positioning to start. Each character takes 4, 16-bit words for storage for a total of 512 words. This storage scheme was stolen from a previous graphics subroutine package designed by one of the authors because to do so was expedient. The time was not taken to consider other schemes which may be more efficient. 4.1.5. Other Structures Some other structures are used in CLICS which are mainly groupings of related objects, but in some cases they are used to facilitate definition of multiple objects of the same type. 4.2. Major Modules Some of the Core functions in CLICS vary enough from the specifications in [2] that they require discussion. Also, several subfunctions of the Core functions in CLICS are separated out into modules. These are discussed here. 4.2.1. Output Primitive Functions The major subfunctions of output primitive functions are similar and are here described by means of a crude pseudo code rather than flow charts. The indentations indicate subfunctions. Check for errors If clipping is in effect: clip primitive If primitive is outside window: update cp perform no more functions(return) Convert from world to normalized device coordinates If open segment is being retained: If primitive attributes have changed: put primitive attributes into SDR Put primitive into SDR For each view surface in segment descriptor: If primitive attributes have changed: send primitive attributes to DD If does not have transformation hardware: transform primitive If must simulate certain attributes: simulate and send appropriate things to DD else send modified primitive to DD (DD will ignore if visibility off) return 4.2.2. Dynamic Segment Attribute Setting Functions Again we use crude pseudo code: check for errors for the named segment: check for segment dependent errors, if any if the change is real and this is not an empty open segment: if this is the open segment: temporarily close it if segment already has repaint flag set: set local flag (used below) mark this segment as needing repaint for each view surface in this segment's list: if the view surface can handle the attribute: notify the DD of the change else: mark the view surface as needing repaint if the view surface is raster (erasure) and segment not already marked as needing repaint (flag set above) erase this segment by redrawing with 0 color and intensity (it will be redrawn at next repaint with new attributes) (new_frame by the user will get rid of anomalies) else: if simulation is necessary for this VS: simulate change attribute in segment descriptor if batch of updates is not in effect: do repaint now(overhead to check all segments for change) if this was an open segment: reopen it else if this is an empty open segment: set up the transformation matrix and the identity flag return In general, it will be time consuming for the user to change the dynamic attributes of the open segment after primitives are created and before the segment is closed, but it also seems unlikely. 4.2.3. The Repaint Subfunction The "repaint" function does the following: for each view surface: if (VS's repaint flag is set) and ((VS is storage type) or (we are doing an explicit repaint)): erase this view surface by calling DD for each segment descriptor: set local flag to false for each VS in this segment's list: if (VS can delete segments) and (segment is not retained) and (not doing explicit repaint) delete this segment from this view surface else if (the VS's repaint flag is set) and ((the segment's repaint flag is set) or (the VS is storage) or (we are doing an explicit repaint)): set local flag to true if local flag is true and this segment is retained: for each VS in this segment's list: if (VS needs segments opened) and (VS's repaint flag and segment's repaint flag are both set) reopen this segment on this view surface by calling DD set up all attributes for the segment by calling DD set up transformation matrix and identity flag for this segment for each SDR function for this segment (as read from PDF): for each VS in this segment's list: if (VS's repaint flag is set) and (segment is visible or VS has visibility hardware) and ((segment repaint flag is set) or (VS is storage type) or (we are doing an explicit repaint)): do the appropriate DD things to create this primitive (this is the big switch statement) for each VS in this segment's list if ((VS's repaint flag and segment's repaint flag are both set) or (we are doing explicit repaint)) and VS can delete segments: close this segment restore all attributes to pre-segdraw values by calling DD if segment is not retained mark segment descriptor frame as empty else: reset this segment's repaint flag reset all VS's repaint flags return 4.2.4. The Segdraw Subfunction The segdraw function is called to repeat the drawing of a segment on a device. It does the following: If this segment's visibility off and no visibility hardware: return else send visibility to DD form current matrix from transformation attributes of this segment for each SDR function for the segment (as read from PDF): do the appropriate DD things /** huge case statement **/ return The segdra0 function is called to erase a segment from a raster type device. It does the same things as the segdraw function except that the color and intensity attributes are set to 0 and subsequent PDR entries which indicate change of color or intensity are ignored. Thus the entire segment is redrawn with zero intensity and color. Color and intensity are restored to their pre-segdraw0 values before returning. Note that these two functions achieve their goals by calls to the DD only. No entries are made in the PDF. 4.2.5. The Setmatrix Subfunction There is only one matrix kept in this system. If there is an open segment, it corresponds to (and is computed from) the transformation parameters of that segment (scale, rotate, and translate). All newly created primitives' points are multiplied by this transformation unless the flag indicating that the transformation is the identity is set. The matrix and the flag are set to the identity default when the segment is opened. If any tranformation attributes are changed before any primitives are put into the segment, it is merely recomputed from those values with no other effects. If the parameters are changed after primitives are added to the segment, the segment is temporarily closed and the same things are done as if it had not been an open segment, after which it is reopened. However, during the course of these things happening the matrix may be changed by the repaint function to correspond to the parameters of other segments. Thus, the reopen function as one of its acts must set the matrix up. 4.2.6. The Reopen Subfunction The existence of a reopensegment function as a module will be convenient later, to allow for appending to any segment, since its function is to take a given segment (above, the previously open segment) and make it the open segment while keeping all of its current primitives in tact. Presently it assumes that the segment it is opening is the most recently created segment, which was closed by tempcloseseg. Thus it is greatly simplified. 4.3. Device Driver Specifications Here we discuss the specifications for the output device drivers for CLICS. 4.3.1. Device Property Flags The device property flags are set according to the following rules: vshardwr - visibility - device keeps identifiable segments in its memory and can on command make them visible or invisible while still retaining them in its memory hlhardwr - highlighting - device keeps identifiable segments in its memory and can on command highlight one or more of them by some means (e.g. blinking). dthardwr - detectability - device keeps identifiable segments in its memory and has an input device (e.g. light pen) which when used can return the pick id of a set of primitives within a segment and the segment name, AND the segments may be marked as either detectable (pickable) or indetectable. trhardwr - translation - device keeps identifiable segments in its memory and can on command translate (move) them from one position to another selected position. schardwr - scaling - see trhardwr rohardwr - rotation - see trhardwr dehardwr - ability to delete a segment - device keeps identifiable segments in its memory and can on command remove a segment from its memory idhardwr - primitive PICK-ID - device keeps identifiable segments in its memory and has an input device (e.g. light pen) which when used can return the pick id of a set of primitives within a segment and the segment name. lshardwr - at least 4 differing line styles(dot,dashed). lwhardwr - more than one line width. inhardwr - gray scaling of a set of primitives (color and intensity are mutually exclusive; if this flag is set, color specifications should be ignored, if received. However, they should not be received because they will be translated by the DI into intensity specifications for your device) clhardwr - coloring of a set of primitives (color and intensity are mutually exclusive, but, of course, a full color device can be used for gray scale under user control; if this flag is set, intensity specifications should be ignored) {efficient use of full color systems for gray scale applications will be made possible by providing separate device drivers, which will, of course, be very similar to their counterpart full color device drivers, but will use fewer bit planes, leaving others free for other gray scale devices if available, or in some cases for storage of programs or data} txhardwr - can provide hardware text generation. erasure - can effectively delete selected parts of an image by redrawing them with 0 intensity and color (e.g. raster) segopclo - device needs to be informed of the opening and closing of segments before it can manipulate them(build them). nwframdv - device requires complete regeneration of an image in order to delete one part (e.g. storage tube, hard copy) 4.3.2. DI-DD Communication Structure The structure used to pass arguments to the DD's looks like: struct { int opcode; int logical; char *string; NOTE: NOT EVERY STRUCTURE MEMBER WILL BE int int1; UTILIZED FOR EACH PARTICULAR OPCODE float float1; SPECIFIED. float float2; float float3; NOTE: A POINTER TO THIS STRUCTURE IS PASSED } ddstruct; AS AN ARGUMENT TO THE DEVICE DRIVER EXAMPLE: driver1(&ddstruct); 4.3.3. DI-DD Opcodes The opcodes and their values are: OPCODE VALUE ------ ----- CLEAR 0 INITIAL 1 SETVSBL 2 SETHILIT 3 SETDTCT 4 DELETE 5 ROTATE 6 SCALE 7 TRANSLATE 8 OPENSEG 9 TERMINATE 10 CLOSEG 11 NDCSP2 12 GETCP 13 SETPID 14 SETCOL 15 SETWIDTH 16 SETSTYL 17 SETINT 18 MOVE 19 LINE 20 TEXT 21 MARK 23 SETFONT 24 SETSIZE 25 SETANGLE 26 The meanings of those opcodes are: OPCODE: CLEAR ----- PERTINENT STRUCTURE MEMBERS: NONE (OTHER THAN 'opcode') FUNCTION: erase the screen (raster, storage), delete all segments (vector) advance to clean paper (hard copy) """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: INITIAL ------- PERTINENT STRUCTURE MEMBERS: NONE FUNCTION: set variables internal to device driver to their initial states. do whatever is necessary to get device ready to do any function. do an implicit clear (see above). """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETVSBL ------- PERTINENT STRUCTURE MEMBERS: logical visibility flag(on or off) int id of segment affected FUNCTION: set or clear visibility bit in display file for segment identified if DD is for device which has 'vshardwr' flag set in VSD. Otherwise, if visibility is set to OFF, the DD should ignore all primitives sent to it until visibility is once again set to ON!!! """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETHILIT -------- PERTINENT STRUCTURE MEMBERS: logical highlighting flag int id of segment affected FUNCTION: set or clear highlighting bit in display file. only applicable to divices which have 'hlhardwr' flag set in VSD. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETDTCT ------- PERTINENT STRUCTURE MEMBERS: logical detectability flag int id of segment affected FUNCTION: set or clear detectability bit in display file. only applicable to devices which have 'dthardwr' flag set in VSD. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: DELETE ------ PERTINENT STRUCTURE MEMBERS: int id of segment affected FUNCTION: delete named segment form screen. only applicable to devices with 'dehardwr' flag set in the VSD. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: ROTATE ------- PERTINENT STRUCTURE MEMBERS: float1 angle of rotation int id of segment affected FUNCTION: Rotate the segment about the origin the given angle of rotation. only applicable to devices with 'rohardwr' flag set in the VSD. (not to be concatenated with previous combined transformation, but rather, replaces previous rotation) """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SCALE ------ PERTINENT STRUCTURE MEMBERS: float1 scaling factor in x direction float2 scaling factor in y direction int id of segment affected FUNCTION: scale the segment in the x and y directions as specified. only applicable to devices with 'schardwr' flag set in the VSD. (not to be concatenated with previous combined transformation, but rather, replaces previous scaling) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: TRANSLATE ---------- PERTINENT STRUCTURE MEMBERS: float1 translation factor in x direction float2 translation factor in y direction int id of segment affected FUNCTION: translate the segment in the x and y directions as specified. only applicable to devices with 'trhardwr' flag set in the VSD. (not to be concatenated with previous combined transformation, but rather, replaces previous translation) """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: OPENSEG ------- PERTINENT STRUCTURE MEMBERS: int id of segment affected FUNCTION: inform the device that the named segment should be created and made ready to accept output primitives. only applicable to devices with 'segopclo' flag set in the VSD. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: TERMINATE --------- PERTINENT STRUCTURE MEMBERS: NONE FUNCTION: do implicit clear. release device. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: CLOSEG ------ PERTINENT STRUCTURE MEMBERS: int id of segment affected FUNCTION: inform the device that the named segment is complete and should therefore be closed. only applicable to devices with 'segopclo' flag set in the VSD. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: NDCSP2 ------ PERTINENT STRUCTURE MEMBERS: float1 width of normalized device coordinate space. float2 height of normalized device coordinate space. FUNCTION: store ndc coordinates specified to be used in calculation of device coordinates. initial values should be 1 for both. NOTE: Mapping of coordinates is as follows: world coordinates -> NDC coordinates -> Device Coordinates When the programmer specifies world coordinates, the system will convert them to NDC coordinates to be used by the device driver to figure device coordinates. The default range for normalized device coordinate space is 0 to 1 along each axis, although this may be further constrained along one axis, but not both, to promote efficient use of non-square display surfaces. The device driver programmer has the decision where to map the NDC space rectangle to on his display surface. If he doesn't chose the origin as the Lower Left Hand Corner of NDC space, then the width and height of the space will be needed in the conversion of NDC coordinates to device coordinates. The mapping will "usually" make the rectangle as large as possible thus minimizing the unusable area of the display surface. The area outside the range of NDC coordinates on the screen can be used for operator communication,error messages, or echoing of input device input. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETPID ------ PERTINENT STRUCTURE MEMBERS: int1 current pick identification number FUNCTION: set primitive pick id to that specified. only applicable to devices with 'idhardwr' flag set in the VSD. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETCOL ------ PERTINENT STRUCTURE MEMBERS: float1 first current color value float2 second current color value float3 third current color value FUNCTION: set color to that specified. only applicable to devices with 'clhardwr' flag set in VSD. Color specification is RGB. Each color's intensity is given in normalized fraction of full intensity and should be translated by the DD. As an example, if device intensities are integral with N values, an integral value of I would be used if the normalized value is between I/N and (I+1)/N. {use of video lookup tables will be provided for when the raster extensions are implemented as will direct pixel manipulation} """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETWIDTH -------- PERTINENT STRUCTURE MEMBERS: float1 current linewidth value FUNCTION: set linewidth to one specified. only applicable to devices with 'lwhardwr' flag set in VSD. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETSTYL ------- PERTINENT STRUCTURE MEMBERS: int1 current linestyle value FUNCTION: set linestyle to one specified. only applicable to devices with 'lshardwr' flag set in VSD. A value of 1 indicates solid lines; all other codes are unspecified but are expected to result in unique linestyles up to a value of 4 if the "lshardwr" flag is set in VSD. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETINT ------ PERTINENT STRUCTURE MEMBERS: int1 current intensity value FUNCTION: set intensity primitive to one specified. only applicable to devices with 'inhardwr' flag set in VSD. Intensity is given in normalized fraction of full intensity and should be translated by the DD. As an example, if device intensities are integral with N values, an integral value of I would be used if the normalized value is between I/N and (I+1)/N. {use of video lookup tables will be provided for when the raster extensions are implemented as will direct pixel manipulation} """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: MOVE ---- PERTINENT STRUCTURE MEMBERS: float1 x coordinate float2 y coordinate FUNCTION: adjust current position to reflect new x,y coordinate. NOTE: device driver must keep track of current position on the screen at all times. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: LINE ---- PERTINENT STRUCTURE MEMBERS: float1 x coordinate float2 y coordinate FUNCTION: draw a line from current position to specified endpoint. update current position. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETFONT ------- PERTINENT STRUCTURE MEMBERS: int1 identifier of font to apply to following text FUNCTION: set font to the specification. Standard ASCII is to be used if indicated font is 1; integers for other fonts are device driver dependent and are deliberately unspecified. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETSIZE ------- PERTINENT STRUCTURE MEMBERS: float1 height of characters in NDC units float2 width of characters in NDC units FUNCTION: set size of characters to specification. If a continuous range of sizes is not available, choose largest size smaller than the specification in both directions. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: SETANGLE ------- PERTINENT STRUCTURE MEMBERS: float1 angle of characters in radians FUNCTION: set angle of characters to specification. If a continuous range of angles is not available, choose available angle that is closest to specification. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: TEXT ---- PERTINENT STRUCTURE MEMBERS: string string to be placed on screen FUNCTION: using a hardware character generator, draw the string of characters at current position. height and width of character are used to obtain a "best fit" for the hardware character size. The largest size smaller that that called for shoud be used. Adjust the current position to the end of string, so that concatenation of strings is possible without an intervening 'move' instruction. Current position is assumed to be the lower left hand corner of the character box. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: MARK ---- PERTINENT STRUCTURE MEMBERS: string marker to be placed on screen FUNCTION: using a hardware character generator, draw the marker "centered" at the current position, unrotated at the standard hardware character size. Marker codes correspond to ascii codes. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OPCODE: GETCP ----- PERTINENT STRUCTURE MEMBERS: float1 x coordinate of current position float2 y coordinate of current position FUNCTION: return your current position on screen in structure members as specified. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" 5. Known Shortcomings It is known that several major shortcomings exist in our design as well as many minor ones. The major ones are discussed here. 5.1. Hardware Clipping and Transformation Presently, CLICS makes no use of clipping hardware capabilities of devices at all. It is all done in software. The original design did include use of transformation hardware, but this is only partially implemented. Where code exists to implement this, it is currently commented out. 5.2. Use of Segment Type by DD CLICS does not send the segment type to the DD's. In some cases this could lead to inefficient storage of segments in display files. 5.3. Internal Segment ID's Currently segments are identified by a string. An internal small integer ID would be more efficient and a table could be kept of the corresponding names, or users could be forced to use integers which is not a bad restriction. 5.4. Batching of Primitives CLICS does not batch primitives. Each primitive is sent to the appropriate DD's as the user creates it. Whether the DD buffers them or not is unspecified. What could happen is for the DD's that can buffer to do so if batch of updates is in effect, emptying only when buffers are full or when ending batch of updates. This would require opcodes to the DD's telling them when batchs of updates begin and end. (Batching of other functions is handled, however, by the repaint structure.) 5.5. Limited Number of Segments Users are currently limited to a fixed (at compile time) number of segments. The absence of a "heap" in C makes allowing unlimited segments difficult. 5.6. No Garbage Collection Although the segment descriptor frames of deleted segments are reusable in CLICS, space in the segment display file is not. A segment display record, once created, exists for the duration even if the owning segment is deleted. 6. Efficiency Improvements Knowledge gained about the C compiler has made us aware of many efficiency improvements. Others were recognized as a result of better understanding of the Core gained from the implementation itself. 6.1. Restructuring Data Structures An example of how restructuring could improve efficiency is the segment desciptor. An alternative structure is: extern struct segstruc { char *segname; struct { unsigned type : 3; /* retain, non-retain, etc. */ unsigned visibility : 1; unsigned detectability : 1; unsigned highlight : 1; unsigned update : 1; /* needs redrawing at next redraw */ unsigned vs1 : 1; /* appears on view surface # 1 */ unsigned vs2 : 1; unsigned vs3 : 1; unsigned vs4 : 1; unsigned vs5 : 1; } flags; float scale[2]; float translate[2]; float rotate; long int pdfptr; /* pointer to primitives in PDF */ struct { float xmax; float ymax; float xmin; float ymin; } extent; /* for pick id computation */ } segment; This would take less space. Implementation would require revision of functions which use the structure, especially those which use the flags. 6.2. In-line versus Function Some groups of operations which are now functions would better be in-line code, e.g. clipping functions, conversion from world coordinates to NDC's image transformations, and setting up the matrix. 6.3. Optimization No experiments have been performed to determine where the critical parts of the code are, in order to increase efficiency. In some cases excessive use of "." and "->" operators can be avoided by some careful precalculation of pointers. 6.4. Restrictions If certain restrictions were placed on the user which the Core does not place, efficiency could be gained. For example, if users could not change dynamic segment attributes while creating a segment, the system would be simplified. 7. Completion of Original Design Completion of the originally intended system would require at least another man year of work. Here we dicuss what needs to be done other than correcting the known shortcomings and improving efficiency. 7.1. Input Functions Specification of the input device drivers, and designing and writing the input functions have not been done. 7.2. Nice Functions Some of the features which are niceties have not been implemented. High quality text has been implemented except for putting all of the character drawing commands into the arrays. Only simple ASCII font characters are intended to be stored, although others could be with little, if any, change in the code. "Simline" which simulates lines of a given width or style when the hardware cannot supply them, has not been written. 7.3. Special Interfaces Hooks and escapes need to be provided. 8. Extensions If resources could be found, the following extensions would be useful. 8.1. Dynamic Loading of DD's If only the DD's asked for at initialization time are loaded, space could be saved. 8.2. Sharable DI A DI that is sharable between tasks would save space where there are multiple graphics users. 8.3. Unlimited Number of Segments If memory can be expanded to accommodate any number of segment descriptors and/or parts of the segment display file, better performance would result. 8.4. Dynamic View Surface List Addition of a view surface to an already created segment is a natural extension to a level 4 system. Getting hard copy of an image would thus be facilitated. 8.5. Raster Extensions Raster extensions as proposed by Foley[1] would be very useful. 8.6. Extending, Copying, and Saving Segments These would be easily implemented with the present structure. References 1. Foley, James D., Templeman, James, and Dastyar, Dara, "Raster Extensions to the Core Graphics System", George Washington University, August, 1978 2. Greatorex, Frank S., and Michener, James C., "Internal Design of the GSPC Core Graphics System, Final Report", 15 December 1977, Contract N66604-M-77-8896, Naval Underwater Systems Center, prepared by Intermetrics, Inc. 3. Kernighan, Brian W., and Ritchie, Dennis M., The C Programming Language, Prentice-Hall, 1978 4. Status Report of the GSPC, ACM SIGGRAPH, ACM, New York, 1977 Appendix A. Core function names in CLICS resulting from rules in section 3.1. movabs2 inqsegsurfaces movabs3 inqnumberofsegs movrel2 inqsegnames movrel3 inqoutcapabilities linabs2 setvisibility linabs3 sethighlighting linrel2 inqvisibility linrel3 inqhighlighting plyabs2 setdetectability plyabs3 inqdetectability plyrel2 enabledevice plyrel3 enableclass text disabldevice mrkabs2 disablclass mrkabs3 disablall mrkrel2 readlocator mrkrel3 readvaluator createseg awaitevent closeseg flushdeviceevents deleteallsegs flushclassevents setcolor flushallevents setintensity associate setlinwidth disassiate setlinstyle disassdevice setfont disassclass setchsize disassall setchspc getpickdata setchplane getlocatordata setchquality getvaluatordata setpickid seteco inqcolor setecoclass inqintensity setecopos inqlinwidth setecosurface inqlinstyle setlocator inqfont setvaluator inqchsize setkeyboard inqchspc setbutton inqchplane setallbutton inqchquality inqinstatusparameters inqpickid inqincapabilities setsegtype settr2 inqsegtype settr3 inqnamedsegtype setro2 vwreferencepoint setro3 vwplanenormal setsc2 vwplanedistance setsc3 parallel inqtr2 perspective inqtr3 vwup3 inqro2 window2 inqro3 vwdepth inqsc2 ndcspc2 inqsc3 vwport2 ndcspc3 vwup2 vwport3 window3 reportmostrecenterror initcore newframe termcore beginbatchofupdates initvwsurface endbatchofupdates selectvwsurface clipwindow deselectvwsurface clipplanes termvwsurface coordinatesystemtype setdefaultattributes modellingtransformation inqpos2 inqmodellingtransformation inqpos3 inqcompositetransformation inqvwparameters escape inqvwtransformation inqescape inqdefaultattributes deleteseg inqoutstatusparameters renameseg