Zum Beispiel das folgende PostScript Programm:
Wie das geht wird im folgenden kurz erklärt.
PostScript ist eine interpretierte Sprache, d.h.
es existiert ein Interpreter, der den Quelltext
(PostScript) einliest und direkt ausführt.
Ein solcher Interpreter ist zum Beispiel ghostscript.
Ghostscript wird aufgerufen durch den Befehl gs
.
Zum Beispiel ergibt
$gs smily.ps |
smily.ps
am Bildschirm.
Ghostscript kann aber auch interaktiv verwendet werden. Dies ist besonders
zum Kennenlernen der Programmiersprache sehr nützlich.
Man ruft dazu das Kommando gs
ohne eine Eingabedatei auf.
So ergibt sich:
$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> |
Die Daten werden von PostScript auf einem Stack abgelegt. Operationen nehmen ihre Operanden vom Stack und legen das Ergebnis wieder auf dem Stack ab.
Das folgende Beispiel verwendet die Daten 10
und 5
und die Operation mul
(Multiplikation).
Die Operation stack
dient um Anzeigen des Stack.
Die Anzahl der Elemente auf dem Stack wird nach der Eingabeaufforderung
in spitzen Klammern angezeigt.
GS> 10 GS<1> stack 10 GS<1> 5 GS<2> stack 5 10 GS<2> mul GS<1> stack 50 GS<1> |
Argumente | Name | Beschreibung |
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 | Wurzel(x) |
Argumente | Name | Beschreibung |
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 | wahr | |
false | falsch | |
x | not | nicht x |
x y | and | x und y |
x y | or | x oder y |
Argumente | Name | Beschreibung |
x | dup | x x (dupliziert x) |
x1...xn n | copy | x1...xn x1...xn (dupliziert n Elemente) |
x y | exch | y x (exchange, tauscht x und y) |
x | pop | entfernt x vom Stack |
n | index | kopiert den n-ten Eintrag des Stacks auf den Stack |
Beispiel: die Prozedur {20 add}
wird auf den Stack gelegt und durch exec
ausgeführt.
GS>10 GS<1>{20 add} GS<2>stack --nostringval-- 10 GS<2>exec GS<1>stack 30 |
Argumente | Name | Beschreibung |
p | exec | führe Prozedur p aus |
b p | if | falls b wahr so führe Prozedur p aus |
b p q | ifelse | falls b wahr so führe Prozedur p aus sonst q |
n p | repeat | führe Prozedur p n-mal aus |
a s e p | for | für alle Werte von a bis e mit Schrittweite s lege jeweils den Wert auf den Stack und führe die Prozedur p aus. |
p | loop | Wiederhole Prozedur p endlos |
exit | Beende die innerste Prozedur |
newpath
und endet entweder
mit dem Befehl stroke
(Linie) oder fill
(Füllen).
Mehrere Pfade können so nacheinander auf einer Seite platziert werden.
Mit dem Befehl showpage
wechselt man bei mehrseitigen Dokumenten
zur nächsten Seite.
Pfade baut man (unter anderem) mit den folgenden Befehlen:
Argumente | Name | Beschreibung |
newpath | beginnt einen neuen Pfad | |
stroke | beendet den Pfad, zeichnet einen Strich | |
closepath | macht aus einem Pfad einen geschlossenen Pfad (Anfangspunkt = Endpunkt) | |
fill | beendet den Pfad, füllt die Fläche | |
x y | moveto | bewegt (absolut) Schreibposition nach x,y |
x y | lineto | Strich von der Schreibposition nach x,y |
x y | rmoveto | bewegt (relativ) Schreibposition um x,y |
x y | rlineto | Strich (relativ) von Schreibposition um x,y |
x y r a e | arc | ein Bogen von Winkel a bis Winkel e um den Mittelpunkt x y mit Radius r |
x1 y1 x2 y2 x3 y3 a e | curveto | eine Bezier Kurve nach x3 y3. |
Erklärungsbedürftig ist vielleicht noch der Befehl curveto. Er zeichnet eine Bezier Kurve vom augenblicklichen Punkt nach (x3,y3). Die Punkte (x1,y1) und (x2,y2) sind Kontrollpunkte. Die Kurve die entsteht ist anschaulich die eines geworfenen Steins, dessen Geschwindigkeit am augenblicklichen Punkt gerade der Vektor nach (x1,y1) ist und dessen Geschwindigkeit bei (x3, y3) gerade der Vektor nach (x2, y2) ist. Dazwischen ändert sich die Geschwindigkeit "so wenig wie möglich".
Zum Beispiel kann die Art des Striches und der Füung
mit setlinewidth
und setrgbcolor
beeinflusst werden.
Weiter gibt es Befehle um den Ursprung des Koordinatensystems zu verschieben
(translate
), zu skalieren (scale
) oder zu rotieren
(rotate
).
Wirklich flexibel werden diese Mechanismen aber erst dadurch, dass man den Zustand
der Graphikmaschine einfach sichern (gsave
) und wieder
herstellen (grestore
) kann. Dabei wird zum Sichern und Restaurieren
ein Stack benutzt, so dass diese Befehle beliebig geschachtelt werden können.
Ein weiterer interessanter Effekt ist Clipping (was hier aber nicht weiter besprochen wird).
Argumente | Name | Beschreibung |
w | setlinewidth | setzt Strichstärke |
r g b | setrgbcolor | setzt Farbe. Die Werte r, g, und b sind zwischen 0.0 und 1.0 |
x y | translate | setzt den Koordinatenursprung |
x | rotate | dreht das Koordinatensystem um x Grad gegen den Uhrzeigersinn |
fx fy | scale | skaliert das Koordinatensystem, mit einem Faktor für die x und die y Richtung |
gsave | sichert den Zustand | |
grestore | stellt den Zustand wieder her. | |
currentpoint | speichert die aktuelle x und y Koordinate auf dem Stack. |
/counter
.
Der einfachste Befehl ist def
. Er nimmt einen Namen und einen Wert vom Stack und speichert
den Wert unter diesem Namen ab. Der Wert selbst kann dann einfach durch Angabe des Namens
wieder auf den Stack geholt werden.
Zum Beispiel:
GS>/counter 50 def GS>counter GS<1>stack 50 |
Dictionaries kann man auch selbst erzeugen. Dazu dient der Befehle dict
. Dieser
Befehl nimmt die Anfangsgrösse vom Stack, erzeugt ein Dictionary
und legt es auf den Stack.
Zum Speichern eines Wertes gibt es den Befehl def
. Dieser Befehle speichert
Paare von Name und Wert im aktuellen Dictionary. PostScript verwaltet einen eigenen Stack
von Dictionaries, den Dictionary Stack. Der Befehl def
greift dabei immer
auf das oberste Dictionary im Dictionary Stack zu. Beim Nachschlagen eines Wertes durch
blosse Angabe des Namens wird der ganze Dictionary Stack von oben nach unten durchsucht um
einen passenden Namen zu finden.
Der Dictionary Stack wird mit den Befehlen begin
und end
bearbeitet.
Der Befehl begin
nimmt ein Dictionary vom Operand Stack und legt es auf den
Dictionary Stack, der Befehl end
entfernt ein Dictionary vom Dictionary Stack.
Ein Beispiel:
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 |
In diesem Zusammenhang ist noch der store
Befehl wichtig: store
verhält sich wie def
es braucht einen Namen und einen Wert und speichert
den Wert unter dem gegebenen Namen auf den Dictionary Stack. Während def
aber immer auf das oberste Dictionary zugreift durchsucht store
den ganzen
Dictionary Stack von oben her nach dem genannten Namen und speichert den Wert dort. Nur
wenn der Name überhaupt nicht gefunden wird legt store
den Namen im
obersten Dictionary neu an (so wie def
).
Argumente | Name | Beschreibung |
i | dict | erzeugt ein Dictionary mit i Einträgen |
d | begin | legt Dictionary d oben auf den Dictionary Stack |
end | entfernt das oberste Dictionary vom Dictionary Stack | |
n x | def | legt den Wert x unter dem Namen n im obersten Dictionary ab |
n x | store | sucht im Dictionary Stack nach n, legt dort den Wert x ab. Sonst wie def. |
Dictionaries kann man auch explizit verwenden. Dazu gibt es die Befehle get
und put
.
Argumente | Name | Beschreibung |
d n w | put | speichert Wert w unter dem Namen n in Dictionary d |
d n | get | legt den Wert des Namens n im Dictionary d auf den Stack |
Beispiel:
GS>/mydict 10 dict def GS>mydict /x 123 put GS>mydict /x get GS<1>stack 123 |
findfont
erzeugt.
Strings erzeugt man durch einschließen einer Zeichenkette in runde Klammern.
Argumente | Name | Beschreibung |
n | findfont | sucht einen Font mit Namen n und legt ihn auf den Stack. |
f i | scalefont | nimmt Font f und Zahl i, skaliert den Font auf i Punkt und legt ihn wieder auf den Stack. |
f | setfont | nimmt den Font f vom Stack und macht ihn zum aktuellen Font |
s | show | nimmt den String s vom Stack und zeigt ihn im aktuellen Font an. |
GS>/Helvetica findfont Loading Helvetica ... GS<1>36 scalefont GS<1>setfont GS>100 100 moveto GS>(Hello world!) show |
%!PS
, der in der Regel
in der ersten Zeile einer PostScript Datei steht.
%!PS-Adobe-2.0 %%Creator: I myself, Copyright 2005 Martin Ruckert %%Title: The explanation file %%Pages: 5 %%PageOrder: Ascend %%BoundingBox: 0 0 596 842 |