INTERFACEDefines a type representing a Juno PostScript state, and implementations for the built-in PostScript procedures.PSImpl ;
IMPORT Drawing, PSFont, View, JunoPt, JunoRect;
IMPORT JunoScope, JunoValue;
IMPORT VBT, PaintOp, Path, Font;
IMPORT Wr;
TYPE
  T = View.PSImpl;
REVEAL
  View.PSImpl <: Public;
TYPE
  Public = View.T OBJECT
    (* PS state *)
    ps: State;
    sp := 0;
    psStack: REF ARRAY OF State
  METHODS
    init(ch: Drawing.ChildPublic; root: View.Root): T
  END;
 The ps field is the current PostScript state. PostScript states are
   pushed and popped from the stack (sp, psStack) on calls to the Juno
   procedures PS.Save and PS.Restore. 
 NEW(T).init(ch, r) creates a new T on the root r with
   child ch. 
TYPE
  Color = RECORD
    r, g, b: JunoValue.Real
  END;
  State = RECORD
    color: Color;
    width: JunoValue.Real;
    end: VBT.EndStyle;
    join: VBT.JoinStyle;
    wind: VBT.WindingCondition;
    path: Path.T;
    moveto: BOOLEAN;
    movetoPt: JunoPt.T;
    currPt, subpathStartPt: JunoPt.T;
    face: TEXT;
    size: CARDINAL;
    ptSize: JunoValue.Real;
    bbox: JunoRect.T;
    (* Trestle painting only *)
    colorOp, textColorOp: PaintOp.T;
    xFont: Font.T;
    (* PS implementation only *)
    psMetric: PSFont.Metric;
  END;
 A State record embodies a complete Juno PostScript state. The state is
   used when both painting to Trestle VBT's and when writing PostScript
   output. Except as noted, all pieces of the state must be maintained in both
   cases (the Trestle state must be maintained even when writing PostScript
   due to the procedures in the PS module for reading parts of the
   state). Also, except for the path field, all coordinates in a State
   record are in Juno coordinates.
   color contains the red, green, and blue coordinates of the current color,
   width is the pen width for strokes, end is the end style for strokes,
   join is the join style for strokes, wind is the winding condition for
   fills, and path is the current path.
   When painting to the drawing view, the current path is determined by
   path, moveto, and movetoPt. If moveto is FALSE, then the current
   path is simply path. If moveto is TRUE, then the current path is
   actually path concatenated with PS.MoveTo(movetoPt). The extra state
   allows us to mimic the PostScript semantics: if a sequence of consecutive
   MoveTo's are performed, only the last one takes effect. The movetoPt is
   incorporated into the path when we know it cannot be followed by another
   call to PS.MoveTo, namely, when processing a call to PS.LineTo,
   PS.CurveTo, or PS.Close.
   The fields currPt and subpathStartPt are defined iff the current
   (logical) path is non-empty. The field currPt stores the current
   point. It is the (last) argument to the most recent call to PS.MoveTo,
   PS.LineTo, or PS.CurveTo. We store this value instead of reading it
   from the current path because points on the path are integer valued, so
   this will guarantee for all points a that the code:
         PS.MoveTo(a);
         b := PS.CurrentPoint()
   has the effect of setting b to a. The field subpathStartPt stores the
   location of the most recent MoveTo on the curernt path; its value is
   valid iff the current path is non-empty and the current sub-path is
   open. This point is saved to implement the PS.Close operation.
   face and size are the current font face and font size. ptSize is the
   size of the current font in points. bbox is the current bounding box.
   When painting in the drawing view, colorOp is the current color for
   strokes and fills, textColorOp is the PaintOp pair that paints the
   foreground in colorOp and the background transparent, and xFont is the
   current X font.
   When painting to a PostScript file, psMetric is the
   metric of the current PostScript font. 
TYPE
  Impl <: ImplPublic;
  ImplPublic = JunoScope.Mod BRANDED "PSImpl.ImplPublic" OBJECT METHODS
    startToFile(wr: Wr.T);
    prologue() RAISES {Wr.Failure};
    epilogue(showPage := FALSE) RAISES {Wr.Failure};
    endToFile()
  END;
 A PS.Impl is a JunoScope.Mod that implements the PS module. By
   default, its procedures direct their output to a particular drawing view.
   Clients can bracket the execution of a particular bytestream by calls to
   the startToFile/prologue and epilogue/endToFile methods to instead
   cause PostScript code to be written to a specified writer.
   The call impl.startToFile(wr) arranges that all the external procedures
   installed on behalf of impl send PostScript output to wr instead of
   updating the drawing view. Clients must call the endToFile method to
   restore the original external procedures. It is a checked run-time error
   to call any of the following three methods without an initial call to
   startToFile.
   The call impl.prologue() writes the PostScript prologue to the writer
   associated with the most recent call to startToFile. The call
   impl.endToFile(showPage)  writes the PostScript epilogue (such as the
   bounding box and number of pages) to the writer associated with the most
   recent call to startToFile. If showPage is true, a PostScript
   showpage command is written to the writer before the epilogue.
   The call impl.endToFile() re-installs the original external
   procedures to direct drawing to the drawing view associated with impl.
   This method does *not* close the underlying
   writer. 
PROCEDURE Reset(d: T; inExec := TRUE);
Reset the PostScript state associated with the drawingd. TheinExecargument is used for logging purposes only, to distinguish those calls toResetwithin the scope of aJunoRT.Execexecution from those that are not.
PROCEDURE New(rt: View.Root): Impl;
 Return an implementation of the PS interface, whose procedures operate on
   the drawing view rt.currView. END PSImpl.