PostScript is a domain-specific language for describing the intended output of printers, i.e., by explaining how to draw the contents on each printed page.
The following video shows a very simple pic diagram being drawn. (The red circle marks PostScript's current page position, which is initially undefined.)
You will see that PostScript uses a two-step process: first a path is defined (paths don't need to be continuous), and separately we ask PostScript to draw that path onto the page.
PostScript has many other commands for creating paths in addition to lineto
.
Here we demonstrate
rlineto
, where you specify the relative location of the far end rather than the absolute position, andclosepath
, which draws a line back to the position of the most recent moveto
. (This is always the preferred final step if you are drawing a closed figure.)If the path you've defined describes a closed figure (particularly if you
finished with closepath
), then instead of drawing the path
on the page with stroke
you
can fill
the interior:
The arc
command is used to draw complete and partial circles; it requires the center of the circle, the radius, and the starting and ending angles of the arc. The resulting path
can be displayed with stroke
or fill
.
Warning: though not apparent from this demo, the arc
command actually starts by drawing a straight line from the current position on the page to the start of the arc! If you don't want this line, either use arc
immediately after newpath
(so there isn't yet a "current position"), or use moveto
to preset the current position to the point where you calculate the arc will start.
Just like the RPN example in Assignment 2, the PostScript language evaluates expressions using a stack. (It's not using the stack, i.e., the program stack used for function calls and returns; it's just using a stack.) Stack-based languages like PostScript are sometimes referred to by the slightly more general term "concatenative" programming language.
So, you will not be surprised to learn that the PostScript code
6 5 3 sub mulhas the effect of pushing 12 on the stack: first the numbers 6, 5, and 3 are successively pushed onto the stack (the “push” is implicit when a constant is mentioned), then the top two (5 and 3) are subtracted (obtaining 2), and then 6 and 2 are multiplied.
The stack can hold any PostScript values, including numbers and strings;
strings in PostScript are delimited with parentheses instead of quotes,
e.g., (Hello!)
.
All PostScript commands take their arguments, if any, on the stack. For
example, the lineto
command pops exactly two values off the stack and uses them as
(x,y) coordinates, while the arc
command pops five values off the stack.
It follows that the
sequence 2 3 moveto 5 4 lineto
does the same thing as the sequence
5 4 2 3 moveto lineto
(especially since PostScript also doesn't care about line breaks or indentation).
One useful feature of PostScript is the ability to modify the entire coordinate system used when defining paths. The following video demonstrates how moving the axes on the page changes how the same filled-triangle code shows up on the page.
The green circle in these next two videos marks the origin, the location of point (0,0). By default, this is the lower-left corner of the page.
The position of this origin is important for two reasons:
You can move the position of the origin on the paper by using translate
, as shown
in the next video.
We can use gsave
and grestore
to save and
restore the PostScript graphics context. This can be useful for
temporarily modifying the coordinate system.
The order of coordinate transformations matters; compare the previous video with this next video.
In general, getting the order wrong can lead to paths being drawn in the wrong place — possibly even outside the boundaries of the page (and disappearing).
Note: in addition to translate
and rotate
, there's a
corresponding two-argument operation scale
. The command
a b scale
makes everything you draw a
times bigger in the x direction and b times bigger in the y
direction. (If a or b are less than 1, then in that
direction your drawings will come out smaller than
smaller than specified.) You probably won't need this for the assignment, though
it can be fun to play around with.
In fact, the videos above are all slightly misleading. By default PostScript measures
all dimensions in points, where 1 points is 1/72 of an inch. So really
to move to a point 2 inches to the right of the bottom corner and 3
inches up, we would say 144 216 moveto
.
For our purposes, measurements in inches are more convenient. We can
do this as long as our PostScript code begins 72 72 scale
.
The provided code for the Lab and the Assignment both ensure
this scaling happens before any of your PostScript code.