summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-09-07 23:33:27 +0000
committerKarl Berry <karl@freefriends.org>2011-09-07 23:33:27 +0000
commitf1cddb2ae051713a3d0b9efa1251d8f85d8131fc (patch)
tree47b6a38de15329b2ffd3a196e7d85e7ad1e93032 /Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx
parentea06cd2704b8ed1c5278b20798ab9e3811e0ca4e (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.dtx245
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