diff options
Diffstat (limited to 'Master/texmf-dist/tex/generic/tex-ps/trans.tex')
-rw-r--r-- | Master/texmf-dist/tex/generic/tex-ps/trans.tex | 653 |
1 files changed, 653 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/generic/tex-ps/trans.tex b/Master/texmf-dist/tex/generic/tex-ps/trans.tex new file mode 100644 index 00000000000..a3869832f6c --- /dev/null +++ b/Master/texmf-dist/tex/generic/tex-ps/trans.tex @@ -0,0 +1,653 @@ +% --------------------------------------------------------------------------- +% TeX macros implementing a standard set of PostScript transformations +% made in BOP (1993--2001), Gda\'nsk, Poland -- public domain software +% authors: Bogus\l{}aw Jackowski, Piotr Pianowski, Piotr Strzelczyk +% e-mail contact: bop@bop.com.pl +% --------------------------------------------------------------------------- +% S Y N O P S I S +% +% In the sequel, `box' means \hbox, \vbox, \box, or \copy, `dimen' means +% a sequence of dimens to be summed up; all macros mentioned below expand +% to \hbox{...}, they can therefore be used wherever \hbox can be. +% +% 1) +% x_scale and y_scale are given in percents (>0) +% \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 a box +% \xyscale{x_scale}{y_scale} followed by a box +% \yxscale{y_scale}{x_scale} followed by a box +% \xscale{x_scale} followed by a box +% \yscale{y_scale} followed by a box +% +% 2) +% \xyscaleto resizes a box uniformly such that the resulting wd=dimen +% \yxscaleto resizes a box uniformly such that the resulting ht=dimen +% \xscaleto resizes a box horizontally such that the resulting wd=dimen +% \yscaleto resizes a box verically such that the resulting ht=dimen +% +% \xyscaleto{dimen} followed by a box +% \yxscaleto{dimen} followed by a box +% \xscaleto{dimen} followed by a box +% \yscaleto{dimen} followed by a box +% +% 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+ rotates +% the box clockwise +% +% \revolve followed by a box +% \revolvedir+ followed by a box +% \revolvedir- followed by a box +% \revolveleft followed by a box (equivalent to \revolvedir-) +% \revolveright followed by a box (equivalent to \revolvedir+) +% \revolvepi followed by a box (equivalent to \xflip\yflip +% but not to \revolve\revolve) +% \rotatepi followed by a box (equivalent to \revolvepi; +% cf. also plain METAFONT rotatedaround and rotatedabout macros) +% 4) +% \rotate rotates a box by an arbitrary angle, clockwise for angle>0, +% width=height=depth=0pt for the resulting box +% +% \rotate{angle} followed by a box +% +% \rotatebb rotates a box by an arbitrary angle, clockwise for angle>0; +% the result is placed in a box having the dimensions of the resulting +% bounding box, protrusion to the left is compensated by appropriate +% shifting (see the macro \put_into_bb) +% +% \rotatebb{angle} followed by a box +% +% 5) +% \xflip and \yflip flip the box horizontally and vertically, +% respectively, i.e., with respect to the vertical and horizontal +% axis of the box, without changing the dimensions of the \box +% +% \xflip followed by a box +% \yflip followed by a box +% +% 6) +% \slant slopes a box by an angle alpha such that tan(alpha)=slant, +% without changing dimensions of the \box; +% +% \slant{slant} followed a box +% +% (negative argument value means slanting to the left) +% +% \slantbb slopes a box by an angle alpha such that tan(alpha)=slant, +% the result is placed in a box having the dimensions of the resulting +% bounding box, protrusion to the left is compensated by appropriate +% shifting (see the macro \put_into_bb) +% +% \slantbb{slant} followed a box +% +% 7) +% \clipbox clips the contents of a box that follows the command; +% the macro expects three dimen parameters: the width, the height +% and the depth of the resulting box +% +% \clipbox{width}{height}{depth} followed a box +% +% Any parameter can be empty; in such a case, the respective dimension +% of the original box is used +% --------------------------------------------------------------------------- +% 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 +% 20 III 2000 ver. 0.5 (pre-release) +% * total reconstruction: +% -- all macros expand to \hbox, so that it is possible to +% superpose them, e.g., \xscale{200}\yscale{50}\hbox{...}; +% one must remeber, however, that \rotate yields a box having +% null dimensions, so an attempt to scale the result +% to a given dimen will produce erroneous PostScript code +% -- the possibility of changing \ht and \dp of a \vbox abolished; +% such an operation yields hardly intuitive results; try, e.g.: +% \hrule width\hsize +% \hbox{\setbox0\hbox{\vrule height1cmwidth1cm}\ht0 0mm \box0} +% \kern20mm +% \hrule width\hsize +% \hbox{\setbox0\vbox{\hrule height1cmwidth1cm}\ht0 0mm \box0} +% -- the box expected by all macros can be a TeX box expression: +% \hbox, \vbox, \box, and \copy +% -- scaling height or width to a given dimension yields exact value +% of the height or width, respectively (or both); this change is +% backward incompatible (but reasonable, one should think) +% -- all transformations store information about the position of the +% lower left corner and the upper right corner of the resulting +% bounding box (with respect to the base point of the transformed +% box) in four globally defined macros: +% \transllx, \translly, \transurx, \transury +% (a piece of funny code for vector rotation was added) +% -- \rotatebb and \slantbb added +% 25 III 2000 ver. 0.51 +% * fraction multiplication improved (speedup in trigonometric +% calculations ca 30%) +% * trigonometry calculations are performed in a group (otherwise using +% them within another \loop ... \repeat would be inconvenient); +% the result is a pair of globally defined macros (instead of dimen +% registers); they expand to a series of digits (i.e., they contain +% a count representation of the resulting dimen) +% * \unhbox (introduced in order to reduce the level of box nesting) +% should be used only in \rotatebb +% * internal macro naming changed +% 27 III 2000 ver. 0.52 +% * a dimen parameter can be a sequence of dimens to be summed up +% * \clipbox added +% 7--10 X 2000 ver. 0.53 +% * a bug in \slant[bb] fixed: \ht and \dp were interchanged due to +% a fallacious interpretation of a slant sign (recall that in dvips +% PostScript, unlike in METAFONT, `-' denotes slanting to the right, +% `+' -- to the left, because the y-axis is directed downwards); +% actually, the problem is much more complex: relying (unconsciously) +% on dvips coordinates means, in this case, that for non-square pixels +% both rotate and slant will not work -- need to be fixed! +% 13 XI 2000 ver. 0.54 +% * @ is a letter during reading trans macros (AMSTeX uses active @) +% * local macro \undtranscode renamed to \transundcode +% 9 VI 2001 ver 0.55 +% * ``mnemonic'' macros added: \revolveleft, \revolveright, \revolvepi +% and \rotatepi +% --------------------------------------------------------------------------- +\def\transspecial#1{\special{ps:#1}}% driver-oriented; default is dvips +% --- +\edef\transundcode{\the\catcode`\_}\catcode`\_11 +\edef\transatcode{\the\catcode`\@}\catcode`\@11 +% \z@ (0pt) and \p@ (1pt) are borrowed from plain +% --- +% a pretty general macro +\def\sumto#1{\def\sum_to_what{#1}\sum_to_what=\z@\relax \sumto_} +\def\sumto_{\futurelet\sum_tok\sumto__} +\def\sumto__{\ifx\sum_tok\relax\else\expandafter\sumto___\fi} +\def\sumto___{\afterassignment\sumto_\advance\sum_to_what} +% --- +\newbox\tmp_box % temporary box register +\newdimen\tmp_dim % temporary dimen registers +\newdimen\tmp_dim_a +\newdimen\tmp_dim_b +\newdimen\tmp_dim_c +\newdimen\tmp_dim_d +\newcount\tmp_count_a % temporary count registers +\newcount\tmp_count_b +\newcount\tmp_count_c +\newif\ifput_into_bb +% --- +\def\jump_setbox{\ifvoid\tmp_box % every box is initially void + \aftergroup\after_setbox \else \after_setbox \fi}% a general trick +% --- +\def\set_std_bb{% + \xdef\transllx{\the\z@}% + \xdef\translly{\ifdim\dp\tmp_box>\z@ -\fi\the\dp\tmp_box}% + \xdef\transurx{\the\wd\tmp_box}% + \xdef\transury{\the\ht\tmp_box}% +} +\def\put_into_bb#1{% #1 = operation: \unhbox for rotation, \box for slanting + \setbox\tmp_box\hbox{\kern-\transllx\rlap{#1\tmp_box}\kern\transurx}% + \ht\tmp_box\transury \dp\tmp_box-\translly \relax +} +% --- +\def\perc_scale#1#2{% #1 -- xscale, #2 -- yscale, in percents, + % to be followed by an \hbox or a \vbox + \def\after_setbox{% + \setbox\tmp_box\hbox{% + \transspecial{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}% + \box\tmp_box \transspecial{grestore}}% + \ifdim#1\p@=100\p@ \else % special treatment of special case (100%) + \tmp_dim\wd\tmp_box + \advance\tmp_dim50sp \divide\tmp_dim100 % rounding rather than floor + \wd\tmp_box#1\tmp_dim + \fi + \ifdim#2\p@=100\p@ \else % ditto + \tmp_dim\ht\tmp_box + \advance\tmp_dim50sp \divide\tmp_dim100 % ditto + \ht\tmp_box#2\tmp_dim + \tmp_dim\dp\tmp_box + \advance\tmp_dim50sp \divide\tmp_dim100 % ditto + \dp\tmp_box#2\tmp_dim + \fi + \set_std_bb + \box\tmp_box\egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +% --- +\def\xyscale#1#2{\hbox\bgroup\perc_scale{#1}{#2}} +\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}} +% --- +{\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\tmp_dim{100\p@}{#1}{#2\tmp_box}% + \xdef\lastscale{\hull_num\the\tmp_dim}\extra_complete}% + \afterassignment\jump_setbox\setbox\tmp_box = +} +% --- +\def\scaleto#1#2#3#4{% #1 -- size of dimen #2 (\wd or \ht) after scaling + % #3 -- actual x-size, #4 -- actual y-size + \hbox\bgroup % `initial' hbox + \sumto\tmp_dim#1\relax % freeze the argument; must not be empty + \setbox\tmp_box\hbox\bgroup % one more setbox in order to control + % the specified dimen + \def\extra_complete{% + \perc_scale{#3}{#4}\box\tmp_box % finish setbox above + #2\tmp_box=\tmp_dim % force the exactness of the specified dimension + \set_std_bb + \box\tmp_box + \egroup % close `initial' hbox + }% + \find_scale{\tmp_dim}#2} +% +\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{\hbox\bgroup \put_into_bbfalse \slant_} +\def\slantbb{\hbox\bgroup \put_into_bbtrue \slant_} +\def\slant_#1{% #1 (slant) = tan(alpha), where alpha is the slant angle, + % to be followed by a box + \def\after_setbox{% + \transspecial{gsave 0 currentpoint neg exch pop 0 currentpoint exch pop + translate [1 0 #1 1 0 0] concat translate}% + % set bounding box + \dim_x\wd\tmp_box + \ifdim#1\p@>\z@ \dim_t-#1\ht\tmp_box \advance\dim_x#1\dp\tmp_box + \else \dim_t#1\dp\tmp_box \advance\dim_x-#1\ht\tmp_box + \fi + \xdef\transllx{\the\dim_t}% + \xdef\translly{\ifdim\dp\tmp_box>\z@ -\fi\the\dp\tmp_box}% + \xdef\transurx{\the\dim_x}% + \xdef\transury{\the\ht\tmp_box}% + \ifput_into_bb \put_into_bb\box \fi + \box\tmp_box \transspecial{grestore}\egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +% --- +\def\update_bb#1#2#3{% used in \rotate + \trigcompute{-#1}{#2}{#3}% clockwise vs anti-clockwise + \ifdim\transllx>\trigxresult sp\xdef\transllx{\trigxresult sp}\fi + \ifdim\translly>\trigyresult sp\xdef\translly{\trigyresult sp}\fi + \ifdim\transurx<\trigxresult sp\xdef\transurx{\trigxresult sp}\fi + \ifdim\transury<\trigyresult sp\xdef\transury{\trigyresult sp}\fi +} +\def\rotate{\hbox\bgroup \put_into_bbfalse \rotate_} +\def\rotatebb{\hbox\bgroup \put_into_bbtrue \rotate_} +\def\rotate_#1{% #1 -- angle, + % to be followed by a box + \def\after_setbox{% + \setbox\tmp_box\hbox{% otherwise does not work with \vbox + \transspecial{gsave currentpoint currentpoint translate + #1 rotate neg exch neg exch translate}% + \box\tmp_box \transspecial{grestore}}% + % set bounding box + \xdef\transllx{\the\z@}\xdef\translly{\the\z@}% + \xdef\transurx{\the\z@}\xdef\transury{\the\z@}% + \update_bb{#1}{\z@}{\ht\tmp_box}% + \update_bb{#1}{\z@}{-\dp\tmp_box}% + \update_bb{#1}{\wd\tmp_box}{\ht\tmp_box}% + \update_bb{#1}{\wd\tmp_box}{-\dp\tmp_box}% + % + \wd\tmp_box\z@ \ht\tmp_box\z@ \dp\tmp_box\z@ + \ifput_into_bb \put_into_bb\unhbox \fi + \box\tmp_box\egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +% --- +\def\plus_{+} +\def\minus_{-} +\def\revolvedir#1{% to be followed by a box + \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{% + \tmp_dim_a\wd\tmp_box +% prepare to revolving: + \setbox\tmp_box\hbox{% + \ifx\param_\plus_\kern-\tmp_dim_a\fi + \box\tmp_box + \ifx\param_\plus_\kern\tmp_dim_a\fi}% +% compute dimensions of the box to be revolved: + \tmp_dim_a\ht\tmp_box \advance\tmp_dim_a\dp\tmp_box + \tmp_dim_b\ht\tmp_box \tmp_dim_c\dp\tmp_box + \dp\tmp_box\z@ \ht\tmp_box\wd\tmp_box \wd\tmp_box\tmp_dim_a +% revolve: + \kern \ifx\param_\plus_ \tmp_dim_c \else \tmp_dim_b \fi + \transspecial{gsave currentpoint currentpoint translate + #190 rotate neg exch neg exch translate}% + \set_std_bb + \box\tmp_box + \transspecial{grestore}% + \kern -\ifx\param_\plus_ \tmp_dim_c \else \tmp_dim_b \fi + \egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +\def\revolveleft{\revolvedir-} +\def\revolveright{\revolvedir+} +\def\revolvepi{\xflip\yflip} +\let\revolve\revolveleft +\let\rotatepi\revolvepi +% --- +\def\xflip{% to be followed by a box + \hbox\bgroup + \def\after_setbox{% + \tmp_dim_a.5\wd\tmp_box +% prepare to flipping: + \setbox\tmp_box + \hbox{\kern-\tmp_dim_a \box\tmp_box \kern\tmp_dim_a}% +% flip: + \kern\tmp_dim_a + \transspecial{gsave currentpoint currentpoint translate + [-1 0 0 1 0 0] concat neg exch neg exch translate}% + \set_std_bb + \box\tmp_box + \transspecial{grestore}% + \kern-\tmp_dim_a + \egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +% --- +\def\yflip{% to be followed by a box + \hbox\bgroup + \def\after_setbox{% + \tmp_dim_a\ht\tmp_box \tmp_dim_b\dp\tmp_box + \tmp_dim_c\tmp_dim_a \advance\tmp_dim_c\tmp_dim_b + \tmp_dim_c.5\tmp_dim_c +% prepare to flipping: + \setbox\tmp_box\vbox{% + \kern\tmp_dim_c\box\tmp_box\kern-\tmp_dim_c}% +% flip: + \advance\tmp_dim_c-\tmp_dim_b + \setbox\tmp_box\hbox{% + \transspecial{gsave currentpoint currentpoint translate + [1 0 0 -1 0 0] concat neg exch neg exch translate}% + \lower\tmp_dim_c\box\tmp_box + \transspecial{grestore}}% +% restore dimensions of the flipped box: + \ht\tmp_box\tmp_dim_a \dp\tmp_box\tmp_dim_b + \set_std_bb + \box\tmp_box + \egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +}% +% --- +% save TeX registers: +\let\clip_wd\tmp_dim_a +\let\clip_ht\tmp_dim_b +\let\clip_dp\tmp_dim_c +% --- +\def\tracingclipcmyk{1 0 0 0} +\def\clip_fix_pos#1{\transspecial{% + currentpoint /clip_#1_y exch def /clip_#1_x exch def% +}} +\def\clip_use_pos#1{clip_#1_x clip_#1_y} +\def\clip_delta#1#2{#1 #2 3 -1 roll exch sub 3 1 roll sub exch} +% +\def\do_clip{\transspecial{% + newpath + \clip_use_pos{LL} moveto + \clip_delta{\clip_use_pos{UR}}{\clip_use_pos{UL}} rlineto + \clip_delta{\clip_use_pos{UR}}{\clip_use_pos{LR}} rlineto + \clip_delta{\clip_use_pos{LL}}{\clip_use_pos{LR}} rlineto + closepath + \ifx\tracingclip\unknown \else + gsave \tracingclipcmyk\space setcmykcolor fill grestore + \fi + clip newpath% +}} +% +\def\clip_use_dim#1{% #1 = wd, ht, or dp + \ifdim\csname clip_#1\endcsname=\maxdimen \csname#1\endcsname\tmp_box + \else \csname clip_#1\endcsname\fi +} +% +\def\clip_fix_dim#1#2{% + \edef\clip_use_dim_param{#2}% + \ifx\clip_use_dim_param\empty #1\maxdimen\else + \ifx\clip_use_dim_param\space #1\maxdimen\else \sumto#1#2\relax \fi\fi +} +% +\def\clipbox#1#2#3{% desired height, width and depth to be followed by a box + \hbox\bgroup + \clip_fix_dim\clip_wd{#1}% + \clip_fix_dim\clip_ht{#2}% + \clip_fix_dim\clip_dp{#3}% + \clipbox_ +} +\def\clipbox_{% + \def\after_setbox{% + \setbox\tmp_box\hbox{\box\tmp_box}% + \clip_wd\clip_use_dim{wd}% freeze dimen + \clip_ht\clip_use_dim{ht}% ditto + \clip_dp\clip_use_dim{dp}% ditto + \transspecial{gsave}% + \rlap{% + \lower \clip_dp \vbox{% + \hbox to\clip_wd{\clip_fix_pos{UL}\hss\clip_fix_pos{UR}} + \kern\clip_ht \kern\clip_dp \nointerlineskip + \hbox to\clip_wd{\clip_fix_pos{LL}\hss\clip_fix_pos{LR}} + \do_clip + }% + }% + \wd\tmp_box=\clip_wd \ht\tmp_box=\clip_ht \dp\tmp_box=\clip_dp + \set_std_bb \box\tmp_box \transspecial{grestore}\egroup}% + \afterassignment\jump_setbox\setbox\tmp_box = +} +% --------------------------------------------------------------------------- +% ``floating point arithmetic'' (excerpted from T. Rokicki): +% r y +% +% ^ +% | +% | +% | +% | +% | +% 0--------------> t x +% +% save TeX registers: +\let\dim_x\tmp_dim_a % horizontal size after scaling +\let\dim_y\tmp_dim_b % vertical size after scaling +\let\dim_t\tmp_dim_c % horizontal size before scaling +\let\dim_r\tmp_dim_d % vertical size before scaling +%\tmp_dim % register for arithmetic manipulation (already declared) +% --- +\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 + \tmp_dim=\dim_r \divide\tmp_dim\dim_t + \dim_y=\dim_x \multiply\dim_y\tmp_dim + \multiply\tmp_dim\dim_t \advance\dim_r-\tmp_dim + \tmp_dim=\dim_x + \loop \advance\dim_r\dim_r \divide\tmp_dim 2 + \ifnum\tmp_dim>0 + \ifnum\dim_r<\dim_t\else + \advance\dim_r-\dim_t \advance\dim_y\tmp_dim \fi + \repeat + % assign result: + #1\dim_y\relax +} +% --------------------------------------------------------------------------- +% ``fixed point arithmetic'' -- fractions and trigometry, inspired by mf.web: +% +% save TeX registers: +\let\fracint\tmp_dim +\let\fracfrac\tmp_count_a +\let\fracprod\tmp_count_b +\def\fracpowlimit{30}% +\def\fracone{1073741824}% = 2^\fracpowlimit +% --- +\def\fracproduct#1#2{% #1 = fraction * 2^\fracpowlimit, #2 = integer +% result: macro \fracresult = floor(#1 * #2 / 2^\fracpowlimit + 1/2) +% expanding to the count equivalent of the respective dimen +\begingroup + \fracfrac#1\relax % \fracfrac <= 2^30 + \fracint#2\relax % \fracint <= \maxdimen + \ifdim\fracint<0pt \fracint-\fracint\def\fracsign{-}\else\def\fracsign{}\fi + \ifnum\fracone=\fracfrac \fracprod\fracint \else + \advance\fracfrac\fracone % \fracfrac < 2^31 + \fracprod\fracone % if \fracprod were dimen, this would yield error + \divide\fracprod2 % \fracprod = 2^29 (representation of 1/2) + \loop + \ifodd\fracfrac \advance \fracprod\fracint \fi + \divide\fracprod2 \divide\fracfrac2 + \ifnum \fracfrac>1 \repeat + \fi + \xdef\fracresult{\fracsign\number\fracprod}% +\endgroup +} +% --- +\newdimen\onedegree +\onedegree16pt % this must be consistent with the table below +% save TeX registers: +\let\trigangle\tmp_dim_a +\let\trigxpart\tmp_dim_b +\let\trigypart\tmp_dim_c +\let\trigxtmp\tmp_dim +\let\trigiter\tmp_count_a +\def\triglimit{28}% +% --- +\def\trigvalarg#1{\csname argscaled:\number#1\endcsname} +\def\trigvalcos#1{\csname cosscaled:\number#1\endcsname} +\def\trigvalsin#1{\csname sinscaled:\number#1\endcsname} +\def\defspectrig#1#2#3#4{% +% #1 -- ordering number (index) +% #2 -- angle in degrees * \onedegree expressed in sp; alpha=#1*2^(-20) +% #3 -- floor(cosd(alpha)*2^30+1/2) (30=\fracpowlimit) +% #4 -- floor(sind(alpha)*2^30+1/2) + \expandafter\def\csname argscaled:#1\endcsname{#2}% + \expandafter\def\csname cosscaled:#1\endcsname{#3}% + \expandafter\def\csname sinscaled:#1\endcsname{#4}% +} +\defspectrig{1}{62914560}{536870912}{929887697} % alpha=60 +\defspectrig{2}{47185920}{759250125}{759250125} % 45 +\defspectrig{3}{31457280}{929887697}{536870912} % 30 +\defspectrig{4}{16777216}{1032146887}{295963357} % 2^4 +\defspectrig{5}{8388608}{1063292242}{149435979} % 2^3 +\defspectrig{6}{4194304}{1071126243}{74900443} % 2^2 +\defspectrig{7}{2097152}{1073087729}{37473049} % 2^1 +\defspectrig{8}{1048576}{1073578288}{18739379} % 2^0 +\defspectrig{9}{524288}{1073700939}{9370046} % 2^-1 +\defspectrig{10}{262144}{1073731603}{4685068} % 2^-2 +\defspectrig{11}{131072}{1073739269}{2342539} % 2^-3 +\defspectrig{12}{65536}{1073741185}{1171270} % 2^-4 +\defspectrig{13}{32768}{1073741664}{585635} % 2^-5 +\defspectrig{14}{16384}{1073741784}{292818} % 2^-6 +\defspectrig{15}{8192}{1073741814}{146409} % 2^-7 +\defspectrig{16}{4096}{1073741822}{73204} % 2^-8 +\defspectrig{17}{2048}{1073741823}{36602} % 2^-9 +\defspectrig{18}{1024}{1073741824}{18301} % 2^-10 +\defspectrig{19}{512}{1073741824}{9151} % 2^-11 +\defspectrig{20}{256}{1073741824}{4575} % 2^-12 +\defspectrig{21}{128}{1073741824}{2288} % 2^-13 +\defspectrig{22}{64}{1073741824}{1144} % 2^-14 +\defspectrig{23}{32}{1073741824}{572} % 2^-15 +\defspectrig{24}{16}{1073741824}{286} % 2^-16 +\defspectrig{25}{8}{1073741824}{143} % 2^-17 +\defspectrig{26}{4}{1073741824}{71} % 2^-18 +\defspectrig{27}{2}{1073741824}{36} % 2^-19 +\defspectrig{28}{1}{1073741824}{18} % 2^-20 +% --- +\def\trigcompute#1#2#3{% +% #1 angle in degrees (a) +% #2 initial xpart (x) +% #3 initial ypart (y) +% result: (x',y')=(x,y) rotated a; the pair of macros +% \trigxresult and \trigyresult contain x' and y', respectively; +% both expand to the count equivalent of the respective dimen +\begingroup + \trigangle#1\onedegree \trigxpart#2\relax \trigypart#3\relax + \loop \ifdim\trigangle<0sp \advance\trigangle360\onedegree \repeat + \loop \ifdim\trigangle>360\onedegree \advance\trigangle-360\onedegree \repeat + \ifdim\trigangle=360\onedegree \trigangle0sp \fi + \ifdim\trigangle<180\onedegree \else % >= + \trigxpart-\trigxpart \trigypart-\trigypart + \advance\trigangle-180\onedegree + \fi + \ifdim\trigangle<90\onedegree \else % >= + \trigxtmp\trigxpart \trigxpart-\trigypart \trigypart\trigxtmp + \advance\trigangle-90\onedegree + \fi + \trigiter1\relax + \loop + \ifnum\trigvalarg\trigiter>\trigangle \else % <= + \advance\trigangle-\trigvalarg\trigiter sp + \trigxtmp\trigxpart + % x=x*cos[i]-y*sin[i] : + \fracproduct{\trigvalcos\trigiter}\trigxpart + \trigxpart\fracresult sp + \fracproduct{\trigvalsin\trigiter}\trigypart + \advance\trigxpart-\fracresult sp + % y=y*cos[i]+x*sin[i] : + \fracproduct{\trigvalcos\trigiter}\trigypart + \trigypart\fracresult sp + \fracproduct{\trigvalsin\trigiter}\trigxtmp + \advance\trigypart\fracresult sp + \fi + \advance\trigiter1 + \ifnum\trigangle>0 \repeat +% result in dimen registers: \trigxpart and \trigypart + \xdef\trigxresult{\number\trigxpart}% + \xdef\trigyresult{\number\trigypart}% +\endgroup +} +% --------------------------------------------------------------------------- +% restore original catcodes: +\catcode`\@\transatcode +\catcode`\_\transundcode +% --------------------------------------------------------------------------- +\endinput + |