pack-box.mkiv /size: 38 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=pack-box,
3%D        version=2002.04.12,
4%D          title=\CONTEXT\ Packaging Macros,
5%D       subtitle=Boxes,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Packaging Macros / Boxes}
15
16%D This module contains all kind of macros for moving content around. Many
17%D macros here come from other modules, but depencies made it more clear
18%D to isolate them. We invite users to document the macros. They can be
19%D handy shortcuts for otherwise complex tasks.
20
21\unprotect
22
23%D We need to set the size, else we get dimensions depending on the content,
24%D which in itself is ok, but can lead to loops due to rounding errors (happened
25%D in demo-obv).
26
27% \definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height]
28% \definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height]
29% \definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height]
30% \definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\d_overlay_width,\c!height=\d_overlay_height]
31
32\definelayer[\v!text-2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight]
33\definelayer[\v!text-1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight]
34\definelayer[\v!text+1][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight]
35\definelayer[\v!text+2][\c!position=\v!yes,\c!region=,\c!width=\textwidth,\c!height=\textheight]
36
37\unexpanded\def\internaltextoverlay#1% will become more generic and installable
38  {\startoverlay                     % i.e. probably an overlay by itself
39     {\positionregionoverlay\textanchor{\v!text#1}}% see later
40     {\composedlayer                   {\v!text#1}}%
41   \stopoverlay}
42
43\defineoverlay[\v!text-2][\internaltextoverlay{-2}]
44\defineoverlay[\v!text-1][\internaltextoverlay{-1}]
45\defineoverlay[\v!text+1][\internaltextoverlay{+1}]
46\defineoverlay[\v!text+2][\internaltextoverlay{+2}]
47
48\installcorenamespace {anchor}
49
50% produces a box too
51%
52% \anchor[text-1][preset=lefttop][framed settings]{HELLO WORLD}
53
54\unexpanded\def\defineanchor
55  {\doquadrupleempty\pack_anchors_define}
56
57\def\pack_anchors_define[#1][#2][#3][#4]% name targetlayer layersetting framedsetting
58  {\setvalue{\??anchor#1}{\pack_anchors_process_defined{#2}{#3}{#4}}}
59
60\def\pack_anchors_process_defined#1#2#3%
61  {\def\pack_anchors_process_defined_indeed[##1][##2]%
62     {\ifsecondargument
63        \def\next{\pack_anchors_process_indeed{#1}{#2,##1}{#3,##2}}%
64      \else\iffirstargument
65        \def\next{\pack_anchors_process_indeed{#1}{#2,##1}{#2,##1}}%
66      \else
67        \def\next{\pack_anchors_process_indeed{#1}{#2}{#3}}%
68      \fi\fi
69      \next}%
70   \dodoubleempty\pack_anchors_process_defined_indeed}
71
72\unexpanded\def\anchor[#1]%
73  {\begingroup
74   \edef\currentanchor{#1}%
75   \ifcsname\??anchor\currentanchor\endcsname
76     \expandafter\lastnamedcs
77   \else
78     \expandafter\pack_anchor_notdefined
79   \fi}
80
81\def\pack_anchor_notdefined
82  {\dodoubleempty\pack_anchor_notdefined_indeed}
83
84\def\pack_anchor_notdefined_indeed
85  {\ifsecondargument
86     \expandafter\pack_anchor_notdefined_two
87   \else
88     \expandafter\pack_anchor_notdefined_one
89   \fi}
90
91\def\pack_anchor_notdefined_one[#1][#2]{\pack_anchors_process_indeed\currentanchor{#1}{#1}}
92\def\pack_anchor_notdefined_two[#1][#2]{\pack_anchors_process_indeed\currentanchor{#1}{#2}}
93
94\def\pack_anchors_process_indeed#1#2#3%
95  {\dowithnextbox{\pack_anchors_process_finish{#1}{#2}{#3}}\vbox}
96
97\newbox  \b_pack_anchors
98\newdimen\d_pack_anchors_width
99\newdimen\d_pack_anchors_height
100\newdimen\d_pack_anchors_depth
101
102% \definelayer[anchor]
103
104\newcount\c_pack_anchors_n
105\newtoks \t_pack_anchors_flush
106
107\unexpanded\def\pack_anchors_register#1#2%
108  {\global\advance\c_pack_anchors_n\plusone
109   \pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]%
110   \putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors
111%    \xtoksapp\t_pack_anchors_flush{\pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}}%
112   \doglobal\appendetoks
113     \pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}%
114   \to \t_pack_anchors_flush
115   \glet\pack_anchors_flush_all\pack_anchors_flush_all_indeed}
116
117\unexpanded\def\pack_anchors_flush#1#2#3%
118  {\doifelseboxincache\v!anchor{#1}
119     {\doifelsereferencefound{\v!layer:\v!anchor:#1}
120        {\ifnum\currentreferencerealpage=\realpageno\relax
121           \setlayer[#2][#3,\c!position=\v!no]{\directboxfromcache\v!anchor{#1}}%
122         \else
123           \donetrue
124         \fi
125         }\donetrue}%
126     \donetrue}%
127
128\unexpanded\def\pack_anchors_flush_all_indeed
129  {\donefalse
130   \the\t_pack_anchors_flush
131   \ifdone\else
132      \global\t_pack_anchors_flush\emptytoks
133      \glet\pack_anchors_flush_all\relax
134   \fi}
135
136\let\pack_anchors_flush_all\relax
137
138\appendtoks
139    \pack_anchors_flush_all
140\to \everybeforepagebody
141
142\def\pack_anchors_process_finish#1#2#3% brrr: we need to apply offset only once .. a bit messy
143  {\checkpositionoverlays
144   \setbox\b_pack_anchors\box\nextbox
145   \framed % could be a predefined framed but used seldom
146     [\c!offset=\v!overlay,\c!frame=\v!off,#3]
147     {\pack_anchors_register{#1}{#2}%
148      \novrule % hm, not needed as we frame the size (but kind of default)
149        \s!width \wd\b_pack_anchors
150        \s!height\ht\b_pack_anchors
151        \s!depth \dp\b_pack_anchors}%
152   \endgroup}
153
154% \setlayeranchored[text-1][preset=lefttop]{HELLO WORLD} produces a simple (empty) hbox
155% synchronizes per page
156
157\unexpanded\def\setlayeranchored
158  {\begingroup
159   \dodoubleempty\pack_anchors_set_finish}
160
161\def\pack_anchors_set_finish[#1][#2]%
162  {\dowithnextbox
163     {\iffirstargument
164        \checkpositionoverlays
165        \setbox\b_pack_anchors\box\nextbox
166        \dontleavehmode\hpack{\pack_anchors_register{#1}{#2}}%
167      \fi
168      \endgroup}\hbox}
169
170% collectors
171
172\installcorenamespace{collectorbox}
173\installcorenamespace{collector}
174
175\installcommandhandler \??collector {collector} \??collector
176
177\setupcollector
178  [\c!state=\v!start,
179   \c!x=\zeropoint,
180   \c!y=\zeropoint,
181   \c!offset=\zeropoint,
182   \c!rotation=, % geen 0 !
183   \c!hoffset=\zeropoint,
184   \c!voffset=\zeropoint,
185   \c!location=rb,
186   \c!corner=]
187
188\appendtoks
189   \ifcsname\??collectorbox\currentcollector\endcsname \else
190     \expandafter\newbox\csname\??collectorbox\currentcollector\endcsname
191   \fi
192\to \everydefinecollector
193
194\unexpanded\def\resetcollector[#1]%
195  {\ifcsname\??collectorbox#1\endcsname
196     \global\setbox\lastnamedcs\emptybox
197   \fi}
198
199\newconditional\c_pack_boxes_collector_valid_box
200
201\let\b_pack_boxes_collector\scratchbox
202
203\def\pack_boxes_collector_check_box#1%
204  {\edef\currentcollector{#1}%
205   \ifcsname\??collectorbox\currentcollector\endcsname
206     \settrue\c_pack_boxes_collector_valid_box
207     \expandafter\let\expandafter\b_pack_boxes_collector\lastnamedcs
208   \else
209     \setfalse\c_pack_boxes_collector_valid_box
210     \writestatus{collector}{unknown collector \currentcollector}%
211   \fi}
212
213\unexpanded\def\setcollector
214  {\bgroup
215   \dodoubleargument\pack_boxes_collector}
216
217\def\pack_boxes_collector[#1][#2]% todo: keep reference point
218  {\pack_boxes_collector_check_box{#1}%
219   \ifconditional\c_pack_boxes_collector_valid_box
220     \setupcurrentcollector[#2]%
221     \expandafter\pack_boxes_collector_yes
222   \else
223     \expandafter\pack_boxes_collector_nop
224   \fi}
225
226\def\pack_boxes_collector_yes
227  {\forgetall
228   \dontcomplain
229   \dowithnextboxcs\pack_boxes_collector_finish\hbox}
230
231\def\pack_boxes_collector_nop
232  {\egroup}
233
234\installcorenamespace{collectorcorners}
235
236\setvalue{\??collectorcorners\v!middle}%
237  {\ifdim\d_pack_layers_x_size>\zeropoint
238      \advance\d_pack_layers_x_position.5\d_pack_layers_x_size
239    \fi
240    \ifdim\d_pack_layers_y_size>\zeropoint
241      \advance\d_pack_layers_y_position.5\d_pack_layers_y_size
242    \fi}
243
244\setvalue{\??collectorcorners\v!bottom}%
245  {\ifdim\d_pack_layers_y_size>\zeropoint
246     \advance\d_pack_layers_y_position-\d_pack_layers_y_size
247     \d_pack_layers_y_position-\d_pack_layers_y_position
248   \fi}
249
250\setvalue{\??collectorcorners\v!right}%
251  {\ifdim\d_pack_layers_x_size>\zeropoint
252     \advance\d_pack_layers_x_position-\d_pack_layers_x_size
253     \d_pack_layers_x_position-\d_pack_layers_x_position
254   \fi}
255
256\def\pack_boxes_collector_check_corner#1%
257  {\ifcsname\??collectorcorners#1\endcsname
258     \lastnamedcs
259   \fi}
260
261\def\pack_boxes_collector_finish
262  {\edef\p_collector_rotation{\collectorparameter\c!rotation}%
263   \edef\p_collector_corner  {\collectorparameter\c!corner}%
264   \ifx\p_collector_rotation\empty \else
265     \setbox\nextbox\hpack
266       {\rotate
267          [\c!location=\v!high,
268           \c!rotation=\p_collector_rotation]
269          {\box\nextbox}}%
270   \fi
271   \d_pack_layers_x_size\wd\b_pack_boxes_collector
272   \d_pack_layers_y_size\htdp\b_pack_boxes_collector
273   \d_pack_layers_x_position\dimexpr\collectorparameter\c!x+\collectorparameter\c!hoffset\relax
274   \d_pack_layers_y_position\dimexpr\collectorparameter\c!y+\collectorparameter\c!voffset\relax
275   \rawprocesscommacommand[\p_collector_corner]\pack_boxes_collector_check_corner
276   \setbox\nextbox\hpack
277     {\alignedbox[\collectorparameter\c!location]\vpack{\box\nextbox}}%
278   \boxmaxdepth\zeropoint % really needed, nice example
279   \global\advance\boxhdisplacement\d_pack_layers_x_position
280   \ifdim\boxhdisplacement<\zeropoint
281     \global\setbox\b_pack_boxes_collector\hpack
282       {\kern-\boxhdisplacement
283        \box\b_pack_boxes_collector}%
284   \fi
285   \global\advance\boxvdisplacement\d_pack_layers_y_position
286   \ifdim\boxvdisplacement<\zeropoint
287     \global\setbox\b_pack_boxes_collector\hpack
288       {\lower-\boxvdisplacement
289        \box\b_pack_boxes_collector}%
290   \fi
291   \d_pack_layers_x_size\wd\b_pack_boxes_collector
292   \d_pack_layers_y_size\htdp\b_pack_boxes_collector
293   \global\setbox\b_pack_boxes_collector\hpack
294     {\box\b_pack_boxes_collector
295      \kern\dimexpr
296        -\d_pack_layers_x_size
297        +\d_pack_layers_x_position
298         \ifdim\boxhdisplacement<\zeropoint
299           -\boxhdisplacement
300         \fi
301      \relax
302      \lower\d_pack_layers_y_position\hpack
303        {\ifdim\boxvdisplacement<\zeropoint
304           \lower-\boxvdisplacement
305         \fi
306         \box\nextbox}}%
307   % combine height and depth into depth only (later flushed as height)
308   \global\setbox\b_pack_boxes_collector\hpack
309     {\lower\ht\b_pack_boxes_collector\box\b_pack_boxes_collector}%
310   % just to be sure
311   \ifdim\wd\b_pack_boxes_collector<\d_pack_layers_x_size
312     \wd\b_pack_boxes_collector\d_pack_layers_x_size
313   \fi
314   \egroup}
315
316\unexpanded\def\flushcollector[#1]%
317  {\bgroup
318   \pack_boxes_collector_check_box{#1}%
319   \ifconditional\c_pack_boxes_collector_valid_box
320     \edef\p_collector_state{\collectorparameter\c!state}%
321     \ifx\p_collector_state\v!stop \else
322       \vpack{\hpack{\raise
323         \dp\b_pack_boxes_collector
324         \ifx\p_collector_state\v!repeat\copy\else\box\fi\b_pack_boxes_collector}}%
325     \fi
326   \fi
327   \egroup}
328
329\unexpanded\def\composedcollector#1% no [], handy as argument
330  {\flushcollector[#1]}
331
332\unexpanded\def\adaptcollector
333  {\dodoubleargument\pack_boxes_collector_adapt}
334
335\def\pack_boxes_collector_adapt[#1][#2]% % a typical case where \global\wd looks better in the code
336  {\begingroup
337   \pack_boxes_collector_check_box{#1}%
338   \ifconditional\c_pack_boxes_collector_valid_box
339     \letcollectorparameter\c!voffset\zeropoint
340     \letcollectorparameter\c!hoffset\zeropoint
341     \ifsecondargument
342       \setupcurrentcollector[#2]%
343     \fi
344     \global\wd\b_pack_boxes_collector\dimexpr\wd\b_pack_boxes_collector+\collectorparameter\c!hoffset\relax
345     \global\ht\b_pack_boxes_collector\dimexpr\ht\b_pack_boxes_collector+\collectorparameter\c!voffset\relax
346   \fi
347   \endgroup}
348
349%\definecollector[test]
350%\setcollector[test]
351%  [location=rb]
352%  {\externalfigure[koe][frame=on,width=3cm]}
353%\setcollector[test]
354%  [corner={right,bottom},location={left,top}]
355%  {\framed{gans}}
356%\composedcollector{test}
357
358\definecollector
359  [caption]
360
361\unexpanded\def\collectedtext % for captions
362  {\bgroup
363   \dodoubleempty\pack_boxes_collector_text}
364
365\def\pack_boxes_collector_text[#1][#2]#3%
366  {\dowithnextbox
367     {\setcollector
368        [caption]
369        {\box\nextbox}%
370      \setcollector
371        [caption][#1]
372        {\letdummyparameter\c!style\empty
373         \letdummyparameter\c!color\empty
374         \getdummyparameters[#2]%
375         \dousestyleparameter{\directdummyparameter\c!style}%
376         \setupinterlinespace
377         \normalexpanded{\framed[\c!foregroundcolor=\directdummyparameter\c!color,\c!foregroundstyle=\directdummyparameter\c!style},\c!frame=\v!overlay,#2]{#3}}%
378      \composedcollector{caption}%
379      \egroup}%
380     \hbox}
381
382% \collectedtext
383%   [corner={right,bottom},location={left,top}]
384%   [background=color,backgroundcolor=white,offset=0pt]
385%   {gans}
386%   {\externalfigure[koe][width=3cm]}
387%
388% \collectedtext
389%   [rotation=90,corner={right,bottom},location={right,top}]
390%   [frame=on,offset=0pt]
391%   {gans}
392%   {\externalfigure[koe][width=3cm]}
393%
394% \collectedtext
395%   [rotation=90,corner={left,bottom},location={left,top}]
396%   [frame=on,offset=0pt]
397%   {gans}
398%   {\externalfigure[koe][width=3cm]}
399
400\installcorenamespace {layeredtext}
401\installcorenamespace {layeredtextlayer}
402\installcorenamespace {layeredtextframed}
403
404\installsimpleframedcommandhandler \??layeredtext {layeredtext} \??layeredtext
405
406\newdimen\d_pack_layeredtexts_width
407\newdimen\d_pack_layeredtexts_height
408
409\definelayer % private
410  [\??layeredtextlayer]
411
412\setuplayer % private
413  [\??layeredtextlayer]
414  [\c!width=\d_pack_layeredtexts_width,
415   \c!height=\d_pack_layeredtexts_height]
416
417\defineframed % private
418  [\??layeredtextframed]
419  [\c!offset=\v!overlay,
420   \c!frame=\v!off,
421   \c!background={\v!foreground,\??layeredtextlayer},
422   \c!width=\d_pack_layeredtexts_width,
423   \c!height=\d_pack_layeredtexts_height]
424
425\setuplayeredtext % public (the attached data, usually small stuff, not the main thing)
426  [\c!frame=\v!overlay,
427   \c!color=,
428   \c!style=,
429   \c!foregroundcolor=\layeredtextparameter\c!color,
430   \c!foregroundstyle=\layeredtextparameter\c!style]
431
432\unexpanded\def\layeredtext
433  {\bgroup
434   \let\currentlayeredtext\empty
435   \dodoubleempty\pack_layeredtexts_place}
436
437\unexpanded\def\placelayeredtext[#1]%
438  {\bgroup
439   \edef\currentlayeredtext{#1}%
440   \checklayeredtextparent % bonus
441   \dodoubleempty\pack_layeredtexts_place}
442
443\def\pack_layeredtexts_place[#1][#2]#3% layersettings content(framed)settings content
444  {\setupcurrentlayeredtext[#2]%
445   \dowithnextbox
446     {\d_pack_layeredtexts_width \wd\nextbox
447      \d_pack_layeredtexts_height\ht\nextbox
448      \begingroup % preserve \nextbox
449      \setlayer
450        [\??layeredtextlayer]%
451        [#1]%
452        {\setfalse\fontattributeisset
453         \uselayeredtextstyleparameter\c!style
454         \ifconditional\fontattributeisset
455           \setupinterlinespace
456         \fi
457         \inheritedlayeredtextframed{#3}}%
458      \endgroup
459      \placeframed[\??layeredtextframed]{\flushnextbox}%
460      \egroup}%
461     \hbox}
462
463% \layeredtext
464%   [corner={right,bottom},location={left,top}]
465%   [background=color,backgroundcolor=white,offset=0pt]
466%   {gans}
467%   {\externalfigure[koe][width=3cm]}
468%
469% \layeredtext
470%   [rotation=90,corner={right,bottom},location={right,top}]
471%   [frame=on,offset=0pt]
472%   {gans}
473%   {\externalfigure[koe][width=3cm]}
474%
475% \layeredtext
476%   [rotation=90,corner={left,bottom},location={left,top}]
477%   [frame=on,offset=0pt]
478%   {gans}
479%   {\externalfigure[koe][width=3cm]}
480
481\unexpanded\def\ornamenttext
482  {\dodoubleempty\pack_ornament_text}
483
484\def\pack_ornament_text[#1][#2]%
485  {\bgroup
486   \doifelseassignment{#1}
487     {\letdummyparameter\c!alternative\v!a
488      \getdummyparameters[#1]%
489      \doifelse{\directdummyparameter\c!alternative}\v!a
490        {\egroup\collectedtext}%
491        {\egroup\layeredtext  }%
492      [#1][#2]}%
493     {\egroup\getvalue{#1}}}
494
495\unexpanded\def\defineornament
496  {\dotripleempty\dodefineornament}
497
498\def\dodefineornament[#1][#2][#3]%
499  {\setuvalue{#1}{\pack_ornament_text[#2][#3]}}
500
501% \defineornament
502%   [affiliation]
503%   [rotation=90,corner={right,bottom},location={right,top},
504%    hoffset=-.25ex]
505%   [frame=on,background=color,backgroundcolor=red,offset=0pt]
506%
507% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}}
508%
509% \defineornament
510%   [affiliation]
511%   [rotation=90,corner={right,bottom},location={right,top},
512%    hoffset=-.25ex,alternative=b]
513%   [frame=on,background=color,backgroundcolor=red,offset=0pt]
514%
515% \ruledhbox{\affiliation{gans}{\externalfigure[koe][width=3cm]}}
516%
517% \defineornament
518%   [affiliation]
519%   [rotation=90,corner={right,bottom},location={left,top},
520%    hoffset=.25ex,voffset=.25ex,alternative=a]
521%   [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt]
522%
523% \affiliation{photo}{\externalfigure[molen][width=3cm]}
524%
525% \defineornament
526%   [affiliation]
527%   [rotation=90,corner={right,bottom},location={left,top},
528%    hoffset=.25ex,voffset=.25ex,alternative=b]
529%   [background=color,style=\ss\tfxx,backgroundcolor=white,offset=0pt]
530%
531% \affiliation{drawing}{\externalfigure[hakker][width=3cm]}
532
533\newcount\c_pack_boxes_bleeds
534
535\installcorenamespace {bleeding}
536
537\installdirectcommandhandler \??bleeding {bleeding} % \??bleeding
538
539\setupbleeding
540  [\c!location=l,
541   \c!stretch=\v!yes,
542   \c!width=3cm,
543   \c!height=3cm,
544   \c!offset=2mm,
545   \c!page=\v!no,
546   \c!voffset=\scratchoffset, % is set to \bleedingparameter\c!offset
547   \c!hoffset=\scratchoffset] % which often saves one resolve
548
549\def\bleedwidth {\the\hsize} % these are global !
550\def\bleedheight{\the\vsize} % these are global !
551
552\newconditional\c_pack_boxes_l
553\newconditional\c_pack_boxes_r
554\newconditional\c_pack_boxes_t
555\newconditional\c_pack_boxes_b
556
557\unexpanded\def\bleed
558  {\hbox\bgroup
559   \dosingleempty\pack_boxes_bleed}
560
561\installcorenamespace{bleedinglocation}
562
563\setvalue{\??bleedinglocation  t}{\settrue\c_pack_boxes_t\scratchhoffset\zeropoint}
564\setvalue{\??bleedinglocation  b}{\settrue\c_pack_boxes_b\scratchhoffset\zeropoint}
565\setvalue{\??bleedinglocation  l}{\settrue\c_pack_boxes_l\scratchvoffset\zeropoint}
566\setvalue{\??bleedinglocation  r}{\settrue\c_pack_boxes_r\scratchvoffset\zeropoint}
567\setvalue{\??bleedinglocation bl}{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_b}
568\setvalue{\??bleedinglocation lb}{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_b}
569\setvalue{\??bleedinglocation br}{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_b}
570\setvalue{\??bleedinglocation rb}{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_b}
571\setvalue{\??bleedinglocation tl}{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_t}
572\setvalue{\??bleedinglocation lt}{\settrue\c_pack_boxes_l\settrue\c_pack_boxes_t}
573\setvalue{\??bleedinglocation tr}{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_t}
574\setvalue{\??bleedinglocation rt}{\settrue\c_pack_boxes_r\settrue\c_pack_boxes_t}
575
576\def\pack_boxes_bleed[#1]%
577  {\global\advance\c_pack_boxes_bleeds\plusone
578   %
579   \xdef\bleedwidth {\the\hsize}%
580   \xdef\bleedheight{\the\vsize}%
581   %
582   \edef\currentbgposition  {bleed:\number\c_pack_boxes_bleeds}%
583   \edef\currentpageposition{page:0}% todo: per page
584   %
585   \setupcurrentbleeding[#1]%
586   %
587   \scratchwidth  \bleedingparameter\c!width
588   \scratchheight \bleedingparameter\c!height
589   \scratchoffset \bleedingparameter\c!offset
590   \scratchhoffset\bleedingparameter\c!hoffset
591   \scratchvoffset\bleedingparameter\c!voffset
592   %
593   \setfalse\c_pack_boxes_l % left
594   \setfalse\c_pack_boxes_r % right
595   \setfalse\c_pack_boxes_t % top
596   \setfalse\c_pack_boxes_b % bottom
597   %
598   \csname\??bleedinglocation\bleedingparameter\c!location\endcsname
599   %
600   \doifelse{\bleedingparameter\c!stretch}\v!yes\donetrue\donefalse
601   %
602   \xdef\bleedwidth{\the\dimexpr
603     \ifdone
604       \ifconditional\c_pack_boxes_l
605         \scratchwidth+\MPx\currentbgposition-\MPx\currentpageposition
606       \else\ifconditional\c_pack_boxes_r
607         \paperwidth  -\MPx\currentbgposition+\MPx\currentpageposition % not checked
608       \else
609         \scratchwidth
610       \fi\fi
611     \else
612       \scratchwidth
613     \fi+\scratchhoffset
614   \relax}%
615   \xdef\bleedheight{\the\dimexpr
616     \ifdone
617       \ifconditional\c_pack_boxes_t
618         \paperheight  -\MPy\currentbgposition+\MPy\currentpageposition % not checked
619       \else\ifconditional\c_pack_boxes_b
620         \scratchheight+\MPy\currentbgposition-\MPy\currentpageposition + \MPh\currentbgposition % not checked (\MPh added)
621       \else
622         \scratchheight
623       \fi\fi
624     \else
625       \scratchheight
626     \fi+\scratchvoffset
627   \relax}%
628   \dowithnextboxcontentcs\pack_boxes_bleed_settings\pack_boxes_bleed_finish\hbox}
629
630\def\pack_boxes_bleed_settings
631  {\hsize\bleedwidth
632   \vsize\bleedheight}
633
634\def\pack_boxes_bleed_finish
635  {\doif{\bleedingparameter\c!page}\v!yes
636     {\setbox\nextbox\topskippedbox{\box\nextbox}}%
637   \setbox\nextbox\hpack to \scratchwidth
638     {\ifconditional\c_pack_boxes_l\hss\fi
639      \box\nextbox
640      \ifconditional\c_pack_boxes_r\hss\fi}%
641   \ifconditional\c_pack_boxes_b
642     \setbox\nextbox\hpack
643       {\lower\bleedheight\hpack{\raise\scratchheight\box\nextbox}}%
644   \fi
645   \wd\nextbox\scratchwidth
646   \ht\nextbox\scratchheight
647   \dp\nextbox\zeropoint
648   \ifdone
649     \hpos\currentbgposition{\box\nextbox}%
650   \else
651     \box\nextbox
652   \fi
653   \egroup}
654
655\defineexternalfigure
656  [bleed] % should be \v!bleed
657  [\c!width=\bleedwidth,
658   \c!height=\bleedheight]
659
660% \placefigure[left]{none}
661%   {\bleed[width=5cm,height=3cm,location=lt]{\externalfigure[koe][bleed]}}
662%
663% \input tufte
664%
665% \placefigure[left]{none}
666%   {\bleed[width=5cm,height=3cm,location=l]{\externalfigure[koe][bleed]}}
667%
668% \input tufte
669%
670% \placefigure[right]{none}
671%   {\bleed[width=5cm,height=3cm,location=r]{\externalfigure[koe][bleed]}}
672%
673% \input tufte
674%
675% \placefigure
676%   [top,none]
677%   {} % no caption
678%   {\bleed
679%      [hoffset=-\backspace,
680%       voffset=3mm,
681%       width=0cm,
682%       height=6\lineheight,
683%       page=yes, % correct for topskip
684%       location=lt]
685%      {\externalfigure[koe][bleed][frame=on]}}
686
687% \setlayerframed[layer id][layer settings][framed setting]{data}
688% \setlayerframed[layer id][combined settings]{data}
689
690% tricky: offsets apply to both the layer and the framed; it makes sense to
691% only apply the offset to ...
692
693\unexpanded\def\setlayerframed
694  {\dotripleempty\pack_layers_set_framed}
695
696\def\pack_layers_set_framed
697  {\ifthirdargument
698     \singleexpandafter\pack_layers_set_framed_t
699   \else\ifsecondargument
700     \doubleexpandafter\pack_layers_set_framed_d
701   \else
702     \doubleexpandafter\pack_layers_set_framed_s
703   \fi\fi}
704
705\def\pack_layers_set_framed_s[#1][#2][#3]%
706  {\setlayer[#1][\c!width=\wd\nextbox,\c!height=\ht\nextbox,\c!offset=\zeropoint]%
707     \normalframedwithsettings[\c!location=\v!normal]} % different kind of location
708
709\def\pack_layers_set_framed_d[#1][#2][#3]%
710  {\setlayer[#1][\c!width=\wd\nextbox,\c!height=\ht\nextbox,#2,\c!offset=\zeropoint]%
711     \normalframedwithsettings[\c!location=\v!normal,#2]} % different kind of location
712
713\def\pack_layers_set_framed_t[#1][#2][#3]%
714  {\setlayer[#1][#2]%
715     \normalframedwithsettings[#3]}
716
717\unexpanded\def\setlayertext
718  {\dotripleempty\pack_layers_set_text}
719
720\def\pack_layers_set_text[#1][#2][#3]%
721  {\bgroup
722   \letdummyparameter\c!align\empty
723   \letdummyparameter\c!width\hsize
724   \letdummyparameter\c!color\empty
725   \letdummyparameter\c!style\empty
726   \getdummyparameters[#3]%
727   \dowithnextboxcontent
728     {\forgetall
729      \hsize\directdummyparameter\c!width
730      \usealignparameter\directdummyparameter
731      \dousestyleparameter{\directdummyparameter\c!style}}
732     {\setlayer[#1][#2]{\strut\dousecolorparameter{\directdummyparameter\c!color}\flushnextbox}% maybe expand the color
733      \egroup}%
734   \vtop}
735
736% \setupbackgrounds
737%   [page]
738%   [background=pagefigures]
739%
740% \definelayer
741%   [pagefigures]
742%   [x=-2mm,
743%    y=-2mm,
744%    width=\paperwidth,
745%    height=\paperheight]
746%
747% \definelayerpreset [lefttop]     [corner={left,top},location={right,bottom}]
748% \definelayerpreset [righttop]    [corner={right,top},location={left,bottom}]
749% \definelayerpreset [leftbottom]  [corner={left,bottom},location={right,top}]
750% \definelayerpreset [rightbottom] [corner={right,bottom},location={left,top}]
751% \definelayerpreset [middle]      [corner=middle,location=middle]
752%
753% \setlayer[pagefigures][preset=lefttop]
754% \setlayer[pagefigures][preset=righttop]
755% \setlayer[pagefigures][preset=leftbottom]
756% \setlayer[pagefigures][preset=rightbottom]
757
758\definelayerpreset
759  [\v!left\v!top]
760  [\c!corner={\v!left,\v!top},\c!location={\v!right,\v!bottom}]
761
762\definelayerpreset
763  [\v!right\v!top]
764  [\c!corner={\v!right,\v!top},\c!location={\v!left,\v!bottom}]
765
766\definelayerpreset
767  [\v!left\v!bottom]
768  [\c!corner={\v!left,\v!bottom},\c!location={\v!right,\v!top}]
769
770\definelayerpreset
771  [\v!right\v!bottom]
772  [\c!corner={\v!right,\v!bottom},\c!location={\v!left,\v!top}]
773
774\definelayerpreset
775  [\v!middle]
776  [\c!corner=\v!middle,\c!location=\v!middle]
777
778\definelayerpreset
779  [\v!middle\v!top]
780  [\c!location=\v!bottom,\c!corner=\v!top,\c!dx=.5\layerwidth]
781
782\definelayerpreset
783  [\v!middle\v!bottom]
784  [\c!location=\v!top,\c!corner=\v!bottom,\c!dx=.5\layerwidth]
785
786\definelayerpreset
787  [\v!middle\v!left]
788  [\c!location=\v!right,\c!corner=\v!left,\c!dy=.5\layerheight]
789
790\definelayerpreset
791  [\v!middle\v!right]
792  [\c!location=\v!left,\c!corner=\v!right,\c!dy=.5\layerheight]
793
794% left and right hanging:
795
796\definelayerpreset
797  [\v!left\v!top\v!left]
798  [\c!location={\v!left,\v!bottom},\c!corner={\v!left,\v!top}]
799
800\definelayerpreset
801  [\v!right\v!top\v!right]
802  [\c!location={\v!right,\v!bottom},\c!corner={\v!right,\v!top}]
803
804\installcorenamespace{alignedboxes}
805
806\unexpanded\def\alignedbox{\dosingleempty\pack_boxes_aligned_box}
807\unexpanded\def\aligned   {\dosingleempty\pack_boxes_aligned}
808
809\def\pack_boxes_aligned_box[#1]{\bgroup\serializecommalist[#1]\dowithnextboxcs\pack_boxes_aligned_finish}
810\def\pack_boxes_aligned    [#1]{\bgroup\serializecommalist[#1]\dowithnextboxcs\pack_boxes_aligned_finish\hbox}
811
812% \def\pack_boxes_aligned_finish
813%   {\csname\??alignedboxes
814%      \ifcsname\??alignedboxes\serializedcommalist\endcsname\serializedcommalist\else\v!middle\fi
815%    \endcsname{\flushnextbox}%
816%    \egroup}
817
818\def\pack_boxes_aligned_finish
819  {\ifcsname\??alignedboxes\serializedcommalist\endcsname
820     \expandafter\lastnamedcs
821   \else
822     \expandafter\middlebox
823   \fi{\flushnextbox}%
824   \egroup}
825
826\letvalue{\??alignedboxes                  }\middlebox
827\letvalue{\??alignedboxes\v!middle         }\middlebox
828\letvalue{\??alignedboxes\v!middle\v!middle}\middlebox
829\letvalue{\??alignedboxes\v!left           }\leftbox
830\letvalue{\??alignedboxes\v!left  \v!top   }\lefttopbox
831\letvalue{\??alignedboxes\v!left  \v!bottom}\leftbottombox
832\letvalue{\??alignedboxes\v!right          }\rightbox
833\letvalue{\??alignedboxes\v!right \v!top   }\righttopbox
834\letvalue{\??alignedboxes\v!right \v!bottom}\rightbottombox
835\letvalue{\??alignedboxes\v!bottom         }\bottombox
836\letvalue{\??alignedboxes\v!bottom\v!left  }\bottomleftbox
837\letvalue{\??alignedboxes\v!bottom\v!right }\bottomrightbox
838\letvalue{\??alignedboxes\v!top            }\topbox
839\letvalue{\??alignedboxes\v!top   \v!left  }\topleftbox
840\letvalue{\??alignedboxes\v!top   \v!right }\toprightbox
841\letvalue{\??alignedboxes\v!line           }\baselinemiddlebox % \v!grid is taken
842\letvalue{\??alignedboxes\v!line  \v!left  }\baselineleftbox
843\letvalue{\??alignedboxes\v!line  \v!middle}\baselinemiddlebox
844\letvalue{\??alignedboxes\v!line  \v!right }\baselinerightbox
845\letvalue{\??alignedboxes                 c}\middlebox
846\letvalue{\??alignedboxes                 l}\leftbox
847\letvalue{\??alignedboxes                 r}\rightbox
848\letvalue{\??alignedboxes                 b}\bottombox
849\letvalue{\??alignedboxes                 t}\topbox
850\letvalue{\??alignedboxes                lt}\lefttopbox
851\letvalue{\??alignedboxes                lb}\leftbottombox
852\letvalue{\??alignedboxes                rt}\righttopbox
853\letvalue{\??alignedboxes                rb}\rightbottombox
854\letvalue{\??alignedboxes                tl}\topleftbox
855\letvalue{\??alignedboxes                bl}\bottomleftbox
856\letvalue{\??alignedboxes                tr}\toprightbox
857\letvalue{\??alignedboxes                br}\bottomrightbox
858\letvalue{\??alignedboxes                 m}\middlebox
859\letvalue{\??alignedboxes                 g}\baselinemiddlebox
860\letvalue{\??alignedboxes                gl}\baselineleftbox
861\letvalue{\??alignedboxes                gc}\baselinemiddlebox
862\letvalue{\??alignedboxes                gr}\baselinerightbox
863
864% left/right/top/bottomoffset -> dimensions change
865% x/y | method=fixed          -> dimensions don't change
866
867\installcorenamespace{offsetbox}
868
869\installautocommandhandler \??offsetbox {offsetbox} \??offsetbox
870
871\setupoffsetbox
872  [\c!x=\zeropoint,
873   \c!y=\zeropoint,
874   \c!width=\wd\nextbox,
875   \c!height=\ht\nextbox,
876   \c!depth=\dp\nextbox,
877   \c!location=,
878   \c!leftoffset=\zeropoint,
879   \c!rightoffset=\zeropoint,
880   \c!topoffset=\zeropoint,
881   \c!bottomoffset=\zeropoint,
882   \c!method=]
883
884\let\setupoffset\setupoffsetbox
885
886\unexpanded\def\offsetbox{\dosingleempty\pack_boxes_offset_box}
887\unexpanded\def\offset   {\dosingleempty\pack_boxes_offset}
888
889\def\pack_boxes_offset_box[#1]%
890  {\bgroup
891   \pack_boxes_offset_check[#1]%
892   \dowithnextboxcs\pack_boxes_offsetfinish}
893
894\def\pack_boxes_offset[#1]%
895  {\bgroup
896   \pack_boxes_offset_check[#1]%
897   \dowithnextboxcs\pack_boxes_offsetfinish\hbox}
898
899\newcount\c_pack_boxes_offset_level
900
901\def\pack_boxes_offset_check
902  {\advance\c_pack_boxes_offset_level\plusone
903   \edef\currentoffsetbox{\the\c_pack_boxes_offset_level}%
904   \checkoffsetboxparent
905   \setupcurrentoffsetbox}
906
907\def\pack_boxes_offsetfinish
908  {\donefalse
909   \scratchxposition   \offsetboxparameter\c!x
910   \scratchyposition   \offsetboxparameter\c!y
911   \scratchleftoffset  \offsetboxparameter\c!leftoffset
912   \scratchrightoffset \offsetboxparameter\c!rightoffset
913   \scratchtopoffset   \offsetboxparameter\c!topoffset
914   \scratchbottomoffset\offsetboxparameter\c!bottomoffset
915   \relax % really needed
916   \ifzeropt\scratchleftoffset  \else\donetrue\fi
917   \ifzeropt\scratchrightoffset \else\donetrue\fi
918   \ifzeropt\scratchtopoffset   \else\donetrue\fi
919   \ifzeropt\scratchbottomoffset\else\donetrue\fi
920   \ifdone
921     \edef\p_method{\offsetboxparameter\c!method}%
922     \ifx\p_method\v!fixed % new
923       \ifzeropt\scratchleftoffset
924         \ifzeropt\scratchrightoffset \else
925           \scratchxposition-\scratchrightoffset
926           \scratchrightoffset\zeropoint
927         \fi
928       \else
929         \scratchxposition\scratchleftoffset
930         \scratchleftoffset\zeropoint
931       \fi
932       \ifzeropt\scratchtopoffset
933         \ifzeropt\scratchbottomoffset \else
934           \scratchyposition-\scratchbottomoffset
935           \scratchbottomoffset\zeropoint
936         \fi
937       \else
938         \scratchyposition\scratchtopoffset
939         \scratchtopoffset\zeropoint
940       \fi
941       \donefalse
942     \fi
943   \fi
944   \ifdone
945     \setbox\nextbox\vpack
946       {\forgetall % already done
947        \offinterlineskip
948        \kern\scratchtopoffset
949        \hpack
950          {\kern\scratchleftoffset
951           \box\nextbox
952           \kern\scratchrightoffset}%
953        \kern\scratchbottomoffset}%
954     \ht\nextbox\htdp\nextbox
955     \dp\nextbox\zeropoint
956   \fi
957   \scratchwidth \offsetboxparameter\c!width
958   \scratchheight\offsetboxparameter\c!height
959   \scratchdepth \offsetboxparameter\c!depth
960   \edef\p_location{\offsetboxparameter\c!location}%
961   \setbox\nextbox\hpack
962     {\kern\scratchxposition
963      \lower\scratchyposition\hpack
964        {\ifx\p_location\empty
965           \box\nextbox
966         \else
967           \alignedbox[\p_location]\hpack{\box\nextbox}%
968         \fi}}%
969   \wd\nextbox\scratchwidth
970   \ht\nextbox\scratchheight
971   \dp\nextbox\scratchdepth
972   \box\nextbox
973   \egroup}
974
975%D \starttyping
976%D \framed[offset=overlay]{\offset[leftoffset=1cm]
977%D   {\framed[offset=overlay]{\offset[rightoffset=1cm]
978%D      {\externalfigure[koe][width=1cm]}}}}
979%D
980%D \blank
981%D
982%D \framed[offset=overlay]{\offset[leftoffset=1cm]  {\externalfigure[koe][width=5cm]}} \blank
983%D \framed[offset=overlay]{\offset[rightoffset=1cm] {\externalfigure[koe][width=5cm]}} \blank
984%D \framed[offset=overlay]{\offset[topoffset=1cm]   {\externalfigure[koe][width=5cm]}} \blank
985%D \framed[offset=overlay]{\offset[bottomoffset=1cm]{\externalfigure[koe][width=5cm]}} \blank
986%D \stoptyping
987
988% \useMPlibrary[pre] \setupbackgrounds[page][background=pagegrid]
989%
990% \placefigure[left,none]{}{\offset[leftoffset=1cm]  {\externalfigure[cow][width=3cm]}} \input tufte
991% \placefigure[left,none]{}{\offset[rightoffset=1cm] {\externalfigure[cow][width=3cm]}} \input tufte
992% \placefigure[left,none]{}{\offset[topoffset=1cm]   {\externalfigure[cow][width=3cm]}} \input tufte
993% \placefigure[left,none]{}{\offset[bottomoffset=1cm]{\externalfigure[cow][width=3cm]}} \input tufte
994
995% Some old code:
996%
997% \ltabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf
998% \ltabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf
999% \ltabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf
1000%
1001% \rtabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf
1002% \rtabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf
1003% \rtabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf
1004%
1005% \ctabbed{\romannumerals{3}}{\romannumerals{1}} test \endgraf
1006% \ctabbed{\romannumerals{3}}{\romannumerals{2}} test \endgraf
1007% \ctabbed{\romannumerals{3}}{\romannumerals{3}} test \endgraf
1008
1009\def\pack_boxes_tabbed#1#2#3#4%
1010  {\dontleavehmode
1011   \begingroup
1012   \setbox\scratchbox\hpack{#3}%
1013   \hpack to \wd\scratchbox{#1#4#2}%
1014   \endgroup}
1015
1016\unexpanded\def\ltabbed{\pack_boxes_tabbed\relax\hss}
1017\unexpanded\def\rtabbed{\pack_boxes_tabbed\hss  \relax}
1018\unexpanded\def\ctabbed{\pack_boxes_tabbed\hss  \hss}
1019
1020\let\mtabbed\ctabbed
1021
1022% to be documented
1023
1024\unexpanded\def\phantombox[#1]% == \framed[\c!empty=\v!yes,\c!offset=\v!overlay,#1]{}
1025  {\hpack\bgroup
1026   \letdummyparameter\c!width \zeropoint
1027   \letdummyparameter\c!height\zeropoint
1028   \letdummyparameter\c!depth \zeropoint
1029   \getdummyparameters[#1]%
1030   \setbox\scratchbox\emptyhbox
1031   \wd\scratchbox\directdummyparameter\c!width
1032   \ht\scratchbox\directdummyparameter\c!height
1033   \dp\scratchbox\directdummyparameter\c!depth
1034   \box\scratchbox
1035   \egroup}
1036
1037% \backgroundimage{1}{\hsize}{\vsize}{\externalfigure[cow][\c!width=3cm]}
1038
1039% \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1040% \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1041% \framed[offset=overlay,width=6cm,height=3cm]{\backgroundimage {3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1042
1043% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1044% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1045% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1046% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1047% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1048% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[cow][width=1cm]}}
1049%
1050% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[mill]}}
1051% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[mill]}}
1052% \framed[offset=overlay,width=4cm,height=2cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[mill]}}
1053% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{1}{\hsize}{\vsize}{\externalfigure[mill]}}
1054% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{2}{\hsize}{\vsize}{\externalfigure[mill]}}
1055% \framed[offset=overlay,width=2cm,height=4cm]{\backgroundimagefill{3}{\hsize}{\vsize}{\externalfigure[mill]}}
1056
1057\unexpanded\def\backgroundimage#1#2#3% repeat hsize vsize
1058  {\bgroup
1059   \forgetall
1060   \scratchcounter#1\relax
1061   \scratchwidth  #2\relax
1062   \scratchheight #3\relax
1063   \dowithnextboxcs\pack_boxes_background_image\hbox}
1064
1065\def\pack_boxes_background_image
1066  {\offinterlineskip
1067   \ifcase\scratchcounter
1068     % just one
1069   \else
1070     \scratchdimen\scratchwidth \divide\scratchdimen\wd\nextbox\scratchnx\scratchdimen\advance\scratchnx\plusone\relax
1071     \scratchdimen\scratchheight\divide\scratchdimen\ht\nextbox\scratchny\scratchdimen\advance\scratchny\plusone\relax
1072     % to be considered: methods
1073     \ifcase\scratchcounter
1074     \or % x and y
1075       \setbox\nextbox\hpack{\dorecurse\scratchnx{\copy\nextbox}}%
1076       \setbox\nextbox\vpack{\dorecurse\scratchny{\copy\nextbox\endgraf}}%
1077     \or % x
1078       \setbox\nextbox\hpack{\dorecurse\scratchnx{\copy\nextbox}}%
1079     \or % y
1080       \setbox\nextbox\vpack{\dorecurse\scratchny{\copy\nextbox\endgraf}}%
1081     \fi
1082   \fi
1083   \ifdim\wd\nextbox>\scratchwidth
1084     \setbox\nextbox\hpack to \scratchwidth{\hss\box\nextbox\hss}%
1085     \setbox\nextbox\hpack{\normalexpanded{\clip[\c!width=\the\scratchwidth,\c!height=\the\ht\nextbox]{\box\nextbox}}}%
1086   \fi
1087   \ifdim\ht\nextbox>\scratchheight
1088     \setbox\nextbox\vpack to \scratchheight{\vss\box\nextbox\vss}%
1089     \setbox\nextbox\hpack{\normalexpanded{\clip[\c!width=\the\wd\nextbox,\c!height=\the\scratchheight]{\box\nextbox}}}%
1090   \fi
1091   \box\nextbox
1092   \egroup}
1093
1094\unexpanded\def\backgroundimagefill#1#2#3% repeat hsize vsize
1095  {\bgroup
1096   \forgetall
1097   \scratchcounter#1\relax
1098   \scratchwidth  #2\relax
1099   \scratchheight #3\relax
1100   \dowithnextboxcs\pack_boxes_background_image_fill\hbox}
1101
1102\def\pack_boxes_background_image_fill
1103  {\offinterlineskip
1104   \setbox\nextbox\hpack\bgroup
1105     \ifdim\scratchwidth>\scratchheight
1106       \scale[\c!width=\the\scratchwidth]{\box\nextbox}%
1107     \else
1108       \scale[\c!height=\the\scratchheight]{\box\nextbox}%
1109     \fi
1110   \egroup
1111   \ifdim\wd\nextbox>\scratchwidth
1112     \setbox\nextbox\hpack to \scratchwidth
1113       {\ifcase\scratchcounter
1114          \hss\box\nextbox\hss
1115        \or
1116          \box\nextbox\hss
1117        \or
1118          \hss\box\nextbox
1119        \else
1120          \hss\box\nextbox\hss
1121        \fi}%
1122     \setbox\nextbox\hpack
1123       {\normalexpanded{\clip[\c!width=\the\scratchwidth,\c!height=\the\ht\nextbox]{\box\nextbox}}}%
1124   \fi
1125   \ifdim\ht\nextbox>\scratchheight
1126     \setbox\nextbox\vpack to \scratchheight
1127       {\ifcase\scratchcounter
1128          \vss\box\nextbox\vss
1129        \or
1130          \box\nextbox\vss
1131        \or
1132          \vss\box\nextbox
1133        \else
1134          \vss\box\nextbox\vss
1135        \fi}%
1136     \setbox\nextbox\hpack
1137       {\normalexpanded{\clip[\c!width=\the\wd\nextbox,\c!height=\the\scratchheight]{\box\nextbox}}}%
1138   \fi
1139   \box\nextbox
1140   \egroup}
1141
1142\unexpanded\def\overlayimage#1%
1143  {\vpack to \overlayheight\bgroup
1144     \vss
1145     \hpack to \overlaywidth\bgroup
1146        \hss
1147        \externalfigure[#1][\c!factor=\v!min,\c!equalwidth=\overlaywidth,\c!equalheight=\overlayheight]%
1148        \hss
1149     \egroup
1150     \vss
1151  \egroup}
1152
1153\unexpanded\def\clippedoverlayimage#1%
1154  {\clip
1155     [\c!width=\overlaywidth,\c!height=\overlayheight]
1156     {\overlayimage{#1}}}
1157
1158
1159\protect \endinput
1160