@X @~%|
~V7 56 2 -5
~D10
~H                   MUSS
~
~
~D10
~H             GRA021
~D10
~MMANCHESTER UNIVERSITY - CONFIDENTIAL
~
~
~V2 -16
                                                                       ISSUE 10~
~V2 0
~V9 -1
~P
~V9 1

~YGRA021
~V2 -6
~M~LGRAPHICS UTILITIES IMPLEMENTATION DESCRIPTION~
~
~M~LSection 21 Version 1~
~S1~LSection 21.1 Core Graphics Subset~
~S1~L1. General Description~
~BThis module provides graphical facilities conforming to
the GSPC CORE GRAPHICS Standard. The version implemented is a strict
suset of the full standard and has the following specification:~
~
   Output Level 1 (Basic output)~
~
   Input Level 1 (No input)~
~
   Dimension Level 1 (Two-dimensional)~
~
   Hiddensurface Level 1 (No hidden surface elimination)~
~
~S1~L2. Interfaces~
~
Other modules used~
   None.~
Hardware registers used~
   None.~
Interface Procedures~
   MOVE.ABS.2 (X, Y)~
   MOVE.REL.2 (DX, DY)~
   LINE.ABS.2 (X, Y)~
   LINE.REL.2 (DX, DY)~
   POLYLINE.ABS.2 (X.ARRAY, Y.ARRAY, COUNT)~
   POLYLINE.REL.2 (DX.ARRAY, DY.ARRAY, COUNT)~
   TEXT (STRING)~
   MARKER.ABS.2 (X, Y)~
   MARKER.REL.2 (DX, DY)~
   POLYMARKER.ABS.2 (X.ARRAY, Y.ARRAY, COUNT)~
   POLYMARKER.REL.2 (DX.ARRAY, DY.ARRAY, COUNT)~
   SET.COLOUR (COLOUR)~
   SET.INTENSITY (INTENSITY)~
   SET.LINESTYLE (STYLE)~
   SET.LINEWIDTH (WIDTH)~
   SET.PEN (PEN)~
   SET.FONT (FONT)~
   SET.CHAR.SIZE (SIZE)~
   SET.CHAR.JUST (JUST1, JUST2)~
   SET.CHAR.PRECISION (PRECISION)~
   SET.MARKER.SYMBOL (INDEX)~
   SET.PRIMITIVE.ATTRIBUTES.2 (ATTRIBUTE.ARRAY)~
   SET.WINDOW (XMIN, XMAX, YMIN, YMAX)~
   SET.VIEW.UP.2 (DX.UP, DY.UP)~
   SET.NDC.SPACE.2 (WIDTH, HEIGHT)~
   SET.VIEWPORT.2 (XMIN, XMAX, YMAIN, YMAX)~
   SET.WINDOW.CLIPPING (ON.OFF)~
   SET.COORD.SYSTEM.TYPE (TYPE)~
   SET.WORLD.COORD.MATRIX.2 (MATRIX)~
   ENQUIRE.COLOUR (COLOUR)~
   ENQUIRE.INTENSITY (INTENSITY)~
   ENQUIRE.LINESTYLE (STYLE)~
   ENQUIRE.LINEWIDTH (WIDTH)~
   ENQUIRE.PEN (PEN)~
   ENQUIRE.FONT (FONT)~
   ENQUIRE.CHAR.SIZE (SIZE)~
   ENQUIRE.CHAR.JUST (JUST1, JUST2)~
   ENQUIRE.CHAR.PRECISION (PRECISION)~
   ENQUIRE.MARKER.SYMBOL (INDEX)~
   ENQUIRE.PRIMITIVE.ATTRIBUTES.2 (ATTRIBUTE.ARRAY)~
   ENQUIRE.WINDOW (XMIN, XMAX, YMIN, YMAX)~
   ENQUIRE.VIEW.UP.2 (DX.UP, DY.UP)~
   ENQUIRE.NDC.SPACE.2 (WIDTH, HEIGHT)~
   ENQUIRE.VIEWPORT.2 (XMIN, XMAX, YMAIN, YMAX)~
   ENQUIRE.WINDOW.CLIPPING (ON.OFF)~
   ENQUIRE.COORD.SYSTEM.TYPE (TYPE)~
   ENQUIRE.WORLD.COORD.MATRIX.2 (MATRIX)~
   CREATE.TEMPORARY.SEGMENT ()~
   CLOSE.TEMPORARY.SEGMENT ()~
   ENQUIRE.OPEN.TEMPORARY.SEGMENT (STATUS)~
   MAP.NDC.TO.WORLD.2 (NDC.X, NDC.Y, WORLD.X, WORLD.Y)~
   MAP.WORLD.TO.NDC.2 (WORLD.X, WORLD.Y, NDC.X, NDC.Y)~
   INITIALISE.CORE (OUTLEVEL, INLEVEL, DIMLEVEL, HSURFLEVEL)~
   TERMINATE.CORE ()~
   INITIALISE.VIEW.SURFACE (NAME)~
   TERMINATE.VIEW.SURFACE (NAME)~
   SELECT.VIEW.SURFACE (NAME)~
   DESELECT.VIEW.SURFACE (NAME)~
   NEW.FRAME ()~
   ENQUIRE.OUTPUT.CAPABILITIES (CAPABILITIES.ARRAY)~
~
Interface Variables~
None.~
~S1~L2.1 Hardware Interface
~BThe Core Subset supports the following graphical output devices:~
~
   GENISCO Raster Scan Display~
~
   MOTOROLA MC68000 Raster Scan Display~
~
   BENSON Pen Plotter~
~
Additionally, a "Pseudo" device is supported, enabling storage and retrieval
of pictures.~
~S1~L2.2 Software Interface
~BThe detailed specification of each interface procedure is given in the
GSPC Core System Standard, and a briefer description in the MUSS User
Manual, Chapter 26 "Graphical Facilities".~
~S1~L3.1 Outline of operation
~BSince the Core Subset allows only one of the three graphical output devices
to be selected at any time, a switch is used to determine which set of
device driver procedures should be called to produce graphical output.
A standard set of device driver procedures is provided for deach device type.
Thus if the user specifies the Genisco raster scan display for use, and
requests a line to be drawn, the kernel will make a call eventually to
GENISCO.LINE (---).
~S1~L3.1.1 Device Capabilities
~BDifferent types of graphical output devices have different capabilities:
 one device may have hardware to draw dashed lines, while another may not.
This means that some forms of graphical output may need to be simulated
by software for a particular device. An extreme case of this is the Motorola
MC68000 raster scan display, which has no special-purpose graphics hardware
or microprocessor. The only graphical operation available with this device
is the capability to set the valuesof pixels in a memory map. Thus all
graphical output is implemented by software.
~BThe decision whether simulation is necessary or not is taken within the
device driver routinesor each device type.
~S1~L3.2 Data Structures
~T| 25
~
~
DEVICE CAPABILITIES~IAn array, indexed by device type number, of entries
describing the functional capabilities of graphic device drivers. Fields
of each entry are as follows:~
   :OUTPUT.LEVEL~IThe core output level supported~
   :DIM.LEVEL~IThe core dimension level supported~
   :DEV.TYPE~IReal or pseudo device~
   :VS.HEIGHT~IThe height of the entire available view surface (in cm.).~
   :VS.WIDTH~IThe width of the entire available view surface (in cm.).~
   :VS.NDC.WIDTH~IThe width of the area onto which NDC space is mapped (in cm.).
~
   :VS.NDC.HEIGHT~IThe height of the area onto which NDC space is mapped (in cm.
).~
   :VS.RES.HORIZ~IThe horizontal resolution of the view surface (addressable
elements per cm.).~
   :VS.RES.VERT~IThe vertical resolution of the view surface (addressable elemen
ts per cm.).~
   :COLOUR.COUNT~IThe number of colour values supported.~
   :INTENSITY.COUNT~IThe number of intensity values supported.~
   :INTENSITY.SIM~IDescribes whether INTENSITY is hardware supported or
simulated.~
   :LINE.STYLE.COUNT~IThe number of LINESTYLE values supported.~
   :LINE.STYLE.SIM~IDescribes whether LINESTYLE is hardware supported or
simulated.~
   :LINE.WIDTH.COUNT~IThe number of LINEWIDTH values supported.~
   :LINE.WIDTH.SIM~IDescribes whether LINEWIDTH is hardware supported or
simulated.~
   :LINE.WIDTH.MAX~IThe maximum LINEWIDTH value supported (in NDC coords).~
   :LINE.WIDTH.MIN~IThe minimum LINEWIDTH value supported (in NDC coords).~
   :PEN.HW.COUNT~IThe number of hardware supported PEN values.~
   :PEN.SW.COUNT~IThe number of simulated PEN values.~
   :FONT.COUNT~IThe number of FONT values supported.~
   :CHAR.SIZES~IThe number of CHARSIZE values supported.~
   :CHAR.SIZE.SIM~IDescribes whether CHARSIZE is hardware supported or
simulated.~
   :MARKER.HW.COUNT~IThe number of hardware supported MARKER values.~
   :MARKER.SW.COUNT~IThe number of simulated MARKER values.~
   :PICK.ID.COUNT~IThe number if PICK.ID values supported.~
   :HIGHLIGHT.SIM~IDescribes whether HIGHLIGHTING is hardware supported
or simulated.~
   :IMAGE.TRANS.SIM~IDescribes whether IMAGE.TRANSFORMATIONS are hardware
supported or simulated.~
~
DEVICE.STATUS~IAn array with one entry per graphic output device in a MUSS
system.Each entry consistes of the following fields:~
   :DEV.TYPE~IThe generic type of the device, such as GENISCO, BENSON.~
   :DEV.VS.NAME~IThe view surface name by which the device is known to
the Core.~
   :DEV.INIT~IThis indicates whether the device has been initialised
by the Core.~
   :DEV.SELECT~IThis indicates whether the device has been seletced by the
