[alt.sources] Postscript to make printer "dumb"

rustyh@wam.umd.edu (Michael Katzmann) (04/13/91)

Since I received a few e-mail requests for this, I don't think it would 
be too much of a waste of bandwidth to post it.  As the description says,
it is a postscript programme to make a postscript printer behave like a
dumb printer.

Simply send it to the postscript device before the text to be printed.

Bugs:  Doesn't handle tabs well on proportionally spaced fonts.

Please send any enhancements or bug fixes to me ath the address below.


--
Michael Katzmann  (VK2BEA/G4NYV/NV3Z)   Please email to this address |
Broadcast Sports Technology                                          |
2135 Espey Ct. #4                                                   \|/
Crofton MD 21114-2442    (301) 721-5151      ...uunet!opel!vk2bea!michael

%	Postscript to print ascii text.
%	[ Turn your Postscript printer into a "dumb" HP like laser printer ]
%
%	Written by Perry Brown 
%	   Trivial mods by   Michael Katzmann 
%	   Bug reports to:  (michael@vk2bea!opel!uunet.uu.na)
%
% ****  You are free to re-distribute this providing the authors name is
%								acknowedged.
%	Instructions:
%		Send to Postscript printer as a header 
%
%	These escape sequences anywhere in the text will modify printing:
%
%	(Escape sequences are in the form of \\X(Y) or \\XY)
%
%	   f[RIiBbUu]    Change font to Reset, Italic, Bold or Underline
%		          (lower case removes enhancement)
%		i.e.      \\fBu  would make the current font Bold and remove
%							underlining.
%
%	   p(size)	  Change font point size.
%		i.e.	  \\p(10) would print in 10 point characters
%
%	   t[THCS]	  Change typeface to Times, Helvetica, Courier or Symbol
%		i.e.	  \\tH    would print in Helvetica
%
%	   g(grey)	  Change shade ( 0 black to 100 white)
%		i.e.	  \\g(50) would print in mid grey
%
%	   P		  Portrait mode orientation.  e.g. \\P
%
%	   L		  Landscape mode orientation. e.g. \\L
%
%	   m(margin)	  Set margin (in numbers of space widths)
%		i.e.	  \\m(10)  Set left margin 10 characters in.
%
%	   
/Escapes [
  6 dict
    dup 8#015 {		% \r
      CarrageReturn
    } put
    dup 8#012 {		% \n
      CarrageReturn
      LineFeed
    } put
    dup 8#014 {		% \f
      FormFeed
    } put
    dup 8#010 {		% \b
      BackSpace
    } put
    dup 8#134 {		% \
      EscEnable {
        /Escaped 1 def
      } {
        8#134 WriteChar
      } ifelse
    } put
    dup 8#011 {		% \t
      Tab
    } put

  1 dict
    dup 8#134 {
      /Escaped 2 def
    } put

  8 dict
    dup 8#146 {		% f
      /Escaped 0 def
      GetChar PickFont
    } put
    dup 8#160 {		% p
      /Escaped 0 def
      GetNum {
        PickPoint
      } if
    } put
    dup 8#164 {		% t
      /Escaped 0 def
      GetChar PickFamily
    } put
    dup 8#147 {		% g
      /Escaped 0 def
      GetNum {
        100 div setgray
      } if
    } put
    dup 8#120 {		% P
      /Escaped 0 def
      /Portrait true def
      FormFeed
    } put
    dup 8#114 {		% L
      /Escaped 0 def
      /Portrait false def
      FormFeed
    } put
    dup 8#041 {		% !
      /Escaped 0 def
      /EscEnable false def
    } put
    dup 8#155 {		% m
      /Escaped 0 def
      GetNum {
        /Margin exch def
      } {
        /Margin 0 def
      } ifelse
      CarrageReturn
    } put
] def

/Main {
  /Stdin (%stdin) (r) file def
  /NewPage true def
  /Column 0 def
  /CurrentFont 0 def
  /PointSize 10 def
  /FontFamily 8#103 def		% 'C'
  /Portrait true def
  /Escaped 0 def
  /EscEnable true def
  /Margin 10 def
  /NeedMargin true def
  KludgeWindow
  SetRotation
  SetFont
  /SquareOne save def
  {
    GetChar PutChar
  } loop
} def

/KludgeWindow {
  /Ty 768 def
  /Tx 594 def
  /By 24 def
  /Bx 18 def
} def

/SetRotation {
  initmatrix
  Portrait {
    /TopMargin Ty def
    /BottomMargin By def
    /LeftMargin Bx def
    /RightMargin Tx def
  } {
    90 rotate
    /TopMargin Bx neg def
    /BottomMargin Tx neg def
    /LeftMargin By def
    /RightMargin Ty def
  } ifelse
} def

/GetChar {
  Stdin read not {
    Finish
  } if
} def

