home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-02 | 48.2 KB | 1,972 lines |
- Newsgroups: comp.sources.misc
- subject: v13i092: lj2ps (07 of 12), a LaserJet to PostScript Translator
- From: lishka@uwslh.slh.wisc.edu (Chris Lishka (relaxing in the Mad-City) )
- Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
-
- Posting-number: Volume 13, Issue 92
- Submitted-by: lishka@uwslh.slh.wisc.edu (Chris Lishka (relaxing in the Mad-City) )
- Archive-name: lj2ps/part07
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is part 07 of a multipart archive
- if touch 2>&1 | fgrep '[-amc]' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= doc/LogFile ==============
- if test X"$1" != X"-c" -a -f 'doc/LogFile'; then
- echo "File already exists: skipping 'doc/LogFile'"
- else
- echo "x - extracting doc/LogFile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/LogFile &&
- XProject: lj2ps, LaserJet PCL to PostScript translator
- XFile: LogFile
- X
- XAuthor: Christopher Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Processing Department
- X
- XRCS: $Header: LogFile,v 1.1 90/06/30 15:54:36 lishka Release $
- X
- X
- X063090 - v1.1 - Chris Lishka
- X
- XThis is the version I am releasing to the general public through
- Xcomp.sources.misc. lj2ps is identical to the 1.0.1.2 local version.
- XHowever, I have updated and cleaned up the documentation for this
- Xrelease revision. I also redrew the two scanners with idraw, as much
- Xso that I could remember how they work as for other people.
- X
- X
- X061690 - v1.0.1.2 - Chris Lishka
- X
- XThis is a local revision which fixes a very major bug as well as
- Xadding some functionality for those who want to extend this program.
- X
- XI have added support for tabs. They function identically to LaserJet
- Xtabs for fixed-spacing fonts. However, the LaserJet does some really
- Xstupid things with proportional font tabs, and I chose to use
- Xsomething completely different (and more logical) for proportional
- Xfonts. As a small step to indicate incompatibility, a warning is
- Xprinted if tabs are used while using a proportional font. My logic is
- Xthat people ought not to be using the brain-damaged LaserJet
- Xproportional tabs anyways.
- X
- XHooks are now present in the scanner for detecting shift-in and
- Xshift-out. Unique tokens are returned for both. However, shift-in
- Xand shift-out are not recognized by the "parser" (actually, the
- Xfunction transform()), so only warnings are produced now. On the
- Xother hand, if anyone wants to *add* shift-in and shift-out
- Xcapabilities (hint, hint, wink, wink, nudge, nudge ;-), they won't
- Xhave to bugger-up the scanner to achieve this (which is somewhat of a
- Xpain).
- X
- X
- X061390 - v1.0.1.1 - Chris Lishka
- X
- XThis is a new local revision, which is built off the 1.0 major
- Xrevision. It fixes a serious bug, and a few minor ones.
- X
- XThe 8.5 inch default right margin has been changed to a "very large"
- Xright margin. This fixes the right margin problem when rotating to
- Xlandscape mode.
- X
- XI have added a command-line option -w, which (when set) suppresses
- Xwarning messages.
- X
- XI have added a compile-time option -DDEBUG which controls whether or
- Xnot debugging code is included in the executable. If -DDEBUG is
- Xincluded, an extra -d command-line option is available to turn on
- Xdifferent levels of diagnostic debugging output.
- X
- XI have added a compile-time option -DVERBOSE_WARNINGS which controls
- Xwhether all types of of warnings are printed. If not set, only
- Ximportant warnings will be printed out. If set, *all* types of
- Xwarnings (both important and trivial) will be printed.
- X
- X
- X060790 - v1.0 - Chris Lishka
- X
- XThe initial revision of lj2ps. This version is currently running,
- Xalthough the one I am checking in right now has a minor efficiency fix
- X(which keeps lj_match_font from running once per attribute!). This is
- Xnot the revision which will be distributed, as that one must have a
- Xproper copyright notice attached.
- SHAR_EOF
- $TOUCH -am 0630160790 doc/LogFile &&
- chmod 0644 doc/LogFile ||
- echo "restore of doc/LogFile failed"
- set `wc -c doc/LogFile`;Wc_c=$1
- if test "$Wc_c" != "2980"; then
- echo original size 2980, current size $Wc_c
- fi
- fi
- # ============= doc/compile.options.doc ==============
- if test X"$1" != X"-c" -a -f 'doc/compile.options.doc'; then
- echo "File already exists: skipping 'doc/compile.options.doc'"
- else
- echo "x - extracting doc/compile.options.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/compile.options.doc &&
- XProject: lj2ps, 1.1 (release)
- XFile: compile.options.doc
- X
- XAuthor: Chris Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Processing Dept.
- X
- XDate: June 13th, 1990
- XLast modified: June 30th, 1990 by Chris Lishka
- X
- X
- Xlj2ps revisions after 1.0 have several compile-time options available.
- XThese options allow certain features to be compiled into the
- Xexecutable. Inclusion of the option will make the lj2ps program more
- Xfunctional; exclusion will yield a slightly faster and smaller
- Xprogram. The options should be set with the -DOPTION flag for the C
- Xcompiler, and will usually be included in a variable definition in the
- XMakefile.
- X
- XWhat follows are descriptions of the options which are currently
- Xavailable:
- X
- XDEBUG
- X
- XNormally debugging information will be left out. If DEBUG is defined,
- Xthen code to implement debugging will be conditionally compiled into
- Xthe final lj2ps executable. This extra code will allow different
- Xlevels of debugging information to be printed out when the -d#
- Xcommand-line option is include, where # is the debugging level.
- XCurrently, the following levels are offered:
- X
- X 0 No debugging info. This is the default.
- X 1 Tokens are printed out. Rather verbose.
- X 2 Tokens and input characters are both printed
- X out. Super-duper verbose.
- X
- XVERBOSE_WARNINGS
- X
- XThere are several warning messages that will occur frequently during
- Xnormal lj2ps usage. For example, since there is only one symbol set,
- Xlj2ps does not recognize any symbol sets in the PCL change-symbol-set
- Xcommand. This leads to many warnings. If VERBOSE_WARNINGS is set,
- Xthen all warning messages will be printed. Otherwise, the common (but
- Xunimportant) warnings will be supressed.
- X
- X
- SHAR_EOF
- $TOUCH -am 0630160890 doc/compile.options.doc &&
- chmod 0664 doc/compile.options.doc ||
- echo "restore of doc/compile.options.doc failed"
- set `wc -c doc/compile.options.doc`;Wc_c=$1
- if test "$Wc_c" != "1683"; then
- echo original size 1683, current size $Wc_c
- fi
- fi
- # ============= doc/limitations.doc ==============
- if test X"$1" != X"-c" -a -f 'doc/limitations.doc'; then
- echo "File already exists: skipping 'doc/limitations.doc'"
- else
- echo "x - extracting doc/limitations.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/limitations.doc &&
- XProgram: lj2ps, 1.1 (release)
- XFile: limitations.doc
- X
- XAuthor: Christopher Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Processing Department
- X
- XDate: April 25th, 1990
- XLast modified: June 30th, 1990 by Chris Lishka
- X
- X
- XThis file contains known limitations of the lj2ps program. The
- Xlimitations come in two basic varieties: (a) those that exist because
- Xof inherent differences between the LaserJet and LaserWriter; and (b)
- Xthose that exist because I do not have enough time to fix them. All
- Xlimitations listed should be assumed to belong in the second category
- Xunless otherwise noted.
- X
- X* As has been mentioned many times in the documentation, I did not
- X have time to implement all LaserJet commands in PCL 4 (let alone PCL
- X 5). Instead, I leave this as an exercise for the reader ;-) I have
- X implemented what was needed by my organization, and represents a
- X subset of PCL 4 which supports (fairly completely) page motion, page
- X setup, and internal and cartridge fonts. Commands which were left
- X out include:
- X
- X ** Macros
- X
- X ** Position stack
- X
- X ** Graphics -- patterns and grayshades
- X
- X ** Graphics -- bitmaps
- X
- X ** Secondary font support
- X
- X ** Downloadable fonts
- X
- X
- X* Although I put a fair amount of work into the Test Suite and Metrics
- X Suite, they are by no means complete. They do test a fair amount of
- X LaserJet quirks, and proved to be very helpful in fine tuning lj2ps.
- X Feel free to add more tests to either suite.
- X
- X* Tabs do not work exactly like the LaserJet when using proportional
- X fonts. This is because a given tab position depends on the current
- X location of the cursor, which might be different from the LaserJet
- X and LaserWriter. Therefore, when a proportional font is used, tabs
- X might end up in the wrong places. However, tabs are not a good
- X thing to use with a proportional font anyway. Note that tabs used
- X with fixed-width fonts should behave exactly the same way.
- X
- X* Another problem related to tabs is the mechanism I have used. On
- X the LaserJet, tabs are counted out using characters printed. To
- X move to the next tab stop, the LaserJet will simply insert enough
- X space characters to reach a position which is a multiple of eight
- X characters. With proportional fonts, this results in tab stops not
- X being in fixed columns, but rather dependent on the width of the
- X characters printed before the tab. (I think this method is
- X downright foolish, because it renders the purpose of tabs useless
- X with proportional fonts). I have chosen to calculate tabs as being
- X in columns, with the distance between columns being eight space
- X characters in the current font. This allows tabs to be used to line
- X up text at each tab stop with proportional fonts. Note that
- X although the two schemes give different results with proportional
- X fonts, the behaviors match exactly when using fixed-width fonts.
- X
- X* The HMI command cannot be fully implemented. This is an inherent
- X problem with the lj2ps program. The HMI command on the LaserJet
- X works in one of two ways:
- X
- X (a) If the font is non-proportional, then the HMI command
- X adjusts the individual width of each character;
- X
- X (b) If the font is proportional, then the HMI command only
- X adjusts the width of the *space* character.
- X
- X Unfortunately, lj2ps uses a crude font mapping mechanism for
- X emulating LaserJet fonts in PostScript. One of the inherent
- X limitations is the inability to adjust the individual width of each
- X character in the PostScript font. It is for this reason that the
- X HMI command cannot be fully implemented. Unfortunately, there is no
- X good way to fix this without overhauling the font mapping mechanism.
- X
- X The HMI command *does* change lj2ps' notion of the current character
- X spacing (in the variable char_width). This is useful for doing
- X horizontal tabs using columns. This is why the HMI command has been
- X implemented at all.
- X
- X* The postscript file produced by lj2ps is definitely not suitable as
- X encapsulated postscript. One important example is that the
- X "initclip" command must be used when resetting the right margin to
- X insure that the clip-path can "grow" if the right margin gets
- X bigger.
- X
- X* To effectively emulate LaserJet relative horizontal motion commands
- X with the current font mechanism, I had to move horizontal motion
- X into the generated PostScript program. Therefore, although
- X horizontal motion is tracked in lj2ps, it is only updated every time
- X an absolute horizontal motion is performed (including non-command
- X motions such as newline). This makes the horizontal cursor position
- X in the lj2ps program innaccurate much of the time. The only fix I
- X can think of is to replace the font emulation mechanism with
- X something better. Note that vertical motion is tracked completely
- X in lj2ps, and is of little importance in the generated PostScript
- X code.
- X
- X
- SHAR_EOF
- $TOUCH -am 0630160890 doc/limitations.doc &&
- chmod 0664 doc/limitations.doc ||
- echo "restore of doc/limitations.doc failed"
- set `wc -c doc/limitations.doc`;Wc_c=$1
- if test "$Wc_c" != "4873"; then
- echo original size 4873, current size $Wc_c
- fi
- fi
- # ============= doc/lj2ps.l ==============
- if test X"$1" != X"-c" -a -f 'doc/lj2ps.l'; then
- echo "File already exists: skipping 'doc/lj2ps.l'"
- else
- echo "x - extracting doc/lj2ps.l (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/lj2ps.l &&
- X.\" Program: lj2ps, LaserJet PCL to PostScript Translator
- X.\" File: lj2ps.l (man page documentation)
- X.\"
- X.\" Author: Chris Lishka
- X.\" Organization: Wisconsin State Laboratory of Hygiene
- X.\" Data Processing Section
- X.\"
- X.TH LJLPR l "June 30th, 1990 (Revision 1.1)"
- X.SH NAME
- X\fBlj2ps\fR \- print \fILaserJet\fR files on a \fIPostScript\fR printer
- X.SH SYNOPSIS
- X\fBljlpr [ \fIoptions\fB ] [ \fIfiles\fB ] \fR
- X.SH DESCRIPTION
- X.PP
- X\fBlj2ps\fR is a translator that reads in a file of text and
- X\fILaserJet PCL\fR commands and converts it to \fIPostScript.\fR
- X\fBlj2ps\fR can currently translate a subset of \fIPCL 4.\fR It will
- Xproperly convert page motion, page setup, and primary font commands.
- XLeft out are macros, position stack commands, secondary font support,
- Xgraphics (both bitmap and pattern/grayscale), and downloadable fonts.
- X.PP
- X\fBlj2ps\fR is set up to mimic a \fILaserJet Series II\fR with the
- X\fIHewlett Packard F\fR and \fIG\fR font cartridges plugged into the
- Xleft and right ports, respectively. Command-line options are provided
- Xthat duplicate the functions in the main menu, accessible from the
- Xfront panel.
- X.PP
- XIf \fIfiles\fR are listed on the command line, then \fBlj2ps\fR will
- Xread each consecutively as if they were all one file. If no files are
- Xlisted, then input will be read from the \fIstandard input.\fR All
- Xoutput is written to the \fIstandard output,\fR and errors to the
- X\fIstandard error.\fR
- X.SH OPTIONS
- X.PP
- X.IP "\fBLaserJet II Main Menu Options\fR" 2
- X.IP "\fB-c##\fR" 5
- XSets the numbers of copies to \fB##\fR. The default is one copy.
- X.IP "\fB-mf\fR" 5
- XSpecifies that paper is to be fed in manually. The default is to
- Xautomatically feed paper in from the tray.
- X.IP "\fB-fs?\fR" 5
- XChange the default font source to \fB?\fR, where \fB?\fR is \fBL\fR
- X(left cartridge), \fBR\fR (right cartridge), \fBI\fR (internal), or
- X\fBS\fR (soft font). The default is \fBI\fR (internal).
- X.IP "\fB-fn##\fR" 5
- XUse font number \fB##\fR from the default font source. The default is
- Xfont number zero.
- X.IP "\fB-fl##\fR" 5
- XSet the form length to \fB##\fR lines. The default is 60 lines.
- X.IP "\fBPage Orientation\fR" 2
- X.IP "\fB-p\fR" 5
- XPrint in portrait mode. This is the default.
- X.IP "\fB-l\fR" 5
- XPrint in landscape mode.
- X.IP "\fBPage Scaling and Offsets\fR" 2
- X.IP "\fB-xs##\fR" 5
- XScale the width of the page by \fB##\fR. The default is 1.0 (no
- Xscaling).
- X.IP "\fB-ys##\fR" 5
- XScale the length of the page by \fB##\fR. The default is 1.0 (no
- Xscaling).
- X.IP "\fB-xo##\fR" 5
- XOffset the left margin by \fB##\fR inches. The default is 0.0 inches.
- X.IP "\fB-yo##\fR" 5
- XOffest the top margin by \fB##\fR inches. The default is 0.0 inches.
- X.IP "\fBMiscellaneous\fR" 2
- X.IP "\fB-X\fR" 5
- XPrint a list of all options recognized.
- X.IP "\fB-w\fR" 5
- XDo not print warning messages.
- X.SH "SEE ALSO"
- XPlease refer to your local printing software to determine how to send
- Xthe \fIPostScript\fR output of \fBlj2ps\fR to your printer.
- X.SH RESTRICTIONS
- XOnly a subset of \fIPCL 4\fR is currently recognized.
- X.SH DIAGNOSTICS
- X.PP
- X\fBljlpr\fR will return with exit code 0 if no errors are
- Xencountered or exit code 1 if a fatal error occurs.
- X.PP
- XFour types of messages are printed:
- X.PP
- X\fBWarnings\fR are printed to inform the user of possible problems
- Xwith the output. Although warnings are never serious, they do
- Xindicate possible problems with the LaserJet commands, or features
- Xbeing used that are not actually implemented in \fBlj2ps\fR. Warnings
- Xcan be turned off with the \fB-w\fR option.
- X.PP
- X\fBErrors\fR indicate recoverable problems in the input or output that
- Xshould be corrected. The program will continue running if an error is
- Xencountered, although the output will likely be missing some features.
- X.PP
- X\fBFatal Errors\fR are non-recoverable errors, and will cause the
- Xprogram to immediately terminate with a non-zero exit code. Fatal
- Xerrors must be corrected before \fBlj2ps\fR will accept the entire
- Xinput file.
- X.PP
- X\fBInternal Errors\fR indicate that an internal consistency check has
- Xfailed, and will cause immediate termination of execution. Please
- Xcontact the person maintaining \fBlj2ps\fR and describe the internal
- Xerror, so that she or he may fix it.
- X.SH BUGS
- X.PP
- XTabs do not work properly with proportional fonts. However, the
- X\fILaserJet\fR's scheme for handling tabs with proportional fonts is
- Xbadly botched, so you shouldn't be using proportional fonts anyway.
- X.PP
- XThe behavior of the HMI command is different from the \fILaserJet\fR.
- X.PP
- XThe \fIPostScript\fR file produced by \fBlj2ps\fR is not suitable as
- X\fIEncapsulated PostScript,\fR because initclip is used to reset the
- Xright margin.
- X
- X
- SHAR_EOF
- $TOUCH -am 0630160890 doc/lj2ps.l &&
- chmod 0664 doc/lj2ps.l ||
- echo "restore of doc/lj2ps.l failed"
- set `wc -c doc/lj2ps.l`;Wc_c=$1
- if test "$Wc_c" != "4619"; then
- echo original size 4619, current size $Wc_c
- fi
- fi
- # ============= doc/measurements.doc ==============
- if test X"$1" != X"-c" -a -f 'doc/measurements.doc'; then
- echo "File already exists: skipping 'doc/measurements.doc'"
- else
- echo "x - extracting doc/measurements.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/measurements.doc &&
- XProject: lj2ps, 1.1 (release)
- XFile: measurements.doc
- X
- XAuthor: Christopher Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Processing Dept.
- X
- XDate: June 30th, 1990
- X
- X
- XMeasurement Name Units per Inch Inches per Unit Comments
- X=============== ======= =============== =============== =======================
- X
- XInch in 1 1 The default unit; fixed
- X
- XPage Height ph Default=0.0909 Default=11 Depends on page size
- X
- XPage Width pw Default=0.1176 Default=8.5 Depends on page size
- X
- XDots dt 300 0.0033 Fixed
- X
- XDecipoints dp 720 0.0031 Fixed
- X
- XLines/Inch li Default=6 Default=0.1667 Can be reset by user
- X
- XColumns/Inch ci Depends on current font
- SHAR_EOF
- $TOUCH -am 0630160890 doc/measurements.doc &&
- chmod 0664 doc/measurements.doc ||
- echo "restore of doc/measurements.doc failed"
- set `wc -c doc/measurements.doc`;Wc_c=$1
- if test "$Wc_c" != "657"; then
- echo original size 657, current size $Wc_c
- fi
- fi
- # ============= doc/parameter.scanner.idraw ==============
- if test X"$1" != X"-c" -a -f 'doc/parameter.scanner.idraw'; then
- echo "File already exists: skipping 'doc/parameter.scanner.idraw'"
- else
- echo "x - extracting doc/parameter.scanner.idraw (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/parameter.scanner.idraw &&
- X%!PS-Adobe-2.0 EPSF-1.2
- X%%DocumentFonts: Courier
- X%%Pages: 1
- X%%BoundingBox: 101 41 511 775
- X%%EndComments
- X
- X50 dict begin
- X
- X/arrowHeight 8 def
- X/arrowWidth 4 def
- X/none null def
- X/numGraphicParameters 17 def
- X/stringLimit 65535 def
- X
- X/Begin {
- Xsave
- XnumGraphicParameters dict begin
- X} def
- X
- X/End {
- Xend
- Xrestore
- X} def
- X
- X/SetB {
- Xdup type /nulltype eq {
- Xpop
- Xfalse /brushRightArrow idef
- Xfalse /brushLeftArrow idef
- Xtrue /brushNone idef
- X} {
- X/brushDashOffset idef
- X/brushDashArray idef
- X0 ne /brushRightArrow idef
- X0 ne /brushLeftArrow idef
- X/brushWidth idef
- Xfalse /brushNone idef
- X} ifelse
- X} def
- X
- X/SetCFg {
- X/fgblue idef
- X/fggreen idef
- X/fgred idef
- X} def
- X
- X/SetCBg {
- X/bgblue idef
- X/bggreen idef
- X/bgred idef
- X} def
- X
- X/SetF {
- X/printSize idef
- X/printFont idef
- X} def
- X
- X/SetP {
- Xdup type /nulltype eq {
- Xpop true /patternNone idef
- X} {
- X/patternGrayLevel idef
- XpatternGrayLevel -1 eq {
- X/patternString idef
- X} if
- Xfalse /patternNone idef
- X} ifelse
- X} def
- X
- X/BSpl {
- X0 begin
- Xstorexyn
- Xnewpath
- Xn 1 gt {
- X0 0 0 0 0 0 1 1 true subspline
- Xn 2 gt {
- X0 0 0 0 1 1 2 2 false subspline
- X1 1 n 3 sub {
- X/i exch def
- Xi 1 sub dup i dup i 1 add dup i 2 add dup false subspline
- X} for
- Xn 3 sub dup n 2 sub dup n 1 sub dup 2 copy false subspline
- X} if
- Xn 2 sub dup n 1 sub dup 2 copy 2 copy false subspline
- XpatternNone not brushLeftArrow not brushRightArrow not and and { ifill } if
- XbrushNone not { istroke } if
- X0 0 1 1 leftarrow
- Xn 2 sub dup n 1 sub dup rightarrow
- X} if
- Xend
- X} dup 0 4 dict put def
- X
- X/Circ {
- Xnewpath
- X0 360 arc
- XpatternNone not { ifill } if
- XbrushNone not { istroke } if
- X} def
- X
- X/CBSpl {
- X0 begin
- Xdup 2 gt {
- Xstorexyn
- Xnewpath
- Xn 1 sub dup 0 0 1 1 2 2 true subspline
- X1 1 n 3 sub {
- X/i exch def
- Xi 1 sub dup i dup i 1 add dup i 2 add dup false subspline
- X} for
- Xn 3 sub dup n 2 sub dup n 1 sub dup 0 0 false subspline
- Xn 2 sub dup n 1 sub dup 0 0 1 1 false subspline
- XpatternNone not { ifill } if
- XbrushNone not { istroke } if
- X} {
- XPoly
- X} ifelse
- Xend
- X} dup 0 4 dict put def
- X
- X/Elli {
- X0 begin
- Xnewpath
- X4 2 roll
- Xtranslate
- Xscale
- X0 0 1 0 360 arc
- XpatternNone not { ifill } if
- XbrushNone not { istroke } if
- Xend
- X} dup 0 1 dict put def
- X
- X/Line {
- X0 begin
- X2 storexyn
- Xnewpath
- Xx 0 get y 0 get moveto
- Xx 1 get y 1 get lineto
- XbrushNone not { istroke } if
- X0 0 1 1 leftarrow
- X0 0 1 1 rightarrow
- Xend
- X} dup 0 4 dict put def
- X
- X/MLine {
- X0 begin
- Xstorexyn
- Xnewpath
- Xn 1 gt {
- Xx 0 get y 0 get moveto
- X1 1 n 1 sub {
- X/i exch def
- Xx i get y i get lineto
- X} for
- XpatternNone not brushLeftArrow not brushRightArrow not and and { ifill } if
- XbrushNone not { istroke } if
- X0 0 1 1 leftarrow
- Xn 2 sub dup n 1 sub dup rightarrow
- X} if
- Xend
- X} dup 0 4 dict put def
- X
- X/Poly {
- X3 1 roll
- Xnewpath
- Xmoveto
- X-1 add
- X{ lineto } repeat
- Xclosepath
- XpatternNone not { ifill } if
- XbrushNone not { istroke } if
- X} def
- X
- X/Rect {
- X0 begin
- X/t exch def
- X/r exch def
- X/b exch def
- X/l exch def
- Xnewpath
- Xl b moveto
- Xl t lineto
- Xr t lineto
- Xr b lineto
- Xclosepath
- XpatternNone not { ifill } if
- XbrushNone not { istroke } if
- Xend
- X} dup 0 4 dict put def
- X
- X/Text {
- Xishow
- X} def
- X
- X/idef {
- Xdup where { pop pop pop } { exch def } ifelse
- X} def
- X
- X/ifill {
- X0 begin
- Xgsave
- XpatternGrayLevel -1 ne {
- Xfgred bgred fgred sub patternGrayLevel mul add
- Xfggreen bggreen fggreen sub patternGrayLevel mul add
- Xfgblue bgblue fgblue sub patternGrayLevel mul add setrgbcolor
- Xeofill
- X} {
- Xeoclip
- XoriginalCTM setmatrix
- Xpathbbox /t exch def /r exch def /b exch def /l exch def
- X/w r l sub ceiling cvi def
- X/h t b sub ceiling cvi def
- X/imageByteWidth w 8 div ceiling cvi def
- X/imageHeight h def
- Xbgred bggreen bgblue setrgbcolor
- Xeofill
- Xfgred fggreen fgblue setrgbcolor
- Xw 0 gt h 0 gt and {
- Xl b translate w h scale
- Xw h true [w 0 0 h neg 0 h] { patternproc } imagemask
- X} if
- X} ifelse
- Xgrestore
- Xend
- X} dup 0 8 dict put def
- X
- X/istroke {
- Xgsave
- XbrushDashOffset -1 eq {
- X[] 0 setdash
- X1 setgray
- X} {
- XbrushDashArray brushDashOffset setdash
- Xfgred fggreen fgblue setrgbcolor
- X} ifelse
- XbrushWidth setlinewidth
- XoriginalCTM setmatrix
- Xstroke
- Xgrestore
- X} def
- X
- X/ishow {
- X0 begin
- Xgsave
- XprintFont findfont printSize scalefont setfont
- Xfgred fggreen fgblue setrgbcolor
- X/vertoffset printSize neg def {
- X0 vertoffset moveto show
- X/vertoffset vertoffset printSize sub def
- X} forall
- Xgrestore
- Xend
- X} dup 0 3 dict put def
- X
- X/patternproc {
- X0 begin
- X/patternByteLength patternString length def
- X/patternHeight patternByteLength 8 mul sqrt cvi def
- X/patternWidth patternHeight def
- X/patternByteWidth patternWidth 8 idiv def
- X/imageByteMaxLength imageByteWidth imageHeight mul
- XstringLimit patternByteWidth sub min def
- X/imageMaxHeight imageByteMaxLength imageByteWidth idiv patternHeight idiv
- XpatternHeight mul patternHeight max def
- X/imageHeight imageHeight imageMaxHeight sub store
- X/imageString imageByteWidth imageMaxHeight mul patternByteWidth add string def
- X0 1 imageMaxHeight 1 sub {
- X/y exch def
- X/patternRow y patternByteWidth mul patternByteLength mod def
- X/patternRowString patternString patternRow patternByteWidth getinterval def
- X/imageRow y imageByteWidth mul def
- X0 patternByteWidth imageByteWidth 1 sub {
- X/x exch def
- XimageString imageRow x add patternRowString putinterval
- X} for
- X} for
- XimageString
- Xend
- X} dup 0 12 dict put def
- X
- X/min {
- Xdup 3 2 roll dup 4 3 roll lt { exch } if pop
- X} def
- X
- X/max {
- Xdup 3 2 roll dup 4 3 roll gt { exch } if pop
- X} def
- X
- X/arrowhead {
- X0 begin
- Xtransform originalCTM itransform
- X/taily exch def
- X/tailx exch def
- Xtransform originalCTM itransform
- X/tipy exch def
- X/tipx exch def
- X/dy tipy taily sub def
- X/dx tipx tailx sub def
- X/angle dx 0 ne dy 0 ne or { dy dx atan } { 90 } ifelse def
- Xgsave
- XoriginalCTM setmatrix
- Xtipx tipy translate
- Xangle rotate
- Xnewpath
- X0 0 moveto
- XarrowHeight neg arrowWidth 2 div lineto
- XarrowHeight neg arrowWidth 2 div neg lineto
- Xclosepath
- XpatternNone not {
- XoriginalCTM setmatrix
- X/padtip arrowHeight 2 exp 0.25 arrowWidth 2 exp mul add sqrt brushWidth mul
- XarrowWidth div def
- X/padtail brushWidth 2 div def
- Xtipx tipy translate
- Xangle rotate
- Xpadtip 0 translate
- XarrowHeight padtip add padtail add arrowHeight div dup scale
- Xarrowheadpath
- Xifill
- X} if
- XbrushNone not {
- XoriginalCTM setmatrix
- Xtipx tipy translate
- Xangle rotate
- Xarrowheadpath
- Xistroke
- X} if
- Xgrestore
- Xend
- X} dup 0 9 dict put def
- X
- X/arrowheadpath {
- Xnewpath
- X0 0 moveto
- XarrowHeight neg arrowWidth 2 div lineto
- XarrowHeight neg arrowWidth 2 div neg lineto
- Xclosepath
- X} def
- X
- X/leftarrow {
- X0 begin
- Xy exch get /taily exch def
- Xx exch get /tailx exch def
- Xy exch get /tipy exch def
- Xx exch get /tipx exch def
- XbrushLeftArrow { tipx tipy tailx taily arrowhead } if
- Xend
- X} dup 0 4 dict put def
- X
- X/rightarrow {
- X0 begin
- Xy exch get /tipy exch def
- Xx exch get /tipx exch def
- Xy exch get /taily exch def
- Xx exch get /tailx exch def
- XbrushRightArrow { tipx tipy tailx taily arrowhead } if
- Xend
- X} dup 0 4 dict put def
- X
- X/midpoint {
- X0 begin
- X/y1 exch def
- X/x1 exch def
- X/y0 exch def
- X/x0 exch def
- Xx0 x1 add 2 div
- Xy0 y1 add 2 div
- Xend
- X} dup 0 4 dict put def
- X
- X/thirdpoint {
- X0 begin
- X/y1 exch def
- X/x1 exch def
- X/y0 exch def
- X/x0 exch def
- Xx0 2 mul x1 add 3 div
- Xy0 2 mul y1 add 3 div
- Xend
- X} dup 0 4 dict put def
- X
- X/subspline {
- X0 begin
- X/movetoNeeded exch def
- Xy exch get /y3 exch def
- Xx exch get /x3 exch def
- Xy exch get /y2 exch def
- Xx exch get /x2 exch def
- Xy exch get /y1 exch def
- Xx exch get /x1 exch def
- Xy exch get /y0 exch def
- Xx exch get /x0 exch def
- Xx1 y1 x2 y2 thirdpoint
- X/p1y exch def
- X/p1x exch def
- Xx2 y2 x1 y1 thirdpoint
- X/p2y exch def
- X/p2x exch def
- Xx1 y1 x0 y0 thirdpoint
- Xp1x p1y midpoint
- X/p0y exch def
- X/p0x exch def
- Xx2 y2 x3 y3 thirdpoint
- Xp2x p2y midpoint
- X/p3y exch def
- X/p3x exch def
- XmovetoNeeded { p0x p0y moveto } if
- Xp1x p1y p2x p2y p3x p3y curveto
- Xend
- X} dup 0 17 dict put def
- X
- X/storexyn {
- X/n exch def
- X/y n array def
- X/x n array def
- Xn 1 sub -1 0 {
- X/i exch def
- Xy i 3 2 roll put
- Xx i 3 2 roll put
- X} for
- X} def
- X
- X%%EndProlog
- X
- X%I Idraw 5 Grid 8
- X
- X%%Page: 1 1
- X
- XBegin
- X%I b u
- X%I cfg u
- X%I cbg u
- X%I f u
- X%I p u
- X%I t
- X[ 0.96 0 0 0.96 0 0 ] concat
- X/originalCTM matrix currentmatrix def
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 2.88889 0 0 2.88889 127.5 804.556 ] concat
- X%I
- X[
- X(Parameter Scanner for lj2ps)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 133 142 ] concat
- X%I
- X[
- X(* All end states include a description of the token recognized)
- X()
- X(* All states include the three letter code that is used in the C-code \(where)
- X( it is preceded by the prefix SP_\).)
- X()
- X(* All transitions are marked with the characters that cause the transition.)
- X()
- X(* The action for all transitions is to store the character in a buffer.)
- X()
- X(* The action for end states UNK, PE, and PC is to accept the last character.)
- X( The action for the end state PE0 is to put the character back into the)
- X( input stream.)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 241 775 ] concat
- X%I
- X[
- X(lj2ps, version 1.1 \(release\))
- X] Text
- XEnd
- X
- XBegin %I Pict
- X%I b u
- X%I cfg u
- X%I cbg u
- X%I f u
- X%I p u
- X%I t
- X[ 0.804699 0 0 0.804699 60.6917 140.023 ] concat
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 1 0 0 1 416 287 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 513 718 ] concat
- X%I
- X[
- X(End)
- X(Parameter)
- X(\(Zero Numeric\))
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 502 680 ] concat
- X%I
- X[
- X(PE0)
- X] Text
- XEnd
- X
- XEnd %I eop
- X
- XBegin %I Pict
- X%I b u
- X%I cfg u
- X%I cbg u
- X%I f u
- X%I p u
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 1 0 0 1 414 78 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 510 500 ] concat
- X%I
- X[
- X(Unknown)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 500 470 ] concat
- X%I
- X[
- X(UNK)
- X] Text
- XEnd
- X
- XEnd %I eop
- X
- XBegin %I Pict
- X%I b u
- X%I cfg u
- X%I cbg u
- X%I f u
- X%I p u
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 1 0 0 1 419 -135 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 515 290 ] concat
- X%I
- X[
- X(End)
- X(Parameter)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 508 257 ] concat
- X%I
- X[
- X(PE)
- X] Text
- XEnd
- X
- XEnd %I eop
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 398.056 -22.7305 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 475.307 318.462 ] concat
- X%I
- X[
- X(Continue)
- X(Parameter)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 468.869 291.907 ] concat
- X%I
- X[
- X(PC)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 258.233 265.547 ] concat
- X%I
- X[
- X(PINT)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 207.342 387.666 ] concat
- X%I
- X[
- X(FLP)
- X] Text
- XEnd
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Gray80
- X0.2 0.2 0.2 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 93.8796 208.023 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 109.388 521.465 ] concat
- X%I
- X[
- X(PRM)
- X] Text
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X133 419 450 295 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X132 410 455 150 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X218 129 218 210 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X102 384 197 119 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X251 244 450 276 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X245 113 459 258 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X250 97 448 129 Line
- XEnd
- X
- XBegin %I BSpl
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I 6
- X212 275
- X199 308
- X175 316
- X162 305
- X168 278
- X194 263
- X6 BSpl
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X234 273 451 475 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X235 124 460 466 Line
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 61.6917 209.023 ] concat
- X%I
- X249 231 450 140 Line
- XEnd
- X
- XBegin %I BSpl
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.534872 0.601209 -0.601209 0.534872 266.082 24.2328 ] concat
- X%I 6
- X212 275
- X199 308
- X175 316
- X162 305
- X168 278
- X194 263
- X6 BSpl
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 109.169 472.964 ] concat
- X%I
- X[
- X(+ | - | 0-9)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 177.568 295.126 ] concat
- X%I
- X[
- X(0-9)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 189.639 298.344 ] concat
- X%I
- X[
- X()
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 202.514 452.042 ] concat
- X%I
- X[
- X(0-9)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 240.335 368.353 ] concat
- X%I
- X[
- X(P)
- X(e)
- X(r)
- X(i)
- X(o)
- X(d)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 243.554 446.409 ] concat
- X%I
- X[
- X(Other)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 292.64 289.493 ] concat
- X%I
- X[
- X(Lowercase)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 158.888 584.888 ] concat
- X%I
- X[
- X(Other)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 269.304 420.659 ] concat
- X%I
- X[
- X(Uppercase)
- X( or)
- X( Symbol)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 261.257 393.299 ] concat
- X%I
- X[
- X(Lowercase)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 252.405 333.751 ] concat
- X%I
- X[
- X(Other)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 289.421 338.579 ] concat
- X%I
- X[
- X(Uppercase)
- X( or)
- X( Symbol)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 171.935 505.957 ] concat
- X%I
- X[
- X(Lowercase)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 0.804699 0 0 0.804699 195.272 556.653 ] concat
- X%I
- X[
- X(Uppercase)
- X( or)
- X( Symbol)
- X] Text
- XEnd
- X
- XBegin %I Line
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 1 0 0 1 -6 51 ] concat
- X%I
- X169 513 429 643 Line
- XEnd
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Gray80
- X0.2 0.2 0.2 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 188.88 70.0228 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Gray80
- X0.2 0.2 0.2 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.804699 0 0 0.804699 188.88 -47.9772 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Gray80
- X0.2 0.2 0.2 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.576954 0 0 0.576954 168.772 -31.7798 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Elli
- X%I b 65535
- X1 0 1 [] 0 SetB
- X%I cfg Black
- X0 0 0 SetCFg
- X%I cbg White
- X1 1 1 SetCBg
- X%I p
- X0 SetP
- X%I t
- X[ 0.576954 0 0 0.576954 369.948 -33.5331 ] concat
- X%I
- X61 418 31 33 Elli
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 226 213 ] concat
- X%I
- X[
- X(= Intermediate State)
- X] Text
- XEnd
- X
- XBegin %I Text
- X%I cfg Black
- X0 0 0 SetCFg
- X%I f *-courier-medium-r-*-80-*
- X/Courier 8 SetF
- X%I t
- X[ 1 0 0 1 426 212 ] concat
- X%I
- X[
- X(= End State)
- X] Text
- XEnd
- X
- XEnd %I eop
- X
- Xshowpage
- X
- X%%Trailer
- X
- Xend
- SHAR_EOF
- $TOUCH -am 0630160890 doc/parameter.scanner.idraw &&
- chmod 0644 doc/parameter.scanner.idraw ||
- echo "restore of doc/parameter.scanner.idraw failed"
- set `wc -c doc/parameter.scanner.idraw`;Wc_c=$1
- if test "$Wc_c" != "17644"; then
- echo original size 17644, current size $Wc_c
- fi
- fi
- # ============= doc/scanner.doc ==============
- if test X"$1" != X"-c" -a -f 'doc/scanner.doc'; then
- echo "File already exists: skipping 'doc/scanner.doc'"
- else
- echo "x - extracting doc/scanner.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/scanner.doc &&
- XProgram: lj2ps, 1.1 (release)
- XFile: scanner.doc
- X
- XAuthor: Christopher Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Deprocessing Dept.
- X
- XDate: March, 1990
- X
- X
- X1. Introduction
- X
- XIn creating a LaserJet-to-Postscript converter, it is necessary to
- Xdevelop a scanner for properly distinguishing between text and
- XLaserJet commands. This document details the scanner I created, which
- Xwas a major section of the lj2ps program.
- X
- XAt first I used lex to generate a scanner module, which I tied into my
- Xprogram with the interface in scan.h. Although lex was likely not the
- Xmost efficient choice (due to the overwhelming features it offers), it
- Xdid allow me to modify my scanner as needed as more and more bugs were
- Xdiscovered in my original design.
- X
- XHowever, the use of lex proved to be a rocky road ending in a wide
- Xravine. Besides struggling with the state feature of lex, I
- Xencountered many small problems that are common when lex is used. The
- Xfinal straw was when I discovered that lex could not handle null
- Xcharacters in the input stream. If the scanner was to be useful and
- Xextendable, null characters *had* to be handled, for their use in
- Xbitmaps graphics was very common. This implied that the lex scanner I
- Xhad built had to be tossed out. The development effort of the lex
- Xscanner was not wasted though. It did provide a suitable platform for
- Xrevising my initial scanner design.
- X
- X
- X2. The Table-Driven Finite State Automata
- X
- XIn place of the inadequate lex scanner, I decided to create a
- Xhand-coded, state-driven FSA. This would provide a fast and efficient
- Xscanner that could overcome the defficiencies of the lex system.
- XHowever, it would also take more time to develop the FSA and translate
- Xit into tables.
- X
- XCertain characteristics of the LaserJet PCL scanner lent themselves
- Xwell to improved efficiency and compact design. One important
- Xcharacteristic was that no *actions* were required on the transitions
- Xfrom state to state. Instead, a single default action of copying the
- Xcurrent character to a token buffer was all that was needed. This
- Xallowed for the complete elimination of the action table. Another
- Xmajor aspect was the relatively small number of character classes.
- XThis allowed for a simple character class table translation mechanism.
- X
- X
- X3. Implementation Details
- X
- XWhat follows is the important details of my implementation.
- X
- X* There are actually *two* scanners. Although this may seem somewhat
- X "kludgy", it actually saves development time (which was a factor)
- X because a true parser does not need to be written. Instead, which
- X scanner is being used is recorded in a global variable, and it is
- X this one that is activated when scan() is run.
- X
- X The reason that two separate scanners can be used lies in the
- X LaserJet PCL language, which consists of text with embedded
- X commands. One scanner is responsible for scanning normal text, and
- X is able to differentiate command prefixes (which always start with
- X an escape character) from the surrounding text. The other scanner
- X is responsible for breaking up command parameters into useful
- X tokens.
- X
- X Each scanner has separate state and character class tables, as well
- X as the necessary state constants that go with them. The text
- X scanner's tables and constants all start with "st_" or "ST_",
- X whereas the parameter scanner uses "sp_" and "SP_".
- X
- X One problem that may crop up in the future is commands that require
- X trailing data. Currently these commands are not implemented. I
- X have not put provisions in for reading variable length data after a
- X PCL command. However, it would be fairly trivial to add another
- X function to the scanner module (say, scan_data(length)) that would
- X read in a fixed number of characters (which would be interpreted as
- X 8-bit bytes).
- X
- X* I have defined mnemonic constants for the various states. These
- X have to be in numeric order (starting with zero) and must correspond
- X directly to the states indexes in the state tables. If this were a
- X perfect world, C would have better enumeration facilities (believe
- X me-I looked into this) and would allow enumerations as indexes into
- X arrays. Since we must live with the flaws, this is what I have come
- X up with.
- X
- X Also note that there are two "special" state types: those marked
- X START and END. START should always be state 1, whereas END should
- X always be state 0. These two constants are used to label the start
- X and end states in both scanners, so they must remain the same for
- X both. I know that fixing the start and end states to predefined
- X numbers was a kludge, but it was a fairly easy (and, hopefully,
- X minor) solution.
- X
- X* My scanner differs slightly from the "traditional" model. In mine,
- X the *only* way to end the scanning of a token is to jump to the
- X *single* END state. "Blasphemy!" some may cry out, but actually
- X this works quite well. Once the END state is reached, the scanner
- X is finished. You can find out what token was scanned by maintaining
- X a notion of what the previous state was and referring back to it
- X when END is reached. Hence the use of the variable prev_state in
- X the function scan().
- X
- X Related to the single END state is the demise of "actions."
- X Although no actions on transitions are required, without a single
- X END state one would need to keep a record of (a) which states are
- X end states and (b) whether a put-back or accept of the last read
- X character should be performed on reaching an end state. (I actually
- X considered using multiple end states first, but then settled on this
- X because it was actually easier.) With only one END state, the only
- X thing that can be done when reaching here is to put-back the
- X character that caused the transition to this state. Therefore, the
- X actions in my scanner are *always* an implicit accept of each
- X character on a transition with a put-back of a character upon
- X arrival at the single END state. This makes everything much easier
- X conceptually.
- X
- X One consequence of this design is that the scanner must contain
- X explicit error states. In addition, *all* characters must belong to
- X some character class and all character classes must have a
- X transition to another state (in many states, most characters will
- X have a transition to an error state). This actually turns out to be
- X a useful mechanism for scanning LaserJet PCL, because all characters
- X can be text or data, and illegal characters in a command just cause
- X the command to be ignored.
- X
- X* The token numbers to be returned are determined at the end of scan()
- X in a large switch() statement (actually two switch()'s because of
- X the multiple scanners). This was the easiest way to do it, and was
- X relatively efficient. Note that prev_state must be examined,
- X because curr_state will *always* equal END when the switch() is
- X reached.
- X
- X
- SHAR_EOF
- $TOUCH -am 0630160890 doc/scanner.doc &&
- chmod 0664 doc/scanner.doc ||
- echo "restore of doc/scanner.doc failed"
- set `wc -c doc/scanner.doc`;Wc_c=$1
- if test "$Wc_c" != "6829"; then
- echo original size 6829, current size $Wc_c
- fi
- fi
- # ============= doc/suggestions.doc ==============
- if test X"$1" != X"-c" -a -f 'doc/suggestions.doc'; then
- echo "File already exists: skipping 'doc/suggestions.doc'"
- else
- echo "x - extracting doc/suggestions.doc (Text)"
- sed 's/^X//' << 'SHAR_EOF' > doc/suggestions.doc &&
- XProgram: lj2ps, 1.1 (release)
- XFile: suggestions.doc
- X
- XAuthor: Christopher Lishka
- XOrganization: Wisconsin State Laboratory of Hygiene
- X Data Processing Department
- X
- XDate: April 25th, 1990
- XLast modified: June 30th, 1990, by Chris Lishka
- X
- X
- XBesides adding missing PCL commands, there are many areas where lj2ps
- Xcould be improved. This file contains suggestions for those who want
- Xto extend the lj2ps program.
- X
- X* Add the missing commands LaserJet commands. These include:
- X
- X ** The position stack commands (fairly easy)
- X
- X ** Secondary font support (fairly easy)
- X
- X ** Macros (medium difficulty)
- X
- X ** Graphics commands (difficult)
- X
- X ** HP soft fonts (very difficult)
- X
- X
- X* Extend either the Test Suite or Metrics Suite (or both!) to include
- X more tests which would better test LaserJet operations and quirks.
- X
- X
- X* The font mechanism should be completely replaced. Here are some
- X suggestions for this area:
- X
- X ** Currently the fonts information is hard-coded into the file
- X ljfonts.c. A parser should be written that reads a file
- X describing which fonts are mounted in the virtual LaserJet.
- X
- X ** Currently there are two PostScript functions for setting the
- X current font: F and FS. In reality, only FS should be needed.
- X However, the scaling information for each font would need to be
- X changed, and I don't have the time to do this.
- X
- X ** Rescaleable, downloadable LaserJet fonts should be created for
- X the LaserWriter. The only way that the two machines will have
- X similar looking fonts is to custom-make LaserJet fonts for the
- X LaserWriter. This, of course, is a helluva lot of work! On the
- X other hand, it would improve the output immensely.
- X
- X
- X* Using two separate scanners is rather kludgy. It is very likely
- X that the text scanner could be replaced by a tightly-coded loop
- X which would read a character, check to see if it was "special", and
- X add it to the buffer if it wasn't. Special characters would include:
- X
- X (a) The escape character: this would throw execution into a special
- X command scanner/parser, which would handle recognition and
- X execution of all PCL commands. This parser would need to be
- X able to read long sequences of binary information (for commands
- X with data). After the command was finished, the parser would
- X return to the above text loop.
- X
- X (b) Left and right parentheses, backslash: these must be quoted in
- X PostScript programs, and cannot simply be written out.
- X
- X (c) Newline: perform PostScript code to write a newline.
- X
- X (d) Form feed: perform PostScript code to start a new page.
- X
- X (e) Tab: perform PostScript code to move to the next tab-stop.
- X
- X (f) Shift in: switch to the secondary character set.
- X
- X (g) Shift out: switch to the primary character set.
- X
- X (h) Null, and other non-special, non-printable characters: these
- X should produce a warning, even though the LaserJet would let
- X them slip by.
- X
- X
- X* I never implemented a real parser for the PCL commands. Instead,
- X each PCL command prefix has its own dedicated function. Each of
- X these functions has a small parser built into it. As you might
- X guess (especially after looking at the code!) this causes a lot of
- X similar code to be duplicated in each function. It would be nice to
- X implement a single "real" parser for the PCL commands, in
- X conjunction with the scanner changes mentioned above. This would
- X make the overall design much cleaner, and may improve the efficiency
- X some.
- SHAR_EOF
- $TOUCH -am 0630160890 doc/suggestions.doc &&
- chmod 0664 doc/suggestions.doc ||
- echo "restore of doc/suggestions.doc failed"
- set `wc -c doc/suggestions.doc`;Wc_c=$1
- if test "$Wc_c" != "3480"; then
- echo original size 3480, current size $Wc_c
- fi
- fi
- echo "End of part 7, continue with part 8"
- exit 0
-
-