* Makefile.in (SEP): Replaced with...
[s-roff.git] / src / xditview / xtotroff.c
blobcea0e70bac2fc34d7c5184b68bcb8f9ebd3c8be6
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 <string.h>
13 #include <fcntl.h>
14 #include "XFontName.h"
15 #include "DviChar.h"
17 #ifdef X_NOT_STDC_ENV
18 char *malloc();
19 #else
20 #include <stdlib.h>
21 #endif
23 /* XFontName.c */
24 extern Bool XParseFontName();
25 extern Bool XFormatFontName();
27 #define charWidth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].width)
28 #define charHeight(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].ascent)
29 #define charDepth(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].descent)
30 #define charLBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].lbearing)
31 #define charRBearing(fi,c) ((fi)->per_char[(c) - (fi)->min_char_or_byte2].rbearing)
33 Display *dpy;
34 int groff_flag = 0;
35 unsigned resolution = 75;
36 unsigned point_size = 10;
38 int charExists (fi, c)
39 XFontStruct *fi;
40 int c;
42 XCharStruct *p;
44 if (c < fi->min_char_or_byte2 || c > fi->max_char_or_byte2)
45 return 0;
46 p = fi->per_char + (c - fi->min_char_or_byte2);
47 return (p->lbearing != 0 || p->rbearing != 0 || p->width != 0
48 || p->ascent != 0 || p->descent != 0 || p->attributes != 0);
51 /* Canonicalize the font name by replacing scalable parts by *s. */
53 static int
54 CanonicalizeFontName (font_name, canon_font_name)
55 char *font_name, *canon_font_name;
57 unsigned int attributes;
58 XFontName parsed;
60 if (!XParseFontName(font_name, &parsed, &attributes)) {
61 fprintf (stderr, "not a standard name: %s\n", font_name);
62 return 0;
65 attributes &= ~(FontNamePixelSize|FontNameAverageWidth
66 |FontNamePointSize
67 |FontNameResolutionX|FontNameResolutionY);
68 XFormatFontName(&parsed, attributes, canon_font_name);
69 return 1;
72 static int
73 FontNamesAmbiguous(font_name, names, count)
74 char *font_name;
75 char **names;
76 int count;
78 char name1[2048], name2[2048];
79 int i;
81 if (count == 1)
82 return 0;
84 for (i = 0; i < count; i++) {
85 if (!CanonicalizeFontName(names[i], i == 0 ? name1 : name2)) {
86 fprintf(stderr, "bad font name: %s\n", names[i]);
87 return 1;
89 if (i > 0 && strcmp(name1, name2) != 0) {
90 fprintf(stderr, "ambiguous font name: %s\n", font_name);
91 fprintf(stderr, " matches %s\n", names[0]);
92 fprintf(stderr, " and %s\n", names[i]);
93 return 1;
97 return 0;
100 static int
101 MapFont (font_name, troff_name)
102 char *font_name;
103 char *troff_name;
105 XFontStruct *fi;
106 int count;
107 char **names;
108 FILE *out;
109 int c;
110 unsigned int attributes;
111 XFontName parsed;
112 int j, k;
113 DviCharNameMap *char_map;
114 char encoding[256];
115 char *s;
116 int wid;
117 char name_string[2048];
119 if (!XParseFontName(font_name, &parsed, &attributes)) {
120 fprintf (stderr, "not a standard name: %s\n", font_name);
121 return 0;
124 attributes &= ~(FontNamePixelSize|FontNameAverageWidth);
125 attributes |= FontNameResolutionX;
126 attributes |= FontNameResolutionY;
127 attributes |= FontNamePointSize;
128 parsed.ResolutionX = resolution;
129 parsed.ResolutionY = resolution;
130 parsed.PointSize = point_size*10;
131 XFormatFontName(&parsed, attributes, name_string);
133 names = XListFonts (dpy, name_string, 100000, &count);
134 if (count < 1) {
135 fprintf (stderr, "bad font name: %s\n", font_name);
136 return 0;
139 if (FontNamesAmbiguous(font_name, names, count))
140 return 0;
142 XParseFontName(names[0], &parsed, &attributes);
143 sprintf (encoding, "%s-%s", parsed.CharSetRegistry,
144 parsed.CharSetEncoding);
145 for (s = encoding; *s; s++)
146 if (isupper (*s))
147 *s = tolower (*s);
148 char_map = DviFindMap (encoding);
149 if (!char_map) {
150 fprintf (stderr, "not a standard encoding: %s\n", encoding);
151 return 0;
154 fi = XLoadQueryFont (dpy, names[0]);
155 if (!fi) {
156 fprintf (stderr, "font does not exist: %s\n", names[0]);
157 return 0;
160 printf ("%s -> %s\n", names[0], troff_name);
162 { /* Avoid race while opening file */
163 int fd;
164 (void) unlink (troff_name);
165 fd = open (troff_name, O_WRONLY | O_CREAT | O_EXCL, 0600);
166 out = fdopen (fd, "w");
169 if (!out) {
170 perror (troff_name);
171 return 0;
173 fprintf (out, "name %s\n", troff_name);
174 if (!strcmp (char_map->encoding, "adobe-fontspecific"))
175 fprintf (out, "special\n");
176 if (charExists (fi, ' ')) {
177 int w = charWidth (fi, ' ');
178 if (w > 0)
179 fprintf (out, "spacewidth %d\n", w);
181 fprintf (out, "charset\n");
182 for (c = fi->min_char_or_byte2; c <= fi->max_char_or_byte2; c++) {
183 char *name = DviCharName (char_map,c,0);
184 if (charExists (fi, c) && (groff_flag || name)) {
186 wid = charWidth (fi, c);
188 fprintf (out, "%s\t%d",
189 name ? name : "---",
190 wid);
191 if (groff_flag) {
192 int param[5];
193 param[0] = charHeight (fi, c);
194 param[1] = charDepth (fi, c);
195 param[2] = 0 /* charRBearing (fi, c) - wid */;
196 param[3] = 0 /* charLBearing (fi, c) */;
197 param[4] = 0; /* XXX */
198 for (j = 0; j < 5; j++)
199 if (param[j] < 0)
200 param[j] = 0;
201 for (j = 4; j >= 0; j--)
202 if (param[j] != 0)
203 break;
204 for (k = 0; k <= j; k++)
205 fprintf (out, ",%d", param[k]);
207 fprintf (out, "\t0\t0%o\n", c);
209 if (name) {
210 for (k = 1; DviCharName(char_map,c,k); k++) {
211 fprintf (out, "%s\t\"\n",
212 DviCharName (char_map,c,k));
217 XUnloadFont (dpy, fi->fid);
218 fclose (out);
219 return 1;
222 static void
223 usage(prog)
224 char *prog;
226 fprintf (stderr,
227 "usage: %s [-g] [-r resolution] [-s pointsize] FontMap\n",
228 prog);
229 exit (1);
233 /* For use by DviChar.c */
235 char *xmalloc(n)
236 int n;
238 char *p = malloc(n);
239 if (!p) {
240 fprintf(stderr, "Out of memory\n");
241 exit(1);
243 return p;
247 main (argc, argv)
248 char **argv;
250 char troff_name[1024];
251 char font_name[1024];
252 char line[1024];
253 char *a, *b, c;
254 int position;
255 FILE *map;
256 int opt;
257 extern int optind;
258 extern char *optarg;
260 while ((opt = getopt(argc, argv, "gr:s:")) != EOF) {
261 switch (opt) {
262 case 'g':
263 groff_flag = 1;
264 break;
265 case 'r':
266 sscanf(optarg, "%u", &resolution);
267 break;
268 case 's':
269 sscanf(optarg, "%u", &point_size);
270 break;
271 default:
272 usage(argv[0]);
275 if (argc - optind != 1)
276 usage(argv[0]);
278 dpy = XOpenDisplay (0);
279 if (!dpy) {
280 fprintf (stderr, "Can't connect to the X server.\n");
281 fprintf (stderr, "Make sure the DISPLAY environment variable is set correctly.\n");
282 exit (1);
284 position = 1;
286 map = fopen (argv[optind], "r");
287 if (map == NULL) {
288 perror (argv[optind]);
289 exit (1);
292 while (fgets (line, sizeof (line), map)) {
293 for (a=line,b=troff_name; *a; a++,b++) {
294 c = (*b = *a);
295 if (c == ' ' || c == '\t')
296 break;
298 *b = '\0';
299 while (*a && (*a == ' ' || *a == '\t'))
300 ++a;
301 for (b=font_name; *a; a++,b++)
302 if ((*b = *a) == '\n')
303 break;
304 *b = '\0';
305 if (!MapFont (font_name, troff_name))
306 exit (1);
307 ++position;
309 exit (0);
313 Local Variables:
314 c-indent-level: 8
315 c-continued-statement-offset: 8
316 c-brace-offset: -8
317 c-argdecl-indent: 8
318 c-label-offset: -8
319 c-tab-always-indent: nil
320 End: