diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv b/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv new file mode 100644 index 00000000000..61ed1e64b75 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/pack-lyr.mkiv @@ -0,0 +1,749 @@ +%D \module +%D [ file=pack-lyr, +%D version=2000.10.20, +%D title=\CONTEXT\ Packaging Macros, +%D subtitle=Layers, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\writestatus{loading}{ConTeXt Packaging Macros / Layers} + +% todo : first / last / next / +... => page key +% test on left/right box when no doublesided option given +% use \ifcsname instead of doifvalue + +\unprotect + +% When being backgrounds layers get the background offset +% displacement. Should be an option, on by default +% (compatibility). + +%D The layering mechanism implemented here is independent of +%D the output routine, but future extensions may depend on a +%D more close cooperation. + +%D First we overload a macro from \type {pack-rul}. From now on +%D we accept a (optional) argument: the specific layer it +%D will go in. This means that we can move an overlay from one +%D background to the other using the dimensions of the parent. + +\ifdefined\defineoverlay \else \message{loaded to early} \wait \fi + +\unexpanded\def\defineoverlay + {\dotripleempty\pack_framed_define_overlay} + +\def\pack_framed_define_overlay[#1][#2][#3]% overlay [layer] content + {\ifthirdargument + %\writestatus{BEWARE}{This (overlay definition) has changed!}% temp + \def\pack_framed_define_overlay_indeed##1{\setvalue{\??overlay##1}{\setlayer[#2]{\executedefinedoverlay{##1}{#3}}}}% + \else + \def\pack_framed_define_overlay_indeed##1{\setvalue{\??overlay##1}{\executedefinedoverlay{##1}{#2}}}% + \fi + \processcommalist[#1]\pack_framed_define_overlay_indeed} + +%D We use the command handler code. The previous, more direct parameter +%D handling was 25\% faster when no parameters were passed when adding +%D content to a layer. However, when we pass for instance a preset, the +%D new methos is some 10\% faster and it happens that in most cases we +%D do pass some parameters. It would be interesting to see if we can push +%D the preset in between the regular chain but it could also lead to +%D unwanted side effects when nesting layer placement. + +\installcorenamespace{layer} +\installcorenamespace{layerbox} +\installcorenamespace{layerpreset} +\installcorenamespace{layerposition} % brr, unreadable + +%D \macros +%D {definelayer,setuplayer} +%D +%D Each layer gets its own (global) box. This also means that +%D the data that goes into a layer, is typeset immediately. +%D Each layer automatically gets an associated overlay, +%D which can be used in any background assignment. +%D +%D After a layer is defined, you can change its +%D characteristics. + +\installcommandhandler \??layer {layer} \??layer + +\setuplayer + [\c!state=\v!start, + %\c!doublesided=, + %\c!preset=, + %\c!option=, + %\c!corner=, + %\c!page=, + %\c!rotation=, % geen 0 ! + \c!direction=\v!normal, + \c!position=\v!no, + \c!method=\v!overlay, + \c!x=\zeropoint, + \c!y=\zeropoint, + \c!line=0, + \c!column=0, + \c!width=\wd\nextbox, % don't change this globally + \c!height=\ht\nextbox, % don't change this globally + \c!offset=\zeropoint, + \c!hoffset=\zeropoint, + \c!voffset=\zeropoint, + \c!dx=\zeropoint, + \c!dy=\zeropoint, + \c!location=rb, + \c!sx=1, + \c!sy=1, + \c!region=\layeranchor] + +\def\layeranchor{\currentlayer:\the\realpageno} + +\let\p_pack_layers_doublesided\empty +\let\p_pack_layers_state \empty +\let\p_pack_layers_option \empty +\let\p_pack_layers_method \empty +\let\p_pack_layers_preset \empty +\let\p_pack_layers_rotation \empty +\let\p_pack_layers_position \empty +\let\p_pack_layers_hoffset \empty +\let\p_pack_layers_voffset \empty +\let\p_pack_layers_offset \empty +\let\p_pack_layers_dx \empty +\let\p_pack_layers_dy \empty +\let\p_pack_layers_sx \empty +\let\p_pack_layers_sy \empty +\let\p_pack_layers_x \empty +\let\p_pack_layers_y \empty +\let\p_pack_layers_corner \empty +\let\p_pack_layers_location \empty +\let\p_pack_layers_line \empty +\let\p_pack_layers_column \empty +\let\p_pack_layers_width \empty +\let\p_pack_layers_height \empty +\let\p_pack_layers_direction \empty +\let\p_pack_layers_region \empty + +\let\m_pack_layers_page \empty +\let\m_pack_layers_target \empty +\let\m_pack_layers_region \empty +\let\m_pack_layers_anchor \empty + +\newconditional\c_pack_layers_repeated +\newconditional\c_pack_layers_trace +\newcount \c_pack_layers_current_data + +\newbox\b_layers + +\newdimen\d_pack_layers_x_size +\newdimen\d_pack_layers_y_size +\newdimen\d_pack_layers_x_offset +\newdimen\d_pack_layers_y_offset +\newdimen\d_pack_layers_x_position +\newdimen\d_pack_layers_y_position + +\newdimen\layerwidth +\newdimen\layerheight + +\let\lastlayerxpos\!!zeropoint +\let\lastlayerypos\!!zeropoint +\let\lastlayerwd \!!zeropoint +\let\lastlayerht \!!zeropoint +\let\lastlayerdp \!!zeropoint + +\appendtoks + \edef\p_pack_layers_doublesided{\layerparameter\c!doublesided}% + \ifx\p_pack_layers_doublesided\v!yes + \relateparameterhandlers{layer}{\v!left \currentlayer}{layer}\currentlayer % permits left* + \relateparameterhandlers{layer}{\v!right\currentlayer}{layer}\currentlayer % permits right* + \pack_layers_preset_box{\v!left \currentlayer}% + \pack_layers_preset_box{\v!right\currentlayer}% + \fi + \pack_layers_preset_box\currentlayer + \normalexpanded{\defineoverlay[\currentlayer][\noexpand\composedlayer{\currentlayer}]}% +\to \everydefinelayer + +\def\pack_layers_preset_box#1% + {\ifcsname\??layerbox#1\endcsname + \resetlayer[#1]% + \else + \expandafter\newbox\csname\??layerbox#1\endcsname + \fi} + +%D \macros +%D {resetlayer} +%D +%D This macro hardly needs an explanation (but is seldom +%D needed anyway). + +\def\pack_layers_reset_box#1% + {\ifcsname\??layerbox#1\endcsname + %\global\setbox\csname\??layerbox#1\endcsname\emptybox + \global\setbox\lastnamedcs\emptybox + \fi} + +\def\resetlayer[#1]% + {\pack_layers_reset_box{#1}% + \pack_layers_reset_box{\v!left #1}% + \pack_layers_reset_box{\v!right#1}% + \pack_layers_reset_box{#1:\the\realpageno}} + +%D \macros +%D {setlayer} +%D +%D Data is moved into a layer with the following macro. When +%D \type {position} is set, relative positioning is used, with +%D the current point as reference point. Otherwise the topleft +%D corner is used as reference point. +%D +%D \starttyping +%D \setlayer [identifier] [optional parameters] {data} +%D \stoptyping + +\def\setcurrentlayerdimensions + {\dodoubleempty\pack_layers_set_current_dimensions} + +\def\pack_layers_set_current_dimensions[#1][#2]% name left|right + {\edef\currentlayerwidth {\thelayerwidth {#2#1}}% + \edef\currentlayerheight{\thelayerheight{#2#1}}} + +\def\thelayerwidth #1{\the\ifcsname\??layerbox#1\endcsname\wd\lastnamedcs\else\zeropoint\fi} +\def\thelayerheight#1{\the\ifcsname\??layerbox#1\endcsname\ht\lastnamedcs\else\zeropoint\fi} + +\unexpanded\def\setlayer + {\dotripleempty\pack_layers_set} + +\def\pack_layers_set[#1][#2][#3]% #4 == box do \fi is ok + {\bgroup + \edef\currentlayer{#1}% + \edef\p_pack_layers_state{\layerparameter\c!state}% + \ifx\p_pack_layers_state\v!stop + \dowithnextboxcs\egroup\hbox % no pack ? + \else\ifthirdargument + \pack_layers_set_indeed[#1][#2][#3]% + \else + \doifelseassignment{#2} + {\pack_layers_set_indeed[#1][][#2]}% + {\pack_layers_set_indeed[#1][#2][]}% + \fi\fi} + +\def\pack_layers_set_indeed[#1][#2][#3]% #2 = links/rechts + {\page_backgrounds_recalculate % brrr + \global\advance\c_pack_layers_current_data\plusone + \forgetall + \dontcomplain + \edef\p_pack_layers_option{\layerparameter\c!option}% + \ifx\p_pack_layers_option\v!test + \settrue\c_pack_layers_trace + \traceboxplacementtrue + \fi + \edef\m_pack_layers_target{#2}% + \dowithnextbox{\pack_layers_set_finish{#3}}\hbox} + +\def\pack_layers_set_finish#1% + {\ifcsname\??layerbox\currentlayer\endcsname % can move up + \ifx\m_pack_layers_target\v!even + \ifodd\realpageno + % discard nextbox + \else + \let\m_pack_layers_target\v!left + \pack_layers_set_content{#1}% + \fi + \else\ifx\m_pack_layers_target\v!odd + \ifodd\realpageno + \let\m_pack_layers_target\v!right + \pack_layers_set_content{#1}% + \else + % discard nextbox + \fi + \else + \pack_layers_set_content{#1}% + \fi\fi + \else + \writestatus{layer}{unknown layer \currentlayer}% + \fi + \egroup} + +% todo left/right + +% todo: get position data in one go + +\def\pack_layers_set_last_position_yes % target: left|right + {% this will become one call + \edef\m_pack_layers_anchor{\??layerposition\the\c_pack_layers_current_data}% + \edef\m_pack_layers_page {\MPp\m_pack_layers_anchor}% + \edef\m_pack_layers_region{\MPr\m_pack_layers_anchor}% + \d_pack_layers_x_position \dimexpr-\MPx\m_pack_layers_region+\MPx\m_pack_layers_anchor\relax + \d_pack_layers_y_position \dimexpr \MPy\m_pack_layers_region-\MPy\m_pack_layers_anchor+\MPh\m_pack_layers_region\relax + \xdef\lastlayerxpos{\the\d_pack_layers_x_position}% + \xdef\lastlayerypos{\the\d_pack_layers_y_position}% + % \writestatus{region}{\m_pack_layers_region -> (\MPx\m_pack_layers_region,\MPy\m_pack_layers_region)}% + % \writestatus{self} {\m_pack_layers_anchor -> (\MPx\m_pack_layers_anchor,\MPy\m_pack_layers_anchor)}% + % \writestatus{delta} {(\lastlayerxpos,\lastlayerypos)}% + % \begingroup + % \edef\currentlayer{\currentlayer\m_pack_layers_page}% + % \global\letlayerparameter\c!position\v!yes + % \endgroup + \global\letlayerparameter\c!state\v!start % needed ? + \setbox\b_layers\vpack to \d_pack_layers_y_size + {\hpack to \d_pack_layers_x_size + {\xypos\m_pack_layers_anchor\hss}% + \vss}} + +\def\pack_layers_set_last_position_nop + {\setbox\b_layers\emptybox + \globallet\lastlayerxpos\!!zeropoint + \globallet\lastlayerypos\!!zeropoint + \doifinset\v!bottom\p_pack_layers_corner\pack_layers_set_bottom_positions + \doifinset\v!right \p_pack_layers_corner\pack_layers_set_right_positions + \doifinset\v!middle\p_pack_layers_corner\pack_layers_set_middle_positions + \edef\m_pack_layers_page{\layerparameter\c!page}} + +\unexpanded\def\definelayerpreset + {\dodoubleargument\pack_layers_define_preset} + +\def\pack_layers_define_preset[#1][#2]% + {\doifelseassignment{#2} + {\setvalue{\??layerpreset#1}{\setupcurrentlayer[#2]}} + {\setvalue{\??layerpreset#1}{\csname\??layerpreset#2\endcsname}}} + +\def\pack_layers_set_content#1% + {\layerwidth \layerparameter\c!width % global (local later) + \layerheight\layerparameter\c!height % global (local later) + \d_pack_layers_x_size\layerwidth + \d_pack_layers_y_size\layerheight + % + \setupcurrentlayer[#1]% preroll + % + \edef\p_pack_layers_preset {\layerparameter\c!preset }% + % + \ifcsname\??layerpreset\p_pack_layers_preset\endcsname + \lastnamedcs + \setupcurrentlayer[#1]% postroll + \fi + % + \edef\p_pack_layers_rotation {\layerparameter\c!rotation }% + \edef\p_pack_layers_position {\layerparameter\c!position }% + \edef\p_pack_layers_hoffset {\layerparameter\c!hoffset }% + \edef\p_pack_layers_voffset {\layerparameter\c!voffset }% + \edef\p_pack_layers_offset {\layerparameter\c!offset }% + \edef\p_pack_layers_dx {\layerparameter\c!dx }% + \edef\p_pack_layers_dy {\layerparameter\c!dy }% + \edef\p_pack_layers_sx {\layerparameter\c!sx }% + \edef\p_pack_layers_sy {\layerparameter\c!sy }% + \edef\p_pack_layers_x {\layerparameter\c!x }% + \edef\p_pack_layers_y {\layerparameter\c!y }% + \edef\p_pack_layers_corner {\layerparameter\c!corner }% + \edef\p_pack_layers_location {\layerparameter\c!location }% + \edef\p_pack_layers_line {\layerparameter\c!line }% + \edef\p_pack_layers_column {\layerparameter\c!column }% + \edef\p_pack_layers_width {\layerparameter\c!width }% local ones + \edef\p_pack_layers_height {\layerparameter\c!height }% local ones + \edef\p_pack_layers_direction{\layerparameter\c!direction}% + % + \ifx\p_pack_layers_position\v!overlay + \let\p_pack_layers_width \zeropoint + \let\p_pack_layers_height \zeropoint + \let\p_pack_layers_position\v!yes + \fi + \ifx\p_pack_layers_rotation\empty \else + % use direct call + \setbox\nextbox\hpack + {\rotate[\c!location=\v!high,\c!rotation=\layerparameter\c!rotation]{\box\nextbox}}% + \fi + \d_pack_layers_x_offset\p_pack_layers_sx\dimexpr + \ifx\p_pack_layers_hoffset\v!max\d_pack_layers_x_size\else\p_pack_layers_hoffset\fi+\p_pack_layers_offset+\p_pack_layers_dx + \relax + \d_pack_layers_y_offset\p_pack_layers_sy\dimexpr + \ifx\p_pack_layers_voffset\v!max\d_pack_layers_y_size\else\p_pack_layers_voffset\fi+\p_pack_layers_offset+\p_pack_layers_dy + \relax + \d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax + \d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax + \ifx\p_pack_layers_position\v!yes + \pack_layers_set_last_position_yes + \else + \pack_layers_set_last_position_nop + \fi + % + \ifx\m_pack_layers_page\empty \else % is expanded + \edef\m_pack_layers_page{:\m_pack_layers_page}% + \ifcsname\??layerbox\m_pack_layers_target\currentlayer\m_pack_layers_page\endcsname \else + \expandafter\newbox\csname\??layerbox\m_pack_layers_target\currentlayer\m_pack_layers_page\endcsname + \fi + \fi + \chardef\layerpagebox\csname\??layerbox\m_pack_layers_target\currentlayer\m_pack_layers_page\endcsname + \ifvoid\layerpagebox + \gsetboxllx\layerpagebox\zeropoint + \gsetboxlly\layerpagebox\zeropoint + \fi + \global\setbox\layerpagebox\vpack %to \layerparameter\c!height % new, otherwise no negative y possible + {\offinterlineskip + \ifvoid\layerpagebox + \let\lastlayerwidth \zeropoint + \let\lastlayerheight\zeropoint + \else + \edef\lastlayerwidth {\the\wd\layerpagebox}% + \edef\lastlayerheight{\the\ht\layerpagebox}% + \ht\layerpagebox\zeropoint + \dp\layerpagebox\zeropoint + \wd\layerpagebox\zeropoint + \ifx\p_pack_layers_direction\v!reverse\else + \box\layerpagebox + \fi + \fi + % don't move + \xdef\lastlayerwd{\the\wd\nextbox}% + \xdef\lastlayerht{\the\ht\nextbox}% % not entirely ok when grid ! + \xdef\lastlayerdp{\the\dp\nextbox}% % not entirely ok when grid ! + % this code + \ifx\p_pack_layers_location\v!grid + \ht\nextbox\strutheight + \dp\nextbox\strutdepth + \else + \setbox\nextbox\hpack + {\alignedbox[\p_pack_layers_location]\vpack{\box\nextbox}}% + \fi + \ifnum\p_pack_layers_line=\zerocount\else % no \ifcase, can be negative + \advance\d_pack_layers_y_position\dimexpr\p_pack_layers_line\lineheight+\topskip-\lineheight-\ht\nextbox\relax + \fi + \ifnum\p_pack_layers_column=\zerocount\else % no \ifcase, can be negative + \advance\d_pack_layers_x_position\layoutcolumnoffset\p_pack_layers_column\relax + \fi + \ifx\p_pack_layers_location\v!grid + \setbox\nextbox\hpack + {\alignedbox[rb]\vpack{\box\nextbox}}% + \fi + % ll registration + \scratchdimen\dimexpr\d_pack_layers_x_position+\d_pack_layers_x_offset\relax + \ifdim\scratchdimen<\getboxllx\layerpagebox + \gsetboxllx\layerpagebox\scratchdimen + \fi + \advance\scratchdimen\wd\nextbox + \wd\nextbox\ifdim\scratchdimen>\lastlayerwidth \scratchdimen \else \lastlayerwidth \fi + \scratchdimen\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax + \ifdim\scratchdimen<\getboxlly\layerpagebox + \gsetboxlly\layerpagebox\scratchdimen + \fi + % ll compensation + \advance\scratchdimen\dimexpr\ht\nextbox+\dp\nextbox\relax + \ht\nextbox\ifdim\scratchdimen>\lastlayerheight \scratchdimen \else \lastlayerheight \fi + \dp\nextbox\zeropoint + % placement + \hsize\p_pack_layers_width + \vpack to \p_pack_layers_height \bgroup + \smashbox\nextbox + \vskip\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax + \hskip\dimexpr\d_pack_layers_x_position+\d_pack_layers_x_offset\relax + \box\nextbox + \ifvoid\layerpagebox + % already flushed + \else + % the reverse case % check ! + \vskip-\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax + \box\layerpagebox + \fi + \egroup}% + % when position is true, the layerbox holds the compensation and needs + % to be placed; never change this ! + \ifvoid\b_layers \else + \box\b_layers + \fi} + +\def\pack_layers_set_bottom_positions + {\ifnum\p_pack_layers_line=\zerocount\else % can be < 0 + \edef\p_pack_layers_line{\the\numexpr-\p_pack_layers_line+\layoutlines+\plusone\relax}% use counter instead ? + \fi + \ifdim\d_pack_layers_y_size>\zeropoint + \advance\d_pack_layers_y_position-\d_pack_layers_y_size + \d_pack_layers_y_position-\d_pack_layers_y_position + \d_pack_layers_y_offset-\d_pack_layers_y_offset + \fi} + +\def\pack_layers_set_right_positions + {\ifnum\p_pack_layers_column=\zerocount\else % can be < 0 + \edef\p_pack_layers_column{\the\numexpr-\layerparameter\c!column+\layoutcolumns+\plusone\relax}% use counter instead ? + \fi + \ifdim\d_pack_layers_x_size>\zeropoint + \advance\d_pack_layers_x_position-\d_pack_layers_x_size + \d_pack_layers_x_position-\d_pack_layers_x_position + \d_pack_layers_x_offset-\d_pack_layers_x_offset + \fi} + +\def\pack_layers_set_middle_positions + {\ifdim\d_pack_layers_x_size>\zeropoint \advance\d_pack_layers_x_position.5\d_pack_layers_x_size \fi + \ifdim\d_pack_layers_y_size>\zeropoint \advance\d_pack_layers_y_position.5\d_pack_layers_y_size \fi} + +%D Given the task to be accomplished, the previous macro is +%D not even that complicated. It mainly comes down to skipping +%D to the right place and placing a box on top of or below the +%D existing content. In the case of position tracking, another +%D reference point is chosen. + +%D \macros +%D {doifelselayerdata} + +\def\doifelselayerdata#1% + {\ifcsname\??layerbox#1\endcsname + %\ifvoid\csname\??layerbox#1\endcsname + \ifvoid\lastnamedcs + \doubleexpandafter\secondoftwoarguments + \else + \doubleexpandafter\firstoftwoarguments + \fi + \else + \expandafter\secondoftwoarguments + \fi} + +\let\doiflayerdataelse\doifelselayerdata + +%D \macros +%D {flushlayer} +%D +%D When we flush a layer, we flush both the main one and the +%D page dependent one (when defined). This feature is more +%D efficient in \ETEX\ since there testing for an undefined +%D macro does not takes hash space. + +% todo: setups before flush, handy hook + +\unexpanded\def\flushlayer[#1]% quite core, so optimized (todo: check for void) + {\begingroup + \forgetall + \edef\currentlayer{#1}% + \edef\p_pack_layers_state{\layerparameter\c!state}% + \ifx\p_pack_layers_state\v!stop + % nothing + \else\ifx\p_pack_layers_state\v!next + \global\letlayerparameter\c!state\v!start % dangerous, stack-built-up + \else\ifx\p_pack_layers_state\v!continue + \global\letlayerparameter\c!state\v!repeat % dangerous, stack-built-up + \else + \edef\p_pack_layers_doublesided{\layerparameter\c!doublesided}% + \ifx\p_pack_layers_doublesided\v!yes + \ifcsname\??layerbox#1\endcsname + % we can make a dedicated one for this + \doifbothsidesoverruled + {\pack_layers_flush_double\v!left }% + {\pack_layers_flush_double\v!right}% + {\pack_layers_flush_double\v!left }% + \else + \pack_layers_flush_single + \fi + \else + \pack_layers_flush_single + \fi + \fi\fi\fi + \endgroup} + +% \ifcase#1\else\writestatus{layer}{unknown layer #3}\fi + +% todo: pass the layer with \lastnamedcs + +\def\pack_layers_flush_single + {\startoverlay + {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% + {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}% + \stopoverlay} + +\def\pack_layers_flush_double#1% + {\startoverlay + {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% + {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}% + {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}% + {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}% + \stopoverlay} + +\let\pack_layers_top_fill \relax +\let\pack_layers_bottom_fill\vss + +\def\pack_layers_flush_indeed#1#2% quite core, so optimized + {\begingroup % already grouped + \offinterlineskip + \edef\p_pack_layers_preset{\layerparameter\c!preset}% + \ifcsname\??layerpreset\p_pack_layers_preset\endcsname + \lastnamedcs + \fi + \edef\p_pack_layers_method{\layerparameter\c!method}% + \edef\p_pack_layers_option{\layerparameter\c!option}% + \ifx\p_pack_layers_option\v!test + \settrue\c_pack_layers_trace + \traceboxplacementtrue + \fi + \ifcase#1\relax + \setfalse\c_pack_layers_repeated + \else + \edef\p_pack_layers_position{\layerparameter\c!position}% + \ifx\p_pack_layers_position\v!yes + \setfalse\c_pack_layers_repeated + \else + \edef\p_pack_layers_repeat{\layerparameter\c!repeat}% + \ifx\p_pack_layers_repeat\v!yes + \settrue\c_pack_layers_repeated + \else\ifx\p_pack_layers_state\v!repeat + \settrue\c_pack_layers_repeated + \else + \setfalse\c_pack_layers_repeated + \fi\fi + \fi + \fi + \chardef\b_layers\csname\??layerbox#2\endcsname % trick + % we need to copy in order to retain the negative offsets for a next + % stage of additions, i.e. llx/lly accumulate in repeat mode and the + % compensation may differ each flush depending on added content + \setbox\nextbox + \ifx\p_pack_layers_method\v!fit + \pack_layers_positioned_box_yes + \else + \pack_layers_positioned_box_nop + \fi + % todo: method=offset => overlayoffset right/down (handy for backgrounds with offset) + \doifelseoverlay{#2}% + {\setlayoutcomponentattribute{\v!layer:#2}}% + \resetlayoutcomponentattribute + % we have conflicting demands: some mechanisms want ll anchoring .. I need to figure this out + % an dmaybe we will have 'origin=bottom' or so + \setbox\nextbox + \ifx\p_pack_layers_option\v!test \ruledvbox \else \vpack \fi \ifx\p_pack_layers_method\v!overlay to \d_overlay_height \fi \layoutcomponentboxattribute + {\pack_layers_top_fill + \hpack \ifx\p_pack_layers_method\v!overlay to \d_overlay_width \fi + {\box\nextbox + \hss}% + \pack_layers_bottom_fill}% + % + % \edef\currentlayer{#2}% :\the\realpageno}% local .. check \anchor + % \edef\p_pack_layers_position{\layerparameter\c!position}% local + \ifx\p_pack_layers_position\v!yes + \edef\p_pack_layers_region{\layerparameter\c!region}% + \ifx\p_pack_layers_region\empty \else + \anch_mark_tagged_box\nextbox\layeranchor + \fi + \fi + \box\nextbox + % + \ifconditional\c_pack_layers_repeated\else + \gsetboxllx\b_layers\zeropoint + \gsetboxlly\b_layers\zeropoint + \fi + \endgroup} + +\def\pack_layers_positioned_box_yes + {\vpack + {\vskip-\getboxlly\b_layers + \hskip-\getboxllx\b_layers + \hsize-\dimexpr\getboxllx\b_layers-\wd\b_layers\relax + \ifconditional\c_pack_layers_repeated\copy\else\box\fi\b_layers}} + +\def\pack_layers_positioned_box_nop + {\ifconditional\c_pack_layers_repeated\copy\else\box\fi\b_layers} + +% \definelayer[test][method=fit] \setupcolors[state=start,option=test] +% +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=10pt]{g}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=-10pt]{bb}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test][x=-20pt]{cccccc}\flushlayer[test]} +% \framed[framecolor=red,offset=overlay]{\setlayer[test]{dd}\setlayer[test][x=-20pt,y=-3pt]{eeeeee}\flushlayer[test]} + +%D \macros +%D {composedlayer,placelayer,tightlayer} +%D +%D This is a handy shortcut, which saves a couple of braces +%D when we use it as parameter. This name also suits better +%D to other layering commands. + +\unexpanded\def\composedlayer#1{\flushlayer[#1]} + +% \unexpanded\def\tightlayer[#1]% +% {\hbox +% {\def\currentlayer{#1}% todo: left/right +% \setbox\nextbox\emptybox +% \hsize\layerparameter\c!width +% \vsize\layerparameter\c!height +% \composedlayer{#1}}} + +\unexpanded\def\tightlayer[#1]% + {\hpack + {\def\currentlayer{#1}% todo: left/right + \setbox\nextbox\emptybox + \d_overlay_width \layerparameter\c!width + \d_overlay_height\layerparameter\c!height + \composedlayer{#1}}} + +\let\placelayer\flushlayer + +%D \macros +%D {setMPlayer} +%D +%D The following layer macro uses the positions that are +%D registered by \METAPOST. +%D +%D \starttyping +%D \definelayer[test] +%D +%D \setMPlayer [test] [somepos-1] {Whatever we want here!} +%D \setMPlayer [test] [somepos-2] {Whatever we need there!} +%D \setMPlayer [test] [somepos-3] {\externalfigure[cow.mps][width=2cm]} +%D +%D \startuseMPgraphic{oeps} +%D draw fullcircle scaled 10cm withcolor red ; +%D register ("somepos-1",2cm,3cm,center currentpicture) ; +%D register ("somepos-2",8cm,5cm,(-1cm,-2cm)) ; +%D register ("somepos-3",0cm,0cm,(-2cm,2cm)) ; +%D \stopuseMPgraphic +%D +%D \getMPlayer[test]{\useMPgraphic{oeps}} +%D \stoptyping +%D +%D The last line is equivalent to +%D +%D \starttyping +%D \framed +%D [background={foreground,test},offset=overlay] +%D {\useMPgraphic{oeps}} +%D \stoptyping + +\unexpanded\def\setMPlayer + {\dotripleempty\pack_layers_set_MP} + +\def\MPlayerwidth {\hsize} +\def\MPlayerheight{\vsize} + +\def\pack_layers_set_MP[#1][#2][#3]% + {\edef\MPlayerwidth {\MPw{#2}}% + \edef\MPlayerheight{\MPh{#2}}% + \setlayer[#1][\c!x=\MPx{#2},\c!y=\MPy{#2},\c!position=\v!no,#3]} + +\unexpanded\def\getMPlayer + {\dodoubleempty\pack_layers_get_MP} + +\def\pack_layers_get_MP[#1][#2]% + {\framed[\c!background={\v!foreground,#1},\c!frame=\v!off,\c!offset=\v!overlay,#2]} % takes argument + +%D Watch out, a redefinition: + +\ifdefined\settextpagecontent \else + \writestatus\m!system{error in page-lyr.tex} \wait +\fi + +\definelayer + [OTRTEXT] + +\setuplayer + [OTRTEXT] + [\c!width=\innermakeupwidth, + \c!height=\textheight] + +\let\normalsettextpagecontent\settextpagecontent % will be overloaded in page-spr + +\unexpanded\def\settextpagecontent#1#2#3% #2 and #3 will disappear + {\doifelselayerdata{OTRTEXT} + {\setbox#1\hpack to \makeupwidth + {\startoverlay + {\tightlayer[OTRTEXT]} % first, otherwise problems with toc + {\normalsettextpagecontent{#1}{#2}{#3}\box#1} + \stopoverlay}% + \dp#1\zeropoint}% + {\normalsettextpagecontent{#1}{#2}{#3}}} + +\protect \endinput |