#! /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