%% BEGIN psd-cust.tex

\part{Custom graphics\label{P-custom}}

\Section{The basics}

PSTricks contains a large palette of graphics objects, but sometimes you need
something special. For example, you might want to shade the region between two
curves. The
  \Mac  \pscustom`*[par]'{commands}
command lets you ``roll you own'' graphics object.

Let's review how PostScript handles graphics. A \emph{path} is a line, in the
mathematical sense rather than the visual sense. A path can have several
disconnected segments, and it can be open or closed. PostScript has various
operators for making paths. The end of the path is called the \emph{current
point}, but if there is no path then there is no current point. To turn the
path into something visual, PostScript can \emph{fill} the region enclosed by
the path (that is what \p{fillstyle} and such are about), and \emph{stroke} the
path (that is what \p{linestyle} and such are about).

At the beginning of \n\pscustom, there is no path. There are various commands
that you can use in \n\pscustom{} for drawing paths. Some of these (the open
curves) can also draw arrows.  \n\pscustom{} fills and strokes the path at the
end, and for special effects, you can fill and stroke the path along the way
using \n\fill{} and \n\stroke{} (see below).

\begin{drivers}
\n\pscustom{} uses \n\pstverb{} and \n\pstunit. There are system-dependent
limits on how long the argument of "\special" can be. You may run into this
limit using \n\pscustom{} because all the PostScript code accumulated by
\n\pscustom{} is the argument of a single "\special" command.
\end{drivers}

\Section{Parameters}

You need to keep the separation between drawing, stroking and filling paths in
mind when setting graphics parameters. The \p{linewidth} and \p{linecolor}
parameters affect the drawing of arrows, but since the path commands do not
stroke or fill the paths, these parameters, and the \p{linestyle},
\p{fillstyle} and related parameters, do not have any other effect (except
that in some cases \p{linewidth} is used in some calculations when drawing the
path). \n\pscustom{} and \n\fill{} make use of \p{fillstyle} and related
parameters, and \n\pscustom{} and \n\stroke{} make use of p{linestyle} and
related parameters.

For example, if you include
\begin{LVerbatim}
  \psline[linewidth=2pt,linecolor=blue,fillstyle=vlines]{<-}(3,3)(4,0)
\end{LVerbatim}
in \n\pscustom, then the changes to \p{linewidth} and \p{linecolor} will
affect the size and color of the arrow but not of the line when it is stroked,
and the change to \p{fillstyle} will have no effect at all.

The \p{shadow}, \p{border}, \p{doubleline} and \p{showpoints} parameters are
disabled in \n\pscustom, and the \p{origin} and \p{swapaxes} parameters only
affect \n\pscustom{} itself, but there are commands (described below) that let
you achieve these special effects.

The \p{dashed} and \p{dotted} line styles need to know something about the
path in order to adjust the dash or dot pattern appropriately. You can give
this information by setting the
\begin{Ex}
  \Par{linetype=int}
\end{Ex}
parameter. If the path contains more than one disconnected segment, there is
no appropriate way to adjust the dash or dot pattern, and you might as well
leave the default value of \p{linetype}. Here are the values for simple paths:
\begin{center}
\begin{tabular}{cl}
  \emph{Value}      & \emph{Type of path}\\
  0                 & Open curve without arrows.\\
  -1                & Open curve with an arrow at the beginning.\\
  -2                & Open curve with an arrow at the end.\\
  -3                & Open curve with an arrow at both ends.\\
  1                 & Closed curve with no particular symmetry.\\
  $n$\textgreater 1 & Closed curve with $n$ symmetric segments.
\end{tabular}
\end{center}

\Section{Graphics objects}

You can use most of the graphics objects in \n\pscustom. These draw paths and
making arrows, but do not fill and stroke the paths.

There are three types of graphics objects:
\begin{description}
\item[Special]
  Special graphics objects include \n\psgrid, \n\psdots, \n\qline{} and
\n\qdisk. You cannot use special graphics objects in \n\pscustom.

\item[Closed]
  You are allowed to use closed graphics objects in \n\pscustom, but their
effect is unpredictable.\footnote{%
The closed objects never use the current point as an coordinate, but typically
they will close any existing paths, and they might draw a line between the
currentpoint and the closed curved.}
Usually you would use the open curves plus \n\closepath{} (see below) to draw
closed curves.

\item[Open]The open graphics objects are the most useful commands for drawing
paths with \n\pscustom. By piecing together several open curves, you can draw
arbitrary paths. The rest of this section pertains to the open graphics
objects.
\end{description}

  By default, the open curves draw a straight line between the current point,
if it exists, and the beginning of the curve, except when the curve begins
with an arrow. For example
\begin{MEx*}(3,3)
  \pscustom{%
    \psarc(0,0){1.5}{5}{85}
    \psarcn{->}(0,0){3}{85}{5}}
\end{MEx*}

Also, the following curves make use of the current point, if it exists, as a
first coordinate:
\begin{quote}
  \n\psline{} and \n\pscurve.\\
  The plot commands, with the "line" or "curve" \p{plotstyle}.\\
  \n\psbezier\, if you only include three coordinates.\\
\end{quote}
For example:
\begin{MEx*}(4,3)
  \pscustom[linewidth=1.5pt]{%
    \psplot[plotstyle=curve]{.67}{4}{2 x div}
    \psline(4,3)}
\end{MEx*}
We'll see later how to make that one more interesting. Here is another example
\begin{MEx*}(4,3)
  \pscustom{%
    \psline[linearc=.2]{|-}(0,2)(0,0)(2,2)
    \psbezier{->}(2,2)(3,3)(1,0)(4,3)}
\end{MEx*}

However, you can control how the open curves treat the current point with the
\begin{Ex}
  \Par{liftpen=0/1/2}
\end{Ex}
parameter.

If \p{liftpen=0}, you get the default behavior described above. For example
\begin{MEx*}(4,3)
  \pscustom[linewidth=2pt,fillstyle=solid,fillcolor=gray]{%
    \pscurve(0,2)(1,2.5)(2,1.5)(4,3)
    \pscurve(4,1)(3,0.5)(2,1)(1,0)(0,.5)}
\end{MEx*}

If \p{liftpen=1}, the curves do not use the current point as the first
coordinate (except \n\psbezier, but you can avoid this by explicitly including
the first coordinate as an argument). For example:
\begin{MEx*}(4,3)
  \pscustom[linewidth=2pt,fillstyle=solid,fillcolor=gray]{%
    \pscurve(0,2)(1,2.5)(2,1.5)(4,3)
    \pscurve[liftpen=1](4,1)(3,0.5)(2,1)(1,0)(0,.5)}
\end{MEx*}

If \p{liftpen=2}, the curves do not use the current point as the first
coordinate, and they do not draw a line between the current point and the
beginning of the curve. For example
\begin{MEx*}(4,3)
  \pscustom[linewidth=2pt,fillstyle=solid,fillcolor=gray]{%
    \pscurve(0,2)(1,2.5)(2,1.5)(4,3)
    \pscurve[liftpen=2](4,1)(3,0.5)(2,1)(1,0)(0,.5)}
\end{MEx*}

Later we will use the second example to fill the region between the two
curves, and then draw the curves.

\Section{Safe tricks}

The commands described under this heading, which can only be used in
\n\pscustom, do not run a risk of PostScript errors (assuming your document
compiles without \TeX{} errors).

Let's start with some path, fill and stroke commands:
\begin{description}

\mitem  \newpath

Clear the path and the current point.

\mitem  \moveto(coor)

  This moves the current point to \c{}.

\mitem  \closepath

  This closes the path, joining the beginning and end of each piece (there may
be more than one piece if you use \n\moveto).\footnote{%
Note that the path is automatically closed when the region is filled. Use
\n\closepath{} if you also want to close the boundary.}

\mitem  \stroke`[par]'

  This strokes the path (non-destructively). \n\pscustom{} automatically
strokes the path, but you might want to stroke it twice, e.g., to add a
border. Here is an example that makes a double line and adds a border (this
example is kept so simple that it doesn't need \n\pscustom{} at all):
\begin{MEx*}(4,3)
  \psline(0,3)(4,0)
  \pscustom[linecolor=white,linewidth=1.5pt]{%
    \psline(0,0)(4,3)
    \stroke[linewidth=5\pslinewidth]
    \stroke[linewidth=3\pslinewidth,linecolor=black]}
\end{MEx*}

\mitem  \fill`[par]'

  This fills the region (non-destructively). \n\pscustom{} automatically fills
the region as well.

\mitem  \gsave

  This saves the current graphics state (i.e., the path, color, line width,
coordinate system, etc.) \n\grestore{} restores the graphics state. \n\gsave{}
and \n\grestore{} must be used in pairs, properly nested with respect to \TeX{}
groups. You can have have nested \n\gsave-\n\grestore{} pairs.

\mitem  \grestore

  See above.

Here is an example that fixes an earlier example, using \n\gsave{} and
\n\grestore:
\begin{MEx}(4,3)
  \psline{<->}(0,3)(0,0)(4,0)
  \pscustom[linewidth=1.5pt]{
    \psplot[plotstyle=curve]{.67}{4}{2 x div}
    \gsave
      \psline(4,3)
      \fill[fillstyle=solid,fillcolor=gray]
    \grestore}
\end{MEx}
Observe how the line added by "\psline(4,3)" is never stroked, because it is
nested in "\gsave" and "\grestore".

Here is another example:
\begin{MEx*}(4,3)
  \pscustom[linewidth=1.5pt]{
    \pscurve(0,2)(1,2.5)(2,1.5)(4,3)
    \gsave
      \pscurve[liftpen=1](4,1)(3,0.5)(2,1)(1,0)(0,.5)
      \fill[fillstyle=solid,fillcolor=gray]
    \grestore}
  \pscurve[linewidth=1.5pt](4,1)(3,0.5)(2,1)(1,0)(0,.5)
\end{MEx*}
Note how I had to repeat the second \n\pscurve{} (I could have repeated it
within \n\pscustom, with \p{liftpen=2}), because I wanted to draw a line
between the two curves to enclose the region but I didn't want this line to be
stroked.
\end{description}

The next set of commands modify the coordinate system.
\begin{description}

\mitem  \translate(coor)

  Translate coordinate system by \c{}. This shifts everything that comes later
by \c{}, but doesn't affect what has already been drawn.

\mitem  \scale{num1 `num2'}

  Scale the coordinate system in both directions by <num1>, or horizontally by
<num1> and vertically by <num2>.

\mitem  \rotate{angle}

  Rotate the coordinate system by <angle>.

\mitem  \swapaxes

  Switch the x and y coordinates. This is equivalent to
\begin{LVerb}
  \rotate{-90}
  \scale{-1 1 scale}
\end{LVerb}

\mitem  \msave

  Save the current coordinate system. You can then restore it with
\n\mrestore. You can have nested \n\msave-\n\mrestore{} pairs. \n\msave{} and
\n\mrestore{} do not have to be properly nested with respect to \TeX{} groups or
\n\gsave{} and \n\grestore. However, remember that \n\gsave{} and \n\grestore
also affect the coordinate system. \n\msave-\n\mrestore{} lets you change the
coordinate system while drawing part of a path, and then restore the old
coordinate system without destroying the path. \n\gsave-\n\grestore, on the
other hand, affect the path and all other componments of the graphics state.

\mitem  \mrestore

  See above.
\end{description}

And now here are a few shadow tricks:
\begin{description}
\mitem  \openshadow`[par]'

Strokes a replica of the current path, using the various shadow parameters.

\mitem  \closedshadow`[par]'

Makes a shadow of the region enclosed by the current path as if it were opaque
regions.

\mitem  \movepath(coor)

Moves the path by \c{}. Use \n\gsave-\n\grestore{} if you don't want to lose
the original path.
\end{description}

\Section{Pretty safe tricks}

The next group of commands are safe, \emph{as long as there is a current
point}!

\begin{description}
\mitem  \lineto(coor)

  This is a quick version of "\psline(<coor>)".

\mitem  \rlineto(coor)

  This is like \n\lineto, but \c{} is interpreted relative to the current
point.

\mitem  \curveto\c1\c2\c3

  This is a quick version of "\psbezier"\c1\c2\c3.

\mitem  \rcurveto\c1\c2\c3

  This is like \n\curveto, but \c1, \c2 and \c3 are interpreted relative to
the current point.
\end{description}

\Section{For hackers only}

For PostScript hackers, there are a few more commands. Be sure to read
Appendix \ref{S-raw} before using these. Needless to say:
\begin{Warning}
Misuse of the commands in this section can cause PostScript errors.
\end{Warning}

 The PostScript environment in effect with \n\pscustom{} has one unit equal to
one \TeX{} "pt".

\begin{description}

\mitem  \code{code}
  Insert the raw PostScript code.

\mitem  \dim{dim}

  Convert the PSTricks dimension to the number of "pt"'s, and inserts it in
the PostScript code.

\mitem  \coor\c1`\c2...\cn'

Convert one or more PSTricks coordinates to a pair of numbers (using "pt"
units), and insert them in the PostScript code.

\mitem  \rcoor\c1`\c2...\cn'

Like \n\coor, but insert the coordinates in reverse order.

\mitem  \file{file}

  This is like \n\code, but the raw PostScript is copied verbatim (except
comments delimited by "%") from <file>.

\mitem  \arrows{arrows}

  This defines the PostScript operators "ArrowA" and "ArrowB" so that
\begin{LVerb}
  x2 y2 x1 y1 ArrowA
  x2 y2 x1 y1 ArrowB
\end{LVerb}
each draws an arrow(head) with the tip at \c1 and pointing from \c2. "ArrowA"
leaves the current point at end of the arrowhead, where a connect line should
start, and leaves \c2 on the stack. "ArrowB" does not change the current
point, but leaves
\begin{LVerb}
  x2 y2 x1' y1'
\end{LVerb}
on the stack, where \c{1'} is the point where a connecting line should join.
To give an idea of how this work, the following is roughly how PSTricks draws
a bezier curve with arrows at the end:
\begin{MEx*}(4,3)
  \pscustom{
    \arrows{|->}
    \code{
      80 140 5 5 ArrowA
      30 -30 110 75 ArrowB
      curveto}}
\end{MEx*}

\mitem  \setcolor{color}

  Set the color to <color>.

\end{description}

\endinput

%% END psd-cust.tex
