diff --git a/l3experimental/l3draw/l3draw-scopes.dtx b/l3experimental/l3draw/l3draw-scopes.dtx index 8e8f9495e0..6cff7201c0 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} % % \end{macrocode} diff --git a/l3kernel/l3drivers.dtx b/l3kernel/l3drivers.dtx index b283ff0ae2..fcccf31bc8 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 ) } } } } % @@ -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}