out: add unicode aliases for fixlist[]
[neatpost.git] / out.c
blob6bfb864486b2deded92a7817ff7927ee487e19ae
1 #include <ctype.h>
2 #include <stdarg.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "post.h"
8 static int o_f, o_s, o_m; /* font and size */
9 static int o_h, o_v; /* current user position */
10 static int p_f, p_s, p_m; /* output postscript font */
11 static int o_qtype; /* queued character type */
12 static int o_qv, o_qh, o_qend; /* queued character position */
13 char o_fonts[FNLEN * NFONTS] = " ";
15 static void outvf(char *s, va_list ap)
17 vfprintf(stdout, s, ap);
20 void outf(char *s, ...)
22 va_list ap;
23 va_start(ap, s);
24 outvf(s, ap);
25 va_end(ap);
28 static void o_flush(void)
30 if (o_qtype == 1)
31 outf(") %d %d w\n", o_qh, o_qv);
32 if (o_qtype == 2)
33 outf("] %d %d g\n", o_qh, o_qv);
34 o_qtype = 0;
37 void outpage(void)
39 o_flush();
40 o_v = 0;
41 o_h = 0;
42 p_s = 0;
43 p_f = 0;
44 p_m = 0;
47 static void o_queue(struct glyph *g)
49 int type = 1 + !isdigit((g)->id[0]);
50 int num = atoi(g->id);
51 if (o_qtype != type || o_qend != o_h || o_qv != o_v) {
52 o_flush();
53 o_qh = o_h;
54 o_qv = o_v;
55 o_qtype = type;
56 outf(type == 1 ? "(" : "[");
58 if (o_qtype == 1) {
59 if (num >= ' ' && num <= '~')
60 outf("%s%c", strchr("()\\", num) ? "\\" : "", num);
61 else
62 outf("\\%d%d%d", (num >> 6) & 7, (num >> 3) & 7, num & 7);
63 } else {
64 outf("/%s", g->id);
66 o_qend = o_h + charwid(g->wid, o_s);
69 /* calls o_flush() if necessary */
70 void out(char *s, ...)
72 va_list ap;
73 o_flush();
74 va_start(ap, s);
75 outvf(s, ap);
76 va_end(ap);
79 /* glyph placement adjustments */
80 static struct fixlist {
81 char *name;
82 int dh, dv;
83 } fixlist[] = {
84 {"", -5, 4},
85 {"", 20, 0},
86 {"", 20, 0},
87 {"", -11, 0},
88 {"", -11, 0},
89 {"", -50, 0},
90 {"br", -5, 4},
91 {"lc", 20, 0},
92 {"lf", 20, 0},
93 {"rc", -11, 0},
94 {"rf", -11, 0},
95 {"rn", -50, 0},
98 static void fixpos(struct glyph *g, int *dh, int *dv)
100 struct font *fn = g->font;
101 int i;
102 *dh = 0;
103 *dv = 0;
104 if (!strcmp("S", fn->name) && !strcmp("Symbol", fn->fontname)) {
105 for (i = 0; i < LEN(fixlist); i++) {
106 if (!strcmp(fixlist[i].name, g->name)) {
107 *dh = charwid(fixlist[i].dh, o_s);
108 *dv = charwid(fixlist[i].dv, o_s);
109 return;
115 static void out_fontup(int fid)
117 char fnname[FNLEN];
118 struct font *fn;
119 if (o_m != p_m) {
120 out("%d %d %d rgb\n", CLR_R(o_m), CLR_G(o_m), CLR_B(o_m));
121 p_m = o_m;
123 if (fid != p_f || o_s != p_s) {
124 fn = dev_font(fid);
125 out("%d /%s f\n", o_s, fn->fontname);
126 p_f = fid;
127 p_s = o_s;
128 sprintf(fnname, " %s ", fn->fontname);
129 if (!strstr(o_fonts, fnname))
130 sprintf(strchr(o_fonts, '\0'), "%s ", fn->fontname);
134 void outc(char *c)
136 struct glyph *g;
137 struct font *fn;
138 int dh, dv;
139 g = dev_glyph(c, o_f);
140 fn = g ? g->font : dev_font(o_f);
141 if (!g) {
142 outrel(*c == ' ' && fn ? charwid(fn->spacewid, o_s) : 1, 0);
143 return;
145 out_fontup(dev_fontid(fn));
146 fixpos(g, &dh, &dv);
147 o_h += dh;
148 o_v += dv;
149 o_queue(g);
150 o_h -= dh;
151 o_v -= dv;
154 void outh(int h)
156 o_h = h;
159 void outv(int v)
161 o_v = v;
164 void outrel(int h, int v)
166 o_h += h;
167 o_v += v;
170 void outfont(int f)
172 o_f = f;
175 /* a font was mounted at pos f */
176 void outmnt(int f)
178 if (p_f == f)
179 p_f = -1;
182 void outsize(int s)
184 o_s = s;
187 void outcolor(int c)
189 o_m = c;
192 static int draw_path; /* number of path segments */
193 static int draw_point; /* point was set for postscript newpath */
195 static void drawmv(void)
197 if (!draw_point)
198 outf("%d %d m ", o_h, o_v);
199 draw_point = 1;
202 /* start a multi-segment path */
203 void drawmbeg(char *s)
205 o_flush();
206 out_fontup(o_f);
207 draw_path = 1;
208 outf("gsave newpath %s\n", s);
211 /* end a multi-segment path */
212 void drawmend(char *s)
214 draw_path = 0;
215 draw_point = 0;
216 outf("%s grestore\n", s);
219 void drawbeg(void)
221 o_flush();
222 out_fontup(o_f);
223 if (draw_path)
224 return;
225 outf("newpath ");
228 void drawend(int close, int fill)
230 if (draw_path)
231 return;
232 draw_point = 0;
233 if (close)
234 outf("closepath ");
235 if (fill)
236 outf("fill\n");
237 else
238 outf("stroke\n");
241 void drawl(int h, int v)
243 drawmv();
244 outrel(h, v);
245 outf("%d %d drawl ", o_h, o_v);
248 void drawc(int c)
250 drawmv();
251 outrel(c, 0);
252 outf("%d %d drawe ", c, c);
255 void drawe(int h, int v)
257 drawmv();
258 outrel(h, 0);
259 outf("%d %d drawe ", h, v);
262 void drawa(int h1, int v1, int h2, int v2)
264 drawmv();
265 outf("%d %d %d %d drawa ", h1, v1, h2, v2);
266 outrel(h1 + h2, v1 + v2);
269 void draws(int h1, int v1, int h2, int v2)
271 drawmv();
272 outf("%d %d %d %d %d %d draws ", o_h, o_v, o_h + h1, o_v + v1,
273 o_h + h1 + h2, o_v + v1 + v2);
274 outrel(h1, v1);