/GetNum {
  GetChar 8#050 eq {		% '('
    0 {
      GetChar dup dup 8#060 ge exch 8#071 le and {	% 0 .. 9
        8#060 sub exch 10 mul add
      } {
        exit
      } ifelse
    } loop
    8#051 eq {		% ')'
      true
    } {
      pop false
    } ifelse
  } {
    false
  } ifelse
} def

/FontMap 7 dict
  dup 8#122 {		% 'R'
    /CurrentFont 0 def
  } put
  dup 8#111 {		% 'I'
    /CurrentFont CurrentFont 2#1 or def
  } put
  dup 8#151 {		% 'i'
    /CurrentFont CurrentFont 2#1 not and def
  } put
  dup 8#102 {		% 'B'
    /CurrentFont CurrentFont 2#10 or def
  } put
  dup 8#142 {		% 'b'
    /CurrentFont CurrentFont 2#10 not and def
  } put
  dup 8#125 {		% 'U'
    /CurrentFont CurrentFont 2#100 or def
  } put
  dup 8#165 {		% 'u'
    /CurrentFont CurrentFont 2#100 not and def
  } put
def

/PutChar {
  Escapes Escaped get exch 2 copy known {
    get exec
  } {
    exch pop
    Escaped 0 ne {
      FlushEsc
      /Escaped 0 def
      PutChar
    } {
      WriteChar
    } ifelse
  } ifelse
} def

/FlushEsc {
  Escaped {
    8#134 WriteChar	% '\'
  } repeat
} def

/PickFont {
  dup FontMap exch 2 copy known {
    get exec
    SetFont
  } {
    pop pop
  } ifelse
} def

/PickPoint {
  dup 5 gt 1 index 50 lt and {
    /PointSize exch def
    SetFont
  } if
} def

/FamilyMap 4 dict
  dup 8#124 [		% 'T'
    (Times-Roman)
    (Times-Italic)
    (Times-Bold)
    (Times-BoldItalic)
  ] put
  dup 8#110 [		% 'H'
    (Helvetica)
    (Helvetica-Oblique)
    (Helvetica-Bold)
    (Helvetica-BoldOblique)
  ] put
  dup 8#103 [		% 'C'
    (Courier)
    (Courier-Oblique)
    (Courier-Bold)
    (Courier-BoldOblique)
  ] put
  dup 8#123 [		% 'S'
    (Symbol)
    dup
    dup
    dup
  ] put
def

/PickFamily {
  dup FamilyMap exch known {
    /FontFamily exch def
    SetFont
  } {
    pop
  } ifelse
} def

/SetFont {
  FamilyMap FontFamily get CurrentFont 2#011 and get findfont
  PointSize scalefont
  setfont
  MakeCurrent
} def

/MakeCurrent {
  NewPage {
    LeftMargin TopMargin
      gsave
      newpath 0 0 moveto (E) false charpath flattenpath pathbbox
        exch pop exch pop exch pop 2 add sub
      grestore
      moveto
  } if
} def

/CarrageReturn {
  /Column 0 def
  currentpoint exch pop LeftMargin exch moveto
  /NeedMargin true def
} def

/WriteChar {
  NeedMargin {
    SetMargin
  } if
  ( \273) dup 0 3 index put
    stringwidth pop currentpoint pop add
      RightMargin ge {
        (\273) show
        CarrageReturn
        LineFeed
        SetMargin
      } if
  ( ) dup 0 4 -1 roll put dup show
    UnderLine
  /NewPage false def
  /Column Column 1 add def
} def

/Finish {
  FlushEsc
  FormFeed
  stop
} def

/SetMargin {
  /NeedMargin false def
  Margin {
    ( ) show
  } repeat
} def

/BackSpace {
  /Column Column 1 sub dup 0 lt {
    pop 0
  } if
  def
  currentpoint exch ( ) stringwidth pop sub dup
    LeftMargin lt {
      /Column 0 def
      pop LeftMargin
    } if
    exch moveto
} def

/LineFeed {
  currentpoint PointSize sub dup PointSize 0.2 mul sub
    BottomMargin lt {
      pop pop
      FormFeed
    } {
      moveto
    } ifelse
} def

/FormFeed {
  NewPage not {
    showpage
  } if
  currentgray EscEnable Margin CurrentFont PointSize FontFamily Escaped Portrait
  SquareOne restore
    [ /Portrait /Escaped /FontFamily /PointSize /CurrentFont /Margin /EscEnable ] {
      exch def
    } forall
    /SquareOne save def
    setgray
    SetRotation
    SetFont
} def

/Tab {
  {
    8#040 WriteChar	% ' '
    Column 8 mod 0 eq {
      exit
    } if
  } loop
} def

/UnderLine {
  CurrentFont 2#100 and 0 ne {
    gsave
    currentpoint
    newpath
    moveto
    0 -0.15 PointSize mul rmoveto
    stringwidth pop neg 0 rlineto
    0.05 PointSize mul setlinewidth
    0 setlinecap
    stroke
    grestore
  } {
    pop
  } ifelse
} def

Main