xref: /netbsd-src/external/gpl2/groff/dist/src/utils/addftinfo/addftinfo.cpp (revision 89a07cf815a29524268025a1139fac4c5190f765)
1 /*	$NetBSD: addftinfo.cpp,v 1.1.1.1 2016/01/13 18:41:49 christos Exp $	*/
2 
3 // -*- C++ -*-
4 /* Copyright (C) 1989-1992, 2000, 2001 Free Software Foundation, Inc.
5      Written by James Clark (jjc@jclark.com)
6 
7 This file is part of groff.
8 
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.
13 
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.
18 
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. */
22 
23 #include "lib.h"
24 
25 #include <ctype.h>
26 #include <assert.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include "errarg.h"
30 #include "error.h"
31 #include "stringclass.h"
32 #include "cset.h"
33 #include "guess.h"
34 
35 extern "C" const char *Version_string;
36 
37 static void usage(FILE *stream);
38 static void usage();
39 static void version();
40 static void convert_font(const font_params &, FILE *, FILE *);
41 
42 typedef int font_params::*param_t;
43 
44 static struct {
45   const char *name;
46   param_t par;
47 } param_table[] = {
48   { "x-height", &font_params::x_height },
49   { "fig-height", &font_params::fig_height },
50   { "asc-height", &font_params::asc_height },
51   { "body-height", &font_params::body_height },
52   { "cap-height", &font_params::cap_height },
53   { "comma-depth", &font_params::comma_depth },
54   { "desc-depth", &font_params::desc_depth },
55   { "body-depth", &font_params::body_depth },
56 };
57 
58 // These are all in thousandths of an em.
59 // These values are correct for PostScript Times Roman.
60 
61 #define DEFAULT_X_HEIGHT 448
62 #define DEFAULT_FIG_HEIGHT 676
63 #define DEFAULT_ASC_HEIGHT 682
64 #define DEFAULT_BODY_HEIGHT 676
65 #define DEFAULT_CAP_HEIGHT 662
66 #define DEFAULT_COMMA_DEPTH 143
67 #define DEFAULT_DESC_DEPTH 217
68 #define DEFAULT_BODY_DEPTH 177
69 
main(int argc,char ** argv)70 int main(int argc, char **argv)
71 {
72   program_name = argv[0];
73   int i;
74   for (i = 1; i < argc; i++) {
75     if (!strcmp(argv[i], "-v") || !strcmp(argv[i],"--version"))
76       version();
77     if (!strcmp(argv[i],"--help")) {
78       usage(stdout);
79       exit(0);
80     }
81   }
82   if (argc < 4)
83     usage();
84   int resolution;
85   if (sscanf(argv[argc-3], "%d", &resolution) != 1)
86     usage();
87   if (resolution <= 0)
88     fatal("resolution must be > 0");
89   int unitwidth;
90   if (sscanf(argv[argc-2], "%d", &unitwidth) != 1)
91     usage();
92   if (unitwidth <= 0)
93     fatal("unitwidth must be > 0");
94   font_params param;
95   const char *font = argv[argc-1];
96   param.italic = (font[0] != '\0' && strchr(font, '\0')[-1] == 'I');
97   param.em = (resolution*unitwidth)/72;
98   param.x_height = DEFAULT_X_HEIGHT;
99   param.fig_height = DEFAULT_FIG_HEIGHT;
100   param.asc_height = DEFAULT_ASC_HEIGHT;
101   param.body_height = DEFAULT_BODY_HEIGHT;
102   param.cap_height = DEFAULT_CAP_HEIGHT;
103   param.comma_depth = DEFAULT_COMMA_DEPTH;
104   param.desc_depth = DEFAULT_DESC_DEPTH;
105   param.body_depth = DEFAULT_BODY_DEPTH;
106   for (i = 1; i < argc && argv[i][0] == '-'; i++) {
107     if (argv[i][1] == '-' && argv[i][2] == '\0') {
108       i++;
109       break;
110     }
111     if (i + 1 >= argc)
112       usage();
113     size_t j;
114     for (j = 0;; j++) {
115       if (j >= sizeof(param_table)/sizeof(param_table[0]))
116 	fatal("parameter `%1' not recognized", argv[i] + 1);
117       if (strcmp(param_table[j].name, argv[i] + 1) == 0)
118 	break;
119     }
120     if (sscanf(argv[i+1], "%d", &(param.*(param_table[j].par))) != 1)
121       fatal("invalid argument `%1'", argv[i+1]);
122     i++;
123   }
124   if (argc - i != 3)
125     usage();
126   errno = 0;
127   FILE *infp = fopen(font, "r");
128   if (infp == 0)
129     fatal("can't open `%1': %2", font, strerror(errno));
130   convert_font(param, infp, stdout);
131   return 0;
132 }
133 
usage(FILE * stream)134 static void usage(FILE *stream)
135 {
136   fprintf(stream, "usage: %s [-v] [-param value] ... "
137 		  "resolution unitwidth font\n",
138 	  program_name);
139 }
usage()140 static void usage()
141 {
142   usage(stderr);
143   exit(1);
144 }
145 
version()146 static void version()
147 {
148   printf("GNU addftinfo (groff) version %s\n", Version_string);
149   exit(0);
150 }
151 
get_line(FILE * fp,string * p)152 static int get_line(FILE *fp, string *p)
153 {
154   int c;
155   p->clear();
156   while ((c = getc(fp)) != EOF) {
157     *p += char(c);
158     if (c == '\n')
159       break;
160   }
161   return p->length() > 0;
162 }
163 
convert_font(const font_params & param,FILE * infp,FILE * outfp)164 static void convert_font(const font_params &param, FILE *infp, FILE *outfp)
165 {
166   string s;
167   while (get_line(infp, &s)) {
168     put_string(s, outfp);
169     if (s.length() >= 8
170 	&& strncmp(&s[0], "charset", 7))
171       break;
172   }
173   while (get_line(infp, &s)) {
174     s += '\0';
175     string name;
176     const char *p = s.contents();
177     while (csspace(*p))
178       p++;
179     while (*p != '\0' && !csspace(*p))
180       name += *p++;
181     while (csspace(*p))
182       p++;
183     for (const char *q = s.contents(); q < p; q++)
184       putc(*q, outfp);
185     char *next;
186     char_metric metric;
187     metric.width = (int)strtol(p, &next, 10);
188     if (next != p) {
189       printf("%d", metric.width);
190       p = next;
191       metric.type = (int)strtol(p, &next, 10);
192       if (next != p) {
193 	name += '\0';
194 	guess(name.contents(), param, &metric);
195 	if (metric.sk == 0) {
196 	  if (metric.left_ic == 0) {
197 	    if (metric.ic == 0) {
198 	      if (metric.depth == 0) {
199 		if (metric.height != 0)
200 		  printf(",%d", metric.height);
201 	      }
202 	      else
203 		printf(",%d,%d", metric.height, metric.depth);
204 	    }
205 	    else
206 	      printf(",%d,%d,%d", metric.height, metric.depth, metric.ic);
207 	  }
208 	  else
209 	    printf(",%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
210 		   metric.left_ic);
211 	}
212 	else
213 	  printf(",%d,%d,%d,%d,%d", metric.height, metric.depth, metric.ic,
214 		 metric.left_ic, metric.sk);
215       }
216     }
217     fputs(p, outfp);
218   }
219 }
220 
221