tinycobol/test.code/ReportGen/trans.tex

292 lines
12 KiB
TeX

%---------------------------------------------------------------
% PostScript transformations for DVIPS (c) BOP 1993, 1994
% BOP s.c.
% ul. Piastowska 70, 80-363 Gda\'nsk, Poland
% tel. +48 58 53-46-59
% email: jacko@ipipan.gda.pl
%
%---------------------------------------------------------------
% USAGE:
%
% 1)
% x_scale and y_scale are given in percents:
% \zscale changes uniformly x_size and y_size (x_scale=y_scale=scale);
% \xscale changes only x_size (y_scale=100);
% \yscale changes only y_size (x_scale=100);
%
% \zscale{scale} followed by an \hbox or a \vbox
% \xyscale{x_scale}{y_scale} followed by an \hbox or a \vbox
% \yxscale{y_scale}{x_scale} followed by an \hbox or a \vbox
% \xscale{x_scale} followed by an \hbox or a \vbox
% \yscale{y_scale} followed by an \hbox or a \vbox
%
% 2)
% \xyscaleto resizes a box uniformly such that the resulting wd=x_dimen;
% \yxscaleto resizes a box uniformly such that the resulting ht=y_dimen;
% \xscaleto resizes a box horizontally such that the resulting wd=x_dimen;
% \yscaleto resizes a box verically such that the resulting ht=y_dimen;
%
% \xyscaleto{x_size} followed by an \hbox or a \vbox
% \yxscaleto{y_size} followed by an \hbox or a \vbox
% \xscaleto{x_size} followed by an \hbox or a \vbox
% \yscaleto{y_size} followed by an \hbox or a \vbox
%
% 3)
% \revolve rotates anticlockwise the box (either \hbox or \vbox
% following the command) by 90 degree; for the resulting box
% width = height + depth of the original box, height = width
% of the original box, and the reference point is the left top corner
% of the original box; this means that revolving a box four times
% yields the original box if and only if its depth is zero.
% \revolvedir- is equivalent to \revolve, \revolvedir+ does almost
% the same, but rotates the box clockwise;
%
% \revolve followed by an \hbox or a \vbox
% \revolvedir+ followed by an \hbox or a \vbox
% \revolvedir- followed by an \hbox or a \vbox
%
% 4)
% \rotate rotates a box bay an arbitrary angle, clockwise for angle>0,
% the resulting box width=height=depth=0pt;
%
% \rotate{angle} followed by an \hbox or a \vbox
%
% 5)
% \xflip and \yflip flip the box horizontally and vertically, resp.,
% i.e., with respect to a vertical and horizontal axis of the box,
% without changing dimensions of the \box;
%
% \xflip followed by an \hbox or a \vbox
% \yflip followed by an \hbox or a \vbox
%
% 6)
% \slant slopes a box by the angle alpha such that tan(alpha)=slant,
% without changing dimensions of the \box;
%
% \slant{slant} followed by an \hbox or a \vbox
%
%---------------------------------------------------------------
% HISTORY:
% 18 VIII 1993 ver. 0.1
% * first release
% 30--31 VIII 1993 ver. 0.2
% * third parameter eliminated from \scale (via \afterassignment
% and \aftergroup hackery)
% * added \zscale, \xyscale, \yxscale, \xscale, and \yscale
% with scaling given in percents
% * added \scaleto, \xyscaleto, \yxscaleto, \xscaleto, and \yscaleto
% 3 IX 1993 ver. 0.21
% * \the_scale renamed to \lastscale and made global, thus it became
% available to a user
% 8 IX 1993 ver. 0.22
% * all transformations return \hbox, because of currentpoint
% positioning
% * the old version of \scale is become undefined
% * \slant and \rotate fit the new convention of parameter's
% hackery -- they are assumed to be followed by an \hbox
% or a \vbox
% 6 XII 1993 ver. 0.23
% * \revolve added
% * \rotate with \vbox patched
% 10 II 1994 ver. 0.24
% * \revolvedir+, \revolvedir-, \xflip, and \yflip added
%---------------------------------------------------------------
\edef\undtranscode{\the\catcode`\_} \catcode`\_11
%---------------------------------------------------------------
\newbox\box_tmp % temporary box register
\newdimen\dim_tmp % temporary dimen register (for arithmetic manipulation)
%---------------------------------------------------------------
\def\jump_setbox{\aftergroup\after_setbox}% a general trick
%---------------------------------------------------------------
% ``floating point arithmetic'' (excerpted from T. Rokicki):
% r y
%
% ^
% |
% |
% |
% |
% |
% 0--------------> t x
%
\def\resize
% dimen registers:
#1% y make y such that y/r=x/t
#2% r
#3% x
#4% t
% We have a sticky problem here: TeX doesn't do floating point arithmetic!
% Our goal is to compute y = rx/t. The following loop does this reasonably
% fast, with an error of at most about 16 sp (about 1/4000 pt).
{%
% save parameters to the internal variables:
\dim_r#2\relax \dim_x#3\relax \dim_t#4\relax
\dim_tmp=\dim_r \divide\dim_tmp\dim_t
\dim_y=\dim_x \multiply\dim_y\dim_tmp
\multiply\dim_tmp\dim_t \advance\dim_r-\dim_tmp
\dim_tmp=\dim_x
\loop \advance\dim_r\dim_r \divide\dim_tmp 2
\ifnum\dim_tmp>0
\ifnum\dim_r<\dim_t\else
\advance\dim_r-\dim_t \advance\dim_y\dim_tmp \fi
\repeat
% assign result:
#1\dim_y\relax
}
\newdimen\dim_x % horizontal size after scaling
\newdimen\dim_y % vertical size after scaling
\newdimen\dim_t % horizontal size before scaling
\newdimen\dim_r % vertical size before scaling
%\newdimen\dim_tmp % register for arithmetic manipulation (already declared)
%---------------------------------------------------------------
\def\perc_scale#1#2{% #1 -- xscale, #2 -- yscale, in percents,
% to be followed by an \hbox or a \vbox
\def\after_setbox{%
\hbox\bgroup
\special{ps: gsave currentpoint #2 100 div div exch #1 100 div div exch
currentpoint neg #2 100 div mul exch neg #1 100 div mul exch
translate #1 100 div #2 100 div scale translate}%
\dim_tmp\wd\box_tmp \divide\dim_tmp100 \wd\box_tmp#1\dim_tmp
\dim_tmp\ht\box_tmp \divide\dim_tmp100 \ht\box_tmp#2\dim_tmp
\dim_tmp\dp\box_tmp \divide\dim_tmp100 \dp\box_tmp#2\dim_tmp
\box\box_tmp \special{ps: grestore}\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
%---------------------------------------------------------------
{\catcode`\p12 \catcode`\t12 \gdef\PT_{pt}}
\def\hull_num{\expandafter\hull_num_}
\expandafter\def\expandafter\hull_num_\expandafter#\expandafter1\PT_{#1}
%---------------------------------------------------------------
\def\find_scale#1#2{% #1 -- size after rescaling, #2 -- \wd or \ht
% Finds a scale (\lastscale macro) such that the box following the macro
% call would have the respective dimen (i.e., #2) equal to #1 after rescaling.
% NOTE: it is assumed that prior to calling \find_scale a macro
% \extra_complete is defined.
\def\after_setbox{%
\resize\dim_tmp{100pt}{#1}{#2\box_tmp}%
\xdef\lastscale{\hull_num\the\dim_tmp}\extra_complete}%
\afterassignment\jump_setbox\setbox\box_tmp =
}
%---------------------------------------------------------------
\def\scaleto#1#2#3#4{% #1 -- size of dimen #2 (\wd or \ht) after scaling
% #3 -- actual x-size, #4 -- actual y-size
\def\extra_complete{\perc_scale{#3}{#4}\hbox{\box\box_tmp}}%
\find_scale{#1}#2}
%---------------------------------------------------------------
\let\xyscale\perc_scale
\def\zscale#1{\xyscale{#1}{#1}}
\def\yxscale#1#2{\xyscale{#2}{#1}}
\def\xscale#1{\xyscale{#1}{100}}
\def\yscale#1{\xyscale{100}{#1}}
%---------------------------------------------------------------
\def\xyscaleto#1{\scaleto{#1}\wd\lastscale\lastscale}
\def\yxscaleto#1{\scaleto{#1}\ht\lastscale\lastscale}
\def\xscaleto#1{\scaleto{#1}\wd\lastscale{100}}
\def\yscaleto#1{\scaleto{#1}\ht{100}\lastscale}
%---------------------------------------------------------------
\def\slant#1{% #1 (slant) = tan(alpha), where alpha is the "italic" angle.
% To be followed by an \hbox or a \vbox
\hbox\bgroup
\def\after_setbox{%
\special{ps: gsave 0 currentpoint neg exch pop 0 currentpoint exch pop
translate [1 0 #1 1 0 0] concat translate}%
\box\box_tmp \special{ps: grestore}\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
%---------------------------------------------------------------
\def\rotate#1{% #1 -- angle,
% to be followed by an \hbox or a \vbox
\hbox\bgroup
\def\after_setbox{%
\setbox\box_tmp\hbox{\box\box_tmp}% otherwise does not work with \vbox
\wd\box_tmp 0pt \ht\box_tmp 0pt \dp\box_tmp 0pt
\special{ps: gsave currentpoint currentpoint translate
#1 rotate neg exch neg exch translate}%
\box\box_tmp
\special{ps: grestore}%
\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
%---------------------------------------------------------------
\newdimen\box_tmp_dim_a
\newdimen\box_tmp_dim_b
\newdimen\box_tmp_dim_c
\def\plus_{+}
\def\minus_{-}
\def\revolvedir#1{% to be followed by an \hbox or a \vbox
\hbox\bgroup
% check parameter:
\def\param_{#1}%
\ifx\param_\plus_ \else \ifx\param_\minus_
\else
\errhelp{I would rather suggest to stop immediately.}%
\errmessage{Argument to \noexpand\revolvedir should be either + or -}%
\fi\fi
\def\after_setbox{%
\box_tmp_dim_a\wd\box_tmp
% prepare to revolving:
\setbox\box_tmp\hbox{%
\ifx\param_\plus_\kern-\box_tmp_dim_a\fi
\box\box_tmp
\ifx\param_\plus_\kern\box_tmp_dim_a\fi}%
% compute dimensions of the box to be revolved:
\box_tmp_dim_a\ht\box_tmp \advance\box_tmp_dim_a\dp\box_tmp
\box_tmp_dim_b\ht\box_tmp \box_tmp_dim_c\dp\box_tmp
\dp\box_tmp0pt \ht\box_tmp\wd\box_tmp \wd\box_tmp\box_tmp_dim_a
% revolve:
\kern \ifx\param_\plus_ \box_tmp_dim_c \else \box_tmp_dim_b \fi
\special{ps: gsave currentpoint currentpoint translate
#190 rotate neg exch neg exch translate}%
\box\box_tmp
\special{ps: grestore}%
\kern -\ifx\param_\plus_ \box_tmp_dim_c \else \box_tmp_dim_b \fi
\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
\def\revolve{\revolvedir-}
%---------------------------------------------------------------
\def\xflip{% to be followed by an \hbox or a \vbox
\hbox\bgroup
\def\after_setbox{%
\box_tmp_dim_a.5\wd\box_tmp
% prepare to flipping:
\setbox\box_tmp
\hbox{\kern-\box_tmp_dim_a \box\box_tmp \kern\box_tmp_dim_a}%
% flip:
\kern\box_tmp_dim_a
\special{ps: gsave currentpoint currentpoint translate
[-1 0 0 1 0 0] concat neg exch neg exch translate}%
\box\box_tmp
\special{ps: grestore}%
\kern-\box_tmp_dim_a
\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
%---------------------------------------------------------------
\def\yflip{% to be followed by an \hbox or a \vbox
\hbox\bgroup
\def\after_setbox{%
\box_tmp_dim_a\ht\box_tmp \box_tmp_dim_b\dp\box_tmp
\box_tmp_dim_c\box_tmp_dim_a \advance\box_tmp_dim_c\box_tmp_dim_b
\box_tmp_dim_c.5\box_tmp_dim_c
% prepare to flipping:
\setbox\box_tmp\hbox{\vbox{%
\kern\box_tmp_dim_c\box\box_tmp\kern-\box_tmp_dim_c}}%
% flip:
\advance\box_tmp_dim_c-\box_tmp_dim_b
\setbox\box_tmp\hbox{%
\special{ps: gsave currentpoint currentpoint translate
[1 0 0 -1 0 0] concat neg exch neg exch translate}%
\lower\box_tmp_dim_c\box\box_tmp
\special{ps: grestore}}%
% restore dimensions of the flipped box:
\ht\box_tmp\box_tmp_dim_a \dp\box_tmp\box_tmp_dim_b
\box\box_tmp
\egroup}%
\afterassignment\jump_setbox\setbox\box_tmp =
}%
%---------------------------------------------------------------
\catcode`\_\undtranscode
%---------------------------------------------------------------
\endinput