% output=pdftex engine=pdftex language=uk
%
% copyright=pragma-ade readme=readme.pdf licence=cc-by-nc-sa

\startcomponent mfun-009

\environment mfun-000

\chapter [sec:effects] {Special effects}

\startintro

Sometimes we want to go beyond \METAPOST's native features.
Examples of such an extension are \CMYK\ colors, shading and
transparency. Although features like this should be used
with care, sometimes the documents look and feel can profit
from it.

If you don't want the whole graphic, but only a part of it,
clipping comes into play. In addition to the standard
clipping features, we can use \METAPOST\ to provide a decent
clipping path. In this chapter we will uncover the details.

We will also introduce ways to include externally defined
graphics and outline fonts. We will demonstrate that within
reasonable bounds you can manipulate such graphics

\stopintro

\section {Shading}

In this section we introduce different kind of shadings.
Since \METAPOST\ does not support this feature directly, we
have to fall back on a few tricks. For the moment shading is
only supported in \PDF. In the following examples, we will
use the next three colors:

\startbuffer
\definecolor[a][darkyellow]
\definecolor[b][s=.8]
\definecolor[c][darkred]
\stopbuffer

\typebuffer

\getbuffer

\startbuffer[a]
\startuniqueMPgraphic{CircularShade}
  path  p ;
  p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
  circular_shade(p,0,\MPcolor{a},\MPcolor{b}) ;
\stopuniqueMPgraphic

\startuniqueMPgraphic{LinearShade}
  path  p ;
  p := unitsquare xscaled \overlaywidth yscaled \overlayheight ;
  linear_shade(p,0,\MPcolor{a},\MPcolor{b});
\stopuniqueMPgraphic
\stopbuffer

\startbuffer[b]
\defineoverlay[circular shade][\uniqueMPgraphic{CircularShade}]
\defineoverlay[linear shade]  [\uniqueMPgraphic{LinearShade}]
\stopbuffer

