1 /* Copyright (C) 1989-2020 Free Software Foundation, Inc.
2 Written by James Clark (jjc@jclark.com)
4 This file is part of groff.
6 groff is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 groff is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include "stringclass.h"
30 extern "C" const char *Version_string;
32 static void usage(FILE *stream);
34 static void usage(const char *problem);
35 static void version();
36 static void convert_font(const font_params &, FILE *, FILE *);
38 typedef int font_params::*param_t;
44 { "asc-height", &font_params::asc_height },
45 { "body-depth", &font_params::body_depth },
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 { "fig-height", &font_params::fig_height },
51 { "x-height", &font_params::x_height },
54 // These are all in thousandths of an em.
55 // These values are correct for PostScript Times Roman.
57 #define DEFAULT_X_HEIGHT 448
58 #define DEFAULT_FIG_HEIGHT 676
59 #define DEFAULT_ASC_HEIGHT 682
60 #define DEFAULT_BODY_HEIGHT 676
61 #define DEFAULT_CAP_HEIGHT 662
62 #define DEFAULT_COMMA_DEPTH 143
63 #define DEFAULT_DESC_DEPTH 217
64 #define DEFAULT_BODY_DEPTH 177
66 int main(int argc, char **argv)
68 program_name = argv[0];
70 for (i = 1; i < argc; i++) {
71 if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version"))
73 if (!strcmp(argv[i],"--help")) {
79 usage("insufficient arguments");
80 /* The next couple of usage() calls cannot provide a meaningful
81 diagnostic because we don't know whether sscanf() failed on a
82 required parameter or an option. A refactor could fix this. */
84 if (sscanf(argv[argc-3], "%d", &resolution) != 1)
87 fatal("resolution must be positive");
89 if (sscanf(argv[argc-2], "%d", &unitwidth) != 1)
92 fatal("unit width must be positive");
94 const char *font = argv[argc-1];
95 param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I');
96 param.em = (resolution*unitwidth)/72;
97 param.x_height = DEFAULT_X_HEIGHT;
98 param.fig_height = DEFAULT_FIG_HEIGHT;
99 param.asc_height = DEFAULT_ASC_HEIGHT;
100 param.body_height = DEFAULT_BODY_HEIGHT;
101 param.cap_height = DEFAULT_CAP_HEIGHT;
102 param.comma_depth = DEFAULT_COMMA_DEPTH;
103 param.desc_depth = DEFAULT_DESC_DEPTH;
104 param.body_depth = DEFAULT_BODY_DEPTH;
105 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
106 if (argv[i][1] == '-' && argv[i][2] == '\0') {
111 usage("option requires argument");
114 if (j >= sizeof(param_table)/sizeof(param_table[0]))
115 fatal("parameter '%1' not recognized", argv[i] + 1);
116 if (strcmp(param_table[j].name, argv[i] + 1) == 0)
119 if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1)
120 fatal("invalid option argument '%1'", argv[i+1]);
124 usage("insufficient arguments");
126 FILE *infp = fopen(font, "r");
128 fatal("can't open '%1': %2", font, strerror(errno));
129 convert_font(param, infp, stdout);
133 static void usage(FILE *stream)
135 fprintf(stream, "usage: %s", program_name);
136 size_t len = sizeof(param_table)/sizeof(param_table[0]);
137 for (size_t i = 0; i < len; i++)
138 fprintf(stream, " [-%s n]", param_table[i].name);
139 fputs(" resolution unit-width font\n", stream);
140 fprintf(stream, "usage: %s {-v | --version}\n"
141 "usage: %s --help\n", program_name, program_name);
150 static void usage(const char *problem)
152 error("%1", problem);
156 static void version()
158 printf("GNU addftinfo (groff) version %s\n", Version_string);
162 static int get_line(FILE *fp, string *p)
166 while ((c = getc(fp)) != EOF) {
171 return p->length() > 0;
174 static void convert_font(const font_params ¶m, FILE *infp,
178 while (get_line(infp, &s)) {
179 put_string(s, outfp);
181 && strncmp(&s[0], "charset", 7))
184 while (get_line(infp, &s)) {
187 const char *p = s.contents();
190 while (*p != '\0' && !csspace(*p))
194 for (const char *q = s.contents(); q < p; q++)
198 metric.width = (int)strtol(p, &next, 10);
200 printf("%d", metric.width);
202 metric.type = (int)strtol(p, &next, 10);
205 guess(name.contents(), param, &metric);
206 if (metric.sk == 0) {
207 if (metric.left_ic == 0) {
208 if (metric.ic == 0) {
209 if (metric.depth == 0) {
210 if (metric.height != 0)
211 printf(",%d", metric.height);
214 printf(",%d,%d", metric.height, metric.depth);
217 printf(",%d,%d,%d", metric.height, metric.depth,
221 printf(",%d,%d,%d,%d", metric.height, metric.depth,
222 metric.ic, metric.left_ic);
225 printf(",%d,%d,%d,%d,%d", metric.height, metric.depth,
226 metric.ic, metric.left_ic, metric.sk);
237 // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: