For example, the following PostScript program:
How to do that will be explained here.
PostScript is an interpreted language, i.e. there is a interpreter
reading the source text (PostScript) and executing it. One such
interpreter is e.g. ghostscript. ghostscript can be invoked
by the command gs
.
For example:
$gs smily.ps |
smily.ps
on the screen.
You can use ghostscript also interactively.
Especially while learning PostScript this is very useful.
You use the command gs
without a file name
and get:
$gs AFPL Ghostscript 7.04 (2002-01-31) Copyright (C) 2001 artofcode LLC, Benicia, CA. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. GS> |
PostScript pushes data on a stack. Operators take operands from the stack and put results back on the stack
The following example uses the data 10
and 5
as well as the operator mul
(Multiplication).
The operator stack
can be used to display the stack
The number if entries on the stack is indicated in pointed brackets.
GS> 10 GS<1> stack 10 GS<1> 5 GS<2> stack 5 10 GS<2> mul GS<1> stack 50 GS<1> |
These are the most important arithmetic operators:
Arguments | Name | Description |
x y | add | x + y |
x y | sub | x - y |
x | neg | - x |
x y | mul | x * y |
x y | div | x / y |
x y | idiv | int(x / y) |
x y | mod | x modulo y |
x | sin | sin(x) |
x | cos | cos(x) |
x y | atan | arctan(x /y) |
x | sqrt | square root(x) |
Arguments | Name | Description |
x y | gt | x greater than y |
x y | lt | x less than y |
x y | ge | x greater or equal than y |
x y | le | x less or equal than y |
x y | eq | x equal to y |
x y | ne | x not equal to y |
true | true | |
false | false | |
x | not | not x |
x y | and | x and y |
x y | or | x or y |
Arguments | Name | Description |
x | dup | x x (duplicating x) |
x1...xn n | copy | x1...xn x1...xn (duplicating n elements) |
x y | exch | y x (swap x and y) |
x | pop | delete x from the stack |
n | index | copy the n-th entry to the top of the stack |
Arguments | Name | Description |
n | array | creates a Array with n Elements |
a i | get | push element i of Array a on the stack |
a i x | put | store x at position i in the array a |
a | length | push the length of array a on the stack |
Example: the procedure {20 add}
is put on the stack and executed by the operator exec
GS>10 GS<1>{20 add} GS<2>stack --nostringval-- 10 GS<2>exec GS<1>stack 30 |
Arguments | Name | Description |
p | exec | execute procedure p |
b p | if | if b is true execute procedure p |
b p q | ifelse | if b is true execute procedure p else execute procedure q |
n p | repeat | execute procedure p n-times |
a s e p | for | for all values from a to e with step s, put the value on the stack and the execute procedure p. |
a p | forall | execute procedure p for all elements of array a |
p | loop | repeat procedure p forever |
exit | exit innermost procedure |
newpath
and ends either with the operator stroke
(Line) or fill
.
Several paths can be placed one after the other on a page. Finally,
the command showpage
will clear the page again and
advances to the next page for multi page documents.
A path can be constructed with the following operators:
Arguments | Name | Description |
newpath | start a new path | |
stroke | finish the path and draw a line | |
closepath | closes the path from the current point to the beginning | |
fill | finish the path and fill the interior. | |
x y | moveto | move the current position to x,y |
x y | lineto | continue the path from the current position to x,y |
x y | rmoveto | move the current position (relative) by x,y |
x y | rlineto | continue the path (relative) from the current position by x,y |
x y r a e | arc | continue the path with an arc from angle a to angle e with a center at x y and radius r |
x1 y1 x2 y2 x3 y3 a e | curveto | make a Bezier Curve to x3 y3. |
setlinewidth
or setrgbcolor
.
Then there are commands to change the origin of the coordinate system
(translate
), to scale it (scale
) or
to rotate it (rotate
).
The best, however, is that you can save (gsave
) and
restore (grestore
) the state of the machine on a separate
stack. This allows nesting of command sequences.
Another interesting feature is clipping (which is beyond the scope of this simple summary).
Arguments | Name | Description |
w | setlinewidth | set the linewidth for stroke |
r g b | setrgbcolor | set the rgb color; r, g, and b values are in the range 0.0 to 1.0 |
x y | translate | set the origin of the coordinate system |
x | rotate | rotate the coordinate system by x degree counterclockwise |
fx fy | scale | scale the coordinate system with a factor for the x and a factor for the y direction |
gsave | save the graphics state | |
grestore | restore the graphics state | |
currentpoint | put the current x and y coordinate on the stack |
/counter
.
A simple command is def
.
It takes a name and a value from the stack and stored the value under this name
in the dictionary. You can put the value back on the stack simply by writing
the name without the slash.
For example:
GS>/counter 50 def GS>counter GS<1>stack 50 |
You can create your own dictionaries by using the command dict
.
This command takes the initial size of the dictionary from the stack,
creates a dictionary and puts it back on the stack.
To store a value you can use the command def
.
It stores the name value pair in the current dictionary.
PostScript uses a separate stack for dictionaries.
The command def
always uses the topmost dictionary on this stack.
To look up a value, PostScript will search the whole stack from top
to bottom to find a suitable name-value pair.
To manage the dictionary stack there are two commands: begin
and end
.
The command begin
takes a dictionary from the value stack and puts it on the dictionary stack.
The command end
removes the topmost dictionary from the
dictionary stack.
For example:
GS>/hallo 111 def GS>hallo GS<1>5 dict begin GS<1>/hallo 222 def GS<2>hallo GS<2>end GS<3>hallo GS<3>stack 111 222 111 |
Another important command in this context is the
store
command. It works similar to def
It needs a name and a value and stores the value under the given name.
def
, however, always uses the topmost dictionary, creating
an entry if necessary, while store
searches the whole
dictionary stack from top to bottom for a matching name. Only if no entry is found,
a new entry is created in the topmost dictionary.
Arguments | Name | Description |
i | dict | creates a dictionary with i entries |
d | begin | moves dictionary d to the dictionary stack |
end | removes the topmost dictionary from the dictionary stack | |
n x | def | stores value x under name n in the topmost dictionary |
n x | store | searches the dictionary stack for name n and stores x there if n is found. otherwise like def |
Dictionaries can also be specified explicitly. You can keep dictionaries in variables (inside other dictionaries) for that purpose and use the following commands.
Arguments | Name | Description |
d n w | put | store value w under name n in dictionary d |
d n | get | get the value of name n in dictionary d, and put it on the stack |
Example:
GS>/mydict 10 dict def GS>mydict /x 123 put GS>mydict /x get GS<1>stack 123 |
Fonts and Strings are data types. Fonts are created with the operator findfont
and literal strings are created by enclosing character sequences
in parentheses.
Arguments | Name | Description |
n | findfont | searches for a font with name n and puts it on the stack |
f i | scalefont | takes font f and number i, scales the font to i point size and puts it back on the stack |
f | setfont | takes font f from the stack and makes it the current font |
s | show | takes a string s from the stack and draws it using the current font |
GS>/Helvetica findfont Loading Helvetica ... GS<1>36 scalefont GS<1>setfont GS>100 100 moveto GS>(Hello world!) show |
%!PS
.
Every PostScript File should start with this comment,
to enable programs processing it to handle it properly.
Other special comments are commonly used at the
beginning of a PostScript file to ease processing.
For example:
%!PS-Adobe-2.0 %%Creator: I myself, Copyright 2005 Martin Ruckert %%Title: The explanation file %%Pages: 5 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 |