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]; 97 int delim, w[NOV]; 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[100], dy[100], 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 249 if (ismot(c = getch())) 250 return; 251 delim = cbits(c); 252 type = cbits(getch()); 253 for (i = 0; i < 50 ; i++) { 254 c = getch(); 255 if (cbits(c) == delim) 256 break; 257 /* ought to pick up optional drawing character */ 258 if (cbits(c) != ' ') 259 ch = c; 260 vflag = 0; 261 dfact = EM; 262 dx[i] = quant(atoi(), HOR); 263 if (dx[i] > MAXMOT) 264 dx[i] = MAXMOT; 265 else if (dx[i] < -MAXMOT) 266 dx[i] = -MAXMOT; 267 if (cbits((c = getch())) == delim) { /* spacer */ 268 dy[i++] = 0; 269 break; 270 } 271 vflag = 1; 272 dfact = lss; 273 dy[i] = quant(atoi(), VERT); 274 if (dy[i] > MAXMOT) 275 dy[i] = MAXMOT; 276 else if (dy[i] < -MAXMOT) 277 dy[i] = -MAXMOT; 278 } 279 dfact = 1; 280 vflag = 0; 281 #ifndef NROFF 282 cbuf[0] = DRAWFCN | chbits | ZBIT; 283 cbuf[1] = type | chbits | ZBIT; 284 cbuf[2] = '.' | chbits | ZBIT; /* indicates to use default drawing character */ 285 for (k = 0, j = 3; k < i; k++) { 286 cbuf[j++] = MOT | ((dx[k] >= 0) ? dx[k] : (NMOT | -dx[k])); 287 cbuf[j++] = MOT | VMOT | ((dy[k] >= 0) ? dy[k] : (NMOT | -dy[k])); 288 } 289 if (type == DRAWELLIPSE) { 290 cbuf[5] = cbuf[4] | NMOT; /* so the net vertical is zero */ 291 j = 6; 292 } 293 cbuf[j++] = '.' | chbits | ZBIT; /* marks end for ptout */ 294 cbuf[j] = 0; 295 cp = cbuf; 296 #endif 297 } 298 299 300 casefc() 301 { 302 register i; 303 tchar j; 304 305 fc = IMP; 306 padc = ' '; 307 if (skip() || ismot(j = getch()) || (i = cbits(j)) == '\n') 308 return; 309 fc = i; 310 if (skip() || ismot(ch) || (ch = cbits(ch)) == fc) 311 return; 312 padc = ch; 313 } 314 315 316 tchar setfield(x) 317 int x; 318 { 319 tchar ii, jj, *fp; 320 register i, j; 321 int length, ws, npad, temp, type; 322 tchar * *pp, *padptr[NPP]; 323 static tchar fbuf[FBUFSZ]; 324 int savfc, savtc, savlc; 325 326 if (x == tabch) 327 rchar = tabc | chbits; 328 else if (x == ldrch) 329 rchar = dotc | chbits; 330 temp = npad = ws = 0; 331 savfc = fc; 332 savtc = tabch; 333 savlc = ldrch; 334 tabch = ldrch = fc = IMP; 335 for (j = 0; ; j++) { 336 if ((tabtab[j] & TMASK) == 0) { 337 if (x == savfc) 338 fprintf(stderr, "troff: zero field width.\n"); 339 jj = 0; 340 goto rtn; 341 } 342 v.hp = sumhp(); /* XXX */ 343 if ((length = ((tabtab[j] & TMASK) - v.hp)) > 0 ) 344 break; 345 } 346 type = tabtab[j] & (~TMASK); 347 fp = fbuf; 348 pp = padptr; 349 if (x == savfc) { 350 while (1) { 351 if (((j = cbits(ii = getch()))) == padc) { 352 npad++; 353 *pp++ = fp; 354 if (pp > (padptr + NPP - 1)) 355 break; 356 goto s1; 357 } else if (j == savfc) 358 break; 359 else if (j == '\n') { 360 temp = j; 361 nlflg = 0; 362 break; 363 } 364 ws += width(ii); 365 s1: 366 *fp++ = ii; 367 if (fp > (fbuf + FBUFSZ - 3)) 368 break; 369 } 370 if (!npad) { 371 npad++; 372 *pp++ = fp; 373 *fp++ = 0; 374 } 375 *fp++ = temp; 376 *fp++ = 0; 377 temp = i = (j = length - ws) / npad; 378 i = (i / HOR) * HOR; 379 if ((j -= i * npad) < 0) 380 j = -j; 381 ii = makem(i); 382 if (temp < 0) 383 ii |= NMOT; 384 for (; npad > 0; npad--) { 385 *(*--pp) = ii; 386 if (j) { 387 j -= HOR; 388 (*(*pp)) += HOR; 389 } 390 } 391 cp = fbuf; 392 jj = 0; 393 } else if (type == 0) { 394 /*plain tab or leader*/ 395 if ((j = width(rchar)) == 0) 396 nchar = 0; 397 else { 398 nchar = length / j; 399 length %= j; 400 } 401 if (length) 402 jj = length | MOT; 403 else 404 jj = getch0(); 405 } else { 406 /*center tab*/ 407 /*right tab*/ 408 while (((j = cbits(ii = getch())) != savtc) && (j != '\n') && (j != savlc)) { 409 ws += width(ii); 410 *fp++ = ii; 411 if (fp > (fbuf + FBUFSZ - 3)) 412 break; 413 } 414 *fp++ = ii; 415 *fp++ = 0; 416 if (type == RTAB) 417 length -= ws; 418 else 419 length -= ws / 2; /*CTAB*/ 420 if (((j = width(rchar)) == 0) || (length <= 0)) 421 nchar = 0; 422 else { 423 nchar = length / j; 424 length %= j; 425 } 426 length = (length / HOR) * HOR; 427 jj = makem(length); 428 cp = fbuf; 429 nlflg = 0; 430 } 431 rtn: 432 fc = savfc; 433 tabch = savtc; 434 ldrch = savlc; 435 return(jj); 436 } 437 438 439