pack-lyr.mkiv /size: 28 Kb    last modification: 2020-07-01 14:35
1
%D \module
2
%D [ file=pack-lyr,
3
%D version=2000.10.20,
4
%D title=\CONTEXT\ Packaging Macros,
5
%D subtitle=Layers,
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
/
Layers
}
15 16
% todo : first / last / next / +... => page key
17
% test on left/right box when no doublesided option given
18
% use \ifcsname instead of doifvalue
19 20
\unprotect
21 22
% When being backgrounds layers get the background offset displacement. Should be
23
% an option, on by default (compatibility).
24 25
%D The layering mechanism implemented here is independent of the output routine, but
26
%D future extensions may depend on a more close cooperation.
27
%D
28
%D First we overload a macro from \type {pack-rul}. From now on we accept a
29
%D (optional) argument: the specific layer it will go in. This means that we can
30
%D move an overlay from one background to the other using the dimensions of the
31
%D parent.
32 33
\ifdefined
\defineoverlay
\else
\message
{
loaded
to
early
}
\wait
\fi
34 35
\unexpanded
\def
\defineoverlay
36
{
\dotripleempty
\pack_framed_define_overlay
}
37 38
\def
\pack_framed_define_overlay
[#
1
][#
2
][#
3
]
% overlay [layer] content
39
{
\ifthirdargument
40
%\writestatus{BEWARE}{This (overlay definition) has changed!}% temp
41
\def
\pack_framed_define_overlay_indeed
##
1
{
\setvalue
{
\??overlay
##
1
}{
\setlayer
[#
2
]
{
\executedefinedoverlay
{
##
1
}{
#
3
}}}}
%
42
\else
43
\def
\pack_framed_define_overlay_indeed
##
1
{
\setvalue
{
\??overlay
##
1
}{
\executedefinedoverlay
{
##
1
}{
#
2
}}}
%
44
\fi
45
\processcommalist
[#
1
]
\pack_framed_define_overlay_indeed
}
46 47
%D We use the command handler code. The previous, more direct parameter handling was
48
%D 25\% faster when no parameters were passed when adding content to a layer.
49
%D However, when we pass for instance a preset, the new methos is some 10\% faster
50
%D and it happens that in most cases we do pass some parameters. It would be
51
%D interesting to see if we can push the preset in between the regular chain but it
52
%D could also lead to unwanted side effects when nesting layer placement.
53 54
\installcorenamespace
{
layer
}
55
\installcorenamespace
{
layerbox
}
56
\installcorenamespace
{
layerpreset
}
57
\installcorenamespace
{
layerposition
}
% brr, unreadable
58 59
%D \macros
60
%D {definelayer,setuplayer}
61
%D
62
%D Each layer gets its own (global) box. This also means that the data that goes
63
%D into a layer, is typeset immediately. Each layer automatically gets an associated
64
%D overlay, which can be used in any background assignment.
65
%D
66
%D After a layer is defined, you can change its characteristics.
67 68
\installcommandhandler
\??layer
{
layer
}
\??layer
69 70
\setuplayer
71
[
\c!state
=
\v!start
,
72
%\c!doublesided=,
73
%\c!preset=,
74
%\c!option=,
75
%\c!corner=,
76
%\c!page=,
77
%\c!rotation=, % geen 0 !
78
\c!direction
=
\v!normal
,
79
\c!position
=
\v!no
,
80
\c!method
=
\v!overlay
,
81
\c!x
=
\zeropoint
,
82
\c!y
=
\zeropoint
,
83
\c!line
=
0
,
84
\c!column
=
0
,
85
\c!width
=
\wd
\nextbox
,
% don't change this globally
86
\c!height
=
\ht
\nextbox
,
% don't change this globally
87
\c!offset
=
\zeropoint
,
88
\c!hoffset
=
\zeropoint
,
89
\c!voffset
=
\zeropoint
,
90
\c!dx
=
\zeropoint
,
91
\c!dy
=
\zeropoint
,
92
\c!location
=
rb
,
93
\c!sx
=
1
,
94
\c!sy
=
1
,
95
\c!region
=
\layeranchor
]
96 97
\def
\layeranchor
{
\currentlayer
:
\the
\realpageno
}
98 99
\let
\p_pack_layers_doublesided
\empty
100
\let
\p_pack_layers_state
\empty
101
\let
\p_pack_layers_option
\empty
102
\let
\p_pack_layers_method
\empty
103
\let
\p_pack_layers_preset
\empty
104
\let
\p_pack_layers_rotation
\empty
105
\let
\p_pack_layers_position
\empty
106
\let
\p_pack_layers_hoffset
\empty
107
\let
\p_pack_layers_voffset
\empty
108
\let
\p_pack_layers_offset
\empty
109
\let
\p_pack_layers_dx
\empty
110
\let
\p_pack_layers_dy
\empty
111
\let
\p_pack_layers_sx
\empty
112
\let
\p_pack_layers_sy
\empty
113
\let
\p_pack_layers_x
\empty
114
\let
\p_pack_layers_y
\empty
115
\let
\p_pack_layers_corner
\empty
116
\let
\p_pack_layers_location
\empty
117
\let
\p_pack_layers_line
\empty
118
\let
\p_pack_layers_column
\empty
119
\let
\p_pack_layers_width
\empty
120
\let
\p_pack_layers_height
\empty
121
\let
\p_pack_layers_direction
\empty
122
\let
\p_pack_layers_region
\empty
123 124
\let
\m_pack_layers_page
\empty
125
\let
\m_pack_layers_target
\empty
126
\let
\m_pack_layers_region
\empty
127
\let
\m_pack_layers_anchor
\empty
128 129
\newconditional
\c_pack_layers_repeated
130
\newconditional
\c_pack_layers_trace
131
\newcount
\c_pack_layers_current_data
132 133
\newbox
\b_layers
134 135
\newdimen
\d_pack_layers_x_size
136
\newdimen
\d_pack_layers_y_size
137
\newdimen
\d_pack_layers_x_offset
138
\newdimen
\d_pack_layers_y_offset
139
\newdimen
\d_pack_layers_x_position
140
\newdimen
\d_pack_layers_y_position
141 142
\newdimen
\layerwidth
143
\newdimen
\layerheight
144 145
\let
\lastlayerxpos
\!!zeropoint
146
\let
\lastlayerypos
\!!zeropoint
147
\let
\lastlayerwd
\!!zeropoint
148
\let
\lastlayerht
\!!zeropoint
149
\let
\lastlayerdp
\!!zeropoint
150 151
\appendtoks
152
\edef
\p_pack_layers_doublesided
{
\layerparameter
\c!doublesided
}
%
153
\ifx
\p_pack_layers_doublesided
\v!yes
154
\relateparameterhandlers
{
layer
}{
\v!left
\currentlayer
}{
layer
}
\currentlayer
% permits left*
155
\relateparameterhandlers
{
layer
}{
\v!right
\currentlayer
}{
layer
}
\currentlayer
% permits right*
156
\pack_layers_preset_box
{
\v!left
\currentlayer
}
%
157
\pack_layers_preset_box
{
\v!right
\currentlayer
}
%
158
\fi
159
\pack_layers_preset_box
\currentlayer
160
\normalexpanded
{
\defineoverlay
[
\currentlayer
][
\noexpand
\composedlayer
{
\currentlayer
}
]
}
%
161
\to
\everydefinelayer
162 163
\def
\pack_layers_preset_box
#
1
%
164
{
\ifcsname
\??layerbox
#
1
\endcsname
165
\resetlayer
[#
1
]
%
166
\else
167
\expandafter
\newbox
\csname
\??layerbox
#
1
\endcsname
168
\fi
}
169 170
%D \macros
171
%D {resetlayer}
172
%D
173
%D This macro hardly needs an explanation (but is seldom needed anyway).
174 175
\def
\pack_layers_reset_box
#
1
%
176
{
\ifcsname
\??layerbox
#
1
\endcsname
177
%\global\setbox\csname\??layerbox#1\endcsname\emptybox
178
\global\setbox\lastnamedcs
\emptybox
179
\fi
}
180 181
\def
\resetlayer
[#
1
]
%
182
{
\pack_layers_reset_box
{
#
1
}
%
183
\pack_layers_reset_box
{
\v!left
#
1
}
%
184
\pack_layers_reset_box
{
\v!right
#
1
}
%
185
\pack_layers_reset_box
{
#
1
:
\the
\realpageno
}}
186 187
%D \macros
188
%D {setlayer}
189
%D
190
%D Data is moved into a layer with the following macro. When \type {position} is
191
%D set, relative positioning is used, with the current point as reference point.
192
%D Otherwise the topleft corner is used as reference point.
193
%D
194
%D \starttyping
195
%D \setlayer [identifier] [optional parameters] {data}
196
%D \stoptyping
197 198
\def
\setcurrentlayerdimensions
199
{
\dodoubleempty
\pack_layers_set_current_dimensions
}
200 201
\def
\pack_layers_set_current_dimensions
[#
1
][#
2
]
% name left|right
202
{
\edef
\currentlayerwidth
{
\thelayerwidth
{
#
2
#
1
}}
%
203
\edef
\currentlayerheight
{
\thelayerheight
{
#
2
#
1
}}}
204 205
\def
\thelayerwidth
#
1
{
\the\ifcsname
\??layerbox
#
1
\endcsname\wd\lastnamedcs\else
\zeropoint
\fi
}
206
\def
\thelayerheight
#
1
{
\the\ifcsname
\??layerbox
#
1
\endcsname\ht\lastnamedcs\else
\zeropoint
\fi
}
207 208
\unexpanded
\def
\setlayer
209
{
\dotripleempty
\pack_layers_set
}
210 211
\def
\pack_layers_set
[#
1
][#
2
][#
3
]
% #4 == box do \fi is ok
212
{
\bgroup
213
\checkpositionoverlays
% otherwise funny regions
214
\edef
\currentlayer
{
#
1
}
%
215
\edef
\p_pack_layers_state
{
\layerparameter
\c!state
}
%
216
\ifx
\p_pack_layers_state
\v!stop
217
\dowithnextboxcs
\egroup
\hbox
% no pack ?
218
\else
\ifthirdargument
219
\pack_layers_set_indeed
[#
1
][#
2
][#
3
]
%
220
\else
221
\doifelseassignment
{
#
2
}
222
{
\pack_layers_set_indeed
[#
1
][][#
2
]
}
%
223
{
\pack_layers_set_indeed
[#
1
][#
2
][]
}
%
224
\fi\fi
}
225 226
\def
\pack_layers_set_indeed
[#
1
][#
2
][#
3
]
% #2 = links/rechts
227
{
\page_backgrounds_recalculate
% brrr
228
\global\advance
\c_pack_layers_current_data
\plusone
229
\forgetall
230
\dontcomplain
231
\edef
\p_pack_layers_option
{
\layerparameter
\c!option
}
%
232
\ifx
\p_pack_layers_option
\v!test
233
\settrue
\c_pack_layers_trace
234
\traceboxplacementtrue
235
\fi
236
\edef
\m_pack_layers_target
{
#
2
}
%
237
\dowithnextbox
{
\pack_layers_set_finish
{
#
3
}}
\hbox
}
238 239
\def
\pack_layers_set_finish
#
1
%
240
{
\ifcsname
\??layerbox
\currentlayer
\endcsname
% can move up
241
\ifx
\m_pack_layers_target
\v!even
242
\ifodd
\realpageno
243
% discard nextbox
244
\else
245
\let
\m_pack_layers_target
\v!left
246
\pack_layers_set_content
{
#
1
}
%
247
\fi
248
\else\ifx
\m_pack_layers_target
\v!odd
249
\ifodd
\realpageno
250
\let
\m_pack_layers_target
\v!right
251
\pack_layers_set_content
{
#
1
}
%
252
\else
253
% discard nextbox
254
\fi
255
\else
256
\pack_layers_set_content
{
#
1
}
%
257
\fi\fi
258
\else
259
\writestatus
{
layer
}{
unknown
layer
\currentlayer
}
%
260
\fi
261
\egroup
}
262 263
% todo: left/right
264
% todo: get position data in one go
265 266
\def
\pack_layers_set_last_position_yes
% target: left|right
267
{
% this will become one call
268
\edef
\m_pack_layers_anchor
{
\??layerposition
\the
\c_pack_layers_current_data
}
%
269
\edef
\m_pack_layers_page
{
\MPp
\m_pack_layers_anchor
}
%
270
%edef\m_pack_layers_region{\MPr\m_pack_layers_anchor}% wrong one
271
\edef
\m_pack_layers_region
{
\layerparameter
\c!region
}
%
272
\d_pack_layers_x_position
\dimexpr
-
\MPx
\m_pack_layers_region
+
\MPx
\m_pack_layers_anchor
\relax
273
\d_pack_layers_y_position
\dimexpr
\MPy
\m_pack_layers_region
-
\MPy
\m_pack_layers_anchor
+
\MPh
\m_pack_layers_region
\relax
274
\xdef
\lastlayerxpos
{
\the
\d_pack_layers_x_position
}
%
275
\xdef
\lastlayerypos
{
\the
\d_pack_layers_y_position
}
%
276
% \writestatus{layering}{region: \m_pack_layers_region=>\MPxywhd\m_pack_layers_region}%
277
% \writestatus {}{anchor: \m_pack_layers_anchor=>\MPxywhd\m_pack_layers_anchor}%
278
% \writestatus {}{offset: \c!dx,\c!dy =>\lastlayerxpos,\lastlayerypos}%
279
\global
\letlayerparameter
\c!state\v!start
% needed ?
280
\setbox
\b_layers
\vpack
to
\d_pack_layers_y_size
281
{
\hpack
to
\d_pack_layers_x_size
282
{
\xypos
\m_pack_layers_anchor
\hss
}
%
283
\vss
}}
284 285
\def
\pack_layers_set_last_position_nop
286
{
\setbox
\b_layers
\emptybox
287
\d_pack_layers_x_position
\p_pack_layers_sx
\dimexpr
\p_pack_layers_x
\relax
288
\d_pack_layers_y_position
\p_pack_layers_sy
\dimexpr
\p_pack_layers_y
\relax
289
\glet
\lastlayerxpos
\!!zeropoint
290
\glet
\lastlayerypos
\!!zeropoint
291
\doifinset
\v!bottom
\p_pack_layers_corner
\pack_layers_set_bottom_positions
292
\doifinset
\v!right
\p_pack_layers_corner
\pack_layers_set_right_positions
293
\doifinset
\v!middle
\p_pack_layers_corner
\pack_layers_set_middle_positions
294
\edef
\m_pack_layers_page
{
\layerparameter
\c!page
}}
295 296
\unexpanded
\def
\definelayerpreset
297
{
\dodoubleargument
\pack_layers_define_preset
}
298 299
\def
\pack_layers_define_preset
[#
1
][#
2
]
%
300
{
\doifelseassignment
{
#
2
}
301
{
\setvalue
{
\??layerpreset
#
1
}{
\setupcurrentlayer
[#
2
]
}}
302
{
\setvalue
{
\??layerpreset
#
1
}{
\csname
\??layerpreset
#
2
\endcsname
}}}
303 304
\def
\pack_layers_set_content
#
1
%
305
{
\layerwidth
\layerparameter
\c!width
% global (local later)
306
\layerheight
\layerparameter
\c!height
% global (local later)
307
\d_pack_layers_x_size
\layerwidth
308
\d_pack_layers_y_size
\layerheight
309
%
310
\setupcurrentlayer
[#
1
]
% preroll
311
%
312
\edef
\p_pack_layers_preset
{
\layerparameter
\c!preset
}
%
313
%
314
\ifcsname
\??layerpreset
\p_pack_layers_preset
\endcsname
315
\lastnamedcs
316
\setupcurrentlayer
[#
1
]
% postroll
317
\fi
318
%
319
\edef
\p_pack_layers_rotation
{
\layerparameter
\c!rotation
}
%
320
\edef
\p_pack_layers_position
{
\layerparameter
\c!position
}
%
321
\edef
\p_pack_layers_hoffset
{
\layerparameter
\c!hoffset
}
%
322
\edef
\p_pack_layers_voffset
{
\layerparameter
\c!voffset
}
%
323
\edef
\p_pack_layers_offset
{
\layerparameter
\c!offset
}
%
324
\edef
\p_pack_layers_dx
{
\layerparameter
\c!dx
}
%
325
\edef
\p_pack_layers_dy
{
\layerparameter
\c!dy
}
%
326
\edef
\p_pack_layers_sx
{
\layerparameter
\c!sx
}
%
327
\edef
\p_pack_layers_sy
{
\layerparameter
\c!sy
}
%
328
\edef
\p_pack_layers_x
{
\layerparameter
\c!x
}
%
329
\edef
\p_pack_layers_y
{
\layerparameter
\c!y
}
%
330
\edef
\p_pack_layers_corner
{
\layerparameter
\c!corner
}
%
331
\edef
\p_pack_layers_location
{
\layerparameter
\c!location
}
%
332
\edef
\p_pack_layers_line
{
\layerparameter
\c!line
}
%
333
\edef
\p_pack_layers_column
{
\layerparameter
\c!column
}
%
334
\edef
\p_pack_layers_width
{
\layerparameter
\c!width
}
% local ones
335
\edef
\p_pack_layers_height
{
\layerparameter
\c!height
}
% local ones
336
\edef
\p_pack_layers_direction
{
\layerparameter
\c!direction
}
%
337
%
338
\ifx
\p_pack_layers_position
\v!overlay
339
\let
\p_pack_layers_width
\zeropoint
340
\let
\p_pack_layers_height
\zeropoint
341
\let
\p_pack_layers_position
\v!yes
342
\fi
343
\ifx
\p_pack_layers_rotation
\empty
\else
344
% use direct call
345
\setbox
\nextbox
\hpack
346
{
\rotate
[
\c!location
=
\v!high
,
\c!rotation
=
\layerparameter
\c!rotation
]
{
\box
\nextbox
}}
%
347
\fi
348
\d_pack_layers_x_offset
\p_pack_layers_sx
\dimexpr
349
\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
350
\relax
351
\d_pack_layers_y_offset
\p_pack_layers_sy
\dimexpr
352
\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
353
\relax
354
\ifx
\p_pack_layers_position
\v!yes
355
\pack_layers_set_last_position_yes
356
\else
357
\pack_layers_set_last_position_nop
358
\fi
359
%
360
\ifx
\m_pack_layers_page
\empty
\else
% is expanded
361
\edef
\m_pack_layers_page
{
:
\m_pack_layers_page
}
%
362
\ifcsname
\??layerbox
\m_pack_layers_target
\currentlayer
\m_pack_layers_page
\endcsname
\else
363
\expandafter
\newbox
\csname
\??layerbox
\m_pack_layers_target
\currentlayer
\m_pack_layers_page
\endcsname
364
\fi
365
\fi
366
\chardef
\layerpagebox
\csname
\??layerbox
\m_pack_layers_target
\currentlayer
\m_pack_layers_page
\endcsname
367
\ifvoid
\layerpagebox
368
\gsetboxllx
\layerpagebox
\zeropoint
369
\gsetboxlly
\layerpagebox
\zeropoint
370
\fi
371
\global\setbox
\layerpagebox
\vpack
%to \layerparameter\c!height % new, otherwise no negative y possible
372
{
\offinterlineskip
373
\ifvoid
\layerpagebox
374
\let
\lastlayerwidth
\zeropoint
375
\let
\lastlayerheight
\zeropoint
376
\else
377
\edef
\lastlayerwidth
{
\the\wd
\layerpagebox
}
%
378
\edef
\lastlayerheight
{
\the\ht
\layerpagebox
}
%
379
\ht
\layerpagebox
\zeropoint
380
\dp
\layerpagebox
\zeropoint
381
\wd
\layerpagebox
\zeropoint
382
\ifx
\p_pack_layers_direction
\v!reverse
\else
383
\box
\layerpagebox
384
\fi
385
\fi
386
% don't move
387
\xdef
\lastlayerwd
{
\the\wd
\nextbox
}
%
388
\xdef
\lastlayerht
{
\the\ht
\nextbox
}
% % not entirely ok when grid !
389
\xdef
\lastlayerdp
{
\the\dp
\nextbox
}
% % not entirely ok when grid !
390
% this code
391
\ifx
\p_pack_layers_location
\v!grid
392
\ht
\nextbox
\strutheight
393
\dp
\nextbox
\strutdepth
394
\else
395
\setbox
\nextbox
\hpack
396
{
\alignedbox
[
\p_pack_layers_location
]
\vpack
{
\box
\nextbox
}}
%
397
\fi
398
\ifnum
\p_pack_layers_line
=
\zerocount
\else
% no \ifcase, can be negative
399
\advance
\d_pack_layers_y_position
\dimexpr
\p_pack_layers_line
\lineheight
+
\topskip
-
\lineheight
-
\ht
\nextbox
\relax
400
\fi
401
\ifnum
\p_pack_layers_column
=
\zerocount
\else
% no \ifcase, can be negative
402
\advance
\d_pack_layers_x_position
\layoutcolumnoffset
\p_pack_layers_column
\relax
403
\fi
404
\ifx
\p_pack_layers_location
\v!grid
405
\setbox
\nextbox
\hpack
406
{
\alignedbox
[
rb
]
\vpack
{
\box
\nextbox
}}
%
407
\fi
408
% ll registration
409
\scratchdimen
\dimexpr
\d_pack_layers_x_position
+
\d_pack_layers_x_offset
\relax
410
\ifdim
\scratchdimen
<
\getboxllx
\layerpagebox
411
\gsetboxllx
\layerpagebox
\scratchdimen
412
\fi
413
\advance
\scratchdimen
\wd
\nextbox
414
\wd
\nextbox
\ifdim
\scratchdimen
>
\lastlayerwidth
\scratchdimen
\else
\lastlayerwidth
\fi
415
\scratchdimen
\dimexpr
\d_pack_layers_y_position
+
\d_pack_layers_y_offset
\relax
416
\ifdim
\scratchdimen
<
\getboxlly
\layerpagebox
417
\gsetboxlly
\layerpagebox
\scratchdimen
418
\fi
419
% ll compensation
420
\advance
\scratchdimen
\dimexpr\ht
\nextbox
+
\dp
\nextbox
\relax
421
\ht
\nextbox
\ifdim
\scratchdimen
>
\lastlayerheight
\scratchdimen
\else
\lastlayerheight
\fi
422
\dp
\nextbox
\zeropoint
423
% placement
424
\hsize
\p_pack_layers_width
425
\vpack
to
\p_pack_layers_height
\bgroup
426
\smashbox\nextbox
427
\vskip\dimexpr
\d_pack_layers_y_position
+
\d_pack_layers_y_offset
\relax
428
\hskip\dimexpr
\d_pack_layers_x_position
+
\d_pack_layers_x_offset
\relax
429
% or maybe instead of the \vskip
430
% \raise-\dimexpr\d_pack_layers_y_position+\d_pack_layers_y_offset\relax
431
\box
\nextbox
432
\ifvoid
\layerpagebox
433
% already flushed
434
\else
435
% the reverse case % check !
436
\vskip
-
\dimexpr
\d_pack_layers_y_position
+
\d_pack_layers_y_offset
\relax
437
\box
\layerpagebox
438
\fi
439
\egroup
}
%
440
% when position is true, the layerbox holds the compensation and needs
441
% to be placed; never change this !
442
\ifvoid
\b_layers
\else
443
\box
\b_layers
444
\fi
}
445 446
\def
\pack_layers_set_bottom_positions
447
{
\ifnum
\p_pack_layers_line
=
\zerocount
\else
% can be < 0
448
\edef
\p_pack_layers_line
{
\the\numexpr
-
\p_pack_layers_line
+
\layoutlines
+
\plusone
\relax
}
% use counter instead ?
449
\fi
450
\ifdim
\d_pack_layers_y_size
>
\zeropoint
451
\advance
\d_pack_layers_y_position
-
\d_pack_layers_y_size
452
\d_pack_layers_y_position
-
\d_pack_layers_y_position
453
\d_pack_layers_y_offset
-
\d_pack_layers_y_offset
454
\fi
}
455 456
\def
\pack_layers_set_right_positions
457
{
\ifnum
\p_pack_layers_column
=
\zerocount
\else
% can be < 0
458
\edef
\p_pack_layers_column
{
\the\numexpr
-
\layerparameter
\c!column
+
\layoutcolumns
+
\plusone
\relax
}
% use counter instead ?
459
\fi
460
\ifdim
\d_pack_layers_x_size
>
\zeropoint
461
\advance
\d_pack_layers_x_position
-
\d_pack_layers_x_size
462
\d_pack_layers_x_position
-
\d_pack_layers_x_position
463
\d_pack_layers_x_offset
-
\d_pack_layers_x_offset
464
\fi
}
465 466
\def
\pack_layers_set_middle_positions
467
{
\ifdim
\d_pack_layers_x_size
>
\zeropoint
\advance
\d_pack_layers_x_position
.
5
\d_pack_layers_x_size
\fi
468
\ifdim
\d_pack_layers_y_size
>
\zeropoint
\advance
\d_pack_layers_y_position
.
5
\d_pack_layers_y_size
\fi
}
469 470
%D Given the task to be accomplished, the previous macro is not even that
471
%D complicated. It mainly comes down to skipping to the right place and placing a
472
%D box on top of or below the existing content. In the case of position tracking,
473
%D another reference point is chosen.
474 475
%D \macros
476
%D {doifelselayerdata}
477 478
\def
\doifelselayerdata
#
1
%
479
{
\ifcsname
\??layerbox
#
1
\endcsname
480
%\ifvoid\csname\??layerbox#1\endcsname
481
\ifvoid
\lastnamedcs
482
\doubleexpandafter\secondoftwoarguments
483
\else
484
\doubleexpandafter\firstoftwoarguments
485
\fi
486
\else
487
\expandafter
\secondoftwoarguments
488
\fi
}
489 490
\let
\doiflayerdataelse\doifelselayerdata
491 492
%D \macros
493
%D {flushlayer}
494
%D
495
%D When we flush a layer, we flush both the main one and the page dependent one
496
%D (when defined). This feature is more efficient in \ETEX\ since there testing for
497
%D an undefined macro does not takes hash space.
498 499
% todo: setups before flush, handy hook
500 501
\unexpanded
\def
\flushlayer
[#
1
]
% quite core, so optimized (todo: check for void)
502
{
\begingroup
503
\forgetall
504
\edef
\currentlayer
{
#
1
}
%
505
\edef
\p_pack_layers_state
{
\layerparameter
\c!state
}
%
506
\ifx
\p_pack_layers_state
\v!stop
507
% nothing
508
\else\ifx
\p_pack_layers_state
\v!next
509
\global
\letlayerparameter
\c!state\v!start
% dangerous, stack-built-up
510
\else\ifx
\p_pack_layers_state
\v!continue
511
\global
\letlayerparameter
\c!state\v!repeat
% dangerous, stack-built-up
512
\else
513
\edef
\p_pack_layers_doublesided
{
\layerparameter
\c!doublesided
}
%
514
\ifx
\p_pack_layers_doublesided
\v!yes
515
\ifcsname
\??layerbox
#
1
\endcsname
516
% we can make a dedicated one for this
517
\doifbothsidesoverruled
518
{
\pack_layers_flush_double
\v!left
}
%
519
{
\pack_layers_flush_double
\v!right
}
%
520
{
\pack_layers_flush_double
\v!left
}
%
521
\else
522
\pack_layers_flush_single
523
\fi
524
\else
525
\pack_layers_flush_single
526
\fi
527
\fi\fi\fi
528
\endgroup
}
529 530
% \ifcase#1\else\writestatus{layer}{unknown layer #3}\fi
531 532
% todo: pass the layer with \lastnamedcs
533 534
% \def\pack_layers_flush_single
535
% {\startoverlay
536
% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
537
% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}%
538
% \stopoverlay}
539
%
540
% \def\pack_layers_flush_double#1%
541
% {\startoverlay
542
% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}%
543
% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}%
544
% {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}%
545
% {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}%
546
% \stopoverlay}
547 548
% optimized:
549 550
\def
\pack_layers_flush_single
551
{
\ifcsname
\??layerbox
\currentlayer
\endcsname
552
\ifvoid
\lastnamedcs
553
\ifcsname
\??layerbox
\currentlayer
:
\the
\realpageno
\endcsname
554
\ifvoid
\lastnamedcs\else
555
\chardef
\b_layer_two
\lastnamedcs
556
\pack_layers_flush_indeed
\zerocount
{
\currentlayer
:
\the
\realpageno
}
\b_layer_two
557
\fi
558
\fi
559
\else
560
\chardef
\b_layer_one
\lastnamedcs
561
\ifcsname
\??layerbox
\currentlayer
:
\the
\realpageno
\endcsname
562
\ifvoid
\lastnamedcs\else
563
\chardef
\b_layer_two
\lastnamedcs
564
\startoverlay
565
{
\pack_layers_flush_indeed
\plusone
\currentlayer
\b_layer_one
}
%
566
{
\pack_layers_flush_indeed
\zerocount
{
\currentlayer
:
\the
\realpageno
}
\b_layer_two
}
%
567
\stopoverlay
568
\fi
569
\else
570
\pack_layers_flush_indeed
\plusone
\currentlayer
\b_layer_one
571
\fi
572
\fi
573
\else\ifcsname
\??layerbox
\currentlayer
:
\the
\realpageno
\endcsname
574
\ifvoid
\lastnamedcs
575
% nothing
576
\else
577
\chardef
\b_layer_two
\lastnamedcs
578
\pack_layers_flush_indeed
\zerocount
{
\currentlayer
:
\the
\realpageno
}
\b_layer_two
579
\fi
580
\fi\fi
}
581 582
% less optimized:
583 584
\def
\pack_layers_flush_double
#
1
%
585
{
\startoverlay
586
{
\ifcsname
\??layerbox
\currentlayer
\endcsname
587
\ifvoid
\lastnamedcs\else
\chardef
\b_layer_two
\lastnamedcs
588
\pack_layers_flush_indeed
\plusone
\currentlayer
\b_layer_two
589
\fi
590
\fi
}
%
591
{
\ifcsname
\??layerbox
\currentlayer
:
\the
\realpageno
\endcsname
592
\ifvoid
\lastnamedcs\else
\chardef
\b_layer_two
\lastnamedcs
593
\pack_layers_flush_indeed
\zerocount
{
\currentlayer
:
\the
\realpageno
}
\b_layer_two
594
\fi
595
\fi
}
%
596
{
\ifcsname
\??layerbox
#
1
\currentlayer
\endcsname
597
\ifvoid
\lastnamedcs\else
\chardef
\b_layer_two
\lastnamedcs
598
\pack_layers_flush_indeed
\plusone
{
#
1
\currentlayer
}
\b_layer_two
599
\fi
600
\fi
}
%
601
{
\ifcsname
\??layerbox
#
1
\currentlayer
:
\the
\realpageno
\endcsname
602
\ifvoid
\lastnamedcs\else
\chardef
\b_layer_two
\lastnamedcs
603
\pack_layers_flush_indeed
\zerocount
{
#
1
\currentlayer
:
\the
\realpageno
}
\b_layer_two
604
\fi
605
\fi
}
%
606
\stopoverlay
}
607 608
\let
\pack_layers_top_fill
\relax
609
\let
\pack_layers_bottom_fill
\vss
610 611
%def\pack_layers_flush_indeed#1#2%
612
\def
\pack_layers_flush_indeed
#
1
#
2
#
3
%
613
{
\begingroup
% already grouped
614
\offinterlineskip
615
\edef
\p_pack_layers_preset
{
\layerparameter
\c!preset
}
%
616
\ifcsname
\??layerpreset
\p_pack_layers_preset
\endcsname
617
\lastnamedcs
618
\fi
619
\edef
\p_pack_layers_method
{
\layerparameter
\c!method
}
%
620
\edef
\p_pack_layers_option
{
\layerparameter
\c!option
}
%
621
\ifx
\p_pack_layers_option
\v!test
622
\settrue
\c_pack_layers_trace
623
\traceboxplacementtrue
624
\fi
625
\ifcase
#
1
\relax
626
\setfalse
\c_pack_layers_repeated
627
\else
628
\edef
\p_pack_layers_position
{
\layerparameter
\c!position
}
%
629
\ifx
\p_pack_layers_position
\v!yes
630
\setfalse
\c_pack_layers_repeated
631
\else
632
\edef
\p_pack_layers_repeat
{
\layerparameter
\c!repeat
}
%
633
\ifx
\p_pack_layers_repeat
\v!yes
634
\settrue
\c_pack_layers_repeated
635
\else\ifx
\p_pack_layers_state
\v!repeat
636
\settrue
\c_pack_layers_repeated
637
\else
638
\setfalse
\c_pack_layers_repeated
639
\fi\fi
640
\fi
641
\fi
642
%chardef\b_layers\csname\??layerbox#2\endcsname % trick
643
\let
\b_layers
#
3
%
644
% we need to copy in order to retain the negative offsets for a next
645
% stage of additions, i.e. llx/lly accumulate in repeat mode and the
646
% compensation may differ each flush depending on added content
647
\setbox
\nextbox
648
\ifx
\p_pack_layers_method
\v!fit
649
\pack_layers_positioned_box_yes
650
\else
651
\pack_layers_positioned_box_nop
652
\fi
653
% todo: method=offset => overlayoffset right/down (handy for backgrounds with offset)
654
\doifelseoverlay
{
#
2
}
%
655
{
\setlayoutcomponentattribute
{
\v!layer
:
#
2
}}
%
656
\resetlayoutcomponentattribute
657
% we have conflicting demands: some mechanisms want ll anchoring .. I need to figure this out
658
% and maybe we will have 'origin=bottom' or so
659
\setbox
\nextbox
660
\ifx
\p_pack_layers_option
\v!test
\ruledvbox
\else
\vpack
\fi
\ifx
\p_pack_layers_method
\v!overlay
to
\d_overlay_height
\fi
\layoutcomponentboxattribute
661
{
\pack_layers_top_fill
662
\hpack
\ifx
\p_pack_layers_method
\v!overlay
to
\d_overlay_width
\fi
663
{
\box
\nextbox
664
\hss
}
%
665
\pack_layers_bottom_fill
}
%
666
% \edef\currentlayer{#2}% :\the\realpageno}% local .. check \anchor
667
% \edef\p_pack_layers_position{\layerparameter\c!position}% local
668
\ifx
\p_pack_layers_position
\v!yes
669
\edef
\p_pack_layers_region
{
\layerparameter
\c!region
}
%
670
\ifx
\p_pack_layers_region
\empty
671
\else
672
\anch_mark_tagged_box
\nextbox
\p_pack_layers_region
% was \layeranchor
673
\fi
674
\fi
675
\box
\nextbox
676
%
677
\ifconditional
\c_pack_layers_repeated
\else
678
\gsetboxllx
\b_layers
\zeropoint
679
\gsetboxlly
\b_layers
\zeropoint
680
\fi
681
\endgroup
}
682 683
\def
\pack_layers_positioned_box_yes
684
{
\vpack
685
{
\vskip
-
\getboxlly
\b_layers
686
\hskip
-
\getboxllx
\b_layers
687
\hsize
-
\dimexpr
\getboxllx
\b_layers
-
\wd
\b_layers
\relax
688
\ifconditional
\c_pack_layers_repeated
\copy\else\box\fi
\b_layers
}}
689 690
\def
\pack_layers_positioned_box_nop
691
{
\ifconditional
\c_pack_layers_repeated
\copy\else\box\fi
\b_layers
}
692 693
% \definelayer[test][method=fit] \setupcolors[state=start,option=test]
694
%
695
% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=10pt]{g}\flushlayer[test]}
696
% \framed[framecolor=red,offset=overlay]{\setlayer[test]{aa}\setlayer[test][x=-10pt]{bb}\flushlayer[test]}
697
% \framed[framecolor=red,offset=overlay]{\setlayer[test][x=-20pt]{cccccc}\flushlayer[test]}
698
% \framed[framecolor=red,offset=overlay]{\setlayer[test]{dd}\setlayer[test][x=-20pt,y=-3pt]{eeeeee}\flushlayer[test]}
699 700
%D \macros
701
%D {composedlayer,placelayer,tightlayer}
702
%D
703
%D This is a handy shortcut, which saves a couple of braces when we use it as
704
%D parameter. This name also suits better to other layering commands.
705 706
\unexpanded
\def
\composedlayer
#
1
{
\flushlayer
[#
1
]
}
707 708
% \unexpanded\def\tightlayer[#1]%
709
% {\hbox
710
% {\def\currentlayer{#1}% todo: left/right
711
% \setbox\nextbox\emptybox
712
% \hsize\layerparameter\c!width
713
% \vsize\layerparameter\c!height
714
% \composedlayer{#1}}}
715 716
\unexpanded
\def
\tightlayer
[#
1
]
%
717
{
\hpack
718
{
\def
\currentlayer
{
#
1
}
% todo: left/right
719
\setbox
\nextbox
\emptybox
720
\d_overlay_width
\layerparameter
\c!width
721
\d_overlay_height
\layerparameter
\c!height
722
\composedlayer
{
#
1
}}}
723 724
\let
\placelayer\flushlayer
725 726
%D \macros
727
%D {setMPlayer}
728
%D
729
%D The following layer macro uses the positions that are registered by \METAPOST.
730
%D
731
%D \starttyping
732
%D \definelayer[test]
733
%D
734
%D \setMPlayer [test] [somepos-1] {Whatever we want here!}
735
%D \setMPlayer [test] [somepos-2] {Whatever we need there!}
736
%D \setMPlayer [test] [somepos-3] {\externalfigure[cow.mps][width=2cm]}
737
%D
738
%D \startuseMPgraphic{oeps}
739
%D draw fullcircle scaled 10cm withcolor red ;
740
%D register ("somepos-1",2cm,3cm,center currentpicture) ;
741
%D register ("somepos-2",8cm,5cm,(-1cm,-2cm)) ;
742
%D register ("somepos-3",0cm,0cm,(-2cm,2cm)) ;
743
%D \stopuseMPgraphic
744
%D
745
%D \getMPlayer[test]{\useMPgraphic{oeps}}
746
%D \stoptyping
747
%D
748
%D The last line is equivalent to
749
%D
750
%D \starttyping
751
%D \framed
752
%D [background={foreground,test},offset=overlay]
753
%D {\useMPgraphic{oeps}}
754
%D \stoptyping
755 756
\unexpanded
\def
\setMPlayer
757
{
\dotripleempty
\pack_layers_set_MP
}
758 759
\def
\MPlayerwidth
{
\hsize
}
760
\def
\MPlayerheight
{
\vsize
}
761 762
\def
\pack_layers_set_MP
[#
1
][#
2
][#
3
]
%
763
{
\edef
\MPlayerwidth
{
\MPw
{
#
2
}}
%
764
\edef
\MPlayerheight
{
\MPh
{
#
2
}}
%
765
\setlayer
[#
1
][
\c!x
=
\MPx
{
#
2
}
,
\c!y
=
\MPy
{
#
2
}
,
\c!position
=
\v!no
,
#
3
]
}
766 767
\unexpanded
\def
\getMPlayer
768
{
\dodoubleempty
\pack_layers_get_MP
}
769 770
\def
\pack_layers_get_MP
[#
1
][#
2
]
%
771
{
\framed
[
\c!background
=
{
\v!foreground
,
#
1
}
,
\c!frame
=
\v!off
,
\c!offset
=
\v!overlay
,
#
2
]
}
% takes argument
772 773
%D Watch out, a redefinition:
774 775
\ifdefined
\settextpagecontent
\else
776
\writestatus
\m!system
{
error
in
page
-
lyr
.
tex
}
\wait
777
\fi
778 779
\definelayer
780
[
OTRTEXT
]
781 782
\setuplayer
783
[
OTRTEXT
]
784
[
\c!width
=
\innermakeupwidth
,
785
\c!height
=
\textheight
]
786 787
\let
\normalsettextpagecontent
\settextpagecontent
% will be overloaded in page-spr
788 789
\unexpanded
\def
\settextpagecontent
#
1
#
2
#
3
% #2 and #3 will disappear
790
{
\doifelselayerdata
{
OTRTEXT
}
791
{
\setbox
#
1
\hpack
to
\makeupwidth
792
{
\startoverlay
793
{
\tightlayer
[
OTRTEXT
]
}
% first, otherwise problems with toc
794
{
\normalsettextpagecontent
{
#
1
}{
#
2
}{
#
3
}
\box
#
1
}
795
\stopoverlay
}
%
796
\dp
#
1
\zeropoint
}
%
797
{
\normalsettextpagecontent
{
#
1
}{
#
2
}{
#
3
}}}
798 799
\protect
\endinput
800