%%% -*- Mode: TeX -*-

%%%% Merging PostScript Illustrations

%%% These TeX macros enable easy insertion of PostScript
%%% Illustrations into documents produced by TeX and LaTeX.
%%% The illustrations are automatically sized.

%%% Source locations at the MIT AI Laboratory
%%%   Canonical Source
%%%     Trix      /tx/glr/tex/psadobe/psadobe.tex
%%%   slaved copies
%%%     Wheaties: /master/usr/lib/tex/localinputs/psadobe.tex
%%%     Reagan:   SYS:TEX;INPUTS;PSADOBE.TEX

%%% References
%%%   Adobe Systems, Inc
%%%     PostScript Language Reference Manual
%%%     Addison-Wesley, 1986
%%%     Appendix C, pages 279-286
%%%   DVILASER/PS User Manual
%%%     ArborText, Inc, 1987

%%% Copyright Gerald Roylance 1987, 1989
%%%   This file may be copied or distributed as long as this
%%%   copyright notice is not removed.

%%% Bugs and Fixes
%%%   add ArborText support [GLR, 3/89]
%%%   clear out some junk [GLR, 3/89]
%%%   convert \mag to a float at runtime [Rich, 12/87]
%%%   removed spurious cr's in psadobeextract, -bb, -header [Rich, 11/87]
%%%   make psfile switch to horizontal mode 
%%%     now LaTeX \leavevmode isn't needed [GLR, 11/87]
%%%   changed \errmessage to \message for file not found
%%%     in \psadobeheader [Rich, 12/87]
%%%   added \psadobepercent [Rich, 12/87]
%%%   added \xpsadobe and \xpsadobepercent [Rich, 2/22]
%%%   Changed default ArborText support to \ArborTextfalse [Rpaul, 09/92]
%%%   added/fixed \ifdvips for dvips support [Rpaul, 01/95]


%%%% Usage

%%% To load the macros, use
%%%       \input{psadobe}
%%% The macros are read from TeX's default input area.

%%% To insert an illustration, use
%%%       \psadobe{filename.ps}
%%% The expression is treated exactly like a character.
%%% You will probably want to center it or use other positioning
%%% commands.  The illustration is also magnified by the \mag
%%% parameter.  If you don't want this magnification, then
%%% use
%%%       \psadobenomag{filename.ps}

%%% Insert a PostScript file, scaling by current value of \mag and a given percent
%%% N.B. The first argument is the *percent* scaling (i.e. 100 is normal size).
%%%
%%%       \psadobepercent{percent}{filename.ps}

%%% The filename may present some difficulty because
%%% both TeX and the dvi converter use the filename.
%%% You may have to provide a fully qualified filename.

%%% The illustrations to be inserted with autosizing must use
%%% the Adobe PostScript File Structuring Conventions (PFSC).
%%% These macros do automatic sizing of the inserted illustation
%%% by reading the PFSC header comment of the PostScript file.
%%% The Lisp Machine program Illustrate produces the correct format.
%%% Most MacIntosh programs do not provide a tight bounding box.

