[1] partea a V-a
În [1] semnalam dicţionarul GS /AdobeGlyphList
; acesta are 4200 de intrări, asociind numelor de caracter posibile în fişiere-font PS, „coduri universale” din Unicode:
vb@Home:~/20-iun$ gs -q # sesiune interactivă Ghostscript GS> (/usr/share/ghostscript/9.26/Resource/Init/gs_agl.ps) run GS> AdobeGlyphList length == 4200 GS>[/abreve /scommaaccent /ahiragana /whitediamondcontainingblacksmalldiamond] {AdobeGlyphList exch get ==} forall GS<1> 259 % /abreve ă (HTML: ă sau ă) 537 % /scommaaccent ș (HTML: ș) 12354 % /ahiragana あ (HTML: あ) 9672 % /whitediamondcontainingblacksmalldiamond ◈ (HTML: ◈) GS> quit
În [1] exprimasem bănuiala că 33 dintre cele 35 de fonturi PS de bază, conţin drept chei în dicţionarele CharStrings
aceleaşi 1004 nume de caracter (dintre cele 4200 posibile, înregistrate în /AdobeGlyphList
); cum am verifica aceasta, cât mai simplu?
Obs. Pentru a învăţa să foloseşti limbajul PostScript, trebuie să-ţi faci două obiceiuri: să consulţi din când în când §8.2 Operator Details din PLRM şi pe de altă parte, să experimentezi în sesiuni de lucru interactiv cu Ghostscript.
Ideea de bază în procesul de confruntare între ele a numelor de caracter din diversele fonturi, constă în folosirea operatorului known
:
vb@Home:~/20-iun$ gs -q GS> /ChrStr /Times-Roman findfont /CharStrings get def GS> ChrStr /abreve known % caută cheia '/abreve' în dicţionarul 'ChrStr' GS<1>pstack true % există! GS<1>pop GS> ChrStr /ahiragana known GS<1>pstack false % numele de caracter '/ahiragana' NU există (în /Times)
Fonturile dintr-o aceeaşi familie modelează aceleaşi caractere (diferind stilul glifelor: regulat, italic, oblic, bold, etc.); deci este suficient să considerăm câte unul din fiecare familie (dar ignorăm deocamdată, /Symbol
şi /ZapfDingbats
):
%! confront.ps /fonts [ /AvantGarde-Demi /Bookman-Light /Courier /Helvetica /NewCenturySchlbk-Roman /Palatino-Roman /Times-Roman /ZapfChancery-MediumItalic ] def % /Symbol /ZapfDingbats
Să fixăm, prin /ChrStr
, dicţionarul "CharStrings" al unuia dintre aceste fonturi, sau (cum preferăm aici) dintr-o derivată stilistică a acestuia (alegem Times-Italic
):
/ChrStr /Times-Italic findfont /CharStrings get def
Putem constata într-o sesiune interactivă GS, că acest ChrStr
are 1004 elemente (prin comanda: ChrStr length ==
) şi că dicţionarele "CharStrings" ale celor opt fonturi indicate în tabloul fonts
au deasemenea, lungimea 1004:
fonts {findfont /CharStrings get length} forall pstack
Obs. Amintim că "CharStrings" conţine perechi < cheie -string- >, unde cheie este un nume PS de caracter, iar -string- reprezintă criptat o anumită secvenţă de instrucţiuni PS prin care se produce traseul grafic al caracterului respectiv.
(putem afişa componentele fiecărei perechi prin: ChrStr {== ==} forall
)
Următoarea procedură presupune că vom fi adus pe stivă dicţionarul "CharStrings" al unuia dintre fonturi; se parcurg (prin forall
) elementele acestuia (descărcând prin pop
partea -string-) şi se verifică prin known
dacă numele curent întâlnit se regăseşte în dicţionarul ChrStr
(dacă da, atunci descărcăm cheia respectivă, trecând la următoarea; dacă nu, atunci descărcăm şi afişăm cheia respectivă prin operatorul ==
, trecând apoi la următorul element al dicţionarului din stivă):
/find_diff { % pe stivă: dicţionarul CharStrings al unui font { pop dup ChrStr exch % stiva: CharStrings, cheie, ChrStr, cheie known {pop}{==} ifelse } % cheie se găseşte în ChrStr? % pe stivă rămâne numai CharStrings forall % repetă blocul {...} pentru toate elementele din CharStrings } bind def
Pentru fiecare font din tabloul fonts
, scoatem pe stivă dicţionarul "CharStrings" al său şi invocăm find_diff
(programul „principal” al fişierului):
fonts { findfont /CharStrings get find_diff } forall
Lansând programul de 16 linii desfăşurat mai sus: gs -q confront.ps
, constatăm că nu se afişează nicio cheie; aceasta înseamnă că toate cheile din dicţionarul "CharString" al fiecăruia dintre fonturile respective, au fost regăsite în dicţionarul „martor” ChrStr
. Altfel spus, cele 33 de fonturi considerate mai sus conţin aceleaşi 1004 caractere (încât, „bănuiala” iniţială este acum confirmată).
Folosind apoi /find_diff
pentru fonturile rămase:
/Symbol findfont /CharStrings get find_diff
(şi analog pentru ZapfDingbats
) pe ecran se vor afişa câteva zeci de nume de caracter prezente în aceste două fonturi şi care nu se regăsesc în ChrStr
(dar sunt prezente în dicţionarul /AdobeGlyphList
).
Desigur, se conturează acum o noua încercare de programare PS: să formulăm un catalog comun, pentru toate fonturile numite în tabloul /fonts
– cam aşa:
În antetul fiecărei pagini scriem (prescurtat) numele fonturilor; apoi, pe fiecare rând, scriem glifele care corespund în fiecare font câte unui aceluiaşi nume de caracter.
Pe fiecare coloană (exceptând ultima) am avea glifele dintr-un acelaşi font (cel al cărui index în antetul paginii este egal cu rangul coloanei), corespunzătoare numelor de caracter indicate pe ultima coloană a paginii.
vezi Cărţile mele (de programare)