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