Eric Weeks - personal pages - graphics techniques

How to do simple PostScript commands - Part I

[home] [research]
[software] [pics]
[misc] [about me]

weeks@physics.emory.edu

This is a brief tutorial on the simplest PostScript commands. You can either make a PostScript file by hand using any text editor, or more likely you will write a program which produces PostScript output.

Step One -- first line of file

The top of your PostScript file should say:

%!PS

This tells the printer that what follows is a PostScript file, and not ordinary text. NOTE: some MS-DOS programs that produce PostScript files will put a control-D character before the %!PS characters. This causes the entire file to be interpreted as plain text by most UNIX-based printers. If you have a problem printing a file made by a MS-DOS program, check to see if the control-D character is there, and if so, remove it. The FIRST characters the printer sees MUST be %!PS.


Step Two -- rescale the page

PostScript normally uses units of "points" for placing graphics on the page. I find it more convenient to work with centimeters. I got the following snippet of PostScript code from a public domain program called "GLE" which I believe is available at any large ftp site; I recommend this graphics program. By examining the PostScript output of that program I collected the following piece of PostScript code:

matrix currentmatrix /originmat exch def /umatrix {originmat matrix concatmatrix setmatrix} def [28.3465 0 0 28.3465 10.5 100.0] umatrix

What this basically does is rescale the page so that now all following commands will work as if the centimeter is the basic unit of length. This places (0,0) near the bottom left of the page and (21,24) near the top right of the page.

If you don't do this, then (0,0) is the bottom left corner of the page and (612,792) is the top right corner of the page (if you are using an 8 1/2 inch by 11 inch sheet of paper). These are the default PostScript units; 72 of these to an inch. 28.3465 to a centimeter, thus the numbers above in the last line of PostScript code.


Step Three -- make a line

Making lines on the page has several parts. Initially, you set the line width. Next, move to the start of the line; then move to the various points you want the line to be drawn through; then set the color of the line; finally tell PostScript to draw the line.

This generates code looking like the following:

0.1 setlinewidth 2 2 newpath moveto 3 3 lineto 3 4 lineto 2 4 lineto 0 setgray stroke

This produces a picture that looks like this:

The commands are fairly self-explanatory. The "stroke" command at the end is what tells PostScript to actually draw the line; without this command PostScript will not print anything. (This is useful later if you want to make a shape and fill it, but not draw the outline.) The "0 setgray" command specifies a black line; for white lines use "1 setgray", and for gray lines use a number between 0 and 1.

Each point is connected to the previous one by a straight line, so to draw curved lines you need to specify lots of points on the line. Generally I find specifying new points every 0.02 cm or so is perfectly fine and will produce smooth looking curves.

If you want to attach the last point to the first point, use the command "closepath" at the end of the line description:

0.1 setlinewidth 2 2 newpath moveto 3 3 lineto 3 4 lineto 2 4 lineto closepath 0 setgray stroke


Step Four -- finish the file

When you draw a line, the line isn't actually drawn in PostScript's mind until you have a "stroke" command. Similiarly, the PostScript page isn't actually printed until you have a "showpage" command. Put this at the end of your PostScript file.

Thus, a complete PostScript file looks like:

%!PS matrix currentmatrix /originmat exch def /umatrix {originmat matrix concatmatrix setmatrix} def [28.3465 0 0 28.3465 10.5 100.0] umatrix 0.1 setlinewidth 2 2 newpath moveto 3 3 lineto 3 4 lineto 2 4 lineto closepath 0 setgray stroke showpage

Click here if you would like to get a copy of this PostScript file.


Step Five -- drawing lots of lines

If you want to draw lots of lines on the page, just repeat the above process. The command "newpath" tells PostScript you're starting a new line. If you just use "moveto" without "newpath" then it thinks you're drawing the same line, although the next point on the line isn't connected to the last point. ("moveto" is picking the pen up and putting it down somewhere else; "lineto" is moving the pen while it is on the page.) If you don't use "newpath" then you can use a single "stroke" command to draw all the lines on your page at once:

0.1 setlinewidth 2 2 newpath moveto 3 3 lineto 3 4 lineto 2 4 lineto 5 3 moveto 6 4 lineto 7 2 moveto 8 4 lineto 0 setgray stroke

Generally you want to start each line separately, so in general use "newpath moveto" every time you start a new line. This is less important when you're just drawing simple lines, but has more important consequences when you start filling polygons that you've drawn. Note that the "stroke" command has the same affect as "newpath"; PostScript uses stroke to draw the line and then forget about it.

If you want all of the lines to be the same color, you can just specify the color once at the very beginning of the file.


Step Six -- compressing the file

In order to make your PostScript file smaller, you will probably want to create some simple one or two letter aliases for some common commands. For example, if you are going to make a picture with 300,000 small straight lines (something which I have done for some of my pictures) it's much easier to have one letter commands instead of saying "newpath moveto" 300,000 times.

At the top of your PostScript file, after the %!PS line, you can start defining some simple commands. To draw lines you will need the following commands:

/m {newpath moveto} bind def /l {lineto} bind def /cp {closepath} bind def /s {stroke} bind def /sg {setgray} bind def

The "bind def" defines the alias; the phrase in { braces } is the definition, and the alias itself is the letter(s) that follow the / symbol. Thus if you use "m" in your PostScript file it actually means "newpath moveto". So the final version of the PostScript file will look like:

%!PS /m {newpath moveto} bind def /l {lineto} bind def /cp {closepath} bind def /s {stroke} bind def /sg {setgray} bind def matrix currentmatrix /originmat exch def /umatrix {originmat matrix concatmatrix setmatrix} def [28.3465 0 0 28.3465 10.5 100.0] umatrix 0.1 setlinewidth 2 2 m 3 3 l 3 4 l 2 4 l cp 0 sg s showpage

Click here if you would like to get a copy of this PostScript file.


Final words of wisdom

Like most computer languages today, PostScript does not care what you do with whitespace (spaces, new lines, blank lines, tabs, etc.). Put them in however you want.

In general, there's no reason not to do the rescaling of the page every time you make a new PostScript file, and also the creation of the aliases. I just copy the same chunk of PostScript code into every C program I write that has to produce PostScript output.

If you look at some of my programs, you might see some extra stuff at the beginning and end of the file; this stuff is superfluous and unneeded (but does not cause any problems). So if you see examples in some of my programs that look slightly different from what I explained above, don't panic; I didn't leave anything out of the above explanation.

Technically, I belive the "aliases" are really called "procedure definitions".

You're in good shape now; you can do a lot with just drawing lines! If you'd like to learn more, click below on "More PostScript commands" for more information on simple PostScript commands: using color, drawing circles, filling shapes that you've drawn.

More PostScript commands

Links...


Current address:
Eric R. Weeks
weeks(circle a)physics.emory.edu
Department of Physics
Emory University
Atlanta, GA 30322-2430