Table of Contents
Stack based graphics Programming Language .
References
- https://en.wikipedia.org/wiki/PostScript
 - PostScript Reference Manual (archive.org) , the red book
 - PostScript Tutorial and Cookbook , the blue book
 - PostScript Language Program Design (archive.org) , the green book
 - PostScript Tutorial
 - GhostScript Output Devices , e.g. for generating PNGs
 - https://wiki.xxiivv.com/site/postscript.html
 - Mathematical Illustrations - A manual of geometry and PostScript
 - http://rosettacode.org/wiki/Category:Initlib
 - http://www.math.ubc.ca/~cass/courses/ps.html
 
REPL
- 
      
gs(in theghostscriptpackage) - 
      
gsnd(no graphical output, "no display") 
PostScript File
- 
      
%!in the beginning, to mark as PS file 
Syntax
- 
      Booleans:
      
true,false - 
      Numbers:
      
1,1.23 - 
      Arrays:
      
[1 2 3](note that there is no "," between elements) 
Moving Around
- 
      
moveto - 
      
rmoveto(relative) 
Drawing Lines
- 
      
lineto - 
      
rlineto(relative) - 
      
<n> setlinewidth 
Line Caps
      Controlled via the
      
       linecap
      
      variable,
      
       0
      
      by default.
     
      
       <n> setlinecap
      
     
- 0, no linecaps
 - 1, round linecaps
 - 2, square linecaps
 
Infinite Lines
      Given a line defined by the equation
      
      ,
     
newpath [a b c] mkline stroke
Example
I'm working on a page of size 1000 x 700.
newpath 100 100 moveto 800 0 rlineto stroke 10 setlinewidth newpath 100 200 moveto 800 0 rlineto stroke 20 setlinewidth newpath 100 300 moveto 800 0 rlineto stroke 30 setlinewidth newpath 100 400 moveto 800 0 rlineto stroke 1 setlinecap newpath 100 500 moveto 800 0 rlineto stroke 2 setlinecap newpath 100 600 moveto 800 0 rlineto stroke
     Polygons
Defining Paths
newpath % define path with "(r)moveto" and "(r)lineto" closepath fill
Function for Drawing Rectangles
/rectpath { 2 dict begin /y exch def /x exch def newpath 0 0 moveto x 0 rlineto 0 y rlineto x neg 0 rlineto closepath end } def /rect { rectpath fill } def
- 
       
<width> <height> rectpathcreates a rectangular path - 
       
<width> <height> rectdraws a filled rectangle 
Linejoin
      How lines join can be controlled via the
      
       linejoin
      
      variable,
      
       0
      
      by
default.
     
      
       <n> setlinejoin
      
     
- 0, no linejoin
 - 1, round linejoin
 - 2, square linejoin
 
Example
50 50 translate newpath 100 100 rectpath fill 200 0 translate 40 setlinewidth 100 100 rectpath stroke 200 0 translate 1 setlinejoin 100 100 rectpath stroke 200 0 translate 2 setlinejoin 100 100 rectpath stroke 200 0 translate 2 setlinejoin 100 100 rectpath gsave stroke grestore fill
     
      
       stroke
      
      and
      
       fill
      
      destroy the current path.
To stroke and fill a path at the same time,
we can save the graphics state before
      
       stroke
      
      it,
then restore it to
      
       fill
      
      .
     
Colors
- 
      
<gray> setgray - 
      
<r> <g> <b> setrgbcolor 
Example
% initial step limit 0 0.10 1 { % the current value is on top of the stack setgray rect 100 0 translate } for
     % initial step limit 0 0.10 1 { /g exch def gsave 0 0.10 1 { % the current value is on top of the stack g 1 setrgbcolor rect 100 0 translate } for grestore 0 100 translate } for
     Transformations
Moving and Scaling
Basic unit: points, 72 points per inch
- 
       
<sx> <sy> scaleto change the scale - 
       
<x> <y> translate 
Example
rect 200 0 translate gsave 0.5 1.0 scale rect grestore 200 0 translate gsave 1.0 0.5 scale rect grestore 200 0 translate gsave 0.5 0.5 scale rect grestore
      Rotation
- 
       
<deg> rotate 
Example
500 500 translate 28 { rectpath stroke 0.86 0.86 scale 10 rotate } repeat
      Mathematical Functions
Results are placed on the stack.
- 
      
<x> <y> add - 
      
<x> <y> sub - 
      
<x> <y> mul - 
      
<x> <y> div - 
      
<x> <y> idiv, integer division - 
      
<x> <y> mod - 
      
<x> neg, negation - 
      
<y> <x> atan, polar angle of - 
      
<x> sqrt - 
      
<x> sin - 
      
<x> cos - 
      
<x> <y> exp, - 
      
x ln, - 
      
x abs, absolute value - 
      
x round - 
      
x floor, - 
      
x ceiling, 
Comparison, Boolean Arithmetic
- 
      
eq()
 - 
      
lt,gt, (,
)
 - 
      
le,ge, (,
)
 
Manipulating the Stack
- 
      
exch, exchange top two items of stack to make themy x - 
      
pop, remove top item of stack - 
      
dup, duplicate item on top of stack - 
      
clear, clear the stack - 
      
=,==, removes and displays value on top of stack. according to a pdf I've read,==should be preferred - 
      
pstack, print stack contents without removing them - 
      
<n> <direction> roll, rotatenelements of the stack 
     
      TODO
     
     Find out Difference between
     
      =
     
     and
     
      ==
     
    
    Examples
- 
       
2 dup add->4 - 
       
4 2 div->2 - 
       
4 2 exch div->0.5 
Pages
- 
      
showpageto show & begin a new page 
Graphical State
Storing / Restoring
Contains scaling, translation, rotation etc.
- 
       
gsaveto save - 
       
grestoreto restore 
When working with multiple pages, the following combination might be useful:
gsave % draw page grestore showpage gsave % draw next page grestore showpage
The graphical state also includes unfinished paths and the current color.
To fill and stroke a shape:
- define a path
 - save the state
 - 
       
fillit - restore the state
 - 
       
strokeit 
TODO Current Position
Variables
     Variable names are written as
     
      /foo
     
     ,
     
      /bar
     
    
- 
      
/foo 1 defdefines a variablefoowith value1 
Variables stored in dictionaries placed on a dictionary stack (similar to variable environments in other languages).
To create a dictionary for 2 local variables (not 100% sure this is correct):
2 dict begin % ... end
     
      TODO
     
     What exactly is the effect of
     
      begin
     
     and
     
      end
     
     ?
    
    Procedures
/my-proc { % instructions } def
     Procedures are called by "inserting" the instructions between the
     
      {}
     
     .
    
Arguments can be passed to procedures through the stack. To bind them to variables inside the procedure, we can use the following trick:
/my-proc { /arg2 exch def /arg1 exch def % ... }
Combined with the pattern for local variables, this turns into
/my-proc { 2 dict begin /arg2 exch def /arg1 exch def % ... end }
Control Structures
If, If-Else
boolean { % ... } if
boolean { % ... } { % ... } ifelse
Repeat-Loop
N { % ... } repeat
For-Loop
initial step limit { % ... } for
The value is placed on top of the stack before the "body" is executed.
Forall-Loop
[a b c d] { % ... } forall
The "body" is executed once for each element of the array, which is placed on top of the stack.
Loop-Loop
{ % ... } loop
      
       exit
      
      breaks out of the loop.
     
Working with Arrays
- 
      
<array> aloadplaces all elements of<array>on the stackIt seems like it also places the array back on the stack so we have to remove it with
pop. 
Examples
/positions [ [50 30] [250 40] [450 50] [650 60] [850 70] ] def positions { gsave aload pop translate 100 100 rect grestore } forall
     Working with Text
- 
      
<text> stringwidth, pushes width & height oftextin the current font on the stack 
Page Size
<< /PageSize [1920 1080] >> setpagedevice curretpagedevice /PageSize get
PDF to GIF Conversion
convert -delay 10 input.pdf prison.gif
- 
      
-alpha offto disable transparency (white background) - 
      
-loop 0to loop the gif 
Other
- 
      
<n> string, create string ofncharacters - 
      
<ob> <str> cvs-> <str>, convert to string