BSD 3 development
[unix-history] / usr / src / cmd / troff / t6.c
CommitLineData
8f6d64d2
BJ
1#include "tdef.h"
2extern
3#include "d.h"
4extern
5#include "v.h"
6
7/*
8troff6.c
9
10width functions, sizes and fonts
11*/
12
13extern int eschar;
14extern int widthp;
15extern int ohc;
16extern int xpts;
17extern int xfont;
18extern int code;
19extern int smnt;
20extern int setwdf;
21extern int cs;
22extern int ccs;
23extern int spacesz;
24extern char trtab[];
25extern int xbitf;
26extern int mfont;
27extern int mpts;
28extern int pfont;
29extern int ppts;
30extern int oldbits;
31extern int chbits;
32extern int spbits;
33extern int nonumb;
34extern int noscale;
35extern int font;
36extern int font1;
37extern int pts;
38extern int pts1;
39extern int apts;
40extern int apts1;
41extern int sps;
42extern int nlflg;
43extern int nform;
44extern int dfact;
45extern int lss;
46extern int lss1;
47extern int vflag;
48extern int ch0;
49extern int lg;
50char fontfile[] = "/usr/lib/font/ftXX";
51int ffi = 16;
52extern int bd;
53extern int level;
54extern int ch;
55extern int res;
56extern int ptid;
57extern char W1[],W2[],W3[],W4[];
58extern int xxx;
59int trflg;
60char *fontab[] = {W1,W2,W3,W4};
61int fontlab[] = {'R','I','B','S',0};
62char pstab[] = {6,7,8,9,10,11,12,14,16,18,20,22,24,28,36,0};
63char psctab[] = {010,000,001,007,002,003,004,005,0211,006,
64 0212,0213,0214,0215,0216,0};
65int cstab[4], ccstab[4];
66int bdtab[4];
67int sbold = 0;
68int spsz = 0;
69struct fz {
70 char sign;
71 char size;
72 int inc;
73 } fz[4];
74
75width(c)
76int c;
77{
78 register i,j,k;
79
80 j = c;
81 k = 0;
82 if(j & MOT){
83 if(j & VMOT)goto rtn;
84 k = j & ~MOTV;
85 if(j & NMOT)k = -k;
86 goto rtn;
87 }
88 if((i = (j & CMASK)) == 010){
89 k = -widthp;
90 goto rtn;
91 }
92 if(i == PRESC)i = eschar;
93 if((i == ohc) ||
94 (i >= 0370))goto rtn;
95 if((j>>BYTE) == oldbits){
96 xfont = pfont;
97 xpts = ppts;
98 }else xbits(j);
99 if(j & ZBIT)goto rtn;
100 if(!trflg)i = trtab[i] & BMASK;
101 if((i -= 32) < 0)goto rtn;
102 k = getcw(i);
103 if(bd)k += bd - 1;
104 if(cs)k = cs;
105 widthp = k;
106rtn:
107 xbitf = trflg = 0;
108 return(k);
109}
110getcw(i)
111int i;
112{
113 register j,k;
114 register char *p;
115 int x;
116 extern char codetab[];
117
118 bd = 0;
119 if((code = codetab[i]) & 0200){
120 if(smnt){
121 p = fontab[smnt-1];
122 if(xfont == (sbold-1))bd = bdtab[smnt-1];
123 goto g0;
124 }
125 code = 0;
126 k = 36;
127 goto g1;
128 }
129 p = fontab[xfont];
130g0:
131 if(!i)k = spacesz;
132 else k = *(p + i) & BMASK;
133 if(setwdf)v.ct |= ((k>>6) & 3);
134g1:
135 k = (j = (k&077)*(xpts&077))/6;
136 if((j%6) >= 3)k++;
137 if(cs = cstab[xfont]){
138 if(ccs = ccstab[xfont])x = ccs; else x = xpts;
139 cs = (j = (cs&077)*(x&077))/6;
140 if((j%6) >= 3)cs++;
141 }
142 if(!bd)bd = bdtab[xfont];
143 return(k);
144}
145xbits(i)
146int i;
147{
148 register j, k;
149
150/*
151 if((j = i >> BYTE) == oldbits){
152 xfont = pfont;
153 xpts = ppts;
154 goto rtn;
155 }
156*/
157 j = i >> BYTE;
158 xfont = (j>>1) & 03;
159 if(k = (j>>3) & 017){
160 xpts = pstab[--k];
161 if(psctab[k] < 0)xpts |= DBL;
162 oldbits = j;
163 pfont = xfont;
164 ppts = xpts;
165 goto rtn;
166 }
167 switch(xbitf){
168 case 0:
169 xfont = font;
170 xpts = pts;
171 break;
172 case 1:
173 xfont = pfont;
174 xpts = ppts;
175 break;
176 case 2:
177 xfont = mfont;
178 xpts = mpts;
179 }
180rtn:
181 xbitf = 0;
182}
183setch(){
184 register i,*j,k;
185 extern int chtab[];
186
187 if((i = getrq()) == 0)return(0);
188 for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0);
189 k = *(++j) | chbits;
190/*
191 if((i & CMASK) == '*'){
192 if(((i = find('R',fontlab)) < 0) &&
193 ((i = find('G',fontlab)) < 0))
194 return(k);
195 else return((k & ~(03<<(BYTE+1))) | (i<<(BYTE+1)));
196 }
197*/
198 return(k);
199}
200find(i,j)
201int i,j[];
202{
203 register k;
204
205 if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k);
206 for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1);
207 return(k);
208}
209casefz(){
210 register i, j, k;
211 int savinc;
212
213 k = 0;
214fz0:
215 if(skip() || !(i = getrq()) ||
216 ((j = find(i,fontlab)) == -1)){
217 if(k)goto fz1;
218 else return;
219 }
220 if(j == (smnt-1)){
221 k = smnt;
222 goto fz0;
223 }
224 if(k){
225 spsz = j + 1;
226 j = k -1;
227 }
228fz1:
229 if((j==font) && fz[j].inc)savinc = fz[j].inc;
230 else savinc = 0;
231 fz[j].inc = fz[j].sign = fz[j].size = 0;
232 if(skip()){
233 if(k)spsz = 0;
234 goto fz2;
235 }
236 if(((i=((k=getch()) & CMASK)) == '+') || (i == '-'))fz[j].sign = i;
237 else{
238 fz[j].sign = 0;
239 ch = k;
240 }
241 noscale++;
242 fz[j].size = atoi();
243 noscale = 0;
244fz2:
245 if(j==font)casps1(apts + savinc);
246 else if(j == smnt-1)mchbits();
247}
248caseps(){
249 register i;
250
251 if(skip())i = apts1;
252 else{
253 noscale++;
254 i = inumb(&apts);
255 noscale = 0;
256 if(nonumb)return;
257 }
258 casps1(i);
259}
260casps1(i)
261int i;
262{
263 if(i <= 0)return;
264 if(fz[font].size){
265 i = getfz(font, i);
266 }
267 apts1 = apts;
268 apts = i;
269 pts1 = pts;
270 pts = findps(i & 077);
271 mchbits();
272}
273findps(i)
274int i;
275{
276 register j, k;
277
278 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
279 if(psctab[j] < 0)k |= DBL;
280 return(k);
281}
282mchbits(){
283 register i, j, k;
284
285 spbits = 0;
286 i = pts & 077;
287 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
288 chbits = (((++j)<<2) | font) << (BYTE + 1);
289 sps = width(' ' | chbits);
290 if(font == (spsz-1)){
291 i = findps(getfz(smnt-1, apts + fz[font].inc));
292 for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;}
293 spbits = (((++j)<<2) | font) << (BYTE + 1);
294 }
295}
296getfz(x,y)
297int x, y;
298{
299 register i, j, k;
300
301 i = fz[x].size;
302 j = fz[x].sign;
303 if(i || j){
304 if(j == '+')i += y;
305 else if(j == '-')i = y - i;
306 }
307 fz[x].inc = y - i;
308 return(i);
309}
310setps(){
311 register i,j;
312
313 if((((i=getch() & CMASK) == '+') || (i == '-')) &&
314 (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){
315 if(i == '-')j = -j;
316 ch = 0;
317 casps1(apts+j);
318 return;
319 }
320 if((i -= '0') == 0){
321 casps1(apts1);
322 return;
323 }
324 if((i > 0) && (i <= 9)){
325 if((i <= 3) &&
326 ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){
327 i = 10*i +j;
328 ch = 0;
329 }
330 casps1(i);
331 }
332}
333caseft(){
334 skip();
335 setfont(1);
336}
337setfont(a)
338int a;
339{
340 register i,j;
341
342 if(a)i = getrq();
343 else i = getsn();
344 if(!i || (i == 'P')){
345 j = font1;
346 goto s0;
347 }
348 if(i == 'S')return;
349 if((j = find(i,fontlab)) == -1)return;
350s0:
351 font1 = font;
352 font = j;
353 i = 0;
354 if(fz[font1].size){
355 i++;
356 casps1(apts + fz[font1].inc);
357 }else if(fz[font].size){
358 i++;
359 casps1(apts);
360 }
361 if(!i)mchbits();
362}
363setwd(){
364 register i, base, wid;
365 int delim, em, k;
366 int savlevel, savhp, savapts, savapts1, savfont, savfont1,
367 savpts, savpts1;
368
369 base = v.st = v.sb = wid = v.ct = 0;
370 if((delim = getch() & CMASK) & MOT)return;
371 savhp = v.hp;
372 savlevel = level;
373 v.hp = level = 0;
374 savapts = apts;
375 savapts1 = apts1;
376 savfont = font;
377 savfont1 = font1;
378 savpts = pts;
379 savpts1 = pts1;
380 setwdf++;
381 while((((i = getch()) & CMASK) != delim) && !nlflg){
382 wid += width(i);
383 if(!(i & MOT)){
384 em = (xpts & 077)*6;
385 }else if(i & VMOT){
386 k = i & ~MOTV;
387 if(i & NMOT)k = -k;
388 base -= k;
389 em = 0;
390 }else continue;
391 if(base < v.sb)v.sb = base;
392 if((k=base + em) > v.st)v.st = k;
393 }
394 nform = 0;
395 setn1(wid);
396 v.hp = savhp;
397 level = savlevel;
398 apts = savapts;
399 apts1 = savapts1;
400 font = savfont;
401 font1 = savfont1;
402 pts = savpts;
403 pts1 = savpts1;
404 mchbits();
405 setwdf = 0;
406}
407vmot(){
408 dfact = lss;
409 vflag++;
410 return(mot());
411}
412hmot(){
413 dfact = 6 * (pts & 077);
414 return(mot());
415}
416mot(){
417 register i, j;
418
419 j = HOR;
420 getch(); /*eat delim*/
421 if(i = atoi()){
422 if(vflag)j = VERT;
423 i = makem(quant(i,j));
424 }
425 getch();
426 vflag = 0;
427 dfact = 1;
428 return(i);
429}
430sethl(k)
431int k;
432{
433 register i;
434
435 i = 3 * (pts & 077);
436 if(k == 'u')i = -i;
437 else if(k == 'r')i = -2*i;
438 vflag++;
439 i = makem(i);
440 vflag = 0;
441 return(i);
442}
443makem(i)
444int i;
445{
446 register j;
447
448 if((j = i) < 0)j = -j;
449 j = (j & ~MOTV) | MOT;
450 if(i < 0)j |= NMOT;
451 if(vflag)j |= VMOT;
452 return(j);
453}
454getlg(i)
455int i;
456{
457 register j, k;
458
459 switch((j = getch0()) & CMASK){
460 case 'f':
461 if(lg!=2){switch((k =getch0()) & CMASK){
462 case 'i':
463 j = 0214;
464 break;
465 case 'l':
466 j = 0215;
467 break;
468 default:
469 ch0 = k;
470 j = 0213;
471 }
472 }else j = 0213;
473 break;
474 case 'l':
475 j = 0212;
476 break;
477 case 'i':
478 j = 0211;
479 break;
480 default:
481 ch0 = j;
482 j = i;
483 }
484 return((i & ~CMASK) | j);
485}
486caselg(){
487
488 lg = 1;
489 if(skip())return;
490 lg = atoi();
491}
492casefp(){
493 register i, j, k;
494 int x;
495
496 skip();
497 if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3)){prstr("fp: bad font position\n"); return;}
498 if(skip() || !(j = getrq())){prstr("fp: no font name\n"); return;}
499 fontfile[ffi] = j & BMASK;
500 fontfile[ffi+1] = j>>BYTE;
501 if((k = open(fontfile,0)) < 0){
502 prstr("Cannot open ");
503 c0:
504 prstr(fontfile);
505 prstr("\n");
506 done(-1);
507 }
508 if(lseek(k,8L * sizeof(int),0) < 0)goto c1;
509 if(read(k,fontab[i],256-32) != 256-32){
510 c1:
511 prstr("Cannot read ");
512 goto c0;
513 }
514 close(k);
515 if(i == (smnt-1)){smnt = 0; sbold = 0; spsz = 0;}
516 if((fontlab[i] = j) == 'S')smnt = i + 1;
517 bdtab[i] = cstab[i] = ccstab[i] = 0;
518 fz[i].inc = fz[i].sign = fz[i].size = 0;
519 if(ptid != 1){
520 prstr("Mount font ");
521 prstr(&fontfile[ffi]);
522 prstr(" on ");
523 x = PAIR((i + '1'),0);
524 prstr((char *)&x);
525 prstr("\n");
526 }
527}
528casecs(){
529 register i, j;
530
531 noscale++;
532 skip();
533 if(!(i=getrq()) ||
534 ((i = find(i,fontlab)) < 0))goto rtn;
535 skip();
536 cstab[i] = atoi();
537 skip();
538 j = atoi();
539 if(!nonumb)ccstab[i] = findps(j);
540rtn:
541 noscale = 0;
542}
543casebd(){
544 register i, j, k;
545
546 k = 0;
547bd0:
548 if(skip() || !(i = getrq()) ||
549 ((j = find(i,fontlab)) == -1)){
550 if(k)goto bd1;
551 else return;
552 }
553 if(j == (smnt-1)){
554 k = smnt;
555 goto bd0;
556 }
557 if(k){
558 sbold = j + 1;
559 j = k -1;
560 }
561bd1:
562 skip();
563 noscale++;
564 bdtab[j] = atoi();
565 noscale = 0;
566}
567casevs(){
568 register i;
569
570 skip();
571 vflag++;
572 dfact = 6; /*default scaling is points!*/
573 res = VERT;
574 i = inumb(&lss);
575 if(nonumb)i = lss1;
576 if(i < VERT)i = VERT;
577 lss1 = lss;
578 lss = i;
579}
580casess(){
581 register i;
582
583 noscale++;
584 skip();
585 if(i = atoi()){
586 spacesz = i& 0177;
587 sps = width(' ' | chbits);
588 }
589 noscale = 0;
590}
591xlss(){
592 register i, j;
593
594 getch();
595 dfact = lss;
596 i = quant(atoi(),VERT);
597 dfact = 1;
598 getch();
599 if((j = i) < 0)j = -j;
600 ch0 = ((j & 03700)<<3) | HX;
601 if(i < 0)ch0 |= 040000;
602 return(((j & 077)<<9) | LX);
603}