diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/spath3/spath3.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/spath3/spath3.dtx | 4228 |
1 files changed, 0 insertions, 4228 deletions
diff --git a/Master/texmf-dist/source/latex/spath3/spath3.dtx b/Master/texmf-dist/source/latex/spath3/spath3.dtx deleted file mode 100644 index 9d6ae2825df..00000000000 --- a/Master/texmf-dist/source/latex/spath3/spath3.dtx +++ /dev/null @@ -1,4228 +0,0 @@ -% \iffalse meta-comment -%<*internal> -\iffalse -%</internal> -%<*readme> ----------------------------------------------------------------- -spath3 --- LaTeX3 functions for manipulating PGF soft paths -E-mail: stacey@math.ntnu.no -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- - -This package defines some functions used to manipulate PGFs soft paths. -As applications of its use, included are a package for drawing calligraphic paths and a package for drawing knot diagrams. -%</readme> -%<*internal> -\fi -\def\nameofplainTeX{plain} -\ifx\fmtname\nameofplainTeX\else - \expandafter\begingroup -\fi -%</internal> -%<*install> -\input docstrip.tex -\keepsilent -\askforoverwritefalse -\preamble ----------------------------------------------------------------- -spath3 --- Functions for manipulating PGF soft paths -E-mail: stacey@math.ntnu.no -Released under the LaTeX Project Public License v1.3c or later -See http://www.latex-project.org/lppl.txt ----------------------------------------------------------------- - -\endpreamble -\postamble - -Copyright (C) 2011-2019 by Andrew Stacey <stacey@math.ntnu.no> - -This work may be distributed and/or modified under the -conditions of the LaTeX Project Public License (LPPL), either -version 1.3c of this license or (at your option) any later -version. The latest version of this license is in the file: - -http://www.latex-project.org/lppl.txt - -This work is "maintained" (as per LPPL maintenance status) by -Andrew Stacey. - -This work consists of the files spath3.dtx - calligraphy_doc.tex - knots_doc.tex -and the derived files spath3.ins, - spath3_code.pdf, - spath3.sty, - tikzlibrarycalligraphy.code.tex - tikzlibraryknots.code.tex - calligraphy.pdf - knots.pdf - README - -\endpostamble -\usedir{tex/latex/spath3} -\generate{ - \file{\jobname.sty}{\from{\jobname.dtx}{spath3}} -} -\generate{ - \file{tikzlibrarycalligraphy.code.tex}{\from{\jobname.dtx}{calligraphy}} -} -\generate{ - \file{tikzlibraryknots.code.tex}{\from{\jobname.dtx}{knots}} -} -%</install> -%<install>\endbatchfile -%<*internal> -\usedir{source/latex/spath3} -\generate{ - \file{\jobname.ins}{\from{\jobname.dtx}{install}} -} -\nopreamble\nopostamble -\usedir{doc/latex/demopkg} -\generate{ - \file{README.txt}{\from{\jobname.dtx}{readme}} -} -\ifx\fmtname\nameofplainTeX - \expandafter\endbatchfile -\else - \expandafter\endgroup -\fi -%</internal> -%<*driver> -\documentclass[full]{l3doc} -\usepackage[T1]{fontenc} -\usepackage{lmodern} -%\usepackage{morefloats} -\usepackage{tikz} -\usepackage{trace} -\usepackage{spath3} -%\traceoff -%\usepackage[numbered]{hypdoc} -\definecolor{lstbgcolor}{rgb}{0.9,0.9,0.9} - -\usepackage{listings} -\lstloadlanguages{[LaTeX]TeX} -\lstset{breakatwhitespace=true,breaklines=true,language=TeX} - -\usepackage{fancyvrb} - -\newenvironment{example} - {\VerbatimEnvironment - \begin{VerbatimOut}[gobble=2]{example.out}} - {\end{VerbatimOut} - \begin{center} -% \setlength{\parindent}{0pt} - \fbox{\begin{minipage}{.9\linewidth} - \lstset{breakatwhitespace=true,breaklines=true,language=TeX,basicstyle=\small} - \lstinputlisting[]{example.out} - \end{minipage}} - - \fbox{\begin{minipage}{.9\linewidth} - \input{example.out} - \end{minipage}} -\end{center} -} -\EnableCrossrefs -\CodelineIndex -\RecordChanges -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% \CheckSum{4488} -% -% \CharacterTable -% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -% Digits \0\1\2\3\4\5\6\7\8\9 -% Exclamation \! Double quote \" Hash (number) \# -% Dollar \$ Percent \% Ampersand \& -% Acute accent \' Left paren \( Right paren \) -% Asterisk \* Plus \+ Comma \, -% Minus \- Point \. Solidus \/ -% Colon \: Semicolon \; Less than \< -% Equals \= Greater than \> Question mark \? -% Commercial at \@ Left bracket \[ Backslash \\ -% Right bracket \] Circumflex \^ Underscore \_ -% Grave accent \` Left brace \{ Vertical bar \| -% Right brace \} Tilde \~} -% -% -% \changes{1.0}{2011/05/03}{Converted to DTX file} -% \changes{1.1}{2016/02/19}{Fixes due to changes in LaTeX3} -% \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3} -% -% \DoNotIndex{\newcommand,\newenvironment} -% -% \providecommand*{\url}{\texttt} -% \GetFileInfo{spath3.sty} -% \title{The \textsf{spath3} package} -% \author{Andrew Stacey \\ \url{stacey@math.ntnu.no}} -% \date{\fileversion~from \filedate} -% -% -% \maketitle -% -% -% \section{Introduction} -% -% The \Verb+spath3+ package is intended as a library for manipulating PGF's \emph{soft paths}. -% In between defining a path and using it, PGF stores a path as a \emph{soft path} where all the defining structure has been resolved into the basic operations but these have not yet been written to the output file. -% They can therefore still be manipulated by \TeX, and as they have a very rigid form (and limited vocabulary), they are relatively easy to modify. -% This package provides some methods for working with these paths. -% It is not really intended for use by end users but as a foundation on which other packages can be built. -% As examples, the \Verb+calligraphy+ package and the \Verb+knot+ package are included. -% The first of these simulates a calligraphic pen stroking a path. -% The second can be used to draw knot (and similar) diagrams. -% -% The format of a soft path is a sequence of triples of the form \Verb+\macro {dimension}{dimension}+. -% The macro is one of a short list, the dimensions are coordinates in points. -% There are certain further restrictions, particularly that every path must begin with a \Verb+move to+, and B\'ezier curves consist of three triples. -% -% \StopEventually{} -% -% \section{Implementation} -% -% \iffalse -%<*spath3> -% \fi -% \subsection{Initialisation} -% -% Load the \LaTeX3 foundation and register us as a \LaTeX3\ package. -% \begin{macrocode} -\NeedsTeXFormat{LaTeX2e} -\RequirePackage{expl3} -\RequirePackage{pgf} -\ProvidesExplPackage {spath3} {2019/02/12} {1.2} {Functions for -manipulating PGF soft paths} -\RequirePackage{xparse} -% \end{macrocode} -% -% We need a slew of temporary variables. -% \begin{macrocode} -\tl_new:N \l__spath_tmpa_tl -\tl_new:N \l__spath_tmpb_tl -\tl_new:N \l__spath_tmpc_tl -\tl_new:N \l__spath_tmpd_tl -\tl_new:N \l__spath_smuggle_tl -\dim_new:N \l__spath_tmpa_dim -\dim_new:N \l__spath_tmpb_dim -\fp_new:N \l__spath_tmpa_fp -\fp_new:N \l__spath_tmpb_fp -\int_new:N \l__spath_tmpa_int -\int_new:N \g__spath_map_int -% \end{macrocode} -% -% We need to be able to compare against the macros that can occur in a soft path so these token lists contain them. -% \begin{macrocode} -\tl_new:N \g__spath_moveto_tl -\tl_new:N \g__spath_lineto_tl -\tl_new:N \g__spath_curveto_tl -\tl_new:N \g__spath_curvetoa_tl -\tl_new:N \g__spath_curvetob_tl -\tl_new:N \g__spath_closepath_tl -\tl_set:Nn \g__spath_moveto_tl {\pgfsyssoftpath@movetotoken} -\tl_set:Nn \g__spath_lineto_tl {\pgfsyssoftpath@linetotoken} -\tl_set:Nn \g__spath_curveto_tl {\pgfsyssoftpath@curvetotoken} -\tl_set:Nn \g__spath_curvetoa_tl {\pgfsyssoftpath@curvetosupportatoken} -\tl_set:Nn \g__spath_curvetob_tl {\pgfsyssoftpath@curvetosupportbtoken} -\tl_set:Nn \g__spath_closepath_tl {\pgfsyssoftpath@closepathtoken} -% \end{macrocode} -% -% \subsection{Basic Structure and Methods} -% -% A soft path is a \Verb+prop+. -% These are lists of the attributes that we define. -% The first consists of all attributes, the second of those that are ``moveable'' in the sense that they change if we transform the path, the third are the ones that contain actual paths. -% -% Note that if using these attributes outside an \Verb+expl3+ context, the spaces should be omitted. -% \begin{macrocode} -\tl_new:N \g__spath_attributes -\tl_new:N \g__spath_moveable_attributes -\tl_new:N \g__spath_path_attributes -\tl_set:Nn \g__spath_attributes { - {path} - {reverse path} - {length} - {real length} - {number of components} - {initial point} - {final point} - {initial action} - {final action} - {min bb} - {max bb} -} -\tl_set:Nn \g__spath_moveable_attributes { - {initial point} - {final point} - {min bb} - {max bb} -} -\tl_set:Nn \g__spath_path_attributes { - {path} - {reverse path} -} -% \end{macrocode} -% -% An \Verb+spath+ object is actually a \Verb+prop+. -% The following functions are wrappers around the underlying \Verb+prop+ functions. -% We prefix the names to avoid clashing with other \Verb+prop+s that might be lying around, this is why all the \Verb+spath+ methods take argument \Verb+:n+ and not \Verb+:N+. -% Given that \Verb+spath+ objects might be created inside a group but used outside it, we work globally throughout. -% \begin{macro}{\spath_new:n} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_new:n #1 -{ - \prop_new:c {l__spath_#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_clear:n} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_clear:n #1 -{ - \prop_gclear:c {l__spath_#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_clear_new:n} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_clear_new:n #1 -{ - \prop_gclear_new:c {l__spath_#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_show:n} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_show:n #1 -{ - \prop_show:c {l__spath_#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_put:nnn} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_put:nnn #1#2#3 -{ - \prop_gput:cnn {l__spath_#1} {#2} {#3} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_remove:nn} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_remove:nn #1#2 -{ - \prop_gremove:cn {l__spath_#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__spath_get:nn} -% This function is an internal one since the real \Verb+get+ function will generate its data if it does not already exist. -% \begin{macrocode} -\cs_new_nopar:Npn \__spath_get:nn #1#2 -{ - \prop_item:cn {l__spath_#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__spath_get:nnN} -% \begin{macrocode} -\cs_new_nopar:Npn \__spath_get:nnN #1#2#3 -{ - \prop_get:cnN {l__spath_#1} {#2} #3 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_if_in:nn} -% \begin{macrocode} -\prg_new_conditional:Npnn \spath_if_in:nn #1#2 {p, T, F, TF} -{ - \prop_if_in:cnTF {l__spath_#1} {#2} - { \prg_return_true: } - { \prg_return_false: } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__spath_get:nnN} -% \begin{macrocode} -\cs_generate_variant:Nn \__prop_split:NnTF {cnTF} -\prg_new_protected_conditional:Npnn \__spath_get:nnN #1#2#3 {T, F, TF} -{ - \__prop_split:cnTF {l__spath_#1} {#2} - { - \tl_set:Nn #3 {##2} - \prg_return_true: - } - { \prg_return_false: } -} -\cs_generate_variant:Nn \spath_put:nnn {nnV, nnx, nno} -\cs_generate_variant:Nn \__spath_get:nn {Vn} -\cs_generate_variant:Nn \__spath_get:nnN {VnN} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_if_exist:n} -% \begin{macrocode} -\prg_new_conditional:Npnn \spath_if_exist:n #1 {p,T,F,TF} -{ - \prop_if_exist:cTF {l__spath_#1} - { - \prg_return_true: - } - { - \prg_return_false: - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_clone:nn} -% Clones an \Verb+spath+. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_clone:nn #1 #2 -{ - \spath_clear_new:n {#2} - \tl_map_inline:Nn \g__spath_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - \spath_put:nnV {#2} {##1} \l__spath_tmpa_tl - } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_get_current_path:n} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_get_current_path:n #1 -{ - \pgfsyssoftpath@getcurrentpath\l__spath_tmpa_tl - \spath_clear_new:n {#1} - \spath_put:nnV {#1} {path} \l__spath_tmpa_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_set_current_path:n} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_set_current_path:n #1 -{ - \spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl - \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl - - \spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl - \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl - - \spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \pgfsyssoftpath@setcurrentpath\l__spath_tmpa_tl - \pgfsyssoftpath@flushcurrentpath -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_use_path:nn} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_use_path:nn #1#2 -{ - \spath_set_current_path:n {#1} - \pgfusepath{#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_protocol_path:n} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_protocol_path:n #1 -{ - \spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl - \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl - - \spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl - \exp_last_unbraced:NV \pgf@protocolsizes\l__spath_tmpa_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_tikz_path:nn} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \spath_tikz_path:nn #1#2 -{ - \path[#1] \pgfextra{ - \spath_get:nnN {#2} {path} \l__spath_tmpa_tl - \pgfsyssoftpath@setcurrentpath \l__spath_tmpa_tl - }; -} -\cs_generate_variant:Nn \spath_tikz_path:nn {Vn} -% \end{macrocode} -% \end{macro} -% -% \subsection{Computing Information} -% -% \begin{macro}{\spath_get:nn} -% The information that we store along with a soft path can be computed from it, but computing it every time is wasteful. -% So this is the real \Verb+\spath_get:nn+ function which checks to see if we have already computed it and then either retrieves it or computes it. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_get:nn #1#2 -{ - \spath_if_in:nnF {#1} {#2} - { - \cs_if_exist_use:cT {spath_generate_#2:n} {{#1}} - } - \__spath_get:nn {#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_get:nnN} -% As above but leaves the result in a token list rather than in the stream. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_get:nnN #1#2#3 -{ - \spath_if_in:nnF {#1} {#2} - { - \cs_if_exist_use:cT {spath_generate_#2:n} {{#1}} - } - \__spath_get:nnN {#1} {#2} #3 -} -\cs_generate_variant:Nn \spath_get:nnN {VnN} -% \end{macrocode} -% \end{macro} -% -% The next slew of functions generate data from the original path, storing it in the \Verb+prop+ for further retrieval. -% \begin{macro}{\spath_generate_length:n} -% Counts the number of triples in the path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_length:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \spath_put:nnx {#1} {length} {\int_eval:n {\tl_count:N \l__spath_tmpa_tl /3 }} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_reallength:n} -% The real length of a path is the number of triples that actually draw something (that is, the number of lines and curves). -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_reallength:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \int_set:Nn \l__spath_tmpa_int {0} - \tl_map_inline:Nn \l__spath_tmpa_tl { - \tl_if_eq:nnT {##1} {\pgfsyssoftpath@linetotoken} - { - \int_incr:N \l__spath_tmpa_int - } - \tl_if_eq:nnT {##1} {\pgfsyssoftpath@curvetotoken} - { - \int_incr:N \l__spath_tmpa_int - } - } - \spath_put:nnx {#1} {real length} {\int_use:N \l__spath_tmpa_int} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_numberofcomponents:n} -% A component is a continuous segment of the path, separated by moves. -% Successive moves are not collapsed, and zero length moves count. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_numberofcomponents:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \int_set:Nn \l__spath_tmpa_int {0} - \tl_map_inline:Nn \l__spath_tmpa_tl { - \tl_if_eq:nnT {##1} {\pgfsyssoftpath@movetotoken} - { - \int_incr:N \l__spath_tmpa_int - } - } - \spath_put:nnx {#1} {number of components} {\int_use:N \l__spath_tmpa_int} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_initialpoint:n} -% The starting point of the path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_initialpoint:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \spath_put:nnV {#1} {initial point} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_finalpoint:n} -% The final point of the path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_finalpoint:n #1 -{ - \tl_clear:N \l__spath_tmpb_tl - \spath_if_in:nnTF {#1} {reverse path} - { - \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - } - { - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_reverse:N \l__spath_tmpa_tl - \tl_put_left:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_left:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - } - \spath_put:nnV {#1} {final point} \l__spath_tmpb_tl -} -\cs_generate_variant:Nn \spath_generate_finalpoint:n {V} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_reversepath:n} -% This computes the reverse of the path. -% TODO: handle closed paths, possibly rectangles. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_reversepath:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_left:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nn \l__spath_tmpd_tl {} - \tl_case:NnF \l__spath_tmpc_tl - { - \g__spath_moveto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_moveto_tl } - \g__spath_lineto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_lineto_tl } - \g__spath_curveto_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetoa_tl } - \g__spath_curvetoa_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curveto_tl } - \g__spath_curvetob_tl {\tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetob_tl } - } - { - \tl_show:N \l__spath_tmpc_tl - } - \tl_put_left:NV \l__spath_tmpb_tl \l__spath_tmpd_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_left:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - \tl_put_left:NV \l__spath_tmpb_tl \g__spath_moveto_tl - \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_initialaction:n} -% This is the first thing that the path does (after the initial move). -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_initialaction:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_if_empty:NF \l__spath_tmpa_tl { - \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - } - \spath_put:nnV {#1} {initial action} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_final action:n} -% This is the last thing that the path does. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_finalaction:n #1 -{ - \tl_clear:N \l__spath_tmpb_tl - \spath_if_in:nnTF {#1} {reverse path} - { - \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - } - { - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_reverse:N \l__spath_tmpa_tl - } - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_if_empty:NF \l__spath_tmpa_tl { - \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - } - \tl_if_eq:NNT \l__spath_tmpa_tl \g__spath_curvetoa_tl - { - \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_curveto_tl - } - \spath_put:nnV {#1} {final action} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_minbb:n} -% This computes the minimum (bottom left) of the bounding box of the path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_minbb:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - } - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_max bb:n} -% This computes the maximum (top right) of the bounding box of the path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_generate_maxbb:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpa_dim}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_max:nn {\tl_head:N \l__spath_tmpa_tl} {\l__spath_tmpb_dim}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - } - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_generate_all:n} -% This function generates all of the data in one fell swoop. -% By traversing the path just once it is quicker than doing each one individually. -% However, it does need to store a lot of data as it goes. -% \begin{itemize} -% \item \Verb+\l__spath_rp_tl+ will hold the reversed path -% \item \Verb+\l__spath_l_int+ will hold the length -% \item \Verb+\l__spath_rl_int+ will hold the real length -% \item \Verb+\l__spath_nc_int+ will hold the number of components -% \item \Verb+\l__spath_ip_tl+ will hold the initial point -% \item \Verb+\l__spath_fp_tl+ will hold the final point -% \item \Verb+\l__spath_ia_tl+ will hold the initial action -% \item \Verb+\l__spath_fa_tl+ will hold the final action -% \item \Verb+\l__spath_minx_dim+ will hold the min x bb -% \item \Verb+\l__spath_miny_dim+ will hold the min y bb -% \item \Verb+\l__spath_maxx_dim+ will hold the max x bb -% \item \Verb+\l__spath_maxy_dim+ will hold the max y bb -% \end{itemize} -% \begin{macrocode} -\tl_new:N \l__spath_rp_tl -\int_new:N \l__spath_l_int -\int_new:N \l__spath_rl_int -\int_new:N \l__spath_nc_int -\tl_new:N \l__spath_ip_tl -\tl_new:N \l__spath_fp_tl -\tl_new:N \l__spath_ia_tl -\tl_new:N \l__spath_fa_tl -\dim_new:N \l__spath_minx_dim -\dim_new:N \l__spath_miny_dim -\dim_new:N \l__spath_maxx_dim -\dim_new:N \l__spath_maxy_dim - -\cs_new_nopar:Npn \spath_generate_all:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - - \tl_clear:N \l__spath_rp_tl - \int_set:Nn \l__spath_l_int {1} - \int_zero:N \l__spath_rl_int - \int_set:Nn \l__spath_nc_int {1} - \tl_clear:N \l__spath_ip_tl - \tl_clear:N \l__spath_fp_tl - \tl_clear:N \l__spath_ia_tl - \tl_clear:N \l__spath_fa_tl - \dim_zero:N \l__spath_minx_dim - \dim_zero:N \l__spath_miny_dim - \dim_zero:N \l__spath_maxx_dim - \dim_zero:N \l__spath_maxy_dim - - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_clear:N \l__spath_ip_tl - \tl_put_right:Nx \l__spath_ip_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - - \dim_set_eq:NN \l__spath_minx_dim \l__spath_tmpa_dim - \dim_set_eq:NN \l__spath_miny_dim \l__spath_tmpb_dim - \dim_set_eq:NN \l__spath_maxx_dim \l__spath_tmpa_dim - \dim_set_eq:NN \l__spath_maxy_dim \l__spath_tmpb_dim - - \tl_put_left:Nx \l__spath_rp_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - - \tl_set:Nx \l__spath_ia_tl {\tl_head:N \l__spath_tmpa_tl} - - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nn \l__spath_tmpd_tl {} - \tl_set_eq:NN \l__spath_fa_tl \l__spath_tmpc_tl - \int_incr:N \l__spath_l_int - - \tl_case:NnF \l__spath_tmpc_tl - { - \g__spath_moveto_tl { - \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_moveto_tl - \int_incr:N \l__spath_nc_int - } - \g__spath_lineto_tl { - \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_lineto_tl - \int_incr:N \l__spath_rl_int - } - \g__spath_curveto_tl { - \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetoa_tl - \int_incr:N \l__spath_rl_int - } - \g__spath_curvetoa_tl { - \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curveto_tl - } - \g__spath_curvetob_tl { - \tl_set_eq:NN \l__spath_tmpd_tl \g__spath_curvetob_tl - } - } - { - \tl_show:N \l__spath_tmpc_tl - } - \tl_put_left:NV \l__spath_rp_tl \l__spath_tmpd_tl - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_minx_dim {\dim_min:nn { \l__spath_minx_dim} {\l__spath_tmpa_dim}} - \dim_set:Nn \l__spath_miny_dim {\dim_min:nn { \l__spath_miny_dim} {\l__spath_tmpb_dim}} - \dim_set:Nn \l__spath_maxx_dim {\dim_max:nn { \l__spath_maxx_dim} {\l__spath_tmpa_dim}} - \dim_set:Nn \l__spath_maxy_dim {\dim_max:nn { \l__spath_maxy_dim} {\l__spath_tmpb_dim}} - - \tl_put_left:Nx \l__spath_rp_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - - \tl_set:Nx \l__spath_fp_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - - } - - \tl_put_left:NV \l__spath_rp_tl \g__spath_moveto_tl - - \spath_put:nnV {#1} {reverse path} \l__spath_rp_tl - \spath_put:nnV {#1} {length} \l__spath_l_int - \spath_put:nnV {#1} {real length} \l__spath_rl_int - \spath_put:nnV {#1} {number of components} \l__spath_nc_int - \spath_put:nnV {#1} {initial point} \l__spath_ip_tl - \spath_put:nnV {#1} {final point} \l__spath_fp_tl - \spath_put:nnV {#1} {initial action} \l__spath_ia_tl - \spath_put:nnV {#1} {final action} \l__spath_fa_tl - - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_minx_dim} - {\dim_use:N \l__spath_miny_dim} - } - \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl - - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_maxx_dim} - {\dim_use:N \l__spath_maxy_dim} - } - \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl - -} -% \end{macrocode} -% \end{macro} -% -% \subsection{Path Manipulation} -% -% \begin{macro}{\spath_translate:nnn} -% Translates a path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_translate:nnn #1#2#3 -{ - \tl_map_inline:Nn \g__spath_moveable_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl + #2} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl + #3} - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } - \tl_map_inline:Nn \g__spath_path_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl + #2} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl + #3} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } -} - -\cs_generate_variant:Nn \spath_translate:nnn {nxx} -% \end{macrocode} -% -% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_translate:nn #1#2 -{ - \spath_translate:nnn {#1} #2 -} - -\cs_generate_variant:Nn \spath_translate:nn {nV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_scale:nnn} -% Scale a path. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_scale:nnn #1#2#3 -{ - \tl_map_inline:Nn \g__spath_moveable_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - - \fp_set:Nn \l__spath_tmpa_fp {\tl_head:N \l__spath_tmpa_tl * #2} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \fp_set:Nn \l__spath_tmpb_fp {\tl_head:N \l__spath_tmpa_tl * #3} - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\fp_to_dim:N \l__spath_tmpa_fp} - {\fp_to_dim:N \l__spath_tmpb_fp} - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } - \tl_map_inline:Nn \g__spath_path_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \fp_set:Nn \l__spath_tmpa_fp {\tl_head:N \l__spath_tmpa_tl * #2} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \fp_set:Nn \l__spath_tmpb_fp {\tl_head:N \l__spath_tmpa_tl * #3} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\fp_to_dim:N \l__spath_tmpa_fp} - {\fp_to_dim:N \l__spath_tmpb_fp} - } - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } -} -\cs_generate_variant:Nn \spath_scale:nnn {nxx} -% \end{macrocode} -% -% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_scale:nn #1#2 -{ - \spath_scale:nnn {#1} #2 -} - -\cs_generate_variant:Nn \spath_scale:nn {nV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_transform:nnnnnnn} -% Applies an affine (matrix and vector) transformation to path. -% The matrix is specified in rows first. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_transform:nnnnnnn #1#2#3#4#5#6#7 -{ - \tl_map_inline:Nn \g__spath_moveable_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_head:N \l__spath_tmpa_tl} - \fp_set:Nn \l__spath_tmpa_fp {\l__spath_tmpa_tl * #2 + \l__spath_tmpb_tl * #3 + #6} - \fp_set:Nn \l__spath_tmpb_fp {\l__spath_tmpa_tl * #4 + \l__spath_tmpb_tl * #5 + #7} - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\fp_to_dim:N \l__spath_tmpa_fp} - {\fp_to_dim:N \l__spath_tmpb_fp} - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } - \tl_map_inline:Nn \g__spath_path_attributes - { - \spath_if_in:nnT {#1} {##1} - { - \__spath_get:nnN {#1} {##1} \l__spath_tmpa_tl - \tl_clear:N \l__spath_tmpb_tl - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_set:Nx \l_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \fp_set:Nn \l__spath_tmpa_fp {\l_tmpa_tl * #2 + \l_tmpb_tl * #3 + #6} - \fp_set:Nn \l__spath_tmpb_fp {\l_tmpa_tl * #4 + \l_tmpb_tl * #5 + #7} - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\fp_to_dim:N \l__spath_tmpa_fp} - {\fp_to_dim:N \l__spath_tmpb_fp} - } - } - \spath_put:nnV {#1} {##1} \l__spath_tmpb_tl - } - } -} - -\cs_generate_variant:Nn \spath_transform:nnnnnnn {nxxxxxx} -% \end{macrocode} -% -% This variant allows for passing the coordinates as a single braced group as it strips off the outer braces of the second argument. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_transform:nn #1#2 -{ - \spath_transform:nnnnnnn {#1} #2 -} - -\cs_generate_variant:Nn \spath_transform:nn {nV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_reverse:n} -% This reverses a path. -% As a lot of the data is invariant under reversing, there isn't a lot to do. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_reverse:n #1 -{ - \spath_if_in:nnF {#1} {reverse path} { - \use:c {spath_generate_reverse path:n} {#1} - } - \spath_swap:nnn {#1} {path} {reverse path} - \spath_swap:nnn {#1} {initial point} {final point} - \spath_swap:nnn {#1} {initial action} {final action} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_swap:nnn} -% Swaps two entries, being careful to ensure that their existence (or otherwise) is preserved. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_swap:nnn #1#2#3 -{ - \__spath_get:nnNF {#1} {#2} \l__spath_tmpa_tl {\tl_clear:N \l__spath_tmpa_tl} - \__spath_get:nnNF {#1} {#3} \l__spath_tmpb_tl {\tl_clear:N \l__spath_tmpb_tl} - \tl_if_empty:NTF \l__spath_tmpb_tl - {\spath_remove:nn {#1} {#2}} - {\spath_put:nnV {#1} {#2} \l__spath_tmpb_tl} - \tl_if_empty:NTF \l__spath_tmpa_tl - {\spath_remove:nn {#1} {#3}} - {\spath_put:nnV {#1} {#3} \l__spath_tmpa_tl} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_weld:nn} -% This welds one path to another, moving the second so that it's initial point coincides with the first's final point. -% It is called a \emph{weld} because the initial move of the second path is removed. -% The first path is updated, the second is not modified. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_weld:nn #1#2 -{ - \spath_clone:nn {#2} {tmp_path} - \spath_get:nnN {#1} {final point} \l__spath_tmpa_tl - - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - - \spath_get:nnN {#2} {initial point} \l__spath_tmpa_tl - - \dim_sub:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_sub:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - - \spath_translate:nxx {tmp_path} {\dim_use:N \l__spath_tmpa_dim} {\dim_use:N \l__spath_tmpb_dim} - - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \__spath_get:nnN {tmp_path} {path} \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - - \spath_put:nnV {#1} {path} \l__spath_tmpa_tl - - \__spath_get:nnNTF {tmp_path} {final point} \l__spath_tmpa_tl - { - \spath_put:nnV {#1} {final point} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {final point} - } - - \__spath_get:nnNTF {tmp_path} {final action} \l__spath_tmpa_tl - { - \spath_put:nnV {#1} {final action} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {final action} - } - - \__spath_get:nnNT {tmp_path} {min bb} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {min bb} \l__spath_tmpb_tl - { - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\l__spath_tmpa_dim} {\tl_head:N \l__spath_tmpb_tl}} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\l__spath_tmpb_dim} {\tl_head:N \l__spath_tmpb_tl}} - - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \spath_put:nnV {#1} {min bb} \l__spath_tmpb_tl - } - } - - \__spath_get:nnNT {tmp_path} {max bb} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {max bb} \l__spath_tmpb_tl - { - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - - \dim_set:Nn \l__spath_tmpa_dim {\dim_max:nn {\l__spath_tmpa_dim} {\tl_head:N \l__spath_tmpb_tl}} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \dim_set:Nn \l__spath_tmpb_dim {\dim_max:nn {\l__spath_tmpb_dim} {\tl_head:N \l__spath_tmpb_tl}} - - \tl_clear:N \l__spath_tmpb_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \spath_put:nnV {#1} {max bb} \l__spath_tmpb_tl - } - } - - \__spath_get:nnNT {tmp_path} {reverse path} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {reverse path} \l__spath_tmpb_tl - { - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - - \spath_put:nnV {#1} {reverse path} \l__spath_tmpa_tl - } - } - - \__spath_get:nnNT {tmp_path} {length} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {length} \l__spath_tmpb_tl - { - \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl - 1} - \spath_put:nnV {#1} {length} \l__spath_tmpa_int - } - } - - \__spath_get:nnNT {tmp_path} {real length} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {real length} \l__spath_tmpb_tl - { - \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl} - \spath_put:nnV {#1} {real length} \l__spath_tmpa_int - } - } - - \__spath_get:nnNT {tmp_path} {number of components} \l__spath_tmpa_tl - { - \__spath_get:nnNT {#1} {number of components} \l__spath_tmpb_tl - { - \int_set:Nn \l__spath_tmpa_int {\l__spath_tmpa_tl + \l__spath_tmpb_tl - 1} - \spath_put:nnV {#1} {number of components} \l__spath_tmpa_int - } - } - -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_prepend_no_move:nn} -% Prepend the path from the second \Verb+spath+ to the first, removing -% the adjoining move. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_prepend_no_move:nn #1#2 -{ - \spath_if_exist:nT {#2} - { - \__spath_get:nnN {#2} {path} \l__spath_tmpa_tl - \__spath_get:nnN {#1} {path} \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {path} \l__spath_tmpa_tl - - \spath_if_in:nnTF {#2} {initial point} - { - \__spath_get:nnN {#2} {initial point} \l__spath_tmpa_tl - \spath_put:nnV {#1} {initial point} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {initial point} - } - - \spath_if_in:nnTF {#2} {initial action} - { - \__spath_get:nnN {#2} {initial action} \l__spath_tmpa_tl - \spath_put:nnV {#1} {initial action} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {initial action} - } - - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {length} - && - \spath_if_in_p:nn {#2} {length} - } - { - \__spath_get:nnN {#1} {length} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {length} \l__spath_tmpb_tl - \spath_put:nnx {#1} {length} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl - 1}} - } - { - \spath_remove:nn {#1} {length} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {real length} - && - \spath_if_in_p:nn {#2} {real length} - } - { - \__spath_get:nnN {#1} {real length} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {real length} \l__spath_tmpb_tl - \spath_put:nnx {#1} {real length} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl }} - } - { - \spath_remove:nn {#1} {real length} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {number of components} - && - \spath_if_in_p:nn {#2} {number of components} - } - { - \__spath_get:nnN {#1} {number of components} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {number of components} \l__spath_tmpb_tl - \spath_put:nnx {#1} {number of components} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl - 1}} - } - { - \spath_remove:nn {#1} {number of components} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {min bb} - && - \spath_if_in_p:nn {#2} {min bb} - } - { - \__spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {min bb} \l__spath_tmpb_tl - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {1}} {\tl_item:Nn - \l__spath_tmpb_tl {1}}} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {2}} {\tl_item:Nn - \l__spath_tmpb_tl {2}}} - \spath_put:nnx {#1} {min bb} { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - { - \spath_remove:nn {#1} {min bb} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {max bb} - && - \spath_if_in_p:nn {#2} {max bb} - } - { - \__spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {max bb} \l__spath_tmpb_tl - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {1}} {\tl_item:Nn - \l__spath_tmpb_tl {1}}} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {2}} {\tl_item:Nn - \l__spath_tmpb_tl {2}}} - \spath_put:nnx {#1} {max bb} { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - { - \spath_remove:nn {#1} {max bb} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {reverse path} - && - \spath_if_in_p:nn {#2} {reverse path} - } - { - \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {reverse path} \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl - } - { - \spath_remove:nn {#1} {reverse path} - } - - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_append_no_move:nn} -% Append the path from the second \Verb+spath+ to the first, removing -% the adjoining move. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_append_no_move:nn #1#2 -{ - \spath_if_exist:nT {#2} - { - \spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \spath_get:nnN {#2} {path} \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {path} \l__spath_tmpa_tl - \spath_if_in:nnTF {#2} {final point} - { - \__spath_get:nnN {#2} {final point} \l__spath_tmpa_tl - \spath_put:nnV {#1} {final point} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {final point} - } - \spath_if_in:nnTF {#2} {final action} - { - \__spath_get:nnN {#2} {final action} \l__spath_tmpa_tl - \spath_put:nnV {#1} {final action} \l__spath_tmpa_tl - } - { - \spath_remove:nn {#1} {final action} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {length} - && - \spath_if_in_p:nn {#2} {length} - } - { - \__spath_get:nnN {#1} {length} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {length} \l__spath_tmpb_tl - \spath_put:nnx {#1} {length} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl - 1}} - } - { - \spath_remove:nn {#1} {length} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {real length} - && - \spath_if_in_p:nn {#2} {real length} - } - { - \__spath_get:nnN {#1} {real length} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {real length} \l__spath_tmpb_tl - \spath_put:nnx {#1} {real length} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl }} - } - { - \spath_remove:nn {#1} {real length} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {number of components} - && - \spath_if_in_p:nn {#2} {number of components} - } - { - \__spath_get:nnN {#1} {number of components} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {number of components} \l__spath_tmpb_tl - \spath_put:nnx {#1} {number of components} {\int_eval:n {\l__spath_tmpa_tl + - \l__spath_tmpb_tl - 1}} - } - { - \spath_remove:nn {#1} {number of components} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {min bb} - && - \spath_if_in_p:nn {#2} {min bb} - } - { - \__spath_get:nnN {#1} {min bb} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {min bb} \l__spath_tmpb_tl - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {1}} {\tl_item:Nn - \l__spath_tmpb_tl {1}}} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {2}} {\tl_item:Nn - \l__spath_tmpb_tl {2}}} - \spath_put:nnx {#1} {min bb} { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - { - \spath_remove:nn {#1} {min bb} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {max bb} - && - \spath_if_in_p:nn {#2} {max bb} - } - { - \__spath_get:nnN {#1} {max bb} \l__spath_tmpa_tl - \__spath_get:nnN {#2} {max bb} \l__spath_tmpb_tl - \dim_set:Nn \l__spath_tmpa_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {1}} {\tl_item:Nn - \l__spath_tmpb_tl {1}}} - \dim_set:Nn \l__spath_tmpb_dim {\dim_min:nn {\tl_item:Nn - \l__spath_tmpa_tl {2}} {\tl_item:Nn - \l__spath_tmpb_tl {2}}} - \spath_put:nnx {#1} {max bb} { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - } - { - \spath_remove:nn {#1} {max bb} - } - \bool_if:nTF - { - \spath_if_in_p:nn {#1} {reverse path} - && - \spath_if_in_p:nn {#2} {reverse path} - } - { - \__spath_get:nnN {#2} {reverse path} \l__spath_tmpa_tl - \__spath_get:nnN {#1} {reverse path} \l__spath_tmpb_tl - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_set:Nx \l__spath_tmpb_tl {\tl_tail:N \l__spath_tmpb_tl} - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {reverse path} \l__spath_tmpb_tl - } - { - \spath_remove:nn {#1} {reverse path} - } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_bake_round:n} -% Ought to clear the reverse path, if set. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_bake_round:n #1 -{ - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \pgf@@processround\l__spath_tmpa_tl\l__spath_tmpb_tl - \spath_put:nnV {#1} {path} \l__spath_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_close_path:n} -% Appends a close path to the end of the path, and to the end of the reverse path. -% For now, the point is the initial or final point (respectively). -% To be future proof, it ought to be the point of the adjacent move to. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_close_path:n #1 -{ - \spath_get:nnN {#1} {initial point} \l__spath_tmpb_tl - \__spath_get:nnN {#1} {path} \l__spath_tmpa_tl - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_closepath_tl - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {path} \l__spath_tmpa_tl - \spath_if_in:nnT {#1} {reverse path} - { - \spath_get:nnN {#1} {final point} \l__spath_tmpb_tl - \__spath_get:nnN {#1} {reverse path} \l__spath_tmpa_tl - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_closepath_tl - \tl_put_right:NV \l__spath_tmpa_tl \l__spath_tmpb_tl - \spath_put:nnV {#1} {reverse path} \l__spath_tmpa_tl - } -} -% \end{macrocode} -% \end{macro} -% -% \subsection{Iteration Functions} -% -% \begin{macro}{\spath_map_component:Nn} -% This iterates through the components of a path, applying the inline function to each. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_map_component:Nn #1#2 -{ - \int_gincr:N \g__spath_map_int - \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 {#2} - \tl_set:NV \l__spath_tmpa_tl #1 - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_moveto_tl - \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_if_eq:NNT \l__spath_tmpc_tl \g__spath_moveto_tl - { - \exp_args:NnV \use:c { __spath_map_ \int_use:N \g__spath_map_int :w } \l__spath_tmpb_tl -\tl_clear:N \l__spath_tmpb_tl - } - \tl_if_single:NTF \l__spath_tmpc_tl - { - \tl_put_right:NV \l__spath_tmpb_tl \l__spath_tmpc_tl - } - { - \tl_put_right:Nx \l__spath_tmpb_tl {{\l__spath_tmpc_tl}} - } - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_map_segment_inline:Nn} -% This iterates through the segments of the path, applying the inline function to each. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_map_segment_inline:Nn #1#2 -{ - \int_gincr:N \g__spath_map_int - \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} - \spath_map_segment_function:Nc #1 { __spath_map_ \int_use:N \g__spath_map_int :w } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_map_segment_inline:nn} -% This iterates through the segments of the path of the \Verb+spath+ object, applying the inline function to each. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_map_segment_inline:nn #1#2 -{ - \int_gincr:N \g__spath_map_int - \cs_gset:cpn { __spath_map_ \int_use:N \g__spath_map_int :w } ##1 ##2 {#2} - \spath_get:nnN {#1} {path} \l__spath_tmpd_tl - \spath_map_segment_function:Nc \l__spath_tmpd_tl { __spath_map_ \int_use:N \g__spath_map_int :w } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\spath_map_segment_function:nN} -% This iterates through the segments of the path of the \Verb+spath+ object, applying the specified function to each. -% The specified function should take two \Verb+N+ type arguments. -% The first is a token representing the type of path segment, the second is the path segment itself. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_map_segment_function:nN #1#2 -{ - \spath_get:nnN {#1} {path} \l__spath_tmpd_tl - \spath_map_segment_function:NN \l__spath_tmpd_tl #2 -} -% \end{macrocode} -% \begin{macrocode} -\cs_new_nopar:Npn \spath_map_segment_function:NN #1#2 -{ - \tl_set_eq:NN \l__spath_tmpa_tl #1 - \tl_clear:N \l__spath_tmpb_tl - \dim_zero:N \l__spath_tmpa_dim - \dim_zero:N \l__spath_tmpb_dim - - \bool_until_do:nn { - \tl_if_empty_p:N \l__spath_tmpa_tl - } - { - \tl_set:Nx \l__spath_tmpc_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_case:NnF \l__spath_tmpc_tl - { - \g__spath_lineto_tl - { - \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - } - - \g__spath_curvetoa_tl - { - \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \tl_put_right:NV \l__spath_tmpb_tl \g__spath_curvetoa_tl - - \prg_replicate:nn {2} { - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - \tl_put_right:Nx \l__spath_tmpb_tl {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - } - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - } - - \g__spath_closepath_tl - { - \tl_set_eq:NN \l__spath_tmpb_tl \g__spath_moveto_tl - \tl_put_right:Nx \l__spath_tmpb_tl - { - {\dim_use:N \l__spath_tmpa_dim} - {\dim_use:N \l__spath_tmpb_dim} - } - \tl_put_right:NV \l__spath_tmpb_tl \g__spath_lineto_tl - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - } - - } - { - - \tl_set_eq:NN \l__spath_tmpb_tl \l__spath_tmpc_tl - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpa_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - \tl_put_right:Nx \l__spath_tmpb_tl {{\tl_head:N \l__spath_tmpa_tl}} - \dim_set:Nn \l__spath_tmpb_dim {\tl_head:N \l__spath_tmpa_tl} - \tl_set:Nx \l__spath_tmpa_tl {\tl_tail:N \l__spath_tmpa_tl} - - } - - #2 \l__spath_tmpc_tl \l__spath_tmpb_tl - \tl_clear:N \l__spath_tmpb_tl - - } -} -\cs_generate_variant:Nn \spath_map_segment_function:NN {Nc} -% \end{macrocode} -% \end{macro} -% -% \subsection{Public Commands} -% -% The next functions are more ``public'' than the previous lot. -% That said, they aren't intended for direct use in a normal document. -% -% Most are just wrappers around internal functions. -% -% \begin{macro}{\MakeSPath} -% Constructs an \Verb+spath+ object out of the given name and path. -% \begin{macrocode} -\NewDocumentCommand \MakeSPath { m m } -{ - \spath_clear_new:n {#1} - \spath_put:nno {#1} {path} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\MakeSPathList} -% This constructs a list of \Verb+spath+ objects from a single path by splitting it into components. -% \begin{macrocode} -\NewDocumentCommand \MakeSPathList { m m } -{ - \tl_gclear_new:c {l__spath_list_#1} - \int_zero:N \l__spath_tmpa_int - \spath_map_component:Nn #2 { - \spath_clear_new:n {#1 _ \int_use:N \l__spath_tmpa_int} - \spath_put:nnn {#1 _ \int_use:N \l__spath_tmpa_int} {path} {##1} - \tl_gput_right:cx {l__spath_list_#1} {{#1 _ \int_use:N \l__spath_tmpa_int}} - \int_incr:N \l__spath_tmpa_int - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\CloneSPath} -% \begin{macrocode} -\NewDocumentCommand \CloneSPath { m m } -{ - \spath_clone:nn {#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathInfo} -% \begin{macrocode} -\NewDocumentCommand \SPathInfo { m m } -{ - \spath_get:nn {#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathPrepare} -% \begin{macrocode} -\NewDocumentCommand \SPathPrepare { m } -{ - \spath_generate_all:n {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathListPrepare} -% \begin{macrocode} -\NewDocumentCommand \SPathListPrepare { m } -{ - \tl_map_inline:cn {l__spath_list_#1} - { - \spath_generate_all:n {##1} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathInfoInto} -% \begin{macrocode} -\NewDocumentCommand \SPathInfoInto { m m m } -{ - \tl_clear_new:N #3 - \spath_get:nnN {#1} {#2} #3 -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathShow} -% \begin{macrocode} -\NewDocumentCommand \SPathShow { m } -{ - \spath_show:n {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathTranslate} -% \begin{macrocode} -\NewDocumentCommand \SPathTranslate { m m m } -{ - \spath_translate:nnn {#1} {#2} {#3} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathTranslateInto} -% Clones the path before translating it. -% \begin{macrocode} -\NewDocumentCommand \SPathTranslateInto { m m m m } -{ - \spath_clone:nn {#1} {#2} - \spath_translate:nnn {#2} {#3} {#4} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathScale} -% \begin{macrocode} -\NewDocumentCommand \SPathScale { m m m } -{ - \spath_scale:nnn {#1} {#2} {#3} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathScaleInto} -% Clones the path first. -% \begin{macrocode} -\NewDocumentCommand \SPathScaleInto { m m m m } -{ - \spath_clone:nn {#1} {#2} - \spath_scale:nnn {#2} {#3} {#4} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathWeld} -% \begin{macrocode} -\NewDocumentCommand \SPathWeld { m m } -{ - \spath_weld:nn {#1} {#2} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\SPathWeldInto} -% \begin{macrocode} -\NewDocumentCommand \SPathWeldInto { m m m } -{ - \spath_clone:nn {#1} {#2} - \spath_weld:nn {#2} {#3} -} -% \end{macrocode} -% \end{macro} -% -% Interfaces via TikZ keys. -% \begin{macrocode} -\tikzset{ - save~spath/.code={ - \tikz@addmode{ - \spath_get_current_path:n {#1} - } - }, - restore~spath/.code={ - \spath_set_current_path:n {#1} - } -} -% \end{macrocode} -% \subsection{Miscellaneous Commands} -% -% \begin{macro}{\spath_split_curve:nnNN} -% Splits a Bezier cubic into pieces. -% \begin{macrocode} -\cs_new_nopar:Npn \spath_split_curve:nnNN #1#2#3#4 -{ - \group_begin: - \tl_gclear:N \l__spath_smuggle_tl - \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl - \tl_put_right:Nx \l__spath_tmpa_tl { - {\tl_item:nn {#2} {2}} - {\tl_item:nn {#2} {3}} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1) * \tl_item:nn {#2} {2} + (#1) * \tl_item:nn {#2} {5} - }} - {\fp_to_dim:n - { - (1 - #1) * \tl_item:nn {#2} {3} + (#1) * \tl_item:nn {#2} {6} - }} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetob_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1)^2 * \tl_item:nn {#2} {2} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {5} + (#1)^2 * \tl_item:nn {#2} {8} - }} - {\fp_to_dim:n - { - (1 - #1)^2 * \tl_item:nn {#2} {3} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {6} + (#1)^2 * \tl_item:nn {#2} {9} - }} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curveto_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1)^3 * \tl_item:nn {#2} {2} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {5} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {8} + (#1)^3 * \tl_item:nn {#2} {11} - }} - {\fp_to_dim:n - { - (1 - #1)^3 * \tl_item:nn {#2} {3} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {6} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {9} + (#1)^3 * \tl_item:nn {#2} {12} - }} - } - \tl_gset_eq:NN \l__spath_smuggle_tl \l__spath_tmpa_tl - \group_end: - \tl_set_eq:NN #3 \l__spath_smuggle_tl - \group_begin: - \tl_set_eq:NN \l__spath_tmpa_tl \g__spath_moveto_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1)^3 * \tl_item:nn {#2} {2} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {5} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {8} + (#1)^3 * \tl_item:nn {#2} {11} - }} - {\fp_to_dim:n - { - (1 - #1)^3 * \tl_item:nn {#2} {3} + 3 * (1 - #1)^2 * (#1) * \tl_item:nn {#2} {6} + 3 * (1 - #1) * (#1)^2 * \tl_item:nn {#2} {9} + (#1)^3 * \tl_item:nn {#2} {12} - }} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetoa_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1)^2 * \tl_item:nn {#2} {5} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {8} + (#1)^2 * \tl_item:nn {#2} {11} - }} - {\fp_to_dim:n - { - (1 - #1)^2 * \tl_item:nn {#2} {6} + 2 * (1 - #1) * (#1) * \tl_item:nn {#2} {9} + (#1)^2 * \tl_item:nn {#2} {12} - }} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curvetob_tl - \tl_put_right:Nx \l__spath_tmpa_tl - { - {\fp_to_dim:n - { - (1 - #1) * \tl_item:nn {#2} {8} + (#1) * \tl_item:nn {#2} {11} - }} - {\fp_to_dim:n - { - (1 - #1) * \tl_item:nn {#2} {9} + (#1) * \tl_item:nn {#2} {12} - }} - } - \tl_put_right:NV \l__spath_tmpa_tl \g__spath_curveto_tl - \tl_put_right:Nx \l__spath_tmpa_tl { - {\tl_item:nn {#2} {11}} - {\tl_item:nn {#2} {12}} - } - \tl_gset_eq:NN \l__spath_smuggle_tl \l__spath_tmpa_tl - \group_end: - \tl_set_eq:NN #4 \l__spath_smuggle_tl -} - -\cs_generate_variant:Nn \spath_split_curve:nnNN {nVNN, VVNN} -% \end{macrocode} -% \end{macro} -% \iffalse -%</spath3> -% \fi -% -% \iffalse -%<*calligraphy> -% \fi -% -% \section{The Calligraphy Package} -% -% \subsection{Initialisation} -% \begin{macrocode} -\RequirePackage{spath3} -\ExplSyntaxOn - -\tl_new:N \l__cal_tmpa_tl -\tl_new:N \l__cal_tmpb_tl -\int_new:N \l__cal_tmpa_int -\int_new:N \l__cal_tmpb_int -\int_new:N \l__cal_path_component_int -\int_new:N \l__cal_label_int -\dim_new:N \l__cal_tmpa_dim -\dim_new:N \l__cal_tmpb_dim -\dim_new:N \l__cal_tmpc_dim -\dim_new:N \l__cal_tmpd_dim -\dim_new:N \l__cal_tmpe_dim -\dim_new:N \l__cal_tmpf_dim -\dim_new:N \l__cal_tmpg_dim -\dim_new:N \l__cal_tmph_dim -\bool_new:N \l__cal_annotate_bool -\bool_new:N \l__cal_taper_start_bool -\bool_new:N \l__cal_taper_end_bool -\bool_new:N \l__cal_taperable_bool -\dim_new:N \l__cal_taper_width_dim -\dim_new:N \l__cal_line_width_dim - -\bool_set_true:N \l__cal_taper_start_bool -\bool_set_true:N \l__cal_taper_end_bool - -\cs_generate_variant:Nn \tl_put_right:Nn {Nv} -% \end{macrocode} -% -% \subsection{TikZ Keys} -% -% The public interface to this package is through TikZ keys and styles. -% \begin{macrocode} -\tikzset{ - define~pen/.code={ - \tikzset{pen~name=#1} - \pgf@relevantforpicturesizefalse - \tikz@addmode{ - \pgfsyssoftpath@getcurrentpath\l__cal_tmpa_tl - \MakeSPathList{calligraphy pen \pgfkeysvalueof{/tikz/pen~name}}{\l__cal_tmpa_tl} - \SPathListPrepare{calligraphy pen \pgfkeysvalueof{/tikz/pen~name}} - \pgfusepath{discard}% - } - }, - define~pen/.default={default}, - use~pen/.code={ - \tikzset{pen~name=#1} - \int_gzero:N \l__cal_path_component_int - \cs_set_eq:NN \pgfpathmoveto \cal_moveto:n - \tikz@addmode{ - \pgfsyssoftpath@getcurrentpath\l__cal_tmpa_tl - \MakeSPathList{calligraphy path}{\l__cal_tmpa_tl} - \SPathListPrepare{calligraphy path} - \CalligraphyPathCreate{calligraphy path}{\pgfkeysvalueof{/tikz/pen~name}} - } - }, - use~pen/.default={default}, - pen~name/.initial={default}, - copperplate/.style={pen~name=copperplate}, - pen~colour/.initial={black}, - weight/.is~choice, - weight/heavy/.style={ - line~width=\pgfkeysvalueof{/tikz/heavy~line~width}, - taper~width=\pgfkeysvalueof{/tikz/light~line~width}, - }, - weight/light/.style={ - line~width=\pgfkeysvalueof{/tikz/light~line~width}, - taper~width=0pt, - }, - heavy/.style={ - weight=heavy - }, - light/.style={ - weight=light - }, - heavy~line~width/.initial=2pt, - light~line~width/.initial=1pt, - taper/.is~choice, - taper/.default=both, - taper/none/.style={ - taper~start=false, - taper~end=false, - }, - taper/both/.style={ - taper~start=true, - taper~end=true, - }, - taper/start/.style={ - taper~start=true, - taper~end=false, - }, - taper/end/.style={ - taper~start=false, - taper~end=true, - }, - taper~start/.code={ - \tl_if_eq:nnTF {#1} {true} - { - \bool_set_true:N \l__cal_taper_start_bool - } - { - \bool_set_false:N \l__cal_taper_start_bool - } - }, - taper~start/.default={true}, - taper~end/.code={ - \tl_if_eq:nnTF {#1} {true} - { - \bool_set_true:N \l__cal_taper_end_bool - } - { - \bool_set_false:N \l__cal_taper_end_bool - } - }, - taper~end/.default={true}, - taper~width/.code={\dim_set:Nn \l__cal_taper_width_dim {#1}}, - nib~style/.code~2~args={ - \tl_clear_new:c {l__cal_nib_style_#1} - \tl_set:cn {l__cal_nib_style_#1} {#2} - }, - stroke~style/.code~2~args={ - \tl_clear_new:c {l__cal_stroke_style_#1} - \tl_set:cn {l__cal_stroke_style_#1} {#2} - }, - this~stroke~style/.code={ - \tl_clear_new:c {l__cal_stroke_inline_style_ \int_use:N \l__cal_path_component_int} - \tl_set:cn {l__cal_stroke_inline_style_ \int_use:N \l__cal_path_component_int} {#1} - }, - annotate/.style={ - annotate~if, - annotate~reset, - annotation~style/.update~value={#1}, - }, - annotate~if/.default={true}, - annotate~if/.code={ - \tl_if_eq:nnTF {#1} {true} - { - \bool_set_true:N \l__cal_annotate_bool - } - { - \bool_set_false:N \l__cal_annotate_bool - } - }, - annotate~reset/.code={ - \int_gzero:N \l__cal_label_int - }, - annotation~style/.initial={draw,->}, - annotation~shift/.initial={(0,1ex)}, - every~annotation~node/.initial={anchor=south~west}, - annotation~node~style/.code~2~args={ - \tl_set:cn {l__cal_annotation_style_ #1 _tl}{#2} - }, - tl~use:N/.code={ - \exp_args:NV \pgfkeysalso #1 - }, - tl~use:c/.code={ - \tl_if_exist:cT {#1} - { - \exp_args:Nv \pgfkeysalso {#1} - } - }, - /handlers/.update~style/.code={ - \tl_if_eq:nnF {#1} {\pgfkeysnovalue} - { - \pgfkeys{\pgfkeyscurrentpath/.code=\pgfkeysalso{#1}} - } - }, - /handlers/.update~value/.code={ - \tl_if_eq:nnF {#1} {\pgfkeysnovalue} - { - \pgfkeyssetvalue{\pgfkeyscurrentpath}{#1} - } - } -} -% \end{macrocode} -% -% Some wrappers around the TikZ keys. -% \begin{macrocode} -\NewDocumentCommand \pen { O{} } -{ - \path[define~ pen,every~ calligraphy~ pen/.try,#1] -} - -\NewDocumentCommand \definepen { O{} } -{ - \tikz \path[define~ pen,every~ calligraphy~ pen/.try,#1] -} - -\NewDocumentCommand \calligraphy { O{} } -{ - \path[use~ pen,every~ calligraphy/.try,#1] -} -% \end{macrocode} -% -% \subsection{The Path Creation} -% -% \begin{macro}{\CalligraphyPathCreate} -% This is the main command for creating the calligraphic paths. -% \begin{macrocode} -\NewDocumentCommand \CalligraphyPathCreate { m m } -{ - \int_zero:N \l__cal_tmpa_int - \tl_map_inline:cn {l__spath_list_#1} - { - \int_incr:N \l__cal_tmpa_int - \int_zero:N \l__cal_tmpb_int - \tl_map_inline:cn {l__spath_list_calligraphy pen #2} - { - \int_incr:N \l__cal_tmpb_int - \group_begin: - \pgfsys@beginscope - - \cal_apply_style:c {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int} - \cal_apply_style:c {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int} - \cal_apply_style:c {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int} - - \spath_clone:nn {##1} {calligraphy temp path} - - \__spath_get:nnN {####1} {initial point} \l__cal_tmpa_tl - \spath_translate:nV {calligraphy temp path} \l__cal_tmpa_tl - - \__spath_get:nnN {####1} {length} \l__cal_tmpa_tl - - \int_compare:nTF {\l__cal_tmpa_tl = 1} - { - \cal_at_least_three:n {calligraphy temp path} - - \spath_protocol_path:n {calligraphy temp path} - - \__spath_get:nnN {calligraphy temp path} {path} \l__cal_tmpa_tl - - \tikz@options - \dim_set:Nn \l__cal_line_width_dim {\pgflinewidth} - \cal_maybe_taper:N \l__cal_tmpa_tl - } - { - - \spath_weld:nn {calligraphy temp path} {####1} - \spath_reverse:n {##1} - \spath_reverse:n {####1} - \spath_weld:nn {calligraphy temp path} {##1} - \spath_weld:nn {calligraphy temp path} {####1} - \spath_reverse:n {##1} - \spath_reverse:n {####1} - - \tl_clear:N \l__cal_tmpa_tl - \tl_set:Nn \l__cal_tmpa_tl {fill=\pgfkeysvalueof{/tikz/pen~colour},draw=none} - \tl_if_exist:cT {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int} - { - \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_stroke_style_ \int_use:N \l__cal_tmpa_int} - } - \tl_if_exist:cT {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int} - { - \tl_put_right:Nn \l__cal_tmpa_tl {,} - \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_stroke_inline_style_ \int_use:N \l__cal_tmpa_int} - } - \tl_if_exist:cT {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int} - { - \tl_put_right:Nn \l__cal_tmpa_tl {,} - \tl_put_right:Nv \l__cal_tmpa_tl {l__cal_nib_style_ \int_use:N \l__cal_tmpb_int} - } - \spath_tikz_path:Vn \l__cal_tmpa_tl {calligraphy temp path} - - } - \pgfsys@endscope - \group_end: - } - \bool_if:NT \l__cal_annotate_bool - { - \spath_clone:nn {##1} {calligraphy temp path} - \tl_set_eq:Nc \l_tmpa_tl {l__spath_list_calligraphy pen #2} - \tl_reverse:N \l_tmpa_tl - \tl_set:Nx \l_tmpa_tl {\tl_head:N \l_tmpa_tl} - \spath_generate_finalpoint:V \l_tmpa_tl - \spath_get:VnN \l_tmpa_tl {final point} \l_tmpa_tl - \spath_translate:nV {calligraphy temp path} \l_tmpa_tl - \tikz@scan@one@point\pgfutil@firstofone\pgfkeysvalueof{/tikz/annotation~shift} - \spath_translate:nnn {calligraphy temp path} {\pgf@x} {\pgf@y} - - \pgfkeysgetvalue{/tikz/annotation~style}{\l_tmpa_tl} - \spath_tikz_path:Vn \l_tmpa_tl {calligraphy temp path} - \spath_get:nnN {calligraphy temp path} {final point} \l_tmpa_tl - \exp_last_unbraced:NV \pgfqpoint \l_tmpa_tl - \begin{scope}[reset~ cm] - \node[every~annotation~node/.try,tl~use:c = {l__cal_annotation_style_ \int_use:N \l__cal_tmpa_int _tl}] at (\pgf@x,\pgf@y) {\int_use:N \l__cal_tmpa_int}; - \end{scope} - } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_moveto:n} -% When creating the path, we need to keep track of the number of components so that we can apply styles accordingly. -% \begin{macrocode} -\cs_new_eq:NN \cal_orig_moveto:n \pgfpathmoveto -\cs_new_nopar:Npn \cal_moveto:n #1 -{ - \int_gincr:N \l__cal_path_component_int - \cal_orig_moveto:n {#1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_apply_style:N} -% Interface for applying \Verb+\tikzset+ to a token list. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_apply_style:N #1 -{ - \tl_if_exist:NT #1 { - \exp_args:NV \tikzset #1 - } -} -\cs_generate_variant:Nn \cal_apply_style:N {c} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_at_least_three:n} -% A tapered path has to have at least three components. -% This figures out if it is necessary and sets up the splitting. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_at_least_three:n #1 -{ - \spath_get:nnN {#1} {real length} \l__cal_tmpa_tl - \tl_clear:N \l__cal_tmpb_tl - \int_compare:nTF {\l__cal_tmpa_tl = 1} - { - \spath_get:nnN {#1} {path} \l__cal_tmpa_tl - \spath_map_segment_inline:Nn \l__cal_tmpa_tl - { - \tl_case:NnF ##1 { - \g__spath_lineto_tl { - \cal_split_line_in_three:NN \l__cal_tmpb_tl ##2 - } - \g__spath_curvetoa_tl { - \cal_split_curve_in_three:NN \l__cal_tmpb_tl ##2 - } - } - { - \tl_put_right:NV \l__cal_tmpb_tl ##2 - } - } - \spath_put:nnV {#1} {path} \l__cal_tmpb_tl - } - { - \int_compare:nT {\l__cal_tmpa_tl = 2} - { - \spath_get:nnN {#1} {path} \l__cal_tmpa_tl - \spath_map_segment_inline:Nn \l__cal_tmpa_tl - { - \tl_case:NnF ##1 { - \g__spath_lineto_tl { - \cal_split_line_in_two:NN \l__cal_tmpb_tl ##2 - } - \g__spath_curvetoa_tl { - \cal_split_curve_in_two:NN \l__cal_tmpb_tl ##2 - } - } - { - \tl_put_right:NV \l__cal_tmpb_tl ##2 - } - } - \spath_put:nnV {#1} {path} \l__cal_tmpb_tl - } - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_split_line_in_two:NN} -% Splits a line in two, adding the splits to the first token list. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_split_line_in_two:NN #1#2 -{ - \tl_set_eq:NN \l__cal_tmpc_tl #2 - - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpa_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpb_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpc_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - \dim_set:Nn \l__cal_tmpd_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \tl_put_right:NV #1 \g__spath_lineto_tl - - \tl_put_right:Nx #1 { - {\dim_eval:n {(\l__cal_tmpa_dim + \l__cal_tmpc_dim)/2}} - {\dim_eval:n {(\l__cal_tmpb_dim + \l__cal_tmpd_dim)/2}} - } - - \tl_put_right:NV #1 \g__spath_lineto_tl - \tl_put_right:Nx #1 { - {\dim_use:N \l__cal_tmpc_dim} - {\dim_use:N \l__cal_tmpd_dim} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_split_line_in_three:NN} -% Splits a line in three, adding the splits to the first token list. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_split_line_in_three:NN #1#2 -{ - \tl_set_eq:NN \l__cal_tmpc_tl #2 - - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpa_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpb_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \dim_set:Nn \l__cal_tmpc_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - \dim_set:Nn \l__cal_tmpd_dim {\tl_head:N \l__cal_tmpc_tl} - \tl_set:Nx \l__cal_tmpc_tl {\tl_tail:N \l__cal_tmpc_tl} - - \tl_put_right:NV #1 \g__spath_lineto_tl - - \tl_put_right:Nx #1 { - {\dim_eval:n {(2\l__cal_tmpa_dim + \l__cal_tmpc_dim)/3}} - {\dim_eval:n {(2\l__cal_tmpb_dim + \l__cal_tmpd_dim)/3}} - } - - \tl_put_right:NV #1 \g__spath_lineto_tl - - \tl_put_right:Nx #1 { - {\dim_eval:n {(\l__cal_tmpa_dim + 2\l__cal_tmpc_dim)/3}} - {\dim_eval:n {(\l__cal_tmpb_dim + 2\l__cal_tmpd_dim)/3}} - } - - \tl_put_right:NV #1 \g__spath_lineto_tl - \tl_put_right:Nx #1 { - {\dim_use:N \l__cal_tmpc_dim} - {\dim_use:N \l__cal_tmpd_dim} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_split_curve_in_two:NN} -% Splits a curve in two, adding the splits to the first token list. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_split_curve_in_two:NN #1#2 -{ - \spath_split_curve:nVNN {.5} #2 \l_tmpa_tl \l_tmpb_tl - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_put_right:NV #1 \l_tmpa_tl - \tl_put_right:NV #1 \l_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_split_curve_in_three:NN} -% Splits a curve in three, adding the splits to the first token list. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_split_curve_in_three:NN #1#2 -{ - \spath_split_curve:nVNN {1/3} #2 \l_tmpa_tl \l_tmpb_tl - - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_put_right:NV #1 \l_tmpa_tl - - \spath_split_curve:nVNN {.5} \l_tmpb_tl \l_tmpa_tl \l_tmpb_tl - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_put_right:NV #1 \l_tmpa_tl - \tl_put_right:NV #1 \l_tmpb_tl -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\cal_maybe_taper:N} -% Possibly tapers the path, depending on the booleans. -% \begin{macrocode} -\cs_new_nopar:Npn \cal_maybe_taper:N #1 -{ - \tl_set_eq:NN \l__cal_tmpa_tl #1 - - \bool_if:NT \l__cal_taper_start_bool - { - - \dim_set:Nn \l__cal_tmpa_dim {\tl_item:Nn \l__cal_tmpa_tl {2}} - \dim_set:Nn \l__cal_tmpb_dim {\tl_item:Nn \l__cal_tmpa_tl {3}} - \tl_set:Nx \l__cal_tmpb_tl {\tl_item:Nn \l__cal_tmpa_tl {4}} - - \tl_case:NnF \l__cal_tmpb_tl - { - \g__spath_lineto_tl - { - - \bool_set_true:N \l__cal_taperable_bool - \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {5}} - \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {6}} - \dim_set:Nn \l__cal_tmpc_dim {(2\l__cal_tmpa_dim + \l__cal_tmpg_dim)/3} - \dim_set:Nn \l__cal_tmpd_dim {(2\l__cal_tmpb_dim + \l__cal_tmph_dim)/3} - \dim_set:Nn \l__cal_tmpe_dim {(\l__cal_tmpa_dim + 2\l__cal_tmpg_dim)/3} - \dim_set:Nn \l__cal_tmpf_dim {(\l__cal_tmpb_dim + 2\l__cal_tmph_dim)/3} - \prg_replicate:nn {4} - { - \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl} - } - \tl_put_left:NV \l__cal_tmpa_tl \g__spath_moveto_tl - } - \g__spath_curvetoa_tl - { - \bool_set_true:N \l__cal_taperable_bool - \dim_set:Nn \l__cal_tmpc_dim {\tl_item:Nn \l__cal_tmpa_tl {5}} - \dim_set:Nn \l__cal_tmpd_dim {\tl_item:Nn \l__cal_tmpa_tl {6}} - \dim_set:Nn \l__cal_tmpe_dim {\tl_item:Nn \l__cal_tmpa_tl {8}} - \dim_set:Nn \l__cal_tmpf_dim {\tl_item:Nn \l__cal_tmpa_tl {9}} - \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {11}} - \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {12}} - \prg_replicate:nn {10} - { - \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl} - } - \tl_put_left:NV \l__cal_tmpa_tl \g__spath_moveto_tl - } - } - { - \bool_set_false:N \l__cal_taperable_bool - } - - \bool_if:NT \l__cal_taperable_bool - { - \__cal_taper_aux: - } - - } - - \bool_if:NT \l__cal_taper_end_bool - { - - \dim_set:Nn \l__cal_tmpa_dim {\tl_item:Nn \l__cal_tmpa_tl {-2}} - \dim_set:Nn \l__cal_tmpb_dim {\tl_item:Nn \l__cal_tmpa_tl {-1}} - \tl_set:Nx \l__cal_tmpb_tl {\tl_item:Nn \l__cal_tmpa_tl {-3}} - - \tl_case:NnF \l__cal_tmpb_tl - { - \g__spath_lineto_tl - { - - \bool_set_true:N \l__cal_taperable_bool - \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {-5}} - \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {-4}} - \dim_set:Nn \l__cal_tmpc_dim {(2\l__cal_tmpa_dim + \l__cal_tmpg_dim)/3} - \dim_set:Nn \l__cal_tmpd_dim {(2\l__cal_tmpb_dim + \l__cal_tmph_dim)/3} - \dim_set:Nn \l__cal_tmpe_dim {(\l__cal_tmpa_dim + 2\l__cal_tmpg_dim)/3} - \dim_set:Nn \l__cal_tmpf_dim {(\l__cal_tmpb_dim + 2\l__cal_tmph_dim)/3} - \tl_reverse:N \l__cal_tmpa_tl - \prg_replicate:nn {3} - { - \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl} - } - \tl_reverse:N \l__cal_tmpa_tl - } - \g__spath_curveto_tl - { - \bool_set_true:N \l__cal_taperable_bool - \dim_set:Nn \l__cal_tmpc_dim {\tl_item:Nn \l__cal_tmpa_tl {-5}} - \dim_set:Nn \l__cal_tmpd_dim {\tl_item:Nn \l__cal_tmpa_tl {-4}} - \dim_set:Nn \l__cal_tmpe_dim {\tl_item:Nn \l__cal_tmpa_tl {-8}} - \dim_set:Nn \l__cal_tmpf_dim {\tl_item:Nn \l__cal_tmpa_tl {-7}} - \dim_set:Nn \l__cal_tmpg_dim {\tl_item:Nn \l__cal_tmpa_tl {-11}} - \dim_set:Nn \l__cal_tmph_dim {\tl_item:Nn \l__cal_tmpa_tl {-10}} - \tl_reverse:N \l__cal_tmpa_tl - \prg_replicate:nn {9} - { - \tl_set:Nx \l__cal_tmpa_tl {\tl_tail:N \l__cal_tmpa_tl} - } - \tl_reverse:N \l__cal_tmpa_tl - } - } - { - \bool_set_false:N \l__cal_taperable_bool - } - - \bool_if:NT \l__cal_taperable_bool - { - \__cal_taper_aux: - } - - } - - \pgfsyssoftpath@setcurrentpath\l__cal_tmpa_tl - \pgfsetstrokecolor{\pgfkeysvalueof{/tikz/pen~colour}} - \pgfusepath{stroke} - -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\__cal_taper_aux:} -% Auxiliary macro to avoid unnecessary code duplication. -% \begin{macrocode} -\cs_new_nopar:Npn \__cal_taper_aux: -{ - \tl_clear:N \l__cal_tmpb_tl - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_moveto_tl - - \fp_set:Nn \l__cal_tmpa_fp - { - \l__cal_tmpd_dim - \l__cal_tmpb_dim - } - \fp_set:Nn \l__cal_tmpb_fp - { - \l__cal_tmpa_dim - \l__cal_tmpc_dim - } - \fp_set:Nn \l__cal_tmpe_fp - { - (\l__cal_tmpa_fp^2 + \l__cal_tmpb_fp^2)^.5 - } - - \fp_set:Nn \l__cal_tmpa_fp {.5*\l__cal_taper_width_dim * \l__cal_tmpa_fp / \l__cal_tmpe_fp} - \fp_set:Nn \l__cal_tmpb_fp {.5*\l__cal_taper_width_dim * \l__cal_tmpb_fp / \l__cal_tmpe_fp} - - \fp_set:Nn \l__cal_tmpc_fp - { - \l__cal_tmph_dim - \l__cal_tmpf_dim - } - \fp_set:Nn \l__cal_tmpd_fp - { - \l__cal_tmpe_dim - \l__cal_tmpg_dim - } - \fp_set:Nn \l__cal_tmpe_fp - { - (\l__cal_tmpc_fp^2 + \l__cal_tmpd_fp^2)^.5 - } - - \fp_set:Nn \l__cal_tmpc_fp {.5*\l__cal_line_width_dim * \l__cal_tmpc_fp / \l__cal_tmpe_fp} - \fp_set:Nn \l__cal_tmpd_fp {.5*\l__cal_line_width_dim * \l__cal_tmpd_fp / \l__cal_tmpe_fp} - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpc_dim}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpd_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpe_dim}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmpf_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim - \fp_to_dim:n{ 1.32 * \l__cal_tmpd_fp}}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim + \fp_to_dim:n {1.32* \l__cal_tmpc_fp}}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim - \fp_to_dim:n {1.32 * \l__cal_tmpd_fp}}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim + \fp_to_dim:n {1.32 * \l__cal_tmpc_fp}}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpg_dim}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmph_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpc_fp + \l__cal_tmpe_dim}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpd_fp + \l__cal_tmpf_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpc_dim}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpd_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetoa_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim + \fp_to_dim:n{ 1.32 * \l__cal_tmpb_fp}}} - {\dim_eval:n { -\fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim - \fp_to_dim:n {1.32* \l__cal_tmpa_fp}}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curvetob_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim + \fp_to_dim:n {1.32 * \l__cal_tmpb_fp}}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim - \fp_to_dim:n {1.32 * \l__cal_tmpa_fp}}} - } - - \tl_put_right:NV \l__cal_tmpb_tl \g__spath_curveto_tl - - \tl_put_right:Nx \l__cal_tmpb_tl - { - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpa_fp + \l__cal_tmpa_dim}} - {\dim_eval:n { \fp_to_dim:N \l__cal_tmpb_fp + \l__cal_tmpb_dim}} - } - - \pgfsyssoftpath@setcurrentpath\l__cal_tmpb_tl - \pgfsetfillcolor{\pgfkeysvalueof{/tikz/pen~colour}} - \pgfusepath{fill} -} -% \end{macrocode} -% \end{macro} -% -% Defines a copperplate pen. -% \begin{macrocode} -\tl_set:Nn \l__cal_tmpa_tl {\pgfsyssoftpath@movetotoken{0pt}{0pt}} -\MakeSPathList{calligraphy pen copperplate}{\l__cal_tmpa_tl} -\SPathListPrepare{calligraphy pen copperplate} -% \end{macrocode} -% -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} -% -% \subsection{Decorations} -% -% If a decoration library is loaded we define some decorations that use the calligraphy library, specifically the copperplate pen with its tapering. -% -% First, a brace decoration. -% \begin{macrocode} -\expandafter\ifx\csname pgfdeclaredecoration\endcsname\relax -\else -\pgfdeclaredecoration{calligraphic brace}{brace} -{ - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathcurveto - {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}} - {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - { - \pgftransformxshift{+\pgfdecorationsegmentaspect\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}} - \pgfpathmoveto{\pgfqpoint{0\pgfdecorationsegmentamplitude}{1\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{.15\pgfdecorationsegmentamplitude}{.7\pgfdecorationsegmentamplitude}} - {\pgfqpoint{.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - } - { - \pgftransformxshift{+\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{-.5\pgfdecorationsegmentamplitude}{.5\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.15\pgfdecorationsegmentamplitude}{.3\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0pt}{0pt}} - } - \tikzset{ - taper width=.5\pgflinewidth, - taper - }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \MakeSPathList{calligraphy path}{\cal@tmp@path}% - \SPathListPrepare{calligraphy path}% - \CalligraphyPathCreate{calligraphy path}{copperplate}% - } - \state{final}{} -} -% \end{macrocode} -% -% The second is a straightened parenthesis (so that when very large it doesn't bow out too far). -% \begin{macrocode} -\pgfdeclaredecoration{calligraphic straight parenthesis}{brace} -{ - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgfpathcurveto - {\pgfqpoint{.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}} - {\pgfqpoint{2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - {\pgfqpoint{3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - { - \pgftransformxshift{+\pgfdecoratedremainingdistance} - \pgfpathlineto{\pgfqpoint{-3.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - \pgfpathcurveto - {\pgfqpoint{-2.3333\pgfdecorationsegmentamplitude}{\pgfdecorationsegmentamplitude}} - {\pgfqpoint{-.76604\pgfdecorationsegmentamplitude}{.64279\pgfdecorationsegmentamplitude}} - {\pgfqpoint{0pt}{0pt}} - } - \tikzset{ - taper width=.5\pgflinewidth, - taper - }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \MakeSPathList{calligraphy path}{\cal@tmp@path}% - \SPathListPrepare{calligraphy path}% - \CalligraphyPathCreate{calligraphy path}{copperplate}% - } - \state{final}{}% -} -% \end{macrocode} -% -% The third is a curved parenthesis. -% \begin{macrocode} -\pgfdeclaredecoration{calligraphic curved parenthesis}{brace} -{ - \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final] - { - \pgfsyssoftpath@setcurrentpath{\pgfutil@empty} - \pgfpathmoveto{\pgfpointorigin} - \pgf@xa=\pgfdecoratedremainingdistance\relax - \advance\pgf@xa by -1.5890\pgfdecorationsegmentamplitude\relax - \edef\cgrphy@xa{\the\pgf@xa} - \pgfpathcurveto - {\pgfqpoint{1.5890\pgfdecorationsegmentamplitude}{1.3333\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}} - {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}} - \tikzset{ - taper width=.5\pgflinewidth, - taper - }% - \pgfsyssoftpath@getcurrentpath\cal@tmp@path - \MakeSPathList{calligraphy path}{\cal@tmp@path}% - \SPathListPrepare{calligraphy path}% - \CalligraphyPathCreate{calligraphy path}{copperplate}% - } - \state{final}{}% -} -% \end{macrocode} -% End the conditional for if pgfdecoration module is loaded -% \begin{macrocode} -\fi -% \end{macrocode} -% \iffalse -%</calligraphy> -% \fi -% -% -% \iffalse -%<*knots> -% \fi -%% -% \section{Drawing Knots} -% -% -% \subsection{Initialisation} -% -% We load the \Verb+spath3+ library and the \Verb+intersections+ TikZ library. -% Then we get going. -% \begin{macrocode} -\RequirePackage{spath3} -\usetikzlibrary{intersections} - -\ExplSyntaxOn - -\tl_new:N \l__knot_tmpa_tl -\tl_new:N \l__knot_tmpb_tl -\tl_new:N \l__knot_tmpc_tl -\tl_new:N \l__knot_tmpd_tl -\tl_new:N \l__knot_tmpe_tl -\tl_new:N \l__knot_tmpf_tl -\tl_new:N \l__knot_tmpg_tl -\tl_new:N \l__knot_redraws_tl -\tl_new:N \l__knot_clip_width_tl -\tl_new:N \l__knot_name_tl -\tl_new:N \l__knot_node_tl -\tl_new:N \l__knot_aux_tl -\tl_new:N \l__knot_auxa_tl - -\int_new:N \l__knot_tmpa_int -\int_new:N \l__knot_strands_int -\int_new:N \l__knot_intersections_int -\int_new:N \l__knot_filaments_int -\int_new:N \l__knot_component_start_int - -\dim_new:N \l__knot_tmpa_dim -\dim_new:N \l__knot_tmpb_dim -\dim_new:N \l__knot_tmpc_dim -\dim_new:N \l__knot_tolerance_dim -\dim_new:N \l__knot_clip_bg_radius_dim -\dim_new:N \l__knot_clip_draw_radius_dim - -\bool_new:N \l__knot_draft_bool -\bool_new:N \l__knot_ignore_ends_bool -\bool_new:N \l__knot_self_intersections_bool -\bool_new:N \l__knot_splits_bool -\bool_new:N \l__knot_super_draft_bool - -\bool_new:N \l__knot_prepend_prev_bool -\bool_new:N \l__knot_append_next_bool -\bool_new:N \l__knot_skip_bool -\bool_new:N \l__knot_save_bool - -\seq_new:N \l__knot_nodes_seq - -\bool_set_true:N \l__knot_ignore_ends_bool -% \end{macrocode} -% -% Configuration is via TikZ keys and styles. -% \begin{macrocode} -\tikzset{ - knot/.code={ - \tl_if_eq:nnTF {#1} {none} - { - \tikz@addmode{\tikz@mode@doublefalse} - } - { - \tikz@addmode{\tikz@mode@doubletrue} - \tl_if_eq:nnTF {\pgfkeysnovalue} {#1} - { - \tikz@addoption{\pgfsetinnerstrokecolor{.}} - } - { - \pgfsetinnerstrokecolor{#1} - } - \tikz@addoption{ - \pgfsetstrokecolor{knotbg} - } - \tl_set:Nn \tikz@double@setup{ - \pgfsetinnerlinewidth{\pgflinewidth} - \pgfsetlinewidth{\dim_eval:n {\tl_use:N \l__knot_gap_tl \pgflinewidth}} - } - } - }, - knot~ gap/.store~ in=\l__knot_gap_tl, - knot~ gap=3, - knot~ diagram/.is~family, - knot~ diagram/.unknown/.code={ - \tl_set_eq:NN \l__knot_tmpa_tl \pgfkeyscurrentname - \pgfkeysalso{ - /tikz/\l__knot_tmpa_tl=#1 - } - }, - background~ colour/.code={% - \colorlet{knotbg}{#1}% - }, - background~ color/.code={% - \colorlet{knotbg}{#1}% - }, - background~ colour=white, - knot~ diagram, - name/.store~ in=\l__knot_name_tl, - name={knot}, - save~ intersections/.is~ choice, - save~ intersections/.default=true, - save~ intersections/true/.code={ - \bool_set_true:N \l__knot_save_bool - }, - save~ intersections/false/.code={ - \bool_set_false:N \l__knot_save_bool - }, - every~ strand/.style={draw}, - ignore~ endpoint~ intersections/.code={ - \tl_if_eq:nnTF {#1} {true} - { - \bool_set_true:N \l__knot_ignore_ends_bool - } - { - \bool_set_false:N \l__knot_ignore_ends_bool - } - }, - ignore~ endpoint~ intersections/.default=true, - consider~ self~ intersections/.is~choice, - consider~ self~ intersections/true/.code={ - \bool_set_true:N \l__knot_self_intersections_bool - \bool_set_true:N \l__knot_splits_bool - }, - consider~ self~ intersections/false/.code={ - \bool_set_false:N \l__knot_self_intersections_bool - \bool_set_false:N \l__knot_splits_bool - }, - consider~ self~ intersections/no~ splits/.code={ - \bool_set_true:N \l__knot_self_intersections_bool - \bool_set_false:N \l__knot_splits_bool - }, - consider~ self~ intersections/.default={true}, - clip~ radius/.code={ - \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} - \dim_set:Nn \l__knot_clip_draw_radius_dim {#1+2pt} - }, - clip~ draw~ radius/.code={ - \dim_set:Nn \l__knot_clip_draw_radius_dim {#1} - }, - clip~ background~ radius/.code={ - \dim_set:Nn \l__knot_clip_bg_radius_dim {#1} - }, - clip~ radius=10pt, - end~ tolerance/.code={ - \dim_set:Nn \l__knot_tolerance_dim {#1} - }, - end~ tolerance=14pt, - clip/.style={ - clip - }, - background~ clip/.style={ - clip - }, - clip~ width/.code={ - \tl_set:Nn \l__knot_clip_width_tl {#1} - }, - clip~ width=3, - flip~ crossing/.code={% - \tl_clear_new:c {l__knot_crossing_#1} - \tl_set:cn {l__knot_crossing_#1} {x} - }, - ignore~ crossing/.code={% - \tl_clear_new:c {l__knot_ignore_crossing_#1} - \tl_set:cn {l__knot_ignore_crossing_#1} {x} - }, - draft~ mode/.is~ choice, - draft~ mode/off/.code={% - \bool_set_false:N \l__knot_draft_bool - \bool_set_false:N \l__knot_super_draft_bool - }, - draft~ mode/crossings/.code={% - \bool_set_true:N \l__knot_draft_bool - \bool_set_false:N \l__knot_super_draft_bool - }, - draft~ mode/strands/.code={% - \bool_set_true:N \l__knot_draft_bool - \bool_set_true:N \l__knot_super_draft_bool - }, - draft/.is~ family, - draft, - crossing~ label/.style={ - overlay, - fill=white, - fill~ opacity=.5, - text~ opacity=1, - text=blue, - pin~ edge={blue,<-} - }, - strand~ label/.style={ - overlay, - circle, - draw=purple, - fill=white, - fill~ opacity=.5, - text~ opacity=1, - text=purple, - inner~ sep=0pt - }, -} -% \end{macrocode} -% -% Wrapper around \Verb+\tikzset+ for applying keys from a token list, checking for if the given token list exists. -% \begin{macrocode} -\cs_new_nopar:Npn \knot_apply_style:N #1 -{ - \tl_if_exist:NT #1 { - \exp_args:NV \tikzset #1 - } -} -\cs_generate_variant:Nn \knot_apply_style:N {c} -% \end{macrocode} -% -%\begin{macro}{\flipcrossings} -% The user can specify a comma separated list of crossings to flip. -% \begin{macrocode} -\NewDocumentCommand \flipcrossings {m} -{ - \tikzset{knot~ diagram/flip~ crossing/.list={#1}}% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\strand} -% This is how the user specifies a strand of the knot. -% \begin{macrocode} -\NewDocumentCommand \strand { O{} } -{ - \int_incr:N \l__knot_strands_int - \tl_clear_new:c {l__knot_options_strand \int_use:N \l__knot_strands_int} - \tl_set:cn {l__knot_options_strand \int_use:N \l__knot_strands_int} {#1} - \path[#1,save~ spath=knot strand \int_use:N \l__knot_strands_int] -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot} -% This is the wrapper environment that calls the knot generation code. -% \begin{macrocode} -\NewDocumentEnvironment{knot} { O{} } -{ - \knot_initialise:n {#1} -} -{ - \knot_render: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_initialise:n} -% Set up some stuff before loading in the strands. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_initialise:n #1 -{ - \tikzset{knot~ diagram/.cd,every~ knot~ diagram/.try,#1} - \int_zero:N \l__knot_strands_int - \tl_clear:N \l__knot_redraws_tl - \seq_gclear:N \l__knot_nodes_seq -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_render:} -% This is the code that starts the work of rendering the knot. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_render: -{ -% \end{macrocode} -% Start a scope and reset the transformation (since all transformations have already been taken into account when defining the strands). -% \begin{macrocode} - \pgfscope - \pgftransformreset -% \end{macrocode} -% Loop through the strands drawing each one for the first time. -% \begin{macrocode} - \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_draw_strand:n -% \end{macrocode} -% In super draft mode we don't do anything else. -% \begin{macrocode} - \bool_if:NF \l__knot_super_draft_bool - { -% \end{macrocode} -% In draft mode we draw labels at the ends of the strands; this also handles splitting curves to avoid self-intersections of Bezier curves if that's requested. -% \begin{macrocode} - \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_draw_labels:n -% \end{macrocode} -% If we're considering self intersections we need to split the strands into filaments. -% \begin{macrocode} - \bool_if:NTF \l__knot_self_intersections_bool - { - \knot_split_strands: - \int_set_eq:NN \l__knot_tmpa_int \l__knot_filaments_int - \tl_set:Nn \l__knot_prefix_tl {filament} - } - { - \int_set_eq:NN \l__knot_tmpa_int \l__knot_strands_int - \tl_set:Nn \l__knot_prefix_tl {strand} - } -% \end{macrocode} -% Initialise the intersection count. -% \begin{macrocode} - \int_gzero:N \l__knot_intersections_int -% \end{macrocode} -% If in draft mode we label the intersections, otherwise we just stick a coordinate at each one. -% \begin{macrocode} - \bool_if:NTF \l__knot_draft_bool - { - \tl_set:Nn \l__knot_node_tl { - \exp_not:N \node[coordinate, - pin={[node~ contents={\int_use:N \l__knot_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \l__knot_intersections_int \c_space_tl label/.try] - }] - } - } - { - \tl_set:Nn \l__knot_node_tl {\exp_not:N \node[coordinate]} - } -% \end{macrocode} -% This double loop steps through the pieces (strands or filaments) and computes the intersections and does stuff with those. -% \begin{macrocode} - \int_step_variable:nnnNn {1} {1} {\l__knot_tmpa_int - 1} \l__knot_tmpa_tl - { - \int_step_variable:nnnNn {\tl_use:N \l__knot_tmpa_tl + 1} {1} {\l__knot_tmpa_int} \l__knot_tmpb_tl - { - \knot_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl - } - } -% \end{macrocode} -% If any redraws were requested, do them here. -% \begin{macrocode} - \tl_use:N \l__knot_redraws_tl -% \end{macrocode} -% Draw the crossing nodes -% \begin{macrocode} - \seq_use:Nn \l__knot_nodes_seq {} - } -% \end{macrocode} -% Close the scope -% \begin{macrocode} - \endpgfscope -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_draw_strand:n} -% This renders a strand using the options originally specified. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_draw_strand:n #1 -{ - \pgfscope - \group_begin: - \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} - \tl_put_right:Nv \l_tmpa_tl {l__knot_options_strand #1} - \tl_put_right:Nn \l_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} - \spath_bake_round:n {knot strand #1} - \spath_tikz_path:Vn \l_tmpa_tl {knot strand #1} - \group_end: - \endpgfscope -} -\cs_generate_variant:Nn \tl_put_right:Nn {Nv} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_draw_labels:n} -% Draw a label at each end of each strand, if in draft mode. -% Also, if requested, split potentially self intersecting Bezier curves. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_draw_labels:n #1 -{ - \bool_if:NT \l__knot_draft_bool - { - \spath_get:nnN {knot strand #1} {final point} \l__knot_tmpb_tl - \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}} - \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; - \spath_get:nnN {knot strand #1} {initial point} \l__knot_tmpb_tl - \dim_set:Nn \l__knot_tmpa_dim {\tl_item:Nn \l__knot_tmpb_tl {1}} - \dim_set:Nn \l__knot_tmpb_dim {\tl_item:Nn \l__knot_tmpb_tl {2}} - \node[knot~ diagram/draft/strand~label] at (\l__knot_tmpa_dim,\l__knot_tmpb_dim) {#1}; - } - \bool_if:nT { - \l__knot_self_intersections_bool - && - \l__knot_splits_bool - } - { - \tl_clear:N \l__knot_tmpa_tl - \spath_map_segment_function:nN {knot strand #1} \knot_split_self_intersects:NN - \spath_put:nnV {knot strand #1} {path} \l__knot_tmpa_tl - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_split_self_intersects:NN} -% This is the macro that does the split. -% Figuring out whether a Bezier cubic self intersects is apparently a difficult problem so we don't bother. -% We compute a point such that if there is an intersection then it lies on either side of the point. -% I don't recall where the formula came from! -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_split_self_intersects:NN #1#2 -{ - \tl_case:NnF #1 - { - \g__spath_curvetoa_tl - { - \fp_set:Nn \l_tmpa_fp - { - (\tl_item:Nn #2 {3} - 3 * \tl_item:Nn #2 {6} + 3 * \tl_item:Nn #2 {9} - \tl_item:Nn #2 {12}) - * - (3 * \tl_item:Nn #2 {8} - 3 * \tl_item:Nn #2 {11}) - - - (\tl_item:Nn #2 {2} - 3 * \tl_item:Nn #2 {5} + 3 * \tl_item:Nn #2 {8} - \tl_item:Nn #2 {11}) - * - (3 * \tl_item:Nn #2 {9} - 3 * \tl_item:Nn #2 {12}) - } - \fp_set:Nn \l_tmpb_fp - { - (\tl_item:Nn #2 {2} - 3 * \tl_item:Nn #2 {5} + 3 * \tl_item:Nn #2 {8} - \tl_item:Nn #2 {11}) - * - (3 * \tl_item:Nn #2 {6} - 6 * \tl_item:Nn #2 {9} + 3 * \tl_item:Nn #2 {12}) - - - (\tl_item:Nn #2 {3} - 3 * \tl_item:Nn #2 {6} + 3 * \tl_item:Nn #2 {9} - \tl_item:Nn #2 {12}) - * - (3 * \tl_item:Nn #2 {5} - 6 * \tl_item:Nn #2 {8} + 3 * \tl_item:Nn #2 {11}) - } - \fp_compare:nTF - { - \l_tmpb_fp != 0 - } - { - \fp_set:Nn \l_tmpa_fp {.5 * \l_tmpa_fp / \l_tmpb_fp} - \fp_compare:nTF - { - 0 < \l_tmpa_fp && \l_tmpa_fp < 1 - } - { - \spath_split_curve:VVNN \l_tmpa_fp #2 \l_tmpa_tl \l_tmpb_tl - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_set:Nx \l_tmpb_tl {\tl_tail:N \l_tmpb_tl} - \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl - \tl_put_right:NV \l__knot_tmpa_tl \l_tmpb_tl - } - { - \tl_set_eq:NN \l_tmpa_tl #2 - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl - } - } - { - \tl_set_eq:NN \l_tmpa_tl #2 - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl - } - } - \g__spath_lineto_tl - { - \tl_set_eq:NN \l_tmpa_tl #2 - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_set:Nx \l_tmpa_tl {\tl_tail:N \l_tmpa_tl} - \tl_put_right:NV \l__knot_tmpa_tl \l_tmpa_tl - } - } - { - \tl_put_right:NV \l__knot_tmpa_tl #2 - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_intersections:nn} -% This computes the intersections of two pieces and steps through them. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_intersections:nn #1#2 -{ - \group_begin: - \tl_set_eq:NN \l__knot_tmpa_tl \l__knot_prefix_tl - \tl_put_right:Nn \l__knot_tmpa_tl {#1} - \tl_set_eq:NN \l__knot_tmpb_tl \l__knot_prefix_tl - \tl_put_right:Nn \l__knot_tmpb_tl {#2} - \spath_get:nnN {knot \tl_use:N \l__knot_tmpa_tl} {path} \l__knot_tmpc_tl - \spath_get:nnN {knot \tl_use:N \l__knot_tmpb_tl} {path} \l__knot_tmpd_tl - - \bool_if:nTF { - \l__knot_save_bool - && - \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} - } - { - \tl_use:c {knot~ intersections~ \tl_use:N \l__knot_name_tl - \tl_use:N \l__knot_tmpa_tl - \tl_use:N \l__knot_tmpb_tl} - } - { -\pgfintersectionofpaths{\pgfsetpath\l__knot_tmpc_tl}{\pgfsetpath\l__knot_tmpd_tl} - - } - \int_compare:nT {\pgfintersectionsolutions > 0} - { - \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n - } - \knot_save_intersections:VV \l__knot_tmpa_tl \l__knot_tmpb_tl - \group_end: -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_save_intersections:nn} -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_save_intersections:nn #1#2 -{ - \bool_if:NT \l__knot_save_bool - { - \tl_clear:N \l__knot_aux_tl - \tl_put_right:Nn \l__knot_aux_tl - { - \def\pgfintersectionsolutions - } - \tl_put_right:Nx \l__knot_aux_tl - { - {\int_eval:n {\pgfintersectionsolutions}} - } - \int_compare:nT {\pgfintersectionsolutions > 0} - { - \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions} - { - \pgfpointintersectionsolution{##1} - \dim_set:Nn \l__knot_tmpa_dim {\pgf@x} - \dim_set:Nn \l__knot_tmpb_dim {\pgf@y} - \tl_put_right:Nn \l__knot_aux_tl - { - \expandafter\def\csname pgfpoint@intersect@solution@##1\endcsname - } - \tl_put_right:Nx \l__knot_aux_tl - { - {\exp_not:N \pgf@x=\dim_use:N \l__knot_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l__knot_tmpb_dim\relax} - } - } - \tl_set:Nn \l__knot_auxa_tl {\expandafter \gdef \csname knot~ intersections~} - \tl_put_right:Nx \l__knot_auxa_tl {\tl_use:N \l__knot_name_tl - #1 - #2} - \tl_put_right:Nn \l__knot_auxa_tl {\endcsname} - \tl_put_right:Nx \l__knot_auxa_tl {{\tl_to_str:N \l__knot_aux_tl}} - \protected@write\@auxout{}{\tl_to_str:N \l__knot_auxa_tl} - } - } -} -\cs_generate_variant:Nn \knot_save_intersections:nn {VV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_do_intersection:n} -% This handles a specific intersection. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_do_intersection:n #1 -{ -% \end{macrocode} -% Get the intersection coordinates. -% \begin{macrocode} - \pgfpointintersectionsolution{#1} - \dim_set:Nn \l__knot_tmpa_dim {\pgf@x} - \dim_set:Nn \l__knot_tmpb_dim {\pgf@y} -% \end{macrocode} -% If we're dealing with filaments, we can get false positives from the end points. -% \begin{macrocode} - \bool_set_false:N \l__knot_skip_bool - \bool_if:NT \l__knot_self_intersections_bool - { -% \end{macrocode} -% If one filament preceded the other, test for the intersection being at the relevant end point. -% \begin{macrocode} - \tl_set:Nn \l_tmpa_tl {knot previous} - \tl_put_right:NV \l_tmpa_tl \l__knot_tmpa_tl - \tl_set:Nv \l_tmpa_tl \l_tmpa_tl - \tl_if_eq:NNT \l_tmpa_tl \l__knot_tmpb_tl - { - \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point} - { - \bool_set_true:N \l__knot_skip_bool - } - } - - \tl_set:Nn \l_tmpa_tl {knot previous} - \tl_put_right:NV \l_tmpa_tl \l__knot_tmpb_tl - \tl_set:Nv \l_tmpa_tl \l_tmpa_tl - \tl_if_eq:NNT \l_tmpa_tl \l__knot_tmpa_tl - { - \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point} - { - \bool_set_true:N \l__knot_skip_bool - } - } - } -% \end{macrocode} -% The user can also say that end points of filaments (or strands) should simply be ignored anyway. -% \begin{macrocode} - \bool_if:NT \l__knot_ignore_ends_bool - { - \knot_test_endpoint:VnT \l__knot_tmpa_tl {initial point} - { - \bool_set_true:N \l__knot_skip_bool - } - \knot_test_endpoint:VnT \l__knot_tmpa_tl {final point} - { - \bool_set_true:N \l__knot_skip_bool - } - \knot_test_endpoint:VnT \l__knot_tmpb_tl {initial point} - { - \bool_set_true:N \l__knot_skip_bool - } - \knot_test_endpoint:VnT \l__knot_tmpb_tl {final point} - { - \bool_set_true:N \l__knot_skip_bool - } - } -% \end{macrocode} -% Assuming that we passed all the above tests, we render the crossing. -% \begin{macrocode} - \bool_if:NF \l__knot_skip_bool - { - - \int_gincr:N \l__knot_intersections_int -% \end{macrocode} -% This is the intersection test. -% If the intersection finder finds too many, it might be useful to ignore some. -% \begin{macrocode} - \bool_if:nF - { - \tl_if_exist_p:c {l__knot_ignore_crossing_ \int_use:N - \l__knot_intersections_int} - && - ! \tl_if_empty_p:c {l__knot_ignore_crossing_ \int_use:N - \l__knot_intersections_int} - } - { -% \end{macrocode} -% This is the flip test. -% We only render one of the paths. -% The ``flip'' swaps which one we render. -% \begin{macrocode} - \bool_if:nTF - { - \tl_if_exist_p:c {l__knot_crossing_ \int_use:N - \l__knot_intersections_int} - && - ! \tl_if_empty_p:c {l__knot_crossing_ \int_use:N - \l__knot_intersections_int} - } - { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpb_tl - } - { - \tl_set_eq:NN \l__knot_tmpg_tl \l__knot_tmpa_tl - } -% \end{macrocode} -% Now we know which one we're rendering, we test to see if we should also render its predecessor or successor to ensure that we render a path through the entire crossing region. -% \begin{macrocode} - \bool_if:NT \l__knot_self_intersections_bool - { - \knot_test_endpoint:VnT \l__knot_tmpg_tl {initial point} - { - \bool_set_true:N \l__knot_prepend_prev_bool - } - { - \bool_set_false:N \l__knot_prepend_prev_bool - } - \knot_test_endpoint:VnT \l__knot_tmpg_tl {final point} - { - \bool_set_true:N \l__knot_append_next_bool - } - { - \bool_set_false:N \l__knot_append_next_bool - } -% \end{macrocode} -% If either of those tests succeeded, do the appending or prepending. -% \begin{macrocode} - \bool_if:nT - { - \l__knot_prepend_prev_bool || \l__knot_append_next_bool - } - { - \spath_clone:nn {knot \tl_use:N \l__knot_tmpg_tl} - {knot \tl_use:N \l__knot_prefix_tl -1} - - \tl_set_eq:cc {l__knot_options_ \tl_use:N \l__knot_prefix_tl -1} {l__knot_options_ \tl_use:N \l__knot_tmpg_tl} - - \bool_if:nT - { - \l__knot_prepend_prev_bool - && - \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}} -% \end{macrocode} -% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment. -% \begin{macrocode} - \bool_if:nT - { - \l__knot_splits_bool - && - \tl_if_exist_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {initial point} - { - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl - \spath_prepend_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l__knot_tmpg_tl}}} - \spath_get:nnN {knot \tl_use:N \l__knot_prefix_tl -1} {path} \l_tmpa_tl - - } - } - } -% \end{macrocode} -% Now the same for appending. -% \begin{macrocode} - \bool_if:nT - { - \l__knot_append_next_bool - && - \tl_if_exist_p:c {knot next \tl_use:N \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}} - \bool_if:nT - { - \l__knot_splits_bool - && - \tl_if_exist_p:c {knot previous \tl_use:N - \l__knot_tmpg_tl} - && - !\tl_if_empty_p:c {knot previous \tl_use:N \l__knot_tmpg_tl} - } - { - \knot_test_endpoint:vnT {knot previous \tl_use:N \l__knot_tmpg_tl} {final point} - { - \spath_append_no_move:nn {knot \tl_use:N \l__knot_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l__knot_tmpg_tl}}} - - } - } - } - - \tl_set:Nn \l__knot_tmpg_tl {\tl_use:N \l__knot_prefix_tl -1} - } - } -% \end{macrocode} -% Now we render the crossing. -% \begin{macrocode} - \pgfscope - \group_begin: - \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \l__knot_intersections_int/.try} - \knot_draw_crossing:nVV {\tl_use:N \l__knot_tmpg_tl} \l__knot_tmpa_dim \l__knot_tmpb_dim - \group_end: - \endpgfscope -% \end{macrocode} -% This ends the boolean as to whether to consider the intersection at all -% \begin{macrocode} - } -% \end{macrocode} -% And stick a coordinate possibly with a label at the crossing. -% \begin{macrocode} - \seq_gpush:Nx \l__knot_nodes_seq { \l__knot_node_tl (\l__knot_name_tl \c_space_tl \int_use:N \l__knot_intersections_int) at (\dim_use:N \l__knot_tmpa_dim, \dim_use:N \l__knot_tmpb_dim) {};} - - } -} - -\cs_generate_variant:Nn \knot_intersections:nn {VV} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_test_endpoint:N} -% Test whether the point is near the intersection point. -% \begin{macrocode} -\prg_new_conditional:Npnn \knot_test_endpoint:N #1 {p,T,F,TF} -{ - \dim_compare:nTF - { - \dim_abs:n { \l__knot_tmpa_dim - \tl_item:Nn #1 {1}} - + - \dim_abs:n { \l__knot_tmpb_dim - \tl_item:Nn #1 {2}} - < - \l__knot_tolerance_dim - } - { - \prg_return_true: - } - { - \prg_return_false: - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_test_endpoint:nn} -% Wrapper around the above. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF} -{ - \spath_get:nnN {knot #1} {#2} \l__knot_tmpd_tl - \knot_test_endpoint:NTF \l__knot_tmpd_tl - { - \prg_return_true: - } - { - \prg_return_false: - } -} - -\cs_generate_variant:Nn \knot_test_endpoint:nnT {VnT,vnT} -\cs_generate_variant:Nn \knot_test_endpoint:nnF {VnF,vnF} -\cs_generate_variant:Nn \knot_test_endpoint:nnTF {VnTF,vnTF} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_draw_crossing:nnn} -% This is the code that actually renders a crossing. -% \begin{macrocode} -\cs_new_nopar:Npn \knot_draw_crossing:nnn #1#2#3 -{ - \group_begin: - \pgfscope - \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l__knot_clip_bg_radius_dim]; - - \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} - \tl_if_exist:cT {l__knot_options_ #1} - { - \tl_put_right:Nv \l_tmpa_tl {l__knot_options_ #1} - } - \tl_put_right:Nn \l_tmpa_tl {,knotbg,line~ width= \tl_use:N \l__knot_clip_width_tl * \pgflinewidth} - \spath_tikz_path:Vn \l_tmpa_tl {knot #1} - - \endpgfscope - - \pgfscope - \path[knot~ diagram/clip] (#2, #3) circle[radius=\l__knot_clip_draw_radius_dim]; - - \tl_set:Nn \l_tmpa_tl {knot~ diagram/every~ strand/.try,} - \tl_if_exist:cT {l__knot_options_ #1} - { - \tl_put_right:Nv \l_tmpa_tl {l__knot_options_ #1} - } - \tl_put_right:Nn \l_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try} - \spath_tikz_path:Vn \l_tmpa_tl {knot #1} - - \endpgfscope - \group_end: -} - -\cs_generate_variant:Nn \knot_draw_crossing:nnn {nVV} - -\cs_new_nopar:Npn \knot_draw_crossing:nn #1#2 -{ - \tikz@scan@one@point\pgfutil@firstofone #2 \relax - \knot_draw_crossing:nVV {#1} \pgf@x \pgf@y -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_split_strands:} -% This, and the following macros, are for splitting strands into filaments. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_split_strands: -{ - \int_gzero:N \l__knot_filaments_int - \int_step_function:nnnN {1} {1} {\l__knot_strands_int} \knot_split_strand:n - \int_step_function:nnnN {1} {1} {\l__knot_filaments_int} \knot_compute_nexts:n -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_compute_nexts:n} -% Each filament needs to know its predecessor and successor. -% We work out the predecessors as we go along, this fills in the successors. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_compute_nexts:n #1 -{ - \tl_clear_new:c {knot next \tl_use:c {knot previous filament #1}} - \tl_set:cn {knot next \tl_use:c {knot previous filament #1}} {filament #1} -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_split_strand:n} -% Sets up the split for a single strand. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_split_strand:n #1 -{ - \int_set_eq:NN \l__knot_component_start_int \l__knot_filaments_int - \int_incr:N \l__knot_component_start_int - \tl_set_eq:Nc \l__knot_tmpa_tl {l__knot_options_strand #1} - \spath_map_segment_function:nN {knot strand #1} \knot_save_filament:NN -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\knot_save_filament:NN} -% Saves a filament as a new \Verb+spath+ object. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \knot_save_filament:NN #1#2 -{ - \tl_case:NnF #1 - { - \g__spath_moveto_tl - { - \int_compare:nT {\l__knot_component_start_int < \l__knot_filaments_int} - { - \int_set_eq:NN \l__knot_component_start_int \l__knot_filaments_int - } - } - \g__spath_lineto_tl - { - \int_gincr:N \l__knot_filaments_int - \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int} - \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} #2 - \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl - - \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int} - \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int} - { - \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}} - } - } - \g__spath_curvetoa_tl - { - \int_gincr:N \l__knot_filaments_int - \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int} - \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} #2 - \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl - - \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int} - \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int} - { - \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}} - } - } - \g__spath_closepath_tl - { - \tl_show:N #2 - \int_gincr:N \l__knot_filaments_int - \spath_clear_new:n {knot filament \int_use:N \l__knot_filaments_int} - \tl_clear:N \l_tmpa_tl - \tl_put_right:Nx {\tl_item:Nn #2 {1}\tl_item:Nn #2 {2}\tl_item:Nn #2 {3}} - \tl_put_right:NV \l_tmpa_tl \g__spath_lineto_tl - \tl_put_right:Nx {\tl_item:Nn #2 {5}\tl_item:Nn #2 {6}} - \tl_show:N \l_tmpa_tl - \spath_put:nnV {knot filament \int_use:N \l__knot_filaments_int} {path} \l_tmpa_tl - \tl_set_eq:cN {l__knot_options_filament \int_use:N \l__knot_filaments_int} \l__knot_tmpa_tl - \tl_clear_new:c {knot previous filament \int_use:N \l__knot_filaments_int} - \int_compare:nF {\l__knot_component_start_int == \l__knot_filaments_int} - { - \tl_set:cx {knot previous filament \int_use:N \l__knot_filaments_int} {filament \int_eval:n {\l__knot_filaments_int - 1}} - } - \tl_set:cx {knot previous filament \int_use:N \l__knot_component_start_int} {filament \int_use:N \l__knot_filaments_int} - } - } - { - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\redraw} -% The user can redraw segments of the strands at specific locations. -% \begin{macrocode} -\NewDocumentCommand \redraw { m m } -{ -% \tikz@scan@one@point\pgfutil@firstofone #2 \relax - \tl_put_right:Nn \l__knot_redraws_tl {\knot_draw_crossing:nn} - \tl_put_right:Nx \l__knot_redraws_tl { - {strand #1} {#2}% {\dim_use:N \pgf@x} {\dim_use:N \pgf@y} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macrocode} -\ExplSyntaxOff -% \end{macrocode} -% -% \begin{macro}{\pgf@sh@@knotanchor} -% Add the extra anchors for the knot crossing nodes. -% \begin{macrocode} -\def\pgf@sh@@knotanchor#1#2{% - \anchor{#2 north west}{% - \csname pgf@anchor@knot #1@north west\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 north east}{% - \csname pgf@anchor@knot #1@north east\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 south west}{% - \csname pgf@anchor@knot #1@south west\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 south east}{% - \csname pgf@anchor@knot #1@south east\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 north}{% - \csname pgf@anchor@knot #1@north\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 east}{% - \csname pgf@anchor@knot #1@east\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 west}{% - \csname pgf@anchor@knot #1@west\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% - \anchor{#2 south}{% - \csname pgf@anchor@knot #1@south\endcsname% - \pgf@x=#2\pgf@x% - \pgf@y=#2\pgf@y% - }% -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot crossing} -% \begin{macrocode} -\pgfdeclareshape{knot crossing} -{ - \inheritsavedanchors[from=circle] % this is nearly a circle - \inheritanchorborder[from=circle] - \inheritanchor[from=circle]{north} - \inheritanchor[from=circle]{north west} - \inheritanchor[from=circle]{north east} - \inheritanchor[from=circle]{center} - \inheritanchor[from=circle]{west} - \inheritanchor[from=circle]{east} - \inheritanchor[from=circle]{mid} - \inheritanchor[from=circle]{mid west} - \inheritanchor[from=circle]{mid east} - \inheritanchor[from=circle]{base} - \inheritanchor[from=circle]{base west} - \inheritanchor[from=circle]{base east} - \inheritanchor[from=circle]{south} - \inheritanchor[from=circle]{south west} - \inheritanchor[from=circle]{south east} - \inheritanchorborder[from=circle] - \pgf@sh@@knotanchor{crossing}{2} - \pgf@sh@@knotanchor{crossing}{3} - \pgf@sh@@knotanchor{crossing}{4} - \pgf@sh@@knotanchor{crossing}{8} - \pgf@sh@@knotanchor{crossing}{16} - \pgf@sh@@knotanchor{crossing}{32} - \backgroundpath{ - \pgfutil@tempdima=\radius% - \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}% - \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}% - \ifdim\pgf@xb<\pgf@yb% - \advance\pgfutil@tempdima by-\pgf@yb% - \else% - \advance\pgfutil@tempdima by-\pgf@xb% - \fi% - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot over cross} -% \begin{macrocode} -\pgfdeclareshape{knot over cross} -{ - \inheritsavedanchors[from=rectangle] % this is nearly a circle - \inheritanchorborder[from=rectangle] - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north west} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{mid} - \inheritanchor[from=rectangle]{mid west} - \inheritanchor[from=rectangle]{mid east} - \inheritanchor[from=rectangle]{base} - \inheritanchor[from=rectangle]{base west} - \inheritanchor[from=rectangle]{base east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{south east} - \inheritanchorborder[from=rectangle] - \backgroundpath{ - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} - } - \foregroundpath{ -% store lower right in xa/ya and upper right in xb/yb - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot under cross} -% \begin{macrocode} -\pgfdeclareshape{knot under cross} -{ - \inheritsavedanchors[from=rectangle] % this is nearly a circle - \inheritanchorborder[from=rectangle] - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north west} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{mid} - \inheritanchor[from=rectangle]{mid west} - \inheritanchor[from=rectangle]{mid east} - \inheritanchor[from=rectangle]{base} - \inheritanchor[from=rectangle]{base west} - \inheritanchor[from=rectangle]{base east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{south east} - \inheritanchorborder[from=rectangle] - \backgroundpath{ - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} - } - \foregroundpath{ -% store lower right in xa/ya and upper right in xb/yb - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot vert} -% \begin{macrocode} -\pgfdeclareshape{knot vert} -{ - \inheritsavedanchors[from=rectangle] % this is nearly a circle - \inheritanchorborder[from=rectangle] - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north west} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{mid} - \inheritanchor[from=rectangle]{mid west} - \inheritanchor[from=rectangle]{mid east} - \inheritanchor[from=rectangle]{base} - \inheritanchor[from=rectangle]{base west} - \inheritanchor[from=rectangle]{base east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{south east} - \inheritanchorborder[from=rectangle] - \backgroundpath{ -% store lower right in xa/ya and upper right in xb/yb - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}} - \pgfpathlineto{\pgfqpoint{\pgf@xa}{\pgf@yb}} - \pgfpathmoveto{\pgfqpoint{\pgf@xb}{\pgf@yb}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} - } -} -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{knot horiz} -% \begin{macrocode} -\pgfdeclareshape{knot horiz} -{ - \inheritsavedanchors[from=rectangle] % this is nearly a circle - \inheritanchorborder[from=rectangle] - \inheritanchor[from=rectangle]{north} - \inheritanchor[from=rectangle]{north west} - \inheritanchor[from=rectangle]{north east} - \inheritanchor[from=rectangle]{center} - \inheritanchor[from=rectangle]{west} - \inheritanchor[from=rectangle]{east} - \inheritanchor[from=rectangle]{mid} - \inheritanchor[from=rectangle]{mid west} - \inheritanchor[from=rectangle]{mid east} - \inheritanchor[from=rectangle]{base} - \inheritanchor[from=rectangle]{base west} - \inheritanchor[from=rectangle]{base east} - \inheritanchor[from=rectangle]{south} - \inheritanchor[from=rectangle]{south west} - \inheritanchor[from=rectangle]{south east} - \inheritanchorborder[from=rectangle] - \foregroundpath{ -% store lower right in xa/ya and upper right in xb/yb - \southwest \pgf@xa=\pgf@x \pgf@ya=\pgf@y - \northeast \pgf@xb=\pgf@x \pgf@yb=\pgf@y - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@ya}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@ya}} - \pgfpathmoveto{\pgfqpoint{\pgf@xa}{\pgf@yb}} - \pgfpathlineto{\pgfqpoint{\pgf@xb}{\pgf@yb}} - } -} -% \end{macrocode} -% \end{macro} -% -% \iffalse -%</knots> -% \fi -%\Finale -\endinput |