summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/metafun/metafun-positioning.tex
blob: 5f18b3ee633f36b5ebdc2db2c1c72ea0b056cc0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
% language=us runpath=texruns:manuals/metafun

\startcomponent metafun-positioning

\environment metafun-environment

\startchapter[reference=sec:positioning,title={Positional graphics}]

\startintro

In this chapter, we will explore one of the more advanced, but also conceptually
more difficult, graphic capabilities of \CONTEXT. It took quite a few experiments
to find the {\em right} way to support these kind of graphics, and you can be
sure that in due time extensions will show up. You can skip this chapter if you
are no \CONTEXT\ user. Because we're now a decade into \MKIV\ the tricks here
will assume that you use \CONTEXT\ \MKIV\ because we have a more convenient
interface there. For old|-|school \MKII\ usage you can look in old \METAFUN\
manuals or in the \type {mkii} source files. Of course we remain compatible, it's
just that more (convenient) interfaces were added.

\stopintro

\startsection[title={The status quo}]

After \TEX\ has read a paragraph of text, it will try to break this paragraph
into lines. When this is done, the result is flushed and after that \TEX\ will
check if a page should be split off. As a result, we can hardly predict how a
document will come out. Therefore, when we want graphics to adapt themselves to
this text, maybe even to text broken across lines, we have to deal with this
asynchronous feature of \TEX\ in a rather advanced way. Before we present a way
of dealing with this complexity, we will elaborate on the nature of embedded
graphics in \TEX.

When \TEX\ entered the world of typesetting, desktop printers were not that
common, let alone color desktop printers. But times have changed and nowadays we
want color and graphics and if possible we want them integrated in the text. When
\METAPOST\ showed up it depended on the \DVI\ processor to recognize the
\POSTSCRIPT\ code as being produced by \METAPOST\ and therefore also include the
fonts that were used. But color was still limited to \RGB. When \PDFTEX\ evolved
I wrote an interpreter (in \TEX) that could translate the output to \PDF. This
also opened up the possibility to add features to \METAPOST, like \CMYK\ colors,
shading, transparencies etc. But basically the \TEX\ and \METAPOST\ processes
were rather isolated. We could of course pass information to \METAPOST\ and pick
up information from \METAPOST\ in a second pass. That has changed in \LUATEX.

In order to really integrate \METAPOST\ graphics into the flow you need to know
where you are on the page and how large graphics should be, especially when you
want them to depend on the layout. A first solution to this was to embed specials
in the \DVI\ that could later be used to extract positions. In retrospect this
was a relative trivial extension, something that could have been around much
earlier but somehow didn't happen. Anyhow, after some experiments \PDFTEX\ got a
native position tracker which meant that no post processor was needed. Of course
\LUATEX\ inherited this feature too. Because positioning is rather bound to the
macro package reading this chapter only makes sense when you use \CONTEXT.

\stopsection

\startbuffer[arrow:1]
\startMPpositionmethod{mypos:arrow}
  \startMPpositiongraphic{mypos:arrow}
    save pa, pb, pm, pab, na, nb, sa, sb ;
    path pa, pb, pm, pab ; numeric na, nb ; string sa, sb ;
    % the tags
    sa := texstr("from") ;
    sb := texstr("to") ;
    % we need to check page crossing so we fetch the page numbers
    na := positionpage(sa) ;
    nb := positionpage(sb) ;
    % we use the repositioned shapes
    pa := positionbox(sa) ;
    pb := positionbox(sb) ;
    % but want circles instead of rectangles
    pa := llcorner pa .. lrcorner pa .. urcorner pa .. ulcorner pa .. cycle ;
    pb := llcorner pb .. lrcorner pb .. urcorner pb .. ulcorner pb .. cycle ;
    pickup pencircle scaled 1pt ;
    if na = nb :
      % both are on the same page
      fill pa withcolor .800white ;
      fill pb withcolor .800white ;
      draw pa withcolor .625yellow ;
      draw pb withcolor .625yellow ;
      pm := .5[center pa,center pb] shifted (0,2*LineHeight) ;
      pab := center pa  .. pm .. center pb ;
      pab := pab cutbefore (pab intersectionpoint pa) ;
      pab := pab cutafter  (pab intersectionpoint pb) ;
      drawarrow pab dashed evenly withcolor .625red ;
      positionatanchor(sa) ;
    elseif nb < na :
      % they are on different pages and we're at the first one
      fill pb withcolor .800white ;
      draw pb withcolor .625yellow ;
      pab := center pb {up} .. ulcorner bbox pb ;
      pab := pab cutbefore (pab intersectionpoint pb) ;
      drawarrow pab dashed evenly withcolor .625red ;
      positionatanchor(sb) ;
    else :
      % they are on different pages and we're at the last one
      fill pa withcolor .800white ;
      draw pa withcolor .625yellow ;
      pab := center pa {up} .. urcorner bbox pa ;
      pab := pab cutbefore (pab intersectionpoint pa) ;
      drawarrow pab dashed evenly withcolor .625red ;
      positionatanchor(sa) ;
    fi ;
  \stopMPpositiongraphic
  % we put it here at the first position
  \MPpositiongraphic{mypos:arrow}
  % we need to carry information forward and make sure that we also
  % check and flush at the second position of the pair
  \ifnum\MPp{\MPvar{from}}<\MPp{\MPvar{to}}\relax
    \expanded{\setMPpositiongraphic{\MPvar{to}}{mypos:arrow}{to=\MPvar{from}}}
  \fi
