3 # Copyright (C) 1989-2000, 2001, 2002 Free Software Foundation, Inc.
4 # Written by James Clark (jjc@jclark.com)
6 # This file is part of groff.
8 # groff is free software; you can redistribute it and/or modify it under
9 # the terms of the GNU General Public License as published by the Free
10 # Software Foundation; either version 2, or (at your option) any later
13 # groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 # You should have received a copy of the GNU General Public License along
19 # with groff; see the file COPYING. If not, write to the Free Software
20 # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 do Getopts('ve:sd:i:a:n');
29 print "GNU afmtodit (groff) version @VERSION@\n";
34 die "Usage: $prog [-nsv] [-d DESC] [-e encoding] [-i n] [-a angle] afmfile mapfile font\n";
40 $desc = $opt_d || "DESC";
44 open(AFM, $afm) || die "$prog: can't open \`$ARGV[0]': $!\n";
49 if ($field[0] eq "FontName") {
52 elsif($field[0] eq "ItalicAngle") {
53 $italic_angle = -$field[1];
55 elsif ($field[0] eq "KPX") {
57 push(kern1, $field[1]);
58 push(kern2, $field[2]);
59 push(kernx, $field[3]);
62 elsif ($field[0] eq "italicCorrection") {
63 $italic_correction{$field[1]} = $field[2];
65 elsif ($field[0] eq "leftItalicCorrection") {
66 $left_italic_correction{$field[1]} = $field[2];
68 elsif ($field[0] eq "subscriptCorrection") {
69 $subscript_correction{$field[1]} = $field[2];
71 elsif ($field[0] eq "StartCharMetrics") {
74 last if ($field[0] eq "EndCharMetrics");
75 if ($field[0] eq "C") {
85 while ($i <= $#field) {
86 if ($field[$i] eq "WX") {
90 elsif ($field[$i] eq "N") {
94 elsif ($field[$i] eq "B") {
95 $llx = $field[$i + 1];
96 $lly = $field[$i + 2];
97 $urx = $field[$i + 3];
98 $ury = $field[$i + 4];
101 elsif ($field[$i] eq "L") {
102 push(ligatures, $field[$i + 2]);
106 while ($i <= $#field && $field[$i] ne ";") {
112 if (!$opt_e && $c != -1) {
114 $in_encoding{$n} = 1;
119 $left_side_bearing{$n} = -$llx;
120 $right_side_bearing{$n} = $urx - $w;
131 open(DESC, $desc) || die "$prog: can't open \`$desc': $!\n";
136 last if $field[0] eq "charset";
137 if ($field[0] eq "res") { $resolution = $field[1]; }
138 if ($field[0] eq "unitwidth") { $unitwidth = $field[1]; }
139 if ($field[0] eq "sizescale") { $sizescale = $field[1]; }
144 # read the encoding file
146 open(ENCODING, $opt_e) || die "$prog: can't open \`$opt_e': $!\n";
152 if ($field[1] >= 0 && defined $width{$field[0]}) {
153 $encoding[$field[1]] = $field[0];
154 $in_encoding{$field[0]} = 1;
163 open(MAP, $map) || die "$prog: can't open \`$map': $!\n";
168 if ($#field == 1 && $in_encoding{$field[0]}) {
169 if (defined $mapped{$field[1]}) {
170 warn "Both $mapped{$field[1]} and $field[0] map to $field[1]";
172 elsif ($field[1] eq "space") {
173 # the PostScript character "space" is automatically mapped
174 # to the groff character "space"; this is for grops
175 warn "you are not allowed to map to the groff character `space'";
177 elsif ($field[0] eq "space") {
178 warn "you are not allowed to map the PostScript character `space'";
181 $nmap{$field[0]} += 0;
182 $map{$field[0],$nmap{$field[0]}} = $field[1];
183 $nmap{$field[0]} += 1;
184 $mapped{$field[1]} = $field[0];
190 $italic_angle = $opt_a if $opt_a;
194 open(FONT, ">$font") || die "$prog: can't open \`$font' for output: $!\n";
197 print("name $font\n");
198 print("internalname $psname\n") if $psname;
199 print("special\n") if $opt_s;
200 printf("slant %g\n", $italic_angle) if $italic_angle != 0;
201 printf("spacewidth %d\n", do conv($width{"space"})) if defined $width{"space"};
206 print("encoding $e\n");
209 if (!$opt_n && $#ligatures >= 0) {
211 foreach $lig (@ligatures) {
218 print("kernpairs\n");
220 for ($i = 0; $i <= $#kern1; $i++) {
223 if ($in_encoding{$c1} == 1 && $nmap{$c1} != 0
224 && $in_encoding{$c2} == 1 && $nmap{$c2} != 0) {
225 for ($j = 0; $j < $nmap{$c1}; $j++) {
226 for ($k = 0; $k < $nmap{$c2}; $k++) {
227 if ($kernx[$i] != 0) {
231 do conv($kernx[$i]));
239 # characters not shorter than asc_boundary are considered to have ascenders
240 $asc_boundary = $height{"t"} - 1;
242 # likewise for descenders
243 $desc_boundary = $depth{"g"};
244 $desc_boundary = $depth{"j"} if $depth{"j"} < $desc_boundary;
245 $desc_boundary = $depth{"p"} if $depth{"p"} < $desc_boundary;
246 $desc_boundary = $depth{"q"} if $depth{"q"} < $desc_boundary;
247 $desc_boundary = $depth{"y"} if $depth{"y"} < $desc_boundary;
250 if (defined $height{"x"}) {
251 $xheight = $height{"x"};
253 elsif (defined $height{"alpha"}) {
254 $xheight = $height{"alpha"};
260 $italic_angle = $italic_angle*3.14159265358979323846/180.0;
261 $slant = sin($italic_angle)/cos($italic_angle);
262 $slant = 0 if $slant < 0;
265 for ($i = 0; $i < 256; $i++) {
267 if ($ch ne "" && $ch ne "space") {
268 $map{$ch,"0"} = "---" if $nmap{$ch} == 0;
274 $type = 1 if $d >= $desc_boundary;
275 $type += 2 if $h >= $asc_boundary;
276 printf("%s\t%d", $map{$ch,"0"}, do conv($width{$ch}));
277 $italic_correction = 0;
279 $subscript_correction = 0;
280 if (defined $opt_i) {
281 $italic_correction = $right_side_bearing{$ch} + $opt_i;
282 $italic_correction = 0 if $italic_correction < 0;
283 $subscript_correction = $slant * $xheight * .8;
284 $subscript_correction = $italic_correction if
285 $subscript_correction > $italic_correction;
286 $left_math_fit = $left_side_bearing{$ch} + $opt_i;
288 if (defined $italic_correction{$ch}) {
289 $italic_correction = $italic_correction{$ch};
291 if (defined $left_italic_correction{$ch}) {
292 $left_math_fit = $left_italic_correction{$ch};
294 if (defined $subscript_correction{$ch}) {
295 $subscript_correction = $subscript_correction{$ch};
297 if ($subscript_correction != 0) {
298 printf(",%d,%d", do conv($h), do conv($d));
299 printf(",%d,%d,%d", do conv($italic_correction),
300 do conv($left_math_fit),
301 do conv($subscript_correction));
303 elsif ($left_math_fit != 0) {
304 printf(",%d,%d", do conv($h), do conv($d));
305 printf(",%d,%d", do conv($italic_correction),
306 do conv($left_math_fit));
308 elsif ($italic_correction != 0) {
309 printf(",%d,%d", do conv($h), do conv($d));
310 printf(",%d", do conv($italic_correction));
313 printf(",%d,%d", do conv($h), do conv($d));
316 # always put the height in to stop groff guessing
317 printf(",%d", do conv($h));
319 printf("\t%d", $type);
320 printf("\t0%03o\t-- %s\n", $i, $ch);
321 for ($j = 1; $j < $nmap{$ch}; $j++) {
322 printf("%s\t\"\n", $map{$ch,$j});
325 if ($ch eq "space" && defined $width{"space"}) {
326 printf("space\t%d\t0\t0%03o\n", do conv($width{"space"}), $i);
331 $_[0]*$unitwidth*$resolution/(72*1000*$sizescale) + ($_[0] < 0 ? -.5 : .5);