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