summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-03-07 21:50:56 +0000
committerKarl Berry <karl@freefriends.org>2018-03-07 21:50:56 +0000
commitf11f49763fc33ac8427d8c175d98a8d1275e4c5c (patch)
tree79aacd4b6ab168db69112977f42c2c99204e1621 /Master/texmf-dist/source/latex/l3experimental
parentfb72b3560bdc8a98d78bf919da56c3316fa7723d (diff)
l3 (6mar18)
git-svn-id: svn://tug.org/texlive/trunk@46875 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx47
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx153
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx182
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx70
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx186
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx395
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx34
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx283
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx670
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins1
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx4
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx6
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx6
15 files changed, 1689 insertions, 360 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx
index f00c047afff..68eaa14452d 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3color/l3color.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -263,7 +263,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3color}{2018/02/21}{}
+\ProvidesExplPackage{l3color}{2018/03/05}{}
{L3 Experimental color support}
%</package>
% \end{macrocode}
@@ -445,6 +445,10 @@
% \begin{macrocode}
\cs_new_protected:Npn \color_parse:nN #1#2
{
+%<*package>
+ \driver_color_pickup:N \l_@@_current_tl
+ \tl_set_eq:cN { l_@@_named_ . _tl } \l_@@_current_tl
+%</package>
\group_begin:
\seq_map_inline:Nn \l_char_active_seq
{
@@ -465,6 +469,7 @@
\tl_if_exist:cTF { l_@@_named_ #1 _tl }
{ \tl_set_eq:Nc #2 { l_@@_named_ #1 _tl } }
{ \@@_parse:Nw #2#1 ! \q_stop }
+ \@@_check_model:N #2
}
\cs_new_protected:Npn \@@_parse:Nw #1#2 ! #3 \q_stop
{
@@ -651,25 +656,15 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\@@_select:}
-% \begin{macro}{\@@_finalise:N}
-% \begin{macro}{\@@_finalise:w}
-% A driver-neutral location for \enquote{last minute} manipulations before
-% handing off to the driver code. We set the special |.| syntax here: this
-% will therefore always be available. The finalisation is separate from the
-% main function so it can also be applied to \emph{e.g.}~page color.
+% \begin{macro}{\@@_check_model:N}
+% \begin{macro}{\@@_check_model:w}
+% Check that the model in use is the one required.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_select:
- {
- \@@_finalise:N \l_@@_current_tl
- \tl_set_eq:cN { l_@@_named_ . _tl } \l_@@_current_tl
- \@@_select:V \l_@@_current_tl
- }
-\cs_new_protected:Npn \@@_finalise:N #1
+\cs_new_protected:Npn \@@_check_model:N #1
{
\tl_if_empty:NF \l_color_fixed_model_tl
{
- \exp_after:wN \@@_finalise:w #1 \q_stop
+ \exp_after:wN \@@_check_model:w #1 \q_stop
\tl_if_eq:NNF \l_@@_model_tl \l_color_fixed_model_tl
{
\@@_convert:VVN \l_@@_model_tl \l_color_fixed_model_tl
@@ -679,7 +674,7 @@
{ \l_color_fixed_model_tl \c_space_tl \l_@@_value_tl }
}
}
-\cs_new_protected:Npn \@@_finalise:w #1 ~ #2 \q_stop
+\cs_new_protected:Npn \@@_check_model:w #1 ~ #2 \q_stop
{
\tl_set:Nn \l_@@_model_tl {#1}
\tl_set:Nn \l_@@_value_tl {#2}
@@ -688,6 +683,20 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_select:}
+% A driver-neutral location for \enquote{last minute} manipulations before
+% handing off to the driver code. We set the special |.| syntax here: this
+% will therefore always be available. The finalisation is separate from the
+% main function so it can also be applied to \emph{e.g.}~page color.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_select:
+ {
+ \tl_set_eq:cN { l_@@_named_ . _tl } \l_@@_current_tl
+ \@@_select:V \l_@@_current_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\color_select:n}
% \begin{macro}{\color_select:nn}
% Parse the input expressions then get the driver to actually activate
@@ -718,6 +727,7 @@
{
\tl_set:Nx #3
{ #1 ~ \use:c { @@_parse_ #1 :w } #2 , 0 , 0 , 0 , 0 \q_stop }
+ \@@_check_model:N #3
}
{
\__kernel_msg_error:nnn { color } { invalid-model } {#1}
@@ -803,6 +813,7 @@
% definition.
% \begin{macrocode}
\tl_new:c { l_@@_named_._tl }
+\tl_set_eq:cN { l_@@_named_._tl } \l_@@_current_tl
% \end{macrocode}
% \end{variable}
%
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
new file mode 100644
index 00000000000..0cfd7239da9
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-boxes.dtx
@@ -0,0 +1,153 @@
+% \iffalse meta-comment
+%
+%% File: l3draw-boxes.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} package\\ Boxes in drawings^^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/03/05}
+%
+% \maketitle
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3draw-boxes} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=draw>
+% \end{macrocode}
+%
+% Inserting boxes requires us to \enquote{interrupt} the drawing state,
+% so is closely linked to scoping. At the same time, there are a few
+% additional features required to make text work in a flexible way.
+%
+% \begin{variable}{\l_@@_tmp_box}
+% \begin{macrocode}
+\box_new:N \l_@@_tmp_box
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\draw_box_use:N}
+% \begin{macro}{\@@_box_use:Nnnnn}
+% Before inserting a box, we need to make sure that the bounding box is being
+% updated correctly. As drawings track transformations as a whole, rather
+% than as separate operations, we do the insertion using an almost-raw
+% matrix. The process is split into two so that coffins are also supported.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_box_use:N #1
+ {
+ \@@_box_use:Nnnnn #1
+ { 0pt } { -\box_dp:N #1 } { \box_wd:N #1 } { \box_ht:N #1 }
+ }
+\cs_new_protected:Npn \@@_box_use:Nnnnn #1#2#3#4#5
+ {
+ \bool_if:NT \l_draw_bb_update_bool
+ {
+ \@@_point_process:nn
+ { \@@_path_update_limits:nn }
+ { \draw_point_transform:n { #2 , #3 } }
+ \@@_point_process:nn
+ { \@@_path_update_limits:nn }
+ { \draw_point_transform:n { #4 , #3 } }
+ \@@_point_process:nn
+ { \@@_path_update_limits:nn }
+ { \draw_point_transform:n { #4 , #5 } }
+ \@@_point_process:nn
+ { \@@_path_update_limits:nn }
+ { \draw_point_transform:n { #2 , #5 } }
+ }
+ \group_begin:
+ \hbox_set:Nn \l_@@_tmp_box
+ {
+ \use:x
+ {
+ \driver_draw_box_use:Nnnnn #1
+ { \fp_use:N \l_@@_matrix_a_fp }
+ { \fp_use:N \l_@@_matrix_b_fp }
+ { \fp_use:N \l_@@_matrix_c_fp }
+ { \fp_use:N \l_@@_matrix_d_fp }
+ }
+ }
+ \hbox_set:Nn \l_@@_tmp_box
+ {
+ \tex_kern:D \l_@@_xshift_dim
+ \box_move_up:nn { \l_@@_yshift_dim }
+ { \box_use_drop:N \l_@@_tmp_box }
+ }
+ \box_set_ht:Nn \l_@@_tmp_box { 0pt }
+ \box_set_dp:Nn \l_@@_tmp_box { 0pt }
+ \box_set_wd:Nn \l_@@_tmp_box { 0pt }
+ \box_use_drop:N \l_@@_tmp_box
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_coffin_use:Nnn}
+% Slightly more than a shortcut: we have to allow for the fact that coffins
+% have no apparent width before the reference point.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_coffin_use:Nnn #1#2#3
+ {
+ \group_begin:
+ \hbox_set:Nn \l_@@_tmp_box
+ { \coffin_typeset:Nnnnn #1 {#2} {#3} { 0pt } { 0pt } }
+ \@@_box_use:Nnnnn \l_@@_tmp_box
+ { \box_wd:N \l_@@_tmp_box - \coffin_wd:N #1 }
+ { -\box_dp:N \l_@@_tmp_box }
+ { \box_wd:N \l_@@_tmp_box }
+ { \box_ht:N \l_@@_tmp_box }
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
index 2fa882e7f1a..09df8391d17 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-paths.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -128,7 +128,7 @@
{ \dim_max:nn \g_@@_path_ymax_dim {#2} }
\dim_gset:Nn \g_@@_path_ymin_dim
{ \dim_min:nn \g_@@_path_ymin_dim {#2} }
- \bool_if:NT \l_@@_update_bb_bool
+ \bool_if:NT \l_draw_bb_update_bool
{
\dim_gset:Nn \g_@@_xmax_dim
{ \dim_max:nn \g_@@_xmax_dim {#1} }
@@ -185,15 +185,10 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\draw_path_corner_arc:n}
-% \begin{macro}{\@@_path_corner_arc:nn}
+% \begin{macro}{\draw_path_corner_arc:nn}
% Calculate the arcs, check they are non-zero.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_path_corner_arc:n #1
- {
- \@@_point_process:nn { \@@_path_corner_arc:nn } {#1}
- }
-\cs_new_protected:Npn \@@_path_corner_arc:nn #1#2
+\cs_new_protected:Npn \draw_path_corner_arc:nn #1#2
{
\dim_set:Nn \l_@@_corner_xarc_dim {#1}
\dim_set:Nn \l_@@_corner_yarc_dim {#2}
@@ -205,7 +200,6 @@
}
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\@@_path_mark_corner:}
% Mark up corners for arc post-processing.
@@ -295,6 +289,33 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Canvas path constructions}
+%
+% \begin{macro}{\draw_path_canvas_moveto:n, \draw_path_canvas_lineto:n}
+% \begin{macro}{\draw_path_canvas_curveto:nnn}
+% Operations with no application of the transformation matrix.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_path_canvas_moveto:n #1
+ { \@@_point_process:nn { \@@_path_moveto:nn } {#1} }
+\cs_new_protected:Npn \draw_path_canvas_lineto:n #1
+ { \@@_point_process:nn { \@@_path_lineto:nn } {#1} }
+\cs_new_protected:Npn \draw_path_canvas_curveto:nnn #1#2#3
+ {
+ \@@_point_process:nnn
+ {
+ \@@_point_process:nn
+ {
+ \@@_path_mark_corner:
+ \@@_path_curveto:nnnnnn
+ }
+ {#1}
+ }
+ {#2} {#3}
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Computed curves}
%
% More complex operations need some calculations. To assist with those, various
@@ -690,7 +711,9 @@
{
\@@_point_process:nnn
{
- \bool_if:NTF \l_@@_corner_arc_bool
+ \bool_lazy_or:nnTF
+ { \l_@@_corner_arc_bool }
+ { \l_@@_matrix_active_bool }
{ \@@_path_rectangle_rounded:nnnn }
{ \@@_path_rectangle:nnnn }
}
@@ -736,33 +759,71 @@
% \subsection{Grids}
%
% \begin{macro}{\draw_path_grid:nnnn}
-% \begin{macro}{\@@_path_grid:nnnnnn}
-% A simple set of loops.
+% \begin{macro}
+% {
+% \@@_path_grid_auxi:nnnnnn, \@@_path_grid_auxi:ffnnnn,
+% \@@_path_grid_auxii:nnnnnn,
+% \@@_path_grid_auxiii:nnnnnn, \@@_path_grid_auxiiii:ffnnnn
+% }
+% \begin{macro}
+% {\@@_path_grid_auxiv:nnnnnnnn, \@@_path_grid_auxiv:ffnnnnnn}
+% The main complexity here is lining up the grid correctly.
+% To keep it simple, we tidy up the argument ordering first.
% \begin{macrocode}
\cs_new_protected:Npn \draw_path_grid:nnnn #1#2#3#4
{
\@@_point_process:nnn
- { \@@_path_grid:nnnnnn {#1} {#2} }
+ {
+ \@@_path_grid_auxi:ffnnnn
+ { \dim_eval:n { \dim_abs:n {#1} } }
+ { \dim_eval:n { \dim_abs:n {#2} } }
+ }
{#3} {#4}
}
-\cs_new_protected:Npn \@@_path_grid:nnnnnn #1#2#3#4#5#6
+\cs_new_protected:Npn \@@_path_grid_auxi:nnnnnn #1#2#3#4#5#6
+ {
+ \dim_compare:nNnTF {#3} > {#5}
+ { \@@_path_grid_auxii:nnnnnn {#1} {#2} {#5} {#4} {#3} {#6} }
+ { \@@_path_grid_auxii:nnnnnn {#1} {#2} {#3} {#4} {#5} {#6} }
+ }
+\cs_generate_variant:Nn \@@_path_grid_auxi:nnnnnn { ff }
+\cs_new_protected:Npn \@@_path_grid_auxii:nnnnnn #1#2#3#4#5#6
+ {
+ \dim_compare:nNnTF {#4} > {#6}
+ { \@@_path_grid_auxiii:nnnnnn {#1} {#2} {#3} {#6} {#5} {#4} }
+ { \@@_path_grid_auxiii:nnnnnn {#1} {#2} {#3} {#4} {#5} {#6} }
+ }
+\cs_new_protected:Npn \@@_path_grid_auxiii:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_path_grid_auxiv:ffnnnnnn
+ { \fp_to_dim:n { #1 * trunc(#3/(#1)) } }
+ { \fp_to_dim:n { #2 * trunc(#4/(#2)) } }
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ }
+\cs_new_protected:Npn \@@_path_grid_auxiv:nnnnnnnn #1#2#3#4#5#6#7#8
{
\dim_step_inline:nnnn
- {#3} { \dim_compare:nNnF {#3} < {#5} { - } \dim_abs:n {#1} } {#5}
+ {#1}
+ {#3}
+ {#7}
{
- \draw_path_moveto:n { ##1 , #4 }
- \draw_path_lineto:n { ##1 , #6 }
+ \draw_path_moveto:n { ##1 , #6 }
+ \draw_path_lineto:n { ##1 , #8 }
}
\dim_step_inline:nnnn
- {#4} { \dim_compare:nNnF {#4} < {#6} { - } \dim_abs:n {#2} } {#6}
+ {#2}
+ {#4}
+ {#8}
{
- \draw_path_moveto:n { #3 , ##1 }
- \draw_path_lineto:n { #5 , ##1 }
+ \draw_path_moveto:n { #5 , ##1 }
+ \draw_path_lineto:n { #7 , ##1 }
}
}
+\cs_generate_variant:Nn \@@_path_grid_auxiv:nnnnnnnn { ff }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \subsection{Using paths}
%
@@ -790,7 +851,7 @@
%
% \begin{macro}{\draw_path_use:n, \draw_path_use_clear:n}
% \begin{macro}{\@@_path_use:n}
-% \begin{macro}{\@@_path_use_action_draw:}
+% \begin{macro}{\@@_path_use_action_draw:, \@@_path_use_action_fillstroke:}
% \begin{macro}{\@@_path_use_stroke_bb:}
% \begin{macro}{\@@_path_use_stroke_bb_aux:NnN}
% There are a range of actions which can apply to a path: they are handled
@@ -833,8 +894,9 @@
{ \ERROR }
}
}
+ \@@_softpath_round_corners:
\bool_lazy_and:nnT
- { \l_@@_update_bb_bool }
+ { \l_draw_bb_update_bool }
{ \l_@@_path_use_stroke_bool }
{ \@@_path_use_stroke_bb: }
\bool_if:NTF \l_@@_path_use_clear_bool
@@ -859,6 +921,11 @@
{
\bool_set_true:N \l_@@_path_use_stroke_bool
}
+\cs_new_protected:Npn \@@_path_use_action_fillstroke:
+ {
+ \bool_set_true:N \l_@@_path_use_fill_bool
+ \bool_set_true:N \l_@@_path_use_stroke_bool
+ }
% \end{macrocode}
% Where the path is relevant to size and is stroked, we need to allow for
% the part which overlaps the edge of the bounding box.
@@ -892,6 +959,75 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Scoping paths}
+%
+% \begin{variable}
+% {
+% \l_@@_path_lastx_dim, \l_@@_path_lasty_dim,
+% \l_@@_path_xmax_dim, \l_@@_path_xmin_dim,
+% \l_@@_path_ymax_dim, \l_@@_path_ymin_dim
+% }
+% \begin{variable}{\l_@@_softpath_corners_bool}
+% Local storage for global data. There is already a
+% \cs{l_@@_softpath_main_tl} for path manipulation, so we can reuse that
+% (it is always grouped when the path is being reconstructed).
+% \begin{macrocode}
+\dim_new:N \l_@@_path_lastx_dim
+\dim_new:N \l_@@_path_lasty_dim
+\dim_new:N \l_@@_path_xmax_dim
+\dim_new:N \l_@@_path_xmin_dim
+\dim_new:N \l_@@_path_ymax_dim
+\dim_new:N \l_@@_path_ymin_dim
+\dim_new:N \l_@@_softpath_lastx_dim
+\dim_new:N \l_@@_softpath_lasty_dim
+\bool_new:N \l_@@_softpath_corners_bool
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\draw_path_scope_begin:, \draw_path_scope_end:}
+% Scoping a path is a bit more involved, largely as there are a number
+% of variables to keep hold of.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_path_scope_begin:
+ {
+ \group_begin:
+ \dim_set_eq:NN \l_@@_path_lastx_dim \g_@@_path_lastx_dim
+ \dim_set_eq:NN \l_@@_path_lasty_dim \g_@@_path_lasty_dim
+ \dim_set_eq:NN \l_@@_path_xmax_dim \g_@@_path_xmax_dim
+ \dim_set_eq:NN \l_@@_path_xmin_dim \g_@@_path_xmin_dim
+ \dim_set_eq:NN \l_@@_path_ymax_dim \g_@@_path_ymax_dim
+ \dim_set_eq:NN \l_@@_path_ymin_dim \g_@@_path_ymin_dim
+ \dim_set_eq:NN \l_@@_softpath_lastx_dim \g_@@_softpath_lastx_dim
+ \dim_set_eq:NN \l_@@_softpath_lasty_dim \g_@@_softpath_lasty_dim
+ \@@_path_reset_limits:
+ \@@_softpath_concat:n { }
+ \tl_set_eq:NN \l_@@_softpath_main_tl \g_@@_softpath_main_tl
+ \bool_set_eq:NN
+ \l_@@_softpath_corners_bool
+ \g_@@_softpath_corners_bool
+ \@@_softpath_clear:
+ }
+\cs_new_protected:Npn \draw_path_scope_end:
+ {
+ \bool_gset_eq:NN
+ \g_@@_softpath_corners_bool
+ \l_@@_softpath_corners_bool
+ \@@_softpath_clear:
+ \tl_gset_eq:NN \g_@@_softpath_main_tl \l_@@_softpath_main_tl
+ \dim_gset_eq:NN \g_@@_softpath_lastx_dim \l_@@_softpath_lastx_dim
+ \dim_gset_eq:NN \g_@@_softpath_lasty_dim \l_@@_softpath_lasty_dim
+ \dim_gset_eq:NN \g_@@_path_xmax_dim \l_@@_path_xmax_dim
+ \dim_gset_eq:NN \g_@@_path_xmin_dim \l_@@_path_xmin_dim
+ \dim_gset_eq:NN \g_@@_path_ymax_dim \l_@@_path_ymax_dim
+ \dim_gset_eq:NN \g_@@_path_ymin_dim \l_@@_path_ymin_dim
+ \dim_gset_eq:NN \g_@@_path_lastx_dim \l_@@_path_lastx_dim
+ \dim_gset_eq:NN \g_@@_path_lasty_dim \l_@@_path_lasty_dim
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
index 01497992889..69ca8b6ae73 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-points.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -485,39 +485,31 @@
% \begin{macro}[EXP]{\@@_point_interpolate_distance:nnnnn}
% \begin{macro}[EXP]
% {
-% \@@_point_interpolate_distance_aux:nnnnnnn,
-% \@@_point_interpolate_distance_aux:nnnnnnn,
-% }
-% \begin{macro}[EXP]
-% {
-% \@@_point_interpolate_distance_aux:nnnnnn,
-% \@@_point_interpolate_distance_aux:fnnnnn,
+% \@@_point_interpolate_distance:nnnnnn,
+% \@@_point_interpolate_distance:fnnnnn,
% }
% Same idea but using the normalised length to obtain the scale factor.
+% The start point is needed twice, so we force evaluation, but the end
+% point is needed only the once.
% \begin{macrocode}
\cs_new:Npn \draw_point_interpolate_distance:nnn #1#2#3
{
- \@@_point_process:nnn
- { \@@_point_interpolate_distance:nnnnn {#1} }
- {#2} {#3}
- }
-\cs_new:Npn \@@_point_interpolate_distance:nnnnn #1#2#3#4#5
- {
- \@@_point_interpolate_distance_aux:nnnnnnn
- { \fp_eval:n { #4 - #2 } }
- { \fp_eval:n { #5 - #3 } }
- {#2} {#3} {#4} {#5} {#1}
+ \@@_point_process:nn
+ { \@@_point_interpolate_distance:nnnn {#1} {#3} }
+ {#2}
}
-\cs_new:Npn \@@_point_interpolate_distance_aux:nnnnnnn #1#2#3#4#5#6#7
+\cs_new:Npn \@@_point_interpolate_distance:nnnn #1#2#3#4
{
- \@@_point_interpolate_distance_aux:fnnnn
- { \fp_eval:n { (#7) / (sqrt ( #1 * #1 + #2 * #2 )) } }
- {#3} {#4} {#5} {#6}
+ \@@_point_process:nn
+ {
+ \@@_point_interpolate_distance:fnnnn
+ { \fp_eval:n {#1} } {#3} {#4}
+ }
+ { \draw_point_unit_vector:n { ( #2 ) - ( #3 , #4 ) } }
}
-\cs_generate_variant:Nn \@@_point_interpolate_distance_aux:nnnnnnn { ff }
-\cs_new:Npn \@@_point_interpolate_distance_aux:nnnnn #1#2#3#4#5
+\cs_new:Npn \@@_point_interpolate_distance:nnnnn #1#2#3#4#5
{ \@@_point_to_dim:n { #2 + #1 * #4 , #3 + #1 * #5 } }
-\cs_generate_variant:Nn \@@_point_interpolate_distance_aux:nnnnn { f }
+\cs_generate_variant:Nn \@@_point_interpolate_distance:nnnnn { f }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -605,7 +597,6 @@
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[EXP]{\draw_point_interpolate_curve:nnnnn}
% \begin{macro}[EXP]{\draw_point_interpolate_curve_auxi:nnnnnnnnn}
@@ -889,20 +880,20 @@
}
\cs_new:Npn \@@_point_transform:nn #1#2
{
- \bool_if:NTF \l_@@_transformcm_active_bool
+ \bool_if:NTF \l_@@_matrix_active_bool
{
\@@_point_to_dim:n
{
(
- \l_@@_transformcm_aa_fp * #1
- + \l_@@_transformcm_ba_fp * #2
- + \l_@@_transformcm_xshift_dim
+ \l_@@_matrix_a_fp * #1
+ + \l_@@_matrix_c_fp * #2
+ + \l_@@_xshift_dim
)
,
(
- \l_@@_transformcm_ab_fp * #1
- + \l_@@_transformcm_bb_fp * #2
- + \l_@@_transformcm_yshift_dim
+ \l_@@_matrix_b_fp * #1
+ + \l_@@_matrix_d_fp * #2
+ + \l_@@_yshift_dim
)
}
}
@@ -910,8 +901,7 @@
\@@_point_to_dim:n
{
(#1, #2)
- + ( \l_@@_transformcm_xshift_dim ,
- \l_@@_transformcm_yshift_dim )
+ + ( \l_@@_xshift_dim , \l_@@_yshift_dim )
}
}
}
@@ -930,18 +920,18 @@
}
\cs_new:Npn \@@_point_transform_noshift:nn #1#2
{
- \bool_if:NTF \l_@@_transformcm_active_bool
+ \bool_if:NTF \l_@@_matrix_active_bool
{
\@@_point_to_dim:n
{
(
- \l_@@_transformcm_aa_fp * #1
- + \l_@@_transformcm_ba_fp * #2
+ \l_@@_matrix_a_fp * #1
+ + \l_@@_matrix_c_fp * #2
)
,
(
- \l_@@_transformcm_ab_fp * #1
- + \l_@@_transformcm_bb_fp * #2
+ \l_@@_matrix_b_fp * #1
+ + \l_@@_matrix_d_fp * #2
)
}
}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
index b87a6a152b7..451226ccdef 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-scopes.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -72,11 +72,11 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l_@@_update_bb_bool}
+% \begin{variable}{\l_draw_bb_update_bool}
% Flag to indicate that a path (or similar) should update the bounding box
% of the drawing.
% \begin{macrocode}
-\bool_new:N \l_@@_update_bb_bool
+\bool_new:N \l_draw_bb_update_bool
% \end{macrocode}
% \end{variable}
%
@@ -87,47 +87,161 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{variable}{\g_@@_id_int}
+% The drawing number.
+% \begin{macrocode}
+\int_new:N \g_@@_id_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_reset_bb:}
+% A simple auxiliary.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_reset_bb:
+ {
+ \dim_gset:Nn \g_@@_xmax_dim { -\c_max_dim }
+ \dim_gset:Nn \g_@@_xmin_dim { \c_max_dim }
+ \dim_gset:Nn \g_@@_ymax_dim { -\c_max_dim }
+ \dim_gset:Nn \g_@@_ymin_dim { \c_max_dim }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\draw_begin:, \draw_end:}
% Drawings are created by setting them into a box, then adjusting the box
-% before inserting into the surroundings. At present the content is simply
-% collected then dumped: work will be required to manipulate the size as
-% this data becomes more defined. It may be that a coffin construct is
-% better here in the longer term: that may become clearer as the code is
-% completed. Another obvious question is whether/where vertical mode should
-% be ended (\emph{i.e.}~should this behave like a raw |\vbox| or like
-% a coffin). In contrast to \pkg{pgf}, we use a vertical box here: material
-% between explicit instructions should not be present anyway. (Consider
-% adding an |\everypar| hook as done for the \LaTeXe{} preamble.)
+% before inserting into the surroundings. Color is set here using the drawing
+% mechanism largely as it then sets up the internal data structures. It may be
+% that a coffin construct is better here in the longer term: that may become
+% clearer as the code is completed. As we need to avoid any insertion of
+% baseline skips, the outer box here has to be an |hbox|.
% \begin{macrocode}
\cs_new_protected:Npn \draw_begin:
{
- \vbox_set:Nw \l_@@_main_box
- \driver_draw_begin:
- \dim_gset:Nn \g_@@_xmax_dim { -\c_max_dim }
- \dim_gset:Nn \g_@@_xmin_dim { \c_max_dim }
- \dim_gset:Nn \g_@@_ymax_dim { -\c_max_dim }
- \dim_gset:Nn \g_@@_ymin_dim { \c_max_dim }
- \bool_set_true:N \l_@@_update_bb_bool
- \draw_transform_reset:
- \draw_linewidth:n { \l_draw_default_linewidth_dim }
+ \group_begin:
+ \int_gincr:N \g_@@_id_int
+ \hbox_set:Nw \l_@@_main_box
+ \driver_draw_begin:
+ \@@_reset_bb:
+ \@@_path_reset_limits:
+ \bool_set_true:N \l_draw_bb_update_bool
+ \draw_transform_matrix_reset:
+ \draw_transform_shift_reset:
+ \@@_softpath_clear:
+ \draw_linewidth:n { \l_draw_default_linewidth_dim }
+ \draw_color:n { . }
}
\cs_new_protected:Npn \draw_end:
{
- \driver_draw_end:
- \vbox_set_end:
- \hbox_set:Nn \l_@@_main_box
- {
- \skip_horizontal:n { -\g_@@_xmin_dim }
- \box_move_down:nn { \g_@@_ymin_dim }
- { \box_use_drop:N \l_@@_main_box }
- }
- \box_set_ht:Nn \l_@@_main_box
- { \g_@@_ymax_dim - \g_@@_ymin_dim }
- \box_set_dp:Nn \l_@@_main_box { 0pt }
- \box_set_wd:Nn \l_@@_main_box
- { \g_@@_xmax_dim - \g_@@_xmin_dim }
- \mode_leave_vertical:
- \box_use_drop:N \l_@@_main_box
+ \driver_draw_end:
+ \hbox_set_end:
+ \dim_compare:nNnT \g_@@_xmin_dim = \c_max_dim
+ {
+ \dim_gzero:N \g_@@_xmax_dim
+ \dim_gzero:N \g_@@_xmin_dim
+ \dim_gzero:N \g_@@_ymax_dim
+ \dim_gzero:N \g_@@_ymin_dim
+ }
+ \hbox_set:Nn \l_@@_main_box
+ {
+ \skip_horizontal:n { -\g_@@_xmin_dim }
+ \box_move_down:nn { \g_@@_ymin_dim }
+ { \box_use_drop:N \l_@@_main_box }
+ }
+ \box_set_ht:Nn \l_@@_main_box
+ { \g_@@_ymax_dim - \g_@@_ymin_dim }
+ \box_set_dp:Nn \l_@@_main_box { 0pt }
+ \box_set_wd:Nn \l_@@_main_box
+ { \g_@@_xmax_dim - \g_@@_xmin_dim }
+ \mode_leave_vertical:
+ \box_use_drop:N \l_@@_main_box
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Scopes}
+%
+% \begin{variable}{\l_@@_linewidth_dim}
+% \begin{variable}{\l_@@_fill_color_tl, \l_@@_stroke_color_tl}
+% Storage for local variables.
+% \begin{macrocode}
+\dim_new:N \l_@@_linewidth_dim
+\tl_new:N \l_@@_fill_color_tl
+\tl_new:N \l_@@_stroke_color_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{macro}{\draw_scope_begin:, \draw_scope_begin:}
+% As well as the graphics (and \TeX{}) scope, also deal with global
+% data structures.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_scope_begin:
+ {
+ \driver_draw_scope_begin:
+ \group_begin:
+ \dim_set_eq:NN \l_@@_linewidth_dim \g_@@_linewidth_dim
+ \draw_path_scope_begin:
+ }
+\cs_new_protected:Npn \draw_scope_end:
+ {
+ \draw_path_scope_end:
+ \dim_gset_eq:NN \g_@@_linewidth_dim \l_@@_linewidth_dim
+ \group_end:
+ \driver_draw_scope_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}
+% {\l_@@_xmax_dim, \l_@@_xmin_dim, \l_@@_ymax_dim, \l_@@_ymin_dim}
+% Storage for the bounding box.
+% \begin{macrocode}
+\dim_new:N \l_@@_xmax_dim
+\dim_new:N \l_@@_xmin_dim
+\dim_new:N \l_@@_ymax_dim
+\dim_new:N \l_@@_ymin_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_scope_bb_begin:, \@@_scope_bb_end:}
+% The bounding box is simple: a straight group-based save and restore
+% approach.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_scope_bb_begin:
+ {
+ \group_begin:
+ \dim_set_eq:NN \l_@@_xmax_dim \g_@@_xmax_dim
+ \dim_set_eq:NN \l_@@_xmin_dim \g_@@_xmin_dim
+ \dim_set_eq:NN \l_@@_ymax_dim \g_@@_ymax_dim
+ \dim_set_eq:NN \l_@@_ymin_dim \g_@@_ymin_dim
+ \@@_reset_bb:
+ }
+\cs_new_protected:Npn \@@_scope_bb_end:
+ {
+ \dim_gset_eq:NN \g_@@_xmax_dim \l_@@_xmax_dim
+ \dim_gset_eq:NN \g_@@_xmin_dim \l_@@_xmin_dim
+ \dim_gset_eq:NN \g_@@_ymax_dim \l_@@_ymax_dim
+ \dim_gset_eq:NN \g_@@_ymin_dim \l_@@_ymin_dim
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\draw_suspend_begin:, \draw_suspend_end:}
+% Suspend all parts of a drawing.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_suspend_begin:
+ {
+ \@@_scope_bb_begin:
+ \draw_path_scope_begin:
+ \draw_transform_matrix_reset:
+ \draw_transform_shift_reset:
+ }
+\cs_new_protected:Npn \draw_suspend_end:
+ {
+ \draw_path_scope_end:
+ \@@_scope_bb_end:
}
% \end{macrocode}
% \end{macro}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
index f10d7928082..f98083584bd 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-softpath.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -58,6 +58,8 @@
%<@@=draw>
% \end{macrocode}
%
+% \subsection{Managing soft paths}
+%
% 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
@@ -100,6 +102,13 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{variable}{\g_@@_softpath_corners_bool}
+% Allow for optimised path use.
+% \begin{macrocode}
+\bool_new:N \g_@@_softpath_corners_bool
+% \end{macrocode}
+% \end{variable}
+%
% \begin{macro}{\@@_softpath_add:n, \@@_softpath_add:x}
% \begin{macro}{\@@_softpath_concat:n}
% \begin{macro}{\@@_softpath_reset_buffers:}
@@ -155,22 +164,6 @@
% \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.
@@ -186,6 +179,7 @@
\tl_gclear:N \g_@@_softpath_main_tl
\tl_gclear:N \g_@@_softpath_buffer_a_tl
\tl_gclear:N \g_@@_softpath_buffer_b_tl
+ \bool_gset_false:N \g_@@_softpath_corners_bool
}
\cs_new_protected:Npn \@@_softpath_use_clear:
{
@@ -267,6 +261,7 @@
{
\@@_softpath_add:n
{ \@@_softpath_roundpoint_op:nn {#1} {#2} }
+ \bool_gset_true:N \g_@@_softpath_corners_bool
}
\cs_generate_variant:Nn \@@_softpath_roundpoint:nn { VV }
% \end{macrocode}
@@ -290,6 +285,8 @@
% \begin{macro}{\@@_softpath_curveto_opi:nnNnnNnn}
% \begin{macro}{\@@_softpath_rectangle_opi:nnNnn}
% The markers for operations: all the top-level ones take two arguments.
+% The support tokens for curves have to be different in meaning to a
+% round point, hence being quark-like.
% \begin{macrocode}
\cs_new_protected:Npn \@@_softpath_close_op:nn #1#2
{ \driver_draw_closepath: }
@@ -297,8 +294,10 @@
{ \@@_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_curveto_opii:nn #1#2
+ { \@@_softpath_curveto_opii:nn }
+\cs_new_protected:Npn \@@_softpath_curveto_opiii:nn #1#2
+ { \@@_softpath_curveto_opiii:nn }
\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
@@ -314,6 +313,364 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Rounding soft path corners}
+%
+% The aim here is to find corner rounding points and to replace them with
+% arcs of appropriate length. The approach is exactly that in \pkg{pgf}:
+% step through, find the corners, find the supporting data, do the rounding.
+%
+% \begin{variable}{\l_@@_softpath_main_tl}
+% For constructing the updated path.
+% \begin{macrocode}
+\tl_new:N \l_@@_softpath_main_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_softpath_part_tl}
+% Data structures.
+% \begin{macrocode}
+\tl_new:N \l_@@_softpath_part_tl
+\tl_new:N \l_@@_softpath_curve_end_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_@@_softpath_lastx_fp, \l_@@_softpath_lasty_fp}
+% \begin{variable}
+% {\l_@@_softpath_corneri_dim, \l_@@_softpath_cornerii_dim}
+% \begin{variable}{\l_@@_softpath_first_tl, \l_@@_softpath_move_tl}
+% Position tracking: the token list data may be entirely empty or set to
+% a co-ordinate.
+% \begin{macrocode}
+\fp_new:N \l_@@_softpath_lastx_fp
+\fp_new:N \l_@@_softpath_lasty_fp
+\dim_new:N \l_@@_softpath_corneri_dim
+\dim_new:N \l_@@_softpath_cornerii_dim
+\tl_new:N \l_@@_softpath_first_tl
+\tl_new:N \l_@@_softpath_move_tl
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\c_@@_softpath_arc_fp}
+% The magic constant.
+% \begin{macrocode}
+\fp_const:Nn \c_@@_softpath_arc_fp { 4/3 * (sqrt(2) - 1) }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_softpath_round_corners:}
+% \begin{macro}{\@@_softpath_round_loop:Nnn}
+% \begin{macro}{\@@_softpath_round_action:nn}
+% \begin{macro}{\@@_softpath_round_action:Nnn}
+% \begin{macro}{\@@_softpath_round_action_curveto:NnnNnn}
+% \begin{macro}{\@@_softpath_round_action_close:}
+% \begin{macro}{\@@_softpath_round_lookahead:NnnNnn}
+% \begin{macro}{\@@_softpath_round_roundpoint:NnnNnnNnn}
+% \begin{macro}{\@@_softpath_round_calc:nnnNnn}
+% \begin{macro}[EXP]
+% {\@@_softpath_round_calc:nnnnnn, \@@_softpath_round_calc:fVnnnn}
+% \begin{macro}[EXP]{\@@_softpath_round_calc:nnnnw}
+% \begin{macro}{\@@_softpath_round_close:nn}
+% \begin{macro}[EXP]{\@@_softpath_round_close:w}
+% \begin{macro}{\@@_softpath_round_end:}
+% Rounding corners on a path means going through the entire path and
+% adjusting it. As such, we avoid this entirely if we know there are no
+% corners to deal with. Assuming there is work to do, we recover the existing
+% path and start a loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_corners:
+ {
+ \bool_if:NT \g_@@_softpath_corners_bool
+ {
+ \group_begin:
+ \tl_clear:N \l_@@_softpath_main_tl
+ \tl_clear:N \l_@@_softpath_part_tl
+ \fp_zero:N \l_@@_softpath_lastx_fp
+ \fp_zero:N \l_@@_softpath_lasty_fp
+ \tl_clear:N \l_@@_softpath_first_tl
+ \tl_clear:N \l_@@_softpath_move_tl
+ \@@_softpath_concat:n { }
+ \exp_after:wN \@@_softpath_round_loop:Nnn
+ \g_@@_softpath_main_tl
+ \q_recursion_tail ? ?
+ \q_recursion_stop
+ \group_end:
+ }
+ \bool_gset_false:N \g_@@_softpath_corners_bool
+ }
+% \end{macrocode}
+% The loop can take advantage of the fact that all soft path operations are
+% made up of a token followed by two arguments. At this stage, there is
+% a simple split: have we round a round point. If so, is there any actual
+% rounding to be done: if the arcs have come through zero, just ignore it.
+% In cases where we are not at a corner, we simply move along the path,
+% allowing for any new part starting due to a \texttt{moveto}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_loop:Nnn #1#2#3
+ {
+ \quark_if_recursion_tail_stop_do:Nn #1 { \@@_softpath_round_end: }
+ \token_if_eq_meaning:NNTF #1 \@@_softpath_roundpoint_op:nn
+ { \@@_softpath_round_action:nn {#2} {#3} }
+ {
+ \tl_if_empty:NT \l_@@_softpath_first_tl
+ { \tl_set:Nn \l_@@_softpath_first_tl { {#2} {#3} } }
+ \fp_set:Nn \l_@@_softpath_lastx_fp {#2}
+ \fp_set:Nn \l_@@_softpath_lasty_fp {#3}
+ \token_if_eq_meaning:NNTF #1 \@@_softpath_moveto_op:nn
+ {
+ \tl_put_right:No \l_@@_softpath_main_tl
+ \l_@@_softpath_move_tl
+ \tl_put_right:No \l_@@_softpath_main_tl
+ \l_@@_softpath_part_tl
+ \tl_set:Nn \l_@@_softpath_move_tl { #1 {#2} {#3} }
+ \tl_clear:N \l_@@_softpath_first_tl
+ \tl_clear:N \l_@@_softpath_part_tl
+ }
+ { \tl_put_right:Nn \l_@@_softpath_part_tl { #1 {#2} {#3} } }
+ \@@_softpath_round_loop:Nnn
+ }
+ }
+\cs_new_protected:Npn \@@_softpath_round_action:nn #1#2
+ {
+ \dim_set:Nn \l_@@_softpath_corneri_dim {#1}
+ \dim_set:Nn \l_@@_softpath_cornerii_dim {#2}
+ \bool_lazy_and:nnTF
+ { \dim_compare_p:nNn \l_@@_softpath_corneri_dim = { 0pt } }
+ { \dim_compare_p:nNn \l_@@_softpath_cornerii_dim = { 0pt } }
+ { \@@_softpath_round_loop:Nnn }
+ { \@@_softpath_round_action:Nnn }
+ }
+% \end{macrocode}
+% We now have a round point to work on and have grabbed the next item in
+% the path. There are only a few cases where we have to do anything. Each of
+% them is picked up by looking for the appropriate action.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_action:Nnn #1#2#3
+ {
+ \tl_if_empty:NT \l_@@_softpath_first_tl
+ { \tl_set:Nn \l_@@_softpath_first_tl { {#2} {#3} } }
+ \token_if_eq_meaning:NNTF #1 \@@_softpath_curveto_opi:nn
+ { \@@_softpath_round_action_curveto:NnnNnn }
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_softpath_close_op:nn
+ { \@@_softpath_round_action_close: }
+ {
+ \token_if_eq_meaning:NNTF #1 \@@_softpath_lineto_op:nn
+ { \@@_softpath_round_lookahead:NnnNnn }
+ { \@@_softpath_round_loop:Nnn }
+ }
+ }
+ #1 {#2} {#3}
+ }
+% \end{macrocode}
+% For a curve, we collect the two control points then move on to grab the
+% end point and add the curve there: the second control point becomes our
+% starter.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_action_curveto:NnnNnn
+ #1#2#3#4#5#6
+ {
+ \tl_put_right:Nn \l_@@_softpath_part_tl
+ { #1 {#2} {#3} #4 {#5} {#6} }
+ \fp_set:Nn \l_@@_softpath_lastx_fp {#5}
+ \fp_set:Nn \l_@@_softpath_lasty_fp {#6}
+ \@@_softpath_round_lookahead:NnnNnn
+ }
+\cs_new_protected:Npn \@@_softpath_round_action_close:
+ {
+ \bool_lazy_and:nnTF
+ { ! \tl_if_empty_p:N \l_@@_softpath_first_tl }
+ { ! \tl_if_empty_p:N \l_@@_softpath_move_tl }
+ {
+ \exp_after:wN \@@_softpath_round_close:nn
+ \l_@@_softpath_first_tl
+ }
+ { \@@_softpath_round_loop:Nnn }
+ }
+% \end{macrocode}
+% At this stage we have a current (sub)operation (|#1|) and the next
+% operation (|#4|), and can therefore decide whether to round or not.
+% In the case of yet another rounding marker, we have to look a bit
+% further ahead.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_lookahead:NnnNnn #1#2#3#4#5#6
+ {
+ \bool_lazy_any:nTF
+ {
+ { \token_if_eq_meaning_p:NN #4 \@@_softpath_lineto_op:nn }
+ { \token_if_eq_meaning_p:NN #4 \@@_softpath_curveto_opi:nn }
+ { \token_if_eq_meaning_p:NN #4 \@@_softpath_close_op:nn }
+ }
+ {
+ \@@_softpath_round_calc:nnnNnn
+ \@@_softpath_round_loop:Nnn {#5} {#6}
+ }
+ {
+ \token_if_eq_meaning:NNTF #4 \@@_softpath_roundpoint_op:nn
+ { \@@_softpath_round_roundpoint:NnnNnnNnn }
+ { \@@_softpath_round_loop:Nnn }
+ }
+ #1 {#2} {#3}
+ #4 {#5} {#6}
+ }
+\cs_new_protected:Npn \@@_softpath_round_roundpoint:NnnNnnNnn
+ #1#2#3#4#5#6#7#8#9
+ {
+ \@@_softpath_round_calc:nnnNnn
+ \@@_softpath_round_loop:Nnn
+ {#8} {#9} #1 {#2} {#3}
+ #4 {#5} {#6} #7 {#8} {#9}
+ }
+% \end{macrocode}
+% We now have all of the data needed to construct a rounded corner: all that
+% is left to do is to work out the detail! At this stage, we have details
+% of where the corner itself is (|#4|, |#5|), and where the next point is
+% (|#1|, |#2|). There are two types of calculations to do. First, we
+% need to interpolate from those two points in the direction of the
+% corner, in order to work out where the curve we are adding will start
+% and end. From those, plus the points we already have, we work out where
+% the control points will lie. All of this is done in an expansion to
+% avoid multiple calls to |\tl_put_right:Nx|. The end point of the line
+% is worked out up-front and saved: we need that if dealing with a
+% close-path operation.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_calc:nnnNnn #1#2#3#4#5#6
+ {
+ \tl_set:Nx \l_@@_softpath_curve_end_tl
+ {
+ \draw_point_interpolate_distance:nnn
+ \l_@@_softpath_cornerii_dim
+ { #5 , #6 } { #2 , #3 }
+ }
+ \tl_put_right:Nx \l_@@_softpath_part_tl
+ {
+ \exp_not:N #4
+ \@@_softpath_round_calc:fVnnnn
+ {
+ \draw_point_interpolate_distance:nnn
+ \l_@@_softpath_corneri_dim
+ { #5 , #6 }
+ {
+ \l_@@_softpath_lastx_fp ,
+ \l_@@_softpath_lasty_fp
+ }
+ }
+ \l_@@_softpath_curve_end_tl
+ {#5} {#6} {#2} {#3}
+ }
+ \fp_set:Nn \l_@@_softpath_lastx_fp {#5}
+ \fp_set:Nn \l_@@_softpath_lasty_fp {#6}
+ #1
+ }
+% \end{macrocode}
+% At this stage we have the two curve end points, but they are in
+% co-ordinate form. So we split them up (with some more reordering).
+% \begin{macrocode}
+\cs_new:Npn \@@_softpath_round_calc:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_softpath_round_calc:nnnnw {#3} {#4} {#5} {#6}
+ #1 \q_mark #2 \q_stop
+ }
+\cs_generate_variant:Nn \@@_softpath_round_calc:nnnnnn { fV }
+% \end{macrocode}
+% The calculations themselves are relatively straight-forward, as we use a
+% quadratic Bézier curve.
+% \begin{macrocode}
+\cs_new:Npn \@@_softpath_round_calc:nnnnw
+ #1#2#3#4 #5 , #6 \q_mark #7 , #8 \q_stop
+ {
+ {#5} {#6}
+ \exp_not:N \@@_softpath_curveto_opi:nn
+ {
+ \fp_to_dim:n
+ { #5 + \c_@@_softpath_arc_fp * ( #1 - #5 ) }
+ }
+ {
+ \fp_to_dim:n
+ { #6 + \c_@@_softpath_arc_fp * ( #2 - #6 ) }
+ }
+ \exp_not:N \@@_softpath_curveto_opii:nn
+ {
+ \fp_to_dim:n
+ { #7 + \c_@@_softpath_arc_fp * ( #1 - #7 ) }
+ }
+ {
+ \fp_to_dim:n
+ { #8 + \c_@@_softpath_arc_fp* ( #2 - #8 ) }
+ }
+ \exp_not:N \@@_softpath_curveto_opiii:nn
+ {#7} {#8}
+ }
+% \end{macrocode}
+% To deal with a close-path operation, we need to do some manipulation.
+% It needs to be treated as a line operation for rounding, and then
+% have the close path operation re-added at the point where the curve
+% ends. That means saving the end point in the calculation step (see
+% earlier), and shuffling a lot.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_close:nn #1#2
+ {
+ \use:x
+ {
+ \@@_softpath_round_calc:nnnNnn
+ {
+ \tl_set:Nx \exp_not:N \l_@@_softpath_move_tl
+ {
+ \@@_softpath_moveto_op:nn
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_softpath_round_close:w
+ \exp_not:N \l_@@_softpath_curve_end_tl
+ \exp_not:N \q_stop
+ }
+ \use:x
+ {
+ \exp_not:N \exp_not:N \exp_not:N \use_i:nnnn
+ {
+ \@@_softpath_round_loop:Nnn
+ \@@_softpath_close_op:nn
+ \exp_not:N \exp_after:wN
+ \exp_not:N \@@_softpath_round_close:w
+ \exp_not:N \l_@@_softpath_curve_end_tl
+ \exp_not:N \q_stop
+ }
+ }
+ }
+ {#1} {#2}
+ \@@_softpath_lineto_op:nn
+ \exp_after:wN \use_none:n \l_@@_softpath_move_tl
+ }
+ }
+\cs_new:Npn \@@_softpath_round_close:w #1 , #2 \q_stop { {#1} {#2} }
+% \end{macrocode}
+% Tidy up the parts of the path, complete the built token list and put
+% it back into action.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_softpath_round_end:
+ {
+ \tl_put_right:No \l_@@_softpath_main_tl
+ \l_@@_softpath_move_tl
+ \tl_put_right:No \l_@@_softpath_main_tl
+ \l_@@_softpath_part_tl
+ \tl_gset_eq:NN \g_@@_softpath_main_tl \l_@@_softpath_main_tl
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
index 5e6eb424d05..4c6bade4569 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-state.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -94,7 +94,7 @@
% Pass through to the driver layer.
% \begin{macrocode}
\cs_new_protected:Npn \draw_miterlimit:n #1
- { \driver_draw_miterlimit:n { \fp_to_dim:n {#1} } }
+ { \driver_draw_miterlimit:n { \fp_eval:n {#1} } }
% \end{macrocode}
% \end{macro}
%
@@ -124,14 +124,6 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\g_@@_fill_color_tl, \g_@@_stroke_color_tl}
-% For tracking.
-% \begin{macrocode}
-\tl_new:N \g_@@_fill_color_tl
-\tl_new:N \g_@@_stroke_color_tl
-% \end{macrocode}
-% \end{variable}
-%
% \begin{macro}{\draw_color:n, \draw_color_fill:n, \draw_color_stroke:n}
% \begin{macro}{\@@_color:nn}
% \begin{macro}{\@@_color_aux:nn, \@@_color_aux:Vn}
@@ -144,8 +136,7 @@
% Much the same as for core color support but calling the relevant
% driver-level function.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_color:n #1
- { \@@_color:nn { } {#1} }
+\cs_new_eq:NN \draw_color:n \color_select:n
\cs_new_protected:Npn \draw_color_fill:n #1
{ \@@_color:nn { fill } {#1} }
\cs_new_protected:Npn \draw_color_stroke:n #1
@@ -153,16 +144,7 @@
\cs_new_protected:Npn \@@_color:nn #1#2
{
\color_parse:nN {#2} \l_@@_color_tmp_tl
- \tl_if_blank:nTF {#1}
- {
- \tl_gset_eq:NN \g_@@_fill_color_tl \l_@@_color_tmp_tl
- \tl_gset_eq:NN \g_@@_stroke_color_tl \l_@@_color_tmp_tl
- \@@_color_aux:Vn \l_@@_color_tmp_tl { color }
- }
- {
- \tl_gset_eq:cN { g_@@_ #1 _color_tl } \l_@@_color_tmp_tl
- \@@_color_aux:Vn \l_@@_color_tmp_tl { #1 }
- }
+ \@@_color_aux:Vn \l_@@_color_tmp_tl {#1}
}
\cs_new_protected:Npn \@@_color_aux:nn #1#2
{ \@@_color:nw {#2} #1 \q_stop }
@@ -170,13 +152,13 @@
\cs_new_protected:Npn \@@_color:nw #1#2 ~ #3 \q_stop
{ \use:c { @@_color_ #2 :nw } {#1} #3 \q_stop }
\cs_new_protected:Npn \@@_color_cmyk:nw #1#2 ~ #3 ~ #4 ~ #5 \q_stop
- { \use:c { driver_draw_ #1 _cmyk:nnnn } {#2} {#3} {#4} {#5} }
+ { \use:c { driver_draw_color_ #1 _cmyk:nnnn } {#2} {#3} {#4} {#5} }
\cs_new_protected:Npn \@@_color_gray:nw #1#2 \q_stop
- { \use:c { driver_draw_ #1 _gray:n } {#2} }
+ { \use:c { driver_draw_color_ #1 _gray:n } {#2} }
\cs_new_protected:Npn \@@_color_rgb:nw #1#2 ~ #3 ~ #4 \q_stop
- { \use:c { driver_draw_ #1 _rgb:nnn } {#2} {#3} {#4} }
+ { \use:c { driver_draw_color_ #1 _rgb:nnn } {#2} {#3} {#4} }
\cs_new_protected:Npn \@@_color_spot:nw #1#2 ~ #3 \q_stop
- { \use:c { driver_draw_ #1 _spot:nn } {#2} {#3} }
+ { \use:c { driver_draw_color_ #1 _spot:nn } {#2} {#3} }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
index 4f325f01092..9b1478b48b7 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw-transforms.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -58,149 +58,159 @@
%<@@=draw>
% \end{macrocode}
%
-% \begin{variable}{\l_@@_transformcm_active_bool}
+% This sub-module covers more-or-less the same ideas as
+% \texttt{pgfcoretransformations.code.tex}. At present, equivalents of the
+% following are currently absent:
+% \begin{itemize}
+% \item \cs{pgfgettransform}, \cs{pgfgettransformentries}: Awaiting use cases.
+% \item \cs{pgftransformlineattime}, \cs{pgftransformarcaxesattime},
+% \cs{pgftransformcurveattime}: Need to look at the use cases for
+% these to fully understand them.
+% \item \cs{pgftransformarrow}: Likely to be done when other arrow functions
+% are added.
+% \item \cs{pgflowlevelsynccm}, \cs{pgflowlevel}: Likely to be added when
+% use cases are encountered in other parts of the code.
+% \end{itemize}
+%
+% \begin{variable}{\l_@@_matrix_active_bool}
% An internal flag to avoid redundant calculations.
% \begin{macrocode}
-\bool_new:N \l_@@_transformcm_active_bool
+\bool_new:N \l_@@_matrix_active_bool
% \end{macrocode}
% \end{variable}
%
% \begin{variable}
% {
-% \l_@@_transformcm_aa_fp, \l_@@_transformcm_ab_fp,
-% \l_@@_transformcm_ba_fp, \l_@@_transformcm_aa_fp,
-% \l_@@_transformcm_xshift_dim,
-% \l_@@_transformcm_yshift_dim
+% \l_@@_matrix_a_fp,
+% \l_@@_matrix_b_fp,
+% \l_@@_matrix_c_fp,
+% \l_@@_matrix_a_fp,
+% \l_@@_xshift_dim,
+% \l_@@_yshift_dim
% }
-% The active matrix itself.
+% The active matrix and shifts.
% \begin{macrocode}
-\fp_new:N \l_@@_transformcm_aa_fp
-\fp_new:N \l_@@_transformcm_ab_fp
-\fp_new:N \l_@@_transformcm_ba_fp
-\fp_new:N \l_@@_transformcm_bb_fp
-\dim_new:N \l_@@_transformcm_xshift_dim
-\dim_new:N \l_@@_transformcm_yshift_dim
+\fp_new:N \l_@@_matrix_a_fp
+\fp_new:N \l_@@_matrix_b_fp
+\fp_new:N \l_@@_matrix_c_fp
+\fp_new:N \l_@@_matrix_d_fp
+\dim_new:N \l_@@_xshift_dim
+\dim_new:N \l_@@_yshift_dim
% \end{macrocode}
% \end{variable}
%
-% \begin{macro}{\draw_transform_reset:}
+% \begin{macro}{\draw_transform_matrix_reset:, \draw_transform_shift_reset:}
% Fast resetting.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_transform_reset:
+\cs_new_protected:Npn \draw_transform_matrix_reset:
+ {
+ \fp_set:Nn \l_@@_matrix_a_fp { 1 }
+ \fp_zero:N \l_@@_matrix_b_fp
+ \fp_zero:N \l_@@_matrix_c_fp
+ \fp_set:Nn \l_@@_matrix_d_fp { 1 }
+ }
+\cs_new_protected:Npn \draw_transform_shift_reset:
{
- \fp_set:Nn \l_@@_transformcm_aa_fp { 1}
- \fp_zero:N \l_@@_transformcm_ab_fp
- \fp_zero:N \l_@@_transformcm_ba_fp
- \fp_set:Nn \l_@@_transformcm_bb_fp { 1 }
- \dim_zero:N \l_@@_transformcm_xshift_dim
- \dim_zero:N \l_@@_transformcm_yshift_dim
+ \dim_zero:N \l_@@_xshift_dim
+ \dim_zero:N \l_@@_yshift_dim
}
-\draw_transform_reset:
+\draw_transform_matrix_reset:
+\draw_transform_shift_reset:
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\draw_transform:nnnnn}
-% \begin{macro}{\@@_transform:nnnnnnn}
+% \begin{macro}{\draw_transform_matrix:nnnn}
+% \begin{macro}{\draw_transform_shift:n}
+% \begin{macro}{\@@_transform_shift:nn}
% Setting the transform matrix is straight-forward, with just a bit
% of expansion to sort out. With the mechanism active, the identity
% matrix is set.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_transform:nnnnn #1#2#3#4#5
+\cs_new_protected:Npn \draw_transform_matrix:nnnn #1#2#3#4
{
- \@@_point_process:nn
- { \@@_transform:nnnnnnn {#1} {#2} {#3} {#4} }
- {#5}
- }
-\cs_new_protected:Npn \@@_transform:nnnnnnn #1#2#3#4#5#6
- {
- \fp_set:Nn \l_@@_transformcm_aa_fp {#1}
- \fp_set:Nn \l_@@_transformcm_ab_fp {#2}
- \fp_set:Nn \l_@@_transformcm_ba_fp {#3}
- \fp_set:Nn \l_@@_transformcm_bb_fp {#4}
- \dim_set:Nn \l_@@_transformcm_xshift_dim {#5}
- \dim_set:Nn \l_@@_transformcm_yshift_dim {#6}
+ \fp_set:Nn \l_@@_matrix_a_fp {#1}
+ \fp_set:Nn \l_@@_matrix_b_fp {#2}
+ \fp_set:Nn \l_@@_matrix_c_fp {#3}
+ \fp_set:Nn \l_@@_matrix_d_fp {#4}
\bool_lazy_all:nTF
{
- { \fp_compare_p:nNn \l_@@_transformcm_aa_fp = \c_one_fp }
- { \fp_compare_p:nNn \l_@@_transformcm_ab_fp = \c_zero_fp }
- { \fp_compare_p:nNn \l_@@_transformcm_ba_fp = \c_zero_fp }
- { \fp_compare_p:nNn \l_@@_transformcm_bb_fp = \c_one_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_a_fp = \c_one_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_b_fp = \c_zero_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_c_fp = \c_zero_fp }
+ { \fp_compare_p:nNn \l_@@_matrix_d_fp = \c_one_fp }
}
- { \bool_set_false:N \l_@@_transformcm_active_bool }
- { \bool_set_true:N \l_@@_transformcm_active_bool }
+ { \bool_set_false:N \l_@@_matrix_active_bool }
+ { \bool_set_true:N \l_@@_matrix_active_bool }
+ }
+\cs_new_protected:Npn \draw_transform_shift:n #1
+ {
+ \@@_point_process:nn
+ { \@@_transform_shift:nn } {#1}
+ }
+\cs_new_protected:Npn \@@_transform_shift:nn #1#2
+ {
+ \dim_set:Nn \l_@@_xshift_dim {#1}
+ \dim_set:Nn \l_@@_yshift_dim {#2}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\draw_transform_concat:nnnnn}
-% \begin{macro}{\@@_transform_concat:nnnnnn}
-% \begin{macro}{\@@_transform_concat_aux:nnnnnn}
-% Much the same story for adding to an existing matrix. The part that is more
-% complex is the calculations required: everything gets passed back to
-% \cs{@@_transform_set:nnnnnn}, with pre-expansion just in case there are
-% \emph{e.g}~random values. The final step is \texttt{x}-type expanded as
-% otherwise later values affect earlier ones.
+% \begin{macro}{\draw_transform_matrix_concat:nnnn}
+% \begin{macro}{\@@_transform_concat:nnnn}
+% \begin{macro}{\draw_transform_shift_concat:n}
+% \begin{macro}{\@@_transform_shift_concat:nn}
+% Much the same story for adding to an existing matrix, with a bit of
+% pre-expansion so that the calculation uses \enquote{frozen} values.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_transform_concat:nnnnn #1#2#3#4#5
- {
- \@@_point_process:nn
- { \@@_transform_concat:nnnnnn {#1} {#2} {#3} {#4} }
- {#5}
- }
-\cs_new_protected:Npn \@@_transform_concat:nnnnnn #1#2#3#4#5#6
+\cs_new_protected:Npn \draw_transform_matrix_concat:nnnn #1#2#3#4
{
\use:x
{
- \@@_transform_concat_aux:nnnnnn
+ \@@_transform_concat:nnnn
{ \fp_eval:n {#1} }
{ \fp_eval:n {#2} }
{ \fp_eval:n {#3} }
{ \fp_eval:n {#4} }
- {#5}
- {#6}
}
}
-\cs_new_protected:Npn \@@_transform_concat_aux:nnnnnn #1#2#3#4#5#6
+\cs_new_protected:Npn \@@_transform_concat:nnnn #1#2#3#4
{
\use:x
{
- \@@_transform:nnnnnnn
- { #1 * \l_@@_transformcm_aa_fp + #2 * \l_@@_transformcm_ba_fp }
- { #1 * \l_@@_transformcm_ab_fp + #2 * \l_@@_transformcm_bb_fp }
- { #3 * \l_@@_transformcm_aa_fp + #4 * \l_@@_transformcm_ba_fp }
- { #3 * \l_@@_transformcm_ab_fp + #4 * \l_@@_transformcm_bb_fp }
- {
- \fp_to_dim:n
- {
- \l_@@_transformcm_xshift_dim
- + \l_@@_transformcm_aa_fp * #5
- + \l_@@_transformcm_ba_fp * #6
- }
- }
- {
- \fp_to_dim:n
- {
- \l_@@_transformcm_yshift_dim
- + \l_@@_transformcm_ab_fp * #5
- + \l_@@_transformcm_bb_fp * #6
- }
- }
+ \draw_transform_matrix:nnnn
+ { #1 * \l_@@_matrix_a_fp + #2 * \l_@@_matrix_c_fp }
+ { #1 * \l_@@_matrix_b_fp + #2 * \l_@@_matrix_d_fp }
+ { #3 * \l_@@_matrix_a_fp + #4 * \l_@@_matrix_c_fp }
+ { #3 * \l_@@_matrix_b_fp + #4 * \l_@@_matrix_d_fp }
}
}
+\cs_new_protected:Npn \draw_transform_shift_concat:n #1
+ {
+ \@@_point_process:nn
+ { \@@_transform_shift_concat:nn } {#1}
+ }
+\cs_new_protected:Npn \@@_transform_shift_concat:nn #1#2
+ {
+ \dim_set:Nn \l_@@_xshift_dim { \l_@@_xshift_dim + #1 }
+ \dim_set:Nn \l_@@_yshift_dim { \l_@@_yshift_dim + #2 }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\draw_transform_invert:}
+% \begin{macro}{\draw_transform_matrix_invert:}
% \begin{macro}{\@@_transform_invert:n, \@@_transform_invert:f}
+% \begin{macro}{\draw_transform_shift_invert:}
% Standard mathematics: calculate the inverse matrix and use that, then
% undo the shifts.
% \begin{macrocode}
-\cs_new_protected:Npn \draw_transform_invert:
+\cs_new_protected:Npn \draw_transform_matrix_invert:
{
- \bool_if:NT \l_@@_transformcm_active_bool
+ \bool_if:NT \l_@@_matrix_active_bool
{
\@@_transform_invert:f
{
@@ -208,44 +218,34 @@
{
1 /
(
- \l_@@_transformcm_aa_fp * \l_@@_transformcm_bb_fp
- - \l_@@_transformcm_ab_fp * \l_@@_transformcm_ba_fp
+ \l_@@_matrix_a_fp * \l_@@_matrix_d_fp
+ - \l_@@_matrix_b_fp * \l_@@_matrix_c_fp
)
}
}
}
- \dim_set:Nn \l_@@_transformcm_xshift_dim
- {
- \fp_to_dim:n
- {
- -\l_@@_transformcm_xshift_dim * \l_@@_transformcm_aa_fp
- -\l_@@_transformcm_yshift_dim * \l_@@_transformcm_ba_fp
- }
- }
- \dim_set:Nn \l_@@_transformcm_yshift_dim
- {
- \fp_to_dim:n
- {
- -\l_@@_transformcm_xshift_dim * \l_@@_transformcm_ab_fp
- -\l_@@_transformcm_yshift_dim * \l_@@_transformcm_bb_fp
- }
- }
}
\cs_new_protected:Npn \@@_transform_invert:n #1
{
- \fp_set:Nn \l_@@_transformcm_aa_fp
- { \l_@@_transformcm_bb_fp * #1 }
- \fp_set:Nn \l_@@_transformcm_ab_fp
- { -\l_@@_transformcm_ab_fp * #1 }
- \fp_set:Nn \l_@@_transformcm_ba_fp
- { -\l_@@_transformcm_ba_fp * #1 }
- \fp_set:Nn \l_@@_transformcm_bb_fp
- { \l_@@_transformcm_aa_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_a_fp
+ { \l_@@_matrix_d_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_b_fp
+ { -\l_@@_matrix_b_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_c_fp
+ { -\l_@@_matrix_c_fp * #1 }
+ \fp_set:Nn \l_@@_matrix_d_fp
+ { \l_@@_matrix_a_fp * #1 }
}
\cs_generate_variant:Nn \@@_transform_invert:n { f }
+\cs_new_protected:Npn \draw_transform_shift_invert:
+ {
+ \dim_set:Nn \l_@@_xshift_dim { -\l_@@_xshift_dim }
+ \dim_set:Nn \l_@@_yshift_dim { -\l_@@_yshift_dim }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\draw_transform_triangle:nnn}
% Simple maths to move the canvas origin to |#1| and the two axes to
@@ -265,18 +265,69 @@
{
\use:x
{
- \@@_transform:nnnnnnn
+ \draw_transform_matrix:nnnn
{ #3 - #1 }
{ #4 - #2 }
{ #5 - #1 }
{ #6 - #2 }
- {#1}
- {#2}
+ \draw_transform_shift:n { #1 , #2 }
}
}
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}
+% {\draw_transform_scale:n, \draw_transform_xscale:n, \draw_transform_yscale:n}
+% \begin{macro}
+% {\draw_transform_xshift:n, \draw_transform_yshift:n}
+% \begin{macro}
+% {\draw_transform_xslant:n, \draw_transform_yslant:n}
+% Lots of shortcuts.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_scale:n #1
+ { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { #1 } }
+\cs_new_protected:Npn \draw_transform_xscale:n #1
+ { \draw_transform_matrix_concat:nnnn { #1 } { 0 } { 0 } { 1 } }
+\cs_new_protected:Npn \draw_transform_yscale:n #1
+ { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { 0 } { #1 } }
+\cs_new_protected:Npn \draw_transform_xshift:n #1
+ { \draw_transform_shift_concat:n { #1 , 0 } }
+\cs_new_protected:Npn \draw_transform_yshift:n #1
+ { \draw_transform_shift_concat:n { 0 , #1 } }
+\cs_new_protected:Npn \draw_transform_xslant:n #1
+ { \draw_transform_matrix_concat:nnnn { 1 } { 0 } { #1 } { 1 } }
+\cs_new_protected:Npn \draw_transform_yslant:n #1
+ { \draw_transform_matrix_concat:nnnn { 1 } { #1 } { 0 } { 1 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\draw_transform_rotate:n}
+% \begin{macro}
+% {
+% \@@_transform_rotate:n, \@@_transform_rotate:f,
+% \@@_transform_rotate:nn, \@@_transform_rotate:ff
+% }
+% Slightly more involved: evaluate the angle only once, and the sine and
+% cosine only once.
+% \begin{macrocode}
+\cs_new_protected:Npn \draw_transform_rotate:n #1
+ { \@@_transform_rotate:f { \fp_eval:n {#1} } }
+\cs_new_protected:Npn \@@_transform_rotate:n #1
+ {
+ \@@_transform_rotate:ff
+ { \fp_eval:n { cosd(#1) } }
+ { \fp_eval:n { sind(#1) } }
+ }
+\cs_generate_variant:Nn \@@_transform_rotate:n { f }
+\cs_new_protected:Npn \@@_transform_rotate:nn #1#2
+ { \draw_transform_matrix_concat:nnnn {#1} {#2} { -#2 } { #1 } }
+\cs_generate_variant:Nn \@@_transform_rotate:nn { ff }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
index 9b7c04d5e54..7cefc6d837d 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.dtx
@@ -25,6 +25,71 @@
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
+\usepackage[utf8]{inputenc}
+\usepackage{l3draw}
+% For creating code demonstrations
+% This needs access to some code-level interfaces in listings
+\usepackage{listings}
+\makeatletter
+\lst@RequireAspects{writefile}
+\newsavebox\demo@box
+\lstnewenvironment{demo}[1][code and example]
+ {%
+ \global\let\lst@intname\@empty
+ \edef\demo@end{%
+ \expandafter\noexpand\csname demo@@#1@end\endcsname
+ }%
+ \@nameuse{demo@@#1}%
+ }
+ {\demo@end}
+\newcommand\demo@new[3]{%
+ \@namedef{demo@@#1}{#2}%
+ \@namedef{demo@@#1@end}{#3}%
+}
+\newcommand*\demo@common{%
+ \setkeys{lst}
+ {%
+ basicstyle = \small\ttfamily,
+ basewidth = 0.51em,
+ gobble = 5,
+ language = [LaTeX]{TeX},
+ }%
+}
+\newcommand*\demo@input{%
+ \ExplSyntaxOn
+ \catcode`\^^M = 10\relax
+ \catcode`\% = 14\relax
+ \input{\jobname.tmp}%
+ \ExplSyntaxOff
+}
+\demo@new{code and example}{%
+ \setbox\demo@box=\hbox\bgroup
+ \lst@BeginAlsoWriteFile{\jobname.tmp}%
+ \demo@common
+}{%
+ \lst@EndWriteFile
+ \egroup
+ \begin{center}
+ \ifdim\wd\demo@box > 0.75\linewidth
+ \begin{minipage}{\linewidth}
+ \usebox\demo@box
+ \end{minipage}%
+ \par
+ \begin{minipage}{\linewidth}
+ \demo@input
+ \end{minipage}
+ \else
+ \begin{minipage}{0.25\linewidth}
+ \demo@input
+ \end{minipage}%
+ \hfil
+ \begin{minipage}{0.75\linewidth}
+ \usebox\demo@box
+ \end{minipage}%
+ \fi
+ \end{center}
+}
+\makeatother
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
@@ -44,7 +109,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -82,6 +147,64 @@
% The drawing created within the environment will be inserted into
% the typesetting stream by the \cs{draw_end:} function, which will
% switch out of vertical mode if required.
+% \begin{demo}
+% \dim_new:N \l_mypos_dim
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , \l_mypos_dim }
+% \draw_path_lineto:n { 1cm , \l_mypos_dim }
+% \dim_set:Nn \l_mypos_dim { 1cm }
+% \draw_path_lineto:n { 1cm , \l_mypos_dim }
+% \draw_path_close:
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+%
+% Within a drawing, the only commands that should appear are those directly
+% aimed at drawing (from \pkg{l3draw}) and those which produce \emph{no}
+% typeset output. For example, it is possible to include loops inside a
+% drawing using |\int_step_function:nnnn| or similar. On the other hand,
+% text should not be included directly in drawings, but should rather be
+% inserted using the appropriate \pkg{l3draw} command.
+% \end{function}
+%
+% Within a drawing, there are different ways of referring to a position.
+% The co-ordinates of a point are given relative to the current
+% \emph{drawing axes}. These can be manipulated and tracked at the code
+% level. Underlying this is the \meta{canvas}, which is at the \pkg{draw}
+% level essentially fixed and in line with the paper. Initially, the two
+% sets of axes are coincident. (It is possible to manipulate the canvas
+% axes at the driver level: this is then \enquote{transparent} to the
+% \pkg{draw} level, and so should be used only when strictly required.)
+%
+% \begin{function}{\draw_suspend_begin:, \draw_suspend_end:}
+% \begin{syntax}
+% \cs{draw_suspend_begin:}
+% ...
+% \cs{draw_suspend_end:}
+% \end{syntax}
+% Suspends all of the drawing mechanisms to allow \enquote{normal}
+% material to be created. Typically, this environment will be applied
+% inside a box which may contain nested pictures.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \hbox_set:Nn \l_tmpa_box
+% {
+% \draw_suspend_begin:
+% This~is~normal~text.
+% \draw_begin: % A subpicture
+% \draw_path_moveto:n { 1cm , 0cm }
+% \draw_path_lineto:n { 1cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% More~text.
+% \draw_suspend_end:
+% }
+% \draw_box_use:N \l_tmpa_box
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \subsection{Graphics state}
@@ -90,10 +213,10 @@
% will appear. Note that these all apply \emph{globally}, though some are
% rest at the start of each drawing (\cs{draw_begin:}).
%
-% \begin{function}{\g_draw_linewidth_default_dim}
+% \begin{variable}{\g_draw_linewidth_default_dim}
% The default value of the linewidth for stokes, set at the start
% of every drawing (\cs{draw_begin:}).
-% \end{function}
+% \end{variable}
%
% \begin{function}{\draw_linewidth:n, \draw_inner_linewidth:n}
% \begin{syntax}
@@ -140,10 +263,54 @@
%
% \begin{function}{\draw_miterlimit:n}
% \begin{syntax}
-% \cs{draw_miterlimit:n} \Arg{limit}
+% \cs{draw_miterlimit:n} \Arg{factor}
% \end{syntax}
-% Sets the miter \meta{limit} of lines joined as a miter, as described in the
-% PDF and PostScript manuals. The \meta{limit} is an \meta{fp expr}.
+% Sets the miter \meta{factor} of lines joined as a miter, as described in the
+% PDF and PostScript manuals. The \meta{factor} is an \meta{fp expr}.
+% \end{function}
+%
+% \subsection{Scoping drawing elements}
+%
+% Scoping drawing elements is necessary to allowing nesting of subparts.
+% These features have specific use requirements: the preconditions must be
+% met. In particular, each type of drawing scope also constitutes a
+% group (\cs{groupd_being:}/\cs{group_end:} pair): as such, they must be
+% nested correctly.
+%
+% \begin{function}{\draw_scope_begin:, \draw_scope_end:}
+% \begin{syntax}
+% \cs{draw_scope_begin:}
+% ...
+% \cs{draw_scope_end:}
+% \end{syntax}
+% Creates a scope for localisation of state settings within a drawing.
+% A scope forms a \TeX{} group but will also localise global state
+% variables (such as \cs{g_draw_linewidth_default_dim}), and driver-level
+% concepts such as the termination of lines.
+% \begin{demo}
+% \draw_begin:
+% \draw_scope_begin:
+% \group_begin:
+% \draw_linewidth:n { 2pt }
+% \draw_path_rectangle:nn { 0 , 0 } { 2ex , 2ex }
+% \draw_path_use:n { stroke }
+% \group_end:
+% \draw_path_rectangle:nn { 3ex , 0ex } { 2ex , 2ex }
+% \draw_path_use:n { stroke }
+% \draw_scope_end:
+% \draw_path_rectangle:nn { 6ex , 0ex } { 2ex , 2ex }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+% Global graphical concepts restricted by scope are
+% \begin{itemize}
+% \item Line width
+% \item Stroke and fill color
+% \item Dash pattern
+% \item Line joining and capping, including the miter limit
+% \item Clipping paths
+% \item Canvas (driver) transformations
+% \end{itemize}
% \end{function}
%
% \subsection{Points}
@@ -180,7 +347,7 @@
% higher-level functions, for example path construction, and allows parts of
% a drawing to be rotated, scaled or skewed. This occurs before writing any
% data to the driver, and so such manipulations are tracked by the drawing
-% mechanisms. See \cs{driver_draw_transformcm:nnnnnn} for driver-level
+% mechanisms. See \cs{driver_draw_cm:nnnn} for driver-level
% manipulation of the canvas axes themselves.
%
% Notice that in contrast to \pkg{pgf} it is possible to give the positions
@@ -235,8 +402,8 @@
% \begin{syntax}
% \cs{draw_point_unit_vector:n} \Arg{point}
% \end{syntax}
-% Expands to the co-ordinates of a unit vector joining the \meta{point}
-% with the origin.
+% Expands to the co-ordinates of a unit vector in the direction of the
+% \meta{point} from the origin.
% \end{function}
%
% \begin{function}[EXP]{\draw_point_transform:n}
@@ -255,9 +422,9 @@
% co-incident with the standard Cartesian axes, but may be altered by
% the user.
%
-% \begin{function}{\draw_xvec_set:n, \draw_yvec_set:n, \draw_zvec_set:n}
+% \begin{function}{\draw_xvec:n, \draw_yvec:n, \draw_zvec:n}
% \begin{syntax}
-% \cs{draw_xvec_set:n} \Arg{point}
+% \cs{draw_xvec:n} \Arg{point}
% \end{syntax}
% Defines the appropriate base vector to point toward the \meta{point}
% on the canvas. The standard settings for the $x$- and $y$-vectors are
@@ -358,16 +525,86 @@
% manipulated or indeed discarded entirely. Only one path is active at
% any one time, and the path is \emph{not} affected by \TeX{} grouping.
%
-% \begin{function}{\draw_path_corner_arc:n}
+% \begin{function}{\draw_path_corner_arc:nn}
+% \begin{syntax}
+% \cs{draw_path_corner_arc:n} \Arg{length1} \Arg{length2}
+% \end{syntax}
+% Sets the degree of rounding applied to corners in a path: the two
+% \meta{length} values are the distances from the corner at which the curving
+% should start. The first \meta{length} applies to the part of the path
+% \enquote{leading in} to the corner (\emph{i.e.}~from the previous path
+% operation), and the second to that \enquote{leading out}. If both
+% values are \texttt{0pt} then corners will not be rounded. The values
+% apply within the scope of the current \TeX{} group.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_corner_arc:nn { 5mm } { 5mm }
+% \draw_path_rectangle_corners:nn
+% { 0cm , 0cm } { 3cm , 2cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+% \begin{demo}
+% \draw_begin:
+% \draw_path_corner_arc:nn { 10mm } { 5mm }
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 2cm }
+% \draw_path_lineto:n { 3cm , 2cm }
+% \draw_path_curveto:nnn
+% { 3cm , 0cm } { 2cm , 0cm } { 1cm , 0 cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+% The corners created are quarter-circles for exact right-angles and
+% close approximations otherwise. Closing a path will result in rounding
+% correctly.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_corner_arc:nn { 4pt } { 4pt }
+% \draw_path_moveto:n
+% { \draw_point_polar:nn { 0 } { 1cm } }
+% \int_step_inline:nnnn { 72 } { 72 } { 359 }
+% {
+% \draw_path_lineto:n
+% { \draw_point_polar:nn { #1 } { 1cm } }
+% }
+% \draw_path_close:
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+% \end{function}
+%
+% \begin{function}{\draw_path_close:}
% \begin{syntax}
-% \cs{draw_path_corner_arc:n} \Arg{length}
+% \cs{draw_path_close:}
% \end{syntax}
-% Sets the degree of rounding applied to corners in a path: if the
-% \meta{length} is \texttt{0pt} then no rounding applies. The value of the
-% \meta{length} is local to the current \TeX{} group. \emph{At present,
-% corner arcs are not activated in the code.}
+% Closes the current part of the path by appending a straight line from
+% the current point to the starting point of the path. In general, any
+% path to be \emph{filled} should include a close instructions.
% \end{function}
%
+% \begin{function}{\draw_path_use:n, \draw_path_use_clear:n}
+% \begin{syntax}
+% \cs{draw_path_use:n} \Arg{action(s)}
+% \end{syntax}
+% Inserts the current path, carrying out one ore more possible \meta{actions}
+% (a comma list):
+% \begin{itemize}
+% \item \texttt{clear} Resets the path to empty
+% \item \texttt{clip} Clips any content outside of the path
+% \item \texttt{draw}
+% \item \texttt{fill} Fills the interior of the path with the current
+% file color
+% \item \texttt{stroke} Draws a line along the current path
+% \end{itemize}
+% \end{function}
+%
+% \subsubsection{Path operations on drawing axes}
+%
+% The standard path functions are all influenced by the active transformation
+% matrix, \emph{i.e.}~the work relative to the drawing axes rather than
+% the canvas.
+%
% \begin{function}{\draw_path_moveto:n}
% \begin{syntax}
% \cs{draw_path_moveto:n} \Arg{point}
@@ -381,6 +618,32 @@
% \cs{draw_path_lineto:n} \Arg{point}
% \end{syntax}
% Joins the current path to the \meta{point} with a straight line.
+% In general, for reliable treatment by viewers, a \cs{draw_path_moveto:n}
+% operation should precede the first use of a \cs{draw_path_lineto:n}
+% on a path.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 1cm , 1cm }
+% \draw_path_lineto:n { 2cm , 1cm }
+% \draw_path_lineto:n { 3cm , 0.5cm }
+% \draw_path_lineto:n { 3cm , 0cm }
+% \draw_color_fill:n { yellow!80!black }
+% \draw_path_use_clear:n { fill , stroke }
+% \draw_end:
+% \end{demo}
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 1cm , 1cm }
+% \draw_path_lineto:n { 2cm , 1cm }
+% \draw_path_moveto:n { 2cm , 1cm } % Begins a new part
+% \draw_path_lineto:n { 3cm , 0.5cm }
+% \draw_path_lineto:n { 3cm , 0cm }
+% \draw_color_fill:n { yellow!80!black }
+% \draw_path_use_clear:n { fill , stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \begin{function}{\draw_path_curveto:nnn}
@@ -388,7 +651,21 @@
% \cs{draw_path_curveto:nnn} \Arg{control1} \Arg{control2} \Arg{end}
% \end{syntax}
% Joins the current path to the \meta{end} with a curved line defined by
-% cubic Bézier points \meta{control1} and \meta{control2}.
+% cubic Bézier points \meta{control1} and \meta{control2}. The bounding box
+% of the path (and image) will fully-contain the curve and control points,
+% \emph{i.e.}~it may be bigger than strictly necessary to contain the curve
+% \emph{alone}.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_curveto:nnn
+% { 1cm , 1cm } % First control
+% { 2cm , 1cm } % Second control
+% { 3cm , 0cm } % End
+% \draw_color_fill:n { yellow!80!black }
+% \draw_path_use_clear:n { fill , stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \begin{function}{\draw_path_curveto:nn}
@@ -396,7 +673,20 @@
% \cs{draw_path_curveto:nn} \Arg{control} \Arg{end}
% \end{syntax}
% Joins the current path to the \meta{end} with a curved line defined by
-% quadratic Bézier point \meta{control}.
+% quadratic Bézier point \meta{control}. The bounding box
+% of the path (and image) will fully-contain the curve and computed (cubic)
+% control points, \emph{i.e.}~it may be bigger than strictly necessary to
+% contain the curve \emph{alone}.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_curveto:nn
+% { 1cm , 1cm }
+% { 2cm , 0cm }
+% \draw_color_fill:n { yellow!80!black }
+% \draw_path_use_clear:n { fill , stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \begin{function}{\draw_path_arc:nnn, \draw_path_arc:nnnn}
@@ -407,9 +697,26 @@
% Joins the current path with an arc between \meta{angle1} and \meta{angle2}
% and of \meta{radius}. The four-argument version accepts two radii of
% different lengths.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_arc:nnn { 180 } { 90 } { 0.5cm }
+% \draw_path_lineto:n { 3cm , 1.5cm }
+% \draw_path_arc:nnn { 90 } { -45 } { 0.5cm }
+% \draw_path_use_clear:n { fill }
+% \draw_end:
+% \end{demo}
%
% Note the interface here has a different argument ordering from that in
% \pkg{pgf}, which has the two centers then the two radii.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_arc:nnnn { 180 } { 45 } { 2cm } { 1cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \begin{function}{\draw_path_arc_axes:nnnn}
@@ -417,15 +724,49 @@
% \cs{draw_path_arc_axes:nnn} \Arg{angle1} \Arg{angle2} \Arg{vector1} \Arg{vector2}
% \end{syntax}
% Appends the portion of an ellipse from \meta{angle1} to \meta{angle2} of an
-% ellipse with axes along \meta{vector1} and \meta{vector2} to the current path.
+% ellipse with axes along \meta{vector1} and \meta{vector2} to the current
+% path.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 2cm , 5mm }
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_moveto:n { 2cm , 5mm }
+% \draw_path_arc_axes:nnnn { 0 } { 90 }
+% { 2cm , 5mm } { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
-% \begin{function}{\draw_path_ellipse:nnnn}
+% \begin{function}{\draw_path_ellipse:nnn}
% \begin{syntax}
% \cs{draw_path_ellipse:nnn} \Arg{center} \Arg{vector1} \Arg{vector2}
% \end{syntax}
% Appends an ellipse at \meta{center} with axes along \meta{vector1} and
-% \meta{vector2} to the current path.
+% \meta{vector2} to the current path. A new part is started if the path
+% is already non-empty. Notice that the underlying drawing is constructed
+% from arcs with appropriate moves: the interfaces is a more efficient
+% convenience.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_ellipse:nnn
+% { 1cm , 0cm }
+% { 1.5cm , 0cm }
+% { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_color:n { red }
+% \draw_path_ellipse:nnn
+% { 1cm , 0cm }
+% { 1cm , 1cm }
+% { -0.5cm , 0.5cm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+%
+% Note that any transformation is applied to the completed ellipse rather than
+% to the axes.
% \end{function}
%
% \begin{function}{\draw_path_circle:nn}
@@ -433,6 +774,7 @@
% \cs{draw_path_circle:nn} \Arg{center} \Arg{radius}
% \end{syntax}
% Appends a circle of \meta{radius} at \meta{center} to the current path.
+% This is a shortcut for \cs{draw_path_ellipse:nnn}.
% \end{function}
%
% \begin{function}{\draw_path_rectangle:nn, \draw_path_rectangle_corners:nn}
@@ -443,44 +785,179 @@
% Appends a rectangle starting at \meta{lower-left} to the current path,
% with the size of the rectangle determined either by a \meta{displacement}
% or the position of the \meta{top-right}.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_rectangle:nn
+% { 1cm , 0cm }
+% { 1.5cm , 1cm }
+% \draw_path_rectangle:nn
+% { 1.5cm , 0.25cm }
+% { 1.5cm , 1cm }
+% \draw_path_rectangle:nn
+% { 2cm , 0.5cm }
+% { 1.5cm , 1cm }
+% \draw_path_use_clear:n { draw }
+% \draw_end:
+% \end{demo}
+% \begin{demo}
+% \draw_begin:
+% \draw_path_rectangle_corners:nn
+% { 1cm , 0cm }
+% { 1.5cm , 1cm }
+% \draw_path_use_clear:n { draw }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \begin{function}{\draw_path_grid:nnnn}
% \begin{syntax}
-% \cs{draw_path_grid:nnnn} \Arg{xspace} \Arg{yspace} \Arg{lower-left} \Arg{upper-right}
+% \cs{draw_path_grid:nnnn} \Arg{xstep} \Arg{ystep} \Arg{lower-left} \Arg{upper-right}
% \end{syntax}
-% Constructs a grid of \meta{xspace} and \meta{yspace} from the
-% \meta{lower-left} to the \meta{upper-right}, and appends this to the
-% current path.
+% Constructs a grid of \meta{xstep} and \meta{ystep} inside the rectangle
+% defined by the \meta{lower-left} and the \meta{upper-right}, and appends
+% this to the current path. The grid will be aligned such that grid lines
+% pass through the origin, which may result in \enquote{protruding} ends
+% if the start/end positions do not fully align.
+% \begin{demo}
+% \draw_begin:
+% \draw_linewidth:n { 0.8pt }
+% \draw_path_grid:nnnn
+% { 1cm } { 1cm }
+% { -3mm , -3mm }
+% { 33mm , 23mm }
+% \draw_path_use_clear:n { stroke }
+% \draw_linewidth:n { 0.4pt }
+% \draw_path_grid:nnnn
+% { 1mm } { 1mm }
+% { -1.5mm , -1.5mm }
+% { 31.5mm , 21.5mm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
+%
+% Any transformation is applied to the finished grid.
+% \begin{demo}
+% \draw_begin:
+% \draw_transform_rotate:n { 10 }
+% \draw_path_grid:nnnn
+% { 1mm } { 2mm }
+% { 0mm , 0mm }
+% { 30mm , 30mm }
+% \draw_path_use_clear:n { stroke }
+% \draw_end:
+% \end{demo}
% \end{function}
%
-% \begin{function}{\draw_path_close:}
+% \subsubsection{Path scope}
+%
+% \begin{function}{\draw_path_scope_begin:, \draw_path_scope_end:}
% \begin{syntax}
-% \cs{draw_path_close:}
+% \cs{draw_path_scope_begin:}
+% ...
+% \cs{draw_path_scope_end:}
% \end{syntax}
-% Closes the current part of the path by appending a straight line from
-% the current point to the starting point of the path.
+% Suspends (and saves) the current (partial) path, initialising a new
+% path within the scope. Path operations are written to output only when
+% used, so the scoped path is stored at the \pkg{expl3} level, not
+% in the output.
% \end{function}
%
-% \begin{function}{\draw_path_use:n, \draw_path_use_clear:n}
+% \subsubsection{Path operations on canvas axes}
+%
+% For \emph{specialist} work, a small number of functions are provided
+% which work relative to the canvas axes, \emph{i.e.}~these functions
+% ignore the transformation matrix.
+%
+% \begin{function}{\draw_path_canvas_moveto:n}
% \begin{syntax}
-% \cs{draw_path_use:n} \Arg{action(s)}
+% \cs{draw_path_canvas_moveto:n} \Arg{canvas point}
% \end{syntax}
-% Inserts the current path, carrying out one ore more possible \meta{actions}
-% (a comma list):
-% \begin{itemize}
-% \item \texttt{clear} Resets the path to empty
-% \item \texttt{clip} Clips any content outside of the path
-% \item \texttt{draw}
-% \item \texttt{fill} Fills the interior of the path with the current
-% file color
-% \item \texttt{stroke} Draws a line along the current path
-% \end{itemize}
+% Moves the reference point of the path to the \meta{canvas point}, but will
+% not join this to any previous point.
+% \end{function}
+%
+% \begin{function}{\draw_path_canvas_lineto:n}
+% \begin{syntax}
+% \cs{draw_path_canvas_lineto:n} \Arg{canvas point}
+% \end{syntax}
+% Joins the current path to the \meta{canvas point} with a straight line.
+% \end{function}
+%
+% \begin{function}{\draw_path_canvas_curveto:nnn}
+% \begin{syntax}
+% \cs{draw_path_canvas_curveto:nnn} \Arg{control1} \Arg{control2} \Arg{end}
+% \end{syntax}
+% Joins the current path to the \meta{end} with a curved line defined by
+% cubic Bézier points \meta{control1} and \meta{control2}. These positions
+% are given as canvas points.
+% \end{function}
+%
+% \subsection{Bounding box}
+%
+% \begin{variable}{\l_draw_bb_update_bool}
+% All functions automatically update the bounding box of the image, unless
+% specified otherwise. This behavior is selectable using the
+% \cs{l_draw_bb_update_bool} boolean.
+% \end{variable}
+%
+% \subsection{Boxes and coffins}
+%
+% \begin{function}{\draw_box_use:N}
+% \begin{syntax}
+% \cs{draw_box_use:N} \meta{box}
+% \end{syntax}
+% Inserts the \meta{box} into a drawing, taking account of the current
+% transformation matrix and shift, and adjusting the drawing bounding
+% box to contain the (apparent) size of the box if this is active
+% (see \cs{l_draw_bb_update_bool}).
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \hbox_set:Nn \l_tmpa_box
+% { This~is~text. }
+% \draw_box_use:N \l_tmpa_box
+% \draw_end:
+% \end{demo}
+% \begin{demo}
+% \draw_begin:
+% \draw_transform_matrix:nnnn { 2 } { 0 } { 1 } { 2 }
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \hbox_set:Nn \l_tmpa_box
+% { This~is~text. }
+% \draw_box_use:N \l_tmpa_box
+% \draw_end:
+% \end{demo}
+% \end{function}
+%
+% \begin{function}{\draw_coffin_use:Nnn}
+% \begin{syntax}
+% \cs{draw_coffin_use:N} \meta{coffin} \Arg{hpole} \Arg{vpole}
+% \end{syntax}
+% Inserts the \meta{coffin} into a drawing, taking account of the current
+% transformation matrix and shift, and adjusting the drawing bounding
+% box to contain the (apparent) size of the box if this is active
+% (see \cs{l_draw_bb_update_bool}). The alignment point of the coffin to
+% the origin is specified by the intersection of the \meta{hpole} and the
+% \meta{vpole}.
+% \begin{demo}
+% \draw_begin:
+% \draw_path_moveto:n { 0cm , 0cm }
+% \draw_path_lineto:n { 0cm , 1cm }
+% \draw_path_use_clear:n { stroke }
+% \hcoffin_set:Nn \l_tmpa_coffin
+% { This~is~text. }
+% \draw_coffin_use:Nnn \l_tmpa_coffin { hc } { vc }
+% \draw_end:
+% \end{demo}
% \end{function}
%
% \subsection{Color}
%
-% \begin{function}{\draw_color:n, \draw_fill:n, \draw_stroke:n}
+% \begin{function}{\draw_color:n, \draw_color_fill:n, \draw_color_stroke:n}
% \begin{syntax}
% \cs{draw_color:n} \Arg{color expression}
% \end{syntax}
@@ -491,34 +968,28 @@
%
% Points are normally used unchanged relative to the canvas axes. This can
% be modified by applying a transformation matrix. The canvas axes themselves
-% may be adjusted using \cs{driver_draw_transformcm:nnnnnn}: note that this
+% may be adjusted using \cs{driver_draw_cm:nnnn}: note that this
% is transparent to the drawing code so is not tracked.
%
-% \begin{function}{\draw_transform_reset:}
-% \begin{syntax}
-% \cs{draw_transform_reset:}
-% \end{syntax}
-% Resets the matrix to the identity.
-% \end{function}
-%
-% \begin{function}{\draw_transform_concat:nnnnn}
+% \begin{function}
+% {\draw_transform_matrix:nnnn, \draw_transform_matrix_concat:nnnn}
% \begin{syntax}
-% \cs{draw_transform_concat:nnnnn}
-% \Arg{a} \Arg{b} \Arg{c} \Arg{d} \Arg{vector}
+% \cs{draw_transform_matrix:nnnnn}
+% \Arg{a} \Arg{b} \Arg{c} \Arg{d}
% \end{syntax}
-% Appends the given transformation to the currently-active one. The
-% transformation is made up of a matrix \meta{a}, \meta{b}, \meta{c} and
-% \meta{d}, and a shift by the \meta{vector}.
+% Applies the transformation matrix $[ \meta{a} \meta{b} \meta{c} \meta{d}]$.
+% The basic version over-writes the current matrix, the |concat| version
+% concatenates.
+% This assignment is local.
% \end{function}
%
-% \begin{function}{\draw_transform:nnnnn}
+% \begin{function}{\draw_transform_shift:n, \draw_transform_shift_concat:n}
% \begin{syntax}
-% \cs{draw_transform:nnnnn}
-% \Arg{a} \Arg{b} \Arg{c} \Arg{d} \Arg{vector}
+% \cs{draw_transform_shift:n} \Arg{vector}
% \end{syntax}
-% Applies the transformation matrix specified, over-writing any existing
-% matrix. The transformation is made up of a matrix \meta{a}, \meta{b},
-% \meta{c} and \meta{d}, and a shift by the \meta{vector}.
+% Applies the transformation \meta{vector} to points. The basic version
+% over-writes the current vector, the |concat| version concatenates.
+% This assignment is local.
% \end{function}
%
% \begin{function}{\draw_transform_triangle:nnn}
@@ -529,14 +1000,77 @@
% Applies a transformation such that the co-ordinates $(0, 0)$, $(1, 0)$
% and $(0, 1)$ are given by the \meta{origin}, \meta{point1} and
% \meta{point2}, respectively.
+% This assignment is local.
+% \end{function}
+%
+% \begin{function}{\draw_transform_rotate:n}
+% \begin{syntax}
+% \cs{draw_transform_rotate:n} \Arg{angle}
+% \end{syntax}
+% Applies a rotation by the \meta{angle}, measured anti-clockwise in degrees.
+% This rotation is \emph{additional} to any prevailing transformation.
+% This assignment is local.
% \end{function}
%
-% \begin{function}{\draw_transform_invert:}
+% \begin{function}
+% {
+% \draw_transform_scale:n,
+% \draw_transform_xscale:n,
+% \draw_transform_xscale:n
+% }
+% \begin{syntax}
+% \cs{draw_transform_scale:n} \Arg{scale}
+% \end{syntax}
+% Applies the \meta{scale} in either $x$ or $y$ (or both).
+% This scale is \emph{added} to any prevailing transformation.
+% This assignment is local.
+% \end{function}
+%
+% \begin{function}
+% {
+% \draw_transform_xshift:n,
+% \draw_transform_yshift:n
+% }
+% \begin{syntax}
+% \cs{draw_transform_shift:n} \Arg{vector}
+% \cs{draw_transform_xshift:n} \Arg{xshift}
+% \end{syntax}
+% Applies an \meta{xshift} or \meta{yshift}, as appropriate. This shift is
+% \emph{added} to any prevailing one.
+% This assignment is local.
+% \end{function}
+%
+% \begin{function}
+% {
+% \draw_transform_xslant:n,
+% \draw_transform_yslant:n
+% }
+% \begin{syntax}
+% \cs{draw_transform_xslant:n} \Arg{slant}
+% \end{syntax}
+% Applies the \meta{slant} (a factor) in either $x$ or $y$.
+% This slant is \emph{added} to any prevailing transformation.
+% This assignment is local.
+% \end{function}
+%
+% \begin{function}
+% {\draw_transform_matrix_invert:, \draw_transform_shift_invert:}
+% \begin{syntax}
+% \cs{draw_transform_matrix_invert:}
+% \end{syntax}
+% Inverts the current transformation matrix or shift vector, as
+% appropriate.
+% This assignment is local.
+% \end{function}
+%
+% \begin{function}
+% {\draw_transform_matrix_reset, \draw_transform_shift_reset:}
% \begin{syntax}
-% \cs{draw_transform_invert:}
+% \cs{draw_transform_matrix_reset:}
% \end{syntax}
-% Inverts the current transformation matrix and reverses the current
-% shift vector.
+% Resets the current transformation matrix or shift vector, as
+% appropriate.
+% This assignment is local.
% \end{function}
%
% \end{documentation}
@@ -555,7 +1089,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3draw}{2018/02/21}{}
+\ProvidesExplPackage{l3draw}{2018/03/05}{}
{L3 Experimental core drawing support}
%</package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins
index d7c3616c607..e91015c2ba1 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins
+++ b/Master/texmf-dist/source/latex/l3experimental/l3draw/l3draw.ins
@@ -54,6 +54,7 @@ and all files in that bundle must be distributed together.
\generate{\file{l3draw.sty}
{
\from{l3draw.dtx} {package}
+ \from{l3draw-boxes.dtx} {package}
\from{l3draw-paths.dtx} {package}
\from{l3draw-points.dtx} {package}
\from{l3draw-scopes.dtx} {package}
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx
index 5691eb65ec9..66a01368167 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-convert.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: l3str-convert.dtx Copyright (C) 2013-2017 The LaTeX3 Project
+%% File: l3str-convert.dtx Copyright (C) 2013-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
@@ -47,7 +47,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -252,7 +252,7 @@
% \end{macrocode}
%
% \begin{macrocode}
-\ProvidesExplPackage{l3str-convert}{2018/02/21}{}
+\ProvidesExplPackage{l3str-convert}{2018/03/05}{}
{L3 Experimental string encoding conversions}
% \end{macrocode}
%
diff --git a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
index 14f6874216c..8075162f725 100644
--- a/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/l3str/l3str-format.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: l3str-format.dtx Copyright (C) 2012-2017 The LaTeX3 Project
+%% File: l3str-format.dtx Copyright (C) 2012-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
@@ -47,7 +47,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -163,7 +163,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3str-format}{2018/02/21}{}
+\ProvidesExplPackage{l3str-format}{2018/03/05}{}
{L3 Experimental string formatting}
%</package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
index dd801e51ae0..e4a7b5b12ea 100644
--- a/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/xcoffins/xcoffins.dtx
@@ -54,7 +54,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -673,7 +673,7 @@
% \end{macrocode}
%
% \begin{macrocode}
-\ProvidesExplPackage{xcoffins}{2018/02/21}{}
+\ProvidesExplPackage{xcoffins}{2018/03/05}{}
{L3 Experimental design level coffins}
% \end{macrocode}
%
diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
index 7533b90e087..f0ff78ee457 100644
--- a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
@@ -1,7 +1,7 @@
% \iffalse
%
%% File: l3galley.dtx Copyright (C) 1999-2001, 2004-2009 Frank Mittelbach
-%% (C) 2010-2017 The LaTeX3 Project
+%% (C) 2010-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
@@ -59,7 +59,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -685,7 +685,7 @@
%
% \begin{macrocode}
%<*package>
-\ProvidesExplPackage{l3galley}{2018/02/21}{}
+\ProvidesExplPackage{l3galley}{2018/03/05}{}
{L3 Experimental galley code}
%</package>
% \end{macrocode}
diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
index d0e62a385c5..7c6dd9656a4 100644
--- a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
+++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
@@ -1,7 +1,7 @@
% \iffalse
%
%% File: xgalley.dtx Copyright (C) 1999-2001, 2004-2009 Frank Mittelbach
-%% (C) 2010-2012,2014,2016-2017 The LaTeX3 Project
+%% (C) 2010-2012,2014,2016-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
@@ -45,7 +45,7 @@
% }^^A
% }
%
-% \date{Released 2018/02/21}
+% \date{Released 2018/03/05}
%
% \maketitle
%
@@ -732,7 +732,7 @@
% \end{macrocode}
%
% \begin{macrocode}
-\ProvidesExplPackage{xgalley}{2018/02/21}{}
+\ProvidesExplPackage{xgalley}{2018/03/05}{}
{L3 Experimental galley}
\RequirePackage{xparse,xtemplate,l3galley}
% \end{macrocode}