#!/usr/local/bin/perl
#
# Copyright (c) Matsushita Electric Industrial Co.,Ltd. 1994
#
# $Id: mkOffsetTbl,v 1.2 1994/03/24 13:21:43 kakiuchi Exp $
#

#### convenient routines

sub char2JISnum {
	@c = unpack("C2", $_[0]);
	$mask = hex("0x7f");
	return ($c[0] & $mask) * 256 + ($c[1] & $mask);
}

sub JISnum2char {
	$n = $_[0] | hex("0x8080");
	$n = pack("S", $n);
	return $n
}

#### used for parsing PL files

sub getPLTAG {
	$fd = $_[0];
	$tag = "";
	while (($ch = getc($fd)) ne "(") {
		if ($ch eq "") {return ""}
	}
	while(($ch = getc($fd)) =~ /[A-Z]/) {$tag .= $ch;}
	return $tag;
}

sub skipToEndOfList {
	$fd = $_[0];
	$lbrace = 1;
	while($lbrace != 0) {
		$ch = getc($fd);
		if ($ch eq "(") {++$lbrace;}
		elsif ($ch eq ")") {--$lbrace;}
	}
}

sub getNextToken {
	$fd = $_[0];
	$item = "";
	while (($ch = getc($fd)) =~ /\s/) {}	# skip space characters
	if ($ch =~ /[)(]/) {return $ch;}	# check braces
	while ($ch =~ /[\S]/) {
		if ($ch eq ")") {last;}		# found end-of-list token
		$item .= $ch;
		$ch = getc($fd);
	}
	return $item;
}

sub parseTYPE {
	$fd = $_[0];
	&getNextToken($fd);			# ignore value
	$n = &getNextToken($fd);		# this is TYPE number
	if ($tag = &getPLTAG($fd)) {
		if ($tag eq "CHARWD") {
			&getNextToken($fd);	# ignore value
			$width[$n] = &getNextToken($fd);
		} else {&skipToEndOfList(PL);}
	}
	do skipToEndOfList($fd);
}

sub parseCHARSINTYPE {
	$fd = $_[0];
	&getNextToken($fd);		# ignore value
	$n = &getNextToken($fd);
	$i = 0;
	while (($ch = &getNextToken($fd)) ne ")") {
		$charsInTypes{$n,$i} = &char2JISnum($ch);
		if ($minCharCode > $charsInTypes{$n,$i}){
			$minCharCode=$charsInTypes{$n,$i};
		}
		if ($maxCharCode < $charsInTypes{$n,$i}) {
			$maxCharCode=$charsInTypes{$n,$i};
		}
		++$i;
	}
	$numChars[$n] = $i;
}

sub parsePL {
	$minCharCode = hex("0xffff");
	$maxCharCode = hex("0x0000");
	open(PL, "<$_[0]");
	while(1) {
		if ($tag = &getPLTAG(PL)) {
			if ($tag eq "CHARSINTYPE") {&parseCHARSINTYPE(PL);}
			elsif ($tag eq "TYPE") {&parseTYPE(PL);}
			else {do skipToEndOfList(PL);}
		} else {last}
	}
	for ($i = 0; $i <= $#width; ++$i) {
		print STDERR "type is $i numchar is $numChars[$i]\n";
		for ($j = 0; $j < $numChars[$i]; ++$j) {
			print STDERR "$charsInTypes{$i,$j},";
		}
		print STDERR "\nwidth = $width[$i]\n";
	}
	close(PL);
}

######### used for parsing AFM files

sub findType {
	if ($minCharCode > $_[0] || $maxCharCode < $_[0] ) {return 0;}
	for ($i = 0; $i <= $#width; ++$i) {
		for ($j = 0; $j < $numChars[$i]; ++$j) {
			if ($charsInTypes{$i,$j} == $_[0]) {
				return $i;
			}
		}
	}
	return 0;
}
sub parseAFM {
	$isVirtical = 0;
	open(AFM, "<$_[0]");
	print "static AdjustRatioRecord $_[1]_adj[] = {\n";
	while(<AFM>) {
		if (/^MetricsSets ([0-2])/) {
			if ($1 == 1) {$isVertical = 1;}
		} elsif (/^CH <(....)> ; B ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ;/) {
			$code = hex("0x" . $1);
			$type = &findType($code);
			if ($type != 0) {
				@lb = ($2,$3);
				@ur = ($4,$5);
				$ch = &JISnum2char($code);
				if ($isVertical) {
					$w = ($ur[1] + $lb[1]) / 1000;
					$offset = ($width[$type] + $w) / 2;
					printf "  { 0x%x,\t0.0,\t%g}, /* %s-%d */\n", $code, $offset, $ch, $type;
				} else {
					$w = ($ur[0] + $lb[0]) / 1000;
					$offset = ($width[$type] - $w) / 2;
					printf "  { 0x%x,\t%g,\t0.0}, /* %s-%d */\n", $code, $offset, $ch, $type;
				}
				print STDERR "$ch, $code, $offset, @ur, @lb, $neww\n";
			}
		}
	}
	print "};\n";
	close(AFM);
}

do parsePL($ARGV[0]);
do parseAFM($ARGV[1], $ARGV[2]);
