[latex3-commits] [git/LaTeX3-latex3-latex3] master: First steps in box inclusion in drawings (ec2925e)

Joseph Wright joseph.wright at morningstar2.co.uk
Sat Mar 3 21:11:39 CET 2018


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/ec2925efd179405fe5a979cd7fb26cc23aba3376

>---------------------------------------------------------------

commit ec2925efd179405fe5a979cd7fb26cc23aba3376
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Sat Mar 3 20:11:39 2018 +0000

    First steps in box inclusion in drawings
    
    In contrast to pgf, we want to do everything using driver-level specials
    rather than raw PostScript/PDF. That means that the interfaces need to
    be adjusted to avoid using translations at the driver level: these have
    to be done in TeX.
    
    There are various corrections to the driver code here.
    
    At present, the SVG path may be completely out-of-line.
    
    Note that some skews seem to mislead dvips/ps2pdf, resulting in entire
    pages rotating. That does not seem to be due to 'leaking' rotations, and
    is therefore likely down to some auto-detection somewhere.


>---------------------------------------------------------------

ec2925efd179405fe5a979cd7fb26cc23aba3376
 l3experimental/l3draw/l3draw-scopes.dtx |   76 +++++++++++++++++++++++++++
 l3kernel/l3drivers.dtx                  |   85 ++++++++++++++++---------------
 2 files changed, 120 insertions(+), 41 deletions(-)

