DEFINITION MODULE PSWriter;

(* Author:         Andrew Trevorrow
   Implementation: University of Hamburg Modula-2 under VAX/VMS version 4
   Date Started:   August, 1986

   Description:
   These routines are used by PSDVI to create the PostScript output file.
   The following calling sequence is largely determined by the PostScript
   definitions that must be prepended (possibly by /HEADER) to the output:

   OpenOutput
   if /HEADER given then OutputHeader end
   for each page selected do
      BeginPage
      if not conserving VM then
         for each new bitmap font do NewBitmapFont end
         for each bitmap font used on this page do
            BeginBitmapFont
            for each new character do LoadBitmap end
         end
      end
      OutputPage
      for each \special on this page do OutputSpecial end
      for each font used on this page do
         if (conserving VM) and (not PostScript font) then SaveVM end
         if PostScript font then BeginPostScriptFont else BeginBitmapFont end
         if (conserving VM) and (not PostScript font) then
            for each character used do LoadBitmap end
         end
         if PostScript font then
            for each character used do SetPostScriptChar end
         else
            for each character used do SetBitmapChar end
         end
         EndFont
         if (conserving VM) and (not PostScript font) then RestoreVM end
      end
      for each rule on this page do SetRule end
      EndPage
   end
   CloseOutput

   Revised:
   December, 1986
 - LoadPSChar has been replaced by LoadBitmap from FontReader.
   Various Put routines are now exported so that LoadBitmap can use them
   to send PostScript code to the output file.

   November, 1987 (while at The Open University)
 - Renamed most routines to make a clear distinction between routines
   applicable to bitmap fonts or to resident PostScript fonts.
 - Added BeginPostScriptFont to generate appropriate code for switching
   to a resident PostScript font.  The main module should call this routine
   after OutputPage for a font whose psfont flag is TRUE.
 - Added SetPostScriptChar to position and show a character from a resident
   PostScript font.  We cannot use SetBitmapChar because the advance widths
   for PostScript fonts are not an integer number of pixels
   (and we'd get accumulated rounding errors).
 - Added SaveVM and RestoreVM routines.  The main module should call these
   routines around bitmap fonts when conserving virtual memory.

   June--August, 1988 (while at Aston University)
 - EndBitmapFont now called EndFont as it is used for both font types.
*)

PROCEDURE OpenOutput (name : ARRAY OF CHAR) : BOOLEAN;
(* Return TRUE if given file can be opened for output. *)

PROCEDURE OutputHeader (name : ARRAY OF CHAR) : BOOLEAN;
(* Return TRUE if given file can be copied to output.
   Return FALSE if file could not be opened.
*)

PROCEDURE BeginPage (DVIpage : CARDINAL);
(* Output some PostScript to indicate the start of a new page. *)

PROCEDURE NewBitmapFont (VAR fontid : ARRAY OF CHAR);
(* Output some PostScript to define a new bitmap font.
   The string parameter is declared to be a variable for efficiency reasons;
   PSWriter will never change its value.
*)

(* Here are the Put routines needed by LoadBitmap in FontReader: *)
PROCEDURE Put       (ch : CHAR);
PROCEDURE PutString (s  : ARRAY OF CHAR);
PROCEDURE PutInt    (i  : INTEGER);
PROCEDURE PutCard   (c  : CARDINAL);

PROCEDURE OutputPage (DVIpage : CARDINAL);
(* Output some PostScript to prepare showing specials, chars and rules on
   the current page.
*)

TYPE specialstring = ARRAY [0..255] OF CHAR;

PROCEDURE OutputSpecial (VAR name : specialstring;
                         hpos, vpos : INTEGER) : BOOLEAN;
(* Return TRUE if given file can be copied to output.
   Return FALSE if file could not be opened.
   name can also include a space and additional PostScript text that will
   be prefixed to the given file as a separate line.  This allows users to
   include a command like "\special{foo.ps 2 2 scale}" in their TeX source.
   name is declared to be a variable parameter for efficiency reasons.
   hpos and vpos define the page position of the \special command.
   It's a good idea to do all specials on a page BEFORE chars and rules so that
   users can do nifty things like overlaying TeX text onto a shaded box.
*)

PROCEDURE SaveVM (VAR fontid : ARRAY OF CHAR);
(* Output some PostScript to remember the current state of VM just before
   downloading the given bitmap font.
   The main module should only call this routine if /CONSERVE_VM is given.
   The string parameter is declared to be a variable for efficiency reasons;
   PSWriter will never change its value.
*)

PROCEDURE BeginBitmapFont (VAR fontid : ARRAY OF CHAR);
(* Output some PostScript to switch to the given bitmap font.
   The string parameter is declared to be a variable for efficiency reasons;
   PSWriter will never change its value.
*)

PROCEDURE BeginPostScriptFont (VAR fontname : ARRAY OF CHAR;
                               scaledsize, mag : INTEGER);
(* Output some PostScript to switch to the given resident PostScript font.
   The string parameter is declared to be a variable for efficiency reasons;
   PSWriter will never change its value.
   The scaledsize and mag parameters are needed to determine the requested
   font scale.
*)

PROCEDURE SetBitmapChar (ch : CHAR; hpos, vpos, pwidth : INTEGER);
(* Output some PostScript to set the given character at the given position.
   pwidth (the advance width in pixels) is used to output PostScript strings,
   minimizing the need to position single characters.
*)

PROCEDURE SetPostScriptChar (ch : CHAR; hpos, vpos, pwidth : INTEGER);
(* Output some PostScript to set the given character at the given position.
   pwidth (the advance width in pixels) is used to output PostScript strings,
   but we have to generate slightly different PostScript code to avoid
   accumulated rounding errors since the true advance width is not
   necessarily an integer number of pixels.
*)

PROCEDURE EndFont;
(* Output some PostScript to end the current font.  This routine must appear
   after the last SetBitmap/PostScriptChar call for this font.
*)

PROCEDURE RestoreVM;
(* Output some PostScript to restore VM to the state saved by the most recent
   SaveVM call.
   The main module should only call this routine if /CONSERVE_VM is given.
*)

PROCEDURE SetRule (wd, ht : CARDINAL; hpos, vpos : INTEGER);
(* Output some PostScript to set the given rule at the given position. *)

PROCEDURE EndPage (DVIpage : CARDINAL);
(* Output some PostScript to end the current page. *)

PROCEDURE CloseOutput;
(* Output any final PostScript and close the file. *)

END PSWriter.
