metafun-effects.tex /size: 78 Kb    last modification: 2023-12-21 09:43
1% language=us runpath=texruns:manuals/metafun
2
3% graphic text takes 5 sec on 21
4
5\startcomponent metafun-effects
6
7\environment metafun-environment
8
9\useMPlibrary[outlines]
10
11\startchapter[reference=sec:effects,title={Special effects}]
12
13\startintro
14
15Sometimes we want to go beyond \METAPOST's native features. Examples of such an
16extension are \CMYK\ colors, shading and transparency. Although features like
17this should be used with care, sometimes the documents look and feel can profit
18from it.
19
20If you don't want the whole graphic, but only a part of it, clipping comes into
21play. In addition to the standard clipping features, we can use \METAPOST\ to
22provide a decent clipping path. In this chapter we will uncover the details.
23
24We will also introduce ways to include externally defined graphics and outline
25fonts. We will demonstrate that within reasonable bounds you can manipulate such
26graphics.
27
28\stopintro
29
30\startsection[title={Spot colors}]
31
32You can define spot and multitone colors directly in \METAFUN, although normally
33you will do it at the \TEX\ end for consistency. At the \TEX\ end we define this:
34
35\startbuffer
36\definecolor [SpotBlue]   [c=1,m=.38,y=0,k=.64]
37\definecolor [SpotYellow] [c=0,m=.28,y=1,k=.06]
38\definemultitonecolor [MultiColor] [SpotBlue=.5,SpotYellow=.25]
39\stopbuffer
40
41\typebuffer \getbuffer
42
43\startbuffer
44draw image  (
45    fill unitsquare shifted (7,0)
46        withcolor namedcolor("MultiColor") ;
47    fill unitsquare shifted (6,0)
48        withcolor .6 * spotcolor("temp1",red) ;
49    fill unitsquare shifted (5,0)
50        withcolor .4 * spotcolor("temp1",red) ;
51    fill unitsquare shifted (4,0)
52        withcolor .5 * spotcolor("temp2",.5green) ;
53    fill unitsquare shifted (3,0)
54        withcolor .5 * spotcolor("temp3",green) ;
55    fill unitsquare shifted (2,0)
56        withcolor multitonecolor("temp4",blue/2,yellow/2,green/2,magenta/3) ;
57) xsized TextWidth ;
58\stopbuffer
59
60Next we process this graphic:
61
62\typebuffer
63
64and get:
65
66\startlinecorrection[blank]
67\processMPbuffer
68\stoplinecorrection
69
70\stopsection
71
72\startsection[title={Transparency}]
73
74\index{transparency}
75
76{\em In the screen version we use a light gray background color. As a result,
77some of the transparency methods demonstrated here give unexpected results. The
78A4 version of this document demonstrates the real effects.}
79
80Although transparent colors have been around for some time already, it was only
81around 2000 that they made it as a high level feature into document format
82languages like \PDF. Supporting such a feature at a higher abstraction level is
83not only more portable, but also less sensitive for misinterpretation.
84
85\startbuffer[mpdef]
86vardef ColorCircle (expr method, factor, ca, cb, cc) =
87  save u, p ; path p ; p := fullcircle shifted (1/4,0) ;
88  image
89    ( fill p rotated  90 withcolor ca withtransparency (method,factor) ;
90      fill p rotated 210 withcolor cb withtransparency (method,factor) ;
91      fill p rotated 330 withcolor cc withtransparency (method,factor) ; )
92enddef ;
93\stopbuffer
94
95\typebuffer[mpdef]
96
97\startbuffer[mp]
98draw ColorCircle ("normal", .5, red, green, blue) xsized 3cm ;
99currentpicture := currentpicture shifted (-4cm,0) ;
100draw ColorCircle ("exclusion", .5, red, green, blue) xsized 3cm ;
101currentpicture := currentpicture shifted (-4cm,0) ;
102draw ColorCircle ("exclusion", 1, red, green, blue) xsized 3cm ;
103\stopbuffer
104
105\typebuffer[mp]
106
107\startlinecorrection[blank]
108\processMPbuffer[mpdef,mp]
109\stoplinecorrection
110
111\startbuffer[mp]
112cmykcolor xcyan    ; xcyan    := (1,0,0,0) ;
113cmykcolor xmagenta ; xmagenta := (0,1,0,0) ;
114cmykcolor xyellow  ; xyellow  := (0,0,1,0) ;
115
116draw ColorCircle ("exclusion", .5, xcyan, xmagenta, xyellow) xsized 3cm ;
117\stopbuffer
118
119\typebuffer[mp]
120
121\startlinecorrection[blank]
122\processMPbuffer[mpdef,mp]
123\stoplinecorrection
124
125You can be tempted to use transparency as a convenient way to achieve soft
126colors. In that case you should be aware of the fact that rendering transparent
127colors takes more time than normal colors \footnote {When your printer does not
128support this feature natively, the intermediate (\POSTSCRIPT) file send to the
129printing engine is also larger.}
130
131Fortunatey, \METAPOST\ provides a similar mechanism. The last circle in the
132following row demonstrates how we can trigger colors proportionally to other
133colors. Normally \type {background} is white, but you can set predefined color
134variables to another value.
135
136\startbuffer[mp]
137path p ; p := fullcircle scaled 2cm ;
138fill p shifted (0cm,0) withcolor blue  ;
139fill p shifted (3cm,0) withcolor .5blue  ;
140fill p shifted (6cm,0) withcolor transparent (1,0.5,blue) ;
141fill p shifted (9cm,0) withcolor .5[blue,white] ;
142\stopbuffer
143
144\typebuffer[mp]
145
146\startlinecorrection[blank]
147\processMPbuffer[mp]
148\stoplinecorrection
149
150The next series demonstrates that we use the complementary factor \type {.7} in
151the \METAPOST\ soft color to achieve the same softness as the \type {.3}
152transparency.
153
154\startbuffer[mp]
155path p ; p := fullcircle scaled 2cm ;
156fill p shifted (0cm,0) withcolor red  ;
157fill p shifted (3cm,0) withcolor .7red ;
158fill p shifted (6cm,0) withcolor transparent (1,0.3,red) ;
159fill p shifted (9cm,0) withcolor .7[red,white] ;
160\stopbuffer
161
162\typebuffer[mp]
163
164\startlinecorrection[blank]
165\processMPbuffer[mp]
166\stoplinecorrection
167
168\startbuffer[mp]
169vardef SampleText (expr t, c) =
170  save p ; picture p ;
171  p := image (draw t infont "\truefontname{Regular}") ;
172  draw (p shifted (- xpart center p,0)) scaled 5 withcolor c;
173enddef ;
174
175SampleText ("Much Of This"   , transparent(1, .5, red  )) ;
176SampleText ("Functionality"  , transparent(1, .5, green)) ;
177SampleText ("Was Written"    , transparent(1, .5, blue )) ;
178SampleText ("While Listening", transparent(1, .5, cmyk(1,0,0,0))) ;
179SampleText ("To the CD's Of" , transparent(1, .5, cmyk(0,1,0,0))) ;
180SampleText ("Tori Amos"      , transparent(1, .5, cmyk(0,0,1,0))) ;
181\stopbuffer
182
183So far we have applied transparent colors to shapes but text can also be the
184target.
185
186\typebuffer[mp]
187
188The source code of this example illustrates that the \CMYK\ color space is also
189supported. The \type {\truefontname} macro communicates the running font from
190\TEX\ to \METAPOST. Instead of such low level code one can of course also use the
191\type {textext} macro.
192
193\startbuffer[mp]
194vardef SampleText (expr t) =
195  draw textext(t) scaled 5 ;
196enddef ;
197
198SampleText ("\colored[a=1,t=.5,r=1]{Much Of This}") ;
199SampleText ("\colored[a=1,t=.5,g=1]{Functionality}") ;
200SampleText ("\colored[a=1,t=.5,b=1]{Was Written}") ;
201SampleText ("\colored[a=1,t=.5,c=1]{While Listening}") ;
202SampleText ("\colored[a=1,t=.5,m=1]{To the CD's Of}") ;
203SampleText ("\colored[a=1,t=.5,y=1]{Tori Amos}") ;
204\stopbuffer
205
206However, as we do the typesetting in \TEX\ in \MKIV\ this is the way to go:
207
208\typebuffer[mp]
209
210As expected we get:
211
212\startlinecorrection[blank]
213\processMPbuffer[mp]
214\stoplinecorrection
215
216Currently the 12 in \PDF\ available transparency methods are supported. \footnote
217{In the future we may also support more control over the individual methods.} You
218can use both numbers and names. As you may expect, both \CONTEXT\ and \METAFUN\
219support transparency in the same way. \in {Figure} [fig:transparencies] shows how
220the method affects the result.
221
222\startuseMPgraphic{test}
223numeric u ; u := if lua.mp.mode("screen") : 12mm else : 20mm fi ;
224
225path p ; p := fullcircle scaled u shifted (u/4,0);
226
227% cmykcolor xyellow ; xyellow := (0,0,1,0) ;
228% color xgreen      ; xgreen  := (0,1,0) ;
229% color xblue       ; xblue   := (0,0,1) ;
230
231% fill p rotated  90 withcolor transparent("\MPvar{a}",.5,xyellow) ;
232% fill p rotated 210 withcolor transparent("\MPvar{a}",.5,xgreen) ;
233% fill p rotated 330 withcolor transparent("\MPvar{a}",.5,xblue) ;
234
235% fill p rotated  90 withcolor (0,0,1,0) withtransparency("\MPvar{a}",.5) ;
236% fill p rotated 210 withcolor (0,1,0)   withtransparency("\MPvar{a}",.5) ;
237% fill p rotated 330 withcolor (0,0,1)   withtransparency("\MPvar{a}",.5) ;
238fill p rotated  90 withcolor (0,0,1,0) withtransparency(\MPvar{b},.5) ;
239fill p rotated 210 withcolor (0,1,0)   withtransparency(\MPvar{b},.5) ;
240fill p rotated 330 withcolor (0,0,1)   withtransparency(\MPvar{b},.5) ;
241\stopuseMPgraphic
242
243\startplacefigure[location=here,reference=fig:transparencies,title={The 12 transparency alternatives by name.}]
244    \doifelsemode {screen} {
245        \setupcombination[nx=8,ny=2]
246    } {
247        \setupcombination[nx=4,ny=4]
248    }
249    \startcombination
250      {\useMPgraphic{test}{b=1,a=normal}}      {\tttf normal}
251      {\useMPgraphic{test}{b=2,a=multiply}}    {\tttf multiply} % here the mu in multiply triggers lookahead in lmtx
252      {\useMPgraphic{test}{b=3,a=screen}}      {\tttf screen}
253      {\useMPgraphic{test}{b=4,a=overlay}}     {\tttf overlay}
254      {\useMPgraphic{test}{b=5,a=softlight}}   {\tttf softlight}
255      {\useMPgraphic{test}{b=6,a=hardlight}}   {\tttf hardlight}
256      {\useMPgraphic{test}{b=7,a=colordodge}}  {\tttf colordodge}
257      {\useMPgraphic{test}{b=8,a=colorburn}}   {\tttf colorburn}
258      {\useMPgraphic{test}{b=9,a=darken}}      {\tttf darken}
259      {\useMPgraphic{test}{b=10,a=lighten}}    {\tttf lighten}
260      {\useMPgraphic{test}{b=11,a=difference}} {\tttf difference}
261      {\useMPgraphic{test}{b=12,a=exclusion}}  {\tttf exclusion}
262      {\useMPgraphic{test}{b=13,a=hue}}        {\tttf hue}
263      {\useMPgraphic{test}{b=14,a=saturation}} {\tttf saturation}
264      {\useMPgraphic{test}{b=15,a=color}}      {\tttf color}
265      {\useMPgraphic{test}{b=16,a=luminosity}} {\tttf luminosity}
266    \stopcombination
267\stopplacefigure
268
269In \CONTEXT\ a transparent color is defined in a similar way as \quote {normal}
270colors. The transparency method is specified with the \type {a} key (either by
271number or by name) and the factor \type {t}.
272
273\startbuffer
274\definecolor [tred]   [r=1,t=.5,a=exclusion]
275\definecolor [tgreen] [g=1,t=.5,a=exclusion]
276\definecolor [tblue]  [b=1,t=.5,a=exclusion]
277\stopbuffer
278
279\typebuffer \getbuffer
280
281Both keys are needed. You can define your own symbolic names using:
282
283\starttyping
284\definetransparency [myowndefault] [1]
285\stoptyping
286
287The \type {\MPcolor} macro passes a color from \CONTEXT\ to \METAPOST, including
288the transparency specification.
289
290\startbuffer[mp]
291u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);
292
293fill p rotated  90 withcolor \MPcolor{tred} ;
294fill p rotated 210 withcolor \MPcolor{tgreen} ;
295fill p rotated 330 withcolor \MPcolor{tblue} ;
296\stopbuffer
297
298\typebuffer
299
300\startlinecorrection[blank]
301\processMPbuffer[mp]
302\stoplinecorrection
303
304Of course this also works well for \CMYK\ colors.
305
306\startbuffer
307\definecolor[tred]  [c=1,k=.2,t=.5,a=1]
308\definecolor[tgreen][m=1,k=.2,t=.5,a=1]
309\definecolor[tblue] [y=1,k=.2,t=.5,a=1]
310\stopbuffer
311
312\typebuffer
313
314\startlinecorrection[blank]
315\processMPbuffer[mp]
316\stoplinecorrection
317
318Gray scales work as well:
319
320\startbuffer
321\definecolor[tgraya][s=.9,t=.7,a=11]
322\definecolor[tgrayb][s=.7,t=.7,a=11]
323\definecolor[tgrayc][s=.5,t=.7,a=11]
324\stopbuffer
325
326\typebuffer \getbuffer
327
328We apply this to some text. By using an overlay we can conveniently explore the
329difference in fonts.
330
331% \startbuffer
332% def SampleText (expr s, f, c) =
333%   draw s infont f scaled 5 withcolor c ;
334% enddef ;
335
336% SampleText("Hello", "\truefontname{Regular}"       , \MPcolor{ta}) ;
337% SampleText("Hello", "\truefontname{RegularBold}"   , \MPcolor{tb}) ;
338% SampleText("Hello", "\truefontname{RegularSlanted}", \MPcolor{tc}) ;
339% \stopbuffer
340
341\startbuffer
342draw textext("\color[tgraya]{\tf Hello}") scaled 5 ;
343draw textext("\color[tgrayb]{\bf Hello}") scaled 5 ;
344draw textext("\color[tgrayc]{\sl Hello}") scaled 5 ;
345\stopbuffer
346
347\typebuffer
348
349\startlinecorrection[blank]
350\processMPbuffer
351\stoplinecorrection
352
353\stopsection
354
355\startsection[title={Shading}]
356
357\startsubsection[title=Introduction]
358
359\index{shading}
360
361In this section we introduce different kinds of shading. Since \METAPOST\ does
362not support this feature directly, we have to fall back on a few tricks. For the
363moment shading is only supported in \PDF. In the following examples, we will use
364the next three colors:
365
366\startbuffer
367\definecolor[mycolora][darkyellow]
368\definecolor[mycolorb][s=.8]
369\definecolor[mycolorc][darkred]
370\stopbuffer
371
372\typebuffer
373
374\getbuffer
375
376Shading support evolved in steps and alongside development of the backend code. Also,
377as it became more used a second interface came available. We discuss both here.
378
379\stopsubsection
380
381\startsubsection[title=The old method]
382
383First we discuss the old method which is still valid and also available in
384\MKII. It illustrates some of the principles.
385
386\startbuffer[a]
387\startuniqueMPgraphic{CircularShade}
388  path  p ;
389  p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
390  circular_shade(p,0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
391\stopuniqueMPgraphic
392
393\startuniqueMPgraphic{LinearShade}
394  path  p ;
395  p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
396  linear_shade(p,0,\MPcolor{mycolora},\MPcolor{mycolorb});
397\stopuniqueMPgraphic
398\stopbuffer
399
400\startbuffer[b]
401\defineoverlay[circular shade][\uniqueMPgraphic{CircularShade}]
402\defineoverlay[linear shade]  [\uniqueMPgraphic{LinearShade}]
403\stopbuffer
404
405\startbuffer[c]
406\framed
407  [background=circular shade,frame=off]
408  {\bf \white Hi there, I'm Circular!}
409\stopbuffer
410
411\startbuffer[d]
412\framed
413  [background=linear shade,frame=off]
414  {\bf \white Whow, this is Linear!}
415\stopbuffer
416
417A shade is a fill with a stepwise change in color. In \POSTSCRIPT\ (level 2), the
418way this color changes can be circular, linear, or according to a user defined
419function. Circular and linear shades look like this:
420
421\startlinecorrection[blank]
422\getbuffer[a,b,c]
423\stoplinecorrection
424
425\startlinecorrection[blank]
426\getbuffer[a,b,d]
427\stoplinecorrection
428
429As you can see, the shade lays behind the text, as a background overlay. These
430overlays are unique \METAPOST\ graphics, so they will adapt themselves to the
431dimensions of the foreground.
432
433\typebuffer[b]
434
435The two framed texts are defined as:
436
437\typebuffer[c]
438
439and:
440
441\typebuffer[d]
442
443We still have to define the graphics. Here we use a macro that takes four
444arguments: a path, a number identifying the center of shading, and the colors to
445start and end with.
446
447\typebuffer[a]
448
449The \METAPOST\ macros, \type {circular_shade} and \type {linear_shade}, add
450information to the \METAPOST\ output file, which is interpreted by the converter
451built in \CONTEXT. Shading comes down to interpolation between two or more points
452or user supplied ranges. A poor mans way of doing this, is to build the graphics
453piecewise with slightly changing colors. But, instead of \quote {manually}
454stepping through the color values, we can use the more efficient and generalized
455\POSTSCRIPT\ level~2 and \PDF\ level~1.3 shading feature.
456
457\def\SomeShade#1#2#3% waarom unique ?
458  {\startuniqueMPgraphic{shade-#1}
459     width := \overlaywidth ;
460     height := \overlayheight ;
461     path p ; p := unitsquare xscaled width yscaled height ;
462     #2_shade(p,#3,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
463   \stopuniqueMPgraphic
464   \defineoverlay[shade-#1][\uniqueMPgraphic{shade-#1}]%
465   \framed[background=shade-#1,width=2cm,height=2cm,frame=off]{}}
466
467\startlinecorrection[blank]
468\startcombination[5*1]
469  {\SomeShade{20}{circular}{0}} {circular 0}
470  {\SomeShade{21}{circular}{1}} {circular 1}
471  {\SomeShade{22}{circular}{2}} {circular 2}
472  {\SomeShade{23}{circular}{3}} {circular 3}
473  {\SomeShade{24}{circular}{4}} {circular 4}
474\stopcombination
475\stoplinecorrection
476
477\startlinecorrection[blank]
478\startcombination[4*2]
479  {\SomeShade{32}{linear}{1}} {linear 1}
480  {\SomeShade{32}{linear}{2}} {linear 2}
481  {\SomeShade{33}{linear}{3}} {linear 3}
482  {\SomeShade{34}{linear}{4}} {linear 4}
483  {\SomeShade{35}{linear}{5}} {linear 5}
484  {\SomeShade{36}{linear}{6}} {linear 6}
485  {\SomeShade{37}{linear}{7}} {linear 7}
486  {\SomeShade{38}{linear}{8}} {linear 8}
487\stopcombination
488\stoplinecorrection
489
490% % This limitation si no longer present in mpiv.
491%
492% Shading is not a \METAPOST\ feature, which means that it has to be implemented
493% using so called specials, directives that end up in the output file.
494% Unfortunately these are not coupled to the specific path, which means that we
495% have to do a significant amount of internal bookkeeping. Also, in \PDF\ we have
496% to make sure that the graphics and their resources (being the shading functions)
497% are packaged together.
498%
499% Because of this implementation, shading may behave somewhat unexpected at times.
500% A rather normal case is the next one, where we place 5~shaded circles in a row.
501%
502% \startbuffer
503% path p ; p := fullcircle scaled 1cm ;
504% for i=0 step 2cm until 8cm :
505%   circular_shade(p shifted (i,0),0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
506% endfor ;
507% \stopbuffer
508%
509% \typebuffer
510%
511% \startlinecorrection[blank]
512% \processMPbuffer
513% \stoplinecorrection
514%
515% At first sight, in the next situation, we would expect something similar, because
516% we simply copy the same circle 5~times. However, due to the way we have
517% implemented shading in \CONTEXT, we do indeed copy the circles, but the shade
518% definition is frozen and the same one is used for all 5~circles. This means that
519% the center of the shading stays at the first circle.
520%
521% \startbuffer
522% circular_shade(fullcircle scaled 1cm,0,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
523% picture s ; s := currentpicture ; currentpicture := nullpicture ;
524% for i=0 step 2cm until 8cm :
525%   addto currentpicture also s shifted (i,0) ;
526% endfor ;
527% \stopbuffer
528%
529% \typebuffer
530%
531% \startlinecorrection[blank]
532% \processMPbuffer
533% \stoplinecorrection
534%
535% Unlike \TEX, \METAPOST\ does not keep its specials attached to the current path,
536% and flushes them before the graphic data. Since we use these specials to register
537% shading information, it is rather hard to tightly connect a specific shade with a
538% certain fill, especially if an already performed fill is not accessible, which is
539% the case when we copy a picture.
540%
541% This may seem a disadvantage, but fortunately it also has its positive side. In
542% the next example we don't copy, but reuse an already defined shade. By storing
543% the reference to this shade, and referring to it by using \type {withshade}, we
544% can use a shade that operates on multiple shapes.
545
546\startbuffer
547sh := define_circular_shade
548  (origin,origin,0,8cm,\MPcolor{mycolora},\MPcolor{mycolorb}) ;
549for i=0 step 2cm until 8cm :
550  fill fullcircle scaled 1cm shifted (i,0) withshade sh ;
551endfor ;
552\stopbuffer
553
554\typebuffer
555
556\startlinecorrection[blank]
557\processMPbuffer
558\stoplinecorrection
559
560The low level macro \type {define_circular_shade} is fed with two pairs (points),
561two radius, and two colors. The shade is distributed between the colors according
562to the radius.
563
564Shading can hardly be called an easy issue. The macros that we provide here are
565in fact simplifications, which means that at a lower level, one can do more
566advanced things. Here we limit ourselves to the more common cases. In the
567previous examples, we used an arrow to indicate the direction and magnitude of
568the shade. The next macro demonstrates the principles in a different way.
569
570\startbuffer[a]
571def test_shade (expr a, b, ra, rb) =
572  pickup pencircle scaled 1mm ;
573
574  color ca ; ca := \MPcolor{mycolora} ;
575  color cb ; cb := \MPcolor{mycolorb} ;
576  color cc ; cc := \MPcolor{mycolorc} ;
577
578  path pa ; pa := fullcircle scaled 2ra shifted a ;
579  path pb ; pb := fullcircle scaled 2rb shifted b ;
580
581  sh := define_circular_shade(a,b,ra,rb,ca,cb) ;
582
583  fill pb withshade sh ;
584  draw pb withcolor cc ;
585  draw pa withcolor cc ;
586enddef ;
587\stopbuffer
588
589\typebuffer[a]
590
591The shade is distributed between two circles, each with a radius and center
592point. All four can be set, but as the next calls demonstrate, we can normally do
593with less, which is why we provided the macro with less parameters.
594
595\startbuffer[b]
596test_shade(origin, origin,   0cm, 1cm) ;
597\stopbuffer
598\startbuffer[c]
599test_shade(origin, origin, .25cm, 1cm) ;
600\stopbuffer
601\startbuffer[d]
602test_shade(origin, origin, .50cm, 1cm) ;
603\stopbuffer
604
605\startbuffer[f]
606\startlinecorrection[blank]
607\hbox
608  {\processMPbuffer[a,b]\quad
609   \processMPbuffer[a,c]\quad
610   \processMPbuffer[a,d]}
611\stoplinecorrection
612\stopbuffer
613
614\typebuffer[b,c,d] \getbuffer[f]
615
616\startbuffer[b]
617test_shade(origin, origin shifted (.25cm,0),   0cm, 1cm) ;
618\stopbuffer
619\startbuffer[c]
620test_shade(origin, origin shifted (.25cm,0), .25cm, 1cm) ;
621\stopbuffer
622\startbuffer[d]
623test_shade(origin, origin shifted (.25cm,0), .50cm, 1cm) ;
624\stopbuffer
625
626\typebuffer[b,c,d] \getbuffer[f]
627
628\startbuffer[b]
629test_shade(origin shifted (.25cm,0), origin,   0cm, 1cm) ;
630\stopbuffer
631\startbuffer[c]
632test_shade(origin shifted (.25cm,0), origin, .25cm, 1cm) ;
633\stopbuffer
634\startbuffer[d]
635test_shade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
636\stopbuffer
637
638\typebuffer[b,c,d] \getbuffer[f]
639
640\startbuffer[a]
641def test_shade (expr a, b) =
642  pickup pencircle scaled 1mm ;
643
644  color ca ; ca := \MPcolor{mycolora} ;
645  color cb ; cb := \MPcolor{mycolorb} ;
646  color cc ; cc := \MPcolor{mycolorc} ;
647
648  sh := define_linear_shade(a,b,ca,cb) ;
649
650  fill fullsquare scaled 2cm withshade sh ;
651  draw a withcolor cc ;
652  draw b withcolor cc ;
653enddef ;
654\stopbuffer
655
656In a similar fashion, we can define a linear shade. This time we only pass two
657points and two colors.
658
659\typebuffer[a]
660
661Although one can control shading to a large extend, in practice only a few cases
662really make sense.
663
664\startbuffer[b]
665test_shade(origin, origin shifted (1cm,0)) ;
666\stopbuffer
667\startbuffer[c]
668test_shade(origin shifted (-1cm,0), origin shifted (1cm,0)) ;
669\stopbuffer
670\startbuffer[d]
671test_shade(origin shifted (-1cm,-1cm), origin shifted (1cm,1cm)) ;
672\stopbuffer
673
674\startbuffer[f]
675\startlinecorrection[blank]
676\hbox
677  {\processMPbuffer[a,b]\quad
678   \processMPbuffer[a,c]\quad
679   \processMPbuffer[a,d]}
680\stoplinecorrection
681\stopbuffer
682
683\typebuffer[b,c,d] \getbuffer[f]
684
685\stopsubsection
686
687\startsubsection[title=The new method]
688
689By now the shader macros are rather advanced and specifications are easier than
690before. Here we discuss the new method. An example is:
691
692\startbuffer
693fill fullsquare xyscaled (TextWidth,1cm)
694    withshademethod "linear"
695    withshadevector (1,0)
696    withshadecolors (darkred,darkgreen)
697;
698\stopbuffer
699
700\typebuffer
701
702\startlinecorrection[blank]
703    \processMPbuffer
704\stoplinecorrection
705
706There are several properties that can be set:
707
708\starttabulate[|l|p|]
709\NC domain  \NC The range over which the colors run, with a minimum of 0 and maximum of 1. \NC \NR
710\NC color   \NC A color to start from and one to end with, we default from black to white. \NC \NR
711\NC type    \NC The shading can be linear or circular. \NC \NR
712\NC center  \NC The origin of the shade vector. \NC \NR
713\NC radius  \NC The radius vector of a circular shade. \NC \NR
714\NC vector  \NC Where we start and end the shading. \NC \NR
715\stoptabulate
716
717For a linear shade the centers are the lower left and upper right corners, for a
718circular shade it's the center of the path. For a circular shade the radius runs
719from zero to the maximum distance from the center as determined by the
720boundingbox.
721
722The vector is used as follows: the first coordinate (xpart) determines the point
723on the path where we start, the second coordinate (ypart) the point on the
724path where we end.
725
726\startbuffer[a]
727fill fullsquare xyscaled (TextWidth,1cm)
728    withshademethod "linear"
729    withshadevector (1,0)
730    withshadecolors (darkred,darkgreen)
731;
732\stopbuffer
733
734\startbuffer[b]
735draw fullsquare xyscaled (TextWidth,1cm)
736    shownshadevector (1,0)
737    withpen pencircle scaled 2
738    withcolor .5white ;
739\stopbuffer
740
741\typebuffer
742
743\startlinecorrection[blank]
744    \processMPbuffer[a,b]
745\stoplinecorrection
746
747In the end only the x coordinate matters, but using a point on the path sort of
748fits in \METAPOST. In the case of a rectangle we have 4 points while circle has 8
749points.
750
751\startbuffer[a]
752fill fullcircle xyscaled (TextWidth,1cm)
753    withshademethod "linear"
754    withshadevector (2,4)
755    withshadecolors (darkred,darkgreen)
756;
757\stopbuffer
758
759\startbuffer[b]
760draw fullcircle xyscaled (TextWidth,1cm)
761    shownshadevector (2,4)
762    withpen pencircle scaled 2
763    withcolor .5white ;
764\stopbuffer
765
766\typebuffer
767
768\startlinecorrection[blank]
769    \processMPbuffer[a,b]
770\stoplinecorrection
771
772A triangle has three points. Using 1 and 2 as second vector value gives the same
773results as do values in the range 0 upto 1 and 2 upto 3 (0 again).
774
775\startbuffer[a]
776fill fulltriangle xyscaled (TextWidth,1cm)
777    withshademethod "linear"
778    withshadevector (0.25,0.75)
779    withshadecolors (darkred,darkgreen)
780;
781\stopbuffer
782
783\startbuffer[b]
784draw fulltriangle xyscaled (TextWidth,1cm)
785    shownshadevector (0.25,0.75)
786    withpen pencircle scaled 2
787    withcolor .5white ;
788\stopbuffer
789
790\typebuffer
791
792\startlinecorrection[blank]
793    \processMPbuffer[a,b]
794\stoplinecorrection
795
796The shadevector relates to (the x coordinates of) points on the path. A variant is
797to use the boundingbox:
798
799\startbuffer[a]
800for i=1 upto 3 :
801    fill fulltriangle xyscaled (TextWidth,1cm)
802        shifted (0,-i*15mm)
803        withshademethod "linear"
804        withshadedirection (1,1-i/4)
805        withshadecolors (darkgreen,darkblue)
806    ;
807endfor ;
808\stopbuffer
809
810\startbuffer[b]
811for i=1 upto 3 :
812    draw fulltriangle xyscaled (TextWidth,1cm)
813        shifted (0,-i*15mm)
814        shownshadevector (1,1-i/4)
815        withpen pencircle scaled 2
816        withcolor .5white ;
817endfor ;
818\stopbuffer
819
820\typebuffer[a]
821
822\startlinecorrection[blank]
823    \processMPbuffer[a,b]
824\stoplinecorrection
825
826So, where a vector is defined as going from {\em point xpart a of pth} to
827{\em point ypart a of pth}, a direction goes from {\em point xpart a of
828boundingbox pth} to {\em point ypart a of boundingbox pth}.
829
830To make life convenient we provide a few constants that indicate directions:
831
832\starttyping
833pair shadedup    ; shadedup    := (0.5,2.5) ;
834pair shadeddown  ; shadeddown  := (2.5,0.5) ;
835pair shadedleft  ; shadedleft  := (1.5,3.5) ;
836pair shadedright ; shadedright := (3.5,1.5) ;
837\stoptyping
838
839\startbuffer[a]
840for d = shadedup, shadeddown, shadedleft, shadedright :
841    fill fullsquare xyscaled (TextWidth,1cm)
842        withshademethod "linear"
843        withshadedirection d
844        withshadecolors (darkgreen,darkblue)
845    ;
846    currentpicture := currentpicture shifted (0,15mm) ;
847endfor ;
848\stopbuffer
849
850\startbuffer[b]
851currentpicture := currentpicture shifted (0,-60mm) ;
852for d = shadedup, shadeddown, shadedleft, shadedright :
853    draw fullsquare xyscaled (TextWidth,1cm)
854        shownshadedirection d
855        withpen pencircle scaled 2
856        withcolor .5white ;
857    currentpicture := currentpicture shifted (0,15mm) ;
858endfor ;
859\stopbuffer
860
861\typebuffer[a]
862
863\startlinecorrection[blank]
864    \processMPbuffer[a,b]
865\stoplinecorrection
866
867In case of a circular shade another method comes in handy:
868
869\startbuffer[a]
870fill fullcircle xyscaled (TextWidth,4cm)
871    withshademethod "circular"
872    withshadecenter (.7,.9)
873    withshadecolors (darkblue,darkyellow)
874;
875\stopbuffer
876
877\startbuffer[b]
878draw fullcircle xyscaled (TextWidth,4cm)
879    shownshadecenter (.7,.9)
880    withpen pencircle scaled 2
881    withcolor .5white ;
882\stopbuffer
883
884\typebuffer
885
886Here the values relate to the center of path i.e.\ they shift the center by the
887given fraction of the width and height of the boundingbox devided by 2.
888
889\startlinecorrection[blank]
890    \processMPbuffer[a,b]
891\stoplinecorrection
892
893You can set a center directly i.e.\ unrelated to the center of the path as
894follows:
895
896\startbuffer[a]
897fill fullcircle xyscaled (TextWidth,4cm)
898    withshademethod "circular"
899    withshadeorigin (-30mm,-15mm)
900    withshadecolors (darkblue,darkyellow)
901;
902\stopbuffer
903
904\startbuffer[b]
905draw fullcircle xyscaled (TextWidth,4cm)
906    shownshadeorigin (-30mm,-15mm)
907    withpen pencircle scaled 2
908    withcolor .5white ;
909\stopbuffer
910
911\typebuffer
912
913\startlinecorrection[blank]
914    \processMPbuffer[a,b]
915\stoplinecorrection
916
917In a similar way you can set an explicit radius:
918
919\startbuffer[a]
920fill fullcircle xyscaled (TextWidth,1cm)
921    withshademethod "circular"
922    withshaderadius (10mm,50mm)
923    withshadecolors (darkblue,darkyellow)
924;
925currentpicture := currentpicture shifted (0,15mm) ;
926fill fullcircle xyscaled (TextWidth,1cm)
927    withshademethod "circular"
928    withshaderadius (50mm,10mm)
929    withshadecolors (darkgreen,darkred)
930;
931currentpicture := currentpicture shifted (0,15mm) ;
932fill fullcircle xyscaled (TextWidth,1cm)
933    withshademethod "circular"
934    withshaderadius (TextWidth/3,0mm)
935    withshadecolors (darkmagenta,darkcyan)
936;
937\stopbuffer
938
939\typebuffer
940
941\startlinecorrection[blank]
942    \processMPbuffer[a]
943\stoplinecorrection
944
945A more fancy feature is combined shades. This works as follows:
946
947\startbuffer[a]
948fill fullsquare xyscaled (TextWidth,1cm)
949    withshademethod "linear"
950    withshadevector (0,1)
951    withshadestep (
952        withshadefraction .3
953        withshadecolors (red,green)
954    )
955    withshadestep (
956        withshadefraction .5
957        withshadecolors (green,blue)
958    )
959    withshadestep (
960        withshadefraction .7
961        withshadecolors (blue,red)
962    )
963    withshadestep (
964        withshadefraction 1
965        withshadecolors (red,yellow)
966    )
967;
968\stopbuffer
969
970\typebuffer[a]
971
972By stepwise defining the colored bands you get:
973
974\startlinecorrection[blank]
975    \processMPbuffer[a]
976\stoplinecorrection
977
978Shades work well with colors and transparencies. This involves quite some
979resource managament in the backend but it's hidden by the interface.
980
981\startbuffer[a]
982fill fullsquare scaled 5cm
983    withshademethod "linear"
984    withshadefactor 1
985    withshadedomain (0,1)
986    withshadevector (0.5,2.75)
987    withshadecolors (red,green) ;
988
989fill fullcircle scaled 5cm
990    withshademethod "circular"
991    withshadefactor 1
992    withshadedomain (0,1)
993    withshadecenter (.25,.25)
994    withshadecolors (green,blue) ;
995
996fill fulltriangle scaled 5cm
997    withshademethod "circular"
998    withshadefactor 1
999    withshadedomain (0,1)
1000    withshadecenter (.25,.25)
1001    withshadecolors (blue,yellow) ;
1002\stopbuffer
1003
1004\startbuffer[b]
1005fill fullsquare scaled 5cm
1006    withcolor white ;
1007fill fullsquare scaled 5cm
1008    withshademethod "linear"
1009    withshadevector (0.5,2.75)
1010    withshadecolors (red,green)
1011    withtransparency (1,.5) ;
1012
1013fill fullcircle scaled 5cm
1014    withcolor white ;
1015fill fullcircle scaled 5cm
1016    withshademethod "circular"
1017    withshadecenter (.25,.25)
1018    withshadecolors (green,blue)
1019    withtransparency (1,.5) ;
1020
1021fill fulltriangle scaled 5cm
1022    withcolor white ;
1023fill fulltriangle scaled 5cm
1024    withshademethod "circular"
1025    withshadecenter (.25,.25)
1026    withcolor blue shadedinto yellow
1027    withtransparency (1,.5) ;
1028\stopbuffer
1029
1030\startbuffer[c]
1031fill fullsquare scaled 5cm
1032    withshademethod "linear"
1033    withshadevector (0.5,2.75)
1034    withshadecolors (red,green)
1035    withtransparency (1,.5) ;
1036
1037fill fullcircle scaled 5cm
1038    withshademethod "circular"
1039    withshadecenter (.25,.25)
1040    withcolor green shadedinto blue
1041    withtransparency (1,.5) ;
1042
1043fill fulltriangle scaled 5cm
1044    withshademethod "circular"
1045    withshadecenter (.25,.25)
1046    withcolor blue shadedinto yellow
1047    withtransparency (1,.5) ;
1048\stopbuffer
1049
1050Here are some shades without transparency:
1051
1052\typebuffer[a]
1053
1054When the background is white, transparency is just a way to achieve soft colors.
1055We leave out the defaults.
1056
1057\typebuffer[b]
1058
1059Real transparency will show op darker due to the accumulated colors. This time we
1060demonstrate an alternative color specification.
1061
1062\typebuffer[c]
1063
1064\startplacefigure[reference=shades:transparency,title={Transparency applied to shades.}]
1065    \startcombination[3*1]
1066        {\processMPbuffer[a]} {no transparency}
1067        {\processMPbuffer[b]} {transparency on white}
1068        {\processMPbuffer[c]} {real transparency}
1069    \stopcombination
1070\stopplacefigure
1071
1072Within reasonable bounds you can move around and adapt shaded paths but you need
1073to keep in mind that due to the fact that we are dealing with relatively complex
1074data structures there are some limits. For instance it is possible to define a
1075shade as (kind of) variable and reuse it. it's also possible then to overload
1076some properties.
1077
1078% % still supported but not advertized:
1079%
1080% numeric n ; n = define_linear_shade (center fullcircle,center fullsquare,red,green) ;
1081%
1082% fill fullcircle randomized 1cm xyscaled(10cm,8cm) withshade n ;
1083
1084\startbuffer
1085defineshade myshade
1086    withshademethod "circular"
1087    withshadefactor 1
1088    withshadedomain (0,1)
1089    withshadecolors (black,white)
1090    withtransparency (1,.5)
1091;
1092
1093for i=1 upto 5 :
1094    fill fullcircle randomized 1 xyscaled(5cm,3cm)
1095        shaded myshade ;
1096endfor ;
1097
1098draw image (
1099    for i=1 upto 5 :
1100        fill fullcircle randomized 1
1101            shaded myshade
1102            withshadecolors (yellow,blue) ;
1103    endfor ;
1104) xyscaled(5cm,3cm) shifted (5cm,0) ;
1105\stopbuffer
1106
1107\typebuffer
1108
1109We get two groups of five overlayed shades here, one with a different color. The
1110shade properties can only be applied to paths (see \in {figure}
1111[fig:shades:defined]).
1112
1113\startplacefigure[reference=fig:shades:defined,title={Reusing defined shaded.}]
1114    \processMPbuffer
1115\stopplacefigure
1116
1117In older versions one could not reposition or scale a shaded path without losing
1118or crippling the shade properties. Nowadays this is no longer a limitation, as we
1119demonstrate in the following examples. You can disable this feature if wanted.
1120The results are shown in \in {figure} [fig:shades:transform]. Without the
1121transform the vectors and such are kept which might be useful in special cases.
1122
1123\startbuffer[a]
1124fill fullsquare xyscaled (15mm, 15mm)
1125    withshademethod "linear"
1126    withshadedirection shadedright
1127    withshadecolors (red,(1,1,1)) ;
1128
1129fill fullsquare xyscaled (10mm, 10mm)
1130    withshademethod "circular"
1131    withshadecolors (green,blue) ;
1132
1133currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
1134currentpicture := currentpicture shifted (5mm,5mm) ;
1135\stopbuffer
1136
1137\typebuffer[a]
1138
1139The transform can be ignored with:
1140
1141\startbuffer[b]
1142fill fullsquare xyscaled (15mm, 15mm)
1143    withshademethod "linear"
1144    withshadetransform "no"
1145    withshadedirection shadedright
1146    withshadecolors (red,(1,1,1)) ;
1147
1148fill fullsquare xyscaled (10mm, 10mm)
1149    withshademethod "circular"
1150    withshadetransform "no"
1151    withshadecolors (green,blue) ;
1152
1153currentpicture := currentpicture xysized (.4TextWidth,30mm) ;
1154currentpicture := currentpicture shifted (5mm,5mm) ;
1155\stopbuffer
1156
1157\typebuffer[b]
1158
1159\startplacefigure[reference=fig:shades:transform,title={Shifting and scaling shades.}]
1160    \startcombination
1161        {\processMPbuffer[a]} {with transform}
1162        {\processMPbuffer[b]} {without transform}
1163    \stopcombination
1164\stopplacefigure
1165
1166\stopsubsection
1167
1168\stopsection
1169
1170\startsection[title={Clipping}]
1171
1172\index{clipping}
1173
1174In this section we will use the graphic representation (although simplified) of a
1175Dutch cow to demonstrate clipping.
1176
1177\startbuffer
1178\placefigure
1179  {A cow.}
1180  {\externalfigure[cow-fun.mps][width=4cm]}
1181\stopbuffer
1182
1183\getbuffer
1184
1185Since this cow is defined as a \METAPOST\ graphic, we use the suffix \type {mps}
1186instead of \type {eps} or a number, although \CONTEXT\ will recognize each as
1187being \METAPOST\ output. The placement of the cow is defined as:
1188
1189\typebuffer
1190
1191Clipping is combined with a matrix, as in \in {figure} [fig:clipped cow 1]. The
1192content to be clipped is divided in \type {nx} by \type {ny} rectangles. For
1193instance, \type {nx=5} and \type {ny=8} will produce a 40~cell grid with
11945~columns of 8~rows.
1195
1196\startbuffer
1197\startbuffer
1198\setupclipping[nx=3,ny=2]
1199\startcombination
1200  {\clip[x=1,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {1,1}
1201  {\clip[x=3,y=1]{\externalfigure[cow-fun.mps][width=4cm]}} {3,1}
1202\stopcombination
1203\stopbuffer
1204
1205\placefigure
1206  [here][fig:clipped cow 1]
1207  {A clipped cow.}{\getbuffer}
1208\stopbuffer
1209
1210\getbuffer
1211
1212Here we have divided the cow in six cells, so that we can clip its head and tail.
1213This kind of clipping enables you to zoom in or focus on a specific part of a
1214graphic.
1215
1216\typebuffer
1217
1218Alternatively, we can specify a \type {width}, \type {height}, \type {hoffset}
1219and \type {voffset}, as demonstrated in \in {figure} [fig:clipped cow 2].
1220
1221\startbuffer
1222\placefigure
1223  [here][fig:clipped cow 2]
1224  {Another clipped cow.}
1225  {\clip
1226     [width=2cm,height=2cm,hoffset=0cm,voffset=0cm]
1227     {\externalfigure[cow-fun.mps][width=4cm]}}
1228\stopbuffer
1229
1230\getbuffer
1231
1232\typebuffer
1233
1234Because \METAPOST\ supports clipping, it will be no surprise that both techniques
1235can be combined. In the next example we will zoom in on the head of the cow. We
1236also use this opportunity to demonstrate how you can package a clip in a figure
1237definition.
1238
1239\startbuffer
1240\startMPclip{head clip}
1241 w := OverlayWidth ; h := OverlayHeight ;
1242 clip currentpicture to
1243  ((0,h)--(w,h){down}..{left}(0,0)--cycle) ;
1244\stopMPclip
1245
1246\placefigure
1247  [here][fig:circular clipped cowhead]
1248  {A quarter circle applied to a cows head.}
1249  {\ruledhbox
1250     {\clip
1251        [nx=2,ny=2,x=1,y=1,mp=head clip]
1252        {\externalfigure[cow-fun.mps][width=4cm]}}}
1253\stopbuffer
1254
1255\typebuffer
1256
1257A more advanced clip is demonstrated in \in {figure} [fig:circular clipped
1258cowhead]. We added \type {\ruledhbox} to demonstrate the dimensions of the
1259resulting graphic. Putting something in such a ruled box is often a quick way to
1260test spacing.
1261
1262\getbuffer
1263
1264Although a clip path definition can contain any \METAPOST\ command, even
1265graphics, it must contain at least one clipping path. The first one encountered
1266in the resulting graphic is used. In the example we used a path that is built out
1267of three subpaths.
1268
1269\starttyping
1270(0,h)--(w,h){down}..{left}(0,0)--cycle
1271\stoptyping
1272
1273We start in the top left corner and draw a straight line. Next we draw a curve to
1274the origin. Directives like \type {down} and \type {right} force the curve in a
1275certain direction. With \type {cycle} we close the path. Because we use this path
1276as a clipping path, we use \type {clip} instead of \type {draw} or \type {fill}.
1277
1278\startbuffer
1279w := 4cm ; h := 2cm ;
1280draw (0,h)--(w,h){down}..{left}(0,0)--cycle
1281  withpen pencircle scaled 1mm withcolor .625red ;
1282\stopbuffer
1283
1284\startlinecorrection[blank]
1285\processMPbuffer
1286\stoplinecorrection
1287
1288Clipping as such is not limited to graphics. Take for instance the text buffer:
1289
1290\startbuffer
1291\startbuffer[sample]
1292\framed
1293  [align=middle,width=4cm,background=screen,frame=off]
1294  {A \METAPOST\ clip is not the same as a video clip,
1295   although we can use \METAPOST\ to produce a video clip.}
1296\stopbuffer
1297\stopbuffer
1298
1299\typebuffer
1300
1301\getbuffer
1302
1303We can call up such a buffer as if it were an external figure. \in {Figure}
1304[fig:clipped text 1] shows the result. This time we use a different clip path:
1305
1306\startbuffer[a]
1307\startMPclip{text clip}
1308  clip currentpicture to fullcircle shifted (.5,.5)
1309    xscaled OverlayWidth yscaled OverlayHeight ;
1310\stopMPclip
1311\stopbuffer
1312
1313\typebuffer[a]
1314
1315To load a buffer, we have to specify its name and type, as in:
1316
1317\startbuffer[b]
1318\placefigure
1319  [here][fig:clipped text 1]
1320  {A clipped buffer (text).}
1321  {\clip
1322     [nx=1,ny=1,mp=text clip]
1323     {\externalfigure[sample][type=buffer,width=4cm]}}
1324\stopbuffer
1325
1326\typebuffer[b]
1327
1328\getbuffer[a,b]
1329
1330The next few lines demonstrate that we can combine techniques like backgrounds
1331and clipping.
1332
1333\startbuffer
1334\startuseMPgraphic{clip outline}
1335 draw fullcircle
1336   xscaled \overlaywidth yscaled \overlayheight
1337   withpen pencircle scaled 4mm
1338   withcolor .625red ;
1339\stopuseMPgraphic
1340
1341\defineoverlay[clip outline][\useMPgraphic{clip outline}]
1342
1343\placefigure
1344  [here][fig:clipped text 2]
1345  {A clipped buffer (text).}
1346  {\framed
1347     [background=clip outline,offset=overlay,frame=off]
1348     {\clip
1349        [nx=1,ny=1,mp=text clip]
1350        {\externalfigure[sample][type=buffer,width=4cm]}}}
1351\stopbuffer
1352
1353\typebuffer
1354
1355We could have avoided the \type {\framed} here, by using the \typ{clip outline}
1356overlay as a background of the sample. In that case, the resulting linewidth
1357would have been 2.5~mm instead of 5~mm, since the clipping path goes through the
1358center of the line.
1359
1360\getbuffer
1361
1362In most cases, the clip path will be a rather simple path and defining such a
1363path every time you need it, can be annoying. \in {Figure} [fig:clipping paths]
1364shows a collection of predefined clipping paths. These are available after
1365loading the \METAPOST\ clipping library.
1366
1367\starttyping
1368\useMPlibrary[clp]
1369\stoptyping
1370
1371We already saw how the circular clipping path was defined. The diamond is defined
1372in a similar way, using the predefined path \type {diamond}:
1373
1374\starttyping
1375\startMPclip{diamond}
1376  clip currentpicture to unitdiamond
1377    xscaled OverlayWidth yscaled OverlayHeight ;
1378\stopMPclip
1379\stoptyping
1380
1381The definition of the negated ellipse (\type {negellipse}) uses the primary \type
1382{peepholed}. This primary is defined in one of the \METAPOST\ modules that come
1383with \CONTEXT.
1384
1385\starttyping
1386\startMPclip{negellipse}
1387  clip currentpicture to (unitcircle peepholed unitsquare)
1388    xscaled OverlayWidth yscaled OverlayHeight ;
1389\stopMPclip
1390\stoptyping
1391
1392The definition of \type {peepholed} is rather dirty and using \type {peepholed}
1393is restricted to well defined situations (like here). It's called a primary
1394because it acts as an operator at the same level as \type {*} and \type {scaled}.
1395
1396\startbuffer
1397\setupclipping  [nx=1,ny=1,x=1,y=1]
1398\setupblackrules[width=2cm,height=1cm]
1399\startcombination[6*3]
1400  {\clip[mp=urellipse] {\darkred\blackrule}} {urellipse}
1401  {\clip[mp=ulellipse] {\darkred\blackrule}} {ulellipse}
1402  {\clip[mp=llellipse] {\darkred\blackrule}} {llellipse}
1403  {\clip[mp=lrellipse] {\darkred\blackrule}} {lrellipse}
1404  {\clip[mp=ellipse]   {\darkred\blackrule}} {ellipse}
1405  {\clip[mp=negellipse]{\darkred\blackrule}} {negellipse}
1406  {\clip[mp=tellipse]  {\darkred\blackrule}} {tellipse}
1407  {\clip[mp=bellipse]  {\darkred\blackrule}} {bellipse}
1408  {\clip[mp=lellipse]  {\darkred\blackrule}} {lellipse}
1409  {\clip[mp=rellipse]  {\darkred\blackrule}} {rellipse}
1410  {}                                         {}
1411  {}                                         {}
1412  {\clip[mp=urtriangle]{\darkred\blackrule}} {urtriangle}
1413  {\clip[mp=ultriangle]{\darkred\blackrule}} {ultriangle}
1414  {\clip[mp=lltriangle]{\darkred\blackrule}} {lltriangle}
1415  {\clip[mp=lrtriangle]{\darkred\blackrule}} {lrtriangle}
1416  {\clip[mp=diamond]   {\darkred\blackrule}} {diamond}
1417  {\clip[mp=negdiamond]{\darkred\blackrule}} {negdiamond}
1418\stopcombination
1419\stopbuffer
1420
1421\placefigure
1422  [here][fig:clipping paths]
1423  {A collection of predefined clipping paths.}
1424  {\getbuffer}
1425
1426\stopsection
1427
1428\startsection[title={Including graphics}]
1429
1430\index{graphics+including}
1431
1432This document demonstrates that it is no big problem to include \METAPOST\
1433graphics in a \TEX\ document. But how about including graphics in a \METAPOST\
1434picture? In this section we will explore a couple of macros that provide you this
1435feature.
1436
1437Before we go into details, we introduce a very impressive program called
1438\PSTOEDIT\ by Wolfgang Glunz. This program runs on top of \GHOSTSCRIPT\ and is
1439able to convert \POSTSCRIPT\ code into other formats, among them \METAPOST\ (that
1440part of the \PSTOEDIT\ code is due to Scott Pakin). Some of the graphics that we
1441use in this section are produced that way. For us, the next call works well, but
1442the exact call may differ per version or platform.
1443
1444\starttyping
1445pstoedit -ssp -dt -f mpost yourfile.ps newfile.mp
1446\stoptyping
1447
1448We have converted the Dutch cow that shows up in many \CONTEXT\ documents into
1449\METAPOST\ using this program. The resulting \METAPOST\ file encapsulates the cow
1450in \METAPOST\ figure~1: \type {beginfig(1)}. Of course you can process this file
1451like any other, but more interesting is to use this code in an indirect way.
1452
1453\startbuffer
1454loadfigure "mycow.mp" number 1 scaled .5 ;
1455\stopbuffer
1456
1457\typebuffer
1458
1459This call will load figure~1 from the specified \METAPOST\ file, in such a way
1460that there is no interference with the current (encapsulating) figure.
1461
1462\startlinecorrection[blank]
1463\processMPbuffer
1464\stoplinecorrection
1465
1466Because this graphic is the result from a conversion, there are only paths. If
1467you want to import a more complex graphic, you need to make sure that the
1468variables used in there do not conflict with the one currently in use.
1469
1470\METAPOST\ is good in drawing vector graphics, but lacks natural support for
1471bitmaps, but the next macro offers a way out. This macro permits you to include
1472graphics in \PNG, \PDF, and \JPG\ format, or more precise: those formats
1473supported by \PDFTEX.\pagereference[hacker]
1474
1475\startbuffer
1476draw externalfigure "hacker.png" xsized 5cm shifted (-6cm,0) ;
1477draw externalfigure "hacker.png" xsized 5cm slanted .5 ;
1478\stopbuffer
1479
1480\typebuffer
1481
1482You can apply the usual transformations, but only those applied directly will be
1483taken into account. This means that you (currently) cannot store external figures
1484in picture variables in order to transform them afterwards.
1485
1486\startlinecorrection[blank]
1487\processMPbuffer
1488\stoplinecorrection
1489
1490Although you are limited in what you can do with such graphics, you can include
1491them multiple times with a minimum of overhead. Graphics are stored in objects
1492and embedded only once.
1493
1494\startbuffer
1495numeric s ; pair d, c ;
1496for i := 1 upto 5 :
1497  s := 3cm randomized 1cm ;           % size of picture
1498  c := .5(s,s) ;                      % center of picture
1499  d := (2cm*i,.5cm) randomized .5cm ; % displacement
1500  draw externalfigure "hacker.png"
1501    ysized s rotatedaround (c,0 randomized 30) shifted d ;
1502endfor ;
1503\stopbuffer
1504
1505\typebuffer
1506
1507Because we cannot store the graphic in a picture and scale afterwards, we
1508calculate the scale in advance, so that we can rotate around the center.
1509
1510\startlinecorrection[blank]
1511\processMPbuffer
1512\stoplinecorrection
1513
1514As long as you don't mess around with a stored external figure, you're safe. The
1515following example demonstrates how we can combine two special driven features:
1516figure inclusion and shading.
1517
1518\startbuffer
1519picture p ;
1520p := externalfigure "hacker.png" xsized 150pt ;
1521clip p to unitcircle scaled 150pt ;
1522circular_shade(boundingbox p enlarged 10pt, 0, .2red, .9red) ;
1523addto currentpicture also p ;
1524\stopbuffer
1525
1526\typebuffer
1527
1528\startlinecorrection[blank]
1529\processMPbuffer
1530\stoplinecorrection
1531
1532We end this section with a few more words to \METAPOST\ inclusion. It may seem
1533that in order to use the features discussed here, you need to use \CONTEXT\ as
1534typesetting engine. This is not true. First of all, you can use the small \TEX\
1535package \MPTOPDF\ (described in another manual) or you can make small \CONTEXT\
1536files with one page graphics. The advantage of the last method is that you can
1537manipulate graphics a bit.
1538
1539\starttyping
1540\setupcolors[cmyk=yes,rgb=no,state=start]
1541
1542\starttext
1543
1544\startMPpage[offset=6pt]
1545  loadfigure "niceone.mp" number 10 ;
1546\stopMPpage
1547
1548\stoptext
1549\stoptyping
1550
1551The resulting \PDF\ file can be included as any other graphic
1552and has the advantage that it is self contained.
1553
1554\stopsection
1555
1556\startsection[reference=sec:conversion,title={Changing colors}]
1557
1558\index{color+manipulating}
1559
1560One of the advantages of \METAPOST\ graphics is that it is rather easy to force
1561consistency in colors and line widths. You seldom can influence third party
1562graphics that way, but we can use some \METAFUN\ trickery to get around this
1563limitation.
1564
1565\startbuffer
1566loadfigure "mycow.mp" number 1 scaled .35 ;
1567refill currentpicture withcolor .625red ;
1568\stopbuffer
1569
1570Say that we want a red cow instead of a black one. The following code does the
1571trick:
1572
1573\typebuffer
1574
1575\startlinecorrection[blank]
1576\processMPbuffer
1577\stoplinecorrection
1578
1579In a similar way we can influence the width and colors of the lines.
1580
1581\startbuffer
1582loadfigure "mycow.mp" number 1 scaled .35 ;
1583refill currentpicture withcolor .625red ;
1584redraw currentpicture withpen pencircle scaled 2pt withcolor .625yellow ;
1585\stopbuffer
1586
1587\typebuffer
1588
1589\startlinecorrection[blank]
1590\processMPbuffer
1591\stoplinecorrection
1592
1593Of course we can also use the more fancy features of \METAFUN, like transparency
1594and shading.
1595
1596\startbuffer
1597loadfigure "mycow.mp" number 1 scaled .35 ;
1598numeric sh ; sh := define_linear_shade
1599  (llcorner currentpicture,urcorner currentpicture,.625red, .625yellow) ;
1600refill currentpicture withshade sh ;
1601redraw currentpicture withpen pencircle scaled 2pt withcolor .5white;
1602\stopbuffer
1603
1604\typebuffer
1605
1606\startlinecorrection[blank]
1607\processMPbuffer
1608\stoplinecorrection
1609
1610Before we show a next trick, we draw a few circles.
1611
1612\startbuffer[a]
1613fill fullcircle scaled 2cm                 withcolor yellow ;
1614fill fullcircle scaled 2cm shifted (3cm,0) withcolor red ;
1615\stopbuffer
1616
1617\typebuffer[a]
1618
1619\startlinecorrection[blank]
1620\processMPbuffer[a]
1621\stoplinecorrection
1622
1623The yellow and red color do not match the main document colors, but this is no
1624problem: we can remap them, without spoiling the original definition.
1625
1626\startbuffer[b]
1627remapcolor(yellow,.625yellow) ;
1628remapcolor(red   ,.625red) ;
1629recolor currentpicture ;
1630resetcolormap ;
1631\stopbuffer
1632
1633\typebuffer[a,b]
1634
1635\startlinecorrection[blank]
1636\processMPbuffer[a,b]
1637\stoplinecorrection
1638
1639We can combine the inclusion technique with remapping colors. This time using an
1640artist impression of one of Hasselts Canals (gracht in Dutch)\pagereference
1641[canal].
1642
1643\startbuffer[a]
1644loadfigure "gracht.mp" number 1 scaled .5 ;
1645\stopbuffer
1646
1647\typebuffer[a]
1648
1649\startlinecorrection[blank]
1650\processMPbuffer[a]
1651\stoplinecorrection
1652
1653If you think that the sky is too bright in this picture, and given that you also
1654know which color is used, you can fool the reader by remapping a few colors.
1655
1656\startbuffer[b]
1657color skycolor   ; skycolor   := (0.8,0.90,1.0) ;
1658color watercolor ; watercolor := (0.9,0.95,1.0) ;
1659remapcolor(skycolor  ,.8skycolor  ) ;
1660remapcolor(watercolor,.8watercolor) ;
1661recolor currentpicture ;
1662resetcolormap ;
1663\stopbuffer
1664
1665\typebuffer[a,b]
1666
1667\startlinecorrection[blank]
1668\processMPbuffer[a,b]
1669\stoplinecorrection
1670
1671Including another \METAPOST\ graphic, refilling, redrawing, and recoloring are
1672all relatively simple features that use no real tricks. Opposite to the next
1673feature, which is implemented using the \METAPOST\ special driver that comes with
1674\CONTEXT.
1675
1676\METAPOST\ is not really meant for manipulating graphics, but the previous
1677examples demonstrated that we have some control over individual colors. In the
1678next series of examples we will treat the picture as a whole. First we invert the
1679colors using \type {inverted}.
1680
1681\startbuffer
1682loadfigure "gracht.mp" number 1 scaled .5 ;
1683addto currentpicture also
1684  inverted currentpicture
1685  shifted (bbwidth(currentpicture)+.5cm,0) ;
1686\stopbuffer
1687
1688\typebuffer
1689
1690\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1691
1692This is a special case of \type {uncolored}. In the next example we explicitly
1693specify the color.
1694
1695\startbuffer
1696loadfigure "gracht.mp" number 1 scaled .5 ;
1697addto currentpicture also
1698  (currentpicture uncolored green)
1699  shifted (bbwidth(currentpicture)+.5cm,0) ;
1700\stopbuffer
1701
1702\typebuffer
1703
1704\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1705
1706You can also multiply each color using \type {softened}. In the next sample, the
1707colors have 80\% of their value.
1708
1709\startbuffer
1710loadfigure "gracht.mp" number 1 scaled .5 ;
1711addto currentpicture also
1712  (currentpicture softened .8)
1713  shifted (bbwidth(currentpicture)+.5cm,0) ;
1714\stopbuffer
1715
1716\typebuffer
1717
1718\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1719
1720You can also use this operator to harden colors, simply by
1721providing a value larger than~1. Keep in mind that colors
1722are clipped at~1 anyway.
1723
1724\startbuffer
1725loadfigure "gracht.mp" number 1 scaled .5 ;
1726addto currentpicture also
1727  (currentpicture softened 1.2)
1728  shifted (bbwidth(currentpicture)+.5cm,0) ;
1729\stopbuffer
1730
1731\typebuffer
1732
1733\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1734
1735By providing a triplet, you can treat each color component
1736independently.
1737
1738\startbuffer
1739loadfigure "gracht.mp" number 1 scaled .5 ;
1740addto currentpicture also
1741  (currentpicture softened (.7,.8,.9))
1742  shifted (bbwidth(currentpicture)+.5cm,0) ;
1743\stopbuffer
1744
1745\typebuffer
1746
1747\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1748
1749After these examples your are probably sick of seeing this picture in color, so
1750let's turn the colors into a weigthed grayscales (in a way similar to the way
1751black and white television treated color).
1752
1753\startbuffer
1754loadfigure "gracht.mp" number 1 scaled .5 ;
1755addto currentpicture also
1756  grayed currentpicture
1757  shifted (bbwidth(currentpicture)+.5cm,0) ;
1758\stopbuffer
1759
1760\typebuffer
1761
1762\startlinecorrection[blank] \processMPbuffer \stoplinecorrection
1763
1764\stopsection
1765
1766% \startsection[title={Outline fonts}]
1767%
1768% \index{text+outlines}
1769% \index{outlines}
1770%
1771% Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
1772% can simulate this in a reasonable way. We will not discuss all details here,
1773% because most details are covered in the \MAKEMPY\ manual.
1774%
1775% The macro responsible for outline fonts is \type {graphictext}. The first
1776% argument should be a string. This string is processed by \TEX. Additionally you
1777% can provide transformation directives and color specifications. The next example
1778% demonstrates this.
1779%
1780% \startbuffer
1781% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
1782%   withdrawcolor blue
1783%   withfillcolor .5white
1784%   withpen pencircle scaled 5pt
1785% \stopbuffer
1786%
1787% \typebuffer
1788%
1789% Once the text is typeset by \TEX, it is converted to \POSTSCRIPT\ and converted
1790% into \METAPOST\ by the \PSTOEDIT\ program. The resulting graphic is imported,
1791% analyzed, and processed conforming the specifications of \type {graphictext}.
1792%
1793% \startlinecorrection[blank]
1794% \processMPbuffer
1795% \stoplinecorrection
1796%
1797% By default the shapes are filled after they are drawn. This has the advantage
1798% that in characters built out of pieces, disturbing lines fragments are covered.
1799% The drawback is that you get only half the linewidth. You can reverse the drawing
1800% order by adding the \type {reversefill} directive. The previous graphic then
1801% comes out as:
1802%
1803% \startbuffer
1804% graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
1805%   reversefill
1806%   withdrawcolor blue
1807%   withfillcolor .5white
1808%   withpen pencircle scaled 5pt
1809% \stopbuffer
1810%
1811% \typebuffer
1812%
1813% The \type {reversefill} directive can be countered by \type {outlinefill}.
1814%
1815% \startlinecorrection[blank]
1816% \processMPbuffer
1817% \stoplinecorrection
1818%
1819% The next example is taken from the \MAKEMPY\ manual. It demonstrates that you can
1820% combine \TEX's powerful line breaking with \METAPOST's graphic capabilities.
1821%
1822% \startbuffer
1823% \startuseMPgraphic{quotation}
1824%   picture one ; one := image ( graphictext
1825%     \MPstring{text}
1826%     scaled 1.5
1827%     withdrawcolor .625blue
1828%     withfillcolor .625white
1829%     withpen pencircle scaled 1pt ; ) ;
1830%   picture two ; two := image ( graphictext
1831%     \MPstring{author}
1832%     scaled 2
1833%     withdrawcolor .625red
1834%     withfillcolor .625white
1835%     withpen pencircle scaled 2pt ; ) ;
1836%   currentpicture := one ;
1837%   addto currentpicture also two
1838%     shifted lrcorner one
1839%     shifted - 1.125 lrcorner two
1840%     shifted (0, - 1.250 * ypart urcorner two)  ;
1841%   setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
1842% \stopuseMPgraphic
1843% \stopbuffer
1844%
1845% \typebuffer \getbuffer
1846%
1847% In this graphic, we have two text fragments, the first one is a text, the second
1848% one the name of the author. We combine the quotation and author into this graphic
1849% using the following definitions:
1850%
1851% \startbuffer
1852% \setMPtext{text}  {\vbox{\hsize 8.5cm \input zapf }}
1853% \setMPtext{author}{\hbox{\sl Hermann Zapf}}
1854% \stopbuffer
1855%
1856% \typebuffer \getbuffer
1857%
1858% These definitions assume that the file \type {zapf.tex} is present on the system
1859% (which is the case when you have installed \CONTEXT). The graphic can now be
1860% typeset using the following call:
1861%
1862% \startbuffer
1863% \placefigure
1864%   {A text does not need to be an outline in order to be
1865%    typeset in an outline font.}
1866%   {\useMPgraphic{quotation}}
1867% \stopbuffer
1868%
1869% \typebuffer \getbuffer
1870%
1871% The quality of the output depends on how the glyphs are constructed. For
1872% instance, in \TEX, math symbols are sometimes composed of glyph fragments and
1873% rules.
1874%
1875% \startbuffer
1876% graphictext
1877%   "$$\sqrt{1+x}$$"
1878%   scaled 8
1879%   withdrawcolor .625red
1880%   withpen pencircle scaled 1.5pt
1881% \stopbuffer
1882%
1883% \typebuffer
1884%
1885% \startlinecorrection[blank]
1886% \processMPbuffer
1887% \stoplinecorrection
1888%
1889% This is not really a problem because we can also fill the shapes. It is the
1890% reason why the fill is applied after the draw and in such case the effective line
1891% width is half the size specified.
1892%
1893% \startbuffer
1894% graphictext
1895%   "$$\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)$$"
1896%   scaled 4
1897%   dashed evenly
1898%   withdrawcolor .625red
1899%   withfillcolor .850white
1900%   withpen pencircle scaled 1.5pt
1901% \stopbuffer
1902%
1903% \typebuffer
1904%
1905% In this example we also use a dashed line. Instead of normal colors, we could
1906% have used shades or transparent colors.
1907%
1908% \startlinecorrection[blank]
1909% \processMPbuffer
1910% \stoplinecorrection
1911%
1912% Instead of supplying the text directly, you can use the indirect method. This
1913% permits you to process rather complex data without messing up your \METAPOST\
1914% code.
1915%
1916% \startbuffer
1917% \setMPtext {some math}%
1918%   {\usemodule[mathml]
1919%    \xmlprocessdata
1920%      {main}
1921%      {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
1922%         <apply> <log/>
1923%           <logbase> <cn> 2 </cn> </logbase>
1924%           <apply> <plus/>
1925%             <ci> x </ci>
1926%             <cn> 1 </cn>
1927%           </apply>
1928%         </apply>
1929%       </math>}
1930%      {}}
1931% \stopbuffer
1932%
1933% \typebuffer \getbuffer
1934%
1935% Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
1936% graphic.
1937%
1938% \startbuffer
1939% graphictext
1940%   \MPstring{some math}
1941%   scaled 4
1942%   withdrawcolor .625red
1943%   withfillcolor .625white
1944%   withpen pencircle scaled 1.5pt
1945% \stopbuffer
1946%
1947% \typebuffer
1948%
1949% \startlinecorrection[blank]
1950% \processMPbuffer
1951% \stoplinecorrection
1952%
1953% \stopsection
1954
1955\startsection[title={Outline fonts}]
1956
1957\index{text+outlines}
1958\index{outlines}
1959
1960Outline fonts don't belong to \METAPOST's repertoire of features. Nevertheless we
1961can simulate this in a reasonable way. The current version of \METAFUN\ uses the
1962outline subsystem of \CONTEXT\ \MKIV, but in earlier days we used an external
1963process: a \PDF\ file is generated that has the snippet, that gets converted to
1964\POSTSCRIPT, which in turn is converted to \METAPOST\ with \type {pstoedit} and
1965from that result we filter the outlines. This method uses \type {graphictext} and
1966is covered in the \MAKEMPY\ manual. Here we discuss the new method using \type
1967{outlinetext}.
1968
1969\startbuffer
1970draw outlinetext.b("\bf Funky")
1971  (withcolor .5white)
1972  (withcolor blue withpen pencircle scaled 1/5)
1973   scaled 4 zscaled (1,0.5) ;
1974\stopbuffer
1975
1976\typebuffer
1977
1978Once the text is typeset by \TEX, the result (a node list) is parsed and a
1979\METAPOST\ representation is created. The glyphs are converted to outlines that
1980are taken from the original font. For the moment this only works for \OPENTYPE\
1981fonts.
1982
1983\startlinecorrection[blank]
1984\processMPbuffer
1985\stoplinecorrection
1986
1987\startbuffer[1]
1988draw outlinetext ("\bf Funky")
1989   scaled 3 ;
1990\stopbuffer
1991
1992\startbuffer[2]
1993draw outlinetext.d ("\bf Funky")
1994   (withcolor red withpen pencircle scaled 1/5)
1995   scaled 3 ;
1996\stopbuffer
1997
1998\startbuffer[3]
1999draw outlinetext.f ("\bf Funky")
2000   (withcolor blue)
2001   scaled 3 ;
2002\stopbuffer
2003
2004\startbuffer[4]
2005draw outlinetext.b ("\bf Funky")
2006   (withcolor blue)
2007   (withcolor red withpen pencircle scaled 1/5)
2008   scaled 3 ;
2009\stopbuffer
2010
2011\startbuffer[5]
2012draw outlinetext.r ("\bf Funky")
2013   (withcolor blue)
2014   (withcolor red withpen pencircle scaled 1/5)
2015   scaled 3 ;
2016\stopbuffer
2017
2018\startplacetable[reference=tab:outlinetext,title={The four variants of \type {graphictext}.}]
2019    \bTABLE[offset=1ex]
2020        \dorecurse{5}{\bTR \bTD \processMPbuffer[#1] \eTD \bTD \typebuffer[#1] \eTD \eTR}
2021    \eTABLE
2022\stopplacetable
2023
2024The five variants of this command are shown in \in {table} [tab:outlinetext]: the
2025suffix determines the number of arguments and rendering. The \type {r} suffix
2026reverses the order: the fill comes over the draw. There is a \type {p} suffix
2027that returns just the picture.
2028
2029
2030The next example demonstrates that you can combine \TEX's powerful line breaking
2031algorithm with \METAPOST's graphic capabilities.
2032
2033\startbuffer
2034\startuseMPgraphic{quotation}
2035  picture one ; one := image ( draw outlinetext.b
2036    (\MPstring{text})
2037    (withcolor .625white)
2038    (withcolor .625blue withpen pencircle scaled 1/5)
2039    scaled 1.5
2040  ) ;
2041  picture two ; two := image ( draw outlinetext.b
2042    (\MPstring{author})
2043    (withcolor .625white)
2044    (withcolor .625red withpen pencircle scaled 1/5)
2045    scaled 2
2046  ) ;
2047  currentpicture := one ;
2048  addto currentpicture also two
2049    shifted lrcorner one
2050    shifted - 1.125 lrcorner two
2051    shifted (0, - 2 * ypart urcorner two)  ;
2052  setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
2053\stopuseMPgraphic
2054\stopbuffer
2055
2056\typebuffer \getbuffer
2057
2058In this graphic, we have two text fragments, the first one is a text, the second
2059one the name of the author. We combine the quotation and author into this graphic
2060using the following definitions:
2061
2062\startbuffer
2063\setMPtext
2064  {text}
2065  {\vbox
2066     {\setupalign[verytolerant,stretch]
2067      \hsize 8.5cm
2068      \input zapf }}
2069\setMPtext
2070  {author}
2071  {\hbox
2072     {\sl Hermann Zapf}}
2073\stopbuffer
2074
2075\typebuffer \getbuffer
2076
2077These definitions assume that the file \type {zapf.tex} is present on the system
2078(which is the case when you have installed \CONTEXT). The graphic can now be
2079typeset using the following call:
2080
2081\startbuffer
2082\placefigure
2083  [here]
2084  [fig:zapf]
2085  {A text does not need to be an outline in order to be
2086   typeset in an outline font.}
2087  {\useMPgraphic{quotation}}
2088\stopbuffer
2089
2090\typebuffer
2091
2092The result is \in {figure} [fig:zapf]. The quality of the output depends on how
2093the glyphs are constructed. For instance, in \TEX, math symbols are sometimes
2094composed of glyph fragments and rules.
2095
2096\start
2097    \def||{-}
2098    \getbuffer
2099\stop
2100
2101\startbuffer
2102draw outlinetext.d
2103  ("\mathematics{\sqrt{1+x}}")
2104  (withcolor .625red withpen pencircle scaled 1/5)
2105  scaled 8
2106\stopbuffer
2107
2108\typebuffer
2109
2110\startlinecorrection[blank]
2111\processMPbuffer
2112\stoplinecorrection
2113
2114This is not really a problem because we can also fill the shapes. It is the
2115reason why the fill is applied after the draw and in such case the effective line
2116width is half the size specified.
2117
2118\startbuffer
2119draw outlinetext.b
2120  ("\mathematics{\left(\frac{\sqrt{1+x}}{\sqrt{2+x^2}}\right)}")
2121  (withcolor .850white)
2122  (withcolor .625red
2123   dashed evenly scaled .1
2124   withpen pencircle scaled 1/5)
2125  scaled 8
2126\stopbuffer
2127
2128\typebuffer
2129
2130In this example (shown in \in {figure} [fig:dashedoutline]) we also use a dashed
2131line.
2132
2133\placefigure
2134  [here]
2135  [fig:dashedoutline]
2136  {A dashed outline text.}
2137  {\processMPbuffer}
2138
2139Instead of supplying the text directly, you can use the indirect method. This
2140permits you to process rather complex data without messing up your \METAPOST\
2141code.
2142
2143\startbuffer
2144\usemodule[mathml]
2145
2146\setMPtext {some math}%
2147  {\xmlprocessdata
2148     {main}
2149     {<math xmlns='http://www.w3c.org/mathml' version='2.0'>
2150        <apply> <log/>
2151          <logbase> <cn> 2 </cn> </logbase>
2152          <apply> <plus/>
2153            <ci> x </ci>
2154            <cn> 1 </cn>
2155          </apply>
2156        </apply>
2157      </math>}
2158     {}}
2159\stopbuffer
2160
2161\typebuffer \getbuffer
2162
2163Here we feed some \MATHML\ into \TEX, which in turn shows up as a \METAPOST\
2164graphic (\in {figure} [fig:mathml]).
2165
2166\startbuffer
2167draw outlinetext.b
2168  (\MPstring{some math})
2169  (withcolor .625white)
2170  (withcolor .625red withpen pencircle scaled 1/5)
2171  scaled 8
2172\stopbuffer
2173
2174\typebuffer
2175
2176\placefigure
2177  [here]
2178  [fig:mathml]
2179  {A \MATHML\ snippet turned into outlines.}
2180  {\processMPbuffer}
2181
2182Outlines are fun to look at. Here are a few ways to visualize a glyph:
2183
2184\startbuffer[1]
2185\startcombination[3*1]
2186    {\ruledhbox\bgroup
2187       \showshape[character=(,alternative=text]%
2188     \egroup} {}
2189    {\ruledhbox\bgroup
2190       \showshape[character=a,alternative=text]%
2191     \egroup} {}
2192    {\ruledhbox\bgroup
2193       \showshape[character=x,alternative=text]%
2194     \egroup} {}
2195\stopcombination
2196\stopbuffer
2197
2198\typebuffer[1]
2199
2200You can control the rendering a bit by setting \type {option}. Possible options
2201are: \type {box}, \type {width}, \type {min}, \type {max} and \type {comment}.
2202The \type {simple} option disables all. The simple results are shown in
2203\in{figure} [fig:showshape].
2204
2205\startbuffer[2]
2206\startcombination[3*1]
2207    {\ruledhbox\bgroup
2208       \showshape[character=(,alternative=text,option=simple]%
2209     \egroup} {}
2210    {\ruledhbox\bgroup
2211       \showshape[character=a,alternative=text,option=simple]%
2212     \egroup} {}
2213    {\ruledhbox\bgroup
2214       \showshape[character=x,alternative=text,option=simple]%
2215     \egroup} {}
2216\stopcombination
2217\stopbuffer
2218
2219\typebuffer[2]
2220
2221\startplacefigure[reference=fig:showshape,title={Showing shapes.}]
2222    \getbuffer[2]
2223\stopplacefigure
2224
2225When you use this feature you need to be aware of the fact that fonts can have
2226features, for instance ligatures and kerns between characters. In \in {figure}
2227[fig:outlines:features] we see a few examples, one with Pagella (the Zapf quote)
2228and one with Dejavu (the Tufte quote).
2229
2230\startplacefigure[reference=fig:outlines:features,title={Pagela and Dejavu}]
2231    \startcombination[1*4]
2232        \bgroup
2233            \def|#1|{-}%
2234            \definedfont[file:texgyrepagella-regular.otf*none]%
2235            \startMPcode
2236                draw outlinetext.b
2237                    ("\framed[align=normal,width=max]{\input{zapf}}")
2238                    (withcolor .375white)
2239                    (withcolor .625red withpen pencircle scaled 1/10) ;
2240            \stopMPcode
2241        \egroup {pagella / no features}
2242        \bgroup
2243            \def|#1|{-}%
2244            \definedfont[file:texgyrepagella-regular.otf*default]%
2245            \startMPcode
2246                draw outlinetext.b
2247                    ("\framed[align=normal,width=max]{\input{zapf}}")
2248                    (withcolor .375white)
2249                    (withcolor .625blue withpen pencircle scaled 1/10) ;
2250            \stopMPcode
2251        \egroup {pagella / default features}
2252        \bgroup
2253            \def|#1|{-}%
2254            \definedfont[file:dejavuserif.ttf*none]%
2255            \startMPcode
2256                draw outlinetext.b
2257                    ("\framed[align=normal,width=max]{\input{tufte}}")
2258                    (withcolor .375white)
2259                    (withcolor .625green withpen pencircle scaled 1/10) ;
2260            \stopMPcode
2261        \egroup {dejavu serif / no features}
2262        \bgroup
2263            \def|#1|{-}%
2264            \definedfont[file:dejavuserif.ttf*default]%
2265            \startMPcode
2266                draw outlinetext.b
2267                    ("\framed[align=normal,width=max]{\input{tufte}}")
2268                    (withcolor .375white)
2269                    (withcolor .625yellow withpen pencircle scaled 1/10) ;
2270            \stopMPcode
2271        \egroup {dejavu serif / default features}
2272    \stopcombination
2273\stopplacefigure
2274
2275Given that a shape has a path that is suitable for it, you can use special effects,
2276like:
2277
2278\startbuffer
2279    draw image (
2280        draw outlinetext.d
2281            ("Abracadabra")
2282            (withpen pencircle scaled 1/10 dashed withdots scaled 1/20) ;
2283    ) xsized TextWidth ;
2284\stopbuffer
2285
2286\typebuffer
2287
2288\startlinecorrection
2289    \processMPbuffer
2290\stoplinecorrection
2291
2292The next example needs the \type {hanbatang-lvt.ttf} font so when you process this
2293you might want to install that first. In \MKIV\ and \LMTX\ you can put that font
2294in \typ {<texroot>/texmf-fonts/data/hanbantang} or a similar path.
2295
2296We start by defining the font:
2297
2298% \definefontfeature
2299%   [korean-base]
2300%   [goodies=hanbatanglvt,
2301%    colorscheme=default,
2302%    mode=node,
2303%    script=hang,
2304%    language=kor]
2305
2306\startbuffer
2307\definefontfeature
2308  [korean-base]
2309  [goodies=hanbatanglvt,
2310   colorscheme=default,
2311   mode=node,
2312   script=hang,
2313   language=kor]
2314
2315\definefont[KoreanFont][file:hanbatanglvt*korean-base]
2316\stopbuffer
2317
2318\typebuffer \getbuffer
2319
2320Next we define a macro that will draw the outline:
2321
2322\startbuffer
2323\startMPdefinitions
2324string KoreanColors[] ;
2325
2326KoreanColors[1] := "darkred" ;
2327KoreanColors[2] := "darkgreen" ;
2328KoreanColors[3] := "darkblue" ;
2329KoreanColors[4] := "darkyellow" ;
2330KoreanColors[5] := "darkgray" ;
2331
2332newinternal KoreanSplit ; KoreanSplit := -1 ;
2333newinternal KoreanCode  ; KoreanCode  := -2 ;
2334newinternal KoreanMode  ; KoreanMode  := KoreanSplit ;
2335
2336def KoreanOutline(expr txt) =
2337  picture p ; p := outlinetext.p(txt) ;
2338  numeric n ; n := 0 ;
2339  string old, new ; old := "" ;
2340  for i within p :
2341    if KoreanMode == KoreanSplit :
2342      n := n + 1 ;
2343    elseif KoreanMode == KoreanCode :
2344      new := prescriptpart i ;
2345      if new <> old :
2346          old := new ;
2347          n := n + 1 ;
2348      fi ;
2349    else :
2350      n := KoreanMode ;
2351    fi ;
2352    if unknown KoreanColors[n] :
2353      n := 1 ;
2354    fi ;
2355    draw pathpart i
2356      withpen pencircle scaled 1/10
2357      withcolor KoreanColors[n] ;
2358  endfor ;
2359enddef ;
2360
2361def KoreanTest(expr txt) =
2362  image (
2363    KoreanMode  := KoreanSplit ; KoreanOutline(txt) ;
2364    currentpicture := currentpicture shifted (- xpart urcorner currentpicture, 0);
2365    KoreanMode  := KoreanCode ; KoreanOutline(txt) ;
2366    currentpicture := currentpicture shifted (- xpart urcorner currentpicture, 0);
2367    KoreanMode  := 3 ; KoreanOutline(txt) ;
2368  )
2369enddef ;
2370\stopMPdefinitions
2371\stopbuffer
2372
2373Because we want to reuse this definition, we define it for all what comes:
2374
2375\typebuffer \getbuffer
2376
2377% entered as three characters: ᄅ  ᅡ  ᆺ (mail collapses)
2378%
2379% \startMPcode KoreanTest("\KoreanFont 랏") ; \stopMPcode
2380
2381\startbuffer
2382\startcombination[3*2]
2383    {\startMPcode draw KoreanTest("\KoreanFont 랏") ysized 15mm ; \stopMPcode} {}
2384    {\startMPcode draw KoreanTest("\KoreanFont ë…Ľ") ysized 15mm ; \stopMPcode} {}
2385    {\startMPcode draw KoreanTest("\KoreanFont 왕") ysized 15mm ; \stopMPcode} {}
2386    {\startMPcode draw KoreanTest("\KoreanFont ë‹­") ysized 15mm ; \stopMPcode} {}
2387    {\startMPcode draw KoreanTest("\KoreanFont ë°•") ysized 15mm ; \stopMPcode} {}
2388    {\startMPcode draw KoreanTest("\KoreanFont ě„ś") ysized 15mm ; \stopMPcode} {}
2389\stopcombination
2390\stopbuffer
2391
2392We use this macro in the following example. The results can be seen in \in
2393{figure} [koreanoutlines]. There is one drawback of this example: It contributes
2394a lot to the runtime: about 2.5~seconds to a 16~second run without this example.
2395\footnote {This is partly due to an enforced intermediate garbage collection
2396step.} The font itself loads fast but the outlines take their time because a few
2397hundred megabytes of \LUA\ tables are involved. Instead you can define the
2398feature to use \typ {goodies=hanbatanglvt} and \typ {colorscheme=default} and
2399play with that.
2400
2401\typebuffer
2402
2403\startplacefigure[title=Some Korean magic,reference=koreanoutlines]
2404    \doifelsemode{optional} {
2405        \getbuffer
2406    } {
2407        \framed{A large optional example is not shown here!}
2408    }
2409\stopplacefigure
2410
2411On the mailing list occasionally questions pop op with respect to outlines and
2412user Garulfo came up with a neat solution for shaded text. First some examples:
2413
2414\startbuffer
2415\startMPcode
2416   picture p ; p := lmt_outline [
2417     text          = "\strut foo f o o",
2418     drawcolor     = "white",
2419     rulethickness = .2
2420   ] ysized 3cm ;
2421   fill boundingbox p
2422    withshademethod "linear"
2423    withshadedirection(0,1)
2424    withshadecolors ("darkblue", "darkyellow") ;
2425   draw p;
2426\stopMPcode
2427\stopbuffer
2428
2429\typebuffer
2430
2431Here the background shines through the text:
2432
2433\startlinecorrection \getbuffer \stoplinecorrection
2434
2435You can actually use the effects features which for a larger text is more
2436efficient because it just renders the font differently. The result is
2437shown in \in {figure} [fig:effects:text].
2438
2439\startbuffer[effects-text]
2440\startuseMPgraphic{MyShade}
2441  fill OverlayBox
2442    withshademethod "linear"
2443    withshadedirection(0,1)
2444   withshadecolors (red, blue) ;
2445\stopuseMPgraphic
2446
2447\defineoverlay[MyShade][\useMPgraphic{MyShade}]
2448
2449\setupbackgrounds[page][background=MyShade]
2450
2451\startmakeup
2452    \definedfont[SerifBold*default @ 50pt] \setupinterlinespace
2453
2454    \defineeffect[MyOutline][alternative=outer,rulethickness=1pt]
2455
2456    \startcolor[white]
2457        \starteffect[MyOutline]
2458            \input jojomayer
2459        \stopeffect
2460    \stopcolor
2461\stopmakeup
2462\stopbuffer
2463
2464\typebuffer[effects-text]
2465
2466\startplacefigure[title=Regular text effects,reference=fig:effects:text]
2467    \typesetbuffer[effects-text][height=.3\textheight]
2468\stopplacefigure
2469
2470We now come to the neat example:
2471
2472\startbuffer
2473\startMPcode
2474    picture tt ; tt := lmt_outline [
2475        kind = "fillup",
2476        text = "\definedfont[name:texgyrepagellabold*default]foo f o o",
2477    ] xsized 12cm ;
2478
2479    path bb ; bb := boundingbox tt ;
2480
2481    path pp ; pp := bb enlarged 2cm ;
2482
2483    fill pp
2484       withshademethod "linear"
2485       withshadedirection down
2486       withshadecolors ("darkred", "darkblue") ;
2487
2488    for i within tt :
2489        nofill pathpart i;
2490    endfor ;
2491
2492    eofill bb withcolor "darkgray" ;
2493    clip currentpicture to bb ;
2494\stopMPcode
2495\stopbuffer
2496
2497\typebuffer
2498
2499It uses a clever combination of refilling the shape and background:
2500
2501\startlinecorrection
2502    \getbuffer
2503\stoplinecorrection
2504
2505\stopsection
2506
2507\startsection[title=Transparency groups]
2508
2509The following feature is not that usefull but implemented anyway. The \PDF\ reference says:
2510
2511\startitemize
2512    \startitem
2513        A group may be isolated or non-isolated, which shall determine the
2514        initial backdrop against which its stack is composited.
2515    \stopitem
2516    \startitem
2517        A group may be knockout or non-knockout, which shall determine whether
2518        the objects within its stack are composited with one another or only with
2519        the group’s backdrop.
2520    \stopitem
2521\stopitemize
2522
2523and then carries on with a detailed explanation of groups. Here we stick to just
2524mentioning how one can create a group in a picture. First we define a helper:
2525
2526\startbuffer
2527\startMPdefinitions
2528    def ShowGroup (expr clr) (text grouped) =
2529        draw image (
2530            drawarrow (10,0) -- (0,0)
2531                withtransparency(1,.5)
2532                withcolor clr ;
2533        ) grouped ;
2534        currentpicture := currentpicture xsized (TextWidth/8) ;
2535        setbounds currentpicture to boundingbox currentpicture enlarged 2mm ;
2536        addbackground withcolor .5white ;
2537    enddef ;
2538\stopMPdefinitions
2539\stopbuffer
2540
2541\typebuffer \getbuffer
2542
2543\startlinecorrection[blank]
2544    \startcombination[5*1]
2545        {\startMPcode ShowGroup(.5red)    ()                            \stopMPcode} {\tttf no group}
2546        {\startMPcode ShowGroup(.5green)  (asgroup "")                  \stopMPcode} {\tttf group}
2547        {\startMPcode ShowGroup(.5blue)   (asgroup "isolated")          \stopMPcode} {\tttf isolated}
2548        {\startMPcode ShowGroup(.5cyan)   (asgroup "knockout")          \stopMPcode} {\tttf knockout}
2549        {\startMPcode ShowGroup(.5magenta)(asgroup "isolated,knockout") \stopMPcode} {\tttf isolated\crlf knockout}
2550    \stopcombination
2551\stoplinecorrection
2552
2553The syntax is:
2554
2555\starttyping
2556draw somepicture|somepath grouped "[isolated|knockout] ;
2557\stoptyping
2558
2559The group becomes an object and is no longer part of the stream of graphic
2560operators but a reference. For what it's worth: I never needed this feature.
2561
2562\stopsection
2563
2564\startsection[title=Decorating]
2565
2566Although the \METAPOST\ language is quite powerful the number of data types is
2567not that large and when it comes to drawing stuff there are only paths and
2568pictures. A path is a list of points (with controlpoints) and a few properties,
2569like the pen, linewidth, linecap, color and such. For a long time in \METAFUN\ we
2570used so called specials to implement extensions (like shading). This was done by
2571using special colors and associating these with entries in the special section at
2572the top of the output.
2573
2574Nowadays we use the pre- and postscript properties of paths. The advantage is
2575that we can add whatever we want, as long as the backend supports it and because
2576the backend is written in \LUA\ there are no real limitations. So, instead of
2577extending \METAPOST\ we extend the \METAFUN\ macros and backend.
2578
2579Most extensions use the prescripts. Think of this:
2580
2581\starttyping
2582draw fullcircle
2583    withprescript "do this"
2584    withprescript "and that"
2585    withprescript "and even more" ;
2586\stoptyping
2587
2588Eventually this becomes a string:
2589
2590\starttyping
2591and even more<newline>and that<newline>do this
2592\stoptyping
2593
2594\typebuffer
2595
2596The prescripts get prepended, while the postscripts (that we use for text only)
2597get appended. When we draw a picture with properties (like color) they get
2598overwritten but not so (with good reason) for the pre- and postscripts: these
2599just accumulate. We will now demonstrate how we can manipulate the picture
2600(a bit).
2601
2602\startbuffer
2603picture MyShape ; MyShape := image (
2604    fill fullsquare xyscaled (4,1) withcolor .625red ;
2605    fill fullsquare xyscaled (3,1) withcolor .625green ;
2606    fill fullsquare xyscaled (2,1) withcolor .625blue ;
2607    fill fullsquare xyscaled (1,1) withcolor .625yellow ;
2608) xysized (TextWidth,1cm) ;
2609
2610draw MyShape;
2611\stopbuffer
2612
2613\typebuffer
2614
2615We just draw the (natural) picture:
2616
2617\startlinecorrection[blank]
2618    \processMPbuffer
2619\stoplinecorrection
2620
2621When we draw the picture with a new color, all its components get recolored:
2622
2623\startbuffer
2624draw MyShape
2625    withcolor .625magenta ;
2626\stopbuffer
2627
2628\typebuffer
2629
2630\startlinecorrection[blank]
2631    \processMPbuffer
2632\stoplinecorrection
2633
2634However, when we add a transparency only the first component gets adapted because
2635we use prescripts for this extension. (An extension using the postscripts would
2636affect the last component.)
2637
2638\startbuffer
2639draw MyShape
2640    withcolor .625magenta
2641    withtransparency (1,.5) ;
2642\stopbuffer
2643
2644\typebuffer
2645
2646\startlinecorrection[blank]
2647    \processMPbuffer
2648\stoplinecorrection
2649
2650The same logic applied to the \type {image}: prescripts get prepended to the
2651first copmponent, postscripts to the last.
2652
2653\startbuffer
2654draw image (draw MyShape)
2655    withcolor .625cyan ;
2656\stopbuffer
2657
2658\typebuffer
2659
2660\startlinecorrection[blank]
2661    \processMPbuffer
2662\stoplinecorrection
2663
2664\startbuffer
2665draw image (draw MyShape)
2666    withcolor .625cyan
2667    withtransparency (1,.5) ;
2668\stopbuffer
2669
2670\typebuffer
2671
2672\startlinecorrection[blank]
2673    \processMPbuffer
2674\stoplinecorrection
2675
2676The \type {undecorated} macro ignores the properties. We can't reset the scripts as
2677this could ruin the effects like shading.
2678
2679\startbuffer
2680draw undecorated (draw MyShape)
2681    withcolor .625white ;
2682\stopbuffer
2683
2684\typebuffer
2685
2686\startlinecorrection[blank]
2687    \processMPbuffer
2688\stoplinecorrection
2689
2690The \type {decorated} macro applies the properties to each component.
2691
2692\startbuffer
2693draw decorated (draw MyShape)
2694    withtransparency (1,.5) ;
2695\stopbuffer
2696
2697\typebuffer
2698
2699\startlinecorrection[blank]
2700    \processMPbuffer
2701\stoplinecorrection
2702
2703Here we kept the colors as they are but next we redo them:
2704
2705\startbuffer
2706draw decorated (draw MyShape)
2707    withcolor .625magenta
2708    withtransparency (1,.5) ;
2709\stopbuffer
2710
2711\typebuffer
2712
2713\startlinecorrection[blank]
2714    \processMPbuffer
2715\stoplinecorrection
2716
2717The \type {redecorated} macro is the most intrusive as it resets the properties.
2718This also means that you will loose texts, shades etc.
2719
2720\startbuffer
2721draw redecorated (draw MyShape)
2722    withtransparency (1,.5) ;
2723\stopbuffer
2724
2725\typebuffer
2726
2727\startlinecorrection[blank]
2728    \processMPbuffer
2729\stoplinecorrection
2730
2731Indeed we get no color (but black) but we can bring back some color:
2732
2733\startbuffer
2734draw redecorated (draw MyShape)
2735    withcolor .625yellow
2736    withtransparency (1,.5) ;
2737\stopbuffer
2738
2739\typebuffer
2740
2741\startlinecorrection[blank]
2742    \processMPbuffer
2743\stoplinecorrection
2744
2745\stopsection
2746
2747\startsection[title=Properties]
2748
2749The (plain) \METAPOST\ macro \type {drawoptions} stored its arguments
2750in a macro that gets expanded when something is drawn (or filled). So, when you say
2751
2752\starttyping
2753drawoptions(withcolor red) ;
2754draw somepath ;
2755\stoptyping
2756
2757This effectively is:
2758
2759\starttyping
2760draw somepath withcolor red ;
2761\stoptyping
2762
2763A disadvantage is that there is not much control over where it gets applied,
2764especially when you hide drawing operations in macros. It's the reason why
2765personally I always prefer explicit options. If you want some abstraction
2766you can use the properties feature:
2767
2768\startbuffer
2769\startMPcode
2770    property p[] ;
2771    p1 = properties(withcolor "darkred") ;
2772    p2 = properties(withcolor "darkblue") ;
2773    p3 = properties(withcolor "darkgreen") ;
2774    fill fullsquare xysized (TextWidth,12mm) withproperties p1 ;
2775    fill fullsquare xysized (TextWidth, 8mm) withproperties p2 ;
2776    fill fullsquare xysized (TextWidth, 4mm) withproperties p3 ;
2777    fill fullsquare xysized (TextWidth, 2mm) withproperties p1 ;
2778\stopMPcode
2779\stopbuffer
2780
2781\typebuffer
2782
2783We get:
2784
2785\startlinecorrection
2786\getbuffer
2787\stoplinecorrection
2788
2789Here we use an \quote {array} of properties but a single property is also possible:
2790
2791\startbuffer
2792\startMPcode
2793    property p ;
2794    p = properties(withcolor "darkyellow") ;
2795    fill fullsquare xysized (TextWidth,4mm) withproperties p ;
2796\stopMPcode
2797\stopbuffer
2798
2799\typebuffer
2800
2801We get:
2802
2803\startlinecorrection
2804\getbuffer
2805\stoplinecorrection
2806
2807\stopsection
2808
2809\stopchapter
2810
2811\stopcomponent
2812