The SCD Graphics Project decided some time ago to abandon the so-called "NCAR System Plot Package" (NSPP) in favor of the "Graphical Kernel System" (GKS) and has devoted a great deal of time and effort to the transition. That effort is now coming of age; in the near future, graphics users will be encouraged to switch from the old package to the new.
In the long run, GKS offers important advantages to the user community. In the short run, however, it offers a bit of a headache. GKS is not particularly user-friendly and is significantly different from NSPP. Accordingly, an NSPP look-alike has been created as an interface to GKS. For lack of a better name, this look-alike is called the "System Plot Package Simulator" (SPPS).
SPPS does not exactly simulate NSPP, nor can it be made to. The major differences are as follows:
Implementations of the "flash-package" routines FLASH1, FLASH2, FLASH3, and FLASH4 are in progress and will be advertised when they are ready.
IMX=IFIX(32767.*FLOAT(IPX-1)/(2.**MX-1.)) IMY=IFIX(32767.*FLOAT(IPY-1)/(2.**MY-1.))Plotter coordinates were used in calls to NSPP routines like POINT, LINE, etc., to specify positions on the plotter frame; they may not be used in calls to the SPPS equivalents. Plotter coordinates could also be used, and are still used, to specify character widths in calls to PWRIT.
CALL SET (PL,PR,PB,PT,UL,UR,UB,UT,LL)PL and PR define the left and right edges, and PB and PT the bottom and top edges, of a rectangular subset of the plotter frame. In direct violation of the FORTRAN standard, the NSPP version of SET allowed these to be stated either as real coordinates in the fractional coordinate system, as shown, or as integer coordinates (call them IL, IR, IB, and IT) in the plotter coordinate system; the SPPS version only allows real values. Default values (stated in the fractional system) are 0., 1., 0., and 1., respectively.
UL and UR define the user x-coordinate values to be mapped into the left and right edges, and UB and UT the user y-coordinate values to be mapped into the bottom and top edges, of the area defined by PL, PR, PB, and PT.
LL defines whether the mappings are to be linear or logarithmic, as follows:
1 --> x linear, y linear 2 --> x linear, y logarithmic 3 --> x logarithmic, y linear 4 --> x logarithmic, y logarithmicAssuming that IL and IR are the plotter-coordinate-system equivalents of PL and PR, the linear mapping of a real user x coordinate RUX into an integer plotter x coordinate IPX is defined as follows:
IPX=IL+IFIX((RUX-UL)/(UR-UL)*FLOAT(IR-IL))The logarithmic mapping of RUX into IPX is defined as follows:
IPX=IL+IFIX((ALOG10(RUX)-ALOG10(UL))/ + (ALOG10( UR)-ALOG10(UL))*FLOAT(IR-IL))The linear and logarithmic mappings of RUY into IPY are defined analogously.
User coordinates are used in calls to routines like POINT, LINE, etc., to specify positions on the plotter frame.
Fractional coordinates RFX and RFY are related to plotter coordinates IPX and IPY by the following formulas:
IPX=1+IFIX(RFX*(2.**MX-1.)) IPY=1+IFIX(RFY*(2.**MY-1.))Fractional coordinates may only be used as the first four arguments of a call to the routine SET.
CFUX(RX) CPFX(IX) KFMX(RX) KPMX(IX) CFUY(RY) CPFY(IY) KFMY(RY) KPMY(IY) CMFX(IX) CPUX(IX) KFPX(RX) KUMX(RX) CMFY(IY) CPUY(IY) KFPY(RY) KUMY(RY) CMUX(IX) CUFX(RX) KMPX(IX) KUPX(RX) CMUY(IY) CUFY(RY) KMPY(IY) KUPY(RY)In each case, the first letter of the name stands for "Convert", spelled with a "C" if the value of the function is of type real, with a "K" if the value of the function is of type integer. The second and third letters of the name indicate the coordinate systems of the argument and the function value, respectively. The fourth letter of the argument indicates whether an x coordinate or a y coordinate is being converted. Thus, for example, CPUX(IX) is the real x coordinate in the user system which corresponds to the integer x coordinate IX in the plotter system, and KPMY(IY) is the integer y coordinate in the metacode system which corresponds to the integer y coordinate IY in the plotter system.
GKS considerations: CLSGKS calls GDAWK to deactivate the metacode workstation, GCLWK to close the workstation, and GCLKS to close GKS.
GKS considerations: If there has been no call to SET or if the mapping defined by the last SET call was linear in both x and y, CURVE calls GPL to create a single NP-point polyline; otherwise, the coordinates are transformed 10 at a time to create a set of 10-point polylines whose union is the desired curve.
GKS considerations: None.
CALL FL2INT (PX,PY,IX,IY)is the same as that of the two statements
IX=KUMX(PX) IY=KUMY(PY)GKS considerations: None.
GKS considerations: FRAME clears all open and active GKS workstations.
CALL FRSTPT (PX,PY)is equivalent to the statement
CALL PLOTIF (CUFX(PX),CUFY(PY),0)GKS considerations: See PLOTIF.
Note: The NSPP routine GETSET returned integer values, in the plotter coordinate system, for the first four arguments of GETSET. The SPPS version returns real values, in the fractional system, so as to be consistent with the routine SET.
GKS considerations: FL, FR, FB, and FT are simply the values defining the viewport of the current normalization transformation. If there has been no call to SET or if the mapping defined by the last SET call was linear in both x and y, UL, UR, UB, and UT are simply the values defining the window of the current normalization transformation and LL is a 1; otherwise, two or more of the values are of the form 10x, where x is a window-defining parameter, and LL is not a 1. The order of UL, UR, UB, and UT may be different from that of the values defining the window of the current normalization transformation; see the paragraph describing GKS considerations for the routine SET.
GKS considerations: None.
See the description of the routine SETUSV, below.
GKS considerations: None.
CALL LINE (X1,Y1,X2,Y2)is equivalent to the statements
CALL PLOTIF (CUFX(X1),CUFY(Y1),0) CALL PLOTIF (CUFX(X2),CUFY(Y2),1)GKS considerations: See PLOTIF.
GKS considerations: None.
GKS considerations: OPNGKS calls GOPKS to open GKS, GOPWK to open a metacode workstation, and GACWK to activate the workstation.
CALL SETUSV ('PB',IS)where IS is an integer between 2 and 50; the value 2 effectively turns buffering off, forcing a buffer flush after every pen move.
GKS considerations: Each flushing of the buffer used by PLOTIF and PLOTIT results in the creation of zero or more polylines. Because of the buffering, objects created by a mixture of calls to SPPS routines and GKS routines may be drawn in the wrong order. This may be bothersome on a pen-oriented device.
CALL SETUSV ('PB',IS)where IS is an integer between 2 and 50; the value 2 effectively turns buffering off, forcing a buffer flush after every pen move.
GKS considerations: Each flushing of the buffer used by PLOTIF and PLOTIT results in the creation of zero or more polylines. Because of the buffering, objects created by a mixture of calls to SPPS routines and GKS routines may be drawn in the wrong order. This may be bothersome on a pen-oriented device.
CALL POINT (PX,PY)is equivalent to the statements
CALL PLOTIF (CUFX(PX)-.0005,CUFY(PY)-.0005,0) CALL PLOTIF (CUFX(PX)+.0005,CUFY(PY)+.0005,1) CALL PLOTIF (CUFX(PX)-.0005,CUFY(PY)+.0005,0) CALL PLOTIF (CUFX(PX)+.0005,CUFY(PY)-.0005,1)GKS considerations: None.
POINTS causes the buffer used by PLOTIF and PLOTIT to be flushed. The "pen" is left at the position (PX(NP),PY(NP)).
GKS considerations: If there has been no call to SET or if the last call to SET specified a linear mapping in both x and y and if the value of IC specifies the use of a GKS polymarker, a single polymarker is created by a call to GPM and, if IL is non-zero, a single polyline is created by a call to GPL. In all other cases, a more complicated set of objects is created, the union of which has the desired effect.
If IC is greater than zero, calls to GTX are used to draw the desired character at each of the points; the horizontal and vertical text-alignment parameters are altered to center each character on its point and then returned to their initial values. Other text attributes may be altered by the user (character orientation, color, etc.).
CALL PWRIT (PX,PY,CH,NC,IS,IO,IC)is equivalent to the statement
CALL WTSTR (PX,PY,CH(1:NC),IS,IO,IC)and, in fact, PWRIT executes this very statement.
WTSTR is to be preferred to PWRIT; having to count characters is annoying, error-prone, and, in a FORTRAN-77 environment, unnecessary.
FL, FR, FB, and FT are real values between 0. and 1. defining the left, right, bottom, and top edges of a rectangle in the fractional coordinate system.
UL, UR, UB, and UT are real values defining the left, right, bottom, and top edges of a rectangle in the user coordinate system.
LL specifies the linear/log nature of the mapping from one system to the other, as follows:
1 --> x linear, y linear 2 --> x linear, y logarithmic 3 --> x logarithmic, y linear 4 --> x logarithmic, y logarithmicThe linear mapping of a user x coordinate UX to an fractional x coordinate FX is defined as follows:
FX=FL+(UX-UL)/(UR-UL)*(FR-FL)The logarithmic mapping of UX to FX is defined as follows:
FX=FL+(ALOG10(UX)-ALOG10(UL))/(ALOG10(UR)-ALOG10(UL)) + *(FR-FL)The linear and logarithmic mappings of a user y coordinate UY to a fractional y coordinate FY are defined analogously.
Note: The NSPP routine SET allowed one to use either integers or reals for the first four arguments. The SPPS routine SET requires that the first four arguments be real.
GKS considerations: Calling SET redefines normalization transformation 1 and makes it the current normalization transformation. The first four arguments define the viewport. The second four arguments (or their base-10 logarithms, depending on the value of LL) define the window. Because of the GKS restriction that the numerical values at the left and bottom edges of the window must be less than the numerical values at the right and top edges, respectively, the user values are swapped as necessary and an internal SPPS variable (the "user state variable" identified by 'MI') is used to remember which ones have been swapped.
GKS considerations: None.
Following is a list of the user state variables:
Variable name Possible values Use -------- ---- --------------- ---------------------------------- 'LS' 1, 2, 3, or 4 Linear/log scaling. 'MI' 1, 2, 3, or 4 Mirror-imaging flag. 'XF' 1, 2, ..., 15 X axis scale factor. 'YF' 1, 2, ..., 15 Y axis scale factor. 'PB' 2, 3, ..., 50 PLOTIF/PLOTIT buffer size. 'MU' a unit number Metacode output unit. 'IR' 1, 2, ... Red intensity. (deprecated) 'IG' 1, 2, ... Green intensity. (deprecated) 'IB' 1, 2, ... Blue intensity. (deprecated) 'IN' 1, 2, ..., 10000 Overall intensity. (deprecated) 'IM' 1, 2, ... Maximum color index. (deprecated) 'II' 1, 2, ... IM Restore color index. (deprecated) 'LW' 1, 2, ... Line width. 'MS' 1, 2, ... Marker size.Note: Use of the variables intended to make it "easy" to set color and intensity is now discouraged. Instead, use direct calls to the GKS interface. (The variables in question are the ones marked "deprecated" in the table above.)
The variable referenced by 'LS' is the same as that referenced by the argument LL in a call to SET or GETSET. The variable referenced by 'MI' has similar values, and indicates whether or not the mappings of user x and y coordinates are to be normal or "mirrored" - reversed end-for-end. Both 'LS' and 'MI' are normally set by a call to the routine SET, rather than by a call to SETUSV.
The variables referenced by 'XF' and 'YF' are the same as those referenced by the arguments IX and IY in a call to GETSI or SETI.
The variable 'MU' specifies the number of the unit to which metacode is to be written.
The variables 'LW' and 'MS' specify the line width and marker size, respectively. Each is stated in thousandths of the "normal" value. For example, the value "2000" represents twice the default line width or marker size. The default value of both parameters is therefore 1000.
All of the variables 'IR', 'IG', 'IB', 'IN', 'IM', and 'II' have to do with setting intensity and color. See the section "INTENSITY AND COLOR", below, for a complete discussion of these variables. (As mentioned above, use of these variables is now deprecated, but the following discussion of them is provided as an aid in deciphering old code that may have used the technique.)
Assuming that IR, IG, IB, and IN are the variables referenced by the names 'IR', 'IG', 'IB', and 'IN', respectively, the red, green and blue intensities are set as follows:
RI = IR / MAX(IR,IG,IB,1) * IN / 10000 GI = IG / MAX(IR,IG,IB,1) * IN / 10000 BI = IB / MAX(IR,IG,IB,1) * IN / 10000The variables 'IR', 'IG', and 'IB' must have positive values; they determine how the desired color is to be mixed (additively) from red, green, and blue primaries; the default values are 1, 1, and 1, giving white. The variable 'IN' must have a value between 0 and 10000; it specifies the desired intensity, expressed in ten-thousandths of the maximum value; its default value is 8000. The GKS calls actually setting the color and intensity are performed during the call setting 'IN'; to set both the color and the intensity, therefore, one should set any or all of 'IR', 'IG', and 'IB', and, finally, 'IN'.
Because of the way in which the GKS metacode translator works when driving a device with only two possible intensities (on and off), values of 'IN' less than 5000 should be avoided. (On the Dicomed, this is reasonable anyway, since intensities in the bottom half of the scale are very dim.)
The variable 'IM' specifies the maximum color index to be used by SPPS; the value given to it must be one appropriate for the device being driven. The default value is 1, which is appropriate for the Dicomed.
The variable 'II' specifies the current color index; the value given should be one previously retrieved by a call to GETUSV.
GKS considerations: When the metacode unit number is changed by a call to GETSET, the current metacode workstation is closed and deactivated and the new one is opened and activated. (It is not clear, as of the time of writing, whether one will be able to resume output of metacode to a previously-used metacode unit; check with a consultant to determine the current situation.) When the parameter 'IN' is set, the aspect source flags for the polyline, polymarker, text, and fill-area color indices are reset to "individual", the color indices themselves are all given a value II between 1 and 'IM', and the color representation for color index II is redefined on all open workstations to obtain the desired effect. When the parameter 'II' is set, the aspect source flags mentioned above are forced to "individual", and the color indices are given the value 'II'. When either of the parameters 'LW' or 'MS' is reset, the appropriate aspect source flag is set to "individual" and the appropriate GKS parameter is set.
CALL VECTOR (PX,PY)is equivalent to the statement
CALL PLOTIF (CUFX(PX),CUFY(PY),1)GKS considerations: See PLOTIF.
IS is the desired character width, in the plotter coordinate system; the value 0 is interpreted to mean 8, the value 1 to mean 12, the value 2 to mean 16, the value 3 to mean 24, and values greater than or equal to 4 as themselves.
IO is the desired orientation of the string, in degrees counter-clockwise from horizontal; 0 means that the string will be written from left to right on the plotter frame, 90 that it will be written from bottom to top, right side up as viewed from the right, etc.
IC is the centering option. If IC is negative, (PX,PY) will be in the center of the left edge of the leftmost character. If IC is zero, (PX,PY) will be in the center of the whole string. If IC is greater than zero, (PX,PY) will be in the center of the right edge of the rightmost character.
The PLOTIF/PLOTIT buffer is flushed before the character string is drawn. The "pen" is left at the point (PX,PY).
GKS considerations: The GKS parameters controlling character height, text path, orientation, and alignment are temporarily altered so that a GTX call can be used to draw the character string; following the GTX call, these parameters are returned to their original values.
CALL POINT (IX,IY)can be rewritten as the SPPS statement
CALL POINT (CPUX(IX),CPUY(IY))This technique can be used for calls to the routines FRSTPT, LINE, POINT, PWRIT, and VECTOR (and for calls to GRIDAL and HALFAX, as well). Calls to the NSPP routines CURVE and POINTS are not so easily modified. The SPPS equivalents will only accept real user coordinates in the input arrays. User code may have to be changed to accomplish this.
Note that this problem does not arise with the routine PLOTIT, which, in both NSPP and SPPS, is called with integer coordinates in the metacode system.
The first four arguments of the NSPP routine SET could be given either as integers in the plotter coordinate system or as reals in the fractional coordinate system. Calls to the SPPS routine SET must use reals. The functions CPFX and CPFY may be used to do the required conversion. The NSPP statement
CALL SET (IL,IR,IB,IT,...becomes the SPPS statement
CALL SET (CPFX(IL),CPFX(IR),CPFY(IB),CPFY(IT),...The NSPP routine GETSET returned integers in the plotter coordinate system for its first four arguments; the SPPS equivalent returns reals in the fractional system. Thus, the NSPP statement
CALL GETSET (IL,IR,IB,IT,...must be replaced by the SPPS statements
CALL GETSET (VL,VR,VB,VT,... IL=KFPX(VL) IR=KFPX(VR) IB=KFPY(VB) IT=KFPY(VT)
CALL POINTS (PX,PY,NP,0,IL)may be left unchanged, but the NSPP call
CALL POINTS (PX,PY,NP,'+',IL)(for example) must be changed. The simplest SPPS equivalent is
CALL POINTS (PX,PY,NP,ICHAR('+'),IL)which will still give a plus sign at each point. It is more efficient, however, to use GKS polymarkers (when possible). The SPPS call
CALL POINTS (PX,PY,NP,-2,IL)uses the plus-sign polymarker. The value -1 gives dots, the value -2 plus signs, the value -3 asterisks, the value -4 circles, and the value -5 diagonal crosses.
The NSPP call
CALL OPTN ('IN',IN)allowed one to set the intensity with which lines, points, and text were subsequently to be drawn. The value of IN was required to lie between 0 and 255. This NSPP call may be replaced by the SPPS call
CALL SETUSV ('IN',IFIX(10000.*FLOAT(IN)/255.))which is almost identical, except that the second argument is between 0 and 10000.
On a device with color capability, one needs a mechanism to select the color to be used for subsequent lines, points, and text. With NSPP, this was done rather clumsily, using calls like this:
CALL OPTN ('CO','RED')Only a few colors (typically, 'WHITE', 'RED', 'BLUE', 'GREEN', 'CYAN', 'MAGENTA', and 'YELLOW') were available. SPPS provides a way to get a desired color by mixing red, green, and blue light. The call above would be replaced by the SPPS calls
CALL SETUSV ('IR',1) CALL SETUSV ('IG',0) CALL SETUSV ('IB',0) CALL SETUSV ('IN',IN)which says that the desired color is to be obtained using 1 part of red light to 0 parts of green light to 0 parts of blue light and that the intensity is to be IN/10000 times the maximum possible. The RGB ratio 0:1:0 gives green, 0:0:1 blue, 1:1:0 yellow, 1:0:1 magenta, 0:1:1 cyan, and 1:1:1 white. The default is 1:1:1 at intensity 8000/10000 - white light at .8 maximum.) RGB ratios like 1:2:1, 13:6:8, etc. give other colors. In general, one must have an RGB color cube available in order to select a meaningful RGB ratio. (This is the one drawback to the RGB scheme, which was chosen because it is used by GKS. A scheme based on hue, saturation, and intensity is more user-friendly; such a scheme could, and probably will - time permitting - be built on top of this one.)
It is important to realize that, in the GKS scheme, the setting of color and intensity are inseparable and that the GKS calls setting them occur as a result of the fourth call in the above sequence - the one setting 'IN'. Re-setting one or more of 'IR', 'IG', and 'IB' will have no effect until after the next call setting 'IN'.
Devices like a pen plotter or a Dicomed record lines, points, and text serially; on such a device, if one sets the color to red and draws a line and then resets the color to blue and draws another line, one can expect to get exactly what one wants - a red line and a blue line. On devices having a screen which is continually refreshed, the situation is more complicated. Typically, each object drawn on such a device is associated with a "color index" - a pointer into a "color table", each element of which defines a particular color and intensity. If an object is drawn with color index 1, and then color table entry 1 is redefined, and then a second object is drawn with color index 1, the two objects will differ in color only until the next time the screen is refreshed - a fraction of a second. Thus, a different color index must be used for each desired color; the problem with that, of course, is that the number of such color indices is limited.
By default, SPPS uses only color index 1, which is appropriate for the Dicomed or for a pen plotter. The SPPS call
CALL SETUSV ('IM',IM)where IM is a positive integer, tells SPPS to use color indices 1 through IM. Such a call should be done once, at the beginning of the program; the value of IM should be appropriate to the graphics device being used. Subsequently, each time the intensity/color is changed, SPPS updates its current color index II to have the new value MOD(II,IM)+1 and uses that value for drawing subsequent objects. Note that II cycles repeatedly through the color indices 1 through IM.
SPPS has no mechanism allowing it to detect when the same intensity/color is being reused. Consider what happens if one sets 'IM' to 3 and draws four objects - the first and third in red, and the second and fourth in blue. If one did this in the obvious way - changing the color before drawing each new object - SPPS would use color index 1 for red, 2 for blue, 3 for red, and, finally, 1, again, for blue. At that point, the color of object 1 would change from red to blue. To get around this problem, one can recover from SPPS the value of the color index used for a particular intensity/color and then re-use that value as needed. The SPPS calls
CALL SETUSV ('IR',1) CALL SETUSV ('IG',0) CALL SETUSV ('IB',0) CALL SETUSV ('IN',5000) CALL GETUSV ('II',I1)define a half-intensity red and retrieve the color index associated with it in I1. At any later time, the SPPS call
CALL SETUSV ('II',I1)requests that the same half-intensity red be used. Thus, if necessary, one can define, up front, all the colors/intensities one is going to use, save the associated color indices in an array, and use SPPS calls like the last one above to switch from one color/intensity to the next.
CALL OPTN ('SS',16)had the effect of setting the "spot size" - the thickness of the beam or pen used to draw objects - to twice its default value of 8. The value given was a value in the metacode coordinate system - 16 really meant 16/32767ths of the distance across the screen. These values were appropriate for the Dicomed. The SPPS call
CALL SETUSV ('LW',2000)requests use of a beam/pen of twice "normal" width - whatever that is for the particular device being driven. The effect is seen only in lines; characters (generated by calls to PWRIT, WTSTR, or POINTS) and "markers" (generated by calls to POINTS) are unaffected.
CALL SETCND ('XT',n)where n had the value 1, 2, or 3, was intended to tell the plot package whether x coordinates in calls to routines like POINT and LINE were allowed to be either integers or reals (n=1), integers only (n=2), or reals only (n=3). Since the SPPS equivalents require that such x coordinates be reals, the above call has no equivalent in SPPS. The NSPP call
CALL SETCND ('YT',n)is analogous, but applied to y coordinates. The NSPP calls
CALL SETCND ('MU',n) CALL GETCND ('MU',n)were intended to get/set the current metacode output unit number. They may be replaced by the SPPS calls
CALL SETUSV ('MU',n) CALL GETUSV ('MU',n)It is unclear at the time of writing what the effect of switching to a previously-written metacode unit will be. It is possible that the new metacode output will simply overwrite the old. Check with a consultant to determine the current situation.