Una Chiave per il Desktop
Publishing
Corso di PostScript
- Marco A. Calamari
Nona Puntata
Nel corso delle precedenti otto puntate, abbiamo impiegato i
font senza preoccuparci minimamente della loro struttura e del
modo in cui l'interprete PostScript li utilizzava.
Per questo motivo dedicheremo questa parte del nostro corso a
fare una indigestione di questo argomento. Alla fine, cominceremo
appena ad apprezzare la nostra... ignoranza di una materia ahimè
decisamente complicata. Consoliamoci, anche se non saremo
(ancora) in grado di crearci da zero i nostri font, sapremo
comunque operare su di essi in modi che ora neppure sospettiamo.
Una descrizione generale
Abbiamo già parlato di che cosa si intende per font di tipo outlined
e di tipo stroked; pur senza perdere di generalità, nel
seguito supporremo di operare sempre su font outlined; chi non si ricordasse,
è pregato di ripassare la sesta puntata (voi non prestate MAI i
numeri arretrati di Bit, vero ?).
Per inciso, durante la pubblicazione del corso alcune puntate
sono state scambiate tra loro; nelle note faremo sempre
riferimento all'ordine come avrebbe dovuto essere se Murphy non
ci avesse messo lo zampino. In ogni caso le puntate sono state
pubblicate in questo ordine 1, 2, 4, 5, 3, 6, 7, 8; per
identificare le puntate dubbie potete fare riferimento al
commento in testa ai relativi listati.
Orbene, cosa succede esattamente nella LaserWriter quando noi
inviamo un programma che deve porre del testo sulla pagina? Per
fissare le idee torniamo per un momento al semplicissimo programma
della prima puntata
- /Times-Bold findfont
- 72 scalefont setfont
- 144 432 moveto
- (PostScript) show
- showpage
L'operatore findfont preleva un nome dallo stack degli
operandi e va a ricercarlo in uno speciale dizionario di sistema
(FontDirectory), che contiene tutte le informazioni relative ai
font conosciuti dalla macchina; se lo trova, pone una copia del
dizionario che contiene le informazioni relative al font sullo
stack.
A questo punto si rendono già necessarie due precisazioni:
Punto primo: FontDirectory è quindi un
dizionario di dizionari? Dal nostro punto di vista la risposta è
si. Ricordate che un dizionario non contiene effettivamente i
dati che descrivono i suoi elementi, ma solo una serie di coppie
nome/puntatore; questi ultimi puntano poi in zone della VM (memoria
virtuale) dell'interprete PostScript che contengono realmente i
dati. Coloro che conoscono il metodo solitamente usato dagli
interpreti Basic per memorizzare le stringhe proveranno a questo
punto una sensazione di déjà vu.
Il PostScript non pone limiti al modo di combinare tra loro
gli oggetti; un dizionario (come qualunque altro oggetto
PostScript di tipo composto) può contenere qualunque tipo di
oggetto come elemento. Potete quindi agevolmente perdervi nei
meandri della programmazione PostScript creando non solo
dizionari di dizionari, ma anche mostri come dizionari di vettori
di dizionari di ....
Punto secondo: i font conosciuti dalla macchina
non sono necessariamente quelli contenuti nelle ROM del
controller PostScript; in FontDirectory sono infatti presenti
anche i font memorizzati sugli eventuali hard disk di cui possono
essere dotate le periferiche PostScript, quelli temporaneamente downloadati
nella memoria del controller, ed infine quelli eventualmente
creati dal programma in esecuzione.
Ritorniamo al nostro esempio. A questo punto entra in
gioco l'operatore scalefont, che preleva il font (cioè il
dizionario che ne contiene le informazioni) ed un numero dallo
stack, ne modifica internamente un elemento in modo da scalarlo
(vedremo poi quale elemento) e lo rimette dove lo aveva preso.
La palla viene poi passata all'operatore setfont, che
riceve e mette in rete; in termini più esatti, preleva il
dizionario dallo stack e rende le informazioni ivi contenute
disponibili alla cosiddetta Font Machinery, cioè a quella parte
dell'interprete PostScript che si occupa di font. In ogni
momento, ricordiamo, esiste un unico font corrente, che viene
implicitamente utilizzato da tutti gli operatori fino a quando
non ne viene reso corrente un altro.
Il programma sposta quindi il punto corrente in una certa
posizione, definisce una stringa ed esegue l'operatore show;
improvvisamente succede una specie di '48, perché show
tenta di stampare la bitmap corrispondente ad una P maiuscola
corpo 72, va a guardare nella zona di memoria dove vengono
conservate le bitmap dei caratteri (detta Font Cache), e non ci
trova niente. L'esecuzione del programma viene quindi sospesa e
la Font Machinery va a cercare fra le informazioni contenute nel
font corrente quelle che descrivono il carattere in questione, le
converte nell'opportuna bitmap, ed invece di passarla
direttamente all'operatore che l'aveva richiesta, la memorizza
nella Font Cache e fa riprendere l'esecuzione del programma dal
passo precedente (quello della richiesta insoddisfatta).
L'operatore show trova questa volta la bitmap, la copia
opportunamente sulla pagina in memoria, ed il programma continua.
In cosa risiede il vantaggio di questo modo di operare?
Semplicemente nel fatto che l'operazione di conversione di un
carattere outlined nella corrispondente bitmap è un'operazione
centinaia di volte più complessa di quella necessaria per
copiare una bitmap già conservata in memoria. Poiché di solito
i caratteri utilizzati in un testo sono solo una parte di quelli
contenuti in un font, e sono usati in pochi corpi diversi, la
Font Cache si riempie rapidamente delle informazioni necessarie a
stampare quel particolare testo, e, dopo un avvio più lento,
tutte le operazioni di stampa vengono velocizzate di due o tre
ordini di grandezza.
È chiaro che la Font Cache, essendo come tutte le cose di
questo mondo di capacità limitata, deve possedere un meccanismo
che le permetta, una volta riempitasi, di eliminare le
informazioni più vecchie per far posto a quelle nuove.
La Font Cache è anche la responsabile di quei misteriosi
lampeggiamenti che il led giallo della LaserWriter compie ogni
tanto anche quando nessuno stampa niente; infatti, per non
sprecare tempo, Mr. Warnock o chi per lui ha pensato bene di non
far poltrire un costoso controller, e, nei momenti liberi fra un
lavoro e l'altro, la Font Machinery entra in azione da sola e
riempie la Font Cache con una opportuna selezione di caratteri
nei corpi più probabili. Se il job successivo contiene questi
caratteri nei corpi previsti, la stampa uscirà in un tempo
sensibilmente minore, altrimenti verrà stampata come se
l'operazione di caching non fosse stata eseguita.
Solo per completezza, chi si addentrasse tra gli operatori che
modificano i parametri persistenti di una stampante PostScript
(elencati di solito in un apposito supplemento incluso nella documentazione
della stampante), troverebbe l'operatore setidlefont che,
come il nome lascia supporre, permette di far memorizzare
permanentemente alla stampante una nuova serie di caratteri da
elaborare nel tempo libero.
La struttura di un font
A questo punto è necessario ritornare seri e metterci a
guardare da vicino come esattamente è composto un font; un font
PostScript è un dizionario che contiene le informazioni
necessarie a tracciare i caratteri che compongono il font stesso.
Tra i contenuti di questo dizionario sono incluse le definizioni
dei caratteri; queste ultime sono delle procedure PostScript che,
una volta eseguite, tracciano ciascuna la sagoma di un
particolare carattere, utilizzando niente altro che i normali operatori
grafici PostScript che già conosciamo.
Un font viene generato ponendo sullo stack un nome ed un
dizionario opportunamente costruito, ed eseguendo poi l'operatore definefont; definefont
preleva dallo stack il nome ed il dizionario, controlla che
quest'ultimo sia ben formato, ne impedisce ulteriori modifiche
rendendolo read-only, ed infine associa nome e dizionario
inserendo una nuova entry in FontDirectory. Oltre a queste operazioni definefont
inserisce un ulteriore elemento nel dizionario che costituisce il
font, e cioè un oggetto di nome FID e di tipo fontID; se
ricordate, questo è un oggetto di tipo semplice di cui avevamo
parlato nella seconda puntata, e che non avevamo poi più
incontrato. L'oggetto tipo fontID permette alla Font
Machinery di eseguire certi compiti interni che sono a conoscenza
solo dei sacerdoti della Adobe System; è quindi indispensabile
che il dizionario abbia almeno una entry libera nel momento in
cui viene sottoposto all'operatore definefont.
Un font PostScript normale, come quelli memorizzati nelle ROM
del controller, contiene le seguenti entità (l'operatore definefont
richiede che le prime quattro siano obbligatoriamente presenti):
- FontMatrix (vettore); è un vettore di 6
elementi, simile alla CTM che abbiamo già incontrato, e che
trasforma il sistema di coordinate in cui viene definito
il carattere in quello della pagina. I font creati da findfont
sono definiti a corpo 1, e vengono ulteriormente scalati dall'operatore scalefont.
- I caratteri dei font PostScript vengono normalmente
definiti in corpo 1000, e la FontMatrix è conseguentemente
[ 0.001 0 0 0.001 0 0]. Quando il font viene scalato
dall'operatore scalefont, la matrice generata
dall'operatore viene concatenata con la FontMatrix, ed il risultato
diventa la nuova FontMatrix.
- FontType (intero); è un parametro che
indica il tipo del font ed in che modo sono organizzate internamente
le informazioni; i normali font PostScript possiedono
valori di FontType di 1 o 2, mentre quelli definiti
dall'utente devono avere FontType uguale a 3.
- FontBBox (vettore); è un vettore formato
da quattro elementi, che danno le coordinate degli angoli
(x basso sinistra, y basso sinistra, x alto destra, y
alto destra) del più piccolo rettangolo che circoscrive
la figura ottenuta stampando sovrapposti tutti i
caratteri del font, stampati con origine in 0,0. La Font
Machinery compie importanti assunzioni basandosi sulla FontBBox;
per questo motivo è molto importante che nemmeno un
angolo esca fuori da essa, altrimenti possono succedere
cose inenarrabili.
- Encoding (vettore); è un vettore di 256
nomi di caratteri, che mette in corrispondenza i codici ASCII
delle stringhe da stampare con i caratteri grafici
memorizzati all'interno del font.
- Il fatto che la descrizione di un carattere sia messa in
corrispondenza con i codici binari da un'entità separata
come l'Encoding vector, permette una notevole
flessibilità; ce ne accorgeremo nella prossima puntata,
e per il momento chiudiamo qui il discorso.
- FontName (nome); è il nome assegnato al
font; questa informazione è solo per riferimento, ma non viene
in realtà utilizzata dalla Font Machinery.
- PaintType (intero); è un codice che indica
come vengono impressi i caratteri sulla pagina; il valore 0
indica che il carattere deve essere stampato da un
separato operatore fill, il valore 1 che il carattere
deve essere stampato dall'operatore stroke, il
valore 2 che i caratteri sono outlined, ed infine il
valore 3 indica che è la stessa procedura di descrizione
del carattere che si preoccupa di utilizzare i giusti
operatori.
- Metrics (dizionario); contiene informazioni
sulla larghezza ed altezza di ciascun carattere. Questa entry
è spesso assente; in tal caso vengono utilizzate le
informazioni memorizzate nella descrizione dei caratteri.
- StrokeWidth (numero); è una entry
normalmente non presente, che viene utilizzata quando si
vuole trasformare un font filled in outlined,
modificando perciò anche il valore di PaintType da 0 a
2.
- FontInfo (dizionario); contiene
informazioni che possono essere usate dai programmi PostScript, ma
che non sono accedute dalla Font Machinery (vedi più
avanti).
- UniqueID (intero); è un intero compreso
tra 0 e 16777215, che deve essere diverso in ogni insieme
di font utilizzati dalla stessa stampante; questa
informazione non è obbligatoria, ma, se presente,
permette alla FontCache di operare in maniera più
efficiente.
- CharStrings (dizionario); può essere
utilizzato per associare i nomi dei caratteri con le descrizioni dei
loro contorni, memorizzate in uno speciale formato
codificato e protetto.
- Private (dizionario); come il nome indica,
solo gli addetti ai lavori sanno cosa esattamente c'è
qui; tutte le informazioni che il produttore del font
(leggi Adobe System) vuole conservare segrete vengono
memorizzate in questo dizionario ed eseguite con lo
speciale operatore eexec. Tra queste informazioni
sono compresi i famosi hints, sui quali torneremo
nella prossima puntata.
Il dizionario FontInfo (che può anche mancare completamente)
contiene le seguenti informazioni:
- Notice (stringa); marchio del produttore
del font con note legali sulla proprietà di esso.
- FullName (stringa); nome completo del font,
di solito espresso con terminologia tipografica.
- FamilyName (stringa); nome completo della
famiglia di font di appartenenza.
- Weight (stringa); peso del font. Si tratta
di un termine tipografico che esprime il maggiore o minore spessore
del font.
- .
- version (stringa); versione del font.
- ItalicAngle (numero); Angolo di
inclinazione del font rispetto alla verticale.
- isFixedPitch (valore logico); indica se il
carattere è a spaziatura costante (non proporzionale, come
il Courier) o variabile (proporzionale, come il Times).
- UnderlinePosition (numero); distanza dalla
base del carattere dell'eventuale segno di sottolineatura.
- UnderlineThickness (numero); spessore
dell'eventuale segno di sottolineatura.
Qualche esempio
È stata una bella indigestione, e per questo motivo
rimandiamo il completamento delle informazioni sulla struttura
dei font e sulla possibilità di modificarla alla prossima
puntata; nel frattempo consigliamo i possessori del già più
volte nominato programma LaserTalk, di usare il Dictionary Browser
che vi è incluso per esaminare la struttura di qualche font.
Il Programma 1, riportato nel Listato 1
ed il cui output è mostrato in Figura 1, è un
semplice esempio di modifica strutturale di un font; vengono
generati, partendo dal normale Times neretto, tre font italici
con angoli diversi, anche anomali come il terzo, che ha
inclinazione negativa.
Il nucleo del programma è l'operatore makefont, che
preleva dallo stack un font ed un vettore, concatena quest'ultimo
alla FontMatrix, e pone il font così modificato nuovamente sullo
stack, da dove lo preleva l'operatore setfont, che lo fa
diventare il font corrente.
Il Programma 2 (riportato nel Listato 2)
è un esempio di generazione di una gradevole forma a spirale,
ottenuta con l'utilizzo degli operatori di trasformazione del
sistema di coordinate, e di charpath, che, come
ricordiamo, permette di estrarre il contorno di un font outlined,
rendendolo la path corrente. La Figura 2 mostra
risultato del programma.
Il Programma 3 (Listato 3 e Figura
3) utilizza nuovamente l'operatore charpath per
generare un effetto tipo sandwich nella stampa realizzata
utilizzando il solito Times.
Qualche parola in più merita il Programma 4 (Listato
4 e Figura 4); questo programma è il più complesso
tra quelli che abbiamo finora incontrato; proprio per questo
motivo vogliamo lasciare un mese di tempo per permettervi di fare
(ovviamente se siete d'accordo) un utile esercizio esaminandone
il funzionamento. Rimanderemo quindi alla prossima puntata i
dettagli sul funzionamento del programma; alcuni aspetti del
programma sui quali è opportuno soffermare l'attenzione sono
l'impiego di un dizionario che contiene tutte le procedure
utilizzate, e l'uso degli operatori transform ed itransform
per eseguire calcoli vettoriali.
... to be continued.
Nella prossima puntata continueremo ad occuparci di font,
mettendo in pratica le nozioni oggi apprese e generando alcuni
semplici esempi di font utente.
- %!PS-Adobe-2.0
- %%Title: Esempio di generazione
di tre font obliqui
- %%Creator: Corso PostScript -
parte IX - programma 1
- %%For: Corso PostScript BIT
- %%CreationDate: (4-10-1989)
(15:56)
- %%BoundingBox: 28 30 566 811
- %%EndComments
- %%EndProlog
- %
- % 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 FontObliquo:
- % Argomenti: font angolo corpo /
-
- % Variabili Globali: -
- % Variabili Locali: Angolo Corpo
- % Procedura per la modifica del
font corrente
- % trsformandolo in obliquo con
angolo dato.
- /FontObliquo {
- /Corpo exch def /Angolo exch def
- findfont
- [ Corpo 0 Corpo Angolo sin
Angolo cos div
- mul Corpo 0 0 ]
- makefont setfont } def
- %
- %
- % Programma principale
- %
- % Incapsulamento e tracciatura
della cornice
- gsave
- tracciaCornice
- %
- % Tracciamento del Times normale
- /Times-Bold findfont
- 48 scalefont setfont
- 2.00 inch 3.0 inch moveto
- (Times normale) show
- %
- % Tracciamento del primo font
- /Times-Bold 30 48 FontObliquo
- 1.25 inch 5.0 inch moveto
- (Times Obliquo +30\312) show
- %
- % Tracciamento del secondo font
- /Times-Bold 15 48 FontObliquo
- 1.25 inch 7.0 inch moveto
- (Times Obliquo +15\312) show
- %
- % Tracciamento del terzo font
- /Times-Bold -20 48 FontObliquo
- 1.25 inch 9.0 inch moveto
- (Times Obliquo -20\312) show
- %
- % Rimozione incapsulamento e
stampa
- grestore
- showpage
- %
- %%Trailer
- %%EOF
- %!PS-Adobe-2.0
- %%Title: Stampa in stile
outlined di una spirale di parole
- %%Creator: Corso PostScript -
parte IX - programma 2
- %%For: Corso PostScript BIT
- %%CreationDate: (4-10-1989)
(15:56)
- %%BoundingBox: 28 30 566 811
- %%EndComments
- %%EndProlog
- %
- % 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 stampaInOutlined:
- % Argomenti: stringa / -
- % Variabili Globali: -
- % Variabili Locali: -
- % Procedura di stampa in stile
outlined.
- /stampaInOutlined
- {true charpath stroke} def
- %
- % Procedura stampaSpirale:
- % Argomenti: - / -
- % Variabili Globali: Stringa
- % Variabili Locali: -
- % Procedura di stampa di una
- % spirale di parole.
- /stampaSpirale
- {15 15 705
- {gsave
- dup 240 div 1 add 1 exch div dup
mul dup scale
- rotate
- 100 0 moveto
- Stringa
- stampaInOutlined grestore}
- for} def
- %
- %
- % Programma principale
- %
- % Incapsulamento e tracciatura
della cornice
- gsave
- tracciaCornice
- %
- % Inizializzazioni
- /Times-BoldItalic findfont
- 60 scalefont setfont
- 200 425 translate
- 0.5 setlinewidth
- /Stringa (PostScript) def
- %
- % Stampa della spirale
- stampaSpirale
- %
- % Stampa dell stringa in grigio
- 100 0 moveto
- Stringa true charpath
- gsave
- 0.3 setgray fill
- grestore
- stroke
- %
- % Rimozione incapsulamento e
stampa
- grestore
- showpage
- %
- %%Trailer
- %%EOF
- %!PS-Adobe-2.0
- %%Title: Stampa in stile
"sandwich" di una scritta
- %%Creator: Corso PostScript -
parte IX - programma 3
- %%For: Corso PostScript BIT
- %%CreationDate: (4-10-1989)
(15:56)
- %%BoundingBox: 28 30 566 811
- %%EndComments
- %%EndProlog
- %
- % 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 stampaASandwich
- % Argomenti: stringa / -
- % Variabili Globali: -
- % Variabili Locali: Stringa
- % Stampa una stringa con effetto
"sandwich".
- /stampaASandwich {
- /Stringa exch def
- gsave Stringa show grestore
- gsave 3 0 rmoveto 1 setgray
- Stringa true charpath gsave fill
grestore
- 1 setlinewidth 0 setgray stroke
grestore
- 6 0 rmoveto Stringa show
- } def
- %
- %
- % Programma principale
- %
- % Incapsulamento e tracciatura
della cornice
- gsave
- tracciaCornice
- %
- % Inizializzazioni
- 1.0 inch 5.5 inch moveto
- /Times-BoldItalic findfont 1.5
inch scalefont setfont
- %
- % Chiamata della procedura
principale
- (PostScript) stampaASandwich
- %
- % Rimozione incapsulamento e
stampa
- grestore
- showpage
- %
- %%Trailer
- %%EOF
- %!PS-Adobe-2.0
- %%Title: Stampa di un testo
lungo una path qualunque
- %%Creator: Corso PostScript -
parte IX - programma 4
- %%For: Corso PostScript BIT
- %%CreationDate: (4-10-1989)
(15:56)
- %%BoundingBox: 28 30 566 811
- %%EndComments
- %%EndProlog
- %
- % Creazione del dizionario che
conterrà le procedure
- /stampaSuLineaDict 30 dict def
- %
- % Apertura del dizionario
- stampaSuLineaDict begin
- %
- % 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
- %
- % Sottoprocedura per trattare un
moveto della path
- /proceduraMoveto {
- /NuovoY exch def /NuovoX exch
def
- /PrimoX NuovoX def /PrimoY
NuovoY def
- /DistanzaInEccesso 0 def
- NuovoX NuovoY transform
- /AttualeY exch def /AttualeX
exch def
- } def
- %
- % Sottoprocedura per trattare un
lineto della path
- /proceduraLineto {
- /VecchioX NuovoX def /VecchioY
NuovoY def
- /NuovoY exch def /NuovoX exch
def
- /DeltaX NuovoX VecchioX sub def
- /DeltaY NuovoY VecchioY sub def
- /Distanza DeltaX dup mul DeltaY
dup mul add sqrt def
- Distanza 0 ne
- {
- /DistanzaX DeltaX Distanza div
DistanzaInEccesso mul def
- /DistanzaY DeltaY Distanza div
DistanzaInEccesso mul def
- VecchioX DistanzaX add VecchioY
DistanzaY add transform
- /AttualeY exch def /AttualeX
exch def
- /LunghezzaPercorsa
LunghezzaPercorsa Distanza add def
- {
- LunghezzaStampata
LunghezzaPercorsa le
- {NumeroCaratteriStampati Stringa
length lt
- {stampaCarattere} {exit} ifelse
}
- { /DistanzaInEccesso
LunghezzaStampata
- LunghezzaPercorsa sub def exit }
- ifelse } loop
- } if
- } def
- %
- % Sottoprocedura per trattare un
curveto della path.
- % (non ci possono essere curveto
dopo un flattenpath,
- % quindi la procedura si riduce
ad una eventuale
- % segnalazione di errore).
- /proceduraCurveto {
- (Non ci possono essere curveto
dopo un flattenpath!\n)
- (L'impossibile è avvenuto !\n)
- (ERRORE: \n)
- print print print
- } def
- %
- % Sottoprocedura per trattare un
closepath della path
- /proceduraClosepath {
- PrimoX PrimoY proceduraLineto
- PrimoX PrimoY proceduraMoveto
- } def
- %
- % Procedura per stampare un
carattere sulla path
- /stampaCarattere {
- /CarattereDaStampare Stringa
- NumeroCaratteriStampati 1
getinterval def
- /NumeroCaratteriStampati
NumeroCaratteriStampati 1 add def
- /larghezzaCarattere
CarattereDaStampare stringwidth pop def
- %
- gsave
- AttualeX AttualeY itransform
translate
- DeltaY DeltaX atan rotate 0 0
moveto CarattereDaStampare show
- currentpoint transform
- /AttualeY exch def /AttualeX
exch def
- grestore
- %
- /LunghezzaStampata
LunghezzaStampata larghezzaCarattere
- add def } def
- %
- % Chiusura del dizionario
- end
- %
- % Procedura principale
stampaSuLinea
- % Argomenti: stringa offset/ -
- % Variabili Globali: -
- % Variabili Locali: Stringa
Offset LunghezzaPercorsa
- % LunghezzaStampata
NumeroCaratteriStampati
- % Richiede che siano definiti
font e path correnti;
- % continua a stampare fino
all'esaurimento della path
- % o della stringa; modifica ma
non resetta la path corrente.
- /stampaSuLinea {
- %
- %Apre il dizionario contenente
le procedure
- stampaSuLineaDict begin
- %
- % Memorizza in variabili locali
gli argomenti
- /Offset exch def
- /Stringa exch def
- %
- % Inizializza le variabili
principali
- /LunghezzaPercorsa 0 def %
Distanza percorsa sulla linea
- /LunghezzaStampata Offset def %
Offset del testo
- /NumeroCaratteriStampati 0 def %
Contatore dei caratteri
- %
- gsave
- flattenpath
- {proceduraMoveto}
{proceduraLineto}
- {proceduraCurveto}
{proceduraClosepath}
- pathforall
- grestore
- %
- % Cancella la path corrente
- newpath
- %
- % Chiude il dizionario
contenente le procedure
- end
- } def
- %
- %
- % Programma principale
- %
- % Incapsulamento, tracciatura
cornice
- % e inizializzazioni
- gsave
- tracciaCornice
- /Times-Bold findfont 24
scalefont setfont
- %
- % Viene tracciata la path
- newpath
- 2.25 inch 5.5 inch moveto
- 5.25 inch 7.5 inch 2 inch 270
180 arc
- 3.25 inch 3.5 inch lineto
- 2.25 inch 3.5 inch 1 inch 0 180
arcn
- 1.25 inch 11.0 inch lineto
- %
- % Vengono posti sullo stack la
stringa da stampare...
- (Programmare in PostScript è un
pò contorto all'inizio, \
- ma i superstiti poi si abituano.
D'altronde, come diceva \
- John Belushi, "... quando
il gioco si fa duro, i duri \
- cominciano a giocare".)
- %
- % ...e l'offset a cui cominciare
a stampare
- 0
- stampaSuLinea
- %
- % Rimozione incapsulamento e
stampa della pagina
- grestore
- showpage
- %
- %%Trailer
- %%EOF
Copyright © 1985: Marco A. Calamari