\startbuffer[c]
\framed
  [background=circular shade,frame=off]
  {\bf \white Hi there, I'm Circular!}
\stopbuffer

\startbuffer[d]
\framed
  [background=linear shade,frame=off]
  {\bf \white Whow, this is Linear!}
\stopbuffer

A shade is a fill with a stepwise change in color. In
\POSTSCRIPT\ (level 2), the way this color changes can be
circular, linear, or according to a user defined function.
Circular and linear shades look like this:

\startlinecorrection[blank]
\getbuffer[a,b,c]
\stoplinecorrection

\startlinecorrection[blank]
\getbuffer[a,b,d]
\stoplinecorrection

As you can see, the shade lays behind the text, as
background overlay. These overlays are unique \METAPOST\
graphics, so they will adapt themselves to the dimensions of
the foreground.

\typebuffer[b]

The two framed texts are defined as:

\typebuffer[c]

and:

\typebuffer[d]

We still have to define the graphics. Here we use a macro
that takes four arguments: a path, a number identifying the
center of shading, and the colors to start and end with.

\typebuffer[a]

The \METAPOST\ macros, \type {circular_shade} and \type
{linear_shade}, add information to the \METAPOST\ output
file, which is interpreted by the converter built in
\CONTEXT. Shading comes down to interpolation between two or
more points or user supplied ranges. A poor mans way of
doing this, is to build the graphics piecewise with slightly
changing colors. But, instead of \quote {manually} stepping
through the color values, we can use the more efficient and
generalized \POSTSCRIPT\ level~2 and \PDF\ level~1.3 shading
feature.

\def\SomeShade#1#2#3% waarom unique ?
  {\startuniqueMPgraphic{shade-#1}
     width := \overlaywidth ;
     height := \overlayheight ;
     path p ; p := unitsquare xscaled width yscaled height ;
     #2_shade(p,#3,\MPcolor{a},\MPcolor{b}) ;
   \stopuniqueMPgraphic
   \defineoverlay[shade-#1][\uniqueMPgraphic{shade-#1}]%
   \framed[background=shade-#1,width=2cm,height=2cm,frame=off]{}}

\startlinecorrection[blank]
\startcombination[5*1]
  {\SomeShade{20}{circular}{0}} {circular 0}
  {\SomeShade{21}{circular}{1}} {circular 1}
  {\SomeShade{22}{circular}{2}} {circular 2}
  {\SomeShade{23}{circular}{3}} {circular 3}
  {\SomeShade{24}{circular}{4}} {circular 4}
\stopcombination
\stoplinecorrection

\startlinecorrection[blank]
\startcombination[4*2]
  {\SomeShade{32}{linear}{1}} {linear 1}
  {\SomeShade{32}{linear}{2}} {linear 2}
  {\SomeShade{33}{linear}{3}} {linear 3}
  {\SomeShade{34}{linear}{4}} {linear 4}
  {\SomeShade{35}{linear}{5}} {linear 5}
  {\SomeShade{36}{linear}{6}} {linear 6}
  {\SomeShade{37}{linear}{7}} {linear 7}
  {\SomeShade{38}{linear}{8}} {linear 8}
\stopcombination
\stoplinecorrection

Shading is not a \METAPOST\ feature, which means that it has
to be implemented using so called specials, directives that
end up in the output file. Unfortunately these are not
coupled to the specific path, which means that we have to do
a significant amount of internal bookkeeping. Also, in \PDF\
we have to make sure that the graphics and their resources
(being the shading functions) are packaged together.

Because of this implementation, shading may behave somewhat
unexpected at times. A rather normal case is the next one,
where we place 5~shaded circles in a row.

\startbuffer
path p ; p := fullcircle scaled 1cm ;
for i=0 step 2cm until 8cm :
  circular_shade(p shifted (i,0),0,\MPcolor{a},\MPcolor{b}) ;
endfor ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

At first sight, in the next situation, we would expect
something similar, because we simply copy the same circle
5~times. However, due to the way we have implemented shading
in \CONTEXT, we do indeed copy the circles, but the shade
definition is frozen and the same one is used for all
5~circles. This means that the center of the shading stays
at the first circle.

\startbuffer
circular_shade(fullcircle scaled 1cm,0,\MPcolor{a},\MPcolor{b}) ;
picture s ; s := currentpicture ; currentpicture := nullpicture ;
for i=0 step 2cm until 8cm :
  addto currentpicture also s shifted (i,0) ;
endfor ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Unlike \TEX, \METAPOST\ does not keep its specials attached
to the current path, and flushes them before the graphic
data. Since we use these specials to register shading
information, it is rather hard to tightly connect a specific
shade with a certain fill, especially if an already
performed fill is not accessible, which is the case when we
copy a picture.

This may seem a disadvantage, but fortunately it also has
its positive side. In the next example we don't copy, but
reuse an already defined shade. By storing the reference to
this shade, and referring to it by using \type {withshade},
we can use a shade that operates on multiple shapes.

\startbuffer
sh := define_circular_shade
  (origin,origin,0,8cm,\MPcolor{a},\MPcolor{b}) ;
for i=0 step 2cm until 8cm :
  fill fullcircle scaled 1cm shifted (i,0) withshade sh ;
endfor ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

The low level macro \type {define_circular_shade} is fed with
two pairs (points), two radius, and two colors. The shade is
distributed between the colors according to the radius.

Shading can hardly be called an easy issue. The macros that
we provide here are in fact simplifications, which means that
at a lower level, one can do more advanced things. Here we
limit ourselves to the more common cases. In the previous
examples, we used an arrow to indicate the direction and
magnitude of the shade. The next macro demonstrates the
principles in a different way.

\startbuffer[a]
def test_shade (expr a, b, ra, rb) =
  pickup pencircle scaled 1mm ;

  color ca ; ca := \MPcolor{a} ;
  color cb ; cb := \MPcolor{b} ;
  color cc ; cc := \MPcolor{c} ;

  path pa ; pa := fullcircle scaled 2ra shifted a ;
  path pb ; pb := fullcircle scaled 2rb shifted b ;

  sh := define_circular_shade(a,b,ra,rb,ca,cb) ;

  fill pb withshade sh ;
  draw pb withcolor cc ;
  draw pa withcolor cc ;
enddef ;
\stopbuffer

\typebuffer[a]

The shade is distributed between two circles, each with a
radius and center point. All four can be set, but as the next
calls demonstrate, we can normally do with less, which is why
we provided the macro with less parameters.

\startbuffer[b]
test_shade(origin, origin,   0cm, 1cm) ;
\stopbuffer
\startbuffer[c]
test_shade(origin, origin, .25cm, 1cm) ;
\stopbuffer
\startbuffer[d]
test_shade(origin, origin, .50cm, 1cm) ;
\stopbuffer

\startbuffer[f]
\startlinecorrection[blank]
\hbox
  {\processMPbuffer[a,b]\quad
   \processMPbuffer[a,c]\quad
   \processMPbuffer[a,d]}
\stoplinecorrection
\stopbuffer

\typebuffer[b,c,d] \getbuffer[f]

\startbuffer[b]
test_shade(origin, origin shifted (.25cm,0),   0cm, 1cm) ;
\stopbuffer
\startbuffer[c]
test_shade(origin, origin shifted (.25cm,0), .25cm, 1cm) ;
\stopbuffer
\startbuffer[d]
test_shade(origin, origin shifted (.25cm,0), .50cm, 1cm) ;
\stopbuffer

\typebuffer[b,c,d] \getbuffer[f]

\startbuffer[b]
test_shade(origin shifted (.25cm,0), origin,   0cm, 1cm) ;
\stopbuffer
\startbuffer[c]
test_shade(origin shifted (.25cm,0), origin, .25cm, 1cm) ;
\stopbuffer
\startbuffer[d]
test_shade(origin shifted (.25cm,0), origin, .50cm, 1cm) ;
\stopbuffer

\typebuffer[b,c,d] \getbuffer[f]

\startbuffer[a]
def test_shade (expr a, b) =
  pickup pencircle scaled 1mm ;

  color ca ; ca := \MPcolor{a} ;
  color cb ; cb := \MPcolor{b} ;
  color cc ; cc := \MPcolor{c} ;

  sh := define_linear_shade(a,b,ca,cb) ;

  fill fullsquare scaled 2cm withshade sh ;
  draw a withcolor cc ;
  draw b withcolor cc ;
enddef ;
\stopbuffer

In a similar fashion, we can define linear shaded. This time
we only pass two points and two colors.

\typebuffer[a]

Although one can control shading to a large extend, in
practice only a few cases really make sense.

\startbuffer[b]
test_shade(origin, origin shifted (1cm,0)) ;
\stopbuffer
\startbuffer[c]
test_shade(origin shifted (-1cm,0), origin shifted (1cm,0)) ;
\stopbuffer
\startbuffer[d]
test_shade(origin shifted (-1cm,-1cm), origin shifted (1cm,1cm)) ;
\stopbuffer

\startbuffer[f]
\startlinecorrection[blank]
\hbox
  {\processMPbuffer[a,b]\quad
   \processMPbuffer[a,c]\quad
   \processMPbuffer[a,d]}
\stoplinecorrection
\stopbuffer

\typebuffer[b,c,d] \getbuffer[f]

\section {Transparency}

{\em In the screen version we use a light gray background
color. As a result, some of the transparency methods
demonstrated here give unexpected results. The A4 version
of this document demonstrates the real effects.}

Although transparent colors have been around for some time
already, it was only around 2000 that they made it as a
high level feature into document format languages like
\PDF. Supporting such a feature at a higher abstraction
level is not only more portable, but also less sensitive
for misinterpretation.

\startbuffer[mpdef]
vardef ColorCircle (expr method, factor, ca, cb, cc) =
  save u, p ; path p ; p := fullcircle shifted (1/4,0) ;
  image
    ( fill p rotated  90 withcolor transparent(method,factor,ca) ;
      fill p rotated 210 withcolor transparent(method,factor,cb) ;
      fill p rotated 330 withcolor transparent(method,factor,cc) )
enddef ;
\stopbuffer

\typebuffer[mpdef]

\startbuffer[mp]
draw ColorCircle ("normal", .5, red, green, blue) xsized 3cm ;
currentpicture := currentpicture shifted (-4cm,0) ;
draw ColorCircle ("exclusion", .5, red, green, blue) xsized 3cm ;
currentpicture := currentpicture shifted (-4cm,0) ;
draw ColorCircle ("exclusion", 1, red, green, blue) xsized 3cm ;
\stopbuffer

\typebuffer[mp]

\startlinecorrection[blank]
\processMPbuffer[mpdef,mp]
\stoplinecorrection

\startbuffer[mp]
color xcyan    ; xcyan    := cmyk(1,0,0,0) ;
color xmagenta ; xmagenta := cmyk(0,1,0,0) ;
color xyellow  ; xyellow  := cmyk(0,0,1,0) ;

draw ColorCircle ("exclusion", .5, xcyan, xmagenta, xyellow) xsized 3cm ;
\stopbuffer

\typebuffer[mp]

\startlinecorrection[blank]
\processMPbuffer[mpdef,mp]
\stoplinecorrection

You can be tempted to use transparency as a convenient way
to achieve soft colors. In that case you should be aware of
the fact that rendering transparent colors takes more time
than normal colors \footnote {When your printer does not
support this feature natively, the intermediate
(\POSTSCRIPT) file send to the printing engine is also
larger.}

Fortunatey, \METAPOST\ provides a similar mechanism. The
last circle in the following row demonstates how we can
trigger colors proportionally to other colors. Normally
\type {background} is white, but you can set predefined
color variable to another value.

\startbuffer[mp]
path p ; p := fullcircle scaled 2cm ;
fill p shifted (0cm,0) withcolor blue  ;
fill p shifted (3cm,0) withcolor .5blue  ;
fill p shifted (6cm,0) withcolor transparent (1,0.5,blue) ;
fill p shifted (9cm,0) withcolor .5[blue,white] ;
\stopbuffer

\typebuffer[mp]

\startlinecorrection[blank]
\processMPbuffer[mp]
\stoplinecorrection

The next series demonstrates that we use the complementary
factor \type {.7} in the \METAPOST\ soft color to achieve
the same softness as the \type {.3} transparency.

\startbuffer[mp]
path p ; p := fullcircle scaled 2cm ;
fill p shifted (0cm,0) withcolor red  ;
fill p shifted (3cm,0) withcolor .7red ;
fill p shifted (6cm,0) withcolor transparent (1,0.3,red) ;
fill p shifted (9cm,0) withcolor .7[red,white] ;
\stopbuffer

\typebuffer[mp]

\startlinecorrection[blank]
\processMPbuffer[mp]
\stoplinecorrection

\startbuffer[mp]
vardef SampleText (expr t, c) =
  save p ; picture p ;
  p := image (draw t infont "\truefontname{Regular}") ;
  draw (p shifted (- xpart center p,0)) scaled 5 withcolor c ;
enddef ;

SampleText ("Much Of This"   , transparent(1, .5, red)          ) ;
SampleText ("Functionality"  , transparent(1, .5, cmyk(1,0,1,0))) ;
SampleText ("Was Written"    , transparent(1, .5, blue)         ) ;
SampleText ("While Listening", transparent(1, .5, cmyk(1,0,0,0))) ;
SampleText ("To the CD's Of" , transparent(1, .5, cmyk(0,1,0,0))) ;
SampleText ("Tori Amos"      , transparent(1, .5, cmyk(0,0,1,0))) ;
\stopbuffer

So far we have applied transparent colors to shapes but text
can also be the target.

\startlinecorrection[blank]
\processMPbuffer[mp]
\stoplinecorrection

The source code of this example illustrates that the
\CMYK\ color space is also supported. The \type
{\truefontname} macro communicates the running font from
\TEX\ to \METAPOST.

\typebuffer[mp]

Currently the 12 in \PDF\ available transparency methods
are supported. \footnote {In the future we may also support
more control over the individual methods.} You can use both
numbers and names. As you may expect, both \CONTEXT\ and
\METAFUN\ support transparency in the same way. \in
{Figure} [fig:transparencies] shows how the method affects
the result.

\startuseMPgraphic{test}
u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);

color xyellow ; xyellow := cmyk(0,0,1,0) ;
color xgreen  ; xgreen  := (0,1,0) ;
color xblue   ; xblue   := (0,0,1) ;

fill p rotated  90 withcolor transparent("\MPvar{a}",.5,xyellow) ;
fill p rotated 210 withcolor transparent("\MPvar{a}",.5,xgreen) ;
fill p rotated 330 withcolor transparent("\MPvar{a}",.5,xblue) ;
\stopuseMPgraphic

\startbuffer
\startcombination[4*3]
  {\useMPgraphic{test}{a=normal}}     {\tttf normal}
  {\useMPgraphic{test}{a=multiply}}   {\tttf multiply}
  {\useMPgraphic{test}{a=screen}}     {\tttf screen}
  {\useMPgraphic{test}{a=overlay}}    {\tttf overlay}
  {\useMPgraphic{test}{a=softlight}}  {\tttf softlight}
  {\useMPgraphic{test}{a=hardlight}}  {\tttf hardlight}
  {\useMPgraphic{test}{a=colordodge}} {\tttf colordodge}
  {\useMPgraphic{test}{a=colorburn}}  {\tttf colorburn}
  {\useMPgraphic{test}{a=darken}}     {\tttf darken}
  {\useMPgraphic{test}{a=lighten}}    {\tttf lighten}
  {\useMPgraphic{test}{a=difference}} {\tttf difference}
  {\useMPgraphic{test}{a=exclusion}}  {\tttf exclusion}
\stopcombination
\stopbuffer

\placefigure
  [here][fig:transparencies]
  {The 12 transparancy alternatives by name.}
  {\getbuffer}

In \CONTEXT\ a transparent color is defined in a similar
way as \quote {normal} colors. The transparency method is
specified with the \type {a} key (either by number, or by
name) and the factor \type {t}.

\startbuffer
\definecolor [tred]   [r=1,t=.5,a=exclusion]
\definecolor [tgreen] [g=1,t=.5,a=exclusion]
\definecolor [tblue]  [b=1,t=.5,a=exclusion]
\stopbuffer

\typebuffer \getbuffer

Both keys are needed. You can define your own symbolic names
using:

\starttyping
\definetransparency [myowndefault] [1]
\stoptyping

The \type {\MPcolor} macro passes a color from \CONTEXT\ to
\METAPOST, including the transparency specification.

\startbuffer[mp]
u := 2cm ; path p ; p := fullcircle scaled u shifted (u/4,0);

fill p rotated  90 withcolor \MPcolor{tred} ;
fill p rotated 210 withcolor \MPcolor{tgreen} ;
fill p rotated 330 withcolor \MPcolor{tblue} ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer[mp]
\stoplinecorrection

Of course this also works well for \CMYK\ colors.

\startbuffer
\definecolor[tred]  [c=1,k=.2,t=.5,a=1]
\definecolor[tgreen][m=1,k=.2,t=.5,a=1]
\definecolor[tblue] [y=1,k=.2,t=.5,a=1]
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer[mp]
\stoplinecorrection

Gray scales work as well:

\startbuffer
\definecolor[ta][s=.9,t=.7,a=11]
\definecolor[tb][s=.7,t=.7,a=11]
\definecolor[tc][s=.5,t=.7,a=11]
\stopbuffer

\typebuffer \getbuffer

We apply this to some text. By using an overlay we can
conveniently explore the difference in fonts.

\startbuffer
def SampleText (expr s, f, c) =
  draw s infont f scaled 5 withcolor c ;
enddef ;

SampleText("Hello", "\truefontname{Regular}"       , \MPcolor{ta}) ;
SampleText("Hello", "\truefontname{RegularBold}"   , \MPcolor{tb}) ;
SampleText("Hello", "\truefontname{RegularSlanted}", \MPcolor{tc}) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

\section {Clipping}

In this chapter we will use the graphic representation
(although simplified) of a Dutch cow to demonstrate
clipping.

\startbuffer
\placefigure
  {A cow.}
  {\externalfigure[cow.mps][width=4cm]}
\stopbuffer

\getbuffer

Since this cow is defined as a \METAPOST\ graphic, we use the
suffix \type {mps} instead of \type {eps} or a number,
although \CONTEXT\ will recognize each as being \METAPOST\
output. The placement of the cow is defined as:

\typebuffer

Clipping is combined with a matrix, as in \in {figure}
[fig:clipped cow 1]. The content to be clipped is divided in
\type {nx} by \type {ny} rectangles. For instance, \type
{nx=5} and \type {ny=8} will produce a 40~cell grid with
5~columns of 8~rows.

\startbuffer
\startbuffer
\setupclipping[nx=3,ny=2]
\startcombination
  {\clip[x=1,y=1]{\externalfigure[cow.mps][width=4cm]}} {1,1}
  {\clip[x=3,y=1]{\externalfigure[cow.mps][width=4cm]}} {3,1}
\stopcombination
\stopbuffer

\placefigure
  [here][fig:clipped cow 1]
  {A clipped cow.}{\getbuffer}
\stopbuffer

\getbuffer

Here we have divided the cow in six cells, so that we can
clip its head and tail. This kind of clipping enables you to
zoom in or focus on a specific part of a graphic.

\typebuffer

Alternatively, we can specify a \type {width}, \type
{height}, \type {hoffset} and \type {voffset}, as
demonstrated in \in {figure} [fig:clipped cow 2].

\startbuffer
\placefigure
  [here][fig:clipped cow 2]
  {Another clipped cow.}
  {\clip
     [width=2cm,height=2cm,hoffset=0cm,voffset=0cm]
     {\externalfigure[cow.mps][width=4cm]}}
\stopbuffer

\getbuffer

\typebuffer

Because \METAPOST\ supports clipping, it will be no surprise
that both techniques can be combined. In the next example we
will zoom in on the head of the cow. We also use this
opportunity to demonstrate how you can package a clip in a
figure definition.

\startbuffer
\startMPclip{head clip}
 w := \width ; h := \height ;
 clip currentpicture to
  ((0,h)--(w,h){down}..{left}(0,0)--cycle) ;
\stopMPclip

\placefigure
  [here][fig:circular clipped cowhead]
  {A quarter circle applied to a cows head.}
  {\ruledhbox
     {\clip
        [nx=2,ny=2,x=1,y=1,mp=head clip]
        {\externalfigure[cow.mps][width=4cm]}}}
\stopbuffer

\typebuffer

A more advanced clip is demonstrated in \in {figure}
[fig:circular clipped cowhead]. We added \type {\ruledhbox}
to demonstrate the dimensions of the resulting graphic.
Putting something in such a ruled box is often a quick way
to test spacing.

\getbuffer

Although a clip path definition can contain any \METAPOST\
command, even graphics, it must contain at least one clipping
path. The first one encountered in the resulting graphic is
used. In the example we used a path that is built out of
three subpaths.

\starttyping
(0,h)--(w,h){down}..{left}(0,0)--cycle
\stoptyping

We start in the top left corner and draw a straight line.
Next we draw a curve to the origin. Directives like \type
{down} and \type {right} force the curve in a certain
direction. With \type {cycle} we close the path. Because we
use this path as a clipping path, we use \type {clip}
instead of \type {draw} or \type {fill}.

\startbuffer
w := 4cm ; h := 2cm ;
draw (0,h)--(w,h){down}..{left}(0,0)--cycle
  withpen pencircle scaled 1mm withcolor .625red ;
\stopbuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Clipping as such is not limited to graphics. Take for
instance the text buffer:

\startbuffer
\startbuffer[sample]
\framed
  [align=middle,width=4cm,background=screen,frame=off]
  {A \METAPOST\ clip is not the same as a video clip,
   although we can use \METAPOST\ to produce a video clip.}
\stopbuffer
\stopbuffer

\typebuffer

\getbuffer

We can call up such a buffer as if it were an external
figure. \in {Figure} [fig:clipped text 1] shows the result.
This time we use a different clip path:

\startbuffer[a]
\startMPclip{text clip}
  clip currentpicture to fullcircle shifted (.5,.5)
    xscaled \width yscaled \height ;
\stopMPclip
\stopbuffer

\typebuffer[a]

To load a buffer, we have to specify its name and type, as
in:

\startbuffer[b]
\placefigure
  [here][fig:clipped text 1]
  {A clipped buffer (text).}
  {\clip
     [nx=1,ny=1,mp=text clip]
     {\externalfigure[sample][type=buffer,width=4cm]}}
\stopbuffer

\typebuffer[b]

\getbuffer[a,b]

The next few lines demonstrate that we can combine techniques
like backgrounds and clipping.

\startbuffer
\startuseMPgraphic{clip outline}
 draw fullcircle
   xscaled \overlaywidth yscaled \overlayheight
   withpen pencircle scaled 4mm
   withcolor .625red ;
\stopuseMPgraphic

\defineoverlay[clip outline][\useMPgraphic{clip outline}]

\placefigure
  [here][fig:clipped text 2]
  {A clipped buffer (text).}
  {\framed
     [background=clip outline,offset=overlay,frame=off]
     {\clip
        [nx=1,ny=1,mp=text clip]
        {\externalfigure[sample][type=buffer,width=4cm]}}}
\stopbuffer

\typebuffer

We could have avoided the \type {\framed} here, by using the
\typ{clip outline} overlay as a background of the sample. In
that case, the resulting linewidth would have been 2.5~mm
instead of 5~mm, since the clipping path goes through the
center of the line.

\getbuffer

In most cases, the clip path will be a rather simple path and
defining such a path every time you need it, can be annoying.
\in {Figure} [fig:clipping paths] shows a collection of
predefined clipping paths. These are available after loading
the \METAPOST\ clipping library.

\starttyping
\useMPlibrary[clp]
\stoptyping

We already saw how the circular clipping path was defined.
The diamond is defined in a similar way, using the predefined
path \type {diamond}:

\starttyping
\startMPclip{diamond}
  clip currentpicture to unitdiamond
    xscaled \width yscaled \height ;
\stopMPclip
\stoptyping

The definition of the negated ellipse (\type {negellipse})
uses the primary \type {peepholed}. This primary is defined
in one of the \METAPOST\ modules that come with \CONTEXT.

\starttyping
\startMPclip{negellipse}
  clip currentpicture to (unitcircle peepholed unitsquare)
    xscaled \width yscaled \height ;
\stopMPclip
\stoptyping

The definition of \type {peepholed} is rather dirty and
using \type {peepholed} is restricted to well defined
situations (like here). It's called a primary because it
acts as an operator at the same level as \type {*} and
\type {scaled}.

\startbuffer
\setupclipping  [nx=1,ny=1,x=1,y=1]
\setupblackrules[width=2cm,height=1cm]
\startcombination[6*3]
  {\clip[mp=urellipse] {\darkred\blackrule}} {urellipse}
  {\clip[mp=ulellipse] {\darkred\blackrule}} {ulellipse}
  {\clip[mp=llellipse] {\darkred\blackrule}} {llellipse}
  {\clip[mp=lrellipse] {\darkred\blackrule}} {lrellipse}
  {\clip[mp=ellipse]   {\darkred\blackrule}} {ellipse}
  {\clip[mp=negellipse]{\darkred\blackrule}} {negellipse}
  {\clip[mp=tellipse]  {\darkred\blackrule}} {tellipse}
  {\clip[mp=bellipse]  {\darkred\blackrule}} {bellipse}
  {\clip[mp=lellipse]  {\darkred\blackrule}} {lellipse}
  {\clip[mp=rellipse]  {\darkred\blackrule}} {rellipse}
  {}                                         {}
  {}                                         {}
  {\clip[mp=urtriangle]{\darkred\blackrule}} {urtriangle}
  {\clip[mp=ultriangle]{\darkred\blackrule}} {ultriangle}
  {\clip[mp=lltriangle]{\darkred\blackrule}} {lltriangle}
  {\clip[mp=lrtriangle]{\darkred\blackrule}} {lrtriangle}
  {\clip[mp=diamond]   {\darkred\blackrule}} {diamond}
  {\clip[mp=negdiamond]{\darkred\blackrule}} {negdiamond}
\stopcombination
\stopbuffer

\placefigure
  [here][fig:clipping paths]
  {A collection of predefined clipping paths.}
  {\getbuffer}

\section{Including graphics}

This document demonstrates that it is no big problem to
include \METAPOST\ graphics in a \TEX\ document. But how
about including graphics in a \METAPOST\ picture? In this
section we will explore a couple of macros that provide you
this feature.

Before we go into details, we introduce a very impressive
program called \PSTOEDIT\ by Wolfgang Glunz. This program
runs on top of \GHOSTSCRIPT\ and is able to convert
\POSTSCRIPT\ code into other formats, among them \METAPOST\
(that part of the \PSTOEDIT\ code is due to Scott Pakin).
Some of the graphics that we use in this section are
produced that way. For us, the next call works well, but the
exact call may differ per version of platform.

\starttyping
pstoedit -ssp -dt -f mpost yourfile.ps newfile.mp
\stoptyping

We have converted the Dutch cow that shows up in many
\CONTEXT\ documents into \METAPOST\ using this program. The
resulting \METAPOST\ file encapsulates the cow in \METAPOST\
figure~1: \type {beginfig(1)}. Of course you can process
this file like any other, but more interesting is to use
this code in an indirect way.

\startbuffer
loadfigure "mycow.mp" number 1 scaled .5 ;
\stopbuffer

\typebuffer

This call will load figure~1 from the specified \METAPOST\
file, in such a way that there is no interference with the
current (encapsulating) figure.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Because this graphic is the result from a conversion, there
are only paths. If you want to import a more complex
graphic, you need to make sure that the variables used in
there do not conflict with the one currently in use.

\METAPOST\ is good in drawing vector graphics, but lacks
natural support for bitmaps, but the next macro offers a way
out. This macro permits you to include graphics in \PNG,
\PDF, and \JPG\ format, or more precise: those formats
supported by \PDFTEX.\pagereference[hacker]

\startbuffer
externalfigure "hacker.png" scaled 5cm shifted (-6cm,0) ;
externalfigure "hacker.png" scaled 5cm slanted .5 ;
\stopbuffer

\typebuffer

You can apply the usual transformations, but only those
applied directly will be taken into account. This means that
you (currently) cannot store external figures in picture
variables in order to transform them afterwards.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Although you are limited in what you can do with such
graphics, you can include them multiple times with a
minimum of overhead. Graphics are stored in objects and
embedded only once.

\startbuffer
numeric s ; pair d, c ;
for i := 1 upto 5 :
  s := 3cm randomized 1cm ;           % size of picture
  c := .5(s,s) ;                      % center of picture
  d := (2cm*i,.5cm) randomized .5cm ; % displacement
  externalfigure "hacker.png"
    scaled s rotatedaround (c,0 randomized 30) shifted d ;
endfor ;
\stopbuffer

\typebuffer

Because we cannot store the graphic in a picture and scale
afterwards, we calculate the scale in advance, so that we
can rotate around the center.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

As long as you don't mess around with a stored external
figure, you're safe. The following example demonstrates how
we can combine two special driven features: figure inclusion
and shading.

\startbuffer
picture p ;
p := image (externalfigure "hacker.png" scaled 150pt) ;
clip p to unitcircle scaled 150pt ;
circular_shade(boundingbox p enlarged 10pt, 0, .2red, .9red) ;
addto currentpicture also p ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

We end this section with a few more words to \METAPOST\
inclusion. It may seem that in order to use the features
discussed here, you need to use \CONTEXT\ as typesetting
engine. This is not true. First of all, you can use the small
\TEX\ package \MPTOPDF\ (described in another manual) or you
can make small \CONTEXT\ files with one page graphics. The
advantage of the last method is that you can manipulate
graphics a bit.

\starttyping
\setupoutput[pdftex]

\setupcolors[cmyk=yes,rgb=no,state=start]

\starttext

\startMPpage[offset=6pt]
  loadfigure "niceone.mp" number 10 ;
\stopMPpage

\stoptext
\stoptyping

The resulting \PDF\ file can be included as any other graphic
and has the advantage that it is self contained.

\section [sec:conversion] {Changing colors}

One of the advantages of \METAPOST\ graphics is that it is
rather easy to force consistency in colors and line widths.
You seldom can influence third party graphic that way, but
we can use some \METAFUN\ trickery to get around this
limitation.

\startbuffer
loadfigure "mycow.mp" number 1 scaled .35 ;
refill currentpicture withcolor .625red ;
\stopbuffer

Say that we want a red cow instead of a black one. The
following code does the trick:

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

In a similar way we can influence the width and colors of
the lines.

\startbuffer
loadfigure "mycow.mp" number 1 scaled .35 ;
refill currentpicture withcolor .625red ;
redraw currentpicture withpen pencircle scaled 2pt withcolor .625yellow ;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Of course we can also use the more fancy features of
\METAFUN, like transparency and shading.

\startbuffer
loadfigure "mycow.mp" number 1 scaled .35 ;
numeric sh ; sh := define_linear_shade
  (llcorner currentpicture,urcorner currentpicture,.625red, .625yellow) ;
refill currentpicture withshade sh ;
redraw currentpicture withpen pencircle scaled 2pt withcolor .5white;
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Before we show a next trick, we draw a few circles.

\startbuffer[a]
fill fullcircle scaled 2cm                 withcolor yellow ;
fill fullcircle scaled 2cm shifted (3cm,0) withcolor red ;
\stopbuffer

\typebuffer[a]

\startlinecorrection[blank]
\processMPbuffer[a]
\stoplinecorrection

The yellow and red color do not match the main document
colors, but this is no problem: we can remap them, without
spoiling the original definition.

\startbuffer[b]
remapcolor(yellow,.625yellow) ;
remapcolor(red   ,.625red) ;
recolor currentpicture ;
resetcolormap ;
\stopbuffer

\typebuffer[a,b]

\startlinecorrection[blank]
\processMPbuffer[a,b]
\stoplinecorrection

We can combine the inclusion technique with remapping
colors. This time using an artist impression of one of
Hasselts Canals (gracht in Dutch)\pagereference [canal].

\startbuffer[a]
loadfigure "gracht.mp" number 1 scaled .5 ;
\stopbuffer

\typebuffer[a]

\startlinecorrection[blank]
\processMPbuffer[a]
\stoplinecorrection

If you think that the sky is too bright in this picture,
and given that you also know which color is used, you can
fool the reader by remapping a few colors.

\startbuffer[b]
color skycolor   ; skycolor   := (0.8,0.90,1.0) ;
color watercolor ; watercolor := (0.9,0.95,1.0) ;
remapcolor(skycolor  ,.8skycolor  ) ;
remapcolor(watercolor,.8watercolor) ;
recolor currentpicture ;
resetcolormap ;
\stopbuffer

\typebuffer[a,b]

\startlinecorrection[blank]
\processMPbuffer[a,b]
\stoplinecorrection

Including another \METAPOST\ graphic, refilling, redrawing,
and recoloring are all relatively simple features that use
no real tricks. Oposite to the next feature, which is
implemented using the \METAPOST\ special driver that comes
with \CONTEXT.

\METAPOST\ is not really meant for manipulating graphics,
but the previous examples demonstrated that we have some
control over individual colors. In the next series of
examples we will treat the picture as a whole. First we
invert the colors using \type {inverted}.

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  inverted currentpicture
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

This is a special case of \type {uncolored}. In the next
example we explicitly specify the color.

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  (currentpicture uncolored green)
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

You can also multiply each color using \type {softened}. In
the next sample, the colors have 80\% of their value.

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  (currentpicture softened .8)
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

You can also use this operator to harden colors, simply by
providing a value larger than~1. Keep in mind that colors
are clipped at~1 anyway.

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  (currentpicture softened 1.2)
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

By providing a triplet, you can treat each color component
independently.

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  (currentpicture softened (.7,.8,.9))
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

After these examples your are probably sick of seeing this
picture in color, so let's turn the colors into a weigthed
grayscales (in a way similar to the way black and white
television treated color).

\startbuffer
loadfigure "gracht.mp" number 1 scaled .5 ;
addto currentpicture also
  grayed currentpicture
  shifted (bbwidth(currentpicture)+.5cm,0) ;
\stopbuffer

\typebuffer

\startlinecorrection[blank] \processMPbuffer \stoplinecorrection

\section {Outline fonts}

Outline fonts don't belong to \METAPOST's repertoire of
features. Nevertheless we can simulate this in a reasonable
way. We will not discuss all details here, because most
details are covered in the \MAKEMPY\ manual.

The macro responsible for outline fonts is \type
{graphictext}. The first argument should be a string. This
string is processed by \TEX. Additionally you can provide
transformation directives and color specifications. The next
example demonstrates this.

\startbuffer
graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
  withdrawcolor blue
  withfillcolor .5white
  withpen pencircle scaled 5pt
\stopbuffer

\typebuffer

Once the text is typeset by \TEX, it is converted to
\POSTSCRIPT\ and converted into \METAPOST\ by the \PSTOEDIT\
program. The resulting graphic is imported, analyzed, and
processed conforming the specifications of \type
{graphictext}.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

By default the shapes are filled after they are drawn. This
has the advantage that in characters built out of pieces,
disturbing lines fragments are covered. The drawback is that
you get only half the linewidth. You can reverse the drawing
order by adding the \type {reversefill} directive. The
previous graphic then comes out as:

\startbuffer
graphictext "\bf Fun" scaled 4 zscaled (1,1.5)
  reversefill
  withdrawcolor blue
  withfillcolor .5white
  withpen pencircle scaled 5pt
\stopbuffer

\typebuffer

The \type {reversefill} directive can be countered by \type
{outlinefill}.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

The next example is taken from the \MAKEMPY\ manual. It
demonstrates that you can combine \TEX's powerful line
breaking with \METAPOST's graphic capabilities.

\startbuffer
\startuseMPgraphic{quotation}
  picture one ; one := image ( graphictext
    \MPstring{text}
    scaled 1.5
    withdrawcolor .625blue
    withfillcolor .625white
    withpen pencircle scaled 1pt ; ) ;
  picture two ; two := image ( graphictext
    \MPstring{author}
    scaled 2
    withdrawcolor .625red
    withfillcolor .625white
    withpen pencircle scaled 2pt ; ) ;
  currentpicture := one ;
  addto currentpicture also two
    shifted lrcorner one
    shifted - 1.125 lrcorner two
    shifted (0, - 1.250 * ypart urcorner two)  ;
  setbounds currentpicture to boundingbox currentpicture enlarged 3pt ;
\stopuseMPgraphic
\stopbuffer

\typebuffer \getbuffer

In this graphic, we have two text fragments, the first one is
a text, the second one the name of the author. We combine the
quotation and author into this graphic using the following
definitions:

\startbuffer
\setMPtext{text}  {\vbox{\hsize 8.5cm \input zapf }}
\setMPtext{author}{\hbox{\sl Hermann Zapf}}
\stopbuffer

\typebuffer \getbuffer

These definitions assume that the file \type {zapf.tex} is
present on the system (which is the case when you have
installed \CONTEXT). The graphic can now be typeset using
the following call:

\startbuffer
\placefigure
  {A text does not need to be an outline in order to be
   typeset in an outline font.}
  {\useMPgraphic{quotation}}
\stopbuffer

\typebuffer \getbuffer

The quality of the output depends on how the glyphs are
constructed. For instance, in \TEX, math symbols are
sometimes composed of glyph fragments and rules.

\startbuffer
graphictext
  "$$\sqrt{1+x}$$"
  scaled 8
  withdrawcolor .625red
  withpen pencircle scaled 1.5pt
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

This is not really a problem because we can also fill the
shapes. It is the reason why the fill is applied after the
draw and in such case the effective line width is half the
size specified.

\startbuffer
graphictext
  "$$\left({{\sqrt{1+x}}\over{\sqrt{2+x^2}}}\right)$$"
  scaled 4
  dashed evenly
  withdrawcolor .625red
  withfillcolor .850white
  withpen pencircle scaled 1.5pt
\stopbuffer

\typebuffer

In this example we also use a dashed line. Instead of normal
colors, we could have used shades or transparent colors.

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

Instead of supplying the text directly, you can use the
indirect method. This permits you to process rather complex
data without messing up your \METAPOST\ code.

\startbuffer
\startMPenvironment
  \usemodule[mathml]
\stopMPenvironment

\setMPtext {some math}%
  {\XMLdata
     {<math> <apply> <log/>
        <logbase> <cn> 2 </cn> </logbase>
        <apply> <plus/> <ci> x </ci> <ci> 1 </ci> </apply>
      </apply> </math>}}
\stopbuffer

\typebuffer \getbuffer

Here we feed some \MATHML\ into \TEX, which in turn shows up
as a \METAPOST\ graphic.

\startbuffer
graphictext
  \MPstring{some math}
  scaled 4
  withdrawcolor .625red
  withfillcolor .625white
  withpen pencircle scaled 1.5pt
\stopbuffer

\typebuffer

\startlinecorrection[blank]
\processMPbuffer
\stoplinecorrection

% \section {Patterns}
%
% {\em Like shades, patterns can be implemented using
% specials. Before I discuss this, I first have to sort out
% how this can be implemented in a comfortable way.}
%
% \section {Fonts}
%
% {\em This section will demonstrate how we can manipulate
% fonts in \METAPOST. Don't expect too much from this section.}

\stopcomponent
