1
2
3
4
5\startcomponent metafuneffects
6
7\environment metafunenvironment
8
9\useMPlibrary[outlines]
10
11\startchapter[reference=sec:effects,title={Special effects}]
12
13\startintro
14
15Sometimes we want to go beyond \METAPOSTs 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 dont 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",blue2,yellow2,green2,magenta3) ;
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 (14,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 CDs 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 CDs 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 (u4,0);
226
227
228
229
230
231
232
233
234
235
236
237
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}
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 (u4,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
332
333
334
335
336
337
338
339
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, Im 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 {circularshade} and \type {linearshade}, 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\ level2 and \PDF\ level1.3 shading feature.
456
457\def\SomeShade#1#2#3
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
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546\startbuffer
547sh := definecircularshade
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 {definecircularshade} 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 testshade (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 := definecircularshade(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]
596testshade(origin, origin, 0cm, 1cm) ;
597\stopbuffer
598\startbuffer[c]
599testshade(origin, origin, .25cm, 1cm) ;
600\stopbuffer
601\startbuffer[d]
602testshade(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]
617testshade(origin, origin shifted (.25cm,0), 0cm, 1cm) ;
618\stopbuffer
619\startbuffer[c]
620testshade(origin, origin shifted (.25cm,0), .25cm, 1cm) ;
621\stopbuffer
622\startbuffer[d]
623testshade(origin, origin shifted (.25cm,0), .50cm, 1cm) ;
624\stopbuffer
625
626\typebuffer[b,c,d] \getbuffer[f]
627
628\startbuffer[b]
629testshade(origin shifted (.25cm,0), origin, 0cm, 1cm) ;
630\stopbuffer
631\startbuffer[c]
632testshade(origin shifted (.25cm,0), origin, .25cm, 1cm) ;
633\stopbuffer
634\startbuffer[d]
635testshade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
636\stopbuffer
637
638\typebuffer[b,c,d] \getbuffer[f]
639
640\startbuffer[a]
641def testshade (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 := definelinearshade(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]
665testshade(origin, origin shifted (1cm,0)) ;
666\stopbuffer
667\startbuffer[c]
668testshade(origin shifted (1cm,0), origin shifted (1cm,0)) ;
669\stopbuffer
670\startbuffer[d]
671testshade(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[lp]
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 its 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,1i4)
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,1i4)
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 (TextWidth3,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 its 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. its also possible then to overload
1076some properties.
1077
1078
1079
1080
1081
1082
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[cowfun.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 40cell grid with
11945columns of 8rows.
1195
1196\startbuffer
1197\startbuffer
1198\setupclipping[nx=3,ny=2]
1199\startcombination
1200 {\clip[x=1,y=1]{\externalfigure[cowfun.mps][width=4cm]}} {1,1}
1201 {\clip[x=3,y=1]{\externalfigure[cowfun.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[cowfun.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[cowfun.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.5mm instead of 5mm, 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). Its 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{graphicsincluding}
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\ figure1: \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 figure1 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 ;
1498 c := .5(s,s) ;
1499 d := (2cm*i,.5cm) randomized .5cm ;
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 dont mess around with a stored external figure, youre 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 ;
1522circularshade(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{colormanipulating}
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 := definelinearshade
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 than1. Keep in mind that colors
1722are clipped at1 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
1750lets 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
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955\startsection[title={Outline fonts}]
1956
1957\index{textoutlines}
1958\index{outlines}
1959
1960Outline fonts dont belong to \METAPOSTs 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 15)
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 15)
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 15)
2008 scaled 3 ;
2009\stopbuffer
2010
2011\startbuffer[5]
2012draw outlinetext.r ("\bf Funky")
2013 (withcolor blue)
2014 (withcolor red withpen pencircle scaled 15)
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 \TEXs powerful line breaking
2031algorithm with \METAPOSTs 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 15)
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 15)
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{1x}}")
2104 (withcolor .625red withpen pencircle scaled 15)
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{1x}}{\sqrt{2x2}}\right)}")
2121 (withcolor .850white)
2122 (withcolor .625red
2123 dashed evenly scaled .1
2124 withpen pencircle scaled 15)
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.orgmathml 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 15)
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:texgyrepagellaregular.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 110) ;
2240 \stopMPcode
2241 \egroup {pagella no features}
2242 \bgroup
2243 \def#1{}
2244 \definedfont[file:texgyrepagellaregular.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 110) ;
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 110) ;
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 110) ;
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 110 dashed withdots scaled 120) ;
2283 ) xsized TextWidth ;
2284\stopbuffer
2285
2286\typebuffer
2287
2288\startlinecorrection
2289 \processMPbuffer
2290\stoplinecorrection
2291
2292The next example needs the \type {hanbatanglvt.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>texmffontsdatahanbantang} or a similar path.
2295
2296We start by defining the font:
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306\startbuffer
2307\definefontfeature
2308 [koreanbase]
2309 [goodies=hanbatanglvt,
2310 colorscheme=default,
2311 mode=node,
2312 script=hang,
2313 language=kor]
2314
2315\definefont[KoreanFont][file:hanbatanglvt*koreanbase]
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 110
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
2378
2379
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.5seconds to a 16second 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[effectstext]
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[effectstext]
2465
2466\startplacefigure[title=Regular text effects,reference=fig:effects:text]
2467 \typesetbuffer[effectstext][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 nonisolated, which shall determine the
2514 initial backdrop against which its stack is composited.
2515 \stopitem
2516 \startitem
2517 A group may be knockout or nonknockout, 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 (TextWidth8) ;
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 somepicturesomepath grouped "[isolatedknockout] ;
2557\stoptyping
2558
2559The group becomes an object and is no longer part of the stream of graphic
2560operators but a reference. For what its 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 cant 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. Its 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 |