* Dvi.c (OpenFile): Use tmpdir() for security reasons.
[s-roff.git] / src / xditview / xtotroff.c
blob97cac0a5893f8c9a88a8728e0bae3f281467c00a
1 /*
2 * xtotroff
4 * convert X font metrics into troff font metrics
5 */
7 #include <X11/Xlib.h>
8 #include <stdio.h>
9 #include <ctype.h>
10 #include <unistd.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include "XFontName.h"
14 #include "DviChar.h"
16 #ifdef X_NOT_STDC_ENV
17 char *malloc();
18 #else
19 #include <stdlib.h>
20 #endif
22 #define charWidth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width)
23 #define charHeight(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent)
24 #define charDepth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent)
25 #define charLBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing)
26 #define charRBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing)
28 Display *dpy;
29 int groff_flag = 0;
30 unsigned resolution = 75;
31 unsigned point_size = 10;
33 int charExists (fi, c)
34 XFontStruct *fi;
35 int c;
37 XCharStruct *p;
39 if (c < fi->min_char_or_byte2 || c > fi->max_char_or_byte2)
40 return 0;
41 p = fi->per_char + (c - fi->min_char_or_byte2);
42 return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0
43 || p->ascent != 0 || p->descent != 0 || p->attributes != 0);
46 /* Canonicalize the font name by replacing scalable parts by *s. */
48 CanonicalizeFontName (font_name, canon_font_name)
49 char *font_name, *canon_font_name;
51 unsigned int attributes;
52 XFontName parsed;
54 if (!XParseFontName(font_name, &parsed, &attributes)) {
55 fprintf (stderr, "not a standard name: %s\n", font_name);
56 return 0;
59 attributes &= ~(FontNamePixelSize|FontNameAverageWidth
60 |FontNamePointSize
61 |FontNameResolutionX|FontNameResolutionY);
62 XFormatFontName(&parsed, attributes, canon_font_name);
63 return 1;
66 int FontNamesAmbiguous(font_name, names, count)
67 char *font_name;
68 char **names;
69 int count;
71 char name1[2048], name2[2048];
72 int i;
74 if (count == 1)
75 return 0;
77 for (i = 0; i < count; i++) {
78 if (!CanonicalizeFontName(names[i], i == 0 ? name1 : name2)) {
79 fprintf(stderr, "bad font name: %s\n", names[i]);
80 return 1;
82 if (i > 0 && strcmp(name1, name2) != 0) {
83 fprintf(stderr, "ambiguous font name: %s\n", font_name);
84 fprintf(stderr, " matches %s\n", names[0]);
85 fprintf(stderr, " and %s\n", names[i]);
86 return 1;
90 return 0;
93 MapFont (font_name, troff_name)
94 char *font_name;
95 char *troff_name;
97 XFontStruct *fi;
98 int count;
99 char **names;
100 FILE *out;
101 int c;
102 unsigned int attributes;
103 XFontName parsed;
104 int j, k;
105 DviCharNameMap *char_map;
106 char encoding[256];
107 char *s;
108 int wid;
109 char name_string[2048];
111 if (!XParseFontName(font_name, &parsed, &attributes)) {
112 fprintf (stderr, "not a standard name: %s\n", font_name);
113 return 0;
116 attributes &= ~(FontNamePixelSize|FontNameAverageWidth);
117 attributes |= FontNameResolutionX;
118 attributes |= FontNameResolutionY;
119 attributes |= FontNamePointSize;
120 parsed.ResolutionX = resolution;
121 parsed.ResolutionY = resolution;
122 parsed.PointSize = point_size*10;
123 XFormatFontName(&parsed, attributes, name_string);
125 names = XListFonts (dpy, name_string, 100000, &count);
126 if (count < 1) {
127 fprintf (stderr, "bad font name: %s\n", font_name);
128 return 0;
131 if (FontNamesAmbiguous(font_name, names, count))
132 return 0;
134 XParseFontName(names[0], &parsed, &attributes);
135 sprintf (encoding, "%s-%s", parsed.CharSetRegistry,
136 parsed.CharSetEncoding);
137 for (s = encoding; *s; s++)
138 if (isupper (*s))
139 *s = tolower (*s);
140 char_map = DviFindMap (encoding);
141 if (!char_map) {
142 fprintf (stderr, "not a standard encoding: %s\n", encoding);
143 return 0;
146 fi = XLoadQueryFont (dpy, names[0]);
147 if (!fi) {
148 fprintf (stderr, "font does not exist: %s\n", names[0]);
149 return 0;
152 printf ("%s -> %s\n", names[0], troff_name);
154 { /* Avoid race while opening file */
155 int fd;
156 (void) unlink (troff_name);
157 fd = open (troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
158 out = fdopen (fd, "w");
161 if (!out) {
162 perror (troff_name);
163 return 0;
165 fprintf (out, "name %s\n", troff_name);
166 if (!strcmp (char_map->encoding, "adobe-fontspecific"))
167 fprintf (out, "special\n");
168 if (charExists (fi, ' ')) {
169 int w = charWidth (fi, ' ');
170 if (w > 0)
171 fprintf (out, "spacewidth %d\n", w);
173 fprintf (out, "charset\n");
174 for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) {
175 char *name = DviCharName (char_map,c,0);
176 if (charExists (fi, c) && (groff_flag || name)) {
178 wid = charWidth (fi, c);
180 fprintf (out, "%s\t%d",
181 name ? name : "---",
182 wid);
183 if (groff_flag) {
184 int param[5];
185 param[0] = charHeight (fi, c);
186 param[1] = charDepth (fi, c);
187 param[2] = 0 /* charRBearing (fi, c) - wid */;
188 param[3] = 0 /* charLBearing (fi, c) */;
189 param[4] = 0; /* XXX */
190 for (j = 0; j < 5; j++)
191 if (param[j] < 0)
192 param[j] = 0;
193 for (j = 4; j >= 0; j--)
194 if (param[j] != 0)
195 break;
196 for (k = 0; k <= j; k++)
197 fprintf (out, ",%d", param[k]);
199 fprintf (out, "\t0\t0%o\n", c);
201 if (name) {
202 for (k = 1; DviCharName(char_map,c,k); k++) {
203 fprintf (out, "%s\t\"\n",
204 DviCharName (char_map,c,k));
209 XUnloadFont (dpy, fi->fid);
210 fclose (out);
211 return 1;
214 static usage(prog)
215 char *prog;
217 fprintf (stderr,
218 "usage: %s [-g] [-r resolution] [-s pointsize] FontMap\n",
219 prog);
220 exit (1);
224 /* For use by DviChar.c */
226 char *xmalloc(n)
227 int n;
229 char *p = malloc(n);
230 if (!p) {
231 fprintf(stderr, "Out of memory\n");
232 exit(1);
234 return p;
237 main (argc, argv)
238 char **argv;
240 char troff_name[1024];
241 char font_name[1024];
242 char line[1024];
243 char *a, *b, c;
244 int position;
245 FILE *map;
246 int opt;
247 extern int optind;
248 extern char *optarg;
250 while ((opt = getopt(argc, argv, "gr:s:")) != EOF) {
251 switch (opt) {
252 case 'g':
253 groff_flag = 1;
254 break;
255 case 'r':
256 sscanf(optarg, "%u", &resolution);
257 break;
258 case 's':
259 sscanf(optarg, "%u", &point_size);
260 break;
261 default:
262 usage(argv[0]);
265 if (argc - optind != 1)
266 usage(argv[0]);
268 dpy = XOpenDisplay (0);
269 if (!dpy) {
270 fprintf (stderr, "Can't connect to the X server.\n");
271 fprintf (stderr, "Make sure the DISPLAY environment variable is set correctly.\n");
272 exit (1);
274 position = 1;
276 map = fopen (argv[optind], "r");
277 if (map == NULL) {
278 perror (argv[optind]);
279 exit (1);
282 while (fgets (line, sizeof (line), map)) {
283 for (a=line,b=troff_name; *a; a++,b++) {
284 c = (*b = *a);
285 if (c == ' ' || c == '\t')
286 break;
288 *b = '\0';
289 while (*a && (*a == ' ' || *a == '\t'))
290 ++a;
291 for (b=font_name; *a; a++,b++)
292 if ((*b = *a) == '\n')
293 break;
294 *b = '\0';
295 if (!MapFont (font_name, troff_name))
296 exit (1);
297 ++position;
299 exit (0);
303 Local Variables:
304 c-indent-level: 8
305 c-continued-statement-offset: 8
306 c-brace-offset: -8
307 c-argdecl-indent: 8
308 c-label-offset: -8
309 c-tab-always-indent: nil
310 End: