Una Chiave per il Desktop
Publishing
Corso di PostScript
- Marco A. Calamari
Quinta Puntata
In questa puntata verranno introdotti gli operatori di
controllo del PostScript, e la definizione di programma
PostScript conforme; sarà inoltre precisato il concetto di incapsulamento,
introdotto la nella precedente puntata. Il nostro senso estetico,
messo a dura prova da una indigestione di teoria pura, sarà
consolato da un esempio di generazione di forme frattali con
l'uso ricorsivo del PostScript.
Siamo rimasti con un debito del mese scorso, cioè la
soluzione dell'esercizio proposto che riguardava la modifica del Programma
3, in modo da ottenere che il fondo della cornice diventasse grigio,
mentre il fondo delle lettere PS restasse bianco. L'esempio
(riportato nel Listato 1, ed il cui output è mostrato in
Figura 1) è stato svolto nella maniera semplice e stupida;
cioè utilizzando le path già definite nel programma originale,
salvandole con l'operatore gsave, riempiendo la prima di grigio
e la seconda di bianco con l'operatore fill. Si è cioè
sfruttata la proprietà del PostScript di scrivere con un
inchiostro coprente, per ottenere il risultato voluto.
Un'altra possibile soluzione, più elegante ma più complessa,
sarebbe stata di eseguire il primo fill (quello nella
procedura tracciaCorniceModificata) con una path forata
con il profilo delle lettere PS, eliminando la necessità di
eseguire il secondo fill in bianco. Questo avrebbe però
richiesto una modifica più estesa del programma, rendendo meno
generale la procedura tracciaCorniceModificata, e
aumentando la dipendenza fra le varie parti del programma.
I nuovi operatori PostScript
Introduciamo ora l'elenco dei nuovi operatori PostScript,
divisi per tipologia, che dovrà ovviamente essere utilizzato
anche per esaminare il funzionamento degli esempi proposti.
Operatori di Controllo - test logici
- - true - : pone il valore logico vero sullo stack
degli operandi.
- - false - : pone il valore logico falso sullo
stack degli operandi.
- any1 any2 eq bool :gli argomenti
possono essere di qualunque tipo purché omogenei fra loro;
pone il valore logico true sullo stack se i due
argomenti sono uguali, e quello false se non lo
sono.
- any1 any2 ne bool : gli argomenti
possono essere di qualunque tipo purché omogenei fra loro; pone
il valore logico true sullo stack se i due
argomenti non sono uguali, e quello false se lo
sono.
- any1 any2 gt bool : gli argomenti
possono essere due numeri o due stringhe; nel caso di numeri pone
il valore logico true sullo stack se num1
è maggiore di num1 , e quello false nel caso contrario.
Nel caso di stringhe viene invece considerato l'ordine
alfabetico, quindi viene posto sullo stack il valore true
se string1 precede string2 in ordine
alfabetico, ed il valore false in caso contrario;
nello stesso modo si comportano gli altri operatori
logici che permettono l'uso di numeri o stringhe, per cui
non ripeteremo questo fatto nella descrizione degli
operatori seguenti.
- any1 any2 ge bool : gli argomenti
possono essere due numeri o due stringhe; nel caso di numeri pone
il valore logico true sullo stack se num1
è maggiore od uguale a num1 , e quello false
nel caso contrario.
- any1 any2 lt bool : gli argomenti
possono essere due numeri o due stringhe; nel caso di numeri pone
il valore logico true sullo stack se num1
è minore di num2, e quello false nel caso
contrario.
- any1 any2 le bool : gli argomenti
possono essere due numeri o due stringhe; nel caso di numeri pone
il valore logico true sullo stack se num1
è minore od uguale di num2, e quello false
nel caso contrario.
- bool1 bool2 and bool3 : pone il
valore logico true sullo stack se bool1 ed bool2 sono ambedue veri,
ed il valore false nel caso contrario.
- bool1 bool2 or bool3 : pone il
valore logico true sullo stack se almeno uno dei
due valori bool1 ed bool2 è vero, ed il
valore false nel caso contrario.
- bool1 bool2 xor bool3 : pone il
valore logico true sullo stack se uno solo dei due
valori bool1 ed bool2 è vero, ed il valore false
nel caso siano ambedue falsi o veri.
- bool1 not bool2 : pone il valore
logico true sullo stack se bool1 è falso,
ed il valore false nel caso opposto.
- int1 int2 bitshift int3 : esegue uno
shift a sinistra dei bit del numero intero int1 di int2 posizioni;
i bit usciti da una estremità sono persi, e quelli
entrati dall'altra sono sempre 0. Se int2 è
negativo lo shift viene eseguito verso destra.
Operatori di Controllo - flusso del programma
- bool proc if - : rimuove i due
argomenti dallo stack ed esegue la procedura proc
solo se il valore bool è vero.
- bool proc1 proc2 ifelse - : rimuove
i tre argomenti dallo stack ed esegue la procedura proc1
se il valore bool è vero, e la procedura proc2
se il valore bool è falso.
- num1 num2 num3 proc for - : esegue
la procedura proc un certo numero di volte,
partendo dal valore num1 ed incrementandolo ogni
volta di num2 fino a quando non raggiunge il valore num3. Prima
di ogni esecuzione di proc il valore corrente del
contatore viene posto in cima allo stack; se la procedura
non lo utilizza e quindi non lo consuma, deve
esplicitamente rimuoverlo, onde evitare che i successivi
valori del contatore si accumulino sullo stack.
- int proc repeat - : esegue la
procedura proc per int volte; non pone
nessun contatore sullo stack.
- int proc loop - : esegue la
procedura proc per un numero infinito di volte;
non pone nessun contatore sullo stack; loop deve
essere interrotto dalla procedura stessa, che deve
eseguire l'operatore exit esplicitamente.
- - exit - : viene usato per
interrompere l'esecuzione di un ciclo determinato dagli
operatori for, repeat e loop.
- - stop - : termina con condizione di fine
irregolare una procedura o file eseguibile iniziato col comando stopped.
Fare riferimento al comando seguente per l'utilizzo.
- proc stopped bool : pone la
procedura proc sullo stack di esecuzione, come se
il suo nome fosse stato incontrato semplicemente nel
flusso del programma; la procedura viene perciò eseguita regolarmente.
Al termine della procedura viene lasciato sullo stack un
valore logico che è falso se essa è terminata
regolarmente, ed è vero se è terminata a causa
dell'esecuzione di uno stop interno alla procedura
stessa. Questo meccanismo può essere utilizzato per una gestione ad
hoc degli errori realizzata dal programma .
- - quit - : questo operatore viene utilizzato in
maniera diversa a seconda del contesto. Se utilizzato durante
la modalità executive, termina l'esecuzione della
modalità interattiva, mentre se incontrato in un
programma solitamente ha lo stesso effetto dell'operatore stop.
In implementazioni del PostScript dotate di sistema
operativo e dischi (ad esempio VAX-11 con VMS) il comando termina
l'esecuzione dell'interprete e restituisce il controllo
al sistema operativo del computer. Questo ovviamente non
avviene in installazioni prive di dischi e sistema
operativo (LaserWriter, LaserWriter Plus, LaserWriter
NT), oppure dotate di dischi ma non di sistema operativo (LaserWriter
NTX, RIP3 Linotype).
Un esempio di ricorsività
Dopo la solita indigestione di nuovi operatori, ci rilasseremo
con un esempio alla moda del PostScript; la generazione di una forma
frattale autosimile. Come ricorderete, nella seconda puntata
avevamo elencato, tra le caratteristiche fondamentali del
PostScript, quella di permettere l'utilizzo della ricorsività;
senza imbastire un trattatello di teoria della programmazione, ci
limiteremo a ricordare che si definisce ricorsivo un
linguaggio che permette di definire procedure (o subroutine) che
hanno la possibilità di richiamare se stesse. Gli esempi più
noti di questa classe di linguaggi sono il Pascal ed il Lisp,
mentre ad esempio Basic, Cobol, C e Fortran sono esempi di linguaggi
non-ricorsivi. La ricorsività non permette di risolvere problemi
impossibili con la classica tecnica dell'iterazione; è anzi
possibile dimostrare che qualunque programma esprimibile in forma ricorsiva
può anche essere scritto in forma iterativa. Queste due
formulazioni sono ovviamente possibili utilizzando il medesimo
linguaggio; solitamente la formulazione iterativa produce un
codice più elegante e compatto, ma spesso anche di esecuzione
più lenta.
Utilizzeremo una applicazione della ricorsività per generare
una forma frattale autosimile, cioè una figura geometrica (in
questo caso una freccia) che è collegata a copie di se stessa
sempre più piccole (teoricamente all'infinito, in pratica fino
al limite della risoluzione dei normali device PostScript, cioè
300 d.p.i.).
I commenti inseriti nel Listato 2 descrivono i dettagli
del funzionamento della procedura ricorsiva frecciaFrattale;
come è possibile vedere rimuovendo questi ultimi, il programma
è estremamente breve ed elegante. Il risultato grafico può
essere variato entro ampi limiti agendo sulle variabili globali LivelloMassimo
e RapportoDiRiduzione; ad esempio, in Figura 3 è
mostrato il cambiamento che si ottiene modificando il valore di RapportoDiRiduzione
da 0.6 a 0.707. Se modificate il valore di LivelloMassimo
, prestate attenzione al fatto che ogni aumento di una unità implica
all'incirca un raddoppio del tempo di esecuzione, e che, con i
valori del Listato 2 (LivelloMassimo=12 e RapportoDiRiduzione=0.6),
la dodicesima generazione di linee tracciate è lunga un solo
pixel.
Se desiderate fare delle ulteriori prove, vi conviene lavorare
con un valore di LivelloMassimo di circa 8, per poi
portarlo al valore desiderato quando il risultato vi soddisferà;
il tempo di esecuzione del programma con 12 livelli di ricorsione
è infatti di circa dieci minuti.
Nel caso che abbiate eseguito il programma coi valori
modificati, noterete che il risultato ottenuto differisce in un
importante dettaglio da quello mostrato in Figura 3; non
preoccupatevi e proseguite nella lettura, il mistero sarà
spiegato, come in ogni giallo che si rispetti, alla fine.
Ancora sull'incapsulamento
Come si può notare dagli esempi di questa puntata,
continuiamo a racchiudere i programmi principali di ogni esempio
fra una coppia di istruzioni gsave e grestore.
Questo ci permette di modificare allegramente qualunque valore
dello stato grafico senza che i cambiamenti si ripercuotano
all'esterno del nostro programma.
È necessario spendere una qualche parola di incoraggiamento,
perché la tentazione di scrivere programmi senza prestare
attenzione alle regole di buona programmazione come questa è
sempre forte; per poter limitare il tempo perso alla caccia di
bachi nei vostri programmi, è indispensabile che le singole
parti in cui suddividete il programma si influenzino
reciprocamente solo dove strettamente necessario. In particolare,
è bene avere sempre presenti queste regole (che, come tutte le
regole, ammettono anche rare e motivate eccezioni):
- una procedura deve lasciare inalterato lo stato grafico
che ha trovato all'inizio;
- gli stack degli operandi e degli stati grafici non devono
contenere oggetti lasciati da altre procedure, se non per
il tempo strettamente necessario a passarli da una
procedura all'altra (ad esempio contatori di loop for
non utilizzati);
- ciascun programma deve, nei limiti del possibile, evitare
di fare assunzioni sullo stato grafico iniziale, ma
considerarlo ignoto, e modificare tutti i parametri non
impostandoli con valori fissi, ma con variazioni di
quelli esistenti. Il modo di operare deve essere analogo
al funzionamento degli operatori PostScript come scale,
infatti 2 2 scale non fissa la scala a 2 ma al
doppio del valore preesistente.
La fatica dedicata a scrivere programmi che seguono le regole
è come un investimento a lungo termine; costa all'inizio, ma
viene ricompensata alla fine da un risparmio nel debugging del programma
e soprattutto dall'ottenimento di un codice facilmente
riutilizzabile.
I programmi conformi
L'utilizzo più comune del PostScript è quello di permettere
alle applicazioni che girano sui più diversi tipi di computer di
stampare in loro output su una stampante laser; ne consegue che,
a parte l'eventuale differenza del collegamento fisico fra
computer e stampante (RS-232 seriale, Centronics parallelo,
AppleTalk ecc.), il computer invia alla stampante un programma
PostScript scritto in caratteri ASCII, esattamente come facciamo
noi. Ci sono tuttavia delle importanti differenze, la principale
delle quali è che i programmi generati dall'applicazione devono
essere più brevi possibile, per diminuire i tempi di
trasmissione, ma anche semplici da generare, per poter essere
prodotti automaticamente da driver di stampante relativamente
semplici. Le due esigenze sono ovviamente in contrasto; i
programmi semplici e stupidi tendono ad essere sempre più lunghi
di quelli intelligenti.
La soluzione che viene adottata permette di soddisfare tutte e
due le esigenze; il programma che viene inviato alla stampante è
di solito diviso in due parti.
- La prima parte, sempre uguale per ogni applicazione,
viene scritta una volta per tutte da esperti programmatori,
e contiene procedure PostScript che realizzano le
particolari primitive di cui l'applicazione necessita (ad
esempio le figure geometriche realizzabili con programmi del
tipo QuickDraw come MacDraft o SuperPaint); i nomi di
queste primitive sono molto brevi per diminuire il tempo
di trasmissione del file, ed esse vengono di solito
memorizzate in un unico dizionario, indicato come preprocessor
o prep di quella particolare applicazione. Questo
dizionario può anche venir memorizzato in permanenza
sulla stampante, evitando quindi di doverlo inviare più volte
nel caso di stampe consecutive provenienti dalla stessa applicazione.
- La seconda parte è invece generata automaticamente
dall'applicazione, e contiene la descrizione del
documento da stampare, fatta utilizzando le primitive del preprocessor.
In ogni ambiente PostScript esiste un metodo per poter
salvare, esaminare e modificare i file di stampa; sui sistemi
Macintosh consiste nel premere Command-F appena chiusa la
finestra di stampa. In questo caso l'applicazione non invia il
programma PostScript alla stampante, ma lo salva in un file
denominato Postscript0 (1, 2, ecc.). Nel far questo
l'applicazione suppone che il preprocessor sia già stato
caricato sulla stampante, e non lo inserisce quindi nel file; lo
si può includere eseguendo la stessa procedura, ma premendo
Command-K.
Dal semplice documento di testo di Word 3.0 mostrato in Figura 4, sono stati ottenuti i Listati
3 (Command-F) e 4 (Command-K).
Nel documento del Listato 3 possiamo individuare un
notevole numero di commenti, detti commenti conformi, che
iniziano con i caratteri %! oppure %%:
- %!PS-Adobe-2.0
- %%Title: Prova
- %%Creator: Microsoft Word
- %%CreationDate: Domenica, 3
dicembre 1989
- %%Pages: (atend)
- %%BoundingBox: ? ? ? ?
- %%PageBoundingBox: 28 30 566 811
- %%For: Marco
- %%IncludeProcSet:
"(AppleDict md)" 68 0
- %%EndComments
- %%EndProlog
- %%BeginDocumentSetup
- md begin
- ......(altri
comandi)......
- F T cp
- %%Trailer
- cd
- end
- %%Pages: 1 0
- %%EOF
I programmi PostScript che contengono commenti di questo tipo
sono detti programmi conformi; tali commenti sono
riconosciuti al di fuori del contesto PostScript da particolari
implementazioni dell'interprete stesso, o da apposite interfacce,
che possono estrarne informazioni utili a preparare l'elaborazione
del programma. L'esempio riportato contiene, nell'ordine, le
seguenti informazioni:
- inizio del programma conforme (include il livello di
conformità PostScript);
- titolo del documento;
- nome dell'applicazione generatrice;
- data di creazione del documento;
- numero totale delle pagine (informazione rinviata alla
fine del programma);
- dimensione del rettangolo che contiene il documento
grafico (non applicabile in questo caso, poiché il
documento è di solo testo);
- dimensione del rettangolo che contiene la pagina;
- destinatario del documento.
- preprocessor utilizzato dal documento.
Altre informazioni possono essere incluse nel corpo di un
programma conforme; alcune di esse sono:
- font utilizzati nel programma;
- font inclusi nel programma;
- font non inclusi nel programma (che devono quindi essere
forniti dalla stampante);
- documenti (testo, bitmap o grafica) utilizzati nel
programma;
- documenti inclusi nel programma;
- documenti non inclusi nel programma (che devono quindi
essere rintracciati esternamente su disco).
Ogni documento PostScript conforme può essere suddiviso in
quattro parti principali, che sono:
- header - che comincia con la prima linea del
documento, contiene solo commenti conformi, cioè linee
che iniziano con %% o !%, e termina con la linea
%%EndComments, o con qualunque altra linea che non inizi
con i caratteri %%;
- prologue - che comincia con la prima linea dopo la
fine dell'header, contiene inizializzazioni particolari,
e termina con la linea %%EndProlog (nel nostro caso è
vuoto);
- script - che comincia con la prima linea dopo la
fine del prologue, contiene la descrizione del documento,
altri tipi di commenti conformi (come quelli sui font
utilizzati), e termina con la linea %%Trailer;
- trailer - che comincia con la prima linea dopo la
fine dello script, contiene principalmente commenti
conformi includenti le eventuali informazioni rinviate
alla fine del documento (come quelli sul numero di
pagine), e termina con la linea %%EOF o con la fine
fisica del file.
Il Listato 4, che contiene sia il preprocessor che il
documento da stampare, è quindi costituito da due distinti
programmi PostScript, ciascuno dei quali termina con %%EOF, ed è
suddiviso nelle parti sopraelencate; si noti che alcune parti
possono mancare, come nel caso del prologue del documento di
stampa.
Un esempio di utilizzo delle informazioni contenute nei
commenti dei programmi PostScript conformi è quello del
rettangolo grigio che programmi come PageMaker rappresentano per
indicare una immagine EPSF importata da un'altra applicazione; le
dimensioni di questo rettangolo e le informazioni (titolo, data,
ecc.) su di esso riportate sono appunto ricavate dai commenti del
file EPSF conforme che è stato incluso nel documento.
Per maggiori dettagli sui programmi conformi potete consultare
i testi elencati nella bibliografia fornita alla fine della terza
puntata, ed in particolare:
- ref. 1, appendice C, per le regole di conformità
minimali e complete nella versione Adobe-1.0;
- ref. 5, capitolo 2 e appendice B, per le regole di
conformità complete nella versione Adobe-2.0.
Ritorneremo sull'argomento dei programmi conformi quando
tratteremo delle implementazioni PostScript in ambienti di rete e
multiutenza.
To be continued .....
Prima di lasciarci vi proponiamo tre esercizi da svolgere.
- Il primo è correlato con il giallo lasciato in sospeso
all'inizio di questa puntata; il risultato ottenuto dal programma
del Listato 2 modificato differisce da quello mostrato in Figura
3 perché in quest'ultima il frattale non deborda oltre la
cornice. Provate quindi a modificare il programma, utilizzando
l'operatore clip, in modo tale che il risultato sia
identico a quello di figura.
- Il secondo è di modificare ulteriormente il Programma
1 di questa puntata al fine di creare una path forata ed
eseguire il riempimento con un unico fill.
- Il terzo è di scrivere una versione non ricorsiva del Programma
2, che faccia uso degli operatori di controllo presentati in
questa puntata; si tratta di sostituire la ricorsività con
l'iterazione.
Nella prossima puntata riprenderemo a parlare di testi e di
font, lasciandovi così il tempo di svolgere gli esercizi sulla
grafica; tratteremo per esteso le problematiche dell'utilizzo
degli operatori dedicati al trattamento dei testi e forniremo
anche qualche cenno sulle principali tecniche di impaginazione.
- % Corso PostScript - parte V -
programma 1
- %
- % Possibile svolgimento
dell'esercizio 1
- % incluso nella IV parte.
- %
- % Esempio di utilizzo
dell'operatore clip
- % (Parte IV - programma 3)
- % modificato in modo da stampare
in grigio
- % chiaro lo spazio compreso tra
la cornice
- % ed il profilo delle lettere
'PS'.
- %
- % Procedura inch
- % Argomenti: XInches / XPoints
- % Converte misure da pollici
- % a punti tipografici.
- /inch { 72 mul } def
- %
- % Procedura
tracciaCorniceModificata
- % Argomenti: - / -
- % Traccia una cornice su pagina
- % A4 a mezzo pollice dal margine
- % e riempie l'interno di grigio
chiaro.
- /tracciaCorniceModificata {
- gsave newpath
- 0.5 inch 0.5 inch moveto
- 7.3 inch 0 inch rlineto
- 0 inch 10.5 inch rlineto
- -7.3 inch 0 inch rlineto
- closepath
- %
- % MODIFICA
----------------------
- % Modifica per riempimento in
grigio:
- % salva la path corrente in uno
stato
- % grafico, la riempie con un
fill, ed
- % infine ripristina lo stato
grafico
- % precedente.
- gsave
- 0.9 setgray fill
- grestore
- %
- 0.05 inch setlinewidth
- 0 setgray stroke
- grestore
- } def
- %
- % Programma principale
- % Viene tracciata la cornice
della pagina
- tracciaCorniceModificata
- %
- % Incapsulamento
- gsave
- %
- % Raddoppia la scala sugli assi
e pone flat=4
- 2 2 scale
- 4.0 setflat
- %
- % Definisce le variabili globali
X e Y
- /X .5 inch def /Y 2.5 inch def
- %
- % Sposta il punto corrente a X,Y
- X Y moveto
- %
- % Definisce il font corrente
come
- % Times-Bold a corpo 200
- /Times-Bold findfont 200
scalefont setfont
- %
- % Definisce la path corrente
uguale al
- % contorno delle lettere PS
- (PS) true charpath
- %
- % MODIFICA
----------------------
- % Modifica per riempimento in
bianco:
- % salva la path corrente in uno
stato
- % grafico, la riempie con un
fill, ed
- % infine ripristina lo stato
grafico
- % precedente.
- gsave
- 1.0 setgray fill
- grestore
- %
- % Salvo lo stato grafico (per
salvare la path
- % corrente), la traccia sulla
pagina ed infine
- % ripristina lo stato grafico
- gsave stroke grestore
- %
- % Definisce la clipping path
uguale al
- % contorno delle lettere PS
- clip
- %
- % Annulla la path corrente (clip
non lo fa)
- newpath
- %
- % Definisce il font corrente
come
- % Times-Roman a corpo 7
- /Times-Roman findfont 7
scalefont setfont
- %
- % Riempie la clipping path
precedentemente
- % definita con un pattern
formato dalla parola
- % PostScript, ottenuto
utilizzando un ciclo
- % per mezzo dell'operatore for,
il quale ripete
- % la procedura fra parentesi
graffe, ponendo ogni
- % volta il contatore aggiornato
sullo stack, per
- % i valori da 0 a 136 a passi di
8.
- 0 8 136
- { Y add X exch moveto
- (PostScript PostScript
PostScript PostScript\
- PostScript PostScript PostScript
PostScript ) show }
- for
- %
- % Rimozione incapsulamento
- grestore
- %
- % Stampa pagina
- showpage
- % Corso PostScript - parte V -
programma 2
- % Esempio di utilizzo ricorsivo
del PostScript
- %
- % Procedura inch
- % Argomenti: XInches / XPoints
- %
- % Converte misure da pollici
- % a punti tipografici.
- /inch { 72 mul } def
- %
- % Procedura tracciaCornice
- % Argomenti: - / -
- %
- % Traccia una cornice su pagina
- % A4 a mezzo pollice dal
margine.
- /tracciaCornice {
- gsave newpath
- 0.5 inch 0.5 inch moveto
- 7.3 inch 0 inch rlineto
- 0 inch 10.5 inch rlineto
- -7.3 inch 0 inch rlineto
- closepath
- .05 inch setlinewidth
- 0 setgray stroke
- grestore
- } def
- %
- % Procedura giuUnLivello
- % Argomenti: - / -
- % Variabili Globali: Livello
- %
- % Incrementa di 1 il valore del
- % livello di ricorsione.
- /giuUnLivello {
- /Livello Livello 1 add def
- } def
- %
- % Procedura suUnLivello
- % Argomenti: - / -
- % Variabili Globali: Livello
- %
- % Decrementa di 1 il valore del
- % livello di ricorsione.
- /suUnLivello {
- /Livello Livello 1 sub def
- } def
- %
- % Procedura faiUnaLinea
- % Argomenti: - / -
- %
- % Traccia una linea verticale di
- % due pollici nel sistema di
- % riferimento corrente, salva
- % sullo stack il punto corrente,
- % imprime la linea sulla pagina
- % (resettando la path ed il
punto
- % correnti) e ripristina infine
- % quest'ultimo.
- /faiUnaLinea {
- 0 inch 2 inch rlineto
- currentpoint stroke
- translate
- 0 inch 0 inch moveto
- } def
- %
- % Procedura frecciaFrattale
- % Argomenti: - / -
- % Variabili Globali: Livello,
- % RapportoDiRiduzione,
- % SpessoreDellaLinea,
- % LivelloMassimo
- %
- % Salva lo stato grafico, scala
- % il sistema di riferimento sui
- % due assi, aumenta di uno il
- % livello di ricorsione, traccia
la linea,
- % controlla che il livello
- % di ricorsione sia minore di
quello
- % massimo, ed infine richiama
- % due volte se stessa, dopo aver
- % ruotato il sistema di
riferimento
- % prima a destra e poi a
sinistra.
- /frecciaFrattale {
- gsave
- RapportoDiRiduzione
- RapportoDiRiduzione scale
- SpessoreDellaLinea setlinewidth
- giuUnLivello faiUnaLinea
- Livello LivelloMassimo le
- {
- +135 rotate frecciaFrattale
- -270 rotate frecciaFrattale
- } if
- suUnLivello grestore
- } def
- %
- %
- % Programma principale
- %
- % Incapsulamento
- gsave
- %
- % Si assegnano i valori iniziali
- % alle variabili globali.
- /Livello 0 def
- /LivelloMassimo 12 def
- /RapportoDiRiduzione 0.6 def
- /SpessoreDellaLinea 0.12 inch
def
- %
- % Si traccia la cornice della
pagina
- tracciaCornice
- %
- % Si fissa il punto iniziale e
la scala
- 4 inch 4 inch moveto
- 0 inch 0 inch translate
- 4 4 scale
- 1 setlinecap
- %
- % Viene richiamata la procedura
ricorsiva
- frecciaFrattale
- %
- % Rimozione incapsulamento e
stampa
- grestore
- showpage
- %!PS-Adobe-2.0
- %%Title: Prova
- %%Creator: Microsoft Word
- %%CreationDate: Domenica, 3
dicembre 1989
- %%Pages: (atend)
- %%BoundingBox: ? ? ? ?
- %%PageBoundingBox: 28 30 566 811
- %%For: Marco
- %%IncludeProcSet:
"(AppleDict md)" 68 0
- %%EndComments
- %%EndProlog
- %%BeginDocumentSetup
- md begin
- T T -30 -28 811 566 100 72 72 3
F F F F T T F psu
- (Marco; document: Prova)jn
- 0 mf
- od
- %%EndDocumentSetup
- %%Page: ? 1
- op
- 30 28 xl
- 1 1 pen
- 99 85 gm
- (nc 30 28 811 566 6 rc)kp
- 1 setTxMode
- 0 fs
- bu fc
- {}mark T /Times-Roman
/|______Times-Roman 0 rf
- bn
- 18 fz
- bu fc
- 2 F /|______Times-Roman fnt
- bn
- 0.32135 0. 32 0.03213 0.(Testo
normale in Times 18)awidthshow
- 117 85 gm
- 1 fs
- bu fc
- {}mark T /Times-Bold
/|______Times-Bold 0 rf
- bn
- bu fc
- 2 F /|______Times-Bold fnt
- bn
- 2.66677 0. 32 0.26667 0.(Testo
neretto in Times 18)awidthshow
- 135 85 gm
- 2 fs
- bu fc
- {}mark T /Times-Italic
/|______Times-Italic 0 rf
- bn
- bu fc
- 2 F /|______Times-Italic fnt
- bn
- 0.78582 0. 32 0.07858 0.(Testo
corsivo in Times 18)awidthshow
- F T cp
- %%Trailer
- cd
- end
- %%Pages: 1 0
- %%EOF
- %%Title: "Laser Prep -- The
Apple PostScript Dictionary (md)"
- %%Creator: Apple Software
Engineering
- %%CreationDate: Thursday, March
19, 1987
- %{appledict version #68 0
- % © CopyRight Apple Computer,
Inc. 1984,1985,1986,1987,1988 All Rights Reserved.
- %%EndComments
- %%BeginProcSet: "(AppleDict
md)" 68 0
- statusdict begin waittimeout 300
lt{0 60 300
- .
- . (un sacco di altra roba)
- .
- cleartomark
- %%EndProcSet
- %%EOF
- %!PS-Adobe-2.0
- %%Title: Prova
- %%Creator: Microsoft Word
- %%CreationDate: Domenica, 3
dicembre 1989
- %%Pages: (atend)
- %%BoundingBox: ? ? ? ?
- %%PageBoundingBox: 28 30 566 811
- %%For: Marco
- %%IncludeProcSet:
"(AppleDict md)" 68 0
- %%EndComments
- %%EndProlog
- %%BeginDocumentSetup
- md begin
- T T -30 -28 811 566 100 72 72 3
F F F F T T F psu
- (Marco; document: Prova)jn
- 0 mf
- od
- %%EndDocumentSetup
- %%Page: ? 1
- op
- 30 28 xl
- 1 1 pen
- 99 85 gm
- (nc 30 28 811 566 6 rc)kp
- 1 setTxMode
- 0 fs
- bu fc
- {}mark T /Times-Roman
/|______Times-Roman 0 rf
- bn
- 18 fz
- bu fc
- 2 F /|______Times-Roman fnt
- bn
- 0.32135 0. 32 0.03213 0.(Testo
normale in Times 18)awidthshow
- 117 85 gm
- 1 fs
- bu fc
- {}mark T /Times-Bold
/|______Times-Bold 0 rf
- bn
- bu fc
- 2 F /|______Times-Bold fnt
- bn
- 2.66677 0. 32 0.26667 0.(Testo
neretto in Times 18)awidthshow
- 135 85 gm
- 2 fs
- bu fc
- {}mark T /Times-Italic
/|______Times-Italic 0 rf
- bn
- bu fc
- 2 F /|______Times-Italic fnt
- bn
- 0.78582 0. 32 0.07858 0.(Testo
corsivo in Times 18)awidthshow
- F T cp
- %%Trailer
- cd
- end
- %%Pages: 1 0
- %%EOF
Copyright © 1985: Marco A. Calamari