diff --git a/l3experimental/l3draw/l3draw-scopes.dtx b/l3experimental/l3draw/l3draw-scopes.dtx
index 8e8f949..6cff720 100644
--- a/l3experimental/l3draw/l3draw-scopes.dtx
+++ b/l3experimental/l3draw/l3draw-scopes.dtx
@@ -234,6 +234,82 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \subsection{Inserting boxes}
+%
+% 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_hbox_set:Nn}
+%   Collect up the input and box, reset all of the structures and typeset.
+%   Note that in \pkg{pgf} the various reset parts are set up in an auxiliary,
+%   but this is not done here at present as it is all done only once.
+%    \begin{macrocode}
+\cs_new_protected:Npn \draw_hbox_set:Nn #1#2
+  {
+    \hbox_set:Nn #1
+      {
+        \color_ensure_current:
+        \@@_scope_bb_begin:
+        \draw_path_scope_begin:
+        \draw_transform_matrix_reset:
+        \draw_transform_shift_reset:
+          #2
+        \draw_path_scope_end:
+        \@@_scope_bb_end:
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\draw_hbox_use:N}
+%   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.
+%    \begin{macrocode}
+\cs_new_protected:Npn \draw_hbox_use:N #1
+  {
+    \@@_point_process:nn
+      { \@@_path_update_limits:nn }
+      { \draw_point_transform:n { 0pt , \box_dp:N #1 } }
+    \@@_point_process:nn
+      { \@@_path_update_limits:nn }
+      { \draw_point_transform:n { \box_wd:N #1 , \box_dp:N #1 } }
+    \@@_point_process:nn
+      { \@@_path_update_limits:nn }
+      { \draw_point_transform:n { 0pt , \box_ht:N #1 } }
+    \@@_point_process:nn
+      { \@@_path_update_limits:nn }
+      { \draw_point_transform:n { \box_wd:N #1 , \box_ht:N #1 } }
+    \group_begin:
+      \hbox_set:Nn \l_@@_tmp_box
+        {
+          \tex_kern:D \l_@@_xshift_dim
+          \box_move_up:nn { \l_@@_yshift_dim } { \box_use:N #1 }
+        }
+      \box_set_ht:Nn \l_@@_tmp_box { 0pt }
+      \box_set_dp:Nn \l_@@_tmp_box { 0pt }
+      \box_set_wd:Nn \l_@@_tmp_box { 0pt }
+      \use:x
+        {
+          \driver_draw_hbox_use:Nnnnn \l_@@_tmp_box
+            { \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 }
+         }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
 %    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}
diff --git a/l3kernel/l3drivers.dtx b/l3kernel/l3drivers.dtx
index b283ff0..fcccf31 100644
--- a/l3kernel/l3drivers.dtx
+++ b/l3kernel/l3drivers.dtx
@@ -428,7 +428,7 @@
 %
 % \subsection{Inserting \TeX{} material}
 %
-% \begin{function}{\driver_draw_hbox:Nnnnnnn}
+% \begin{function}{\driver_draw_hbox_use:Nnnnn}
 %   \begin{syntax}
 %     \cs{driver_draw_hbox:Nnnnnnn} \meta{box}
 %       \Arg{a} \Arg{b} \Arg{c} \Arg{d} \Arg{x} \Arg{y}
@@ -1179,7 +1179,7 @@
       {
         \fp_compare:nNnTF {#1} = \c_zero_fp
           { 0 }
-          { \fp_eval:n { round ( -#1 , 5 ) } } ~
+          { \fp_eval:n { round ( -#1, 5 ) } } ~
           rotate
       }
     \@@_draw_literal:n
@@ -1192,7 +1192,7 @@
       {
         \fp_compare:nNnTF {#4} = \c_zero_fp
           { 0 }
-          { \fp_eval:n { round ( -#1 , 5 ) } } ~
+          { \fp_eval:n { round ( -#4 , 5 ) } } ~
           rotate
       }
   }
@@ -1200,7 +1200,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\driver_draw_hbox:Nnnnnnn}
+% \begin{macro}{\driver_draw_hbox_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. Instead, we need to reverse the effect of
@@ -1210,7 +1210,7 @@
 %   drawing origin so has to be done purely in driver code not using \TeX{}
 %   offsets.
 %    \begin{macrocode}
-\cs_new_protected:Npn \driver_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7
+\cs_new_protected:Npn \driver_draw_hbox_use:Nnnnn #1#2#3#4#5
   {
     \@@_scope_begin:
     \@@_draw_literal:n { [end] }
@@ -1218,10 +1218,7 @@
     \@@_draw_literal:n { 72~Resolution~div~72~VResolution~div~neg~scale }
     \@@_draw_literal:n { magscale~{1~DVImag~div~dup~scale}~if }
     \@@_draw_literal:n { l3x~neg~l3y~neg~translate }
-    \box_set_wd:Nn #1 { 0pt }
-    \box_set_ht:Nn #1 { 0pt }
-    \box_set_dp:Nn #1 { 0pt }
-    \box_use:N #1
+    \hbox_overlap_right:n { \box_use:N #1 }
     \@@_draw_literal:n { [begin] }
     \@@_scope_end:
   }
@@ -2091,25 +2088,25 @@
 %<*dvipdfmx|xdvipdfmx>
 \cs_new_protected:Npn \@@_draw_cm:nnnn #1#2#3#4
   {
-    \@@_draw_literal:n
+    \tex_special:D
       {
         x:rotate~
         \fp_compare:nNnTF {#1} = \c_zero_fp
           { 0 }
-          { \fp_eval:n { round ( #1 , 5 ) } }
+          { \fp_eval:n { round ( -#1 , 5 ) } }
       }
-    \@@_draw_literal:n
+    \tex_special:D
       {
         x:scale~
         \fp_eval:n { round ( #2 , 5 ) } ~
         \fp_eval:n { round ( #3 , 5 ) }
       }
-    \@@_draw_literal:n
+    \tex_special:D
       {
         x:rotate~
         \fp_compare:nNnTF {#4} = \c_zero_fp
           { 0 }
-          { \fp_eval:n { round ( -#1 , 5 ) } }
+          { \fp_eval:n { round ( -#4 , 5 ) } }
       }
   }
 %</dvipdfmx|xdvipdfmx>
@@ -2117,7 +2114,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\driver_draw_hbox:Nnnnnnn}
+% \begin{macro}{\driver_draw_hbox_use:Nnnnn}
 % \begin{variable}{\l_@@_tmp_box}
 %   Inserting a \TeX{} box transformed to the requested position and using
 %   the current matrix is done using a mixture of \TeX{} and low-level
@@ -2126,19 +2123,12 @@
 %   operation can never be cached, the scope is set directly not using the
 %   \texttt{draw} version.
 %    \begin{macrocode}
-\cs_new_protected:Npn \driver_draw_hbox:Nnnnnnn #1#2#3#4#5#6#7
+\cs_new_protected:Npn \driver_draw_hbox_use:Nnnnn #1#2#3#4#5
   {
-    \hbox_set_to_wd:Nnn \l_@@_tmp_box { 0pt }
-      {
-        \tex_kern:D \dim_eval:n {#6}
-        \driver_draw_scope_begin:
-        \driver_draw_cm:nnnn {#2} {#3} {#4} {#5}
-        \box_move_up:nn {#7} { \box_use:N #1 }
-        \driver_draw_scope_end:
-      }
-    \box_set_ht:Nn \l_@@_tmp_box { 0pt }
-    \box_set_dp:Nn \l_@@_tmp_box { 0pt }
-    \box_use:N \l_@@_tmp_box
+    \driver_draw_scope_begin:
+    \driver_draw_cm:nnnn {#2} {#3} {#4} {#5}
+    \hbox_overlap_right:n { \box_use:N #1 }
+    \driver_draw_scope_end:
   }
 \box_new:N \l_@@_tmp_box
 %    \end{macrocode}
@@ -2778,7 +2768,11 @@
 %
 % \begin{macro}{\@@_draw_cm_decompose:nnnnN}
 % \begin{macro}
-%   {\@@_draw_cm_decompose_auxi:nnnnN, \@@_draw_cm_decompose_auxii:nnnnN}
+%   {
+%     \@@_draw_cm_decompose_auxi:nnnnN,
+%     \@@_draw_cm_decompose_auxii:nnnnN,
+%     \@@_draw_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
@@ -2816,14 +2810,16 @@
 %   \]
 %   From these, we can find that
 %   \begin{align*}
-%     \frac{w_{1} + w_{2}}{1} &= \sqrt{E^{2} + H^{2}} \\
-%     \frac{w_{1} - w_{2}}{1} &= \sqrt{F^{2} + G^{2}} \\
+%     \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.)
+%   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}
 \cs_new_protected:Npn \@@_draw_cm_decompose:nnnnN #1#2#3#4#5
   {
@@ -2831,9 +2827,9 @@
       {
         \@@_draw_cm_decompose_auxi:nnnnN
           { \fp_eval:n { (#1 + #4) / 2 } }
-          { \fp_eval:n { #1 - (#1 + #4) / 2 } }
-          { \fp_eval:n { (#2 + #3) / 2 } }
-          { \fp_eval:n { #2 - (#2 + #3) / 2 } }
+          { \fp_eval:n { (#1 - #4) / 2 } }
+          { \fp_eval:n { (#3 + #2) / 2 } }
+          { \fp_eval:n { (#3 - #2) / 2 } }
       }
         #5
   }
@@ -2842,10 +2838,10 @@
     \use:x
       {
         \@@_draw_cm_decompose_auxii:nnnnN
-          { \fp_eval:n { sqrt ( #1 * #1 + #4 * #4 ) } }
-          { \fp_eval:n { sqrt ( #2 * #2 + #3 * #3 ) } }
-          { \fp_eval:n { atand ( #3 / #2 ) } }
-          { \fp_eval:n { atand ( #4 / #1 ) } }
+          { \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
   }
@@ -2853,12 +2849,19 @@
   {
     \use:x
       {
-        \exp_not:N #5
+        \@@_draw_cm_decompose_auxiii:nnnnN
           { \fp_eval:n { ( #4 - #3 ) / 2 } }
-          { \fp_eval:n { #1 + #2 } }
-          { \fp_eval:n { #1 - #2 } }
+          { \fp_eval:n { ( #1 + #2 ) / 2 } }
+          { \fp_eval:n { ( #1 - #2 ) / 2 } }
           { \fp_eval:n { ( #4 + #3 ) / 2 } }
       }
+        #5
+  }
+\cs_new_protected:Npn \@@_draw_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} }
   }
 %    \end{macrocode}
 % \end{macro}





More information about the latex3-commits mailing list