4

Is there any way to produce exactly following PS and SVG code with Metapost/Metafun? Unfortunately, unfill won't work for me, as there is a background in the resulting page. And this example is stripped down, as the real path is much more complex.

Desired postscript output:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 100 100
%%BeginProlog
%%EndProlog%%Page: 1 1
newpath 0 100 moveto 100 100 lineto 100 0 lineto 0 0 lineto 0 100 lineto closepath
        10 90 moveto 10 10 lineto 90 10 lineto 90 90 lineto 10 90 lineto closepath
fill         
%%EOF

Desired SVG output:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="125" height="125">
 <g transform="matrix(1.25,0,0,-1.25,0,125)">
  <g transform="scale(0.1,0.1)">
   <path d="m 0,1000 1000,0 L 1000,0 0,0 0,1000 z m 100,-100 0,-800 800,0 0,800 -800,0" id="3"
         style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
  </g>
 </g>
</svg>
  • Welcome to TeX.SX. I don't know enough about postscript to answer the question but these look like two closed paths to me so it should be possible in MetaPost. Another option is TikZ. Having used both MetaPost and TikZ, I'd recommend the latter. – user10274 Dec 23 '13 at 13:04
  • 2
    Thank you. I like TikZ a lot but it's slow as heck compared to Metapost which kind of irritates me. – Alexey Naidyonov Dec 23 '13 at 14:18
2

There's a standard trick to do this in MetaPost. I decided to include the solution because MetaPost's unfill really doesn't unfill anything but fills with the background colour.

The following shows the solution.

beginfig( 0 )

path clockwisepath, anticlockwisepath;
clockwisepath := (0,100) -- (100,100) -- (100,0) -- (0,0) -- (0,100) -- cycle;
anticlockwisepath := (10,90) -- (10,10) -- (90,10) -- (90,90) -- (10,90) -- cycle;

fill clockwisepath -- anticlockwisepath -- cycle;

endfig;

end.

The following is the produced eps:

%!PS
%%BoundingBox: 0 0 100 100 
%%HiResBoundingBox: 0 0 100 100 
%%Creator: MetaPost 1.902
%%CreationDate: 2014.12.19:1511
%%Pages: 1
%%BeginProlog
%%EndProlog
%%Page: 1 1
 0 0 0 setrgbcolor
newpath 0 100 moveto 100 100 lineto 100 0 lineto 0 0 lineto 0 100 lineto
        0 100 lineto 10 90 lineto 10 10 lineto 90 10 lineto 90 90 lineto
        10 90 lineto 10 90 lineto
 closepath fill
showpage
%%EOF

Note that the code doesn't produce the exact same eps but for filling it really doesn't matter.

  • 1
    Thank you! That time I solved my problem with TikZ, now I have to update the code and I think I'll switch back to metapost now when I know the solution. – Alexey Naidyonov Sep 16 '15 at 10:10
2

Fill and unfill:

%% naid.mp
u:=1bp;
beginfig(1);
fill (0,0)--(100u,0)--(100u,100u)--(0,100u)--cycle;
unfill (10u,10u)--(90u,10u)--(90u,90u)--(10u,90u)--cycle;
endfig;
end.

Here is the output of mpost naid.mp:

%!PS
%%BoundingBox: 0 0 100 100 
%%HiResBoundingBox: 0 0 100 100 
%%Creator: MetaPost 1.803
%%CreationDate: 2013.12.23:1356
%%Pages: 1
%%BeginProlog
%%EndProlog
%%Page: 1 1
 0 0 0 setrgbcolor
newpath 0 0 moveto
100 0 lineto
100 100 lineto
0 100 lineto
 closepath fill
 1 1 1 setrgbcolor
newpath 10 10 moveto
90 10 lineto
90 90 lineto
10 90 lineto
 closepath fill
showpage
%%EOF

and here is the output of

mpost '\outputformat:="svg";outputtemplate:="%j-%c.svg";input naid.mp'

in file naid-1.svg

<?xml version="1.0"?>
<!-- Created by MetaPost 1.803 on 2013.12.23:1445 -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100.000000" height="100.000000" viewBox="0 0 100.000000 100.000000">
<!-- Original BoundingBox: 0.000000 0.000000 100.000000 100.000000 -->
  <path d="M0.000000 100.000000L100.000000 100.000000L100.000000 -0.000000L0.000000 -0.000000Z" style="fill: rgb(0.000000%,0.000000%,0.000000%);stroke: none;"></path>
  <path d="M10.000000 90.000000L90.000000 90.000000L90.000000 10.000000L10.000000 10.000000Z" style="fill: rgb(100.000000%,100.000000%,100.000000%);stroke: none;"></path>
</svg>
  • I mentioned that unfill won't work for me as it would create another figure filled with white, which is not exactly what I need. – Alexey Naidyonov Dec 23 '13 at 14:14
  • Thank for the command line example nevertheless, nice to know this trick! – Alexey Naidyonov Dec 23 '13 at 14:15
1

I've never used Metapost, but since Asymptote is based on it, an Asymptote answer might possibly help someone figure out a Metapost answer.

Make a file foo.asy with the following contents:

fill((0,100)--(100,100)--(100,0)--(0,0)--cycle ^^ (10,90)--(10,10)--(90,10)--(90,90)--cycle);

Running asy foo.asy from the command line then gives an eps file foo.eps with the following contents (modulo some obvious differences, e.g., creation time):

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 255 345 356 446
%%HiResBoundingBox: 255.5 345.5 355.5 445.5
%%Creator: Asymptote 2.23
%%CreationDate: 2013.12.23 10:10:49
%%Pages: 1
%%Page: 1 1
/Setlinewidth {0 exch dtransform dup abs 1 lt {pop 0}{round} ifelse
idtransform setlinewidth pop} bind def
gsave
 255.5 345.5 translate
newpath 0 100 moveto
 100 100 lineto
 100 0 lineto
 0 0 lineto
 0 100 lineto
closepath
 10 90 moveto
 10 10 lineto
 90 10 lineto
 90 90 lineto
 10 90 lineto
closepath
0 setgray
0.5 Setlinewidth
1 setlinecap
1 setlinejoin
10 setmiterlimit
fill
grestore
showpage
%%EOF

The result as a graphic:

enter image description here

  • Brilliant! This is exactly what I need. Unfortunately neither Metapost nor Metafun offer anything like path ^^ path operator. I still have hope that I'm just missing it, though :) – Alexey Naidyonov Dec 23 '13 at 18:02
  • @AlexeyNaidyonov: I don't know if it would help you find what you need, but the path ^^ path ("lift pen") operator in Asymptote actually produces an array of paths rather than a single path. For this "stripped-down" example, you might also try filling the region bounded by the simple path (0,100)--(100,100)--(100,0)--(0,0)--(0,100)--(10,90)--(10,10)--(90,10)--(90,90)--(10,90)--cycle, but I don't know if that would work for the "real" example. – Charles Staats Dec 23 '13 at 19:08
  • @AlexeyNaidyonov what with the path -- path construction of MetaPost? – Franck Pastor May 12 '14 at 8:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.