\stopMPpositionmethod
\stopbuffer

\startbuffer[arrow:2]
\setMPpositiongraphic{A-1}{mypos:arrow}{to=A-2}
\stopbuffer

\startbuffer[box:1]
\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
    string tag; tag := "\MPvar{self}" ;
    path box ; box := positionbox(tag) ;
    box := box enlarged  \MPvar{filloffset} ;
    fill box
        withcolor \MPvar{fillcolor} ;
    draw box
        withcolor \MPvar{linecolor}
        withpen pencircle scaled \MPvar{linewidth} ;
    positioninregion ;
\stopMPpositiongraphic
\stopbuffer

\startbuffer[box:1:also]
\startMPpositiongraphic{mpos:box}{fillcolor,linecolor,linewidth}
    path box ; box := positionbox(texstr("self")) ;
    box := box enlarged  texvar("filloffset") ;
    fill box
        withcolor texvar("fillcolor") ;
    draw box
        withcolor texvar("linecolor")
        withpen pencircle scaled texvar("linewidth") ;
    positioninregion ;
\stopMPpositiongraphic
\stopbuffer

\startbuffer[box:2]
\setupMPvariables
  [mpos:box]
  [linecolor=blue,
   linewidth=\linewidth,
   fillcolor=lightgray,
   filloffset=2pt]

\setupMPvariables[mpos:box][linecolor=darkred]
\setupMPvariables[mpos:par][linecolor=darkred]

\startpositionoverlay{backgraphics}
  \setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
  \setMPpositiongraphic{A-3}{mpos:box}{self=A-3}
  \setMPpositiongraphic{A-4}{mpos:box}{self=A-4}
\stoppositionoverlay
\stopbuffer

\getbuffer[arrow:1,arrow:2]
\getbuffer[box:1,box:2]

\startsection[title={The concept}]

\index {graphics+positioning}
\index {positioning}
\index {anchoring}

Because we have a \LUA\ connection in \MPLIB, we have implemented a couple of
helpers that make live easier. This is also why the following examples are \MKIV\
specific, although \MKII\ can do the same, but with a bit different set of
helpers. We can for instance query properties of \hpos {A-0} {positions} without
using \TEX\ macros but can use \METAPOST\ macros instead. Let's give an example.
The background and frame behind the word \type {position} in this paragraph is
not done with \type {\framed} but using a different mechanism:

\starttyping
to get \hpos {A-0} {positions} sorted
\stoptyping

The \type {\hpos} refers to a position and we have bound that position to a graphic:

\starttyping
\setMPpositiongraphic{A-0}{mpos:box}{self=A-0}
\stoptyping

The graphic itself is defined with:

\typebuffer[box:1]

A variant that has no macro calls and does all via the \LUA\ intercaface in \MKIV\ is
the following:

\typebuffer[box:1:also]

A \type {\hpos} position has several properties: the coordinates of the origin:
\type {x} and \type {y}, the dimensions of the boxed content, \type {w}, \type
{h} and \type {d}, and the page number \type {p}. An additional helper \type
{positioninregion} will move the drawing to the right spot in the region.
Examples or regions are the page, text area or some overlay. The \type
{positionatanchor} variant relocates to the anchor of the given tag. The first
helper is actually a shortcut for:

\starttyping
currentpicture := currentpicture shifted - positionxy(positionanchor) ;
\stoptyping

In our case we use a dedicated layer \type {backgraphics} that we have hooked into
the page backgrounds:

