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 theghostscript
package) -
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> rectpath
creates a rectangular path -
<width> <height> rect
draws 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> scale
to 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
, rotaten
elements 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
-
showpage
to show & begin a new page
Graphical State
Storing / Restoring
Contains scaling, translation, rotation etc.
-
gsave
to save -
grestore
to 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
-
fill
it - restore the state
-
stroke
it
TODO Current Position
Variables
Variable names are written as
/foo
,
/bar
-
/foo 1 def
defines a variablefoo
with 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> aload
places 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 oftext
in 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 off
to disable transparency (white background) -
-loop 0
to loop the gif
Other
-
<n> string
, create string ofn
characters -
<ob> <str> cvs
-> <str>, convert to string