1114402Sru// -*- C++ -*-
2114402Sru/* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc.
3114402Sru     Written by James Clark (jjc@jclark.com)
4114402Sru
5114402SruThis file is part of groff.
6114402Sru
7114402Srugroff is free software; you can redistribute it and/or modify it under
8114402Sruthe terms of the GNU General Public License as published by the Free
9114402SruSoftware Foundation; either version 2, or (at your option) any later
10114402Sruversion.
11114402Sru
12114402Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
13114402SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
14114402SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15114402Srufor more details.
16114402Sru
17114402SruYou should have received a copy of the GNU General Public License along
18114402Sruwith groff; see the file COPYING.  If not, write to the Free Software
19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
20114402Sru
21114402Sru#include "lib.h"
22114402Sru
23114402Sru#include <ctype.h>
24114402Sru#include <assert.h>
25114402Sru#include <stdlib.h>
26114402Sru#include <errno.h>
27114402Sru#include "errarg.h"
28114402Sru#include "error.h"
29114402Sru#include "stringclass.h"
30114402Sru#include "cset.h"
31114402Sru#include "guess.h"
32114402Sru
33114402Sruextern "C" const char *Version_string;
34114402Sru
35114402Srustatic void usage(FILE *stream);
36114402Srustatic void usage();
37114402Srustatic void version();
38114402Srustatic void convert_font(const font_params &, FILE *, FILE *);
39114402Sru
40114402Srutypedef int font_params::*param_t;
41114402Sru
42114402Srustatic struct {
43114402Sru  const char *name;
44114402Sru  param_t par;
45114402Sru} param_table[] = {
46114402Sru  { "x-height", &font_params::x_height },
47114402Sru  { "fig-height", &font_params::fig_height },
48114402Sru  { "asc-height", &font_params::asc_height },
49114402Sru  { "body-height", &font_params::body_height },
50114402Sru  { "cap-height", &font_params::cap_height },
51114402Sru  { "comma-depth", &font_params::comma_depth },
52114402Sru  { "desc-depth", &font_params::desc_depth },
53114402Sru  { "body-depth", &font_params::body_depth },
54114402Sru};
55114402Sru
56114402Sru// These are all in thousandths of an em.
57114402Sru// These values are correct for PostScript Times Roman.
58114402Sru
59114402Sru#define DEFAULT_X_HEIGHT 448
60114402Sru#define DEFAULT_FIG_HEIGHT 676
61114402Sru#define DEFAULT_ASC_HEIGHT 682
62114402Sru#define DEFAULT_BODY_HEIGHT 676
63114402Sru#define DEFAULT_CAP_HEIGHT 662
64114402Sru#define DEFAULT_COMMA_DEPTH 143
65114402Sru#define DEFAULT_DESC_DEPTH 217
66114402Sru#define DEFAULT_BODY_DEPTH 177
67114402Sru
68114402Sruint main(int argc, char **argv)
69114402Sru{
70114402Sru  program_name = argv[0];
71114402Sru  int i;
72114402Sru  for (i = 1; i < argc; i++) {
73114402Sru    if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version"))
74114402Sru      version();
75114402Sru    if (!strcmp(argv[i],"--help")) {
76114402Sru      usage(stdout);
77114402Sru      exit(0);
78114402Sru    }
79114402Sru  }
80114402Sru  if (argc < 4)
81114402Sru    usage();
82114402Sru  int resolution;
83114402Sru  if (sscanf(argv[argc-3], "%d", &resolution) != 1)
84114402Sru    usage();
85114402Sru  if (resolution <= 0)
86114402Sru    fatal("resolution must be > 0");
87114402Sru  int unitwidth;
88114402Sru  if (sscanf(argv[argc-2], "%d", &unitwidth) != 1)
89114402Sru    usage();
90114402Sru  if (unitwidth <= 0)
91114402Sru    fatal("unitwidth must be > 0");
92114402Sru  font_params param;
93114402Sru  const char *font = argv[argc-1];
94114402Sru  param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I');
95114402Sru  param.em = (resolution*unitwidth)/72;
96114402Sru  param.x_height = DEFAULT_X_HEIGHT;
97114402Sru  param.fig_height = DEFAULT_FIG_HEIGHT;
98114402Sru  param.asc_height = DEFAULT_ASC_HEIGHT;
99114402Sru  param.body_height = DEFAULT_BODY_HEIGHT;
100114402Sru  param.cap_height = DEFAULT_CAP_HEIGHT;
101114402Sru  param.comma_depth = DEFAULT_COMMA_DEPTH;
102114402Sru  param.desc_depth = DEFAULT_DESC_DEPTH;
103114402Sru  param.body_depth = DEFAULT_BODY_DEPTH;
104114402Sru  for (i = 1; i < argc && argv[i][0] == '-'; i++) {
105114402Sru    if (argv[i][1] == '-' && argv[i][2] == '\0') {
106114402Sru      i++;
107114402Sru      break;
108114402Sru    }
109114402Sru    if (i + 1 >= argc)
110114402Sru      usage();
111114402Sru    size_t j;
112114402Sru    for (j = 0;; j++) {
113114402Sru      if (j >= sizeof(param_table)/sizeof(param_table[0]))
114114402Sru	fatal("parameter `%1' not recognized", argv[i] + 1);
115114402Sru      if (strcmp(param_table[j].name, argv[i] + 1) == 0)
116114402Sru	break;
117114402Sru    }
118114402Sru    if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1)
119114402Sru      fatal("invalid argument `%1'", argv[i+1]);
120114402Sru    i++;
121114402Sru  }
122114402Sru  if (argc - i != 3)
123114402Sru    usage();
124114402Sru  errno = 0;
125114402Sru  FILE *infp = fopen(font, "r");
126114402Sru  if (infp == 0)
127114402Sru    fatal("can't open `%1': %2", font, strerror(errno));
128114402Sru  convert_font(param, infp, stdout);
129114402Sru  return 0;
130114402Sru}
131114402Sru
132114402Srustatic void usage(FILE *stream)
133114402Sru{
134114402Sru  fprintf(stream, "usage: %s [-v] [-param value] ... "
135114402Sru		  "resolution unitwidth font\n",
136114402Sru	  program_name);
137114402Sru}
138114402Srustatic void usage()
139114402Sru{
140114402Sru  usage(stderr);
141114402Sru  exit(1);
142114402Sru}
143114402Sru
144114402Srustatic void version()
145114402Sru{
146114402Sru  printf("GNU addftinfo (groff) version %s\n", Version_string);
147114402Sru  exit(0);
148114402Sru}
149114402Sru
150114402Srustatic int get_line(FILE *fp, string *p)
151114402Sru{
152114402Sru  int c;
153114402Sru  p->clear();
154114402Sru  while ((c = getc(fp)) != EOF) {
155114402Sru    *p += char(c);
156114402Sru    if (c == '\n')
157114402Sru      break;
158114402Sru  }
159114402Sru  return p->length() > 0;
160114402Sru}
161114402Sru
162114402Srustatic void convert_font(const font_params &param, FILE *infp, FILE *outfp)
163114402Sru{
164114402Sru  string s;
165114402Sru  while (get_line(infp, &s)) {
166114402Sru    put_string(s, outfp);
167114402Sru    if (s.length() >= 8
168114402Sru	&& strncmp(&s[0], "charset", 7))
169114402Sru      break;
170114402Sru  }
171114402Sru  while (get_line(infp, &s)) {
172114402Sru    s += '\0';
173114402Sru    string name;
174114402Sru    const char *p = s.contents();
175114402Sru    while (csspace(*p))
176114402Sru      p++;
177114402Sru    while (*p != '\0' && !csspace(*p))
178114402Sru      name += *p++;
179114402Sru    while (csspace(*p))
180114402Sru      p++;
181114402Sru    for (const char *q = s.contents(); q < p; q++)
182114402Sru      putc(*q, outfp);
183114402Sru    char *next;
184114402Sru    char_metric metric;
185114402Sru    metric.width = (int)strtol(p, &next, 10);
186114402Sru    if (next != p) {
187114402Sru      printf("%d", metric.width);
188114402Sru      p = next;
189114402Sru      metric.type = (int)strtol(p, &next, 10);
190114402Sru      if (next != p) {
191114402Sru	name += '\0';
192114402Sru	guess(name.contents(), param, &metric);
193114402Sru	if (metric.sk == 0) {
194114402Sru	  if (metric.left_ic == 0) {
195114402Sru	    if (metric.ic == 0) {
196114402Sru	      if (metric.depth == 0) {
197114402Sru		if (metric.height != 0)
198114402Sru		  printf(",%d", metric.height);
199114402Sru	      }
200114402Sru	      else
201114402Sru		printf(",%d,%d", metric.height, metric.depth);
202114402Sru	    }
203114402Sru	    else
204114402Sru	      printf(",%d,%d,%d", metric.height, metric.depth, metric.ic);
205114402Sru	  }
206114402Sru	  else
207114402Sru	    printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
208114402Sru		   metric.left_ic);
209114402Sru	}
210114402Sru	else
211114402Sru	  printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
212114402Sru		 metric.left_ic, metric.sk);
213114402Sru      }
214114402Sru    }
215114402Sru    fputs(p, outfp);
216114402Sru  }
217114402Sru}
218114402Sru
219