\starttyping
\setupbackgrounds
  [page]
  [background={backgraphics,foreground,foregraphics}]

\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]
\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
\stoptyping

The relation between position graphics and that layer are defined as follows
(we will come back to this in a moment):

\typebuffer[box:2]

\stopsection

\startsection[title={A more detailed view}]

As we know, a decent portion of \TEX's attention is focused on breaking
paragraphs into lines and determining the optimal point to split off the page.
Trying to locate the optimal points to break lines is a dynamic process. The
space between words is flexible and we don't know in advance when a \hpos {A-1}
{word} or piece of a word |<|maybe it's best to talk of typographic \hpos {A-2}
{globs} instead|>| will end up on the page. It might even cross the page
boundary.

In the previous section we saw \hpos {A-3} {word} and \hpos {A-4} {globs}
encircled and connected by an arrow. This graphic can be drawn only when the
position and dimensions are known. Unfortunately, this information is only
available after the paragraph is typeset and the best breakpoints are chosen.
\bpos {A-5} Because the text must be laid on top of the graphic, the graphic must
precede the first word in the typeset stream or it must be positioned on a
separate layer. In the latter case it can be calculated directly after the
paragraph is typeset, but in the former case a second pass is needed. \epos {A-5}
Because such graphics are not bound to one paragraph, the multi||pass option
suits better because it gives us more control: the more we know about he final
state, the better we can act upon it. Think of graphics on the first page that
depend on the content of the last page \bpos {A-6} or, as in this paragraph,
backgrounds that depend on the typeset text. \epos {A-6}

The arrows that connect the shapes are drawn with the following code that now
looks familiar:

\typebuffer[arrow:1]

and

\typebuffer[arrow:2]

However, here we anchor at one of the positions because we don't flush in a layer
but at the position itself. Indeed it looks complex.

It may be clear now that we need some positional information in order to provide
features like the ones shown here. The fact that we will act upon in a second
pass simplifies the task, although it forces us to store the positional
information between runs in some place. This may look uncomfortable at first
sight, but it also enables us to store some additional information. Now why is
that needed?

A position has no dimensions, it's just a place somewhere on the page. In order
to do tricks like those shown here, we also need to know the height and depth of
lines at a specific point as well as the width of the box(es) we're dealing with.
In the encircled examples, the dimensions of the box following the positional
node are stored along with the position.

In order to process the graphics, we tag each point with a name, so that we can
attach actions to those points. In fact they become trigger points. As we will
demonstrate, we also need to store the current page number. This brings the data
stored with a point to:

\starttyping
<identifier> <pagenumber> <x> <y> <width> <height> <depth>
\stoptyping

Actually we store more information, for example the region in which the positions
sit. Depending on the use we can also get access to paragraph and line properties
but discussing these is beyond this manual. These are for instance used in the
text backgrounds.

The page number is needed in order to let the graphics engine determine boundary
conditions. Backgrounds like those shown here can span multiple pages. In order
to calculate the right backgrounds, some additional information must be
available, like the top and bottom of the current text area. In fact, these are
just normal points that can be saved while processing the split off page. So,
apart from positioning anchors in the text we need anchors on crucial points of
the layout. This means that this kind of support cannot be fully integrated into
the \TEX\ kernel, unless we also add extensive support for layout definitions,
and that is probably not what we want.

As soon as something like $(x,y)$ shows up, a logical question is where $(0,0)$
is located. Although this is a valid question, the answer is less important than
you may expect. Even if we know that ($0,0)$ is \quote {officially} located in
the bottom left corner of the page, the simple fact that in \CONTEXT\ we are
dealing with a mixed page concept, like paper size and print paper size, or left
and right pages, forces us to think in relative positions instead of absolute
ones. Therefore, graphics, even those that involve multiple positions, are
anchored to a position on the layer on which they are located.

Users who simply want to use these features may wonder why we go into so much
detail. The main reason is that in the end many users will want to go beyond the
simple cases, and when dealing with these issues, you must be aware not only of
height, depth and width, but also of the crossing of a page boundary, and the
height and depth of lines. In some cases your graphics may have to respond to
layout characteristics, like differences between odd and even pages. Given that
unique identifiers are used for anchor points, in \CONTEXT\ you can have access
to all the information needed. Here are some of the helpers:

