summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/generic/pgf/text-en/pgfmanual-en-pgfsys-paths.tex
blob: 0b87a7d108b51d3ecafbc637cb422023611d1dfa (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
% Copyright 2003 by Till Tantau <tantau@cs.tu-berlin.de>.
%
% This program can be redistributed and/or modified under the terms
% of the LaTeX Project Public License Distributed from CTAN
% archives in directory macros/latex/base/lppl.txt.

\section{The Soft Path Subsystem}

\label{section-soft-paths}

\makeatletter


This section describes a set of commands for creating \emph{soft
  paths} as opposed to the commands of the previous section, which
created \emph{hard paths}. A soft path is a path that can still be
``changed'' or ``molded.'' Once you (or the \pgfname\ system) is
satisfied with a soft path, it is turned into a hard path, which can
be inserted into the resulting |.pdf| or |.ps| file.

Note that the commands described in this section are ``high-level'' in
the sense that they are not implemented in driver files, but rather
directly by the \pgfname-system layer. For this reason, the commands for
creating soft paths do not start with |\pgfsys@|, but rather with
|\pgfsyssoftpath@|. On the other hand, as a user you will never use
these commands directly, so they are described as part of the
low-level interface. 



\subsection{Path Creation Process}

When the user writes a command like |\draw (0bp,0bp) -- (10bp,0bp);|
quite a lot happens behind the scenes:
\begin{enumerate}
\item
  The frontend command is translated by \tikzname\ into commands
  of the basic layer. In essence, the command is translated to
  something like
\begin{codeexample}[code only]
\pgfpathmoveto{\pgfpoint{0bp}{0bp}}
\pgfpathlineto{\pgfpoint{10bp}{0bp}}
\pgfusepath{stroke}
\end{codeexample}
\item
  The |\pgfpathxxxx| command do \emph{not} directly call ``hard''
  commands like |\pgfsys@xxxx|. Instead, the command |\pgfpathmoveto|
  invokes a special command called |\pgfsyssoftpath@moveto| and
  |\pgfpathlineto| invokes |\pgfsyssoftpath@lineto|. 

  The |\pgfsyssoftpath@xxxx| commands, which are described below,
  construct a soft path. Each time such a command is used, special
  tokens are added to the end of an internal macro that stores the
  soft path currently being constructed. 
\item
  When the |\pgfusepath| is encountered, the soft path stored in
  the internal macro is ``invoked.'' Only now does a special macro
  iterate over the soft path. For each line-to or move-to
  operation on this path it calls an appropriate |\pgfsys@moveto| or
  |\pgfsys@lineto| in order to, finally, create the desired hard path,
  namely, the string of literals in the |.pdf| or |.ps| file.
\item
  After the path has been invoked, |\pgfsys@stroke| is called to
  insert the literal for stroking the path.
\end{enumerate}

Why such a complicated process? Why not have |\pgfpathlineto| directly
call |\pgfsys@lineto| and be done with it? There are two reasons:
\begin{enumerate}
\item
  The \pdf\ specification requires that a path is not interrupted by
  any non-path-construction commands. Thus, the following code will
  result in a corrupted |.pdf|:
\begin{codeexample}[code only]
\pgfsys@moveto{0}{0}
\pgfsys@setlinewidth{1}
\pgfsys@lineto{10}{0}
\pgfsys@stroke
\end{codeexample}
  Such corrupt code is \emph{tolerated} by most viewers, but not
  always. It is much better to create only (reasonably) legal code.
\item
  A soft path can still be changed, while a hard path is fixed. For
  example, one can still change the starting and end points of a soft
  path or do optimizations on it. Such transformations are not possible
  on hard paths.
\end{enumerate}


\subsection{Starting and Ending a Soft Path}

No special action must be taken in order to start the creation of a
soft path. Rather, each time a command like |\pgfsyssoftpath@lineto|
is called, a special token is added to the (global) current soft path
being constructed.

However, you can access and change the current soft path. In this way,
it is possible to store a soft path, to manipulate it, or to invoke
it.

\begin{command}{\pgfsyssoftpath@getcurrentpath\marg{macro name}}
  This command will store the current soft path in \meta{macro name}.
\end{command}

\begin{command}{\pgfsyssoftpath@setcurrentpath\marg{macro name}}
  This command will set the current soft path to be the path stored in
  \meta{macro name}. This macro should store a path that has
  previously been extracted using the |\pgfsyssoftpath@getcurrentpath|
  command and has possibly been modified subsequently.
\end{command}

\begin{command}{\pgfsyssoftpath@invokecurrentpath}
  This command will turn the current soft path in a ``hard'' path. To
  do so, it iterates over the soft path and calls an appropriate
  |\pgfsys@xxxx| command for each element of the path. Note that the
  current soft path is \emph{not changed} by this command. Thus, in
  order to start a new soft path after the old one has been invoked
  and is no longer needed, you need to set the current soft path to be
  empty. This may seems strange, but it is often useful to immediately
  use the last soft path again.
\end{command}

\begin{command}{\pgfsyssoftpath@flushcurrentpath}
  This command will invoke the current soft path and then set it to be
  empty. 
\end{command}



\subsection{Soft Path Creation Commands}

\begin{command}{\pgfsyssoftpath@moveto\marg{x}\marg{y}}
  This command appends a ``move-to'' segment to the current soft
  path. The coordinates \meta{x} and \meta{y} are given as normal
  \TeX\ dimensions.

  \example One way to draw a line:
\begin{codeexample}[code only]
\pgfsyssoftpath@moveto{0pt}{0pt}
\pgfsyssoftpath@lineto{10pt}{10pt}
\pgfsyssoftpath@flushcurrentpath
\pgfsys@stroke
\end{codeexample}
\end{command}

\begin{command}{\pgfsyssoftpath@lineto\marg{x}\marg{y}}
  Appends a ``line-to'' segment to the current soft path. 
\end{command}

\begin{command}{\pgfsyssoftpath@curveto\marg{a}\marg{b}\marg{c}\marg{d}\marg{x}\marg{y}}
  Appends a ``curve-to'' segment to the current soft path with controls
  $(a,b)$ and $(c,d)$.
\end{command}

\begin{command}{\pgfsyssoftpath@rect\marg{lower left x}\marg{lower left y}\marg{width}\marg{height}}
  Appends a rectangle segment to the current soft path. 
\end{command}

\begin{command}{\pgfsyssoftpath@closepath}
  Appends a ``close-path'' segment to the current soft path. 
\end{command}




\subsection{The Soft Path Data Structure}

A soft path is stored in a standardized way, which makes it possible to
modify it before it becomes ``hard.'' Basically, a soft path is a long
sequence of triples. Each triple starts with a \emph{token} that
identifies what is going on. This token is followed by two dimensions in
braces. For example, the following is a soft path that means ``the
path starts at $(0\mathrm{bp}, 0\mathrm{bp})$ and then
continues in a straight line to $(10\mathrm{bp},
0\mathrm{bp})$.''

\begin{codeexample}[code only]
\pgfsyssoftpath@movetotoken{0bp}{0bp}\pgfsyssoftpath@linetotoken{10bp}{0bp}
\end{codeexample}

A curve-to is hard to express in this way since we need six numbers to
express it, not two. For this reasons, a curve-to is expressed using
three triples as follows: The command
\begin{codeexample}[code only]
\pgfsyssoftpath@curveto{1bp}{2bp}{3bp}{4bp}{5bp}{6bp}
\end{codeexample}
\noindent
results in the following three triples:
\begin{codeexample}[code only]
\pgfsyssoftpath@curvetosupportatoken{1bp}{2bp}
\pgfsyssoftpath@curvetosupportbtoken{3bp}{4bp}
\pgfsyssoftpath@curvetotoken{5bp}{6bp}
\end{codeexample}

These three triples must always ``remain together.'' Thus, a lonely
|supportbtoken| is forbidden.

In details, the following tokens exist:
\begin{itemize}
\item
  \declare{|\pgfsyssoftpath@movetotoken|} indicates a move-to
  operation. The two following numbers indicate the position to which
  the current point should be moved.
\item
  \declare{|\pgfsyssoftpath@linetotoken|} indicates a line-to
  operation. 
\item
  \declare{|\pgfsyssoftpath@curvetosupportatoken|} indicates the first
  control point of a curve-to operation. The triple must be followed
  by a |\pgfsyssoftpath@curvetosupportbtoken|.
\item
  \declare{|\pgfsyssoftpath@curvetosupportbtoken|} indicates the second
  control point of a curve-to operation. The triple must be followed
  by a |\pgfsyssoftpath@curvetotoken|.
\item
  \declare{|\pgfsyssoftpath@curvetotoken|} indicates the target
  of a curve-to operation.
\item
  \declare{|\pgfsyssoftpath@rectcornertoken|} indicates the corner of
  a rectangle on the soft path. The triple must be followed
  by a |\pgfsyssoftpath@rectsizetoken|.
\item
  \declare{|\pgfsyssoftpath@rectsizetoken|} indicates the size of
  a rectangle on the soft path.
\item
  \declare{|\pgfsyssoftpath@closepath|} indicates that the subpath
  begun with the last move-to operation should be closed. The parameter
  numbers are currently not important, but if set to anything
  different from |{0pt}{0pt}|, they should be set to the coordinate of
  the original move-to operation to which the path ``returns'' now.
\end{itemize}