%          psfig  Package GENERAL PUBLIC LICENSE
%                         17 Nov 1988
% This file is part of the TeXPS Software Package.

% The TeXPS Software Package is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY.  No author or distributor
% accepts responsibility to anyone for the consequences of using it
% or for whether it serves any particular purpose or works at all,
% unless he says so in writing.  Refer to the TeXPS Software Package
% General Public License for full details.

% Everyone is granted permission to copy, modify and redistribute
% the TeXPS Software Package, but only under the conditions described in the
% TeXPS Software Package General Public License.   A copy of this license is
% supposed to have been given to you along with TeXPS Software Package so you
% can know your rights and responsibilities.  It should be in a
% file named CopyrightLong.  Among other things, the copyright notice
% and this notice must be preserved on all copies.  */

\catcode`\@=11
%
% Changes done by Stephan Bechtolsheim:
% 1. Comments and indentation improved.
% 2. The \special which instructs the driver, is specified here.
% 3. Instead of numerical counter and dimension registers
%    symbolic register names are used.
% 4. scale parameter of \psfig introduced.
%
\def\@SpecialCodeDriver{dvitps: }
%
\newcount\psfc@a
\newcount\psfc@b
\newcount\psfc@c
\newcount\psfc@d
\newcount\psfc@e
\newcount\psfc@f
\newcount\psfc@g
\newcount\psfc@h
\newcount\psfc@i
\newcount\psfc@j
\newcount\psscale@count
\newtoks\psfigtoks@
% A dimension register for temporarily storing a dimension in
% \@pDimenToSpNumber.
\newdimen\psfig@dimen
%
\newwrite\@unused
\def\typeout#1{{\let\protect\string\immediate\write\@unused{#1}}}
% Identifying message is here.
\typeout{psfig/tex 1.4 / TeXPS}
%
% @psdo control structure -- similar to Latex @for.
% I redefined these with different names so that psfig can
% be used with TeX as well as LaTeX, and so that it will not 
% be vunerable to future changes in LaTeX's internal
% control structure.
\def\@nnil{\@nil}
\def\@empty{}
\def\@psdonoop#1\@@#2#3{}
\def\@psdo#1:=#2\do#3{\edef\@psdotmp{#2}\ifx\@psdotmp\@empty \else
    \expandafter\@psdoloop#2,\@nil,\@nil\@@#1{#3}\fi}
\def\@psdoloop#1,#2,#3\@@#4#5{\def#4{#1}\ifx #4\@nnil \else
       #5\def#4{#2}\ifx #4\@nnil \else#5\@ipsdoloop #3\@@#4{#5}\fi\fi}
\def\@ipsdoloop#1,#2\@@#3#4{\def#3{#1}\ifx #3\@nnil 
       \let\@nextwhile=\@psdonoop \else
      #4\relax\let\@nextwhile=\@ipsdoloop\fi\@nextwhile#2\@@#3{#4}}
\def\@tpsdo#1:=#2\do#3{\xdef\@psdotmp{#2}\ifx\@psdotmp\@empty \else
    \@tpsdoloop#2\@nil\@nil\@@#1{#3}\fi}
\def\@tpsdoloop#1#2\@@#3#4{\def#3{#1}\ifx #3\@nnil 
       \let\@nextwhile=\@psdonoop \else
      #4\relax\let\@nextwhile=\@tpsdoloop\fi\@nextwhile#2\@@#3{#4}}
% 
\def\psdraft{%
	\def\@psdraft{0}
	%\typeout{draft level now is \@psdraft \space.}
}
\def\psfull{%
	\def\@psdraft{100}
	%\typeout{draft level now is \@psdraft \space.}
}
\psfull
\newif\if@prologfile
\newif\if@postlogfile
\newif\if@noisy
\def\pssilent{%
	\@noisyfalse
}
\def\psnoisy{%
	\@noisytrue
}
\psnoisy
% These are for the option list: 
%	a specification of the form a = b maps to calling \@p@@sa{b}.
\newif\if@bbllx
\newif\if@bblly
\newif\if@bburx
\newif\if@bbury
\newif\if@height
\newif\if@width
\newif\if@rheight
\newif\if@rwidth
\newif\if@clip
\newif\if@scale
\newif\if@verbose
\def\@p@@sclip#1{\@cliptrue}
\def\@p@@sfile#1{% 
	%\typeout{file is #1}
	\def\@p@sfile{#1}% 
}
\def\@p@@sfigure#1{% 
	\def\@p@sfile{#1}% 
}
% \@pDimenToSpNumber
% ==================
% Convert a dimension into scaled points.
% #1: the name of macro which will expand to the dimension in
% 		scaled points, without the unit 'sp' though, i.e. as a pure
% 		integer.
% #2: the dimension (not a dimension register, use
% 		\the if dimension is stored in a dimension register).
\def\@pDimenToSpNumber #1#2{% 
	\psfig@dimen = #2\relax
	\edef#1{\number\psfig@dimen}%
}
\def\@p@@sbbllx#1{% 
	%\typeout{bbllx is #1}
	\@bbllxtrue
	\@pDimenToSpNumber{\@p@sbbllx}{#1}% 
}
\def\@p@@sbblly#1{% 
	%\typeout{bblly is #1}
	\@bbllytrue
	\@pDimenToSpNumber{\@p@sbblly}{#1}% 
}
\def\@p@@sbburx#1{%
	%\typeout{bburx is #1}
	\@bburxtrue
	\@pDimenToSpNumber{\@p@sbburx}{#1}% 
}
\def\@p@@sbbury#1{%
	%\typeout{bbury is #1}
	\@bburytrue
	\@pDimenToSpNumber{\@p@sbbury}{#1}% 
}
\def\@p@@sheight#1{
	\@heighttrue
	\@pDimenToSpNumber{\@p@sheight}{#1}% 
	%\typeout{Height is \@p@sheight}
}
\def\@p@@swidth#1{%
	%\typeout{Width is #1}
	\@widthtrue
	\@pDimenToSpNumber{\@p@swidth}{#1}% 
}
\def\@p@@srheight#1{
	%\typeout{Reserved height is #1}
	\@rheighttrue
	\@pDimenToSpNumber{\@p@srheight}{#1}% 
}
\def\@p@@srwidth#1{
	%\typeout{Reserved width is #1}
	\@rwidthtrue
	\@pDimenToSpNumber{\@p@srwidth}{#1}% 
}
\def\@p@@ssilent#1{% 
	\@verbosefalse
}
\def\@p@@sscale #1{% 
	\def\@p@scale{#1}%
	\@scaletrue
}

\def\@p@@sprolog#1{\@prologfiletrue\def\@prologfileval{#1}}
\def\@p@@spostlog#1{\@postlogfiletrue\def\@postlogfileval{#1}}
\def\@cs@name#1{\csname #1\endcsname}
\def\@setparms#1=#2,{\@cs@name{@p@@s#1}{#2}}
%
% Initialize the defaults.
%
\def\ps@init@parms{
	\@bbllxfalse \@bbllyfalse
	\@bburxfalse \@bburyfalse
	\@heightfalse \@widthfalse
	\@rheightfalse \@rwidthfalse
	\@scalefalse
	\def\@p@sbbllx{}\def\@p@sbblly{}
	\def\@p@sbburx{}\def\@p@sbbury{}
	\def\@p@sheight{}\def\@p@swidth{}
	\def\@p@srheight{}\def\@p@srwidth{}
	\def\@p@sfile{}
	\def\@p@scost{10}
	\def\@sc{}
	\@prologfilefalse
	\@postlogfilefalse
	\@clipfalse
	\if@noisy
		\@verbosetrue
	\else
		\@verbosefalse
	\fi
}
%
% Go through the options setting things up.
%
\def\parse@ps@parms#1{
 	\@psdo\@psfiga:=#1\do
	   {\expandafter\@setparms\@psfiga,}% 
}
%
% Compute bb height and width
%
\newif\ifno@bb
\newif\ifnot@eof
\newread\ps@stream
\def\bb@missing{%
	\if@verbose
		\typeout{psfig: searching \@p@sfile \space  for bounding box}% 
	\fi
	\openin\ps@stream=\@p@sfile
	\no@bbtrue
	\not@eoftrue
	\catcode`\%=12
	\ifeof\ps@stream
		\errmessage{FATAL ERROR: cannot open \@p@sfile}
	\fi
	\loop
		\read\ps@stream to \line@in
		\global\psfigtoks@=\expandafter{\line@in}
		\ifeof\ps@stream \not@eoffalse \fi
		%\typeout{ looking at :: \the\psfigtoks@ }
		\@bbtest{\psfigtoks@}
		\if@bbmatch\not@eoffalse\expandafter\bb@cull\the\psfigtoks@\fi
	\ifnot@eof \repeat
	\catcode`\%=14
}	
\newif\if@bbmatch

% '% ' becomes a regular character for a very short time.
{ 
	\catcode`\%=12
	\gdef\@bbtest#1{\expandafter\@a@\the#1%%BoundingBox:\@bbtest\@a@}
	\global\long\def\@a@#1%%BoundingBox:#2#3\@a@{\ifx\@bbtest#2\@bbmatchfalse\else\@bbmatchtrue\fi}
}

