Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / groff / src / utils / tfmtodit / tfmtodit.cpp
blob987fd3d29a5bf1d0a08c3885fc33ae8176880eba
1 /* $NetBSD$ */
3 // -*- C++ -*-
4 /* Copyright (C) 1989-1992, 2000, 2001, 2004 Free Software Foundation, Inc.
5 Written by James Clark (jjc@jclark.com)
7 This file is part of groff.
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING. If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
23 /* I have tried to incorporate the changes needed for TeX 3.0 tfm files,
24 but I haven't tested them. */
26 /* Groff requires more font metric information than TeX. The reason
27 for this is that TeX has separate Math Italic fonts, whereas groff
28 uses normal italic fonts for math. The two additional pieces of
29 information required by groff correspond to the two arguments to the
30 math_fit() macro in the Metafont programs for the CM fonts. In the
31 case of a font for which math_fitting is false, these two arguments
32 are normally ignored by Metafont. We need to get hold of these two
33 parameters and put them in the groff font file.
35 We do this by loading this definition after cmbase when creating cm.base.
37 def ignore_math_fit(expr left_adjustment,right_adjustment) =
38 special "adjustment";
39 numspecial left_adjustment*16/designsize;
40 numspecial right_adjustment*16/designsize;
41 enddef;
43 This puts the two arguments to the math_fit macro into the gf file.
44 (They will appear in the gf file immediately before the character to
45 which they apply.) We then create a gf file using this cm.base. Then
46 we run tfmtodit and specify this gf file with the -g option.
48 This need only be done for a font for which math_fitting is false;
49 When it's true, the left_correction and subscript_correction should
50 both be zero. */
52 #include "lib.h"
54 #include <stdlib.h>
55 #include <math.h>
56 #include <errno.h>
57 #include "errarg.h"
58 #include "error.h"
59 #include "assert.h"
60 #include "cset.h"
61 #include "nonposix.h"
63 extern "C" const char *Version_string;
65 /* Values in the tfm file should be multiplied by this. */
67 #define MULTIPLIER 1
69 struct char_info_word {
70 unsigned char width_index;
71 char height_index;
72 char depth_index;
73 char italic_index;
74 char tag;
75 unsigned char remainder;
78 struct lig_kern_command {
79 unsigned char skip_byte;
80 unsigned char next_char;
81 unsigned char op_byte;
82 unsigned char remainder;
85 class tfm {
86 int bc;
87 int ec;
88 int nw;
89 int nh;
90 int nd;
91 int ni;
92 int nl;
93 int nk;
94 int np;
95 int cs;
96 int ds;
97 char_info_word *char_info;
98 int *width;
99 int *height;
100 int *depth;
101 int *italic;
102 lig_kern_command *lig_kern;
103 int *kern;
104 int *param;
105 public:
106 tfm();
107 ~tfm();
108 int load(const char *);
109 int contains(int);
110 int get_width(int);
111 int get_height(int);
112 int get_depth(int);
113 int get_italic(int);
114 int get_param(int, int *);
115 int get_checksum();
116 int get_design_size();
117 int get_lig(unsigned char, unsigned char, unsigned char *);
118 friend class kern_iterator;
121 class kern_iterator {
122 tfm *t;
123 int c;
124 int i;
125 public:
126 kern_iterator(tfm *);
127 int next(unsigned char *c1, unsigned char *c2, int *k);
131 kern_iterator::kern_iterator(tfm *p)
132 : t(p), c(t->bc), i(-1)
136 int kern_iterator::next(unsigned char *c1, unsigned char *c2, int *k)
138 for (; c <= t->ec; c++)
139 if (t->char_info[c - t->bc].tag == 1) {
140 if (i < 0) {
141 i = t->char_info[c - t->bc].remainder;
142 if (t->lig_kern[i].skip_byte > 128)
143 i = (256*t->lig_kern[i].op_byte
144 + t->lig_kern[i].remainder);
146 for (;;) {
147 int skip = t->lig_kern[i].skip_byte;
148 if (skip <= 128 && t->lig_kern[i].op_byte >= 128) {
149 *c1 = c;
150 *c2 = t->lig_kern[i].next_char;
151 *k = t->kern[256*(t->lig_kern[i].op_byte - 128)
152 + t->lig_kern[i].remainder];
153 if (skip == 128) {
154 c++;
155 i = -1;
157 else
158 i += skip + 1;
159 return 1;
161 if (skip >= 128)
162 break;
163 i += skip + 1;
165 i = -1;
167 return 0;
170 tfm::tfm()
171 : char_info(0), width(0), height(0), depth(0), italic(0), lig_kern(0),
172 kern(0), param(0)
176 int tfm::get_lig(unsigned char c1, unsigned char c2, unsigned char *cp)
178 if (contains(c1) && char_info[c1 - bc].tag == 1) {
179 int i = char_info[c1 - bc].remainder;
180 if (lig_kern[i].skip_byte > 128)
181 i = 256*lig_kern[i].op_byte + lig_kern[i].remainder;
182 for (;;) {
183 int skip = lig_kern[i].skip_byte;
184 if (skip > 128)
185 break;
186 // We are only interested in normal ligatures, for which
187 // op_byte == 0.
188 if (lig_kern[i].op_byte == 0
189 && lig_kern[i].next_char == c2) {
190 *cp = lig_kern[i].remainder;
191 return 1;
193 if (skip == 128)
194 break;
195 i += skip + 1;
198 return 0;
201 int tfm::contains(int i)
203 return i >= bc && i <= ec && char_info[i - bc].width_index != 0;
206 int tfm::get_width(int i)
208 return width[char_info[i - bc].width_index];
211 int tfm::get_height(int i)
213 return height[char_info[i - bc].height_index];
216 int tfm::get_depth(int i)
218 return depth[char_info[i - bc].depth_index];
221 int tfm::get_italic(int i)
223 return italic[char_info[i - bc].italic_index];
226 int tfm::get_param(int i, int *p)
228 if (i <= 0 || i > np)
229 return 0;
230 else {
231 *p = param[i - 1];
232 return 1;
236 int tfm::get_checksum()
238 return cs;
241 int tfm::get_design_size()
243 return ds;
246 tfm::~tfm()
248 a_delete char_info;
249 a_delete width;
250 a_delete height;
251 a_delete depth;
252 a_delete italic;
253 a_delete lig_kern;
254 a_delete kern;
255 a_delete param;
258 int read2(unsigned char *&s)
260 int n;
261 n = *s++ << 8;
262 n |= *s++;
263 return n;
266 int read4(unsigned char *&s)
268 int n;
269 n = *s++ << 24;
270 n |= *s++ << 16;
271 n |= *s++ << 8;
272 n |= *s++;
273 return n;
277 int tfm::load(const char *file)
279 errno = 0;
280 FILE *fp = fopen(file, FOPEN_RB);
281 if (!fp) {
282 error("can't open `%1': %2", file, strerror(errno));
283 return 0;
285 int c1 = getc(fp);
286 int c2 = getc(fp);
287 if (c1 == EOF || c2 == EOF) {
288 fclose(fp);
289 error("unexpected end of file on `%1'", file);
290 return 0;
292 int lf = (c1 << 8) + c2;
293 int toread = lf*4 - 2;
294 unsigned char *buf = new unsigned char[toread];
295 if (fread(buf, 1, toread, fp) != (size_t)toread) {
296 if (feof(fp))
297 error("unexpected end of file on `%1'", file);
298 else
299 error("error on file `%1'", file);
300 a_delete buf;
301 fclose(fp);
302 return 0;
304 fclose(fp);
305 if (lf < 6) {
306 error("bad tfm file `%1': impossibly short", file);
307 a_delete buf;
308 return 0;
310 unsigned char *ptr = buf;
311 int lh = read2(ptr);
312 bc = read2(ptr);
313 ec = read2(ptr);
314 nw = read2(ptr);
315 nh = read2(ptr);
316 nd = read2(ptr);
317 ni = read2(ptr);
318 nl = read2(ptr);
319 nk = read2(ptr);
320 int ne = read2(ptr);
321 np = read2(ptr);
322 if (6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np != lf) {
323 error("bad tfm file `%1': lengths do not sum", file);
324 a_delete buf;
325 return 0;
327 if (lh < 2) {
328 error("bad tfm file `%1': header too short", file);
329 a_delete buf;
330 return 0;
332 char_info = new char_info_word[ec - bc + 1];
333 width = new int[nw];
334 height = new int[nh];
335 depth = new int[nd];
336 italic = new int[ni];
337 lig_kern = new lig_kern_command[nl];
338 kern = new int[nk];
339 param = new int[np];
340 int i;
341 cs = read4(ptr);
342 ds = read4(ptr);
343 ptr += (lh-2)*4;
344 for (i = 0; i < ec - bc + 1; i++) {
345 char_info[i].width_index = *ptr++;
346 unsigned char tem = *ptr++;
347 char_info[i].depth_index = tem & 0xf;
348 char_info[i].height_index = tem >> 4;
349 tem = *ptr++;
350 char_info[i].italic_index = tem >> 2;
351 char_info[i].tag = tem & 3;
352 char_info[i].remainder = *ptr++;
354 for (i = 0; i < nw; i++)
355 width[i] = read4(ptr);
356 for (i = 0; i < nh; i++)
357 height[i] = read4(ptr);
358 for (i = 0; i < nd; i++)
359 depth[i] = read4(ptr);
360 for (i = 0; i < ni; i++)
361 italic[i] = read4(ptr);
362 for (i = 0; i < nl; i++) {
363 lig_kern[i].skip_byte = *ptr++;
364 lig_kern[i].next_char = *ptr++;
365 lig_kern[i].op_byte = *ptr++;
366 lig_kern[i].remainder = *ptr++;
368 for (i = 0; i < nk; i++)
369 kern[i] = read4(ptr);
370 ptr += ne*4;
371 for (i = 0; i < np; i++)
372 param[i] = read4(ptr);
373 assert(ptr == buf + lf*4 - 2);
374 a_delete buf;
375 return 1;
378 class gf {
379 int left[256];
380 int right[256];
381 static int sread4(int *p, FILE *fp);
382 static int uread3(int *p, FILE *fp);
383 static int uread2(int *p, FILE *fp);
384 static int skip(int n, FILE *fp);
385 public:
386 gf();
387 int load(const char *file);
388 int get_left_adjustment(int i) { return left[i]; }
389 int get_right_adjustment(int i) { return right[i]; }
392 gf::gf()
394 for (int i = 0; i < 256; i++)
395 left[i] = right[i] = 0;
398 int gf::load(const char *file)
400 enum {
401 paint_0 = 0,
402 paint1 = 64,
403 boc = 67,
404 boc1 = 68,
405 eoc = 69,
406 skip0 = 70,
407 skip1 = 71,
408 new_row_0 = 74,
409 xxx1 = 239,
410 yyy = 243,
411 no_op = 244,
412 pre = 247,
413 post = 248
415 int got_an_adjustment = 0;
416 int pending_adjustment = 0;
417 int left_adj = 0, right_adj = 0; // pacify compiler
418 const int gf_id_byte = 131;
419 errno = 0;
420 FILE *fp = fopen(file, FOPEN_RB);
421 if (!fp) {
422 error("can't open `%1': %2", file, strerror(errno));
423 return 0;
425 if (getc(fp) != pre || getc(fp) != gf_id_byte) {
426 error("bad gf file");
427 return 0;
429 int n = getc(fp);
430 if (n == EOF)
431 goto eof;
432 if (!skip(n, fp))
433 goto eof;
434 for (;;) {
435 int op = getc(fp);
436 if (op == EOF)
437 goto eof;
438 if (op == post)
439 break;
440 if ((op >= paint_0 && op <= paint_0 + 63)
441 || (op >= new_row_0 && op <= new_row_0 + 164))
442 continue;
443 switch (op) {
444 case no_op:
445 case eoc:
446 case skip0:
447 break;
448 case paint1:
449 case skip1:
450 if (!skip(1, fp))
451 goto eof;
452 break;
453 case paint1 + 1:
454 case skip1 + 1:
455 if (!skip(2, fp))
456 goto eof;
457 break;
458 case paint1 + 2:
459 case skip1 + 2:
460 if (!skip(3, fp))
461 goto eof;
462 break;
463 case boc:
465 int code;
466 if (!sread4(&code, fp))
467 goto eof;
468 if (pending_adjustment) {
469 pending_adjustment = 0;
470 left[code & 0377] = left_adj;
471 right[code & 0377] = right_adj;
473 if (!skip(20, fp))
474 goto eof;
475 break;
477 case boc1:
479 int code = getc(fp);
480 if (code == EOF)
481 goto eof;
482 if (pending_adjustment) {
483 pending_adjustment = 0;
484 left[code] = left_adj;
485 right[code] = right_adj;
487 if (!skip(4, fp))
488 goto eof;
489 break;
491 case xxx1:
493 int len = getc(fp);
494 if (len == EOF)
495 goto eof;
496 char buf[256];
497 if (fread(buf, 1, len, fp) != (size_t)len)
498 goto eof;
499 if (len == 10 /* strlen("adjustment") */
500 && memcmp(buf, "adjustment", len) == 0) {
501 int c = getc(fp);
502 if (c != yyy) {
503 if (c != EOF)
504 ungetc(c, fp);
505 break;
507 if (!sread4(&left_adj, fp))
508 goto eof;
509 c = getc(fp);
510 if (c != yyy) {
511 if (c != EOF)
512 ungetc(c, fp);
513 break;
515 if (!sread4(&right_adj, fp))
516 goto eof;
517 got_an_adjustment = 1;
518 pending_adjustment = 1;
520 break;
522 case xxx1 + 1:
523 if (!uread2(&n, fp) || !skip(n, fp))
524 goto eof;
525 break;
526 case xxx1 + 2:
527 if (!uread3(&n, fp) || !skip(n, fp))
528 goto eof;
529 break;
530 case xxx1 + 3:
531 if (!sread4(&n, fp) || !skip(n, fp))
532 goto eof;
533 break;
534 case yyy:
535 if (!skip(4, fp))
536 goto eof;
537 break;
538 default:
539 fatal("unrecognized opcode `%1'", op);
540 break;
543 if (!got_an_adjustment)
544 warning("no adjustment specials found in gf file");
545 return 1;
546 eof:
547 error("unexpected end of file");
548 return 0;
551 int gf::sread4(int *p, FILE *fp)
553 *p = getc(fp);
554 if (*p >= 128)
555 *p -= 256;
556 *p <<= 8;
557 *p |= getc(fp);
558 *p <<= 8;
559 *p |= getc(fp);
560 *p <<= 8;
561 *p |= getc(fp);
562 return !ferror(fp) && !feof(fp);
565 int gf::uread3(int *p, FILE *fp)
567 *p = getc(fp);
568 *p <<= 8;
569 *p |= getc(fp);
570 *p <<= 8;
571 *p |= getc(fp);
572 return !ferror(fp) && !feof(fp);
575 int gf::uread2(int *p, FILE *fp)
577 *p = getc(fp);
578 *p <<= 8;
579 *p |= getc(fp);
580 return !ferror(fp) && !feof(fp);
583 int gf::skip(int n, FILE *fp)
585 while (--n >= 0)
586 if (getc(fp) == EOF)
587 return 0;
588 return 1;
592 struct char_list {
593 char *ch;
594 char_list *next;
595 char_list(const char *, char_list * = 0);
598 char_list::char_list(const char *s, char_list *p) : ch(strsave(s)), next(p)
603 int read_map(const char *file, char_list **table)
605 errno = 0;
606 FILE *fp = fopen(file, "r");
607 if (!fp) {
608 error("can't open `%1': %2", file, strerror(errno));
609 return 0;
611 for (int i = 0; i < 256; i++)
612 table[i] = 0;
613 char buf[512];
614 int lineno = 0;
615 while (fgets(buf, int(sizeof(buf)), fp)) {
616 lineno++;
617 char *ptr = buf;
618 while (csspace(*ptr))
619 ptr++;
620 if (*ptr == '\0' || *ptr == '#')
621 continue;
622 ptr = strtok(ptr, " \n\t");
623 if (!ptr)
624 continue;
625 int n;
626 if (sscanf(ptr, "%d", &n) != 1) {
627 error("%1:%2: bad map file", file, lineno);
628 fclose(fp);
629 return 0;
631 if (n < 0 || n > 255) {
632 error("%1:%2: code out of range", file, lineno);
633 fclose(fp);
634 return 0;
636 ptr = strtok(0, " \n\t");
637 if (!ptr) {
638 error("%1:%2: missing names", file, lineno);
639 fclose(fp);
640 return 0;
642 for (; ptr; ptr = strtok(0, " \n\t"))
643 table[n] = new char_list(ptr, table[n]);
645 fclose(fp);
646 return 1;
650 /* Every character that can participate in a ligature appears in the
651 lig_chars table. `ch' gives the full-name of the character, `name'
652 gives the groff name of the character, `i' gives its index in
653 the encoding, which is filled in later (-1 if it does not appear). */
655 struct S {
656 const char *ch;
657 int i;
658 } lig_chars[] = {
659 { "f", -1 },
660 { "i", -1 },
661 { "l", -1 },
662 { "ff", -1 },
663 { "fi", -1 },
664 { "fl", -1 },
665 { "Fi", -1 },
666 { "Fl", -1 },
669 // Indices into lig_chars[].
671 enum { CH_f, CH_i, CH_l, CH_ff, CH_fi, CH_fl, CH_ffi, CH_ffl };
673 // Each possible ligature appears in this table.
675 struct S2 {
676 unsigned char c1, c2, res;
677 const char *ch;
678 } lig_table[] = {
679 { CH_f, CH_f, CH_ff, "ff" },
680 { CH_f, CH_i, CH_fi, "fi" },
681 { CH_f, CH_l, CH_fl, "fl" },
682 { CH_ff, CH_i, CH_ffi, "ffi" },
683 { CH_ff, CH_l, CH_ffl, "ffl" },
686 static void usage(FILE *stream);
688 int main(int argc, char **argv)
690 program_name = argv[0];
691 int special_flag = 0;
692 int skewchar = -1;
693 int opt;
694 const char *gf_file = 0;
695 static const struct option long_options[] = {
696 { "help", no_argument, 0, CHAR_MAX + 1 },
697 { "version", no_argument, 0, 'v' },
698 { NULL, 0, 0, 0 }
700 while ((opt = getopt_long(argc, argv, "svg:k:", long_options, NULL)) != EOF)
701 switch (opt) {
702 case 'g':
703 gf_file = optarg;
704 break;
705 case 's':
706 special_flag = 1;
707 break;
708 case 'k':
710 char *ptr;
711 long n = strtol(optarg, &ptr, 0);
712 if ((n == 0 && ptr == optarg)
713 || *ptr != '\0'
714 || n < 0
715 || n > UCHAR_MAX)
716 error("invalid skewchar");
717 else
718 skewchar = (int)n;
719 break;
721 case 'v':
723 printf("GNU tfmtodit (groff) version %s\n", Version_string);
724 exit(0);
725 break;
727 case CHAR_MAX + 1: // --help
728 usage(stdout);
729 exit(0);
730 break;
731 case '?':
732 usage(stderr);
733 exit(1);
734 break;
735 case EOF:
736 assert(0);
738 if (argc - optind != 3) {
739 usage(stderr);
740 exit(1);
742 gf g;
743 if (gf_file) {
744 if (!g.load(gf_file))
745 return 1;
747 const char *tfm_file = argv[optind];
748 const char *map_file = argv[optind + 1];
749 const char *font_file = argv[optind + 2];
750 tfm t;
751 if (!t.load(tfm_file))
752 return 1;
753 char_list *table[256];
754 if (!read_map(map_file, table))
755 return 1;
756 errno = 0;
757 if (!freopen(font_file, "w", stdout)) {
758 error("can't open `%1' for writing: %2", font_file, strerror(errno));
759 return 1;
761 printf("name %s\n", font_file);
762 if (special_flag)
763 fputs("special\n", stdout);
764 char *internal_name = strsave(argv[optind]);
765 int len = strlen(internal_name);
766 if (len > 4 && strcmp(internal_name + len - 4, ".tfm") == 0)
767 internal_name[len - 4] = '\0';
768 // DIR_SEPS[] are possible directory separator characters, see nonposix.h.
769 // We want the rightmost separator of all possible ones.
770 // Example: d:/foo\\bar.
771 const char *s = strrchr(internal_name, DIR_SEPS[0]), *s1;
772 const char *sep = &DIR_SEPS[1];
773 while (*sep)
775 s1 = strrchr(internal_name, *sep);
776 if (s1 && (!s || s1 > s))
777 s = s1;
778 sep++;
780 printf("internalname %s\n", s ? s + 1 : internal_name);
781 int n;
782 if (t.get_param(2, &n)) {
783 if (n > 0)
784 printf("spacewidth %d\n", n*MULTIPLIER);
786 if (t.get_param(1, &n) && n != 0)
787 printf("slant %f\n", atan2(n/double(1<<20), 1.0)*180.0/PI);
788 int xheight;
789 if (!t.get_param(5, &xheight))
790 xheight = 0;
791 unsigned int i;
792 // Print the list of ligatures.
793 // First find the indices of each character that can participate in
794 // a ligature.
795 for (i = 0; i < 256; i++)
796 for (unsigned int j = 0; j < sizeof(lig_chars)/sizeof(lig_chars[0]); j++)
797 for (char_list *p = table[i]; p; p = p->next)
798 if (strcmp(lig_chars[j].ch, p->ch) == 0)
799 lig_chars[j].i = i;
800 // For each possible ligature, if its participants all exist,
801 // and it appears as a ligature in the tfm file, include in
802 // the list of ligatures.
803 int started = 0;
804 for (i = 0; i < sizeof(lig_table)/sizeof(lig_table[0]); i++) {
805 int i1 = lig_chars[lig_table[i].c1].i;
806 int i2 = lig_chars[lig_table[i].c2].i;
807 int r = lig_chars[lig_table[i].res].i;
808 if (i1 >= 0 && i2 >= 0 && r >= 0) {
809 unsigned char c;
810 if (t.get_lig(i1, i2, &c) && c == r) {
811 if (!started) {
812 started = 1;
813 fputs("ligatures", stdout);
815 printf(" %s", lig_table[i].ch);
819 if (started)
820 fputs(" 0\n", stdout);
821 printf("checksum %d\n", t.get_checksum());
822 printf("designsize %d\n", t.get_design_size());
823 // Now print out the kerning information.
824 int had_kern = 0;
825 kern_iterator iter(&t);
826 unsigned char c1, c2;
827 int k;
828 while (iter.next(&c1, &c2, &k))
829 if (c2 != skewchar) {
830 k *= MULTIPLIER;
831 char_list *q = table[c2];
832 for (char_list *p1 = table[c1]; p1; p1 = p1->next)
833 for (char_list *p2 = q; p2; p2 = p2->next) {
834 if (!had_kern) {
835 printf("kernpairs\n");
836 had_kern = 1;
838 printf("%s %s %d\n", p1->ch, p2->ch, k);
841 printf("charset\n");
842 char_list unnamed("---");
843 for (i = 0; i < 256; i++)
844 if (t.contains(i)) {
845 char_list *p = table[i] ? table[i] : &unnamed;
846 int m[6];
847 m[0] = t.get_width(i);
848 m[1] = t.get_height(i);
849 m[2] = t.get_depth(i);
850 m[3] = t.get_italic(i);
851 m[4] = g.get_left_adjustment(i);
852 m[5] = g.get_right_adjustment(i);
853 printf("%s\t%d", p->ch, m[0]*MULTIPLIER);
854 int j;
855 for (j = int(sizeof(m)/sizeof(m[0])) - 1; j > 0; j--)
856 if (m[j] != 0)
857 break;
858 for (k = 1; k <= j; k++)
859 printf(",%d", m[k]*MULTIPLIER);
860 int type = 0;
861 if (m[2] > 0)
862 type = 1;
863 if (m[1] > xheight)
864 type += 2;
865 printf("\t%d\t%04o\n", type, i);
866 for (p = p->next; p; p = p->next)
867 printf("%s\t\"\n", p->ch);
869 return 0;
872 static void usage(FILE *stream)
874 fprintf(stream, "usage: %s [-sv] [-g gf_file] [-k skewchar] tfm_file map_file font\n",
875 program_name);