[latex3-commits] [l3svn] branch master updated: Driver drawing support for SVG
noreply at latex-project.org
noreply at latex-project.org
Thu May 19 14:59:08 CEST 2016
This is an automated email from the git hooks/post-receive script.
joseph pushed a commit to branch master
in repository l3svn.
The following commit(s) were added to refs/heads/master by this push:
new 902ba5e Driver drawing support for SVG
902ba5e is described below
commit 902ba5ef541cb2c3a3ddab8ae1ffea79f2adf7d7
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date: Thu May 19 13:58:47 2016 +0100
Driver drawing support for SVG
This completes, more or less, the 'basics' of drawing support in
the driver. This is not everything e.g. pgf can do but is everything
picture mode can. Perhaps next some 'basic' interfaces: depends on
time!
---
l3kernel/l3drivers.dtx | 503 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 488 insertions(+), 15 deletions(-)
diff --git a/l3kernel/l3drivers.dtx b/l3kernel/l3drivers.dtx
index cf164f5..150fef6 100755
--- a/l3kernel/l3drivers.dtx
+++ b/l3kernel/l3drivers.dtx
@@ -285,8 +285,15 @@
% specific stroke color is set). The path may also be used for clipping.
% For paths which are self-intersecting or comprising multiple parts, the
% determination of which areas are inside the path is made using the nonzero
-% winding rule number unless \cs{__driver_draw_eor_bool} is \texttt{true},
-% in which case the even-odd rule is used.
+% winding rule number unless the even-odd rule is active.
+% \end{function}
+%
+% \begin{function}{\__driver_draw_nonzero_rule:, \__driver_draw_evenodd_rule:}
+% \begin{syntax}
+% \cs{__driver_draw_nonzero_rule:}
+% \end{syntax}
+% Active either the non-zero winding number or the even-odd rule,
+% respectively, for determining what is inside a fill or clip area.
% \end{function}
%
% \begin{function}{\__driver_draw_clip:}
@@ -903,12 +910,18 @@
% \end{macro}
% \end{macro}
%
-% \begin{variable}[int]{\@@_draw_eor_bool}
+% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:}
+% \begin{variable}[aux]{\g_@@_draw_eor_bool}
% The even-odd rule here can be implemented as a simply switch.
% \begin{macrocode}
-\bool_new:N \@@_draw_eor_bool
+\cs_new_protected_nopar:Npn \@@_draw_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected_nopar:Npn \@@_draw_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
% \end{macrocode}
% \end{variable}
+% \end{macro}
%
% \begin{macro}[int]
% {
@@ -932,17 +945,17 @@
\cs_new_protected_nopar:Npn \@@_draw_fill:
{
\@@_draw_literal:x
- { f \bool_if:NT \@@_draw_eor_bool * }
+ { f \bool_if:NT \g_@@_draw_eor_bool * }
}
\cs_new_protected_nopar:Npn \@@_draw_fillstroke:
{
\@@_draw_literal:x
- { B \bool_if:NT \@@_draw_eor_bool * }
+ { B \bool_if:NT \g_@@_draw_eor_bool * }
}
\cs_new_protected_nopar:Npn \@@_draw_clip:
{
\@@_draw_literal:x
- { W \bool_if:NT \@@_draw_eor_bool * }
+ { W \bool_if:NT \g_@@_draw_eor_bool * }
}
\cs_new_protected_nopar:Npn \@@_draw_discardpath:
{ \@@_draw_literal:n { n } }
@@ -1408,12 +1421,18 @@
% \end{macro}
% \end{macro}
%
-% \begin{variable}[int]{\@@_draw_eor_bool}
+% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:}
+% \begin{variable}[aux]{\g_@@_draw_eor_bool}
% The even-odd rule here can be implemented as a simply switch.
% \begin{macrocode}
-\bool_new:N \@@_draw_eor_bool
+\cs_new_protected_nopar:Npn \@@_draw_evenodd_rule:
+ { \bool_gset_true:N \g_@@_draw_eor_bool }
+\cs_new_protected_nopar:Npn \@@_draw_nonzero_rule:
+ { \bool_gset_false:N \g_@@_draw_eor_bool }
+\bool_new:N \g_@@_draw_eor_bool
% \end{macrocode}
% \end{variable}
+% \end{macro}
%
% \begin{macro}[int]
% {
@@ -1447,7 +1466,7 @@
{
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
clip
}
}
@@ -1464,7 +1483,7 @@
\@@_draw_literal:n { currentdict~/l3fc~known~{gsave~l3fc}~if }
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
fill
}
\@@_draw_literal:n { currentdict~/l3fc~known~{grestore}~if }
@@ -1475,7 +1494,7 @@
{
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
clip
}
}
@@ -1487,7 +1506,7 @@
\@@_draw_literal:n { currentdict~/l3fc~known~{gsave~l3fc}~if }
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
fill
}
\@@_draw_literal:n { currentdict~/l3fc~known~{grestore}~if }
@@ -1495,7 +1514,7 @@
{
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
clip
}
}
@@ -1511,7 +1530,7 @@
{
\@@_draw_literal:x
{
- \bool_if:NT \@@_draw_eor_bool { eo }
+ \bool_if:NT \g_@@_draw_eor_bool { eo }
clip
}
}
@@ -1945,6 +1964,460 @@
% \end{macro}
% \end{macro}
%
+% \subsection{Drawing}
+%
+% \begin{macro}[aux]{\@@_draw_literal:n, \@@_draw_literal:x}
+% The same as the more general literal call.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_draw_literal:n \@@_literal:n
+\cs_generate_variant:Nn \@@_draw_literal:n { x }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_begin:, \@@_draw_end:}
+% A drawing needs to be set up such that the co-ordinate system is
+% translated. That is done inside a scope, which as described below
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_begin:
+ {
+ \@@_draw_scope_begin:
+ \@@_draw_scope:n { transform="translate({?x},{?y})~scale(1,-1)" }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_end:
+ { \@@_draw_scope_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_scope_begin:, \@@_draw_scope_end:}
+% \begin{macro}[aux]{\@@_draw_scope:n, \@@_draw_scope:x}
+% \begin{variable}[aux]{\g_@@_draw_scope_int, \l_@@_draw_scope_int}
+% Several settings that with other drivers are \enquote{stand alone} have
+% to be given as part of a scope in SVG. As a result, there is a need to
+% provide a mechanism to automatically close these extra scopes. That is
+% done using a dedicated function and a pair of tracking variables. Within
+% each graphics scope we use a global variable to do the work, with a group
+% used to save the value between scopes. The result is that no direct action
+% is needed when creating a scope.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_scope_begin:
+ {
+ \int_set_eq:NN
+ \l_@@_draw_scope_int
+ \g_@@_draw_scope_int
+ \group_begin:
+ \int_gset:Nn \g_@@_draw_scope_int { 0 }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_scope_end:
+ {
+ \prg_replicate:nn
+ { \g_@@_draw_scope_int }
+ { \@@_draw_literal:n { </g> } }
+ \group_end:
+ \int_gset_eq:NN
+ \g_@@_draw_scope_int
+ \l_@@_draw_scope_int
+ }
+\cs_new_protected:Npn \@@_draw_scope:n #1
+ {
+ \@@_draw_literal:n { <g~ #1 > }
+ \int_gincr:N \g_@@_draw_scope_int
+ }
+\cs_generate_variant:Nn \__driver_draw_scope:n { x }
+\int_new:N \g_@@_draw_scope_int
+\int_new:N \l_@@_draw_scope_int
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_moveto:nn, \@@_draw_lineto:nn}
+% \begin{macro}[int]{\@@_draw_rectangle:nnnn}
+% \begin{macro}[int]{\@@_draw_curveto:nnnnnn}
+% \begin{macro}[aux]{\@@_draw_add_to_path:n}
+% \begin{variable}[aux]{\g_@@_draw_path_tl}
+% Once again, some work is needed to get path constructs correct. Rather
+% then write the values as they are given, the entire path needs to be
+% collected up before being output in one go. For that we use a dedicated
+% storage routine, which will add spaces as required. Since paths should
+% be fully expanded there is no need to worry about the internal
+% \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_moveto:nn #1#2
+ {
+ \@@_draw_add_to_path:n
+ { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_draw_lineto:nn #1#2
+ {
+ \@@_draw_add_to_path:n
+ { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
+ }
+\cs_new_protected:Npn \@@_draw_rectangle:nnnn #1#2#3#4
+ {
+ \@@_draw_add_to_path:n
+ {
+ M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2}
+ h ~ \dim_to_decimal:n {#3} ~
+ v ~ \dim_to_decimal:n {#4} ~
+ h ~ \dim_to_decimal:n { -#3 } ~
+ Z
+ }
+ }
+\cs_new_protected:Npn \@@_draw_curveto:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_draw_add_to_path:n
+ {
+ C ~
+ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} ~
+ \dim_to_decimal:n {#3} ~ \dim_to_decimal:n {#4} ~
+ \dim_to_decimal:n {#5} ~ \dim_to_decimal:n {#6}
+ }
+ }
+\cs_new_protected:Npn \@@_draw_add_to_path:n #1
+ {
+ \tl_gset:Nx \g_@@_draw_path_tl
+ {
+ \g_@@_draw_path_tl
+ \tl_if_empty:NF \g_@@_draw_path_tl { \c_space_tl }
+ #1
+ }
+ }
+\tl_new:N \g_@@_draw_path_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_evenodd_rule:, \@@_draw_nonzero_rule:}
+% The fill rules here have to be handled as scopes.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_evenodd_rule:
+ { \@@_draw_scope:n { fill-rule="evenodd" } }
+\cs_new_protected_nopar:Npn \@@_draw_nonzero_rule:
+ { \@@_draw_scope:n { fill-rule="nonzero" } }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[aux]{\@@_draw_path:n}
+% \begin{macro}[int]
+% {
+% \@@_draw_closepath: ,
+% \@@_draw_stroke: ,
+% \@@_draw_closestroke: ,
+% \@@_draw_fill: ,
+% \@@_draw_fillstroke: ,
+% \@@_draw_clip: ,
+% \@@_draw_discardpath:
+% }
+% \begin{variable}[aux]{\l_@@_draw_clip_bool}
+% \begin{variable}[aux]{\g_@@_draw_path_int}
+% Setting fill and stroke effects and doing clipping all has to be done using
+% scopes. This means setting up the various requirements in a shared
+% auxiliary which deals with the bits and pieces. Clipping paths are reused
+% for path drawing: not essential but avoids constructing them twice.
+% Discarding a path needs a separate function as it's not quite the same.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_draw_closepath:
+ { \@@_draw_add_to_path:n { Z } }
+\cs_new_protected_nopar:Npn \@@_draw_path:n #1
+ {
+ \bool_if:NTF \g__driver_draw_clip_bool
+ {
+ \int_gincr:N \g_@@_clip_path_int
+ \@@_draw_literal:x
+ {
+ < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_draw_path_tl "/> { ?nl }
+ < /clipPath > { ? nl }
+ <
+ use~xlink:href =
+ "\c_hash_str l3path \int_use:N \g_@@_path_int " ~
+ #1
+ />
+ }
+ \@@_draw_scope:x
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int)"
+ }
+ }
+ {
+ \@@_draw_literal:x
+ { <path ~ d=" \g__driver_draw_path_tl " ~ #1/> }
+ }
+ \tl_gclear:N \g__driver_draw_path_tl
+ \bool_gset_false:N \g__driver_draw_clip_bool
+ }
+\int_new:N \g_@@_path_int
+\cs_new_protected_nopar:Npn \@@_draw_stroke:
+ { \@@_draw_path:n { style="fill:none" } }
+\cs_new_protected_nopar:Npn \@@_draw_closestroke:
+ {
+ \@@_draw_closepath:
+ \@@_draw_stroke:
+ }
+\cs_new_protected_nopar:Npn \@@_draw_fill:
+ { \@@_draw_path:n { style="stroke:none" } }
+\cs_new_protected_nopar:Npn \@@_draw_fillstroke:
+ { \@@_draw_path:n { } }
+\cs_new_protected_nopar:Npn \@@_draw_clip:
+ { \bool_set_true:N \l_@@_draw_clip_bool }
+\bool_new:N \l_@@_draw_clip_bool
+\cs_new_protected_nopar:Npn \@@_draw_discardpath:
+ {
+ \bool_if:NT \g__driver_draw_clip_bool
+ {
+ \int_gincr:N \g_@@_clip_path_int
+ \@@_draw_literal:x
+ {
+ < clipPath~id = " l3cp \int_use:N \g_@@_clip_path_int " >
+ { ?nl }
+ <path~d=" \g_@@_draw_path_tl "/> { ?nl }
+ < /clipPath >
+ }
+ \@@_draw_scope:x
+ {
+ clip-path =
+ "url( \c_hash_str l3cp \int_use:N \g_@@_clip_path_int)"
+ }
+ }
+ \tl_gclear:N \g__driver_draw_path_tl
+ \bool_gset_false:N \g__driver_draw_clip_bool
+ }
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_dash:nn}
+% \begin{macro}[aux]{\@@_draw_dash:n}
+% \begin{macro}[aux]{\@@_draw_dash_aux:nn}
+% \begin{macro}[int]{\@@_draw_linewidth:n}
+% \begin{macro}[int]{\@@_draw_miterlimit:n}
+% \begin{macro}[int]^^A
+% {
+% \@@_draw_cap_butt:, \@@_draw_cap_round:, \@@_draw_cap_rectangle:,
+% \@@_draw_join_miter:, \@@_draw_join_round:, \@@_draw_join_bevel:
+% }
+% All of these ideas are properties of scopes in SVG. The only slight
+% complexity is converting the dash array properly (doing any required
+% maths).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_dash:nn #1#2
+ {
+ \use:x
+ {
+ \@@_draw_dash_aux:nn
+ { \clist_map_function:nn {#1} \@@_draw_dash:n }
+ { \dim_to_decimal:n {#2} }
+ }
+ }
+\cs_new:Npn \@@_draw_dash:n #1
+ { , \dim_to_decimal_in_bp:n {#1} }
+\cs_new_protected:Npn \@@_draw_dash_aux:nn #1#2
+ {
+ \@@_draw_scope:x
+ {
+ stroke-dasharray =
+ "
+ \tl_if_empty:oTF { \use_none:n #1 }
+ { none }
+ { \use_none:n #1 }
+ " ~
+ stroke-offset=" #2 "
+ }
+ }
+
+\cs_new_protected:Npn \@@_draw_linewidth:n #1
+ { \@@_draw_scope:x { stroke-width=" \dim_to_decimal:n {#1} " } }
+\cs_new_protected:Npn \@@_draw_miterlimit:n #1
+ { \@@_draw_scope:x { stroke-miterlimit=" \fp_eval:n {#1} " } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_butt:
+ { \@@_draw_scope:n { stroke-linecap="butt" } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_round:
+ { \@@_draw_scope:n { stroke-linecap="round" } }
+\cs_new_protected_nopar:Npn \@@_draw_cap_rectangle:
+ { \@@_draw_scope:n { stroke-linecap="square" } }
+\cs_new_protected_nopar:Npn \@@_draw_join_miter:
+ { \@@_draw_scope:n { stroke-linejoin="miter" } }
+\cs_new_protected_nopar:Npn \@@_draw_join_round:
+ { \@@_draw_scope:n { stroke-linejoin="round" } }
+\cs_new_protected_nopar:Npn \@@_draw_join_bevel:
+ { \@@_draw_scope:n { stroke-linejoin="bevel" } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]
+% {
+% \@@_draw_color_cmyk:nnnn ,
+% \@@_draw_color_cmyk_fill:nnnn ,
+% \@@_draw_color_cmyk_stroke:nnnn
+% }
+% \begin{macro}[int]
+% {
+% \@@_draw_color_gray:n ,
+% \@@_draw_color_gray_fill:n ,
+% \@@_draw_color_gray_stroke:n
+% }
+% \begin{macro}[int]
+% {
+% \@@_draw_color_rgb:nnn ,
+% \@@_draw_color_rgb_fill:nnn ,
+% \@@_draw_color_rgb_stroke:nnn
+% }
+% SVG only works with RGB colors, so there is some conversion to
+% do. The values also need to be given as percentages, which means a
+% little more maths.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_color_cmyk_aux:NNnnnnn #1#2#3#4#5#6
+ {
+ \use:x
+ {
+ \@@_draw_color_rgb_auxii:nnn
+ { \fp_eval:n { -100 * ( (#3) * ( 1 - (#6) ) -1 ) } }
+ { \fp_eval:n { -100 * ( (#4) * ( 1 - (#6) ) + #6 -1 ) } }
+ { \fp_eval:n { -100 * ( (#5) * ( 1 - (#6) ) + #6 -1 ) } }
+ }
+ #1 #2
+ }
+\cs_new_protected_nopar:Npn \@@_draw_color_cmyk:nnnn
+ { \@@_draw_color_cmyk_aux:NNnnnnn \c_true_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_cmyk_fill:nnnn
+ { \@@_draw_color_cmyk_aux:NNnnnnn \c_false_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_cmyk_stroke:nnnn
+ { \@@_draw_color_cmyk_aux:NNnnnnn \c_true_bool \c_false_bool }
+\cs_new_protected:Npn \@@_draw_color_gray_aux:NNn #1#2#3
+ {
+ \use:x
+ {
+ \@@_draw_color_gray_aux:nNN
+ { \fp_eval:n { 100 * (#3)} }
+ }
+ #1 #2
+ }
+\cs_new_protected:Npn \@@_draw_color_gray_aux:nNN #1
+ { \@@_draw_color_rgb_auxii:nnnNN {#1} {#1} {#1} }
+\cs_generate_variant:Nn \@@_draw_color_gray_aux:nNN { x }
+\cs_new_protected_nopar:Npn \@@_draw_color_gray:n
+ { \@@_draw_color_gray_aux:NNn \c_true_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_gray_fill:n
+ { \@@_draw_color_gray_aux:NNn \c_false_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_gray_stroke:n
+ { \@@_draw_color_gray_aux:NNn \c_true_bool \c_false_bool }
+\cs_new_protected:Npn \@@_draw_color_rgb_auxi:NNnnn #1#2#3#4#5
+ {
+ \use:x
+ {
+ \@@_draw_color_rgb_auxii:nnnNN
+ { \fp_eval:n { 100 * (#1) } }
+ { \fp_eval:n { 100 * (#2) } }
+ { \fp_eval:n { 100 * (#3) } }
+ }
+ #1 #2
+ }
+\cs_new_protected:Npn \@@_draw_color_rgb_auxii:nnnNN #1#2#3#4#5
+ {
+ \@@_draw_scope:x
+ {
+ \bool_if:NT #4
+ {
+ fill =
+ "
+ rgb
+ (
+ #1 \c_percent_str ,
+ #2 \c_percent_str ,
+ #3 \c_percent_str
+ )
+ "
+ \bool_if:NT #5 { ~ }
+ }
+ \bool_if:NT #5
+ {
+ stroke =
+ "
+ rgb
+ (
+ #1 \c_percent_str ,
+ #2 \c_percent_str ,
+ #3 \c_percent_str
+ )
+ "
+ }
+ }
+ }
+\cs_new_protected_nopar:Npn \@@_draw_color_rgb:nnn
+ { \@@_draw_color_rgb_auxi:NNnnn \c_true_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_rgb_fill:nnn
+ { \@@_draw_color_rgb_auxi:NNnnn \c_false_bool \c_true_bool }
+\cs_new_protected_nopar:Npn \@@_draw_color_rgb_stroke:nnn
+ { \@@_draw_color_rgb_auxi:NNnnn \c_true_bool \c_false_bool }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_transformcm:nnnnnn}
+% The first four arguments here are floats (the affine matrix), the last
+% two are a displacement vector. Once again, force evaluation to allow for
+% caching.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_transformcm:nnnnnn #1#2#3#4#5#6
+ {
+ \@@_draw_scope:x
+ {
+ transform =
+ "
+ matrix
+ (
+ \fp_eval:n {#1} , \fp_eval:n {#2} ,
+ \fp_eval:n {#3} , \fp_eval:n {#4} ,
+ \dim_to_decimal:n {#5} , \dim_to_decimal:n {#6}
+ )
+ "
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_draw_hbox:Nnnnnnn}
+% \begin{variable}[aux]{\l_@@_tmp_box}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7
+ {
+ \@@_scope_begin:
+ \@@_draw_transformcm:nnnnnn {#2} {#3} {#4} {#5} {#6} {#7}
+ \hbox_set:Nn \l_@@_tmp_box { \box_use:N #1 }
+ \box_set_wd:Nn \l_@@_tmp_box { 0pt }
+ \box_set_ht:Nn \l_@@_tmp_box { 0pt }
+ \box_set_dp:Nn \l_@@_tmp_box { 0pt }
+ \@@_literal:n
+ {
+ < g~
+ stroke="none"~
+ transform="scale(-1,1)~
+ translate({?x},{?y})~
+ scale(-1,-1)"
+ >
+ }
+ \box_use:N \l__driver_tmp_box
+ \@@_literal:n { </g> }
+ \@@_scope_end:
+ }
+\box_new:N \l_@@_tmp_box
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+
+%
% \begin{macrocode}
%</dvisvgm>
% \end{macrocode}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the latex3-commits
mailing list