home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / POSTOGRF.ZIP / POSTOGRF.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-08-10  |  61.8 KB  |  1,625 lines

  1. {$A+,B-,D+,E-,F-,I+,L+,N-,O-,R-,S-,V-}
  2. {$M 32000,0,655360}
  3. Program POSTogrf;
  4. { (O] SCRC Z; EXIT; }
  5. {    Written by T. B. Passin in Turbo Pascal 5.0.
  6.      Writes labels onto graphs using Postscript laser printer.  The labels
  7.      can be moved, sized, edited, and the font can be chosen.  This
  8.      program takes as input the graph file from J. R. VanZandt's
  9.      graph program GRAPHLI, which is a version of GRAPH that puts
  10.      out a command file that drives the C. Itoh LIPS laser printer.
  11.      POSTOGRF also can read its own output file, the output from LIPSOGRF,
  12.      and the output from VanZandt's GRAPHPS.
  13.  
  14.      POSTOGRF interactively adds labels to the file and outputs
  15.      a merged file containing both the graph and the labels ready to print
  16.      on a Postscript printer.
  17.  
  18.     10 Aug 90 v6.14. Changes default font style when you change font.
  19.     4 June 90 v6.14x5.
  20.     31 May 90 v6.14x3 Now can also size CopyBlock automatically, or with
  21.        mover keys.  Changed CopyBLock menu item function keys.
  22.     25 May 90 v6.14x2.  Now has new mode: F8, moves Copyblock around
  23.        on page. Adjusted Copyblock defaults and positions of the VG
  24.        bar & MITRE Logo.  Most changes are to Copybloc.inc.  CopyBlock
  25.        now described in Postscript coords relative to origin.  Added
  26.        types Rect, ScreenRect.  Added var CopyBlock.
  27.     21 May 90 v6.14x1.  Now rotates labels 90 deg.  2 new Postscript
  28.        words for this: 'rs' rotates and does 's', 'rsho' rotates and does
  29.         'show'.
  30.      2 May 90 v6.13e.  'X' option now autosaves without requesting
  31.         confirmation for output filename (omit save if unchanged).
  32.      25 Apr 90 v6.13d. Now defaults to 'y' for save when quitting.  Added
  33.         'X' exit option: automatically saves file before quitting.
  34.      18 Apr 90 v6.13c. Minor fix for read-file message.
  35.      17 Apr90 v6.13b. Bug fix in init:split into init + init1, init1 comes
  36.          before ReadGRAPHLI. Initscrn now before ReadGRAPHLI;  Now new labels
  37.          are spaced right in expanded viewing (fix AddLabel);
  38.      28 Mar 90 v6.13.  Slightly increased default vertical spacing between
  39.          labels.  Bug fix: after exiting a file without changing it,
  40.          a new file (no filename) no longer incorporates the previous one
  41.          (fixed Init, WritePrt);  New file: label background now transparent.
  42.          Label background now defaults to most recent setting. ^-home, ^-end
  43.          now select head, tail of linked list, Home = PF6, End = PF8.
  44.          Now F10 to save/quit, new main menu.
  45.      18 Jan 90. v6.12. No confirmation needed to write to LPT3, COM3.
  46.      5 Jan 90. v 6.11.  Now uses VGA mode: changes to init, initscreen.
  47. }
  48.  
  49. Uses Graph, CRT, DOS,
  50.      Lipsfont,   { BGI sansserif font }
  51.      lipsdrvr; { all the BGI drivers (except 3270) }
  52. {$DEFINE POSTOGRF}
  53. {$I pstrings.i}
  54. {$I beboop.src}
  55. {type db = array[1..100] of char;
  56.      dbPtr = ^db;}
  57.  
  58. Type Fontlist = (Times, TimesBold, Helv, HelvBold, Symbol,
  59.                  MitreLogo);
  60.      paintType = (trans, opaque);
  61.      FontRec = record
  62.                   {POSTabrv   : string[6];}
  63.                   FontNum  : integer;
  64.                   LipsStyle: Fontlist;
  65.                   FontStr  : string[80];      (* font descriptor *)
  66.                end;                      (* for reference only: *)
  67.      TextPtr = ^TextRec;                 (* TextSettingsType - record *)
  68.      {String80 = string[80];}            (*   Font          : word; *)
  69.      TextRec = Record                    (*   Direction     : word; *)
  70.         Link:  TextPtr;                  (*   CharSize      : word; *)
  71.         Tstr:  string[80] ;              (*   Horiz         : word; *)
  72.         CurrText: TextSettingsType ;     (*   Vert          : word; end; *)
  73.         PrtSize: integer; (* in points *)
  74.         LipsFont: FontRec;
  75.         LabelBkGround: paintType;
  76.      end ;
  77.      String6 = string[6];
  78.  
  79.      StyleNames = array [Times..MitreLogo] of string[20];
  80.      StyleAbrv = array [Times..MitreLogo] of string6 ;
  81.  
  82.      Filearray = array[1..65000] of char;
  83.      Fileptr = ^Filearray;
  84.  
  85.      ConfigRec = record
  86.                    WriteMitreLogo: boolean;
  87.                    DoBar: boolean;
  88.                  end;
  89.  
  90.      ExpandoRec = record
  91.                     SF,              {scale factor for expansion}
  92.                     Xcent,           {new screen center in original}
  93.                     Ycent,           {unscaled screen coordinates}
  94.                     ScrnW,           {1/2 new screen width}
  95.                     ScrnH: integer;  {1/2 new screen height}
  96.                    end;
  97.  
  98.      Rect       = record
  99.                    LLx, LLy, URx, URy, w, h: integer; end;
  100.      ScreenRect = record
  101.                    ULx, ULy, LRx, LRy, sw, sh: integer; end;
  102.  
  103.      PointRec = record x,y: integer; end;
  104.      LayoutRec  = record
  105.                   BoundingBox            : Rect;     {in points}
  106.                   Origin                 : PointRec; {in 1/1000's}
  107.                   Landscape, ChangeLayout: boolean;
  108.                 end;
  109.  
  110.      VideoColors = (mono,color);
  111.  
  112.      GraphFileType = (GRAPHL, LIPSGRF, POSTSCRIPT, none);
  113.  
  114.      OnOffType = (on, off);
  115.  
  116.      type CBmodeType = (move, size);
  117.  
  118. const {Yes: set of char = ['Y','y'];}
  119.       UserDiv: byte = 100;
  120.  
  121.       POSTStyleStr : StyleNames = ('Times-Roman', 'Times-Bold', 'Helvetica',
  122.                    'Helvetica-Bold',  'Symbol', 'MitreLogo'{'Courier-Bold'});
  123.  
  124.       UserStyleNames: StyleNames = ('Times', 'TimesBold',
  125.                     'Helv', 'HelvBold', 'Symbol', 'MitreLogo' );
  126.  
  127.       Ver: string80 = 'POSTogrf version 6.14';
  128.       JimDefFontStr = '/font1 /Helvetica-Bold findfont 181 scalefont def';
  129.  
  130.       CharSizeAdjX = 35;  { fudge factor to make screen label the same }
  131.                           { width as printed label }
  132.  
  133.       defaultConfig: ConfigRec = (WriteMitreLogo: false; DoBar: false);
  134.       defaultBarY = 5100;
  135.  
  136.       MitreLogoLabel: TextRec = (
  137.                         Link           : nil;
  138.                         Tstr           : 'MITRE';
  139.                         CurrText: (
  140.                           font         : 100;
  141.                           Direction    : 0;
  142.                           CharSize     : 0;
  143.                           Horiz        : 0;
  144.                           Vert         : 0);
  145.                         PrtSize        : 20;
  146.                         LipsFont: (
  147.                           FontNum      : 100;
  148.                           LIPSStyle    : MitreLogo;
  149.                           FontStr      : '');
  150.                         LabelBkGround  : opaque);
  151.  
  152.       LogoX = 3800; LogoY = -275;   {position of MITRE logo in thousandths}
  153.  
  154.    { ------------------ initial default font params -------------}
  155.       DefaultFsize:integer = 20;
  156.       DefaultLIPSStyle: fontlist = HelvBold;
  157.  
  158.       {ESC = #27;          BS  = #8;            CR = #13;  LF = #10;}
  159.       Uparrow  = #72;     Downarrow  = #80;
  160.       Leftarrow  = #75;   Rightarrow  = #77;
  161.       Del  = #83;         Ins  = #82;
  162.       {Home  = #71;        En  = #79;}  CNTLHome = #119; CNTLEnd = #117;
  163.       PF1 = #59;   PF2 = #60;   PF3 = #61;   PF4 = #62;   PF5 = #63;
  164.       PF6 = #64;   PF7 = #65;   PF8 = #66;   PF9 = #67;   PF10 = #68;
  165.       movers: set of char = [leftarrow, rightarrow, uparrow, downarrow,
  166.                    Home, #115, #116, #73, #81];
  167.  
  168.       { ------------------------------------------------------------- }
  169.       pwhitespace : set of char = [#9, #10, #12, #13, ' ', ',', ';'];
  170.       printables: set of char =
  171.         ['('..'+', '-'..':', '<'..'}', '!', '#'..'&'] ;
  172.       quotes: set of char = [#39,#34];
  173.       numbers: set of char = ['0'..'9','.'];
  174.  
  175.      defaultLayout: LayoutRec = (
  176.                   BoundingBox: (LLx: 0; LLy : 0; URx : 612; URy : 792;
  177.                                  w: 612; h : 792); {points}
  178.                   Origin: (x :7375; y : 1500); {1/1000s in.}
  179.                   Landscape : true;
  180.                   ChangeLayout : false);
  181.  
  182. Var  CurrSettings                              : TextSettingsType ;
  183.      TempText, SaveLastTextRec                 : TextRec ;
  184.      Theight, TWidth, Ffont                    : word ;
  185.      Saveh, Savev                              : word;
  186.      Ckey, curs, key                           : char ;
  187.    GraphDriver                                 : integer ;
  188.    Graphmode                                   : integer ;
  189.    errorcode                                   : integer ;
  190.      HorizScrFs, VertScrFs                     : integer ;
  191.      HorizPrtFs, VertPrtFs                     : integer ;
  192.      HPSScale, VPSScale                        : real ;
  193.      HorizLIPSFs, VertLIPSFs                   : integer ;
  194.      HorizPrinterDots, VertPrinterDots         : integer ;
  195.      MenuLineY                                 : integer;
  196.      HPrtScale, VPrtScale                      : real ;
  197.      HScale, VScale                            : real;
  198.      PrtInitStr, PrtExitStr                    : string[80] ;
  199.    HelpStr                                   : string[80] ;
  200.    PrtFile                                   : text ;
  201.    PrtFileName                               : string80 ;
  202.      PointsPerPixelH, PointsPerPixelV, Fsize     : integer;
  203.      UserSizeX, UserSizeY                        : word{byte};
  204.    FontTotal                                   : integer;
  205.    TempFontRec                                 : FontRec;
  206.    tempFontNum                                 : integer;
  207.      GRAPHLI                                   : file;
  208.      GRAPHLIName                               : string80;
  209.      JimFile                                   : Fileptr;
  210.      error, count                              : word;
  211.    barY                                        : integer;
  212.  
  213.      CopyRight                                 : string80;
  214.  
  215.    here, JimFileStart         : word;
  216.    mark                       : word;
  217.    JimFileBlock               : word;
  218.    StartLabels, EndLabels, EndProlog     : word;
  219.    BeginSetup, EndSetup, FontDefinitions : word;
  220.    EndFonts, SetOrigin, StartGraph       : word;
  221.    EndGraph                              : word;
  222.    SetOriginStr, DefaultOriginStr        : string;
  223.    font0str, defaultFont0str             : string80;
  224.    defaultPaintType                      : paintType;
  225.  
  226.    OnOff                                 : onofftype;  {for copybloc.inc}
  227.    CopyBlkX, CopyBlkY                    : integer;        {""}
  228.    CopyBlkOffsetX, CopyBlkOffsetY        : integer;        {""}
  229.    NoShow                                : boolean;        {""}
  230.    CopyBlock                             : rect;
  231.    CBmode                                : CBmodeType;
  232.  
  233.  
  234.    done, finished, newfile    : boolean;
  235.    saved, fileOK              : boolean;
  236.    InGraphMode, firsttime     : boolean;
  237.  
  238.  { ---------------------- linked list variables ----------------- }
  239.      head, cp, select, temp   : textPtr;
  240.  { ---------------------- video stuff --------------------------- }
  241.    Driver, Mode                 : integer ;
  242.    FontF                        : file;
  243.    FontP                        : pointer;
  244.    VidCol                       : VideoColors;
  245.    LinesPerChar                 : integer;
  246.    swapColors            : boolean;
  247.   { ------------------------------------------------------------ }
  248.    GraphFile                    : GraphFileType;
  249.  
  250.    Lconfig                      : ConfigRec;
  251.    Expand                       : ExpandoRec;
  252.    Layout                       : LayoutRec;
  253.    PageRect                     : ScreenRect;
  254.  
  255.  { ------------------------------------------------------------- }
  256.  
  257. Procedure ChangeDirection(Tlabel:textptr) ; { vertical labels }
  258. var xtext: TextSettingsType;
  259. begin
  260.      with Tlabel^.Currtext do begin
  261.           if Direction = HorizDir then Direction := VertDir
  262.             else direction := HorizDir;
  263.           SetTextStyle(Font, Direction, CharSize);
  264.           Tlabel^.LabelBkGround := opaque;
  265.           saved := false;
  266.       end; {with Tlabel^ do ...}
  267. end ;
  268.  
  269.         { --------------------------------------------------------
  270.                           change font size
  271.         -------------------------------------------------------------- }
  272. Procedure ChangeSize;       { changes screen and printer size in points }
  273. var error:integer; s1, s2:string80;
  274. begin
  275.     write('new character size in points: ');
  276.          saveh := TempText.CurrText.Horiz;  { need to get text settings but }
  277.          savev := tempText.CurrText.Vert;   { they clobber H & V values }
  278.          GetTextSettings(TempText.CurrText); { so save & restore them }
  279.          TempText.currText.Horiz := saveh;
  280.      TempText.CurrText.Vert := savev;
  281.      if swapcolors then textcolor(white);
  282.     {$I-} Readln(Fsize);{$I+} error := IOResult;
  283.     if swapcolors then textcolor(black);
  284.     if (error <> 0) or (Fsize > 60)
  285.     then begin
  286.        write('input must be an integer < 61 - no changes made'); clrEOL;
  287.        delay(1000);
  288.     end
  289.     else begin
  290.        TempFontRec := TempText.LIPSfont;
  291.        TempText.PrtSize := Fsize;
  292.        DefaultFsize := Fsize; { so next label will use these parameters }
  293.        UserSizeX := {byte}((100*Fsize)Div(PointsPerPixelH*CharSizeAdjX));
  294.        UserSizeY := {byte}((100*Fsize)Div(PointsPerPixelV*44));
  295.        TempText.CurrText.CharSize:= UserCharSize;
  296.        SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  297.        SetTextStyle(Ffont, TempText.CurrText.Direction,
  298.            TempText.CurrText.CharSize);
  299.        TempText.LipsFont := TempfontRec;            { make this font }
  300.     end; { else}
  301. end ;
  302.  
  303.     { --------------------------------------------------------------
  304.                        change printer font style
  305.        ------------------------------------------------------------- }
  306.  
  307. Procedure SetLipsFont;   { change font to be used by printer }
  308. var temp, tstyle: FontList; ans: integer; s1, s2:string[10];
  309. begin
  310.      Clrscr;
  311.      for temp := Times to MitreLogo do   { the 6 possible styles }
  312.         write(ord(temp), ': ', UserStyleNames[temp] ,'  ');
  313.      gotoxy(1,2);
  314.      Write('select font style (now ',
  315.        UserStyleNames[TempText.LipsFont.LIPSstyle], '): '); clrEOL;
  316.      if swapcolors then TextColor(white);
  317.      {$I-} readln(ans); {$I+}
  318.      if swapColors then Textcolor(black);
  319.      error := IOResult;
  320.      if (ans > ord(MitreLogo)) or (error <> 0)
  321.      then begin write('font number must be an integer from 0 - 5: no change'); delay(1000);end
  322.      else
  323.         begin tstyle := fontlist(ans);   (* build font specification *)
  324.            tempFontRec.LIPSstyle := tstyle;
  325.            TempText.LipsFont := TempfontRec;
  326.            DefaultLIPSStyle := tstyle;
  327.         end ;
  328. end;
  329.  
  330. { ----------------------------------------------------------------
  331.                   label editor
  332.  ------------------------------------------------------------------ }
  333. {moved procedure XOR_char to PSTRINGS.I}
  334.  
  335. procedure Showcursor(cursor:byte);
  336. begin
  337.     GoToXY(cursor,1);
  338.     XOR_Char(curs); GoToXY(cursor,1);
  339. end;
  340.  
  341. procedure Showit(s:string; cursor:byte);  { print string w/ cursor }
  342. var n:integer;
  343.   begin  clrscr; { EGA BIOS bug: clears to foreground color. }
  344.          write(s); ShowCursor(cursor); {also won't write in new color }
  345.   end;                                   { until after a writeln !}
  346.  
  347. procedure UpdateEOS(s:string; cursor:byte);
  348. var n:integer;
  349. begin GoToXY(cursor,1);
  350.       for n := cursor to length(s)
  351.       do write(s[n]);
  352. end;
  353.  
  354. Procedure EditLabel;
  355.  var str : string;            { Have to make our own cursor in graphics mode:}
  356.      ch: char;                { can't get regular cursor in graphics mode }
  357.      cursor :byte;            { (IBM - cursors on you !! ) }
  358.      insrt:boolean;
  359. begin
  360.      str := TempText.Tstr;
  361.      cursor := length(str)+ 1;   insrt := true; curs := curins;
  362.      clrscr; Showit(str,cursor);
  363.      repeat
  364.        ch := ReadKey;
  365.        if ch <> #0                         (* ordinary key *)
  366.        then case ch of
  367.              Esc: exit;                (* restore original string and quit *)
  368.              CR: begin TempText.Tstr := str; exit; end;  (* accept changes *)
  369.              BS:  begin if cursor = 1 then {nothing}
  370.                         else begin
  371.                                 GoToXY(cursor,1); write(' ');
  372.                                 dec(cursor);
  373.                                 GoToXY(length(str),1); write(' ');
  374.                                 delete(str,cursor,1);
  375.                                 UpDateEOS(str,cursor);
  376.                                 ShowCursor(cursor);
  377.                               end;
  378.                    end;
  379.              ELSE case insrt of
  380.                     true: begin insert(ch,str,cursor);
  381.                                 UpDateEOS(str,cursor);
  382.                                 inc(cursor);
  383.                                 ShowCursor(cursor);
  384.                           end;
  385.                     false: begin if cursor > length(str)
  386.                                  then str := str + ch
  387.                                  else str[cursor] := ch;
  388.                                  UpdateEOS(str,cursor);
  389.                                  inc(cursor);
  390.                                  ShowCursor(cursor);
  391.                            end;
  392.                   end; {case insrt}
  393.            end  {case ordinary key}
  394.        else begin ch := Readkey;          (* special key *)
  395.            case ch of
  396.               Leftarrow: begin if cursor <> length(str) + 1
  397.                                then write(str[cursor]) else clreol;
  398.                                dec(cursor);
  399.                                if cursor < 1 then cursor := 1;
  400.                                ShowCursor(cursor); end;
  401.               Rightarrow: begin if cursor > length(str)-1
  402.                                 then begin if cursor = length(str)
  403.                                            then XOR_Char(curs);
  404.                                            GoToXY(length(str)+1, whereY);
  405.                                            write(' ');
  406.                                            GoToXY(whereX-1, WhereY);
  407.                                            cursor := length(str) + 1;
  408.                                       end
  409.                                 else begin write(str[cursor]);
  410.                                            inc(cursor);
  411.                                      end;
  412.                                 ShowCursor(cursor); end;
  413.               Del: if cursor > length(str) then {nothing}
  414.                          else begin
  415.                                    GoToXY(length(str),1); write(' ');
  416.                                    delete(str,cursor,1);
  417.                                    UpDateEOS(str,cursor);
  418.                                    ShowCursor(Cursor);
  419.                                end; {else}
  420.               Ins: if insrt = true then
  421.                           begin XOR_Char(curs);
  422.                                 curs := curover;insrt := false;
  423.                                 ShowCursor(cursor);
  424.                           end
  425.                      else begin XOR_Char(curs);
  426.                                 curs := curins; insrt := true;
  427.                                 ShowCursor(cursor);
  428.                           end;
  429.         Home: begin XOR_Char(curs);
  430.                       cursor := 1;
  431.                       ShowCursor(cursor);
  432.           end;
  433.               En: begin XOR_Char(curs);
  434.                         cursor := length(str) + 1;
  435.                         ShowCursor(cursor);
  436.                   end;
  437.               PF10: begin str := TempText.Tstr; (* restore initial string *)
  438.                           cursor := length(str) + 1;
  439.                           Showit(str, cursor);
  440.                      end;
  441.            end;  {case extended keys}
  442.          end; {else}
  443.      until ch = Esc;
  444. end;
  445.  
  446. { ------------------------------------------------------------------
  447.              convert from printer to screen coordinates
  448.    ---------------------------------------------------------------- }
  449. Procedure ScrConv(var x,y:integer);
  450. begin
  451.      with Expand do begin
  452.        x := SF*(integer(round(x/HPrtScale)) - Xcent + ScrnW);
  453.        y := SF *(integer(round(y/VPrtScale)) - Ycent + ScrnH);
  454.      end;
  455. end;
  456.  
  457. { -------------------------------------------------------------------
  458.             convert from screen to printer coordinates (@ 300 dpi)
  459.  --------------------------------------------------------------------- }
  460. Procedure PrConv(var Tlabel:TextPtr) ;
  461. begin
  462.       HorizPrinterDots := integer(round(HprtScale*Tlabel^.CurrText.Horiz));
  463.       VertPrinterDots := integer(round(VprtScale*(Tlabel^.CurrText.Vert-7)));
  464. end ;
  465.  
  466. Procedure OutPrConv(var Tlabel:TextPtr); { label position in PS coords}
  467. begin
  468.       PrConv(Tlabel);
  469.       HorizPrinterDots := integer(round(HPSScale*HorizPrinterDots)) - 1000 ;
  470.       VertPrinterDots := -integer(round(VPSScale*VertPrinterDots))  + 6370 ;
  471. end ;
  472.  
  473. { --------------------------------------------------------------------
  474.   Convert from Postscript coordinates ( in 1/1000 's of an inch) to
  475.   screen coordinates.
  476.   -------------------------------------------------------------------- }
  477. Procedure PStoScreen(var x,y:integer);
  478. begin
  479.      with Expand do begin
  480.         x := SF*(integer(round((x + 1000)*Hscale)) - Xcent + ScrnW);
  481.         y := 7 + SF*(integer(round((6370 - y)*VScale)) - Ycent + ScrnH);
  482.       end;
  483. end;
  484.  
  485. Procedure OutPrPos(var x,y:integer);  { GRAPHLI position in PS coords }
  486. begin
  487.      x := integer(round(HPSScale*x)) - 1000;
  488.      y := -integer(round(VPSscale * (y-7))) + 6370;
  489. end;
  490.  
  491. procedure SetCopyBlockDef;
  492. const conv = 1000.0/72;
  493. var tx1, ty: integer;
  494.     DefBBox: boolean;
  495. begin
  496.    DefBBox := false;
  497.   with DefaultLayout.BoundingBox do
  498.       if (Layout.boundingBox.LLx = LLx) and (Layout.boundingBox.LLy = LLy)
  499.          and (Layout.boundingBox.URx = URx) and (Layout.boundingBox.URy = URy)
  500.        then DefBBox := true;
  501.   with CopyBlock do begin
  502.      if (GRAPHLIName = '') or DefBBox
  503.      then                               {set defaults if no input file}
  504.         if Lconfig.Dobar then begin
  505.             LLx := -250; LLy := Layout.origin.x - 7130;
  506.             w := 8500; h := 6250;
  507.             URx := LLx + w; URy := LLy + h;
  508.          end else begin
  509.             LLx := 0; LLy := 0;
  510.             w := 8500; h := 6250;
  511.             URx := LLx + w; URy := LLy + h;
  512.       end else             {set from parsed parameters from input file}
  513.             with Layout do begin
  514.                 if Landscape then begin
  515.                     LLx := (round(conv*BoundingBox.LLy)) - origin.y;
  516.                     LLy := origin.x - (round(conv*BoundingBox.LLx));
  517.                     URx := (round(conv*BoundingBox.URy)) - origin.y;
  518.                     URy := origin.x - (round(conv*BoundingBox.URx));
  519.                  end else begin
  520.                     LLx := (round(conv*BoundingBox.LLx - origin.x));
  521.                     LLy := (round(conv*BoundingBox.LLy - origin.y));
  522.                     URx := (round(conv*BoundingBox.URx - origin.x));
  523.                     URy := (round(conv*BoundingBox.URy - origin.y));
  524.                  end;
  525.              end; {with Layout do...}
  526.             if URx < LLx then begin
  527.                  w := URx; URx := LLx; LLx := w;
  528.              end;
  529.             if URy < LLy then begin
  530.                  w := URy; URy := LLy; LLy := w;
  531.              end;
  532.             w := URx - LLx;
  533.             h := URy - LLy;
  534.    end; {with CopyBlock do...}
  535. end;
  536.  
  537. procedure MenuLine;
  538. begin
  539.      if vidcol = color then SetColor(Yellow) else SetColor(white);
  540.      SetViewPort(0,0,HorizScrFS, MenuLineY, Clipon);
  541.      Line(0, MenuLineY, GetMaxX, MenuLineY);
  542.      SetViewPort(0,0,HorizScrFS, MenuLineY - 1, Clipon);
  543. end;
  544.  
  545. { ----------------------------- parsing ----------------------- }
  546.  
  547. Procedure GetAWord(var s:string80);
  548. var i: byte;
  549. begin
  550.      done := false;
  551.      while JimFile^[here] in pwhitespace
  552.      do begin
  553.              if here > count then begin done := true; exit; end ;
  554.              here := succ(here);
  555.         end;
  556.      i := 1;
  557.      mark := here;
  558.      while JimFile^[here] in printables
  559.      do begin
  560.              s[i] := JimFile^[here];
  561.              here := succ(here);
  562.              i := succ(i);
  563.         end;
  564.      s[0] := chr(i-1);
  565.      here := succ(here);
  566. end;
  567.  
  568. Procedure GetAQuote(var s:string80);
  569. const q1 = #39;
  570. var i: byte; q2 : char;
  571. begin
  572.      done := false;
  573.      i := 1; q2 := JimFile^[here];
  574.      here := succ(here);
  575.      repeat
  576.              s[i] := JimFile^[here];
  577.              here := succ(here);
  578.              i := succ(i);
  579.      until JimFile^[here] {in quotes} = q2 ;  { continue past quotes til q2 }
  580.      s[0] := chr(i-1);
  581.      here := succ(here);
  582. end;
  583.  
  584. { ------------------------------------------------------------------------
  585.   GetAWordBack scans from JimFile + offset backwards to extract the last
  586.   previous word (delineated by whitespace).  On entry, offset points
  587.   to a whitespace char that follows the target word.  On exit,
  588.   dest contains the string, and offset points to the first whitespace
  589.   char before the string.  The procdure will get one word after another
  590.   when called repeatedly.
  591.   ------------------------------------------------------------------------ }
  592. procedure GetAWordBack(var dest: string80; var offset: word);
  593. begin
  594.      done := false; dest := '';
  595.      while JimFile^[offset] in pwhitespace do begin
  596.            dec(offset);
  597.            if offset < 0 then begin
  598.               done := true; exit; end;
  599.      end; {while}
  600.      while (Jimfile^[offset] in printables)
  601.               or (Jimfile^[offset] in quotes) do begin
  602.            dest := JimFile^[offset] + dest;
  603.            dec(offset);
  604.            if offset < 0 then begin
  605.               done := true; exit; end;
  606.      end; {while}
  607. end; {GetAWordBack}
  608.  
  609. { -------------------------------------------------------------------------
  610.   ParsePSstring - parse a PostScript string to extract the string itself
  611.   from the parentheses.  Postscript strings are delineated by a pair of
  612.   parentheses.  Also extracts the any chars escaped using '\'.
  613.   Keeps track correctly of embedded parens (must have matching left and
  614.   right parens, just as for Postscript).
  615.   Limitations: doesn't recognize octal escaped numbers.  Doesn't translate
  616.   '\n', '\r', '\b', '\t' (doesn't pass them to dest).
  617.   Offset refers to locations relative to JimFile (i.e., JimFile^[offset]).
  618.  
  619.   On entry, offset points to opening parens.
  620.   On exit, offset points past end of string.
  621.   ------------------------------------------------------------------------- }
  622. procedure ParsePSstring(var dest: string80; var offset: word);
  623. const escapees: set of char = ['n', 't', 'b', 'r'];
  624. var
  625.     parenCount: word;
  626.     ch: char;
  627.     n1: word;
  628. begin
  629.      parenCount := 1; dest := ''; n1 := offset;
  630.      repeat
  631.            inc(offset);
  632.            ch := JimFile^[offset];
  633.            case ch of
  634.                 '\': begin
  635.                         inc(offset);
  636.                         ch := JimFile^[offset];
  637.                         if not (ch in escapees) then dest := dest + ch
  638.                         else inc(offset);
  639.                      end;
  640.                 '(': inc(parenCount);
  641.                 ')': dec(parenCount);
  642.                 else dest := dest + ch;
  643.            end; {case}
  644.      until (parenCount = 0) or (offset > count);
  645.      inc(offset);
  646. end;
  647.  
  648.  
  649. {$I ScanPS}
  650.  
  651.      { -----------------------------------------------------------------
  652.                        read input graph from GRAPHLI
  653.         Also checks file to see if it is an original GRAPHLI file, a
  654.         modified LIPSOGRF file, a POSTOGRF file, or the wrong file type.
  655.         Also locates the start of the GRAPHLI file embedded in a LIPSOGRF
  656.         file.
  657.  
  658.         For Postscript files, locates the offset within the file of a
  659.         number of internal markers (endlabels. etc).
  660.         ------------------------------------------------------------------ }
  661. Procedure ReadGRAPHLI; { <CR> for filename omits reading the file }
  662. const POSTOGRFName = 'POSTOGRF';
  663.       GRAPHName    = 'GRAPH';
  664. type charArray = array[1..length(POSTOGRFName)] of char;
  665.      POSTPtr = ^charArray;
  666.      chArray1 = array[1..length(GRAPHName)] of char;
  667.      GRAPHPtr = ^chArray1;
  668. var s, s1, stemp:string80; n, nn:integer;
  669.  
  670. begin if InGraphMode and not firsttime then clrscr;
  671.      count := 0;
  672.      if (firsttime) and (paramcount <> 0) then GRAPHLIName := paramstr(1)
  673.      else begin
  674.     write('input filename? ');
  675.     if swapColors and InGraphMode then TextColor(white);
  676.     readln(GRAPHLIName);
  677.     if swapColors and InGraphMode then TextColor(black);
  678.       end;
  679.      if GRAPHLIName = '' then exit ;
  680.      repeat
  681.            assign(GRAPHLI,GRAPHLIName);
  682.      {$I-} Reset(GRAPHLI,1); {$I+};
  683.            error := IOResult;
  684.            if error <> 0
  685.            then begin
  686.                      if InGraphMode then clrscr;
  687.                      write('can''t open ' , GRAPHLIName); delay(1000);
  688.              if InGraphMode then gotoxy(1,1) else writeln;
  689.                      write('key new name (CR = none): '); clrEOL;
  690.              if swapColors and InGraphMode then TextColor(white);
  691.              readln(GRAPHLIName);
  692.              if swapcolors and InGraphMode then TextColor(black);
  693.                      if GRAPHLIName = '' then
  694.                                            begin GraphFile := none;
  695.                                                  JimFileStart := 1;
  696.                                                  exit;
  697.                                            end;
  698.                 end;
  699.      until error = 0;
  700.      {if firsttime then write('reading input file...');}
  701.      {gotoxy(1, wherey);}
  702.      if FileSize(GRAPHLI) > 65500 then begin    {file is too large}
  703.         close(GRAPHLI);
  704.         beboop;
  705.         write('this file is too big - must be smaller than 65,500 bytes');
  706.         GRAPHLIName := ''; delay(1500);
  707.         exit;
  708.      end; {if}
  709.  
  710.      JimFileBlock := 10 + FileSize(GRAPHLI);
  711.      GetMem(JimFile, JimFileBlock); { allocate memory }
  712.      blockread(GRAPHLI, JimFile^, JimFileBlock-10, count);
  713.      close(GRAPHLI);
  714.      here := 1; getaword(s);
  715.  
  716.      if pos('%!PS-', s) <> 0  then begin
  717.          GraphFile := POSTSCRIPT;
  718.          gotoxy(1, 1);
  719.          write('this is a PostScript file '); clrEOL;
  720.          JimFileStart := here;
  721.          nn := here + 10;
  722.          repeat                    {scan for 'POSTOGRF'}
  723.             inc(nn);
  724.          until (POSTptr(@Jimfile^[nn])^ = POSTOGRFName)
  725.                or (GRAPHPtr(@Jimfile^[nn])^ = GRAPHName)
  726.                or (nn = here + 300);
  727.          if nn = here + 300 then begin
  728.             writeln('but can''t use it: it''s not a POSTOGRF or GRAPH file');
  729.             GRAPHLIName := ''; delay(1000);
  730.             exit;
  731.          end
  732.          else begin
  733.                     write('and it''s ');
  734.                     if POSTptr(@Jimfile^[nn])^ = POSTOGRFName then
  735.                        writeln('a POSTOGRF file')
  736.                     else writeln('an original GRAPH file');
  737.             ScanPsOffsets;
  738.             if (StartGraph = count) then begin
  739.                        StartGraph := endLabels;
  740.                        EndGraph := StartGraph;
  741.                     end;
  742.                     JimFileStart := StartGraph;
  743.             delay(500);
  744.               end;
  745.      end
  746.      else begin
  747.           if s <> '(O]'
  748.           then begin
  749.     write('Can''t use this file: it''s not a LIPS, POSTOGRF, or GRAPH file') ;
  750.                {close(GRAPHLI);}
  751.                GRAPHLIName := ''; delay(1500);
  752.                exit;
  753.           end;
  754.           SetOriginStr := DefaultOriginStr;
  755.           Layout := DefaultLayout;
  756.           getaword(s);
  757.           getaword(s); { skip 2nd word, test 3rd one }
  758.           if s = 'DAM' then begin GraphFile := GRAPHL;
  759.                              write('this is an original GRAPHLI file');
  760.                              delay(1000);
  761.                              JimFileStart := here;
  762.                              EndGraph := count;
  763.                              delay(500);
  764.                        end
  765.           else if s = 'DTF'
  766.                then begin GraphFile := LIPSGRF;
  767.                     write('this file has been modified by LIPSOGRF');
  768.                     delay(1000);
  769.                     here := 1;   s1 := '';
  770.                     repeat
  771.                           repeat GetaWord(s) until (s = 'FONT') or (s = 'PAGE');
  772.                           if s = 'PAGE' then
  773.                                           begin {GraphFile := none;}
  774.                                              JimFileStart:= here - 5;
  775.                                           end
  776.                           else GetaWord(s1);
  777.                     until (s1 = '2') or (s = 'PAGE'); { looking for 'FONT 2' }
  778.                     if s1 = '2'
  779.                     then JimFileStart := here - 8;    { found it }
  780.                     EndGraph := count;
  781.                end;
  782.      { ---------------------------------------------------------
  783.           Correct tail of GRAPHLI output to be 'EXIT,E;'
  784.       ----------------------------------------------------------}
  785.      n := count;        (* scan backwards to find 'EXIT'*)
  786.      repeat n := n-1 until JimFile^[n] = 'T';
  787.      JimFile^[n+1] := ',' ;    (* fix up tail *)
  788.      JimFile^[n+2] := 'E' ;
  789.      JimFile^[n+3] := ';' ;
  790.      count := n+3;
  791.   end;
  792. end; {ReadGraphLI}
  793.  
  794.  
  795.     { -------------------------------------------------------------
  796.             omit header lines from original GRAPHLI output
  797.        ------------------------------------------------------------ }
  798.  
  799. Procedure DumpJimFileHead;
  800. var s:string80;
  801. begin
  802.      here := 1;
  803.      repeat
  804.            GetAWord(s);
  805.      until (s = 'SPO') or (s = 'EXIT');
  806.      if s = 'EXIT' then here := 1
  807.      else GetAWord(s);
  808. end;
  809.  
  810.     { ----------------------------------------------------------
  811.                      header to set up Postscript
  812.       ------------------------------------------------------------- }
  813. {$I posthd3.}
  814. {$I writelog.inc}
  815.  
  816.      { ------------------------------------------------------------
  817.                  write merged output to file
  818.        ------------------------------------------------------------ }
  819. {$I writeprt.inc }
  820.  
  821.      { -------------------------------------------------------
  822.                      open, close output file
  823.         ------------------------------------------------------ }
  824.  
  825. {$I openprt.pas }
  826.  
  827.      { ------------------------------------------------------
  828.                         set LIPS font size
  829.         ------------------------------------------------------- }
  830.  
  831. Procedure SetPrtFontSize(var size:integer);
  832. begin
  833.          saveh := TempText.CurrText.Horiz;
  834.          savev := tempText.CurrText.Vert;
  835.          GetTextSettings(TempText.CurrText);
  836.          TempText.currText.Horiz := saveh;
  837.          TempText.CurrText.Vert := savev;
  838.        TempText.PrtSize := size;
  839.        UserSizeX := (Expand.SF*(100*size)Div(PointsPerPixelH*CharSizeAdjX));
  840.        UserSizeY := (Expand.SF*(100*size)Div(PointsPerPixelV*44));
  841.        TempText.CurrText.CharSize:= UserCharSize;
  842.        SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  843.        SetTextStyle(Ffont, TempText.CurrText.Direction,
  844.            TempText.CurrText.CharSize);
  845. end ;
  846.  
  847. Procedure RestorePrtFontSize(var size:integer);
  848. begin
  849.        TempText.PrtSize := size;
  850.        UserSizeX := (Expand.SF*(100*size)Div(PointsPerPixelH*CharSizeAdjX));
  851.        UserSizeY := (Expand.SF*(100*size)Div(PointsPerPixelV*44));
  852.        TempText.CurrText.CharSize:= UserCharSize;
  853.        SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  854.        SetTextStyle(Ffont, TempText.CurrText.Direction,
  855.            TempText.CurrText.CharSize);
  856. end;
  857.  
  858.         { -------------------------------------------------------------
  859.                         draw the graph on the screen
  860.            ------------------------------------------------------------- }
  861.  
  862. procedure DrawJimFile;
  863. var XPos, Ypos, error, temp  : integer;
  864.     PenDia                   : word;
  865.     n1                       : word;
  866.     str                      : string80;
  867.     sFlag                    : boolean;
  868. begin
  869.      if here > EndGraph then begin
  870.         done := true; exit; end;
  871.      GetAWord(str);
  872.      case GraphFile of
  873.           GRAPHL, LIPSGRF: begin
  874.      if str = 'EXIT' then begin done := true; exit ; end ELSE
  875.      if str = 'MAP' then   { move to position }
  876.         begin GetAWord(str); Val(str,Xpos,error); (* *** ADD ERROR CHECKING *)
  877.               GetAWord(str); Val(str,Ypos,error);
  878.               ScrConv(XPos, YPos);
  879.               MoveTo(Xpos,YPos);
  880.         end ELSE
  881.      if str = 'DAP' then   { draw to position }
  882.         begin GetAWord(str); Val(str,Xpos,error); (* *** ADD ERROR CHECKING *)
  883.               GetAWord(str); Val(str,Ypos,error);
  884.               ScrConv(XPos,YPos);
  885.               LineTo(Xpos,YPos);
  886.         end ELSE
  887.      if str = 'SPD' then        { set pen diameter - only an approximation }
  888.         begin GetAWord(str); Val(str,PenDia, error); (* *** ADD ERROR CHECK *)
  889.               PenDia := word(round(10 * PenDia/VPrtScale)) div 3;
  890.                   SetLineStyle(0,0,PenDia);
  891.         end ELSE
  892.      if str = 'FONT' then { he asks for internal landscape font - fake it }
  893.         begin GetAWord(str); if str = '3' then  begin
  894.               temp:= 12; SetPrtFontSize(temp); end else (* nothing *);
  895.         end ELSE
  896.      if str = 'TEXT' then    { write the following text string }
  897.         begin GetAQuote(str); OutText(str);
  898.         end ELSE (* nothing *);
  899.    end; {case GRAPHL, LIPSGRF}
  900.    POSTSCRIPT: begin
  901.     temp := 13; SetPrtFontSize(temp);
  902.     if str[1] = 's' then sFlag := true else sFlag := false;
  903.         if str[1] = '%' then
  904.        repeat
  905.           inc(here)
  906.        until (JimFile^[here] = CR) or (JimFile^[here] = LF);
  907.         if str[1] = '(' then begin       {found a label}
  908.           ParsePSstring(str,mark);
  909.           OutText(str);
  910.           here := mark;
  911.         end ELSE
  912.        if (str[1] = 'm') then begin
  913.          if ((str = 'm') or (str = 'moveto')) then begin
  914.              n1 := here - 1; GetAWordBack(str,n1); GetAWordBack(str, n1);
  915.              Val(str, YPos, error);
  916.              if error <> 0 then exit;
  917.              GetAWordBack(str,n1);
  918.              Val(str,XPos,error);
  919.              if error <> 0 then exit;
  920.              PStoScreen(XPos, YPos);
  921.              MoveTo(XPos, YPos);
  922.          end;
  923.        end ELSE
  924.        if (str[1] = 'l') then begin
  925.          if ((str = 'l') or (str = 'lineto')) then begin
  926.              n1 := here - 1; GetAWordBack(str,n1); GetAWordBack(str, n1);
  927.              Val(str, YPos, error);
  928.              GetAWordBack(str,n1);
  929.              Val(str,XPos,error);
  930.              PStoScreen(XPos, YPos);
  931.              LineTo(XPos, YPos);
  932.          end;
  933.        end ELSE
  934.        if (sflag) and (str = 'setlinewidth') then begin
  935.           n1 := here -1; GetAWordBack(str,n1); GetAWordBack(str, n1);
  936.           Val(str,PenDia,error);
  937.           if error = 0 then begin
  938.              PenDia := word(round(PenDia)) div 10;
  939.           end else PenDia := 1;
  940.           SetLineStyle(0,0,PenDia);
  941.        end ELSE
  942.        if (sFlag) and (str = 'sf') then begin        {set active font size}
  943.              {any labels here are default 13 pt labels}
  944.           temp := 13; SetPrtFontSize(temp); end ELSE
  945.        if (sFlag) and (str = 'setfont') then begin
  946.           temp := 13; SetPrtFontSize(temp);
  947.        end ELSE
  948.        if (sFlag) and (str = 'showpage') then begin done := true; exit ;
  949.      end; {if..ELSE}
  950.     end; {POSTSCRIPT}
  951.   end; {case}
  952. end; {DrawJimFile}
  953.  
  954. procedure AddRec;                 { create & insert new record }
  955. begin cp := head;                 { exit with cp pointing to }
  956.       new(head);                  { new record }
  957.       head^.link := cp;
  958.       cp := head;
  959. end;
  960.  
  961.  
  962. procedure SetUpLabel(var Tlabel: textptr);
  963. var t1:integer;
  964. begin if Tlabel = nil then exit;
  965.       t1 := Tlabel^.PrtSize;
  966.       with Expand do begin
  967.         UserSizeX := (SF*(100*t1)Div(PointsPerPixelH*CharSizeAdjX));
  968.         UserSizeY := (SF*(100*t1)Div(PointsPerPixelV*44));
  969.        end;
  970.       SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  971.       SetTextStyle(Ffont, Tlabel^.CurrText.direction,
  972.              Tlabel^.CurrText.CharSize);
  973. end;
  974.  
  975. procedure Showlabel( var Tlabel: textptr; wColor:word);
  976. begin if Tlabel = nil then exit else;
  977.       SetColor(wColor);
  978.       SetUpLabel(Tlabel);
  979.       with Expand do
  980.         OutTextXY(SF*(Tlabel^.CurrText.Horiz - Xcent + ScrnW),
  981.              SF*(Tlabel^.CurrText.Vert - Ycent + ScrnH), Tlabel^.Tstr);
  982. end;
  983.  
  984. procedure BoxLabel(Tlabel:textptr; wColor:word);
  985. var xt, yt: integer;
  986. begin
  987.      if Tlabel = nil then exit;
  988.      SetColor(wColor);
  989.      SetUpLabel(Tlabel);
  990.      saveh := Tlabel^.CurrText.Horiz;
  991.      savev := Tlabel^.CurrText.Vert;
  992.      GetTextSettings(Tlabel^.CurrText);
  993.      Tlabel^.currText.Horiz := saveh;
  994.      Tlabel^.CurrText.Vert := savev;
  995.      with Expand do begin
  996.         xt := Tlabel^.currText.Horiz ;
  997.         yt := Tlabel^.CurrText.Vert ;
  998.  
  999.        SetWriteMode(XORPut);
  1000.        case Tlabel^.currText.Direction of
  1001.          HorizDir:
  1002.              Rectangle(
  1003.        SF*(xt  - Xcent + ScrnW + 1) + TextWidth(Tlabel^.Tstr),
  1004.        SF*(yt  + 2 - Ycent + ScrnH) - TextHeight(Tlabel^.Tstr),
  1005.        SF*(xt - Xcent + ScrnW -1) , SF*(yt - Ycent + ScrnH + 2));
  1006.          VertDir:
  1007.              Rectangle(
  1008.        SF*(xt  - Xcent + ScrnW + 1) + TextHeight(Tlabel^.Tstr),
  1009.        SF*(yt  + 2 - Ycent + ScrnH) - TextWidth(Tlabel^.Tstr),
  1010.        SF*(xt - Xcent + ScrnW -1) , SF*(yt - Ycent + ScrnH + 2));
  1011.         end; {case}
  1012.       end; {with Expand do ...}
  1013.       SetWriteMode(CopyPut);
  1014.  
  1015. end;
  1016.  
  1017. procedure UnBoxLabel(Tlabel:textptr);
  1018. begin
  1019.      If VidCol = color then exit;
  1020.      SetWriteMode(XorPut);
  1021.      BoxLabel(Tlabel, white);
  1022.      SetWriteMode(CopyPut);
  1023. end;
  1024.  
  1025.  
  1026. procedure HighLight(Tlabel: textptr);
  1027. begin
  1028.      if VidCol = color then ShowLabel(Tlabel, yellow)
  1029.      else begin ShowLabel(Tlabel, white);
  1030.                 BoxLabel(Tlabel, white);
  1031.           end;
  1032. end;
  1033.  
  1034. procedure UnHighLight(Tlabel: textptr);
  1035. begin
  1036.      if VidCol = color then ShowLabel(Tlabel, white)
  1037.      else begin Showlabel(Tlabel, white);
  1038.                 UnBoxLabel(Tlabel);
  1039.           end;
  1040. end;
  1041.  
  1042. procedure SelectRec;                    { traverse list one step }
  1043. begin if head = nil then exit;          { if no labels, then quit }
  1044.       if select <> nil then             { if label is already selected, }
  1045.            begin select^ := TempText;   { then update it }
  1046.                UnHighLight(select);     { unhighlight it }
  1047.            end;
  1048.       if (select^.link  = nil) or (select= nil)  then cp := head
  1049.       else cp := select^.link ;
  1050.       HighLight(cp);
  1051.       TempText := cp^; select := cp; {select new label }
  1052.       key := #0;                     { exit code for main }
  1053. end;
  1054.  
  1055. procedure SelectRecBack;                { select previous label }
  1056. begin
  1057.      if head = nil then exit;
  1058.      cp := head;
  1059.      if select <> nil then begin
  1060.         select^ := TempText;
  1061.         UnHighLight(select);
  1062.      end;
  1063.      if select = head then
  1064.            while (cp^.link <> nil) do
  1065.               cp := cp^.link               { choose last one }
  1066.         else if select = nil then cp := head
  1067.         else while not (cp^.link = select) do cp := cp^.link;
  1068.      HighLight(cp);
  1069.      TempText := cp^; select := cp; {select new label }
  1070.      key := #0;                     { exit code for main }
  1071. end;
  1072.  
  1073. procedure selectHead;                   { select head of list of labels }
  1074. begin if head = nil then exit;          { if no labels, the quit }
  1075.       if select <> nil then             { if label is already selected, }
  1076.            begin select^ := TempText;   { then update it }
  1077.                UnHighLight(select);     { unhighlight it }
  1078.            end;
  1079.       cp := head;
  1080.       HighLight(cp);
  1081.       TempText := cp^; select := cp; {select new label }
  1082.       key := #0;                     { exit code for main }
  1083. end;
  1084.  
  1085. procedure selectTail;                   { move to tail of linked list}
  1086. var temp: textPtr;
  1087. begin if head = nil then exit;          { if no labels, the quit }
  1088.       if select <> nil then             { if label is already selected, }
  1089.            begin select^ := TempText;   { then update it }
  1090.                UnHighLight(select);     { unhighlight it }
  1091.            end;
  1092.       temp := head;
  1093.       while temp^.link <> nil do temp := temp^.link;
  1094.       cp := temp;
  1095.       HighLight(cp);
  1096.       TempText := cp^; select := cp; {select new label }
  1097.       key := #0;                     { exit code for main }
  1098. end;
  1099.  
  1100. procedure SetLabelDefaults(Tlabel: textptr);
  1101. begin Fsize := DefaultFsize;
  1102.      with Tlabel^ do
  1103.      begin  Tstr := '';
  1104.             {PrtSize := Fsize;}
  1105.             (* CurrText.horiz := 100; CurrText.vert := 100 ;*)
  1106.             CurrText.Direction := HorizDir;
  1107.             PrtSize := Fsize;
  1108.             {LIPSFont.LIPSStyle := HelvBold;}
  1109.             LIPSFont.LIPSStyle := DefaultLIPSStyle;
  1110.      end;
  1111.      UserSizeX := (100*Fsize)Div(PointsPerPixelH*CharSizeAdjX);
  1112.      UserSizeY := (100*Fsize)Div(PointsPerPixelV*44);
  1113.      Tlabel^.CurrText.CharSize:= UserCharSize;
  1114.      Tlabel^.LabelBkGround := defaultPaintType;
  1115.      SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  1116. end;
  1117.  
  1118. procedure AddLabel;            { create record, set default attributes, }
  1119. begin If select = nil then {nothing}
  1120.       else begin select^ := temptext;
  1121.                  UnHighLight(select);
  1122.            end;
  1123.       AddRec;
  1124.       SetLabelDefaults(cp);
  1125.       SetUpLabel(cp);
  1126.       cp^.CurrText.horiz := TempText.CurrText.horiz;
  1127.       cp^.CurrText.Vert := TempText.CurrText.vert +
  1128.               ((45*TextHeight(TempText.Tstr)) div 32) div expand.sf;
  1129.       TempText := cp^;
  1130.       EditLabel;
  1131.       cp^ := TempText;
  1132.       HighLight(cp);
  1133.       select := cp;
  1134.       saved := false;
  1135. end;
  1136.  
  1137. procedure DeleteLabel;          { delete selected label }
  1138. var temp: TextPtr;
  1139. begin if select = nil then begin beboop; exit; end ;
  1140.       cp := head;
  1141.       if cp = nil then exit;
  1142.       UnBoxLabel(select);
  1143.       ShowLabel(select, black);
  1144.       if select = head then begin
  1145.          head := head^.link ;                       { relink }
  1146.          temp := head;
  1147.       end
  1148.       else begin
  1149.            while not (cp^.link = select)
  1150.                  do cp := cp^.link;
  1151.            temp := cp;
  1152.            cp^.link := select^.link;                { relink}
  1153.       end;
  1154.       SaveLastTextRec := select^;                   { save for UnDelete }
  1155.       SaveLastTextRec.Link := @SaveLastTExtRec;
  1156.       dispose(select);                              { dump it }
  1157.       if temp <> nil then begin                   { select previous label }
  1158.          select := temp;
  1159.          temptext := select^;
  1160.          HighLight(select);
  1161.        end
  1162.        else select := nil;
  1163.       saved := false;
  1164. end;
  1165.  
  1166. procedure UnDelete;               {restore deleted label }
  1167. begin
  1168.      if SaveLastTextRec.link = nil then exit;
  1169.      UnHighlight(select);
  1170.      AddRec;
  1171.      SaveLastTextRec.Link := cp^.link;
  1172.      cp^ := SaveLastTextRec;
  1173.      tempText := cp^;
  1174.      select := cp;
  1175.      Highlight(cp);
  1176.      Key := #1;
  1177.      SaveLastTextRec.link := nil;
  1178. end;
  1179.  
  1180. procedure AddNewLogo;
  1181. var tlink: TextPtr;
  1182.     trec: textRec;
  1183.     tx, ty: integer;
  1184.  
  1185. begin
  1186.       trec := select^;
  1187.       AddRec;
  1188.       tlink := cp^.link;
  1189.       cp^ := MitreLogoLabel;
  1190.       cp^.link := tlink;
  1191.       tx := LogoX; ty := {LogoY}-( 8500 - 750 - Layout.origin.x);
  1192.       PStoScreen(tx,ty);
  1193.       cp^.CurrText.horiz := tx;
  1194.       cp^.CurrText.Vert := ty {+ (44*TextHeight(TempText.Tstr)) div 32};
  1195.       {ShowLabel(cp, white);}
  1196.       select^ := trec;
  1197.       saved := false;
  1198. end;
  1199.  
  1200. procedure AddLogoLabel;
  1201. begin
  1202.   AddNewLogo;
  1203.   ShowLabel(cp, white);
  1204. end;
  1205.  
  1206. procedure DeleteLogoLabel;
  1207. var temp, temp1: TextPtr;
  1208.  
  1209.    { ---------------------------------------------------------------------
  1210.       search through label chain starting at here.  Find next label that
  1211.       uses the MITRELogo font.  Return true if found, false otherwise.
  1212.      --------------------------------------------------------------------- }
  1213.    function findLogoLabel(var here: TextPtr): boolean;
  1214.    var tptr: TextPtr;
  1215.    begin
  1216.        if head = nil then begin
  1217.           findLogoLabel := false; exit; end;
  1218.        tptr := head;
  1219.        while (tptr^.Lipsfont.LipsStyle <> MitreLogo) and (tptr <> nil) do
  1220.           tptr := tptr^.link;
  1221.        here := tptr;
  1222.        findLogoLabel := (tptr <> nil);
  1223.    end; {findLogoLabel}
  1224.  
  1225.    procedure UnLinkLogoLabel(var here:TextPtr);
  1226.    var temp: TextPtr;
  1227.    begin
  1228.       if here = nil then exit;
  1229.       if here = select then begin
  1230.         if here = head then select := head^.link
  1231.          else if select^.link = nil
  1232.            then select := head
  1233.           else select := select^.link;
  1234.         TempText := select^;                {needed for correct updating}
  1235.         unHighlight(here);
  1236.         HighLight(Select);
  1237.         cp := select;
  1238.        end;
  1239.       if here = head then head := head^.link
  1240.        else begin             {traverse list to find predecessor}
  1241.          temp := head;
  1242.          repeat temp := temp^.link
  1243.           until temp^.link = here;
  1244.          temp^.link := here^.link;
  1245.         end;
  1246.        showLabel(here, black);
  1247.        dispose(here);
  1248.    end; {UnLinkLogoLabel}
  1249.  
  1250. begin
  1251.   while findLogoLabel(temp) do
  1252.      UnLinkLogoLabel(temp);
  1253.   saved := false;
  1254. end; {DeleteLogoLabel}
  1255.  
  1256. procedure DoVGBar;
  1257. const barxl = -1000 ; barxr = 9500;
  1258. var xx, yy : integer;
  1259.     tcolor: word;
  1260. begin
  1261.     tcolor := GetColor;
  1262.     if Lconfig.DoBar then setcolor(white)
  1263.      else setcolor(GetBkColor);
  1264.     barY := Layout.origin.x - 1750;
  1265.     xx := barxl; yy := bary;
  1266.     PStoScreen(xx, yy);
  1267.     MoveTo(xx, yy);
  1268.     xx := barxr; yy := bary;
  1269.     PStoScreen(xx,yy);
  1270.     LineTo(xx, yy);
  1271.     setcolor(tcolor);
  1272. end;
  1273.  
  1274. procedure VGFormat;
  1275. begin
  1276.     if Lconfig.DOBar and (not firsttime)
  1277.       then AddLogoLabel
  1278.      else DeleteLogoLabel;
  1279.     DoVGBar;
  1280. end;
  1281.  
  1282. { Moved RePaint1 to copybloc.inc}
  1283. { -----------------------------------------------------------------------
  1284.     procedures to show and move the box that indicates the copyblock
  1285.    ------------------------------------------------------------------------ }
  1286. {$I copybloc.inc}
  1287.  
  1288. { ---Repaint, MoveLabel, and Attributes have been moved to Copybloc.inc ---- }
  1289.  
  1290. {$I extrlabs}
  1291.  
  1292. procedure PrtOutput;
  1293. begin
  1294.      repeat
  1295.         gotoxy(1,1); clrscr;
  1296.         OpenPrtFile(PrtFile, PrtFileName, GRAPHLIName,key);
  1297.         if key = ESC then exit;
  1298.         WritePrt;
  1299.         ClosePrtFile(PrtFile,PrtFileName);
  1300.      until fileOK;
  1301.      saved := true;
  1302.      if key = #0  then begin
  1303.                GoToXY(1,1); clreol;
  1304.                writeln('quit this graph (y/n)? ');
  1305.                key := readkey;
  1306.                if key in yes then begin
  1307.                    newfile := true; key := ESC;
  1308.                 end else begin newfile := false; key := #0; end;
  1309.       end
  1310.      else begin newfile := true; key := ESC; end;
  1311.      if newfile then begin
  1312.                         if JimFileBlock > 0
  1313.                         then begin FreeMem(JimFile, JimFileBlock);
  1314.                         JimFileBlock := 0;
  1315.                         Jimfile := nil;
  1316.                     end;
  1317.       end;
  1318. end;
  1319.  
  1320. {$I extramen.inc}
  1321.  
  1322. procedure LabelMenu;
  1323. const HelpStr1 =
  1324. 'F1 Add    F2 Attrib    F3 Delete    F4 Edit    F5 Repaint    F6 Extras ';
  1325. Helpstr2 =
  1326. 'F7 Copyblock   F8 Layout  F9 Undelete   F10 save/quit   Home, End select +,-' ;
  1327.      movers: set of char = [leftarrow, rightarrow, uparrow, downarrow,
  1328.               #115, #116, #73, #81];
  1329.  
  1330.    procedure ShowHelpStr;
  1331.    begin
  1332.       clrscr;
  1333.       MenuLine;
  1334.       write(Helpstr1);
  1335.       gotoXY(1,2); write(Helpstr2);
  1336.       gotoxy(1,1);
  1337.    end; {ShowHelpStr}
  1338.  
  1339. begin repeat
  1340.         if key = #0 then ShowHelpStr;
  1341.         key := ReadKey;
  1342.         if key = #0
  1343.            then begin key := readkey;
  1344.                       case key of      {function keys}
  1345.                            PF1: begin AddLabel ; key := #0; end;
  1346.                            PF2: begin Attributes; key := #0; end;
  1347.                            PF3: DeleteLabel;
  1348.                            PF4: Begin                       { edit label }
  1349.                                     if select = nil
  1350.                                     then begin write('nothing is selected');
  1351.                                                delay(500);
  1352.                                          end
  1353.                                      else begin
  1354.                                                Select^ := TempText;
  1355.                                                EditLabel;
  1356.                                                ShowLabel(select, black);
  1357.                                                UnBoxlabel(select);
  1358.                                                Select^ := TempText;
  1359.                                                HighLight(select);
  1360.                                                saved := false;
  1361.                                           end; {else }
  1362.                                      key := #0;
  1363.                                 end; {begin}
  1364.                            PF5: begin
  1365.                                   clrscr; Repaint;
  1366.                                   ShowHelpStr;
  1367.                                  end;
  1368.                            PF6: ExtraMenu;
  1369.                        PF7: CopyBlockMenu;
  1370.                            PF8: begin
  1371.                                    ChangeLayout;
  1372.                                    clrscr; Repaint;
  1373.                                    ShowHelpStr;
  1374.                                  end;
  1375.                            PF9: begin Undelete; key := #1; end;
  1376.                            PF10: begin
  1377.                                      clrscr;
  1378.                                      write(
  1379. 'X quit (autosave)   Q quit   <CR> save, new file   ESC return to main menu');
  1380.                  key := upcase(readkey);
  1381.                  case key of
  1382.                      CR: begin
  1383.                            if select <> nil then select^ := TempText;
  1384.                            PrtOutput;
  1385.                            key := #0;
  1386.                          end;
  1387.                      'Q': case saved of
  1388.                              false: begin
  1389.                                 beboop;
  1390.                                 GoToXY(1,1); Clrscr;
  1391.                                 write('Graph has been changed. ');
  1392.                                 write('Save it before quitting (y/n)? [y]');
  1393.                                 gotoxy(wherex-2, wherey);
  1394.                                 Ckey := readkey; write(Ckey);
  1395.                                 if not (Ckey in No) then begin
  1396.                                      if select <> nil then select^ := TempText;
  1397.                                      PrtOutPut;
  1398.                                   end;
  1399.                                 finished := true;
  1400.                               end; {false}
  1401.                              true: begin gotoxy(1,1); clrscr;
  1402.                                          finished := true;
  1403.                                     end; {true}
  1404.                           end; {case saved}
  1405.                        'X': begin   {force writing output}
  1406.                                 if select <> nil then select^ := TempText;
  1407.                                 if GRAPHLIName = '' then PrtOutPut else begin
  1408.                                     case saved of
  1409.                                        false: begin
  1410.                                           PrtFileName := GRAPHLIName;
  1411.                                           Assign(PrtFIle, PrtFileName);
  1412.                                           Rewrite(PrtFile);
  1413.                                           WritePrt;
  1414.                                           ClosePrtFile(PrtFile,PrtFileName);
  1415.                                           if FileOK then finished := true else
  1416.                                              PrtOutput;
  1417.                                          end; {false}
  1418.                                        true: ;
  1419.                                      end; {case saved of}
  1420.                                   end; {if GRAPHLIName...}
  1421.                                 finished := true;
  1422.                              end; {case X }
  1423.                        ESC: key := #0;
  1424.                        #0: begin key := readkey; key := #0; end;
  1425.                   end; {case key of}
  1426.                  end; {PF10 begin}
  1427.  
  1428.                            CNTLHOME: begin SelectHead; key := #1; end;
  1429.                            CNTLEND: begin SelectTail; key := #1; end;
  1430.                            Home: begin SelectRec; key := #1; end;
  1431.                            En: begin SelectRecBack; key := #1; end;
  1432.                       else if key in movers then MoveLabel;
  1433.                       end; {case function keys}
  1434.                 end; {if}
  1435.       until finished or newfile;
  1436. end;
  1437.  
  1438. procedure KillList;
  1439. begin while head <> nil
  1440.       do begin cp := head^.link;
  1441.                      dispose(head);
  1442.                      head := cp;
  1443.          end;
  1444. end;
  1445.  
  1446.  
  1447. procedure init1;
  1448. begin
  1449.      { --------------- printer, screen params ----------------
  1450.      xxLIPSFs are coordinate values output from GRAPHLI.
  1451.      xxPrtFs refers to the postscript printer.
  1452.      --------------------------------------------------------- }
  1453.      HorizScrFs := GetMaxX ; HorizPrtFs := 10000 ; HorizLIPSFs := 3000;
  1454.      VertScrFs := GetMaxY - 1*linesperChar;
  1455.      VertPrtFs := 10000; VertLIPSFs := 2400;
  1456.      HPrtScale := HorizLIPSFs / HorizScrFs ;
  1457.      VPrtScale := VertLIPSFs / VertScrFs ;
  1458.      HPSScale := HorizPrtFs/HorizLIPSFs;
  1459.      VPSScale := VertPrtFs/HorizLIPSFs;
  1460.      HScale := 1/(HPSScale*HprtScale);
  1461.      VScale := 1/(VPSScale*VprtScale);
  1462.      { ------------------------------------------------------------- }
  1463.      with Expand do begin
  1464.         SF := 1;
  1465.         Xcent := HorizScrFS div 2; Ycent := VertScrFS div 2;
  1466.         ScrnW := HorizScrFS div 2;
  1467.         ScrnH := VertScrFS div 2;
  1468.       end;
  1469.  
  1470.      SetViewPort(0,0,HorizScrFS, MenuLineY-1, Clipon);
  1471.      PointsPerPixelH := 720 Div HorizScrFS; (* 10 in. = 720 points wide *)
  1472.      PointsPerPixelV := 576 Div VertScrFS; (* 8 in. = 576 points high *)
  1473.  
  1474. end;
  1475.  
  1476. procedure Init;
  1477. begin
  1478.      key := #0; finished := false; newfile := false; firsttime := false;
  1479.      saved := true; noshow := true;
  1480.      onoff := off;
  1481.      if GRAPHLIName = '' then begin
  1482.          JimFileBlock := 0;
  1483.          Layout := defaultLayout;
  1484.          setOriginStr := defaultOriginStr;
  1485.          barY := defaultBarY;
  1486.       end;
  1487.      SetCopyBlockDef;
  1488.      if Lconfig.doBar then barY := Layout.origin.x - 1750;
  1489.      Fsize := 20;
  1490.      TempText.PrtSize := Fsize;
  1491.      Ffont := SansSerifFont ;
  1492.      defaultPaintType := trans;
  1493.  
  1494.      UserSizeX := (100*Fsize)Div(PointsPerPixelH*CharSizeAdjX);
  1495.      UserSizeY := (100*Fsize)Div(PointsPerPixelV*44);
  1496.      with TempText do
  1497.           begin CurrText.horiz := 100;  CurrText.Vert := 100;
  1498.                 CurrText.Direction := HorizDir;
  1499.                 CurrText.CharSize:= UserCharSize;
  1500.           end;
  1501.      SetUserCharSize(UserSizeX, UserDiv, UserSizeY, UserDiv);
  1502.      SetTextJustify(lefttext, bottomtext) ;
  1503.      SetTextStyle(SansSerifFont,Horizdir,UserCHarSize);
  1504.  
  1505.      PrtExitStr := 'showpage grestore ' + CR + LF + 'restore' + CR + LF
  1506.                     + '%%Trailer'+ CR + LF + #4;
  1507.      defaultFont0str := '/font0 /Helvetica-Bold findfont 181 scalefont def';
  1508.      font0str := defaultFont0str;
  1509.  
  1510.      { --------------- linked list of labels ---------------- }
  1511.      cp := nil; select := nil; head := nil; TempText.link := nil;
  1512.      SaveLastTextRec.Link := nil;
  1513.  
  1514.      { --------------- misc --------------------------------- }
  1515.      here := 1;
  1516.  
  1517.      CopyRight :=
  1518.         'Created By T. B. Passin using Borland''s TurboPascal, June 1990';
  1519. end ;
  1520.  
  1521. Procedure InitScreen;
  1522. var BGIdirectory, FontFName: string[80];
  1523.     loline, hiline: word;
  1524.  
  1525.      procedure Abort(Msg : string);
  1526.      begin
  1527.           Writeln(Msg, ': ', GraphErrorMsg(GraphResult));
  1528.           Halt(1);
  1529.       end;
  1530. begin
  1531.    if InGraphMode then exit;
  1532.   { Register all the drivers }
  1533.   if RegisterBGIdriver(@CGADriverProc) < 0 then
  1534.     Abort('CGA');
  1535.   if RegisterBGIdriver(@EGAVGADriverProc) < 0 then
  1536.     Abort('EGA/VGA');
  1537.   if RegisterBGIdriver(@HercDriverProc) < 0 then
  1538.     Abort('Herc');
  1539.   if RegisterBGIdriver(@ATTDriverProc) < 0 then
  1540.     Abort('AT&T');
  1541.  
  1542.   { Register all the fonts }
  1543.   if RegisterBGIfont(@SansSerifFontProc) < 0 then
  1544.     Abort('SansSerif');
  1545.  
  1546.   DetectGraph(GraphDriver, GraphMode);      { autodetect the hardware }
  1547.  
  1548.    case GraphDriver of
  1549.         EGA, EGA64: VidCol := color;
  1550.         EGAMono: VidCol := mono;
  1551.         VGA: VidCol := color;
  1552.         CGA: VidCol := mono;
  1553.         MCGA: VidCol := mono{color};
  1554.         ATT400: VidCol := mono;
  1555.         HercMono: Vidcol := mono;
  1556.    ELSE begin
  1557.       writeln('sorry - can''t use this video adapter');
  1558.           halt(1);
  1559.     end;
  1560.    end; {case}
  1561.    case GraphDriver of
  1562.         CGA : LinesPerChar := 8;
  1563.         MCGA, VGA: LinesPerCHar := 16;
  1564.       else LinesPerChar := 14;
  1565.    end; {case GraphDriver}
  1566.  
  1567.   InitGraph(GraphDriver, GraphMode, '');  { activate graphics }
  1568.   if GraphResult <> grOk then             { any errors? }
  1569.   begin
  1570.     writeln('sorry - can''t initialize graphics mode');
  1571.     textMode(LastMode);
  1572.     Halt(1);
  1573.   end;
  1574.    InGraphMode := true;
  1575.    DirectVideo := false;
  1576.    begin
  1577.     TextColor(black);
  1578.     swapcolors := true;
  1579.       end;
  1580.      {Window(1,23,80,25);}
  1581.      hiline := GetMaxY div LinesPerChar ;
  1582.      loline := hiline - 2;
  1583.      WindMin := lo(WindMin) + $100*loline;
  1584.      WindMax := lo(WindMax) + $100*hiline;
  1585.      if VidCol = color then SetColor(yellow) else SetColor(white);
  1586.      MenuLineY := GetMaxY-3*LinesPerChar;
  1587.      MenuLine;
  1588.      Assign(output,''); rewrite(output);
  1589. end;
  1590.  
  1591. (* ************************************************************************
  1592.                                MAIN
  1593.    ************************************************************************ *)
  1594. begin
  1595.    InGraphMode := false; firsttime := true;
  1596.         DefaultOriginStr :=
  1597. '/setorigin { 7.375 inch 1.5 inch translate  % move to starting point' + CR + LF
  1598. + '             90 rotate                      % landscape' + CR + LF
  1599. + '             0 0 m  } def                   % move to new origin';
  1600.  repeat
  1601.    lConfig := defaultConfig;
  1602.    InitScreen;
  1603.    Init1;
  1604.    if firsttime then begin
  1605.      gotoxy(1,1); write(ver); gotoxy(1,2);
  1606.     end;
  1607.    ReadGRAPHLI;
  1608.    init ;
  1609.    ExtractLabels;
  1610.    if GRAPHLIName = '' then { nothing } else RePaint;
  1611.    ShowCopyBlock;
  1612.    SelectRec;
  1613.    labelMenu ;
  1614.    KillList;
  1615.    if not finished then ClearViewPort;
  1616.  until finished;
  1617.   CloseGraph;
  1618.   TextMode(LastMode);
  1619.   {Window(1,1,80,25);}
  1620. end.
  1621.  
  1622. { (Z] SCRC O; EXIT; }
  1623.  
  1624.  
  1625.