diff options
author | Karl Berry <karl@freefriends.org> | 2011-09-07 23:33:27 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2011-09-07 23:33:27 +0000 |
commit | f1cddb2ae051713a3d0b9efa1251d8f85d8131fc (patch) | |
tree | 47b6a38de15329b2ffd3a196e7d85e7ad1e93032 /Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx | |
parent | ea06cd2704b8ed1c5278b20798ab9e3811e0ca4e (diff) |
l3kernel 2729 (5sep11)
git-svn-id: svn://tug.org/texlive/trunk@23865 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx | 245 |
1 files changed, 212 insertions, 33 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index 87df9402d1d..8feef032c77 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx @@ -35,8 +35,8 @@ %% % %<*driver|package> -\RequirePackage{l3names,graphicx,color} -\GetIdInfo$Id: l3coffins.dtx 2624 2011-08-18 19:02:45Z joseph $ +\RequirePackage{l3names} +\GetIdInfo$Id: l3coffins.dtx 2717 2011-09-03 13:40:31Z joseph $ {L3 Experimental coffin code layer} %</driver|package> %<*driver> @@ -72,7 +72,7 @@ % for coffins. For details about the design concept of a coffin, see % the \pkg{xcoffins} module (in the \pkg{l3experimental} bundle). % -% \section{Code-level coffin functions} +% \section{Creating and initialising coffins} % % \begin{function}{\coffin_new:N, \coffin_new:c} % \begin{syntax} @@ -99,6 +99,8 @@ % Sets both the content and poles of \meta{coffin1} equal to those % of \meta{coffin2} within the current \TeX\ group level. % \end{function} +% +% \section{Setting coffin content and poles} % % \begin{function}{\hcoffin_set:Nn, \hcoffin_set:cn} % \begin{syntax} @@ -148,7 +150,22 @@ % \cs{Width}, which will evaluate to the appropriate dimensions of % the \meta{coffin}. % \end{function} -% +% +% \section{Coffin transformations} +% +% \begin{function}{\coffin_resize:Nnn, \coffin_resize:cnn} +% \begin{syntax} +% \cs{coffin_resize:Nnn} \meta{coffin} \Arg{width} \Arg{total-height} +% \end{syntax} +% Resized the \meta{coffin} to \meta{width} and \meta{total-height}, +% both of which should be given as dimension expressions. These may +% include the terms \cs{TotalHeight}, \cs{Height}, \cs{Depth} and +% \cs{Width}, which will evaluate to the appropriate dimensions of +% the \meta{coffin}. +% +% \textbf{This function is experimental.} +% \end{function} +% % \begin{function}{\coffin_rotate:Nn, \coffin_rotate:cn} % \begin{syntax} % \cs{coffin_rotate:Nn} \meta{coffin} \Arg{angle} @@ -159,6 +176,19 @@ % the bounding box of the coffin growing unnecessarily. % \end{function} % +% \begin{function}{\coffin_scale:Nnn, \coffin_scale:cnn} +% \begin{syntax} +% \cs{coffin_scale:Nnn} \meta{coffin} \Arg{x-scale} \Arg{y-scale} +% \end{syntax} +% Scales the \meta{coffin} by a factors \meta{x-scale} and +% \meta{y-scale} in the horizontal and vertical directions, +% respectively. The two scale factors should be given as real numbers. +% +% \textbf{This function is experimental.} +% \end{function} +% +% \section{Joining and using coffins} +% % \begin{function} % { % \coffin_attach:NnnNnnnn, \coffin_attach:cnnNnnnn, @@ -221,6 +251,8 @@ % therefore analogous to carrying out an alignment where the % \enquote{parent} coffin is the current insertion point. % \end{function} +% +% \section{Coffin diagnostics} % % \begin{function}{\coffin_display_handles:cn, \coffin_display_handles:cn} % \begin{syntax} @@ -476,12 +508,12 @@ \cs_if_exist:cTF { l_coffin_poles_ \int_value:w #1 _prop } { #2 } { - \msg_kernel_error:nnx { coffin } { unknown-coffin } + \msg_kernel_error:nnx { coffins } { unknown-coffin } { \token_to_str:N #1 } } } { - \msg_kernel_error:nnx { coffin } { unknown-coffin } + \msg_kernel_error:nnx { coffins } { unknown-coffin } { \token_to_str:N #1 } } } @@ -535,15 +567,10 @@ { \hbox_set:Nn #1 { - \group_begin: -%<*initex> - \color_set_current: % TODO -%</initex> -%<*package> - \set@color -%</package> + \color_group_begin: + \color_ensure_current: #2 - \group_end: + \color_group_end: } \coffin_reset_structure:N #1 \coffin_update_poles:N #1 @@ -567,15 +594,10 @@ \vbox_set:Nn #1 { \dim_set:Nn \tex_hsize:D {#2} - \group_begin: -%<*initex> - \color_set_current: -%</initex> -%<*package> - \set@color -%</package> + \color_group_begin: + \color_ensure_current: #3 - \group_end: + \color_group_end: } \coffin_reset_structure:N #1 \coffin_update_poles:N #1 @@ -641,7 +663,7 @@ \prop_get:cnNF { l_coffin_poles_ \int_value:w #1 _prop } {#2} #3 { - \msg_kernel_error:nnxx { coffin } { unknown-coffin-pole } + \msg_kernel_error:nnxx { coffins } { unknown-coffin-pole } {#2} { \token_to_str:N #1 } \tl_set:Nn #3 { { 0 pt } { 0 pt } { 0 pt } { 0 pt } } } @@ -843,7 +865,7 @@ \l_coffin_pole_a_tl \l_coffin_pole_b_tl \bool_if:NT \l_coffin_error_bool { - \msg_kernel_error:nn { coffin } { no-pole-intersection } + \msg_kernel_error:nn { coffins } { no-pole-intersection } \dim_zero:N \l_coffin_x_dim \dim_zero:N \l_coffin_y_dim } @@ -1379,12 +1401,7 @@ % \begin{macrocode} \coffin_find_corner_maxima:N #1 \coffin_find_bounding_shift: -%<*initex> - \hbox_set:Nn #1 { \box_rotate:Nn #1 {#2} } % TODO -%</initex> -%<*package> - \hbox_set:Nn #1 { \rotatebox {#2} { \box_use:N #1 } } -%</package> + \box_rotate:Nn #1 {#2} % \end{macrocode} % The correction of the box position itself takes place here. The idea % is that the bounding box for a coffin is tight up to the content, and @@ -1587,6 +1604,168 @@ % \end{macrocode} % \end{macro} % \end{macro} +% +% \subsection{Resizing coffins} +% +% \begin{variable}{\l_coffin_scale_x_fp} +% \begin{variable}{\l_coffin_scale_y_fp} +% Storage for the scaling factors in $x$ and $y$, respectively. +% \begin{macrocode} +\fp_new:N \l_coffin_scale_x_fp +\fp_new:N \l_coffin_scale_y_fp +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{variable}{\l_coffin_scaled_total_height_dim} +% \begin{variable}{\l_coffin_scaled_width_dim} +% When scaling, the values given have to be turned into absolute values. +% \begin{macrocode} +\dim_new:N \l_coffin_scaled_total_height_dim +\dim_new:N \l_coffin_scaled_width_dim +% \end{macrocode} +% \end{variable} +% \end{variable} +% +% \begin{macro}{\coffin_resize:Nnn, \coffin_resize:cnn} +% Resizing a coffin begins by setting up the user-friendly names for +% the dimensions of the coffin box. The new sizes are then turned into +% scale factor. This is the same operation as takes place for the +% underlying box, but that operation is grouped and so the same +% calculation is done here. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_resize:Nnn #1#2#3 + { + \coffin_set_user_dimensions:N #1 + \box_resize:Nnn #1 {#2} {#3} + \fp_set_from_dim:Nn \l_coffin_scale_x_fp {#2} + \fp_set_from_dim:Nn \l_coffin_tmp_fp { \Width } + \fp_div:Nn \l_coffin_scale_x_fp { \l_coffin_tmp_fp } + \fp_set_from_dim:Nn \l_coffin_scale_y_fp {#3} + \fp_set_from_dim:Nn \l_coffin_tmp_fp { \TotalHeight } + \fp_div:Nn \l_coffin_scale_y_fp { \l_coffin_tmp_fp } + \coffin_resize_common:Nnn #1 {#2} {#3} + } +\cs_generate_variant:Nn \coffin_resize:Nnn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_resize_common:Nnn} +% The poles and corners of the coffin are scaled to the appropriate +% places before actually resizing the underlying box. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_resize_common:Nnn #1#2#3 + { + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_scale_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_scale_pole:Nnnnnn #1 {##1} ##2 } +% \end{macrocode} +% Negative $x$-scaling values will place the poles in the wrong +% location: this is corrected here. +% \begin{macrocode} + \fp_compare:NNNT \l_coffin_scale_x_fp < \c_zero_fp + { + \prop_map_inline:cn { l_coffin_corners_ \int_value:w #1 _prop } + { \coffin_x_shift_corner:Nnnn #1 {##1} ##2 } + \prop_map_inline:cn { l_coffin_poles_ \int_value:w #1 _prop } + { \coffin_x_shift_pole:Nnnnnn #1 {##1} ##2 } + } + \coffin_end_user_dimensions: + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_scale:Nnn, \coffin_scale:cnn} +% For scaling, the opposite calculation is done to find the new +% dimensions for the coffin. Only the total height is needed, as this +% is the shift required for corners and poles. The scaling is done +% the \TeX{} way as this works properly with floating point values +% without needing to use the \texttt{fp} module. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_scale:Nnn #1#2#3 + { + \box_scale:Nnn #1 {#2} {#3} + \coffin_set_user_dimensions:N #1 + \fp_set:Nn \l_coffin_scale_x_fp {#2} + \fp_set:Nn \l_coffin_scale_y_fp {#3} + \fp_compare:NNNTF \l_coffin_scale_y_fp > \c_zero_fp + { \l_coffin_scaled_total_height_dim #3 \TotalHeight } + { \l_coffin_scaled_total_height_dim -#3 \TotalHeight } + \fp_compare:NNNTF \l_coffin_scale_x_fp > \c_zero_fp + { \l_coffin_scaled_width_dim -#2 \Width } + { \l_coffin_scaled_width_dim #2 \Width } + \coffin_resize_common:Nnn #1 + { \l_coffin_scaled_width_dim } { \l_coffin_scaled_total_height_dim } + } +\cs_generate_variant:Nn \coffin_scale:Nnn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_scale_vector:nnNN} +% This functions scales a vector from the origin using the pre-set scale +% factors in $x$ and $y$. This is a much less complex operation +% than rotation, and as a result the code is a lot clearer. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_scale_vector:nnNN #1#2#3#4 + { + \fp_set_from_dim:Nn \l_coffin_tmp_fp {#1} + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_scale_x_fp } + \dim_set:Nn #3 { \fp_to_dim:N \l_coffin_tmp_fp } + \fp_set_from_dim:Nn \l_coffin_tmp_fp {#2} + \fp_mul:Nn \l_coffin_tmp_fp { \l_coffin_scale_y_fp } + \dim_set:Nn #4 { \fp_to_dim:N \l_coffin_tmp_fp } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\coffin_scale_corner:Nnnn} +% \begin{macro}{\coffin_scale_pole:Nnnnnn} +% Scaling both corners and poles is a simple calculation using the +% preceding vector scaling. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_scale_corner:Nnnn #1#2#3#4 + { + \coffin_scale_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } {#2} + { { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } } + } +\cs_new_protected_nopar:Npn \coffin_scale_pole:Nnnnnn #1#2#3#4#5#6 + { + \coffin_scale_vector:nnNN {#3} {#4} \l_coffin_x_dim \l_coffin_y_dim + \coffin_set_pole:Nnx #1 {#2} + { + { \dim_use:N \l_coffin_x_dim } { \dim_use:N \l_coffin_y_dim } + {#5} {#6} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\coffin_x_shift_corner:Nnnn} +% \begin{macro}{\coffin_x_shift_pole:Nnnnnn} +% These functions correct for the $x$ displacement that takes +% place with a negative horizontal scaling. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \coffin_x_shift_corner:Nnnn #1#2#3#4 + { + \prop_put:cnx { l_coffin_corners_ \int_value:w #1 _prop } {#2} + { + { \dim_eval:n { #3 + \box_wd:N #1 } } {#4} + } + } +\cs_new_protected_nopar:Npn \coffin_x_shift_pole:Nnnnnn #1#2#3#4#5#6 + { + \prop_put:cnx { l_coffin_poles_ \int_value:w #1 _prop } {#2} + { + { \dim_eval:n #3 + \box_wd:N #1 } {#4} + {#5} {#6} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \subsection{Coffin diagnostics} % @@ -1954,7 +2133,7 @@ % \subsection{Messages} % % \begin{macrocode} -\msg_kernel_new:nnnn { coffin } { no-pole-intersection } +\msg_kernel_new:nnnn { coffins } { no-pole-intersection } { No~intersection~between~coffin~poles. } { \c_msg_coding_error_text_tl @@ -1962,10 +2141,10 @@ but~they~do~not~have~a~unique~meeting~point:~ the~value~(0~pt,~0~pt)~will~be~used. } -\msg_kernel_new:nnnn { coffin } { unknown-coffin } +\msg_kernel_new:nnnn { coffins } { unknown-coffin } { Unknown~coffin~'#1'. } { The~coffin~'#1'~was~never~defined. } -\msg_kernel_new:nnnn { coffin } { unknown-coffin-pole } +\msg_kernel_new:nnnn { coffins } { unknown-coffin-pole } { Pole~'#1'~unknown~for~coffin~'#2'. } { \c_msg_coding_error_text_tl |