1 #ifndef lint 2 static char sccsid[] = "@(#)n9.c 2.1 (CWI) 85/07/18"; 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]; 95 int delim, w[NOV]; 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 /* l dx dy: line from here by dx,dy */ 245 /* c x: circle of diameter x, left side here */ 246 /* e x y: ellipse of diameters x,y, left side here */ 247 /* a dx1 dy1 dx2 dy2: 248 ccw arc: ctr at dx1,dy1, then end at dx2,dy2 from there */ 249 /* ~ dx1 dy1 dx2 dy2...: 250 spline to dx1,dy1 to dx2,dy2 ... */ 251 /* f dx dy ...: f is any other char: like spline */ 252 253 if (ismot(c = getch())) 254 return; 255 delim = cbits(c); 256 type = cbits(getch()); 257 for (i = 0; i < NPAIR ; i++) { 258 c = getch(); 259 if (cbits(c) == delim) 260 break; 261 /* ought to pick up optional drawing character */ 262 if (cbits(c) != ' ') 263 ch = c; 264 vflag = 0; 265 dfact = EM; 266 dx[i] = quant(atoi(), HOR); 267 if (dx[i] > MAXMOT) 268 dx[i] = MAXMOT; 269 else if (dx[i] < -MAXMOT) 270 dx[i] = -MAXMOT; 271 if (cbits((c = getch())) == delim) { /* spacer */ 272 dy[i++] = 0; 273 break; 274 } 275 vflag = 1; 276 dfact = lss; 277 dy[i] = quant(atoi(), VERT); 278 if (dy[i] > MAXMOT) 279 dy[i] = MAXMOT; 280 else if (dy[i] < -MAXMOT) 281 dy[i] = -MAXMOT; 282 } 283 dfact = 1; 284 vflag = 0; 285 #ifndef NROFF 286 drawbuf[0] = DRAWFCN | chbits | ZBIT; 287 drawbuf[1] = type | chbits | ZBIT; 288 drawbuf[2] = '.' | chbits | ZBIT; /* use default drawing character */ 289 for (k = 0, j = 3; k < i; k++) { 290 drawbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k])); 291 drawbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k])); 292 } 293 if (type == DRAWELLIPSE) { 294 drawbuf[5] = drawbuf[4] | NMOT; /* so the net vertical is zero */ 295 j = 6; 296 } 297 drawbuf[j++] = DRAWFCN | chbits | ZBIT; /* marks end for ptout */ 298 drawbuf[j] = 0; 299 pushback(drawbuf); 300 #endif 301 } 302 303 304 casefc() 305 { 306 register i; 307 tchar j; 308 309 gchtab[fc] &= ~FCBIT; 310 fc = IMP; 311 padc = ' '; 312 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n') 313 return; 314 fc = i; 315 gchtab[fc] |= FCBIT; 316 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc) 317 return; 318 padc = ch; 319 } 320 321 322 tchar 323 setfield(x) 324 int x; 325 { 326 register tchar ii, jj, *fp; 327 register i, j; 328 int length, ws, npad, temp, type; 329 tchar **pp, *padptr[NPP]; 330 tchar fbuf[FBUFSZ]; 331 int savfc, savtc, savlc; 332 tchar rchar; 333 int savepos; 334 335 if (x == tabch) 336 rchar = tabc | chbits; 337 else if (x == ldrch) 338 rchar = dotc | chbits; 339 temp = npad = ws = 0; 340 savfc = fc; 341 savtc = tabch; 342 savlc = ldrch; 343 tabch = ldrch = fc = IMP; 344 savepos = numtab[HP].val; 345 gchtab[tabch] &= ~TABBIT; 346 gchtab[ldrch] &= ~LDRBIT; 347 gchtab[fc] &= ~FCBIT; 348 gchtab[IMP] |= TABBIT|LDRBIT|FCBIT; 349 for (j = 0; ; j++) { 350 if ((tabtab[j] & TABMASK) == 0) { 351 if (x == savfc) 352 errprint("zero field width."); 353 jj = 0; 354 goto rtn; 355 } 356 if ((length = ((tabtab[j] & TABMASK) - numtab[HP].val)) > 0 ) 357 break; 358 } 359 type = tabtab[j] & (~TABMASK); 360 fp = fbuf; 361 pp = padptr; 362 if (x == savfc) { 363 while (1) { 364 j = cbits(ii = getch()); 365 jj = width(ii); 366 widthp = jj; 367 numtab[HP].val += jj; 368 if (j == padc) { 369 npad++; 370 *pp++ = fp; 371 if (pp > (padptr + NPP - 1)) 372 break; 373 goto s1; 374 } else if (j == savfc) 375 break; 376 else if (j == '\n') { 377 temp = j; 378 nlflg = 0; 379 break; 380 } 381 ws += jj; 382 s1: 383 *fp++ = ii; 384 if (fp > (fbuf + FBUFSZ - 3)) 385 break; 386 } 387 if (!npad) { 388 npad++; 389 *pp++ = fp; 390 *fp++ = 0; 391 } 392 *fp++ = temp; 393 *fp++ = 0; 394 temp = i = (j = length - ws) / npad; 395 i = (i / HOR) * HOR; 396 if ((j -= i * npad) < 0) 397 j = -j; 398 ii = makem(i); 399 if (temp < 0) 400 ii |= NMOT; 401 for (; npad > 0; npad--) { 402 *(*--pp) = ii; 403 if (j) { 404 j -= HOR; 405 (*(*pp)) += HOR; 406 } 407 } 408 pushback(fbuf); 409 jj = 0; 410 } else if (type == 0) { 411 /*plain tab or leader*/ 412 if ((j = width(rchar)) > 0) { 413 int nchar = length / j; 414 while (nchar-->0 && pbp < &pbbuf[NC-3]) { 415 numtab[HP].val += j; 416 widthp = j; 417 *pbp++ = rchar; 418 } 419 length %= j; 420 } 421 if (length) 422 jj = length | MOT; 423 else 424 jj = getch0(); 425 } else { 426 /*center tab*/ 427 /*right tab*/ 428 while (((j = cbits(ii = getch())) != savtc) && (j != '\n') && (j != savlc)) { 429 jj = width(ii); 430 ws += jj; 431 numtab[HP].val += jj; 432 widthp = jj; 433 *fp++ = ii; 434 if (fp > (fbuf + FBUFSZ - 3)) 435 break; 436 } 437 *fp++ = ii; 438 *fp++ = 0; 439 if (type == RTAB) 440 length -= ws; 441 else 442 length -= ws / 2; /*CTAB*/ 443 pushback(fbuf); 444 if ((j = width(rchar)) != 0 && length > 0) { 445 int nchar = length / j; 446 while (nchar-- > 0 && pbp < &pbbuf[NC-3]) 447 *pbp++ = rchar; 448 length %= j; 449 } 450 length = (length / HOR) * HOR; 451 jj = makem(length); 452 nlflg = 0; 453 } 454 rtn: 455 gchtab[fc] &= ~FCBIT; 456 gchtab[tabch] &= ~TABBIT; 457 gchtab[ldrch] &= ~LDRBIT; 458 fc = savfc; 459 tabch = savtc; 460 ldrch = savlc; 461 gchtab[fc] |= FCBIT; 462 gchtab[tabch] = TABBIT; 463 gchtab[ldrch] |= LDRBIT; 464 numtab[HP].val = savepos; 465 return(jj); 466 } 467 468 469