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.
Drawing a Box
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). The conversion is simple,
we just multiply the number of inches by 72. This gives us the
function
/inch {72 mul} defTo 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 movetoAt 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 linetoWe 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 showpageYou can view and try the complete example, if you like.
Refinements
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 vertices 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 rlinetoThis 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 Shapes
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.
Shading and Width
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 it's 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.