\starttabulate[|T||]
\NC positionpath  (tag) \NC the path determined by width, height and depth \NC \NR
\NC positionxy    (tag) \NC the origin \NC \NR
\NC positionwhd   (tag) \NC the dimensions (in a triplet) \NC \NR
\NC positionpage  (tag) \NC the page number fo the position \NC \NR
\NC positionregion(tag) \NC the region that the position sits in \NC \NR
\NC positionbox   (tag) \NC the positioned box (path shifted over coordinates) \NC \NR
\NC positionanchor      \NC the current anchor of the region \NC \NR
\stoptabulate

The \type {positionwhd} macro returns a triplet that you can query, like:

\starttyping
triplet whd ; whd := positionwhd("\MPvar{from}");
numeric wd; wd := wdpart whd ;
\stoptyping

We will add more such convenient helpers in the future. In the \CONTEXT\
distribution you can find examples (in manuals or librarties) that demonstrate
other tricks with positioning.

\stopsection

\startsection[title={Anchors and layers}]

\index{anchoring}
\index{layers}

\startbuffer[g-circle]
\startMPpositiongraphic{mypos:circle}
  path p ; p := positionbox(texstr("self")) ;
  p := fullcircle xsized (bbwidth(p)+4pt) shifted center p ;
  pickup pencircle scaled 1pt ;
  fill p withcolor .800white ;
  draw p withcolor .625yellow ;
  positioninregion ;
\stopMPpositiongraphic
\stopbuffer

\startbuffer[g-line]
\startMPpositiongraphic{mypos:line}
  path pa, pb, pab ; numeric na, nb ; string ta, tb ;
  ta := texstr("from") ;
  tb := texstr("to") ;
  na := positionpage(ta) ;
  nb := positionpage(tb) ;
  pa := positionbox(ta) ;
  pb := positionbox(tb) ;
  pa := fullcircle xsized (bbwidth(pa)+4pt) shifted center pa ;
  pb := fullcircle xsized (bbwidth(pb)+4pt) shifted center pb ;
  if na = nb :
    pab := center pa -- center pb ;
    pab := pab cutbefore (pab intersectionpoint pa) ;
    pab := pab cutafter  (pab intersectionpoint pb) ;
    pickup pencircle scaled 1pt ;
    draw pab withcolor .625yellow ;
    positioninregion ;
  fi ;
\stopMPpositiongraphic
\stopbuffer

\getbuffer[g-circle,g-line]

\startbuffer[a]
\setMPpositiongraphic{X-1}{mypos:arrow}{to=X-2}
\setMPpositiongraphic{X-2}{mypos:arrow}{to=X-3}
\stopbuffer

\startbuffer[b]
In a previous section we saw that some \hpos {X-1} {words} were
\hpos {X-2} {circled} and connected by an \hpos {X-3} {arrow}.
As with most things in \CONTEXT, marking these words is separated
from declaring what to do with those words. This paragraph is keyed
in as:
\stopbuffer

\getbuffer[a,b]

\typebuffer[b]

We see three position anchors, each marked by an identifier: \type {X-1}, \type
{X-2} and \type {X-3}. Each of these anchors can be associated with a (series) of
graphic operations. Here we defined:

\typebuffer[a]

These examples clearly demonstrate that we cannot control to what extent graphics
will cover text and vice versa. A solution to this problem is using position
overlays. We can define such an overlay as follows:

\startbuffer
\startpositionoverlay{backgraphics}
  \setMPpositiongraphic{G-1}{mypos:circle}
  \setMPpositiongraphic{G-2}{mypos:circle}
  \setMPpositiongraphic{G-3}{mypos:circle}
  \setMPpositiongraphic{G-4}{mypos:circle}
\stoppositionoverlay

\startpositionoverlay{foregraphics}
  \setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
  \setMPpositiongraphic{G-2}{mypos:line}{to=G-3}
  \setMPpositiongraphic{G-3}{mypos:line}{to=G-4}
\stoppositionoverlay
\stopbuffer

\getbuffer \typebuffer

\startbuffer
First we have defined an \hpos {G-1} {\strut overlay}. This
overlay can be attached to some overlay layer, like, in our
case, the \hpos {G-2} {\strut page}. We define four small \hpos
{G-3} {\strut circles}. These are drawn as soon as the page
overlay is typeset. Because they are located in the
background, they don't cover the \hpos {G-4} {\strut text}, while
the lines do. The previous paragraph was typeset by saying:
\stopbuffer

\getbuffer \typebuffer

As said, the circles are on the background layer, but the lines are not! They are
positioned on top of the text. This is a direct result of the definition of the
page background:

\starttyping
\defineoverlay [foregraphics] [\positionoverlay{foregraphics}]
\defineoverlay [backgraphics] [\positionoverlay{backgraphics}]

\setupbackgrounds
  [page]
  [background={backgraphics,foreground,foregraphics}]
\stoptyping

\doifmode{screen}{\writestatus{CHECK}{POSITION GRAPHICS}}

In this definition, the predefined overlay \type {foreground} inserts the page
data itself, so the foreground graphics end up on top. This example also
demonstrates that you should be well aware of the way \CONTEXT\ builds a page.
There are six main layers, in some cases with sublayers. The body text goes into
the main text layer, which, unless forced otherwise, lays on top.

\startitemize[packed,n,columns,three]
\item  paper background
\item  area backgrounds
\item  page backgrounds
\item  text areas
\item  logo areas
\item  main text
\stopitemize

The paper background is used for special (sometimes internal) purposes. There are
three page backgrounds: left, right and both. The text areas, logo areas and
backgrounds form a $5 \times 5$ matrix with columns containing the leftedge,
leftmargin, text, rightmargin, and rightedge. The rows of the matrix contain the
top, header, text, footer, and bottom. The main text is what you are reading now.

Since the page background is applied last, the previous layers can be considered
to be the foreground to the page background layer. And, indeed, it is available
as an overlay under the name \type {foreground}, as we already saw in the
example. Foregrounds are available in most cases, but (for the moment) not when
we are dealing with the text area. Since anchoring the graphics is implemented
rather independent of the position of the graphics themselves, this is no real
problem, we can put them all on the page layer, if needed in separate overlays.

How is such a graphic defined? In fact these graphics are a special case of the
already present mechanism of including \METAPOST\ graphics. The circles are
defined as follows:

\typebuffer[g-circle]

Drawing the lines is handled in a similar fashion.

\typebuffer[g-line]

The command \tex {startMPpositiongraphic} defines a graphic, in this example we
have called it \type {mypos:circle}. Here we show the definition out of order but
normally you need to define it before you refer to it.

The \METAPOST\ macro \type {positionbox} returns a box that is constructed from
the coordinates and dimensions. After this call, the corners are available via
\type {llcorner}, \type {lrcorner}, \type {urcorner} and \type {ulcorner}. The
center is accessible by \type {center}. When we are finished drawing the graphic,
we can anchor the result with \type {positioninregion}. This macro automatically
handles positioning on specific layers. The helper macros are not loaded by
default, you do that with:

\typebuffer[g-include]

The position macro \type {\MPpos} returns the current characteristics of a
position. The previously defined G~positions return:

\starttabulate[|c|c|c|c|c|c|c|]
\HL
\NC position\NC page\NC$x$\NC$y$\NC width\NC height\NC depth\NC\NR
\HL
\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
\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
\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
\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
\HL
\stoptabulate

The numbers represent the real pagenumber~$p$, the current position $(x,y)$, and
the dimensions of the box $(w,h,d)$ if known. These values are fed directly into
\METAPOST\ graphics but the individual components can be asked for by \type
{\MPp}, \type {\MPx}, \type {\MPy}, \type {\MPw}, \type {\MPh} and \type {\MPd}.

In the previous definition of the graphic, we saw another macro, \type {\MPvar}.
When we invoke a graphic or attach a graphic to a layer, we can pass variables.
We can also set specific variables in other ways, as we will see later.

\starttyping
\setMPpositiongraphic{G-1}{mypos:circle}
\setMPpositiongraphic{G-1}{mypos:line}{to=G-2}
\stoptyping

In the second definition, we let the variable \type {to} point to another
position. When needed, we can ask for the value of \type {to} by \type
{\MPvar{to}}. For reasons of convenience, the current position is assigned
automatically to \type {from} and \type {self}. This means that in the line we
saw in the graphic:

\starttyping
path p ; p := positionbox(texstr("self")) ;
\stoptyping

\type {texstr("self")} will return the current position, which, fed to \type
{positionbox} will return a box with the right dimensions. We already warned the
reader: this is not an easy chapter.

\stopsection

\startsection[title={More layers}]

\index{layers}

\setupbackgrounds
  [state=repeat]

Overlays are one of the nicer features of \CONTEXT\ and even more nice things can
be build on top of them. Overlays are defined first and then assigned to framed
boxes using the \type {background} variable.

You can stack overlays, which is why they are called as such. You can use the
special overlay called \type {foreground} to move the topmost (often text) layer
down in the stack.

\starttabulate
\HL
\NC background overlay \NC a text, graphic, hyperlink or widget      \NC \NR
\NC position overlay   \NC a series of macros triggered by positions \NC \NR
\NC background layer   \NC a box that can hold boxes with offsets    \NC \NR
\HL
\stoptabulate

The last kind of layer can be used in other situations as well, but in most cases
it will be hooked into a background overlay.

\startbuffer
\definelayer[MyLayer][option=test]

\setupbackgrounds[text][leftmargin][background=MyLayer]

\setlayer[MyLayer][x=.5cm,y=5cm]
  {\rotate{\framed{This goes to the background}}}
\stopbuffer

\typebuffer \getbuffer \setuplayer[MyLayer][option=] % no frames

In this case the framed text will be placed in the background of the (current)
page with the given offset to the topleft corner. Instead of a fixed position,
you can inherit the current position using the \type {position} directive. Say
that we have a layer called \type {YourLayer} which we put in the background of
the text area.

\startbuffer
\definelayer[YourLayer]
\setupbackgrounds[text][text][background=YourLayer]
\stopbuffer

\typebuffer \getbuffer

We can now move some framed text to this layer using \type {\setlayer} with the
directive \type {position} set to \type {yes}.

\startbuffer
here: \setlayer[YourLayer][position=yes]{\inframed{Here}}
\stopbuffer

\typebuffer

You can influence the placement by explicitly providing an offset (\type
{hoffset} and|/|or \type {voffset}), a position (\type {x} and|/|or \type {y}) or
a location directive (\type {location}). Normally you will use the offsets for
the layer as a whole and the positions for individual contributions. The next
example demonstrates the use of a location directive.

\startbuffer
here: \setlayer[YourLayer][position=yes,location=c]{\inframed{Here}}
\stopbuffer

\typebuffer \getbuffer

Many layers can be in use at the same time. In the next example we put something
in the page layer. By default, we turn on position tracking, which visualizes the
bounding box of the content and shows the reference point.

\startbuffer
\definelayer[BackLayer][position=yes]
\setupbackgrounds[page][background=BackLayer]
\stopbuffer

\typebuffer \getbuffer

\setupbackgrounds
  [page]
  [background={PageFrame,BackLayer,backgraphics,foreground,foregraphics}]

Next we define an overlay that we can put behind for instance framed texts. We
use \METAPOST\ to draw \type {Shape}.

\startbuffer
\defineoverlay[Shape] [BackLayer] [\uniqueMPgraphic{Shape}]

\startuniqueMPgraphic{Shape}
  path p ; p := fullcircle xyscaled(OverlayWidth,OverlayHeight) ;
  fill p withcolor \MPcolor{lightgray} ;
  draw p withpen pencircle scaled 1pt withcolor \MPcolor{darkred} ;
\stopuniqueMPgraphic
\stopbuffer

\typebuffer \getbuffer

\startbuffer[def]
\defineframed[Shaped][background=Shape,frame=off,location=low]
\stopbuffer

\getbuffer[def]

We can now put this background shape behind the running text, for instance with:

\startbuffer
.... some \inframed[background=Shape]{text} with a frame ...
.... some \Shaped{text} with a frame ...
\stopbuffer

\typebuffer

\startlines
\getbuffer
\stoplines

The \type {\Shaped} macro was defined as:

\typebuffer[def]

Watch how the graphics are moved to the background while the frame of the first
text stays on top, since it remains part of the text flow.

\startbuffer[def]
\setuplayer[BackLayer][direction=reverse]
\stopbuffer

\getbuffer[def]

\startlines
\getbuffer
\stoplines

In the previous instance of the example we have reversed the stacking. Reversal
can be done with the \type {direction} directive.

\typebuffer[def]

% next series

\startbuffer
\setuplayer
  [BackLayer]
  [position=no,corner=bottom,height=\paperheight]

\setlayer[BackLayer][x=2cm,y=10cm,location=bl]
  {\externalfigure[somecow.pdf][width=1cm]}

\setlayer[BackLayer][x=1cm,y=8cm,location=br]
  {\externalfigure[somecow.pdf][width=1cm]}

\setlayer[BackLayer][x=2cm,y=4cm,location=tl]
  {\externalfigure[somecow.pdf][width=1cm]}

\setlayer[BackLayer][x=10cm,y=1cm,location=tr]
  {\externalfigure[somecow.pdf][width=1cm]}
\stopbuffer

You can influence the placement of a background component by using a different
anchor point.

\typebuffer {\setuplayer[option=test]\getbuffer}

\startbuffer[xx]
\setuplayer
  [BackLayer]
  [position=no,corner=bottom,height=\paperheight]

\setlayer[BackLayer][x=15cm,y=5cm,location=bl]
  {\externalfigure[somecow.pdf][width=3cm]}

\setlayer[BackLayer][x=15cm,y=5cm,location=br]
  {\externalfigure[somecow.pdf][width=3cm]}

\setlayer[BackLayer][x=15cm,y=5cm,location=tl]
  {\externalfigure[somecow.pdf][width=2cm]}

\setlayer[BackLayer][x=15cm,y=5cm,location=tr]
  {\externalfigure[somecow.pdf][width=2cm]}

\setlayer[BackLayer][x=15cm,y=5cm,location=c]
  {\externalfigure[somecow.pdf][width=3cm]}
\stopbuffer

% \startpostponing

Instead of using relative positions, you can also use absolute ones. Of course
you need to know how your coordinates relate to the rest of the layout
definition.

\typebuffer[xx]

These examples again demonstrate how we can influence the placement by assigning
an anchor point to \type {position}. Here we also put the reference point in the
lower left corner (\type {bottom}). This mechanism only works when we also use
\type {height}.

{\setuplayer[option=test]\getbuffer[xx]}

\page

% \stoppostponing

\setupbackgrounds
  [page]
  [background={PageFrame,DemoLayer,backgraphics,foreground,foregraphics}]

\definelayer
  [DemoLayer]
  [position=yes]

\startbuffer
\definelayer
  [DemoLayer]
  [position=yes]

\startplacefigure[title={Demo 1}]
    \ruledhbox\bgroup
        \setlayerframed
            [DemoLayer] [hoffset=-10mm,voffset=5mm]
            {\startMPcode
                fill fullcircle scaled 2cm withcolor .625red ;
             \stopMPcode}%
        \setlayerframed
            [DemoLayer] [voffset=-10mm]
            {\startMPcode
                fill fullcircle scaled 2cm withcolor .625green ;
             \stopMPcode}%
        \setlayerframed
            [DemoLayer] [hoffset=10mm,voffset=5mm]
            {\startMPcode
                fill fullcircle scaled 2cm withcolor .625blue ;
             \stopMPcode}%
    \egroup
\stopplacefigure
\stopbuffer

\getbuffer

One of the reasons for developing the layer mechanism was that we needed to
slightly change the position of figures in the final stage of typesetting. The
previous pages demonstrate how one can position anything anywhere on the page,
but in the case of figures the position may depend on where the text ends up on
the page.

Normally, when you manipulate a document this way, you are in the final stage of
typesetting. You may qualify this as desk top publishing without actually using a
desktop.

\typebuffer

\startbuffer[demo]
\startbuffer
\setlayer [DemoLayer]
  [position=yes,
   voffset=-1.5cm,
   width=3cm,
   height=2cm]
  {\MPfigure{somecow.pdf}{scaled .5 slanted .5}}
\stopbuffer

\placefigure[right]{}{\ruledhbox{\getbuffer}}
\stopbuffer

{\setuplayer[option=test]\getbuffer[demo]}

The previous example also demonstrated the use of \METAPOST\ for rotating the
picture. The \type {\MPfigure} macro encapsulates the code in a shortcut. You can
achieve special effects by using the layers behind floating bodies and alike, but
always keep in mind that the readability of the text should not be violated too
much.

\typebuffer[demo]

In these examples we added a \type {\ruledhbox} around the pseudo graphics so
that you can see what the size is of those graphics.

% summary

We have already seen a lot of parameters that can be used to control the content
of a layer. There are a few more. General housekeeping takes place with:

\starttabulate[|Tl|Tl|l|]
\HL
\NC state     \NC start   \NC enable the layer            \NC \NR
\NC           \NC stop    \NC disable the layer           \NC \NR
\NC position  \NC no      \NC use absolute positions      \NC \NR
\NC           \NC yes     \NC use relative positions      \NC \NR
\NC           \NC overlay \NC idem, but ignore the size   \NC \NR
\NC direction \NC normal  \NC put new data on top         \NC \NR
\NC           \NC reverse \NC put new data below old data \NC \NR
\HL
\stoptabulate

Sometimes all data needs to be offset in a similar way. You can use both offset
parameters for that.

\starttabulate[|Tl|l|]
\HL
\NC hoffset \NC an additional horizontal displacement \NC \NR
\NC voffset \NC an additional vertical   displacement \NC \NR
\HL
\stoptabulate

