metafun-layout.tex /size: 31 Kb    last modification: 2023-12-21 09:43
1% language=us runpath=texruns:manuals/metafun
2
3\startcomponent metafun-layout
4
5\environment metafun-environment
6
7\startchapter[title={Enhancing the layout}]
8
9\startintro
10
11One of the most powerful and flexible commands of \CONTEXT\ is \type {\framed}.
12We can use the background features of this command to invoke and position
13graphics that adapt themselves to the current situation. Once understood,
14overlays will become a natural part of the \CONTEXT\ users toolkit.
15
16\stopintro
17
18\startsection[title={Overlays}]
19
20\index{overlays}
21
22Many \CONTEXT\ commands support overlays. The term {\em overlay} is a bit
23confusing, since such an overlay in most cases will lay under the text. However,
24because there can be many layers on top of each other, the term suits its
25purpose.
26
27When we want to put a \METAPOST\ graphic under some text, we go through a three
28step process. First we define the graphic itself:
29
30\startbuffer
31\startuniqueMPgraphic{demo circle}
32  path p ;
33  p := fullcircle xscaled \overlaywidth yscaled \overlayheight ;
34  fill p withcolor .85white ;
35  draw p withpen pencircle scaled 2pt withcolor .625red ;
36\stopuniqueMPgraphic
37\stopbuffer
38
39\typebuffer
40
41\getbuffer
42
43This graphic will adapt itself to the width and height of the overlay. Both \type
44{\overlaywidth} and \type {\overlayheight} are macros that return a dimension
45followed by a space. The next step is to register this graphic as an overlay.
46
47\startbuffer
48\defineoverlay[demo circle][\uniqueMPgraphic{demo circle}]
49\stopbuffer
50
51\typebuffer
52
53\getbuffer
54
55We can now use this overlay in any command that provides the \type {\framed}
56functionality. Since this graphic is defined as unique, \CONTEXT\ will try to
57reuse already calculated and embedded graphics when possible.
58
59\startbuffer
60\framed[background=demo circle]{This text is overlayed.}
61\stopbuffer
62
63\typebuffer
64
65The background can be set to \type {color}, \type {screen}, an overlay
66identifier, like \typ {demo circle}, or a comma separated list of those.
67
68\startlinecorrection[blank]
69\getbuffer
70\stoplinecorrection
71
72The \type {\framed} command automatically draws a ruled box, which can be quite
73useful when debugging a graphic. However, in this case we want to turn the frame
74off.
75
76\startbuffer
77\framed
78  [background=demo circle,frame=off]
79  {This text is overlayed.}
80\stopbuffer
81
82\typebuffer
83
84\startlinecorrection[blank]
85\getbuffer
86\stoplinecorrection
87
88In this case, it would have made sense to either set the \type {offset} to a
89larger value, or to set \type {backgroundoffset}. In the latter case, the ellipse
90is positioned outside the frame.
91
92The difference between the three offsets \type {offset}, \type {frameoffset} and
93\type {backgroundoffset} is demonstrated in \in {figure} [fig:offsets]. While the
94\type {offset} is added to the (natural or specified) dimensions of the content
95of the box, the other two are applied to the frame and background and don't add
96to the dimensions.
97
98In the first row we only set the \type {offset}, while in the second row, the
99(text) offset is set to \type {3pt}. When not specified, the \type {offset} has a
100comfortable default value of \type {.25ex} (some 25\% of the height of an~x).
101
102\startbuffer
103\setupframed
104  [width=.3\textwidth,
105   background=demo circle]
106\startcombination[3*3]
107  {\framed[offset=none]         {\TeX}} {\tt offset=none}
108  {\framed[offset=overlay]      {\TeX}} {\tt offset=overlay}
109  {\framed[offset=0pt]          {\TeX}} {\tt offset=0pt}
110  {\framed[offset=1pt]          {\TeX}} {\tt offset=1pt}
111  {\framed[offset=2pt]          {\TeX}} {\tt offset=2pt}
112  {\framed[offset=4pt]          {\TeX}} {\tt offset=4pt}
113  {\framed[offset=3pt]          {\TeX}} {\tt offset=3pt}
114  {\framed[frameoffset=3pt]     {\TeX}} {\tt frameoffset=3pt}
115  {\framed[backgroundoffset=3pt]{\TeX}} {\tt backgroundoffset=3pt}
116\stopcombination
117\stopbuffer
118
119\typebuffer
120
121\placefigure
122  [here][fig:offsets]
123  {The three offsets.}
124  {\getbuffer}
125
126As the first row in \in {figure} [fig:offsets] demonstrates, instead of a value,
127one can pass a keyword. The \type {overlay} keyword implies that there is no
128offset at all and that the lines cover the content. With \type {none} the frame
129is drawn tight around the content. When the offset is set to \type {0pt} or more,
130the text is automatically set to at least the height of a line. You can turn this
131feature off by saying \type {strut=off}. More details can be found in the
132\CONTEXT\ manual.
133
134In \in {figure} [fig:all offsets] we have set {offset} to \type {3pt}, \type
135{frameoffset} to \type {6pt} and \type {backgroundoffset} to \type {9pt}. Both
136the frame and background offset are sort of imaginary, since they don't
137contribute to the size of the box.
138
139\startbuffer
140\ruledhbox
141  {\framed
142     [offset=3pt,frameoffset=6pt,backgroundoffset=9pt,
143      background=screen,backgroundscreen=.85]
144     {Welcome in the hall of frame!}}
145\stopbuffer
146
147\typebuffer
148
149\placefigure
150  [here][fig:all offsets]
151  {The three offsets.}
152  {\getbuffer}
153
154\stopsection
155
156\startsection[title={Overlay variables}]
157
158The communication between \TEX\ and embedded \METAPOST\ graphics takes place by
159means of some macros.
160
161\starttabulate[|l|p|]
162\HL
163\NC overlay status macro    \NC meaning                        \NC \NR
164\HL
165\NC \tex {overlaywidth}     \NC the width of the graphic, as
166                                calculated from the actual
167                                width and background offset    \NC \NR
168\NC \tex {overlayheight}    \NC the height of the graphic, as
169                                calculated from the actual
170                                height, depth and background
171                                offset                         \NC \NR
172\NC \tex {overlaydepth}     \NC the depth of the graphic, if
173                                available                      \NC \NR
174\NC \tex {overlaycolor}     \NC the background color, if given \NC \NR
175\NC \tex {overlaylinecolor} \NC the color of the frame         \NC \NR
176\NC \tex {overlaylinewidth} \NC the width of the frame         \NC \NR
177\HL
178\stoptabulate
179
180The dimensions of the overlay are determined by dimensions of the background,
181which normally is the natural size of a \type {\framed}. When a background offset
182is specified, it is added to \type {overlayheight} and \type {overlaywidth}.
183
184Colors can be converted by \type {\MPcolor} and in addition to the macros
185mentioned, you can use all macros that expand into a dimension or dimen register
186prefixed by the \TEX\ primitive \type {\the} (this and other primitives are
187explained in \quotation {The \TeX book}, by Donald Knuth).
188
189\stopsection
190
191\startsection[title={Stacking overlays}]
192
193A background can be a gray scale (\type {screen}), a color (\type {color}), a
194previously defined overlay identifier, or any combination of these. The next
195assignments are therefore valid:
196
197\starttyping
198\framed[background=color,backgroundcolor=red]{...}
199\framed[background=screen,backgroundscreen=.8]{...}
200\framed[background=circle]{...}
201\framed[background={color,cow},backgroundcolor=red]{...}
202\framed[background={color,cow,grid},backgroundcolor=red]{...}
203\stoptyping
204
205In the last three cases of course you have to define \type {circle}, \type {cow}
206and \type {grid} as overlay. These items are packed in a comma separated list,
207which has to be surrounded by \type {{}}.
208
209\stopsection
210
211\startsection[title={Foregrounds}]
212
213\startbuffer[a]
214\startuniqueMPgraphic{backfore}
215  draw fullcircle
216    xscaled \overlaywidth yscaled \overlayheight
217    withpen pencircle scaled 2pt
218    withcolor .625yellow ;
219\stopuniqueMPgraphic
220
221\defineoverlay[backfore][\uniqueMPgraphic{backfore}]
222\stopbuffer
223
224\startbuffer[b]
225\framed
226  [background=backfore,backgroundoffset=4pt]
227  {one, two, three, \unknown}
228\stopbuffer
229
230\startbuffer[c]
231\framed
232  [background={foreground,backfore},backgroundoffset=4pt]
233  {one, two, three, \unknown}
234\stopbuffer
235
236The overlay system is actually a system of layers. Sometimes we are confronted
237with a situation in which we want the text behind another layer. This can be
238achieved by explicitly placing the foreground layer, as in \in {figure}
239[fig:foreground].
240
241\getbuffer[a]
242
243\placefigure
244  [here][fig:foreground]
245  {Foreground material moved backwards.}
246  {\setupframed[linewidth=1pt]%
247   \startcombination
248     {\getbuffer[b]} {frame on top layer}
249     {\getbuffer[c]} {frame on bottom layer}
250   \stopcombination}
251
252The graphic layer is defined as follows:
253
254\typebuffer[a]
255
256The two framed texts have a slightly different definition. The leftmost graphic
257is defined as:
258
259\typebuffer[b]
260
261The rightmost graphic is specified as:
262
263\typebuffer[c]
264
265The current values of the frame color and frame width are passed to the overlay.
266It often makes more sense to use colors defined at the document level, if only to
267force consistency.
268
269\startbuffer
270\startuniqueMPgraphic{super ellipse}
271  path p ; p := unitsquare
272    xscaled \overlaywidth yscaled \overlayheight
273    superellipsed .85 ;
274  pickup pencircle scaled \overlaylinewidth ;
275  fill p withcolor \MPcolor{\overlaycolor} ;
276  draw p withcolor \MPcolor{\overlaylinecolor} ;
277\stopuniqueMPgraphic
278
279\defineoverlay[super ellipse][\uniqueMPgraphic{super ellipse}]
280\stopbuffer
281
282\typebuffer \getbuffer
283
284This background demonstrates that a super ellipse is rather well suited as frame.
285
286\startbuffer
287\framed
288  [background=super ellipse,
289   frame=off,
290   width=3cm,
291   align=middle,
292   framecolor=darkyellow,
293   rulethickness=2pt,
294   backgroundcolor=darkgray]
295  {\white This is a\\Super Ellipsed\\sentence.}
296\stopbuffer
297
298\typebuffer
299
300Such a super ellipse looks quite nice and is a good candidate for backgrounds,
301for which the superness should be at least~.85.
302
303\startlinecorrection[blank]
304\getbuffer
305\stoplinecorrection
306
307\stopsection
308
309\startsection[title={Typesetting graphics}]
310
311I have run into people who consider it kind of strange when you want to use \TEX\
312for non||mathematical typesetting. If you agree with them, you may skip this
313section with your eyes closed.
314
315One of the \CONTEXT\ presentation styles (number 15, tagged as balls) stepwise
316builds screens full of sentences, quotes or concepts, packages in balloons and
317typesets them as a paragraph. We will demonstrate that \TEX\ can typeset graphics
318using the following statement.
319
320% \let\processword\relax
321
322\startbuffer[lions]
323\processwords{As you may know, \TEX's ambassador is a lion, while {\METAFONT}
324is represented by a lioness. It is still unclear if they have a relationship,
325but if so, and if a cub is born, may it enjoy \METAFUN.}
326\stopbuffer
327
328\pushoverloadmode
329\startquotation
330\def\processwords#1{#1}\getbuffer[lions]
331\stopquotation
332\popoverloadmode
333
334The low level \CONTEXT\ macro \type {\processwords} provides a mechanism to treat
335the individual words of its argument. The macro is called as follows:
336
337\typebuffer[lions]
338
339In order to perform a task, you should also define a macro \type {\processword},
340which takes one argument. The previous quote was typeset with the following
341definition in place:
342
343\starttyping
344\def\processword#1{#1}
345\stoptyping
346
347A slightly more complicated definition is the following:
348
349\startbuffer
350\def\processword#1{\noindent\framed{#1}\space}
351\stopbuffer
352
353\typebuffer \getbuffer
354
355We now get:
356
357\blank\getbuffer[lions]\blank
358
359If we can use \type {\framed}, we can also use backgrounds.
360
361\startbuffer
362\def\processword#1%
363  {\noindent\framed[frame=off,background=lions]{#1} }
364\stopbuffer
365
366\typebuffer \getbuffer
367
368We can add a supperellipsed frame using the following definition:
369
370\startbuffer
371\startuniqueMPgraphic{lions a}
372  path p ; p := fullsquare
373   xyscaled (\overlaywidth,\overlayheight) superellipsed .85 ;
374  pickup pencircle scaled 1pt ;
375  fill p withcolor .850white ; draw p withcolor .625yellow ;
376\stopuniqueMPgraphic
377
378\defineoverlay[lions][\uniqueMPgraphic{lions a}]
379\stopbuffer
380
381\typebuffer \getbuffer
382
383\bgroup \blank \veryraggedright\getbuffer[lions]\unskip \blank \egroup
384
385\startbuffer
386\startuseMPgraphic{lions b}
387  path p ; p := fullsquare
388    xyscaled (\overlaywidth,\overlayheight) randomized 5pt ;
389  pickup pencircle scaled 1pt ;
390  fill p withcolor .850white ; draw p withcolor .625yellow ;
391\stopuseMPgraphic
392
393\defineoverlay[lions][\uniqueMPgraphic{lions b}]
394\stopbuffer
395
396\typebuffer \getbuffer
397
398\bgroup \blank \veryraggedcenter\getbuffer[lions]\unskip \blank \egroup
399
400\startbuffer
401\startuniqueMPgraphic{lions c}
402  path p ; p := fullsquare
403    xyscaled (\overlaywidth,\overlayheight) squeezed 2pt ;
404  pickup pencircle scaled 1pt ;
405  fill p withcolor .850white ; draw p withcolor .625yellow ;
406\stopuniqueMPgraphic
407
408\defineoverlay[lions][\uniqueMPgraphic{lions c}]
409\stopbuffer
410
411\typebuffer \getbuffer
412
413\bgroup \blank \veryraggedleft\getbuffer[lions]\unskip \blank \egroup
414
415These paragraphs were typeset with the following settings.
416
417\starttyping
418\setupalign[broad, right]  % == \veryraggedright
419\setupalign[broad, middle] % == \veryraggedcenter
420\setupalign[broad, left]   % == \veryraggedleft
421\stoptyping
422
423The \type {broad} increases the raggedness. We defined three different graphics
424(a, b and c) because we want some to be unique, which saves some processing. Of
425course we don't reuse the random graphics. In the definition of \type
426{\processword} we have to use \type {\noindent} because otherwise \TEX\ will put
427each graphic on a line of its own. Watch the space at the end of the macro.
428
429\stopsection
430
431\startsection[title={Graphics and macros}]
432
433Because \TEX's typographic engine and \METAPOST's graphic engine are separated,
434interfacing between them is not as natural as you may expect. In \CONTEXT\ we
435have tried to integrate them as much as possible, but using the interface is not
436always as convenient as it should be. What method you follow, depends on the
437problem at hand.
438
439The official \METAPOST\ way to embed \TEX\ code into graphics is to use \typ
440{btex ... etex}. As soon as \CONTEXT\ writes the graphic data to the intermediate
441\METAPOST\ file, it looks for these commands. When it has encountered an \type
442{etex}, \CONTEXT\ will make sure that the text that is to be typeset by \TEX\ is
443{\em not} expanded. This is what you may expect, because when you would embed
444those commands in a stand||alone graphic, they would also not be expanded, if
445only because \METAPOST\ does not know \TEX. With expansion we mean that \TEX\
446commands are replaced by their meaning (which can be quite extensive).
447
448{\em Users of \CONTEXT\ MKIV\ can skip the next paragraph}.
449
450When \METAPOST\ sees a \type {btex} command, it will consult a so called \type
451{mpx} file. This file holds the \METAPOST\ representation of the text typeset by
452\TEX. Before \METAPOST\ processes a graphic definition file, it first calls
453another program that filters the \type {btex} commands from the source file, and
454generates a \TEX\ file from them. This file is then processed by \TEX, and after
455that converted to a \type {mpx} file. In \CONTEXT\ we let \TEXEXEC\ take care of
456this whole process.
457
458Because the \typ {btex ... etex} commands are filtered from the raw \METAPOST\
459source code, they cannot be part of macro definitions and loop constructs. When
460used that way, only one instance would be found, while in practice multiple
461instances may occur.
462
463This drawback is overcome by \METAFUN's \type {textext} command. This command
464still uses \typ {btex ... etex} but writes these commands to a separate job
465related file each time it is used. \footnote {It took the author a while to find
466out that there is a \METAPOST\ module called \type {tex.mp} that provides a
467similar feature, but with the disadvantage that each text results in a call to
468\TEX. Each text goes into a temporary file, which is then included and results in
469\METAPOST\ triggering \TEX.} After the first \METAPOST\ run, this file is merged
470with the original file, and \METAPOST\ is called again. So, at the cost of an
471additional run, we can use text typeset by \TEX\ in a more versatile way. Because
472\METAPOST\ runs are much faster than \TEX\ runs, the price to pay in terms of run
473time is acceptable. Unlike \typ {btex ... etex}, the \TEX\ code in \type
474{textext} command is expanded, but as long as \CONTEXT\ is used this is seldom a
475problem, because most commands are somewhat protected.
476
477If we define a graphic with text to be typeset by \TEX, there is a good chance
478that this text is not frozen but passes as argument. A \TEX||like solution for
479passing arbitrary content to such a graphic is the following: \footnote {The \type
480{\unexpanded} prefix makes the command robust for being passed as argument. It is not
481to be confused with the primitive. We had this feature already when the primitive
482showed up and it was considered to be inconvenient for other macro packages to adapt to
483the \CONTEXT\ situation. So keep that in mind when you mix macro packages.}
484
485\startbuffer[def]
486\unexpanded\def\RotatedText#1#2%
487  {\startuseMPgraphic{RotatedText}
488     draw btex #2 etex rotated #1 ;
489   \stopuseMPgraphic
490   \useMPgraphic{RotatedText}}
491\stopbuffer
492
493\typebuffer[def] \getbuffer[def]
494
495This macro takes two arguments (the \type {#} identifies an
496argument):
497
498\startbuffer[exa]
499\RotatedText{15}{Some Rotated Text}
500\stopbuffer
501
502\typebuffer[exa]
503
504The text is rotated over 15 degrees about the origin in a counterclockwise
505direction.
506
507\startlinecorrection[blank]
508\getbuffer[exa]
509\stoplinecorrection
510
511In \CONTEXT\ we seldom pass settings like the angle of rotation in this manner.
512You can use \type {\setupMPvariables} to set up graphic||specific variables. Such
513a variable can be accessed with \type {\MPvar}.
514
515\startbuffer[def]
516\setupMPvariables[RotatedText][rotation=90]
517
518\startuseMPgraphic{RotatedText}
519  draw textext{Some Text} rotated \MPvar{rotation} ;
520\stopuseMPgraphic
521\stopbuffer
522
523\typebuffer[def] \getbuffer[def]
524
525An example:
526
527\startbuffer[exa]
528\RotatedText{-15}{Some Rotated Text}
529\stopbuffer
530
531\typebuffer[exa]
532
533\startlinecorrection[blank]
534\getbuffer[exa]
535\stoplinecorrection
536
537In a similar fashion we can isolate the text. This permits us to use the same
538graphics with different settings.
539
540\startbuffer[def]
541\setupMPvariables[RotatedText][rotation=270]
542
543\setMPtext{RotatedText}{Some Text}
544
545\startuseMPgraphic{RotatedText}
546  draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
547\stopuseMPgraphic
548\stopbuffer
549
550\typebuffer[def] \getbuffer[def]
551
552This works as expected:
553
554\startbuffer[exa]
555\RotatedText{165}{Some Rotated Text}
556\stopbuffer
557
558\typebuffer[exa]
559
560\startlinecorrection[blank]
561\getbuffer[exa]
562\stoplinecorrection
563
564It is now a small step towards an encapsulating macro (we assume that you are
565familiar with \TEX\ macro definitions).
566
567\startbuffer[def]
568\def\RotatedText[#1]#2%
569  {\setupMPvariables[RotatedText][#1]%
570   \setMPtext{RotatedText}{#2}%
571   \useMPgraphic{RotatedText}}
572
573\setupMPvariables[RotatedText][rotation=90]
574
575\startuseMPgraphic{RotatedText}
576  draw \MPbetex{RotatedText} rotated \MPvar{rotation} ;
577\stopuseMPgraphic
578\stopbuffer
579
580\typebuffer[def] \getbuffer[def]
581
582Again, we default to a 90 degrees rotation, and pass both the settings and text
583in an indirect way. This method permits you to build complicated graphics and
584still keep macros readable.
585
586\startbuffer[exa]
587\RotatedText[rotation=240]{Some Rotated Text}
588\stopbuffer
589
590\typebuffer[exa]
591
592\startlinecorrection[blank]
593\getbuffer[exa]
594\stoplinecorrection
595
596You may wonder why we don't use the variable mechanism to pass the text. The main
597reason is that the text mechanism offers a few more features, one of which is
598that it passes the text straight on, without the danger of unwanted expansion of
599embedded macros. Using \type {\setMPtext} also permits you to separate \TEX\ and
600\METAPOST\ code and reuse it multiple times (imagine using the same graphic in a
601section head command).
602
603There are three ways to access a text defined with \type {\setMPtext}. Imagine
604that we have the following definitions:
605
606\startbuffer
607\setMPtext {1} {Now is this \TeX\ or not?}
608\setMPtext {2} {See what happens here.}
609\setMPtext {3} {Text streams become pictures.}
610\stopbuffer
611
612\typebuffer \getbuffer
613
614The \type {\MPbetex} macro returns a \typ {btex ... etex} construct. The \type
615{\MPstring} returns the text as a \METAPOST\ string, between quotes. The raw text
616can be fetched with \type {\MPtext}.
617
618\startbuffer
619\startMPcode
620  picture p ; p :=           \MPbetex {1}          ;
621  picture q ; q :=  textext( \MPstring{2}        ) ;
622  picture r ; r := thelabel("\MPtext  {3}",origin) ;
623
624  for i=p, boundingbox p : draw i withcolor .625red    ; endfor ;
625  for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
626  for i=r, boundingbox r : draw i withcolor .625white  ; endfor ;
627
628  currentpicture := currentpicture scaled 2 ;
629  draw origin
630    withpen pencircle scaled 5.0mm withcolor white ;
631  draw origin
632    withpen pencircle scaled 2.5mm withcolor black ;
633  draw boundingbox currentpicture
634    withpen pencircle scaled .1mm
635    dashed evenly ;
636\stopMPcode
637\stopbuffer
638
639\typebuffer
640
641The first two lines return text typeset by \TEX, while the last line leaves this
642to \METAPOST.
643
644\startlinecorrection[blank]
645\getbuffer
646\stoplinecorrection
647
648If you watch closely, you will notice that the first (red) alternative is
649positioned with the baseline on the origin.
650
651\startbuffer
652\startMPcode
653  picture p ; p :=                  \MPbetex {1}          ;
654  picture q ; q :=  textext.origin( \MPstring{2}        ) ;
655  picture r ; r := thelabel.origin("\MPtext  {3}",origin) ;
656
657  for i=p, boundingbox p : draw i withcolor .625red    ; endfor ;
658  for i=q, boundingbox q : draw i withcolor .625yellow ; endfor ;
659  for i=r, boundingbox r : draw i withcolor .625white  ; endfor ;
660
661  currentpicture := currentpicture scaled 2 ;
662  draw origin withpen pencircle scaled 5.0mm
663    withcolor white ;
664  draw origin withpen pencircle scaled 2.5mm
665    withcolor black ;
666  draw boundingbox currentpicture
667    withpen pencircle scaled .1mm
668    dashed evenly ;
669\stopMPcode
670\stopbuffer
671
672\typebuffer
673
674This draws:
675
676\startlinecorrection[blank]
677\getbuffer
678\stoplinecorrection
679
680This picture demonstrates that we can also position \type {textext}'s and \type
681{label}'s on the baseline. For this purpose the repertoire of positioning
682directives (\type {top}, \type {lft}, etc.) is extended with an \type {origin}
683directive. Another extra positioning directive is \type {raw}. This one does not
684do any positioning at all.
685
686\starttyping
687picture q ; q :=  textext.origin( \MPstring{2}        ) ;
688picture r ; r := thelabel.origin("\MPtext  {3}",origin) ;
689\stoptyping
690
691We will now apply this knowledge of text inclusion in graphics to a more advanced
692example. The next definitions are the answer to a question on the \CONTEXT\
693mailinglist with regards to framed texts with titles.
694
695\startbuffer[a]
696\defineoverlay[FunnyFrame][\useMPgraphic{FunnyFrame}]
697
698\defineframedtext[FunnyText][frame=off,background=FunnyFrame]
699
700\def\StartFrame{\startFunnyText}
701\def\StopFrame {\stopFunnyText }
702
703\def\FrameTitle#1%
704  {\setMPtext{FunnyFrame}{\hbox spread 1em{\hss\strut#1\hss}}}
705
706\setMPtext{FunnyFrame}{} % initialize the text variable
707\stopbuffer
708
709\startbuffer[b]
710\startuseMPgraphic{FunnyFrame}
711  picture p ; numeric w, h, o ;
712  p := textext.rt(\MPstring{FunnyFrame}) ;
713  w := OverlayWidth ; h := OverlayHeight ; o := BodyFontSize ;
714  p := p shifted (2o,h-ypart center p) ; draw p ;
715  drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
716  draw (2o,h)--(0,h)--(0,0)--(w,0)--(w,h)--(xpart urcorner p,h) ;
717  draw boundingbox p ;
718  setbounds currentpicture to unitsquare xyscaled(w,h) ;
719\stopuseMPgraphic
720\stopbuffer
721
722\startbuffer[c1]
723\FrameTitle{Zapf (1)}
724
725\StartFrame
726Coming back to the use of typefaces in electronic
727publishing: many of the new typographers receive their
728knowledge and information about the rules of typography from
729books, from computer magazines or the instruction manuals
730which they get with the purchase of a PC or software.
731\StopFrame
732\stopbuffer
733
734\getbuffer[a,b,c1]
735
736In this example, the title is positioned on top of the frame. Title and text are
737entered as:
738
739\typebuffer[c1]
740
741The implementation is not that complicated and uses the frame commands that are
742built in \CONTEXT. Instead of letting \TEX\ draw the frame, we use \METAPOST,
743which we also use for handling the title. The graphic is defined as follows:
744
745\typebuffer[b]
746
747Because the framed title is partly positioned outside the main frame, and because
748the main frame will be combined with the text, we need to set the boundingbox
749explicitly. This is a way to create so called free figures, where part of the
750figure lays beyond the area that is taken into account when positioning the
751graphic. The shift
752
753\starttyping
754... shifted (2o,h-ypart center p)
755\stoptyping
756
757ensures that the title is vertically centered over the top line of the main box.
758
759The macros that use this graphic combine some techniques of defining macros,
760using predefined \CONTEXT\ classes, and passing information to graphics.
761
762\typebuffer[a]
763
764There is a little bit of low level \TEX\ code involved, like a horizontal box
765(\type {\hbox}) that stretches one em||space beyond its natural size (\type
766{spread 1em}) with a centered text (two times \type {\hss}). Instead of applying
767this spread, we could have enlarged the frame on both sides.
768
769\startbuffer[b]
770\startuseMPgraphic{FunnyFrame}
771  picture p ; numeric o ; path a, b ; pair c ;
772  p := textext.rt(\MPstring{FunnyFrame}) ;
773  a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
774  o := BodyFontSize ;
775  p := p shifted (2o,OverlayHeight-ypart center p) ;
776  drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
777  b := a randomized (o/2) ;
778  fill b withcolor .85white ; draw b ;
779  b := (boundingbox p) randomized (o/8) ;
780  fill b withcolor .85white ; draw b ;
781  draw p withcolor black;
782  setbounds currentpicture to a ;
783 \stopuseMPgraphic
784\stopbuffer
785
786In the previous graphic we calculated the big rectangle taking the small one into
787account. This was needed because we don't use a background fill. The next
788definition does, so there we can use a more straightforward approach by just
789drawing (and filling) the small rectangle on top of the big one.
790
791\typebuffer[b] \getbuffer[b]
792
793\startbuffer[c2]
794\FrameTitle{Zapf (2)}
795
796\StartFrame
797There is not so much basic instruction, as of now, as there
798was in the old days, showing the differences between good
799and bad typographic design.
800\StopFrame
801\stopbuffer
802
803\getbuffer[c2]
804
805Because we use a random graphic, we cannot guarantee beforehand that the left and
806right edges of the small shape touch the horizontal lines in a nice way. The next
807alternative displaces the small shape plus text so that its center lays on the
808line. On the average, this looks better.
809
810\startbuffer[b]
811\startuseMPgraphic{FunnyFrame}
812  picture p ; numeric o ; path a, b ; pair c ;
813  p := textext.rt(\MPstring{FunnyFrame}) ;
814  a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
815  o := BodyFontSize ;
816  p := p shifted (2o,OverlayHeight-ypart center p) ;
817  drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
818  b := a randomized (o/2) ;
819  fill b withcolor .85white ; draw b ;
820  c := center p ;
821  c := b intersectionpoint (c shifted (0,-o)--c shifted(0,o)) ;
822  p := p shifted (c-center p) ;
823  b := (boundingbox p) randomized (o/8) ;
824  fill b withcolor .85white ; draw b ;
825  draw p withcolor black;
826  setbounds currentpicture to a ;
827 \stopuseMPgraphic
828\stopbuffer
829
830\typebuffer[b] \getbuffer[b]
831
832\getbuffer[c2]
833
834Yet another definition uses super ellipsed shapes instead of random ones. We need
835a high degree of superness (.95) in order to make sure that the curves don't
836touch the texts.
837
838\startbuffer[b]
839\startuseMPgraphic{FunnyFrame}
840  picture p ; numeric o ; path a, b ; pair c ;
841  p := textext.rt(\MPstring{FunnyFrame}) ;
842  o := BodyFontSize ;
843  a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
844  p := p shifted (2o,OverlayHeight-ypart center p) ;
845  drawoptions (withpen pencircle scaled 1pt withcolor .625red) ;
846  b := a superellipsed .95 ;
847  fill b withcolor .85white ; draw b ;
848  b := (boundingbox p) superellipsed .95 ;
849  fill b withcolor .85white ; draw b ;
850  draw p withcolor black ;
851  setbounds currentpicture to a ;
852\stopuseMPgraphic
853\stopbuffer
854
855\typebuffer[b] \getbuffer[b]
856
857\startbuffer[c3]
858\FrameTitle{Zapf (3)}
859
860\StartFrame
861Many people are just fascinated by their PC's tricks, and
862think that a widely||praised program, called up on the
863screen, will make everything automatic from now on.
864\StopFrame
865\stopbuffer
866
867\getbuffer[c3]
868
869There are quite some hard coded values in these graphics, like the linewidths,
870offsets and colors. Some of these can be fetched from the \type {\framed}
871environment either by using \TEX\ macros or dimensions, or by using their
872\METAFUN\ counterparts. In the following table we summarize both the available
873\METAPOST\ variables and their \TEX\ counterparts. They may be used
874interchangeably.
875
876\starttabulate[|l|Tl|l|]
877\HL
878\NC \bf \METAPOST\ variable \NC \rm \bf \TEX\ command \NC \bf meaning \NC\NR
879\HL
880\NC OverlayWidth     \NC \string\overlaywidth
881                     \NC current width \NC\NR
882\NC OverlayHeight    \NC \string\overlayheight
883                     \NC current height \NC\NR
884\NC OverlayDepth     \NC \string\overlayheight
885                     \NC current depth (often zero) \NC\NR
886\NC OverlayColor     \NC \string\MPcolor\string{\string\overlaycolor\string}
887                     \NC background color \NC\NR
888\NC OverlayLineWidth \NC \string\overlaylinewidth
889                     \NC width of the frame \NC\NR
890\NC OverlayLineColor \NC \string\MPcolor\string{\overlaylinecolor\string}
891                     \NC color of the frame \NC\NR
892\NC BaseLineSkip     \NC \string\the\string\baselineskip
893                     \NC main line distance \NC\NR
894\NC LineHeight       \NC \string\the\string\baselineskip
895                     \NC idem \NC\NR
896\NC BodyFontSize     \NC \string\the\string\bodyfontsize
897                     \NC font size of the running text \NC\NR
898\NC StrutHeight      \NC \string\strutheight
899                     \NC space above the baseline \NC\NR
900\NC StrutDepth       \NC \string\strutdepth
901                     \NC space below the baseline \NC\NR
902\NC ExHeight         \NC 1ex
903                     \NC height of an x \NC \NR
904\NC EmWidth          \NC 1em
905                     \NC width of an m-dash \NC \NR
906\HL
907\stoptabulate
908
909\startbuffer[b]
910\startuseMPgraphic{FunnyFrame}
911  picture p ; numeric o ; path a, b ; pair c ;
912  p := textext.rt(\MPstring{FunnyFrame}) ;
913  o := BodyFontSize ;
914  a := unitsquare xyscaled(OverlayWidth,OverlayHeight) ;
915  p := p shifted (2o,OverlayHeight-ypart center p) ;
916  pickup pencircle scaled OverlayLineWidth ;
917  b := a superellipsed .95 ;
918  fill b withcolor OverlayColor ;
919  draw b withcolor OverlayLineColor ;
920  b := (boundingbox p) superellipsed .95 ;
921  fill b withcolor OverlayColor ;
922  draw b withcolor OverlayLineColor ;
923  draw p withcolor black ;
924  setbounds currentpicture to a ;
925\stopuseMPgraphic
926\stopbuffer
927
928\typebuffer[b] \getbuffer[b]
929
930\startbuffer[d]
931\setupframedtexts
932  [FunnyText]
933  [backgroundcolor=lightgray,
934   framecolor=darkred,
935   rulethickness=2pt,
936   offset=\bodyfontsize,
937   before={\blank[big,medium]},
938   after={\blank[big]},
939   width=\textwidth]
940\stopbuffer
941
942\getbuffer[d,c3]
943
944We used the following command to pass the settings:
945
946\typebuffer[d]
947
948In a real implementation, we should also take care of some additional spacing
949before the text, which is why we have added more space before than after the
950framed text.
951
952We demonstrated that when defining graphics that are part of the layout, you need
953to have access to information known to the typesetting engine. Take \in {figure}
954[fig:penalty]. The line height needs to match the font and the two thin
955horizontal lines should match the {\em x}||height. We also need to position the
956baseline, being the lowest one of a pair of lines, in such a way that it suits
957the proportions of the line as specified by the strut. A strut is an imaginary
958large character with no width. You should be aware of the fact that while \TEX\
959works its way top||down, in \METAPOST\ the origin is in the lower left corner.
960
961\startmode[screen]
962
963\placefigure
964  [page][fig:penalty]
965  {Penalty lines.}
966  {\typesetfile[mfun-902.tex][page=1,frame=on,height=.85\textheight]}
967
968\stopmode
969
970\startnotmode[screen]
971
972\placefigure
973  [here][fig:penalty]
974  {Penalty lines.}
975  {\typesetfile[mfun-902.tex][page=1,frame=on,height=.50\textheight]}
976
977\stopnotmode
978
979\typebuffer[handwrit]
980
981This code demonstrates the use of \type {LineHeight}, \type {ExHeight}, \type
982{StrutHeight} and \type {StrutDepth}. We set the interline spacing to 1.5 so that
983we get a bit more loose layout. The variables mentioned are set each time a
984graphic is processed and thereby match the current font settings.
985
986\stopsection
987
988\stopchapter
989
990\stopcomponent
991