the Core.~
~
~
The following variables hold the current values of Core attributes.~
~
~
LINEWIDTH~IThe current LINEWIDTH in NDC coords.~
LINE.STYLE~IThe current LINESTYLE value.~
CHAR.SIZE~IThe current CHARSIZE value.~
PEN~IThe current PEN value.~
LINE.COL~IAn array of three elements defining the current line colour.~
LINE.INT~IThe current line INTENSITY value.~
FILL.COL~IAn array of three elements defining the current fill colour.~
FILL.INT~IThe current intensity value for filled polygons.~
TEXT.COL~IAn array of three values defining the current text colour.~
TEXT.INT~IThe current text intensity value.~
FONT~IThe current character FONT value.~
CH.PATH~IThe current CHARPATH value.~
CH.JUST~IAn array of two valus defining the current pair of CHARJUST values.~
PICK.ID~IThe current PICK.ID value.~
MARKER~IThe current MARKER.SYMBOL value.~
LINE.INDEX~IThe current LINE.INDEX value.~
FILL.INDEX~IThe current FILL.INDEX value.~
TEXT.INDEX~IThe current FILL.INDEX value.~
POLY.INTR~IThe current polygon INTERIOR.STYLE value.~
EDGE.STYLE~IThe current EDGE.STYLE value.~
BACK.INDEX~IThe current BACKGROUND.INDEX value.~
~
CP.X~IThe x-component of the current position.~
CP.Y~IThe y-component of the current position.~
~
VIEW.Up~IAn array of two elements defining the current VIEW.UP vector. The
fields are:~
   :VU.X~Ithe x-component of the vector~
   :VU.Y~Ithe y-component of the vector~
~
NDC.SPACE~IAn array of two elements defining the current NDC space. The fields a
re:~
   :NDC.HEIGHT~Iheight of NDC space~
   :NDC.WIDTH~Iwidth of NDC space~
~
VIEWPORT~IAn array of four elements defining the current viewport. The fields ar
e:~
   :V.XMIN~Ilow x-coordinate of the viewport~
   :V.XMAX~Ihigh x-coordinate of the viewport~
   :V.YMIN~Ilow y-coordinate of the viewport~
   :V.YMAX~Ihigh y-coordinate of the viewport~
~
WORLD.MATRIX~IAn array of nine values defining the current world coordinate
transformation matrix. If the matrix is written as~
~
~Ma b c
~Md e f
~Mg h i
~
~Ithen the values are stored in the array as:~
~
~Ma b c d e f g h i


~
CORE.STATUS~IAn array describing the current state of teh Core Subset. The
fields are:~
   :CLIPPING~Idescribes if window clipping is enabled or disabled~
   :WORLD.TYPE~Idescribes the handedness of the user world coordinate system~
   :SEGMENT~Idescribes whether a temorary segment is currently open~
   :NDC.INIT~Idescribes whether NDC space has yet been defined~
~S1~L3.3 Special Notes
~B None.
~S1~L4. Compile Jobs~
~S1~L4.1 Private Library Compile Job for SUBSET on VAX
~
::BEGIN COMP PRIVATE SUBSET FOR VAX~
OPENDIR UTIL ITIES~
MUSL 0 SUBSET %405 64~
**TLSEG 0 0	%170000 -1 2~
**TLSEG 1 0 0 -3 0~
**TLSEG 2 0	%300000 -2 12~
**TLSEG 3 %10000 %110000 -3 12~
**TLLOAD 1 6~
**TLLOAD 2 7~
**TLLOAD 3 8~
*INFORM %2400;~
$PS KERNEL.INIT();~
$PS GEN.INIT (); $PS BENSON.INIT (); $PS M68.INIT (); $PS HP.INIT ();~
$PS KERNEL.TERM();~
$PS GEN.TERM (); $PS BENSON.TERM (); $PS M68.TERM (); $PS HP.TERM ();~
$PS KERNEL.NEW.FRAME ();~
$PS GEN.NEW.FRAME (); $PS BENSON.NEW.FRAME ();~
$PS M68.NEW.FRAME(); $PS HP.NEW.FRAME ();~
$PS KERNEL.LINE($RE,$RE,$RE,$RE);~
$PS GEN.LINE ($RE, $RE, $RE, $RE);~ $PS BENSON.LINE ($RE, $RE, $RE, $RE);
$PS M68.LINE ($RE, $RE, $RE, $RE);~ $PS HP.LINE ($RE, $RE, $RE, $RE);
$PS KERNEL.TEXT($RE, $RE, $AD [$LO8], $IN);~
$PS GEN.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS BENSON.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS M68.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS HP.TEXT ($RE, $RE, $AD [$LO8], $IN);~
$PS KERNEL.MARKER ($RE, $RE, $LO8);~
$PS GEN.MARKER ($RE, $RE, $LO8); $PS BENSON.MARKER ($RE, $RE, $LO8);~
$PS M68.MARKER ($RE, $RE, $LO8); $PS HP.MARKER ($RE, $RE, $LO8);~
$PS KERNEL.ATTR ($IN);~
$PS GEN.ATTR ($IN);~ $PS BENSON.ATTR ($IN);
$PS M68.ATTR ($IN); $PS HP.ATTR ($IN);~
$PS KERNEL.REPORT ($AD [$RE], $AD [$IN]);~
$PS GEN.REPORT ($AD [$RE], $AD [$IN]);~
$PS BENSON.REPORT ($AD [$RE], $AD [$IN]);~
$PS M68.REPORT ($AD [$RE], $AD [$IN]);~
$PS HP.REPORT ($AD [$RE], $AD [$IN]);~
MODULE (DEV.INIT, DEV.TERM, DEV.NEW.FRAME, DEV.LINE,~
   DEV.TEXT, DEV.MARKER, DEV.ATTR, DEV.REPORT, DEV.NAME, DEVS,~
   DEV.INIT.PS,DEV.TERM.PS,DEV.NEW.FRAME.PS,DEV.LINE.PS,~
   DEV.TEXT.PS,DEV.MARKER.PS,DEV.ATTR.PS,DEV.REPORT.PS);~
$LI DEVS = 5;~
-> ROUND;
*GLOBAL 1;
$DA DEV.NAME ($LO64)~
"KERNEL"~
"GENISCO"~
"MOTOROLA"~
"BENSON"~
"HP"~
END~
$PS DEV.INIT.PS (); $PS DEV.TERMPS ();~
$PS DEV.NEW.FRAME.PS ();~
$PS DEV.LINE.PS ($RE, $RE, $RE, $RE);~
$PS DEV.TEXT.PS ($RE, $RE, $AD [$LO8], $IN);~
$PS DEV.MARKER.PS ($RE, $RE, $LO8);~
$PS DEV.ATTR.PS ($IN);
$PS DEV.REPORT.PS ($AD [$RE], $AD [$IN]);~
$DA DEV.INIT ($AD DEV.INIT.PS)~
KERNEL.INIT~
GEN.INIT~
BENSON.INIT~
M68.INIT~
HP.INIT~
END
$DA DEV.TERM ($AD DEV.TERM.PS)~
KERNEL.TERM~
GEN.TERM~
BENSON.TERM~
M68.TERM~
HP.TERM~
END
$DA DEV.NEW.FRAME ($AD DEV.NEW.FRAME.PS)~
KERNEL.NEW.FRAME~
GEN.NEW.FRAME~
BENSON.NEW.FRAME~
M68.NEW.FRAME~
HP.NEW.FRAME~
END
$DA DEV.LINE ($AD DEV.LINE.PS)~
KERNEL.LINE~
GEN.LINE~
BENSON.LINE~
M68.LINE~
HP.LINE~
END~
$DA DEV.TEXT ($AD DEV.TEXT.PS)~
KERNEL.TEXT~
GEN.TEXT~
BENSON.TEXT~
M68.TEXT~
HP.TEXT~
END~
$DA DEV.MARKER ($AD DEV.MARKER.PS)~
KERNEL.MARKER~
GEN.MARKER~
BENSON.MARKER~
M68.MARKER~
HP.MARKER~
END~
$DA DEV.ATTR ($AD DEV.ATTR.PS)~
KERNEL.ATTR~
GEN.ATTR~
BENSON.ATTR~
M68.ATTR~
HP.ATTR~
END~
$DA DEV.REPORT ($AD DEV.REPORT.PS)~
KERNEL.REPORT~
GEN.REPORT~
BENSON.REPORT~
M68.REPORT~
HP.REPORT~
END;~
*GLOBAL 0;
ROUND:
*END~
FLIP GRA021/MU6S 1~
GRA02~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP DOC111/MU6S 1~
DOC11~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP DOC121/MU6S 1~
DOC12~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP DOC131/MU6S 1~
DOC13~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP DOC141/MU6S 1~
DOC14~
DI 4 0~
MUSL 0 0 %C00~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
FLIP DOC151/MU6S 1~
DOC15~
DI 4 0~
MUSL 0 0 %800~
*INFORM %2400;~
**SELECTINPUT 4~
EI 4~
STOP~
::END COMP~
~
~
~Y
~P
~V9 -1
~D 15
~HFLOWCHARTS
~
~
~H           GRA021
~V9 -1
~F
@TITLE GRA02(1,10)
@COL 1S-2R-3R-4R-5R-6F
@FLOW 1-2-3-4-5-6
@BOX 1.0
GRA02 MASTER
@BOX 2.0
@BOX 3.0
@BOX 4.0
SUB-SECTIONS IN MODULE:
   1 CONTROL
   2 OUTPUT PRIMITIVES
   3 ATTRIBUTES
   4 PICTURE SEGMENTATION
   5 VIEWING
   6 GENISCO DEVICE DRIVER
   7 BENSON DEVICE DRIVER
@BOX 5.0
@BOX 6.0
END
@BOX 1.1
#GRA02/1
$PS DEV.INIT.PS();
$PS DEV.TERM.PS();
$PS DEV.NEWFRAME.PS();
$PS DEV.LINE.PS($RE,$RE,$RE,$RE);
$PS DEV.TEXT.PS($RE,$RE,$AD[$LO8],$IN);
$PS DEV.MARKER.PS($RE,$RE,$LO8);
$PS DEV.ATTR.PS($IN);
$PS DEV.REPORT.PS($AD[$RE], $AD[$IN]);
$IM $LI DEVS;
$LO64 [DEVS] DEV.NAME;
$AD DEV.INIT.PS [DEVS] DEV.INIT;
$AD DEV.TERM.PS [DEVS] DEV.TERM;
$AD DEV.NEWFRAME.PS [DEVS] DEV.NEWFRAME;
$AD DEV.LINE.PS [DEVS] DEV.LINE;
$AD DEV.TEXT.PS [DEVS] DEV.TEXT;
$AD DEV.MARKER.PS [DEVS] DEV.MARKER;
$AD DEV.ATTR.PS [DEVS] DEV.ATTR;
$AD DEV.REPORT.PS [DEVS] DEV.REPORT;
MODULE (initIALISE.CORE, termINATE.CORE, InitIALISE.VIEW.sUrfACE, tErmINATE.VIEW
.sUrfACE,
   selECT.VIEW.sUrfACE, deSElECT.VIEW.sUrfACE, new.frAmE, movE.aBS.2, movE.rEL.2
,
   linE.aBS.2, linE.rEL.2, pOLYlinE.aBS.2, pOLYlinE.rEL.2, TEXT, markER.aBS.2, m
arkER.rEL.2,
   pOLYmarkER.aBS.2, pOLYmarkER.rEL.2, SET.INTENSITY, sET.lINEstylE,
   sET.lInE.INdEx, sET.tEXT.INdEx, iNQ.lInE.INdEx, iNQ.tEXT.IndEx,
   sET.lINEwidTH, sET.pen, sET.font, sET.chARsizE, sET.chARjUst, sET.chARpreCISI
ON,
   sET.mARkER.symBOL, INQ.INTENSITY, SET.CHARPATH, INQ.CHARPATH,
   iNQ.lINEstylE, iNQ.lINEwidTH, iNQ.pen, iNQ.font, iNQ.chARsizE,
  iNQ.chARjUst, iNQ.chARpreCISION, iNQ.mARkER.symBOL,
    crEAtE.TEMP.seg, clOSE.tEMP.seg, iNQ.oPEN.tEMP.seg,
   sET.windoW, sET.ndc.sPACE.2, sET.vIEWpOrt.2, sET.clip.w,
   mAP.nDC.to.wORLD.2, iNQ.windoW, iNQ.outPUT.cAPS, INQ.TEXT.EXTENT.2,
   iNQ.ndc.sPACE.2, iNQ.vIEWpOrt.2, iNQ.clip.w, mAP.wORLD.to.nDC.2,
   PW0,PW1,PW2,PW3,PW4,PW5,PW6,
   C.LINE.STYLE,C.LINE.INDEX,C.TEXT.INDEX,C.CHAR.PATH,PEN,CHARSZ.HEIGHT,CHARSZ.W
IDTH,
   NDC.SCALE,OLD.OUTPUT.STREAM,C.COLOUR,PLT.X ,PLT.Y,C.LINEWIDTH,C.FONT,C.MARKER
,
TXSIN,TXCOS);
@BOX 2.1
*GLOBAL 6;
$IN PW0, PW1, PW2, PW3, PW4, PW5, PW6;
$LO64 PWW0, PWW1, PWW2, PWW3, PWW4;
*GLOBAL 7;
$ADDEV.INIT.PS DEV.INIT.P;
$ADDEV.TERM.PS DEV.TERM.P;
$ADDEV.NEWFRAME.PS DEV.NEWFRAME.P;
$ADDEV.LINE.PS DEV.LINE.P;
$ADDEV.TEXT.PS DEV.TEXT.P;
$ADDEV.MARKER.PS DEV.MARKER.P;
$ADDEV.ATTR.PS DEV.ATTR.P;
$ADDEV.REPORT.PS DEV.REPORT.P;
LITERAL / INTEGER GEN = 1, BEN = 2, NONE = -1;
LITERAL / LOGICAL8  INIT = 3, TERM = 4,
                   UNDEF = 5, OFF = 0, ON = 1, OPEN = 8, CLOSED = 9, DEF = 10,
                   SOLID = 1, DASHED = 2, CR = %0D, LF = %0A;
LITERAL / INTEGER SYS14.SEG.SIZE = %10000, GR.MAPPED.SEG = 0, PEN.UP = 0, PEN.DO
WN = 1;
ADDR [$IN16] GENISCO;
$IN GENISCO.VA, PTR, BLOCK.NO, GEN.SEG.NO, OLD.SEG.NO;
INTEGER OLD.OUTPUT.STREAM, BEN.FILE;
INTEGER SELECTED.DEVICE, INITIALISED.DEVICE, CORE.STATUS,
        CLIPPING, SEG.STATUS, NDC.STATUS;
 $IN [DEVS] D.INIT;
INTEGER C.MARKER, C.COLOUR, INTENSITY, C.LINESTYLE, C.LINEWIDTH, MAX.INDEX,
        PEN, C.FONT, C.CHARSIZE, C.CHARJUST, C.CHARPRECISION,
        C.CHARJUST.H, C.CHARJUST.V, C.LINE.INDEX, C.TEXT.INDEX;
REAL CP.X, CP.Y, VP.X.SCALE, VP.Y.SCALE, VP.X.MIN, VP.X.MAX, VP.Y.MIN, VP.Y.MAX,
     WNDW.X.MIN, WNDW.X.MAX, WNDW.Y.MIN, WNDW.Y.MAX, NDC.X, NDC.Y,
     TX.COS, TX.SIN, CH.NDC.W, CH.NDC.H,
     CHARSZ.HEIGHT, CHARSZ.WIDTH, NDC.SCALE, PLT.X, PLT.Y;
INTEGER C.CHARPATH;
 TYPE DEV.ID.TYPE IS
      $IN OSTR,DEV.NO,DEV.SPN,DEV.PID
      $IN D.TYPE,D.MODE
      $LO8 SELECTED;
  DEV.ID.TYPE [DEVS] DEV.ID;
::DEVICE CAPABILITY BLOCK
INTEGER OP.LEVEL, DIM.LEVEL, PHYSICAL, COL.COUNT, INTEN.COUNT, INTEN.SIM,
        LINSTYL.HW.COUNT, LINSTYL.SW.COUNT, LINEWIDTH.COUNT, LINEWIDTH.SIM,
        PEN.HW.COUNT, PEN.SW.COUNT, FONT.COUNT, CH.SIZE.COUNT, CH.SIZE.SIM,
        MARK.HW.COUNT, MARK.SW.COUNT, PICK.ID.COUNT, HIGHLT.SIM, IM.TRANS,
        BATCHING;
REAL VS.FULL.WIDTH, VS.FULL.HEIGHT, MAPPED.NDC.WIDTH, MAPPED.NDC.HEIGHT,
     RES.HORIZ, RES.VERT, LINEWIDTH.MIN, LINEWIDTH.MAX, CH.SIZE.MIN,
     CH.SIZE.MAX;
*GLOBAL 0;
@BOX 3.1
@BOX 4.1
   #GRA02.5/1
   #GRA02.1
   #GRA02.2
   #GRA02.3
   #GRA02.4
   #GRA02.5
@BOX 5.1
@BOX 6.1
*END
@END

