summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-02-23 21:54:14 +0000
committerKarl Berry <karl@freefriends.org>2018-02-23 21:54:14 +0000
commit87d871a3d83784d48b71fa3712b9f525bfc710d2 (patch)
treef12f9ffdc697b5af9ee14c06874ec0e2f72c9f94 /Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
parentccc63194ce7813106830c8a8755c54d89de831b4 (diff)
l3 (22feb18)
git-svn-id: svn://tug.org/texlive/trunk@46720 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx323
1 files changed, 323 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
new file mode 100644
index 00000000000..f10d7928082
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
@@ -0,0 +1,323 @@
+% \iffalse meta-comment
+%
+%% File: l3draw-softpath.dtx Copyright(C) 2018 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the "l3experimental bundle" (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex3
+%
+% for those people who are interested.
+%
+%<*driver>
+\RequirePackage{expl3}
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3draw-softpath} package\\ Soft paths^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2018/02/21}
+%
+% \maketitle
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3draw-softpath} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=draw>
+% \end{macrocode}
+%
+% There are two linked aims in the code here. The most significant is to
+% provide a way to modify paths, for example to shorten the ends or round
+% the corners. This means that the path cannot be written piecemeal as
+% specials, but rather needs to be held in macros. The second aspect that
+% follows from this is performance: simply adding to a single macro a piece
+% at a time will have poor performance as the list gets long. Paths need to
+% be global (as specials are), so we cannot use \pkg{l3tl-build} or a similar
+% approach. Instead, we use the same idea as \pkg{pgf}: use a series of buffer
+% macros such that in most cases we don't add tokens to the main list. This
+% will get slow only for \emph{enormous} paths.
+%
+% Each marker (operation) token takes two arguments, which makes processing
+% more straight-forward. As such, some operations have dummy arguments, whilst
+% others have to be split over several tokens. As the code here is at a low
+% level, all dimension arguments are assumed to be explicit and fully-expanded.
+%
+% \begin{variable}
+% {
+% \g_@@_softpath_main_tl ,
+% \g_@@_softpath_buffer_a_tl ,
+% \g_@@_softpath_buffer_b_tl
+% }
+% The soft path itself.
+% \begin{macrocode}
+\tl_new:N \g_@@_softpath_main_tl
+\tl_new:N \g_@@_softpath_buffer_a_tl
+\tl_new:N \g_@@_softpath_buffer_b_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_@@_softpath_buffer_a_int ,
+% \g_@@_softpath_buffer_b_int
+% }
+% Tracking data.
+% \begin{macrocode}
+\int_new:N \g_@@_softpath_buffer_a_int
+\int_new:N \g_@@_softpath_buffer_b_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_softpath_add:n, \@@_softpath_add:x}
+% \begin{macro}{\@@_softpath_concat:n}
+% \begin{macro}{\@@_softpath_reset_buffers:}
+% The softpath itself is quite simple. We use three token lists to hold the
+% data: two buffers of limited length, and the main list of arbitrary size.
+% Most of the time this will mean that we don't add to the full list, so
+% performance will be acceptable.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_add:n #1
+ {
+ \int_compare:nNnTF \g_@@_softpath_buffer_a_int < { 40 }
+ {
+ \int_gincr:N \g_@@_softpath_buffer_a_int
+ \tl_gput_right:Nn \g_@@_softpath_buffer_a_tl {#1}
+ }
+ {
+ \int_compare:nNnTF \g_@@_softpath_buffer_b_int < { 40 }
+ {
+ \int_gincr:N \g_@@_softpath_buffer_b_int
+ \tl_gset:Nx \g_@@_softpath_buffer_b_tl
+ {
+ \exp_not:V \g_@@_softpath_buffer_b_tl
+ \exp_not:V \g_@@_softpath_buffer_a_tl
+ \exp_not:n {#1}
+ }
+ \int_gzero:N \g_@@_softpath_buffer_a_int
+ \tl_gclear:N \g_@@_softpath_buffer_a_tl
+ }
+ { \@@_softpath_concat:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \@@_softpath_add:n { x }
+\cs_new_protected:Npn \@@_softpath_concat:n #1
+ {
+ \tl_gset:Nx \g_@@_softpath_main_tl
+ {
+ \exp_not:V \g_@@_softpath_main_tl
+ \exp_not:V \g_@@_softpath_buffer_b_tl
+ \exp_not:V \g_@@_softpath_buffer_a_tl
+ \exp_not:n {#1}
+ }
+ \@@_softpath_reset_buffers:
+ }
+\cs_new_protected:Npn \@@_softpath_reset_buffers:
+ {
+ \int_gzero:N \g_@@_softpath_buffer_a_int
+ \tl_gclear:N \g_@@_softpath_buffer_a_tl
+ \int_gzero:N \g_@@_softpath_buffer_b_int
+ \tl_gclear:N \g_@@_softpath_buffer_b_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_softpath_get:N, \@@_softpath_set_eq:N}
+% Save and restore functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_get:N #1
+ {
+ \@@_softpath_concat:n { }
+ \tl_set_eq:NN #1 \g_@@_softpath_main_tl
+ }
+\cs_new_protected:Npn \@@_softpath_set_eq:N #1
+ {
+ \tl_gset_eq:NN \g_@@_softpath_main_tl #1
+ \@@_softpath_reset_buffers:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {\@@_softpath_use:, \@@_softpath_clear:, \@@_softpath_use_clear:}
+% Using and clearing is trivial.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_use:
+ {
+ \g_@@_softpath_main_tl
+ \g_@@_softpath_buffer_b_tl
+ \g_@@_softpath_buffer_a_tl
+ }
+\cs_new_protected:Npn \@@_softpath_clear:
+ {
+ \tl_gclear:N \g_@@_softpath_main_tl
+ \tl_gclear:N \g_@@_softpath_buffer_a_tl
+ \tl_gclear:N \g_@@_softpath_buffer_b_tl
+ }
+\cs_new_protected:Npn \@@_softpath_use_clear:
+ {
+ \@@_softpath_use:
+ \@@_softpath_clear:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\g_@@_softpath_lastx_dim, \g_@@_softpath_lasty_dim}
+% For tracking the end of the path (to close it).
+% \begin{macrocode}
+\dim_new:N \g_@@_softpath_lastx_dim
+\dim_new:N \g_@@_softpath_lasty_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_softpath_move_bool}
+% Track if moving a point should update the close position.
+% \begin{macrocode}
+\bool_new:N \g_@@_softpath_move_bool
+\bool_gset_true:N \g_@@_softpath_move_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_softpath_curveto:nnnnnn}
+% \begin{macro}
+% {
+% \@@_softpath_lineto:nn,
+% \@@_softpath_moveto:nn
+% }
+% \begin{macro}{\@@_softpath_rectangle:nnnn}
+% \begin{macro}{\@@_softpath_roundpoint:nn, \@@_softpath_roundpoint:VV}
+% The various parts of a path expressed as the appropriate soft path
+% functions.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_closepath:
+ {
+ \@@_softpath_add:x
+ {
+ \@@_softpath_close_op:nn
+ { \dim_use:N \g_@@_softpath_lastx_dim }
+ { \dim_use:N \g_@@_softpath_lasty_dim }
+ }
+ }
+\cs_new_protected:Npn \@@_softpath_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_softpath_add:n
+ {
+ \@@_softpath_curveto_opi:nn {#1} {#2}
+ \@@_softpath_curveto_opii:nn {#3} {#4}
+ \@@_softpath_curveto_opiii:nn {#5} {#6}
+ }
+ }
+\cs_new_protected:Npn \@@_softpath_lineto:nn #1#2
+ {
+ \@@_softpath_add:n
+ { \@@_softpath_lineto_op:nn {#1} {#2} }
+ }
+\cs_new_protected:Npn \@@_softpath_moveto:nn #1#2
+ {
+ \@@_softpath_add:n
+ { \@@_softpath_moveto_op:nn {#1} {#2} }
+ \bool_if:NT \g_@@_softpath_move_bool
+ {
+ \dim_gset:Nn \g_@@_softpath_lastx_dim {#1}
+ \dim_gset:Nn \g_@@_softpath_lasty_dim {#2}
+ }
+ }
+\cs_new_protected:Npn \@@_softpath_rectangle:nnnn #1#2#3#4
+ {
+ \@@_softpath_add:n
+ {
+ \@@_softpath_rectangle_opi:nn {#1} {#2}
+ \@@_softpath_rectangle_opii:nn {#3} {#4}
+ }
+ }
+\cs_new_protected:Npn \@@_softpath_roundpoint:nn #1#2
+ {
+ \@@_softpath_add:n
+ { \@@_softpath_roundpoint_op:nn {#1} {#2} }
+ }
+\cs_generate_variant:Nn \@@_softpath_roundpoint:nn { VV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \@@_softpath_close_op:nn ,
+% \@@_softpath_curveto_opi:nn ,
+% \@@_softpath_curveto_opii:nn ,
+% \@@_softpath_curveto_opiii:nn ,
+% \@@_softpath_lineto_op:nn ,
+% \@@_softpath_moveto_op:nn ,
+% \@@_softpath_roundpoint_op:nn ,
+% \@@_softpath_rectangle_opi:nn ,
+% \@@_softpath_rectangle_opii:nn
+% }
+% \begin{macro}{\@@_softpath_curveto_opi:nnNnnNnn}
+% \begin{macro}{\@@_softpath_rectangle_opi:nnNnn}
+% The markers for operations: all the top-level ones take two arguments.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_close_op:nn #1#2
+ { \driver_draw_closepath: }
+\cs_new_protected:Npn \@@_softpath_curveto_opi:nn #1#2
+ { \@@_softpath_curveto_opi:nnNnnNnn {#1} {#2} }
+\cs_new_protected:Npn \@@_softpath_curveto_opi:nnNnnNnn #1#2#3#4#5#6#7#8
+ { \driver_draw_curveto:nnnnnn {#1} {#2} {#4} {#5} {#7} {#8} }
+\cs_new_protected:Npn \@@_softpath_curveto_opii:nn #1#2 { }
+\cs_new_protected:Npn \@@_softpath_curveto_opiii:nn #1#2 { }
+\cs_new_protected:Npn \@@_softpath_lineto_op:nn #1#2
+ { \driver_draw_lineto:nn {#1} {#2} }
+\cs_new_protected:Npn \@@_softpath_moveto_op:nn #1#2
+ { \driver_draw_moveto:nn {#1} {#2} }
+\cs_new_protected:Npn \@@_softpath_roundpoint_op:nn #1#2 { }
+\cs_new_protected:Npn \@@_softpath_rectangle_opi:nn #1#2
+ { \@@_softpath_rectangle_opi:nnNnn {#1} {#2} }
+\cs_new_protected:Npn \@@_softpath_rectangle_opi:nnNnn #1#2#3#4#5
+ { \driver_draw_rectangle:nnnn {#1} {#2} {#4} {#5} }
+ \cs_new_protected:Npn \@@_softpath_rectangle_opii:nn #1#2 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex