summaryrefslogtreecommitdiff
path: root/graphics/pgf/contrib/spath3/spath3_code.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/pgf/contrib/spath3/spath3_code.dtx')
-rw-r--r--graphics/pgf/contrib/spath3/spath3_code.dtx4137
1 files changed, 3169 insertions, 968 deletions
diff --git a/graphics/pgf/contrib/spath3/spath3_code.dtx b/graphics/pgf/contrib/spath3/spath3_code.dtx
index c5c584c4f8..621ab942f7 100644
--- a/graphics/pgf/contrib/spath3/spath3_code.dtx
+++ b/graphics/pgf/contrib/spath3/spath3_code.dtx
@@ -35,7 +35,7 @@ See http://www.latex-project.org/lppl.txt
\endpreamble
\postamble
-Copyright (C) 2011-2019 by Andrew Stacey <loopspace@mathforge.org>
+Copyright (C) 2011-2021 by Andrew Stacey <loopspace@mathforge.org>
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License (LPPL), either
@@ -47,7 +47,7 @@ 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
+This work consists of the files spath3_code.dtx
calligraphy_doc.tex
knots_doc.tex
spath3.tex
@@ -143,7 +143,7 @@ and the derived files spath3.ins,
%</driver>
% \fi
%
-% \CheckSum{6848}
+% \CheckSum{8404}
%
% \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
@@ -167,9 +167,15 @@ and the derived files spath3.ins,
% \changes{1.2}{2019/02/12}{More fixes due to changes in LaTeX3}
% \changes{1.4}{2020/12/18}{A fair amount of code reimplementation and reorganisation, together with defining TikZ keys to make functions available for use.}
% \changes{2.0}{2021/01/19}{Refactored the code to remove the OO approach and make it functional, introduced the spath3 TikZ library to provide a user interface.}
+% \changes{2.2}{2021/02/05}{Bugfixes and improvements, mainly with regard to the intersection and splitting routines.}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
+% \pdfstringdefDisableCommands{%
+% \def\\{}%
+% \def\url#1{<#1>}%
+% }
+%
% \providecommand*{\url}{\texttt}
% \GetFileInfo{spath3.sty}
% \title{The \textsf{spath3} package: code}
@@ -250,12 +256,13 @@ and the derived files spath3.ins,
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}
\RequirePackage{pgf}
-\ProvidesExplPackage {spath3} {2021/01/19} {2.0} {Functions for
+\ProvidesExplPackage {spath3} {2021/02/05} {2.2} {Functions for
manipulating PGF soft paths}
\RequirePackage{xparse}
% \end{macrocode}
%
% Utilities copied from \url{https://github.com/loopspace/LaTeX3-Utilities} for adding something in braces to a token list.
+% I find I use this quite a lot in my packages.
% \begin{macrocode}
\cs_new_protected:Nn \@@_tl_put_right_braced:Nn
{
@@ -281,33 +288,77 @@ manipulating PGF soft paths}
\cs_generate_variant:Nn \@@_tl_gput_left_braced:Nn { NV, cV, cv, Nx, cx }
% \end{macrocode}
%
-% We need a slew of temporary variables.
+%
+% I had to think a bit about how to get \TeX\ to work the way I wanted.
+% I'm really defining \emph{functions} but \TeX\ doesn't really have that concept, even with all the amazing \LaTeX3 stuff.
+% The main issue I had was with scoping and return values.
+% By default, \TeX\ functions aren't scoped -- they work on the same level as the calling functions.
+% To protect the internals from being overwritten, each core function works inside a group.
+% But then I have to work to get the answer out of it.
+% So each of my core functions finishes by storing its return value in an appropriate \Verb+output+ variable.
+% The core functions are then wrapped in a more user friendly interface that will take that output and assign it to a variable.
+% This also means that I can deal with local and global versions without duplicating code.
+%
+% \begin{macrocode}
+\tl_new:N \g_@@_output_tl
+\int_new:N \g_@@_output_int
+\seq_new:N \g_@@_output_seq
+\bool_new:N \g_@@_output_bool
+% \end{macrocode}
+%
+% To avoid creating vast numbers of variables, we provide ourselves with a few that we reuse frequently.
+% For that reason, most of them don't have very exciting names.
+%
+% These are general purpose variables.
% \begin{macrocode}
\tl_new:N \l_@@_tmpa_tl
\tl_new:N \l_@@_tmpb_tl
\tl_new:N \l_@@_tmpc_tl
\tl_new:N \l_@@_tmpd_tl
\tl_new:N \l_@@_tmpe_tl
+\tl_new:N \l_@@_tmpf_tl
+\tl_new:N \l_@@_tmpg_tl
+\tl_new:N \l_@@_tmph_tl
+\tl_new:N \l_@@_tmpi_tl
\seq_new:N \l_@@_tmpa_seq
\seq_new:N \l_@@_tmpb_seq
-
-\tl_new:N \g_@@_output_tl
-\int_new:N \g_@@_output_int
-\seq_new:N \g_@@_output_seq
+\seq_new:N \l_@@_tmpc_seq
\dim_new:N \l_@@_tmpa_dim
\dim_new:N \l_@@_tmpb_dim
-\dim_new:N \l_@@_move_x_dim
-\dim_new:N \l_@@_move_y_dim
+
\fp_new:N \l_@@_tmpa_fp
\fp_new:N \l_@@_tmpb_fp
+\fp_new:N \l_@@_tmpc_fp
+
\int_new:N \l_@@_tmpa_int
+\int_new:N \l_@@_tmpb_int
-\bool_new:N \g_@@_output_bool
+\bool_new:N \l_@@_tmpa_bool
+% \end{macrocode}
+%
+% Whenever I need more than two \Verb+dim+ variables it is because I need to remember the position of a move.
+%
+% \begin{macrocode}
+\dim_new:N \l_@@_move_x_dim
+\dim_new:N \l_@@_move_y_dim
+% \end{macrocode}
+%
+% Closed paths often need special handling.
+% When it's needed, this will say whether the path is closed or not.
+%
+% \begin{macrocode}
\bool_new:N \l_@@_closed_bool
% \end{macrocode}
%
+% The intersection routine can't happen inside a group so we need two token lists to hold the paths that we'll intersect.
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_intersecta_tl
+\tl_new:N \l_@@_intersectb_tl
+% \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.
% These are global constants so that they can be used in other packages.
% \begin{macrocode}
@@ -319,28 +370,16 @@ manipulating PGF soft paths}
\tl_const:Nn \c_spath_closepath_tl {\pgfsyssoftpath@closepathtoken}
% \end{macrocode}
%
-%
% We will want to be able to use anonymous spaths internally, so we create a global counter that we can use to refer to them.
% \begin{macrocode}
\int_new:N \g_@@_anon_int
\int_gzero:N \g_@@_anon_int
% \end{macrocode}
%
-% Groups and iterations don't mix well and I haven't got a good scheme for protecting local calculations when iterating, so we do our best with iteration-specific variables.
-% \begin{macrocode}
-\tl_new:N \l_@@_itera_tl
-\tl_new:N \l_@@_iterb_tl
-\tl_new:N \l_@@_iterc_tl
-\tl_new:N \l_@@_iterd_tl
-\tl_new:N \l_@@_iterp_tl
-\dim_new:N \l_@@_itera_dim
-\dim_new:N \l_@@_iterb_dim
-\seq_new:N \l_@@_iter_seq
-% \end{macrocode}
-%
% And some error messages
% \begin{macrocode}
-\msg_new:nnn { spath3 } { unknown path construction } { The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.}
+\msg_new:nnn { spath3 } { unknown path construction }
+{ The~ path~ construction~ element~ #1~ is~ not~ currently~ supported.}
% \end{macrocode}
%
%
@@ -351,7 +390,7 @@ manipulating PGF soft paths}
% The macro to store it in is the first argument.
% These functions occur in two versions, the one with the \texttt{g} makes the assignment global.
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_segments_to_seq:Nn,
% \spath_segments_gto_seq:Nn
%}
@@ -360,131 +399,131 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \@@_segments_to_seq:n #1
{
\group_begin:
- \tl_set:Nn \l_@@_itera_tl {#1}
- \tl_clear:N \l_@@_iterb_tl
- \seq_clear:N \l_@@_iter_seq
- \dim_zero:N \l_@@_itera_dim
- \dim_zero:N \l_@@_iterb_dim
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \seq_clear:N \l_@@_tmpa_seq
+ \dim_zero:N \l_@@_tmpa_dim
+ \dim_zero:N \l_@@_tmpb_dim
\bool_until_do:nn {
- \tl_if_empty_p:N \l_@@_itera_tl
+ \tl_if_empty_p:N \l_@@_tmpa_tl
}
{
- \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
- \tl_case:NnF \l_@@_iterc_tl
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_case:NnF \l_@@_tmpc_tl
{
\c_spath_moveto_tl
{
- \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_set:Nx \l_@@_iterd_tl {\tl_head:N \l_@@_itera_tl}
- \tl_if_eq:NNF \l_@@_iterd_tl \c_spath_moveto_tl
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_if_eq:NNF \l_@@_tmpd_tl \c_spath_moveto_tl
{
- \tl_clear:N \l_@@_iterb_tl
+ \tl_clear:N \l_@@_tmpb_tl
}
}
\c_spath_lineto_tl
{
- \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
- \tl_put_right:Nx \l_@@_iterb_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_use:N \l_@@_itera_dim}
- {\dim_use:N \l_@@_iterb_dim}
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
}
- \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_lineto_tl
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
\c_spath_curvetoa_tl
{
- \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
- \tl_put_right:Nx \l_@@_iterb_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_use:N \l_@@_itera_dim}
- {\dim_use:N \l_@@_iterb_dim}
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
}
- \tl_put_right:NV \l_@@_iterb_tl \c_spath_curvetoa_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
\prg_replicate:nn {2} {
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
\c_spath_closepath_tl
{
- \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
- \tl_put_right:Nx \l_@@_iterb_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_use:N \l_@@_itera_dim}
- {\dim_use:N \l_@@_iterb_dim}
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
}
- \tl_put_right:NV \l_@@_iterb_tl \c_spath_lineto_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \c_spath_lineto_tl
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
}
{
- \tl_set_eq:NN \l_@@_iterb_tl \l_@@_iterc_tl
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_itera_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpc_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \tl_put_right:Nx \l_@@_iterb_tl {{\tl_head:N \l_@@_itera_tl}}
- \dim_set:Nn \l_@@_iterb_dim {\tl_head:N \l_@@_itera_tl}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\tl_head:N \l_@@_tmpa_tl}}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_if_empty:NF \l_@@_iterb_tl
+ \tl_if_empty:NF \l_@@_tmpb_tl
{
- \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl
+ \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpb_tl
}
- \tl_clear:N \l_@@_iterb_tl
+ \tl_clear:N \l_@@_tmpb_tl
}
\seq_gclear:N \g_@@_output_seq
- \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq
+ \seq_gset_eq:NN \g_@@_output_seq \l_@@_tmpa_seq
\group_end:
}
\cs_new_protected_nopar:Npn \spath_segments_to_seq:Nn #1#2
@@ -506,7 +545,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_components_to_seq:Nn,
% \spath_components_gto_seq:Nn,
% \spath_components_to_clist:Nn,
@@ -517,33 +556,33 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \@@_components_to_seq:n #1
{
\group_begin:
- \tl_set:Nn \l_@@_itera_tl {#1}
- \seq_clear:N \l_@@_iter_seq
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
- \tl_put_right:NV \l_@@_itera_tl \c_spath_moveto_tl
- \tl_set_eq:NN \l_@@_iterb_tl \c_spath_moveto_tl
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \seq_clear:N \l_@@_tmpa_seq
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \c_spath_moveto_tl
\bool_do_until:nn {
- \tl_if_empty_p:N \l_@@_itera_tl
+ \tl_if_empty_p:N \l_@@_tmpa_tl
}
{
- \tl_set:Nx \l_@@_iterc_tl {\tl_head:N \l_@@_itera_tl}
- \tl_if_eq:NNT \l_@@_iterc_tl \c_spath_moveto_tl
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_if_eq:NNT \l_@@_tmpc_tl \c_spath_moveto_tl
{
- \seq_put_right:NV \l_@@_iter_seq \l_@@_iterb_tl
- \tl_clear:N \l_@@_iterb_tl
+ \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpb_tl
+ \tl_clear:N \l_@@_tmpb_tl
}
- \tl_if_single:NTF \l_@@_iterc_tl
+ \tl_if_single:NTF \l_@@_tmpc_tl
{
- \tl_put_right:NV \l_@@_iterb_tl \l_@@_iterc_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpc_tl
}
{
- \tl_put_right:Nx \l_@@_iterb_tl {{\l_@@_iterc_tl}}
+ \tl_put_right:Nx \l_@@_tmpb_tl {{\l_@@_tmpc_tl}}
}
- \tl_set:Nx \l_@@_itera_tl {\tl_tail:N \l_@@_itera_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
\seq_gclear:N \g_@@_output_seq
- \seq_gset_eq:NN \g_@@_output_seq \l_@@_iter_seq
+ \seq_gset_eq:NN \g_@@_output_seq \l_@@_tmpa_seq
\group_end:
}
\cs_new_protected_nopar:Npn \spath_components_to_seq:Nn #1#2
@@ -582,7 +621,7 @@ manipulating PGF soft paths}
% \end{macro}
%
%
-% \begin{macro}{\spath_length:n}
+% \begin{macro}[internal]{\spath_length:n}
% Counts the number of triples in the path.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \spath_length:n #1
@@ -593,7 +632,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_reallength:Nn,
% \spath_greallength:Nn
% }
@@ -604,8 +643,8 @@ manipulating PGF soft paths}
\group_begin:
\int_set:Nn \l_@@_tmpa_int {0}
\tl_map_inline:nn {#1} {
- \tl_set:Nn \l_@@_tmpc_tl {##1}
- \tl_case:NnT \l_@@_tmpc_tl
+ \tl_set:Nn \l_@@_tmpa_tl {##1}
+ \tl_case:NnT \l_@@_tmpa_tl
{
\c_spath_lineto_tl {}
\c_spath_curveto_tl {}
@@ -636,7 +675,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_numberofcomponents:Nn,
% \spath_gnumberofcomponents:Nn
% }
@@ -667,18 +706,18 @@ manipulating PGF soft paths}
\int_set_eq:NN #1 \g_@@_output_int
\int_gzero:N \g_@@_output_int
}
-\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV}
+\cs_generate_variant:Nn \spath_numberofcomponents:Nn {NV, cn, cV, Nv}
\cs_new_protected_nopar:Npn \spath_gnumberofcomponents:Nn #1#2
{
\@@_numberofcomponents:n {#2}
\int_gset_eq:NN #1 \g_@@_output_int
\int_gzero:N \g_@@_output_int
}
-\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV}
+\cs_generate_variant:Nn \spath_gnumberofcomponents:Nn {NV, cn, cV, Nv}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_initialpoint:Nn,
% \spath_ginitialpoint:Nn
% }
@@ -687,13 +726,13 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \@@_initialpoint:n #1
{
\group_begin:
- \tl_clear:N \l_@@_tmpb_tl
- \tl_set:Nx \l_@@_tmpb_tl
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_set:Nx \l_@@_tmpa_tl
{
{ \tl_item:nn {#1} {2} }
{ \tl_item:nn {#1} {3} }
}
- \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
\cs_new_protected_nopar:Npn \spath_initialpoint:Nn #1#2
@@ -713,7 +752,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_finalpoint:Nn,
% \spath_gfinalpoint:Nn,
% }
@@ -750,7 +789,60 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
+% \spath_finalmovepoint:Nn,
+% \spath_gfinalmovepoint:Nn
+% }
+% Get the last move on the path.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_finalmovepoint:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpc_tl { {0pt} {0pt} }
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \bool_do_until:nn
+ {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_case:Nn \l_@@_tmpb_tl
+ {
+ \c_spath_moveto_tl
+ {
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ { \tl_item:Nn \l_@@_tmpa_tl {2} }
+ { \tl_item:Nn \l_@@_tmpa_tl {3} }
+ }
+ }
+ }
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpc_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_finalmovepoint:Nn #1#2
+{
+ \@@_finalmovepoint:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_finalmovepoint:Nn {NV, cn, cV}
+\cs_new_protected_nopar:Npn \spath_gfinalmovepoint:Nn #1#2
+{
+ \@@_finalmovepoint:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gfinalmovepoint:Nn {NV, cn, cV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
% \spath_reverse:Nn,
% \spath_greverse:Nn
% }
@@ -836,7 +928,10 @@ manipulating PGF soft paths}
\bool_set_true:N \l_@@_closed_bool
}
{
- \msg_warning:nnx { spath3 } { unknown path construction } {\l_@@_tmpc_tl }
+ \msg_warning:nnx
+ { spath3 }
+ { unknown path construction }
+ {\l_@@_tmpc_tl }
}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
@@ -891,7 +986,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_initialaction:Nn,
% \spath_ginitialaction:Nn,
% }
@@ -931,7 +1026,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_finalaction:Nn,
% \spath_gfinalaction:Nn
% }
@@ -977,7 +1072,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_minbb:Nn,
% \spath_gminbb:Nn
% }
@@ -997,9 +1092,11 @@ manipulating PGF soft paths}
}
{
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \dim_set:Nn \l_@@_tmpa_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
+ \dim_set:Nn \l_@@_tmpa_dim
+ {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \dim_set:Nn \l_@@_tmpb_dim {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
+ \dim_set:Nn \l_@@_tmpb_dim
+ {\dim_min:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
\tl_clear:N \l_@@_tmpb_tl
@@ -1028,7 +1125,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_maxbb:Nn,
% \spath_gmaxbb:Nn,
% }
@@ -1048,9 +1145,11 @@ manipulating PGF soft paths}
}
{
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \dim_set:Nn \l_@@_tmpa_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
+ \dim_set:Nn \l_@@_tmpa_dim
+ {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpa_dim}}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \dim_set:Nn \l_@@_tmpb_dim {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
+ \dim_set:Nn \l_@@_tmpb_dim
+ {\dim_max:nn {\tl_head:N \l_@@_tmpa_tl} {\l_@@_tmpb_dim}}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
\tl_clear:N \l_@@_tmpb_tl
@@ -1079,7 +1178,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_save_to_aux:Nn,
% \spath_save_to_aux:N
% }
@@ -1124,13 +1223,13 @@ manipulating PGF soft paths}
% There is always a variant in which the path is specified by a macro and restored back in that same macro.
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_translate:Nnnn,
% \spath_translate:Nnn,
% \spath_gtranslate:Nnnn,
% \spath_gtranslate:Nnn
% }
-% Translates a path.
+% Translates a path by an amount.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_translate:nnn #1#2#3
{
@@ -1159,6 +1258,7 @@ manipulating PGF soft paths}
\tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
\group_end:
}
+\cs_generate_variant:Nn \@@_translate:nnn {nVV}
\cs_new_protected_nopar:Npn \spath_translate:Nnnn #1#2#3#4
{
\@@_translate:nnn {#2}{#3}{#4}
@@ -1200,8 +1300,80 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
+%
+%
+% \begin{macro}[internal]{
+% \spath_translate_to:Nnnn,
+% \spath_translate_to:Nnn,
+% \spath_gtranslate_to:Nnnn,
+% \spath_gtranslate_to:Nnn
+% }
+% Translates a path so that it starts at a point.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_translate_to:nnn #1#2#3
+{
+ \group_begin:
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {#1}
+
+ \dim_set:Nn \l_@@_tmpa_dim
+ {
+ #2
+ -
+ \tl_item:Nn \l_@@_tmpa_tl {1}
+ }
+ \dim_set:Nn \l_@@_tmpb_dim
+ {
+ #3
+ -
+ \tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+
+ \@@_translate:nVV {#1} \l_@@_tmpa_dim \l_@@_tmpb_dim
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_translate_to:Nnnn #1#2#3#4
+{
+ \@@_translate_to:nnn {#2}{#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_translate_to:Nnnn {NVxx, NVVV, NVnn}
+\cs_new_protected_nopar:Npn \spath_translate_to:Nnn #1#2#3
+{
+ \spath_translate_to:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_translate_to:Nnn {NVV, cnn, cVV}
+\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnnn #1#2#3#4
+{
+ \@@_translate_to:nnn {#2}{#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gtranslate_to:Nnnn {NVxx, NVVV, NVnn}
+\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nnn #1#2#3
+{
+ \spath_gtranslate_to:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_gtranslate_to:Nnn {NVV, cnn, cVV}
+% \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_protected_nopar:Npn \spath_translate_to:Nn #1#2
+{
+ \spath_translate_to:Nnn #1 #2
+}
+\cs_generate_variant:Nn \spath_translate_to:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gtranslate_to:Nn #1#2
+{
+ \spath_gtranslate_to:Nnn #1 #2
+}
+\cs_generate_variant:Nn \spath_gtranslate_to:Nn {NV}
+% \end{macrocode}
+% \end{macro}
+%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_scale:Nnnn,
% \spath_scale:Nnn,
% \spath_gscale:Nnnn,
@@ -1279,7 +1451,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_transform:Nnnnnnnn,
% \spath_transform:Nnnnnnn,
% \spath_gtransform:Nnnnnnnn,
@@ -1304,8 +1476,10 @@ manipulating PGF soft paths}
\tl_set:Nx \l_@@_tmpd_tl {\tl_head:N \l_@@_tmpa_tl}
\tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
- \fp_set:Nn \l_@@_tmpa_fp {\l_@@_tmpc_tl * #2 + \l_@@_tmpd_tl * #4 + #6}
- \fp_set:Nn \l_@@_tmpb_fp {\l_@@_tmpc_tl * #3 + \l_@@_tmpd_tl * #5 + #7}
+ \fp_set:Nn \l_@@_tmpa_fp
+ {\l_@@_tmpc_tl * #2 + \l_@@_tmpd_tl * #4 + #6}
+ \fp_set:Nn \l_@@_tmpb_fp
+ {\l_@@_tmpc_tl * #3 + \l_@@_tmpd_tl * #5 + #7}
\tl_put_right:Nx \l_@@_tmpb_tl
{
{\fp_to_dim:N \l_@@_tmpa_fp}
@@ -1322,7 +1496,8 @@ manipulating PGF soft paths}
\tl_set_eq:NN #1 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_transform:Nnnnnnnn {NVnnnnnn, Nnxxxxxx, cnnnnnnn}
+\cs_generate_variant:Nn \spath_transform:Nnnnnnnn
+{NVnnnnnn, Nnxxxxxx, cnnnnnnn}
\cs_new_protected_nopar:Npn \spath_transform:Nnnnnnn #1#2#3#4#5#6#7
{
\spath_transform:NVnnnnnn #1#1{#2}{#3}{#4}{#5}{#6}{#7}
@@ -1364,7 +1539,305 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
+% \spath_span:Nnnn,
+% \spath_span:Nnn,
+% \spath_gspan:Nnnn,
+% \spath_gspan:Nnn,
+% \spath_normalise:Nn,
+% \spath_normalise:N,
+% \spath_gnormalise:Nn,
+% \spath_gnormalise:N
+% }
+% The \Verb+span+ functions transform a path to start and end at specified points.
+% The \Verb+normalise+ functions transform it to start at the origin and end at \((1\mathrm{pt},0\mathrm{pt})\).
+%
+% If the path starts and ends at the same point then it is translated to the specified point (or origin) but not otherwise changed.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_span:nnn #1#2#3
+{
+ \group_begin:
+ \spath_initialpoint:Nn \l_@@_tmpa_tl {#1}
+ \spath_finalpoint:Nn \l_@@_tmpb_tl {#1}
+
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ (\tl_item:Nn \l_@@_tmpb_tl {1}) -
+ (\tl_item:Nn \l_@@_tmpa_tl {1})
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ (\tl_item:Nn \l_@@_tmpb_tl {2}) -
+ (\tl_item:Nn \l_@@_tmpa_tl {2})
+ }
+ \fp_set:Nn \l_@@_tmpc_fp
+ {
+ (\l_@@_tmpa_fp) * (\l_@@_tmpa_fp)
+ +
+ (\l_@@_tmpb_fp * \l_@@_tmpb_fp)
+ }
+
+ \fp_compare:nTF
+ {
+ \l_@@_tmpc_fp < 0.001
+ }
+ {
+ \spath_translate_to:Nnnn \l_@@_tmpd_tl {#1} #2
+ }
+ {
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ (
+ ((\tl_item:nn {#3} {1})
+ -
+ (\tl_item:nn {#2} {1}))
+ *
+ ((\tl_item:Nn \l_@@_tmpb_tl {1})
+ -
+ (\tl_item:Nn \l_@@_tmpa_tl {1}))
+ +
+ ((\tl_item:nn {#3} {2})
+ -
+ (\tl_item:nn {#2} {2}))
+ *
+ ((\tl_item:Nn \l_@@_tmpb_tl {2})
+ -
+ (\tl_item:Nn \l_@@_tmpa_tl {2}))
+ )
+ /
+ \l_@@_tmpc_fp
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ (
+ ((\tl_item:nn {#3} {2})
+ -
+ (\tl_item:nn {#2} {2}))
+ *
+ ((\tl_item:Nn \l_@@_tmpb_tl {1})
+ -
+ (\tl_item:Nn \l_@@_tmpa_tl {1}))
+ -
+ ((\tl_item:nn {#3} {1})
+ -
+ (\tl_item:nn {#2} {1}))
+ *
+ ((\tl_item:Nn \l_@@_tmpb_tl {2})
+ -
+ (\tl_item:Nn \l_@@_tmpa_tl {2}))
+ )
+ /
+ \l_@@_tmpc_fp
+ }
+
+ \tl_set:Nx \l_@@_tmpc_tl
+ {
+ {
+ \fp_to_decimal:N \l_@@_tmpa_fp
+ }
+ {
+ \fp_to_decimal:N \l_@@_tmpb_fp
+ }
+ {
+ \fp_eval:n { - \l_@@_tmpb_fp }
+ }
+ {
+ \fp_to_decimal:N \l_@@_tmpa_fp
+ }
+ {
+ \fp_to_dim:n
+ {
+ \tl_item:nn {#2} {1}
+ -
+ \l_@@_tmpa_fp * (\tl_item:Nn \l_@@_tmpa_tl {1})
+ +
+ \l_@@_tmpb_fp * (\tl_item:Nn \l_@@_tmpa_tl {2})
+ }
+ }
+ {
+ \fp_to_dim:n
+ {
+ \tl_item:nn {#2} {2}
+ -
+ \l_@@_tmpb_fp * (\tl_item:Nn \l_@@_tmpa_tl {1})
+ -
+ \l_@@_tmpa_fp * (\tl_item:Nn \l_@@_tmpa_tl {2})
+ }
+ }
+ }
+ \spath_transform:NnV \l_@@_tmpd_tl {#1} \l_@@_tmpc_tl
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpd_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_span:Nnnn #1#2#3#4
+{
+ \@@_span:nnn {#2}{#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_span:Nnnn {NVnn, NVVV, NnVV}
+\cs_new_protected_nopar:Npn \spath_span:Nnn #1#2#3
+{
+ \spath_span:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_span:Nnn {NVV, cnn, cvv, cVV}
+\cs_new_protected_nopar:Npn \spath_gspan:Nnnn #1#2#3#4
+{
+ \@@_span:nnn {#2}{#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gspan:Nnnn {NVnn, NVVV}
+\cs_new_protected_nopar:Npn \spath_gspan:Nnn #1#2#3
+{
+ \spath_gspan:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_gspan:Nnn {NVV, cnn, cvv, cVV}
+\cs_new_protected_nopar:Npn \@@_normalise:n #1
+{
+ \@@_span:nnn {#1}{{0pt}{0pt}}{{1pt}{0pt}}
+}
+\cs_new_protected_nopar:Npn \spath_normalise:Nn #1#2
+{
+ \@@_normalise:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_normalise:Nn {cn,NV, cV, cv}
+\cs_new_protected_nopar:Npn \spath_normalise:N #1
+{
+ \spath_normalise:NV #1#1
+}
+\cs_generate_variant:Nn \spath_normalise:N {c}
+\cs_new_protected_nopar:Npn \spath_gnormalise:Nn #1#2
+{
+ \@@_normalise:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gnormalise:Nn {cn,NV, cV, cv}
+\cs_new_protected_nopar:Npn \spath_gnormalise:N #1
+{
+ \spath_gnormalise:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gnormalise:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[internal]{
+% \spath_splice_between:Nnnn,
+% \spath_splice_between:Nnn,
+% \spath_gsplice_between:Nnnn,
+% \spath_gsplice_between:Nnn
+% }
+% This takes three paths and returns a single path in which the middle one is adjusted (and welded) so that it joins the first path to the third.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_splice_between:nnn #1#2#3
+{
+ \group_begin:
+ \spath_finalpoint:NV \l_@@_tmpd_tl {#1}
+ \spath_initialpoint:NV \l_@@_tmpe_tl {#3}
+ \spath_span:NnVV \l_@@_tmpb_tl {#2} \l_@@_tmpd_tl \l_@@_tmpe_tl
+ \spath_append_no_move:NnV \l_@@_tmpa_tl {#1} \l_@@_tmpb_tl
+ \spath_append_no_move:Nn \l_@@_tmpa_tl {#3}
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_splice_between:Nnnn #1#2#3#4
+{
+ \@@_splice_between:nnn {#2}{#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_splice_between:Nnnn {NVnn, NVVV}
+\cs_new_protected_nopar:Npn \spath_splice_between:Nnn #1#2#3
+{
+ \spath_splice_between:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_splice_between:Nnn {NVV, cnn, cvv, Nvn}
+\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnnn #1#2#3#4
+{
+ \@@_splice_between:nnn {#2}{#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplice_between:Nnnn {NVnn, NVVV}
+\cs_new_protected_nopar:Npn \spath_gsplice_between:Nnn #1#2#3
+{
+ \spath_gsplice_between:NVnn #1#1{#2}{#3}
+}
+\cs_generate_variant:Nn \spath_gsplice_between:Nnn {NVV, cnn, cvv}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
+% \spath_close_with:Nn,
+% \spath_gclose_with:Nn
+% }
+% Closes the first path by splicing in the second.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_close_with:nn #1#2
+{
+ \group_begin:
+ \spath_finalmovepoint:Nn \l_@@_tmpa_tl {#1}
+ \spath_finalpoint:Nn \l_@@_tmpb_tl {#1}
+ \dim_compare:nTF
+ {
+ \dim_abs:n
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {1}
+ -
+ \tl_item:Nn \l_@@_tmpb_tl {1}
+ }
+ +
+ \dim_abs:n
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {2}
+ -
+ \tl_item:Nn \l_@@_tmpb_tl {2}
+ }
+ < 0.01pt
+ }
+ {
+ \@@_close:n {#1}
+ }
+ {
+ \spath_span:NnVV \l_@@_tmpc_tl {#2} \l_@@_tmpb_tl \l_@@_tmpa_tl
+ \spath_append_no_move:NnV \l_@@_tmpd_tl {#1} \l_@@_tmpc_tl
+ \@@_close:V \l_@@_tmpd_tl
+ }
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_close_with:Nnn #1#2#3
+{
+ \@@_close_with:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_close_with:Nnn {cnn, cVV, cvv, NVn}
+\cs_new_protected_nopar:Npn \spath_close_with:Nn #1#2
+{
+ \spath_close_with:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_close_with:Nn {cn, cV, cv, NV}
+\cs_new_protected_nopar:Npn \spath_gclose_with:Nnn #1#2#3
+{
+ \@@_close_with:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gclose_with:Nnn {cnn, cVV, cvv, NVn}
+\cs_new_protected_nopar:Npn \spath_gclose_with:Nn #1#2
+{
+ \spath_gclose_with:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gclose_with:Nn {cn, cV, cv, NV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
% \spath_weld:Nnn,
% \spath_weld:Nn,
% \spath_gweld:Nnn,
@@ -1378,32 +1851,10 @@ manipulating PGF soft paths}
\group_begin:
\tl_set:Nn \l_@@_tmpa_tl {#1}
\tl_set:Nn \l_@@_tmpb_tl {#2}
+ \spath_finalpoint:Nn \l_@@_tmpc_tl {#1}
+ \spath_translate_to:NV \l_@@_tmpb_tl \l_@@_tmpc_tl
- \spath_finalpoint:NV \l_@@_tmpc_tl \l_@@_tmpa_tl
- \spath_initialpoint:NV \l_@@_tmpd_tl \l_@@_tmpb_tl
-
- \dim_set:Nn \l_@@_tmpa_dim
- {
- \tl_item:Nn \l_@@_tmpc_tl {1}
- -
- \tl_item:Nn \l_@@_tmpd_tl {1}
- }
- \dim_set:Nn \l_@@_tmpb_dim
- {
- \tl_item:Nn \l_@@_tmpc_tl {2}
- -
- \tl_item:Nn \l_@@_tmpd_tl {2}
- }
-
- \spath_translate:NVV \l_@@_tmpb_tl \l_@@_tmpa_dim \l_@@_tmpb_dim
-
- \prg_replicate:nn {3}
- {
- \tl_set:Nx \l_@@_tmpb_tl {\tl_tail:N \l_@@_tmpb_tl}
- }
-
- \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
- \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ \@@_append_no_move:VV \l_@@_tmpa_tl \l_@@_tmpb_tl
\group_end:
}
\cs_new_protected_nopar:Npn \spath_weld:Nnn #1#2#3
@@ -1434,7 +1885,7 @@ manipulating PGF soft paths}
% \end{macro}
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_append_no_move:Nnn,
% \spath_append_no_move:Nn,
% \spath_gappend_no_move:Nnn,
@@ -1456,18 +1907,19 @@ manipulating PGF soft paths}
\tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
+\cs_generate_variant:Nn \@@_append_no_move:nn {VV}
\cs_new_protected_nopar:Npn \spath_append_no_move:Nnn #1#2#3
{
\@@_append_no_move:nn {#2}{#3}
\tl_set_eq:NN #1 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn}
+\cs_generate_variant:Nn \spath_append_no_move:Nnn {NVV, NVn, NnV}
\cs_new_protected_nopar:Npn \spath_append_no_move:Nn #1#2
{
\spath_append_no_move:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv}
+\cs_generate_variant:Nn \spath_append_no_move:Nn {NV, cv, Nv}
\cs_new_protected_nopar:Npn \spath_gappend_no_move:Nnn #1#2#3
{
\@@_append_no_move:nn {#2}{#3}
@@ -1479,11 +1931,11 @@ manipulating PGF soft paths}
{
\spath_gappend_no_move:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv}
+\cs_generate_variant:Nn \spath_gappend_no_move:Nn {NV, cv, Nv}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_append:Nnn,
% \spath_append:Nn,
% \spath_gappend:Nnn,
@@ -1501,7 +1953,7 @@ manipulating PGF soft paths}
{
\spath_append:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_append:Nn {NV, Nv}
+\cs_generate_variant:Nn \spath_append:Nn {NV, Nv, cv}
\cs_new_protected_nopar:Npn \spath_gappend:Nnn #1#2#3
{
\tl_gset:Nn #1 {#2}
@@ -1512,12 +1964,12 @@ manipulating PGF soft paths}
{
\spath_gappend:NVn #1#1{#2}
}
-\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv}
+\cs_generate_variant:Nn \spath_gappend:Nn {NV, Nv, cv}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_prepend_no_move:Nnn,
% \spath_prepend_no_move:Nn,
% \spath_gprepend_no_move:Nnn,
@@ -1549,7 +2001,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_prepend:Nnn,
% \spath_prepend:Nn,
% \spath_gprepend:Nnn,
@@ -1580,7 +2032,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_bake_round:Nn,
% \spath_bake_round:N,
% \spath_gbake_round:Nn,
@@ -1625,26 +2077,25 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_close:Nn,
% \spath_close:N,
% \spath_gclose:Nn,
% \spath_gclose:N
% }
% Appends a close path to the end of the 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_protected_nopar:Npn \@@_close:n #1
{
\group_begin:
\tl_set:Nn \l_@@_tmpa_tl {#1}
- \spath_initialpoint:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
+ \spath_finalmovepoint:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
\tl_put_right:NV \l_@@_tmpa_tl \c_spath_closepath_tl
\tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
\tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
+\cs_generate_variant:Nn \@@_close:n {V}
\cs_new_protected_nopar:Npn \spath_close:Nn #1#2
{
\@@_close:n {#2}
@@ -1673,7 +2124,7 @@ manipulating PGF soft paths}
% \end{macro}
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_open:Nn,
% \spath_open:N,
% \spath_gopen:Nn,
@@ -1783,7 +2234,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_remove_empty_components:Nn,
% \spath_remove_empty_components:N,
% \spath_gremove_empty_components:Nn,
@@ -1836,7 +2287,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\spath_if_eq:nn}
+% \begin{macro}[internal]{\spath_if_eq:nn}
% Test if two soft paths are equal, we allow a little tolerance on the calculations.
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \spath_if_eq:nn #1#2 { T, F, TF }
@@ -1845,7 +2296,10 @@ manipulating PGF soft paths}
\tl_set:Nn \l_@@_tmpa_tl {#1}
\tl_set:Nn \l_@@_tmpb_tl {#2}
\bool_gset_true:N \g_@@_tmpa_bool
- \int_compare:nNnTF {\tl_count:N \l_@@_tmpa_tl} = {\tl_count:N \l_@@_tmpb_tl}
+ \int_compare:nNnTF
+ {\tl_count:N \l_@@_tmpa_tl}
+ =
+ {\tl_count:N \l_@@_tmpb_tl}
{
\int_step_inline:nnnn {1} {3} {\tl_count:N \l_@@_tmpa_tl}
{
@@ -1857,13 +2311,27 @@ manipulating PGF soft paths}
}
\dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+1}}
\dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+1}}
- \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt }
+ \dim_compare:nF
+ {
+ \dim_abs:n
+ {
+ \l_@@_tmpa_dim - \l_@@_tmpb_dim
+ }
+ < 0.001pt
+ }
{
\bool_gset_false:N \g_@@_tmpa_bool
}
\dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpa_tl {##1+2}}
\dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {##1+2}}
- \dim_compare:nF { \dim_abs:n { \l_@@_tmpa_dim - \l_@@_tmpb_dim} < 0.001pt }
+ \dim_compare:nF
+ {
+ \dim_abs:n
+ {
+ \l_@@_tmpa_dim - \l_@@_tmpb_dim
+ }
+ < 0.001pt
+ }
{
\bool_gset_false:N \g_@@_tmpa_bool
}
@@ -1887,7 +2355,7 @@ manipulating PGF soft paths}
%
% \subsection{Splitting Commands}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_split_curve:NNnn,
% \spath_gsplit_curve:NNnn
% }
@@ -1919,11 +2387,15 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- (1 - #2)^2 * \tl_item:nn {#1} {2} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5} + (#2)^2 * \tl_item:nn {#1} {8}
+ (1 - #2)^2 * \tl_item:nn {#1} {2}
+ + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {5}
+ + (#2)^2 * \tl_item:nn {#1} {8}
}}
{\fp_to_dim:n
{
- (1 - #2)^2 * \tl_item:nn {#1} {3} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6} + (#2)^2 * \tl_item:nn {#1} {9}
+ (1 - #2)^2 * \tl_item:nn {#1} {3}
+ + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {6}
+ + (#2)^2 * \tl_item:nn {#1} {9}
}}
}
@@ -1932,11 +2404,17 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11}
+ (1 - #2)^3 * \tl_item:nn {#1} {2}
+ + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5}
+ + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8}
+ + (#2)^3 * \tl_item:nn {#1} {11}
}}
{\fp_to_dim:n
{
- (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12}
+ (1 - #2)^3 * \tl_item:nn {#1} {3}
+ + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6}
+ + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9}
+ + (#2)^3 * \tl_item:nn {#1} {12}
}}
}
@@ -1949,11 +2427,17 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- (1 - #2)^3 * \tl_item:nn {#1} {2} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8} + (#2)^3 * \tl_item:nn {#1} {11}
+ (1 - #2)^3 * \tl_item:nn {#1} {2}
+ + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {5}
+ + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {8}
+ + (#2)^3 * \tl_item:nn {#1} {11}
}}
{\fp_to_dim:n
{
- (1 - #2)^3 * \tl_item:nn {#1} {3} + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6} + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9} + (#2)^3 * \tl_item:nn {#1} {12}
+ (1 - #2)^3 * \tl_item:nn {#1} {3}
+ + 3 * (1 - #2)^2 * (#2) * \tl_item:nn {#1} {6}
+ + 3 * (1 - #2) * (#2)^2 * \tl_item:nn {#1} {9}
+ + (#2)^3 * \tl_item:nn {#1} {12}
}}
}
@@ -1962,11 +2446,15 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- (1 - #2)^2 * \tl_item:nn {#1} {5} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8} + (#2)^2 * \tl_item:nn {#1} {11}
+ (1 - #2)^2 * \tl_item:nn {#1} {5}
+ + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {8}
+ + (#2)^2 * \tl_item:nn {#1} {11}
}}
{\fp_to_dim:n
{
- (1 - #2)^2 * \tl_item:nn {#1} {6} + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9} + (#2)^2 * \tl_item:nn {#1} {12}
+ (1 - #2)^2 * \tl_item:nn {#1} {6}
+ + 2 * (1 - #2) * (#2) * \tl_item:nn {#1} {9}
+ + (#2)^2 * \tl_item:nn {#1} {12}
}}
}
\tl_put_right:NV \l_@@_tmpa_tl \c_spath_curvetob_tl
@@ -1990,6 +2478,7 @@ manipulating PGF soft paths}
\@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
+\cs_generate_variant:Nn \@@_split_curve:nn {nv, nV}
\cs_new_protected_nopar:Npn \spath_split_curve:NNnn #1#2#3#4
{
\@@_split_curve:nn {#3}{#4}
@@ -2009,7 +2498,224 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+%
+% \begin{macro}[internal]{
+% \spath_maybe_split_curve:Nn,
+% \spath_maybe_gsplit_curve:Nn,
+% }
+% Possibly splits a bezier curve to ensure that the pieces don't self-intersect.
+% 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 \@@_maybe_split_curve:n #1
+{
+ \group_begin:
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ (
+ \tl_item:nn {#1} {3}
+ - 3 * \tl_item:nn {#1} {6}
+ + 3 * \tl_item:nn {#1} {9}
+ - \tl_item:nn {#1} {12}
+ )
+ *
+ (3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11})
+ -
+ (
+ \tl_item:nn {#1} {2}
+ - 3 * \tl_item:nn {#1} {5}
+ + 3 * \tl_item:nn {#1} {8}
+ - \tl_item:nn {#1} {11}
+ )
+ *
+ (3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12})
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ (
+ \tl_item:nn {#1} {2}
+ - 3 * \tl_item:nn {#1} {5}
+ + 3 * \tl_item:nn {#1} {8}
+ - \tl_item:nn {#1} {11}
+ )
+ *
+ (
+ 3 * \tl_item:nn {#1} {6}
+ - 6 * \tl_item:nn {#1} {9}
+ + 3 * \tl_item:nn {#1} {12}
+ )
+ -
+ (
+ \tl_item:nn {#1} {3}
+ - 3 * \tl_item:nn {#1} {6}
+ + 3 * \tl_item:nn {#1} {9}
+ - \tl_item:nn {#1} {12}
+ )
+ *
+ (
+ 3 * \tl_item:nn {#1} {5}
+ - 6 * \tl_item:nn {#1} {8}
+ + 3 * \tl_item:nn {#1} {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
+ }
+ {
+ \@@_split_curve:nV {#1} \l_@@_tmpa_fp
+ }
+ {
+ \tl_gset:Nn \g_@@_output_tl { {#1} {} }
+ }
+ }
+ {
+ \tl_gset:Nn \g_@@_output_tl { {#1} {} }
+ }
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_maybe_split_curve:NNn #1#2#3
+{
+ \@@_maybe_split_curve:n {#3}
+ \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_maybe_split_curve:NNn {NNn, NNV }
+\cs_new_protected_nopar:Npn \spath_maybe_gsplit_curve:NNn #1#2#3
+{
+ \@@_maybe_split_curve:n {#3}
+ \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
+ \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_maybe_gsplit_curve:NNn {NNn, NNV}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
+% \spath_split_curves:Nn,
+% \spath_gsplit_curves:Nn,
+% }
+% Slurp through the path ensuring that beziers don't self-intersect.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_curves:n #1
+{
+ \group_begin:
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_clear:N \l_@@_tmpc_tl
+ \bool_do_until:nn
+ {
+ \tl_if_empty_p:N \l_@@_tmpa_tl
+ }
+ {
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_tmpa_tl}
+ \tl_case:NnF \l_@@_tmpc_tl
+ {
+ \c_spath_curvetoa_tl
+ {
+ \tl_clear:N \l_@@_tmpd_tl
+ \tl_set_eq:NN \l_@@_tmpd_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {
+ { \dim_use:N \l_@@_tmpa_dim }
+ { \dim_use:N \l_@@_tmpb_dim }
+ }
+ \dim_set:Nn \l_@@_tmpa_dim
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {8}
+ }
+ \dim_set:Nn \l_@@_tmpb_dim
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {9}
+ }
+ \prg_replicate:nn {3}
+ {
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {1}
+ {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ {\tl_item:Nn \l_@@_tmpa_tl {3}}
+ }
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ }
+
+ \spath_maybe_split_curve:NNV
+ \l_@@_tmpd_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpd_tl
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpd_tl {\tl_tail:N \l_@@_tmpd_tl}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl}
+ }
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpd_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
+ }
+ }
+ {
+ \dim_set:Nn \l_@@_tmpa_dim
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ \dim_set:Nn \l_@@_tmpb_dim
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {3}
+ }
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {1}
+ {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ {\tl_item:Nn \l_@@_tmpa_tl {3}}
+ }
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ }
+ }
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_curves:Nn #1#2
+{
+ \@@_split_curves:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_curves:Nn {NV, cV, cn, cv }
+\cs_new_protected_nopar:Npn \spath_split_curves:N #1
+{
+ \spath_split_curves:NV #1#1
+}
+\cs_generate_variant:Nn \spath_split_curves:N {c}
+\cs_new_protected_nopar:Npn \spath_gsplit_curves:Nn #1#2
+{
+ \@@_split_curves:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_curves:Nn {NV, cV, cn, cv }
+\cs_new_protected_nopar:Npn \spath_gsplit_curves:N #1
+{
+ \spath_gsplit_curves:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gsplit_curves:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
% \spath_split_line:NNnn,
% \spath_gsplit_line:NNnn
% }
@@ -2079,21 +2785,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macrocode}
-\int_new:N \l_@@_split_int
-\int_new:N \l_@@_splitat_int
-\fp_new:N \l_@@_split_fp
-\bool_new:N \l_@@_split_bool
-\tl_new:N \l_@@_split_path_tl
-\tl_new:N \l_@@_split_patha_tl
-\tl_new:N \l_@@_split_pathb_tl
-\tl_new:N \l_@@_split_intoa_tl
-\tl_new:N \l_@@_split_intob_tl
-\dim_new:N \l_@@_splitx_dim
-\dim_new:N \l_@@_splity_dim
-% \end{macrocode}
-%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_split_at:NNnn,
% \spath_split_at:Nnn,
% \spath_split_at:Nn,
@@ -2107,165 +2799,165 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \@@_split_at:nn #1#2
{
\group_begin:
- \int_set:Nn \l_@@_splitat_int {\fp_to_int:n {floor(#2) + 1}}
- \fp_set:Nn \l_@@_split_fp {#2 - floor(#2)}
+ \int_set:Nn \l_@@_tmpa_int {\fp_to_int:n {floor(#2) + 1}}
+ \fp_set:Nn \l_@@_tmpa_fp {#2 - floor(#2)}
% Is split point near one end or other of a component?
\fp_compare:nT
{
- \l_@@_split_fp < 0.01
+ \l_@@_tmpa_fp < 0.01
}
{
% Near the start, so we'll place it at the start
- \fp_set:Nn \l_@@_split_fp {0}
+ \fp_set:Nn \l_@@_tmpa_fp {0}
}
\fp_compare:nT
{
- \l_@@_split_fp > 0.99
+ \l_@@_tmpa_fp > 0.99
}
{
% Near the end, so we'll place it at the end
- \fp_set:Nn \l_@@_split_fp {0}
- \int_incr:N \l_@@_splitat_int
+ \fp_set:Nn \l_@@_tmpa_fp {0}
+ \int_incr:N \l_@@_tmpa_int
}
- \int_zero:N \l_@@_split_int
- \bool_set_true:N \l_@@_split_bool
+ \int_zero:N \l_@@_tmpb_int
+ \bool_set_true:N \l_@@_tmpa_bool
- \tl_set:Nn \l_@@_split_path_tl {#1}
- \tl_clear:N \l_@@_split_patha_tl
+ \tl_set:Nn \l_@@_tmpe_tl {#1}
+ \tl_clear:N \l_@@_tmpc_tl
- \dim_zero:N \l_@@_splitx_dim
- \dim_zero:N \l_@@_splity_dim
+ \dim_zero:N \l_@@_tmpa_dim
+ \dim_zero:N \l_@@_tmpb_dim
\bool_until_do:nn {
- \tl_if_empty_p:N \l_@@_split_path_tl
+ \tl_if_empty_p:N \l_@@_tmpe_tl
||
- \int_compare_p:n { \l_@@_splitat_int == \l_@@_split_int }
+ \int_compare_p:n { \l_@@_tmpa_int == \l_@@_tmpb_int }
}
{
- \tl_set:Nx \l_@@_tmpc_tl {\tl_head:N \l_@@_split_path_tl}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
- \tl_case:Nn \l_@@_tmpc_tl
+ \tl_set:Nx \l_@@_tmpf_tl {\tl_head:N \l_@@_tmpe_tl}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
+ \tl_case:Nn \l_@@_tmpf_tl
{
\c_spath_lineto_tl
{
- \int_incr:N \l_@@_split_int
+ \int_incr:N \l_@@_tmpb_int
}
\c_spath_curvetoa_tl
{
- \int_incr:N \l_@@_split_int
+ \int_incr:N \l_@@_tmpb_int
}
}
- \int_compare:nT { \l_@@_split_int < \l_@@_splitat_int }
+ \int_compare:nT { \l_@@_tmpb_int < \l_@@_tmpa_int }
{
- \tl_put_right:NV \l_@@_split_patha_tl \l_@@_tmpc_tl
+ \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpf_tl
- \tl_put_right:Nx \l_@@_split_patha_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \dim_set:Nn \l_@@_splitx_dim {\tl_head:N \l_@@_split_path_tl}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpc_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \dim_set:Nn \l_@@_tmpa_dim {\tl_head:N \l_@@_tmpe_tl}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
- \tl_put_right:Nx \l_@@_split_patha_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \dim_set:Nn \l_@@_splity_dim {\tl_head:N \l_@@_split_path_tl}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpc_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \dim_set:Nn \l_@@_tmpb_dim {\tl_head:N \l_@@_tmpe_tl}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
}
}
- \tl_clear:N \l_@@_split_pathb_tl
- \tl_put_right:NV \l_@@_split_pathb_tl \c_spath_moveto_tl
- \tl_put_right:Nx \l_@@_split_pathb_tl
+ \tl_clear:N \l_@@_tmpd_tl
+ \tl_put_right:NV \l_@@_tmpd_tl \c_spath_moveto_tl
+ \tl_put_right:Nx \l_@@_tmpd_tl
{
- {\dim_use:N \l_@@_splitx_dim}
- {\dim_use:N \l_@@_splity_dim}
+ {\dim_use:N \l_@@_tmpa_dim}
+ {\dim_use:N \l_@@_tmpb_dim}
}
\fp_compare:nTF
{
- \l_@@_split_fp == 0
+ \l_@@_tmpa_fp == 0
}
{
- \tl_set_eq:NN \l_@@_split_intob_tl \l_@@_split_pathb_tl
- \tl_if_empty:NF \l_@@_split_path_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpd_tl
+ \tl_if_empty:NF \l_@@_tmpe_tl
{
- \tl_put_right:NV \l_@@_split_intob_tl \l_@@_tmpc_tl
- \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpf_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
}
}
{
- \tl_case:Nn \l_@@_tmpc_tl
+ \tl_case:Nn \l_@@_tmpf_tl
{
\c_spath_lineto_tl
{
- \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:NV \l_@@_tmpd_tl \l_@@_tmpf_tl
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
\spath_split_line:NNVV
- \l_@@_split_intoa_tl
- \l_@@_split_intob_tl
- \l_@@_split_pathb_tl
- \l_@@_split_fp
+ \l_@@_tmpa_tl
+ \l_@@_tmpb_tl
+ \l_@@_tmpd_tl
+ \l_@@_tmpa_fp
\prg_replicate:nn {3} {
- \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl
- \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
}
\c_spath_curvetoa_tl
{
- \tl_put_right:NV \l_@@_split_pathb_tl \l_@@_tmpc_tl
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:NV \l_@@_tmpd_tl \l_@@_tmpf_tl
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
\prg_replicate:nn {2} {
- \tl_put_right:Nx \l_@@_split_pathb_tl
- { \tl_head:N \l_@@_split_path_tl }
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ { \tl_head:N \l_@@_tmpe_tl }
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
- \tl_put_right:Nx \l_@@_split_pathb_tl
- {{ \tl_head:N \l_@@_split_path_tl }}
- \tl_set:Nx \l_@@_split_path_tl {\tl_tail:N \l_@@_split_path_tl }
+ \tl_put_right:Nx \l_@@_tmpd_tl
+ {{ \tl_head:N \l_@@_tmpe_tl }}
+ \tl_set:Nx \l_@@_tmpe_tl {\tl_tail:N \l_@@_tmpe_tl }
}
\spath_split_curve:NNVV
- \l_@@_split_intoa_tl
- \l_@@_split_intob_tl
- \l_@@_split_pathb_tl \l_@@_split_fp
+ \l_@@_tmpa_tl
+ \l_@@_tmpb_tl
+ \l_@@_tmpd_tl \l_@@_tmpa_fp
\prg_replicate:nn {3} {
- \tl_set:Nx \l_@@_split_intoa_tl {\tl_tail:N \l_@@_split_intoa_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_put_right:NV \l_@@_split_patha_tl \l_@@_split_intoa_tl
- \tl_put_right:NV \l_@@_split_intob_tl \l_@@_split_path_tl
+ \tl_put_right:NV \l_@@_tmpc_tl \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpb_tl \l_@@_tmpe_tl
}
}
}
\tl_gclear:N \g_@@_output_tl
- \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_patha_tl
- \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_intob_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpc_tl
+ \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_tmpb_tl
\group_end:
}
\cs_new_protected_nopar:Npn \spath_split_at:NNnn #1#2#3#4
@@ -2291,7 +2983,11 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \spath_split_at:Nnn #1#2#3
{
\@@_split_at:nn {#2}{#3}
- \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}}
+ \tl_set:Nx #1
+ {
+ \tl_item:Nn \g_@@_output_tl {1}
+ \tl_item:Nn \g_@@_output_tl {2}
+ }
\tl_gclear:N \g_@@_output_tl
}
\cs_generate_variant:Nn \spath_split_at:Nnn {NVn, NVV}
@@ -2302,7 +2998,11 @@ manipulating PGF soft paths}
\cs_new_protected_nopar:Npn \spath_gsplit_at:Nnn #1#2#3
{
\@@_split_at:nn {#2}{#3}
- \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1} \tl_item:Nn \g_@@_output_tl {2}}
+ \tl_gset:Nx #1
+ {
+ \tl_item:Nn \g_@@_output_tl {1}
+ \tl_item:Nn \g_@@_output_tl {2}
+ }
\tl_gclear:N \g_@@_output_tl
}
\cs_generate_variant:Nn \spath_gsplit_at:Nnn {NVn, NVV}
@@ -2323,19 +3023,7 @@ manipulating PGF soft paths}
% As in the previous section, there are various versions.
% In particular, there are versions where the path can be specified by a macro and is saved back into that macro.
%
-% \begin{macrocode}
-\tl_new:N \l_@@_shorten_fa_tl
-\tl_new:N \l_@@_shorten_path_tl
-\tl_new:N \l_@@_shorten_last_tl
-\tl_new:N \l_@@_shorten_lasta_tl
-\tl_new:N \l_@@_shorten_lastb_tl
-\int_new:N \l_@@_shorten_int
-\fp_new:N \l_@@_shorten_x_fp
-\fp_new:N \l_@@_shorten_y_fp
-\fp_new:N \l_@@_shorten_len_fp
-% \end{macrocode}
-%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_shorten_at_end:Nnn
% }
% This macro shortens a path from the end by a dimension.
@@ -2349,121 +3037,121 @@ manipulating PGF soft paths}
}
{
\group_begin:
- \tl_set:Nn \l_@@_shorten_path_tl {#1}
- \tl_reverse:N \l_@@_shorten_path_tl
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \tl_reverse:N \l_@@_tmpa_tl
- \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {3}}
- \tl_clear:N \l_@@_shorten_last_tl
- \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl
+ \tl_clear:N \l_@@_tmpe_tl
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curveto_tl
{
- \int_set:Nn \l_@@_shorten_int {3}
+ \int_set:Nn \l_@@_tmpa_int {3}
}
{
- \int_set:Nn \l_@@_shorten_int {1}
+ \int_set:Nn \l_@@_tmpa_int {1}
}
- \prg_replicate:nn { \l_@@_shorten_int }
+ \prg_replicate:nn { \l_@@_tmpa_int }
{
- \tl_put_right:Nx \l_@@_shorten_last_tl
+ \tl_put_right:Nx \l_@@_tmpe_tl
{
- {\tl_head:N \l_@@_shorten_path_tl}
+ {\tl_head:N \l_@@_tmpa_tl}
}
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
- \tl_put_right:Nx \l_@@_shorten_last_tl
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_put_right:Nx \l_@@_tmpe_tl
{
- {\tl_head:N \l_@@_shorten_path_tl}
+ {\tl_head:N \l_@@_tmpa_tl}
}
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
- \tl_put_right:Nx \l_@@_shorten_last_tl
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ \tl_put_right:Nx \l_@@_tmpe_tl
{
- \tl_head:N \l_@@_shorten_path_tl
+ \tl_head:N \l_@@_tmpa_tl
}
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_put_right:Nx \l_@@_shorten_last_tl
+ \tl_put_right:Nx \l_@@_tmpe_tl
{
- {\tl_item:Nn \l_@@_shorten_path_tl {1}}
- {\tl_item:Nn \l_@@_shorten_path_tl {2}}
+ {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ {\tl_item:Nn \l_@@_tmpa_tl {2}}
}
- \tl_put_right:NV \l_@@_shorten_last_tl \c_spath_moveto_tl
+ \tl_put_right:NV \l_@@_tmpe_tl \c_spath_moveto_tl
- \tl_reverse:N \l_@@_shorten_path_tl
+ \tl_reverse:N \l_@@_tmpa_tl
- \fp_set:Nn \l_@@_shorten_x_fp
+ \fp_set:Nn \l_@@_tmpa_fp
{
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {4}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {4}}
-
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {1}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {1}}
}
- \fp_set:Nn \l_@@_shorten_y_fp
+ \fp_set:Nn \l_@@_tmpb_fp
{
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {5}}
-
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {2}}
}
- \fp_set:Nn \l_@@_shorten_len_fp
+ \fp_set:Nn \l_@@_tmpc_fp
{
- sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp )
+ sqrt(
+ \l_@@_tmpa_fp * \l_@@_tmpa_fp
+ +
+ \l_@@_tmpb_fp * \l_@@_tmpb_fp
+ ) * \l_@@_tmpa_int
}
\fp_compare:nTF
{
- \l_@@_shorten_len_fp > #2
+ \l_@@_tmpc_fp > #2
}
{
- \fp_set:Nn \l_@@_shorten_len_fp
+ \fp_set:Nn \l_@@_tmpc_fp
{
- (\l_@@_shorten_len_fp - #2)/ \l_@@_shorten_len_fp
+ (\l_@@_tmpc_fp - #2)/ \l_@@_tmpc_fp
}
- \tl_reverse:N \l_@@_shorten_last_tl
+ \tl_reverse:N \l_@@_tmpe_tl
- \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curveto_tl
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curveto_tl
{
- \fp_set:Nn \l_@@_shorten_len_fp
- {
- 1 - (1 -\l_@@_shorten_len_fp)/3
- }
\spath_split_curve:NNVV
- \l_@@_shorten_lasta_tl
- \l_@@_shorten_lastb_tl
- \l_@@_shorten_last_tl
- \l_@@_shorten_len_fp
+ \l_@@_tmpc_tl
+ \l_@@_tmpd_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpc_fp
}
{
\spath_split_line:NNVV
- \l_@@_shorten_lasta_tl
- \l_@@_shorten_lastb_tl
- \l_@@_shorten_last_tl
- \l_@@_shorten_len_fp
+ \l_@@_tmpc_tl
+ \l_@@_tmpd_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpc_fp
}
\prg_replicate:nn {3}
{
- \tl_set:Nx \l_@@_shorten_lasta_tl {\tl_tail:N \l_@@_shorten_lasta_tl}
+ \tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
}
- \tl_put_right:NV \l_@@_shorten_path_tl \l_@@_shorten_lasta_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpc_tl
}
{
\int_compare:nT
{
- \tl_count:N \l_@@_shorten_path_tl > 3
+ \tl_count:N \l_@@_tmpa_tl > 3
}
{
- \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } }
- \spath_shorten_at_end:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim
+ \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_tmpc_fp } }
+ \spath_shorten_at_end:NV \l_@@_tmpa_tl \l_@@_tmpa_dim
}
}
- \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
{
@@ -2497,7 +3185,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_shorten_at_start:Nnn,
% \spath_shorten_at_start:Nn,
% \spath_gshorten_at_start:Nnn,
@@ -2515,110 +3203,120 @@ manipulating PGF soft paths}
}
{
\group_begin:
- \tl_set:Nn \l_@@_shorten_path_tl {#1}
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
- \tl_set:Nx \l_@@_shorten_fa_tl {\tl_item:Nn \l_@@_shorten_path_tl {4}}
+ \tl_set:Nx \l_@@_tmpb_tl {\tl_item:Nn \l_@@_tmpa_tl {4}}
- \tl_clear:N \l_@@_shorten_last_tl
+ \tl_clear:N \l_@@_tmpe_tl
- \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curvetoa_tl
{
- \int_set:Nn \l_@@_shorten_int {3}
+ \int_set:Nn \l_@@_tmpa_int {3}
}
{
- \int_set:Nn \l_@@_shorten_int {1}
+ \int_set:Nn \l_@@_tmpa_int {1}
}
- \tl_set_eq:NN \l_@@_shorten_last_tl \c_spath_moveto_tl
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl }
+ \tl_set_eq:NN \l_@@_tmpe_tl \c_spath_moveto_tl
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl }
- \prg_replicate:nn { \l_@@_shorten_int }
+ \prg_replicate:nn { \l_@@_tmpa_int }
{
- \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}}
- \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}}
- \tl_put_right:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {3}}
+ \@@_tl_put_right_braced:Nx
+ \l_@@_tmpe_tl
+ {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ \@@_tl_put_right_braced:Nx
+ \l_@@_tmpe_tl
+ {\tl_item:Nn \l_@@_tmpa_tl {2}}
+ \tl_put_right:Nx \l_@@_tmpe_tl {\tl_item:Nn \l_@@_tmpa_tl {3}}
\prg_replicate:nn {3}
{
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl }
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl }
}
}
- \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {1}}
- \@@_tl_put_right_braced:Nx \l_@@_shorten_last_tl {\tl_item:Nn \l_@@_shorten_path_tl {2}}
+ \@@_tl_put_right_braced:Nx
+ \l_@@_tmpe_tl
+ {\tl_item:Nn \l_@@_tmpa_tl {1}}
+ \@@_tl_put_right_braced:Nx
+ \l_@@_tmpe_tl
+ {\tl_item:Nn \l_@@_tmpa_tl {2}}
- \fp_set:Nn \l_@@_shorten_x_fp
+ \fp_set:Nn \l_@@_tmpa_fp
{
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {5}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {5}}
-
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {2}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {2}}
}
- \fp_set:Nn \l_@@_shorten_y_fp
+ \fp_set:Nn \l_@@_tmpb_fp
{
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {6}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {6}}
-
- \dim_to_fp:n {\tl_item:Nn \l_@@_shorten_last_tl {3}}
+ \dim_to_fp:n {\tl_item:Nn \l_@@_tmpe_tl {3}}
}
- \fp_set:Nn \l_@@_shorten_len_fp
+ \fp_set:Nn \l_@@_tmpc_fp
{
- sqrt( \l_@@_shorten_x_fp * \l_@@_shorten_x_fp + \l_@@_shorten_y_fp * \l_@@_shorten_y_fp )
+ sqrt(
+ \l_@@_tmpa_fp * \l_@@_tmpa_fp
+ +
+ \l_@@_tmpb_fp * \l_@@_tmpb_fp
+ )
+ *
+ \l_@@_tmpa_int
}
\fp_compare:nTF
{
- \l_@@_shorten_len_fp > #2
+ \l_@@_tmpc_fp > #2
}
{
- \fp_set:Nn \l_@@_shorten_len_fp
+ \fp_set:Nn \l_@@_tmpc_fp
{
- #2/ \l_@@_shorten_len_fp
+ #2/ \l_@@_tmpc_fp
}
- \tl_if_eq:NNTF \l_@@_shorten_fa_tl \c_spath_curvetoa_tl
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \c_spath_curvetoa_tl
{
- \fp_set:Nn \l_@@_shorten_len_fp
- {
- \l_@@_shorten_len_fp/3
- }
\spath_split_curve:NNVV
- \l_@@_shorten_lasta_tl
- \l_@@_shorten_lastb_tl
- \l_@@_shorten_last_tl
- \l_@@_shorten_len_fp
+ \l_@@_tmpc_tl
+ \l_@@_tmpd_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpc_fp
}
{
\spath_split_line:NNVV
- \l_@@_shorten_lasta_tl
- \l_@@_shorten_lastb_tl
- \l_@@_shorten_last_tl
- \l_@@_shorten_len_fp
+ \l_@@_tmpc_tl
+ \l_@@_tmpd_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpc_fp
}
\prg_replicate:nn {2}
{
- \tl_set:Nx \l_@@_shorten_path_tl {\tl_tail:N \l_@@_shorten_path_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
- \tl_put_left:NV \l_@@_shorten_path_tl \l_@@_shorten_lastb_tl
+ \tl_put_left:NV \l_@@_tmpa_tl \l_@@_tmpd_tl
}
{
- \tl_put_left:NV \l_@@_shorten_path_tl \c_spath_moveto_tl
+ \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl
\int_compare:nT
{
- \tl_count:N \l_@@_shorten_path_tl > 3
+ \tl_count:N \l_@@_tmpa_tl > 3
}
{
- \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_shorten_len_fp } }
- \spath_shorten_at_start:NV \l_@@_shorten_path_tl \l_@@_tmpa_dim
+ \dim_set:Nn \l_@@_tmpa_dim {\fp_to_dim:n {#2 - \l_@@_tmpc_fp } }
+ \spath_shorten_at_start:NV \l_@@_tmpa_tl \l_@@_tmpa_dim
}
}
- \tl_gset_eq:NN \g_@@_output_tl \l_@@_shorten_path_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
\group_end:
}
{
@@ -2655,7 +3353,7 @@ manipulating PGF soft paths}
%
% \subsection{Points on a Path}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_point_at:Nnn,
% \spath_gpoint_at:Nnn,
% }
@@ -2687,7 +3385,9 @@ manipulating PGF soft paths}
}
{
- \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
+ \tl_set:Nx
+ \l_@@_tmpa_tl
+ {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
\int_compare:nTF
{
@@ -2765,11 +3465,21 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {2} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {5} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {8} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {11}
+ (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {2}
+ + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp)
+ * \tl_item:Nn \l_@@_tmpa_tl {5}
+ + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2
+ * \tl_item:Nn \l_@@_tmpa_tl {8}
+ + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {11}
}}
{\fp_to_dim:n
{
- (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {3} + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp) * \tl_item:Nn \l_@@_tmpa_tl {6} + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2 * \tl_item:Nn \l_@@_tmpa_tl {9} + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {12}
+ (1 - \l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {3}
+ + 3 * (1 - \l_@@_tmpa_fp)^2 * (\l_@@_tmpa_fp)
+ * \tl_item:Nn \l_@@_tmpa_tl {6}
+ + 3 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp)^2
+ * \tl_item:Nn \l_@@_tmpa_tl {9}
+ + (\l_@@_tmpa_fp)^3 * \tl_item:Nn \l_@@_tmpa_tl {12}
}}
}
}
@@ -2799,7 +3509,7 @@ manipulating PGF soft paths}
% \end{macro}
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_tangent_at:Nnn,
% \spath_gtangent_at:Nnn,
% }
@@ -2831,7 +3541,9 @@ manipulating PGF soft paths}
}
{
- \tl_set:Nx \l_@@_tmpa_tl {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
+ \tl_set:Nx
+ \l_@@_tmpa_tl
+ {\seq_item:Nn \l_@@_tmpa_seq { \l_@@_tmpa_int} }
\int_compare:nTF
{
@@ -2909,16 +3621,24 @@ manipulating PGF soft paths}
{
{\fp_to_dim:n
{
- 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {5} - \tl_item:Nn \l_@@_tmpa_tl {2})
- + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {8} - \tl_item:Nn \l_@@_tmpa_tl {5})
- + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {11} - \tl_item:Nn \l_@@_tmpa_tl {8})
+ 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {5}
+ - \tl_item:Nn \l_@@_tmpa_tl {2})
+ + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) *
+ (\tl_item:Nn \l_@@_tmpa_tl {8}
+ - \tl_item:Nn \l_@@_tmpa_tl {5})
+ + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {11}
+ - \tl_item:Nn \l_@@_tmpa_tl {8})
}
}
{\fp_to_dim:n
{
- 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {6} - \tl_item:Nn \l_@@_tmpa_tl {3})
- + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) * (\tl_item:Nn \l_@@_tmpa_tl {9} - \tl_item:Nn \l_@@_tmpa_tl {6})
- + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {12} - \tl_item:Nn \l_@@_tmpa_tl {9})
+ 3*(1 - \l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {6}
+ - \tl_item:Nn \l_@@_tmpa_tl {3})
+ + 6 * (1 - \l_@@_tmpa_fp) * (\l_@@_tmpa_fp) *
+ (\tl_item:Nn \l_@@_tmpa_tl {9}
+ - \tl_item:Nn \l_@@_tmpa_tl {6})
+ + 3*(\l_@@_tmpa_fp)^2 * (\tl_item:Nn \l_@@_tmpa_tl {12}
+ - \tl_item:Nn \l_@@_tmpa_tl {9})
}}
}
}
@@ -2948,7 +3668,7 @@ manipulating PGF soft paths}
% \end{macro}
%
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_transformation_at:Nnn,
% \spath_gtransformation_at:Nnn
% }
@@ -2960,15 +3680,24 @@ manipulating PGF soft paths}
\tl_clear:N \l_@@_tmpa_tl
\@@_tangent_at:nn {#1}{#2}
\tl_set_eq:NN \l_@@_tmpb_tl \g_@@_output_tl
- \fp_set:Nn \l_@@_tmpa_fp { sqrt( (\tl_item:Nn \l_@@_tmpb_tl {1})^2 + (\tl_item:Nn \l_@@_tmpb_tl {2})^2 ) }
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ sqrt(
+ (\tl_item:Nn \l_@@_tmpb_tl {1})^2
+ +
+ (\tl_item:Nn \l_@@_tmpb_tl {2})^2
+ )
+ }
\fp_compare:nTF {\l_@@_tmpa_fp = 0}
{
\fp_set:Nn \l_@@_tmpa_fp {1}
\fp_set:Nn \l_@@_tmpb_fp {0}
}
{
- \fp_set:Nn \l_@@_tmpb_fp { (\tl_item:Nn \l_@@_tmpb_tl {2}) / \l_@@_tmpa_fp }
- \fp_set:Nn \l_@@_tmpa_fp { (\tl_item:Nn \l_@@_tmpb_tl {1}) / \l_@@_tmpa_fp }
+ \fp_set:Nn \l_@@_tmpb_fp
+ { (\tl_item:Nn \l_@@_tmpb_tl {2}) / \l_@@_tmpa_fp }
+ \fp_set:Nn \l_@@_tmpa_fp
+ { (\tl_item:Nn \l_@@_tmpb_tl {1}) / \l_@@_tmpa_fp }
}
\tl_set:Nx \l_@@_tmpa_tl
{
@@ -3005,26 +3734,7 @@ manipulating PGF soft paths}
% The intersection library is 0-based, but the user interface is 1-based (since if we ``count'' in a \Verb+\foreach+ then it starts at 1).
% This should be more consistent.
%
-% \begin{macrocode}
-\tl_new:N \l_@@_split_path_a_tl
-\tl_new:N \l_@@_split_path_b_tl
-\tl_new:N \l_@@_split_path_a_start_tl
-\tl_new:N \l_@@_split_path_b_start_tl
-\tl_new:N \l_@@_split_path_a_end_tl
-\tl_new:N \l_@@_split_path_b_end_tl
-\tl_new:N \l_@@_split_path_a_final_tl
-\tl_new:N \l_@@_split_path_b_final_tl
-
-\tl_new:N \l_@@_split_prev_first_tl
-\tl_new:N \l_@@_split_prev_second_tl
-
-\seq_new:N \l_@@_split_first_seq
-\seq_new:N \l_@@_split_second_seq
-
-\int_new:N \l_@@_split_segment_int
-% \end{macrocode}
-%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_intersect:NN,
% \spath_intersect:nn,
% }
@@ -3039,8 +3749,6 @@ manipulating PGF soft paths}
\pgfsetpath #2
}
}
-\tl_new:N \l_@@_intersecta_tl
-\tl_new:N \l_@@_intersectb_tl
\cs_new_protected_nopar:Npn \spath_intersect:nn #1#2
{
\tl_set:Nn \l_@@_intersecta_tl {#1}
@@ -3050,154 +3758,220 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
-% \spath_split_at_intersections:NNnn,
-% \spath_split_at_intersections:NN,
-% \spath_gsplit_at_intersections:NNnn,
-% \spath_gsplit_at_intersections:NN
+% \begin{macro}[internal]{
+% \spath_split_component_at_intersections:Nnn
% }
-% Given two paths, split them at points where they intersect and store them in the macros.
+% Split a component where it intersects a path.
+% Key assumption is that the first path is a single component, so if it is closed then the end joins up to the beginning.
+% The component is modified but the path is not.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_split_at_intersections:nn #1#2
+\cs_new_protected_nopar:Npn \@@_split_component_at_intersections:nn #1#2
{
\group_begin:
-
- % Clear some token lists and sequences
- \tl_clear:N \l_@@_split_path_a_final_tl
- \tl_clear:N \l_@@_split_path_b_final_tl
- \seq_clear:N \l_@@_split_first_seq
- \seq_clear:N \l_@@_split_second_seq
+ \tl_clear:N \l_@@_tmpe_tl
+ \seq_clear:N \l_@@_tmpb_seq
- \pgfintersectionsortbyfirstpath
% Find the intersections of these segments
- \tl_set:Nn \l_@@_split_path_a_tl {#1}
- \tl_set:Nn \l_@@_split_path_b_tl {#2}
- % Remove empty components
-% \spath_path_remove_empty_components:N \l_@@_split_path_a_tl
-% \spath_path_remove_empty_components:N \l_@@_split_path_b_tl
+ \tl_set:Nn \l_@@_tmpb_tl {#1}
+ \tl_set:Nn \l_@@_tmpc_tl {#2}
- \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl
+ \spath_reallength:Nn \l_@@_tmpa_int {#1}
- % If we get intersections
- \int_compare:nT {\pgfintersectionsolutions > 0}
+ % Remember if the component is closed
+ \spath_finalaction:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+
+ \bool_set:Nn \l_@@_closed_bool
{
- % Find the times of the intersections on each path
- \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
- {
- \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
- \seq_put_left:NV \l_@@_split_first_seq \l_@@_split_first_tl
- }
+ \tl_if_eq_p:NN \l_@@_tmpa_tl \c_spath_closepath_tl
}
- \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl
+ % Open it
+ \spath_open:N \l_@@_tmpb_tl
+
+ % Sort intersections along the component
+ \pgfintersectionsortbyfirstpath
+ \spath_intersect:NN \l_@@_tmpb_tl \l_@@_tmpc_tl
% If we get intersections
\int_compare:nT {\pgfintersectionsolutions > 0}
{
- % Find the times of the intersections on each path
+ % Find the times of the intersections on the component
\int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
{
- \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
- \seq_put_left:NV \l_@@_split_second_seq \l_@@_split_first_tl
+ \pgfintersectiongetsolutiontimes{##1}{\l_@@_tmph_tl}{\l_@@_tmpi_tl}
+ \seq_put_left:NV \l_@@_tmpb_seq \l_@@_tmph_tl
}
- }
-
- \tl_set:Nn \l_@@_split_prev_first_tl {-1}
- \seq_map_inline:Nn \l_@@_split_first_seq
- {
- \tl_set:Nn \l_@@_split_first_tl {##1}
-
- \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl
- \int_compare:nT
+ \seq_get_left:NN \l_@@_tmpb_seq \l_@@_tmpa_tl
+ \fp_compare:nT
{
- \fp_to_int:n {floor( \l_@@_split_first_tl) }
- =
- \fp_to_int:n {floor( \l_@@_split_prev_first_tl) }
+ \l_@@_tmpa_tl > \l_@@_tmpa_int - .01
}
{
- \tl_set:Nx \l_@@_split_first_tl
- {
- \fp_eval:n {
- floor( \l_@@_split_first_tl )
- +
- ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) )
- /
- ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) )
- }
- }
+ \bool_set_false:N \l_@@_closed_bool
}
- \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl
-
- \spath_split_at:NNVV \l_@@_split_path_a_start_tl \l_@@_split_path_a_end_tl \l_@@_split_path_a_tl \l_@@_split_first_tl
-
- \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_end_tl
- \tl_set_eq:NN \l_@@_split_path_a_tl \l_@@_split_path_a_start_tl
-
- }
-
- \tl_set:Nn \l_@@_split_prev_second_tl {-1}
-
- \seq_map_inline:Nn \l_@@_split_second_seq
- {
- \tl_set:Nn \l_@@_split_second_tl {##1}
-
- \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_second_tl
- \int_compare:nT
+ \seq_get_right:NN \l_@@_tmpb_seq \l_@@_tmpa_tl
+ \fp_compare:nT
{
- \fp_to_int:n {floor( \l_@@_split_second_tl) }
- =
- \fp_to_int:n {floor( \l_@@_split_prev_second_tl) }
+ \l_@@_tmpa_tl < .01
}
{
- \tl_set:Nx \l_@@_split_second_tl
+ \bool_set_false:N \l_@@_closed_bool
+ }
+
+
+ \tl_set:Nn \l_@@_tmpg_tl {-1}
+
+ \seq_map_inline:Nn \l_@@_tmpb_seq
+ {
+ \tl_set:Nn \l_@@_tmph_tl {##1}
+
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmph_tl
+ \int_compare:nT
{
- \fp_eval:n {
- floor( \l_@@_split_second_tl )
- +
- ( \l_@@_split_second_tl - floor( \l_@@_split_second_tl) )
- /
- ( \l_@@_split_prev_second_tl - floor( \l_@@_split_prev_second_tl) )
+ \fp_to_int:n {floor( \l_@@_tmph_tl) }
+ =
+ \fp_to_int:n {floor( \l_@@_tmpg_tl) }
+ }
+ {
+ \tl_set:Nx \l_@@_tmph_tl
+ {
+ \fp_eval:n {
+ floor( \l_@@_tmph_tl )
+ +
+ ( \l_@@_tmph_tl - floor( \l_@@_tmph_tl) )
+ /
+ ( \l_@@_tmpg_tl - floor( \l_@@_tmpg_tl) )
+ }
}
}
+ \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpa_tl
+
+ \spath_split_at:NNVV
+ \l_@@_tmpd_tl
+ \l_@@_tmpf_tl
+ \l_@@_tmpb_tl
+ \l_@@_tmph_tl
+
+ \tl_put_left:NV \l_@@_tmpe_tl \l_@@_tmpf_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpd_tl
+
}
- \tl_set_eq:NN \l_@@_split_prev_second_tl \l_@@_tmpa_tl
- \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl\l_@@_split_second_tl
-
- \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl
- \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl
-
- }
- \tl_put_left:NV \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl
- \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ \tl_put_left:NV \l_@@_tmpe_tl \l_@@_tmpb_tl
+
+ \spath_remove_empty_components:N \l_@@_tmpe_tl
- \tl_if_empty:NT \l_@@_split_path_a_final_tl
- {
- \tl_set_eq:NN \l_@@_split_path_a_final_tl \l_@@_split_path_a_tl
+ \tl_set_eq:NN \l_@@_tmpb_tl \l_@@_tmpe_tl
}
- \tl_if_empty:NT \l_@@_split_path_b_final_tl
+
+ \bool_if:NT \l_@@_closed_bool
{
- \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ \spath_join_component:Nn \l_@@_tmpb_tl {1}
}
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpb_tl
- \spath_remove_empty_components:N \l_@@_split_path_a_final_tl
- \spath_remove_empty_components:N \l_@@_split_path_b_final_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nnn #1#2#3
+{
+ \@@_split_component_at_intersections:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_component_at_intersections:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_split_component_at_intersections:Nn #1#2
+{
+ \spath_split_component_at_intersections:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_split_component_at_intersections:Nn {cn, cv}
+\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nnn #1#2#3
+{
+ \@@_split_component_at_intersections:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nnn {NVn, NVV}
+\cs_new_protected_nopar:Npn \spath_gsplit_component_at_intersections:Nn #1#2
+{
+ \spath_gsplit_component_at_intersections:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gsplit_component_at_intersections:Nn {cn, cv}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[internal]{
+% \spath_split_path_at_intersections:Nnn,
+% \spath_split_path_at_intersections:Nn,
+% \spath_gsplit_path_at_intersections:Nnn,
+% \spath_gsplit_path_at_intersections:Nn,
+% \spath_split_at_intersections:NNnn,
+% \spath_split_at_intersections:NN,
+% \spath_gsplit_at_intersections:NNnn,
+% \spath_gsplit_at_intersections:NN,
+% }
+% Split paths at their intersections.
+% The \Verb+path+ versions only split the first path.
+% The others split both paths.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_path_at_intersections:nn #1#2
+{
+ \group_begin:
+
+ \seq_clear:N \l_@@_tmpa_seq
+ \seq_clear:N \l_@@_tmpb_seq
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \spath_split_component_at_intersections:Nnn \l_@@_tmpa_tl {##1} {#2}
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
+
\tl_gclear:N \g_@@_output_tl
- \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_a_final_tl
- \@@_tl_gput_right_braced:NV \g_@@_output_tl \l_@@_split_path_b_final_tl
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {} }
\group_end:
}
+\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nnn #1#2#3
+{
+ \@@_split_path_at_intersections:nn {#2}{#3}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_path_at_intersections:Nnn
+{NVn, NVV, cVn, cVV, cvn, cvv}
+\cs_new_protected_nopar:Npn \spath_split_path_at_intersections:Nn #1#2
+{
+ \spath_split_path_at_intersections:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_split_path_at_intersections:Nn {cv, NV}
+\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nnn #1#2#3
+{
+ \@@_split_path_at_intersections:nn {#2}{#3}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nnn
+{NVn, NVV, cVn, cVV, cvn, cvv}
+\cs_new_protected_nopar:Npn \spath_gsplit_path_at_intersections:Nn #1#2
+{
+ \spath_gsplit_path_at_intersections:NVn #1#1{#2}
+}
+\cs_generate_variant:Nn \spath_gsplit_path_at_intersections:Nn {cv, NV}
\cs_new_protected_nopar:Npn \spath_split_at_intersections:NNnn #1#2#3#4
{
- \@@_split_at_intersections:nn {#3}{#4}
- \tl_set:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
- \tl_set:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \@@_split_path_at_intersections:nn {#3}{#4}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \@@_split_path_at_intersections:nn {#4}{#3}
+ \tl_set_eq:NN #2 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_split_at_intersections:NNnn {NNVV, ccVV, ccvv}
+\cs_generate_variant:Nn \spath_split_at_intersections:NNnn
+{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv}
\cs_new_protected_nopar:Npn \spath_split_at_intersections:NN #1#2
{
\spath_split_at_intersections:NNVV #1#2#1#2
@@ -3205,12 +3979,14 @@ manipulating PGF soft paths}
\cs_generate_variant:Nn \spath_split_at_intersections:NN {cc}
\cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NNnn #1#2#3#4
{
- \@@_split_at_intersections:nn {#3}{#4}
- \tl_gset:Nx #1 {\tl_item:Nn \g_@@_output_tl {1}}
- \tl_gset:Nx #2 {\tl_item:Nn \g_@@_output_tl {2}}
+ \@@_split_path_at_intersections:nn {#3}{#4}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \@@_split_path_at_intersections:nn {#4}{#3}
+ \tl_gset_eq:NN #2 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn {NNVV, ccVV, ccvv}
+\cs_generate_variant:Nn \spath_gsplit_at_intersections:NNnn
+{NNVn, NNVV, ccVn, ccVV, ccvn, ccvv}
\cs_new_protected_nopar:Npn \spath_gsplit_at_intersections:NN #1#2
{
\spath_gsplit_at_intersections:NNVV #1#2#1#2
@@ -3219,211 +3995,293 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
-% \spath_split_at_self_intersections:Nn,
-% \spath_split_at_self_intersections:N,
-% \spath_gsplit_at_self_intersections:Nn,
-% \spath_gsplit_at_self_intersections:N,
+%
+% \begin{macro}[internal]{
+% \spath_split_component_at_self_intersections:Nn,
+% \spath_split_component_at_self_intersections:N,
+% \spath_gsplit_component_at_self_intersections:Nn,
+% \spath_gsplit_component_at_self_intersections:N,
% }
-% Given a path, split it at points where it self-intersects and store in the given macro.
+% Given a component of a path, split it at points where it self-intersects.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \@@_split_at_self_intersections:n #1
+\cs_new_protected_nopar:Npn \@@_split_component_at_self_intersections:n #1
{
\group_begin:
+ \tl_set:Nn \l_@@_tmpe_tl {#1}
+
+ % Remember if the component is closed
+ \spath_finalaction:NV \l_@@_tmpa_tl \l_@@_tmpe_tl
+
+ \bool_set:Nn \l_@@_closed_bool
+ {
+ \tl_if_eq_p:NN \l_@@_tmpa_tl \c_spath_closepath_tl
+ }
% Copy the path
- \tl_set:Nn \l_@@_split_path_b_tl {#1}
+ \tl_set:Nn \l_@@_tmpe_tl {#1}
% Open the path
- \spath_open:N \l_@@_split_path_b_tl
- % Remove empty components
- \spath_remove_empty_components:N \l_@@_split_path_b_tl
+ \spath_open:N \l_@@_tmpe_tl
+ % Ensure beziers don't self-intersect
+ \spath_split_curves:N \l_@@_tmpe_tl
+
% Make a copy for later
- \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpe_tl
% Clear some token lists and sequences
- \tl_clear:N \l_@@_split_path_a_tl
- \seq_clear:N \l_@@_split_first_seq
- \int_zero:N \l_@@_split_segment_int
+ \tl_clear:N \l_@@_tmpd_tl
+ \seq_clear:N \l_@@_tmpb_seq
+ \int_zero:N \l_@@_tmpa_int
\pgfintersectionsortbyfirstpath
- \bool_do_until:nn
- {
- \int_compare_p:n
- {
- \tl_count:N \l_@@_split_path_b_tl < 4
- }
- }
- {
- \tl_clear:N \l_@@_split_path_a_tl
- \tl_put_right:Nx \l_@@_split_path_a_tl
- {
- \tl_item:Nn \l_@@_split_path_b_tl {1}
- {\tl_item:Nn \l_@@_split_path_b_tl {2}}
- {\tl_item:Nn \l_@@_split_path_b_tl {3}}
- }
+ % Split the path into a sequence of segments
+ \spath_segments_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpe_tl
- \tl_set:Nx \l_@@_tmpa_tl { \tl_item:Nn \l_@@_split_path_b_tl {4} }
-
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
-
- \int_zero:N \l_@@_tmpa_int
-
- \tl_case:Nn \l_@@_tmpa_tl
- {
- \c_spath_moveto_tl
- {
- \tl_clear:N \l_@@_split_path_a_tl
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
- }
- \c_spath_lineto_tl
- {
- \int_set:Nn \l_@@_tmpa_int {1}
- }
- \c_spath_curvetoa_tl
- {
- \int_set:Nn \l_@@_tmpa_int {3}
- }
- }
-
- \prg_replicate:nn { \l_@@_tmpa_int }
- {
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
-
- \tl_put_right:Nx \l_@@_split_path_a_tl
- {
- \tl_item:Nn \l_@@_split_path_b_tl {1}
- {\tl_item:Nn \l_@@_split_path_b_tl {2}}
- {\tl_item:Nn \l_@@_split_path_b_tl {3}}
- }
-
- \tl_set:Nx \l_@@_split_path_b_tl {\tl_tail:N \l_@@_split_path_b_tl}
- }
-
- \tl_put_left:NV \l_@@_split_path_b_tl \c_spath_moveto_tl
-
- \tl_if_empty:NF \l_@@_split_path_a_tl
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
{
- % Intersect the current segment with the rest of the path
- \spath_intersect:NN \l_@@_split_path_a_tl \l_@@_split_path_b_tl
-
-
- % If we get intersections
- \int_compare:nT {\pgfintersectionsolutions > 0}
+ % Don't intersect a segment with itself
+ \int_compare:nF
{
- % Find the times of the intersections on each path
- \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
- {
- \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
- \fp_compare:nT
- {
- \l_@@_split_first_tl < .99
- }
- {
- \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int}}
- \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl
- }
- }
+ ##1 == ####1
}
-
- \spath_intersect:NN \l_@@_split_path_b_tl \l_@@_split_path_a_tl
-
- % If we get intersections
- \int_compare:nT {\pgfintersectionsolutions > 0}
{
- % Find the times of the intersections on each path
- \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
+ \spath_intersect:nn {##2} {####2}
+
+ \int_compare:nT {\pgfintersectionsolutions > 0}
{
- \pgfintersectiongetsolutiontimes{##1}{\l_@@_split_first_tl}{\l_@@_split_second_tl}
- \fp_compare:nT
- {
- \l_@@_split_first_tl > .01
- }
+ % Find the times of the intersections on each path
+ \int_step_inline:nnnn {1} {1} {\pgfintersectionsolutions}
{
- \tl_set:Nx \l_@@_tmpa_tl {\fp_to_decimal:n {\l_@@_split_first_tl + \l_@@_split_segment_int + 1}}
- \seq_put_right:NV \l_@@_split_first_seq \l_@@_tmpa_tl
+ \pgfintersectiongetsolutiontimes
+ {########1}{\l_@@_tmpb_tl}{\l_@@_tmpc_tl}
+
+ \bool_if:nT
+ {
+ !(
+ \fp_compare_p:n { \l_@@_tmpb_tl > .99 }
+ &&
+ \int_compare_p:n {##1 + 1 == ####1}
+ )
+ &&
+ !(
+ \fp_compare_p:n { \l_@@_tmpb_tl < .01 }
+ &&
+ \int_compare_p:n {##1 - 1 == ####1}
+ )
+ &&
+ !(
+ \l_@@_closed_bool
+ &&
+ \fp_compare_p:n { \l_@@_tmpb_tl < .01 }
+ &&
+ \int_compare_p:n {##1 == 1}
+ &&
+ \int_compare_p:n {\seq_count:N \l_@@_tmpa_seq == ####1}
+ )
+ &&
+ !(
+ \l_@@_closed_bool
+ &&
+ \fp_compare_p:n { \l_@@_tmpb_tl > .99 }
+ &&
+ \int_compare_p:n {####1 == 1}
+ &&
+ \int_compare_p:n {\seq_count:N \l_@@_tmpa_seq == ##1}
+ )
+ }
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {\fp_to_decimal:n {\l_@@_tmpb_tl + ##1 - 1}}
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
}
}
}
-
}
- % Increment the segment counter
- \int_incr:N \l_@@_split_segment_int
}
% Sort the sequence by reverse order along the path
- \seq_sort:Nn \l_@@_split_first_seq
+ \seq_sort:Nn \l_@@_tmpb_seq
{
\fp_compare:nNnTF { ##1 } < { ##2 }
{ \sort_return_swapped: }
{ \sort_return_same: }
}
+ \seq_get_left:NN \l_@@_tmpb_seq \l_@@_tmpa_tl
+ \fp_compare:nT
+ {
+ \l_@@_tmpa_tl > \seq_count:N \l_@@_tmpa_seq - .01
+ }
+ {
+ \bool_set_false:N \l_@@_closed_bool
+ }
+ \seq_get_right:NN \l_@@_tmpb_seq \l_@@_tmpa_tl
+ \fp_compare:nT
+ {
+ \l_@@_tmpa_tl < .01
+ }
+ {
+ \bool_set_false:N \l_@@_closed_bool
+ }
+
% Restore the original copy of the path
- \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_final_tl
+ \tl_set_eq:NN \l_@@_tmpe_tl \l_@@_tmpg_tl
% Clear the token lists
- \tl_clear:N \l_@@_split_path_b_start_tl
- \tl_clear:N \l_@@_split_path_b_end_tl
- \tl_clear:N \l_@@_split_path_b_final_tl
+ \tl_clear:N \l_@@_tmpf_tl
+ \tl_clear:N \l_@@_tmph_tl
+ \tl_clear:N \l_@@_tmpg_tl
- \tl_set:Nn \l_@@_split_prev_first_tl {-1}
+ \tl_set:Nn \l_@@_tmpi_tl {-1}
- \seq_map_inline:Nn \l_@@_split_first_seq
+ \seq_map_inline:Nn \l_@@_tmpb_seq
{
- \tl_set:Nn \l_@@_split_first_tl {##1}
- \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_split_first_tl
+ \tl_set:Nn \l_@@_tmpb_tl {##1}
+ \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_tmpb_tl
\int_compare:nT
{
- \fp_to_int:n {floor( \l_@@_split_first_tl ) }
+ \fp_to_int:n {floor( \l_@@_tmpb_tl ) }
=
- \fp_to_int:n {floor( \l_@@_split_prev_first_tl) }
+ \fp_to_int:n {floor( \l_@@_tmpi_tl) }
}
{
- \tl_set:Nx \l_@@_split_first_tl
+ \tl_set:Nx \l_@@_tmpb_tl
{
\fp_eval:n {
- floor( \l_@@_split_first_tl )
+ floor( \l_@@_tmpb_tl )
+
- ( \l_@@_split_first_tl - floor( \l_@@_split_first_tl) )
+ ( \l_@@_tmpb_tl - floor( \l_@@_tmpb_tl) )
/
- ( \l_@@_split_prev_first_tl - floor( \l_@@_split_prev_first_tl) )
+ ( \l_@@_tmpi_tl - floor( \l_@@_tmpi_tl) )
}
}
}
- \tl_set_eq:NN \l_@@_split_prev_first_tl \l_@@_tmpa_tl
+ \tl_set_eq:NN \l_@@_tmpi_tl \l_@@_tmpa_tl
- \spath_split_at:NNVV \l_@@_split_path_b_start_tl \l_@@_split_path_b_end_tl \l_@@_split_path_b_tl \l_@@_split_first_tl
+ \spath_split_at:NNVV
+ \l_@@_tmpf_tl
+ \l_@@_tmph_tl
+ \l_@@_tmpe_tl
+ \l_@@_tmpb_tl
- \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_end_tl
- \tl_set_eq:NN \l_@@_split_path_b_tl \l_@@_split_path_b_start_tl
+ \tl_put_left:NV \l_@@_tmpg_tl \l_@@_tmph_tl
+ \tl_set_eq:NN \l_@@_tmpe_tl \l_@@_tmpf_tl
}
- \tl_put_left:NV \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ \tl_put_left:NV \l_@@_tmpg_tl \l_@@_tmpe_tl
- \tl_if_empty:NT \l_@@_split_path_b_final_tl
+ \tl_if_empty:NT \l_@@_tmpg_tl
{
- \tl_set_eq:NN \l_@@_split_path_b_final_tl \l_@@_split_path_b_tl
+ \tl_set_eq:NN \l_@@_tmpg_tl \l_@@_tmpe_tl
}
- \spath_remove_empty_components:N \l_@@_split_path_b_final_tl
+ \spath_remove_empty_components:N \l_@@_tmpg_tl
+
+ % Do something with closed
+ \bool_if:NT \l_@@_closed_bool
+ {
+ \spath_join_component:Nn \l_@@_tmpg_tl {1}
+ }
\tl_gclear:N \g_@@_output_tl
- \tl_gset_eq:NN \g_@@_output_tl \l_@@_split_path_b_final_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpg_tl
+ \group_end:
+}
+\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:Nn #1#2
+{
+ \@@_split_component_at_self_intersections:n {#2}
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_split_component_at_self_intersections:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_split_component_at_self_intersections:N #1
+{
+ \spath_split_component_at_self_intersections:NV #1#1
+}
+\cs_generate_variant:Nn \spath_split_component_at_self_intersections:N {c}
+\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:Nn #1#2
+{
+ \@@_split_component_at_self_intersections:n {#2}
+ \tl_gset_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:Nn {NV}
+\cs_new_protected_nopar:Npn \spath_gsplit_component_at_self_intersections:N #1
+{
+ \spath_gsplit_component_at_self_intersections:NV #1#1
+}
+\cs_generate_variant:Nn \spath_gsplit_component_at_self_intersections:N {c}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[internal]{
+% \spath_split_at_self_intersections:Nn,
+% \spath_split_at_self_intersections:N,
+% \spath_gsplit_at_self_intersections:Nn,
+% \spath_gsplit_at_self_intersections:N,
+% }
+% Split a path at its self intersections.
+% We iterate over the components, splitting each where it meets all the others and itself.
+% To make this more efficient, we split against the components of the original path rather than updating each time.
+%
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_split_at_self_intersections:n #1
+{
+ \group_begin:
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_clear:N \l_@@_tmpc_seq
+
+ % Iterate over the components of the original path.
+ \bool_do_until:nn
+ {
+ \seq_if_empty_p:N \l_@@_tmpa_seq
+ }
+ {
+ % Get the next component
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+ % Copy for later
+ \tl_set_eq:NN \l_@@_tmpc_tl \l_@@_tmpa_tl
+ \int_compare:nT
+ {
+ \tl_count:N \l_@@_tmpa_tl > 3
+ }
+ {
+
+ % Split against itself
+ \spath_split_component_at_self_intersections:N \l_@@_tmpa_tl
+ % Grab the rest of the path
+ \tl_set:Nx \l_@@_tmpb_tl
+ {
+ \seq_use:Nn \l_@@_tmpb_seq {}
+ \seq_use:Nn \l_@@_tmpa_seq {}
+ }
+ % Split against the rest of the path
+ \spath_split_path_at_intersections:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ }
+ % Save the split path
+ \seq_put_right:NV \l_@@_tmpc_seq \l_@@_tmpa_tl
+ % Add the original copy to the sequence of processed components
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpc_tl
+ }
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpc_seq {} }
\group_end:
}
+\cs_generate_variant:Nn \@@_split_at_self_intersections:n {V, v}
\cs_new_protected_nopar:Npn \spath_split_at_self_intersections:Nn #1#2
{
\@@_split_at_self_intersections:n {#2}
\tl_set_eq:NN #1 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV}
+\cs_generate_variant:Nn \spath_split_at_self_intersections:Nn {NV, cn, cV, cv}
\cs_new_protected_nopar:Npn \spath_split_at_self_intersections:N #1
{
\spath_split_at_self_intersections:NV #1#1
@@ -3435,7 +4293,7 @@ manipulating PGF soft paths}
\tl_gset_eq:NN #1 \g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
-\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV}
+\cs_generate_variant:Nn \spath_gsplit_at_self_intersections:Nn {NV, cn, cV, cv}
\cs_new_protected_nopar:Npn \spath_gsplit_at_self_intersections:N #1
{
\spath_gsplit_at_self_intersections:NV #1#1
@@ -3444,8 +4302,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_join_component:Nnn,
% \spath_join_component:Nn,
% \spath_gjoin_component:Nnn,
@@ -3453,58 +4310,76 @@ manipulating PGF soft paths}
% }
% Join the specified component of the spath to its predecessor.
% \begin{macrocode}
-\tl_new:N \l_@@_tmpj_tl
\cs_new_protected_nopar:Npn \@@_join_component:nn #1#2
{
\group_begin:
- \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
- \int_compare:nT
- {
- #2 == 1
- }
- {
- \tl_clear:N \l_@@_tmpj_tl
- \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpj_tl
-
- \prg_replicate:nn {3}
- {
- \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl}
- }
+ \spath_numberofcomponents:Nn \l_@@_tmpa_int {#1}
- \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl
- }
- \bool_if:nT
+ \bool_if:nTF
{
- \int_compare_p:n
- {
- #2 > 1
- }
+ \int_compare_p:n { #2 >= 1 }
&&
- \int_compare_p:n
- {
- #2 <= \seq_count:N \l_@@_tmpa_seq
- }
+ \int_compare_p:n { #2 <= \l_@@_tmpa_int }
}
{
-
- \seq_clear:N \l_@@_tmpb_seq
- \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ \int_compare:nTF
+ {
+ #2 == 1
+ }
{
- \tl_set:Nn \l_@@_tmpj_tl {##2}
- \int_compare:nT {##1 = #2}
+ \int_compare:nTF
+ {
+ \l_@@_tmpa_int == 1
+ }
{
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
+ \spath_initialpoint:Nn \l_@@_tmpb_tl {#1}
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_closepath_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset_eq:NN \g_@@_output_tl \l_@@_tmpa_tl
+ }
+ {
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+
\prg_replicate:nn {3}
{
- \tl_set:Nx \l_@@_tmpj_tl {\tl_tail:N \l_@@_tmpj_tl}
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
}
+
+ \seq_put_right:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
+
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpa_seq {}}
}
- \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpj_tl
}
+ {
+ \spath_components_to_seq:Nn \l_@@_tmpa_seq {#1}
+
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {##2}
+ \int_compare:nT {##1 = #2}
+ {
+ \prg_replicate:nn {3}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl {\tl_tail:N \l_@@_tmpa_tl}
+ }
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
- \seq_set_eq:NN \l_@@_tmpa_seq \l_@@_tmpb_seq
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {}}
+ }
+ }
+ {
+ \tl_gclear:N \g_@@_output_tl
+ \tl_gset:Nn \g_@@_output_tl {#1}
}
- \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpa_seq {} }
\group_end:
}
\cs_new_protected_nopar:Npn \spath_join_component:Nnn #1#2#3
@@ -3534,7 +4409,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_spot_weld_components:Nn,
% \spath_spot_weld_components:N,
% \spath_spot_gweld_components:Nn,
@@ -3562,12 +4437,16 @@ manipulating PGF soft paths}
{
\dim_compare_p:n
{
- \dim_abs:n {\l_@@_move_x_dim - \tl_item:Nn \l_@@_tmpa_tl {2} } < 0.01pt
+ \dim_abs:n
+ {\l_@@_move_x_dim - \tl_item:Nn \l_@@_tmpa_tl {2} }
+ < 0.01pt
}
&&
\dim_compare_p:n
{
- \dim_abs:n {\l_@@_move_y_dim - \tl_item:Nn \l_@@_tmpa_tl {3} } < 0.01pt
+ \dim_abs:n
+ {\l_@@_move_y_dim - \tl_item:Nn \l_@@_tmpa_tl {3} }
+ < 0.01pt
}
}
{
@@ -3595,12 +4474,22 @@ manipulating PGF soft paths}
{
\dim_compare_p:n
{
- \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {1} - \tl_item:Nn \l_@@_tmpb_tl {1} } < 0.01pt
+ \dim_abs:n
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {1} - \tl_item:Nn \l_@@_tmpb_tl {1}
+ }
+ <
+ 0.01pt
}
&&
\dim_compare_p:n
{
- \dim_abs:n {\tl_item:Nn \l_@@_tmpa_tl {2} - \tl_item:Nn \l_@@_tmpb_tl {2} } < 0.01pt
+ \dim_abs:n
+ {
+ \tl_item:Nn \l_@@_tmpa_tl {2} - \tl_item:Nn \l_@@_tmpb_tl {2}
+ }
+ <
+ 0.01pt
}
}
{
@@ -3660,7 +4549,7 @@ manipulating PGF soft paths}
%
% \subsection{Exporting Commands}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_convert_to_svg:Nn,
% \spath_gconvert_to_svg:Nn,
% }
@@ -3679,7 +4568,7 @@ manipulating PGF soft paths}
\iow_newline:
<svg~ xmlns="http://www.w3.org/2000/svg"~ version="1.1"~viewBox="
}
-
+
\spath_minbb:Nn \l_@@_tmpb_tl {#1}
\spath_maxbb:Nn \l_@@_tmpc_tl {#1}
\tl_put_right:Nx \l_@@_tmpa_tl
@@ -3718,7 +4607,7 @@ manipulating PGF soft paths}
<path~ d="
}
\tl_set:Nn \l_@@_tmpc_tl {use:n}
- \tl_map_inline:Nn #1
+ \tl_map_inline:nn {#1}
{
\tl_set:Nn \l_@@_tmpb_tl {##1}
\tl_case:NnF \l_@@_tmpb_tl
@@ -3751,7 +4640,9 @@ manipulating PGF soft paths}
}
}
{
- \tl_put_right:Nx \l_@@_tmpa_tl {\use:c { \l_@@_tmpc_tl } {\dim_to_decimal:n {##1}} ~}
+ \tl_put_right:Nx
+ \l_@@_tmpa_tl
+ {\use:c { \l_@@_tmpc_tl } {\dim_to_decimal:n {##1}} ~}
}
}
\tl_put_right:Nn \l_@@_tmpa_tl
@@ -3779,7 +4670,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_export_to_svg:nn
% }
% Save a soft path to an SVG file.
@@ -3787,18 +4678,21 @@ manipulating PGF soft paths}
\iow_new:N \g_@@_stream
\cs_new_protected_nopar:Npn \spath_export_to_svg:nn #1#2
{
- \spath_convert_path_to_svg:Nn \l_@@_iterp_tl {#2}
+ \group_begin:
+ \spath_convert_to_svg:Nn \l_@@_tmpa_tl {#2}
\iow_open:Nn \g_@@_stream {#1 .svg}
\iow_now:Nx \g_@@_stream
{
- \tl_use:N \l_@@_iterp_tl
+ \tl_use:N \l_@@_tmpa_tl
}
\iow_close:N \g_@@_stream
+ \group_end:
}
+\cs_generate_variant:Nn \spath_export_to_svg:nn {nv, nV}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\spath_show:n}
+% \begin{macro}[internal]{\spath_show:n}
% Displays the soft path on the terminal.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \spath_show:n #1
@@ -3806,9 +4700,9 @@ manipulating PGF soft paths}
\int_step_inline:nnnn {1} {3} {\tl_count:n {#1}}
{
\iow_term:x {
- \tl_item:Nn \l_@@_tmpa_tl {##1}
- {\tl_item:Nn \l_@@_tmpa_tl {##1+1}}
- {\tl_item:Nn \l_@@_tmpa_tl {##1+2}}
+ \tl_item:nn {#1} {##1}
+ {\tl_item:nn {#1} {##1+1}}
+ {\tl_item:nn {#1} {##1+2}}
}
}
}
@@ -3820,7 +4714,7 @@ manipulating PGF soft paths}
%
% Spaths come from PGF so we need some functions that get and set spaths from the pgf system.
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_get_current_path:N,
% \spath_gget_current_path:N
% }
@@ -3841,7 +4735,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\spath_protocol_path:n}
+% \begin{macro}[internal]{\spath_protocol_path:n}
% This feeds the bounding box of the soft path to PGF to ensure that its current bounding box contains the soft path.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \spath_protocol_path:n #1
@@ -3856,7 +4750,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_set_current_path:n,
% \spath_set_current_path:N
% }
@@ -3877,7 +4771,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{
+% \begin{macro}[internal]{
% \spath_use_path:nn
% }
% Uses the given soft path at the PGF level.
@@ -3890,7 +4784,7 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\spath_tikz_path:nn}
+% \begin{macro}[internal]{\spath_tikz_path:nn}
% Uses the given soft path at the TikZ level.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \spath_tikz_path:nn #1#2
@@ -3904,22 +4798,99 @@ manipulating PGF soft paths}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\spath_set_tikz_coords:n}
+% \begin{macro}[internal]{\spath_set_tikz_data:n}
% Sets the \Verb+\tikz@lastx+ and other coordinates from the soft path.
% \begin{macrocode}
-\cs_new_protected_nopar:Npn \spath_set_tikz_coords:n #1
+\cs_new_protected_nopar:Npn \spath_set_tikz_data:n #1
{
\spath_finalpoint:Nn \l_@@_tmpa_tl {#1}
\tl_set:Nx \l_@@_tmpa_tl
{
- \exp_not:c {tikz@lastx}=\tl_item:Nn \l_@@_tmpa_tl {1}
- \exp_not:c {tikz@lasty}=\tl_item:Nn \l_@@_tmpa_tl {2}
- \exp_not:c {tikz@lastxsaved}=\tl_item:Nn \l_@@_tmpa_tl {1}
- \exp_not:c {tikz@lastysaved}=\tl_item:Nn \l_@@_tmpa_tl {2}
+ \exp_not:c {pgf@x}=\tl_item:Nn \l_@@_tmpa_tl {1}
+ \exp_not:c {pgf@y}=\tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ \use:c {pgf@process}{%
+ \tl_use:N \l_@@_tmpa_tl
+ \pgftransforminvert
+ \use:c {pgf@pos@transform@glob}
+ }
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:c {tikz@lastx}=\exp_not:c {pgf@x}
+ \exp_not:c {tikz@lasty}=\exp_not:c {pgf@y}
+ \exp_not:c {tikz@lastxsaved}=\exp_not:c {pgf@x}
+ \exp_not:c {tikz@lastysaved}=\exp_not:c {pgf@y}
}
\tl_use:N \l_@@_tmpa_tl
+ \spath_finalmovepoint:Nn \l_@@_tmpa_tl {#1}
+ \ifpgfsyssoftpathmovetorelevant%
+ \tl_gset_eq:cN {pgfsyssoftpath@lastmoveto} \l_@@_tmpa_tl
+ \fi
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:c {pgf@x}=\tl_item:Nn \l_@@_tmpa_tl {1}
+ \exp_not:c {pgf@y}=\tl_item:Nn \l_@@_tmpa_tl {2}
+ }
+ \use:c {pgf@process}{%
+ \tl_use:N \l_@@_tmpa_tl
+ \pgftransforminvert
+ \use:c {pgf@pos@transform@glob}
+ }
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:c {tikz@lastmovetox}=\exp_not:c {pgf@x}
+ \exp_not:c {tikz@lastmovetoy}=\exp_not:c {pgf@y}
+ }
+ \tl_use:N \l_@@_tmpa_tl
+ \tl_clear_new:c {tikz@timer}
+ \tl_set:cn {tikz@timer}
+ {
+ \spath_reallength:Nn \l_@@_tmpa_int {#1}
+ \tl_set_eq:Nc \l_@@_tmpb_tl {tikz@time}
+ \tl_set:Nx \l_@@_tmpb_tl
+ {\fp_to_decimal:n {(\l_@@_tmpb_tl) * (\l_@@_tmpa_int)}}
+ \spath_transformation_at:NnV \l_@@_tmpc_tl {#1} \l_@@_tmpb_tl
+
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ \exp_not:N \pgfpoint
+ { \tl_item:Nn \l_@@_tmpc_tl {5} }
+ { \tl_item:Nn \l_@@_tmpc_tl {6} }
+ }
+ \exp_args:NV \pgftransformshift \l_@@_tmpa_tl
+
+ \ifpgfresetnontranslationattime
+ \pgftransformresetnontranslations
+ \fi
+
+ \ifpgfslopedattime
+
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ { \tl_item:Nn \l_@@_tmpc_tl {1} }
+ { \tl_item:Nn \l_@@_tmpc_tl {2} }
+ { \tl_item:Nn \l_@@_tmpc_tl {3} }
+ { \tl_item:Nn \l_@@_tmpc_tl {4} }
+ }
+ \ifpgfallowupsidedownattime
+ \else
+ \fp_compare:nT { \tl_item:Nn \l_@@_tmpc_tl {4} < 0}
+ {
+ \tl_set:Nx \l_@@_tmpa_tl
+ {
+ { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {1})} }
+ { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {2})} }
+ { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {3})} }
+ { \fp_eval:n { - (\tl_item:Nn \l_@@_tmpc_tl {4})} }
+ }
+ }
+ \fi
+ \tl_put_right:Nn \l_@@_tmpa_tl {{\pgfpointorigin}}
+ \exp_last_unbraced:NV \pgftransformcm \l_@@_tmpa_tl
+ \fi
+ }
}
-\cs_generate_variant:Nn \spath_set_tikz_coords:n {V, v}
+\cs_generate_variant:Nn \spath_set_tikz_data:n {V, v}
% \end{macrocode}
% \end{macro}
%
@@ -3952,6 +4923,13 @@ manipulating PGF soft paths}
\bool_new:N \l_@@_draft_bool
% \end{macrocode}
%
+% We surround all the keys with checks to ensure that the soft path under consideration does actually exist, but if it doesn't we should warn the user.
+%
+% \begin{macrocode}
+\msg_new:nnn { spath3 } { missing soft path } { Soft~ path~ #1~ doesn't~ exist }
+\msg_new:nnn { spath3 } { empty soft path } { Soft~ path~ #1~ is~ empty }
+% \end{macrocode}
+%
% When saving a soft path, by default we use a naming convention that is compatible with the intersections library so that paths saved here and paths saved by the \texttt{name path} facility of the intersections library are mutually exchangeable.
%
% \begin{macrocode}
@@ -3991,6 +4969,34 @@ manipulating PGF soft paths}
\cs_generate_variant:Nn \spath_gsave_path:Nn {cn, NV, cV}
% \end{macrocode}
%
+% \begin{macro}[internal]{
+% \@@_process_tikz_point:Nn
+% }
+% Process a point via TikZ and store the resulting dimensions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_process_tikz_point:Nn #1#2
+{
+ \group_begin:
+ \use:c {tikz@scan@one@point} \use:n #2 \scan_stop:
+ \tl_gset:Nx \g_@@_output_tl
+ {
+ { \dim_use:c {pgf@x} }
+ { \dim_use:c {pgf@y} }
+ }
+ \group_end:
+ \tl_set_eq:NN #1 \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+}
+% \end{macrocode}
+% \end{macro}
+%
+% When we split a soft path into components, we make it a comma separated list so that it can be fed into a \Verb+\foreach+ loop.
+% This can also make it possible to extract a single component, but to do this we need a wrapper around \Verb+\clist_item:Nn+ (there doesn't appear to be a PGF way of getting an item of a CS list).
+%
+% \begin{macrocode}
+\cs_set_eq:NN \getComponentOf \clist_item:Nn
+% \end{macrocode}
+%
% Now we define all of our keys.
%
% \begin{macrocode}
@@ -4031,11 +5037,14 @@ manipulating PGF soft paths}
\tikz@addmode{
\spath_get_current_path:N \l_@@_tmpa_tl
\spath_bake_round:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
- \spath_save_path:cV {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} \l_@@_tmpa_tl
+ \spath_save_path:cV
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
}
},
clone/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
\tl_clear_new:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
@@ -4043,9 +5052,13 @@ manipulating PGF soft paths}
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
},
clone~ global/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
\tl_gclear_new:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
@@ -4053,6 +5066,9 @@ manipulating PGF soft paths}
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
},
save~ global/.code={
\tikz@addmode{
@@ -4069,11 +5085,15 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
save~ to~ aux/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_save_to_aux:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4081,12 +5101,69 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
restore/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_set_current_path:c
+ \tl_if_empty:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
- \spath_set_tikz_coords:v
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
+ \spath_set_current_path:V \l_@@_tmpa_tl
+ \spath_set_tikz_data:V \l_@@_tmpa_tl
+ \msg_warning:nnn { spath3 } { empty soft path } { #1 }
+ }
+ {
+ \spath_set_current_path:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_tikz_data:v
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ }
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
+ \spath_set_current_path:V \l_@@_tmpa_tl
+ \spath_set_tikz_data:V \l_@@_tmpa_tl
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Restores the reverse of a soft path to the current path.
+%
+% \begin{macrocode}
+ restore~ reverse/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_empty:cTF
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
+ \spath_set_current_path:V \l_@@_tmpa_tl
+ \spath_set_tikz_data:V \l_@@_tmpa_tl
+ \msg_warning:nnn { spath3 } { empty soft path } { #1 }
+ }
+ {
+ \spath_reverse:Nv
+ \l_@@_reverse_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_current_path:N \l_@@_reverse_tl
+ \spath_set_tikz_data:V \l_@@_reverse_tl
+ }
+ }
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ \tl_put_right:NV \l_@@_tmpa_tl \c_spath_moveto_tl
+ \tl_put_right:Nn \l_@@_tmpa_tl {{0pt}{0pt}}
+ \spath_set_current_path:V \l_@@_tmpa_tl
+ \spath_set_tikz_data:V \l_@@_tmpa_tl
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4107,10 +5184,22 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
show/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_empty:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \msg_warning:nnn { spath3 } { empty soft path } { #1 }
+ }
+ {
+ \iow_term:n {---~ soft~ path~ #1~ ---}
+ \spath_show:v
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ }
{
- \iow_term:n {---~ soft~ path~ #1~ ---}
- \spath_show:v {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4119,14 +5208,21 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
append/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_get_current_path:N \l_@@_current_tl
- \spath_weld:Nv
- \l_@@_current_tl
+ \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl
+ \tl_set_eq:Nc
+ \l_@@_tmpb_tl
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_translate_to:NV \l_@@_tmpb_tl \l_@@_tmpa_tl
+ \spath_append_no_move:NV \l_@@_current_tl \l_@@_tmpb_tl
\spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_coords:V \l_@@_current_tl
+ \spath_set_tikz_data:V \l_@@_tmpb_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4135,14 +5231,22 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
join~ with/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
\spath_append:cv
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4151,11 +5255,26 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
spot~ weld/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_spot_weld_components:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ spot~ weld~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_gweld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4163,11 +5282,26 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
reverse/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_reverse:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ reverse~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_reverse:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4175,15 +5309,21 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
append~ reverse/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_reverse:Nv
\l_@@_reverse_tl
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
\spath_get_current_path:N \l_@@_current_tl
- \spath_weld:NV \l_@@_current_tl \l_@@_reverse_tl
+ \spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_current_tl
+ \spath_translate_to:NV \l_@@_reverse_tl \l_@@_tmpa_tl
+ \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl
\spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_coords:V \l_@@_current_tl
+ \spath_set_tikz_data:V \l_@@_reverse_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4192,14 +5332,19 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
insert/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_get_current_path:N \l_@@_current_tl
\spath_append:Nv
\l_@@_current_tl
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
\spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_coords:V \l_@@_current_tl
+ \spath_set_tikz_data:v
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4208,7 +5353,8 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
insert~ reverse/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_reverse:Nv
\l_@@_reverse_tl
@@ -4216,7 +5362,301 @@ manipulating PGF soft paths}
\spath_get_current_path:N \l_@@_current_tl
\spath_append:NV \l_@@_current_tl \l_@@_reverse_tl
\spath_set_current_path:N \l_@@_current_tl
- \spath_set_tikz_coords:V \l_@@_current_tl
+ \spath_set_tikz_data:V \l_@@_reverse_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Appends the named path to the current path without translating it.
+%
+% \begin{macrocode}
+ append~ no~ move/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_append_no_move:Nv
+ \l_@@_current_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_data:v
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Appends the reverse of the named path without translating it.
+%
+% \begin{macrocode}
+ append~ reverse~ no~ move/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_reverse:Nv
+ \l_@@_reverse_tl
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \spath_get_current_path:N \l_@@_current_tl
+ \spath_append_no_move:NV \l_@@_current_tl \l_@@_reverse_tl
+ \spath_set_current_path:N \l_@@_current_tl
+ \spath_set_tikz_data:V \l_@@_reverse_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Adjust a path to span between two points.
+%
+% \begin{macrocode}
+ span/.code ~n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \@@_process_tikz_point:Nn \l_@@_tmpa_tl {#2}
+ \@@_process_tikz_point:Nn \l_@@_tmpb_tl {#3}
+ \spath_span:cVV
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl \l_@@_tmpb_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ span~ global/.code ~n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \@@_process_tikz_point:Nn \l_@@_tmpa_tl {#2}
+ \@@_process_tikz_point:Nn \l_@@_tmpb_tl {#3}
+ \spath_gspan:cVV
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl \l_@@_tmpb_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Defines a to path
+%
+% \begin{macrocode}
+ to/.style={
+ to~path={
+ [
+ spath/span={#1}{(\tikztostart)}{(\tikztotarget)},
+ spath/append~no~move={#1},
+ ]
+ \tikztonodes
+ }
+ },
+% \end{macrocode}
+%
+% Splice three paths together, transforming the middle one so that it exactly fits between the first and third.
+%
+% \begin{macrocode}
+ splice/.code ~n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_splice_between:cvv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #3 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ splice~ global/.code ~n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplice_between:cvv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #3 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #3 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Join the components of a path by splicing in the second path whenever the components are sufficiently far apart.
+%
+% \begin{macrocode}
+ join~ components~ with/.code~2~args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_weld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \spath_splice_between:Nvn \l_@@_tmpa_tl
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {##1}
+ }
+ \tl_set_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ join~ components~ globally~ with/.code~2~args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_gweld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+
+ \seq_pop_left:NN \l_@@_tmpa_seq \l_@@_tmpa_tl
+
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \spath_gsplice_between:Nvn \l_@@_tmpa_tl
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {##1}
+ }
+ \tl_set_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \l_@@_tmpa_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Close a path.
+%
+% \begin{macrocode}
+ close/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_close:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ close~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gclose:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Close a path with another path.
+%
+% \begin{macrocode}
+ close~ with/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_close_with:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ close~ globally~ with/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gclose_with:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4225,27 +5665,74 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
shorten~ at~ end/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_shorten_at_end:cn
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
shorten~ at~ start/.code~ 2~ args ={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_shorten_at_start:cn
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
shorten~ at~ both~ ends/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_shorten_at_end:cn
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
\spath_shorten_at_start:cn
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ shorten~ globally~ at~ end/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gshorten_at_end:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ shorten~ globally~ at~ start/.code~ 2~ args ={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gshorten_at_start:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ shorten~ globally~ at~ both~ ends/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_shorten_at_end:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ \spath_shorten_at_start:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl} {#2}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4253,11 +5740,53 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
translate/.code~ n~ args={3}{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_translate:cnn
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{#2}{#3}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ translate~ globally/.code~ n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gtranslate:cnn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{#2}{#3}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% This normalises the named path.
+%
+% \begin{macrocode}
+ normalise/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_normalise:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ normalise~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gnormalise:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4265,11 +5794,15 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
export~ to~ svg/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \spath_export_to_svg:c
+ \spath_export_to_svg:nv {#1}
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4277,7 +5810,8 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
transform/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
\pgftransformreset
@@ -4292,9 +5826,13 @@ manipulating PGF soft paths}
\group_end:
\tl_use:N \g_@@_smuggle_tl
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
- transform~global/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ transform~globally/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
\pgftransformreset
@@ -4309,6 +5847,52 @@ manipulating PGF soft paths}
\group_end:
\tl_use:N \g_@@_smuggle_tl
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
+% Splits first path where it intersects with the second.
+%
+% \begin{macrocode}
+ split~ at~ intersections~ with/.code~ n~ args={2}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_split_path_at_intersections:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ split~ globally~ at~ intersections~ with/.code~ n~ args={2}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_path_at_intersections:cv
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4316,14 +5900,41 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
split~ at~ intersections/.code~ n~ args={2}{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
{
\spath_split_at_intersections:cc
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ split~ globally~ at~ intersections/.code~ n~ args={2}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_at_intersections:cc
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\tl_use:N \l_@@_prefix_tl #2 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #2 }
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
}
},
% \end{macrocode}
@@ -4332,11 +5943,26 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
split~ at~ self~ intersections/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_split_at_self_intersections:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ split~ globally~ at~ self~ intersections/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gsplit_at_self_intersections:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4344,7 +5970,8 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
get~ components~ of/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\clist_clear_new:N #2
\spath_components_to_seq:Nv
@@ -4353,13 +5980,54 @@ manipulating PGF soft paths}
\seq_map_inline:Nn \l_@@_tmpa_seq
{
\tl_new:c
- {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl}
+ {
+ \tl_use:N \l_@@_prefix_tl
+ anonymous_\int_use:N \g_@@_anon_int
+ \tl_use:N \l_@@_suffix_tl
+ }
\tl_set:cn
- {\tl_use:N \l_@@_prefix_tl anonymous_\int_use:N \g_@@_anon_int \tl_use:N \l_@@_suffix_tl} {##1}
+ {
+ \tl_use:N \l_@@_prefix_tl
+ anonymous_\int_use:N \g_@@_anon_int
+ \tl_use:N \l_@@_suffix_tl
+ } {##1}
\clist_put_right:Nx #2 {anonymous_\int_use:N \g_@@_anon_int}
\int_gincr:N \g_@@_anon_int
}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ get~ components~ of~ globally/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \clist_gclear_new:N #2
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_map_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_new:c
+ {
+ \tl_use:N \l_@@_prefix_tl
+ anonymous_\int_use:N \g_@@_anon_int
+ \tl_use:N \l_@@_suffix_tl
+ }
+ \tl_gset:cn
+ {
+ \tl_use:N \l_@@_prefix_tl
+ anonymous_\int_use:N \g_@@_anon_int
+ \tl_use:N \l_@@_suffix_tl
+ } {##1}
+ \clist_gput_right:Nx #2 {anonymous_\int_use:N \g_@@_anon_int}
+ \int_gincr:N \g_@@_anon_int
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4367,7 +6035,8 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
render~ components/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
\spath_components_to_seq:Nv
@@ -4390,6 +6059,9 @@ manipulating PGF soft paths}
}
\group_end:
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4398,15 +6070,24 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
insert~ gaps~ after~ components/.code~ n~ args={3}{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\group_begin:
\seq_gclear:N \g_@@_tmpa_seq
\seq_gclear:N \g_@@_tmpb_seq
+ \spath_numberofcomponents:Nv \l_@@_tmpa_int
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
\foreach \l_@@_tmpa_tl in {#3}
{
\seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
- \seq_gput_right:Nx \g_@@_tmpb_seq {\int_eval:n { \l_@@_tmpa_tl + 1 }}
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {\int_eval:n
+ {
+ \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ }
+ }
}
\spath_components_to_seq:Nv
\l_@@_tmpa_seq
@@ -4432,6 +6113,58 @@ manipulating PGF soft paths}
\g_@@_output_tl
\tl_gclear:N \g_@@_output_tl
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ insert~ gaps~ globally~ after~ components/.code~ n~ args={3}{
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \group_begin:
+ \seq_gclear:N \g_@@_tmpa_seq
+ \seq_gclear:N \g_@@_tmpb_seq
+ \spath_numberofcomponents:Nv \l_@@_tmpa_int
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \foreach \l_@@_tmpa_tl in {#3}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ \seq_gput_right:Nx
+ \g_@@_tmpb_seq
+ {
+ \int_eval:n
+ {
+ \int_mod:nn { \l_@@_tmpa_tl }{ \l_@@_tmpa_int } + 1
+ }
+ }
+ }
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpa_tl {##2}
+ \seq_if_in:NnT \g_@@_tmpa_seq {##1}
+ {
+ \spath_shorten_at_end:Nn \l_@@_tmpa_tl {#2/2}
+ }
+ \seq_if_in:NnT \g_@@_tmpb_seq {##1}
+ {
+ \spath_shorten_at_start:Nn \l_@@_tmpa_tl {#2/2}
+ }
+ \seq_put_right:NV \l_@@_tmpb_seq \l_@@_tmpa_tl
+ }
+ \tl_gset:Nx \g_@@_output_tl {\seq_use:Nn \l_@@_tmpb_seq {} }
+ \group_end:
+ \tl_gset_eq:cN
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \g_@@_output_tl
+ \tl_gclear:N \g_@@_output_tl
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4439,7 +6172,8 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
join~ components/.code~ 2~ args={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\seq_gclear:N \g_@@_tmpa_seq
\foreach \l_@@_tmpa_tl in {#2}
@@ -4458,6 +6192,34 @@ manipulating PGF soft paths}
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{##1}
}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ join~ components~ globally/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \seq_gclear:N \g_@@_tmpa_seq
+ \foreach \l_@@_tmpa_tl in {#2}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} > {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ \seq_map_inline:Nn \g_@@_tmpa_seq
+ {
+ \spath_gjoin_component:cn
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}{##1}
+ }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
@@ -4465,14 +6227,123 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
remove~ empty~ components/.code={
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_remove_empty_components:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ remove~ empty~ components~ globally/.code={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_gremove_empty_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
},
% \end{macrocode}
%
+%
+% Join the specified components together, joining each to its previous one.
+%
+% \begin{macrocode}
+ remove~ components/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \seq_gclear:N \g_@@_tmpa_seq
+ \foreach \l_@@_tmpa_tl in {#2}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ }
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {##1}
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \l_@@_tmpa_tl
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ }
+ }
+ {
+ \seq_put_right:Nn \l_@@_tmpb_seq {##2}
+ }
+ }
+ \tl_set:cx {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\seq_use:Nn \l_@@_tmpb_seq {} }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+ remove~ components~ globally/.code~ 2~ args={
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \seq_gclear:N \g_@@_tmpa_seq
+ \foreach \l_@@_tmpa_tl in {#2}
+ {
+ \seq_gput_right:NV \g_@@_tmpa_seq \l_@@_tmpa_tl
+ }
+ \seq_gsort:Nn \g_@@_tmpa_seq
+ {
+ \int_compare:nNnTF {##1} < {##2}
+ { \sort_return_same: }
+ { \sort_return_swapped: }
+ }
+ \spath_components_to_seq:Nv
+ \l_@@_tmpa_seq
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ }
+ \seq_clear:N \l_@@_tmpb_seq
+ \seq_map_indexed_inline:Nn \l_@@_tmpa_seq
+ {
+ \tl_set:Nn \l_@@_tmpb_tl {##1}
+ \tl_if_eq:NNTF \l_@@_tmpb_tl \l_@@_tmpa_tl
+ {
+ \seq_gpop_left:NNF \g_@@_tmpa_seq \l_@@_tmpa_tl
+ {
+ \tl_clear:N \l_@@_tmpa_tl
+ }
+ }
+ {
+ \seq_put_right:Nn \l_@@_tmpb_seq {##2}
+ }
+ }
+ \tl_gset:cx {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {\seq_use:Nn \l_@@_tmpb_seq {} }
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ },
+% \end{macrocode}
+%
% This puts a conditional around the \texttt{spot weld} key because when figuring out a knot drawing then we will initially want to render it without the spot weld to keep the number of components constant.
%
% \begin{macrocode}
@@ -4486,11 +6357,29 @@ manipulating PGF soft paths}
maybe~ spot~ weld/.code={
\bool_if:NF \l_@@_draft_bool
{
- \tl_if_exist:cT {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
{
\spath_spot_weld_components:c
{\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
}
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
+ }
+ },
+ maybe~ spot~ weld~ globally/.code={
+ \bool_if:NF \l_@@_draft_bool
+ {
+ \tl_if_exist:cTF
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ {
+ \spath_spot_gweld_components:c
+ {\tl_use:N \l_@@_prefix_tl #1 \tl_use:N \l_@@_suffix_tl}
+ }
+ {
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
+ }
}
},
% \end{macrocode}
@@ -4527,6 +6416,7 @@ manipulating PGF soft paths}
\tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl
}
{
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
\tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} }
}
\group_end:
@@ -4567,6 +6457,7 @@ manipulating PGF soft paths}
\tl_gset_eq:NN \g_@@_smuggle_tl \l_@@_tmpc_tl
}
{
+ \msg_warning:nnn { spath3 } { missing soft path } { #1 }
\tl_gset_eq:NN \g_@@_smuggle_tl { {1}{0}{0}{1}{0pt}{0pt} }
}
\fp_compare:nT { \tl_item:Nn \g_@@_smuggle_tl {4} < 0}
@@ -4591,11 +6482,18 @@ manipulating PGF soft paths}
%
% \begin{macrocode}
knot/.style~ n~ args={3}{
- spath/.cd,
- split~ at~ self~ intersections=#1,
- insert~ gaps~ after~ components={#1}{#2}{#3},
- maybe~ spot~ weld=#1,
- render~ components=#1
+ spath/split~ at~ self~ intersections=#1,
+ spath/remove~ empty~ components=#1,
+ spath/insert~ gaps~ after~ components={#1}{#2}{#3},
+ spath/maybe~ spot~ weld=#1,
+ spath/render~ components=#1
+ },
+ global~ knot/.style~ n~ args={3}{
+ spath/split~ globally~ at~ self~ intersections=#1,
+ spath/remove~ empty~ components~ globally=#1,
+ spath/insert~ gaps~ globally ~after~ components={#1}{#2}{#3},
+ spath/maybe~ spot~ weld~ globally=#1,
+ spath/render~ components=#1
},
}
% \end{macrocode}
@@ -4649,10 +6547,15 @@ manipulating PGF soft paths}
}
}
{
+ \msg_warning:nnx { spath3 } { missing soft path } { \tl_use:N \l_@@_tmpa_tl }
\tl_gset_eq:NN \g_@@_smuggle_tl \pgfpointorigin
}
- \group_end:
+ \group_end:
+ \use:c {pgf@process}{%
\tl_use:N \g_@@_smuggle_tl
+ \pgftransforminvert
+ \use:c {pgf@pos@transform@glob}
+ }
}
\ExplSyntaxOff
@@ -4733,7 +6636,8 @@ manipulating PGF soft paths}
\pgfsyssoftpath@getcurrentpath\l_@@_tmpa_tl
\spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
\seq_gclear_new:c {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
- \seq_gset_eq:cN {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} \l_@@_tmpa_seq
+ \seq_gset_eq:cN
+ {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq} \l_@@_tmpa_seq
\pgfusepath{discard}%
}
},
@@ -4747,10 +6651,12 @@ manipulating PGF soft paths}
\spath_components_to_seq:NV \l_@@_tmpa_seq \l_@@_tmpa_tl
\tl_if_exist:cTF {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
{
- \cal_path_create:Nc \l_@@_tmpa_seq {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
+ \cal_path_create:Nc \l_@@_tmpa_seq
+ {g_@@_pen_\pgfkeysvalueof{/tikz/pen~name}_seq}
}
{
- \msg_warning:nnx { calligraphy } { undefined pen } { \pgfkeysvalueof{/tikz/pen~name} }
+ \msg_warning:nnx { calligraphy } { undefined pen }
+ { \pgfkeysvalueof{/tikz/pen~name} }
}
}
},
@@ -4823,8 +6729,10 @@ manipulating PGF soft paths}
\tl_set:cn {l_@@_stroke_style_#1} {#2}
},
this~stroke~style/.code={
- \tl_clear_new:c {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int}
- \tl_set:cn {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} {#1}
+ \tl_clear_new:c
+ {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int}
+ \tl_set:cn
+ {l_@@_stroke_inline_style_ \int_use:N \g_@@_path_component_int} {#1}
},
annotate/.style={
annotate~if,
@@ -4944,23 +6852,29 @@ manipulating PGF soft paths}
\spath_weld:NV \l_@@_tmp_patha_tl \l_@@_tmp_rpathb_tl
\tl_clear:N \l_@@_tmpa_tl
- \tl_set:Nn \l_@@_tmpa_tl {fill=\pgfkeysvalueof{/tikz/pen~colour},draw=none}
+ \tl_set:Nn \l_@@_tmpa_tl
+ {
+ fill=\pgfkeysvalueof{/tikz/pen~colour},
+ draw=none
+ }
\tl_if_exist:cT {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
{
- \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
+ \tl_put_right:Nv \l_@@_tmpa_tl
+ {l_@@_stroke_style_ \int_use:N \l_@@_tmpa_int}
}
\tl_if_exist:cT {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
{
\tl_put_right:Nn \l_@@_tmpa_tl {,}
- \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
+ \tl_put_right:Nv \l_@@_tmpa_tl
+ {l_@@_stroke_inline_style_ \int_use:N \l_@@_tmpa_int}
}
\tl_if_exist:cT {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
{
\tl_put_right:Nn \l_@@_tmpa_tl {,}
- \tl_put_right:Nv \l_@@_tmpa_tl {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
+ \tl_put_right:Nv \l_@@_tmpa_tl
+ {l_@@_nib_style_ \int_use:N \l_@@_tmpb_int}
}
\spath_tikz_path:VV \l_@@_tmpa_tl \l_@@_tmp_patha_tl
-
}
\pgfsys@endscope
\group_end:
@@ -4971,7 +6885,9 @@ manipulating PGF soft paths}
\seq_get_right:NN #2 \l_@@_tmpa_tl
\spath_finalpoint:NV \l_@@_tmpa_tl \l_@@_tmpa_tl
\spath_translate:NV \l_@@_tmp_path_tl \l_@@_tmpa_tl
- \tikz@scan@one@point\pgfutil@firstofone\pgfkeysvalueof{/tikz/annotation~shift}
+ \tikz@scan@one@point
+ \pgfutil@firstofone
+ \pgfkeysvalueof{/tikz/annotation~shift}
\spath_translate:Nnn \l_@@_tmp_path_tl {\pgf@x} {\pgf@y}
@@ -4982,7 +6898,10 @@ manipulating PGF soft paths}
\exp_last_unbraced:NV \pgfqpoint \l_@@_tmpa_tl
\begin{scope}[reset~ cm]
- \node[every~annotation~node/.try,tl~use:c = {l_@@_annotation_style_ \int_use:N \l_@@_tmpa_int _tl}] at (\pgf@x,\pgf@y) {\int_use:N \l_@@_tmpa_int};
+ \node[
+ every~annotation~node/.try,
+ tl~use:c = {l_@@_annotation_style_ \int_use:N \l_@@_tmpa_int _tl}
+ ] at (\pgf@x,\pgf@y) {\int_use:N \l_@@_tmpa_int};
\end{scope}
}
}
@@ -5191,8 +7110,18 @@ manipulating PGF soft paths}
(\l_@@_tmpa_fp^2 + \l_@@_tmpb_fp^2)^.5
}
- \fp_set:Nn \l_@@_tmpa_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpa_fp / \l_@@_tmpe_fp}
- \fp_set:Nn \l_@@_tmpb_fp {.5*\l_@@_taper_width_dim * \l_@@_tmpb_fp / \l_@@_tmpe_fp}
+ \fp_set:Nn \l_@@_tmpa_fp
+ {
+ .5*\l_@@_taper_width_dim
+ *
+ \l_@@_tmpa_fp / \l_@@_tmpe_fp
+ }
+ \fp_set:Nn \l_@@_tmpb_fp
+ {
+ .5*\l_@@_taper_width_dim
+ *
+ \l_@@_tmpb_fp / \l_@@_tmpe_fp
+ }
\fp_set:Nn \l_@@_tmpc_fp
{
@@ -5207,13 +7136,23 @@ manipulating PGF soft paths}
(\l_@@_tmpc_fp^2 + \l_@@_tmpd_fp^2)^.5
}
- \fp_set:Nn \l_@@_tmpc_fp {.5*\l_@@_line_width_dim * \l_@@_tmpc_fp / \l_@@_tmpe_fp}
- \fp_set:Nn \l_@@_tmpd_fp {.5*\l_@@_line_width_dim * \l_@@_tmpd_fp / \l_@@_tmpe_fp}
+ \fp_set:Nn \l_@@_tmpc_fp
+ {
+ .5*\l_@@_line_width_dim
+ *
+ \l_@@_tmpc_fp / \l_@@_tmpe_fp
+ }
+ \fp_set:Nn \l_@@_tmpd_fp
+ {
+ .5*\l_@@_line_width_dim
+ *
+ \l_@@_tmpd_fp / \l_@@_tmpe_fp
+ }
\tl_put_right:Nx \l_@@_tmpb_tl
{
{\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}}
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
}
\tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetoa_tl
@@ -5244,16 +7183,44 @@ manipulating PGF soft paths}
\tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n{ 1.32 * \l_@@_tmpd_fp}}}
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32* \l_@@_tmpc_fp}}}
+ {
+ \dim_eval:n
+ {
+ \fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim
+ - \fp_to_dim:n{ 1.32 * \l_@@_tmpd_fp
+ }
+ }
+ }
+ {
+ \dim_eval:n
+ {
+ \fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim
+ + \fp_to_dim:n {1.32* \l_@@_tmpc_fp
+ }
+ }
+ }
}
\tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
\tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim - \fp_to_dim:n {1.32 * \l_@@_tmpd_fp}}}
- {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim + \fp_to_dim:n {1.32 * \l_@@_tmpc_fp}}}
+ {
+ \dim_eval:n
+ {
+ -\fp_to_dim:N \l_@@_tmpc_fp + \l_@@_tmpg_dim
+ - \fp_to_dim:n {1.32 * \l_@@_tmpd_fp
+ }
+ }
+ }
+ {
+ \dim_eval:n
+ {
+ -\fp_to_dim:N \l_@@_tmpd_fp + \l_@@_tmph_dim
+ + \fp_to_dim:n {1.32 * \l_@@_tmpc_fp
+ }
+ }
+ }
}
\tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
@@ -5292,16 +7259,40 @@ manipulating PGF soft paths}
\tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n{ 1.32 * \l_@@_tmpb_fp}}}
- {\dim_eval:n { -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32* \l_@@_tmpa_fp}}}
+ {
+ \dim_eval:n
+ {
+ -\fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim
+ + \fp_to_dim:n{ 1.32 * \l_@@_tmpb_fp}
+ }
+ }
+ {
+ \dim_eval:n
+ {
+ -\fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim
+ - \fp_to_dim:n {1.32* \l_@@_tmpa_fp}
+ }
+ }
}
\tl_put_right:NV \l_@@_tmpb_tl \c_spath_curvetob_tl
\tl_put_right:Nx \l_@@_tmpb_tl
{
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim + \fp_to_dim:n {1.32 * \l_@@_tmpb_fp}}}
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim - \fp_to_dim:n {1.32 * \l_@@_tmpa_fp}}}
+ {
+ \dim_eval:n
+ {
+ \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim
+ + \fp_to_dim:n {1.32 * \l_@@_tmpb_fp}
+ }
+ }
+ {
+ \dim_eval:n
+ {
+ \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim
+ - \fp_to_dim:n {1.32 * \l_@@_tmpa_fp}
+ }
+ }
}
\tl_put_right:NV \l_@@_tmpb_tl \c_spath_curveto_tl
@@ -5309,7 +7300,7 @@ manipulating PGF soft paths}
\tl_put_right:Nx \l_@@_tmpb_tl
{
{\dim_eval:n { \fp_to_dim:N \l_@@_tmpa_fp + \l_@@_tmpa_dim}}
- {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
+ {\dim_eval:n { \fp_to_dim:N \l_@@_tmpb_fp + \l_@@_tmpb_dim}}
}
\pgfsyssoftpath@setcurrentpath\l_@@_tmpb_tl
@@ -5327,7 +7318,7 @@ manipulating PGF soft paths}
\seq_gset_eq:NN \g_@@_pen_copperplate_seq \l_@@_tmpa_seq
% \end{macrocode}
%
-% \begin{macro}{\CopperplatePath}
+% \begin{macro}[internal]{\CopperplatePath}
% This is used in the decorations section to convert a path to a copperplate path.
% \begin{macrocode}
\DeclareDocumentCommand \CopperplatePath { m }
@@ -5350,75 +7341,160 @@ manipulating PGF soft paths}
% \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}}
+\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}{.3\pgfdecorationsegmentamplitude}}
- {\pgfqpoint{0pt}{0pt}}
- }
- \tikzset{
- taper width=.5\pgflinewidth,
- taper
+ {%
+ \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}%
+ }%
}%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \CopperplatePath{\cal@tmp@path}
- }
- \state{final}{}
-}
+ {%
+ \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%
+ \CopperplatePath{\cal@tmp@path}%
+ }%
+ \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
+ \state{brace}[width=+\pgfdecoratedremainingdistance,next state=final]%
+ {%
+ \pgfsyssoftpath@setcurrentpath{\pgfutil@empty}%
+ \pgfpathmoveto{\pgfpointorigin}%
+ \pgfpathcurveto%
+ {%
+ \pgfqpoint%
+ {.76604\pgfdecorationsegmentamplitude}%
+ {.64279\pgfdecorationsegmentamplitude}%
}%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \CopperplatePath{\cal@tmp@path}
- }
+ {%
+ \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%
+ \CopperplatePath{\cal@tmp@path}%
+ }%
\state{final}{}%
}
% \end{macrocode}
@@ -5427,24 +7503,28 @@ manipulating PGF soft paths}
% \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
+ \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}%
}%
- \pgfsyssoftpath@getcurrentpath\cal@tmp@path
- \CopperplatePath{\cal@tmp@path}
- }
+ {\pgfqpoint{\cgrphy@xa}{1.3333\pgfdecorationsegmentamplitude}}%
+ {\pgfqpoint{\pgfdecoratedremainingdistance}{0pt}}%
+ \tikzset{%
+ taper width=.5\pgflinewidth,%
+ taper%
+ }%
+ \pgfsyssoftpath@getcurrentpath\cal@tmp@path%
+ \CopperplatePath{\cal@tmp@path}%
+ }%
\state{final}{}%
}
% \end{macrocode}
@@ -5504,6 +7584,7 @@ manipulating PGF soft paths}
\dim_new:N \l_@@_tmpa_dim
\dim_new:N \l_@@_tmpb_dim
\dim_new:N \l_@@_tolerance_dim
+\dim_new:N \l_@@_redraw_tolerance_dim
\dim_new:N \l_@@_clip_bg_radius_dim
\dim_new:N \l_@@_clip_draw_radius_dim
@@ -5747,6 +7828,14 @@ manipulating PGF soft paths}
\pgfscope
\pgftransformreset
% \end{macrocode}
+% Set the dimension for deciding when to include neighbouring strands
+% \begin{macrocode}
+ \dim_set:Nn \l_@@_redraw_tolerance_dim {\fp_to_dim:n
+ {
+ sqrt(2) * max(\l_@@_clip_bg_radius_dim, \l_@@_clip_draw_radius_dim)
+ }
+ }
+% \end{macrocode}
% Loop through the strands drawing each one for the first time.
% \begin{macrocode}
\int_step_function:nnnN {1} {1} {\l_@@_strands_int} \knot_draw_strand:n
@@ -5784,7 +7873,12 @@ manipulating PGF soft paths}
{
\tl_set:Nn \l_@@_node_tl {
\exp_not:N \node[coordinate,
- pin={[node~ contents={\int_use:N \g_@@_intersections_int},knot~ diagram/draft/crossing~ label, knot~ diagram/draft/crossing~ \int_use:N \g_@@_intersections_int \c_space_tl label/.try]
+ pin={[
+ node~ contents={\int_use:N \g_@@_intersections_int},
+ knot~ diagram/draft/crossing~ label,
+ knot~ diagram/draft/crossing~
+ \int_use:N \g_@@_intersections_int \c_space_tl label/.try
+ ]
}]
}
}
@@ -5793,7 +7887,10 @@ manipulating PGF soft paths}
% \begin{macrocode}
\int_step_variable:nnnNn {1} {1} {\l_@@_tmpa_int - 1} \l_@@_tmpa_tl
{
- \int_step_variable:nnnNn {\tl_use:N \l_@@_tmpa_tl + 1} {1} {\l_@@_tmpa_int} \l_@@_tmpb_tl
+ \int_step_variable:nnnNn
+ {\tl_use:N \l_@@_tmpa_tl + 1}
+ {1}
+ {\l_@@_tmpa_int} \l_@@_tmpb_tl
{
\knot_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl
}
@@ -5825,7 +7922,12 @@ manipulating PGF soft paths}
\spath_bake_round:c {knot strand #1}
\tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
\tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_strand #1}
- \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ ,
+ knot~ diagram/only~ when~ rendering/.try,
+ only~ when~ rendering/.try
+ }
\spath_tikz_path:Vv \l_@@_tmpa_tl {knot strand #1}
\group_end:
\endpgfscope
@@ -5845,11 +7947,15 @@ manipulating PGF soft paths}
\spath_finalpoint:Nv \l_@@_tmpb_tl {knot strand #1}
\dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}}
\dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}}
- \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
+ \node[
+ knot~ diagram/draft/strand~label
+ ] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
\spath_initialpoint:Nv \l_@@_tmpb_tl {knot strand #1}
\dim_set:Nn \l_@@_tmpa_dim {\tl_item:Nn \l_@@_tmpb_tl {1}}
\dim_set:Nn \l_@@_tmpb_dim {\tl_item:Nn \l_@@_tmpb_tl {2}}
- \node[knot~ diagram/draft/strand~label] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
+ \node[
+ knot~ diagram/draft/strand~label
+ ] at (\l_@@_tmpa_dim,\l_@@_tmpb_dim) {#1};
}
\bool_if:nT {
\l_@@_self_intersections_bool
@@ -5858,6 +7964,8 @@ manipulating PGF soft paths}
}
{
\tl_clear:N \l_@@_tmpa_tl
+ \spath_initialpoint:Nv \l_@@_tmpa_tl {knot strand #1}
+ \tl_put_left:NV \l_@@_tmpa_tl \c_spath_moveto_tl
\spath_segments_to_seq:Nv \l_@@_segments_seq {knot strand #1}
\seq_map_function:NN \l_@@_segments_seq \knot_split_self_intersects:N
\tl_set_eq:cN {knot strand #1} \l_@@_tmpa_tl
@@ -5881,23 +7989,29 @@ manipulating PGF soft paths}
{
\fp_set:Nn \l_@@_tmpa_fp
{
- (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
+ (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6}
+ + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
*
(3 * \tl_item:nn {#1} {8} - 3 * \tl_item:nn {#1} {11})
-
- (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
+ (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5}
+ + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
*
(3 * \tl_item:nn {#1} {9} - 3 * \tl_item:nn {#1} {12})
}
\fp_set:Nn \l_@@_tmpb_fp
{
- (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5} + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
+ (\tl_item:nn {#1} {2} - 3 * \tl_item:nn {#1} {5}
+ + 3 * \tl_item:nn {#1} {8} - \tl_item:nn {#1} {11})
*
- (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9} + 3 * \tl_item:nn {#1} {12})
+ (3 * \tl_item:nn {#1} {6} - 6 * \tl_item:nn {#1} {9}
+ + 3 * \tl_item:nn {#1} {12})
-
- (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6} + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
+ (\tl_item:nn {#1} {3} - 3 * \tl_item:nn {#1} {6}
+ + 3 * \tl_item:nn {#1} {9} - \tl_item:nn {#1} {12})
*
- (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8} + 3 * \tl_item:nn {#1} {11})
+ (3 * \tl_item:nn {#1} {5} - 6 * \tl_item:nn {#1} {8}
+ + 3 * \tl_item:nn {#1} {11})
}
\fp_compare:nTF
{
@@ -5910,7 +8024,11 @@ manipulating PGF soft paths}
0 < \l_@@_tmpa_fp && \l_@@_tmpa_fp < 1
}
{
- \spath_split_curve:NNnV \l_@@_tmpc_tl \l_@@_tmpd_tl {#1} \l_@@_tmpa_fp
+ \spath_split_curve:NNnV
+ \l_@@_tmpc_tl
+ \l_@@_tmpd_tl
+ {#1}
+ \l_@@_tmpa_fp
\tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
\tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
\tl_set:Nx \l_@@_tmpc_tl {\tl_tail:N \l_@@_tmpc_tl}
@@ -5968,19 +8086,33 @@ manipulating PGF soft paths}
\bool_if:nTF {
\l_@@_save_bool
&&
- \tl_if_exist_p:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl}
+ \tl_if_exist_p:c {
+ knot~ intersections~
+ \tl_use:N \l_@@_name_tl -
+ \tl_use:N \l_@@_tmpa_tl -
+ \tl_use:N \l_@@_tmpb_tl
+ }
}
{
- \tl_use:c {knot~ intersections~ \tl_use:N \l_@@_name_tl - \tl_use:N \l_@@_tmpa_tl - \tl_use:N \l_@@_tmpb_tl}
+ \tl_use:c
+ {
+ knot~ intersections~ \tl_use:N \l_@@_name_tl -
+ \tl_use:N \l_@@_tmpa_tl -
+ \tl_use:N \l_@@_tmpb_tl
+ }
}
{
-\pgfintersectionofpaths{\pgfsetpath\l_@@_tmpc_tl}{\pgfsetpath\l_@@_tmpd_tl}
+ \pgfintersectionofpaths{\pgfsetpath\l_@@_tmpc_tl}{\pgfsetpath\l_@@_tmpd_tl}
}
\int_compare:nT {\pgfintersectionsolutions > 0}
{
- \int_step_function:nnnN {1} {1} {\pgfintersectionsolutions} \knot_do_intersection:n
+ \int_step_function:nnnN
+ {1}
+ {1}
+ {\pgfintersectionsolutions}
+ \knot_do_intersection:n
}
\knot_save_intersections:VV \l_@@_tmpa_tl \l_@@_tmpb_tl
@@ -6017,7 +8149,16 @@ manipulating PGF soft paths}
}
\tl_put_right:Nx \l_@@_aux_tl
{
- {\exp_not:N \pgf@x=\dim_use:N \l_@@_tmpa_dim\exp_not:N\relax\exp_not:N \pgf@y =\dim_use:N \l_@@_tmpb_dim\relax}
+ {
+ \exp_not:N \pgf@x
+ =
+ \dim_use:N \l_@@_tmpa_dim
+ \exp_not:N \relax
+ \exp_not:N \pgf@y
+ =
+ \dim_use:N \l_@@_tmpb_dim
+ \exp_not:N \relax
+ }
}
}
\tl_set:Nn \l_@@_auxa_tl {\expandafter \gdef \csname knot~ intersections~}
@@ -6057,7 +8198,7 @@ manipulating PGF soft paths}
\tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl
\tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpb_tl
{
- \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {final point}
{
\bool_set_true:N \l_@@_skip_bool
}
@@ -6068,7 +8209,7 @@ manipulating PGF soft paths}
\tl_set:Nv \l_@@_tmpc_tl \l_@@_tmpc_tl
\tl_if_eq:NNT \l_@@_tmpc_tl \l_@@_tmpa_tl
{
- \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {final point}
{
\bool_set_true:N \l_@@_skip_bool
}
@@ -6079,19 +8220,19 @@ manipulating PGF soft paths}
% \begin{macrocode}
\bool_if:NT \l_@@_ignore_ends_bool
{
- \knot_test_endpoint:VnT \l_@@_tmpa_tl {initial point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {initial point}
{
\bool_set_true:N \l_@@_skip_bool
}
- \knot_test_endpoint:VnT \l_@@_tmpa_tl {final point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpa_tl {final point}
{
\bool_set_true:N \l_@@_skip_bool
}
- \knot_test_endpoint:VnT \l_@@_tmpb_tl {initial point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {initial point}
{
\bool_set_true:N \l_@@_skip_bool
}
- \knot_test_endpoint:VnT \l_@@_tmpb_tl {final point}
+ \knot_test_endpoint:NVnT \l_@@_tolerance_dim \l_@@_tmpb_tl {final point}
{
\bool_set_true:N \l_@@_skip_bool
}
@@ -6140,14 +8281,16 @@ manipulating PGF soft paths}
% \begin{macrocode}
\bool_if:NT \l_@@_self_intersections_bool
{
- \knot_test_endpoint:VnT \l_@@_tmpg_tl {initial point}
+ \knot_test_endpoint:NVnT
+ \l_@@_redraw_tolerance_dim \l_@@_tmpg_tl {initial point}
{
\bool_set_true:N \l_@@_prepend_prev_bool
}
{
\bool_set_false:N \l_@@_prepend_prev_bool
}
- \knot_test_endpoint:VnT \l_@@_tmpg_tl {final point}
+ \knot_test_endpoint:NVnT
+ \l_@@_redraw_tolerance_dim \l_@@_tmpg_tl {final point}
{
\bool_set_true:N \l_@@_append_next_bool
}
@@ -6163,10 +8306,14 @@ manipulating PGF soft paths}
}
{
\tl_clear_new:c {knot \tl_use:N \l_@@_prefix_tl -1}
- \tl_set_eq:cc {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:N \l_@@_tmpg_tl}
+ \tl_set_eq:cc
+ {knot \tl_use:N \l_@@_prefix_tl -1}
+ {knot \tl_use:N \l_@@_tmpg_tl}
\tl_clear_new:c {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1}
- \tl_set_eq:cc {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1} {l_@@_options_ \tl_use:N \l_@@_tmpg_tl}
+ \tl_set_eq:cc
+ {l_@@_options_ \tl_use:N \l_@@_prefix_tl -1}
+ {l_@@_options_ \tl_use:N \l_@@_tmpg_tl}
\bool_if:nT
{
@@ -6177,7 +8324,9 @@ manipulating PGF soft paths}
!\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
}
{
- \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}
+ \spath_prepend_no_move:cv
+ {knot \tl_use:N \l_@@_prefix_tl -1}
+ {knot \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}
% \end{macrocode}
% If we split potentially self intersecting curves, we test to see if we should prepend yet another segment.
% \begin{macrocode}
@@ -6190,10 +8339,18 @@ manipulating PGF soft paths}
!\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
}
{
- \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {initial point}
+ \knot_test_endpoint:NvnT
+ \l_@@_redraw_tolerance_dim
+ {knot previous \tl_use:N \l_@@_tmpg_tl}
+ {initial point}
{
-
- \spath_prepend_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot previous \tl_use:c {knot previous \tl_use:N \l_@@_tmpg_tl}}}
+ \spath_prepend_no_move:cv
+ {knot \tl_use:N \l_@@_prefix_tl -1}
+ {knot \tl_use:c
+ {knot previous \tl_use:c
+ {knot previous \tl_use:N \l_@@_tmpg_tl}
+ }
+ }
\tl_set_eq:Nc \l_@@_tmpa_tl {knot \tl_use:N \l_@@_prefix_tl -1}
}
}
@@ -6210,7 +8367,9 @@ manipulating PGF soft paths}
!\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
}
{
- \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}
+ \spath_append_no_move:cv
+ {knot \tl_use:N \l_@@_prefix_tl -1}
+ {knot \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}
\bool_if:nT
{
\l_@@_splits_bool
@@ -6221,14 +8380,21 @@ manipulating PGF soft paths}
!\tl_if_empty_p:c {knot previous \tl_use:N \l_@@_tmpg_tl}
}
{
- \knot_test_endpoint:vnT {knot previous \tl_use:N \l_@@_tmpg_tl} {final point}
+ \knot_test_endpoint:NvnT
+ \l_@@_redraw_tolerance_dim
+ {knot previous \tl_use:N \l_@@_tmpg_tl}
+ {final point}
{
- \spath_append_no_move:cv {knot \tl_use:N \l_@@_prefix_tl -1} {knot \tl_use:c {knot next \tl_use:c {knot next \tl_use:N \l_@@_tmpg_tl}}}
-
+ \spath_append_no_move:cv
+ {knot \tl_use:N \l_@@_prefix_tl -1}
+ {knot \tl_use:c
+ {knot next \tl_use:c
+ {knot next \tl_use:N \l_@@_tmpg_tl}
+ }
+ }
}
}
}
-
\tl_set:Nn \l_@@_tmpg_tl {\tl_use:N \l_@@_prefix_tl -1}
}
}
@@ -6237,9 +8403,15 @@ manipulating PGF soft paths}
% \begin{macrocode}
\pgfscope
\group_begin:
- \tikzset{knot~ diagram/every~ intersection/.try, every~ intersection/.try, knot~ diagram/intersection~ \int_use:N \g_@@_intersections_int/.try}
+ \tikzset{
+ knot~ diagram/every~ intersection/.try,
+ every~ intersection/.try,
+ knot~ diagram/intersection~ \int_use:N \g_@@_intersections_int/.try
+ }
\knot_draw_crossing:VVV \l_@@_tmpg_tl \l_@@_tmpa_dim \l_@@_tmpb_dim
- \coordinate (\l_@@_name_tl \c_space_tl \int_use:N \g_@@_intersections_int) at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim);
+ \coordinate
+ (\l_@@_name_tl \c_space_tl \int_use:N \g_@@_intersections_int)
+ at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim);
\group_end:
\endpgfscope
% \end{macrocode}
@@ -6251,7 +8423,13 @@ manipulating PGF soft paths}
% \begin{macrocode}
\tl_if_empty:NF \l_@@_node_tl
{
- \seq_gpush:Nx \g_@@_nodes_seq { \l_@@_node_tl at (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim) {};}
+ \seq_gpush:Nx
+ \g_@@_nodes_seq
+ {
+ \l_@@_node_tl
+ at
+ (\dim_use:N \l_@@_tmpa_dim, \dim_use:N \l_@@_tmpb_dim) {};
+ }
}
}
}
@@ -6263,15 +8441,15 @@ manipulating PGF soft paths}
% \begin{macro}[internal]{\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}
+\prg_new_conditional:Npnn \knot_test_endpoint:NN #1#2 {p,T,F,TF}
{
\dim_compare:nTF
{
- \dim_abs:n { \l_@@_tmpa_dim - \tl_item:Nn #1 {1}}
+ \dim_abs:n { \l_@@_tmpa_dim - \tl_item:Nn #2 {1}}
+
- \dim_abs:n { \l_@@_tmpb_dim - \tl_item:Nn #1 {2}}
+ \dim_abs:n { \l_@@_tmpb_dim - \tl_item:Nn #2 {2}}
<
- \l_@@_tolerance_dim
+ #1
}
{
\prg_return_true:
@@ -6286,10 +8464,10 @@ manipulating PGF soft paths}
% \begin{macro}[internal]{\knot_test_endpoint:nn}
% Wrapper around the above.
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \knot_test_endpoint:nn #1#2 {T,F,TF}
+\prg_new_protected_conditional:Npnn \knot_test_endpoint:Nnn #1#2#3 {T,F,TF}
{
- \use:c {spath_#2:Nv} \l_@@_tmpd_tl {knot #1}
- \knot_test_endpoint:NTF \l_@@_tmpd_tl
+ \use:c {spath_#3:Nv} \l_@@_tmpd_tl {knot #2}
+ \knot_test_endpoint:NNTF #1 \l_@@_tmpd_tl
{
\prg_return_true:
}
@@ -6298,9 +8476,9 @@ manipulating PGF soft paths}
}
}
-\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}
+\cs_generate_variant:Nn \knot_test_endpoint:NnnT {NVnT,NvnT}
+\cs_generate_variant:Nn \knot_test_endpoint:NnnF {NVnF,NvnF}
+\cs_generate_variant:Nn \knot_test_endpoint:NnnTF {NVnTF,NvnTF}
% \end{macrocode}
% \end{macro}
%
@@ -6311,27 +8489,37 @@ manipulating PGF soft paths}
{
\group_begin:
\pgfscope
- \path[knot~ diagram/background~ clip] (#2, #3) circle[radius=\l_@@_clip_bg_radius_dim];
+ \path[knot~ diagram/background~ clip] (#2, #3)
+ circle[radius=\l_@@_clip_bg_radius_dim];
\tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
\tl_if_exist:cT {l_@@_options_ #1}
{
\tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1}
}
- \tl_put_right:Nn \l_@@_tmpa_tl {,knotbg,line~ width= \tl_use:N \l_@@_clip_width_tl * \pgflinewidth}
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ ,knotbg
+ ,line~ width= \tl_use:N \l_@@_clip_width_tl * \pgflinewidth
+ }
\spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1}
\endpgfscope
\pgfscope
- \path[knot~ diagram/clip] (#2, #3) circle[radius=\l_@@_clip_draw_radius_dim];
+ \path[knot~ diagram/clip] (#2, #3)
+ circle[radius=\l_@@_clip_draw_radius_dim];
\tl_set:Nn \l_@@_tmpa_tl {knot~ diagram/every~ strand/.try,}
\tl_if_exist:cT {l_@@_options_ #1}
{
\tl_put_right:Nv \l_@@_tmpa_tl {l_@@_options_ #1}
}
- \tl_put_right:Nn \l_@@_tmpa_tl {,knot~ diagram/only~ when~ rendering/.try,only~ when~ rendering/.try}
+ \tl_put_right:Nn \l_@@_tmpa_tl
+ {
+ ,knot~ diagram/only~ when~ rendering/.try
+ ,only~ when~ rendering/.try
+ }
\spath_tikz_path:Vv \l_@@_tmpa_tl {knot #1}
\endpgfscope
@@ -6408,12 +8596,14 @@ manipulating PGF soft paths}
\tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1}
\tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int}
- \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int}
+ \l_@@_tmpa_tl
\tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
\int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
{
- \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int}
+ {filament \int_eval:n {\g_@@_filaments_int - 1}}
}
}
\c_spath_curvetoa_tl
@@ -6422,12 +8612,15 @@ manipulating PGF soft paths}
\tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int}
\tl_set:cn {knot filament \int_use:N \g_@@_filaments_int} {#1}
\tl_clear_new:c {l_@@_options_filament \int_use:N \g_@@_filaments_int}
- \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int}
+ \l_@@_tmpa_tl
\tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
\int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
{
- \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ \tl_set:cx
+ {knot previous filament \int_use:N \g_@@_filaments_int}
+ {filament \int_eval:n {\g_@@_filaments_int - 1}}
}
}
\c_spath_closepath_tl
@@ -6435,18 +8628,26 @@ manipulating PGF soft paths}
\int_gincr:N \g_@@_filaments_int
\tl_clear_new:c {knot filament \int_use:N \g_@@_filaments_int}
\tl_clear:N \l_@@_tmpa_tl
- \tl_put_right:Nx {\tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3}}
+ \tl_put_right:Nx
+ {
+ \tl_item:nn {#1} {1}\tl_item:nn {#1} {2}\tl_item:nn {#1} {3}
+ }
\tl_put_right:NV \l_@@_tmpa_tl \c_spath_lineto_tl
\tl_put_right:Nx {\tl_item:nn {#1} {5}\tl_item:nn {#1} {6}}
\tl_set:cV {knot filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
- \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int} \l_@@_tmpa_tl
+ \tl_set_eq:cN {l_@@_options_filament \int_use:N \g_@@_filaments_int}
+ \l_@@_tmpa_tl
\tl_clear_new:c {knot previous filament \int_use:N \g_@@_filaments_int}
\int_compare:nF {\l_@@_component_start_int == \g_@@_filaments_int}
{
- \tl_set:cx {knot previous filament \int_use:N \g_@@_filaments_int} {filament \int_eval:n {\g_@@_filaments_int - 1}}
+ \tl_set:cx
+ {knot previous filament \int_use:N \g_@@_filaments_int}
+ {filament \int_eval:n {\g_@@_filaments_int - 1}}
}
- \tl_set:cx {knot previous filament \int_use:N \l_@@_component_start_int} {filament \int_use:N \g_@@_filaments_int}
+ \tl_set:cx
+ {knot previous filament \int_use:N \l_@@_component_start_int}
+ {filament \int_use:N \g_@@_filaments_int}
}
}
{