@TITLE GRA02/1(1,10)
@COL 1S-2R-3R-4R
@FLOW 1-2-3-4
@BOX 1.0
OTHER MODULES REFERENCED
@BOX 2.0
@BOX 3.0
@BOX 4.0
@BOX 1.1
::EXTERNAL ENVIRONMENT
@BOX 2.1
LSPEC START.GR.OPERATION ($IN);
LSPEC STOP.GR.OPERATION ($IN);
LSPEC CREATE.SEGMENT ($IN, $IN);
LSPEC MAP ($IN, $IN, $IN);
LSPEC GR.WRITE ($IN, $IN, $IN, $IN);
LSPEC CURRENT.OUTPUT () / $IN;
LSPEC DEFINE.OUTPUT ($IN, ADDR [$LO8], $IN, $IN, $IN, $IN) / $IN;
LSPEC SELECT.OUTPUT ($IN);
@BOX 3.1
@BOX 4.1
@END
@TITLE GRA02.1(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
CONTROL
@BOX 2.0
PROCEDURES IN SUBSECTION :
   INITIALISE CORE
   TERMINATE CORE
   INITIALISE VIEW SURFACE
   TERMINATE VIEW SURFACE
   SELECT VIEW SURFACE
   DESELECT VIEW SURFACE
   NEW FRAME
   FAULT
@BOX 1.1
::CONTROL
LSPEC SET.CHARSIZE ($RE, $RE);
LSPEC INITIALISE.CORE ($IN, $IN, $IN, $IN);
LSPEC TERMINATE.CORE ();
LSPEC INITIALISE.VIEW.SURFACE ($IN, $IN, $IN);
LSPEC TERMINATE.VIEW.SURFACE ($IN);
LSPEC SELECT.VIEW.SURFACE ($IN);
LSPEC DESELECT.VIEW.SURFACE ( $IN);
LSPEC NEW.FRAME ();
PSPEC FAULT ($IN, $IN);
@BOX 2.1
#GRA02.1.1
#GRA02.1.2
#GRA02.1.3
#GRA02.1.4
#GRA02.1.5
#GRA02.1.6
#GRA02.1.7
#GRA02.1.8
@END
@TITLE GRA02.1.1(1,10)
@COL 7R
@COL 8R
@COL 1S-2T-3T-4R-5R-9R-6F
@ROW 8-4
@ROW 7-5
@FLOW 1-2NOT INIT-3VALID-4-5-9-6
@FLOW 2INIT-7-6
@FLOW 3NOT VALID-8-6
@BOX 1.0
INITIALISE CORE (OUT LEV, IN LEV, DIM LEV)
@BOX 2.0
CORE ALREADY INITIALISED ?
@BOX 3.0
ALL REQUESTED LEVELS VALID ?
@BOX 4.0
MARK CORE AS INITIALISED
@BOX 5.0
SET ALL CORE DEFAULTS
@BOX 6.0
END
@BOX 7.0
ERROR
@BOX 8.0
ERROR
@BOX 9.0
SET UP DEVICE TABLE
@BOX 1.1
PROC INITIALISE.CORE (OUT.LEV, IN.LEV, DIM.LEV, HID.SURF);
  $IN I,J;
@BOX 2.1
IF CORE.STATUS = INIT
@BOX 3.1
IF OUT.LEV /= 1 OR IN.LEV /= 1 OR DIM.LEV /= 1 OR HID.SURF /= 1
@BOX 4.1
INIT => CORE.STATUS;
@BOX 5.1
0.0 => WNDW.X.MIN => WNDW.Y.MIN => VP.X.MIN => VP.Y.MIN;
1.0 => VP.X.SCALE => VP.Y.SCALE;
1.0 => WNDW.X.MAX => WNDW.Y.MAX => VP.X.MAX => VP.Y.MAX;
0.0 => CP.X => CP.Y;
0.01 => CHARSZ.HEIGHT => CHARSZ.WIDTH;
0 => C.MARKER => PEN => C.CHARPATH;
1 => C.CHARPRECISION => C.LINE.INDEX => C.TEXT.INDEX;
UNDEF => NDC.STATUS;
ON => CLIPPING;
CLOSED => SEG.STATUS;
NONE => SELECTED.DEVICE;
@BOX 6.1
END
@BOX 7.1
FAULT (14, 6);
@BOX 8.1
FAULT (15, 4);
@BOX 9.1
FOR I< DEVS DO
  TERM => D.INIT[I];
  SELECT DEV.ID [I];
   0=> OSTR =>SELECTED;
   I=> DEV.NO;
OD
@END
@TITLE GRA02.1.2(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
TERMINATE.CORE ()
@BOX 2.0
TERMINATE SELECTED DEVICE IF ANY
@BOX 3.0
RESET CORE STATUS
@BOX 4.0
END
@BOX 1.1
PROC TERMINATE.CORE;
$IN I,J;
@BOX 2.1
FOR I < DEVS DO
  IF D.INIT [I] = INIT THEN
    TERM => D.INIT [I];
    DEV.NO OF DEV.ID [I] =>J;
    DEV.TERM [J] => DEV.TERM.P;
    DEV.TERM.P^ ();
  FI;
OD;
@BOX 3.1
TERM => CORE.STATUS;
@BOX 4.1
END
@END
@TITLE GRA02.1.3(1,10)
@COL 6R
@COL 1S-2T-4T-9T-10R-8R-5F
@COL 7R
@ROW 6-4
@ROW 8-7
@FLOW 1-2NO-6-5
@FLOW 2YES-4ILLEGAL-7-5
@FLOW 4LEGAL-9NOT DEF-10-8-5
@FLOW 9DEF-8
@BOX 1.0
INITIALISE VIEW SURFACE (SURFACE, S.TYPE, MODE)
@BOX 2.0
CAN A DEVICE BE INITIALISED ?
@BOX 4.0
LEGAL SURFACE REQUESTED ?
@BOX 5.0
END
@BOX 6.0
ERROR
@BOX 7.0
ERROR
@BOX 8.0
INITIALISE THE VIEW SURFACE
@BOX 9.0
IS NDC SPACE DEFINED ?
@BOX 10.0
DEFINE DEFAULT NDC SPACE
[GRA02.5.2]
@BOX 1.1
PROC INITIALISE.VIEW.SURFACE (SURFACE, S.TYPE, MODE);
@BOX 2.1
IF INITIALISED.DEVICE = INIT
@BOX 4.1
IF SURFACE <1 OR SURFACE > DEVS
@BOX 5.1
END
@BOX 6.1
FAULT (17, 8);
@BOX 7.1
FAULT (16, 7);
@BOX 8.1
DEV.INIT [DEV.NO OF DEV.ID[SURFACE-1] ] => DEV.INIT.P;
 DEV.INIT.P ^();
INIT => D.INIT [SURFACE-1] => INITIALISED.DEVICE;
@BOX 9.1
IF NDC.STATUS = DEF
@BOX 10.1
SET.NDC.SPACE.2 (1.0, 1.0);
@END
@TITLE GRA02.1.4(1,10)
@COL 1S-3T-6R-4F
@COL 5R
@ROW 6-5
@FLOW 1-3ILLEGAL-5-4
@FLOW 3LEGAL-6-4
@BOX 1.0
TERMINATE VIEW SURFACE (SURFACE)
@BOX 3.0
LEGAL VIEW SURFACE IDENTIFIER ?
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 6.0
TERMINATE VIEW SURFACE
@BOX 1.1
PROC TERMINATE.VIEW.SURFACE (SURFACE);
   $IN I ,J;
@BOX 3.1
IF SURFACE <1 OR SURFACE>DEVS
@BOX 4.1
END
@BOX 5.1
FAULT (16, 7);
@BOX 6.1
 DEV.NO OF DEV.ID [SURFACE-1] => I;
 DEV.TERM [I] => DEV.TERM.P;
 DEV.TERM.P^();
TERM => D.INIT [SURFACE-1];
NONE => INITIALISED.DEVICE;
@END
@TITLE GRA02.1.5(1,10)
@COL 9R
@COL 10R
@COL 1S-2T-4T-5T-6T-7R-8F
@COL 11R
@COL 12R
@ROW 9-4
@ROW 10-6-12
@ROW 7-11
@FLOW 1-2VALID-4VALID-5YES-6NO-7-8
@FLOW 2INVALID-9-8
@FLOW 4INVALID-10-8
@FLOW 5NO-12-8
@FLOW 6YES-11-8
@BOX 1.0
SELECT.VIEW.SURFACE (SURFACE);
@BOX 2.0
VALID TO SELECT A DEVICE ?
@BOX 4.0
VALID SURFACE IDENTIFIER ?
@BOX 5.0
DEVICE ALREADY INITIALISED ?
@BOX 6.0
DEVICE ALREADY SELECTED ?
@BOX 7.0
MARK DEVICE A S SELECTED
@BOX 8.0
END
@BOX 9.0
ERROR
@BOX 10.0
ERROR
@BOX 11.0
ERROR
@BOX 12.0
ERROR
@BOX 1.1
PROC SELECT.VIEW.SURFACE (SURFACE);
@BOX 2.1
IF SELECTED.DEVICE /= NONE
@BOX 4.1
 IF SURFACE <1 OR SURFACE>DEVS
@BOX 5.1
 IF D.INIT [SURFACE-1] /= INIT
@BOX 6.1
 SELECT DEV.ID [SURFACE-1]
   IF SELECTED =1
@BOX 7.1
 1 => SELECTED;
 DEV.NO => SELECTED.DEVICE;
 DEV.ATTR [DEV.NO] => DEV.ATTR.P;
  DEV.ATTR.P^(3);
@BOX 8.1
END
@BOX 9.1
FAULT (19, 8);
@BOX 10.1
FAULT (16, 7);
@BOX 11.1
FAULT (18, 6);
@BOX 12.1
FAULT (16, 6);
@END

@TITLE GRA02.1.6(1,10)
@COL 7R
@COL 1S-3T-4T-5R-6F
@COL 8R
@ROW 4-8
@ROW 7-5
@FLOW 1-3VALID-4YES-5-6
@FLOW 3INVALID-8-6
@FLOW 4NO-7-6
@BOX 1.0
DESELECT VIEW SURFACE (SURFACE)
@BOX 3.0
VALID SURFACE IDENTIFIER ?
@BOX 4.0
DEVICE SELECTED ?
@BOX 5.0
DESELECT DEVICE
@BOX 6.0
END
@BOX 7.0
ERROR
@BOX 8.0
ERROR
@BOX 1.1
PROC DESELECT.VIEW.SURFACE (SURFACE);
@BOX 3.1
IF SURFACE <1 OR SURFACE >DEVS
@BOX 4.1
SELECT DEV.ID [SURFACE-1];
 IF SELECTED /=1
@BOX 5.1
 0=> SELECTED;
NONE => SELECTED.DEVICE;
@BOX 6.1
END
@BOX 7.1
FAULT (20, 6);
@BOX 8.1
FAULT (16, 7);
@END

@TITLE GRA02.1.7(1,10)
@COL 5R
@ROW 5-3
@COL 1S-2T-3R-4F
@FLOW 1-2YES-3-4
@FLOW 2NO-5-4
@BOX 1.0
NEW FRAME ()
@BOX 2.0
IS A VIEW SURFACE SELECTED ?
@BOX 3.0
SWITCH ON DEVICE TYPE TO CALL
DEVICE NEW FRAME
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC NEW.FRAME ;
@BOX 2.1
IF SELECTED.DEVICE = NONE
@BOX 3.1
DEV.NEWFRAME [SELECTED.DEVICE] =>DEV.NEWFRAME.P;
 DEV.NEWFRAME.P^();
@BOX 4.1
END
@BOX 5.1
FAULT (4,1);
@END
@TITLE GRA02.1.8(1,10)
@COL 1S-4R-2R-5R-3F
@FLOW 1-4-2-5-3
@BOX 1.0
FAULT (REASON, SEVERITY)
@BOX 2.0
SWITCH ON FAULT CODE AND PRODUCE MESSAGE
@BOX 3.0
END
@BOX 4.0
IF BENSON SELECTED
SELECT FAULT MESSAGE OUTPUT STREAM
@BOX 5.0
IF BENSON SELECTED
DESELECT FAULT OUTPUT STREAM
@BOX 1.1
PROC FAULT (REASON, SEVERITY);
  $IN I ,J;
@BOX 2.1
CAPTION (%"CORE ERROR ");
ALTERNATIVE REASON FROM
   CAPTION (%"(0,0) NOTHING");
   CAPTION (%"(2,5) N is less than or equal to zero ");
   CAPTION (%"(6,6) a temporary segment is open ");
   CAPTION (%"(301,6) there already is an open segment ");
   CAPTION (%"(307,6) there is no open temporary segment ");
   CAPTION (%"(401,5) one or more attribute values is invalid ");
   CAPTION (%"(501,5) x.min not less than x.max or y.min not less than y.max ");
   CAPTION (%"(503,6) SET.NDC.SPACE.2 has already been invoked ");
   CAPTION (%"(505,5) a parameter is not in the range 0 to 1 ");
   CAPTION (%"(506,5) neither width nor height has a value of 1 ");
   CAPTION (%"(507,5) width or height equals zero ");
   CAPTION (%"(508,5) one or more viewport corners is outside NDC space ");
   CAPTION (%"(510,5) the specified NDC position is outside the current viewport
 ");
   CAPTION (%"(512,5) the specified World position is outside the current window
 ");
   CAPTION (%"(701,6) the Core is already initialised ");
   CAPTION (%"(702,4) the specified output level cannot be supported ");
   CAPTION (%"(706,7) no output device is associated with the specified view sur
face");
   CAPTION (%"(707,8) no other view surface can currently be initialised ");
   CAPTION (%"(709,6) the specified view surface is already initialised ");
   CAPTION (%"(710,8) the specified view surface cannot be selected ");
   CAPTION (%"(711,6) the specified view surface is not selected ");
END;
CAPTION (%"$L");
@BOX 3.1
END
@BOX 4.1
  -1 => J;
FOR I < DEVS DO
 IF DEV.NO OF DEV.ID [I]=SELECTED.DEVICE AND
    OSTR  OF DEV.ID [I] /= OLD.OUTPUT.STREAM THEN

   SELECT.OUTPUT (OLD.OUTPUT.STREAM);
       I>J;
    -> OUT;
 FI;
DO
 OUT:
@BOX 5.1
IF J /=-1 THEN
  SELECT.OUTPUT (OSTR OF DEV.ID[J];
FI;
@END
@TITLE GRA02.2(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
OUTPUT PRIMITIVES
@BOX 2.0
PROCEDURES IN SUBSECTION :
   MOVE ABS 2
   MOVE REL 2
   LINE ABS 2
   LINE REL 2
   POLYLINE ABS 2
   POLYLINE REL 2
   TEXT
   MARKER ABS 2
   MARKER REL 2
   POLYMARKER ABS 2
   POLYMARKER REL 2
@BOX 1.1
LSPEC MOVE.ABS.2 ($RE, $RE);
LSPEC MOVE.REL.2 ($RE, $RE);
LSPEC LINE.ABS.2 ($RE, $RE);
LSPEC LINE.REL.2 ($RE, $RE);
LSPEC POLYLINE.ABS.2 (ADDR [$RE], ADDR [$RE], $IN);
LSPEC POLYLINE.REL.2 (ADDR [$RE], ADDR [$RE], $IN);
LSPEC TEXT (ADDR [$LO8], $IN);
LSPEC MARKER.ABS.2 ($RE, $RE);
LSPEC MARKER.REL.2 ($RE, $RE);
LSPEC POLYMARKER.ABS.2 (ADDR [$RE], ADDR [$RE], $IN);
LSPEC POLYMARKER.REL.2 (ADDR [$RE], ADDR [$RE], $IN);
@BOX 2.1
#GRA02.2.1
#GRA02.2.2
#GRA02.2.3
#GRA02.2.4
#GRA02.2.5
#GRA02.2.6
#GRA02.2.7
#GRA02.2.8
#GRA02.2.9
#GRA02.2.10
#GRA02.2.11
@END

@TITLE GRA02.2.1(1,10)
@COL 1S-2R-4F
@FLOW 1-2-4
@BOX 1.0
MOVE ABS 2 (X, Y)
@BOX 2.0
UPDATE CURRENT POSITION
@BOX 4.0
END
@BOX 1.1
PROC MOVE.ABS.2 (X, Y);
@BOX 2.1
X  => CP.X;
Y  => CP.Y;
@BOX 4.1
END
@END
@TITLE GRA02.2.2(1,10)
@COL 1S-2R-4F
@FLOW 1-2-4
@BOX 1.0
MOVE REL 2 (DX, DY)
@BOX 2.0
UPDATE CURRENT POSITION
@BOX 4.0
END
@BOX 1.1
PROC MOVE.REL.2 (DX, DY);
@BOX 2.1
DX +> CP.X ;
DY +> CP.Y ;
@BOX 4.1
END
@END

@TITLE GRA02.2.3(1,10)
@COL 1S-2R-3R-8T-4T-5R-6R-7F
@FLOW 1-2-3-8CLIP-4VISIBLE-5-6-7
@FLOW 8NO CLIP-5
@FLOW 4REJECT-7
@BOX 1.0
LINE ABS 2 (X, Y)
@BOX 2.0
COPY CORE CP
@BOX 3.0
UPDATE CORE CP
@BOX 4.0
CLIP TO CURRENT WINDOW
[GRA02.5.9]
IS LINE VISIBLE ?
@BOX 5.0
MAP WORLD TO VIEWPORT
[GRA02.5.7]
@BOX 6.0
SWITCH ON DEVOCE TYPE TO DRAW LINE
@BOX 7.0
END
@BOX 8.0
IS WINDOW CLIPPING ON ?
@BOX 1.1
PROC LINE.ABS.2 (X1, Y1);
$RE X0, Y0;
@BOX 2.1
CP.X => X0;
CP.Y => Y0;
@BOX 3.1
X1 => CP.X;
Y1 => CP.Y;
@BOX 4.1
IF  CLIP (^X0, ^Y0, ^X1, ^Y1) /= 1
@BOX 5.1
WORLD.TO.VIEWPORT (^X0, ^Y0);
WORLD.TO.VIEWPORT (^X1, ^Y1);
@BOX 6.1
 DEV.LINE [SELECTED.DEVICE] => DEV.LINE.P;
 DEV.LINE.P^ (X0,Y0,X1,Y1);
@BOX 7.1
END
@BOX 8.1
IF CLIPPING = OFF
@END
@TITLE GRA02.2.4(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
LINE REL 2 (DX, DY)
@BOX 2.0
CALL LINE ABS 2 TO CP.X+DX, CP.Y+DY
@BOX 3.0
END
@BOX 1.1
PROC LINE.REL.2 (DX, DY);
@BOX 2.1
LINE.ABS.2 (CP.X + DX, CP.Y + DY);
@BOX 3.1
END
@END

@TITLE GRA02.2.5(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@FLOW 1-2NO-5-4
@FLOW 2OK-3-4
@ROW 5-3
@BOX 1.0
POLYLINE ABS 2 (X.ARRAY, Y.ARRAY, N)
@BOX 2.0
SIZE OF N IN RANGE ?
@BOX 3.0
DRAW EACH ABS LINE
[GRA02.2.3]
@BOX 4.0
ERROR
@BOX 5.0
ERROR
@BOX 1.1
PROC POLYLINE.ABS.2 (X.ARRAY, Y.ARRAY, N);
$IN I;
@BOX 2.1
IF N =< 0

@BOX 3.1
FOR I < N DO
   LINE.ABS.2 (X.ARRAY^[I], Y.ARRAY^[I]);
OD;
@BOX 4.1
END
@BOX 5.1
FAULT (1, 5);
@END

@TITLE GRA02.2.6(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2NO-5-4
@FLOW 2OK-3-4
@BOX 1.0
POLYLINE REL 2 (DX.ARRAY, DY.ARRAY, N)
@BOX 2.0
SIZE OF N IN RANGE ?
@BOX 3.0
DRAW EACH REL LINE
[GRA02.2.4]
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC POLYLINE.REL.2 (DX.ARRAY, DY.ARRAY, N);
$IN I;
@BOX 2.1
IF N =< 0
@BOX 3.1
FOR I < N DO
   LINE.ABS.2 (CP.X + DX.ARRAY^[I], CP.Y + DY.ARRAY^[I]);
OD;
@BOX 4.1
END
@BOX 5.1
FAULT (1, 5);
@END
@TITLE GRA02.2.7(1,10)
@COL 1S-4T-2R-3F
@FLOW 1-4VIS-2-3
@FLOW 4INVIS-3
@BOX 1.0
TEXT (STRING, LENGTH)
@BOX 2.0
SWITCH ON DEVICE TYPE TO DRAW TEXT
@BOX 3.0
END
@BOX 4.0
IS CP WITHIN CURRENT WINDOW ?
@BOX 1.1
PROC TEXT (STRING, LENGTH);
$RE X, Y;
@BOX 2.1
CP.X => X; CP.Y => Y;
WORLD.TO.VIEWPORT (^X, ^Y);
DEV.TEXT [SELECTED.DEVICE] =>DEV.TEXT.P;
DEV.TEXT.P^(X, Y, STRING, LENGTH);
@BOX 3.1
END
@BOX 4.1
IF CP.X < WNDW.X.MIN OR CP.X > WNDW.X.MAX OR
   CP.Y < WNDW.Y.MIN OR CP.Y > WNDW.Y.MAX
@END

@TITLE GRA02.2.8(1,10)
@COL 1S-5R-6T-2R-3R-4F
@FLOW 1-5-6VISIBLE-2-3-4
@FLOW 6INVISIBLE-4
@BOX 1.0
MARKER ABS 2 (X, Y);
@BOX 2.0
MAP WORLD TO VIEWPORT
[GRA02.5.7]
@BOX 3.0
SWITCH ON DEVICE TYPE TO DRAW MARKER
@BOX 4.0
END
@BOX 5.0
MOVE ABS 2 (X, Y)
@BOX 6.0
IS MARKER WITHIN WINDOW ?
@BOX 1.1
PROC MARKER.ABS.2 (X, Y);
DATAVEC MARKERS ($LO8)
".+*0X>_^#"
END
$RE XX, YY;
@BOX 2.1
CP.X => XX; CP.Y => YY;
WORLD.TO.VIEWPORT (^XX, ^YY);
@BOX 3.1
DEV.MARKER [SELECTED.DEVICE] => DEV.MARKER.P;
DEV.MARKER.P^ (XX, YY, MARKERS[C.MARKER] );
@BOX 4.1
END
@BOX 5.1
MOVE.ABS.2 (X, Y);
@BOX 6.1
IF CP.X < WNDW.X.MIN OR CP.X > WNDW.X.MAX OR
   CP.Y < WNDW.Y.MIN OR CP.Y > WNDW.Y.MAX
@END
@TITLE GRA02.2.9(1,10)
@COL 1S-5R-6T-2R-3R-4F
@FLOW 1-5-6VISIBLE-2-3-4
@FLOW 6INVISIBLE-4
@BOX 1.0
MARKER REL 2 (DX, DY)
@BOX 2.0
MAP WORLD TO NDC
[GRA02.5.7]
@BOX 3.0
SWITCH ON DEVICE TYPE TO DRAW MARKER
@BOX 4.0
END
@BOX 5.0
MOVE REL TO (DX, DY)
@BOX 6.0
IS MARKER WITHIN CURRENT WINDOW ?
@BOX 1.1
PROC MARKER.REL.2 (DX, DY);
DATAVEC MARKERS ($LO8)
".+*0X>_^#"
END
$RE XX, YY;
@BOX 2.1
CP.X => XX; CP.Y => YY;
WORLD.TO.VIEWPORT (^XX, ^YY);
@BOX 3.1
DEV.MARKER [SELECTED.DEVICE]  =>DEV.MARKER.P;
DEV.MARKER.P^ (XX, YY, MARKERS[C.MARKER]);
@BOX 4.1
END
@BOX 5.1
MOVE.ABS.2 (CP.X + DX, CP.Y + DY);
@BOX 6.1
IF CP.X < WNDW.X.MIN OR CP.X > WNDW.X.MAX OR
   CP.Y < WNDW.Y.MIN OR CP.Y > WNDW.Y.MAX
@END

@TITLE GRA02.2.10(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2NO-5-4
@FLOW 2OK-3-4
@BOX 1.0
POLYMARKER ABS 2 (X.ARRAY, Y.ARRAY, N)
@BOX 2.0
IS SIZE OF N IN RANGE ?
@BOX 3.0
DRAW EACH ABS MARKER
[GRA02.2.8]
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC POLYMARKER.ABS.2 (X.ARRAY, Y.ARRAY, N);
$IN I;
@BOX 2.1
IF N =< 0
@BOX 3.1
FOR I< N DO
   MARKER.ABS.2 (X.ARRAY^[I], Y.ARRAY^[I]);
OD;
@BOX 4.1
END
@BOX 5.1
FAULT (1, 5);
@END

@TITLE GRA02.2.11(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@FLOW 1-2NO-5-4
@FLOW 2OK-3-4
@ROW 5-3
@BOX 1.0
POLYMARKER REL 2 (DX.ARRAY, DY.ARRAY, N)
@BOX 2.0
IS N IN RANGE ?
@BOX 3.0
DRAW EACH REL MARKER
[GRA02.2.9]
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC POLYMARKER.REL.2 (DX.ARRAY, DY.ARRAY, N);
$IN I;
@BOX 2.1
IF N =< 0
@BOX 3.1
FOR I < N DO
   MARKER.REL.2 (DX.ARRAY^[I], DY.ARRAY^[I]);
OD;
@BOX 4.1
END
@BOX 5.1
FAULT (1, 5);
@END

@TITLE GRA02.3(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
SETTING AND ENQUIRY OF ATTRIBUTES
@BOX 2.0
PROCEDURES IN SUBSECTION :
   SET LINE INDEX        ENQUIRE LINE INDEX
   SET TEXT INDEX        ENQUIRE TEXT INDEX
   SET LINE STYLE        ENQUIRE LINE STYLE
   SET LINE WIDTH        ENQUIRE LINE WIDTH
   SET PEN               ENQUIRE PEN
   SET FONT              ENQUIRE FONT
   SET CHAR SIZE         ENQUIRE CHAR SIZE
   SET CHAR JUST         ENQUIRE CHAR JUST
   SET CHAR PRECISION    ENQUIRE CHAR PRECISION
   SET MARKER SYMBOL     ENQUIRE MARKER SYMBOL
   SET CHAR PATH         ENQUIRE CHAR PATH
@BOX 1.1
LSPEC SET.LINE.INDEX ($IN);
LSPEC INQ.LINE.INDEX (ADDR $IN);
LSPEC SET.TEXT.INDEX ($IN);
LSPEC INQ.TEXT.INDEX (ADDR $IN);
LSPEC SET.LINESTYLE ($IN);
LSPEC INQ.LINESTYLE (ADDR $IN);
LSPEC SET.LINE.WIDTH ($IN);
LSPEC INQ.LINE.WIDTH (ADDR $RE);
LSPEC SET.PEN ($IN);
LSPEC INQ.PEN (ADDR $IN);
LSPEC SET.FONT ($IN);
LSPEC INQ.FONT (ADDR $IN);
::LSPEC SET.CHAR.SIZE ($RE, $RE);
LSPEC SET.CHAR.JUST ($IN, $IN);
LSPEC INQ.CHAR.JUST (ADDR $IN, ADDR $IN);
LSPEC INQ.CHAR.SIZE (ADDR $RE, ADDR $RE);
LSPEC SET.CHAR.PRECISION ($IN);
LSPEC INQ.CHAR.PRECISION (ADDR $IN);
LSPEC SET.MARKER.SYMBOL ($IN);
LSPEC INQ.MARKER.SYMBOL (ADDR $IN);
LSPEC SET.INTENSITY ($IN);
LSPEC INQ.INTENSITY (ADDR $IN);
LSPEC INQ.OUTPUT.CAPS ($IN, ADDR [$IN], ADDR [$RE]);
LSPEC SET.CHARPATH ($IN);
LSPEC INQ.CHARPATH (ADDR $IN);
LSPEC INQ.TEXT.EXTENT.2 (ADDR [$LO8], $IN, ADDR $RE, ADDR $RE);
@BOX 2.1
   #GRA02.3.1
   #GRA02.3.2
   #GRA02.3.3
   #GRA02.3.4
@END
@TITLE GRA02.3.1(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
SETTING OF ATTRIBUTES
@BOX 2.0
PROCEDURES FOR ATTRIBUTE SETTING:
   SET LINE INDEX
   SET TEXT INDEX
   SET BACKGROUND INDEX
   SET LINE STYLE
   SET LINE WIDTH
   SET PEN
   SET CHAR SIZE
   SET CHAR JUST
   SET CHAR PRECISION
   SET MARKER SYMBOL
   SET INTENSITY
   SET CHAR PATH
@BOX 1.1
::SETTING ATTRIBUTES
@BOX 2.1
PROC SET.LINE.INDEX (INDEX);
IF INDEX > MAX.INDEX THEN FAULT (5, 5)
ELSE INDEX => C.LINE.INDEX
FI
END

PROC SET.TEXT.INDEX (INDEX);
IF INDEX > MAX.INDEX THEN FAULT (5, 5)
ELSE INDEX => C.TEXT.INDEX
FI
END

PROC SET.LINESTYLE (STYLE);
  STYLE => C.LINESTYLE;
DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
 DEV.ATTR.P^ (1);
END

PROC SET.LINEWIDTH (WIDTH);
WIDTH => C.LINEWIDTH;
DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
DEV.ATTR.P^ (2);
END

PROC SET.PEN (PENS);
PENS => PEN;
DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
DEV.ATTR.P^ (6);
END

PROC SET.FONT (FONT);
FONT => C.FONT;
DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
DEV.ATTR.P^ (5);
END

PROC SET.CHAR.SIZE (WIDTH, HEIGHT);
$RE W, H, X, Y;
HEIGHT => CHARSZ.HEIGHT;
WIDTH => CHARSZ.WIDTH ;
WNDW.X.MIN + WIDTH => W;
WNDW.Y.MIN + HEIGHT => H;
WORLD.TO.VIEWPORT (^W, ^H);
WNDW.X.MIN => X; WNDW.Y.MIN => Y;
WORLD.TO.VIEWPORT (^X, ^Y);
W - X => W; H - Y => H;
 DEV.ATTR [SELECTED.DEVICE] =>DEV.ATTR.P;
DEV.ATTR.P^ (3);
END

PROC SET.CHAR.JUST (HORIZ, VERT);
HORIZ => C.CHARJUST.H;
VERT => C.CHARJUST.V;
END

PROC SET.CHARPRECISION (PRECISION);
IF PRECISION /= 1 THEN FAULT (5, 5)
ELSE PRECISION => C.CHARPRECISION
FI
END

PROC SET.MARKER.SYMBOL (INDEX);
IF INDEX =< 0 > 10 THEN FAULT (5, 5)
ELSE INDEX => C.MARKER;
    DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
    DEV.ATTR.P^ (10);
FI
END

PROC SET.INTENSITY (INTEN.PARA);
INTEN.PARA => INTENSITY;

 DEV.ATTR [SELECTED.DEVICE] => DEV.ATTR.P;
 DEV.ATTR.P^ (9);
END

PROC SET.CHARPATH (PATH);
PATH => C.CHARPATH;
END
@END
@TITLE GRA02.3.2(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
ENQUIRY OF ATTRIBUTES
@BOX 2.0
PROCEDURES FOR ATTRIBUTE ENQUIRY:
   ENQUIRE LINE INDEX
   ENQUIRE TEXT INDEX
   ENQUIRE BACKGROUND INDEX
   ENQUIRE LINE STYLE
   ENQUIRE LINE WIDTH
   ENQUIRE PEN
   ENQUIRE CHAR SIZE
   ENQUIRE CHAR JUST
   ENQUIRE CHAR PRECISION
   ENQUIRE MARKER SYMBOL
   ENQUIRE INTENSITY
   ENQUIRE CHAR PATH
@BOX 1.1
::ATTRIBUTE ENQUIRY
@BOX 2.1
PROC INQ.LINE.INDEX (INDEX);
C.LINE.INDEX => INDEX^;
END

PROC INQ.TEXT.INDEX (INDEX);
C.TEXT.INDEX => INDEX^;
END

PROC INQ.LINESTYLE (STYLE);
C.LINESTYLE => STYLE^;
END

PROC INQ.LINEWIDTH (WIDTH);
C.LINEWIDTH => WIDTH^;
END

PROC INQ.PEN (PENS);
PEN => PENS^;
END

PROC INQ.FONT (FONT);
C.FONT => FONT^;
END


PROC INQ.CHAR.SIZE (H, W);
CHARSZ.HEIGHT => H^;
CHARSZ.WIDTH => W^;
END

PROC INQ.CHAR.JUST (H, V);
C.CHARJUST.H => H^;
C.CHARJUST.V => V^;
END

PROC INQ.CHARPRECISION (PRECISION);
C.CHAR.PRECISION => PRECISION^;
END

PROC INQ.MARKER.SYMBOL (SYM);
C.MARKER => SYM^;
END

PROC INQ.INTENSITY (INTEN.PARA);
INTENSITY => INTEN.PARA^;
END

PROC INQ.CHARPATH (PATH);
C.CHARPATH => PATH^;
END
@END
@TITLE GRA02.3.3(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2FAULT-5-4
@FLOW 2OK-3-4
@BOX 1.0
INQUIRE OUTPUT CAPABILITIES (SURFACE, INT.ARRAY, REAL.ARRAY);
@BOX 2.0
IS THE CURRENTLY INITIALISED DEVICE REQUESTED ?
@BOX 3.0
RETURN THE CAPABILITIES OF THE DEVICE DRIVER
@BOX 4.0
END
@BOX 1.1
PROC INQ.OUTPUT.CAPS (SURFACE, INT.ARRAY, REAL.ARRAY);
@BOX 2.1
IF DEV.NO OF DEV.ID [SURFACE-1] /= SELECTED.DEVICE
@BOX 3.1
OP.LEVEL => INT.ARRAY^ [0];
DIM.LEVEL => INT.ARRAY^ [1];
PHYSICAL => INT.ARRAY^ [2];
COL.COUNT => INT.ARRAY^ [3];
INTEN.COUNT => INT.ARRAY^ [4];
INTEN.SIM => INT.ARRAY^ [5];
LINSTYL.HW.COUNT => INT.ARRAY^ [6];
LINSTYL.SW.COUNT => INT.ARRAY^ [7];
LINEWIDTH.COUNT => INT.ARRAY^ [8];
LINEWIDTH.SIM => INT.ARRAY^ [9];
PEN.HW.COUNT => INT.ARRAY^ [10];
PEN.SW.COUNT => INT.ARRAY^ [11];
FONT.COUNT => INT.ARRAY^ [12];
CH.SIZE.COUNT => INT.ARRAY^ [13];
CH.SIZE.SIM => INT.ARRAY^ [14];
MARK.HW.COUNT => INT.ARRAY^ [15];
MARK.SW.COUNT => INT.ARRAY^ [16];
PICK.ID.COUNT => INT.ARRAY^ [17];
HIGHLT.SIM => INT.ARRAY^ [18];
IM.TRANS => INT.ARRAY^ [19];
BATCHING => INT.ARRAY^ [20];
VS.FULL.WIDTH => REAL.ARRAY^ [0];
VS.FULL.HEIGHT => REAL.ARRAY^ [1];
MAPPED.NDC.WIDTH => REAL.ARRAY^ [2];
MAPPED.NDC.HEIGHT => REAL.ARRAY^ [3];
RES.HORIZ => REAL.ARRAY^ [4];
RES.VERT => REAL.ARRAY^ [5];
LINEWIDTH.MIN => REAL.ARRAY^ [6];
LINEWIDTH.MAX => REAL.ARRAY^ [7];
CH.SIZE.MIN => REAL.ARRAY^ [8];
CH.SIZE.MAX => REAL.ARRAY^ [9];
@BOX 4.1
END
@BOX 5.1
FAULT (20, 6);
@END
@TITLE GRA02.3.4(1,10)
@COL 7R
@COL 1S-2T-3T-4R-5R-6F
@COL 8R
@ROW 7-3
@ROW 4-8
@FLOW 1-2NO-3YES-4-5-6
@FLOW 2YES-7-5
@FLOW 3NO-8-6
@BOX 1.0
INQUIRE TEXT EXTENT 2 (STRING, SURFACE, DX, DY)
@BOX 2.0
BENSON REQUESTED ?
@BOX 3.0
GENISCO REQUESTED ?
@BOX 4.0
COMPUTE WORLD SIZE OF ONE CHARACTER
@BOX 5.0
COMPUTE TEXT EXTENT ACCORDING TO CHARPATH
@BOX 6.0
END
@BOX 7.0
COMPUTE WORLD SIZE OF ONE CHARACTER
@BOX 8.0
ERROR
@BOX 1.1
PROC INQ.TEXT.EXTENT.2 (STRING, SURF, DX, DY);
$IN SZ;
$RE CH.W, CH.H, X, Y, X0, Y0, X1, Y1;
@BOX 2.1
IF SURF = 1
@BOX 3.1
IF SURF /= 0
@BOX 4.1
CH.NDC.W + VP.X.MIN => X;
CH.NDC.H + VP.Y.MIN => Y;
MAP.NDC.TO.WORLD.2 (X, Y, ^X1, ^Y1);
VP.X.MIN => X;
VP.Y.MIN => Y;
MAP.NDC.TO.WORLD.2 (X, Y, ^X0, ^Y0);
X1 - X0 => CH.W;
Y1 - Y0 => CH.H;
@BOX 5.1
SIZE (STRING) => SZ;
ALTERNATIVE C.CHARPATH FROM
   BEGIN
   (SZ) * CH.W => DX^;
   CH.H => DY^
   END
   BEGIN
   (SZ) * CH.W => DY^;
   0.0 - CH.H => DX^;
   END
   BEGIN
   0.0 - (SZ) * CH.W => DX^;
   0.0 - CH.H => DY^;
   END
   BEGIN
   0.0 - (SZ) * CH.W => DY^;
   CH.H => DX^;
   END
END
@BOX 6.1
END
@BOX 7.1
CHARSZ.WIDTH => CH.W;
CHARSZ.HEIGHT => CH.H;
@BOX 8.1
FAULT (16, 7);
@END

@TITLE GRA02.4(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
PICTURE SEGMENTATION
@BOX 2.0
PROCEDURES IN SUBSECTION :
   CREATE TEMP SEG
   CLOSE TEMP SEG
   ENQ OPEN TEMP SEG
@BOX 1.1
LSPEC CREATE.TEMP.SEG ();
LSPEC CLOSE.TEMP.SEG ();
LSPEC INQ.OPEN.TEMP.SEG (ADDR $IN);
@BOX 2.1
   #GRA02.4.1
   #GRA02.4.2
   #GRA02.4.3
@END

@TITLE GRA02.4.1(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
CREATE TEMP SEG ()
@BOX 2.0
DUMMY - SEGMENTATION NOT IMPLEMENTED
@BOX 3.0
END
@BOX 1.1
PROC CREATE.TEMP.SEG ;
@BOX 2.1
IF NDC.STATUS /= DEF THEN
  SET.NDC.SPACE.2 (1.0, 1.0)
FI;
IF SEG.STATUS /= OPEN THEN
   OPEN => SEG.STATUS
ELSE FAULT (3, 6)
FI;
@BOX 3.1
END
@END

@TITLE GRA02.4.2(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
CLOSE TEMP SEG ()
@BOX 2.0
DUMMY - SEGMENTATION NOT IMPLEMENTED
@BOX 3.0
END
@BOX 1.1
PROC CLOSE.TEMP.SEG ;
@BOX 2.1
IF SEG.STATUS = OPEN THEN
   CLOSED => SEG.STATUS
ELSE FAULT (4, 6)
FI;
@BOX 3.1
END
@END
@TITLE GRA02.4.3(1,10)
@COL 1S-2R-3F
@FLOW 1-2-3
@BOX 1.0
ENQUIRE OPEN TEMPORARY SEGMENT ()
@BOX 2.0
RETURN SEGMENT STATUS
@BOX 3.0
END
@BOX 1.1
PROC INQ.OPEN.TEMP.SEG (SEG);
@BOX 2.1
SEG.STATUS => SEG^;
@BOX 3.1
END
@END
@TITLE GRA02.5(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
VIEWING OPERATIONS
@BOX 2.0
PROCEDURES IN SUBSECTION :
   SET WINDOW        ENQUIRE WINDOW
   SET NDC SPACE 2   ENQUIRE NDC SPACE 2
   SET VIEWPORT 2    ENQUIRE VIEWPORT 2
   SET WINDOW CLIP   ENQUIRE WINDOW CLIP
   MAP NDC WORLD     MAP WORL NDC
   WORLD TO VIEWPORT
@BOX 1.1
::VIEWING
@BOX 2.1
LSPEC SET.WINDOW ($RE, $RE, $RE, $RE);
::LSPEC SET.NDC.SPACE.2 ($RE, $RE);
LSPEC SET.VIEWPORT.2 ($RE, $RE, $RE, $RE);
LSPEC SET.CLIP.W ($IN);
::PSPEC MAP.NDC.TO.WORLD.2 ($RE, $RE, ADDR $RE, ADDR $RE);
LSPEC MAP.WORLD.TO.NDC.2 ($RE, $RE, ADDR $RE, ADDR $RE);
::PSPEC WORLD.TO.VIEWPORT (ADDR $RE, ADDR $RE);
LSPEC INQ.WINDOW (ADDR $RE, ADDR $RE, ADDR $RE, ADDR $RE);
LSPEC INQ.NDC.SPACE.2 (ADDR $RE, ADDR $RE);
LSPEC INQ.VIEWPORT.2 (ADDR $RE, ADDR $RE, ADDR $RE, ADDR $RE);
LSPEC INQ.CLIP.W (ADDR $IN);
   #GRA02.5.1
   #GRA02.5.2
   #GRA02.5.3
   #GRA02.5.4
   #GRA02.5.5
   #GRA02.5.6
   #GRA02.5.7
   #GRA02.5.8
   #GRA02.5.9
@END
@TITLE GRA02.5/1(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
PROCEDURE SPECS
@BOX 2.0
@BOX 1.1
::PROC SPECS
@BOX 2.1
LSPEC SET.NDC.SPACE.2 ($RE, $RE);
PSPEC WORLD.TO.VIEWPORT (ADDR $RE, ADDR $RE);
PSPEC CLIP (ADDR $RE, ADDR $RE, ADDR $RE, ADDR $RE) / $IN;
LSPEC MAP.NDC.TO.WORLD.2 ($RE, $RE, ADDR $RE, ADDR $RE);
@END

@TITLE GRA02.5.1(1,10)
@COL 9R
@COL 1S-2T-3T-4T-5R-6R-7R-8F
@COL 10R
@ROW 9-5-10
@FLOW 1-2NO-3OK-4OK-5-6-7-8
@FLOW 2YES-10-8
@FLOW 3NO-9-8
@FLOW 4NO-9-8
@BOX 1.0
SET WINDOW (X.MIN, X.MAX, Y.MIN, Y.MAX)
@BOX 2.0
IS A SEGMENT OPEN ?
@BOX 3.0
WINDOW X BOUNDS OK?
@BOX 4.0
WINDOW Y BOUNDS OK?
@BOX 5.0
SET CORE WINDOW PARAMETERS
@BOX 6.0
COMPUTE NEW WORLD TO VIEWPORT X MAPPING
@BOX 7.0
COMPUTE NEW WORLD TO VIEWPORT Y MAPPING
@BOX 8.0
END
@BOX 9.0
ERROR
@BOX 10.0
ERROR
@BOX 1.1
PROC SET.WINDOW (X.MIN, X.MAX, Y.MIN, Y.MAX);
@BOX 2.1
IF SEG.STATUS = OPEN
@BOX 3.1
IF X.MAX =< X.MIN
@BOX 4.1
IF Y.MAX =< Y.MIN
@BOX 5.1
X.MIN => WNDW.X.MIN;
X.MAX => WNDW.X.MAX;
Y.MIN => WNDW.Y.MIN;
Y.MAX => WNDW.Y.MAX;
@BOX 6.1
(VP.X.MAX - VP.X.MIN)/(WNDW.X.MAX - WNDW.X.MIN) => VP.X.SCALE;
@BOX 7.1
(VP.Y.MAX - VP.Y.MIN)/(WNDW.Y.MAX - WNDW.Y.MIN) => VP.Y.SCALE;
@BOX 8.1
END
@BOX 9.1
FAULT (6, 5);
@BOX 10.1
FAULT (2, 6);
@END
@TITLE GRA02.5.2(1,10)
@COL 7R
@COL 1S-2T-3R-4R-5R-6F
@ROW 7-4
@FLOW 1-2YES-7-6
@FLOW 2OK-3-4-5-6
@BOX 1.0
SET NDC SPACE 2 (X, Y)
@BOX 2.0
IS NDC SPACE ALREADY DEFINED ?
@BOX 3.0
CHECK VALUES OF X AND Y
@BOX 4.0
SET CORE NDC SPACE PARAMATERS
@BOX 5.0
SET THE DEFAULT VIEWPORT
[GRA02.5.3]
@BOX 6.0
END
@BOX 7.0
ERROR
@BOX 1.1
PROC SET.NDC.SPACE.2 (X, Y);
@BOX 2.1
IF NDC.STATUS = DEF
@BOX 3.1
IF X < 0.0 > 1.0 OR Y < 0.0 > 1.0 THEN
   FAULT (8, 5);
   -> OUT
FI;
IF X = 0.0 OR Y = 0.0 THEN
   FAULT (10, 5);
   -> OUT
FI;
IF X /= 1.0 AND Y /= 1.0 THEN
   FAULT (9, 5);
   -> OUT
FI;
@BOX 4.1
X => NDC.X;
Y => NDC.Y;
DEF => NDC.STATUS;
@BOX 5.1
SET.VIEWPORT.2 (0.0, X, 0.0, Y);
@BOX 6.1
OUT:
END
@BOX 7.1
FAULT (7, 6);
@END
@TITLE GRA02.5.3(1,10)
@COL 11R
@COL 1S-2T-3T-4T-5T-6T-7R-8R-9R-10F
@COL 13R
@COL 12R
@ROW 11-7-13-12
@FLOW 1-2NO-3OK-4OK-5OK-6OK-7-8-9-10
@FLOW 2NO-12-10
@FLOW 3NO-11-10
@FLOW 4NO-11-10
@FLOW 5NO-13-10
@FLOW 6NO-13-10
@BOX 1.0
SET VIEWPORT 2 (X.MIN, X.MAX, Y.MIN, Y.MAX)
@BOX 2.0
IS A SEGMENT OPEN ?
@BOX 3.0
ARE VIEWPORT X BOUNDS VALID ?
@BOX 4.0
ARE VIEWPORT Y BOUNDS VALID ?
@BOX 5.0
ARE VIEWPORT X BOUNDS IN NDC SPACE ?
@BOX 6.0
ARE VIEWPORT Y BOUNDS IN NDC SPACE ?
@BOX 7.0
SET CORE VIEWPORT PARAMETERS
@BOX 8.0
COMPUTE WORLD TO VIEWPORT MAPPING
@BOX 9.0
COMPUTE WORLD TO VIEWPORT Y MAPPING
@BOX 10.0
END
@BOX 11.0
ERROR
@BOX 12.0
ERROR
@BOX 13.0
ERROR
@BOX 1.1
PROC SET.VIEWPORT.2 (X.MIN, X.MAX, Y.MIN, Y.MAX);
@BOX 2.1
IF SEG.STATUS = OPEN
@BOX 3.1
IF X.MAX =< X.MIN
@BOX 4.1
IF Y.MAX =< Y.MIN
@BOX 5.1
IF X.MIN > NDC.X OR X.MAX > NDC.X
@BOX 6.1
IF Y.MIN > NDC.Y OR Y.MAX > NDC.Y
@BOX 7.1
X.MIN => VP.X.MIN;
X.MAX => VP.X.MAX;
Y.MIN => VP.Y.MIN;
Y.MAX => VP.Y.MAX;
@BOX 8.1
(VP.X.MAX - VP.X.MIN)/(WNDW.X.MAX - WNDW.X.MIN) => VP.X.SCALE;
@BOX 9.1
(VP.Y.MAX - VP.Y.MIN)/(WNDW.Y.MAX - WNDW.Y.MIN) => VP.Y.SCALE;
@BOX 10.1
END
@BOX 11.1
FAULT (6, 5);
@BOX 12.1
FAULT (2, 6);
@BOX 13.1
FAULT (11, 5);
@END
@TITLE GRA02.5.4(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2YES-5-4
@FLOW 2NO-3-4
@BOX 1.0
SET WINDOW CLIPPING (ON.OFF)
@BOX 2.0
IS A SEGMENT OPEN ?
@BOX 3.0
SET CORE CLIPPING STATUS
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC SET.CLIP.W (ON.OFF);
@BOX 2.1
IF SEG.STATUS = OPEN
@BOX 3.1
ON.OFF => CLIPPING;
@BOX 4.1
END
@BOX 5.1
FAULT (2, 6);
@END
@TITLE GRA02.5.5(1,10)
@COL 5R
@COL 1S-2T-3R-4F
@ROW 5-3
@FLOW 1-2NO-5-4
@FLOW 2OK-3-4
@BOX 1.0
MAP NDC TO WORLD 2 (X.NDC, Y.NDC, X, Y)
@BOX 2.0
IS NDC POSITION WITHIN CURRENT VIEWPORT ?
@BOX 3.0
PERFORM INVERSE WORLD TO VIEWPORT MAPPING
@BOX 4.0
END
@BOX 5.0
ERROR
@BOX 1.1
PROC MAP.NDC.TO.WORLD.2 (X.NDC, Y.NDC, X, Y);
@BOX 2.1
IF X.NDC < VP.X.MIN > VP.X.MAX AND
   Y.NDC < VP.Y.MIN > VP.Y.MAX
@BOX 3.1
(X.NDC - VP.X.MIN) / VP.X.SCALE + WNDW.X.MIN => X^;
(Y.NDC - VP.Y.MIN) / VP.Y.SCALE + WNDW.Y.MIN => Y^;
@BOX 4.1
END
@BOX 5.1
FAULT (12, 5);
@END
@TITLE GRA02.5.6(1,10)
@COL 6R
@COL 1S-2T-3R-4R-5F
@ROW 6-3
@FLOW 1-2NO-6-5
@FLOW 2YES-3-4-5
@BOX 1.0
MAP WORLD TO NDC 2 (X, Y, X.NDC, Y.NDC)
@BOX 2.0
IS WORLD POSITION WITHIN CURRENT WINDOW ?
@BOX 3.0
MAP WORLD TO VIEWPORT
[GRA02.5.7]
@BOX 4.0
RETURN NDC COORDS
@BOX 5.0
END
@BOX 6.0
ERROR
@BOX 1.1
PROC MAP.WORLD.TO.NDC.2 (X, Y, X.NDC, Y.NDC);
@BOX 2.1
IF X < WNDW.X.MIN > WNDW.X.MAX OR
   Y < WNDW.Y.MIN > WNDW.Y.MAX
@BOX 3.1
WORLD.TO.VIEWPORT (^X, ^Y);
@BOX 4.1
X => X.NDC^;
Y => Y.NDC^;
@BOX 5.1
END
@BOX 6.1
FAULT (13, 5);
@END
@TITLE GRA02.5.7(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
WORLD TO VIEWPORT (X, Y)
@BOX 2.0
MAP X
@BOX 3.0
MAP Y
@BOX 4.0
END
@BOX 1.1
PROC WORLD.TO.VIEWPORT (X, Y);
@BOX 2.1
VP.X.SCALE * (X^ - WNDW.X.MIN) + VP.X.MIN => X^;
@BOX 3.1
VP.Y.SCALE * (Y^ - WNDW.Y.MIN) + VP.Y.MIN => Y^;
@BOX 4.1
END
@END
@TITLE GRA02.5.8(1,10)
@COL 1S-2R
@FLOW 1-2
@BOX 1.0
VIEWING ENQUIRY PROCEDURES
@BOX 2.0
PROCEDURES FOR VIEWING ENQUIRY :
   INQUIRE WINDOW
   INQUIRE NDC SPACE 2
   INQUIRE VIEWPORT 2
   INQUIRE CLIP W
@BOX 1.1
::VIEWING ENQUIRY PROCEDURES
@BOX 2.1
PROC INQ.WINDOW (X.MIN, X.MAX, Y.MIN, Y.MAX);
WNDW.X.MIN => X.MIN^;
WNDW.X.MAX => X.MAX^;
WNDW.Y.MIN => Y.MIN^;
WNDW.Y.MAX => Y.MAX^;
END

PROC INQ.NDC.SPACE.2 (W, H);
NDC.X => W^;
NDC.Y => H^;
END

PROC INQ.VIEWPORT.2 (X.MIN, X.MAX, Y.MIN, Y.MAX);
VP.X.MIN => X.MIN^;
VP.X.MAX => X.MAX^;
VP.Y.MIN => Y.MIN^;
VP.Y.MAX => Y.MAX^;
END

PROC INQ.CLIP.W (CLIP);
CLIPPING => CLIP^;
END
@END
@TITLE GRA02.5.9(1,10)
@COL 1S-2R-3R-4F
@FLOW 1-2-3-4
@BOX 1.0
CLIP (X0, Y0, X1, Y1) VISIBLE
@BOX 2.0
PROCEDURE "CODE" TO COMPUTE
4-BIT CODES FOR LINE ENDPOINTS
@BOX 3.0
CLIP LINE TO CURRENT WINDOW
AND RETURN VISIBILITY STATUS
@BOX 4.0
END
@BOX 1.1
PROC CLIP (X.MIN, Y.MIN, X.MAX, Y.MAX);
$RE XDIFF, YDIFF, X, Y, X0, Y0, X1, Y1;
$LO8 CODE0, CODE1, CODEC;
$IN VISIBLE;
@BOX 2.1
PSPEC CODE ($RE, $RE) / $LO8;
PROC CODE (X, Y);
0 => CODE;
IF X < WNDW.X.MIN THEN
   1 !> CODE
ELSE
   IF X > WNDW.X.MAX THEN
      2 !> CODE
   FI
FI;
IF Y < WNDW.Y.MIN THEN
   4 !> CODE
ELSE
   IF Y > WNDW.Y.MAX THEN
      8 !> CODE
   FI
FI
END
@BOX 3.1
X.MIN^ => X0; Y.MIN^ => Y0;
X.MAX^ => X1; Y.MAX^ => Y1;
CODE (X0, Y0) => CODE0; 0 => VISIBLE;
CODE (X1, Y1) => CODE1;
WHILE CODE0 /= 0 OR CODE1 /= 0 DO
   X1 - X0 => XDIFF;
   Y1 - Y0 => YDIFF;
   IF CODE0 & CODE1 /= 0 THEN  -> INVIS FI;
   IF CODE0 = 0 THEN CODE1 => CODEC
                ELSE CODE0 => CODEC
   FI;
   IF (CODEC & 1) /= 0 THEN
      Y0 + (YDIFF * (WNDW.X.MIN - X0) / XDIFF) => Y;
      WNDW.X.MIN => X;
   ELSE
   IF (CODEC & 2) /= 0 THEN
      Y0 + (YDIFF * (WNDW.X.MAX - X0) / XDIFF) => Y;
      WNDW.X.MAX => X;
   ELSE
   IF (CODEC & 4) /= 0 THEN
      X0 + (XDIFF * (WNDW.Y.MIN - Y0) / YDIFF) => X;
      WNDW.Y.MIN => Y;
   ELSE
   IF (CODEC & 8) /= 0 THEN
      X0 + (XDIFF * (WNDW.Y.MAX - Y0) / YDIFF) => X;
      WNDW.Y.MAX => Y;
   FI;
   FI;
   FI;
   FI;
IF CODEC = CODE0 THEN
   X => X0; Y => Y0;
   CODE (X0, Y0) => CODE0
ELSE
   X => X1; Y => Y1;
   CODE (X1, Y1) => CODE1
FI;
OD;
X0 => X.MIN^; Y0 => Y.MIN^;
X1 => X.MAX^; Y1 => Y.MAX^;
1 => VISIBLE;
INVIS: VISIBLE => CLIP;
@BOX 4.1
END
@END

