#!/usr/bin/perl
# 
#  Copyright (c) 1998
#   Sergey A. Babkin.  All rights reserved.
# 
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions
#  are met:
#  1. Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#  2. Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
# 
#  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# 
#  Sergey A. Babkin (sab123@hotmail.com, babkin@bellatlantic.net)
# 

#
# Force the font to use the encoding as close to ISO Latin-1 as possible
#
# Use:
#   forceiso [format] <file1.t1a >file2.t1a
# where format is a printf-type format used to select names for the
# glyphs without standard Latin-1 names. It must expect one argument,
# the character code. The default format is "_%d".

%latin1=(
   0, "",
   1, "",
   2, "",
   3, "",
   4, "",
   5, "",
   6, "",
   7, "",
   8, "",
   9, "",
  10, "",
  11, "",
  12, "",
  13, "",
  14, "",
  15, "",
  16, "",
  17, "",
  18, "",
  19, "",
  20, "",
  21, "",
  22, "",
  23, "",
  24, "",
  25, "",
  26, "",
  27, "",
  28, "",
  29, "",
  30, "",
  31, "",
  32, "space",
  33, "exclam",
  34, "quotedbl",
  35, "numbersign",
  36, "dollar",
  37, "percent",
  38, "ampersand",
  39, "quoteright",
  40, "parenleft",
  41, "parenright",
  42, "asterisk",
  43, "plus",
  44, "comma",
  45, "hyphen",
  46, "period",
  47, "slash",
  48, "zero",
  49, "one",
  50, "two",
  51, "three",
  52, "four",
  53, "five",
  54, "six",
  55, "seven",
  56, "eight",
  57, "nine",
  58, "colon",
  59, "semicolon",
  60, "less",
  61, "equal",
  62, "greater",
  63, "question",
  64, "at",
  65, "A",
  66, "B",
  67, "C",
  68, "D",
  69, "E",
  70, "F",
  71, "G",
  72, "H",
  73, "I",
  74, "J",
  75, "K",
  76, "L",
  77, "M",
  78, "N",
  79, "O",
  80, "P",
  81, "Q",
  82, "R",
  83, "S",
  84, "T",
  85, "U",
  86, "V",
  87, "W",
  88, "X",
  89, "Y",
  90, "Z",
  91, "bracketleft",
  92, "backslash",
  93, "bracketright",
  94, "asciicircum",
  95, "underscore",
  96, "grave",
  97, "a",
  98, "b",
  99, "c",
 100, "d",
 101, "e",
 102, "f",
 103, "g",
 104, "h",
 105, "i",
 106, "j",
 107, "k",
 108, "l",
 109, "m",
 110, "n",
 111, "o",
 112, "p",
 113, "q",
 114, "r",
 115, "s",
 116, "t",
 117, "u",
 118, "v",
 119, "w",
 120, "x",
 121, "y",
 122, "z",
 123, "braceleft",
 124, "bar",
 125, "braceright",
 126, "asciitilde",
 127, "",
 128, "",
 129, "",
 130, "",
 131, "",
 132, "",
 133, "",
 134, "",
 135, "",
 136, "",
 137, "",
 138, "",
 139, "",
 140, "",
 141, "",
 142, "",
 143, "",
 144, "",
 145, "",
 146, "",
 147, "",
 148, "",
 149, "",
 150, "",
 151, "",
 152, "",
 153, "",
 154, "",
 155, "",
 156, "",
 157, "",
 158, "",
 159, "",
 160, "",
 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"
);

# how to treat the unknown characters
$unk = "_%d";

if($#ARGV >= 0) {
	$unk = $ARGV[0];
}

# fill in the unnamed characters
if( sprintf($unk, 0) eq sprintf($unk, 1) ) {
	die "The format for unnamed characters must not be a constant"
}
for($i=0; $i < 256; $i++) {
	if($latin1{$i} eq "") {
		$latin1{$i} = sprintf($unk, $i);
	}
}

while(<STDIN>) {
	print $_;
	if(/^\/Encoding\s+.*\s+array/) {
		$fontfile=1;
		last;
	}
	if(/^StartCharMetrics\s+/) {
		$fontfile=0;
		last;
	}
}

$ndups=0;

if($fontfile) { # .t1a file 
	while(<STDIN>) {
		if($_ !~ /^dup\s+(\d+)\s+\/(\S+)\s+put/) {
			print $_;
			last;
		}
		$code=$1+0;
		$name=$2;
		if($name eq ".notdef") {
			print $_;
		} else {
			printf("dup %d /%s put\n",$code,$latin1{$code});
			if($trans{$name}) { # two or more references to the same glyph
				$ndups++;
				#printf(STDERR "forceiso: %d dups\n", $ndups);
				if($copies{$name} eq "") {
					$copies{$name} = $latin1{$code};
				} else {
					$copies{$name} .= "|" . $latin1{$code};
				}
			} else {
				$trans{$name}=$latin1{$code};
			}
		}

	}

	while(<STDIN>) {
		if( /\/CharStrings\s+(\d+)\s/) {
			$nchars=$1+$ndups;
			#printf(STDERR "forceiso: %d dups %d chars\n", $ndups, $nchars);
			$_ =~ s|/CharStrings\s+\d+\s|/CharStrings $nchars |;
			print $_;
			last;
		}
		print $_;
	}

	while(<STDIN>) {
		if(/^\/(\S+)/) {
			$name=$1;
			$to=$trans{$name};

			$header=$_;
			$body="";

			if($to ne "") {
				$_ =~ s/^\/\S+/\/$to/;
			}
			print $_;
		} elsif(/endchar/) {
			print $_;
			if($copies{$name}) {
				for $to (split(/\|/,$copies{$name})) {
					$header =~ s/^\/\S+/\/$to/;
					print($header, $body, $_);
				}
			}
		} else {
			print $_;
			$body .= $_;
		}
	}
} else { # .afm file 
	while(<STDIN>) {
		if($_ !~ /^C\s+(\d+)(\s*;.*N\s+)(\S+)(\s*;.*)\n/) {
			print $_;
			last;
		}
		$code=$1+0;
		$name=$3;
		$part2=$2;
		$part4=$4;
		if($name eq ".notdef") {
			print $_;
		} else {
			printf("C %d%s%s%s\n",$code,$part2,$latin1{$code},$part4);
			if($copies{$name} eq "") {
				$copies{$name} = $latin1{$code};
			} else {
				$copies{$name} .= "|" . $latin1{$code};
				$ndups++;
				#printf(STDERR "forceiso: %d dups\n", $ndups);
			}
		}

	}

	while(<STDIN>) {
		if(/^StartKernPairs\s+(\d+)/) {
			last;
		}
		print $_;
	}

	$npairs=0;
	$kps="";
	while(<STDIN>) {
		if(/^KPX\s+(\S+)\s+(\S+)\s+(.*)\n/) {
			$name1=$1;
			$name2=$2;
			$metric=$3;

			$cp1=$copies{$name1};
			if($cp1 eq "") {
				$cp1=$name1;
			}

			$cp2=$copies{$name2};
			if($cp2 eq "") {
				$cp2=$name2;
			}

			for $to1 (split(/\|/,$cp1)) {
				for $to2 (split(/\|/,$cp2)) {
					$kps .= sprintf("KPX %s %s %s\n", $to1, $to2, $metric);
					$npairs++;
				}
			}
		} else {
			if($npairs!=0) {
				printf("StartKernPairs %d\n", $npairs);
				printf("%s", $kps);
				$npairs=0;
				$kps="";
			}
			print $_;
		}
	}
}
