groff before CVS: release 1.06
[s-roff.git] / addftinfo / addftinfo.cc
blobe6d96695c8a7c67bffa5744d2d998af25f083b96
1 // -*- C++ -*-
2 /* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
3 Written by James Clark (jjc@jclark.com)
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include "lib.h"
28 #include "errarg.h"
29 #include "error.h"
30 #include "stringclass.h"
31 #include "cset.h"
32 #include "guess.h"
34 static void usage();
35 static void convert_font(const font_params &, FILE *, FILE *);
37 typedef font_params::*param_t;
39 static struct {
40 const char *name;
41 param_t par;
42 } param_table[] = {
43 "x-height", &font_params::x_height,
44 "fig-height", &font_params::fig_height,
45 "asc-height", &font_params::asc_height,
46 "body-height", &font_params::body_height,
47 "cap-height", &font_params::cap_height,
48 "comma-depth", &font_params::comma_depth,
49 "desc-depth", &font_params::desc_depth,
50 "body-depth", &font_params::body_depth,
53 // These are all in thousandths of an em.
54 // These values are correct for PostScript Times Roman.
56 #define DEFAULT_X_HEIGHT 448
57 #define DEFAULT_FIG_HEIGHT 676
58 #define DEFAULT_ASC_HEIGHT 682
59 #define DEFAULT_BODY_HEIGHT 676
60 #define DEFAULT_CAP_HEIGHT 662
61 #define DEFAULT_COMMA_DEPTH 143
62 #define DEFAULT_DESC_DEPTH 217
63 #define DEFAULT_BODY_DEPTH 177
65 int main(int argc, char **argv)
67 program_name = argv[0];
68 if (argc < 4)
69 usage();
70 int resolution;
71 if (sscanf(argv[argc-3], "%d", &resolution) != 1)
72 usage();
73 if (resolution <= 0)
74 fatal("resolution must be > 0");
75 int unitwidth;
76 if (sscanf(argv[argc-2], "%d", &unitwidth) != 1)
77 usage();
78 if (unitwidth <= 0)
79 fatal("unitwidth must be > 0");
80 font_params param;
81 const char *font = argv[argc-1];
82 param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I');
83 param.em = (resolution*unitwidth)/72;
84 param.x_height = DEFAULT_X_HEIGHT;
85 param.fig_height = DEFAULT_FIG_HEIGHT;
86 param.asc_height = DEFAULT_ASC_HEIGHT;
87 param.body_height = DEFAULT_BODY_HEIGHT;
88 param.cap_height = DEFAULT_CAP_HEIGHT;
89 param.comma_depth = DEFAULT_COMMA_DEPTH;
90 param.desc_depth = DEFAULT_DESC_DEPTH;
91 param.body_depth = DEFAULT_BODY_DEPTH;
92 for (int i = 1; i < argc && argv[i][0] == '-'; i++) {
93 if (argv[i][1] == '-' && argv[i][2] == '\0') {
94 i++;
95 break;
97 if (i + 1 >= argc)
98 usage();
99 for (int j = 0;; j++) {
100 if (j >= sizeof(param_table)/sizeof(param_table[0]))
101 fatal("parameter `%1' not recognized", argv[i] + 1);
102 if (strcmp(param_table[j].name, argv[i] + 1) == 0)
103 break;
105 if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1)
106 fatal("invalid argument `%1'", argv[i+1]);
107 i++;
109 if (argc - i != 3)
110 usage();
111 errno = 0;
112 FILE *infp = fopen(font, "r");
113 if (infp == 0)
114 fatal("can't open `%1': %2", font, strerror(errno));
115 convert_font(param, infp, stdout);
116 exit(0);
119 static void usage()
121 fprintf(stderr, "usage: %s [-param value] ... resolution unitwidth font\n",
122 program_name);
123 exit(1);
126 static int get_line(FILE *fp, string *p)
128 int c;
129 p->clear();
130 while ((c = getc(fp)) != EOF) {
131 *p += char(c);
132 if (c == '\n')
133 break;
135 return p->length() > 0;
138 static void convert_font(const font_params &param, FILE *infp, FILE *outfp)
140 string s;
141 while (get_line(infp, &s)) {
142 put_string(s, outfp);
143 if (s.length() >= 8
144 && strncmp(&s[0], "charset", 7))
145 break;
147 while (get_line(infp, &s)) {
148 s += '\0';
149 string name;
150 const char *p = s.contents();
151 while (csspace(*p))
152 p++;
153 while (*p != '\0' && !csspace(*p))
154 name += *p++;
155 while (csspace(*p))
156 p++;
157 for (const char *q = s.contents(); q < p; q++)
158 putc(*q, outfp);
159 char *next;
160 char_metric metric;
161 metric.width = (int)strtol(p, &next, 10);
162 if (next != p) {
163 printf("%d", metric.width);
164 p = next;
165 metric.type = (int)strtol(p, &next, 10);
166 if (next != p) {
167 name += '\0';
168 guess(name.contents(), param, &metric);
169 if (metric.sk == 0) {
170 if (metric.left_ic == 0) {
171 if (metric.ic == 0) {
172 if (metric.depth == 0) {
173 if (metric.height != 0)
174 printf(",%d", metric.height);
176 else
177 printf(",%d,%d", metric.height, metric.depth);
179 else
180 printf(",%d,%d,%d", metric.height, metric.depth, metric.ic);
182 else
183 printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
184 metric.left_ic);
186 else
187 printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
188 metric.left_ic, metric.sk);
191 fputs(p, outfp);