CS 3723/3721
Programming Languages
Postscript Basics


Postscript:


Basic Topics (from the Blue Book):

  1. Three types of graphics objects:
    1. Text: characters in many fonts, positioned and oriented in any way.
    2. Geometric figures: Drawn using powerful 2-dimensional graphics operators, using lines, curves, filled regions, color.
    3. Images: anything that can be digitized.
    (See Blue Book, pages 1-2.)
  2. The imaging model:
    1. Current page: can place anything anywhere, overwriting old stuff
    2. Current path: a set of connected lines and curves making a path, often closed.
    3. Current clipping path: a closed path within which all drawing occurs.
    (See Blue Book, pages 2-3.)
  3. Initial graphics: (See Blue Book, pages 3-4.)
  4. The Stack: used for all computations and operators. Postfix notation. (See Blue Book, page 4, 7-15.)
  5. Coordinate systems: x (horizontal) and y (vertical) coordinates, with (0, 0) in the lower left corner. Units are Postscipt points, where 1 point = 1/72 inch (in actual publishing, 1 point = 1/72.27 inch.) (See Blue Book, Chapter 3, pages 17-25.)
  6. Variables and procedures: (It's getting harder now.) (See Blue Book, Chapter 4, pages 27-33.)
  7. Text: (See Blue Book, Chapter 5, pages 35-46.)
  8. More graphics: (See Blue Book, Chapter 6, pages 47-60.)
  9. Conditionals and for loops: (See Blue Book, Section 7.1 and first page of 7.2, pages 61-68.)
  10. Outline fonts: (See Blue Book, Section 9.4, pages 97-99.)
  11. Clipping: (See Blue Book, Section 10.1, pages 101-104.)


Example of overlapping boxes: This example is from the Blue Book, pages 23, 30, 31: three different Postscript programs produce exactly the same three overlapping boxes. The first program is basic Postscript with no functions. The second uses one function, while the third has three functions, each with parameters. Here are all three listings presented side-by-side, along with a fourth version that illustrates parameters (explained in the next section):

First Version Second Version Third Version Fourth Version
%!PS-Adobe-2.0
newpath % black
  252 324 moveto
  0 72 rlineto
  72 0 rlineto
  0 -72 rlineto
  closepath
  fill
newpath % dark
  270 360 moveto
  0 72 rlineto
  72 0 rlineto
  0 -72 rlineto
  closepath
  .4 setgray
  fill
newpath % light
  288 396 moveto
  0 72 rlineto
  72 0 rlineto
  0 -72 rlineto
  closepath
  .8 setgray
  fill
showpage % print
%!PS-Adobe-2.0
% Define box proc
/box
{ 72 0 rlineto
  0 72 rlineto
  -72 0 rlineto
  closepath } def
  
% Begin Program
newpath % black
  252 324 moveto box
  0 setgray fill
newpath % dark
  270 360 moveto box
  .4 setgray fill
newpath % light
  288 396 moveto box
  .8 setgray fill
showpage
%!PS-Adobe-2.0
% Define procedures
/inch {72 mul} def

/box  
 % stack: x y => ---
{ newpath moveto
  1 inch 0 rlineto
  0 1 inch rlineto
  -1 inch 0 rlineto
  closepath } def
  
/fillbox 
 % stack: gray => ---
{ setgray fill } def

% Main Program
3.5 inch 4.5 inch box
0 fillbox
3.75 inch 5 inch box
.4 fillbox
4 inch 5.5 inch box
.8 fillbox
showpage
%!PS-Adobe-2.0
% Define procedures
/inch {72 mul} def

/box  
 % stack: x y => ---
{ /y exch def % save
  /x exch def % save
  newpath x y moveto
  1 inch 0 rlineto
  0 1 inch rlineto
  -1 inch 0 rlineto
  closepath } def
  
/fillbox 
 % stack: gray => ---
{ setgray fill } def

% Main Program
3.5 inch 4.5 inch box
0 fillbox
3.75 inch 5 inch box
.4 fillbox
4 inch 5.5 inch box
.8 fillbox
showpage
Result: box1.pdf Result: box2.pdf Result: box3.pdf Result: box4.pdf


How to handle parameters: The "Cookbook" part of the Bluebook shows a simple way to handle parameters in Postscript. Ordinarily parameters are passed by pushing them on the stack, and there is no support in the language for normal formal/actual parameters. This is illustrated in the third "Box" program above: "box3.ps", where the procedure box gets x and y coordinates passed to it on the stack, for use one time by the moveto function. But suppose you wanted to use those parameters a second time? In Postscript it is always possible to use dup and rotate to arrange to put extra copies of the parameters on the stack, but it is much simpler (and makes programming easier) to save the input parameters into named variables where they can easily be used as often as needed. The fourth box program above illustrates this, with the necessary additions in bold red. In the first case, for example, the code /y exch def % save will push the name y on the stack, then exchange this name with the value for y, and finally use def to pop both these and give y the desired value.


Practice with translate, rotate, and scale: Consider the following Postscript code that lays out coordinate axes and numbers the four quadrants (1, 2, 3, 4). The function that does this leaves the origin at (0, 0). In order to show the figure, the code below translates the origin to (200, 200). This code also puts a standard border around the page. The following examples will only supply new code for the last few lines (shown in red below).

Postscript Program
%!PS-Adobe-2.0
/width 25 def
/outline { % print standard border on page
   /Times-Bold findfont 15 scalefont setfont
   newpath width width moveto
   0 792 width 2 mul sub rlineto
   612 width 2 mul sub 0 rlineto
   0 -792 width 2 mul add rlineto
   closepath stroke
   275 width 5 add moveto (Bottom of Page) show
   275 792 width sub 15 sub moveto (Top of Page) show
} def

/coord {
   /Times-Bold findfont 50 scalefont setfont
   20 20 moveto (1) show
   -50 20 moveto (2) show
   -50 -50 moveto (3) show
   20 -50 moveto (4) show
   3 setlinewidth
   newpath 0 60 moveto 0 -60 lineto stroke
   newpath 60 0 moveto -60 0 lineto stroke
} def
outline
%%%%%%% only change what comes after this comment %%%%%%
200 200 translate
coord
   
showpage
Result in: .ps, or as .pdf

Now keeping the same functions outline and coords, try some different instructions at the end and see what happens. In each case try to guess what the result will be first and then see what the result is. (I am leaving off the definition of the function and leaving off the final showpage.)

Substitute for red code Result
200 200 translate
rotate 90
coord
.ps, or as .pdf
rotate 90
200 200 translate
coord
.ps, or as .pdf
90 rotate
200 -200 translate
-90 rotate coord
.ps, or as .pdf
200 200 translate
90 rotate
2 2 scale
coord
.ps, or as .pdf
2 2 scale
200 200 translate
90 rotate
coord
.ps, or as .pdf
1 1 30 {
  pop % throw away loop variable
  300 150 translate
  45 rotate
  coord
  0.75 0.75 scale
} for % just loops 30 times
.ps, or as .pdf


The star example: This example uses rotate and translate in a clever way to draw a five-sided star: star.html.
More complex example: Here is a second example Postscript file, much more complicated than the first, stored using the filename abc3.ps:

Postscript Program
%!PS-Adobe-2.0
/path {            % path is the outline of the chars ABC
   /Times-Bold findfont 200 scalefont setfont
   newpath 0 0 moveto (ABC) false charpath
} def
  
/oneline {         % draw one line from the origin
   0 0 moveto 450 0 lineto stroke
} def

/lines {           % draw 180 lines at 1 degree rotations
   180 {1 rotate oneline} repeat 
} def

100 300 translate  % up to middle of page
3 setlinewidth     % thick lines
path stroke        % outline the characters
1 setlinewidth     % thin lines
path clip          % clip to inside of charactes
180 0 translate    % to middle of string
lines              % draw the lines inside the string
showpage           % actually render the page
Result in: abc3.ps, or as abc3.pdf


Other complex examples:


Revision date: 2004-03-19. (Please use ISO 8601, the International Standard Date and Time Notation.)