metafun-positioning.tex /size: 35 Kb    last modification: 2023-12-21 09:43
1% language=us runpath=texruns:manuals/metafun
2
3\startcomponent metafun-positioning
4
5\environment metafun-environment
6
7\startchapter[reference=sec:positioning,title={Positional graphics}]
8
9\startintro
10
11In this chapter, we will explore one of the more advanced, but also conceptually
12more difficult, graphic capabilities of \CONTEXT. It took quite a few experiments
13to find the {\em right} way to support these kind of graphics, and you can be
14sure that in due time extensions will show up. You can skip this chapter if you
15are no \CONTEXT\ user. Because we're now a decade into \MKIV\ the tricks here
16will assume that you use \CONTEXT\ \MKIV\ because we have a more convenient
17interface there. For old|-|school \MKII\ usage you can look in old \METAFUN\
18manuals or in the \type {mkii} source files. Of course we remain compatible, it's
19just that more (convenient) interfaces were added.
20
21\stopintro
22
23\startsection[title={The status quo}]
24
25After \TEX\ has read a paragraph of text, it will try to break this paragraph
26into lines. When this is done, the result is flushed and after that \TEX\ will
27check if a page should be split off. As a result, we can hardly predict how a
28document will come out. Therefore, when we want graphics to adapt themselves to
29this text, maybe even to text broken across lines, we have to deal with this
30asynchronous feature of \TEX\ in a rather advanced way. Before we present a way
31of dealing with this complexity, we will elaborate on the nature of embedded
32graphics in \TEX.
33
34When \TEX\ entered the world of typesetting, desktop printers were not that
35common, let alone color desktop printers. But times have changed and nowadays we
36want color and graphics and if possible we want them integrated in the text. When
37\METAPOST\ showed up it depended on the \DVI\ processor to recognize the
38\POSTSCRIPT\ code as being produced by \METAPOST\ and therefore also include the
39fonts that were used. But color was still limited to \RGB. When \PDFTEX\ evolved
40I wrote an interpreter (in \TEX) that could translate the output to \PDF. This
41also opened up the possibility to add features to \METAPOST, like \CMYK\ colors,
42shading, transparencies etc. But basically the \TEX\ and \METAPOST\ processes
43were rather isolated. We could of course pass information to \METAPOST\ and pick
44up information from \METAPOST\ in a second pass. That has changed in \LUATEX.
45
46In order to really integrate \METAPOST\ graphics into the flow you need to know
47where you are on the page and how large graphics should be, especially when you
48want them to depend on the layout. A first solution to this was to embed specials
49in the \DVI\ that could later be used to extract positions. In retrospect this
50was a relative trivial extension, something that could have been around much
51earlier but somehow didn't happen. Anyhow, after some experiments \PDFTEX\ got a
52native position tracker which meant that no post processor was needed. Of course
53\LUATEX\ inherited this feature too. Because positioning is rather bound to the
54macro package reading this chapter only makes sense when you use \CONTEXT.
55
56\stopsection
57
58\startbuffer[arrow:1]
59\startMPpositionmethod{mypos:arrow}
60  \startMPpositiongraphic{mypos:arrow}
61    save pa, pb, pm, pab, na, nb, sa, sb ;
62    path pa, pb, pm, pab ; numeric na, nb ; string sa, sb ;
63    % the tags
64    sa := texstr("from") ; % MPvars
65    sb := texstr("to") ;
66    % we need to check page crossing so we fetch the page numbers
67    na := positionpage(sa) ;
68    nb := positionpage(sb) ;
69    % we use the repositioned shapes
70    pa := positionbox(sa) ;
71    pb := positionbox(sb) ;
72    % but want circles instead of rectangles
73    pa := llcorner pa .. lrcorner pa .. urcorner pa .. ulcorner pa .. cycle ;
74    pb := llcorner pb .. lrcorner pb .. urcorner pb .. ulcorner pb .. cycle ;
75    pickup pencircle scaled 1pt ;
76    if na = nb :
77      % both are on the same page
78      fill pa withcolor .800white ;
79      fill pb withcolor .800white ;
80      draw pa withcolor .625yellow ;
81      draw pb withcolor .625yellow ;
82      pm := .5[center pa,center pb] shifted (0,2*LineHeight) ;
83      pab := center pa  .. pm .. center pb ;
84      pab := pab cutbefore (pab intersectionpoint pa) ;
85      pab := pab cutafter  (pab intersectionpoint pb) ;
86      drawarrow pab dashed evenly withcolor .625red ;
87      positionatanchor(sa) ;
88    elseif nb < na :
89      % they are on different pages and we're at the first one
90      fill pb withcolor .800white ;
91      draw pb withcolor .625yellow ;
92      pab := center pb {up} .. ulcorner bbox pb ;
93      pab := pab cutbefore (pab intersectionpoint pb) ;
94      drawarrow pab dashed evenly withcolor .625red ;
95      positionatanchor(sb) ;
96    else :
97      % they are on different pages and we're at the last one
98      fill pa withcolor .800white ;
99      draw pa withcolor .625yellow ;
100      pab := center pa {up} .. urcorner bbox pa ;
101      pab := pab cutbefore (pab intersectionpoint pa) ;
102      drawarrow pab dashed evenly withcolor .625red ;
103      positionatanchor(sa) ;
104    fi ;
105  \stopMPpositiongraphic
106  % we put it here at the first position
107  \MPpositiongraphic{mypos:arrow}
108  % we need to carry information forward and make sure that we also
109  % check and flush at the second position of the pair
110  \ifnum\MPp{\MPvar{from}}<\MPp{\MPvar{to}}\relax
111    \expanded{\setMPpositiongraphic{\MPvar{to}}{mypos:arrow}{to=\MPvar{from}}}
112  \fi
113\stopMPpositionmethod
114\stopbuffer
115
116\startbuffer[arrow:2]
117\setMPpositiongraphic{A-1}{mypos:arrow}{to=A-2}
118\stopbuffer
119
120\startbuffer[box:1]
121\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
122    string tag; tag := "\MPvar{self}" ;
123    path box ; box := positionbox(tag) ;
124    box := box enlarged  \MPvar{filloffset} ;
125    fill box
126        withcolor \MPvar{fillcolor} ;
127    draw box
128        withcolor \MPvar{linecolor}
129        withpen pencircle scaled \MPvar{linewidth} ;
130    positioninregion ;
131\stopMPpositiongraphic
132\stopbuffer
133
134\startbuffer[box:1:also]
135\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
136    path box ; box := positionbox(texstr("self")) ;
137%     path box ; box := positionbox("\MPvar{self}") ;
138    box := box enlarged  texvar("filloffset") ;
139    fill box
140        withcolor texvar("fillcolor") ;
141    draw box
142        withcolor texvar("linecolor")
143        withpen pencircle scaled texvar("linewidth") ;
144    positioninregion ;
145\stopMPpositiongraphic
146\stopbuffer
147
148\startbuffer[box:2]
149\setupMPvariables
150  [mpos:box]
151  [linecolor=blue,
152   linewidth=\linewidth,
153   fillcolor=lightgray,
154   filloffset=2pt]
155
156\setupMPvariables[mpos:box][linecolor=darkred]
157\setupMPvariables[mpos:par][linecolor=darkred]
158
159\startpositionoverlay{backgraphics}
160  \setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
161  \setMPpositiongraphic{A-3}{mpos:box}{self=A-3}
162  \setMPpositiongraphic{A-4}{mpos:box}{self=A-4}
163\stoppositionoverlay
164\stopbuffer
165
166\getbuffer[arrow:1,arrow:2]
167\getbuffer[box:1,box:2]
168
169\startsection[title={The concept}]
170
171\index {graphics+positioning}
172\index {positioning}
173\index {anchoring}
174
175Because we have a \LUA\ connection in \MPLIB, we have implemented a couple of
176helpers that make live easier. This is also why the following examples are \MKIV\
177specific, although \MKII\ can do the same, but with a bit different set of
178helpers. We can for instance query properties of \hpos {A-0} {positions} without
179using \TEX\ macros but can use \METAPOST\ macros instead. Let's give an example.
180The background and frame behind the word \type {position} in this paragraph is
181not done with \type {\framed} but using a different mechanism:
182
183\starttyping
184to get \hpos {A-0} {positions} sorted
185\stoptyping
186
187The \type {\hpos} refers to a position and we have bound that position to a graphic:
188
189\starttyping
190\setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
191\stoptyping
192
193The graphic itself is defined with:
194
195\typebuffer[box:1]
196
197A variant that has no macro calls and does all via the \LUA\ intercaface in \MKIV\ is
198the following:
199
200\typebuffer[box:1:also]
201
202A \type {\hpos} position has several properties: the coordinates of the origin:
203\type {x} and \type {y}, the dimensions of the boxed content, \type {w}, \type
204{h} and \type {d}, and the page number \type {p}. An additional helper \type
205{positioninregion} will move the drawing to the right spot in the region.
206Examples or regions are the page, text area or some overlay. The \type
207{positionatanchor} variant relocates to the anchor of the given tag. The first
208helper is actually a shortcut for:
209
210\starttyping
211currentpicture := currentpicture shifted - positionxy(positionanchor) ;
212\stoptyping
213
214In our case we use a dedicated layer \type {backgraphics} that we have hooked into
215the page backgrounds:
216
217\starttyping
218\setupbackgrounds
219  [page]
220  [background={backgraphics,foreground,foregraphics}]
221
222\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
223\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
224\stoptyping
225
226The relation between position graphics and that layer are defined as follows
227(we will come back to this in a moment):
228
229\typebuffer[box:2]
230
231\stopsection
232
233\startsection[title={A more detailed view}]
234
235As we know, a decent portion of \TEX's attention is focused on breaking
236paragraphs into lines and determining the optimal point to split off the page.
237Trying to locate the optimal points to break lines is a dynamic process. The
238space between words is flexible and we don't know in advance when a \hpos {A-1}
239{word} or piece of a word |<|maybe it's best to talk of typographic \hpos {A-2}
240{globs} instead|>| will end up on the page. It might even cross the page
241boundary.
242
243In the previous section we saw \hpos {A-3} {word} and \hpos {A-4} {globs}
244encircled and connected by an arrow. This graphic can be drawn only when the
245position and dimensions are known. Unfortunately, this information is only
246available after the paragraph is typeset and the best breakpoints are chosen.
247\bpos {A-5} Because the text must be laid on top of the graphic, the graphic must
248precede the first word in the typeset stream or it must be positioned on a
249separate layer. In the latter case it can be calculated directly after the
250paragraph is typeset, but in the former case a second pass is needed. \epos {A-5}
251Because such graphics are not bound to one paragraph, the multi||pass option
252suits better because it gives us more control: the more we know about he final
253state, the better we can act upon it. Think of graphics on the first page that
254depend on the content of the last page \bpos {A-6} or, as in this paragraph,
255backgrounds that depend on the typeset text. \epos {A-6}
256
257The arrows that connect the shapes are drawn with the following code that now
258looks familiar:
259
260\typebuffer[arrow:1]
261
262and
263
264\typebuffer[arrow:2]
265
266However, here we anchor at one of the positions because we don't flush in a layer
267but at the position itself. Indeed it looks complex.
268
269It may be clear now that we need some positional information in order to provide
270features like the ones shown here. The fact that we will act upon in a second
271pass simplifies the task, although it forces us to store the positional
272information between runs in some place. This may look uncomfortable at first
273sight, but it also enables us to store some additional information. Now why is
274that needed?
275
276A position has no dimensions, it's just a place somewhere on the page. In order
277to do tricks like those shown here, we also need to know the height and depth of
278lines at a specific point as well as the width of the box(es) we're dealing with.
279In the encircled examples, the dimensions of the box following the positional
280node are stored along with the position.
281
282In order to process the graphics, we tag each point with a name, so that we can
283attach actions to those points. In fact they become trigger points. As we will
284demonstrate, we also need to store the current page number. This brings the data
285stored with a point to:
286
287\starttyping
288<identifier> <pagenumber> <x> <y> <width> <height> <depth>
289\stoptyping
290
291Actually we store more information, for example the region in which the positions
292sit. Depending on the use we can also get access to paragraph and line properties
293but discussing these is beyond this manual. These are for instance used in the
294text backgrounds.
295
296The page number is needed in order to let the graphics engine determine boundary
297conditions. Backgrounds like those shown here can span multiple pages. In order
298to calculate the right backgrounds, some additional information must be
299available, like the top and bottom of the current text area. In fact, these are
300just normal points that can be saved while processing the split off page. So,
301apart from positioning anchors in the text we need anchors on crucial points of
302the layout. This means that this kind of support cannot be fully integrated into
303the \TEX\ kernel, unless we also add extensive support for layout definitions,
304and that is probably not what we want.
305
306As soon as something like $(x,y)$ shows up, a logical question is where $(0,0)$
307is located. Although this is a valid question, the answer is less important than
308you may expect. Even if we know that ($0,0)$ is \quote {officially} located in
309the bottom left corner of the page, the simple fact that in \CONTEXT\ we are
310dealing with a mixed page concept, like paper size and print paper size, or left
311and right pages, forces us to think in relative positions instead of absolute
312ones. Therefore, graphics, even those that involve multiple positions, are
313anchored to a position on the layer on which they are located.
314
315Users who simply want to use these features may wonder why we go into so much
316detail. The main reason is that in the end many users will want to go beyond the
317simple cases, and when dealing with these issues, you must be aware not only of
318height, depth and width, but also of the crossing of a page boundary, and the
319height and depth of lines. In some cases your graphics may have to respond to
320layout characteristics, like differences between odd and even pages. Given that
321unique identifiers are used for anchor points, in \CONTEXT\ you can have access
322to all the information needed. Here are some of the helpers:
323
324\starttabulate[|T||]
325\NC positionpath  (tag) \NC the path determined by width, height and depth \NC \NR
326\NC positionxy    (tag) \NC the origin \NC \NR
327\NC positionwhd   (tag) \NC the dimensions (in a triplet) \NC \NR
328\NC positionpage  (tag) \NC the page number fo the position \NC \NR
329\NC positionregion(tag) \NC the region that the position sits in \NC \NR
330\NC positionbox   (tag) \NC the positioned box (path shifted over coordinates) \NC \NR
331\NC positionanchor      \NC the current anchor of the region \NC \NR
332\stoptabulate
333
334The \type {positionwhd} macro returns a triplet that you can query, like:
335
336\starttyping
337triplet whd ; whd := positionwhd("\MPvar{from}");
338numeric wd; wd := wdpart whd ;
339\stoptyping
340
341We will add more such convenient helpers in the future. In the \CONTEXT\
342distribution you can find examples (in manuals or librarties) that demonstrate
343other tricks with positioning.
344
345\stopsection
346
347\startsection[title={Anchors and layers}]
348
349\index{anchoring}
350\index{layers}
351
352\startbuffer[g-circle]
353\startMPpositiongraphic{mypos:circle}
354  path p ; p := positionbox(texstr("self")) ;
355%   path p ; p := positionbox("\MPvar{self}") ;
356  p := fullcircle xsized (bbwidth(p)+4pt) shifted center p ;
357  pickup pencircle scaled 1pt ;
358  fill p withcolor .800white ;
359  draw p withcolor .625yellow ;
360  positioninregion ;
361\stopMPpositiongraphic
362\stopbuffer
363
364\startbuffer[g-line]
365\startMPpositiongraphic{mypos:line}
366  path pa, pb, pab ; numeric na, nb ; string ta, tb ;
367  ta := texstr("from") ; % "\MPvar{from}"
368  tb := texstr("to") ;   % "\MPvar{to}"
369  na := positionpage(ta) ;
370  nb := positionpage(tb) ;
371  pa := positionbox(ta) ;
372  pb := positionbox(tb) ;
373  pa := fullcircle xsized (bbwidth(pa)+4pt) shifted center pa ;
374  pb := fullcircle xsized (bbwidth(pb)+4pt) shifted center pb ;
375  if na = nb :
376    pab := center pa -- center pb ;
377    pab := pab cutbefore (pab intersectionpoint pa) ;
378    pab := pab cutafter  (pab intersectionpoint pb) ;
379    pickup pencircle scaled 1pt ;
380    draw pab withcolor .625yellow ;
381    positioninregion ;
382  fi ;
383\stopMPpositiongraphic
384\stopbuffer
385
386\getbuffer[g-circle,g-line]
387
388\startbuffer[a]
389\setMPpositiongraphic{X-1}{mypos:arrow}{to=X-2}
390\setMPpositiongraphic{X-2}{mypos:arrow}{to=X-3}
391\stopbuffer
392
393\startbuffer[b]
394In a previous section we saw that some \hpos {X-1} {words} were
395\hpos {X-2} {circled} and connected by an \hpos {X-3} {arrow}.
396As with most things in \CONTEXT, marking these words is separated
397from declaring what to do with those words. This paragraph is keyed
398in as:
399\stopbuffer
400
401\getbuffer[a,b]
402
403\typebuffer[b]
404
405We see three position anchors, each marked by an identifier: \type {X-1}, \type
406{X-2} and \type {X-3}. Each of these anchors can be associated with a (series) of
407graphic operations. Here we defined:
408
409\typebuffer[a]
410
411These examples clearly demonstrate that we cannot control to what extent graphics
412will cover text and vice versa. A solution to this problem is using position
413overlays. We can define such an overlay as follows:
414
415\startbuffer
416\startpositionoverlay{backgraphics}
417  \setMPpositiongraphic{G-1}{mypos:circle}
418  \setMPpositiongraphic{G-2}{mypos:circle}
419  \setMPpositiongraphic{G-3}{mypos:circle}
420  \setMPpositiongraphic{G-4}{mypos:circle}
421\stoppositionoverlay
422
423\startpositionoverlay{foregraphics}
424  \setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
425  \setMPpositiongraphic{G-2}{mypos:line}{to=G-3}
426  \setMPpositiongraphic{G-3}{mypos:line}{to=G-4}
427\stoppositionoverlay
428\stopbuffer
429
430\getbuffer \typebuffer
431
432\startbuffer
433First we have defined an \hpos {G-1} {\strut overlay}. This
434overlay can be attached to some overlay layer, like, in our
435case, the \hpos {G-2} {\strut page}. We define four small \hpos
436{G-3} {\strut circles}. These are drawn as soon as the page
437overlay is typeset. Because they are located in the
438background, they don't cover the \hpos {G-4} {\strut text}, while
439the lines do. The previous paragraph was typeset by saying:
440\stopbuffer
441
442\getbuffer \typebuffer
443
444As said, the circles are on the background layer, but the lines are not! They are
445positioned on top of the text. This is a direct result of the definition of the
446page background:
447
448\starttyping
449\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
450\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
451
452\setupbackgrounds
453  [page]
454  [background={backgraphics,foreground,foregraphics}]
455\stoptyping
456
457\doifmode{screen}{\writestatus{CHECK}{POSITION GRAPHICS}}
458
459In this definition, the predefined overlay \type {foreground} inserts the page
460data itself, so the foreground graphics end up on top. This example also
461demonstrates that you should be well aware of the way \CONTEXT\ builds a page.
462There are six main layers, in some cases with sublayers. The body text goes into
463the main text layer, which, unless forced otherwise, lays on top.
464
465\startitemize[packed,n,columns,three]
466\item  paper background
467\item  area backgrounds
468\item  page backgrounds
469\item  text areas
470\item  logo areas
471\item  main text
472\stopitemize
473
474The paper background is used for special (sometimes internal) purposes. There are
475three page backgrounds: left, right and both. The text areas, logo areas and
476backgrounds form a $5 \times 5$ matrix with columns containing the leftedge,
477leftmargin, text, rightmargin, and rightedge. The rows of the matrix contain the
478top, header, text, footer, and bottom. The main text is what you are reading now.
479
480Since the page background is applied last, the previous layers can be considered
481to be the foreground to the page background layer. And, indeed, it is available
482as an overlay under the name \type {foreground}, as we already saw in the
483example. Foregrounds are available in most cases, but (for the moment) not when
484we are dealing with the text area. Since anchoring the graphics is implemented
485rather independent of the position of the graphics themselves, this is no real
486problem, we can put them all on the page layer, if needed in separate overlays.
487
488How is such a graphic defined? In fact these graphics are a special case of the
489already present mechanism of including \METAPOST\ graphics. The circles are
490defined as follows:
491
492\typebuffer[g-circle]
493
494Drawing the lines is handled in a similar fashion.
495
496\typebuffer[g-line]
497
498The command \tex {startMPpositiongraphic} defines a graphic, in this example we
499have called it \type {mypos:circle}. Here we show the definition out of order but
500normally you need to define it before you refer to it.
501
502The \METAPOST\ macro \type {positionbox} returns a box that is constructed from
503the coordinates and dimensions. After this call, the corners are available via
504\type {llcorner}, \type {lrcorner}, \type {urcorner} and \type {ulcorner}. The
505center is accessible by \type {center}. When we are finished drawing the graphic,
506we can anchor the result with \type {positioninregion}. This macro automatically
507handles positioning on specific layers. The helper macros are not loaded by
508default, you do that with:
509
510\typebuffer[g-include]
511
512The position macro \type {\MPpos} returns the current characteristics of a
513position. The previously defined G~positions return:
514
515\starttabulate[|c|c|c|c|c|c|c|]
516\HL
517\NC position\NC page\NC$x$\NC$y$\NC width\NC height\NC depth\NC\NR
518\HL
519\NC G-1\NC\MPp{G-1}\NC\MPx{G-1}\NC\MPy{G-1}\NC\MPw{G-1}\NC\MPh{G-1}\NC\MPd{G-1}\NC\NR
520\NC G-2\NC\MPp{G-2}\NC\MPx{G-2}\NC\MPy{G-2}\NC\MPw{G-2}\NC\MPh{G-2}\NC\MPd{G-2}\NC\NR
521\NC G-3\NC\MPp{G-3}\NC\MPx{G-3}\NC\MPy{G-3}\NC\MPw{G-3}\NC\MPh{G-3}\NC\MPd{G-3}\NC\NR
522\NC G-4\NC\MPp{G-4}\NC\MPx{G-4}\NC\MPy{G-4}\NC\MPw{G-4}\NC\MPh{G-4}\NC\MPd{G-4}\NC\NR
523\HL
524\stoptabulate
525
526The numbers represent the real pagenumber~$p$, the current position $(x,y)$, and
527the dimensions of the box $(w,h,d)$ if known. These values are fed directly into
528\METAPOST\ graphics but the individual components can be asked for by \type
529{\MPp}, \type {\MPx}, \type {\MPy}, \type {\MPw}, \type {\MPh} and \type {\MPd}.
530
531In the previous definition of the graphic, we saw another macro, \type {\MPvar}.
532When we invoke a graphic or attach a graphic to a layer, we can pass variables.
533We can also set specific variables in other ways, as we will see later.
534
535\starttyping
536\setMPpositiongraphic{G-1}{mypos:circle}
537\setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
538\stoptyping
539
540In the second definition, we let the variable \type {to} point to another
541position. When needed, we can ask for the value of \type {to} by \type
542{\MPvar{to}}. For reasons of convenience, the current position is assigned
543automatically to \type {from} and \type {self}. This means that in the line we
544saw in the graphic:
545
546\starttyping
547path p ; p := positionbox(texstr("self")) ;
548% path p ; p := positionbox("\MPvar{self}") ;
549\stoptyping
550
551\type {texstr("self")} will return the current position, which, fed to \type
552{positionbox} will return a box with the right dimensions. We already warned the
553reader: this is not an easy chapter.
554
555\stopsection
556
557\startsection[title={More layers}]
558
559\index{layers}
560
561\setupbackgrounds
562  [state=repeat]
563
564Overlays are one of the nicer features of \CONTEXT\ and even more nice things can
565be build on top of them. Overlays are defined first and then assigned to framed
566boxes using the \type {background} variable.
567
568You can stack overlays, which is why they are called as such. You can use the
569special overlay called \type {foreground} to move the topmost (often text) layer
570down in the stack.
571
572\starttabulate
573\HL
574\NC background overlay \NC a text, graphic, hyperlink or widget      \NC \NR
575\NC position overlay   \NC a series of macros triggered by positions \NC \NR
576\NC background layer   \NC a box that can hold boxes with offsets    \NC \NR
577\HL
578\stoptabulate
579
580The last kind of layer can be used in other situations as well, but in most cases
581it will be hooked into a background overlay.
582
583\startbuffer
584\definelayer[MyLayer][option=test]
585
586\setupbackgrounds[text][leftmargin][background=MyLayer]
587
588\setlayer[MyLayer][x=.5cm,y=5cm]
589  {\rotate{\framed{This goes to the background}}}
590\stopbuffer
591
592\typebuffer \getbuffer \setuplayer[MyLayer][option=] % no frames
593
594In this case the framed text will be placed in the background of the (current)
595page with the given offset to the topleft corner. Instead of a fixed position,
596you can inherit the current position using the \type {position} directive. Say
597that we have a layer called \type {YourLayer} which we put in the background of
598the text area.
599
600\startbuffer
601\definelayer[YourLayer]
602\setupbackgrounds[text][text][background=YourLayer]
603\stopbuffer
604
605\typebuffer \getbuffer
606
607We can now move some framed text to this layer using \type {\setlayer} with the
608directive \type {position} set to \type {yes}.
609
610\startbuffer
611here: \setlayer[YourLayer][position=yes]{\inframed{Here}}
612\stopbuffer
613
614\typebuffer
615
616You can influence the placement by explicitly providing an offset (\type
617{hoffset} and|/|or \type {voffset}), a position (\type {x} and|/|or \type {y}) or
618a location directive (\type {location}). Normally you will use the offsets for
619the layer as a whole and the positions for individual contributions. The next
620example demonstrates the use of a location directive.
621
622\startbuffer
623here: \setlayer[YourLayer][position=yes,location=c]{\inframed{Here}}
624\stopbuffer
625
626\typebuffer \getbuffer
627
628Many layers can be in use at the same time. In the next example we put something
629in the page layer. By default, we turn on position tracking, which visualizes the
630bounding box of the content and shows the reference point.
631
632\startbuffer
633\definelayer[BackLayer][position=yes]
634\setupbackgrounds[page][background=BackLayer]
635\stopbuffer
636
637\typebuffer \getbuffer
638
639\setupbackgrounds
640  [page]
641  [background={PageFrame,BackLayer,backgraphics,foreground,foregraphics}]
642
643Next we define an overlay that we can put behind for instance framed texts. We
644use \METAPOST\ to draw \type {Shape}.
645
646\startbuffer
647\defineoverlay[Shape] [BackLayer] [\uniqueMPgraphic{Shape}]
648
649\startuniqueMPgraphic{Shape}
650  path p ; p := fullcircle xyscaled(OverlayWidth,OverlayHeight) ;
651  fill p withcolor \MPcolor{lightgray} ;
652  draw p withpen pencircle scaled 1pt withcolor \MPcolor{darkred} ;
653\stopuniqueMPgraphic
654\stopbuffer
655
656\typebuffer \getbuffer
657
658\startbuffer[def]
659\defineframed[Shaped][background=Shape,frame=off,location=low]
660\stopbuffer
661
662\getbuffer[def]
663
664We can now put this background shape behind the running text, for instance with:
665
666\startbuffer
667.... some \inframed[background=Shape]{text} with a frame ...
668.... some \Shaped{text} with a frame ...
669\stopbuffer
670
671\typebuffer
672
673\startlines
674\getbuffer
675\stoplines
676
677The \type {\Shaped} macro was defined as:
678
679\typebuffer[def]
680
681Watch how the graphics are moved to the background while the frame of the first
682text stays on top, since it remains part of the text flow.
683
684\startbuffer[def]
685\setuplayer[BackLayer][direction=reverse]
686\stopbuffer
687
688\getbuffer[def]
689
690\startlines
691\getbuffer
692\stoplines
693
694In the previous instance of the example we have reversed the stacking. Reversal
695can be done with the \type {direction} directive.
696
697\typebuffer[def]
698
699% next series
700
701\startbuffer
702\setuplayer
703  [BackLayer]
704  [position=no,corner=bottom,height=\paperheight]
705
706\setlayer[BackLayer][x=2cm,y=10cm,location=bl]
707  {\externalfigure[somecow.pdf][width=1cm]}
708
709\setlayer[BackLayer][x=1cm,y=8cm,location=br]
710  {\externalfigure[somecow.pdf][width=1cm]}
711
712\setlayer[BackLayer][x=2cm,y=4cm,location=tl]
713  {\externalfigure[somecow.pdf][width=1cm]}
714
715\setlayer[BackLayer][x=10cm,y=1cm,location=tr]
716  {\externalfigure[somecow.pdf][width=1cm]}
717\stopbuffer
718
719You can influence the placement of a background component by using a different
720anchor point.
721
722\typebuffer {\setuplayer[option=test]\getbuffer}
723
724\startbuffer[xx]
725\setuplayer
726  [BackLayer]
727  [position=no,corner=bottom,height=\paperheight]
728
729\setlayer[BackLayer][x=15cm,y=5cm,location=bl]
730  {\externalfigure[somecow.pdf][width=3cm]}
731
732\setlayer[BackLayer][x=15cm,y=5cm,location=br]
733  {\externalfigure[somecow.pdf][width=3cm]}
734
735\setlayer[BackLayer][x=15cm,y=5cm,location=tl]
736  {\externalfigure[somecow.pdf][width=2cm]}
737
738\setlayer[BackLayer][x=15cm,y=5cm,location=tr]
739  {\externalfigure[somecow.pdf][width=2cm]}
740
741\setlayer[BackLayer][x=15cm,y=5cm,location=c]
742  {\externalfigure[somecow.pdf][width=3cm]}
743\stopbuffer
744
745% \startpostponing
746
747Instead of using relative positions, you can also use absolute ones. Of course
748you need to know how your coordinates relate to the rest of the layout
749definition.
750
751\typebuffer[xx]
752
753These examples again demonstrate how we can influence the placement by assigning
754an anchor point to \type {position}. Here we also put the reference point in the
755lower left corner (\type {bottom}). This mechanism only works when we also use
756\type {height}.
757
758{\setuplayer[option=test]\getbuffer[xx]}
759
760\page
761
762% \stoppostponing
763
764\setupbackgrounds
765  [page]
766  [background={PageFrame,DemoLayer,backgraphics,foreground,foregraphics}]
767
768\definelayer
769  [DemoLayer]
770  [position=yes]
771
772\startbuffer
773\definelayer
774  [DemoLayer]
775  [position=yes]
776
777\startplacefigure[title={Demo 1}]
778    \ruledhbox\bgroup
779        \setlayerframed
780            [DemoLayer] [hoffset=-10mm,voffset=5mm]
781            {\startMPcode
782                fill fullcircle scaled 2cm withcolor .625red ;
783             \stopMPcode}%
784        \setlayerframed
785            [DemoLayer] [voffset=-10mm]
786            {\startMPcode
787                fill fullcircle scaled 2cm withcolor .625green ;
788             \stopMPcode}%
789        \setlayerframed
790            [DemoLayer] [hoffset=10mm,voffset=5mm]
791            {\startMPcode
792                fill fullcircle scaled 2cm withcolor .625blue ;
793             \stopMPcode}%
794    \egroup
795\stopplacefigure
796\stopbuffer
797
798\getbuffer
799
800One of the reasons for developing the layer mechanism was that we needed to
801slightly change the position of figures in the final stage of typesetting. The
802previous pages demonstrate how one can position anything anywhere on the page,
803but in the case of figures the position may depend on where the text ends up on
804the page.
805
806Normally, when you manipulate a document this way, you are in the final stage of
807typesetting. You may qualify this as desk top publishing without actually using a
808desktop.
809
810\typebuffer
811
812\page
813
814\startbuffer[demo]
815\startbuffer
816\setlayer [DemoLayer]
817  [position=yes,
818   voffset=-1.5cm,
819   width=3cm,
820   height=2cm]
821  {\MPfigure{somecow.pdf}{scaled .5 slanted .5}}
822\stopbuffer
823
824\placefigure[right]{}{\ruledhbox{\getbuffer}}
825\stopbuffer
826
827{\setuplayer[option=test]\getbuffer[demo]}
828
829The previous example also demonstrated the use of \METAPOST\ for rotating the
830picture. The \type {\MPfigure} macro encapsulates the code in a shortcut. You can
831achieve special effects by using the layers behind floating bodies and alike, but
832always keep in mind that the readability of the text should not be violated too
833much.
834
835\typebuffer[demo]
836
837In these examples we added a \type {\ruledhbox} around the pseudo graphics so
838that you can see what the size is of those graphics.
839
840% summary
841
842We have already seen a lot of parameters that can be used to control the content
843of a layer. There are a few more. General housekeeping takes place with:
844
845\starttabulate[|Tl|Tl|l|]
846\HL
847\NC state     \NC start   \NC enable the layer            \NC \NR
848\NC           \NC stop    \NC disable the layer           \NC \NR
849\NC position  \NC no      \NC use absolute positions      \NC \NR
850\NC           \NC yes     \NC use relative positions      \NC \NR
851\NC           \NC overlay \NC idem, but ignore the size   \NC \NR
852\NC direction \NC normal  \NC put new data on top         \NC \NR
853\NC           \NC reverse \NC put new data below old data \NC \NR
854\HL
855\stoptabulate
856
857Sometimes all data needs to be offset in a similar way. You can use both offset
858parameters for that.
859
860\starttabulate[|Tl|l|]
861\HL
862\NC hoffset \NC an additional horizontal displacement \NC \NR
863\NC voffset \NC an additional vertical   displacement \NC \NR
864\HL
865\stoptabulate
866
867You can position data anywhere in the layer. When positioning is turned on, the
868current position will get a placeholder. You can change the dimensions of that
869placeholder (when \type {position} is set to \type {overlay}), zero dimensions
870are used.
871
872\starttabulate[|Tl|l|]
873\HL
874\NC x        \NC the horizontal displacement \NC \NR
875\NC y        \NC the vertical   displacement \NC \NR
876\NC width    \NC the (non natural) width     \NC \NR
877\NC height   \NC the (non natural) height    \NC \NR
878\NC location \NC \tttf l r t b c lt lb rt rb \NC \NR
879\HL
880\stoptabulate
881
882The \type {location} directive determines what point of the data is used as
883reference point. You can keep track of this point and the placement when you
884enable test mode. This is how the rectangles in the previous examples were
885drawn.
886
887\starttabulate[|Tl|Tl|l|]
888\HL
889\NC option \NC test \NC show positioning information \NC \NR
890\HL
891\stoptabulate
892
893When you are enhancing the final version of a document, you can explicitly
894specify on what page the data will go. Use this option with care.
895
896\starttabulate[|Tl|l|]
897\HL
898\NC page \NC the page where the data will go \NC \NR
899\HL
900\stoptabulate
901
902Because layers can migrate to other pages, they may disappear due to the
903background not being recalculated. In case of doubt, you can force repetitive
904background calculation by:
905
906\starttyping
907\setupbackgrounds[state=repeat]
908\stoptyping
909
910% restore 'm
911
912\setupbackgrounds
913  [page]
914  [background={PageFrame,backgraphics,foreground,foregraphics}]
915
916\setupbackgrounds
917  [state=start]
918
919\stopsection
920
921\startsection[title={Complex text in graphics}]
922
923\index{text}
924
925If you like to embed \METAPOST\ snippets in \CONTEXT, you may want to combine
926text and graphics and let \METAPOST\ provide the position and the dimensions of
927the text to be typeset outside by \TEX. For most applications using the \METAFUN\
928\type {textext} macro works well enough, but when the typeset text needs to
929communicate with the typesetting engine, for instance because it contains
930hyperlinks or references, you can use the following method:
931
932\startitemize[packed]
933\item define a layer
934\item define a (reusable) graphic
935\item put your text into the layer
936\item combine the graphic with the text
937\stopitemize
938
939You must be aware of the fact that when the layer is flushed, its content is
940gone. You can take advantage of this by using the same graphic with multiple
941texts.
942
943\startbuffer
944\definelayer[test]
945\stopbuffer
946
947\typebuffer \getbuffer
948
949You don't need to pass the width and height explicitly, but when you do so, you
950have access to them later.
951
952\startbuffer
953\startuseMPgraphic{oeps}
954  path p ; p := fullcircle scaled 6cm ;
955  fill p withcolor .8white ;
956  draw p withpen pencircle scaled 1mm withcolor .625red ;
957  register ("somepos-1",0cm,0cm,center currentpicture) ;
958  register ("somepos-2",3cm,1cm,(-1cm,-1cm)) ;
959  register ("somepos-3",2cm,0cm,(-2cm,2cm)) ;
960\stopuseMPgraphic
961\stopbuffer
962
963\typebuffer \getbuffer
964
965The \METAFUN\ \type {register} macro takes the following arguments:
966
967\starttyping
968register ("tag",width,height,(x offset,y offset)) ;
969\stoptyping
970
971The width and height are available in the macros \type {\MPlayerwidth} and \type
972{\MPlayerheight} and are equivalent to \type {\MPw{tag}} and \type {\MPh{tag}},
973
974\startbuffer
975\setMPlayer [test] [somepos-1] [location=c]
976  {Does it work al right?}
977
978\setMPlayer [test] [somepos-2]
979  {\framed
980     [width=\MPlayerwidth,height=\MPlayerheight,
981      background=color,backgroundcolor=white]
982     {It Works!}}
983
984\setMPlayer [test] [somepos-3]
985  {\externalfigure[cow-fun.mps][width=2cm]}
986\stopbuffer
987
988\typebuffer \getbuffer
989
990Combining the graphic and the text is handled by the macro \type {\getMPlayer}.
991
992\startbuffer
993\getMPlayer [test] {\useMPgraphic{oeps}}
994\stopbuffer
995
996\typebuffer \getbuffer
997
998The macro \type {\getMPlayer} is built on top of \type {\framed}. The settings
999passed in the (optional) second argument are the same as those to \type
1000{\framed}.
1001
1002\starttyping
1003\getMPlayer
1004  [test]
1005  [frame=on,offset=5pt]
1006  {\useMPgraphic{oeps}}
1007\stoptyping
1008
1009As you see, you need a bit of a twisted mind to handle graphics this way, but at
1010least the functionality is there to create complex graphics in a declarative way.
1011
1012\stopsection
1013
1014\stopchapter
1015
1016\stopcomponent
1017