summaryrefslogtreecommitdiff
path: root/fonts/utilities/t1tools
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /fonts/utilities/t1tools
Initial commit
Diffstat (limited to 'fonts/utilities/t1tools')
-rw-r--r--fonts/utilities/t1tools/afm-inf.bat64
-rw-r--r--fonts/utilities/t1tools/afm-pfm.bat93
-rw-r--r--fonts/utilities/t1tools/afm-sort.bat14
-rw-r--r--fonts/utilities/t1tools/apple.enc173
-rw-r--r--fonts/utilities/t1tools/fm.ps1
-rw-r--r--fonts/utilities/t1tools/getmetri.bat60
-rw-r--r--fonts/utilities/t1tools/getmetri.ps298
-rw-r--r--fonts/utilities/t1tools/getmetric67
-rw-r--r--fonts/utilities/t1tools/gpreview277
-rw-r--r--fonts/utilities/t1tools/makeafm198
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/fontbbox.sed9
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/fontinf1.sed14
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/fontinf2.sed5
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/fontmetr.sed5
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/makeafm.bat129
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/pccinfo.sed7
-rw-r--r--fonts/utilities/t1tools/makeafm.dir/pccnames.sed90
-rw-r--r--fonts/utilities/t1tools/pcs.ps330
-rw-r--r--fonts/utilities/t1tools/pfb-abf.bat57
-rw-r--r--fonts/utilities/t1tools/pfb-enc.bat11
-rw-r--r--fonts/utilities/t1tools/pfb-sfp.bat58
-rw-r--r--fonts/utilities/t1tools/pfblist.bat1
-rw-r--r--fonts/utilities/t1tools/pfbnames.pas58
-rw-r--r--fonts/utilities/t1tools/pfbpr.bat20
-rw-r--r--fonts/utilities/t1tools/pfbshow.bat41
-rw-r--r--fonts/utilities/t1tools/pfshow.ps181
-rw-r--r--fonts/utilities/t1tools/readme228
-rw-r--r--fonts/utilities/t1tools/t1tidy/@t1tidy.doc281
-rw-r--r--fonts/utilities/t1tools/t1tidy/afm.pas361
-rw-r--r--fonts/utilities/t1tools/t1tidy/data.pas158
-rw-r--r--fonts/utilities/t1tools/t1tidy/pathunit.pas1135
-rw-r--r--fonts/utilities/t1tools/t1tidy/strtype.pas196
-rw-r--r--fonts/utilities/t1tools/t1tidy/t1t.bat48
-rw-r--r--fonts/utilities/t1tools/t1tidy/t1tidy.pas531
-rw-r--r--fonts/utilities/t1tools/t1tools.doc211
-rw-r--r--fonts/utilities/t1tools/w.enc144
36 files changed, 5554 insertions, 0 deletions
diff --git a/fonts/utilities/t1tools/afm-inf.bat b/fonts/utilities/t1tools/afm-inf.bat
new file mode 100644
index 0000000000..e88bb004c3
--- /dev/null
+++ b/fonts/utilities/t1tools/afm-inf.bat
@@ -0,0 +1,64 @@
+@echo off
+set dumvar=
+set del=
+if not "%1"=="-" goto mach
+set del=rem
+shift
+
+:mach
+egrep CapHeight %1.afm > %1.inf
+if not errorlevel 1 goto capok
+egrep FontBBox %1.afm | sed "s,.* \([-0-9][-0-9]*\) *$,CapHeight \1," > %1.inf
+:capok
+echo Serif true >> %1.inf
+echo Pi false >> %1.inf
+:getstyle
+if "%3"=="" goto genstyle
+echo VPStyle (%3) >> %1.inf
+goto getname
+:genstyle
+egrep "FontName.*(Demi|Semi|Bold|Heavy|Black|Ultra|Three)" %1.afm > nul
+if errorlevel 1 goto testweight
+goto testobl
+:testweight
+egrep "Weight.*(Demi|Semi|Bold|Heavy|Black|Ultra)" %1.afm > nul
+if errorlevel 1 goto notbold
+:testobl
+egrep "FontName.*(Italic|Oblique|Slanted)" %1.afm > nul
+if errorlevel 1 goto bold
+echo ItalicAngle -20 >> %1.inf
+echo VPStyle (T) >> %1.inf
+goto getname
+:bold
+echo VPStyle (B) >> %1.inf
+goto getname
+:notbold
+egrep "FontName.*(Italic|Oblique|Slanted)" %1.afm > nul
+if errorlevel 1 goto normal
+echo ItalicAngle -20 >> %1.inf
+echo VPStyle (I) >> %1.inf
+goto getname
+:normal
+echo VPStyle (N) >> %1.inf
+
+:getname
+if "%2"=="" goto genname
+if "%2"=="-" goto genname
+if not "%3"=="" echo DOS command restriction: family name may not contain blanks
+echo MSMenuName (%2) >> %1.inf
+goto end
+
+rem this was used with dos grep and without sed:
+:gennameold
+grep FamilyName %1.afm | sort > MSMenu$$.bat
+call MSMenu$$.bat
+type MSMenu$$.i >> %1.inf
+%del% del MSMenu$$.bat
+%del% del MSMenu$$.i
+goto end
+
+:genname
+egrep -e FamilyName %1.afm | sed "s,FamilyName *\(.*\) *$,MSMenuName (\1)," >> %1.inf
+rem with DOS grep, grep -o could be used here instead of egrep -e
+
+:end
diff --git a/fonts/utilities/t1tools/afm-pfm.bat b/fonts/utilities/t1tools/afm-pfm.bat
new file mode 100644
index 0000000000..a9fa22bc8f
--- /dev/null
+++ b/fonts/utilities/t1tools/afm-pfm.bat
@@ -0,0 +1,93 @@
+@echo off
+set dumvar=
+set del=
+if not "%1"=="-" goto mach
+set del=rem
+shift
+
+:mach
+if exist %1.afm goto los
+echo "Parameter: [-] fontfile [without afm suffix] [MSMenuName | - ] [N | I | B | T]"
+goto end
+
+:los
+set enc=C:\Adobe\foundry\w
+if exist %1.enc set enc=%1
+if exist %1.inf goto makepfminf
+
+egrep CapHeight %1.afm > %1.inf
+if not errorlevel 1 goto capok
+egrep FontBBox %1.afm | sed "s,.* \([-0-9][-0-9]*\) *$,CapHeight \1," > %1.inf
+:capok
+echo Serif true >> %1.inf
+echo Pi false >> %1.inf
+:getstyle
+if "%3"=="" goto genstyle
+echo VPStyle (%3) >> %1.inf
+goto getname
+:genstyle
+egrep "FontName.*(Demi|Semi|Bold|Heavy|Black|Ultra|Three)" %1.afm > nul
+if errorlevel 1 goto testweight
+goto testobl
+:testweight
+egrep "Weight.*(Demi|Semi|Bold|Heavy|Black|Ultra)" %1.afm > nul
+if errorlevel 1 goto notbold
+:testobl
+egrep "FontName.*(Italic|Oblique|Slanted)" %1.afm > nul
+if errorlevel 1 goto bold
+echo ItalicAngle -20 >> %1.inf
+echo VPStyle (T) >> %1.inf
+goto getname
+:bold
+echo VPStyle (B) >> %1.inf
+goto getname
+:notbold
+egrep "FontName.*(Italic|Oblique|Slanted)" %1.afm > nul
+if errorlevel 1 goto normal
+echo ItalicAngle -20 >> %1.inf
+echo VPStyle (I) >> %1.inf
+goto getname
+:normal
+echo VPStyle (N) >> %1.inf
+
+:getname
+if "%2"=="" goto genname
+if "%2"=="-" goto genname
+if not "%3"=="" echo DOS command restriction: family name may not contain blanks
+echo MSMenuName (%2) >> %1.inf
+goto makepfm
+
+rem this was used with dos grep and without sed:
+:gennameold
+grep FamilyName %1.afm | sort > MSMenu$$.bat
+call MSMenu$$.bat
+type MSMenu$$.i >> %1.inf
+%del% del MSMenu$$.bat
+%del% del MSMenu$$.i
+goto makepfm
+
+:genname
+egrep -e FamilyName %1.afm | sed "s,FamilyName *\(.*\) *$,MSMenuName (\1)," >> %1.inf
+rem with DOS grep, grep -o could be used here instead of egrep -e
+
+:makepfm
+C:\Adobe\foundry\makepfm.exe -e %enc%.enc -i %1.inf -l nul %1.afm
+%del% del %1.inf
+if exist %1.pfm goto end
+goto error
+
+:makepfminf
+C:\Adobe\foundry\makepfm.exe -e %enc%.enc -i %1.inf -l nul %1.afm
+if exist %1.pfm goto end
+
+:error
+echo off
+echo makepfm failed. Possible errors:
+echo 1. CapHeight entry must be present (last value of B box of letter H)
+echo 2. StartCharMetrics entry must contain exact number of character entries
+echo 3. Character entries must have B box information. To fake them, take
+echo the FontBBox x1 y1 x2 y2 entry and insert behind every character's
+echo N (name) entry: B x1 y1 x2 y2 ;
+echo 4. makepfm doesn't seem to like character position 0 in afm files
+echo 5. .inf file was not built properly
+:end
diff --git a/fonts/utilities/t1tools/afm-sort.bat b/fonts/utilities/t1tools/afm-sort.bat
new file mode 100644
index 0000000000..2604ada5e0
--- /dev/null
+++ b/fonts/utilities/t1tools/afm-sort.bat
@@ -0,0 +1,14 @@
+@echo off
+set dumvar=
+set del=
+if not "%1"=="-" goto mach
+set del=rem
+shift
+
+:mach
+sed -e /StartFontMetrics/,/StartKernPairs/p -e d %1.afm > %1.afs
+egrep KPX %1.afm | sort >> %1.afs
+sed -e /EndKernPairs/,/EndFontMetrics/p -e d %1.afm >> %1.afs
+%del% if exist %1.af$ del %1.af$
+ren %1.afm %1.af$
+ren %1.afs %1.afm
diff --git a/fonts/utilities/t1tools/apple.enc b/fonts/utilities/t1tools/apple.enc
new file mode 100644
index 0000000000..b116cc915e
--- /dev/null
+++ b/fonts/utilities/t1tools/apple.enc
@@ -0,0 +1,173 @@
+%
+% This encoding vector represents the differences between the PostScript
+% standard encoding and the AppleStandardEncoding character set.
+% assembled by Thomas Wolff - Dec 92
+%
+MaxIndex 255
+MaxEncoded 255
+%
+StartEncoding
+0 NUL
+1 Eth
+2 eth
+3 Lslash
+4 lslash
+5 Scaron
+6 scaron
+7 Yacute
+8 yacute
+9 HT
+10 LF
+11 Thorn
+12 thorn
+13 CR
+14 Zcaron
+15 zcaron
+16 DLE
+17 DC1
+18 DC2
+19 DC3
+20 DC4
+21 onehalf
+22 onequarter
+23 onesuperior
+24 threequarters
+25 threesuperior
+26 twosuperior
+27 brokenbar
+28 minus
+29 multiply
+30 RS
+31 US
+39 quotesingle
+96 grave
+127 DEL
+128 Adieresis
+129 Aring
+130 Ccedilla
+131 Eacute
+132 Ntilde
+133 Odieresis
+134 Udieresis
+135 aacute
+136 agrave
+137 acircumflex
+138 adieresis
+139 atilde
+140 aring
+141 ccedilla
+142 eacute
+143 egrave
+144 ecircumflex
+145 edieresis
+146 iacute
+147 igrave
+148 icircumflex
+149 idieresis
+150 ntilde
+151 oacute
+152 ograve
+153 ocircumflex
+154 odieresis
+155 otilde
+156 uacute
+157 ugrave
+158 ucircumflex
+159 udieresis
+160 dagger
+161 degree
+162 cent
+163 sterling
+164 section
+165 bullet
+166 paragraph
+167 germandbls
+168 registered
+169 copyright
+170 trademark
+171 acute
+172 dieresis
+173 notequal
+174 AE
+175 Oslash
+176 infinity
+177 plusminus
+178 lessequal
+179 greaterequal
+180 yen
+181 mu
+182 partialdiff
+183 summation
+184 product
+185 pi
+186 integral
+187 ordfeminine
+188 ordmasculine
+189 Omega
+190 ae
+191 oslash
+192 questiondown
+193 exclamdown
+194 logicalnot
+195 radical
+196 florin
+197 approxequal
+198 Delta
+199 guillemotleft
+200 guillemotright
+201 ellipsis
+202 nbspace
+203 Agrave
+204 Atilde
+205 Otilde
+206 OE
+207 oe
+208 endash
+209 emdash
+210 quotedblleft
+211 quotedblright
+212 quoteleft
+213 quoteright
+214 divide
+215 lozenge
+216 ydieresis
+217 Ydieresis
+218 fraction
+219 currency
+220 guilsinglleft
+221 guilsinglright
+222 fi
+223 fl
+224 daggerdbl
+225 periodcentered
+226 quotesinglbase
+227 quotedblbase
+228 perthousand
+229 Acircumflex
+230 Ecircumflex
+231 Aacute
+232 Edieresis
+233 Egrave
+234 Iacute
+235 Icircumflex
+236 Idieresis
+237 Igrave
+238 Oacute
+239 Ocircumflex
+240 apple
+241 Ograve
+242 Uacute
+243 Ucircumflex
+244 Ugrave
+245 dotlessi
+246 circumflex
+247 tilde
+248 macron
+249 breve
+250 dotaccent
+251 ring
+252 cedilla
+253 hungarumlaut
+254 ogonek
+255 caron
+EndEncoding
diff --git a/fonts/utilities/t1tools/fm.ps b/fonts/utilities/t1tools/fm.ps
new file mode 100644
index 0000000000..649c0fdc81
--- /dev/null
+++ b/fonts/utilities/t1tools/fm.ps
@@ -0,0 +1 @@
+/deviceinfo 0 dict def
diff --git a/fonts/utilities/t1tools/getmetri.bat b/fonts/utilities/t1tools/getmetri.bat
new file mode 100644
index 0000000000..7f68f3cf7a
--- /dev/null
+++ b/fonts/utilities/t1tools/getmetri.bat
@@ -0,0 +1,60 @@
+@echo off
+if not "%1"=="-" goto weiter
+set dumvar=
+set del=rem
+shift
+:weiter
+if not "%1"=="" goto los
+echo Parameter: font-file (without .pfb / .pfa suffix) [/FontName]
+goto end
+
+:los
+rem copy %GS_LIB%\getmetri.ps %TEMP%\getafm$$.ps
+if exist %1.pfa goto pfa
+if exist %1.pfb goto pfb
+echo no font file (.pfb / .pfa) present
+goto end
+:pfa
+type %1.pfa > %TEMP%\getafm$$.ps
+goto fontok
+:pfb
+D:\fonts\progs\t1utils\t1ascii %1.pfb > %TEMP%\getafm$$.ps
+:fontok
+echo appendnewfont >> %TEMP%\getafm$$.ps
+echo fontname %2 getmetric0 quit >> %TEMP%\getafm$$.ps
+
+rem try to save kerning information from previous .afm file
+rem or to extract it from .pfm file
+if exist %1.afm goto afmkern
+if not exist %1.pfm goto startafm
+echo extracting kerning information from %1.pfm
+pfm2afm %1
+rem dumppfm %1.pfm %1.afm
+
+:afmkern
+rem echo saving kerning information from %1.afm
+rem egrep -e "^(StartKern|EndKern|KPX)" %1.afm > %TEMP%\%1.kpx
+echo saving Composite and KernData information from %1.afm
+rem sed -e /StartComposites/,/EndComposites/p -e /StartKernData/,/EndKernData/p -e d < %1.afm > %TEMP%\%1.kpx
+sed -e /EndCharMetrics/,/EndFontMetrics/p -e d < %1.afm > %TEMP%\%1.kpx
+
+:startafm
+echo generating afm information
+gs -q -DNODFONT -DNODISPLAY getmetri.ps %TEMP%\getafm$$.ps | sed -e /StartFontMetrics/,$p -e d > %1.afm
+
+rem insert previously extracted or saved kerning information
+if not exist %TEMP%\%1.kpx goto nokern
+echo adding kerning and composite information
+type %TEMP%\%1.kpx >> %1.afm
+rem if sorting of KPX entries is desired, they must be kept apart from CC etc
+rem egrep -e "^StartKern" %TEMP%\%1.kpx >> %1.afm
+rem egrep -e "^KPX" %TEMP%\%1.kpx | sort >> %1.afm
+rem egrep -e "^EndKern" %TEMP%\%1.kpx >> %1.afm
+goto fini
+:nokern
+echo EndCharMetrics>> %1.afm
+echo EndFontMetrics>> %1.afm
+:fini
+if exist %TEMP%\%1.kpx %del% del %TEMP%\%1.kpx
+%del% del %TEMP%\getafm$$.ps
+:end
diff --git a/fonts/utilities/t1tools/getmetri.ps b/fonts/utilities/t1tools/getmetri.ps
new file mode 100644
index 0000000000..cf2cec0be1
--- /dev/null
+++ b/fonts/utilities/t1tools/getmetri.ps
@@ -0,0 +1,298 @@
+%!
+% Get the Font Metric Information from a font
+
+% Written by W.T. Roberts, Queen Mary College, LONDON UK
+% (liam@cs.qmc.ac.uk, liam@qmc-cs.UUCP)
+
+% modified 3/91 by Bryan Bayerdorffer, UT Austin, Austin, TX, USA
+% (bryan@cs.utexas.edu)
+
+% modified 4/93 by Thomas Wolff (wolff@inf.fu-berlin.de):
+% must discard UniqueID as well as FID when generating modified font copy
+% ligature information must only be printed if ligatures are present
+% the availability of the four CapHeight etc entries is decided separately
+% to allow CapHeight to be generated even if the font does not
+% contain small characters
+% if no CapHeight can be determined (because there is no letter "H") the
+% height value of FontBBox is taken instead - Adobe's makepfm
+% program requires the presence of this entry
+% moved the FontName line behind the Comment lines
+% added the EncodingScheme information
+% now printing FontInfo contents in well-defined order
+% added character count in StartCharMetrics
+% changed BBox information for null characters to 0 0 0 0
+% don't generate entries for undefined characters, even if included in
+% the font's encoding
+% getmetric0 variant leaves out final "End..." entries to simplify
+% merging in kerning and composite information from other sources
+% added code for automatic new font name detection to enable cooperation
+% with simple MSDOS batch script
+
+%statusdict begin 0 setjobtimeout end
+
+/xdef {exch def} def
+/sp {( ) print} def
+/nl {(\n) print flush} def
+/eof {(\034) print flush} def %Amiga end-of-file
+
+/= { %dup type (stringtype) ne {
+ buffer cvs
+ %} if
+ print} def
+/toupper {
+ dup dup (a) 0 get ge exch (z) 0 get le and
+ {(a) 0 get sub (A) 0 get add} if % convert to lowercase
+} def
+
+/buffer 250 string def
+
+/getmetric0 {
+% /VMsave save def
+ dup findfont /fontdict xdef % grab the font
+ (StartFontMetrics 1.0) print nl
+ (Comment generated by getmetric.ps (by W.T. Roberts, qmc-cs.UUCP)) print nl
+ (Comment (modified 3/91 by Bryan Bayerdorffer, 4/93 by Thomas Wolff)) print nl
+ (FontName ) print = nl % record PostScript name
+ getFontInfo
+ getEncodingScheme
+ getFontBBox
+ iniBBox
+ recorddefaults % get the default encoding
+ miscHeights
+ recordunencoded
+ (StartCharMetrics ) print #name = nl
+ getCharMetrics
+ checkBBox
+% VMsave restore
+} def
+
+/getmetric {
+ getmetric0
+ (EndCharMetrics) print nl
+ (EndFontMetrics) print nl
+} def
+
+/iniBBox { /llx 1000 def /lly 1000 def /urx -1000 def /ury -1000 def } def
+
+/checkBBox {
+ llx BBllx 1 sub lt
+ lly BBlly 1 sub lt
+ urx BBurx 1 add gt
+ ury BBury 1 add gt
+ or or or
+ {(Comment calculated FontBBox) print
+ ury urx lly llx
+ 4 {sp =} repeat % convert to 1000 point and print
+ nl
+ } if
+} def
+
+/getFontInfo {
+ fontdict /FontInfo known
+ {fontdict /FontInfo get
+ {exch buffer cvs dup
+ dup 0 get toupper 0 exch put % convert first letter to UC
+ print sp = nl} forall
+ }
+ if
+} def
+
+/getFontInfo {
+ fontdict /FontInfo known
+ {fontdict /FontInfo get
+ [/FullName /FamilyName /Weight /ItalicAngle /isFixedPitch
+ /UnderlinePosition /UnderlineThickness /version /Notice]
+ {2 copy known
+ {2 copy get
+ exch buffer cvs dup
+ dup 0 get toupper 0 exch put % convert first letter to upper case
+ print sp = nl}
+ {pop}
+ ifelse
+ }
+ forall
+ }
+ if
+} def
+
+/getFontBBox {
+ fontdict /FontMatrix get dup
+ length array /fmat xdef
+ fmat copy pop
+ fontdict /FontBBox get aload pop % llx lly trx try
+ fmat transform 4 2 roll fmat transform % TRX TRY LLX LLY
+ 4 {1000 mul round cvi 4 1 roll} repeat % convert to 1000 point
+ (FontBBox) print
+ 4 copy /BBlly xdef /BBllx xdef /BBury xdef /BBurx xdef
+ 2 {exch sp = sp =} repeat
+ nl
+} def
+
+/getEncodingScheme {
+ /EncodingScheme (FontSpecific) def % the default
+ fontdict /Encoding get
+ dup StandardEncoding eq
+ {/EncodingScheme (AdobeStandardEncoding) def} if
+ dup SymbolEncoding eq
+ {/EncodingScheme (SymbolEncoding) def} if
+ % others...
+ pop
+ (EncodingScheme ) print EncodingScheme print nl
+} def
+
+/maketempfont { % encoding vector
+ fontdict length dict /testdict xdef
+ fontdict
+ { 1 index dup /FID ne exch /UniqueID ne and
+ {testdict 3 1 roll put} {pop pop} ifelse
+ } forall % copy contents of fontdict
+ testdict begin
+ /Encoding encoding def
+ end % install the encoding vector
+ /TestName testdict definefont 1000 scalefont setfont
+} def
+
+/recorddefaults {
+ fontdict /CharStrings known
+ {fontdict /CharStrings get length
+ 256 gt
+ {fontdict /CharStrings get length}
+ {256}
+ ifelse}
+ {256}
+ ifelse
+ array /names xdef % make array to hold the names
+ /#name 0 def
+ /defaultEncoding 256 dict def
+ fontdict begin
+ defaultEncoding begin
+ 0 1 Encoding length 1 sub
+ {dup Encoding exch get dup
+ dup /.notdef ne % ignore .notdef ...
+ exch fontdict /CharStrings known
+ {fontdict /CharStrings get exch known} % and undefined characters
+ {pop true}
+ ifelse
+ and
+ {dup recordname exch def}
+ {pop pop}
+ ifelse % record number
+ } for
+ end
+ end
+} def
+
+/recordname {
+ userdict begin
+ names exch #name exch put
+ /#name #name 1 add def
+ end
+} def
+
+/recordunencoded {
+ fontdict /CharStrings known
+ {fontdict /CharStrings get
+ {pop dup dup
+ /.notdef eq exch % ignore .notdef
+ defaultEncoding exch known or % and defaultEncoding names
+ {pop} {recordname} ifelse
+ } forall
+ }
+ if
+} def
+
+/getCharMetrics {
+ 256 array /encoding xdef
+ /namecount #name def /first 0 def
+ % while (true)
+ {namecount 256 le
+ {names first namecount getinterval}
+ {names first 256 getinterval}
+ ifelse
+ encoding copy pop
+ maketempfont
+ 0 1 encoding length namecount le
+ {encoding length 1 sub}
+ {namecount 1 sub}
+ ifelse
+ {getcharmetric}
+ for
+ /namecount namecount 256 sub def
+ /first first 256 add def
+ namecount 0 le {exit} if
+ } loop
+} def
+
+/miscHeights {
+ /encoding fontdict /Encoding get def maketempfont % make real font
+ defaultEncoding begin
+ currentdict /H known
+ {H nbbox (CapHeight ) print dup = nl 4p}
+ {(CapHeight ) print BBury = nl} ifelse
+ currentdict /x known
+ {x nbbox (XHeight ) print dup = nl 4p} if
+ currentdict /d known
+ {d nbbox (Ascender ) print dup = nl 4p} if
+ currentdict /p known
+ {p nbbox (Descender ) print 2 index = nl 4p} if
+ end
+} def
+
+/4p {pop pop pop pop} def
+/nbbox {char exch 0 exch put charbbox} def
+/charbbox {
+ newpath 0 0 moveto char true charpath flattenpath pathbbox
+ 4 {4 1 roll round cvi} repeat
+} def
+
+/char ( ) def
+/getcharmetric {
+ /n exch def % grab the character code
+ char 0 n put % make a string from it
+ /label encoding n get def % record its text name
+ (C ) print
+ defaultEncoding label known
+ {defaultEncoding label get} {-1} ifelse
+ = ( ; ) print
+ char stringwidth round cvi /ywidth exch def round cvi /xwidth exch def
+ ywidth 0 eq
+ {(WX ) print xwidth = }
+ {(W ) print xwidth = sp ywidth =}
+ ifelse
+ ( ; N ) print label =
+ ( ; B) print
+ charbbox
+ dup 3 index eq 2 index 5 index eq and
+ {pop pop pop pop 0 0 0 0} if
+ 4 copy
+ ury max /ury xdef urx max /urx xdef lly min /lly xdef llx min /llx xdef
+ 4 2 roll 2 {exch sp = sp =} repeat
+ label /f eq
+ {fontdict /CharStrings known
+ {fontdict /CharStrings get
+ dup /fi known
+ {( ; L i fi) print}
+ if
+ /fl known
+ {( ; L l fl) print}
+ if
+ }
+ if
+ }
+ if
+ ( ;) print nl
+} def
+%end
+
+/fontlist [] def
+/FontDirectoryKnown FontDirectory dup length 20 add dict copy def
+/appendnewfont {
+ /fontlist [ fontlist aload pop
+ FontDirectoryKnown begin
+ FontDirectory
+ {FontDirectoryKnown 2 index known {pop pop} {2 copy def pop} ifelse
+ } forall
+ end
+ ] def
+ } def
+/fontname {fontlist 0 get} def
diff --git a/fonts/utilities/t1tools/getmetric b/fonts/utilities/t1tools/getmetric
new file mode 100644
index 0000000000..e58a2a6603
--- /dev/null
+++ b/fonts/utilities/t1tools/getmetric
@@ -0,0 +1,67 @@
+#! /bin/sh
+
+afmdir=${afmdir-afm}
+
+pfafontname () {
+ sed -e '/\<eexec\>/q' -e '/\<CharStrings\>/q' |
+ sed -e 's,.*FontName *[[{(]\(.*\)[]})].*,\1,' -e t \
+ -e 's,.*FontName[ /]*\([^ ]*\).*,\1,' -e t \
+ -e d
+ }
+
+for file in $*
+do font=`basename $file .pfb`
+ font=`basename $font .pfa`
+ if [ ! -f $font.pfa ]
+ then t1ascii $font.pfb $font.pfa
+ delpfa=/bin/rm
+ else delpfa=#
+ fi
+ FontName=`pfafontname < $font.pfa`
+
+ if [ -f $font.afm ]
+ then echo saving Composite and KernData information from old afm
+ # sed -e /StartComposites/,/EndComposites/p -e /StartKernData/,/EndKernData/p -e d < $font.afm > $font.cck
+ sed -e /EndCharMetrics/,/EndFontMetrics/p -e d < $font.afm > $font.cck
+ elif [ -f $font.pfm ]
+ then
+ echo EndCharMetrics > $font.cck
+ set - ` ( /bin/dd ibs=1 skip=195 count=2 < $font.pfm | /bin/dd conv=swab | /bin/od -d ) 2> /dev/null `
+ pairs=`expr $2 + 0`
+ if [ $pairs -ne 0 ]
+ then
+ WinANSI=`dirname $0`/WinANSI
+ len=`expr $pairs \* 4`
+
+ set - ` ( /bin/dd ibs=1 skip=131 count=4 < $font.pfm | /bin/dd conv=swab | /bin/od -d ) 2> /dev/null `
+ start=`expr $3 \* 65536 + $2 + 2`
+
+ echo StartKernData >> $font.cck
+ echo StartKernPairs $pairs >> $font.cck
+
+ /bin/dd ibs=1 skip=$start count=$len < $font.pfm | /bin/dd conv=swab |
+ /bin/od -vbiw4 |
+ sed -e '/^0/N' -e 's,^[0-7]* *\([0-7]*\) \([0-7]*\) [0-7]* [0-7]*[^-0-9]*[-0-9]* *\([-0-9]*\)$,KPX C\2 C\1 \3,' -f ${WinANSI}1 |
+ sed -f ${WinANSI}2 >> $font.cck
+
+ echo EndKernPairs >> $font.cck
+ echo EndKernData >> $font.cck
+ else
+ echo no kern pairs in $font.pfm
+ fi
+ echo EndFontMetrics >> $font.cck
+ fi
+
+ echo /$FontName getmetric0 | gs -DNODISPLAY -q $font.pfa getmetri.ps - > $font.afm
+
+ if [ -f $font.cck ]
+ then cat $font.cck >> $font.afm
+ fi
+
+ eval $delpfa $font.pfa
+ /bin/rm $font.cck
+ if [ -d $afmdir ]
+ then ln $font.afm $afmdir/$FontName.afm
+ else ln $font.afm $FontName.afm
+ fi
+done
diff --git a/fonts/utilities/t1tools/gpreview b/fonts/utilities/t1tools/gpreview
new file mode 100644
index 0000000000..dbeed59505
--- /dev/null
+++ b/fonts/utilities/t1tools/gpreview
@@ -0,0 +1,277 @@
+#! /bin/sh
+
+case `basename $0` in
+ gprev*) show="cat > /tmp/gs$$.ps; gs /tmp/gs$$.ps < /dev/tty; rm -f /tmp/gs$$.ps"; prep="erasepage 20 780 sethome" ;;
+ prev*) show=psh ; prep="erasepage 20 780 sethome" ;;
+ pspre*) show=cat ; prep="12 setfontsize" ;;
+ *) show=lpr ; prep="12 setfontsize" ;;
+esac
+
+psatops () {
+# 3 further transformations on decomp's output:
+# ^M -> ^J : to edit it on unix machines
+# < > -> { } : to make it a PostScript program
+# remove access restriction operators to play around with it in an
+# interactive PostScript interpreter
+ sed -e 'y/ <>/\n{}/' -e 's/executeonly//g' -e 's/noaccess//g' -e 's/readonly//g'
+ }
+
+pfbtops () {
+ if t1disasm $1
+ then true # t1disasm did the job
+ elif decrypt $1 | decomp | psatops
+ then true # decrypt, decomp did the job
+ else false # no one found to do the job
+ fi
+ }
+
+pfbtopfa () {
+ if t1ascii $1
+ then true # t1ascii did the job
+ elif pfb2ps < $1
+ then true # one of numerous PD programs could do this simple job
+ else case $1 in
+ *.pfb) fmAdobePCFont $1 ${TMPDIR-/tmp}/$$.pfa ;;
+ *.pfe|*.rsrc) fmAdobeMacFont $1 ${TMPDIR-/tmp}/$$.pfa ;;
+ esac
+ # this should be found in $FMHOME/bin
+ # it runs slower than others
+ cat ${TMPDIR-/tmp}/$$.pfa
+ /bin/rm ${TMPDIR-/tmp}/$$.pfa
+ fi
+ }
+
+((cat
+echo $prep
+if [ "$show" = "psh" ]
+then cat $HOME/ps/emulate.ps - << \*EOP*
+%!
+% (emulate.ps) run % alternatively to cat-ting it in
+/eexec {pop} def
+/*definefont /definefont load def
+/definefont {dup /FontType get 1 eq
+ {dup length 3 add dict copy
+ dup /FontType 3 put
+ dup /Type1EmuDict dup load put
+ dup /BuildChar dup load put
+ } if
+ 1 index registername % this could be left out if only
+ % new fonts (not preloaded into NeWS) are displayed
+ *definefont
+ } def
+/*closefile /closefile load def
+/closefile {pop} def % NeWS's closefile crashes
+/executeonly {} def
+/noaccess {} def
+/readonly {} def
+*EOP*
+fi
+for param in $*
+do if [ `dirname $param` = / ]
+ then echo $param registername
+ # take this as explicitly specified fontname instead of filename
+ else
+ case $param in
+ *.pfb|*.pfe|*.rsrc)
+ if [ "$show" = "psh" ]
+ then pfbtops $param
+ else pfbtopfa $param
+ fi
+ echo appendnewfont ;;
+ *.pfa) if [ "$show" = "psh" ]
+ then pfbtops $param
+ else cat $param
+ fi
+ echo appendnewfont ;;
+ *.Z) zcat $param
+ echo appendnewfont ;;
+ *.zip) unzip -p $param
+ echo appendnewfont ;;
+ *) cat $param
+ echo appendnewfont ;;
+ esac
+ fi
+done ; echo " " showallfonts showpage quit) | eval $show) << \*EOP*
+%! print font samples and character sets
+/home {leftborder top moveto} def
+/sethome {/top exch def /leftborder exch def} def
+/setfontsize {/fontsize exch def} def
+/setrightborder {/rightborder exch def} def
+40 790 sethome
+18 setfontsize
+550 setrightborder
+/leading 4 def
+/nl {currentpoint exch pop leftborder exch fontsize sub leading sub moveto} def
+
+/fontN {fontN} def
+/fontB {fontN} def
+/fontI {fontB} def
+/fontBI {fontB} def
+/N {fontN setfont} def
+/B {fontB setfont} def
+/I {fontI setfont} def
+/BI {fontBI setfont} def
+/pushfont {/fontBI /fontI load def
+ /fontI /fontB load def
+ /fontB /fontN load def
+ /fontN currentfont def
+ } def
+/nextfonti 0 def
+/setnextfont {[/fontN /fontI /fontB /fontBI] nextfonti get currentfont def
+ /nextfonti nextfonti 1 add def
+ } def
+
+/namefont {currentfont} def
+/showtext {
+ N
+ (Scoloplos ist euryök. Er ist in der gesamten borealen Region ) show nl
+ (in fast allen marinen Sedimenten zu finden, die einen sandigen ) show nl
+ (Anteil aufweisen. Man findet ihn von ) show B (Grönland ) show
+ N (bis zum ) show I (Mittelmeer) show N (, ) show nl
+ (in der ) show BI (Nordsee) show
+ N (, an der kanadischen Küste und im Weißen Meer. ) show nl
+ (Er besiedelt sowohl das Eulitoral als auch das Bathyal.) show nl
+ } def
+/showcset {[cs1 cs2 cs3 cs4 cs5 cs6 cs7] {show nl} forall
+ currentfont
+ currentpoint
+ dup fontsize leading add 3 mul add
+ currentfont /FontName get findfont 50 scalefont setfont
+ rightborder (Forqen) stringwidth pop sub exch moveto
+ (Forqen) show
+ moveto
+ setfont
+ } def
+/showcsetbig {
+ 2 2 scale
+ [cs1 cs2 cs3 cs4 cs5 cs6 cs7] {show nl} forall
+ .5 .5 scale
+ currentfont
+ currentpoint
+ dup fontsize leading add -2 mul add
+ currentfont /FontName get findfont 100 scalefont setfont
+ rightborder (Forqen) stringwidth pop sub exch moveto
+ (Forqen) show
+ moveto
+ setfont
+ } def
+/showname {currentfont namefont setfont
+ dup /FontName get dup length string cvs show
+ setfont nl
+ } def
+/showfont { % param: fontname
+ fontsize ff
+ home
+ showtext
+ showname
+ showcset % or: showcsetbig
+ } def
+/showallfonts {
+ % if registername was used, replace the automatically generated
+ % fontlist with the explicit one:
+ fontlistr length 0 ne {/fontlist fontlistr def} if
+
+ fontlist {fontsize ff setnextfont} forall
+ home showtext
+ [fontN fontI fontB fontBI] 0 fontlist length getinterval
+ {nl setfont ( ) show showname nl
+ showcset % or: showcsetbig
+ } forall
+ } def
+
+/findfontISO {dup findfont
+ dup maxlength dict begin
+ {1 index /FID ne {def} {pop pop } ifelse} forall
+ Encoding StandardEncoding eq
+ % pop true
+ {/Encoding ISO-Latin-1 def} if
+ currentdict end
+ definefont
+ } def
+/ff {exch findfontISO exch dup /fontsize exch def scalefont
+ setfont} def
+
+/fontlist [] def
+/fontlistr [] def
+/FontDirectoryKnown FontDirectory dup length 20 add dict begin
+ {def}
+ forall
+ currentdict end def
+/appendnewfont {
+ /fontlist [ fontlist aload pop
+ FontDirectoryKnown begin
+ FontDirectory
+ {FontDirectoryKnown 2 index known {pop pop} {2 copy def pop} ifelse
+ } forall
+ end
+ ] def
+ } def
+/registerfont {run appendnewfont} def
+/registername {/newfont exch def
+ /fontlistr [ fontlistr aload pop newfont ] def
+ } def
+
+/=dict { % for debugging
+ {2 array astore ==} forall
+ } def
+
+/cs1 ( !"#$%&'()*+,-./0123456789:;<=>?) def
+/cs2 (@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_) def
+/cs3 (`abcdefghijklmnopqrstuvwxyz{|}~) def
+/cs4 (€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ) def
+/cs5 ( ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿) def
+/cs6 (ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß) def
+/cs7 (àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ) def
+
+/ISO-Latin-1 [
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright
+% or: /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+% or: /grave
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /fraction
+% accents not in ISO-Latin-1:
+/dotlessi /ring /circumflex /tilde /breve /dotaccent
+/grave % see comment below
+% FrameMaker characters:
+/quotesingle % comment: must have /quoteleft instead of /grave, or
+ % /quoteright instead of /quotesingle, resp.,
+ % depending on which is already present above
+/quotesinglbase /quotedblbase /quotedblleft /quotedblright
+/guilsinglleft /guilsinglright
+/trademark
+/caron /hungarumlaut /ogonek
+/OE /oe
+/fi /fl
+/dagger /daggerdbl /ellipsis /emdash /florin /periodcentered /perthousand
+% DEC-supplemental (also /OE /oe):
+/Ydieresis
+% further PostScript chars:
+/Lslash /lslash
+
+% this must align with 240 octal
+/space /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /endash /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /bullet
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis
+] def
+
+*EOP*
diff --git a/fonts/utilities/t1tools/makeafm b/fonts/utilities/t1tools/makeafm
new file mode 100644
index 0000000000..c40f34cc9d
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm
@@ -0,0 +1,198 @@
+#! /bin/sh
+
+# makeafm: generate .afm file from PostScript type 1 font file
+# (leaves out character bounding box information)
+# It accepts the file formats:
+# .pfb - type 1 encrypted binary file
+# .pfa - hex version of .pfb
+# .psb - first level of decryption; character outlines still encrypted
+# .psa - second level of decryption; character outlines embedded in
+# < > to recognize them for back-encryption; thus not PostScript
+# .ps - PostScript version of .psa as generated by makeps
+
+# This script uses:
+# - the programs decrypt and decomp posted by Per Lindqvist
+# ("ps-accent", comp.lang.postscript:3943, alt.sources:1978, 24 Jan 92)
+# in a slightly modified version that can also read from stdin
+# or alternatively:
+# the program t1disasm from the package t1utils posted by
+# I. Lee Hetherington with the following modification to t1disasm.c:
+# look up the line output(" {\n");
+# at the beginning of the routine do_charstring and remove the \n .
+
+# The afm's generated can be used with FrameMaker (on Sun's). Since they
+# do not contain character bounding box information, they cannot be
+# transformed to tex metrics files (.tfm), nor can Per Lindqvist's accent
+# making algorithm be applied to them (the programs I got from the posting
+# don't seem to work anyway, but the algorithm seems to be alright and the
+# coverage of many accents of many languages and the integration of their
+# placement specifications seems to be well done so far...)
+
+mergekpx () {
+ if [ -f $font.kpx ]
+ then echo merging $kpxfont kern pairs from $font.kpx
+ echo StartKernData >> $font.afm
+ echo StartKernPairs $kpxfont >> $font.afm
+ egrep "^KPX" $font.kpx >> $font.afm
+ echo EndKernPairs >> $font.afm
+ echo EndKernData >> $font.afm
+ elif [ -f $base.kpx ]
+ then echo merging $kpxbase kern pairs from $base.kpx
+ echo StartKernData >> $font.afm
+ echo StartKernPairs $kpxbase >> $font.afm
+ egrep "^KPX" $base.kpx >> $font.afm
+ echo EndKernPairs >> $font.afm
+ echo EndKernData >> $font.afm
+ fi
+ }
+
+makeafm () {
+ echo extracting information from $base
+# first, extract all information we need into a separate file since the
+# source file is very long and we need to scan its information several times
+ sed -e 'y/ /\n /' -e "s,^ *,," | egrep -e '(^/.*def|^/[A-z0-9]* *[<{].*sbw|^[- 0-9]*seac)' > /tmp/$base.extract
+# extract FontName
+ font=` sed -e '\@^/FontName@!{' -e 'd;b' -e '}' -e 's,^/FontName /\([^ ]*\).*,\1,' -e q /tmp/$base.extract `
+ font=${font:-$base}
+ echo making $font.afm
+ kpxfont=0
+ kpxbase=0
+ kpxpfm=0
+ if [ -f $font.afm ]
+ then kpxfont=`egrep -c "^KPX" $font.afm`
+ if [ $kpxfont -ne 0 ]
+ then egrep "^KPX" $font.afm > $font.kpx
+ echo $kpxfont kern pairs in previous $font.afm
+ fi
+ fi
+ if [ -f $base.afm ]
+ then kpxbase=`egrep -c "^KPX" $base.afm`
+ if [ $kpxbase -ne 0 ]
+ then egrep "^KPX" $base.afm > $base.kpx
+ echo $kpxbase kern pairs in $base.afm
+ fi
+ fi
+ echo StartFontMetrics 1.0 > $font.afm
+ echo Comment generated from Type 1 font description >> $font.afm
+# generate fixed Encoding specification (mind!)
+ echo EncodingScheme AdobeStandardEncoding >> $font.afm
+# extract font information items and transform into afm syntax
+ sed -e /FontName/b -e /FullName/b -e /FamilyName/b -e /Weight/b \
+ -e /ItalicAngle/b -e /Underline/b -e /FontBBox/b \
+ -e /Notice/b -e /Comment/b \
+ -e /isFixedPitch/s,i,I, -e /version/s,v,V, -e t -e d \
+ /tmp/$base.extract | sed \
+ -e 's,^/\([A-z]*\) *[[{(]\(.*\)[]})].*,\1 \2,' -e t \
+ -e 's,^/\([A-z]* [^ ]*\).*,\1,' -e 's,[/()],,g' >> $font.afm
+# determine if the ligatures fi and fl are present
+ fifl=`sed -e 's,^/f\([il]\) .*, L \1 f\1 ;,' -e t -e d /tmp/$base.extract`
+ if [ -n "$fifl" ]
+ then fifl=" `echo $fifl`"
+ # remove newline from $fifl
+ fi
+# now extract the metrics information
+ echo StartCharMetrics >> $font.afm
+ sed -e 's,^/\([A-z0-9]*\) *[<{] *[-0-9]* *\([-0-9]*\) *hsbw *$,C -1 ; WX \2 ; N \1 ;,' \
+ -e 's,^/\([A-z0-9]*\) *[<{] *[-0-9]* *[-0-9]* *\([-0-9]*\) *\([-0-9]*\) *sbw *$,C -1 ; W \2 \3 ; N \1 ;,' \
+ -e "s,\( N f .*\)$,\1$fifl," \
+ -e t -e d /tmp/$base.extract >> $font.afm
+ echo EndCharMetrics >> $font.afm
+# look for a dumped pfm file (if possible, dumppfm $base.pfm > $base.dfm
+# should have been inserted here)
+## I used the following generation of kerning information from a
+## pfm file dump made by dumppfm before I crypted that extraction
+## into dd/od/sed commands myself.
+## if [ -f $base.dfm ]
+## then
+## pairs=`sed -e 's,.* etmKernPairs *[0-F]* *\([0-9]*\)[^0-9]*,\1,' -e t -e d $base.dfm`
+## if [ $pairs -ne 0 ]
+## then
+## echo including $pairs kern pairs from $base.dfm
+## echo StartKernData >> $font.afm
+## echo StartKernPairs $pairs >> $font.afm
+## sed -e 's,^[0-F]* [0-F]* KernPair\[[0-F]*\] *[0-F]* [0-F]* [0-F]* [0-F]* *\([0-z]*\) *\([0-z]*\) *\([-0-9]*\)[^0-9]*,KPX \1 \2 \3,' -e t -e d $base.dfm >> $font.afm
+## echo EndKernPairs >> $font.afm
+## echo EndKernData >> $font.afm
+## else
+## echo no kern pairs in $base.dfm
+## fi
+## elif ...
+ if [ -f $base.pfm ]
+ then
+ set - ` ( /bin/dd ibs=1 skip=195 count=2 < $base.pfm | /bin/dd conv=swab | /bin/od -d ) 2> /dev/null `
+ pairs=`expr $2 + 0`
+ if [ $pairs -ne 0 ]
+ then
+ WinANSI=`dirname $0`/WinANSI
+ len=`expr $pairs \* 4`
+
+ set - ` ( /bin/dd ibs=1 skip=131 count=4 < $base.pfm | /bin/dd conv=swab | /bin/od -d ) 2> /dev/null `
+ start=`expr $3 \* 65536 + $2 + 2`
+
+ echo StartKernData >> $font.afm
+ echo StartKernPairs $pairs >> $font.afm
+
+ /bin/dd ibs=1 skip=$start count=$len < $base.pfm | /bin/dd conv=swab |
+ /bin/od -vbiw4 |
+ sed -e '/^0/N' -e 's,^[0-7]* *\([0-7]*\) \([0-7]*\) [0-7]* [0-7]*[^-0-9]*[-0-9]* *\([-0-9]*\)$,KPX C\2 C\1 \3,' -f ${WinANSI}1 |
+ sed -f ${WinANSI}2 >> $font.afm
+
+ echo EndKernPairs >> $font.afm
+ echo EndKernData >> $font.afm
+ kpxpfm=$pairs
+ echo merged $kpxpfm kern pairs from $base.pfm
+ else
+ echo no kern pairs in $base.pfm
+ mergekpx
+ fi
+ else
+ mergekpx
+ fi
+# finally, extract composite character information as available
+ if true # no Composites entries needed for FrameMaker
+ then
+ echo StartComposites >> $font.afm
+ # since we will only find character encodings
+ # (as index into StandardEncoding), we have to translate them into
+ # their names using the list PCCnames - hopefully being found so:
+ PCCnames=`dirname $0`/PCCnames
+ sed -e '\@^/\([A-z0-9]*\) *[<{][-0-9 ]* hsbw *$@h' \
+ -e '\@^/\([A-z0-9]*\) *[<{][-0-9 ]* sbw *$@h' \
+ -e '/ seac *$/G' \
+ -e 's,^ *[-0-9]* *\([-0-9]*\) *\([-0-9]*\) *\([0-9]*\) *\([0-9]*\) *seac *\n/\([A-z0-9]*\) *[<{].*$,CC \5 2 ; PCC \3 0 0 ; PCC \4 \1 \2 ;,' \
+ -e t -e d /tmp/$base.extract | sed -f $PCCnames >> $font.afm
+ # The accent shift values (substituted as \1 and \2 above)
+ # are not exact. The difference of the "side bearing points"
+ # (letter - accent) would have to be added to it.
+ echo EndComposites >> $font.afm
+ fi
+# and finish the job
+ echo EndFontMetrics >> $font.afm
+ /bin/rm /tmp/$base.extract
+ }
+
+disasm () {
+ if t1disasm
+ then true
+ else decrypt | decomp
+ fi
+ }
+
+for file in $*
+do base=`basename $file .pfb`
+ base=`basename $base .pfa`
+ base=`basename $base .psb`
+ base=`basename $base .psa`
+ base=`basename $base .ps`
+ if [ -f $file ]
+ then case $file in
+ *.pfb | *.pfa)
+ disasm < $file | makeafm ;;
+ # if decomp cannot read stdin, use temp file instead
+ *.psb) decomp $file | makeafm ;;
+ *.psa | *.ps) makeafm < $file ;;
+ *) echo no file found for $file ;;
+ esac
+ else echo no file found for $file
+ fi
+done
diff --git a/fonts/utilities/t1tools/makeafm.dir/fontbbox.sed b/fonts/utilities/t1tools/makeafm.dir/fontbbox.sed
new file mode 100644
index 0000000000..1d3a3a48e4
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/fontbbox.sed
@@ -0,0 +1,9 @@
+s,^FontBBox *\([-0-9]*\) *\([-0-9]*\) *\([-0-9]*\) *\([-0-9]*\) *$,set llx=\1\
+set urx=\3\
+set Descender=\2\
+set CapHeight=\4\
+set XHeight=\4\
+set Ascender=\4,
+tx
+d
+:x
diff --git a/fonts/utilities/t1tools/makeafm.dir/fontinf1.sed b/fonts/utilities/t1tools/makeafm.dir/fontinf1.sed
new file mode 100644
index 0000000000..cc76fc89ce
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/fontinf1.sed
@@ -0,0 +1,14 @@
+/FontName/bx
+/FullName/bx
+/FamilyName/bx
+/Weight/bx
+/ItalicAngle/bx
+/Underline/bx
+/FontBBox/bx
+/Notice/bx
+/Comment/bx
+/isFixedPitch/s,i,I,
+/version/s,v,V,
+tx
+d
+:x \ No newline at end of file
diff --git a/fonts/utilities/t1tools/makeafm.dir/fontinf2.sed b/fonts/utilities/t1tools/makeafm.dir/fontinf2.sed
new file mode 100644
index 0000000000..b2bbbe1cbd
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/fontinf2.sed
@@ -0,0 +1,5 @@
+s,^ */\([A-z]*\) *[[{(]\(.*\)[]})].*,\1 \2,
+tx
+s,^ */\([A-z]*\)[ /]\([^ ]*\).*,\1 \2,
+s,[/()],,g
+:x
diff --git a/fonts/utilities/t1tools/makeafm.dir/fontmetr.sed b/fonts/utilities/t1tools/makeafm.dir/fontmetr.sed
new file mode 100644
index 0000000000..8b03e55437
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/fontmetr.sed
@@ -0,0 +1,5 @@
+s,^/\([A-z0-9]*\) *[<{] *[-0-9]* *\([-0-9]*\) *hsbw *$,C -1 ; WX \2 ; N \1 ;,
+s,^/\([A-z0-9]*\) *[<{] *[-0-9]* *[-0-9]* *\([-0-9]*\) *\([-0-9]*\) *sbw *$,C -1 ; W \2 \3 ; N \1 ;,
+tx
+d
+:x
diff --git a/fonts/utilities/t1tools/makeafm.dir/makeafm.bat b/fonts/utilities/t1tools/makeafm.dir/makeafm.bat
new file mode 100644
index 0000000000..998d98b46f
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/makeafm.bat
@@ -0,0 +1,129 @@
+@echo off
+
+rem makeafm: generate .afm file from PostScript type 1 font file
+rem (faking character bounding box information)
+rem It accepts the file formats:
+rem .pfb - type 1 encrypted binary file
+
+rem This script uses:
+rem 1. To disassemble the type 1 font (.pfb file):
+rem the program t1disasm from the package t1utils posted by
+rem I. Lee Hetherington with the following modification to t1disasm.c:
+rem look up the line output(" {\n");
+rem at the beginning of the routine do_charstring and remove the \n .
+rem 2. To extract pair kerning information from .pfm files:
+rem a) either the program pfm2afm
+rem b) or the program dumppfm (version 1.5.3)
+
+set dumvar=
+set dumvar2=
+if not "%1"=="-" goto normal
+set del=rem
+shift
+:normal
+if not exist %1.pfb goto error
+
+rem first, extract all information we need into a separate file since the
+rem source file is very long and we need to scan its information several times
+if exist %1.ps$ goto ext
+if exist %1.ps goto ps
+echo extracting information from %1.pfb
+D:\fonts\progs\t1utils\t1disasm %1.pfb > %TEMP%\%1.ps
+sed -e "y/ / /" %TEMP%\%1.ps > %TEMP%\%1.pb$
+%del% del %TEMP%\%1.ps
+goto pb
+:ps
+sed -e "y/ / /" %1.ps > %TEMP%\%1.pb$
+:pb
+egrep -e "(^ */.*def|^/[A-z0-9]* *[<{].*sbw|^[- 0-9]*seac)" %TEMP%\%1.pb$ > %1.ps$
+%del% del %TEMP%\%1.pb$
+:ext
+
+rem try to save kerning information from previous .afm file or to extract
+rem it from .pfm file
+if exist %1.afm goto afmkern
+if not exist %1.pfm goto startafm
+echo extracting kerning and height information from %1.pfm
+pfm2afm %1
+rem dumppfm %1.pfm %1.afm
+if not exist %1.inf call afm-inf %1
+:afmkern
+echo saving kerning and height information from %1.afm
+egrep -e "^(StartKern|EndKern|KPX)" %1.afm > %TEMP%\%1.kpx
+egrep -e "^(CapHeight|XHeight|Ascender|Descender)" %1.afm > %TEMP%\%1.hei
+
+:startafm
+echo making %1.afm
+echo StartFontMetrics 1.0 > %1.afm
+echo Comment generated from Type 1 font >> %1.afm
+rem generate fixed Encoding specification (mind!)
+echo EncodingScheme AdobeStandardEncoding >> %1.afm
+rem extract font information items and transform into afm syntax
+sed -f D:\fonts\progs\makeafm\fontinf1.sed %1.ps$ > %TEMP%\%1.fi
+sed -f D:\fonts\progs\makeafm\fontinf2.sed %TEMP%\%1.fi >> %1.afm
+%del% del %TEMP%\%1.fi
+rem determine if the ligatures fi and fl are present
+sed -e "s,^/f\([il]\) .*,set fifl=%%fifl%% L \1 f\1 ;," -e tx -e d -e :x %1.ps$ > %TEMP%\%1.bat
+sed -f D:\fonts\progs\makeafm\fontbbox.sed %1.afm >> %TEMP%\%1.bat
+if not exist %TEMP%\%1.hei goto nohei
+rem type %TEMP%\%1.hei >> %1.afm
+egrep -v CapHeight %TEMP%\%1.hei >> %1.afm
+sed -e "s,^\([^ ][^ ]*\) *\([-0-9]*\) *$,set \1=\2," %TEMP%\%1.hei >> %TEMP%\%1.bat
+%del% del %TEMP%\%1.hei
+:nohei
+set fifl=
+call %TEMP%\%1.bat
+echo CapHeight %CapHeight% >> %1.afm
+set BBoxC= B %llx% %Descender% %urx% %CapHeight% ;
+set BBoxX= B %llx% %Descender% %urx% %XHeight% ;
+set BBox= B %llx% %Descender% %urx% %Ascender% ;
+%del% del %TEMP%\%1.bat
+
+rem now extract the metrics information
+rem echo StartCharMetrics >> %1.afm
+sed -f D:\fonts\progs\makeafm\fontmetr.sed %1.ps$ > %TEMP%\%1.ex
+egrep -c -e . %TEMP%\%1.ex | sed -e "s,^,StartCharMetrics " >> %1.afm
+echo s,\( N *f .*\)$,\1%BBox%%fifl%,> %TEMP%\%1.sed
+echo s,\( N *[A-Z][^;]*;\),\1%BBoxC%,>> %TEMP%\%1.sed
+rem echo s,\( N *[acegm-su-z][^;]*;\),\1%BBoxX%,>> %TEMP%\%1.sed
+echo s,\( N *x[^;]*;\),\1%BBoxX%,>> %TEMP%\%1.sed
+echo tx>> %TEMP%\%1.sed
+echo s,\( N [^;]*;\),\1%BBox%,>> %TEMP%\%1.sed
+echo tx>> %TEMP%\%1.sed
+echo d>> %TEMP%\%1.sed
+echo :x>> %TEMP%\%1.sed
+sed -f %TEMP%\%1.sed %TEMP%\%1.ex >> %1.afm
+%del% del %TEMP%\%1.ex
+%del% del %TEMP%\%1.sed
+echo EndCharMetrics >> %1.afm
+
+rem insert previously extracted or saved kerning information
+if not exist %TEMP%\%1.kpx goto nokern
+rem type %TEMP%\%1.kpx >> %1.afm
+egrep -e "^StartKern" %TEMP%\%1.kpx >> %1.afm
+egrep -e "^KPX" %TEMP%\%1.kpx | sort >> %1.afm
+egrep -e "^EndKern" %TEMP%\%1.kpx >> %1.afm
+:nokern
+
+goto nocompo
+rem finally, extract composite character information as available
+echo StartComposites >> %1.afm
+rem since we will only find character encodings (as index into
+rem StandardEncoding), we have to translate them into their names:
+sed -f D:\fonts\progs\makeafm\PCCinfo.sed %1.ps$ > %TEMP%\%1.pcc
+sed -f D:\fonts\progs\makeafm\PCCnames.sed %TEMP%\%1.pcc >> %1.afm
+%del% del %TEMP%\%1.pcc
+rem The accent shift values (substituted as \1 and \2 above)
+rem are not exact. The difference of the "side bearing points"
+rem (letter - accent) would have to be added to it.
+echo EndComposites >> %1.afm
+:nocompo
+rem and finish the job
+echo EndFontMetrics >> %1.afm
+%del% del %1.ps$
+if exist %TEMP%\%1.kpx %del% del %TEMP%\%1.kpx
+goto end
+
+:error
+echo makeafm failed
+:end
diff --git a/fonts/utilities/t1tools/makeafm.dir/pccinfo.sed b/fonts/utilities/t1tools/makeafm.dir/pccinfo.sed
new file mode 100644
index 0000000000..58e5a25b2b
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/pccinfo.sed
@@ -0,0 +1,7 @@
+/^\/\([A-z0-9]*\) *[<{][-0-9 ]* hsbw *$/h
+/^\/\([A-z0-9]*\) *[<{][-0-9 ]* sbw *$/h
+/ seac *$/G
+s,^ *[-0-9]* *\([-0-9]*\) *\([-0-9]*\) *\([0-9]*\) *\([0-9]*\) *seac *\n/\([A-z0-9]*\) *[<{].*$,CC \5 2 ; PCC \3 0 0 ; PCC \4 \1 \2 ;,
+tx
+d
+:x
diff --git a/fonts/utilities/t1tools/makeafm.dir/pccnames.sed b/fonts/utilities/t1tools/makeafm.dir/pccnames.sed
new file mode 100644
index 0000000000..7c963ac1cc
--- /dev/null
+++ b/fonts/utilities/t1tools/makeafm.dir/pccnames.sed
@@ -0,0 +1,90 @@
+s,PCC 34,PCC quotedbl,
+s,PCC 42,PCC asterisk,
+s,PCC 43,PCC plus,
+s,PCC 44,PCC comma,
+s,PCC 45,PCC hyphen,
+s,PCC 46,PCC period,
+s,PCC 47,PCC slash,
+s,PCC 58,PCC colon,
+s,PCC 60,PCC less,
+s,PCC 61,PCC equal,
+s,PCC 62,PCC greater,
+s,PCC 65,PCC A,
+s,PCC 66,PCC B,
+s,PCC 67,PCC C,
+s,PCC 68,PCC D,
+s,PCC 69,PCC E,
+s,PCC 70,PCC F,
+s,PCC 71,PCC G,
+s,PCC 72,PCC H,
+s,PCC 73,PCC I,
+s,PCC 74,PCC J,
+s,PCC 75,PCC K,
+s,PCC 76,PCC L,
+s,PCC 77,PCC M,
+s,PCC 78,PCC N,
+s,PCC 79,PCC O,
+s,PCC 80,PCC P,
+s,PCC 81,PCC Q,
+s,PCC 82,PCC R,
+s,PCC 83,PCC S,
+s,PCC 84,PCC T,
+s,PCC 85,PCC U,
+s,PCC 86,PCC V,
+s,PCC 87,PCC W,
+s,PCC 88,PCC X,
+s,PCC 89,PCC Y,
+s,PCC 90,PCC Z,
+s,PCC 92,PCC backslash,
+s,PCC 94,PCC asciicircum,
+s,PCC 95,PCC underscore,
+s,PCC 97,PCC a,
+s,PCC 98,PCC b,
+s,PCC 99,PCC c,
+s,PCC 100,PCC d,
+s,PCC 101,PCC e,
+s,PCC 102,PCC f,
+s,PCC 103,PCC g,
+s,PCC 104,PCC h,
+s,PCC 105,PCC i,
+s,PCC 106,PCC j,
+s,PCC 107,PCC k,
+s,PCC 108,PCC l,
+s,PCC 109,PCC m,
+s,PCC 110,PCC n,
+s,PCC 111,PCC o,
+s,PCC 112,PCC p,
+s,PCC 113,PCC q,
+s,PCC 114,PCC r,
+s,PCC 115,PCC s,
+s,PCC 116,PCC t,
+s,PCC 117,PCC u,
+s,PCC 118,PCC v,
+s,PCC 119,PCC w,
+s,PCC 120,PCC x,
+s,PCC 121,PCC y,
+s,PCC 122,PCC z,
+s,PCC 124,PCC bar,
+s,PCC 126,PCC asciitilde,
+s,PCC 164,PCC fraction,
+s,PCC 169,PCC quotesingle,
+s,PCC 177,PCC endash,
+s,PCC 180,PCC periodcentered,
+s,PCC 183,PCC bullet,
+s,PCC 184,PCC quotesinglbase,
+s,PCC 188,PCC ellipsis,
+s,PCC 193,PCC grave,
+s,PCC 194,PCC acute,
+s,PCC 195,PCC circumflex,
+s,PCC 196,PCC tilde,
+s,PCC 197,PCC macron,
+s,PCC 198,PCC breve,
+s,PCC 199,PCC dotaccent,
+s,PCC 200,PCC dieresis,
+s,PCC 202,PCC ring,
+s,PCC 203,PCC cedilla,
+s,PCC 205,PCC hungarumlaut,
+s,PCC 206,PCC ogonek,
+s,PCC 207,PCC caron,
+s,PCC 208,PCC emdash,
+s,PCC 245,PCC dotlessi,
diff --git a/fonts/utilities/t1tools/pcs.ps b/fonts/utilities/t1tools/pcs.ps
new file mode 100644
index 0000000000..004f429822
--- /dev/null
+++ b/fonts/utilities/t1tools/pcs.ps
@@ -0,0 +1,330 @@
+%! print and compare font character sets
+/home {leftmargin top moveto} def
+/rightmargin {leftmargin} def
+/sethome {/top exch def /leftmargin exch def} def
+/setfontsize {/fontsize exch def} def
+/setrightborder {/rightborder exch def} def
+70 740 sethome
+20 setfontsize
+550 setrightborder
+/leading 4 def
+/nl {currentpoint exch pop leftmargin exch
+ fontsize sub leading sub moveto} def
+/hl {currentpoint exch pop leftmargin exch
+ fontsize 2 div sub leading sub moveto} def
+
+/comparecs {
+ fontlist dup 0 get fontsize ffont /reffont exch def
+ 1 get fontsize ffont /chkfont exch def
+
+ chkfont /FontInfo get /ItalicAngle get abs
+ dup [ 1 0 4 -1 roll sin 1 0 0 ] /slantmatrix exch def
+ home
+ [cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7]
+ { {
+ currentpoint ( ) dup 0 6 -1 roll put dup /ch exch def
+ reffont setfont show
+ currentpoint % stack: x0 y0 x y
+ 4 2 roll pop % stack: x y x0
+ 3 copy pop pop sub % stack: x y x0-x
+ chkfont setfont ch stringwidth pop dup /width exch def
+ sub 2 div 0 rmoveto
+ 0 fontsize neg rmoveto currentpoint
+ % here we are at base point of character to be shown
+ % draw width and height reference box:
+ 0 fontsize slantmatrix transform
+ 2 copy 2 copy rmoveto neg exch neg exch rlineto
+ width 0 rlineto rlineto
+ 0 setlinewidth
+ % currentrgbcolor .5 .0 .0 setrgbcolor stroke setrgbcolor
+ % 2 copy moveto
+ % 0 fontsize
+ % 2 copy 2 copy rmoveto neg exch neg exch rlineto
+ % width 0 rlineto rlineto
+ currentrgbcolor .0 .5 .0 setrgbcolor stroke setrgbcolor
+ % back to base point:
+ moveto
+ ch show
+ moveto
+ fontsize 5 div 0 rmoveto
+ } forall
+ nl nl
+ } forall
+ } def
+
+/findfont+ {dup findfont
+ dup maxlength dict begin
+ {1 index dup /FID ne exch /UniqueID ne and
+ {def} {pop pop} ifelse} forall
+ Encoding StandardEncoding eq
+ % pop true % for unconditional re-encoding
+ {/Encoding Win31+
+ % pop CP437 % CP437 / CP850 / PrestigeElite-additionals / ...
+ def} if
+ currentdict end
+ definefont
+ } def
+/ffont {exch findfont+ exch dup /fontsize exch def scalefont
+ } def
+/ff {exch findfont+ exch dup /fontsize exch def scalefont
+ setfont} def
+
+/fontlist [] def
+%/newfontnames [/font2 /font1] def
+/FontDirectoryKnown FontDirectory dup length 20 add dict copy def
+/appendnewfont {
+ /fontlist [ fontlist aload pop
+ FontDirectoryKnown begin
+ FontDirectory
+ {FontDirectoryKnown 2 index known {pop pop} {2 copy def pop} ifelse
+ } forall
+ end
+ % font renaming to allow comparison of two fonts with equal name:
+ % third attempt, useless
+ % findfont
+ % /newfontnames
+ % [ newfontnames aload pop /newfontname exch def ] def
+ % newfontname exch definefont pop
+ % newfontname
+ ] def
+ } def
+/setreffont {
+ [ exch ] /fontlist exch def
+ } def
+/registerfont {run appendnewfont} def
+
+/=dict { % for debugging
+ {2 array astore ==} forall
+ } def
+
+{
+% the following module should allow multiple samples with the same font name
+% but it does not work
+/appendnewfont {} def
+%/*definefont /definefont load def
+/*definefont {definefont} bind def
+/fontnamelist [] def
+/fontnewnames [/f1 /f2] def
+/fontnewnamei 0 def
+/definefont {
+ % (definefont) =
+ 2 copy *definefont /FontName get /fontname exch def
+ % this yields "invalidaccess" !???
+ /fontnamelist [ fontnamelist aload pop fontname ] def
+ /fontnewname fontnewnames fontnewnamei get def
+ /fontnewnamei dup load 1 add def
+ /fontlist [ fontlist aload pop fontnewname ] def
+ exch pop fontnewname exch
+ *definefont
+ %/*definefont load exec
+ } store
+} pop
+
+{
+% the following module should allow multiple samples with the same font name
+% second attempt, doesn't work either
+/fontnamelist [] def
+/fontnewnames [/f1 /f2] def
+/fontnewnamei 0 def
+/appendnewfont {
+ FontDirectory
+ dup length dict /FontNewDirectory exch def
+ dup length dict /FontDirectoryKnown exch def
+ {FontDirectoryKnown 2 index known
+ {FontNewDirectory 3 copy pop put
+ FontDirectoryKnown 3 copy pop put
+ }
+ {
+ /fontnewname fontnewnames fontnewnamei get def
+ /fontnewnamei dup load 1 add def
+ FontNewDirectory fontnewname 2 index put
+ FontDirectoryKnown fontnewname 2 index put
+ /fontlist [ fontlist aload pop fontnewname ] def
+fontnewname ==
+ }
+ ifelse
+ pop pop
+ } forall
+ /FontDirectory FontNewDirectory def
+ } def
+} pop
+
+/fillsample { % param: name from-code
+ 32 string dup
+ 3 -1 roll dup 1 exch 31 add
+ {dup 32 mod exch put dup}
+ for pop def
+ } def
+/cs0 0 fillsample
+/cs1 32 fillsample
+/cs2 64 fillsample
+/cs3 96 fillsample
+/cs4 128 fillsample
+/cs5 160 fillsample
+/cs6 192 fillsample
+/cs7 224 fillsample
+
+/Win31+ [
+% Windows 3.1 character set extended with other common characters,
+% nbspace instead of second space, minus instead of second hyphen;
+% first 32 positions filled up with additional characters from MacIntosh.
+% Windows 3.1 character set is basically an extension of ISO Latin-1
+% with a few deviations.
+/NUL /HT /LF /CR /DLE /DC1 /DC2 /DC3 /DC4 /US /RS /DEL
+/lessequal /greaterequal /notequal /approxequal /lozenge /apple
+/infinity /partialdiff /summation /product /integral /radical
+/Delta /Omega /pi
+/breve /dotaccent /hungarumlaut /ogonek /ring
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /fraction
+
+/fi /fl /quotesinglbase /florin
+ /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /Scaron /guilsinglleft /OE /Lslash /Zcaron /caron
+/dotlessi /quoteleft /quoteright /quotedblleft
+ /quotedblright /bullet /endash /emdash
+/tilde /trademark /scaron /guilsinglright /oe /lslash /zcaron /Ydieresis
+
+/nbspace /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /minus /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis
+] def
+
+/PrestigeElite-additionals [
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/Hbar /IJ /Ldot /Tbar /dbar /hbar /ij /kgreenlandic
+/ldot /napostrophe /tbar
+/Gamma /Omega /Phi /Sigma /Theta
+/alpha /delta /epsilon
+/phi /pi /sigma /tau
+/Pts /deutschmark /franc
+/oneeighth
+/threeeighths /fiveeighths /seveneighths
+/Eng /apostrophereverse
+/approxequal /arrowboth /arrowdown
+/arrowleft /arrowright /arrowup /caretinverted
+/club /diamond /diamondopen /eng
+/equivalence /exclamdbl /female /filledbox /greaterequal
+/heart /infinity /intersection /lessequal
+/male /minus /monospacedash /musicalnote
+/musicalnotedbl /nsuperior /overscore /radical
+/spade /underscoredbl /zeroslash /SA420000
+/SD630000 /SF010000 /SF020000 /SF030000 /SF040000 /SF050000 /SF060000 /SF070000
+/SF080000 /SF090000 /SF100000 /SF110000 /SF140000 /SF150000 /SF160000 /SF190000
+/SF200000 /SF210000 /SF220000 /SF230000 /SF240000 /SF250000 /SF260000 /SF270000
+/SF280000 /SF360000 /SF370000 /SF380000 /SF390000 /SF400000 /SF410000 /SF420000
+/SF430000 /SF440000 /SF450000 /SF460000 /SF470000 /SF480000 /SF490000 /SF500000
+/SF510000 /SF520000 /SF530000 /SF540000 /SF570000 /SF580000 /SF590000 /SF600000
+/SF610000 /SM570001 /SM590000 /SM600000 /SM630000 /SM680000 /SM690000 /SM700000
+/SM750000 /SM750002 /SM760000 /SM770000 /SM790000 /SP320000 /SS000000 /SS010000
+/SS260000 /SS270000 /SV040000 /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
+] def
+
+/CP437 [
+/space/SS000000/SS010000/heart/diamond/club/spade/bullet
+/SM570001/HT/SM750002/male/female/musicalnote/musicalnotedbl/SM690000
+/SM590000/SM630000/SM760000/exclamdbl/paragraph/section/SM700000/SM770000
+/arrowup/arrowdown/arrowright/arrowleft/SA420000/arrowboth/SM600000/SV040000
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde
+/SM790000
+% €‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ
+/Ccedilla/udieresis/eacute/acircumflex/adieresis/agrave/aring/ccedilla
+/ecircumflex/edieresis/egrave/idieresis/icircumflex/igrave/Adieresis/Aring
+/Eacute/ae/AE/ocircumflex/odieresis/ograve/ucircumflex/ugrave
+/ydieresis/Odieresis/Udieresis/cent/sterling/yen/Pts/florin
+%  ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿
+/aacute/iacute/oacute/uacute/ntilde/Ntilde/ordfeminine/ordmasculine
+/questiondown /SM680000 /logicalnot/onehalf/onequarter/exclamdown
+/guillemotleft /guillemotright
+/SF140000/SF150000/SF160000/SF110000/SF090000/SF190000/SF200000/SF210000
+/SF220000/SF230000/SF240000/SF250000/SF260000/SF270000/SF280000/SF030000
+% ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
+/SF020000/SF070000/SF060000/SF080000/SF100000/SF050000/SF360000/SF370000
+/SF380000/SF390000/SF400000/SF410000/SF420000/SF430000/SF440000/SF450000
+/SF460000/SF470000/SF480000/SF490000/SF500000/SF510000/SF520000/SF530000
+/SF540000/SF040000/SF010000/SF610000/SF570000/SF580000/SF590000/SF600000
+% àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
+/alpha /germandbls /Gamma /pi /Sigma /sigma /mu /gamma
+/Phi /Theta /Omega /delta /infinity /infinity /epsilon /intersection
+/equivalence /plusminus /greaterequal /lessequal
+/SS260000/SS270000 /divide /approxequal
+/degree /SD630000 /SP320000 /radical /nsuperior /twosuperior /filledbox /space
+] def
+
+/CP850 [
+/space/SS000000/SS010000/heart/diamond/club/spade/bullet
+/SM570001/HT/SM750002/male/female/musicalnote/musicalnotedbl/SM690000
+/SM590000/SM630000/SM760000/exclamdbl/paragraph/section/SM700000/SM770000
+/arrowup/arrowdown/arrowright/arrowleft/SA420000/arrowboth/SM600000/SV040000
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O /P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w /x /y /z /braceleft /bar /braceright /asciitilde
+/SM790000
+% €‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ
+/Ccedilla/udieresis/eacute/acircumflex/adieresis/agrave/aring/ccedilla
+/ecircumflex/edieresis/egrave/idieresis/icircumflex/igrave/Adieresis/Aring
+/Eacute/ae/AE/ocircumflex/odieresis/ograve/ucircumflex/ugrave
+/ydieresis/Odieresis/Udieresis/oslash/sterling/Oslash/multiply/florin
+%  ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿
+/aacute/iacute/oacute/uacute/ntilde/Ntilde/ordfeminine/ordmasculine
+/questiondown/registered/logicalnot/onehalf/onequarter/exclamdown
+/guillemotleft /guillemotright
+/SF140000/SF150000/SF160000/SF110000/SF090000 /Aacute /Acircumflex /Agrave
+/copyright /SF230000/SF240000/SF250000/SF260000 /cent /yen /SF030000
+% ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞß
+/SF020000/SF070000/SF060000/SF080000/SF100000/SF050000 /atilde /Atilde
+/SF380000/SF390000/SF400000/SF410000/SF420000/SF430000/SF440000 /currency
+/delta /Eth /Ecircumflex /Edieresis /Egrave /quotesingle /Iacute /Icircumflex
+/Idieresis /SF040000/SF010000/SF610000/SF570000 /brokenbar /Igrave /SF600000
+% àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
+/Oacute /germandbls /Ocircumflex /Ograve /otilde /Otilde /mu /thorn
+/Thorn /Uacute /Ucircumflex /Ugrave /yacute /Yacute /macron /acute
+/minus /plusminus /underscoredbl /threequarters
+/paragraph /section /divide /cedilla
+/degree /dieresis /periodcentered /onesuperior
+/threesuperior /twosuperior /filledbox /space
+] def
diff --git a/fonts/utilities/t1tools/pfb-abf.bat b/fonts/utilities/t1tools/pfb-abf.bat
new file mode 100644
index 0000000000..808be18f34
--- /dev/null
+++ b/fonts/utilities/t1tools/pfb-abf.bat
@@ -0,0 +1,57 @@
+@ echo off
+
+if not "%1"=="" goto los
+echo pfb-abf [-] fontname outnam [resolutionx] [resolutiony] [encoding]
+echo fontname without .pfb
+echo outnam at most 6 characters
+echo screen resolution defaults to 72 72
+echo encoding vector file (without suffix .enc)
+echo - defaults to fontname.ENC if existing, C:\Adobe\APPLE.ENC otherwise
+echo SIZES may be set to list of sizes to be generated, defaults to 10 12 14 18 24
+echo an additional starting "-" leaves intermediate files and doesn't zip
+goto end
+
+:los
+rem try to make some space in environment (NC problem):
+set dumvar=
+
+set del=
+if not "%1"=="-" goto mach
+set del=rem
+shift
+
+:mach
+set name=%1
+set namo=%2
+if "%2"=="" set namo=%1
+if "%sizes%" == "" set sizes=10 12 14 18 24
+
+set resx=72
+set resy=72
+if not "%3"=="" set resx=%3
+if not "%4"=="" set resy=%4
+echo generating for resolution %resx% %resy%
+
+set enc=C:\Adobe\APPLE
+if exist %1.enc set enc=%1
+if not "%5"=="" set enc=%5
+
+echo StartTypeface > %namo%.mb
+echo Resolution %resx% %resy% >> %namo%.mb
+echo Orientation Portrait >> %namo%.mb
+echo StandardEncoding %enc%.ENC >> %namo%.mb
+echo SpecialEncoding >> %namo%.mb
+for %%s in (%sizes%) do call C:\Adobe\makemb %namo% %%s
+echo EndTypeface >> %namo%.mb
+
+C:\Adobe\foundry\MAKEBIT.EXE -i %namo%.MB -l nul %name%.pfb
+%del% del %namo%.mb
+
+for %%s in (%sizes%) do C:\Adobe\foundry\MAKEABF.EXE -l nul %namo%%%s.BIT
+
+%del% del %namo%*.bit
+
+%del% pkzip %namo% %namo%*.abf
+%del% del %namo%*.abf
+
+:end
diff --git a/fonts/utilities/t1tools/pfb-enc.bat b/fonts/utilities/t1tools/pfb-enc.bat
new file mode 100644
index 0000000000..a8c546b49b
--- /dev/null
+++ b/fonts/utilities/t1tools/pfb-enc.bat
@@ -0,0 +1,11 @@
+if exist %1.pfb goto los
+echo kein .pfb-Fontfile da.
+goto end
+
+:los
+echo MaxIndex 255 > %1.enc
+echo MaxEncoded 255 >> %1.enc
+echo StartEncoding >> %1.enc
+sed -e /eexec/d -e /eexec/q -e "s,^dup \(.*\)/\(.*\) put$,\1\2," -e tx -e d -e :x %1.pfb >> %1.enc
+echo EndEncoding >> %1.enc
+:end
diff --git a/fonts/utilities/t1tools/pfb-sfp.bat b/fonts/utilities/t1tools/pfb-sfp.bat
new file mode 100644
index 0000000000..c474b12906
--- /dev/null
+++ b/fonts/utilities/t1tools/pfb-sfp.bat
@@ -0,0 +1,58 @@
+@ echo off
+
+if not "%1"=="" goto los
+echo pfb-sfp [-] fontname outnam [resolutionx] [resolutiony] [encoding]
+echo fontname without .pfb
+echo outnam at most 6 characters
+echo printer resolution defaults to 300 300
+echo encoding vector file (without suffix .enc)
+echo - defaults to fontname.ENC if existing, C:\Adobe\foundry\W.ENC otherwise
+echo PSIZES may be set to list of sizes to be generated, defaults to 10 12
+echo an additional starting "-" leaves intermediate files
+goto end
+
+:los
+rem try to make some space in environment (NC problem):
+set dumvar=
+
+set del=
+if not "%1"=="-" goto mach
+set del=rem
+shift
+
+:mach
+set name=%1
+set namo=%2
+if "%2"=="" set namo=%1
+if "%PSIZES%" == "" set PSIZES=10 12
+
+set resx=300
+set resy=300
+if not "%3"=="" set resx=%3
+if not "%4"=="" set resy=%4
+echo generating for resolution %resx% %resy%
+
+set enc=C:\Adobe\foundry\W
+if exist %1.enc set enc=%1
+if not "%5"=="" set enc=%5
+
+echo StartTypeface > %namo%.mb
+echo Resolution %resx% %resy% >> %namo%.mb
+echo Orientation Portrait >> %namo%.mb
+echo StandardEncoding %enc%.ENC >> %namo%.mb
+echo SpecialEncoding >> %namo%.mb
+for %%s in (%PSIZES%) do call C:\Adobe\makemb %namo% %%s
+echo EndTypeface >> %namo%.mb
+
+C:\Adobe\foundry\MAKEBIT.EXE -i %namo%.MB %name%.pfb
+%del% del %namo%.mb
+
+for %%s in (%PSIZES%) do C:\Adobe\foundry\MAKELJF.EXE -c 9U -s 1 -w 0 -t 182 -o %namo%%%s.SFP %namo%%%s.BIT
+rem for %%s in (%PSIZES%) do C:\Adobe\foundry\MAKEPFM.EXE -h 1 -p %%s -e W.ENC -o %namo%%%s.pfm %name%.AFM
+
+%del% del %namo%*.bit
+
+rem %del% pkzip %namo% %namo%*.sfp
+rem %del% del %namo%*.sfp
+
+:end
diff --git a/fonts/utilities/t1tools/pfblist.bat b/fonts/utilities/t1tools/pfblist.bat
new file mode 100644
index 0000000000..e889bd0671
--- /dev/null
+++ b/fonts/utilities/t1tools/pfblist.bat
@@ -0,0 +1 @@
+pfbnames | C:\DOS\sort /+15 > @fontpfb.lst \ No newline at end of file
diff --git a/fonts/utilities/t1tools/pfbnames.pas b/fonts/utilities/t1tools/pfbnames.pas
new file mode 100644
index 0000000000..4c44f593b7
--- /dev/null
+++ b/fonts/utilities/t1tools/pfbnames.pas
@@ -0,0 +1,58 @@
+program pfbnames;
+
+uses Dos;
+
+var DirInfo: SearchRec;
+
+function getFontName (fn: string): string;
+const separators = [' ', ^I, ^M, ^J];
+var f: file of char;
+ { 'text' would sometimes interpret one of the first 6 binary
+ (block header) bytes as EOF . On the other hand, 'file of char'
+ is slow (stupid Turbo, probably not buffering file input other
+ than 'text' (Does Turbo-7 remedy this?). Maybe 'file' with
+ block operations should be used. }
+ lasttoken: string;
+ lastch: char;
+
+ procedure getchar;
+ begin
+ if eof (f) then lastch := chr (0)
+ else read (f, lastch)
+ end;
+
+ procedure gettoken;
+ begin
+ while lastch in separators do getchar;
+ if lastch = '/' then begin
+ lasttoken := '/';
+ getchar;
+ end else lasttoken := '';
+ while not eof (f) and not (lastch in separators + ['/']) do begin
+ lasttoken := lasttoken + lastch;
+ getchar;
+ end;
+ end;
+begin
+ assign (f, fn);
+ reset (f);
+ lastch := ' ';
+ lasttoken := '';
+ while not eof (f) and (lasttoken <> '/FontName')
+ do gettoken;
+ gettoken;
+ getFontName := lasttoken;
+ close (f)
+end;
+
+begin
+ if paramcount > 0 then writeln (getFontName (paramstr (1)))
+ else begin
+ FindFirst ('*.pfb', $00, DirInfo);
+ while DosError = 0 do begin
+ writeln (DirInfo.Name, ':', ' ': 13 - length (DirInfo.Name),
+ getFontName (DirInfo.Name));
+ FindNext (DirInfo)
+ end
+ end
+end.
diff --git a/fonts/utilities/t1tools/pfbpr.bat b/fonts/utilities/t1tools/pfbpr.bat
new file mode 100644
index 0000000000..f9b61f77ee
--- /dev/null
+++ b/fonts/utilities/t1tools/pfbpr.bat
@@ -0,0 +1,20 @@
+echo off
+if not "%1"=="" goto los
+echo Parameter: Font-Dateien (.pfb), max. 4
+goto end
+
+:los
+rem copy %GS_LIB%\pfshow.ps %TEMP%\pfshow$$.ps
+echo 70 740 sethome 12 setfontsize > %TEMP%\pfshow$$.ps
+:next
+if exist %1.pfa type %1.pfa >> %TEMP%\pfshow$$.ps
+if exist %1.pfb D:\fonts\progs\t1utils\t1ascii %1.pfb >> %TEMP%\pfshow$$.ps
+if exist %1 D:\fonts\progs\t1utils\t1ascii %1 >> %TEMP%\pfshow$$.ps
+echo appendnewfont >> %TEMP%\pfshow$$.ps
+shift
+if not "%1"=="" goto next
+echo showallfonts showpage quit >> %TEMP%\pfshow$$.ps
+
+gs -q -sPAPERSIZE=a4 -sDEVICE=deskjet -r300 -dNOPAUSE pfshow.ps %TEMP%\pfshow$$.ps
+del %TEMP%\pfshow$$.ps
+:end
diff --git a/fonts/utilities/t1tools/pfbshow.bat b/fonts/utilities/t1tools/pfbshow.bat
new file mode 100644
index 0000000000..b7e805146a
--- /dev/null
+++ b/fonts/utilities/t1tools/pfbshow.bat
@@ -0,0 +1,41 @@
+@echo off
+rem show font text sample and character sets
+rem point size is automatically adjusted to number of fonts (1..4)
+rem additionally required programs:
+rem the PostScript file pfshow.ps
+rem ghostscript
+rem a program to convert .pfb to .pfa hex representation (here t1ascii)
+
+if not "%1"=="-" goto weiter
+set dumvar=
+set del=rem
+shift
+:weiter
+if not "%1"=="" goto los
+echo Parameter: font-files (.pfb), max. 4
+goto end
+
+:los
+rem copy %GS_LIB%\pfshow.ps %TEMP%\pfshow$$.ps
+echo 40 730 sethome 40 setfontsize 1000 setrightborder > %TEMP%\pfshow$$.ps
+rem with one line less, appropriate sizes are 45/28/18/13
+if not "%2"=="" echo 25 setfontsize >> %TEMP%\pfshow$$.ps
+if not "%3"=="" echo 16 setfontsize >> %TEMP%\pfshow$$.ps
+if not "%4"=="" echo 11 setfontsize >> %TEMP%\pfshow$$.ps
+:next
+if "%1"=="-a" goto arial
+if exist %1.pfa type %1.pfa >> %TEMP%\pfshow$$.ps
+if exist %1.pfb D:\fonts\progs\t1utils\t1ascii %1.pfb >> %TEMP%\pfshow$$.ps
+if exist %1 D:\fonts\progs\t1utils\t1ascii %1 >> %TEMP%\pfshow$$.ps
+goto append
+:arial
+D:\fonts\progs\t1utils\t1ascii D:\fonts\profi\_a______.pfb >> %TEMP%\pfshow$$.ps
+:append
+echo appendnewfont >> %TEMP%\pfshow$$.ps
+shift
+if not "%1"=="" goto next
+echo showallfonts showpage quit >> %TEMP%\pfshow$$.ps
+
+gs -q %GSOPT% pfshow.ps %TEMP%\pfshow$$.ps
+%del% del %TEMP%\pfshow$$.ps
+:end
diff --git a/fonts/utilities/t1tools/pfshow.ps b/fonts/utilities/t1tools/pfshow.ps
new file mode 100644
index 0000000000..37e3e388b0
--- /dev/null
+++ b/fonts/utilities/t1tools/pfshow.ps
@@ -0,0 +1,181 @@
+%! print font samples and character sets
+/home {leftmargin top moveto} def
+/rightmargin {leftmargin} def
+/sethome {/top exch def /leftmargin exch def} def
+/setfontsize {/fontsize exch def} def
+/setrightborder {/rightborder exch def} def
+70 740 sethome
+20 setfontsize
+550 setrightborder
+/leading 4 def
+/nl {currentpoint exch pop leftmargin exch
+ fontsize sub leading sub moveto} def
+/hl {currentpoint exch pop leftmargin exch
+ fontsize 2 div sub leading sub moveto} def
+
+/fontN {currentfont} def
+/fontB {fontN} def
+/fontI {fontB} def
+/fontBI {fontB} def
+/N {fontN setfont} def
+/B {fontB setfont} def
+/I {fontI setfont} def
+/BI {fontBI setfont} def
+/pushfont {/fontBI /fontI load def
+ /fontI /fontB load def
+ /fontB /fontN load def
+ /fontN currentfont def
+ } def
+/nextfonti 0 def
+/setnextfont {[/fontN /fontI /fontB /fontBI] nextfonti get currentfont def
+ /nextfonti nextfonti 1 add def
+ } def
+
+/namefont {currentfont} def
+/showtext {
+ N
+ (Scoloplos ist eury) show odieresis show
+ (k. Er ist in der gesamten borealen Region in fast allen) show nl
+ (marinen Sedimenten zu finden, die einen sandigen Anteil aufweisen. Man) show nl
+ (findet ihn von ) show B (Gr) show odieresis show (nland ) show
+ N (bis zum ) show I (Mittelmeer) show
+ N (, in der ) show BI (Nordsee) show
+ N (, an der kanadischen) show nl
+ (K) show udieresis show (ste und im Wei) show germandbls show
+ (en Meer (Markelova 1981).) show nl
+ quotedblleft show (Er besiedelt sowohl das ) show guillemotleft show
+ (Eulitoral) show guillemotright show ( als auch das ) show quotedblbase show
+ (Bathyal) show quotedblleft show (.) show quotedblright show nl
+ quoteleft show (Er besiedelt sowohl das ) show guilsinglleft show
+ (Eulitoral) show guilsinglright show ( als auch das ) show quotesinglbase show
+ (Bathyal) show quoteleft show (.) show quoteright show nl
+ } def
+/showcset {
+ [cs0 cs1 cs2 cs3 cs4 cs5 cs6 cs7] {show nl} forall
+ currentfont
+ currentpoint
+ dup fontsize leading add 3 mul add
+ % leftmargin 400 add exch moveto
+ currentfont /FontName get findfont 70 scalefont setfont
+ rightborder (Forqen) stringwidth pop sub exch moveto
+ (Forqen) show
+ moveto
+ setfont
+ } def
+/showname {currentfont namefont setfont
+ dup /FontName get dup length string cvs show
+ setfont nl
+ } def
+/showfont { % param: fontname
+ fontsize ff
+ home
+ showtext
+ showname
+ showcset
+ } def
+/showallfonts {
+ % /fontlist [ FontDirectory {pop} forall ] def
+% fontlist
+% {dup findfont copyfont definefont pop}
+% forall
+
+ fontlist {fontsize ff setnextfont} forall
+ fontlist length 0 ne {home showtext} if
+ [fontN fontI fontB fontBI] 0 fontlist length getinterval
+ {hl setfont ( ) show showname hl showcset} forall
+ } def
+
+/findfont+ {dup findfont
+ dup maxlength dict begin
+ {1 index dup /FID ne exch /UniqueID ne and
+ {def} {pop pop} ifelse} forall
+ Encoding StandardEncoding eq
+ % pop true % for unconditional re-encoding
+ {/Encoding Win31+ def} if
+ % /Encoding PrestigeElite def
+ currentdict end
+ definefont
+ } def
+/ff {exch findfont+ exch dup /fontsize exch def scalefont
+ setfont} def
+
+/fontlist [] def
+/FontDirectoryKnown FontDirectory dup length 20 add dict copy def
+/appendnewfont {
+ /fontlist [ fontlist aload pop
+ FontDirectoryKnown begin
+ FontDirectory
+ {FontDirectoryKnown 2 index known {pop pop} {2 copy def pop} ifelse
+ } forall
+ end
+ ] def
+ } def
+/registerfont {run appendnewfont} def
+
+/=dict { % for debugging
+ {2 array astore ==} forall
+ } def
+
+/fillsample { % param: name from-code
+ 32 string dup
+ 3 -1 roll dup 1 exch 31 add
+ {dup 32 mod exch put dup}
+ for pop def
+ } def
+/cs0 0 fillsample
+/cs1 32 fillsample
+/cs2 64 fillsample
+/cs3 96 fillsample
+/cs4 128 fillsample
+/cs5 160 fillsample
+/cs6 192 fillsample
+/cs7 224 fillsample
+
+/Win31+ [
+% Windows 3.1 character set extended with other common characters,
+% nbspace instead of second space, minus instead of second hyphen;
+% first 32 positions filled up with additional characters from MacIntosh.
+% Windows 3.1 character set is basically an extension of ISO Latin-1
+% with a few deviations.
+/NUL /HT /LF /CR /DLE /DC1 /DC2 /DC3 /DC4 /US /RS /DEL
+/lessequal /greaterequal /notequal /approxequal /lozenge /apple
+/infinity /partialdiff /summation /product /integral /radical
+/Delta /Omega /pi
+/breve /dotaccent /hungarumlaut /ogonek /ring
+/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle
+/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash
+/zero /one /two /three /four /five /six /seven
+/eight /nine /colon /semicolon /less /equal /greater /question
+/at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O
+/P /Q /R /S /T /U /V /W
+/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore
+/grave /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o
+/p /q /r /s /t /u /v /w
+/x /y /z /braceleft /bar /braceright /asciitilde /fraction
+
+/fi /fl /quotesinglbase /florin
+ /quotedblbase /ellipsis /dagger /daggerdbl
+/circumflex /perthousand /Scaron /guilsinglleft /OE /Lslash /Zcaron /caron
+/dotlessi /quoteleft /quoteright /quotedblleft
+ /quotedblright /bullet /endash /emdash
+/tilde /trademark /scaron /guilsinglright /oe /lslash /zcaron /Ydieresis
+
+/nbspace /exclamdown /cent /sterling /currency /yen /brokenbar /section
+/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /minus /registered /macron
+/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered
+/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown
+
+/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
+/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis
+/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply
+/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls
+/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla
+/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
+/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide
+/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis
+] def
+Win31+
+0 1 31 {2 copy get exch 1 string dup 0 4 -1 roll put def} for
+127 1 255 {2 copy get exch 1 string dup 0 4 -1 roll put def} for
+pop
+
diff --git a/fonts/utilities/t1tools/readme b/fonts/utilities/t1tools/readme
new file mode 100644
index 0000000000..7dd1c2f083
--- /dev/null
+++ b/fonts/utilities/t1tools/readme
@@ -0,0 +1,228 @@
+t1tools is a collection of programs and batch files useful for
+handling type 1 fonts on MSDOS and Unix systems.
+Documentation is ad-hoc to get the package out at last - sorry for
+any inconvenience this may impose. The package is not meant for
+people without knowledge about type 1 font and metrics stuff.
+If you detect any incompleteness or have any suggestions for improvement,
+please tell me.
+Thomas Wolff@inf.fu-berlin.de
+
+
+The package is available by anonymous ftp:
+ ftp.fu-berlin.de: pub/postscript/t1tools.zip
+
+
+The package contains the following tools:
+
+makeafm.bat (MSDOS)
+makeafm (Unix)
+ Generates an .afm font metrics file from a .pfb font file.
+ The information is taken directly from the font itself by
+ first disassembling it using an appropriate program.
+ If pair kerning information is available from any previously
+ existing .afm or .pfm file for that font it will be included
+ in the generated .afm file.
+
+ Syntax: makeafm font-file-base
+ Don't include .pfb / .pfa suffix in file name.
+ Examples:
+ makeafm photina
+
+ Disadvantage: character bounding box information will not be
+ included. This does not matter for use with FrameMaker (which
+ I originally wrote the script for), but for some Tex-ps adaptations.
+ The MSDOS version, however, does at least include simulated character
+ bounding box information derived from other font information to
+ enable Adobe's makepfm to work on the .afm file.
+ Required:
+ 1. To disassemble the type 1 font (.pfb file):
+ the program t1disasm from the package t1utils posted by
+ I. Lee Hetherington with the following modification to t1disasm.c:
+ look up the line output(" {\n");
+ at the beginning of the routine do_charstring and remove the \n .
+ 2. To extract pair kerning information from .pfm files on MSDOS:
+ a) either the program pfm2afm
+ b) or the program dumppfm (version 1.5.3)
+ (Extraction from .pfm files works without additional software on Unix.)
+
+
+getmetri.bat (MSDOS)
+getmetric (Unix)
+ Generates an .afm font metrics file by interpretation of the font
+ using GhostScript. Like makeafm, this script will try to include
+ kerning information from previous sources.
+
+ Syntax: getmetric font-file-base [/FontName]
+ Don't include .pfb / .pfa suffix in file name.
+ Explicit /FontName can choose among several fonts in file.
+ Examples:
+ getmetric photina
+ getmetric hvn_____ /Helvetica-Narrow
+
+ Disadvantage: GhostScript in its current version still has a bug
+ which causes incorrect width information to be calculated for
+ characters composed by seac and having a different width from their
+ base character - actually, this should not be allowed according to
+ the type 1 font specification, but to accomodate existing fonts to
+ work, rather Adobe's "Do what we implement" semantics should be
+ realized. The problem especially occurs with fonts bundled with
+ Micrografx Designer (which even compose characters like double
+ qoute marks from single quote marks etc), so don't apply getmetri
+ on them.
+
+ Required: GhostScript
+ getmetri.ps (enclosed), which is a corrected and enhanced
+ version of the PostScript program posted by W.T. Roberts
+ and Bryan Bayerdorffer.
+
+pfbshow.bat (MSDOS)
+gpreview (Unix)
+preview (Unix)
+pfbpr.bat (MSDOS)
+preprint (Unix)
+ [preview and preprint differ from gpreview only by their name and
+ can be created by setting respective links.]
+ Generates a sample text and character set listing of up to four
+ fonts (preferably of one family).
+ The latter two print, the first three display on screen.
+
+ Syntax: pfbshow fontfile1 [fontfile2 [fontfile3 [fontfile4]]]
+ pfbpr fontfile1 [fontfile2 [fontfile3 [fontfile4]]]
+ preview (fontfile|fontname) ...
+ Up to four fonts make sense. The Unix scripts can accept
+ FontNames instead of file names to explicitly select a
+ font which must then be previously known to the interpreter.
+ Examples:
+ pfbshow photina.pfb
+ pfbshow photina photinai photinab
+ gpreview Times-Roman.pfb /Hershey-Roman
+
+ Required:
+ one of several .pfb/.pfa converters (e.g. from t1utils)
+ pfbshow.bat, pfbpr.bat: pfshow.ps (enclosed)
+ pfbshow, gpreview, pfbpr: GhostScript
+ preprint: a PostScript printer
+ preview: a type 1 font emulation package for OpenWindows
+ and a font disassembler (e.g. from t1utils)
+ (or maybe, native type 1 font interpretation in
+ OpenWindows 3.1 which I don't have)
+
+pcs.bat (MSDOS)
+ Display the character set of a font in comparison with that of
+ an installed reference font (or a second font) including a
+ coloured width and slant angle box. It can be used to judge
+ quality, similarity, and correct/incorrect character set assignment
+ of fonts.
+
+ Syntax: pcs filename [filename2]
+ Examples:
+ pcs gocmase_.pfb
+ pcs agar agarsc
+
+pfblist.bat (MSDOS)
+ Generates a list of file and font names of the current directory.
+ Requires: pfbnames.pas/.exe (enclosed)
+
+afm-pfm.bat (MSDOS)
+ Generates .pfm from .afm files using Adobe's makepfm program.
+ Generates .inf information as needed for makepfm. Also tries
+ to extract the correct Bold/Italic combination from .afm information.
+ Can be called with explicit information about the Windows menu
+ font name and Bold/Italic combination to be used.
+
+ Syntax: afm-pfm fontfile [MSMenuName | - ] [N | I | B | T]
+ Don't include .afm suffix in fontfile.
+ MSMenuName selects a name under which the font should appear
+ in MS Windows menus for most programs if this is different
+ from the FamilyName in the .afm file. (Annoyingly, only
+ 4 fonts can be grouped under one name in MS Windows.)
+ N forces the generated style information to be normal,
+ I italic, B bold, T bold-italic.
+ Examples:
+ afm-pfm agar
+ afm-pfm agarb AGaramondBold N
+ If the MS menu name to be generated should contain blanks, an .inf
+ file must be generated first and the name inserted there.
+
+ Required: makepfm.exe from Adobe's "font foundry".
+
+afm-inf.bat (MSDOS)
+ Part of afm-pfm, can also be called separately.
+ Example: afm-inf agar
+
+afm-sort.bat (MSDOS)
+ Sorts the pair kerning list within an .afm file. Needed for some
+ .afm files to prevent Adobe's simple-minded makepfm program
+ from crashing.
+ Example: afm-sort agar
+
+pfb-abf.bat (MSDOS)
+ Generate .abf files for 72x72 resolution as required to generate
+ FrameMaker screen font files for use on Sun workstations.
+
+ Syntax: pfb-abf fontname [outnam [resolutionx [resolutiony [encoding]]]]
+ Don't include .pfb suffix in fontname.
+ If fontname is longer than 6 characters a unique outnam with
+ at most 6 characters must additionally be specified (five if
+ you should generate point sizes > 99).
+ Screen resolution defaults to 72x72 (for Sun workstations)
+ but can be changed.
+ The encoding vector to be applied (to be given without its
+ .enc suffix) defaults to fontname.ENC if that exists,
+ C:\Adobe\APPLE.ENC otherwise (adapt the path in the script
+ to where you place the APPLE.ENC file enclosed).
+ The set of point sizes to be generated defaults to
+ 10 12 14 18 24 but may changed by the environment variable
+ SIZES, e.g. (for display fonts) set SIZES=18 24 36
+ Note that FrameMaker needs at least sizes 18 and 24.
+
+ Required: makebit.exe, makeabf.exe from Adobe's "font foundry".
+
+pfb-sfp.bat (MSDOS)
+ Generate HP Laserjet soft fonts from .pfb fonts.
+
+ Syntax: pfb-abf fontname [outnam [resolutionx [resolutiony [encoding]]]]
+ Don't include .pfb suffix in fontname.
+ If fontname is longer than 6 characters a unique outnam with
+ at most 6 characters must additionally be specified (five if
+ you should generate point sizes > 99).
+ Printer resolution defaults to 300x300.
+ The encoding vector to be applied (to be given without its
+ .enc suffix) defaults to fontname.ENC if that exists,
+ C:\Adobe\foundry\W.ENC otherwise (adapt path in the script).
+ The set of point sizes to be generated defaults to
+ 10 12 but may changed by the environment variable PSIZES,
+ e.g. set PSIZES=9 10 12 14 18
+
+ Required: makebit.exe, makeljf.exe from Adobe's "font foundry".
+
+pfb-enc.bat (MSDOS)
+ Extracts an .ENC encoding description from a font specific encoding
+ vector for use with pfb-abf or pfb-sfp.
+ Example:
+ pfb-enc agarexp
+
+fm.ps
+ A one-liner. Prepended to FrameMaker generated PostScript files
+ it makes them work with GhostScript.
+
+compose.bat (MSDOS) (not included)
+ This script calculates positions of accent marks and other
+ character parts to be composed for composed characters.
+ It can be used as batch file or interactively, enabling
+ visual correction of character slant values, accent distance, etc.
+ The program (actually, compose.ps) generates output usable by my
+ "t1tidy" program which will then generate according characters
+ into the font.
+ Since the interactive version has not been developed to a state
+ I would like to see posted publically (I have only used it myself
+ for a few fonts) it is not included in the ftp-able package but
+ I will mail it to anyone who states interest.
+
+Debugging: All MSDOS scripts accept an additional first parameter "-"
+in which case they do not delete their intermediate files.
+
+Remark: Due to that silly MSDOS path restriction, all my MSDOS scripts
+(.bat files) contain full path names for several programs. These will have
+to be adapted to your installation. Also, for pcs, a reference font will
+have to be chosen and installed in the script.
diff --git a/fonts/utilities/t1tools/t1tidy/@t1tidy.doc b/fonts/utilities/t1tools/t1tidy/@t1tidy.doc
new file mode 100644
index 0000000000..61f728f91d
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/@t1tidy.doc
@@ -0,0 +1,281 @@
+t1tidy - tidy up your type 1 font programs
+May 1993 version
+
+Purpose
+ This program was intended and is capable to reduce the size
+ of many amateur font programs (type 1 fonts) significantly, i.e.
+ by 20-35% (this also applies to many of the clone fonts bundled with
+ Coreldraw and some of those bundled with Micrografx Designer).
+ Of course, no loss of information will occur.
+ The reduction is achieved by 3 different operations:
+ - Find common subpaths in the character descriptions and put them
+ into subroutines (Subrs entry). Apparently, many font generating
+ programs (e.g. FontMonger) are not clever enough to do this.
+ - If an explicit encoding vector is present in a text font, this
+ should be replaced by the simple entry
+ /Encoding StandardEncoding def
+ The explicit vector is stupid anyway since automatic adjustment
+ to the operating system specific (or otherwise environment
+ specific) encoding scheme will often be disabled. And it's also
+ a waste of storage (more than 4 KB!).
+ - Many amateur fonts around were apparently generated by font
+ software (e.g. ZSoft's SoftType) which is so stupid as to
+ include a large bunch of PostScript code for hint replacement
+ and curve flexing although the font does not use these features
+ at all. t1tidy detects if no use of that code occurs and in that
+ case removes that junk code (5 KB, after all!).
+
+Further functions of t1tidy are:
+ - Insert dummy zero-move commands where subpaths start with a
+ drawing command. Their omission, although alright according to
+ the type 1 format specifications, appeared to cause display
+ problems with ATM 1.3 which would display inappropriate junk
+ lines (I have not checked this with ATM 2).
+ - t1tidy can attempt to generate some missing characters from
+ others, namely quote marks.
+ - t1tidy can generate composite characters from their base
+ characters and accents if external composition information
+ if given. This can either be supplied by the CC lines of an afm
+ file or can be generated separately by a PostScript script
+ attached to this package, 'compose.bat' and 'compose.ps'.
+ - Empty character descriptions are removed to make them free
+ for automatically generated characters (and to save some space).
+ Some font generation programs seem to store entries for all
+ character names of their favourite encoding even if the designer
+ of the font was too lazy to design that character.
+ - If an afm file is present, it is copied along with the
+ transformation. All metrics entries are checked and
+ corrected if necessary and missing entries and entries for
+ generated characters are supplemented.
+ - Optionally, t1tidy can also expand (instead of factor out)
+ existing Subrs into full character path descriptions. This is
+ useful to take characters from one font into another.
+
+Why is there a need to reduce storage at all?
+ Smaller font files do not only reduce the amount of disk storage
+ used which might be of less interest to some people. They also
+ reduce virtual memory use in the PostScript printer which may
+ already be less available. And, of course, downloading time (there
+ are still a lot of PostScript printers connected by serial lines).
+
+Liability
+ None. Don't delete the original font file before you have verified
+ that the tidied font works.
+
+Copyright
+ 1. Private users without commercial advantage from using fonts
+ may apply t1tidy freely to any font file not created by
+ themselves (cf. 3.) for private, non-commercial use.
+ 2. Commercial users send 15 ECU / 20 US$ to me. Remember
+ that you may save downloading time with t1tidy and time is money!
+ 3. Font designers who lack appropriate font software and wish
+ to use t1tidy to keep their font small or to generate
+ additional characters, are permitted to use it with the
+ following restrictions:
+ - I request that a free copy of your font is granted and sent
+ to me.
+ - If you make a text font based on the Latin alphabet (i.e. not
+ a Chinese, Cyrillic, etc. or an ornamental font),
+ I only allow to use t1tidy on it if character set completeness
+ is respected:
+ Your font should contain all characters of
+ AdobeStandardEncoding, and also all commonly used combinations
+ of letters and accent marks as included, e.g., in the
+ Windows 3.1 character set (a superset of ISO-Latin-1) or the
+ Macintosh character set.
+ If you only make a stub font without these characters, using
+ t1tidy on it is a violation of my copyright. Sorry, but I'm
+ really fed up with all these useless junk fonts I've wasted
+ downloading time for.
+
+Requirements
+ MSDOS, (Turbo-Pascal to compile).
+ Type 1 font disassembling and assembling software. I recommend
+ t1utils which is freely available on ftp servers. A future
+ version of t1tidy may perform this step itself.
+
+Syntax
+ t1tidy [options] infont.ps outfont.ps
+ or, with batch file:
+ t1t [options] infont outfont
+ t1t [options] infont outdir
+
+ The font name(s) for t1t must be given without any suffix. (The
+ primitive MSDOS command interpreter does not allow for such things
+ as stripping suffixes for more comfortable command processing.)
+ Also unfortunately, the stupid MSDOS command interpreter does not
+ allow us to recognize if the first argument start with a '-', so we
+ can only have a small number of specific option strings here.
+ Option strings recognized by t1t are: -g, -e, -ge, -eg, -s, +c, +x .
+ Within t1t, add recognizable option sets to your needs or the -v
+ option according to your taste.
+
+ For convenience, the second argument to the scripts can be the
+ name of a directory which the tidied fonts are then collected in.
+ This simplifies working on a bunch of fonts.
+ In t1t, modify the paths of t1tidy.exe and the type 1 font
+ assembly/disassembly programs according to your installation.
+
+Actions
+ The transformation will be performed on the (disassembled type 1)
+ font file infont.ps and written to outfont.ps. If infont.afm is
+ present, it will be copied to outfont.afm and modifications
+ accordingly applied, including renumbering of the entries if the
+ -e option is given.
+ Incomplete afm files will be completed with respect to some
+ basic entries (e.g. CapHeight which is needed by Adobe's makepfm)
+ and adding missing bounding boxes from default assumptions (also
+ required for some metrics transformation software).
+
+Options
+ Except for +c, all options are selected by default! Options can
+ be selected with +<letter> or deselected with -<letter>.
+ s split Perform path splitting and subroutine extraction.
+ t1tidy cannot currently generate new Subrs for
+ fonts which do not already have a Subrs entry.
+ In that case, insert one manually in the
+ disassembled version of the font:
+ /Subrs 4 array
+ dup 0 {} put
+ dup 1 {} put
+ dup 2 {} put
+ dup 3 {} put
+ def
+ into the font directory, typically called
+ /FontDirectory, typically before the lines
+ end NP
+ dup /CharString ... dict dup begin
+ (details may vary). The size of the font directory
+ might have to be increased by 1.
+ This option should be disabled, e.g., if some
+ aspect of the font is too large to handle it but
+ another function of t1tidy (e.g. character
+ generation) shall be applied.
+ e encoding Replace encoding vector with StandardEncoding.
+ This option should and should only be deselected
+ for use on ornamental or foreign letter-type fonts
+ if they use their own character naming scheme.
+ o OtherSubrs Enable removal of OtherSubrs unless they are used
+ in the font. This saves 5 KB of wasted storage in
+ many amateur fonts (e.g. generated by SoftType).
+ g generate Try to generate missing quote marks from others.
+ The following generations are implemented:
+ halfchar ('/quotedbl', '/quotesingle');
+ downchar ('/quotedblright', '/quotedblbase');
+ halfchar ('/quotedblbase', '/quotesinglbase');
+ halfchar ('/quotedblleft', '/quoteleft');
+ halfchar ('/quotedblright', '/quoteright');
+ downchar ('/quoteright', '/quotesinglbase');
+ halfchar ('/guillemotleft', '/guilsinglleft');
+ halfchar ('/guillemotright', '/guilsinglright');
+ copychar ('/less', '/guilsinglleft');
+ copychar ('/greater', '/guilsinglright');
+ either copychar ('/endash', '/minus')
+ or copychar ('/hyphen', '/minus');
+ copychar ('/slash', '/fraction');
+ copychar ('/bar', '/brokenbar');
+ copychar ('/asciitilde', '/tilde');
+ copychar ('/asciicircum', '/circumflex');
+ copychar ('/degree', '/ring');
+ halfchar generates the second from the first by
+ taking the first closed part of its path description.
+ downchar generates the second from the first by
+ setting its vertical offset to zero. Hints are
+ adjusted.
+ copychar copies the first into the second.
+ Every generation is only performed if the affected
+ character does not already exist.
+ Deselect this option if the font is not a Latin
+ letter font (i.e., e.g., Greek, or ornaments) but
+ contains its foreign letters or symbols under Latin
+ letter names (as is often the case).
+ x expand Reexpands existing Subrs into full character path
+ descriptions. This is useful to take characters from
+ one font into another.
+ a afmcheck Enables checking of afm entries for all characters.
+ c corelfix Apply 3 fixes for problems encountered with
+ wfn font files (those transformed with WFNBOSS
+ from CorelDraw 2 fonts - I don't know if the same
+ problems occur with CorelDraw 3 fonts).
+ Exchange wrongly encoded characters, derive some
+ missing characters from others (i.e., -g is implied),
+ solve the UniqueID problem by assigning increasing
+ UniqueID values using a configuration file
+ uniqueid.int.
+ As long as you tidy wfn font files, you should keep
+ the file uniqueid.int (generated on first use)
+ always in the working directory.
+ (The zero-move command insertion also primarily
+ serves wfn fonts, but not exclusively.)
+ t ttfix Rename characters from PostScript-embedded fonts
+ which Windows generated from TrueType fonts
+ (manual adjustments still to be done).
+ v verbose Tell user about every major step.
+
+Procedure:
+ 1. Display or print a sample of the font to be tidied to determine
+ if any characters are misplaced (i.e. are not registered with
+ their correct name) or any junk characters take positions which
+ need to be used for automatic character generation. You may use
+ my "pcs.bat" and "pcs.ps" for character set display, or
+ "pfbshow.bat" and "pfshow.ps" for style and character samples.
+ Manually change the names of misplaced characters or delete the
+ descriptions of useless characters. Some fonts contain a
+ character showing a copyright notice. This tends to comsume
+ up to 5KB of memory due to an extraordinarily long character
+ path which also exceeds t1tidy's path length limit.
+ 2. Apply t1tidy to perform path length reduction and generation
+ of characters, e.g. single from double quotemarks, circumflex
+ from asciicircum (sometimes not nice) etc. If important accent
+ marks are still missing: if the font conatains not all but some
+ accented characters, try to extract accents from characters
+ by manually removing parts of their character description (after
+ copying the path and giving the copy the right name), else
+ design new accent marks or take them from another font fitting
+ to the font style.
+ 3. If accented character are to be generated, generate an .afm or
+ .cc file containing appropriate "CC ..." entries for them. You
+ can use my "compose.bat" and "compose.ps" for this task. Then
+ apply t1tidy again to incorporate the compositions into the font.
+
+Precautions to be observed:
+1. t1tidy should not be applied to professional quality fonts. It should
+ be expected from professional fonts anyway that optimizations
+ like those performed by t1tidy should not be necessary. (However,
+ this need not always be the case. I have seen commercially sold
+ text fonts which included explicit encoding vectors and few Subrs.)
+2. t1tidy will crash and leave incomplete output on fonts which are too
+ large or contain too large character paths. This is basically
+ due to the old 640KB restriction and will probably change when
+ compiled with Turbo-Pascal 7 (I don't have it yet). For the path
+ length restriction, also constant maxpathlen in pathunit.pas and
+ some code would have to be changed because I did not implement
+ path description storage with a dynamic data structure since this
+ would have caused even more memory problems in the 640KB limited
+ version.
+
+Future improvements
+ - Repeated applications of t1tidy would currently not find
+ common subpaths between already existing Subrs and newly
+ extracted subpaths. This should really be smoothed.
+ Moreover, more than a single level of common subpath extraction
+ might be desirable.
+ - An initial Subrs entry should be generated automatically if no
+ one is present.
+ - When trying to generate a half or doubled character description,
+ subpath determination should consider Subrs called. Also stems
+ should be adjusted.
+ - More automization on extracting embedded fonts generated from
+ printing TrueType fonts might be useful.
+ - More information in the afm file should be checked and corrected,
+ like FontName, EncodingScheme, etc.
+
+Availability
+ by ftp from ftp.fu-berlin.de: pub/postscript/t1tidy.zip
+
+Author
+ Thomas Wolff
+ Hebbelstra$e 3
+ D-10585 Berlin
+ wolff@inf.fu-berlin.de
+
diff --git a/fonts/utilities/t1tools/t1tidy/afm.pas b/fonts/utilities/t1tools/t1tidy/afm.pas
new file mode 100644
index 0000000000..676deeaafe
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/afm.pas
@@ -0,0 +1,361 @@
+unit afm;
+
+
+interface
+
+procedure openafm (var afmin, afmout: text);
+procedure closeafm (var afmin, afmout: text);
+
+procedure getafmchar (var C, WX: integer; name: string; var lx, ly, rx, ry: integer);
+procedure putafmchar (C, WX: integer; pname: string; lx, ly, rx, ry: integer);
+
+procedure opencc (var ccin: text);
+procedure composeCCs;
+
+
+implementation
+
+uses strtype, data, pathunit;
+
+function makeint (s: string): integer;
+var i, c: integer;
+begin
+ val (s, i, c);
+ makeint := i
+end;
+
+function intstr (i: integer): string;
+var s: string;
+begin
+ str (i, s);
+ intstr := s
+end;
+
+var line: strec;
+
+procedure readline (var f: text);
+(* accept DOS, Unix, and Mac line-ends *)
+var s: string;
+ c: char;
+begin
+ c := ' ';
+ s := '';
+ while not eoln (f) and (c <> #$0A) do begin
+ read (f, c);
+ if c <> #$0A then s := s + c
+ end;
+ if eoln (f) then readln (f);
+ line.ini (s)
+end;
+
+type ligpoi = ^ ligature;
+ ligature = record
+ second, ligname: string [30];
+ nextlig: ligpoi
+ end;
+ charmetrics = record
+ C: integer;
+ WX: integer;
+ N: string [30];
+ lx, ly, rx, ry: integer;
+ lig: ligpoi;
+ end;
+ charmetricspoi = ^ charmetrics;
+ composespec = record
+ name, name1, name2: string [30];
+ x1, y1, x2, y2: integer;
+ end;
+ composespecpoi = ^ composespec;
+
+const maxmetricsentry = 600;
+ maxcomposeentry = 300;
+var charentries: array [0..maxmetricsentry] of charmetricspoi;
+ (* 0..255 are encoded entries, those above are unencoded *)
+ composeentries: array [1..maxcomposeentry] of composespecpoi;
+ unencodedindex: integer;
+ afmopen: Boolean;
+ entrycount, composecount: integer;
+ CapHeight, XHeight, Ascender, Descender: Boolean;
+ afmintermediate: text;
+
+procedure parseCC (line: strec; fromafm: Boolean);
+(* parse a line like CC Aacute 2 ; PCC A 0 0 ; PCC acute 183 227 ; *)
+var composeentry: composespec;
+begin
+ with composeentry do begin
+ name := line.nexttoken;
+ if line.nexttoken <> '2' then begin
+ if fromafm (* or afmopen ? But then include StartComposites etc. *)
+ then writeln (afmintermediate, line.str);
+ end else begin
+ if fromafm (* or afmopen ? *)
+ then writeln (afmintermediate, line.str);
+ (* or re-generate entries? *)
+ line.gotonexttoken; line.gotonexttoken;
+ name1 := line.nexttoken;
+ x1 := makeint (line.nexttoken);
+ y1 := makeint (line.nexttoken);
+ line.gotonexttoken; line.gotonexttoken;
+ name2 := line.nexttoken;
+ x2 := makeint (line.nexttoken);
+ y2 := makeint (line.nexttoken);
+ composecount := composecount + 1;
+ new (composeentries [composecount]);
+ composeentries [composecount] ^ := composeentry;
+ end
+ end
+end;
+
+procedure openafm (var afmin, afmout: text);
+var charentry: charmetrics;
+ newmetric: charmetricspoi;
+ afmcmd: string;
+ FontBBoxlx, FontBBoxly, FontBBoxrx, FontBBoxry: integer;
+ i: integer;
+
+ function getligature: ligpoi;
+ var newlig: ligpoi;
+ begin
+ line.gotonexttoken;
+ if line.nexttoken = 'L' then begin
+ new (newlig);
+ newlig ^. second := line.nexttoken;
+ newlig ^. ligname := line.nexttoken;
+ newlig ^. nextlig := getligature;
+ getligature := newlig
+ end
+ else getligature := nil
+ end;
+
+begin
+ afmopen := true;
+ rewrite (afmout);
+ (* set defaults: *)
+ FontBBoxlx := 0;
+ FontBBoxly := 0;
+ FontBBoxrx := 0;
+ FontBBoxry := 0;
+ CapHeight := false;
+ XHeight := false;
+ Ascender := false;
+ Descender := false;
+ for i := 0 to maxmetricsentry do charentries [i] := nil;
+ unencodedindex := 255;
+
+ readline (afmin); afmcmd := line.firsttoken;
+ while afmcmd <> 'StartCharMetrics' do begin
+ writeln (afmout, line.str);
+ if afmcmd = 'FontBBox' then begin
+ FontBBoxlx := makeint (line.nexttoken);
+ FontBBoxly := makeint (line.nexttoken);
+ FontBBoxrx := makeint (line.nexttoken);
+ FontBBoxry := makeint (line.nexttoken);
+ end
+ else if afmcmd = 'CapHeight' then CapHeight := true
+ else if afmcmd = 'XHeight' then XHeight := true
+ else if afmcmd = 'Ascender' then Ascender := true
+ else if afmcmd = 'Descender' then Descender := true
+ ;
+ readline (afmin); afmcmd := line.firsttoken
+ end;
+ readline (afmin);
+ while line.nexttoken = 'C' do with charentry do begin
+ C := makeint (line.nexttoken);
+ line.gotonexttoken; line.gotonexttoken;
+ WX := makeint (line.nexttoken);
+ line.gotonexttoken; line.gotonexttoken;
+ N := line.nexttoken;
+ if N <> ';' (* name may be missing, e.g. with wfnboss's files *)
+ then begin
+ if stdenc then C := getSEcode ('/' + N);
+ entrycount := entrycount + 1;
+ line.gotonexttoken;
+ if line.nexttoken = 'B' then begin
+ lx := makeint (line.nexttoken);
+ ly := makeint (line.nexttoken);
+ rx := makeint (line.nexttoken);
+ ry := makeint (line.nexttoken);
+ end else begin
+ lx := FontBBoxlx;
+ ly := FontBBoxly;
+ rx := FontBBoxrx;
+ ry := FontBBoxry;
+ end;
+ lig := getligature;
+ if C = 0 then C := -1 (* makepfm doesn't like 0 *);
+ new (newmetric);
+ newmetric^ := charentry;
+ if C >= 0 then charentries [C] := newmetric
+ else begin
+ unencodedindex := unencodedindex + 1;
+ charentries [unencodedindex] := newmetric;
+ end;
+ end;
+ readline (afmin);
+ end;
+ makefilebuffer (afmintermediate, 'afminter.med');
+ repeat
+ writeln (afmintermediate, line.str);
+ if not eof (afmin) then readline (afmin);
+ until eof (afmin) or (line.firsttoken = 'CC');
+ if not eof (afmin) then
+ while line.firsttoken = 'CC' do begin
+ parseCC (line, true);
+ readline (afmin);
+ end;
+end;
+
+procedure opencc (var ccin: text);
+var s: string;
+ ccline: strec;
+begin
+ while not eof (ccin) do begin
+ readln (ccin, s);
+ ccline.ini (s);
+ if ccline.firsttoken = 'CC' then parseCC (ccline, false);
+ end
+end;
+
+procedure closeafm (var afmin, afmout: text);
+var c: char;
+ i: integer;
+
+ procedure writelig (lp: ligpoi);
+ begin
+ if lp <> nil then begin
+ write (afmout, ' L ', lp^.second, ' ', lp^.ligname, ' ;');
+ writelig (lp^.nextlig)
+ end
+ end;
+
+begin
+ if not CapHeight then if charentries [ord ('H')] <> nil then
+ writeln (afmout, 'CapHeight ', charentries [ord ('H')]^.ry);
+ if not XHeight then if charentries [ord ('x')] <> nil then
+ writeln (afmout, 'XHeight ', charentries [ord ('x')]^.ry);
+ if not Ascender then if charentries [ord ('d')] <> nil then
+ writeln (afmout, 'Ascender ', charentries [ord ('d')]^.ry);
+ if not Descender then if charentries [ord ('p')] <> nil then
+ writeln (afmout, 'Descender ', charentries [ord ('p')]^.ly);
+ writeln (afmout, 'StartCharMetrics ', entrycount);
+ for i := 0 to maxmetricsentry do if charentries [i] <> nil then
+ with charentries [i]^ do begin
+ write (afmout, 'C ', C, ' ; WX ', WX, ' ; N ', N,
+ ' ; B ', lx, ' ', ly, ' ', rx, ' ', ry, ' ;');
+ writelig (lig);
+ if (N = 'f') and (lig = nil) then begin
+ if getCharString ('/fi') <> nil then write (afmout, ' L i fi ;');
+ if getCharString ('/fl') <> nil then write (afmout, ' L l fl ;');
+ end;
+ writeln (afmout)
+ end;
+ getfilebuffer (afmintermediate, afmout);
+ writeln (afmout, line.str);
+ while not eof (afmin) do begin
+ read (afmin, c);
+ write (afmout, c);
+ end;
+ close (afmin);
+ close (afmout);
+end;
+
+function purename (s: string): string;
+begin
+ if pos ('/', s) = 1 then purename := copy (s, 2, length (s) - 1)
+ else purename := s
+end;
+
+procedure composeCCs;
+var i: integer;
+ cc1, cc2: integer;
+ CS1, CS2: CharStrpointer;
+ pname, pname1, pname2: string [30];
+begin
+ for i := 1 to composecount do with composeentries [i] ^ do begin
+ pname := '/' + name;
+ pname1 := '/' + name1;
+ pname2 := '/' + name2;
+ if getCharString (pname) = nil then
+ if (x1 = 0) and (y1 = 0) then begin
+ cc1 := getSEcode (pname1);
+ cc2 := getSEcode (pname2);
+ CS1 := getCharString (pname1);
+ CS2 := getCharString (pname2);
+ if (cc1 >= 0) and (cc2 >= 0)
+ and (CS1 <> nil) and (CS2 <> nil) then begin
+ CharStringscount := CharStringscount + 1;
+ new (CharStrings [CharStringscount], ini);
+ CharStrings [CharStringscount] ^ . setname (pname);
+ CharStrings [CharStringscount] ^ . compose
+ (CS1, CS2, cc1, cc2, x2, y2)
+ end
+ end
+ else writeln ('% cannot compose with first char offset')
+ end
+end;
+
+procedure getafmchar (var C, WX: integer; name: string; var lx, ly, rx, ry: integer);
+var i: integer;
+ N: string;
+begin
+ N := purename (name);
+ C := -2; (* error indication if not found *)
+ WX := 0;
+ lx := 0; ly := 0; rx := 0; ry := 0;
+ if afmopen then begin
+ for i := 0 to maxmetricsentry do if charentries [i] <> nil then
+ if charentries [i]^.N = N then begin
+ C := charentries [i]^.C;
+ WX := charentries [i]^.WX;
+ lx := charentries [i]^.lx;
+ ly := charentries [i]^.ly;
+ rx := charentries [i]^.rx;
+ ry := charentries [i]^.ry;
+ end
+ end
+end;
+
+procedure putafmchar (C, WX: integer; pname: string; lx, ly, rx, ry: integer);
+var index: integer;
+ name: string [30];
+ found: Boolean;
+begin
+ name := purename (pname);
+ if afmopen then begin
+ if C >= 0 then
+ if charentries [C] = nil then index := C
+ else if charentries [C]^.N = name then index := C
+ else C := -1;
+ if C < 0 then begin
+ index := 255; (* last encoded index *)
+ found := false;
+ repeat index := index + 1;
+ if index > unencodedindex then begin
+ found := true;
+ unencodedindex := index;
+ end else if charentries [index] <> nil
+ then if charentries [index]^.N = name
+ then found := true
+ until found
+ end;
+ if charentries [index] = nil then begin
+ entrycount := entrycount + 1;
+ new (charentries [index]);
+ charentries [index]^.N := name;
+ charentries [index]^.lig := nil;
+ end;
+ charentries [index]^.C := C;
+ charentries [index]^.WX := WX;
+ charentries [index]^.lx := lx;
+ charentries [index]^.ly := ly;
+ charentries [index]^.rx := rx;
+ charentries [index]^.ry := ry;
+ end
+end;
+
+begin
+ afmopen := false;
+ ccopen := false;
+ entrycount := 0;
+ composecount := 0;
+end.
diff --git a/fonts/utilities/t1tools/t1tidy/data.pas b/fonts/utilities/t1tools/t1tidy/data.pas
new file mode 100644
index 0000000000..f0d427f5b7
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/data.pas
@@ -0,0 +1,158 @@
+unit data;
+
+
+interface
+
+uses pathunit;
+
+(* options: *)
+
+var corelfix, generate, split, ttfix, verbose, stdenc,
+ noOtherSubrs, afmcheck: Boolean;
+
+(* flags: *)
+
+var afmopen, ccopen: Boolean;
+
+(* CharStrings storage *)
+
+const maxCharStrings = 300;
+
+var CharStrings: array [1..maxCharStrings] of CharStrpointer;
+ CharStringscount: integer;
+
+(* Encoding vectors *)
+
+const (* Windows encoding vector used for ttfix option *)
+ WinANSI: array [0..255] of string [30] = (
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/space', '/exclam', '/quotedbl', '/numbersign', '/dollar', '/percent', '/ampersand', '/quotesingle',
+ '/parenleft', '/parenright', '/asterisk', '/plus', '/comma', '/hyphen', '/period', '/slash',
+ '/zero', '/one', '/two', '/three', '/four', '/five', '/six', '/seven',
+ '/eight', '/nine', '/colon', '/semicolon', '/less', '/equal', '/greater', '/question',
+ '/at', '/A', '/B', '/C', '/D', '/E', '/F', '/G', '/H', '/I', '/J', '/K', '/L', '/M', '/N', '/O',
+ '/P', '/Q', '/R', '/S', '/T', '/U', '/V', '/W',
+ '/X', '/Y', '/Z', '/bracketleft', '/backslash', '/bracketright', '/asciicircum', '/underscore',
+ '/grave', '/a', '/b', '/c', '/d', '/e', '/f', '/g', '/h', '/i', '/j', '/k', '/l', '/m', '/n', '/o',
+ '/p', '/q', '/r', '/s', '/t', '/u', '/v', '/w',
+ '/x', '/y', '/z', '/braceleft', '/bar', '/braceright', '/asciitilde', '/.notdef',
+ '/.notdef', '/.notdef', '/quotesinglbase', '/florin',
+ '/quotedblbase', '/ellipsis', '/dagger', '/daggerdbl',
+ '/circumflex', '/perthousand', '/Scaron', '/guilsinglleft', '/OE', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/quoteleft', '/quoteright', '/quotedblleft',
+ '/quotedblright', '/bullet', '/endash', '/emdash',
+ '/tilde', '/trademark', '/scaron', '/guilsinglright', '/oe', '/.notdef', '/.notdef', '/Ydieresis',
+ '/space', '/exclamdown', '/cent', '/sterling', '/currency', '/yen', '/brokenbar', '/section',
+ '/dieresis', '/copyright', '/ordfeminine', '/guillemotleft',
+ '/logicalnot', '/minus', '/registered', '/macron',
+ '/degree', '/plusminus', '/twosuperior', '/threesuperior',
+ '/acute', '/mu', '/paragraph', '/periodcentered',
+ '/cedilla', '/onesuperior', '/ordmasculine', '/guillemotright',
+ '/onequarter', '/onehalf', '/threequarters', '/questiondown',
+ '/Agrave', '/Aacute', '/Acircumflex', '/Atilde', '/Adieresis', '/Aring', '/AE', '/Ccedilla',
+ '/Egrave', '/Eacute', '/Ecircumflex', '/Edieresis', '/Igrave', '/Iacute', '/Icircumflex', '/Idieresis',
+ '/Eth', '/Ntilde', '/Ograve', '/Oacute', '/Ocircumflex', '/Otilde', '/Odieresis', '/multiply',
+ '/Oslash', '/Ugrave', '/Uacute', '/Ucircumflex', '/Udieresis', '/Yacute', '/Thorn', '/germandbls',
+ '/agrave', '/aacute', '/acircumflex', '/atilde', '/adieresis', '/aring', '/ae', '/ccedilla',
+ '/egrave', '/eacute', '/ecircumflex', '/edieresis', '/igrave', '/iacute', '/icircumflex', '/idieresis',
+ '/eth', '/ntilde', '/ograve', '/oacute', '/ocircumflex', '/otilde', '/odieresis', '/divide',
+ '/oslash', '/ugrave', '/uacute', '/ucircumflex', '/udieresis', '/yacute', '/thorn', '/ydieresis'
+ );
+
+ (* StandardEncoding vector used for generate option *)
+ StandardEncoding: array [0..255] of string [30] = (
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/space', '/exclam', '/quotedbl', '/numbersign', '/dollar', '/percent', '/ampersand', '/quoteright',
+ '/parenleft', '/parenright', '/asterisk', '/plus', '/comma', '/hyphen', '/period', '/slash',
+ '/zero', '/one', '/two', '/three', '/four', '/five', '/six', '/seven',
+ '/eight', '/nine', '/colon', '/semicolon', '/less', '/equal', '/greater', '/question',
+ '/at', '/A', '/B', '/C', '/D', '/E', '/F', '/G', '/H', '/I', '/J', '/K', '/L', '/M', '/N', '/O',
+ '/P', '/Q', '/R', '/S', '/T', '/U', '/V', '/W',
+ '/X', '/Y', '/Z', '/bracketleft', '/backslash', '/bracketright', '/asciicircum', '/underscore',
+ '/quoteleft', '/a', '/b', '/c', '/d', '/e', '/f', '/g', '/h', '/i', '/j', '/k', '/l', '/m', '/n', '/o',
+ '/p', '/q', '/r', '/s', '/t', '/u', '/v', '/w',
+ '/x', '/y', '/z', '/braceleft', '/bar', '/braceright', '/asciitilde', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/exclamdown', '/cent', '/sterling', '/fraction', '/yen', '/florin', '/section',
+ '/currency', '/quotesingle', '/quotedblleft', '/guillemotleft',
+ '/guilsinglleft', '/guilsinglright', '/fi', '/fl',
+ '/.notdef', '/endash', '/dagger', '/daggerdbl',
+ '/periodcentered', '/.notdef', '/paragraph', '/bullet',
+ '/quotesinglbase', '/quotedblbase', '/quotedblright', '/guillemotright',
+ '/ellipsis', '/perthousand', '/.notdef', '/questiondown',
+ '/.notdef', '/grave', '/acute', '/circumflex', '/tilde', '/macron', '/breve', '/dotaccent',
+ '/dieresis', '/.notdef', '/ring', '/cedilla', '/.notdef', '/hungarumlaut', '/ogonek', '/caron',
+ '/emdash', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/AE', '/.notdef', '/ordfeminine', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/Lslash', '/Oslash', '/OE', '/ordmasculine', '/.notdef', '/.notdef', '/.notdef', '/.notdef',
+ '/.notdef', '/ae', '/.notdef', '/.notdef', '/.notdef', '/dotlessi', '/.notdef', '/.notdef',
+ '/lslash', '/oslash', '/oe', '/germandbls', '/.notdef', '/.notdef', '/.notdef', '/.notdef'
+ );
+
+function getCharString (n: string): CharStrpointer;
+function getSEcode (n: string): integer;
+procedure makefilebuffer (var buf: text; name: string);
+procedure getfilebuffer (var buf, out: text);
+
+
+implementation
+
+uses Dos;
+
+function getCharString (n: string): CharStrpointer;
+var i: integer;
+begin
+ i := 1;
+ getCharString := nil;
+ while i <= CharStringscount do
+ if CharStrings [i] ^.name = n then begin
+ getCharString := CharStrings [i];
+ i := CharStringscount + 1
+ end
+ else i := i + 1
+end;
+
+function getSEcode (n: string): integer;
+var i: integer;
+ weiter: Boolean;
+begin
+ i := 255;
+ weiter := true;
+ while weiter and (i >= 0) do
+ if StandardEncoding [i] = n
+ then weiter := false
+ else i := i - 1;
+ getSEcode := i
+end;
+
+procedure makefilebuffer (var buf: text; name: string);
+begin
+ if getenv ('TEMP') <> ''
+ then assign (buf, getenv ('TEMP') + '\' + name)
+ else assign (buf, name);
+ rewrite (buf);
+end;
+
+procedure getfilebuffer (var buf, out: text);
+var s: string;
+begin
+ reset (buf);
+ while not eof (buf) do begin
+ readln (buf, s);
+ writeln (out, s)
+ end;
+ close (buf);
+ erase (buf);
+end;
+
+end.
diff --git a/fonts/utilities/t1tools/t1tidy/pathunit.pas b/fonts/utilities/t1tools/t1tidy/pathunit.pas
new file mode 100644
index 0000000000..3751a07540
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/pathunit.pas
@@ -0,0 +1,1135 @@
+{$B-}
+
+unit pathunit;
+
+interface
+
+const pathlenunit = 50;
+ maxpathlen = 10 * pathlenunit;
+ (* 92 recommended for normal operation
+ 170 for longer paths with many characters *)
+
+type t1cmd =
+ (callothersubr, callsubr, closepath, t1div, dotsection, endchar,
+ hlineto, hmoveto, hsbw, hstem, hstem3, hvcurveto, pop, return,
+ rlineto, rmoveto, rrcurveto, sbw, seac, setcurrentpoint,
+ vhcurveto, vlineto, vmoveto, vstem, vstem3);
+
+const cmdcount = 25;
+ cmdtab: array [1..cmdcount] of record
+ cmd: t1cmd;
+ str: string;
+ case code1: byte of
+ 12: (code2: byte)
+ end = (
+ (cmd: callothersubr; str: 'callothersubr'; code1: 12; code2: 16),
+ (cmd: callsubr; str: 'callsubr'; code1: 10),
+ (cmd: closepath; str: 'closepath'; code1: 9),
+ (cmd: t1div; str: 'div'; code1: 12; code2: 12),
+ (cmd: dotsection; str: 'dotsection'; code1: 12; code2: 0),
+ (cmd: endchar; str: 'endchar'; code1: 14),
+ (cmd: hlineto; str: 'hlineto'; code1: 6),
+ (cmd: hmoveto; str: 'hmoveto'; code1: 22),
+ (cmd: hsbw; str: 'hsbw'; code1: 13),
+ (cmd: hstem; str: 'hstem'; code1: 1),
+ (cmd: hstem3; str: 'hstem3'; code1: 12; code2: 2),
+ (cmd: hvcurveto; str: 'hvcurveto'; code1: 31),
+ (cmd: pop; str: 'pop'; code1: 12; code2: 17),
+ (cmd: return; str: 'return'; code1: 11),
+ (cmd: rlineto; str: 'rlineto'; code1: 5),
+ (cmd: rmoveto; str: 'rmoveto'; code1: 21),
+ (cmd: rrcurveto; str: 'rrcurveto'; code1: 8),
+ (cmd: sbw; str: 'sbw'; code1: 12; code2: 7),
+ (cmd: seac; str: 'seac'; code1: 12; code2: 6),
+ (cmd: setcurrentpoint; str: 'setcurrentpoint'; code1: 12; code2: 33),
+ (cmd: vhcurveto; str: 'vhcurveto'; code1: 30),
+ (cmd: vlineto; str: 'vlineto'; code1: 7),
+ (cmd: vmoveto; str: 'vmoveto'; code1: 4),
+ (cmd: vstem; str: 'vstem'; code1: 3),
+ (cmd: vstem3; str: 'vstem3'; code1: 12; code2: 1));
+
+var cmdstring: array [t1cmd] of string;
+var expand: Boolean;
+
+type commandpoi = ^ command;
+ SubrTpointer = ^ SubrT;
+ SubPathpointer = ^ SubPath;
+ CharStrpointer = ^ CharStrT;
+ command = record
+ Subr: SubPathpointer;
+ case Boolean of
+ true (* if Subr = nil: *):
+ (cmd: t1cmd;
+ paramnum: integer;
+ param: array [1..6] of integer;
+ );
+ false (* if Subr <> nil: *):
+ (closed: Boolean;
+ offsetx, offsety: integer;
+ )
+ end;
+
+ commandsarray0 = array [1..maxpathlen] of commandpoi;
+ commandsarray1 = array [1..1 * pathlenunit] of commandpoi;
+ commandsarray2 = array [1..2 * pathlenunit] of commandpoi;
+ commandsarray3 = array [1..3 * pathlenunit] of commandpoi;
+ commandsarray4 = array [1..4 * pathlenunit] of commandpoi;
+ commandsarray5 = array [1..5 * pathlenunit] of commandpoi;
+ commandsarray6 = array [1..6 * pathlenunit] of commandpoi;
+ commandsarray7 = array [1..7 * pathlenunit] of commandpoi;
+ commandsarray8 = array [1..8 * pathlenunit] of commandpoi;
+ commandsarray9 = array [1..9 * pathlenunit] of commandpoi;
+
+ varcommandspoi = record case byte of
+ 0: (cp0: ^commandsarray0);
+ 1: (cp1: ^commandsarray1);
+ 2: (cp2: ^commandsarray2);
+ 3: (cp3: ^commandsarray3);
+ 4: (cp4: ^commandsarray4);
+ 5: (cp5: ^commandsarray5);
+ 6: (cp6: ^commandsarray6);
+ 7: (cp7: ^commandsarray7);
+ 8: (cp8: ^commandsarray8);
+ 9: (cp9: ^commandsarray9);
+ end;
+
+ Path = object
+ commands: varcommandspoi;
+ pathlen: integer;
+ mayuseothersubrs: Boolean;
+ constructor ini;
+ procedure appendtoken (var s: string);
+ procedure clippath;
+ procedure setdef (s: string); virtual;
+ procedure splitpath;
+ procedure cleanup;
+ function usesothersubrs: Boolean;
+ private
+ procedure appendcommand (cmd: commandpoi);
+ procedure delete (i: integer);
+ function pathcmd (i: integer): t1cmd;
+ function pathcomponent (i: integer): commandpoi;
+ procedure getoffset (i: integer; var x, y: integer);
+ procedure printpath (var out: text; checkzmove, printreturn: Boolean);
+ function firstorlastcmd (i: integer; last: Boolean): t1cmd;
+ procedure traceBBox (var x, y, llx, lly, urx, ury: integer; var errcmd: t1cmd);
+ end;
+
+ CharStrT = object (Path)
+ name: string [30];
+ function clearifempty: Boolean;
+ procedure setname (n: string);
+ procedure setdef (s: string); virtual;
+ procedure print (var out: text);
+ procedure copyhalf (var newc: CharStrT; newname: string);
+ procedure downpath (var newc: CharStrT; newname: string);
+ procedure copypath (var newc: CharStrT; newname: string);
+ procedure compose (CS1, CS2: CharStrpointer; cc1, cc2, dx, dy: integer);
+ procedure checkafm (checkBBox: Boolean);
+ end;
+
+ SubrT = object (Path)
+ index: integer;
+ procedure setindex (i: integer);
+ procedure setdef (s: string); virtual;
+ procedure print (var out: text);
+ end;
+
+ SubPath = object (SubrT)
+ used: integer;
+ closedunique, offsetunique, closed: Boolean;
+ offsetx, offsety: integer;
+ procedure checkunique (x, y: integer; cl: Boolean);
+ procedure setdef (s: string); virtual;
+ procedure printSubr (var out: text);
+ end;
+
+const maxSubrs = 500;
+var Subrs: array [1..maxSubrs] of ^SubrT;
+ Subrscount: integer;
+ MoreSubrscount: integer;
+ Subrstotal: integer;
+
+procedure sortMoreSubrs;
+
+procedure arrangeMoreSubrs (Subrscount: integer);
+
+procedure printMoreSubrs (var out: text);
+
+procedure printusedStat;
+
+procedure swappaths (var c1, c2: CharStrT);
+
+(************************************************************************)
+
+implementation
+
+uses afm, data;
+
+function getSubr (i: integer): SubrTpointer;
+var k: integer;
+ result: SubrTpointer;
+begin
+ result := nil;
+ if Subrs [i + 1]^.index = i then result := Subrs [i + 1]
+ else for k := 1 to Subrscount do
+ if Subrs [k]^.index = i then result := Subrs [k];
+ getSubr := result
+end;
+
+var NP, ND: string (* name of Subr / CharString definition command *);
+
+type comparison = (less, equal, greater);
+
+function pathcompare (var p1, p2: SubPath): comparison;
+var i: integer;
+ result: comparison;
+ function cmdcompare (var c1, c2: command): comparison;
+ var i: integer;
+ result: comparison;
+ begin
+ if c1.Subr <> nil then
+ if c2.Subr = nil then cmdcompare := less
+ else cmdcompare := pathcompare (c1.Subr^, c2.Subr^)
+ else if c2.Subr <> nil then cmdcompare := greater
+ else if c1.cmd < c2.cmd then cmdcompare := less
+ else if c1.cmd > c2.cmd then cmdcompare := greater
+ else if c1.paramnum < c2.paramnum then cmdcompare := less
+ else if c1.paramnum > c2.paramnum then cmdcompare := greater
+ else begin
+ i := 1;
+ result := equal;
+ while (result = equal) and (i <= c1.paramnum) do begin
+ if c1.param [i] > c2.param [i] then result := greater
+ else if c1.param [i] < c2.param [i] then result := less;
+ i := i + 1;
+ end;
+ cmdcompare := result
+ end
+ end;
+begin
+ if p1.pathlen < p2.pathlen then pathcompare := less
+ else if p1.pathlen > p2.pathlen then pathcompare := greater
+ else begin
+ i := 1;
+ result := equal;
+ while (result = equal) and (i <= p1.pathlen) do begin
+ result := cmdcompare (p1.commands.cp0^[i]^, p2.commands.cp0^[i]^);
+ i := i + 1;
+ end;
+ pathcompare := result
+ end
+end;
+
+(*
+procedure sortMoreSubrs;
+ procedure quicksort (l, r: integer);
+ var i, j: integer; x, w: SubPathpointer;
+ begin i := l; j := r;
+ x := a [(l + r) div 2];
+ repeat
+ while pathcompare (a [i]^, x^) = less do i := i + 1;
+ while pathcompare (x^, a [j]^) = less do j := j - 1;
+ if i <= j then begin
+ w := a [i]; a [i] := a [j]; a [j] := w;
+ i := i + 1; j := j - 1
+ end
+ until i > j;
+ if l < j then quicksort (l, j);
+ if i < r then quicksort (i, r)
+ end;
+begin
+ quicksort (1, MoreSubrscount)
+end;
+*)
+procedure sortMoreSubrs;
+begin
+end;
+
+type SubPathtree = ^SubPathrec;
+ SubPathrec = record SB: SubPathpointer;
+ left, right: SubPathtree
+ end;
+
+var MoreSubrs: SubPathtree;
+
+
+procedure disposeSubPath (SP: SubPathpointer);
+var i: integer;
+begin
+ for i := 1 to SP^.pathlen do begin
+ if SP^.commands.cp0^[i]^.Subr <> nil
+ then disposeSubPath (SP^.commands.cp0^[i]^.Subr);
+ dispose (SP^.commands.cp0^[i])
+ end;
+ dispose (SP)
+end;
+
+function insertSubPath (var SBp: SubPathtree; SP: SubPathpointer): SubPathpointer;
+begin
+ if SBp = nil then begin
+ new (SBp); SBp^.left := nil; SBp^.right := nil;
+ SBp^.SB := SP; MoreSubrscount := MoreSubrscount + 1;
+ insertSubPath := SP
+ end else if pathcompare (SP^, SBp^.SB^) = equal then begin
+ SBp^.SB^.used := SBp^.SB^.used + 1;
+ disposeSubPath (SP);
+ insertSubPath := SBp^.SB
+ end else if pathcompare (SP^, SBp^.SB^) = less then
+ insertSubPath := insertSubPath (SBp^.left, SP)
+ else insertSubPath := insertSubPath (SBp^.right, SP)
+end;
+
+type PathProc = procedure (sp: SubPathpointer; var out: text);
+ (* The second parameter and its dummy setting at several places
+ of one of the two application cases below is due to the
+ silly restriction of Turbo-Pascal which doesn't allow nested
+ procedures to be passed as parameters as standard Pascal does. *)
+procedure applyMoreSubrs (PP: PathProc; var out: text);
+ procedure apply (SBp: SubPathtree);
+ begin
+ if SBp <> nil then begin
+ apply (SBp^.left);
+ PP (SBp^.SB, out);
+ apply (SBp^.right)
+ end
+ end;
+begin
+ apply (MoreSubrs)
+end;
+
+const maxused = 50;
+var usedStat: array [0..maxused] of integer;
+ zeromoves: integer;
+
+procedure Pindex (sp: SubPathpointer; (*dummy*) var out: text); far;
+begin if (sp^.used > 1) and (sp^.index < 0) then begin
+ sp^.setindex (Subrstotal);
+ Subrstotal := Subrstotal + 1;
+ end;
+ if sp^.used > maxused then
+ usedStat [0] := usedStat [0] + 1
+ else usedStat [sp^.used] := usedStat [sp^.used] + 1
+end;
+procedure arrangeMoreSubrs (Subrscount: integer);
+begin Subrstotal := Subrscount;
+ applyMoreSubrs (Pindex, (*dummy*) output)
+end;
+
+procedure Pprint (sp: SubPathpointer; var out: text); far;
+begin if sp^.used > 1 then
+ sp^.printSubr (out)
+end;
+procedure printMoreSubrs (var out: text);
+begin applyMoreSubrs (Pprint, out)
+end;
+
+procedure printusedStat;
+var i: integer;
+begin
+ writeln ('extracted Subrs use statistics:');
+ writeln ('# used # Subrs');
+ for i := 1 to maxused do
+ if usedStat [i] > 0 then
+ writeln (i: 6, usedStat [i]: 6);
+ if usedStat [0] > 0 then
+ writeln (' more:', usedStat [0]: 6);
+ if zeromoves > 0 then
+ writeln (' inserted ', zeromoves, ' zero move commands for ATM''s sake');
+end;
+
+(************************************************************************)
+
+function cmdstr (cmd: t1cmd): string;
+begin cmdstr := cmdstring [cmd] end;
+
+function strcmd (var (* for some efficiency *) s: string): t1cmd;
+var l, r, i: integer;
+ cs: string;
+begin l := 1; r := cmdcount;
+ repeat
+ i := (l + r) div 2;
+ cs := cmdtab [i].str;
+ if s < cs then r := i - 1
+ else if s > cs then l := i + 1
+ else l := r + 1
+ until l > r;
+ if s = cs then strcmd := cmdtab [i].cmd
+ else begin
+ writeln ('% WARNING: unknown command "', s, '" detected');
+ strcmd := endchar
+ end
+end;
+
+procedure setNPND (var def: string; s: string);
+begin if def = '' then def := s
+ else if s <> ''
+ then if def <> s then writeln ('% WARNING: NP/ND command names differ')
+end;
+
+
+procedure printoffset (var out: text; x, y: integer);
+begin
+ if x <> 0 then
+ if y <> 0 then writeln (out, ' ', x, ' ', y, ' rmoveto')
+ else writeln (out, ' ', x, ' hmoveto')
+ else if y <> 0 then writeln (out, ' ', y, ' vmoveto')
+ else begin (* atm (1.15) bug: also write zero move command *)
+ zeromoves := zeromoves + 1;
+ writeln (out, ' 0 hmoveto')
+ end
+end;
+
+(************************************************************************)
+
+var commandactive: Boolean;
+
+constructor Path.ini;
+begin pathlen := 0;
+ commandactive := false;
+ mayuseothersubrs := true;
+ new (commands.cp0)
+end;
+
+function Path.usesothersubrs: Boolean;
+var i: integer;
+ othersfound: Boolean;
+ icmd: t1cmd;
+ sub: ^SubrT;
+begin
+ if not mayuseothersubrs then usesothersubrs := false
+ else begin
+ i := 1;
+ othersfound := false;
+ while (i <= pathlen) and not othersfound do begin
+ icmd := pathcmd (i);
+ if icmd = callothersubr then othersfound := true
+ else if icmd = callsubr then with commands.cp0^[i]^ do begin
+ if Subr = nil
+ then if paramnum = 0
+ then sub := nil (* something like pop callsubr *)
+ else sub := getSubr (param [paramnum])
+ else sub := Subr;
+ if sub <> nil then othersfound := sub^.usesothersubrs;
+ end;
+ i := i + 1;
+ end;
+ if not othersfound then mayuseothersubrs := false;
+ usesothersubrs := othersfound
+ end
+end;
+
+procedure Path.appendtoken (var (* for some efficiency *) s: string);
+var i, c: integer;
+begin if not commandactive then begin
+ if pathlen < maxpathlen then begin
+ pathlen := pathlen + 1;
+ new (commands.cp0^[pathlen]);
+ commands.cp0^[pathlen]^.paramnum := 0;
+ commands.cp0^[pathlen]^.Subr := nil;
+ end else begin
+ writeln ('ERROR: max. path length exceeded');
+ halt
+ end
+ end;
+ val (s, i, c);
+ if c = 0 then with commands.cp0^[pathlen]^ do begin
+ paramnum := paramnum + 1;
+ param [paramnum] := i;
+ commandactive := true
+ end else begin
+ commands.cp0^[pathlen]^.cmd := strcmd (s);
+ commandactive := false
+ end
+end;
+
+procedure Path.clippath;
+(* shortens path storage according to current pathlen *)
+var longpath: varcommandspoi;
+ i: integer;
+begin
+ longpath := commands;
+ case (pathlen - 1) div pathlenunit + 1 of
+ 1: new (commands.cp1);
+ 2: new (commands.cp2);
+ 3: new (commands.cp3);
+ 4: new (commands.cp4);
+ 5: new (commands.cp5);
+ 6: new (commands.cp6);
+ 7: new (commands.cp7);
+ 8: new (commands.cp8);
+ 9: new (commands.cp9);
+ else new (commands.cp0);
+ end;
+ for i := 1 to pathlen do commands.cp0^[i] := longpath.cp0^[i];
+ dispose (longpath.cp0)
+end;
+
+procedure Path.appendcommand (cmd: commandpoi);
+begin if pathlen < maxpathlen then begin
+ pathlen := pathlen + 1;
+ new (commands.cp0^[pathlen]);
+ commands.cp0^[pathlen]^ := cmd ^;
+ end else begin
+ writeln ('ERROR: max. path length exceeded');
+ halt
+ end
+end;
+
+procedure Path.delete (i: integer);
+var k: integer;
+begin
+ pathlen := pathlen - 1;
+ dispose (commands.cp0^[i]);
+ for k := i to pathlen do commands.cp0^[k] := commands.cp0^[k + 1]
+end;
+
+procedure Path.cleanup;
+var i, k: integer;
+ prevcmd: t1cmd;
+ x, y: integer;
+begin
+ i := 1;
+ while i <= pathlen do begin
+ if i = 1 then prevcmd := pop (* dummy, just not a moveto *)
+ else prevcmd := commands.cp0^[i - 1]^.cmd;
+ case commands.cp0^[i]^.cmd of
+ closepath: if prevcmd in [closepath, endchar, hmoveto, hsbw,
+ return, rmoveto, sbw, vmoveto]
+ then delete (i)
+ else i := i + 1;
+ hmoveto, rmoveto, vmoveto:
+ if prevcmd in [hmoveto, rmoveto, vmoveto] then begin
+ x := 0; y := 0;
+ for k := i - 1 to i do with commands.cp0^[k]^ do
+ case cmd of
+ hmoveto: x := x + param [1];
+ vmoveto: y := y + param [1];
+ rmoveto: begin x := x + param [1];
+ y := y + param [2]
+ end
+ end;
+ delete (i);
+ i := i - 1;
+ with commands.cp0^[i]^ do begin
+ cmd := rmoveto;
+ param [1] := x;
+ param [2] := y;
+ paramnum := 2;
+ end
+ end else with commands.cp0^[i]^ do begin
+ (* if (param [1] = 0) and
+ (* ((cmd <> rmoveto) or (param [2] = 0))
+ (* then delete (i)
+ (* don't delete (i): atm (1.15) has a bug
+ (* else *)
+ if (cmd = rmoveto) and (param [2] = 0)
+ then begin
+ cmd := hmoveto;
+ paramnum := 1;
+ end else
+ if (cmd = rmoveto) and (param [1] = 0)
+ then begin
+ cmd := vmoveto;
+ param [1] := param [2];
+ paramnum := 1;
+ end else
+ if (cmd = vmoveto) and (param [1] = 0)
+ then begin
+ cmd := hmoveto;
+ end else
+ i := i + 1
+ end;
+ rlineto: with commands.cp0^[i]^ do begin
+ if param [1] = 0 (* 0 y rlineto *)
+ then begin
+ cmd := vlineto;
+ param [1] := param [2];
+ paramnum := 1;
+ end else if param [2] = 0 (* x 0 rlineto *)
+ then begin
+ cmd := hlineto;
+ paramnum := 1;
+ end;
+ i := i + 1
+ end;
+ rrcurveto: with commands.cp0^[i]^ do begin
+ if (param [1] = 0) and (param [6] = 0)
+ then begin
+ cmd := vhcurveto;
+ for k := 1 to 4 do
+ param [k] := param [k + 1];
+ paramnum := 4;
+ end
+ else if (param [2] = 0) and (param [5] = 0)
+ then begin
+ cmd := hvcurveto;
+ param [2] := param [3];
+ param [3] := param [4];
+ param [4] := param [6];
+ paramnum := 4;
+ end;
+ i := i + 1
+ end;
+ else i := i + 1
+ end
+ end
+end;
+
+const hintcmds = [hstem, hstem3, vstem, vstem3, dotsection];
+ movecmds = [hmoveto, rmoveto, vmoveto];
+ drawcmds = [hlineto, hvcurveto, rlineto,
+ rrcurveto, vhcurveto, vlineto];
+ curvecmds = [hvcurveto, rrcurveto, vhcurveto];
+
+function Path.pathcmd (i: integer): t1cmd;
+begin
+ if (i > pathlen) or (i < 1) then pathcmd := pop
+ else if commands.cp0^[i]^.Subr = nil then pathcmd := commands.cp0^[i]^.cmd
+ else pathcmd := callsubr
+end;
+
+function Path.pathcomponent (i: integer): commandpoi;
+begin
+ if (i > pathlen) or (i < 1) then pathcomponent := nil
+ else pathcomponent := commands.cp0^[i]
+end;
+
+procedure Path.getoffset (i: integer; var x, y: integer);
+begin
+ if pathcmd (i) in movecmds then with commands.cp0^[i]^ do begin
+ case cmd of
+ hmoveto: begin x := param [1]; y := 0 end;
+ vmoveto: begin y := param [1]; x := 0 end;
+ rmoveto: begin x := param [1]; y := param [2] end;
+ end
+ end else begin
+ x := 0; y := 0
+ end
+end;
+
+procedure Path.splitpath;
+var i, pathstart, k: integer;
+ newSubr: ^SubPath;
+ x, y: integer;
+
+begin
+ i := 1;
+ while i <= pathlen do begin
+ while (i <= pathlen) and
+ not (pathcmd (i) in drawcmds + hintcmds) do
+ i := i + 1;
+ if i <= pathlen then begin
+ pathstart := i;
+ (* heuristics which sorts of command groups to build: *)
+ if pathcmd (pathstart) in hintcmds then
+ repeat i := i + 1 until not (pathcmd (i) in hintcmds)
+ else begin (* pathcmd (pathstart) in drawcmds *)
+ repeat i := i + 1 until not (pathcmd (i) in drawcmds);
+ (* if pathcmd (i) = closepath then i := i + 1; *)
+ end;
+ if (i - pathstart > 1) or
+ (pathcmd (pathstart) in curvecmds) then begin
+ new (newSubr, ini);
+ newSubr^.used := 1;
+ newSubr^.index := -1;
+ newSubr^.pathlen := i - pathstart;
+ newSubr^.clippath;
+ for k := 1 to newSubr^.pathlen do
+ newSubr^.commands.cp0^[k] := commands.cp0^[pathstart+k-1];
+ pathlen := pathlen - i + pathstart + 1;
+ for k := pathstart + 1 to pathlen do begin
+ commands.cp0^[k] := commands.cp0^[k - pathstart - 1 + i];
+ (* don't dispose them - they are still needed in the Subr *)
+ end;
+ new (commands.cp0^[pathstart]);
+ newSubr := insertSubPath (MoreSubrs, newSubr);
+ (* to replace newSubr by unique one on second use *)
+ commands.cp0^[pathstart]^.Subr := newSubr;
+ getoffset (pathstart - 1, x, y);
+ commands.cp0^[pathstart]^.offsetx := x;
+ commands.cp0^[pathstart]^.offsety := y;
+ if pathcmd (pathstart + 1) = closepath then begin
+ newSubr^.checkunique (x, y, true);
+ delete (pathstart + 1);
+ commands.cp0^[pathstart]^.closed := true
+ end else begin
+ newSubr^.checkunique (x, y, false);
+ commands.cp0^[pathstart]^.closed := false
+ end;
+ if pathcmd (pathstart - 1) in movecmds then begin
+ pathstart := pathstart - 1;
+ delete (pathstart)
+ end;
+ i := pathstart + 1;
+ end
+ end
+ end
+end;
+
+function Path.firstorlastcmd (i: integer; last: Boolean): t1cmd;
+var cmd: t1cmd;
+ sub: ^SubrT;
+begin
+ cmd := pathcmd (i);
+ if cmd = callsubr then with commands.cp0^[i]^ do begin
+ if Subr = nil
+ then if paramnum <> 1
+ then sub := nil (* something like pop callsubr
+ or n m callsubr *)
+ else sub := getSubr (param [paramnum])
+ else sub := Subr;
+ if sub = nil
+ then firstorlastcmd := rmoveto (* pretend it's alright *)
+ else if last
+ then if sub^.pathcmd (sub^.pathlen) = return
+ then firstorlastcmd := (* last of original Subr *)
+ sub^.firstorlastcmd (sub^.pathlen - 1, true)
+ else firstorlastcmd := (* last of extracted Subr *)
+ sub^.firstorlastcmd (sub^.pathlen, true)
+ else firstorlastcmd := sub^.firstorlastcmd (1, false)
+ end else firstorlastcmd := cmd
+end;
+
+procedure Path.printpath (var out: text; checkzmove, printreturn: Boolean);
+const nozeromovecmds = drawcmds + movecmds
+ + [setcurrentpoint, callothersubr, dotsection];
+var i, k: integer;
+begin for i := 1 to pathlen - ord (not printreturn) do
+ with commands.cp0^[i]^ do begin
+ if Subr = nil then begin
+ if expand and (cmd = callsubr)
+ and (paramnum >= 1) and (param [paramnum] >= 4) then begin
+ if paramnum > 1 then begin
+ write (out, ' ');
+ for k := 1 to paramnum - 1 do begin
+ write (out, param [k], ' ');
+ end;
+ end;
+ getSubr (param [paramnum])^.printpath (out, false, false)
+ end else begin
+ if checkzmove then
+ if firstorlastcmd (i, false) in drawcmds
+ then if not (firstorlastcmd (i - 1, true) in nozeromovecmds)
+ then printoffset (out, 0, 0);
+ write (out, ' ');
+ for k := 1 to paramnum do begin
+ write (out, param [k], ' ');
+ end;
+ writeln (out, cmdstr (cmd));
+ end
+ end else if (Subr^.used > 1) and not expand then begin
+ if (not Subr^.offsetunique)
+ or ((Subr^.offsetx = 0) and (Subr^.offsety = 0)) then
+ if Subr^.pathcmd (1) in drawcmds then
+ if (offsetx <> 0) or (offsety <> 0)
+ or not (firstorlastcmd (i - 1, true) in nozeromovecmds)
+ then printoffset (out, offsetx, offsety);
+ writeln (out, ' ', Subr^.index, ' callsubr');
+ if closed and not Subr^.closedunique then writeln (out, ' closepath');
+ end else begin
+ if Subr^.pathcmd (1) in drawcmds then
+ if (offsetx <> 0) or (offsety <> 0)
+ or not (firstorlastcmd (i - 1, true) in nozeromovecmds)
+ then printoffset (out, offsetx, offsety);
+ Subr^.printpath (out, false, true);
+ if closed then writeln (out, ' closepath');
+ end
+ end
+end;
+
+function CharStrT.clearifempty: Boolean;
+(* clippath must not have been called! *)
+var i: integer;
+ isempty: Boolean;
+begin isempty := true;
+ i := 1;
+ while (i <= pathlen) and isempty do begin
+ if pathcmd (i) in drawcmds + [callsubr, callothersubr, seac]
+ then isempty := false;
+ i := i + 1;
+ end;
+ if isempty then
+ if (name = '/.notdef') or (pos ('space', name) > 0) or (pos ('blank', name) > 0)
+ then isempty := false
+ else begin
+ for i := 1 to pathlen do dispose (commands.cp0^[i]);
+ dispose (commands.cp0);
+ end;
+ clearifempty := isempty
+end;
+
+procedure CharStrT.setname (n: string);
+begin name := n end;
+
+procedure CharStrT.print (var out: text);
+begin
+ write (out, name, ' {');
+ printpath (out, true, true);
+ writeln (out, ' } ', ND)
+end;
+
+procedure CharStrT.setdef (s: string);
+begin setNPND (ND, s); clippath end;
+
+procedure SubrT.setindex (i: integer);
+begin index := i end;
+
+procedure SubrT.print (var out: text);
+begin
+ write (out, 'dup ', index, ' {');
+ printpath (out, false, true);
+ writeln (out, ' } ', NP)
+end;
+
+procedure Path.setdef (s: string);
+begin clippath end;
+
+procedure SubPath.checkunique (x, y: integer; cl: Boolean);
+begin
+ if used <= 1 then begin
+ offsetx := x; offsety := y; offsetunique := true;
+ closed := cl; closedunique := true
+ end else begin
+ if (x <> offsetx) or (y <> offsety) then offsetunique := false;
+ if cl <> closed then closedunique := false
+ end
+end;
+
+procedure SubPath.setdef (s: string);
+begin clippath end;
+
+procedure SubPath.printSubr (var out: text);
+begin
+ write (out, 'dup ', index, ' {');
+ if offsetunique then
+ if pathcmd (1) in drawcmds then
+ if (offsetx <> 0) or (offsety <> 0) then
+ printoffset (out, offsetx, offsety);
+ printpath (out, false, true);
+ if closedunique and closed then writeln (out, ' closepath');
+ writeln (out, ' return');
+ writeln (out, ' } ', NP)
+end;
+
+procedure SubrT.setdef (s: string);
+begin setNPND (NP, s); clippath end;
+
+(************************************************************************)
+
+function newafmcode (name: string): integer;
+begin
+ if stdenc then newafmcode := getSEcode (name)
+ else newafmcode := -1
+end;
+
+procedure CharStrT.copyhalf (var newc: CharStrT; newname: string);
+(* This is a heuristic attempt to generate single-part characters from
+ double-part ones, especially quote marks. It was designed for wfnboss
+ generated fonts which lack some single quote marks.
+ The proceudre assumes that the path of the character to be split contains
+ exactly 2 move commands! *)
+var i, m1, m2, x1, x2, y1, y2, widthsub: integer;
+ C, WX, lx, ly, rx, ry: integer;
+begin
+ newc.setname (newname);
+ i := 1;
+ while (i <= pathlen) and not (pathcmd (i) in movecmds) do i := i + 1;
+ m1 := i;
+ repeat i := i + 1 until (i > pathlen) or (pathcmd (i) in movecmds);
+ if i > pathlen then i := pathlen;
+ m2 := i;
+ getoffset (m1, x1, y1);
+ getoffset (m2, x2, y2);
+ for i := 1 to m2 - 1 do newc.appendcommand (commands.cp0^[i]);
+ newc.appendcommand (commands.cp0^[pathlen]);
+ newc.clippath;
+ if x2 < 0 then begin
+ (* first part of path was right part; shift it left *)
+ with newc.commands.cp0^[m1]^ do begin
+ cmd := rmoveto; (* might have been hmoveto or vmoveto *)
+ paramnum := 2;
+ param [1] := x1 + x2;
+ param [2] := y1;
+ end;
+ widthsub := - x2;
+ end else begin
+ widthsub := x2;
+ end;
+ with newc.commands.cp0^[1]^ do (* reduce wx *)
+ case cmd of
+ hsbw: param [2] := param [2] - widthsub;
+ sbw: param [3] := param [3] - widthsub;
+ end;
+ newc.cleanup;
+ if afmopen then begin
+ getafmchar (C, WX, name, lx, ly, rx, ry);
+ putafmchar (newafmcode (newname), WX - widthsub, newc.name, lx, ly, rx - widthsub, ry);
+ end
+end;
+
+procedure CharStrT.downpath (var newc: CharStrT; newname: string);
+(* This is a heuristic attempt to generate base line quote marks from
+ upper quote marks *)
+var i, m, x, y, heightsub: integer;
+ C, WX, lx, ly, rx, ry: integer;
+begin
+ newc.setname (newname);
+ i := 1;
+ while (i <= pathlen) and not (pathcmd (i) in movecmds) do i := i + 1;
+ m := i;
+ getoffset (m, x, y);
+ heightsub := y; (* This might be more sophisticated *)
+ for i := 1 to pathlen do newc.appendcommand (commands.cp0^[i]);
+ newc.clippath;
+ for i := 1 to m do
+ with newc.commands.cp0^[i]^ do
+ case cmd of
+ hmoveto: (* would only have to be handled
+ if we could derive non-zero down-shift
+ values from this *);
+ vmoveto: param [1] := param [1] - heightsub;
+ rmoveto: param [2] := param [2] - heightsub;
+ hstem: param [1] := param [1] - heightsub;
+ hstem3: begin
+ param [1] := param [1] - heightsub;
+ param [3] := param [3] - heightsub;
+ param [5] := param [5] - heightsub;
+ end
+ else ;
+ end;
+ newc.cleanup;
+ if afmopen then begin
+ getafmchar (C, WX, name, lx, ly, rx, ry);
+ putafmchar (newafmcode (newname), WX, newc.name, lx, ly - heightsub, rx, ry - heightsub);
+ end
+end;
+
+procedure CharStrT.copypath (var newc: CharStrT; newname: string);
+var i, C, WX, lx, ly, rx, ry: integer;
+begin
+ newc.setname (newname);
+ for i := 1 to pathlen do newc.appendcommand (commands.cp0^[i]);
+ newc.clippath;
+ newc.cleanup;
+ if afmopen then begin
+ getafmchar (C, WX, name, lx, ly, rx, ry);
+ putafmchar (newafmcode (newname), WX, newc.name, lx, ly, rx, ry);
+ end
+end;
+
+procedure CharStrT.compose (CS1, CS2: CharStrpointer; cc1, cc2, dx, dy: integer);
+var seaccmd: commandpoi;
+ WX, WX1, WX2, sbx1, sby1, sbx2, sby2: integer;
+ C, llx1, lly1, urx1, ury1, llx2, lly2, urx2, ury2: integer;
+
+ procedure getsb (CS: CharStrpointer; var sbx, sby: integer);
+ begin
+ sbx := CS^.pathcomponent (1)^.param [1];
+ if CS^.pathcmd (1) = sbw
+ then sby := CS^.pathcomponent (1)^.param [2]
+ else sby := 0
+ end;
+
+ function getwidth (CS: CharStrpointer): integer;
+ begin
+ with CS^.pathcomponent (1)^ do case cmd of
+ hsbw: getwidth := param [2];
+ sbw: getwidth := param [3];
+ else getwidth := 0
+ end
+ end;
+
+begin
+ appendcommand (CS1^.pathcomponent (1));
+ WX1 := getwidth (CS1);
+ WX := WX1;
+ if length (CS2^.name) = 2 then begin
+ (* a letter appended to another *)
+ WX2 := getwidth (CS2) + dx;
+ if WX2 > WX1 then with pathcomponent (1)^ do begin
+ WX := WX2;
+ case cmd of
+ hsbw: param [2] := WX;
+ sbw: param [3] := WX;
+ end
+ end
+ end;
+ new (seaccmd);
+ getsb (CS1, sbx1, sby1);
+ getsb (CS2, sbx2, sby2);
+ with seaccmd^ do begin
+ Subr := nil;
+ cmd := seac;
+ paramnum := 5;
+ param [4] := cc1;
+ param [5] := cc2;
+ param [1] := sbx2;
+ param [2] := dx + sbx2 - sbx1;
+ param [3] := dy + sby2 - sby1;
+ end;
+ appendcommand (seaccmd);
+ clippath;
+ if afmopen then begin
+ getafmchar (C, WX1, CS1^.name, llx1, lly1, urx1, ury1);
+ getafmchar (C, WX2, CS2^.name, llx2, lly2, urx2, ury2);
+ if llx2 + dx < llx1 then llx1 := llx2 + dx;
+ if lly2 + dy < lly1 then lly1 := lly2 + dy;
+ if urx2 + dx > urx1 then urx1 := urx2 + dx;
+ if ury2 + dy > ury1 then ury1 := ury2 + dy;
+ putafmchar (newafmcode (name), WX, name, llx1, lly1, urx1, ury1);
+ end
+end;
+
+procedure swappaths (var c1, c2: CharStrT);
+(* to fix wfnboss's exchange of bullet and periodcentered descriptions *)
+var name: string; wx, wx1, wx2: integer;
+begin
+ name := c1.name;
+ c1.name := c2.name;
+ c2.name := name;
+ if c1.commands.cp0^[1]^.cmd = hsbw then wx1 := 2 else wx1 := 3;
+ if c2.commands.cp0^[1]^.cmd = hsbw then wx2 := 2 else wx2 := 3;
+ wx := c1.commands.cp0^[1]^.param [wx1];
+ c1.commands.cp0^[1]^.param [wx1] := c2.commands.cp0^[1]^.param [wx2];
+ c2.commands.cp0^[1]^.param [wx2] := wx;
+ (* the case that only one path has an sbw command
+ is not handled completely correct *)
+ wx := c1.commands.cp0^[1]^.param [wx1 + 1];
+ c1.commands.cp0^[1]^.param [wx1 + 1] := c2.commands.cp0^[1]^.param [wx2 + 1];
+ c2.commands.cp0^[1]^.param [wx2 + 1] := wx;
+end;
+
+(************************************************************************)
+
+procedure Path.traceBBox (var x, y, llx, lly, urx, ury: integer; var errcmd: t1cmd);
+var i: integer;
+ x1, y1: integer;
+ procedure newpoint (newx, newy: integer);
+ begin
+ x := newx;
+ y := newy;
+ if x < llx then llx := x
+ else if x > urx then urx := x;
+ if y < lly then lly := y
+ else if y > ury then ury := y;
+ end;
+begin
+ i := 1;
+ while (i <= pathlen) do with pathcomponent (i) ^ do begin
+ if Subr <> nil then Subr^.traceBBox (x, y, llx, lly, urx, ury, errcmd)
+ else
+ case cmd of
+ callothersubr: errcmd := callothersubr;
+ callsubr: getSubr (param [paramnum])^.traceBBox (x, y, llx, lly, urx, ury, errcmd);
+ t1div: errcmd := t1div;
+ closepath, return, endchar, pop: ;
+ dotsection, hstem, hstem3, vstem, vstem3: ;
+ hsbw: x := param [1];
+ sbw: begin x := param [1]; y := param [2] end;
+ seac: begin x1 := x; y1 := y; (* save current sidebearing point *)
+ getCharString (StandardEncoding [param [4]])^.
+ traceBBox (x, y, llx, lly, urx, ury, errcmd);
+ x := x1 + param [2] - param [1];
+ y := y1 + param [3] (* - sby (accent), hopefully 0 *);
+ getCharString (StandardEncoding [param [5]])^.
+ traceBBox (x, y, llx, lly, urx, ury, errcmd)
+ end;
+ hlineto: newpoint (x + param [1], y);
+ hmoveto: newpoint (x + param [1], y);
+ rlineto: newpoint (x + param [1], y + param [2]);
+ rmoveto: newpoint (x + param [1], y + param [2]);
+ vlineto: newpoint (x, y + param [2]);
+ vmoveto: newpoint (x, y + param [2]);
+ (* with the curves, hope for horizontal and vertical tangents: *)
+ hvcurveto: newpoint (x + param [1] + param [2],
+ y + param [3] + param [4]);
+ rrcurveto: newpoint (x + param [1] + param [3] + param [5],
+ y + param [2] + param [4] + param [6]);
+ vhcurveto: newpoint (x + param [2] + param [4],
+ y + param [1] + param [3]);
+ setcurrentpoint: if paramnum = 2 then begin
+ x := param [1]; y := param [2]
+ end
+ else errcmd := setcurrentpoint;
+ end;
+ i := i + 1
+ end
+end;
+
+procedure CharStrT.checkafm (checkBBox: Boolean);
+(* Check afm entries for correct width and (optionally)
+ bounding box information. The latter procedure seems to be
+ currently a great rubbish. *)
+var C, WX, llx, lly, urx, ury,
+ oldWX, oldllx, oldlly, oldurx, oldury: integer;
+ x, y: integer;
+ errcmd: t1cmd;
+ putit: Boolean;
+begin
+ if name <> '/.notdef' then begin
+ if pathcmd (1) = hsbw
+ then WX := pathcomponent (1)^.param [2]
+ else if pathcmd (1) = sbw
+ then WX := pathcomponent (1)^.param [3]
+ else begin
+ writeln ('% path error: first command not hsbw or sbw in character ', name);
+ WX := 0;
+ end;
+ getafmchar (C, oldWX, name, oldllx, oldlly, oldurx, oldury);
+ putit := false;
+
+ if C = -2 then begin
+ writeln ('% afm error: missing entry for character ', name);
+ putit := true;
+ C := newafmcode (name);
+ end
+ else if oldWX <> WX then begin
+ writeln ('% afm error: wrong width for character ', name);
+ putit := true;
+ end;
+
+ if checkBBox then begin
+ llx := maxint;
+ urx := - maxint;
+ lly := maxint;
+ ury := - maxint;
+ x := 0;
+ y := 0;
+ errcmd := return;
+ traceBBox (x, y, llx, lly, urx, ury, errcmd);
+ if errcmd <> return then begin
+ writeln ('% tracing BBox of ', name, ': cannot handle ', cmdstr (errcmd));
+ llx := oldllx; lly := oldlly; urx := oldurx; ury := oldury;
+ end
+ else if C = -2 then putit := true
+ else if abs (llx - oldllx) + abs (lly - oldlly)
+ + abs (urx - oldurx) + abs (ury - oldury) < 30
+ then begin (* keep old values *)
+ llx := oldllx; lly := oldlly; urx := oldurx; ury := oldury;
+ end
+ else begin
+ putit := true;
+ writeln ('% adjusting afm BBox information for ', name);
+ end;
+ end
+ else begin
+ llx := oldllx; lly := oldlly; urx := oldurx; ury := oldury;
+ end;
+
+ if putit then putafmchar (C, WX, name, llx, lly, urx, ury);
+ end
+end;
+
+(************************************************************************)
+
+var i: integer;
+begin
+ for i := 1 to cmdcount do with cmdtab [i] do
+ cmdstring [cmd] := str;
+ NP := ''; ND := '';
+ MoreSubrscount := 0;
+ MoreSubrs := nil;
+ for i := 0 to maxused do usedStat [i] := 0;
+ zeromoves := 0;
+end.
diff --git a/fonts/utilities/t1tools/t1tidy/strtype.pas b/fonts/utilities/t1tools/t1tidy/strtype.pas
new file mode 100644
index 0000000000..8ecf3d61ea
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/strtype.pas
@@ -0,0 +1,196 @@
+unit strtype;
+
+interface
+
+type strec = object
+ function isblank (c: char): Boolean;
+ function isdigit (c: char): Boolean;
+ function isletter (c: char): Boolean;
+ function isname (c: char): Boolean;
+ function hasat (i: integer; s1: string): Boolean;
+ function posof (s1: string): integer;
+ procedure replace (j, k: integer; s1: string);
+ function hasprefix (s1: string): Boolean;
+ function empty: Boolean;
+ function str: string;
+ procedure ini (s1: string);
+ (* token functions: *)
+ procedure resetposition;
+ function nexttoken: string;
+ function lasttoken: string;
+ function firsttoken: string;
+ function nthtoken (n: integer): string;
+ function lookuptoken (s1: string): Boolean;
+ function findtoken (s1: string): Boolean;
+ procedure gotonexttoken;
+ procedure replacelasttoken (s1: string);
+ private
+ s: string;
+ len: integer;
+ position: integer (* current scan position *);
+ startpos: integer (* start of last retrieved token *);
+ function cc: char;
+ end;
+
+implementation
+
+function strec.isblank (c: char): Boolean;
+begin isblank := (c = ' ') or (c = ' ')
+end;
+
+function strec.isdigit (c: char): Boolean;
+begin isdigit := (c >= '0') and (c <= '9')
+end;
+
+function strec.isletter (c: char): Boolean;
+begin isletter := ((c >= 'A') and (c <= 'Z')) or ((c >= 'a') and (c <= 'z'))
+end;
+
+function strec.isname (c: char): Boolean;
+begin (*
+ isname := not isblank (c) and
+ (c <> '(') and (c <> ')') and (c <> '<') and (c <> '>') and
+ (c <> '[') and (c <> ']') and (c <> '{') and (c <> '}') and
+ (c <> '/') and (c <> '%')
+ *)
+ isname := not (c in [' ', ' ', '(', ')', '<', '>', '[', ']', '{', '}', '/', '%'])
+end;
+
+function strec.cc: char;
+begin if position > len
+ then cc := ' '
+ else cc := s [position]
+end;
+
+function strec.hasat (i: integer; s1: string): Boolean;
+begin hasat := pos (s1, s) = i end;
+
+function strec.posof (s1: string): integer;
+begin posof := pos (s1, s) end;
+
+procedure strec.replace (j, k: integer; s1: string);
+begin delete (s, j, k - j + 1);
+ insert (s1, s, j)
+end;
+
+function strec.hasprefix (s1: string): Boolean;
+begin hasprefix := pos (s1, s) = 1 end;
+
+function strec.empty: Boolean;
+begin empty := s = '' end;
+
+function strec.str: string;
+begin str := s end;
+
+procedure strec.ini (s1: string);
+begin s := s1; position := 0; len := length (s) end;
+
+procedure strec.resetposition;
+begin position := 0 end;
+
+function strec.nexttoken: string;
+const specialchars = [' ', ' ', '(', ')', '<', '>', '[', ']', '{', '}', '/', '%'];
+var level: integer;
+ quote: Boolean;
+ nexttok: string;
+begin
+ if position = 0 then position := position + 1;
+ while (position <= len) and isblank (s [position])
+ do position := position + 1;
+ startpos := position;
+ if startpos > len
+ then nexttok := ''
+ else begin
+ if (cc = '/') or not (cc in specialchars)
+ then begin (* scan name or number *)
+ if cc = '/'
+ then begin
+ position := position + 1;
+ (* ignore the special cases /[ and /] *)
+ if cc = '/' then position := position + 1;
+ end;
+ while not (cc in specialchars) do position := position + 1
+ end else if cc = '='
+ then begin (* scan special symbol *)
+ position := position + 1;
+ if cc = '=' then position := position + 1
+ end else if cc = '<'
+ then begin (* scan hex string *)
+ while (position <= len) and (cc <> '>')
+ do position := position + 1;
+ if position <= len
+ then position := position + 1
+ end else if cc = '('
+ then begin (* scan string *)
+ position := position + 1;
+ level := 1;
+ quote := false;
+ while (position <= len) and (level > 0) do begin
+ if not quote
+ then if cc = '\'
+ then quote := true
+ else begin
+ quote := false;
+ if cc = '('
+ then level := level + 1
+ else if cc = ')'
+ then level := level - 1
+ end;
+ position := position + 1
+ end
+ end else if cc = '%'
+ then (* scan comment *)
+ position := len + 1
+ else (* scan one-character symbol *)
+ position := position + 1;
+ nexttok := copy (s, startpos, position - startpos)
+ end;
+ (* writeln ('nexttoken: ¯', nexttok, '®'); *)
+ nexttoken := nexttok
+end;
+
+function strec.lasttoken: string;
+begin if startpos > len
+ then lasttoken := ''
+ else lasttoken := copy (s, startpos, position - startpos)
+end;
+
+function strec.firsttoken: string;
+begin position := 0;
+ firsttoken := nexttoken
+end;
+
+function strec.nthtoken (n: integer): string;
+var i: integer;
+ r: string;
+begin position := 0;
+ for i := 1 to n do r := nexttoken;
+ nthtoken := r
+end;
+
+function strec.lookuptoken (s1: string): Boolean;
+var t: string;
+ r: Boolean;
+begin r := false;
+ t := nexttoken;
+ while t <> '' do
+ if t = s1 then begin r := true; t := '' end
+ else t := nexttoken;
+ lookuptoken := r
+end;
+
+function strec.findtoken (s1: string): Boolean;
+begin position := 0;
+ findtoken := lookuptoken (s1)
+end;
+
+procedure strec.gotonexttoken;
+var t: string;
+begin t := nexttoken
+end;
+
+procedure strec.replacelasttoken (s1: string);
+begin replace (startpos, position - 1, s1)
+end;
+
+end.
diff --git a/fonts/utilities/t1tools/t1tidy/t1t.bat b/fonts/utilities/t1tools/t1tidy/t1t.bat
new file mode 100644
index 0000000000..af8c75caf5
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/t1t.bat
@@ -0,0 +1,48 @@
+@echo off
+set dumvar=
+rem Options: unfortunately, the stupid MSDOS command interpreter does not
+rem allow us to recognize if the first argument start with a '-', so we
+rem can only have a small number of specific option strings here.
+set option=
+:options
+if "%1"=="-g" goto option
+if "%1"=="-e" goto option
+if "%1"=="-ge" goto option
+if "%1"=="-eg" goto option
+if "%1"=="-s" goto option
+if "%1"=="+c" goto option
+if "%1"=="+x" goto option
+goto optok
+:option
+set option=%option% %1
+shift
+goto :options
+:optok
+echo options: %option%
+if exist %1.ps set genps=rem
+if "%2"=="" goto empty
+if exist %2\nul goto dir
+
+%genps% D:\fonts\progs\t1utils\t1disasm %1.pfb %1.ps
+D:\fonts\progs\t1tidy\t1tidy %option% %1.ps %2.ps
+D:\fonts\progs\t1utils\t1asm %2.ps %2.pfa
+D:\fonts\progs\t1utils\t1binary %2.pfa %2.pfb
+%genps% del %1.ps
+del %2.ps
+del %2.pfa
+goto end
+
+:dir
+%genps% D:\fonts\progs\t1utils\t1disasm %1.pfb %1.ps
+D:\fonts\progs\t1tidy\t1tidy %option% %1.ps %2
+D:\fonts\progs\t1utils\t1asm %2\%1.ps %2\%1.pfa
+D:\fonts\progs\t1utils\t1binary %2\%1.pfa %2\%1.pfb
+%genps% del %1.ps
+del %2\%1.ps
+del %2\%1.pfa
+goto end
+
+:empty
+echo No destination font file name given
+
+:end
diff --git a/fonts/utilities/t1tools/t1tidy/t1tidy.pas b/fonts/utilities/t1tools/t1tidy/t1tidy.pas
new file mode 100644
index 0000000000..a80ecb09e8
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tidy/t1tidy.pas
@@ -0,0 +1,531 @@
+program T1tidy;
+
+uses Dos, pathunit, strtype, afm, data;
+
+function makeint (s: string): integer;
+var i, c: integer;
+begin
+ val (s, i, c);
+ makeint := i
+end;
+
+function hex (c: char): integer;
+begin
+ if c < '0' then hex := 0
+ else if c <= '9' then hex := ord (c) - ord ('0')
+ else if upcase (c) < 'A' then hex := 0
+ else if upcase (c) <= 'F' then hex := ord (upcase (c)) - ord ('A') + 10
+ else hex := 0
+end;
+
+function intstr (i: longint): string;
+var s: string;
+begin
+ str (i, s);
+ intstr := s
+end;
+
+function basename (fn: string): string;
+begin
+ if pos ('.', fn) > 0 then
+ basename := copy (fn, 1, pos ('.', fn) - 1)
+ else basename := fn
+end;
+
+function isdir (fn: string): Boolean;
+var f: file;
+ a: word;
+begin
+ assign (f, fn);
+ GetFAttr (f, a);
+ isdir := (a and $10) <> 0
+end;
+
+(* main procedure: *)
+
+procedure tidy (var infile, out: text);
+
+const maxintermediatelines = 40;
+
+var line, Subrsline, CharStringsline: strec;
+ intermediatelines: array [1..maxintermediatelines] of string;
+ linesafterOtherSubrs, linesafterSubrs: integer;
+
+ blanklines: integer;
+ i: integer;
+
+(***************************************************************************)
+
+ function eofile: Boolean;
+ begin eofile := eof (infile) end;
+
+ procedure readline;
+ var s: string;
+ begin
+ readln (infile, s);
+ line.ini (s)
+ end;
+
+ function nexttoken: string;
+ var r: string;
+ begin
+ r := line.nexttoken;
+ while r = '' do begin
+ readline;
+ r := line.nexttoken
+ end;
+ nexttoken := r
+ end;
+
+ procedure readSubr;
+ var s: string;
+ index: integer;
+ begin
+ Subrscount := Subrscount + 1;
+ new (Subrs [Subrscount], ini);
+ with Subrs [Subrscount] ^ do begin
+ index := makeint (nexttoken);
+ (* writeln ('% reading Subr ', index); *)
+ setindex (index);
+ if nexttoken <> '{' then writeln ('% missing { in Subr');
+ s := nexttoken;
+ while s <> '}' (* and ... Fehlerabfang! *)
+ do begin
+ if s = '' then writeln ('% empty line detected in Subr');
+ appendtoken (s);
+ s := nexttoken;
+ end;
+ if s <> '}' then writeln ('% missing } in Subr');
+ s := nexttoken;
+ if s = 'noaccess' then s := s + ' ' + nexttoken;
+ setdef (s);
+ cleanup
+ end
+ end;
+
+ procedure readCharString;
+ var s: string;
+ begin
+ CharStringscount := CharStringscount + 1;
+ new (CharStrings [CharStringscount], ini);
+ with CharStrings [CharStringscount] ^ do begin
+ s := line.lasttoken;
+ if ttfix then
+ if (s [2] = 'G') and (length (s) = 4) then begin
+ i := hex (s [3]) * 16 + hex (s [4]);
+ if WinANSI [i] <> '/.notdef' then s := WinANSI [i]
+ end;
+ setname (s);
+ if nexttoken <> '{' then writeln ('% missing { in CharString');
+ s := nexttoken;
+ while s <> '}' (* and ... Fehlerabfang! *)
+ do begin
+ appendtoken (s);
+ s := nexttoken;
+ end;
+ if s <> '}' then writeln ('% missing } in CharString');
+ s := nexttoken;
+ if s = 'noaccess' then s := s + ' ' + nexttoken;
+ if clearifempty
+ then begin
+ dispose (CharStrings [CharStringscount]);
+ CharStringscount := CharStringscount - 1
+ end
+ else begin
+ setdef (s);
+ cleanup;
+ if not generate and split then splitpath
+ end
+ end
+ end;
+
+ procedure fixchars;
+
+ procedure halfchar (oldname, newname: string);
+ var CSold, CSnew: CharStrpointer;
+ begin
+ CSold := getCharString (oldname);
+ CSnew := getCharString (newname);
+ if (CSnew = nil) and (CSold <> nil) then begin
+ new (CSnew, ini);
+ CSold^.copyhalf (CSnew^, newname);
+ CharStringscount := CharStringscount + 1;
+ CharStrings [CharStringscount] := CSnew;
+ end
+ end;
+
+ procedure downchar (oldname, newname: string);
+ var CSold, CSnew: CharStrpointer;
+ begin
+ CSold := getCharString (oldname);
+ CSnew := getCharString (newname);
+ if (CSnew = nil) and (CSold <> nil) then begin
+ new (CSnew, ini);
+ CSold^.downpath (CSnew^, newname);
+ CharStringscount := CharStringscount + 1;
+ CharStrings [CharStringscount] := CSnew;
+ end
+ end;
+
+ procedure copychar (oldname, newname: string);
+ var CSold, CSnew: CharStrpointer;
+ begin
+ CSold := getCharString (oldname);
+ CSnew := getCharString (newname);
+ if (CSnew = nil) and (CSold <> nil) then begin
+ new (CSnew, ini);
+ CSold^.copypath (CSnew^, newname);
+ CharStringscount := CharStringscount + 1;
+ CharStrings [CharStringscount] := CSnew;
+ end
+ end;
+
+ var CSbullet, CSperiodcentered: CharStrpointer;
+ begin
+ if verbose then writeln ('% generating missing characters');
+ if corelfix then begin
+ CSbullet := getCharString ('/bullet');
+ CSperiodcentered := getCharString ('/periodcentered');
+ if (CSbullet <> nil) and (CSperiodcentered <> nil) then
+ swappaths (CSbullet^, CSperiodcentered^);
+ end;
+ halfchar ('/quotedbl', '/quotesingle');
+ downchar ('/quotedblright', '/quotedblbase');
+ halfchar ('/quotedblbase', '/quotesinglbase');
+ halfchar ('/quotedblleft', '/quoteleft');
+ halfchar ('/quotedblright', '/quoteright');
+ downchar ('/quoteright', '/quotesinglbase');
+ halfchar ('/guillemotleft', '/guilsinglleft');
+ halfchar ('/guillemotright', '/guilsinglright');
+ copychar ('/less', '/guilsinglleft');
+ copychar ('/greater', '/guilsinglright');
+ if getCharString ('/endash') <> nil
+ then copychar ('/endash', '/minus')
+ else copychar ('/hyphen', '/minus');
+ copychar ('/slash', '/fraction');
+ copychar ('/bar', '/brokenbar');
+ copychar ('/asciitilde', '/tilde');
+ copychar ('/asciicircum', '/circumflex');
+ copychar ('/degree', '/ring');
+
+ if afmopen or ccopen then begin
+ if verbose then writeln ('% generating composed characters');
+ composeCCs;
+ end
+ end;
+
+var uidfile: text; UniqueID, OtherSubrsfilepos: longint;
+ OtherSubrs: text;
+ savedOtherSubrs: Boolean;
+ s: string;
+ OtherSubrslevel: integer;
+ OtherSubrsup, OtherSubrsdown: string;
+
+begin (* tidy *)
+ Subrscount := 0;
+ linesafterOtherSubrs := 0;
+ savedOtherSubrs := false;
+ linesafterSubrs := 0;
+ CharStringscount := 0;
+ UniqueID := 0;
+
+ readline;
+ (* i := line.posof ('FontType1-1.0');
+ (* if i > 0 then line.replace (i, i + 12, 'PS-AdobeFont-1.0'); *)
+ blanklines := 0;
+ while not eofile and not line.findtoken ('/Subrs')
+ and not line.findtoken ('/OtherSubrs')
+ and not line.findtoken ('/CharStrings') do begin
+ if line.str <> '' then
+ if line.firsttoken = '' then blanklines := blanklines + 1
+ else begin
+ if line.hasprefix ('/FontName') then
+ writeln ('% FontName: ', line.nthtoken (2));
+ if corelfix then begin
+ (* The following modification, if desired at all,
+ would have to be accompanied with metrics
+ adjustment in the .afm file *)
+ (* if line.hasprefix ('/FontMatrix') then begin
+ if line.findtoken ('0.001000')
+ then line.replacelasttoken ('0.000950');
+ if line.findtoken ('0.001000')
+ then line.replacelasttoken ('0.000950');
+ end;
+ *)
+ if line.hasprefix ('/UniqueID') then
+ if line.findtoken ('4221071') then begin
+ if UniqueID = 0 then begin
+ assign (uidfile, 'UniqueID.int');
+ (*$I-*) reset (uidfile) (*$I+*);
+ if IOresult = 0 then read (uidfile, UniqueID)
+ else UniqueID := 4221071;
+ UniqueID := UniqueID + 1;
+ rewrite (uidfile);
+ write (uidfile, UniqueID);
+ close (uidfile);
+ end;
+ line.replacelasttoken (intstr (UniqueID));
+ end
+ end;
+ if stdenc then begin
+ if line.findtoken ('/Encoding') then begin
+ while not line.findtoken ('def') do begin
+ stdenc := false;
+ readline;
+ end;
+ line.ini ('/Encoding StandardEncoding def');
+ if verbose and not stdenc then
+ writeln ('% replacing encoding vector with StandardEncoding')
+ end
+ end;
+ writeln (out, line.str);
+ end;
+ readline;
+ end;
+ if blanklines > 0 then begin
+ writeln ('% ', blanklines, ' blank lines removed');
+ end;
+ if line.findtoken ('/OtherSubrs') then begin
+ (* Borland unwisely prohibited filepos / seek on text files,
+ so we must save the OtherSubrs part in an intermediate
+ file to paste it in again if needed. *)
+ if getenv ('TEMP') <> ''
+ then assign (OtherSubrs, getenv ('TEMP') + '\other.sub')
+ else assign (OtherSubrs, 'other.sub');
+ rewrite (OtherSubrs);
+ OtherSubrslevel := 1;
+ OtherSubrsup := '';
+ repeat s := line.nexttoken;
+ if s = '' then begin
+ writeln (OtherSubrs, line.str);
+ readline;
+ end else if OtherSubrsup = '' then begin
+ OtherSubrsup := s;
+ if s = '[' then OtherSubrsdown := ']'
+ else OtherSubrsdown := '}';
+ end else if s = OtherSubrsup then
+ OtherSubrslevel := OtherSubrslevel + 1
+ else if s = OtherSubrsdown then
+ OtherSubrslevel := OtherSubrslevel - 1;
+ until OtherSubrslevel = 0;
+ writeln (OtherSubrs, line.str);
+ reset (OtherSubrs);
+ savedOtherSubrs := true;
+
+ readline;
+ while not eofile and not line.findtoken ('/Subrs')
+ and not line.findtoken ('/CharStrings') do begin
+ if not line.empty then begin
+ linesafterOtherSubrs := linesafterOtherSubrs + 1;
+ intermediatelines [linesafterOtherSubrs] := line.str;
+ end;
+ readline
+ end;
+ end;
+ if line.findtoken ('/Subrs') then begin
+ if verbose then writeln ('% reading Subrs');
+ Subrsline := line;
+ readline;
+ while nexttoken = 'dup' do readSubr;
+ end else
+ writeln ('% /Subrs not found');
+
+ linesafterSubrs := linesafterOtherSubrs;
+ while not eofile and not line.findtoken ('/CharStrings') do begin
+ if not line.empty then begin
+ linesafterSubrs := linesafterSubrs + 1;
+ intermediatelines [linesafterSubrs] := line.str;
+ end;
+ readline
+ end;
+ if line.findtoken ('/CharStrings') then begin
+ if verbose then writeln ('% reading CharStrings');
+ CharStringsline := line;
+ readline;
+ while pos ('/', nexttoken) = 1 do begin
+ readCharString;
+ (* readline; *)
+ end;
+ end else
+ writeln ('% /CharStrings not found');
+
+ i := 1;
+ while noOtherSubrs and (i <= CharStringscount) do begin
+ noOtherSubrs := not CharStrings [i]^.usesothersubrs;
+ i := i + 1
+ end;
+ (* Borland unwisely prohibited filepos / seek on text files
+ if noOtherSubrs then seek (out, OtherSubrsfilepos);
+ *)
+ if savedOtherSubrs then begin
+ if noOtherSubrs
+ then writeln ('% unused /OtherSubrs removed')
+ else while not eof (OtherSubrs) do begin
+ readln (OtherSubrs, s);
+ writeln (out, s)
+ end;
+ close (OtherSubrs);
+ erase (OtherSubrs);
+ end;
+ for i := 1 to linesafterOtherSubrs do
+ writeln (out, intermediatelines [i]);
+
+ if Subrscount > 0 then begin
+ (* re-structure Subrs and CharStrings: *)
+ (* if verbose then write ('% cleaning junk operations - '); *)
+ (* for i := 1 to Subrscount do Subrs [i]^.cleanup; *)
+ (* for i := 1 to CharStringscount do CharStrings [i]^.cleanup; *)
+ if generate then begin
+ if verbose then write ('% generating missing chars - ');
+ fixchars;
+ end;
+ if generate and split then begin
+ if verbose then write ('% splitting paths - ');
+ for i := 1 to CharStringscount do CharStrings [i]^.splitpath; (**)
+ end;
+ (* sort and number subroutines, collect statistics *)
+ sortMoreSubrs;
+ if verbose then writeln ('% arranging new subpaths');
+ arrangeMoreSubrs (Subrscount);
+
+ (* output Subrs: *)
+ if expand then begin
+ Subrstotal := 4;
+ Subrscount := 4 (* assume they sit on the first positions *)
+ end;
+ Subrsline.gotonexttoken;
+ Subrsline.replacelasttoken (intstr (Subrstotal));
+ writeln (out, Subrsline.str);
+ begin (* writeln (out, '% Subrs: -------'); *)
+ if verbose then write ('% writing previous Subrs - ');
+ for i := 1 to Subrscount do
+ Subrs [i]^.print (out);
+ if not expand then begin
+ if verbose then writeln ('% writing new Subrs');
+ printMoreSubrs (out)
+ end
+ end;
+
+ for i := linesafterOtherSubrs + 1 to linesafterSubrs do
+ writeln (out, intermediatelines [i]);
+ end;
+
+ if afmcheck and afmopen then begin
+ if verbose then writeln ('% checking afm measure information');
+ for i := 1 to CharStringscount do CharStrings [i]^.checkafm (false);
+ end;
+
+ if CharStringscount > 0 then begin
+ (* output CharStrings: *)
+ CharStringsline.gotonexttoken;
+ CharStringsline.replacelasttoken (intstr (CharStringscount));
+ writeln (out, CharStringsline.str);
+ begin (* writeln (out, '% CharStrings: -------'); *)
+ if verbose then writeln ('% writing CharStrings');
+ for i := 1 to CharStringscount do
+ CharStrings [i]^.print (out)
+ end;
+ end;
+
+ while not eofile do begin
+ writeln (out, line.str);
+ readline;
+ end;
+ write (out, line.str);
+ writeln (out);
+end;
+
+var infile, out, afmin, ccin, afmout: text;
+ fontfile, fontname: string;
+ paramindex, i: integer;
+ option: string;
+ optionvalue: Boolean;
+
+ function isoption: Boolean;
+ begin if paramindex > paramcount then isoption := false
+ else begin
+ option := paramstr (paramindex);
+ if length (option) = 0 then isoption := false
+ else isoption := option [1] in ['-', '+', '/']
+ end
+ end;
+begin
+ corelfix := false;
+ generate := true;
+ split := true;
+ ttfix := true;
+ verbose := true;
+ stdenc := true;
+ noOtherSubrs := true;
+ afmcheck := true;
+ expand := false;
+ paramindex := 1;
+ while isoption do begin
+ optionvalue := true;
+ for i := 1 to length (option) do
+ case option [i] of
+ '+': optionvalue := true;
+ '-': optionvalue := false;
+ 'c': corelfix := optionvalue;
+ 'g': generate := optionvalue;
+ 's': split := optionvalue;
+ 't': ttfix := optionvalue;
+ 'v': verbose := optionvalue;
+ 'e': stdenc := optionvalue;
+ 'o': noOtherSubrs := optionvalue;
+ 'a': afmcheck := optionvalue;
+ 'x': expand := optionvalue;
+ end;
+ if corelfix then generate := true;
+ if expand then split := false;
+ paramindex := paramindex + 1
+ end;
+
+ if paramindex <= paramcount then begin
+ fontfile := paramstr (paramindex);
+ fontname := basename (fontfile);
+ assign (infile, fontfile); reset (infile);
+ assign (afmin, fontname + '.afm');
+ assign (ccin, fontname + '.cc');
+
+ paramindex := paramindex + 1;
+ if paramindex <= paramcount then begin
+ if isdir (paramstr (paramindex)) then begin
+ fontfile := paramstr (paramindex) + '\' + fontfile;
+ fontname := paramstr (paramindex) + '\' + fontname;
+ end else begin
+ fontfile := paramstr (paramindex);
+ fontname := basename (fontfile);
+ end;
+ assign (out, fontfile);
+ assign (afmout, fontname + '.afm');
+ end else begin
+ assign (out, '' (* use standard output *));
+ assign (afmout, fontname + '.af$');
+ end;
+ (*$I-*) reset (afmin) (*$I+*);
+ afmopen := IOresult = 0;
+ if afmopen then begin
+ if verbose then writeln ('% reading afm information');
+ openafm (afmin, afmout);
+ end;
+ (*$I-*) reset (ccin) (*$I+*);
+ ccopen := IOresult = 0;
+ if ccopen then begin
+ if verbose then writeln ('% reading compose information');
+ opencc (ccin);
+ close (ccin);
+ end;
+
+ rewrite (out);
+ tidy (infile, out);
+ close (out);
+
+ if afmopen then begin
+ if verbose then writeln ('% finishing afm file');
+ closeafm (afmin, afmout);
+ end;
+ close (infile)
+ end else tidy (input, output);
+ printusedstat;
+end.
diff --git a/fonts/utilities/t1tools/t1tools.doc b/fonts/utilities/t1tools/t1tools.doc
new file mode 100644
index 0000000000..10ed517d3b
--- /dev/null
+++ b/fonts/utilities/t1tools/t1tools.doc
@@ -0,0 +1,211 @@
+t1tools is a collection of programs and batch files useful for
+handling type 1 fonts on MSDOS and Unix systems.
+Documentation is ad-hoc to get the package out at last - sorry for
+any inconvenience this may impose. The package is not meant for
+people without knowledge about type 1 font and metrics stuff.
+If you detect any incompleteness or have any suggestions for improvement,
+please tell me.
+Thomas Wolff@inf.fu-berlin.de
+
+
+The package contains the following tools:
+
+makeafm.bat (MSDOS)
+makeafm (Unix)
+ Generates an .afm font metrics file from a .pfb font file.
+ The information is taken directly from the font itself by
+ first disassembling it using an appropriate program.
+ If pair kerning information is available from any previously
+ existing .afm or .pfm file for that font it will be included
+ in the generated .afm file.
+
+ Syntax: makeafm font-file-base
+ Don't include .pfb / .pfa suffix in file name.
+ Examples:
+ makeafm photina
+
+ Disadvantage: character bounding box information will not be
+ included. This does not matter for use with FrameMaker (which
+ I originally wrote the script for), but for some Tex-ps adaptations.
+ The MSDOS version, however, does at least include simulated character
+ bounding box information derived from other font information to
+ enable Adobe's makepfm to work on the .afm file.
+ Required:
+ 1. To disassemble the type 1 font (.pfb file):
+ the program t1disasm from the package t1utils posted by
+ I. Lee Hetherington with the following modification to t1disasm.c:
+ look up the line output(" {\n");
+ at the beginning of the routine do_charstring and remove the \n .
+ 2. To extract pair kerning information from .pfm files on MSDOS:
+ a) either the program pfm2afm
+ b) or the program dumppfm (version 1.5.3)
+ (Extraction from .pfm files works without additional software on Unix.)
+
+
+getmetri.bat (MSDOS)
+getmetric (Unix)
+ Generates an .afm font metrics file by interpretation of the font
+ using GhostScript. Like makeafm, this script will try to include
+ kerning information from previous sources.
+
+ Syntax: getmetric font-file-base [/FontName]
+ Don't include .pfb / .pfa suffix in file name.
+ Explicit /FontName can choose among several fonts in file.
+ Examples:
+ getmetric photina
+ getmetric hvn_____ /Helvetica-Narrow
+
+ Disadvantage: GhostScript in its current version still has a bug
+ which causes incorrect width information to be calculated for
+ characters composed by seac and having a different width from their
+ base character - actually, this should not be allowed according to
+ the type 1 font specification, but to accomodate existing fonts to
+ work, rather Adobe's "Do what we implement" semantics should be
+ realized. The problem especially occurs with fonts bundled with
+ Micrografx Designer (which even compose characters like double
+ qoute marks from single quote marks etc), so don't apply getmetri
+ on them.
+
+ Required: GhostScript
+ getmetri.ps (enclosed), which is a corrected and enhanced
+ version of the PostScript program posted by W.T. Roberts
+ and Bryan Bayerdorffer.
+
+pfbshow.bat (MSDOS)
+gpreview (Unix)
+preview (Unix)
+pfbpr.bat (MSDOS)
+preprint (Unix)
+ [preview and preprint differ from gpreview only by their name and
+ can be created by setting respective links.]
+ Generates a sample text and character set listing of up to four
+ fonts (preferably of one family).
+ The latter two print, the first three display on screen.
+
+ Syntax: pfbshow fontfile1 [fontfile2 [fontfile3 [fontfile4]]]
+ pfbpr fontfile1 [fontfile2 [fontfile3 [fontfile4]]]
+ preview (fontfile|fontname) ...
+ Up to four fonts make sense. The Unix scripts can accept
+ FontNames instead of file names to explicitly select a
+ font which must then be previously known to the interpreter.
+ Examples:
+ pfbshow photina.pfb
+ pfbshow photina photinai photinab
+ gpreview Times-Roman.pfb /Hershey-Roman
+
+ Required:
+ one of several .pfb/.pfa converters (e.g. from t1utils)
+ pfbshow.bat, pfbpr.bat: pfshow.ps (enclosed)
+ pfbshow, gpreview, pfbpr: GhostScript
+ preprint: a PostScript printer
+ preview: a type 1 font emulation package for OpenWindows
+ and a font disassembler (e.g. from t1utils)
+ (or maybe, native type 1 font interpretation in
+ OpenWindows 3.1 which I don't have)
+
+pcs.bat (MSDOS)
+ Display the character set of a font in comparison with that of
+ an installed reference font (or a second font) including a
+ coloured width and slant angle box. It can be used to judge
+ quality, similarity, and correct/incorrect character set assignment
+ of fonts.
+
+ Syntax: pcs filename [filename2]
+ Examples:
+ pcs gocmase_.pfb
+ pcs agar agarsc
+
+pfblist.bat (MSDOS)
+ Generates a list of file and font names of the current directory.
+ Requires: pfbnames.pas/.exe (enclosed)
+
+afm-pfm.bat (MSDOS)
+ Generates .pfm from .afm files using Adobe's makepfm program.
+ Generates .inf information as needed for makepfm. Also tries
+ to extract the correct Bold/Italic combination from .afm information.
+ Can be called with explicit information about the Windows menu
+ font name and Bold/Italic combination to be used.
+
+ Syntax: afm-pfm fontfile [MSMenuName | - ] [N | I | B | T]
+ Don't include .afm suffix in fontfile.
+ MSMenuName selects a name under which the font should appear
+ in MS Windows menus for most programs if this is different
+ from the FamilyName in the .afm file. (Annoyingly, only
+ 4 fonts can be grouped under one name in MS Windows.)
+ N forces the generated style information to be normal,
+ I italic, B bold, T bold-italic.
+ Examples:
+ afm-pfm agar
+ afm-pfm agarb AGaramondBold N
+ If the MS menu name to be generated should contain blanks, an .inf
+ file must be generated first and the name inserted there.
+
+ Required: makepfm.exe from Adobe's "font foundry".
+
+afm-inf.bat (MSDOS)
+ Part of afm-pfm, can also be called separately.
+ Example: afm-inf agar
+
+afm-sort.bat (MSDOS)
+ Sorts the pair kerning list within an .afm file. Needed for some
+ .afm files to prevent Adobe's simple-minded makepfm program
+ from crashing.
+ Example: afm-sort agar
+
+pfb-abf.bat (MSDOS)
+ Generate .abf files for 72x72 resolution as required to generate
+ FrameMaker screen font files for use on Sun workstations.
+
+ Syntax: pfb-abf fontname [outnam [resolutionx [resolutiony [encoding]]]]
+ Don't include .pfb suffix in fontname.
+ If fontname is longer than 6 characters a unique outnam with
+ at most 6 characters must additionally be specified (five if
+ you should generate point sizes > 99).
+ Screen resolution defaults to 72x72 (for Sun workstations)
+ but can be changed.
+ The encoding vector to be applied (to be given without its
+ .enc suffix) defaults to fontname.ENC if that exists,
+ C:\Adobe\APPLE.ENC otherwise (adapt the path in the script
+ to where you place the APPLE.ENC file enclosed).
+ The set of point sizes to be generated defaults to
+ 10 12 14 18 24 but may changed by the environment variable
+ SIZES, e.g. (for display fonts) set SIZES=18 24 36
+ Note that FrameMaker needs at least sizes 18 and 24.
+
+ Required: makebit.exe, makeabf.exe from Adobe's "font foundry".
+
+pfb-sfp.bat (MSDOS)
+ Generate HP Laserjet soft fonts from .pfb fonts.
+
+ Syntax: pfb-abf fontname [outnam [resolutionx [resolutiony [encoding]]]]
+ Don't include .pfb suffix in fontname.
+ If fontname is longer than 6 characters a unique outnam with
+ at most 6 characters must additionally be specified (five if
+ you should generate point sizes > 99).
+ Printer resolution defaults to 300x300.
+ The encoding vector to be applied (to be given without its
+ .enc suffix) defaults to fontname.ENC if that exists,
+ C:\Adobe\foundry\W.ENC otherwise (adapt path in the script).
+ The set of point sizes to be generated defaults to
+ 10 12 but may changed by the environment variable PSIZES,
+ e.g. set PSIZES=9 10 12 14 18
+
+ Required: makebit.exe, makeljf.exe from Adobe's "font foundry".
+
+pfb-enc.bat (MSDOS)
+ Extracts an .ENC encoding description from a font specific encoding
+ vector for use with pfb-abf or pfb-sfp.
+ Example:
+ pfb-enc agarexp
+
+fm.ps
+ A one-liner. Prepended to FrameMaker generated PostScript files
+ it makes them work with GhostScript.
+
+Debugging: All MSDOS scripts accept an additional first parameter "-"
+in which case they do not delete their intermediate files.
+
+Remark: Due to that silly MSDOS path restriction, all my MSDOS scripts
+(.bat files) contain full path names for several programs. These will have
+to be adapted to your installation. Also, for pcs, a reference font will
+have to be chosen and installed in the script.
diff --git a/fonts/utilities/t1tools/w.enc b/fonts/utilities/t1tools/w.enc
new file mode 100644
index 0000000000..f03b4aae2f
--- /dev/null
+++ b/fonts/utilities/t1tools/w.enc
@@ -0,0 +1,144 @@
+%
+% Copyright 1989 Adobe Systems Inc. All Rights Reserved.
+% This encoding vector represents the differences between the PostScript
+% standard encoding and the MS-Windows ANSI character set.
+% Digby Horner - 01/11/89
+% yh - 08/27/91 Added some characters for Windows 3.1
+% rm - 11-21-91 added tilde @ 152 and circumflex @ 136 for win 3.1
+%
+MaxIndex 255
+MaxEncoded 255
+%
+StartEncoding
+39 quotesingle
+96 grave
+128 .notdef
+129 .notdef
+130 quotesinglbase
+131 florin
+132 quotedblbase
+133 ellipsis
+134 dagger
+135 daggerdbl
+136 circumflex
+137 perthousand
+138 Scaron
+139 guilsinglleft
+140 OE
+141 .notdef
+142 .notdef
+143 .notdef
+144 .notdef
+145 quoteleft
+146 quoteright
+147 quotedblleft
+148 quotedblright
+149 bullet
+150 endash
+151 emdash
+152 tilde
+153 trademark
+154 scaron
+155 guilsinglright
+156 oe
+157 .notdef
+158 .notdef
+159 Ydieresis
+160 space
+161 exclamdown
+162 cent
+163 sterling
+164 currency
+165 yen
+166 brokenbar
+167 section
+168 dieresis
+169 copyright
+170 ordfeminine
+171 guillemotleft
+172 logicalnot
+173 minus
+174 registered
+175 macron
+176 degree
+177 plusminus
+178 twosuperior
+179 threesuperior
+180 acute
+181 mu
+182 paragraph
+183 periodcentered
+184 cedilla
+185 onesuperior
+186 ordmasculine
+187 guillemotright
+188 onequarter
+189 onehalf
+190 threequarters
+191 questiondown
+192 Agrave
+193 Aacute
+194 Acircumflex
+195 Atilde
+196 Adieresis
+197 Aring
+198 AE
+199 Ccedilla
+200 Egrave
+201 Eacute
+202 Ecircumflex
+203 Edieresis
+204 Igrave
+205 Iacute
+206 Icircumflex
+207 Idieresis
+208 Eth
+209 Ntilde
+210 Ograve
+211 Oacute
+212 Ocircumflex
+213 Otilde
+214 Odieresis
+215 multiply
+216 Oslash
+217 Ugrave
+218 Uacute
+219 Ucircumflex
+220 Udieresis
+221 Yacute
+222 Thorn
+223 germandbls
+224 agrave
+225 aacute
+226 acircumflex
+227 atilde
+228 adieresis
+229 aring
+230 ae
+231 ccedilla
+232 egrave
+233 eacute
+234 ecircumflex
+235 edieresis
+236 igrave
+237 iacute
+238 icircumflex
+239 idieresis
+240 eth
+241 ntilde
+242 ograve
+243 oacute
+244 ocircumflex
+245 otilde
+246 odieresis
+247 divide
+248 oslash
+249 ugrave
+250 uacute
+251 ucircumflex
+252 udieresis
+253 yacute
+254 thorn
+255 ydieresis
+EndEncoding
+ \ No newline at end of file