]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/troff/t10.c
cc: fix void cast crash
[plan9front.git] / sys / src / cmd / troff / t10.c
1 #include "tdef.h"
2 #include "fns.h"
3 #include "ext.h"
4
5 /*
6  * troff10.c
7  * 
8  * typesetter interface
9  */
10
11 int     vpos     = 0;   /* absolute vertical position on page */
12 int     hpos     = 0;   /* ditto horizontal */
13
14 extern Font fonts[MAXFONTS+1];
15
16 int     Inch;
17 int     Hor;
18 int     Vert;
19 int     Unitwidth;
20 int     nfonts;
21
22
23
24 void t_ptinit(void)
25 {
26         int i;
27         char buf[100], *p;
28
29         hmot = t_hmot;
30         makem = t_makem;
31         setabs = t_setabs;
32         setch = t_setch;
33         sethl = t_sethl;
34         setht = t_setht;
35         setslant = t_setslant;
36         vmot = t_vmot;
37         xlss = t_xlss;
38         findft = t_findft;
39         width = t_width;
40         mchbits = t_mchbits;
41         ptlead = t_ptlead;
42         ptout = t_ptout;
43         ptpause = t_ptpause;
44         setfont = t_setfont;
45         setps = t_setps;
46         setwd = t_setwd;
47
48         /* open table for device, */
49         /* read in resolution, size info, font info, etc., set params */
50         if ((p = getenv("TYPESETTER")) != 0){
51                 strncpy(devname, p, sizeof devname);
52                 devname[sizeof devname-1] = 0;
53         }
54         if (termtab[0] == 0)
55                 strcpy(termtab, DWBfontdir);
56         if (fontdir[0] == 0)
57                 strcpy(fontdir, DWBfontdir);
58         if (devname[0] == 0)
59                 strcpy(devname, TDEVNAME);
60         hyf = 1;
61         lg = 1;
62
63         snprintf(buf, sizeof buf, "/dev%s/DESC", devname);
64         strcat(termtab, buf);
65         if (getdesc(termtab) < 0) {
66                 ERROR "can't open DESC file %s", termtab WARN;
67                 done3(1);
68         }
69         if (!ascii) {
70                 OUT "x T %s\n", devname PUT;
71                 OUT "x res %d %d %d\n", Inch, Hor, Vert PUT;
72                 OUT "x init\n" PUT;
73         }
74         for (i = 1; i <= nfonts; i++)
75                 setfp(i, fontlab[i], (char *) 0, 0);
76         sps = EM/3;     /* space size */
77         ics = EM;       /* insertion character space */
78         for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++)
79                 tabtab[i] = DTAB * (i + 1);
80         tabtab[NTAB-1] = 0;
81         pl = 11 * INCH;                 /* paper length */
82         po = PO;                /* page offset */
83         spacesz = SS;
84         lss = lss1 = VS;
85         ll = ll1 = lt = lt1 = LL;
86         t_specnames();  /* install names like "hyphen", etc. */
87 }
88
89 void t_specnames(void)
90 {
91         int     i;
92
93         for (i = 0; spnames[i].n; i++)
94                 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
95 }
96
97 void t_ptout(Tchar i)
98 {
99         int dv;
100         Tchar *k;
101         int temp, a, b;
102         int diff;
103
104         if (cbits(i) != '\n') {
105                 if (olinep >= oline + olnsize) {
106                         diff = olinep - oline;
107                         olnsize += OLNSIZE;
108                         if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
109                                 if (diff && olinep)
110                                         olinep = oline + diff;
111                         } else {
112                                 ERROR "Output line overflow." WARN;
113                                 done(2);
114                         }
115                 }
116                 *olinep++ = i;
117                 return;
118         }
119         if (olinep == oline) {
120                 lead += lss;
121                 return;
122         }
123
124         hpos = po;      /* ??? */
125         esc = 0;        /* ??? */
126         ptesc();        /* the problem is to get back to the left end of the line */
127         dv = 0;
128         for (k = oline; k < olinep; k++) {
129                 if (ismot(*k) && isvmot(*k)) {
130                         temp = absmot(*k);
131                         if (isnmot(*k))
132                                 temp = -temp;
133                         dv += temp;
134                 }
135         }
136         if (dv) {
137                 vflag++;
138                 *olinep++ = makem(-dv);
139                 vflag = 0;
140         }
141
142         b = dip->blss + lss;
143         lead += dip->blss + lss;
144         dip->blss = 0;
145         for (k = oline; k < olinep; )
146                 k += ptout0(k); /* now passing a pointer! */
147         olinep = oline;
148         lead += dip->alss;
149         a = dip->alss;
150         dip->alss = 0;
151         /*
152         OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;
153 */
154         OUT "n%d %d\n", b, a PUT;       /* be nice to chuck */
155 }
156
157 int ptout0(Tchar *pi)
158 {
159         int j, k, w;
160         int z, dx, dy, dx2, dy2, n;
161         Tchar i;
162         int outsize;    /* size of object being printed */
163
164         outsize = 1;    /* default */
165         i = *pi;
166         k = cbits(i);
167         if (ismot(i)) {
168                 j = absmot(i);
169                 if (isnmot(i))
170                         j = -j;
171                 if (isvmot(i))
172                         lead += j;
173                 else 
174                         esc += j;
175                 return(outsize);
176         }
177         if (k == CHARHT) {
178                 xpts = fbits(i);        /* sneaky, font bits as size bits */
179                 if (xpts != mpts)
180                         ptps();
181                 OUT "x H %d\n", sbits(i) PUT;
182                 return(outsize);
183         }
184         if (k == SLANT) {
185                 OUT "x S %d\n", sfbits(i)-180 PUT;
186                 return(outsize);
187         }
188         if (k == WORDSP) {
189                 oput('w');
190                 return(outsize);
191         }
192         if (sfbits(i) == oldbits) {
193                 xfont = pfont;
194                 xpts = ppts;
195         } else 
196                 xbits(i, 2);
197         if (k == XON) {
198                 extern int xon;
199                 ptflush();      /* guarantee that everything is out */
200                 if (esc)
201                         ptesc();
202                 if (xfont != mfont)
203                         ptfont();
204                 if (xpts != mpts)
205                         ptps();
206                 if (lead)
207                         ptlead();
208                 OUT "x X " PUT;
209                 xon++;
210                 for (j = 1; cbits(pi[j]) != XOFF; j++)
211                         outascii(pi[j]);
212                 oput('\n');
213                 xon--;
214                 return j+1;
215         }
216         if (k < 040 && k != DRAWFCN)
217                 return(outsize);
218         j = z = 0;
219         if (k != DRAWFCN) {
220                 if (widcache[k].fontpts == (xfont<<8) + xpts  && !setwdf) {
221                         w = widcache[k].width;
222                         bd = 0;
223                         cs = 0;
224                 } else
225                         w = getcw(k);
226                 if (cs) {
227                         if (bd)
228                                 w += (bd - 1) * HOR;
229                         j = (cs - w) / 2;
230                         w = cs - j;
231                         if (bd)
232                                 w -= (bd - 1) * HOR;
233                 }
234                 if (iszbit(i)) {
235                         if (cs)
236                                 w = -j; 
237                         else 
238                                 w = 0;
239                         z = 1;
240                 }
241         }
242         esc += j;
243         if (xfont != mfont)
244                 ptfont();
245         if (xpts != mpts)
246                 ptps();
247         if (lead)
248                 ptlead();
249         /* put out the real character here */
250         if (k == DRAWFCN) {
251                 if (esc)
252                         ptesc();
253                 w = 0;
254                 dx = absmot(pi[3]);
255                 if (isnmot(pi[3]))
256                         dx = -dx;
257                 dy = absmot(pi[4]);
258                 if (isnmot(pi[4]))
259                         dy = -dy;
260                 switch (cbits(pi[1])) {
261                 case DRAWCIRCLE:        /* circle */
262                         OUT "D%c %d\n", DRAWCIRCLE, dx PUT;     /* dx is diameter */
263                         hpos += dx;
264                         break;
265                 case DRAWELLIPSE:
266                         OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;
267                         hpos += dx;
268                         break;
269                 case DRAWBUILD:
270                         k = cbits(pi[2]);
271                         OUT "D%c %d ", DRAWBUILD, dx PUT;
272                         if (k < ALPHABET)
273                                 OUT "%c\n", k PUT;
274                         else
275                                 ptchname(k);
276                         hpos += dx;
277                         break;
278                 case DRAWLINE:  /* line */
279                         k = cbits(pi[2]);
280                         OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;
281                         if (k < ALPHABET)
282                                 OUT "%c\n", k PUT;
283                         else
284                                 ptchname(k);
285                         hpos += dx;
286                         vpos += dy;
287                         break;
288                 case DRAWARC:   /* arc */
289                         dx2 = absmot(pi[5]);
290                         if (isnmot(pi[5]))
291                                 dx2 = -dx2;
292                         dy2 = absmot(pi[6]);
293                         if (isnmot(pi[6]))
294                                 dy2 = -dy2;
295                         OUT "D%c %d %d %d %d\n", DRAWARC,
296                                 dx, dy, dx2, dy2 PUT;
297                         hpos += dx + dx2;
298                         vpos += dy + dy2;
299                         break;
300
301                 case 's':       /* using 's' internally to avoid .tr ~ */
302                         pi[1] = '~';
303                 case DRAWSPLINE:        /* spline */
304                 default:        /* something else; copy it like spline */
305                         OUT "D%c %d %d", cbits(pi[1]), dx, dy PUT;
306                         hpos += dx;
307                         vpos += dy;
308                         if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
309                                 /* it was somehow defective */
310                                 OUT "\n" PUT;
311                                 break;
312                         }
313                         for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
314                                 dx = absmot(pi[n]);
315                                 if (isnmot(pi[n]))
316                                         dx = -dx;
317                                 dy = absmot(pi[n+1]);
318                                 if (isnmot(pi[n+1]))
319                                         dy = -dy;
320                                 OUT " %d %d", dx, dy PUT;
321                                 hpos += dx;
322                                 vpos += dy;
323                         }
324                         OUT "\n" PUT;
325                         break;
326                 }
327                 for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
328                         ;
329                 outsize = n + 1;
330         } else if (k < ALPHABET) {
331                 /* try to go faster and compress output */
332                 /* by printing nnc for small positive motion followed by c */
333                 /* kludgery; have to make sure set all the vars too */
334                 if (esc > 0 && esc < 100) {
335                         oput(esc / 10 + '0');
336                         oput(esc % 10 + '0');
337                         oput(k);
338                         hpos += esc;
339                         esc = 0;
340                 } else {
341                         if (esc)
342                                 ptesc();
343                         oput('c');
344                         oput(k);
345                         oput('\n');
346                 }
347         } else {
348                 if (esc)
349                         ptesc();
350                 ptchname(k);
351         }
352         if (bd) {
353                 bd -= HOR;
354                 if (esc += bd)
355                         ptesc();
356                 if (k < ALPHABET)
357                         OUT "c%c\n", k PUT;
358                 else
359                         ptchname(k);
360                 if (z)
361                         esc -= bd;
362         }
363         esc += w;
364         return(outsize);
365 }
366
367 void ptchname(int k)
368 {
369         char *chn = chname(k);
370
371         switch (chn[0]) {
372         case MBchar:
373                 OUT "c%s\n", chn+1 PUT; /* \n not needed? */
374                 break;
375         case Number:
376                 OUT "N%s\n", chn+1 PUT;
377                 break;
378         case Troffchar:
379                 OUT "C%s\n", chn+1 PUT;
380                 break;
381         default:
382                 ERROR "illegal char type %s", chn WARN;
383                 break;
384         }
385 }
386
387 void ptflush(void)      /* get us to a clean output state */
388 {
389         if (TROFF) {
390                 /* ptesc(); but always H, no h */
391                 hpos += esc;
392                 OUT "\nH%d\n", hpos PUT;
393                 esc = 0;
394                 ptps();
395                 ptfont();
396                 ptlead();
397         }
398 }
399
400 void ptps(void)
401 {
402         int i, j, k;
403
404         i = xpts;
405         for (j = 0; i > (k = pstab[j]); j++)
406                 if (!k) {
407                         k = pstab[--j];
408                         break;
409                 }
410         if (!ascii)
411                 OUT "s%d\n", k PUT;     /* really should put out string rep of size */
412         mpts = i;
413 }
414
415 void ptfont(void)
416 {
417         mfont = xfont;
418         if (ascii)
419                 return;
420         if (xfont > nfonts) {
421                 ptfpcmd(0, fonts[xfont].longname, 0);   /* Put the desired font in the
422                                          * fontcache of the filter */
423                 OUT "f0\n" PUT; /* make sure that it gets noticed */
424         } else
425                 OUT "f%d\n", xfont PUT;
426 }
427
428 void ptfpcmd(int f, char *s, char *longname)
429 {
430         if (f > nfonts)         /* a bit risky? */
431                 f = 0;
432         if (longname) {
433                 OUT "x font %d %s %s\n", f, s, longname PUT;
434         } else {
435                 OUT "x font %d %s\n", f, s PUT;
436         }
437 /*      OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */
438                                 /* which apparently believes that x font means */
439                                 /* to set the font, not just the position. */
440 }
441
442 void t_ptlead(void)
443 {
444         vpos += lead;
445         if (!ascii)
446                 OUT "V%d\n", vpos PUT;
447         lead = 0;
448 }
449
450 void ptesc(void)
451 {
452         hpos += esc;
453         if (!ascii)
454                 if (esc > 0) {
455                         oput('h');
456                         if (esc>=10 && esc<100) {
457                                 oput(esc/10 + '0');
458                                 oput(esc%10 + '0');
459                         } else
460                                 OUT "%d", esc PUT;
461                 } else
462                         OUT "H%d\n", hpos PUT;
463         esc = 0;
464 }
465
466 void ptpage(int n)      /* called at end of each output page, we hope */
467 {
468         int i;
469
470         if (NROFF)
471                 return;
472         ptlead();
473         vpos = 0;
474         if (ascii)
475                 return;
476         OUT "p%d\n", n PUT;     /* new page */
477         for (i = 0; i <= nfonts; i++)
478                 if (fontlab[i]) {
479                         if (fonts[i].truename)
480                                 OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;
481                         else
482                                 OUT "x font %d %s\n", i, fonts[i].longname PUT;
483                 }
484         ptps();
485         ptfont();
486 }
487
488 void pttrailer(void)
489 {
490         if (TROFF)
491                 OUT "x trailer\n" PUT;
492 }
493
494 void ptstop(void)
495 {
496         if (TROFF)
497                 OUT "x stop\n" PUT;
498 }
499
500 void t_ptpause(void)
501 {
502         if (ascii)
503                 return;
504         ptlead();
505         vpos = 0;
506         pttrailer();
507         ptlead();
508         OUT "x pause\n" PUT;
509         flusho();
510         mpts = mfont = 0;
511         ptesc();
512         esc = po;
513         hpos = vpos = 0;        /* probably in wrong place */
514 }