summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3backend/l3backend-draw.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3backend/l3backend-draw.dtx')
-rw-r--r--macros/latex/contrib/l3backend/l3backend-draw.dtx1067
1 files changed, 0 insertions, 1067 deletions
diff --git a/macros/latex/contrib/l3backend/l3backend-draw.dtx b/macros/latex/contrib/l3backend/l3backend-draw.dtx
deleted file mode 100644
index eef86886f5..0000000000
--- a/macros/latex/contrib/l3backend/l3backend-draw.dtx
+++ /dev/null
@@ -1,1067 +0,0 @@
-% \iffalse meta-comment
-%
-%% File: l3backend-draw.dtx
-%
-% Copyright (C) 2019-2024 The LaTeX 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
-%
-% https://www.latex-project.org/lppl.txt
-%
-% This file is part of the "l3backend 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>
-\documentclass[full,kernel]{l3doc}
-\begin{document}
- \DocInput{\jobname.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \title{^^A
-% The \pkg{l3backend-draw} package\\ Backend drawing support^^A
-% }
-%
-% \author{^^A
-% The \LaTeX{} Project\thanks
-% {^^A
-% E-mail:
-% \href{mailto:latex-team@latex-project.org}
-% {latex-team@latex-project.org}^^A
-% }^^A
-% }
-%
-% \date{Released 2024-03-14}
-%
-% \maketitle
-%
-% \begin{documentation}
-%
-% \end{documentation}
-%
-% \begin{implementation}
-%
-% \section{\pkg{l3backend-draw} implementation}
-%
-% \begin{macrocode}
-%<*package>
-%<@@=draw>
-% \end{macrocode}
-%
-% \subsection{\texttt{dvips} backend}
-%
-% \begin{macrocode}
-%<*dvips>
-% \end{macrocode}
-%
-% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
-% The same as literal PostScript: same arguments about positioning apply
-% here.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_postscript:n
-\cs_generate_variant:Nn \@@_backend_literal:n { e }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
-% The |ps::[begin]| special here deals with positioning but allows us to
-% continue on to a matching |ps::[end]|: contrast with |ps:|, which positions
-% but where we can't split material between separate calls. The
-% |@beginspecial|/|@endspecial| pair are from |special.pro| and correct the
-% scale and $y$-axis direction.
-% As for \pkg{pgf}, we need to save the current point as this is
-% required for box placement. (Note that
-% |@beginspecial|/|@endspecial| forms a backend scope.)
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_begin:
- {
- \@@_backend_literal:n { [begin] }
- \@@_backend_literal:n { /draw.x~currentpoint~/draw.y~exch~def~def }
- \@@_backend_literal:n { @beginspecial }
- }
-\cs_new_protected:Npn \@@_backend_end:
- {
- \@@_backend_literal:n { @endspecial }
- \@@_backend_literal:n { [end] }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
-% Scope here may need to contain saved definitions, so the entire memory
-% rather than just the graphic state has to be sent to the stack.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_scope_begin:
- { \@@_backend_literal:n { save } }
-\cs_new_protected:Npn \@@_backend_scope_end:
- { \@@_backend_literal:n { restore } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
-% \begin{macro}{\@@_backend_rectangle:nnnn}
-% \begin{macro}{\@@_backend_curveto:nnnnnn}
-% Path creation operations mainly resolve directly to PostScript primitive
-% steps, with only the need to convert to \texttt{bp}. Notice that
-% \texttt{x}-type expansion is included here to ensure that any variable
-% values are forced to literals before any possible caching. There is
-% no native rectangular path command (without also clipping, filling or
-% stroking), so that task is done using a small amount of PostScript.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#1} ~
- \dim_to_decimal_in_bp:n {#2} ~ moveto
- }
- }
-\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#1} ~
- \dim_to_decimal_in_bp:n {#2} ~ lineto
- }
- }
-\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#4} ~ \dim_to_decimal_in_bp:n {#3} ~
- \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
- moveto~dup~0~rlineto~exch~0~exch~rlineto~neg~0~rlineto~closepath
- }
- }
-\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
- \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
- \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
- curveto
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
-% \begin{variable}{\g_@@_draw_eor_bool}
-% The even-odd rule here can be implemented as a simply switch.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_evenodd_rule:
- { \bool_gset_true:N \g_@@_draw_eor_bool }
-\cs_new_protected:Npn \@@_backend_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}
-% {
-% \@@_backend_closepath: ,
-% \@@_backend_stroke: ,
-% \@@_backend_closestroke: ,
-% \@@_backend_fill: ,
-% \@@_backend_fillstroke: ,
-% \@@_backend_clip: ,
-% \@@_backend_discardpath:
-% }
-% \begin{variable}{\g_@@_draw_clip_bool}
-% Unlike PDF, PostScript doesn't track separate colors for strokes and other
-% elements. It is also desirable to have the |clip| keyword after a stroke or
-% fill. To achieve those outcomes, there is some work to do. For color, the
-% stoke color is simple but the fill one has to be inserted by hand. For
-% clipping, the required ordering is achieved using a \TeX{} switch. All of
-% the operations end with a new path instruction as they do not terminate
-% (again in contrast to PDF).
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_closepath:
- { \@@_backend_literal:n { closepath } }
-\cs_new_protected:Npn \@@_backend_stroke:
- {
- \@@_backend_literal:n { gsave }
- \@@_backend_literal:n { color.sc }
- \@@_backend_literal:n { stroke }
- \@@_backend_literal:n { grestore }
- \bool_if:NT \g_@@_draw_clip_bool
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- clip
- }
- }
- \@@_backend_literal:n { newpath }
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-\cs_new_protected:Npn \@@_backend_closestroke:
- {
- \@@_backend_closepath:
- \@@_backend_stroke:
- }
-\cs_new_protected:Npn \@@_backend_fill:
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- fill
- }
- \bool_if:NT \g_@@_draw_clip_bool
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- clip
- }
- }
- \@@_backend_literal:n { newpath }
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-\cs_new_protected:Npn \@@_backend_fillstroke:
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- fill
- }
- \@@_backend_literal:n { gsave }
- \@@_backend_literal:n { color.sc }
- \@@_backend_literal:n { stroke }
- \@@_backend_literal:n { grestore }
- \bool_if:NT \g_@@_draw_clip_bool
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- clip
- }
- }
- \@@_backend_literal:n { newpath }
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-\cs_new_protected:Npn \@@_backend_clip:
- { \bool_gset_true:N \g_@@_draw_clip_bool }
-\bool_new:N \g_@@_draw_clip_bool
-\cs_new_protected:Npn \@@_backend_discardpath:
- {
- \bool_if:NT \g_@@_draw_clip_bool
- {
- \@@_backend_literal:e
- {
- \bool_if:NT \g_@@_draw_eor_bool { eo }
- clip
- }
- }
- \@@_backend_literal:n { newpath }
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_dash_pattern:nn}
-% \begin{macro}{\@@_backend_dash:n}
-% \begin{macro}{\@@_backend_linewidth:n}
-% \begin{macro}{\@@_backend_miterlimit:n}
-% \begin{macro}
-% {
-% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
-% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
-% }
-% Converting paths to output is again a case of mapping directly to
-% PostScript operations.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
- {
- \@@_backend_literal:e
- {
- [
- \exp_args:Nf \use:n
- { \clist_map_function:nN {#1} \@@_backend_dash:n }
- ] ~
- \dim_to_decimal_in_bp:n {#2} ~ setdash
- }
- }
-\cs_new:Npn \@@_backend_dash:n #1
- { ~ \dim_to_decimal_in_bp:n {#1} }
-\cs_new_protected:Npn \@@_backend_linewidth:n #1
- {
- \@@_backend_literal:e
- { \dim_to_decimal_in_bp:n {#1} ~ setlinewidth }
- }
-\cs_new_protected:Npn \@@_backend_miterlimit:n #1
- { \@@_backend_literal:n { #1 ~ setmiterlimit } }
-\cs_new_protected:Npn \@@_backend_cap_butt:
- { \@@_backend_literal:n { 0 ~ setlinecap } }
-\cs_new_protected:Npn \@@_backend_cap_round:
- { \@@_backend_literal:n { 1 ~ setlinecap } }
-\cs_new_protected:Npn \@@_backend_cap_rectangle:
- { \@@_backend_literal:n { 2 ~ setlinecap } }
-\cs_new_protected:Npn \@@_backend_join_miter:
- { \@@_backend_literal:n { 0 ~ setlinejoin } }
-\cs_new_protected:Npn \@@_backend_join_round:
- { \@@_backend_literal:n { 1 ~ setlinejoin } }
-\cs_new_protected:Npn \@@_backend_join_bevel:
- { \@@_backend_literal:n { 2 ~ setlinejoin } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_backend_cm:nnnn}
-% In \texttt{dvips}, keeping the transformations in line with the engine
-% is unfortunately not possible for scaling and rotations: even if we
-% decompose the matrix into those operations, there is still no backend
-% tracking (\emph{cf.}~\texttt{dvipdfmx}/\XeTeX{}). Thus we take the shortest
-% path available and simply dump the matrix as given.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
- {
- \@@_backend_literal:n
- { [ #1 ~ #2 ~ #3 ~ #4 ~ 0 ~ 0 ] ~ concat }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_box_use:Nnnnn}
-% Inside a picture |@beginspecial|/|@endspecial| are active, which is
-% normally a good thing but means that the position and scaling would be off
-% if the box was inserted directly. To deal with that, there are a number of
-% possible approaches. A previous implementation suggested by Tom Rokici
-% used |@endspecial|/|@beginspecial|. This avoids needing internals of
-% \texttt{dvips}, but fails if there the box is used inside a scope
-% (see \url{https://github.com/latex3/latex3/issues/1504}). Instead,
-% we use the same method as \pkg{pgf}, which means tracking the position
-% at the PostScript level. Also note that using |@endspecial| would
-% close the scope it creates, meaning that after a box insertion, any
-% local changes would be lost. Keeping \texttt{dvips} on track is
-% non-trivial, hence the |[begin]|/|[end]| pair before the
-% |save| and around the |restore|.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
- {
- \@@_backend_literal:n { save }
- \@@_backend_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale }
- \@@_backend_literal:n { magscale { 1~DVImag~div~dup~scale } if }
- \@@_backend_literal:n { draw.x~neg~draw.y~neg~translate }
- \@@_backend_literal:n { [end] }
- \@@_backend_literal:n { [begin] }
- \@@_backend_literal:n { save }
- \@@_backend_literal:n { currentpoint }
- \@@_backend_literal:n { currentpoint~translate }
- \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
- \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
- \@@_backend_cm:nnnn { 1 } { 0 } { 0 } { -1 }
- \@@_backend_literal:n { neg~exch~neg~exch~translate }
- \@@_backend_literal:n { [end] }
- \hbox_overlap_right:n { \box_use:N #1 }
- \@@_backend_literal:n { [begin] }
- \@@_backend_literal:n { restore }
- \@@_backend_literal:n { [end] }
- \@@_backend_literal:n { [begin] }
- \@@_backend_literal:n { restore }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macrocode}
-%</dvips>
-% \end{macrocode}
-%
-% \subsection{\LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{}}
-%
-% \LuaTeX{}, \pdfTeX{}, \texttt{dvipdfmx} and \XeTeX{} directly produce PDF output
-% and understand a shared set of specials for drawing commands.
-%
-% \begin{macrocode}
-%<*dvipdfmx|luatex|pdftex|xetex>
-% \end{macrocode}
-%
-% \subsubsection{Drawing}
-%
-% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
-% Pass data through using a dedicated interface.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_pdf:n
-\cs_generate_variant:Nn \@@_backend_literal:n { e }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_begin:, \@@_backend_end:}
-% No special requirements here, so simply set up a drawing scope.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_begin:
- { \@@_backend_scope_begin: }
-\cs_new_protected:Npn \@@_backend_end:
- { \@@_backend_scope_end: }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
-% Use the backend-level scope mechanisms.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
-\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
-% \begin{macro}{\@@_backend_curveto:nnnnnn}
-% \begin{macro}{\@@_backend_rectangle:nnnn}
-% Path creation operations all resolve directly to PDF primitive steps, with
-% only the need to convert to \texttt{bp}.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_moveto:nn #1#2
- {
- \@@_backend_literal:e
- { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ m }
- }
-\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
- {
- \@@_backend_literal:e
- { \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~ l }
- }
-\cs_new_protected:Npn \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
- \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
- \dim_to_decimal_in_bp:n {#5} ~ \dim_to_decimal_in_bp:n {#6} ~
- c
- }
- }
-\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
- {
- \@@_backend_literal:e
- {
- \dim_to_decimal_in_bp:n {#1} ~ \dim_to_decimal_in_bp:n {#2} ~
- \dim_to_decimal_in_bp:n {#3} ~ \dim_to_decimal_in_bp:n {#4} ~
- re
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
-% \begin{variable}{\g_@@_draw_eor_bool}
-% The even-odd rule here can be implemented as a simply switch.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_evenodd_rule:
- { \bool_gset_true:N \g_@@_draw_eor_bool }
-\cs_new_protected:Npn \@@_backend_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}
-% {
-% \@@_backend_closepath: ,
-% \@@_backend_stroke: ,
-% \@@_backend_closestroke: ,
-% \@@_backend_fill: ,
-% \@@_backend_fillstroke: ,
-% \@@_backend_clip: ,
-% \@@_backend_discardpath:
-% }
-% Converting paths to output is again a case of mapping directly to
-% PDF operations.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_closepath:
- { \@@_backend_literal:n { h } }
-\cs_new_protected:Npn \@@_backend_stroke:
- { \@@_backend_literal:n { S } }
-\cs_new_protected:Npn \@@_backend_closestroke:
- { \@@_backend_literal:n { s } }
-\cs_new_protected:Npn \@@_backend_fill:
- {
- \@@_backend_literal:e
- { f \bool_if:NT \g_@@_draw_eor_bool * }
- }
-\cs_new_protected:Npn \@@_backend_fillstroke:
- {
- \@@_backend_literal:e
- { B \bool_if:NT \g_@@_draw_eor_bool * }
- }
-\cs_new_protected:Npn \@@_backend_clip:
- {
- \@@_backend_literal:e
- { W \bool_if:NT \g_@@_draw_eor_bool * }
- }
-\cs_new_protected:Npn \@@_backend_discardpath:
- { \@@_backend_literal:n { n } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_dash_pattern:nn}
-% \begin{macro}{\@@_backend_dash:n}
-% \begin{macro}{\@@_backend_linewidth:n}
-% \begin{macro}{\@@_backend_miterlimit:n}
-% \begin{macro}
-% {
-% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
-% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_join_bevel:
-% }
-% Converting paths to output is again a case of mapping directly to
-% PDF operations.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_dash_pattern:nn #1#2
- {
- \@@_backend_literal:e
- {
- [
- \exp_args:Nf \use:n
- { \clist_map_function:nN {#1} \@@_backend_dash:n }
- ] ~
- \dim_to_decimal_in_bp:n {#2} ~ d
- }
- }
-\cs_new:Npn \@@_backend_dash:n #1
- { ~ \dim_to_decimal_in_bp:n {#1} }
-\cs_new_protected:Npn \@@_backend_linewidth:n #1
- {
- \@@_backend_literal:e
- { \dim_to_decimal_in_bp:n {#1} ~ w }
- }
-\cs_new_protected:Npn \@@_backend_miterlimit:n #1
- { \@@_backend_literal:e { #1 ~ M } }
-\cs_new_protected:Npn \@@_backend_cap_butt:
- { \@@_backend_literal:n { 0 ~ J } }
-\cs_new_protected:Npn \@@_backend_cap_round:
- { \@@_backend_literal:n { 1 ~ J } }
-\cs_new_protected:Npn \@@_backend_cap_rectangle:
- { \@@_backend_literal:n { 2 ~ J } }
-\cs_new_protected:Npn \@@_backend_join_miter:
- { \@@_backend_literal:n { 0 ~ j } }
-\cs_new_protected:Npn \@@_backend_join_round:
- { \@@_backend_literal:n { 1 ~ j } }
-\cs_new_protected:Npn \@@_backend_join_bevel:
- { \@@_backend_literal:n { 2 ~ j } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_cm:nnnn}
-% \begin{macro}{\@@_backend_cm_aux:nnnn}
-% Another split here between \LuaTeX{}/pdfTeX{} and \texttt{dvipdfmx}/\XeTeX{}.
-% In the former, we have a direct method to maintain alignment: the backend
-% can use a matrix itself. For \texttt{dvipdfmx}/\XeTeX{}, we can to decompose the
-% matrix into rotations and a scaling, then use those operations as they
-% are handled by the backend. (There is backend support for matrix operations in
-% \texttt{dvipdfmx}/\XeTeX{}, but as a matched pair so not suitable for the
-% \enquote{stand alone} transformation set up here.) The specials used here
-% are from \texttt{xdvipdfmx} originally: they are well-tested, but probably
-% equivalent to the \texttt{pdf:} versions!
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
- {
-%<*luatex|pdftex>
- \__kernel_backend_matrix:n { #1 ~ #2 ~ #3 ~ #4 }
-%</luatex|pdftex>
-%<*dvipdfmx|xetex>
- \@@_backend_cm_decompose:nnnnN {#1} {#2} {#3} {#4}
- \@@_backend_cm_aux:nnnn
-%</dvipdfmx|xetex>
- }
-%<*dvipdfmx|xetex>
-\cs_new_protected:Npn \@@_backend_cm_aux:nnnn #1#2#3#4
- {
- \__kernel_backend_literal:e
- {
- x:rotate~
- \fp_compare:nNnTF {#1} = \c_zero_fp
- { 0 }
- { \fp_eval:n { round ( -#1 , 5 ) } }
- }
- \__kernel_backend_literal:e
- {
- x:scale~
- \fp_eval:n { round ( #2 , 5 ) } ~
- \fp_eval:n { round ( #3 , 5 ) }
- }
- \__kernel_backend_literal:e
- {
- x:rotate~
- \fp_compare:nNnTF {#4} = \c_zero_fp
- { 0 }
- { \fp_eval:n { round ( -#4 , 5 ) } }
- }
- }
-%</dvipdfmx|xetex>
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_cm_decompose:nnnnN}
-% \begin{macro}
-% {
-% \@@_backend_cm_decompose_auxi:nnnnN,
-% \@@_backend_cm_decompose_auxii:nnnnN,
-% \@@_backend_cm_decompose_auxiii:nnnnN,
-% }
-% Internally, transformations for drawing are tracked as a matrix. Not all
-% engines provide a way of dealing with this: if we use a raw matrix, the
-% engine looses track of positions (for example for hyperlinks), and this is
-% not desirable. They do, however, allow us to track rotations and scalings.
-% Luckily, we can decompose any (two-dimensional) matrix into two rotations
-% and a single scaling:
-% \[
-% \begin{bmatrix}
-% A & B \\ C & D
-% \end{bmatrix}
-% =
-% \begin{bmatrix}
-% \cos\beta & \sin\beta \\ -\sin\beta & \cos\beta
-% \end{bmatrix}
-% \begin{bmatrix}
-% w_{1} & 0 \\ 0 & w_{2}
-% \end{bmatrix}
-% \begin{bmatrix}
-% \cos\gamma & \sin\gamma \\ -\sin\gamma & \cos\gamma
-% \end{bmatrix}
-% \]
-% The parent matrix can be converted to
-% \[
-% \begin{bmatrix}
-% A & B \\ C & D
-% \end{bmatrix}
-% =
-% \begin{bmatrix}
-% E & H \\-H & E
-% \end{bmatrix}
-% +
-% \begin{bmatrix}
-% F & G \\ G & -F
-% \end{bmatrix}
-% \]
-% From these, we can find that
-% \begin{align*}
-% \frac{w_{1} + w_{2}}{2} &= \sqrt{E^{2} + H^{2}} \\
-% \frac{w_{1} - w_{2}}{2} &= \sqrt{F^{2} + G^{2}} \\
-% \gamma - \beta &= \tan^{-1}(G/F) \\
-% \gamma + \beta &= \tan^{-1}(H/E)
-% \end{align*}
-% at which point we just have to do various pieces of re-arrangement to
-% get all of the values. (See J.~Blinn, \emph{IEEE Comput.\ Graph.\ Appl.},
-% 1996, \textbf{16}, 82--88.) There is one wrinkle: the PostScript (and PDF)
-% way of specifying a transformation matrix exchanges where one would
-% normally expect $B$ and $C$ to be.
-% \begin{macrocode}
-%<*dvipdfmx|xetex>
-\cs_new_protected:Npn \@@_backend_cm_decompose:nnnnN #1#2#3#4#5
- {
- \use:e
- {
- \@@_backend_cm_decompose_auxi:nnnnN
- { \fp_eval:n { (#1 + #4) / 2 } }
- { \fp_eval:n { (#1 - #4) / 2 } }
- { \fp_eval:n { (#3 + #2) / 2 } }
- { \fp_eval:n { (#3 - #2) / 2 } }
- }
- #5
- }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxi:nnnnN #1#2#3#4#5
- {
- \use:e
- {
- \@@_backend_cm_decompose_auxii:nnnnN
- { \fp_eval:n { 2 * sqrt ( #1 * #1 + #4 * #4 ) } }
- { \fp_eval:n { 2 * sqrt ( #2 * #2 + #3 * #3 ) } }
- { \fp_eval:n { atand ( #3 , #2 ) } }
- { \fp_eval:n { atand ( #4 , #1 ) } }
- }
- #5
- }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxii:nnnnN #1#2#3#4#5
- {
- \use:e
- {
- \@@_backend_cm_decompose_auxiii:nnnnN
- { \fp_eval:n { ( #4 - #3 ) / 2 } }
- { \fp_eval:n { ( #1 + #2 ) / 2 } }
- { \fp_eval:n { ( #1 - #2 ) / 2 } }
- { \fp_eval:n { ( #4 + #3 ) / 2 } }
- }
- #5
- }
-\cs_new_protected:Npn \@@_backend_cm_decompose_auxiii:nnnnN #1#2#3#4#5
- {
- \fp_compare:nNnTF { abs( #2 ) } > { abs ( #3 ) }
- { #5 {#1} {#2} {#3} {#4} }
- { #5 {#1} {#3} {#2} {#4} }
- }
-%</dvipdfmx|xetex>
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_box_use:Nnnnn}
-% Inserting a \TeX{} box transformed to the requested position and using
-% the current matrix is done using a mixture of \TeX{} and low-level
-% manipulation. The offset can be handled by \TeX{}, so only any rotation/^^A
-% skew/scaling component needs to be done using the matrix operation. As this
-% operation can never be cached, the scope is set directly not using the
-% \texttt{draw} version.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
- {
- \__kernel_backend_scope_begin:
-%<*luatex|pdftex>
- \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
-%</luatex|pdftex>
-%<*dvipdfmx|xetex>
- \__kernel_backend_literal:n
- { pdf:btrans~matrix~ #2 ~ #3 ~ #4 ~ #5 ~ 0 ~ 0 }
-%</dvipdfmx|xetex>
- \hbox_overlap_right:n { \box_use:N #1 }
-%<*dvipdfmx|xetex>
- \__kernel_backend_literal:n { pdf:etrans }
-%</dvipdfmx|xetex>
- \__kernel_backend_scope_end:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macrocode}
-%</dvipdfmx|luatex|pdftex|xetex>
-% \end{macrocode}
-%
-% \subsection{\texttt{dvisvgm} backend}
-%
-% \begin{macrocode}
-%<*dvisvgm>
-% \end{macrocode}
-%
-% \begin{macro}{\@@_backend_literal:n, \@@_backend_literal:e}
-% The same as the more general literal call.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_backend_literal:n \__kernel_backend_literal_svg:n
-\cs_generate_variant:Nn \@@_backend_literal:n { e }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_scope_begin:, \@@_backend_scope_end:}
-% Use the backend-level scope mechanisms.
-% \begin{macrocode}
-\cs_new_eq:NN \@@_backend_scope_begin: \__kernel_backend_scope_begin:
-\cs_new_eq:NN \@@_backend_scope_end: \__kernel_backend_scope_end:
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_begin:, \@@_backend_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:Npn \@@_backend_begin:
- {
- \__kernel_backend_scope_begin:
- \__kernel_backend_scope:n { transform="translate({?x},{?y})~scale(1,-1)" }
- }
-\cs_new_eq:NN \@@_backend_end: \__kernel_backend_scope_end:
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_moveto:nn, \@@_backend_lineto:nn}
-% \begin{macro}{\@@_backend_rectangle:nnnn}
-% \begin{macro}{\@@_backend_curveto:nnnnnn}
-% \begin{macro}{\@@_backend_add_to_path:n}
-% \begin{variable}{\g_@@_backend_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 adds 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 \@@_backend_moveto:nn #1#2
- {
- \@@_backend_add_to_path:n
- { M ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
- }
-\cs_new_protected:Npn \@@_backend_lineto:nn #1#2
- {
- \@@_backend_add_to_path:n
- { L ~ \dim_to_decimal:n {#1} ~ \dim_to_decimal:n {#2} }
- }
-\cs_new_protected:Npn \@@_backend_rectangle:nnnn #1#2#3#4
- {
- \@@_backend_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 \@@_backend_curveto:nnnnnn #1#2#3#4#5#6
- {
- \@@_backend_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 \@@_backend_add_to_path:n #1
- {
- \tl_gset:Ne \g_@@_backend_path_tl
- {
- \g_@@_backend_path_tl
- \tl_if_empty:NF \g_@@_backend_path_tl { \c_space_tl }
- #1
- }
- }
-\tl_new:N \g_@@_backend_path_tl
-% \end{macrocode}
-% \end{variable}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_evenodd_rule:, \@@_backend_nonzero_rule:}
-% The fill rules here have to be handled as scopes.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_evenodd_rule:
- { \__kernel_backend_scope:n { fill-rule="evenodd" } }
-\cs_new_protected:Npn \@@_backend_nonzero_rule:
- { \__kernel_backend_scope:n { fill-rule="nonzero" } }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_path:n}
-% \begin{macro}
-% {
-% \@@_backend_closepath: ,
-% \@@_backend_stroke: ,
-% \@@_backend_closestroke: ,
-% \@@_backend_fill: ,
-% \@@_backend_fillstroke: ,
-% \@@_backend_clip: ,
-% \@@_backend_discardpath:
-% }
-% \begin{variable}{\g_@@_draw_clip_bool}
-% \begin{variable}{\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:Npn \@@_backend_closepath:
- { \@@_backend_add_to_path:n { Z } }
-\cs_new_protected:Npn \@@_backend_path:n #1
- {
- \bool_if:NTF \g_@@_draw_clip_bool
- {
- \int_gincr:N \g__kernel_clip_path_int
- \@@_backend_literal:e
- {
- < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
- { ?nl }
- <path~d=" \g_@@_backend_path_tl "/> { ?nl }
- < /clipPath > { ? nl }
- <
- use~xlink:href =
- "\c_hash_str l3path \int_use:N \g_@@_backend_path_int " ~
- #1
- />
- }
- \__kernel_backend_scope:e
- {
- clip-path =
- "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
- }
- }
- {
- \@@_backend_literal:e
- { <path ~ d=" \g_@@_backend_path_tl " ~ #1 /> }
- }
- \tl_gclear:N \g_@@_backend_path_tl
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-\int_new:N \g_@@_backend_path_int
-\cs_new_protected:Npn \@@_backend_stroke:
- { \@@_backend_path:n { style="fill:none" } }
-\cs_new_protected:Npn \@@_backend_closestroke:
- {
- \@@_backend_closepath:
- \@@_backend_stroke:
- }
-\cs_new_protected:Npn \@@_backend_fill:
- { \@@_backend_path:n { style="stroke:none" } }
-\cs_new_protected:Npn \@@_backend_fillstroke:
- { \@@_backend_path:n { } }
-\cs_new_protected:Npn \@@_backend_clip:
- { \bool_gset_true:N \g_@@_draw_clip_bool }
-\bool_new:N \g_@@_draw_clip_bool
-\cs_new_protected:Npn \@@_backend_discardpath:
- {
- \bool_if:NT \g_@@_draw_clip_bool
- {
- \int_gincr:N \g__kernel_clip_path_int
- \@@_backend_literal:e
- {
- < clipPath~id = " l3cp \int_use:N \g__kernel_clip_path_int " >
- { ?nl }
- <path~d=" \g_@@_backend_path_tl "/> { ?nl }
- < /clipPath >
- }
- \__kernel_backend_scope:e
- {
- clip-path =
- "url( \c_hash_str l3cp \int_use:N \g__kernel_clip_path_int)"
- }
- }
- \tl_gclear:N \g_@@_backend_path_tl
- \bool_gset_false:N \g_@@_draw_clip_bool
- }
-% \end{macrocode}
-% \end{variable}
-% \end{variable}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_dash_pattern:nn}
-% \begin{macro}{\@@_backend_dash:n}
-% \begin{macro}{\@@_backend_dash_aux:nn}
-% \begin{macro}{\@@_backend_linewidth:n}
-% \begin{macro}{\@@_backend_miterlimit:n}
-% \begin{macro}
-% {
-% \@@_backend_cap_butt:, \@@_backend_cap_round:, \@@_backend_cap_rectangle:,
-% \@@_backend_join_miter:, \@@_backend_join_round:, \@@_backend_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 \@@_backend_dash_pattern:nn #1#2
- {
- \use:e
- {
- \@@_backend_dash_aux:nn
- { \clist_map_function:nN {#1} \@@_backend_dash:n }
- { \dim_to_decimal:n {#2} }
- }
- }
-\cs_new:Npn \@@_backend_dash:n #1
- { , \dim_to_decimal_in_bp:n {#1} }
-\cs_new_protected:Npn \@@_backend_dash_aux:nn #1#2
- {
- \__kernel_backend_scope:e
- {
- stroke-dasharray =
- "
- \tl_if_empty:nTF {#1}
- { none }
- { \use_none:n #1 }
- " ~
- stroke-offset=" #2 "
- }
- }
-\cs_new_protected:Npn \@@_backend_linewidth:n #1
- { \__kernel_backend_scope:e { stroke-width=" \dim_to_decimal:n {#1} " } }
-\cs_new_protected:Npn \@@_backend_miterlimit:n #1
- { \__kernel_backend_scope:e { stroke-miterlimit=" #1 " } }
-\cs_new_protected:Npn \@@_backend_cap_butt:
- { \__kernel_backend_scope:n { stroke-linecap="butt" } }
-\cs_new_protected:Npn \@@_backend_cap_round:
- { \__kernel_backend_scope:n { stroke-linecap="round" } }
-\cs_new_protected:Npn \@@_backend_cap_rectangle:
- { \__kernel_backend_scope:n { stroke-linecap="square" } }
-\cs_new_protected:Npn \@@_backend_join_miter:
- { \__kernel_backend_scope:n { stroke-linejoin="miter" } }
-\cs_new_protected:Npn \@@_backend_join_round:
- { \__kernel_backend_scope:n { stroke-linejoin="round" } }
-\cs_new_protected:Npn \@@_backend_join_bevel:
- { \__kernel_backend_scope:n { stroke-linejoin="bevel" } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_cm:nnnn}
-% The four arguments here are floats (the affine matrix), the last
-% two are a displacement vector.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_cm:nnnn #1#2#3#4
- {
- \__kernel_backend_scope:n
- {
- transform =
- " matrix ( #1 , #2 , #3 , #4 , 0pt , 0pt ) "
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_backend_box_use:Nnnnn}
-% No special savings can be made here: simply displace the box inside
-% a scope. As there is nothing to re-box, just make the box passed of
-% zero size.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_backend_box_use:Nnnnn #1#2#3#4#5
- {
- \__kernel_backend_scope_begin:
- \@@_backend_cm:nnnn {#2} {#3} {#4} {#5}
- \__kernel_backend_literal_svg:n
- {
- < g~
- stroke="none"~
- transform="scale(-1,1)~translate({?x},{?y})~scale(-1,-1)"
- >
- }
- \box_set_wd:Nn #1 { 0pt }
- \box_set_ht:Nn #1 { 0pt }
- \box_set_dp:Nn #1 { 0pt }
- \box_use:N #1
- \__kernel_backend_literal_svg:n { </g> }
- \__kernel_backend_scope_end:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macrocode}
-%</dvisvgm>
-% \end{macrocode}
-%
-% \begin{macrocode}
-%</package>
-% \end{macrocode}
-%
-% \end{implementation}
-%
-% \PrintIndex