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.