\long\def\bb@cull#1 #2 #3 #4 #5 {
	\@pDimenToSpNumber{\@p@sbbllx}{#2bp}%
	\@pDimenToSpNumber{\@p@sbblly}{#3bp}%
	\@pDimenToSpNumber{\@p@sbburx}{#4bp}%
	\@pDimenToSpNumber{\@p@sbbury}{#5bp}%
	\no@bbfalse
}
% Compute \@bbw and \@bbh, the width and height of the
% bounding box.
\def\compute@bb{
	\no@bbfalse
	\if@bbllx \else \no@bbtrue \fi
	\if@bblly \else \no@bbtrue \fi
	\if@bburx \else \no@bbtrue \fi
	\if@bbury \else \no@bbtrue \fi
	\ifno@bb \bb@missing \fi
	\ifno@bb
		\errmessage{\string\compute@bb: FATAL ERROR: no bounding box
		supplied (in \string\psfig) or found (in PostScript file).}
	\fi
	% Now compute the size of the bounding box.
	\psfc@c=\@p@sbburx
	\psfc@b=\@p@sbbury
	\advance\psfc@c by -\@p@sbbllx
	\advance\psfc@b by -\@p@sbblly
	\edef\@bbw{\number\psfc@c}
	\edef\@bbh{\number\psfc@b}
	%\typeout{\string\compute@bb: bbh = \@bbh, bbw = \@bbw}
}
%
% \in@hundreds performs #1 * (#2 / #3) correct to the hundreds,
%		then leaves the result in \@result.
%
\def\in@hundreds #1#2#3{% 
	\psfc@g=#2
	\psfc@d=#3
	\psfc@a=\psfc@g	% First digit #2/#3.
	\divide\psfc@a by \psfc@d
	\psfc@f=\psfc@a
	\multiply\psfc@f by \psfc@d
	\advance\psfc@g by -\psfc@f
	\multiply\psfc@g by 10
	\psfc@f=\psfc@g	% Second digit of #2/#3.
	\divide\psfc@f by \psfc@d
	\psfc@j=\psfc@f
	\multiply\psfc@j by \psfc@d
	\advance\psfc@g by -\psfc@j
	\multiply\psfc@g by 10
	\psfc@j=\psfc@g	% Third digit.
	\divide\psfc@j by \psfc@d
	\psfc@h=#1\psfc@i=0
	\psfc@e=\psfc@h
	\multiply\psfc@e by \psfc@a
	\advance\psfc@i by \psfc@e
	\psfc@e=\psfc@h
	\divide\psfc@e by 10
	\multiply\psfc@e by \psfc@f
	\advance\psfc@i by \psfc@e
	%
	\psfc@e=\psfc@h
	\divide\psfc@e by 100
	\multiply\psfc@e by \psfc@j
	\advance\psfc@i by \psfc@e
	%
	\edef\@result{\number\psfc@i}
}
% Scale a value #1 by the current scaling factor and reassign the new
% scaled value.
\def\@ScaleInHundreds #1{% 
	\in@hundreds{#1}{\@p@scale}{100}%
	\edef#1{\@result}% 
}
% 
%
% Compute width from height.
\def\compute@wfromh{
	% computing : width = height * (bbw / bbh)
	\in@hundreds{\@p@sheight}{\@bbw}{\@bbh}
	%\typeout{ \@p@sheight * \@bbw / \@bbh, = \@result }
	\edef\@p@swidth{\@result}
	%\typeout{w from h: width is \@p@swidth}
}
% Compute height from width.
\def\compute@hfromw{
	% computing : height = width * (bbh / bbw)
	\in@hundreds{\@p@swidth}{\@bbh}{\@bbw}
	%\typeout{ \@p@swidth * \@bbh / \@bbw = \@result }
	\edef\@p@sheight{\@result}
	%\typeout{h from w : height is \@p@sheight}
}
% Compute height and width, i.e. \@p@sheight and \@p@swidth.
\def\compute@handw{
	% If height is given.
	\if@height 
		% If width is given
		\if@width
		\else
			% Height, no width: compute width.
			\compute@wfromh
		\fi
	\else 
		% No height.
		\if@width
			% Width is given, no height though: compute it.
			\compute@hfromw
		\else
			% Neither width no height is give.
			\edef\@p@sheight{\@bbh}
			\edef\@p@swidth{\@bbw}
		\fi
	\fi
}
% Compute the amount of space to reserve. Unless defined
% using rheight and rwidth when \psfig is called, these values
% default to \@p@sheight and \@p@swidth.
\def\compute@resv{
	\if@rheight \else \edef\@p@srheight{\@p@sheight} \fi
	\if@rwidth \else \edef\@p@srwidth{\@p@swidth} \fi
}
%
%
% \psfig
% ======
% usage: \psfig{file=, height=, width=, bbllx=, bblly=, bburx=, bbury=,
%			rheight=, rwidth=, clip=, scale=}
%
% "clip=" is a switch and takes no value, but the `=' must be present.
\def\psfig#1{% 
	\vbox {%
		\ps@init@parms
		\parse@ps@parms{#1}
		% Compute any missing sizes.
		\compute@bb
		\compute@handw
		\compute@resv
		\if@scale
			\if@verbose
				\typeout{psfig: scaling by \@p@scale}% 
			\fi
			% We now scale the width and height as reported to the PS printer.
			\@ScaleInHundreds{\@p@swidth}% 
			\@ScaleInHundreds{\@p@sheight}% 
			\@ScaleInHundreds{\@p@srwidth}% 
			\@ScaleInHundreds{\@p@srheight}% 
		\fi
		%
		\ifnum\@p@scost<\@psdraft
			\if@verbose
				\typeout{psfig: including \@p@sfile \space}
			\fi
			% Cause "psfig.pro" to be included during pass0 processing of
			% the driver.
			\special{\@SpecialCodeDriver Include0 "psfig.pro"}
			% Now generate the instruction to include the figure.
			\special{% 
				\@SpecialCodeDriver Literal
				"\@p@swidth \space
				\@p@sheight \space
				\@p@sbbllx \space
				\@p@sbblly \space
				\@p@sbburx \space
				\@p@sbbury \space
				startTexFig \space"}
			% If clipping you may generate a message now.
			\if@clip
				\if@verbose
					\typeout{(clip)}
				\fi
				\special{\@SpecialCodeDriver Literal "doclip \space"}
			\fi
			\if@prologfile
			    \special{\@SpecialCodeDriver Include0 "\@prologfileval"}
			\fi
			\special{\@SpecialCodeDriver Include1 "\@p@sfile"}
			\if@postlogfile
			    \special{\@SpecialCodeDriver Include0 "\@postlogfileval"}
			\fi
			\special{\@SpecialCodeDriver Literal "endTexFig \space" }
			% End of \special generation.
			% Create a vbox to reserve the proper amount of space for the figure.
			\vbox to \@p@srheight true sp{
				\hbox to \@p@srwidth true sp{}
				\vss
			}
		\else
			% Draft modus: reserve the space for the figure and print the
			% path name.
			\vbox to \@p@srheight true sp{
				\hbox to \@p@srwidth true sp{%
					\if@verbose
						\@p@sfile
					\fi
				}
				\vss
			}
		\fi
	}
}

\catcode`\@=12
