% \iffalse meta-comment % %% File: l3coffins.dtx Copyright(C) 2010,2011 The LaTeX3 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 %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the "l3experimental bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- %% % %<*driver|package> \RequirePackage{expl3} \GetIdInfo$Id: l3coffins-scaling.dtx 2678 2011-08-28 07:02:32Z joseph $ {L3 Experimental coffin scaling code} % %<*driver> \documentclass[full]{l3doc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \textsf{l3coffins-scaling} package\\ Scaling coffins^^A % \thanks{This file describes v\ExplFileVersion, % last revised \ExplFileDate.}^^A % } % % \author{^^A % The \LaTeX3 Project\thanks % {^^A % E-mail: % \href{mailto:latex-team@latex-project.org} % {latex-team@latex-project.org}^^A % }^^A % } % % \date{Released \ExplFileDate} % % \maketitle % % \begin{documentation} % % The material in this module provides low-level support for scaling % and resizing coffins. The core coffin implementation is found in % \pkg{l3coffins} in the \pkg{l3kernel} bundle. In contrast to that stable % code, this code is highly experimental. % % \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}. % \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. % \end{function} % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3coffins-scaling} Implementation} % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macrocode} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} % \end{macrocode} % % \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 \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 } \hbox_set:Nn #1 { \resizebox * {#2} {#3} { \box_use:N #1 } } \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 { \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 } \hbox_set:Nn #1 { \scalebox {#2} [#3] { \box_use:N #1 } } \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} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex