out: simply ignore unknown characters
[neatroff.git] / dev.c
blob49e6b94f79cca552a66e8ffdcd9d59c50d3eab02
1 /* output device */
2 #include <ctype.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "roff.h"
8 char dev_dir[PATHLEN]; /* device directory */
9 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 mounted 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 sprintf(path, "%s/dev%s/%s", dev_dir, dev_dev, name);
45 fn = font_open(path);
46 if (!fn)
47 return -1;
48 if (fn_font[pos])
49 font_close(fn_font[pos]);
50 if (fn_name[pos] != name) /* ignore if fn_name[pos] is passed */
51 strcpy(fn_name[pos], id);
52 fn_font[pos] = fn;
53 out("x font %d %s\n", pos, name);
54 return pos;
57 int dev_open(char *dir, char *dev)
59 char path[PATHLEN];
60 char tok[ILNLEN];
61 int i;
62 FILE *desc;
63 strcpy(dev_dir, dir);
64 strcpy(dev_dev, dev);
65 sprintf(path, "%s/dev%s/DESC", dir, dev);
66 desc = fopen(path, "r");
67 if (!desc)
68 return 1;
69 while (fscanf(desc, "%s", tok) == 1) {
70 if (tok[0] == '#') {
71 skipline(desc);
72 continue;
74 if (!strcmp("fonts", tok)) {
75 fscanf(desc, "%d", &fn_n);
76 for (i = 0; i < fn_n; i++)
77 fscanf(desc, "%s", fn_name[i + 1]);
78 fn_n++;
79 continue;
81 if (!strcmp("sizes", tok)) {
82 while (fscanf(desc, "%s", tok) == 1)
83 if (!strcmp("0", tok))
84 break;
85 continue;
87 if (!strcmp("res", tok)) {
88 fscanf(desc, "%d", &dev_res);
89 continue;
91 if (!strcmp("unitwidth", tok)) {
92 fscanf(desc, "%d", &dev_uwid);
93 continue;
95 if (!strcmp("hor", tok)) {
96 fscanf(desc, "%d", &dev_hor);
97 continue;
99 if (!strcmp("ver", tok)) {
100 fscanf(desc, "%d", &dev_ver);
101 continue;
103 if (!strcmp("charset", tok))
104 break;
105 skipline(desc);
107 fclose(desc);
108 dev_prologue();
109 for (i = 0; i < fn_n; i++)
110 if (*fn_name[i])
111 dev_mnt(i, fn_name[i], fn_name[i]);
112 return 0;
115 static void dev_epilogue(void)
117 out("x trailer\n");
118 out("x stop\n");
121 void dev_close(void)
123 int i;
124 dev_epilogue();
125 for (i = 0; i < fn_n; i++) {
126 if (fn_font[i])
127 font_close(fn_font[i]);
128 fn_font[i] = NULL;
132 /* glyph handling functions */
134 static struct glyph *dev_find(char *c, int fn, int byid)
136 struct glyph *(*find)(struct font *fn, char *name);
137 struct glyph *g;
138 int i;
139 find = byid ? font_glyph : font_find;
140 if ((g = find(fn_font[fn], c)))
141 return g;
142 for (i = 0; i < fspecial_n; i++)
143 if (dev_pos(fspecial_fn[i]) == fn && dev_pos(fspecial_sp[i]) >= 0)
144 if ((g = find(dev_font(dev_pos(fspecial_sp[i])), c)))
145 return g;
146 for (i = 0; i < fn_n; i++)
147 if (fn_font[i] && fn_font[i]->special)
148 if ((g = find(fn_font[i], c)))
149 return g;
150 return NULL;
153 struct glyph *dev_glyph(char *c, int fn)
155 if ((c[0] == c_ec || c[0] == c_ni) && c[1] == c_ec)
156 c++;
157 if (c[0] == c_ec && c[1] == '(')
158 c += 2;
159 return dev_find(cmap_map(c), fn, 0);
162 struct glyph *dev_glyph_byid(char *c, int fn)
164 return dev_find(c, fn, 1);
167 int dev_kernpair(char *c1, char *c2)
169 return 0;
172 /* return the mounted position of a font */
173 int dev_pos(char *id)
175 int i;
176 if (isdigit(id[0])) {
177 int num = atoi(id);
178 if (num < 0 || num >= fn_n || !fn_font[num]) {
179 errmsg("bad font position\n");
180 return -1;
182 return num;
184 for (i = 1; i < fn_n; i++)
185 if (!strcmp(fn_name[i], id))
186 return i;
187 if (!strcmp(fn_name[0], id))
188 return 0;
189 return dev_mnt(0, id, id);
192 /* return the mounted position of a font struct */
193 int dev_fontpos(struct font *fn)
195 int i;
196 for (i = 0; i < fn_n; i++)
197 if (fn_font[i] == fn)
198 return i;
199 return 0;
202 /* return the font struct at pos */
203 struct font *dev_font(int pos)
205 return pos >= 0 && pos < fn_n ? fn_font[pos] : NULL;
208 int dev_getcs(int fn)
210 return dev_font(fn)->cs;
213 void dev_setcs(int fn, int cs)
215 if (fn >= 0)
216 dev_font(fn)->cs = cs;
219 int dev_getbd(int fn)
221 return dev_font(fn)->bd;
224 void dev_setbd(int fn, int bd)
226 if (fn >= 0)
227 dev_font(fn)->bd = bd;
230 void tr_fspecial(char **args)
232 char *fn = args[1];
233 int i;
234 if (!fn) {
235 fspecial_n = 0;
236 return;
238 for (i = 2; i < NARGS; i++) {
239 if (args[i] && fspecial_n < LEN(fspecial_fn)) {
240 strcpy(fspecial_fn[fspecial_n], fn);
241 strcpy(fspecial_sp[fspecial_n], args[i]);
242 fspecial_n++;