You can position data anywhere in the layer. When positioning is turned on, the
current position will get a placeholder. You can change the dimensions of that
placeholder (when \type {position} is set to \type {overlay}), zero dimensions
are used.

\starttabulate[|Tl|l|]
\HL
\NC x        \NC the horizontal displacement \NC \NR
\NC y        \NC the vertical   displacement \NC \NR
\NC width    \NC the (non natural) width     \NC \NR
\NC height   \NC the (non natural) height    \NC \NR
\NC location \NC \tttf l r t b c lt lb rt rb \NC \NR
\HL
\stoptabulate

The \type {location} directive determines what point of the data is used as
reference point. You can keep track of this point and the placement when you
enable test mode. This is how the rectangles in the previous examples were
drawn.

\starttabulate[|Tl|Tl|l|]
\HL
\NC option \NC test \NC show positioning information \NC \NR
\HL
\stoptabulate

When you are enhancing the final version of a document, you can explicitly
specify on what page the data will go. Use this option with care.

\starttabulate[|Tl|l|]
\HL
\NC page \NC the page where the data will go \NC \NR
\HL
\stoptabulate

Because layers can migrate to other pages, they may disappear due to the
background not being recalculated. In case of doubt, you can force repetitive
background calculation by:

\starttyping
\setupbackgrounds[state=repeat]
\stoptyping

% restore 'm

\setupbackgrounds
  [page]
  [background={PageFrame,backgraphics,foreground,foregraphics}]

\setupbackgrounds
  [state=start]

\stopsection

\startsection[title={Complex text in graphics}]

\index{text}

If you like to embed \METAPOST\ snippets in \CONTEXT, you may want to combine
text and graphics and let \METAPOST\ provide the position and the dimensions of
the text to be typeset outside by \TEX. For most applications using the \METAFUN\
\type {textext} macro works well enough, but when the typeset text needs to
communicate with the typesetting engine, for instance because it contains
hyperlinks or references, you can use the following method:

\startitemize[packed]
\item define a layer
\item define a (reusable) graphic
\item put your text into the layer
\item combine the graphic with the text
\stopitemize

You must be aware of the fact that when the layer is flushed, its content is
gone. You can take advantage of this by using the same graphic with multiple
texts.

\startbuffer
\definelayer[test]
\stopbuffer

\typebuffer \getbuffer

You don't need to pass the width and height explicitly, but when you do so, you
have access to them later.

\startbuffer
\startuseMPgraphic{oeps}
  path p ; p := fullcircle scaled 6cm ;
  fill p withcolor .8white ;
  draw p withpen pencircle scaled 1mm withcolor .625red ;
  register ("somepos-1",0cm,0cm,center currentpicture) ;
  register ("somepos-2",3cm,1cm,(-1cm,-1cm)) ;
  register ("somepos-3",2cm,0cm,(-2cm,2cm)) ;
\stopuseMPgraphic
\stopbuffer

\typebuffer \getbuffer

The \METAFUN\ \type {register} macro takes the following arguments:

\starttyping
register ("tag",width,height,(x offset,y offset)) ;
\stoptyping

The width and height are available in the macros \type {\MPlayerwidth} and \type
{\MPlayerheight} and are equivalent to \type {\MPw{tag}} and \type {\MPh{tag}},

\startbuffer
\setMPlayer [test] [somepos-1] [location=c]
  {Does it work al right?}

\setMPlayer [test] [somepos-2]
  {\framed
     [width=\MPlayerwidth,height=\MPlayerheight,
      background=color,backgroundcolor=white]
     {It Works!}}

\setMPlayer [test] [somepos-3]
  {\externalfigure[cow-fun.mps][width=2cm]}
\stopbuffer

\typebuffer \getbuffer

Combining the graphic and the text is handled by the macro \type {\getMPlayer}.

\startbuffer
\getMPlayer [test] {\useMPgraphic{oeps}}
\stopbuffer

\typebuffer \getbuffer

The macro \type {\getMPlayer} is built on top of \type {\framed}. The settings
passed in the (optional) second argument are the same as those to \type
{\framed}.

\starttyping
\getMPlayer
  [test]
  [frame=on,offset=5pt]
  {\useMPgraphic{oeps}}
\stoptyping

As you see, you need a bit of a twisted mind to handle graphics this way, but at
least the functionality is there to create complex graphics in a declarative way.

\stopsection

\stopchapter

\stopcomponent