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
. TheinExec
argument is used for logging purposes only, to distinguish those calls toReset
within the scope of aJunoRT.Exec
execution 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.