1 #ifndef lint 2 static char sccsid[] = "@(#)n9.c 2.2 (CWI) 93/02/25"; 3 #endif lint 4 #include "tdef.h" 5 #ifdef NROFF 6 #include "tw.h" 7 #endif 8 #include <sgtty.h> 9 #include "ext.h" 10 11 /* 12 * troff9.c 13 * 14 * misc functions 15 */ 16 17 tchar setz() 18 { 19 tchar i; 20 21 if (!ismot(i = getch())) 22 i |= ZBIT; 23 return(i); 24 } 25 26 setline() 27 { 28 register tchar *i; 29 tchar c; 30 int length; 31 int w, cnt, delim, rem, temp; 32 tchar linebuf[NC]; 33 34 if (ismot(c = getch())) 35 return; 36 delim = cbits(c); 37 vflag = 0; 38 dfact = EM; 39 length = quant(atoi(), HOR); 40 dfact = 1; 41 if (!length) { 42 eat(delim); 43 return; 44 } 45 s0: 46 if ((cbits(c = getch())) == delim) { 47 ch = c; 48 c = RULE | chbits; 49 } else if (cbits(c) == FILLER) 50 goto s0; 51 w = width(c); 52 i = linebuf; 53 if (length < 0) { 54 *i++ = makem(length); 55 length = -length; 56 } 57 if (!(cnt = length / w)) { 58 *i++ = makem(-(temp = ((w - length) / 2))); 59 *i++ = c; 60 *i++ = makem(-(w - length - temp)); 61 goto s1; 62 } 63 if (rem = length % w) { 64 if (cbits(c) == RULE || cbits(c) == UNDERLINE || cbits(c) == ROOTEN) 65 *i++ = c | ZBIT; 66 *i++ = makem(rem); 67 } 68 if (cnt) { 69 *i++ = RPT; 70 *i++ = cnt; 71 *i++ = c; 72 } 73 s1: 74 *i++ = 0; 75 eat(delim); 76 pushback(linebuf); 77 } 78 79 80 eat(c) 81 register int c; 82 { 83 register i; 84 85 while ((i = cbits(getch())) != c && (i != '\n')) 86 ; 87 return(i); 88 } 89 90 91 setov() 92 { 93 register j, k; 94 tchar i, o[NOV+1]; 95 int delim, w[NOV+1]; 96 97 if (ismot(i = getch())) 98 return; 99 delim = cbits(i); 100 for (k = 0; (k < NOV) && ((j = cbits(i = getch())) != delim) && (j != '\n'); k++) { 101 o[k] = i; 102 w[k] = width(i); 103 } 104 o[k] = w[k] = 0; 105 if (o[0]) 106 for (j = 1; j; ) { 107 j = 0; 108 for (k = 1; o[k] ; k++) { 109 if (w[k-1] < w[k]) { 110 j++; 111 i = w[k]; 112 w[k] = w[k-1]; 113 w[k-1] = i; 114 i = o[k]; 115 o[k] = o[k-1]; 116 o[k-1] = i; 117 } 118 } 119 } 120 else 121 return; 122 *pbp++ = makem(w[0] / 2); 123 for (k = 0; o[k]; k++) 124 ; 125 while (k>0) { 126 k--; 127 *pbp++ = makem(-((w[k] + w[k+1]) / 2)); 128 *pbp++ = o[k]; 129 } 130 } 131 132 133 setbra() 134 { 135 register k; 136 tchar i, *j, dwn; 137 int cnt, delim; 138 tchar brabuf[NC]; 139 140 if (ismot(i = getch())) 141 return; 142 delim = cbits(i); 143 j = brabuf + 1; 144 cnt = 0; 145 #ifdef NROFF 146 dwn = (2 * t.Halfline) | MOT | VMOT; 147 #endif 148 #ifndef NROFF 149 dwn = EM | MOT | VMOT; 150 #endif 151 while (((k = cbits(i = getch())) != delim) && (k != '\n') && (j <= (brabuf + NC - 4))) { 152 *j++ = i | ZBIT; 153 *j++ = dwn; 154 cnt++; 155 } 156 if (--cnt < 0) 157 return; 158 else if (!cnt) { 159 ch = *(j - 2); 160 return; 161 } 162 *j = 0; 163 #ifdef NROFF 164 *--j = *brabuf = (cnt * t.Halfline) | MOT | NMOT | VMOT; 165 #endif 166 #ifndef NROFF 167 *--j = *brabuf = (cnt * EM) / 2 | MOT | NMOT | VMOT; 168 #endif 169 *--j &= ~ZBIT; 170 pushback(brabuf); 171 } 172 173 174 setvline() 175 { 176 register i; 177 tchar c, rem, ver, neg; 178 int cnt, delim, v; 179 tchar vlbuf[NC]; 180 register tchar *vlp; 181 182 if (ismot(c = getch())) 183 return; 184 delim = cbits(c); 185 dfact = lss; 186 vflag++; 187 i = quant(atoi(), VERT); 188 dfact = 1; 189 if (!i) { 190 eat(delim); 191 vflag = 0; 192 return; 193 } 194 if ((cbits(c = getch())) == delim) { 195 c = BOXRULE | chbits; /*default box rule*/ 196 } else 197 getch(); 198 c |= ZBIT; 199 neg = 0; 200 if (i < 0) { 201 i = -i; 202 neg = NMOT; 203 } 204 #ifdef NROFF 205 v = 2 * t.Halfline; 206 #endif 207 #ifndef NROFF 208 v = EM; 209 #endif 210 cnt = i / v; 211 rem = makem(i % v) | neg; 212 ver = makem(v) | neg; 213 vlp = vlbuf; 214 if (!neg) 215 *vlp++ = ver; 216 if (absmot(rem) != 0) { 217 *vlp++ = c; 218 *vlp++ = rem; 219 } 220 while ((vlp < (vlbuf + NC - 3)) && cnt--) { 221 *vlp++ = c; 222 *vlp++ = ver; 223 } 224 *(vlp - 2) &= ~ZBIT; 225 if (!neg) 226 vlp--; 227 *vlp++ = 0; 228 pushback(vlbuf); 229 vflag = 0; 230 } 231 232 #define NPAIR (NC/2-6) /* max pairs in spline, etc. */ 233 234 setdraw() /* generate internal cookies for a drawing function */ 235 { 236 int i, j, k, dx[NPAIR], dy[NPAIR], delim, type; 237 tchar c, drawbuf[NC]; 238 239 /* input is \D'f dx dy dx dy ... c' (or at least it had better be) */ 240 /* this does drawing function f with character c and the */ 241 /* specified dx,dy pairs interpreted as appropriate */ 242 /* pairs are deltas from last point, except for radii */ 243 244 /* t x set line thickness to x */ 245 /* s x set line style to bit-map x (x BETTER be in "u")*/ 246 /* l dx dy: line from here by dx,dy */ 247 /* c x: circle of diameter x, left side here */ 248 /* e x y: ellipse of diameters x,y, left side here */ 249 /* a dx1 dy1 dx2 dy2: 250 ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */ 251 /* [Pp] s x y ...: for polygons filled with stipple s */ 252 /* ~ x y ...: wiggly line -or- */ 253 /* g x y ...: for gremlin-style curves */ 254 /* ~ dx1 dy1 dx2 dy2...: 255 spline to dx1,dy1 to dx2,dy2 ... */ 256 /* f dx dy ...: f is any other char: like spline */ 257 258 if (ismot(c = getch())) 259 return; 260 delim = cbits(c); 261 type = cbits(getch()); 262 for (i = 0; i < NPAIR ; i++) { 263 if (nlflg) 264 break; 265 c = getch(); 266 if (cbits(c) == delim) 267 break; 268 /* ought to pick up optional drawing character */ 269 if (cbits(c) != ' ') 270 ch = c; 271 vflag = 0; 272 if (i == 0 && (type == DRAWPOLY || type == DRAWUBPOLY)) { 273 dfact = 1; 274 dx[0] = quant(atoi(), 1); 275 if (dx[0] < 0 || dx[0] > MAXMOT) 276 dx[0] = 0; 277 dy[0] = 0; 278 continue; 279 } 280 dfact = EM; 281 dx[i] = quant(atoi(), HOR); 282 if (dx[i] > MAXMOT) 283 dx[i] = MAXMOT; 284 else if (dx[i] < -MAXMOT) 285 dx[i] = -MAXMOT; 286 if (cbits((c = getch())) == delim) { /* spacer */ 287 dy[i++] = 0; 288 break; 289 } 290 vflag = 1; 291 dfact = lss; 292 dy[i] = quant(atoi(), VERT); 293 if (dy[i] > MAXMOT) 294 dy[i] = MAXMOT; 295 else if (dy[i] < -MAXMOT) 296 dy[i] = -MAXMOT; 297 } 298 dfact = 1; 299 vflag = 0; 300 #ifndef NROFF 301 drawbuf[0] = DRAWFCN | chbits | ZBIT; 302 drawbuf[1] = type | chbits | ZBIT; 303 for (k = 0, j = 2; k < i; k++) { 304 drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k])); 305 drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k])); 306 } 307 if (type == DRAWELLIPSE) { 308 drawbuf[4] = drawbuf[3] | NMOT; /* so the net vertical is zero */ 309 j = 5; 310 } else if (type == DRAWTHICK || type == DRAWSTYLE) { 311 drawbuf[3] = drawbuf[2] | NMOT; /* so net horizontal is zero */ 312 } 313 drawbuf[j++] = '.' | chbits | ZBIT; /* marks end for ptout */ 314 drawbuf[j] = 0; 315 pushback(drawbuf); 316 #endif 317 } 318 319 320 casefc() 321 { 322 register i; 323 tchar j; 324 325 gchtab[fc] &= ~FCBIT; 326 fc = IMP; 327 padc = ' '; 328 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n') 329 return; 330 fc = i; 331 gchtab[fc] |= FCBIT; 332 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc) 333 return; 334 padc = ch; 335 } 336 337 338 tchar 339 setfield(x) 340 int x; 341 { 342 register tchar ii, jj, *fp; 343 register i, j; 344 int length, ws, npad, temp, type; 345 tchar **pp, *padptr[NPP]; 346 tchar fbuf[FBUFSZ]; 347 int savfc, savtc, savlc; 348 tchar rchar; 349 int savepos; 350 351 if (x == tabch) 352 rchar = tabc | chbits; 353 else if (x == ldrch) 354 rchar = dotc | chbits; 355 temp = npad = ws = 0; 356 savfc = fc; 357 savtc = tabch; 358 savlc = ldrch; 359 tabch = ldrch = fc = IMP; 360 savepos = numtab[HP].val; 361 gchtab[tabch] &= ~TABBIT; 362 gchtab[ldrch] &= ~LDRBIT; 363 gchtab[fc] &= ~FCBIT; 364 gchtab[IMP] |= TABBIT|LDRBIT|FCBIT; 365 for (j = 0; ; j++) { 366 if ((tabtab[j] & TABMASK) == 0) { 367 if (x == savfc) 368 errprint("zero field width."); 369 jj = 0; 370 goto rtn; 371 } 372 if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 ) 373 break; 374 } 375 type = tabtab[j] & (~TABMASK); 376 fp = fbuf; 377 pp = padptr; 378 if (x == savfc) { 379 while (1) { 380 j = cbits(ii = getch()); 381 jj = width(ii); 382 widthp = jj; 383 numtab[HP].val += jj; 384 if (j == padc) { 385 npad++; 386 *pp++ = fp; 387 if (pp > (padptr + NPP - 1)) 388 break; 389 goto s1; 390 } else if (j == savfc) 391 break; 392 else if (j == '\n') { 393 temp = j; 394 nlflg = 0; 395 break; 396 } 397 ws += jj; 398 s1: 399 *fp++ = ii; 400 if (fp > (fbuf + FBUFSZ - 3)) 401 break; 402 } 403 if (!npad) { 404 npad++; 405 *pp++ = fp; 406 *fp++ = 0; 407 } 408 *fp++ = temp; 409 *fp++ = 0; 410 temp = i = (j = length - ws) / npad; 411 i = (i / HOR) * HOR; 412 if ((j -= i * npad) < 0) 413 j = -j; 414 ii = makem(i); 415 if (temp < 0) 416 ii |= NMOT; 417 for (; npad > 0; npad--) { 418 *(*--pp) = ii; 419 if (j) { 420 j -= HOR; 421 (*(*pp)) += HOR; 422 } 423 } 424 pushback(fbuf); 425 jj = 0; 426 } else if (type == 0) { 427 /*plain tab or leader*/ 428 if ((j = width(rchar)) > 0) { 429 int nchar = length / j; 430 while (nchar-->0 && pbp < &pbbuf[NC-3]) { 431 numtab[HP].val += j; 432 widthp = j; 433 *pbp++ = rchar; 434 } 435 length %= j; 436 } 437 if (length) 438 jj = length | MOT; 439 else 440 jj = getch0(); 441 } else { 442 /*center tab*/ 443 /*right tab*/ 444 while (((j = cbits(ii = getch())) != savtc) && (j != '\n') && (j != savlc)) { 445 jj = width(ii); 446 ws += jj; 447 numtab[HP].val += jj; 448 widthp = jj; 449 *fp++ = ii; 450 if (fp > (fbuf + FBUFSZ - 3)) 451 break; 452 } 453 *fp++ = ii; 454 *fp++ = 0; 455 if (type == RTAB) 456 length -= ws; 457 else 458 length -= ws / 2; /*CTAB*/ 459 pushback(fbuf); 460 if ((j = width(rchar)) != 0 && length > 0) { 461 int nchar = length / j; 462 while (nchar-- > 0 && pbp < &pbbuf[NC-3]) 463 *pbp++ = rchar; 464 length %= j; 465 } 466 length = (length / HOR) * HOR; 467 jj = makem(length); 468 nlflg = 0; 469 } 470 rtn: 471 gchtab[fc] &= ~FCBIT; 472 gchtab[tabch] &= ~TABBIT; 473 gchtab[ldrch] &= ~LDRBIT; 474 fc = savfc; 475 tabch = savtc; 476 ldrch = savlc; 477 gchtab[fc] |= FCBIT; 478 gchtab[tabch] = TABBIT; 479 gchtab[ldrch] |= LDRBIT; 480 numtab[HP].val = savepos; 481 return(jj); 482 } 483 484 485