The main purpose of PostScript is to draw graphics on the page. One of the elegant aspects of PostScript is that even text is a kind of graphic. The main task that must be mastered, then, is constructing paths which may be used to create the image.
To draw and fill shapes, the basic sequence is:
This basic sequence can be modified to do more complicated things as we will see later.
In this first example, we will draw a square inch box toward the lower left corner of the page. We start off by defining a function to convert inches into PostScript's main unit, the point (a point is defined in PostScript as 1/72th of an inch, which is slightly shorter than a true printer’s point of 1/72.27 inch). The conversion is simple, we just multiply the number of inches by 72. This gives us the function
/inch {72 mul} def
To actually draw the square, we start a new path and move the current point to a point an inch in from both margins. This is accomplished with the code:
newpath 1 inch 1 inch moveto
At this point, the path contains only the point (72, 72). We add in line segments leading away from this point with the lineto operator. This operator adds a line segment from the current point to the point specified to lineto and makes that point the new current point. We can build three sides of the box as follows:
2 inch 1 inch lineto 2 inch 2 inch lineto 1 inch 2 inch lineto
We can add the last line by telling PostScript to close up the path with the smallest possible line segment. The closepath operator does this. This operator is especially useful if you need a closed figure for filling. Once we have closed the path, we can draw it with the stroke operator. We finish off the example by ejecting the page (if you are using a printer). PostScript ejects a page with the showpage operator:
closepath stroke showpage
You can view and try the complete example, if you like.
The lineto operator works in absolute coordinates within user space.
That is, 72 72 lineto
adds a line segment from the current point
to the point (72, 72) in user space. In drawing the box, however, it is
more convenient to ignore the absolute coordinates of the box's vertexes
and think instead of the lengths and directions of its sides. Fortunately,
PostScript provides a version of lineto which takes relative coordinates
instead. This is the rlineto
operator. rlineto adds the coordinates given as operands to the coordinates
of the current point in the path to find the destination point. That is,
10 20 rlineto
will draw a line from the current point to a point
10 points to the right and 20 points toward the top of the page. This is
in contrast to 10 20 lineto
which adds a line segment which always
ends at (10, 20).
To see how we can use rlineto, let's replace the lineto lines in the last example with the following code:
1 inch 0 inch rlineto 0 inch 1 inch rlineto -1 inch 0 inch rlineto
This new example will draw the same figure, but it draws the lines using relative coordinates instead of absolute. This makes it a little easier to visualize and has the added benefit that the same code can draw the three lines at a different location. Note that a negative relative x coordinate moves the point in the left direction while a negative relative y coordinate moves the point down the page.
Filling a shape is just as easy as drawing it. You create the path using the standard path creation operators, but instead of calling stroke at the end, you invoke the fill operator. The fill operator will fill the path with the current ink settings. If you want to fill a shape with a pattern, you will need to do some special tricks which we will cover later. We will use the box from above as an example, but we replace the original invocation of stroke with fill.
Fill uses a simple winding rule (which is described in the Programming Language Reference Manual) to determine what parts of the page are inside or outside the path. The regions that are inside are painted. Note that arbitrarily complex shapes can be filled with this operator so long as you have enough memory on your PostScript interpreter. You can easily fill in different shades and even some patterns, but to fill an area with a complex image takes some special effects which we will cover later.
In PostScript, you can view lines as being drawn by pens that have a given width and ink as having particular shades. You are not restricted to completely black ink and one-point wide lines. PostScript provides two handy operators to change these characteristics.
The setgray operator sets the intensity of the ink used in drawing lines and filling shapes (actually, setgray affects all subsequent markings made on the page). setgray takes a single numerical argument between 0 and 1. “0” signifies black, and “1” signifies white. Numbers between these two values signify various shades of gray.
The setlinewidth operator does just what its name suggests: it sets the width of lines to be drawn. It takes a single numerical argument which is the width of the line in points. setlinewidth affects all lines stroked after the operator is invoked.
Both of these operators affect the markings placed on the page after they are called... they do not effect the path until it is stroked or filled. In particular, you can not set the width or gray level for one part of the path and then change it for another... they are the same for all parts of the path, since it is stroked or filled only once. Also, both of these operators affect part of the graphics state and can be saved with gsave and restored with grestore.
I have worked up an example using both these operators. I also demonstrate how you can use gsave and grestore to control the graphics state.