%
% \iffalse
%%
%% Source File `pspicture.dtx'.
%% Copyright (C) 1992 1999 David Carlisle
%% This file may be distributed under the terms of the LPPL.
%% See 00readme.txt for details.
%%
%
%<*dtx>
\ProvidesFile{pspicture.dtx}
%
%\NeedsTeXFormat{LaTeX2e}
%\ProvidesPackage{pspicture}
%\ProvidesFile{pspicture.drv}
%<*package,driver>
% \fi
% \ProvidesFile{pspicture.dtx}
[1999/04/11/ v2.02 Picture mode via PS specials (DPC)]
%
% \iffalse
%
%<*driver>
\documentclass{ltxdoc}
\begin{document}
\DocInput{pspicture.dtx}
\end{document}
%
% \fi
%
% \GetFileInfo{pspicture.dtx}
% \CheckSum{110}
%
% \changes{1} {1989/05/10}{(Not made widely available)}
% \changes{2} {1992/01/02}{support for dvips added}
% \changes{2.01}{1992/06/16}{First public release}
% \changes{2.02}{1999/04/11}{Fix for `new' docstrip, and LPPL}
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% \title{The \textsf{pspicture} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}}
%
% \author{D. P. Carlisle}
% \date{16 June 1992}
% \maketitle
%
%
% \section{Introduction}
% {\tt pspicture} is a re-implementation, and extension of, \LaTeX's
% {\tt picture} environment, using PostScript |\special|'s. This has
% several advantages, mainly that lines of arbitrary slope and thickness
% may be specified, and there is no limit on the size of the circles
% that may be drawn\footnote{^^A
% There is a certain amount of overlap between this style option and the
% widely available {\tt eepic} option. However when I wrote the first
% version of this, in 1989, I was not aware of {\tt eepic}, and {\tt
% pspicture} has been reasonably popular in Manchester, even
% though {\tt epic} and {\tt eepic} have been installed.}.
%
% One disadvantage is that the picture can no longer be previewed on a
% |dvi| previewer, such as |xdvi|. To help with this problem, a
% companion style option, {\tt texpicture}, may be used while developing
% a document, this uses the standard picture commands as much as
% possible, and silently omits any picture objects that can not be drawn
% with standard \LaTeX.
%
% A second disadvantage, is that a {\tt dvi} file produced with {\tt
% pspicture} will contain embedded |\special| commands. These commands
% will only work with the driver program for which they were intended.
% This makes the {\tt dvi} file less portable. {\tt pspicture} will by
% default use |\special|'s set up for Rokicki's {\tt dvips} program,
% although it should be easy to modify the code to work with other
% PostScript drivers. A {\sc DocStrip} option for a version of {\tt
% dvi2ps} is included with this distribution.
%
% \subsection{Commands Available}{\parskip=\baselineskip\parindent=0pt
% \DescribeMacro{\circle}\DescribeMacro{\circle*}
% Use as described in the \LaTeX\ book but with no maximum diameter.
% The thickness of the circle is altered by the |\linethickness|
% command. The size of the circle produced by |\circle*| is not
% affected by |\linethickness|, so it is not the same as `filling in'
% the circle drawn by |\circle|.
%
% \DescribeMacro{\oval}
% Use as described in the \LaTeX\ book, but as there is no maximum
% diameter for the circular arcs, the oval (in the absence of the
% optional |[tr]| etc) always consists of two semi-circular arcs
% joined by a pair of parallel lines. To obtain a `rectangle with
% rounded corners' the oval command has a second optional argument
% (given first !).\\
% |\oval[20](100,200)[t]|\\
% Produces the top half of an oval with quarter circles of radius
% 20*unitlength.
% If unitlength = 1pt then this is equivalent to the standard oval
% command. In general |\oval[R](x,y)| uses circular arcs of radius
% $\min(R,x/2,y/2)$.
%
% \DescribeMacro{\line}\DescribeMacro{\vector}
% Use as described in the \LaTeX\ book but with no restriction on the
% available slopes. The thickness of a sloping line is altered by the
% |\linethickness| command.
%
% \DescribeMacro{\Line}\DescribeMacro{\Vector}
% New forms of the line and vector commands.\\
% |\put(x1,y1){\Line(x2,y2)}|\\
% produces a line from (x1,y1) to (x1+x2,y1+y2) and similarly for
% |\Vector|.
%
% \DescribeMacro{\Curve}
% Like |\Line| except that it produce a curve!\\
% |\put(x1,y1){\Curve(x2,y2){m}}|\\
% produces a curve from (x1,y1) to (x1+x2,y1+y2). the amount of
% curvature is controlled by m but try $1$ or $-1$ first. m does not
% have to be an integer. Negative numbers curve the opposite way to
% positive numbers.
%
% \DescribeMacro{\thinlines}\DescribeMacro{\thicklines}%
% \DescribeMacro{\linethickness}
% These commands alter the thickness of {\bf all} lines including
% slanted lines and circular arcs.\vspace{\baselineskip}
%
% \DescribeMacro{\arrowlength}
% A new command which specifies the size of the arrowhead drawn by the
% |\vector| and |\Vector| commands. Like |\linethickness| it does not
% get multiplied by |\unitlength|. At present the arrowhead is
% triangular. If a head with curved sides more like the standard
% \LaTeX\ head is required the definition of |!A| in pspicture.ps
% should be altered.
%
% Other {\tt picture} mode commands are not altered by this style, and
% so may be used, just as described in the \LaTeX\ book. These include:
% |\put|, |\multiput|, |\makebox|, |\framebox|, |dashbox| and
% |\shortstack|.
%
% }\newpage\section{Examples}
%
% \noindent A picture built with \LaTeX's line and circle fonts.
%
% \noindent\begin{picture}(300,130)
% \put(0,0){\line(1,2){50}}
% \put(50,50){\vector(1,1){30}}
% \put(50,50){\circle{30}}
% \put(100,50){\circle*{10}}
% \put(150,50){\oval(50,20)[t]}
% \put(150,100){\oval(30,30)[bl]}
%
% ^^A LaTeX does not do these so well
% \put(250,60){\circle{60}}
% \put(250,60){\circle{50}}
%
% \end{picture}
%
% \bigskip
% \def\eatmodule#1>{}
%\eatmodule
%<*x>
\ifcat a\noexpand @\else
\MakePercentComment
\def\ProvidesPackage#1[#2]{}
\def\NeedsTeXFormat#1{}
\makeatletter ^^A This is NOT the usual way to access this
\input{pspicture.sty} ^^A style. It is intended as a style option:
\makeatother ^^A \documentstyle[a4,pspicture]{article}
\MakePercentIgnore
\fi
%\eatmodule
%
%
% \noindent The same picture built with PostScript |\special|'s.
%
% \noindent\begin{picture}(300,130)
% \put(0,0){\line(1,2){50}}
% \put(50,50){\vector(1,1){30}}
% \put(50,50){\circle{30}}
% \put(100,50){\circle*{10}}
% \put(150,50){\oval(50,20)[t]}
% \put(150,100){\oval(30,30)[bl]}
%
% ^^A LaTeX does not do these so well
% \put(250,60){\circle{60}}
% \put(250,60){\circle{50}}
%
% \end{picture}
%
% \bigskip
% \noindent Some extra features not available using the standard picture
% mode.
%
% \noindent\begin{picture}(300,150)
% \put(250,60){\vector(-8,1){50}} ^^A Vector of any slope.
% \put(200,0){\Line(100,100)} ^^A Line command.
% \put(210,100){\Vector(90,10)} ^^A Vector command.
% \put(70,90){\oval(100,70)} ^^A Control over the radius of
% \put(70,90){\oval[10](100,70)} ^^A `corners' of an oval.
% \linethickness{3pt}
% \put(20,20){\circle{20}} ^^A Circles of any thickness and size.
% \put(20,20){\line(10,1){30}} ^^A Sloping lines of any thickness.
%
% \end{picture}
%
% \StopEventually{}
%
% \section{pspicture.sty}
% \begin{macrocode}
%<*package>
% \end{macrocode}
%
% First we set up the code that is specific to the driver program that
% is being used. If the driver can incorporate a header file, define
% |\PS@header| appropriately, |\PS@special| should expand to the format
% for inline PostScript code. The driver should protect this code with a
% (g)save (g)restore pair. dvips is treated specially so that it will be
% the default driver if this file is used without being stripped. If you
% find definitions of these macros which work for the driver you use,
% email me, and I will include them in the next release.
% \begin{macro}{\PS@header}
% Code to include the PostScript header.
% \begin{macrocode}
%<*dvips>
\def\PS@header#1{\special{header=#1}}
%
%\def\PS@header#1{\typeout{Print with the option -i #1}}
\PS@header{pspicture.ps}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\PS@special}
% The format of the |\special| command for inline PostScript.
% \begin{macrocode}
%<*dvips>
\def\PS@special#1{\special{"#1}}
%
%\def\PS@special#1{\special{pstext="#1"}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\strippt}
% Strip the final `pt' off the string returned by |\the|.
% \begin{macrocode}
{\catcode`t=12\catcode`p=12\gdef\noPT#1pt{#1}}
\def\strippt#1{\expandafter\noPT\the#1\space}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@circle}
% Internal name for |\circle|.
% \begin{macrocode}
\def\@circle#1{%
\@tempdimb #1\unitlength
\PS@special{%
\strippt\@wholewidth
\strippt\@tempdimb
!C}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@dot}
% Internal name for |\circle*|.
% \begin{macrocode}
\def\@dot#1{%
\@tempdimb #1\unitlength
\PS@special{%
\strippt\@tempdimb
!D}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\line}
% Line with a \LaTeX\ style slope specification.
% \begin{macrocode}
\def\line(#1,#2)#3{%
\@linelen=#3\unitlength
\PS@special{%
\strippt\@wholewidth
#1
#2
\strippt\@linelen
!L}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\vector}
% Line and arrow head with a \LaTeX\ style slope specification.
% \begin{macrocode}
\def\vector(#1,#2)#3{%
\@linelen=#3\unitlength
\PS@special{%
\strippt\@arrowlength
\strippt\@wholewidth
#1
#2
\strippt\@linelen
!V}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\oval}
% If no optional argument appears, use a default of maximum radius of
% \TeX's maximum length.
% \begin{macrocode}
\def\oval{%
\@ifnextchar[%
{\@ov@l}%
{\count@=\maxdimen \divide\count@ by \unitlength \@ov@l[\count@]}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@ov@l}
% Look for an optional |tlbr| argument.
% \begin{macrocode}
\def\@ov@l[#1](#2,#3){%
\@ifnextchar[{\@oval[#1](#2,#3)}{\@oval[#1](#2,#3)[]}}%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@oval}
% The PostScript version of the |\oval| command will print each quarter
% of the oval separately, each quarter will only be printed if the
% appropriate argument is $1$. An optional argument of |t| causes the
% arguments for the two bottom quarters to be set to $0$, similarly, |r|
% causes the two left quarters to be set to $0$. Thus an argument [tr]
% will set the bottom and left quarters to $0$, resulting in only the
% top right quarter being printed.
% \begin{macrocode}
\def\@oval[#1](#2,#3)[#4]{\begingroup
\@tempdimb #1\unitlength
\@ovxx #2\unitlength
\@ovyy #3\unitlength
\def\r{\def\TL{0 }\def\BL{0 }}%
\def\l{\def\TR{0 }\def\BR{0 }}%
\def\t{\def\BL{0 }\def\BR{0 }}%
\def\b{\def\TL{0 }\def\TR{0 }}%
\def\TL{1 }\def\BL{1 }\def\TR{1 }\def\BR{1 }%
\@tfor\@tempa :=#4\do{\csname\@tempa\endcsname}%
\PS@special{%
\BR\BL\TR\TL
\strippt\@wholewidth
\strippt\@tempdimb
\strippt\@ovxx
\strippt\@ovyy
!O}%
\endgroup}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Line}
% New style |\Line| command.
% \begin{macrocode}
\def\Line(#1,#2){%
\@ovxx #1\unitlength
\@ovyy #2\unitlength
\PS@special{%
\strippt\@wholewidth
\strippt\@ovxx
\strippt\@ovyy
!L2}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Curve}
% Not particularly good, but it will do for now.
% \begin{macrocode}
\def\Curve(#1,#2)#3{%
\@ovxx #1\unitlength
\@ovyy #2\unitlength
\PS@special{%
\strippt\@wholewidth
\strippt\@ovxx
\strippt\@ovyy
#3
!C2}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\Vector}
% New style |\Vector| command.
% \begin{macrocode}
\def\Vector(#1,#2){%
\@ovxx #1\unitlength
\@ovyy #2\unitlength
\PS@special{%
\strippt\@arrowlength
\strippt\@wholewidth
\strippt\@ovxx
\strippt\@ovyy
!V2}}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@arrowlength}
% Length of an arrow head.
% \begin{macrocode}
\newdimen\@arrowlength
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\arrowlength}
% Set the length of an arrow head.
% \begin{macrocode}
\def\arrowlength#1{\@arrowlength #1}
\arrowlength{8pt}
% \end{macrocode}
% \end{macro}
% If this file is used as a {\tt .sty} file without being stripped, we
% want to stop here. The |\endinput| must not be at the beginning of the
% line, or {\sf DocStrip} will stop here as well!.
% \begin{macrocode}
\endinput
% \end{macrocode}
%
% \begin{macrocode}
%
% \end{macrocode}
% \section{texpicture.sty}
% A dummy style file so that documents using {\tt pspicture.sty}
% can be previewed or printed (as much as possible) using a
% dvi (not PostScript) previewer or printer driver.
% Just change `{\tt pspicture}' to `{\tt texpicture}' in the
% |\documentstyle| options list.
% \begin{macrocode}
%<*texsty>
% \end{macrocode}
% \begin{macrocode}
\@warning{texpicture.sty in operation:^^J\@spaces
LaTeX document with pspicture.sty before printing}
% \end{macrocode}
% \begin{macro}{\Line}
% \begin{macro}{\Vector}
% \begin{macro}{\arrowlength}
% \begin{macro}{\Curve}
% Define all these new commands to silently gobble their arguments.
% \begin{macrocode}
\def\Line(#1,#2){}
\def\Vector(#1,#2){}
\def\arrowlength#1{}
\def\Curve(#1,#2)#3{}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\@badlinearg}
% If a vector or line is called with a slope specification that is not
% allowed by standard \LaTeX, |\@badlinearg| is called to produce the
% error message. We do not want to see these errors, so:
% \begin{macrocode}
\def\@badlinearg{}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\oval}
% \begin{macro}{\@@v@l}
% \begin{macro}{\@@vv@l}
% Give the standard |\oval| command another optional argument (which
% will be ignored), to match the extra argument defined in {\tt
% pspicture.sty}.
% \begin{macrocode}
\let\@@v@l\oval
\def\@@@v@l[#1]{\@@v@l}
\def\oval{\@ifnextchar[{\@@@v@l}{\@@v@l}}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \section{pspicture.ps}
% The PostScript header file for use with {\tt pspicture.sty}.
% Probably this should use the PostScript dictionary mechanism, to keep
% identifiers local to this package, but for now, just give them names
% begining with {\tt!}.
% \begin{macrocode}
%<*ps>
% \end{macrocode}
%
% \begin{macro}{!BP}
% PostScript uses \TeX's |bp|, that is $1/72$ of an inch, not \TeX's
% |pt|, $1/72.27$ of an inch, but it is inconvenient to get \TeX\ to
% output in |bp|, so we need to scale the PostScript.
% \begin{macrocode}
/!BP{
72 72.27 div dup scale
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!A}
% Arrow head:\\
% \meta{arrow length} |!A|
% \begin{macrocode}
/!A{
newpath
0 0 moveto
dup neg dup .4 mul rlineto
.8 mul 0 exch rlineto
closepath
fill
} def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!V}
% |\vector(|\meta{x}|,|\meta{y}|)| \\
% \meta{arrow length} \meta{line width} \meta{x} \meta{y}
% \meta{len*unitlength} |!V|
% \begin{macrocode}
/!V{
!BP
/!X exch def
/!y exch def
/!x exch def
newpath
0 0 moveto
!x 0 eq {0 !y 0 lt {!X neg}{!X} ifelse}
{!x 0 lt {!X neg}{!X}ifelse !X !y mul !x abs div} ifelse
lineto
setlinewidth % @wholewidth
currentpoint
stroke
translate
!y !x atan
rotate
!A % @arrowlength
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!L}
% |\line(|\meta{x}|,|\meta{y}|)| \\
% \meta{arrow length} \meta{line width} \meta{x} \meta{y}
% \meta{len*unitlength} |!L|
% \begin{macrocode}
/!L{
!BP
/!X exch def
/!y exch def
/!x exch def
newpath
0 0 moveto
!x 0 eq {0 !y 0 lt {!X neg}{!X} ifelse}
{!x 0 lt {!X neg}{!X}ifelse !X !y mul !x abs div} ifelse
lineto
setlinewidth % @wholewidth
stroke
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!C}
% |\circle{|\meta{diam}|}| \\
% \meta{line width} \meta{diam*unitlength} |!C|
% \begin{macrocode}
/!C{
!BP
0 0 3 2 roll
2 div 0 360 arc
setlinewidth % @wholewidth
stroke
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!D}
% |\circle*{|\meta{diam}|}| \\
% \meta{diam*unitlength} |!D|
% \begin{macrocode}
/!D{
!BP
0 0 3 2 roll
2 div 0 360 arc fill
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!O}
% |\oval[|\meta{max-radius}|](|\meta{x}|,|\meta{y}|)[|\meta{tlbr}|]| \\
% \meta{br}\meta{bl}\meta{tr}\meta{tl}\\
% \meta{line width} \meta{max-radius*unitlength}
% \meta{x*unitlength} \meta{y*unitlength} |!O|\\
% The first four arguments should be either $0$, denoting that that
% quarter should not be drawn, or $1$, to draw a quarter oval.
% \begin{macrocode}
/!O{
!BP
/!y exch 2 div def
/!x exch 2 div def
/!r exch !x !y
% \end{macrocode}
% Ghostscript appears to have a {\tt min} operator, so the following 2
% lines could be coded as {\tt min min}, but it's not in the
% Ref.~Manual, and it doesn't work on my printer!
% \begin{macrocode}
2 copy gt {exch} if pop
2 copy gt {exch} if pop
def
setlinewidth % @wholewidth
1 eq
{newpath
!x neg 0 moveto
!x neg !y 0 !y !r arcto 4 {pop} repeat
0 !y lineto
stroke}if
1 eq
{newpath
!x 0 moveto
!x !y 0 !y !r arcto 4 {pop} repeat
0 !y lineto
stroke}if
1 eq
{newpath
!x neg 0 moveto
!x neg !y neg 0 !y neg !r arcto 4 {pop} repeat
0 !y neg lineto
stroke}if
1 eq
{newpath
!x 0 moveto
!x !y neg 0 !y neg !r arcto 4 {pop} repeat
0 !y neg lineto
stroke}if
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!V2}
% |\Vector(|\meta{x}|,|\meta{y}|)| \\
% \meta{arrow length} \meta{line width} \meta{x*unitlength}
% \meta{y*unitlength} |!V2|
% \begin{macrocode}
/!V2{
!BP
2 copy exch
atan
/a exch def
2 copy
newpath
0 0 moveto
lineto %
3 2 roll
setlinewidth % @wholewidth
stroke
translate %
a rotate
!A % @arrowlength
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!L2}
% |\Line(|\meta{x}|,|\meta{y}|)| \\
% \meta{line width} \meta{x*unitlength} \meta{y*unitlength} |!L2|
% \begin{macrocode}
/!L2{
!BP
newpath
0 0 moveto
lineto %
setlinewidth % @wholewidth
stroke
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{!C2}
% |\Curve(|\meta{x}|,|\meta{y}|){|\meta{$\pm$}|}| \\
% \meta{line width} \meta{x*unitlength} \meta{y*unitlength} \meta{$\pm$}
% |!C2|
% \begin{macrocode}
/!C2{
!BP
/!s exch def
/!y exch def
/!x exch def
newpath
0 0 moveto
0 0
!x 2 div !y 10 div !s mul add
!y 2 div !x 10 div !s mul sub
!x !y
curveto
setlinewidth % @wholewidth
stroke
}def
% \end{macrocode}
% \end{macro}
%
% \begin{macrocode}
%
% \end{macrocode}
%
% \end{document}
% \Finale