%%% In order to insert a PostScript file, the .dvi to PostScript
%%% converter must implement \special{PSFILE...} or use ArborText's
%%% \special{ps:...} commands.  The MIT AI Lab uses the Unix program
%%% dvi2ps (available from ???) and a Lisp Machine dvi converter
%%% (available from the Symbolics LispMachine Users' Group).

%%% If your converter cannot understand a set of special commands,
%%% then after loading psadobe turn off the appropriate set of specials:
%%%       \dvitopsfalse
%%%       \ArborTextfalse

%%% For further information, see MIT AI Laboratory Working Paper 299a.


%%%% Subroutines

\newif\ifdvitops   \dvitopstrue         % include PSFILE specials
\newif\ifArborText \ArborTextfalse      % include ArborText specials
\newif\ifdvips     \dvipstrue	        % dvips compatibility (or dvi2ps)

%%% The fundamental insertion macro.  This inserts a PostScript file
%%% putting the origin at (x,y) and building a TeX box whose
%%% size is (w,h).  Nothing fancy is done.  x,y,w,h are TeX dimensions.
%%% The magnification m is a string that should be something like 1.40.
%%%
%%% psfile(x,y,w,h,m,filename)
%%%
\newbox\psvoid
%%%
\def\psfile#1#2#3#4#5#6{%
  \unhbox\psvoid%       switch to horizontal mode (just like a letter would)
  \hbox to #3{%         make a box w wide
     \kern-#1%          offset the illustration's x-pos
     \vbox to #4{%      make a box h tall
        \vfil%          push the special down to the bottom
        \kern#2%        offset by the illustration's y-pos
        \ifdvitops\special{psfile=#6 hscale=#5 vscale=#5}\fi%
        \ifArborText%
           \special{ps::[asis,begin]
                0 SPB
                /PSFileCheckPoint save def
                /showpage  {} def
                /erasepage {} def
                /copypage  {} def
                /letter    {} def
                /note      {} def
                /legal     {} def
                /ledger    {} def
                /11x17     {} def
                /a3        {} def
                /a4        {} def
                Xpos Ypos translate
                #5 dup scale
                /xdefaultmatrix matrix currentmatrix def
                /defaultmatrix {xdefaultmatrix exch copy} def
                /initmatrix    {xdefaultmatrix setmatrix} def
                /initgraphics
                  {initmatrix newpath initclip
                   1 setlinewidth 0 setlinecap 0 setlinejoin
                   [] 0 setdash 0 setgray 10 setmiterlimit} def
                }%
           \special{ps: plotfile #6 asis}%
           \special{ps::[asis,end]
                PSFileCheckPoint restore
                0 SPE }%
           \fi%
        \kern-#2}%      unoffset y
     \kern#1\hfil%      unoffset x and push the special left
     }}

%%% Convert an integer to a floating point string.
%%% This gross hack works if \mag < 10000
%%%
\newcount\float \float=\mag \ifdvips \divide\float by 10 \else \advance\float by 10000\fi%
\def\floater#1#2#3#4#5{#2.#3#4#5}


%%%% Parse a PostScript Header

%%% The header looks like
%%%
%%%    %!PS-Adobe-1.0
%%%    %%Creator: Illustrate Version 11.0
%%%    %%CreationDate: 6/23/87 17:35:01
%%%    %%Pages: 1
%%%    %%BoundingBox: 466.12912 718.63934 612.0283 792.0283
%%%    %%EndComments
%%%
%%% *** Should complain if #2 is (atend)

%%% Dimensions of the illustration
\newdimen\psadobex
\newdimen\psadobey
\newdimen\psadobew
\newdimen\psadobeh

\newif\ifpsadobeflag

\newread\psadobefile

%%% psadobeextract(junk llx lly urx ury true)

\catcode`\%=12

\def\psadobeextract #1 #2 #3 #4 #5%%BoundingBox:\heaven#6{\global\psadobex= #2 #6bp
  \global\psadobey= #3 #6bp
  \global\psadobew= #4 #6bp
  \global\advance\psadobew by -\psadobex
  \global\psadobeh= #5 #6bp
  \global\advance\psadobeh by -\psadobey}

\def\psadobebb #1%%BoundingBox:#2\EOL#3{\ifx#2\heaven \psadobeflagtrue 
    \else \psadobeflagfalse \psadobeextract#2{#3}\closein\psadobefile\fi}

\def\psadobeheader#1#2{\openin\psadobefile=#2
  \global\psadobex= 72 #1bp
  \global\psadobey= 72 #1bp
  \global\psadobew= 72 #1bp
  \global\psadobeh= 72 #1bp
  \ifeof\psadobefile
    \message{Postscript file not found: #2.}\else
    \begingroup
       \catcode`\%=12
       \loop
          \ifeof\psadobefile
             \psadobeflagfalse
             \errmessage{No Bounding Box information in #2}\else
             \read\psadobefile to \line
             \expandafter\psadobebb\line %%BoundingBox:\heaven\EOL{#1}\fi
          \ifpsadobeflag\repeat
       \catcode`\%=14
       \endgroup\fi}

\catcode`\%=14


%%%% Automatic Sizing of a PostScript File

%%% These are the advertised calls.
%%%   Everything else may change.

%%% Insert a Postscript file with scaling by \mag
%%%
\def\psadobe#1{\xpsadobe{#1}{#1}}

%%% Following auxiliary definition allows a different pathname syntax
%%% to be used on Tex'ing machine versus dvi->ps machine.
%%% [Float mag has to be done here because of expansion problems -- CR]
%%%
\def\xpsadobe#1#2{%
  \psadobeheader{}{#1}%
  {\ifdvips\float=\mag \divide\float by 10\else\float=\mag \advance\float by 10000\fi%
   \psfile{\psadobex}{\psadobey}{\psadobew}%
         {\psadobeh}{\ifdvips\the\float\else{\expandafter\floater\the\float}\fi}{#2}}}


%%% Insert a PostScript file without scaling by \mag
%%%   read header using true dimensions
%%%   insert the file with a magnification of 1
\def\psadobenomag#1{%
  \psadobeheader{true}{#1}%
  \psfile{\psadobex}{\psadobey}{\psadobew}{\psadobeh}{\ifdvips{100}\else{1.000}\fi}{#1}}

%%% Insert a PostScript file, scaling by current value of \mag and a given percent
%%% N.B. The first argument is the *percent* scaling (i.e. 100 is normal size).
%%%
%%% psadobepercent( percent, file )

\def\psadobepercent#1#2{\xpsadobepercent{#1}{#2}{#2}}

%%% Similarly to \xpsadobe

\def\xpsadobepercent#1#2#3{%
  \psadobeheader{}{#2}%
  \global\divide\psadobex by 100\global\multiply\psadobex by #1%
  \global\divide\psadobey by 100\global\multiply\psadobey by #1%
  \global\divide\psadobew by 100\global\multiply\psadobew by #1%
  \global\divide\psadobeh by 100\global\multiply\psadobeh by #1%
  {\ifdvips\float=#1\else\float=\mag \multiply\float by #1\divide\float by 100
        \advance\float by 10000\fi
          \psfile{\psadobex}{\psadobey}{\psadobew}%
               {\psadobeh}{\ifdvips\the\float\else\expandafter\floater\the\float\fi}{#3}}}

\endinput
