home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / lang / distill.sit / still.ps < prev   
Text File  |  1989-04-03  |  69KB  |  2,199 lines

  1. %!PS-Adobe-2.1
  2. %%Title: still.ps
  3. %%Creator: Glenn Reid, Adobe Systems <adobe!greid@decwrl.dec.com>
  4. %%CreationDate:    greid Wed Jul  6 18:02:53 1988 EDIT: Wed Mar 15 12:46:06 1989
  5. %%VMUsage: 44036 (approx)
  6. %%EndComments
  7.  
  8. % Notice: Copyright 1988 1989 Adobe Systems Incorporated.  All Rights Reserved.
  9.  
  10. /adobe_distill 155 200 add dict def    % 155 required by still.ps
  11. /adobe_still_version ((V 1.0d release 10 edit 08)) def
  12.  
  13. % options:
  14. /debug true def            % generate debugging messages
  15. /messages false def        % generate more debugging messages (verbose!)
  16. /trace true  def        % print tracing messages like "page: 3"
  17. /substitutefonts true def    % substitute fonts if guess_font fails....
  18. /includeuserfonts true def    % copy embedded user-defined fonts to output?;
  19. /printpages false def        % do you want the pages to print?
  20. /optimize true  def        % optimize "show" to "widthshow", etc.
  21. /tolerance .05 def        % for "essentially equal to" operations
  22. /cachedir 60 dict def        % how many font dicts to cache (optimization)
  23. /includeprologue true def    % output files with/without prologue
  24.  
  25. % HOW TO USE: [see section below]
  26. %
  27. % OVERVIEW:
  28. %    This is a meta-utility program that "distills" any PostScript
  29. %    language program into a simpler one.  The resulting program
  30. %    will print exactly the same page as the original, but all
  31. %    unnecessary execution overhead is eliminated and the file is
  32. %    clean, uniform, and fast.
  33. %
  34. % RELEASE NOTES: [recent changes and details]
  35. %    First public release: 2/10/89
  36. %    Second release (numbered release 8): 2/17/89
  37. %        - reimplemented guess_font routines
  38. %        - added support for color; not careful about RGB->CMYK->RGB
  39. %        - added selective printing of pages during distill
  40. %    Release 9: 3/2/89
  41. %        - fixed color-induced [major efficiency loss] bug
  42. %        - produces %%BoundingBox and %%PageBoundingBox info (atend)
  43. %        - works better (bugs fixed) on rotated (landscape) documents
  44. %        - fixed horrible bug related to CTM that made it resolution-
  45. %          dependent in some cases.
  46. %        - included flag to omit the prologue on output if desired
  47. %        - moved some of the flags to the beginning of the file
  48. %        - improved prologue code to simulate CMYK color with RGB
  49. %    Release 10: 3/10/89
  50. %        - fixed bug related to rotated text
  51. %        - fixed rotated charpath bug mentioned in KNOWN PROBLEMS list
  52. %        - fixed bug with "closepath" followed by "rmoveto"
  53. %        - '=' and 'print' operators now pass data through to output
  54. %        - bug fixes for and much better support of user-defined fonts
  55. %        - (edit 07) fixed "undefined" "fd" problem.
  56. %        - (edit 08) took out redefinitions of '=' and 'print'; fixed
  57. %          a different "undefined" "fd" problem!
  58. %
  59. % MANY USES:
  60. %    * If you archive documents in PostScript format, they can be
  61. %      made compact and efficient by distilling them.
  62. %    * As a development tool, you can see what your program is
  63. %      really doing, and how simple and fast the driver could be.
  64. %    * Distilled files can be used as an interchange format,
  65. %      since arbitrary PostScript files can be converted to this
  66. %      uniform representation.
  67. %    * If your program can parse these files, then any arbitrary
  68. %      PostScript program can be used as input after distilling.
  69. %    * Many others.
  70. %
  71. % FEATURES:
  72. %    * correctly distills arbitrarily complex PostScript programs
  73. %    * output is universal, simple, and in default user coordinates
  74. %    * handles "charpath", "image", "imagemask", "awidthshow", etc.
  75. %    * correctly follows "save", "restore", "gsave", "grestore"
  76. %    * re-encodes fonts automatically to match application encoding
  77. %    * reduces prologue size to only about 25-30 lines
  78. %    * For machine-generated code:
  79. %        * output files are almost always SMALLER than original files
  80. %         * output files are almost always FASTER than original files
  81. %    * optimizes "show" to use "widthshow" whenever possible.
  82. %    * uses save/restore at page boundaries
  83. %    * observes structuring conventions and page independence
  84. %    * caches font dictionaries instead of repeating "findfonts"
  85. %    * output is normally VERY fast.
  86. %
  87. % HOW TO USE:
  88. %    This program redefines a bunch of operators, and is invoked
  89. %    with the word "distill".  This file has to precede the job it is
  90. %    distilling, and you have to invoke it by calling "distill".
  91. %
  92. %    PRINTERS:
  93. %        In general, start with this file (still.ps), add the word
  94. %        "distill" at the end (to invoke the procedure), and tack
  95. %        any PostScript language file onto the end.  Send this to
  96. %        your favorite PostScript printer with an appropriate
  97. %        end-of-file indication at the end.  Results will
  98. %        be returned across communication channel, often to a log
  99. %        file somewhere (Unix: /usr/adm/printername.log)
  100. %
  101. %    INTERPRETERS: if you have an interpreter with a file system
  102. %        handy, first type "(still.ps) run" to load this file, then
  103. %        distill your file like this: "(prog.ps) distill".  It will
  104. %        write the results in "prog.psx" (appends an x to the file
  105. %        name you give it).
  106. %    MACINTOSH: I have written a small Mac utility that is called
  107. %        "DistillPS" (an adaptation of "SendPS") that will perform the
  108. %        above PRINTER steps for you.  If you are an Adobe registered
  109. %        developer, you can get a copy directly from Adobe (or see
  110. %        posting in USENET comp.binaries.mac group).
  111. %
  112. % BACKGROUND
  113. % The basic idea is to execute the input file completely, with all of
  114. % the painting operators redefined.  When one of these operators is
  115. % called by the client program, the distillery will write the
  116. % path the output file (with all coordinates normalized to the default
  117. % userspace coordinate system).  Note that it will usually take LONGER
  118. % to distill a file than it would to print it, because it executes the
  119. % whole program, and much of it in a redefined state (slower).  Usually
  120. % only about 20% slower than original print time to distill.
  121. % The routines in this file are broken down into several areas.  Most
  122. % of them are concerned with writing things to the output file,
  123. % actually, although there are two other interesting areas.  The first
  124. % are the graphics state procedures, which attempt to keep track of the
  125. % graphics state and, when a painting op is called, it writes out any
  126. % changes to the graphics state since the last time it was called.  This
  127. % keeps each painting op from having to write gstate itself.  The other
  128. % interesting procs are simply the redefinitions of the painting ops
  129. % themselves.
  130. %
  131. % KNOWN COMPATIBLE PROGRAMS
  132. % The following applications have been tested (with some version of the
  133. % driver, at least), successfully:
  134. %    Lotus Manuscript
  135. %    Macintosh "LaserPrep" (all documents, I think)
  136. %    DEC's VaxDocument
  137. %    Scribe
  138. %    PageMaker
  139. %    Frame Maker
  140. %    Adobe Illustrator
  141. %    TranScript (ditroff and enscript drivers)
  142. %
  143. % KNOWN PROBLEMS:
  144. %    Clipping isn't handled correctly.
  145. %
  146. %    I'm not convinced that the bounding box for images is right.
  147. %
  148. %    Hand-written PostScript language programs (especially those
  149. %    that take advantage of looping constructs) may get BIGGER
  150. %    when you distill them, because the Distillery unrolls all loops.
  151. %    It is really intended for machine-generated files, but it should
  152. %    still work on programs tightly coded by hand (like Cookbook
  153. %    examples).
  154. %
  155. %    Use of the "put" and "putinterval" operators to overwrite
  156. %    string bodies can confuse the optimization technique.  If you
  157. %    see strange output (wrong characters printed, especially),
  158. %    try changing "/optimize true def" to "/optimize false def"
  159. %    at the very beginning of this program.
  160. %
  161. %    Programs that use the "transform" operator to make resolution-
  162. %    rounding decisions may have the output file bound to a specific
  163. %    resolution.  The last ProcSet (called "hacks") redefines a few
  164. %    operators to try to work around this.  Output file is still
  165. %    device-independent in any case, but might look different.
  166. %
  167. %    Distillery relies on bug in save/restore related to string bodies
  168. %    to preserve some information across save/restore. It is localized
  169. %    to the "adobe_staticvar" procedure set, but may not always work.
  170. %
  171. %    In order to optimize re-encoding of fonts, the distillery takes
  172. %    an educated guess that the first re-encoded font it sees will
  173. %    have a representative encoding vector ("stdvec").  If this
  174. %    first font is not encountered before other marks are made, the encoding
  175. %    vector cannot be produced in the %%BeginSetup section, and the still
  176. %    is forced to repeat the vector every time a font is used.  Work
  177. %    is in progress on a heuristic to improve this.
  178. %
  179. %       In order to avoid building up the dictionary stack during
  180. %       execution, all definitions are made in one dictionary
  181. %       (PROLOGUE) and it is not explicitly brought to the top of
  182. %       the dictionary stack for each operation (to avoid
  183. %       "dictstackoverflow" errors).  Most of the identifiers have
  184. %       been chosen to be reasonably unique, but there could be a
  185. %       conflict if user programs use the same names.
  186. %
  187. %    Sometimes generates unnecessarily verbose code in the presence
  188. %    of lots of save/restores in original file.  Try distilling the
  189. %    output a second time to improve this (like whiskey)....
  190. %
  191. %    Some of the ProcSets depend on each other in weird ways, which
  192. %    is definitely wrong, since only the script should depend on
  193. %    the procset definitions.  Eventually this will get fixed.
  194. %
  195. %    Does not always work correctly with user-defined fonts, especially
  196. %    those defined by the standard TeX driver (unfortunately).  In
  197. %    particular, TeX bitmap fonts that are defined and have characters
  198. %    added on the fly are almost impossible to deal with reliably in this
  199. %    distillery approach.
  200.  
  201. %%BeginProcSet: originals 0.5
  202. % This dictionary contains the original definitions of native operators
  203. % that have been redefined by the Distillery.  They are needed on
  204. % occasion to permit the original program to execute operators without
  205. % having the results distilled.  The motivating factor for this is
  206. % user-defined fonts, which "draw" into the font cache, but the effects
  207. % are not wanted in the output file.
  208. %
  209. % This also serves as a list of the redbook operators that are redefined
  210. % by the distillery code.
  211.  
  212. mark
  213.   /show
  214.   /widthshow
  215.   /ashow
  216.   /awidthshow
  217.   /kshow
  218.   /fill
  219.   /eofill
  220.   /stroke
  221.   /clip
  222.   /image
  223.   /imagemask
  224.   /showpage
  225.   /pathbbox
  226.   /save
  227.   /restore
  228.   /gsave
  229.   /grestore
  230.   /charpath
  231.   /newpath
  232.   /definefont
  233.   /flushfile
  234.   /=
  235.   /print
  236. counttomark dup dict begin { dup load def } repeat pop
  237. /originals currentdict end def
  238.  
  239. %%EndProcSet: originals 0.5
  240.  
  241. %%BeginProcSet: distill_defs 1.0 0
  242. /setpacking where { pop currentpacking true setpacking } if
  243. /firstmtx matrix currentmatrix def
  244.  
  245. /bdef { bind def } bind def
  246.  
  247. /ifnotdef { %def
  248.   % only does the "def" if the key has not already been defined:
  249.     1 index where { pop pop pop }{ def } ifelse
  250. } bdef
  251.  
  252. /*flushfile /flushfile load ifnotdef
  253.  
  254. printpages not { %if
  255.     /showpage { erasepage initgraphics } bind def
  256. } if
  257.  
  258. /currentcmykcolor where { pop }{ %else
  259.     /currentcmykcolor { %def
  260.         currentrgbcolor 3 { 1 exch sub 3 1 roll } repeat 0
  261.     } bind def
  262. } ifelse
  263.  
  264. /setpacking where { pop setpacking } if
  265. %%EndProcSet
  266.  
  267. %%BeginProcSet: Adobe_staticvar 1.0 0
  268.     % this procedure set implements the "magic" stuff to hide numbers
  269.     % and other things where they will not be subject to save/restore
  270.     /magicval { 8 string } bdef
  271.     /hideval { %def    % /name int :    % "hideval" uses save/restore bug!
  272.     exch load dup 0 (\040\040\040\040\040\040\040\040) putinterval
  273.     exch (\040\040\040\040\040\040\040\040) cvs
  274.     dup length 8 exch sub exch putinterval
  275.     } bdef
  276.     /magicbool { 5 string } bdef
  277.     /hidebool { %def    % /name int :    % "hideval" uses save/restore bug!
  278.     exch load dup 0 (\040\040\040\040\040) putinterval
  279.     exch (\040\040\040\040\040) cvs 0 exch putinterval
  280.     } bdef
  281.     /cvnum { cvx exec } bdef    % makes hidden val back into an integer
  282.     /cvbool { cvx exec } bdef    % makes hidden val back into a boolean
  283.     /hidefontname { %def
  284.     % hides a font name in a string body, for use in %%DocumentFonts
  285.     scratch cvs
  286.     % look to see if it is already in the docfonts string:
  287.     % lots of hacks to search for (FontName\n), not just (FontName)
  288.     save    % cause we're using memory for temporary string
  289.         adobe_distill begin
  290.         1 index length 1 add string /tmpstring exch def
  291.         tmpstring dup length 1 sub (\040) 0 get put
  292.         tmpstring 0 3 index putinterval
  293.         pagefonts tmpstring search {pop pop pop false}{pop true} ifelse
  294.         docfonts tmpstring search {pop pop pop false}{pop true}ifelse
  295.         end
  296.     3 -1 roll restore        % roll save object past booleans
  297.  
  298.     % first deal with docfonts, then with pagefonts booleans
  299.     { %ifelse
  300.         exch    % extra boolean for page fonts
  301.         dup dfontcount cvnum 1 index length add 1 add
  302.         docfonts length lt {
  303.         dup docfonts exch dfontcount cvnum exch putinterval
  304.         length 1 add dfontcount cvnum add /dfontcount exch hideval
  305.         docfonts dfontcount cvnum 1 sub (\040) putinterval
  306.         }{ %else
  307.         pop (% No more room for fonts in document font list\n) d=
  308.         } ifelse
  309.         messages { %if
  310.         (document fonts: ) pr=
  311.         docfonts 0 dfontcount cvnum getinterval d= flush
  312.         } if
  313.         exch % page font boolean still on stack, under "dup"ed string
  314.     }{ } ifelse
  315.     { %ifelse
  316.         pfontcount cvnum 1 index length add 1 add
  317.         pagefonts length lt {
  318.         dup pagefonts exch pfontcount cvnum exch putinterval
  319.         length 1 add pfontcount cvnum add /pfontcount exch hideval
  320.         pagefonts pfontcount cvnum 1 sub (\040) putinterval
  321.         }{ %else
  322.         pop (% No more room for fonts in page font list\n) d=
  323.         } ifelse
  324.         messages { %if
  325.         (page fonts: ) pr=
  326.         pagefonts 0 pfontcount cvnum getinterval d= flush
  327.         } if
  328.     }{ pop } ifelse
  329.     } bdef
  330. %%EndProcSet: Adobe_staticvar 1.0 0
  331.  
  332. %%BeginProcSet: distill 1.0 0
  333. /setpacking where { pop currentpacking true setpacking } if
  334.  
  335. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  336.  
  337. % some variables
  338.     % magic variables depending on "hideval", not subject to save/restore
  339.     /pagecount magicval def    /pagecount 1 hideval
  340.     /beginsetup magicbool def    /beginsetup true hidebool
  341.     /lastshowpage magicbool def    /lastshowpage false hidebool
  342.     /begunpage magicbool def    /begunpage false hidebool
  343.     /?distilling magicbool def    /?distilling true hidebool
  344.  
  345.     /dfontcount magicval def     /dfontcount 0 hideval
  346.     /pfontcount magicval def    /pfontcount 0 hideval
  347.     /docfonts 40 30 mul string def        % room for 40 30-byte font names
  348.     /pagefonts 40 30 mul string def        % room for 40 30-byte font names
  349.     /LLx magicval def        /LLx 10000 hideval
  350.     /LLy magicval def        /LLy 10000 hideval
  351.     /URx magicval def        /URx -10000 hideval
  352.     /URy magicval def        /URy -10000 hideval
  353.     /docLLx magicval def    /docLLx 10000 hideval
  354.     /docLLy magicval def    /docLLy 10000 hideval
  355.     /docURx magicval def    /docURx -10000 hideval
  356.     /docURy magicval def    /docURy -10000 hideval
  357.  
  358.     /optim optimize def
  359.     /scratch 128 string def
  360.     /fontcount 0 def
  361.     /indentlevel 0 def
  362.     /ANYtype null def
  363.     /insideproc false def
  364.     /Dfont null def
  365.     /Ffont null def
  366.     /Fname null def
  367.     /lastshow false def
  368.     /imageproc null def
  369.     /imagematrix null def
  370.     /imagedepth null def
  371.     /imageheight null def
  372.     /imagewidth null def
  373.     /unames 120 dict def    % for keeping track of user-defined names
  374.  
  375. % a few of them go into userdict:
  376. /cvp {
  377.     messages { % ifelse
  378.     (                     ) cvs pr= (\040) pr=
  379.     }{ pop } ifelse
  380. } bdef
  381. /pr= { messages { rprint }{ pop } ifelse } bdef
  382. /d= { messages { r= }{ pop } ifelse } bdef
  383.  
  384. /distill {
  385.     adobe_distill begin
  386.     debug{(%!PS-Adobe-2.1 debug version ) rprint adobe_still_version == }if
  387.     userdict /orig_dictcount countdictstack put
  388.     count 0 eq { %ifelse
  389.         /INfile (%stdin) def
  390.         /OUTfile (%stdout) def
  391.         /fd (%stdout) (w) file def
  392.         initstill
  393.         writeprologue
  394.         initgstate
  395.         INfile (r) file cvx exec
  396.         writetrailer
  397.     }{ %else
  398.         dup type /stringtype ne { %if
  399.         (\n% Distill Error; invoked with bogus file name: ) print
  400.         == (\n) print flush
  401.         stop
  402.         } if
  403.         /filenameforall where { pop }{ %ifelse
  404.         (\n% Distill Error; invoked with file name: ) print == 
  405.         (% This interpreter cannot open files directly.) = 
  406.         (% Please add "distill" at end of file and concatenate with) = 
  407.         (% file to be distilled.) = (\n) print flush
  408.         stop
  409.         } ifelse
  410.         initgraphics
  411.         /saveall save def
  412.         /INfile exch def
  413.         /OUTfile INfile length 1 add string def
  414.         OUTfile 0 INfile putinterval
  415.         OUTfile dup length 1 sub (x) 0 get put
  416.         trace { (output file: ) rprint OUTfile == } if
  417.         /outfile OUTfile (w) file def
  418.         /fd /outfile load def
  419.         initstill
  420.         writeprologue
  421.         initgstate
  422.         debug { %ifelse
  423.             INfile run
  424.         }{ % else
  425.             { INfile run } stopped { % if
  426.              errordict begin $error begin
  427.                 (\n%%[Error: ) wout
  428.                 /errorname load =string cvs wout
  429.                 (; OffendingCommand: ) wout
  430.                 /command load =string cvs wout (]%%) wout writeNL
  431.                 (STACK:) writeop /ostack load type /arraytype eq {
  432.                 ostack { =string cvs writeop } forall
  433.                 } if
  434.                 fd systemdict /flushfile get exec
  435.                 handleerror
  436.             end end
  437.             } if
  438.         } ifelse
  439.         writetrailer
  440.         fd closefile
  441.         countdictstack orig_dictcount sub { end } repeat
  442.         clear
  443.         saveall { restore } stopped { %if
  444.         trace { (couldn't restore after distill.) r= } if
  445.         } if
  446.     } ifelse
  447.    end
  448. } bdef
  449.  
  450. % the rest of them go in "adobe_distill"
  451. adobe_distill begin
  452.     /setdistill { %def
  453.     /?distilling exch hidebool
  454.     } bdef
  455.  
  456.     /initstill { %def
  457.     /beginsetup true hidebool
  458.     /lastshowpage false hidebool
  459.     /begunpage false hidebool
  460.     /pagecount 1 hideval
  461.     /STDvec 0 hideval
  462.     /PAGEvec 0 hideval
  463.     /dfontcount 0 hideval
  464.     /pfontcount 0 hideval
  465.     /LLx 10000 hideval  /LLy 10000 hideval
  466.     /URx -10000 hideval /URy -10000 hideval
  467.     /docLLx 10000 hideval  /docLLy 10000 hideval
  468.     /docURx -10000 hideval /docURy -10000 hideval
  469.     /SharedFontDirectory where { %ifelse
  470.         /SharedFontDirectory get
  471.     }{ /FontDirectory load } ifelse
  472.     /FontDirectory exch def
  473.     0 1 pagefonts length 1 sub { pagefonts exch 0 put } for
  474.     0 1 docfonts length 1 sub { docfonts exch 0 put } for
  475.     } bdef
  476.     debug { %if
  477.     /BB {
  478.         debug {
  479.         (% BBox: ) pr=
  480.         LLx pr= ( ) pr= LLy pr= ( ) pr=
  481.         URx pr= ( ) pr= URy pr= (\n) pr= flush
  482.         (% DocBBox: ) pr=
  483.         docLLx pr= ( ) pr= docLLy pr= ( ) pr=
  484.         docURx pr= ( ) pr= docURy pr= () r= flush
  485.         } if
  486.     } bdef
  487.     } if
  488.     /?box { %def    % X Y
  489.     dup URy cvnum gt { dup /URy exch cvi hideval } if
  490.     dup LLy cvnum lt { dup /LLy exch cvi hideval } if pop
  491.     dup URx cvnum gt { dup /URx exch cvi hideval } if
  492.     dup LLx cvnum lt { dup /LLx exch cvi hideval } if pop
  493.     } bdef
  494.     /doc?box {
  495.     dup docURy cvnum gt { dup /docURy exch cvi hideval } if
  496.     dup docLLy cvnum lt { dup /docLLy exch cvi hideval } if pop
  497.     dup docURx cvnum gt { dup /docURx exch cvi hideval } if
  498.     dup docLLx cvnum lt { dup /docLLx exch cvi hideval } if pop
  499.     } bdef
  500.     /pageBBox-docBBox {
  501.     LLx cvnum LLy cvnum doc?box
  502.     URx cvnum URy cvnum doc?box
  503.     } bdef
  504.     /writeRmove { %def
  505.     2 copy lineY sub exch lineX sub exch
  506.     dup 0.0 eq { pop writenum (x) writeop }{ %ifelse
  507.         1 index 0.0 eq { writenum (y) writeop pop }{ %ifelse
  508.         writepair (r) writeop
  509.         } ifelse
  510.     } ifelse
  511.     2 copy ?box
  512.     /lineY exch store /lineX exch store
  513.     } bdef
  514.     /writelines { %def
  515.     counttomark REPEAT_LINETO_THRESHOLD gt { % ifelse
  516.         counttomark /lcount exch store
  517.         lcount -2 2 { %for
  518.         dup /rcount exch store
  519.         -2 roll 2 copy lineY sub exch lineX sub exch 4 -2 roll
  520.         2 copy ?box
  521.         /lineY exch store /lineX exch store
  522.         rcount 2 roll
  523.         } for
  524.         lcount 2 idiv { writepair writeNL } repeat
  525.         lcount 2 idiv writenum (R) writeop
  526.     }{ % else
  527.         counttomark -2 2 { -2 roll writeRmove } for
  528.     } ifelse
  529.     } bdef
  530.     /writepath {
  531.     /closed false store
  532.     % optimize special case of just "moveto lineto stroke"
  533.     mark
  534.     % pathforall
  535.     { counttomark 2 gt { cleartomark false exit } if thruCTM true }
  536.     { counttomark 5 gt { cleartomark false exit } if thruCTM true }
  537.     { cleartomark false exit }
  538.     { cleartomark false exit }
  539.     pathforall { %ifelse
  540.         counttomark 5 ne { %ifelse
  541.         % degenerate case...
  542.         ischarpath counttomark 2 eq and {    % just moveto
  543.             2 copy ?box
  544.             writepair (m) writeop
  545.         } if
  546.         cleartomark
  547.         }{ %else
  548.         3 -1 roll pop
  549.         /?simplepath true store
  550.         simplepath astore pop
  551.         pop %mark
  552.         } ifelse
  553.     }{ %else
  554.         /?simplepath false store
  555.         mark
  556.         { % moveto
  557.         closed { (cp ) wout /closed false store } if
  558.         counttomark 2 gt { %if
  559.             counttomark 1 add 2 roll writelines 3 1 roll
  560.         } if
  561.         2 copy thruCTM /lineY exch store /lineX exch store
  562.         /closeX lineX store  /closeY lineY store
  563.         2 copy ?box
  564.         writeTpair (m) writeop
  565.         } % moveto proc
  566.         { %lineto proc
  567.         thruCTM count 490 gt { writelines } if
  568.         } % lineto
  569.         { % curveto
  570.         counttomark 6 gt { %if
  571.             counttomark 1 add 6 roll writelines 7 1 roll
  572.         } if
  573.         2 copy thruCTM /lineY exch store /lineX exch store
  574.         3 { %repeat
  575.             6 -2 roll 2 copy thruCTM
  576.             2 copy ?box
  577.             exch writenum writenum
  578.         } repeat (c) writeop 6 {pop} repeat
  579.         } % curveto
  580.         { % closepath
  581.         counttomark 0 gt { writelines } if
  582.         /closed true store
  583.         /lineX closeX store  /lineY closeY store
  584.         } % closepath
  585.         pathforall
  586.         counttomark 0 gt { writelines } if
  587.         pop %mark
  588.     } ifelse
  589.     } bdef
  590.     /hashpath { %def
  591.       % manufacture a [fairly] unique integer to represent a path:
  592.     -1                % initial value
  593.     { .5 add add 2 div add }    % moveto
  594.     { add sub }            % lineto
  595.     { add add sub add add add }    % curveto
  596.     { 1 add }            % closepath
  597.     pathforall
  598.     dup 100 lt { 10 mul truncate 10 div } if
  599.     } bdef
  600.     /hashencoding { %def
  601.       % manufacture a [fairly] unique integer for an encoding vector,
  602.       % by alternately adding then subtracting the length of the name.
  603.       % The alternation makes reordered lists with same names still come out
  604.       % with a different hash value (the "-1 exch" and the "mul" do this)
  605.     -1 exch 0 exch            % initial value: 0
  606.     { % forall
  607.         dup type /nametype eq { length }{ pop 1 } ifelse
  608.         2 index mul add    % multiply by 1 or -1 and add
  609.         exch -1 mul exch    % flip 1 and -1
  610.     } forall
  611.     exch pop            % get rid of -1, leave hash val
  612.     } bdef
  613.     /STDvec magicval def /STDvec 0 hideval
  614.     /PAGEvec magicval def /PAGEvec 0 hideval
  615.     /enc1 null def /enc2 null def
  616.     /diffencoding { %def
  617.     % check the "top128" boolean to see if it's worth reencoding them
  618.     /enc2 exch store /enc1 exch store    % enc2 is the new one
  619.     [ 
  620.         32 1 127 { %for                % 0 1 255 ??
  621.         dup dup enc2 exch get exch enc1 exch get
  622.         1 index eq { pop pop } if
  623.         } for
  624.     ]
  625.     } bdef
  626.     /indent { indentlevel { fd (  ) writestring } repeat } bdef
  627.     /++ { dup load 1 add store } bdef
  628.     /-- { dup load dup 1 ge { 1 sub } if store } bdef
  629.  
  630. end %adobe_distill
  631. /setpacking where { pop setpacking } if
  632. %%EndProcSet
  633.  
  634. %%BeginProcSet: distill_writetofile 1.0 0
  635. /setpacking where { pop currentpacking true setpacking } if
  636. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  637. adobe_distill begin
  638.     /writetrailer { %def    % :
  639.     stackptr 0 ne { stackshow } if
  640.     begunpage cvbool { %if
  641.         lastshowpage cvbool not { %if
  642.         ( /showpage {} def) writeop
  643.         } if
  644.         pagecount cvnum scratch cvs wout ( ENDPAGE\n) wout
  645.         (%%PageTrailer) writeop
  646.         (%%PageFonts: ) wout
  647.         pfontcount cvnum 0 eq { writeNL }{ %else
  648.         pfontcount cvnum 200 lt { %ifelse
  649.             pagefonts 0 pfontcount cvnum getinterval writeop
  650.         }{ %else
  651.             pagefonts (\040) search not { writeop }{ %else
  652.             writeop    % first one without the %%+
  653.             { %loop
  654.                 search { (%%+ ) wout writeop }{ %else
  655.                 (\000) search { writeop pop pop }{ pop } ifelse
  656.                 exit
  657.                 } ifelse
  658.             } loop
  659.             } ifelse
  660.         } ifelse
  661.         0 1 pfontcount cvnum { pagefonts exch 0 put } for
  662.         /pfontcount 0 hideval
  663.         } ifelse
  664.         LLx 10000 eq LLy 10000 eq or
  665.         URx -10000 eq URy -10000 eq or or not {
  666.         (%%PageBoundingBox: ) wout
  667.           LLx cvnum writenum LLy cvnum writenum
  668.           URx cvnum writenum URy cvnum writenum writeNL
  669.         } if
  670.         pageBBox-docBBox
  671.     } if
  672.     (%%Trailer) writeop
  673.     (end %PROLOGUE) writeop
  674.     (%%Pages: ) wout pagecount cvnum writenum writeNL
  675.     (%%BoundingBox: ) wout
  676.       docLLx cvnum writenum docLLy cvnum writenum
  677.       docURx cvnum writenum docURy cvnum writenum writeNL
  678.     (%%DocumentFonts: ) wout
  679.     dfontcount cvnum 0 eq { writeNL }{ %else
  680.         dfontcount cvnum 200 lt { %ifelse
  681.         docfonts 0 dfontcount cvnum getinterval writeop
  682.         }{ %else
  683.         docfonts (\040) search not { writeop }{ %else
  684.             writeop    % first one without the %%+
  685.             { %loop
  686.             search { (%%+ ) wout writeop }{ %else
  687.                 (\000) search { writeop pop pop }{ pop } ifelse
  688.                 exit
  689.             } ifelse
  690.             } loop
  691.         } ifelse
  692.         } ifelse
  693.     } ifelse
  694.     (%%EOF) writeop
  695.     } bdef
  696.     /writecomments { %def
  697.     fd (%!PS-Adobe-2.1\n) writestring
  698.     fd (%%Title: ) writestring fd OUTfile writestring fd (\n) writestring
  699.     fd (%%Creator: Glenn Reid and still.ps ) writestring
  700.     fd adobe_still_version writestring fd (\n) writestring
  701.     fd (%%BoundingBox: (atend)\n) writestring
  702.     fd (%%Pages: (atend)\n) writestring
  703.     includeprologue { %ifelse
  704.         fd (%%DocumentProcSets: Adobe_distill 0.95\n) writestring
  705.     }{ %else
  706.         fd (%%DocumentNeededProcSets: Adobe_distill 0.95\n) writestring
  707.     } ifelse
  708.     fd (%%EndComments\n) writestring
  709.     } bdef
  710.     /writeprologue { %def    % :
  711.     writecomments
  712.     includeprologue { %ifelse
  713.         mark
  714.         (%%BeginProcSet: Adobe_distill 0.95)
  715.         (/PROLOGUE 30 40 add dict def)
  716.         ( % 30 procedure entries + room for 40 cached font dictionaries)
  717.         ( PROLOGUE begin)
  718.         ( /clip { } def    % causes problems. remove if "clip" is needed)
  719.         ( /bdef { bind def } bind def    /ldef { load def } bdef)
  720.         ( /T { moveto show } bdef    /A { moveto ashow } bdef)
  721.         ( /W { moveto widthshow } bdef    /AW { moveto awidthshow } bdef)
  722.         ( /f /fill ldef            /R { { rlineto } repeat } bdef)
  723.         ( /r /rlineto ldef        /L { { lineto } repeat } bdef)
  724.         ( /m /moveto ldef        /l { moveto lineto stroke } bdef)
  725.         ( /x { 0 rlineto } bdef        /y { 0 exch rlineto } bdef)
  726.         ( /c /curveto ldef        /cp /closepath ldef)
  727.         ( /s /stroke ldef        /w /setlinewidth ldef)
  728.         ( /g /setgray ldef        /j /setlinejoin ldef)
  729.         ( /d /setdash ldef        /F /setfont ldef)
  730.         ( /C /setcmykcolor where { /setcmykcolor get }{ %ifelse)
  731.         (   { %def)
  732.         (     1 sub 3 { 3 index add neg dup 0 lt { pop 0 } if 3 1 roll } repeat)
  733.         (     setrgbcolor)
  734.         (   } bind)
  735.         ( } ifelse def)
  736.         ( /MF { findfont exch makefont setfont } bdef)
  737.         ( /DF { findfont exch scalefont setfont currentfont def } bdef)
  738.         ( /BEGINPAGE { pop /pagesave save def } bdef)
  739.         ( /ENDPAGE { pop pagesave restore showpage } def)
  740.         ( /REMAP { %def)
  741.         (   FontDirectory 2 index known { pop pop pop } { %ifelse)
  742.         (     findfont dup length dict begin)
  743.         (       { 1 index /FID ne {def}{pop pop} ifelse } forall)
  744.         (       exch dup length 0 gt { /Encoding exch def }{ pop } ifelse)
  745.         (     currentdict end definefont pop)
  746.         (   } ifelse)
  747.         ( } bdef)
  748.         ( /RECODE { %def)
  749.         (    3 -1 roll 1 index findfont /Encoding get 256 array copy exch)
  750.         (    0 exch { %forall)
  751.         (     dup type/nametype eq)
  752.         (       { 3 {2 index} repeat put pop 1 add }{ exch pop }ifelse)
  753.         (    } forall pop 3 1 roll REMAP)
  754.         ( } bdef)
  755.         ( end %PROLOGUE)
  756.         (%%EndProcSet: Adobe_distill 0.95)
  757.         % write all the above strings to the output file:
  758.         counttomark -1 1 { %for
  759.         -1 roll fd exch writestring fd (\n) writestring
  760.         } for
  761.         fd systemdict /flushfile get exec
  762.         pop %mark
  763.     }{ %else
  764.         (%%IncludeProcSet: Adobe_distill 0.95\n) fd exch writestring
  765.     } ifelse
  766.     fd (%%EndProlog\n) writestring
  767.     fd (%%BeginSetup\n) writestring
  768.     fd (PROLOGUE begin\n) writestring
  769.     } bdef
  770.     /checksetup { %def
  771.     % called from "fontstate", "graphicstate", and "definefont"
  772.     beginsetup cvbool {
  773.         /beginsetup false hidebool
  774.         fd (\n%%EndSetup\n%%Page: 1 1\n) writestring
  775.         fd (%%PageFonts: (atend)\n) writestring
  776.         fd (%%PageBoundingBox: (atend)\n) writestring
  777.         fd (1 BEGINPAGE\n) writestring
  778.         /begunpage true hidebool
  779.         /fontcount 0 store
  780.     }{ %else
  781.         lastshowpage cvbool { %if
  782.         /lastshowpage false hidebool
  783.         /fontcount 0 store
  784.         writeNL (%%Page: ) wout
  785.         trace { (page: ) rprint pagecount cvnum == flush } if
  786.         /pagecount pagecount cvnum 1 add hideval
  787.         pagecount cvnum dup writenum writenum writeNL
  788.         (%%PageFonts: (atend)) writeop
  789.         (%%PageBoundingBox: (atend)) writeop
  790.         pagecount cvnum scratch cvs wout ( BEGINPAGE\n) wout
  791.         /begunpage true hidebool
  792.          % invalidate all remapped fonts, for page independence
  793.         FontDirectory { %forall
  794.             exch pop dup /FontInfo known { %ifelse
  795.             /FontInfo get dup /pleasemap known { %ifelse
  796.                 begin (Glenn Reid)
  797.                 pleasemap cvbool not {
  798.                     /pleasemap true hidebool
  799.                 } if pop
  800.                 end
  801.             }{ pop } ifelse
  802.             }{ pop } ifelse
  803.         } forall
  804.         % forcegstate
  805.         } if
  806.     } ifelse
  807.     } bdef
  808.     /writenamearray {        % [ /name ... ] :
  809.     fd ([) writestring
  810.     /indentlevel ++ fd (\n) writestring indent
  811.     /CNT 1 store
  812.     %| maintain CNT to count bytes.  wrap lines at a reasonable
  813.     %| place when writing out character names, to avoid long lines
  814.     { %forall
  815.         fd (/) writestring
  816.         dup type /nametype eq { scratch cvs }{ pop (.notdef) } ifelse
  817.         dup  length 1 add CNT add /CNT exch store  fd exch writestring
  818.         CNT 60 ge { /CNT 1 store fd (\n) writestring indent } if
  819.     } forall
  820.     /indentlevel -- fd (\n) writestring indent fd (]) writestring
  821.     } bdef
  822.     /writediffencoding {    % [ 32/name 37/etc ... ] :
  823.     fd ([) writestring
  824.     /indentlevel ++ fd (\n) writestring indent
  825.     /CNT 1 store
  826.     %| maintain CNT to count bytes.  wrap lines at a reasonable
  827.     %| place when writing out character names, to avoid long lines
  828.     { %forall
  829.         dup type /integertype eq { %ifelse
  830.         fd (\040) writestring
  831.         scratch cvs fd exch writestring /CNT CNT 4 add store
  832.         }{ %else
  833.         fd (/) writestring
  834.         dup type /nametype eq { scratch cvs }{ pop (.notdef) } ifelse
  835.         dup  length 1 add CNT add /CNT exch store  fd exch writestring
  836.         } ifelse
  837.         CNT 60 ge { /CNT 1 store fd (\n) writestring indent } if
  838.     } forall
  839.     /indentlevel -- fd (\n) writestring indent fd (]) writestring
  840.     } bdef
  841.  
  842.   % write numbers in various formats:
  843.  
  844.     /thruCTM { CTM transform } bdef
  845.     /dthruCTM { CTM dtransform } bdef
  846.     /XthruCTM { %def
  847.     dup CTM dtransform
  848.     rot not { pop }{ %else
  849.         2 copy gt { pop }{ exch pop } ifelse
  850.     } ifelse
  851.     } bdef
  852.  
  853.     /*writestring { %def
  854.     writestring fd *flushfile
  855.     } bdef
  856.     /shave { %def
  857.       % eliminate significant digits beyond .001; compensate for roundoff
  858.     dup type /realtype eq { %if
  859.         1000 mul truncate 1000 div
  860.     } if
  861.     } bdef
  862.     /writenum { % def        % num :
  863.     dup abs 0.001 le { pop 0 } if        % --> 0
  864.     dup dup cvi eq { cvi } if
  865.     fd exch scratch cvs writestring _space
  866.     } bdef
  867.     /writeprecisenum { % def        % num :
  868.     fd exch scratch cvs writestring _space
  869.     } bdef
  870.     /writeXnum { % def        % num :
  871.     CTM 0 get mul writenum
  872.     } bdef
  873.     /writeYnum { % def        % num :
  874.     CTM 3 get mul writenum
  875.     } bdef
  876.     /writeTpair { % def        % num1 num2 :
  877.     thruCTM exch
  878.     writenum writenum
  879.     } bdef
  880.     /writepair { % def        % num1 num2 :
  881.     exch writenum writenum
  882.     } bdef
  883.     /writenumarray {        % [ nums ] : 
  884.     fd ([) writestring
  885.     { writenum } forall
  886.     fd (] ) writestring
  887.     } bdef
  888.  
  889.   % write out names and strings:
  890.     /rprint /print load def
  891.     /r= /= load def
  892. %    /print { fd exch writestring } bind def
  893. %    /= { scratch cvs fd exch writestring writeNL } bind def
  894.  
  895.     /writeNL { fd (\n) writestring } bdef
  896.     /_space { fd (\040) writestring } bdef
  897.     /wout { % def        % (string) :
  898.      fd exch writestring
  899.     } bdef
  900.     /writestr { % def        % (string) :
  901.     fd exch writestring _space
  902.     } bdef
  903.     /writeop { %def        % (string) :
  904.     fd exch writestring writeNL
  905.     } bdef
  906.     /writePSstring { % def    % (string) :
  907.     fd (\() writestring dup length 75 gt exch
  908.     wordfix fd (\) ) writestring { writeNL } if % if length > 75 bytes
  909.     } bdef
  910.     /writename { % def        % name :
  911.     scratch cvs fd exch writestring  _space
  912.     } bdef
  913.     /writeRname { % def        % name :
  914.     (/) wout scratch cvs wout (R ) wout
  915.     } bdef
  916.     /checkusernames { %def    % array :
  917.     { % forall
  918.         dup type /nametype ne { pop }{ %ifelse
  919.         dup systemdict exch known { pop }{ % ifelse
  920.             dup xcheck not { pop }{ %ifelse
  921.             dup unames exch known { pop }{ %ifelse
  922.                 dup where not { %ifelse
  923.                 dup unames exch true put
  924.                 pop % assume it's taken care of
  925.                 }{ %else
  926.                 pop dup load dup type /arraytype eq
  927.                 1 index type /packedarraytype eq or
  928.                   { checkusernames }{ pop } ifelse
  929.                 indent (userdict /) wout dup writename
  930.                 dup unames exch true put
  931.                 load writeANY
  932.                 (put) writeop indent
  933.                 } ifelse
  934.             } ifelse
  935.             } ifelse
  936.         } ifelse
  937.         } ifelse
  938.     } forall
  939.     } bdef
  940.     /arrayusernames { %def
  941.     dup type /arraytype eq 1 index type /packedarraytype eq or { %ifelse
  942.         dup checkusernames
  943.         { arrayusernames } forall
  944.     }{ pop } ifelse
  945.     } bdef
  946.     /writeproc { %def
  947.     ({) writestr
  948.     insideproc exch /insideproc true store
  949.     dup type /arraytype eq 1 index type /packedarraytype eq or { % ifelse
  950.         dup length 20 lt { %ifelse
  951.         { writeANY } forall
  952.         }{ %else
  953.         writeNL /indentlevel ++ indent
  954.         { writeANY writeNL indent } forall
  955.         /indentlevel -- writeNL indent
  956.         } ifelse
  957.     }{ %else
  958.         writename
  959.     } ifelse
  960.     /insideproc exch store
  961.     (} ) writestr
  962.     } bdef
  963.     /typedict 12 dict def
  964.     typedict begin
  965.     /stringtype {
  966.         dup 0 get 0 eq 1 index dup length 1 sub get 0 eq or {
  967.         (<) wout fd exch writehexstring (> ) wout
  968.         }{ writePSstring } ifelse
  969.     } bdef
  970.     /arraytype { %def
  971.         % dup checkusernames
  972.         dup xcheck { %ifelse
  973.         writeproc
  974.         }{ %else
  975.         /CNT 1 store
  976.         dup length 20 lt { %ifelse
  977.             ([ ) wout { writeANY } forall (] ) wout
  978.         }{ %else
  979.             ([) writeop /indentlevel ++
  980.             { indent writeANY writeNL } forall
  981.             /indentlevel -- indent (] ) wout
  982.         } ifelse
  983.         } ifelse
  984.     } bdef
  985.     /packedarraytype /arraytype load def
  986.     /dicttype { %def
  987.               % safety: 1 add (needed for User Fonts)
  988.         dup maxlength 1 add writenum (dict begin) writeop indent
  989.         { %forall
  990.         exch writeANY writeANY (def ) writeop indent
  991.         } forall (currentdict end ) wout
  992.     } bdef
  993.     /integertype { writenum } def
  994.     /realtype { writenum } def
  995.     /nulltype { pop (null ) wout } def
  996.     /operatortype { %def
  997.         insideproc { %ifelse
  998.         writename
  999.         }{ %else
  1000.         (/) wout writename (load) writestr
  1001.         } ifelse
  1002.     } bdef
  1003.     /nametype { %def
  1004.         dup xcheck not { (/) wout dup unames exch true put } if
  1005.         writename
  1006.     } bdef
  1007.     end % typedict
  1008.     /writeANY { %def 
  1009.     dup type dup typedict exch known { %ifelse
  1010.         typedict exch get exec
  1011.     }{ %else
  1012.         pop writename
  1013.     } ifelse
  1014.     } bdef
  1015.     % The following writes an escaped string that may contain special chars.
  1016.     % It regenerates the (\035string) notation.
  1017.     /wordfix { %def        % (string) :
  1018.     (\() search { %ifelse
  1019.         rparenfix (\\\() wout pop wordfix
  1020.     }{ rparenfix } ifelse
  1021.     } bdef
  1022.     /rparenfix { %def
  1023.     (\)) search { %ifelse
  1024.         binaryfix (\\\)) wout pop rparenfix
  1025.     }{ binaryfix } ifelse
  1026.     } bdef
  1027.     /str1 1 string def
  1028.     /longstr 1028 string def
  1029.     /writetomark { %def
  1030.     counttomark -1 0 { %for
  1031.         longstr exch exch put
  1032.     } for
  1033.     } bdef
  1034.     /binaryfix { %def
  1035.     dup false exch { %forall
  1036.         dup 128 gt 1 index 32 lt or { %ifelse
  1037.         str1 exch 0 exch put pop true exit
  1038.         }{ pop } ifelse
  1039.     } forall
  1040.     { %ifelse    % depending on whether num>128 was found
  1041.         str1 search {
  1042.         quotefix        % string previous to num>128
  1043.         (\\) wout        % the backslash
  1044.                     % write suspicious char as octal
  1045.         0 get 8 scratch cvrs    % padding with leading 0 as needed
  1046.         dup length 3 exch sub { (0) wout } repeat wout
  1047.         binaryfix        % recurse on rest of string
  1048.         }{
  1049.         (ERROR: search lied in "binaryfix".) r= flush stop
  1050.         } ifelse
  1051.     }{ quotefix } ifelse
  1052.     } bdef
  1053.     /quotefix { %def
  1054.     (\\) search {  %ifelse
  1055.         wout (\\\\) wout pop quotefix
  1056.     }{ wout } ifelse
  1057.     } bdef
  1058.  
  1059. end %adobe_distill
  1060. /setpacking where { pop setpacking } if
  1061. %%EndProcSet
  1062.  
  1063. %%BeginProcSet: distill_graphicstate 1.0 0
  1064. % we don't want packed arrays for all these matrices; set packing later
  1065. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  1066. adobe_distill begin
  1067.  
  1068.   % define a bunch of state variables, then use "store" subsequently
  1069.   % to write into them (to avoid currentdict problems).
  1070.     /mtx matrix def
  1071.     /tmpmtx matrix def
  1072.     /fontmtx matrix def
  1073.     /curfontmtx matrix def
  1074.     /CTM matrix currentmatrix def
  1075.     /normalCTM tmpmtx currentmatrix matrix invertmatrix def
  1076.     /compareCTM matrix currentmatrix def
  1077.     /newCTM matrix def
  1078.     /mtx1 0 def
  1079.     /mtx2 0 def
  1080.     /$normalize {
  1081.     dup tmpmtx copy normalCTM 3 -1 roll concatmatrix
  1082.     } bind def
  1083.     /rot false def
  1084.     /gray currentgray def
  1085.     currentcmykcolor
  1086.     /colK exch def /colY exch def /colM exch def /colC exch def
  1087.     /linewidth currentlinewidth def
  1088.     /linecap currentlinecap def
  1089.     /linejoin currentlinejoin def
  1090.     /miterlimit currentmiterlimit def
  1091.     /screenang null def
  1092.     /screenfreq null def
  1093.     /screenproc null def
  1094.     /closed false def
  1095.     currentdash /dashoff exch def /dasharray exch def
  1096.     /pointX -1 def /pointY -1 def
  1097.     /initfontscale { 1 0 0 1 0 0 $fontscale astore pop } bind def
  1098.     /$fontscale matrix  def
  1099.     /0a 0 def /0b 0 def
  1100.     /X1 0 def /X2 0 def
  1101.     /origfontname null def
  1102.     /currfontdict null def
  1103.     /definefontname null def
  1104.     /tempfontname /Courier def
  1105. %    /defaultfontname substitutefonts { /Courier }{ /Unknown } ifelse def
  1106.     /defaultfontname {
  1107.     /FontType where { %ifelse
  1108.         pop FontType 3 eq {
  1109.         FontInfo /realname get
  1110.         }{ substitutefonts { /Courier }{ /Unknown } ifelse } ifelse
  1111.     }{ %else
  1112.         substitutefonts { /Courier }{ /Unknown } ifelse
  1113.     } ifelse
  1114.     } def
  1115.     /ischarpath false def
  1116.     /currpath newpath hashpath def
  1117.     /pathstr () def
  1118.     /pathbool false def
  1119.     /pathX 0 def /pathY 0 def
  1120.     /lineX 0 def /lineY 0 def
  1121.     /closeX 0 def /closeY 0 def
  1122.     /lcount 0 def /rcount 0 def
  1123.     /REPEAT_LINETO_THRESHOLD 20 def    % point at which repeat loop is used
  1124.     /currX -1 def /currY -1 def
  1125.     /diffX 0 def
  1126.     /gstates 0 def
  1127.     /charpathgstate 0 def
  1128.     /CNT 0 def
  1129.     /showX null def /showY null def
  1130.     /currfont currentfont def
  1131.     /cliphash newpath hashpath def
  1132.     /?simplepath false def
  1133.     /simplepath [ 0 0 0 0 ] def
  1134.  
  1135. /setpacking where { pop currentpacking true setpacking } if
  1136.  
  1137.     /matrixeq { %def        % compares two matrices
  1138.     /mtx2 exch store
  1139.     /mtx1 exch store
  1140.     0 1 5 { %for
  1141.         dup mtx1 exch get
  1142.         exch mtx2 exch get eq
  1143.     } for
  1144.     5 { and } repeat
  1145.     } bdef
  1146.  
  1147.   % procedure definitions for state machinery ---------------
  1148.  
  1149.     /initgstate { %def
  1150.     gsave
  1151.         initgraphics
  1152.         /CTM mtx currentmatrix $normalize store
  1153.         tmpmtx currentmatrix compareCTM matrixeq not {
  1154.         .345 dup 0 dtransform pop 0 idtransform
  1155.         pop ne dup /rot exch store not optimize and /optim exch store
  1156.         } if
  1157.         compareCTM currentmatrix pop
  1158.         /gray currentgray store
  1159.         currentcmykcolor
  1160.         /colK exch store /colY exch store
  1161.         /colM exch store /colC exch store
  1162.         /linewidth currentlinewidth XthruCTM store
  1163.         /linecap currentlinecap store
  1164.         /linejoin currentlinejoin store
  1165.         /miterlimit currentmiterlimit store
  1166.         currentdash /dashoff exch store /dasharray exch store
  1167.         /origfontname /InvalidFont store
  1168.         /definefontname /InvalidFont store
  1169.         initfontscale
  1170.         /currfontdict currentfont store
  1171.         currentscreen
  1172.         /screenproc exch store
  1173.         /screenang exch store
  1174.         /screenfreq exch store
  1175.         /cliphash clippath hashpath store    % Wed Dec 28 12:41:07 1988
  1176.     grestore
  1177.     } bdef % initgstate
  1178.     /forcegstate { %def
  1179.     % after save & restore, you may have to explicitly "undo" anything
  1180.     % that was done within the saved context.  Since save & restore
  1181.     % affect all our state variables, we dump anything that is different
  1182.     % from the default graphics state:
  1183.     /CTM [1.01 0 1.01 0 .5 .5] store
  1184.     /compareCTM [1.01 0 1.01 0 .5 .5] store
  1185.     initfontscale
  1186.     /currfontdict null store
  1187.     /gray null store
  1188.     /colC null store
  1189.     % checkgstate % fontstate
  1190.     } bdef % initgstate
  1191.     /checkgstate { %def
  1192.     graphicstate
  1193.     fontstate
  1194.     } def %checkgstate
  1195.     /checkCTM { %def
  1196.     tmpmtx currentmatrix compareCTM matrixeq not {
  1197.         % /CTM mtx currentmatrix $normalize store
  1198.         CTM currentmatrix $normalize pop
  1199.         compareCTM currentmatrix $normalize pop
  1200.         .345 dup 0 dtransform pop 0 idtransform
  1201.         pop ne dup /rot exch store not optimize and /optim exch store
  1202.     } if
  1203.     } bdef
  1204.     /generalstate { %def
  1205.     stackptr 0 ne { stackshow } if
  1206.     /lastshow false store
  1207.     checkCTM
  1208.     } bdef % generalstate
  1209.     /colorstate { %def
  1210.     mark currentcmykcolor
  1211.     colC colM colY colK 4 { %repeat
  1212.         dup 5 index ne 10 1 roll 8 1 roll
  1213.     } repeat
  1214.     cleartomark or or or {
  1215.         currentcmykcolor
  1216.         /colK exch store /colY exch store
  1217.         /colM exch store /colC exch store
  1218.         colC 0 eq colM 0 eq colY 0 eq and and not { %ifelse % COLOR
  1219.         colC writenum colM writenum colY writenum colK writenum
  1220.         (C) writeop
  1221.         }{ %else                        % GRAY
  1222.         1 colK sub shave writenum (g) writeop
  1223.         } ifelse
  1224.     } if
  1225.     } bdef % colorstate
  1226.     /registerfont { %def
  1227.     dup cachedir exch 20 dict put    % allow 20 point sizes
  1228.     cachedir exch get        % ptsize dict
  1229.     exch fontcount put
  1230.     } bdef
  1231.     /addfontsize { %def
  1232.     cachedir exch get
  1233.     exch fontcount put
  1234.     } bdef
  1235.  
  1236.     /fontstate { %def
  1237.       currentfont null eq not    { %if
  1238.     currentfont dup /ScaleMatrix known not { pop }{ %ifelse
  1239.         begin
  1240.          % determine if anything has changed:
  1241.         tmpmtx currentmatrix compareCTM matrixeq not
  1242.         currfontdict currentfont ne or
  1243.         ScaleMatrix CTM tmpmtx concatmatrix $fontscale matrixeq not or
  1244.         { %if
  1245.           % get and set new font names
  1246.             /origfontname
  1247.             /FontInfo where { %ifelse
  1248.                 pop FontInfo /realname known
  1249.                 { FontInfo /realname get }{ % ifelse
  1250.                 /FontName where { pop FontName }{
  1251.                     defaultfontname
  1252.                 } ifelse
  1253.                 } ifelse
  1254.             }{ %else
  1255.                 /FontName where { pop FontName }{
  1256.                 defaultfontname
  1257.                 } ifelse
  1258.             } ifelse
  1259.             store
  1260.             /definefontname
  1261.             /FontName where { pop FontName }{
  1262.                 defaultfontname
  1263.             } ifelse
  1264.             FontDirectory { %forall
  1265.                 currentdict eq
  1266.                 { exch pop exit }
  1267.                 { pop } ifelse
  1268.             } forall
  1269.             store
  1270.             origfontname hidefontname
  1271.          % check for font reencoding:
  1272.          % The current font is the one required in the distilled
  1273.          % program.  If it is a reeconded font, we must generate
  1274.          % a call to "REMAP", but at the same time let's mark it
  1275.          % so we don't generate too may "REMAP" calls.
  1276.  
  1277.             checksetup generalstate colorstate
  1278.          % worry about reencoding:
  1279.             /FontInfo where { %ifelse
  1280.             pop FontInfo /pleasemap known { %ifelse
  1281.                 FontInfo /pleasemap get cvbool
  1282.             }{ %else
  1283.                 false  % evidently has not been reencoded...
  1284.             } ifelse % leaves a boolean
  1285.             }{ false } ifelse
  1286.             { % if remapping has not been done yet:
  1287.             Encoding hashencoding
  1288.             origfontname findfont /Encoding get hashencoding
  1289.             ne { %ifelse
  1290.                 Encoding hashencoding
  1291.                 STDvec cvnum eq { %ifelse
  1292.                 (stdvec) writestr
  1293.                 origfontname writeRname
  1294.                 origfontname (/) wout writename
  1295.                 ( REMAP) writeop
  1296.                 }{ %else
  1297.                   Encoding hashencoding PAGEvec cvnum eq {
  1298.                   (pagevec) writestr
  1299.                   origfontname writeRname
  1300.                   origfontname (/) wout writename
  1301.                   ( REMAP) writeop
  1302.                   }{ %else
  1303.                   origfontname findfont /Encoding get Encoding
  1304.                   diffencoding writediffencoding
  1305.                   origfontname writeRname
  1306.                   origfontname (/) wout writename
  1307.                   ( RECODE) writeop
  1308.                   } ifelse
  1309.                 } ifelse
  1310.                 /FontInfo where { %if
  1311.                 pop FontInfo /pleasemap known { %if
  1312.                     FontInfo begin
  1313.                         /pleasemap false hidebool
  1314.                     end
  1315.                 } if
  1316.                 } if
  1317.             } if
  1318.             } if % /pleasemap
  1319.          % check font scale change:
  1320.          % This stuff is absolutely horrible....
  1321.             ScaleMatrix CTM $fontscale concatmatrix
  1322.              aload pop                % Xscale 0a 0b Yscale 0 0
  1323.             pop pop 3 1 roll            % X Y 0b 0a
  1324.            % if 0a and 0b are really both 0 ...
  1325.            % and X Y are equal and positive, then you can use
  1326.            % "scalefont", else you have to use "makefont"
  1327.             /0a exch store /0b exch store
  1328.             /X1 exch store /X2 exch store
  1329.              X1 X2            % leave on stack
  1330.             0a 0b eq 0b 0 eq and    % make sure 0's are 0
  1331.              X1 X2 EQ and        % X1 and X2 are equal
  1332.              X1 dup abs eq X2 dup abs eq and    % and positive
  1333.             and
  1334.             { %ifelse
  1335.             pop dup dup round EQ { round } if
  1336.              % if you find it in the "font dict cache"....
  1337.             cachedir definefontname known { %ifelse
  1338.                 cachedir definefontname get dup 2 index known {
  1339.                 exch get (F) wout writenum
  1340.                 (F) writeop
  1341.                 }{ %else
  1342.                 pop
  1343.                 /fontcount ++
  1344.                 dup definefontname addfontsize
  1345.                 (/F) wout fontcount writenum %+ cvnum writenum
  1346.                 writenum
  1347.                 origfontname
  1348.                 /FontInfo where { %ifelse
  1349.                     pop FontInfo /pleasemap known { %ifelse
  1350.                     FontInfo /pleasemap get cvbool
  1351.                     }{ false } ifelse % leaves a boolean
  1352.                 }{ false } ifelse
  1353.                 Encoding hashencoding
  1354.                 origfontname findfont /Encoding get
  1355.                 hashencoding ne and
  1356.                 { %ifelse
  1357.                     writeRname
  1358.                 }{ (/) wout writename } ifelse
  1359.                 (DF) writeop
  1360.                 } ifelse
  1361.             }{ %else if you DON'T find the name in the cache
  1362.                 /fontcount ++
  1363.                 dup definefontname registerfont
  1364.                 (/F) wout fontcount writenum
  1365.                 writenum
  1366.                 origfontname
  1367.                 /FontInfo where { %ifelse
  1368.                 pop FontInfo /pleasemap known { %ifelse
  1369.                     FontInfo /pleasemap get cvbool not
  1370.                 }{ false } ifelse % leaves a boolean
  1371.                 }{ false } ifelse
  1372.                 Encoding hashencoding
  1373.                 origfontname findfont /Encoding get
  1374.                 hashencoding ne and
  1375.                 { %ifelse
  1376.                 writeRname
  1377.                 }{ (/) wout writename } ifelse
  1378.                 (DF) writeop
  1379.             } ifelse
  1380.             }{ %else
  1381.              % need either "makefont" or rotated coordinate system
  1382.             pop pop $fontscale aload pop curfontmtx astore
  1383.             dup 4 ScaleMatrix 4 get put
  1384.             dup 5 ScaleMatrix 5 get put  % no translate
  1385.             writenumarray
  1386.             origfontname
  1387.             /FontInfo where {
  1388.                 pop FontInfo /pleasemap known
  1389.             }{ false } ifelse { %ifelse
  1390.                 writeRname
  1391.             }{ (/) wout writename } ifelse
  1392.             (MF) writeop
  1393.             } ifelse
  1394.             /currfontdict currentfont store
  1395.         } if % anything has changed
  1396.         end
  1397.     } ifelse
  1398.     beginsetup cvbool not {
  1399.         generalstate
  1400.         colorstate
  1401.     } if
  1402.       } if
  1403.     } bdef %fontstate
  1404.  
  1405.     /graphicstate { %def
  1406.     checksetup
  1407.     generalstate
  1408.     colorstate
  1409.     linewidth currentlinewidth XthruCTM ne {
  1410.         /linewidth currentlinewidth XthruCTM store
  1411.         linewidth shave writenum (w) writeop
  1412.     } if
  1413.     linecap currentlinecap ne {
  1414.         /linecap currentlinecap store
  1415.         linecap writenum (setlinecap) writeop
  1416.     } if
  1417.     linejoin currentlinejoin ne {
  1418.         /linejoin currentlinejoin store
  1419.         linejoin writenum (j) writeop
  1420.     } if
  1421.     miterlimit currentmiterlimit ne {
  1422.         /miterlimit currentmiterlimit store
  1423.         miterlimit shave writenum (setmiterlimit) writeop
  1424.     } if
  1425.     currentdash dashoff ne exch dasharray ne or {
  1426.         currentdash /dashoff exch store /dasharray exch store
  1427.         fd ([) writestring
  1428.         dasharray { XthruCTM writenum } forall
  1429.         fd (] ) writestring
  1430.         dashoff XthruCTM writenum (d) writeop
  1431.     } if
  1432.     gsave
  1433.       % don't clip to degenerate paths of any kind:
  1434.         newpath clippath hashpath cliphash ne { %if
  1435.         mark { pathbbox } stopped not {
  1436.             exch 4 -1 roll sub abs 1 gt
  1437.             3 1 roll sub abs 1 gt and { % if
  1438.             writepath
  1439.             (clip newpath) writeop
  1440.             /cliphash hashpath store
  1441.             } if
  1442.         } if cleartomark
  1443.         } if
  1444.     grestore
  1445.     currentscreen
  1446.     /screenproc load ne exch screenang ne or exch screenfreq ne or { %if
  1447.         currentscreen
  1448.         /screenproc exch store
  1449.         /screenang exch store
  1450.         /screenfreq exch store
  1451.         screenfreq writenum screenang writenum writeNL
  1452.         /screenproc load
  1453.         dup type /arraytype eq
  1454.         1 index type /packedarraytype eq or { %ifelse
  1455.         checkusernames
  1456.         }{ pop } ifelse
  1457.         /screenproc load writeproc
  1458.         (setscreen) writeop
  1459.     } if
  1460.     } bdef %graphicstate
  1461.  
  1462. end %adobe_distill
  1463. /setpacking where { pop setpacking } if
  1464. %%EndProcSet
  1465.  
  1466. %%BeginProcSet: distill_optimize 1.0 0
  1467. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  1468. adobe_distill begin
  1469.   % These procedures implement an optimization scheme for recognizing
  1470.   % sequences of "show" operations that could be optimized into calls
  1471.   % to "widthshow" (or just "show" with a longer string body).  In
  1472.   % order to accomplish this, we have implemented a stack to store
  1473.   % string bodies until they are flushed by a font change, a change
  1474.   % in Y coordinate, or an inter-string space that is inconsistent.
  1475.   % When comparing coordinates for equality, anything with the given
  1476.   % tolerance is accepted as being equal (to combat roundoff error).
  1477.     /tolerance .05 ifnotdef
  1478.     /EQ { sub abs tolerance le } bdef
  1479.     /stack 250 array def
  1480.     /stackptr 0 def
  1481. /setpacking where { pop currentpacking true setpacking } if
  1482.     /push { %def
  1483.     stackptr 0 eq { % if
  1484.         currentpoint thruCTM
  1485.         /showY exch store /showX exch store
  1486.     } if
  1487.     /stackptr stackptr 1 add store
  1488.       stackptr 249 ge { (STACK OVERFLOW!) r= flush exit } if
  1489.     stack stackptr 3 -1 roll put
  1490.     } bdef
  1491.     /pull { %def
  1492.     stack stackptr get
  1493.     /stackptr stackptr dup 0 gt { 1 sub } if store
  1494.     } bdef
  1495.  
  1496.     /*save systemdict /save get def
  1497.     /save { % def
  1498.     stackshow    % in case there's anything pending....
  1499.     *save
  1500.     } bdef
  1501.  
  1502.     /*restore systemdict /restore get def
  1503.     /restore { % def
  1504.     % after save & restore, you may have to explicitly "undo" anything
  1505.     % that was done within the saved context.  Since save & restore
  1506.     % affect all distillery state variables, we dump anything different
  1507.     % from the default graphics state:
  1508.     stackshow    % in case there's anything pending....
  1509.       currentlinecap    % 5
  1510.       currentlinewidth    % 4
  1511.       currentgray        % 3
  1512.       currentmiterlimit    % 2
  1513.       currentlinejoin    % 1
  1514.         6 -1 roll *restore
  1515.       setlinejoin        % 1
  1516.       setmiterlimit        % 2
  1517.       setgray        % 3
  1518.       setlinewidth        % 4
  1519.       setlinecap        % 5
  1520.     forcegstate % checkgstate %graphicstate
  1521.     } bdef
  1522.  
  1523.     /stackshow { %def
  1524.     stackptr 0 ne { %if
  1525.         messages {
  1526.         (stackshow: ) d=
  1527.         1 1 stackptr { (  ) pr= stack exch get == } for
  1528.         } if
  1529. %         currfont /FontType known {
  1530. %         currfont /FontType get 3 eq {
  1531. %             ?distilling false setdistill
  1532. %         } if
  1533. %         } if
  1534.         stackptr 1 eq { %ifelse
  1535.         %- if there is only one string, use "show":
  1536.         pull writePSstring
  1537.         showX showY writepair (T) writeop
  1538.         }{ %else
  1539.         %- otherwise, build single string (with \b to use W):
  1540.         diffX 0 EQ not { % if
  1541.             gsave        % figure out widthshow value
  1542.             currfont setfont
  1543.             diffX (\b) stringwidth CTM dtransform pop sub
  1544.             grestore
  1545.             writenum (0) writestr (\b) 0 get writenum
  1546.             (\\b)    % padding character
  1547.         }{ % else
  1548.             ()        % empty padding character
  1549.         } ifelse
  1550.         (\() wout
  1551.         1 1 stackptr 1 sub { % for
  1552.             stack exch get wordfix dup wout
  1553.         } for
  1554.         pop        % padding character
  1555.         pull wordfix
  1556.         (\)) wout writeNL
  1557.         showX showY writepair
  1558.         %- if diffX is 0, don't use "widthshow":
  1559.         diffX 0 EQ { (T) }{ (W) } ifelse writeop
  1560.         } ifelse
  1561.         /stackptr 0 store
  1562. %         currfont /FontType known {
  1563. %         currfont /FontType get 3 eq { setdistill } if
  1564. %         } if
  1565.     } if
  1566.     } bdef
  1567.  
  1568.     /setcurrpoint { %def
  1569.     currentpoint thruCTM
  1570.     /currY exch store /currX exch store
  1571.     } bdef % setcurrpoint
  1572.  
  1573. end %adobe_distill
  1574. /setpacking where { pop setpacking } if
  1575. %%EndProcSet
  1576.  
  1577. %%BeginProcSet: distill_paintops 1.0 0
  1578. /setpacking where { pop currentpacking true setpacking } if
  1579. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  1580. adobe_distill begin
  1581.  
  1582.   % text operators
  1583.     /sameYcoords { %def
  1584.       % this is pulled out of the "show" proc for readability; it is
  1585.       % not used anywhere else
  1586.     currentfont currfont ne { %ifelse
  1587.         stackshow fontstate push
  1588.     }{ %else
  1589.         currentpoint thruCTM pop
  1590.         currX sub dup diffX EQ { %ifelse
  1591.         pop     % dup'ed value
  1592.         push
  1593.         }{ %else
  1594.         diffX -1 eq { %ifelse
  1595.             /diffX exch store push
  1596.         }{ % else
  1597.             pop stackshow fontstate
  1598.             /diffX -1 store push
  1599.         } ifelse
  1600.         } ifelse
  1601.     } ifelse
  1602.     } bdef
  1603.  
  1604.     /*stringwidth /stringwidth load def
  1605.     /stringwidth { %def
  1606.     false setdistill *stringwidth true setdistill
  1607.     } bdef
  1608.     /show { %def
  1609.     checkCTM currentpoint thruCTM ?box
  1610.     optim { %ifelse
  1611.         dup length 0 eq { pop } { %ifelse
  1612.         dup            % save string for use at the end
  1613.         lastshow not { %ifelse
  1614.             stackshow fontstate
  1615.             /currfont currentfont store
  1616.             push
  1617.             /diffX -1 store
  1618.         }{ % else
  1619.           % don't optimize if matrix is different...
  1620.             tmpmtx currentmatrix compareCTM matrixeq
  1621.             currentpoint thruCTM exch pop
  1622.             currY eq and { %ifelse        Y = Y
  1623.             sameYcoords
  1624.             }{ %else currY ne
  1625.             stackshow    % flush the pending show stack
  1626.             fontstate
  1627.             push        % the string (and set showX, showY)
  1628.             /diffX -1 store
  1629.             } ifelse
  1630.             /currfont currentfont store
  1631.         } ifelse %lastshow
  1632.         currentfont /FontType known {
  1633.             currentfont /FontType get 3 eq {
  1634.             false setdistill show true setdistill
  1635.             }{ show } ifelse
  1636.         }{ false setdistill show true setdistill } ifelse
  1637.         setcurrpoint
  1638.         /lastshow true store
  1639.         } ifelse % if length is not 0
  1640.     }{ % else
  1641.         dup length 0 eq { pop } { %ifelse
  1642.         fontstate
  1643.         dup writePSstring currentpoint writeTpair
  1644.         (T) writeop
  1645.         currentfont /FontType known {
  1646.             currentfont /FontType get 3 eq {
  1647.             false setdistill show true setdistill
  1648.             }{ show } ifelse
  1649.         }{ false setdistill show true setdistill } ifelse
  1650.         } ifelse % if operand is not null string
  1651.     } ifelse
  1652.     currentpoint thruCTM ?box
  1653.     } bdef
  1654.  
  1655.     /widthshow { %def
  1656.     checkCTM currentpoint thruCTM ?box
  1657.     optim { %ifelse
  1658.         dup length 0 eq { 4{pop}repeat } { %ifelse
  1659.         4 copy pop pop
  1660.         1 index EQ exch 0.0 EQ and { % ifelse
  1661.             fontstate
  1662.             4 1 roll pop pop pop
  1663.             show    % make sure it's not "bound"
  1664.         }{ %else
  1665.             fontstate
  1666.             4 copy
  1667.             4 2 roll dthruCTM writepair %exch writeXnum writeYnum
  1668.             exch writenum writePSstring currentpoint writeTpair
  1669.             (W) writeop
  1670.             currentfont /FontType known {
  1671.             currentfont /FontType get 3 eq {
  1672.                 false setdistill widthshow true setdistill
  1673.             }{ widthshow } ifelse
  1674.             }{ false setdistill widthshow true setdistill } ifelse
  1675.         } ifelse
  1676.         } ifelse
  1677.     }{ %else
  1678.         % Cx Cy char (string) widthshow
  1679.         dup length 0 eq { 4{pop}repeat } { %ifelse
  1680.         fontstate
  1681.         4 copy
  1682.         % 4 -2 roll exch writeXnum writeYnum exch writenum
  1683.         4 -2 roll dthruCTM writepair exch writenum
  1684.         writePSstring currentpoint writeTpair
  1685.         (W) writeop
  1686.         currentfont /FontType known {
  1687.             currentfont /FontType get 3 eq {
  1688.             false setdistill widthshow true setdistill
  1689.             }{ widthshow } ifelse
  1690.         }{ false setdistill widthshow true setdistill } ifelse
  1691.         } ifelse
  1692.     } ifelse
  1693.     currentpoint thruCTM ?box
  1694.     } bdef
  1695.  
  1696.     /ashow { %bdef
  1697.     checkCTM currentpoint thruCTM ?box
  1698.     optim { %ifelse
  1699.         dup length 0 eq { pop pop pop } { %ifelse
  1700.         3 copy pop
  1701.         1 index EQ exch 0.0 EQ and { % ifelse
  1702.             fontstate
  1703.             3 1 roll pop pop
  1704.             show    % make sure it's not "bound"
  1705.         }{ %else
  1706.             fontstate
  1707.             3 copy
  1708.             3 1 roll dthruCTM writepair
  1709.             writePSstring currentpoint writeTpair
  1710.             (A) writeop
  1711.             currentfont /FontType known {
  1712.             currentfont /FontType get 3 eq {
  1713.                 false setdistill ashow true setdistill
  1714.             }{ ashow } ifelse
  1715.             }{ false setdistill ashow true setdistill } ifelse
  1716.         } ifelse
  1717.         } ifelse
  1718.     }{ %else
  1719.         dup length 0 eq { pop pop pop } { %ifelse
  1720.         fontstate
  1721.         3 copy
  1722.         3 1 roll dthruCTM writepair % exch writeXnum writeYnum
  1723.         writePSstring currentpoint writeTpair
  1724.         (A) writeop
  1725.         currentfont /FontType known {
  1726.             currentfont /FontType get 3 eq {
  1727.             false setdistill ashow true setdistill
  1728.             }{ ashow } ifelse
  1729.         }{ false setdistill ashow true setdistill } ifelse
  1730.         } ifelse
  1731.     } ifelse
  1732.     currentpoint thruCTM ?box
  1733.     } bdef
  1734.  
  1735.     /awidthshow { %def
  1736.     % Cx Cy 32 Ax Ay (string) awidthshow
  1737.     checkCTM currentpoint thruCTM ?box
  1738.     optim { %def
  1739.         dup length 0 eq { 6{pop}repeat } { %ifelse
  1740.         fontstate
  1741.         6 copy 6 1 roll
  1742.         1 index EQ exch 0.0 EQ and { %ifelse
  1743.             4 1 roll 1 index eq exch 0.0 eq and { %leaves 32 (str)
  1744.             8 1 roll 7 { pop } repeat
  1745.             show    % make sure it's not "bound"
  1746.             }{ %else
  1747.             pop pop 3 1 roll pop pop
  1748.             widthshow    % make sure it's not "bound"
  1749.             } ifelse
  1750.         }{ %else
  1751.             pop pop pop pop 6 copy 6 -3 roll pop
  1752.             1 index EQ exch 0.0 EQ and { % ifelse
  1753.             9 3 roll 6 { pop } repeat
  1754.             ashow    % make sure it's not "bound"
  1755.             }{ %else
  1756.             pop pop pop 6 copy
  1757.             6 -2 roll dthruCTM writepair
  1758.             4 -1 roll writenum 3 1 roll dthruCTM writepair
  1759.             writePSstring currentpoint writeTpair
  1760.             (AW) writeop
  1761.             currentfont /FontType known {
  1762.                 currentfont /FontType get 3 eq {
  1763.                 false setdistill awidthshow true setdistill
  1764.                 }{ awidthshow } ifelse
  1765.             }{ false setdistill awidthshow true setdistill } ifelse
  1766.             } ifelse
  1767.         } ifelse
  1768.         } ifelse
  1769.     }{ %else
  1770.         dup length 0 eq { 6{pop}repeat } { %ifelse
  1771.         fontstate
  1772.         6 copy
  1773.         % 6 -2 roll exch writeXnum writeYnum
  1774.         % 4 -1 roll writenum 3 -1 roll writeXnum exch writeYnum
  1775.         6 -2 roll dthruCTM writepair
  1776.         4 -1 roll writenum 3 1 roll dthruCTM writepair
  1777.         writePSstring currentpoint writeTpair
  1778.         (AW) writeop
  1779.             currentfont /FontType known {
  1780.             currentfont /FontType get 3 eq {
  1781.                 false setdistill awidthshow true setdistill
  1782.             }{ awidthshow } ifelse
  1783.             }{ false setdistill awidthshow true setdistill } ifelse
  1784.         } ifelse
  1785.     } ifelse
  1786.     currentpoint thruCTM ?box
  1787.     } bdef
  1788.  
  1789.     /kshow { %def
  1790.     (%AAAAAH: kshow) writeop
  1791.     kshow
  1792.     } bdef
  1793.  
  1794.    % graphics operators
  1795.     /fillguts { %def
  1796.     (starting fill) d=
  1797.     generalstate
  1798.     graphicstate
  1799.     writepath
  1800.     ischarpath { % if
  1801.         pathstr length 0 gt {
  1802.         pathX writenum pathY writenum (m) writeop
  1803.         pathstr writePSstring (false charpath) writeop
  1804.         } if
  1805.         gstates 0 le {
  1806.         /ischarpath false store
  1807.         /closed false store
  1808.         } if
  1809.     } if
  1810.     } bdef
  1811.  
  1812.     /fill { %def
  1813.     ?distilling cvbool { %if
  1814.         fillguts
  1815.         ?simplepath {
  1816.         simplepath aload pop
  1817.         4 2 roll writepair (moveto) writeop writepair (lineto) writeop
  1818.         /?simplepath false store
  1819.         } if
  1820.         (f) writeop
  1821.     } if
  1822.     fill
  1823.     } bdef
  1824.     /eofill { %def
  1825.     ?distilling cvbool { %if
  1826.         fillguts
  1827.         ?simplepath { %ifelse
  1828.         simplepath aload pop
  1829.         4 2 roll writepair (moveto) writeop writepair (lineto) writeop
  1830.         /?simplepath false store
  1831.         } if
  1832.         (eofill) writeop
  1833.     } if
  1834.     eofill
  1835.     } bdef
  1836.  
  1837.     /stroke { %def
  1838.     ?distilling cvbool { %if
  1839.         fillguts
  1840.         ?simplepath { %ifelse
  1841.         generalstate graphicstate
  1842.         simplepath aload pop writepair writepair (l) writeop
  1843.         /?simplepath false store
  1844.         }{ % else
  1845.         closed { (cp ) wout } if
  1846.         (s) writeop
  1847.         } ifelse
  1848.     } if
  1849.     stroke
  1850.     } bdef
  1851.  
  1852.     /clip { %def
  1853.     ?distilling cvbool { %if
  1854.         /lastshow false store
  1855.     } if
  1856.     clip
  1857.     } bdef
  1858.     /eoclip /clip load def
  1859.     /imageguts { % def
  1860.     graphicstate
  1861.     /imageproc exch store
  1862.     /imagematrix exch store
  1863.     /imagedepth exch store
  1864.     /imageheight exch store
  1865.     /imagewidth exch store
  1866.      % set up the call to "image" in the output file:
  1867.     (/imagesave save def) writeop
  1868.     CTM writenumarray (concat) writeop
  1869.     0 0 thruCTM ?box
  1870.     imagewidth imagedepth dup type /booleantype eq { pop 1 } if
  1871.     div imageheight imagematrix itransform thruCTM ?box
  1872.     (/imagebuff) writestr
  1873.     imagedepth dup type /booleantype eq { pop 1 } if
  1874.     imagewidth mul dup dup 8 idiv 8 mul eq {8 idiv}{8 idiv 1 add} ifelse
  1875.     writenum ( string def) writeop
  1876.      % invoke "image" with correct args in output file:
  1877.     imagewidth writenum imageheight writenum
  1878.     imagedepth (     ) cvs writestr
  1879.     imagematrix writenumarray
  1880.     } bdef
  1881.     /image { %def    % width height depth matrix { proc } :
  1882.     ?distilling cvbool { %ifelse
  1883.         imageguts
  1884.         ({ currentfile imagebuff readhexstring pop } image) writeop
  1885.         imagewidth imageheight imagedepth imagematrix
  1886.         { imageproc dup fd exch writehexstring writeNL } image
  1887.         (imagesave restore) writeop
  1888.     }{ image } ifelse
  1889.     } bdef
  1890.     /imagemask { % def    % width height depth matrix { proc } :
  1891.     ?distilling cvbool { %ifelse
  1892.         imageguts
  1893.         ({ currentfile imagebuff readhexstring pop } imagemask) writeop
  1894.         imagewidth imageheight imagedepth imagematrix
  1895.         { imageproc dup fd exch writehexstring writeNL } imagemask
  1896.         (imagesave restore) writeop
  1897.     }{ imagemask } ifelse
  1898.     } bdef
  1899.     % don't actually print the pages...   Fri Feb 17 13:13:10 1989
  1900.     % /*showpage systemdict /showpage get def
  1901.     /*showpage where { pop }{ %ifelse
  1902.     /*showpage /showpage load def
  1903.     } ifelse
  1904.     /showpage { %def
  1905.     stackshow
  1906.     pagecount cvnum scratch cvs wout ( ENDPAGE\n) wout
  1907.     /lastshowpage true hidebool
  1908.     /begunpage false hidebool
  1909.     /PAGEvec 0 hideval
  1910.     *showpage
  1911.     (%%PageTrailer) writeop
  1912.     (%%PageFonts: ) wout
  1913.     pfontcount cvnum 0 eq { writeNL }{ %else
  1914.         pfontcount cvnum 200 lt { %ifelse
  1915.         pagefonts 0 pfontcount cvnum getinterval writeop
  1916.         }{ %else
  1917.         pagefonts (\040) search not { writeop }{ %else
  1918.             writeop    % first one without the %%+
  1919.             { %loop
  1920.             search { (%%+ ) wout writeop }{ %else
  1921.                 (\000) search { writeop pop pop }{ pop } ifelse
  1922.                 exit
  1923.             } ifelse
  1924.             } loop
  1925.         } ifelse
  1926.         } ifelse
  1927.     } ifelse
  1928.     0 1 pfontcount cvnum { pagefonts exch 0 put } for
  1929.     /pfontcount 0 hideval
  1930.     LLx 10000 eq LLy 10000 eq or URx -10000 eq URy -10000 eq or or not {
  1931.         (%%PageBoundingBox: ) wout
  1932.           LLx cvnum writenum LLy cvnum writenum
  1933.           URx cvnum writenum URy cvnum writenum writeNL
  1934.         pageBBox-docBBox
  1935.     } if
  1936.     /LLx 10000 hideval  /LLy 10000 hideval
  1937.     /URx -10000 hideval /URy -10000 hideval
  1938.     % checksetup
  1939.     } bdef
  1940.     /*pathbbox systemdict /pathbbox get def
  1941.     /pathbbox { %def
  1942.     ?distilling cvbool { %if
  1943.         ischarpath { %ifelse
  1944.         gsave
  1945.             { currentpoint } stopped { 0 0 } if
  1946.             systemdict /moveto get exec
  1947.             pathstr false charpath flattenpath *pathbbox
  1948.         grestore
  1949.         }{ %else
  1950.         *pathbbox
  1951.         } ifelse
  1952.     } if
  1953.     } bdef
  1954.     /gsave { % def
  1955.     ?distilling cvbool { /gstates gstates 1 add store } if
  1956.     gsave
  1957.     } bdef
  1958.     /grestore { % def
  1959.     ?distilling cvbool { %if
  1960.         gstates 0 gt { %if
  1961.         /gstates gstates 1 sub store
  1962.         gstates charpathgstate lt { /ischarpath false store } if
  1963.         } if
  1964.     } if
  1965.     grestore
  1966.     } bdef
  1967.     /charpath { %def
  1968.     % need to make sure that when "stroke" or "fill" comes along
  1969.     % that the "charpath" elements are in the right place in the path...
  1970.     %- writepath
  1971.     ?distilling cvbool { %if
  1972.         checkgstate
  1973.         /ischarpath true store
  1974.         /charpathgstate gstates store
  1975.         /pathbool exch store
  1976.         /pathstr exch store
  1977.         { currentpoint } stopped { 0 0 } if thruCTM
  1978.         /pathY exch store /pathX exch store
  1979.         pathstr stringwidth rmoveto
  1980.     } if
  1981.     } bdef
  1982.     /newpath { %def
  1983.     ?distilling cvbool { gstates 0 le { /ischarpath false store } if } if
  1984.     newpath
  1985.     } bdef
  1986.  
  1987. end %adobe_distill
  1988. /setpacking where { pop setpacking } if
  1989. %%EndProcSet: distill_paintops 1.0
  1990.  
  1991. %%BeginProcSet: distill_guessfont 1.0
  1992. /setpacking where { pop currentpacking true setpacking } if
  1993. /adobe_distill dup where { pop pop }{ 165 200 add dict def } ifelse
  1994. adobe_distill begin
  1995.     /*definefont systemdict /definefont get def
  1996.     /definefont { %def
  1997.     % make a dictionary into which to put things
  1998.     % put the ORIGINAL name of the font into that dictionary
  1999.     % put the original FID in that dictionary, for easy comparison
  2000.     dup /FontType known {
  2001.         dup /FontType get 3 eq { %ifelse
  2002.         dup begin
  2003.             includeuserfonts { %if
  2004.             (%%BeginFont: ) wout 1 index writename writeNL
  2005.             currentdict maxlength writenum (dict begin) writeop
  2006.             save
  2007.                 /indentlevel ++
  2008.                 unames /Encoding true put
  2009.                 currentdict { %forall
  2010.                 exch dup /Encoding eq { %ifelse
  2011.                     indent (/) wout writename
  2012.                     writenamearray ( def) writeop indent
  2013.                 }{ %else
  2014.                     % dup unames exch true put
  2015.                     ( /) wout writename writeANY
  2016.                     (def) writeop indent
  2017.                 } ifelse
  2018.                 } forall
  2019.                 currentdict { pop unames exch true put } forall
  2020.                 currentdict { exch pop arrayusernames } forall
  2021.             restore
  2022.             indent (currentdict end\n) wout
  2023.             1 index writeANY (exch definefont pop) writeop
  2024.             (%%EndFont: ) wout 1 index writename writeNL
  2025.             } if
  2026.             currentdict /FontInfo known not
  2027.             currentdict dup length 2 add exch maxlength ge and { %if
  2028.             % make slightly bigger version of current dictionary
  2029.             pop currentdict end
  2030.             dup maxlength 1 add dict begin
  2031.             { def } forall currentdict
  2032.             } if
  2033.             /FontInfo 5 dict def
  2034.             FontInfo begin
  2035.             /realname 2 index def
  2036.             /pleasemap magicbool def
  2037.             /pleasemap false hidebool
  2038.             end
  2039.         end
  2040.         false
  2041.         }{ true } ifelse
  2042.     }{ true } ifelse
  2043.     % previous code leaves either true or false on stack
  2044.     { %if
  2045.         /Dfont exch store
  2046.      % This might be the first time we've ever seen a new
  2047.      % encoding.  If so, let's guess that we'll see lots
  2048.      % more of the vector, and give it the name "stdvec".
  2049.          Dfont begin
  2050.         %gcr FontType 1 eq STDvec cvnum 0 eq and
  2051.             STDvec cvnum 0 eq
  2052.         Encoding StandardEncoding ne and { %if
  2053.             /STDvec Encoding hashencoding hideval
  2054.             fd (/stdvec\n) *writestring
  2055.             STDvec
  2056.             StandardEncoding hashencoding eq { %ifelse
  2057.             fd (StandardEncoding ) *writestring
  2058.             }{ %else
  2059.             Encoding writenamearray
  2060.             } ifelse
  2061.             fd (def\n) *writestring
  2062.             checksetup
  2063.         }{ %else
  2064.             %gcr FontType 1 eq STDvec cvnum 0 eq and
  2065.             STDvec cvnum 0 eq
  2066.             Encoding StandardEncoding ne and { %if
  2067.             /PAGEvec Encoding hashencoding hideval
  2068.             fd (/pagevec\n) *writestring
  2069.             PAGEvec
  2070.             StandardEncoding hashencoding eq { %ifelse
  2071.                 fd (StandardEncoding ) *writestring
  2072.             }{ %else
  2073.                 Encoding writenamearray
  2074.             } ifelse
  2075.             fd (def\n) *writestring
  2076.             checksetup
  2077.             } if
  2078.         } ifelse
  2079.         end
  2080.      % try to find the "real" font in FontDirectory from which this
  2081.      % font was derived, assuming it was reencoded....
  2082.         /tempfontname /Courier store
  2083.         /tempfontname /UnKnownFont store
  2084.         FontDirectory { %forall
  2085.         /Ffont exch store /Fname exch store
  2086.         % if the font was already touched, ignore it:
  2087.         Ffont /FontInfo known { %ifelse
  2088.             Ffont /FontInfo get /realname known not
  2089.         }{ true } ifelse    % leaves boolean
  2090.         { % if
  2091.             % if UniqueID's match, grab it!
  2092.             Dfont /UniqueID known Ffont /UniqueID known and {
  2093.             Dfont /UniqueID get Ffont /UniqueID get eq {
  2094.                 /tempfontname Fname store exit
  2095.             } if
  2096.             } if
  2097.         } if % /realname is not there
  2098.         } forall
  2099.         tempfontname /UnKnownFont eq { %if
  2100.           Dfont begin
  2101.         FontDirectory { %forall
  2102.           /Ffont exch store /Fname exch store
  2103.           % if CharStrings match, then compare FontMatrix.  If
  2104.           % FontMatrix matches or the *second* elements match,
  2105.           % (it might be oblique), then grab it.
  2106.           Dfont /FontType known {
  2107.             FontType 1 eq {
  2108.               Dfont/CharStrings known Ffont/CharStrings known and {
  2109.             Dfont/CharStrings get Ffont/CharStrings get eq {
  2110.               Dfont/FontMatrix known Ffont/FontMatrix known and {
  2111.                 Dfont/FontMatrix get Ffont/FontMatrix get
  2112.                 2 copy eq  3 1 roll
  2113.                 2 get exch 2 get eq or {
  2114.                 /tempfontname Fname store exit
  2115.                 } if
  2116.               } if
  2117.             } if
  2118.               } if
  2119.             } if
  2120.           } if
  2121.         } forall
  2122.           end
  2123.         } if
  2124.         tempfontname /UnKnownFont eq { %if
  2125.           FontDirectory { %forall
  2126.         /Ffont exch store /Fname exch store
  2127.           % if everything matches but some keys, grab it
  2128.           true    % start with "true" on stack
  2129.           Dfont { %forall
  2130.             exch dup /Encoding eq 1 index /FID eq or { %ifelse
  2131.             pop pop
  2132.             }{ % else
  2133.             dup Ffont exch known {
  2134.                 Ffont exch get ne { pop false exit } if
  2135.             }{ pop pop } ifelse
  2136.             } ifelse
  2137.           } forall
  2138.           % use either "true" that was there, or "false" from loop
  2139.           { %if
  2140.               /tempfontname Fname store exit
  2141.           } if
  2142.           } forall
  2143.         } if
  2144.          tempfontname /UnKnownFont eq {
  2145.         Dfont /Encoding get StandardEncoding eq
  2146.         substitutefonts or { %ifelse
  2147.           % If there is no comparable fontdict already there, and
  2148.           % if this is of FontType 1 and has StandardEncoding,
  2149.           % we guess that this is a downloadable font, and ignore it
  2150.             Dfont /FontName known {
  2151.             /tempfontname Dfont /FontName get store
  2152.             }{
  2153.             /tempfontname /Courier store
  2154.             } ifelse
  2155.             (%substituting ) wout tempfontname writename writeNL
  2156.             messages {
  2157.             (substituting: ) pr= tempfontname ==
  2158.             } if
  2159.             Dfont    % needed by *definefont below...
  2160.         }{ %else
  2161.             (ERROR: Couldn't find original fontdict to match: ) print
  2162.             Dfont /FontName get == flush
  2163.             (Fonts in FontDirectory include:) r=
  2164.             FontDirectory { pop (\040) print == } forall flush
  2165.             stop
  2166.         } ifelse
  2167.         } if
  2168.         Dfont dup begin
  2169.         /FontInfo 5 dict def
  2170.         FontInfo begin
  2171.             /realname tempfontname def
  2172.             /pleasemap magicbool def
  2173.             /pleasemap
  2174.             tempfontname findfont /Encoding get
  2175.             StandardEncoding eq
  2176.             hidebool
  2177.         end
  2178.         end
  2179.     } if
  2180.     *definefont
  2181.     } bdef
  2182.  
  2183. end %adobe_distill
  2184. /setpacking where { pop setpacking } if
  2185. %%EndProcSet: distill_guessfont 1.0
  2186.  
  2187. %%BeginProcSet: hacks 0.5
  2188.   % defeat the "transform round exch round exch itransform" trick:
  2189.     /round { } bdef
  2190.     /transform { dup type /arraytype eq { pop } if } bdef
  2191.     /itransform { dup type /arraytype eq { pop } if } bdef
  2192.   % redefine control-D:
  2193.     (\004) { (\n%%EOF) writeop } bdef
  2194. %%EndProcSet: hacks 0.5
  2195.  
  2196.