How can I draw a path that fills the whole page in Postscript?

334 views Asked by At

I want to create an image in postscript that has a transparent hole in it, like this one:

Desired image, with transparent hole

The best solution I can think of was to create a clipping path that fills the while page except for the hole, like this:

Clipping path

My current postscript code for all of ths is as follows:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 100 100
%%Pages: 1
%%EndComments
%%EndProlog


% Create clipping path

newpath
-200 -200 moveto
 200 -200 lineto
 200  200 lineto
-200  200 lineto
closepath
70 50 moveto
60 50 10 360 0 arcn
closepath
clip

% Draw rest of the image
% In the actual image I am working on this rest of the image
% has a bunch of complex shapes.

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath

0 0.5 0.5 setrgbcolor
fill

The part that bothers me in my solution is that to draw the clipping path I had to draw a large rectangle that was larger than the whole page, with some a hardcoded large coordinates (-200 to +200). Is there a better way to do this?

I would have preferred to just be able to tell postcript to paint outside the circle centered at 60 50 for the clipping path, without needing to create the large rectangle that creates everything. Is that possible?

If that isn't possible, I would have at least preferred a way to create the large rectangle without relying on hardcoded coordinates, perhaps by querying the coordinates of the corners of the image. Is there a way to do that?

1

There are 1 answers

4
KenS On BEST ANSWER

OK firstly you need to be careful with your terminology, an 'image' in PostScript is a bitmap (see the image operator) so when you talk about an image, anyone who understands PostScript thinks in terms of a bitmap.

Secondly, that you are creating an EPS here, not a full PostScript program, and so you absolutely should not mess with full pages, the results will not likely be what any user might expect. By writing outside the BoundingBox declared by your EPS you are making it invalid. In practice most applications will put a 'clip' round your EPS matching its BoundingBox, but that doesn't mean you should rely on it.

Moving on from there; do you need the filled region to cover the whole page ? If so then yes, you need to create a clip which also covers the whole page. Or more accurately, the whole bounding box of your EPS. However, if the clip is only required to match the size of a given object, then you only need to draw it the size of the object.

I can't see why this:

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath
70 50 moveto
60 50 10 360 0 arcn
closepath
clip

newpath
20 20 moveto
66 20 lineto
66 70 lineto
20 70 lineto
closepath

0 0.5 0.5 setrgbcolor
fill

wouldn't give the same result as setting a clip for the entire page (and indeed, it does for me).

Obviously you would want to wrap that in a gsave/grestore pair so that you can undo the clip afterwards.

To answer the actual question; if you were writing a full PostScript program, you would expect to issue a media size request yourself, matching the media required for the document. So you would already know the media size. However, in language level 2 or 3 you can always ask the interpreter for the current media size:

currentpagedevice /PageSize get

will return an array with two members, the width and height of the currently selected media, in PostScript units.

Off the top of my head I can't remember how to retrieve the media size in level 1 PostScript, but really you shouldn't have to worry about that.