tr: clean up macrobody()
[neatroff.git] / dev.c
blobe76b2c9ab808a0839da2c76f3fe85e1529dd1254
1 /* output device */
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "roff.h"
8 static char dev_dir[PATHLEN]; /* device directory */
9 static char dev_dev[PATHLEN]; /* output device name */
10 int dev_res; /* device resolution */
11 int dev_uwid; /* device unitwidth */
12 int dev_hor; /* minimum horizontal movement */
13 int dev_ver; /* minimum vertical movement */
15 /* mounted fonts */
16 static char fn_name[NFONTS][FNLEN]; /* font names */
17 static struct font *fn_font[NFONTS]; /* font structs */
18 static int fn_n; /* number of device fonts */
20 /* .fspecial request */
21 static char fspecial_fn[NFONTS][FNLEN]; /* .fspecial first arguments */
22 static char fspecial_sp[NFONTS][FNLEN]; /* .fspecial special fonts */
23 static int fspecial_n; /* number of fonts in fspecial_sp[] */
25 static void skipline(FILE* filp)
27 int c;
28 do {
29 c = getc(filp);
30 } while (c != '\n' && c != EOF);
33 static void dev_prologue(void)
35 out("x T %s\n", dev_dev);
36 out("x res %d %d %d\n", dev_res, dev_hor, dev_ver);
37 out("x init\n");
40 int dev_mnt(int pos, char *id, char *name)
42 char path[PATHLEN];
43 struct font *fn;
44 if (pos >= NFONTS)
45 return -1;
46 sprintf(path, "%s/dev%s/%s", dev_dir, dev_dev, name);
47 fn = font_open(path);
48 if (!fn)
49 return -1;
50 if (fn_font[pos])
51 font_close(fn_font[pos]);
52 if (fn_name[pos] != name) /* ignore if fn_name[pos] is passed */
53 strcpy(fn_name[pos], id);
54 fn_font[pos] = fn;
55 out("x font %d %s\n", pos, name);
56 return pos;
59 int dev_open(char *dir, char *dev)
61 char path[PATHLEN];
62 char tok[ILNLEN];
63 int i;
64 FILE *desc;
65 strcpy(dev_dir, dir);
66 strcpy(dev_dev, dev);
67 sprintf(path, "%s/dev%s/DESC", dir, dev);
68 desc = fopen(path, "r");
69 if (!desc)
70 return 1;
71 while (fscanf(desc, "%s", tok) == 1) {
72 if (tok[0] == '#') {
73 skipline(desc);
74 continue;
76 if (!strcmp("fonts", tok)) {
77 fscanf(desc, "%d", &fn_n);
78 for (i = 0; i < fn_n; i++)
79 fscanf(desc, "%s", fn_name[i + 1]);
80 fn_n++;
81 continue;
83 if (!strcmp("sizes", tok)) {
84 while (fscanf(desc, "%s", tok) == 1)
85 if (!strcmp("0", tok))
86 break;
87 continue;
89 if (!strcmp("res", tok)) {
90 fscanf(desc, "%d", &dev_res);
91 continue;
93 if (!strcmp("unitwidth", tok)) {
94 fscanf(desc, "%d", &dev_uwid);
95 continue;
97 if (!strcmp("hor", tok)) {
98 fscanf(desc, "%d", &dev_hor);
99 continue;
101 if (!strcmp("ver", tok)) {
102 fscanf(desc, "%d", &dev_ver);
103 continue;
105 if (!strcmp("charset", tok))
106 break;
107 skipline(desc);
109 fclose(desc);
110 dev_prologue();
111 for (i = 0; i < fn_n; i++)
112 if (*fn_name[i])
113 dev_mnt(i, fn_name[i], fn_name[i]);
114 return 0;
117 static void dev_epilogue(void)
119 out("x trailer\n");
120 out("x stop\n");
123 void dev_close(void)
125 int i;
126 dev_epilogue();
127 for (i = 0; i < NFONTS; i++) {
128 if (fn_font[i])
129 font_close(fn_font[i]);
130 fn_font[i] = NULL;
134 /* glyph handling functions */
136 static struct glyph *dev_find(char *c, int fn, int byid)
138 struct glyph *(*find)(struct font *fn, char *name);
139 struct glyph *g;
140 int i;
141 find = byid ? font_glyph : font_find;
142 if ((g = find(fn_font[fn], c)))
143 return g;
144 for (i = 0; i < fspecial_n; i++)
145 if (dev_pos(fspecial_fn[i]) == fn && dev_pos(fspecial_sp[i]) >= 0)
146 if ((g = find(dev_font(dev_pos(fspecial_sp[i])), c)))
147 return g;
148 for (i = 0; i < NFONTS; i++)
149 if (fn_font[i] && fn_font[i]->special)
150 if ((g = find(fn_font[i], c)))
151 return g;
152 return NULL;
155 struct glyph *dev_glyph(char *c, int fn)
157 if ((c[0] == c_ec || c[0] == c_ni) && c[1] == c_ec)
158 c++;
159 if (c[0] == c_ec && c[1] == '(')
160 c += 2;
161 c = cmap_map(c);
162 if (!strncmp("GID=", c, 4))
163 return dev_find(c + 4, fn, 1);
164 return dev_find(c, fn, 0);
167 /* return the mounted position of a font */
168 int dev_pos(char *id)
170 int i;
171 if (isdigit(id[0])) {
172 int num = atoi(id);
173 if (num < 0 || num >= NFONTS || !fn_font[num]) {
174 errmsg("bad font position\n");
175 return -1;
177 return num;
179 for (i = 1; i < NFONTS; i++)
180 if (!strcmp(fn_name[i], id))
181 return i;
182 if (!strcmp(fn_name[0], id))
183 return 0;
184 return dev_mnt(0, id, id);
187 /* return the mounted position of a font struct */
188 int dev_fontpos(struct font *fn)
190 int i;
191 for (i = 0; i < NFONTS; i++)
192 if (fn_font[i] == fn)
193 return i;
194 return 0;
197 /* return the font struct at pos */
198 struct font *dev_font(int pos)
200 return pos >= 0 && pos < NFONTS ? fn_font[pos] : NULL;
203 int dev_getcs(int fn)
205 return dev_font(fn)->cs;
208 void dev_setcs(int fn, int cs)
210 if (fn >= 0)
211 dev_font(fn)->cs = cs;
214 int dev_getbd(int fn)
216 return dev_font(fn)->bd;
219 void dev_setbd(int fn, int bd)
221 if (fn >= 0)
222 dev_font(fn)->bd = bd;
225 void tr_fspecial(char **args)
227 char *fn = args[1];
228 int i;
229 if (!fn) {
230 fspecial_n = 0;
231 return;
233 for (i = 2; i < NARGS; i++) {
234 if (args[i] && fspecial_n < LEN(fspecial_fn)) {
235 strcpy(fspecial_fn[fspecial_n], fn);
236 strcpy(fspecial_sp[fspecial_n], args[i]);
237 fspecial_n++;