summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/generic/pstricks/psd-cust.tex
blob: 03441baca4ffc972703b53849e7acecc340d4850 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
%% 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