Blob
1 #include "tdef.h"2 #include "fns.h"3 #include "ext.h"5 /*6 * troff10.c7 *8 * typesetter interface9 */11 int vpos = 0; /* absolute vertical position on page */12 int hpos = 0; /* ditto horizontal */14 extern Font fonts[MAXFONTS+1];16 int Inch;17 int Hor;18 int Vert;19 int Unitwidth;20 int nfonts;24 void t_ptinit(void)25 {26 int i;27 char buf[100], *p;29 hmot = t_hmot;30 makem = t_makem;31 setabs = t_setabs;32 setch = t_setch;33 sethl = t_sethl;34 setht = t_setht;35 setslant = t_setslant;36 vmot = t_vmot;37 xlss = t_xlss;38 findft = t_findft;39 width = t_width;40 mchbits = t_mchbits;41 ptlead = t_ptlead;42 ptout = t_ptout;43 ptpause = t_ptpause;44 setfont = t_setfont;45 setps = t_setps;46 setwd = t_setwd;48 /* open table for device, */49 /* read in resolution, size info, font info, etc., set params */50 if ((p = getenv("TYPESETTER")) != 0)51 strcpy(devname, p);52 if (termtab[0] == 0)53 strcpy(termtab, DWBfontdir);54 if (fontdir[0] == 0)55 strcpy(fontdir, DWBfontdir);56 if (devname[0] == 0)57 strcpy(devname, TDEVNAME);58 hyf = 1;59 lg = 1;61 sprintf(buf, "/dev%s/DESC", devname);62 strcat(termtab, buf);63 if (getdesc(termtab) < 0) {64 ERROR "can't open DESC file %s", termtab WARN;65 done3(1);66 }67 if (!ascii) {68 OUT "x T %s\n", devname PUT;69 OUT "x res %d %d %d\n", Inch, Hor, Vert PUT;70 OUT "x init\n" PUT;71 }72 for (i = 1; i <= nfonts; i++)73 setfp(i, fontlab[i], (char *) 0, 0);74 sps = EM/3; /* space size */75 ics = EM; /* insertion character space */76 for (i = 0; i < (NTAB - 1) && DTAB * (i + 1) < TABMASK; i++)77 tabtab[i] = DTAB * (i + 1);78 tabtab[NTAB] = 0;79 pl = 11 * INCH; /* paper length */80 po = PO; /* page offset */81 spacesz = SS;82 lss = lss1 = VS;83 ll = ll1 = lt = lt1 = LL;84 t_specnames(); /* install names like "hyphen", etc. */85 }87 void t_specnames(void)88 {89 int i;91 for (i = 0; spnames[i].n; i++)92 *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);93 }95 void t_ptout(Tchar i)96 {97 int dv;98 Tchar *k;99 int temp, a, b;100 int diff;102 if (cbits(i) != '\n') {103 if (olinep >= oline + olnsize) {104 diff = olinep - oline;105 olnsize += OLNSIZE;106 if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {107 if (diff && olinep)108 olinep = oline + diff;109 } else {110 ERROR "Output line overflow." WARN;111 done(2);112 }113 }114 *olinep++ = i;115 return;116 }117 if (olinep == oline) {118 lead += lss;119 return;120 }122 hpos = po; /* ??? */123 esc = 0; /* ??? */124 ptesc(); /* the problem is to get back to the left end of the line */125 dv = 0;126 for (k = oline; k < olinep; k++) {127 if (ismot(*k) && isvmot(*k)) {128 temp = absmot(*k);129 if (isnmot(*k))130 temp = -temp;131 dv += temp;132 }133 }134 if (dv) {135 vflag++;136 *olinep++ = makem(-dv);137 vflag = 0;138 }140 b = dip->blss + lss;141 lead += dip->blss + lss;142 dip->blss = 0;143 for (k = oline; k < olinep; )144 k += ptout0(k); /* now passing a pointer! */145 olinep = oline;146 lead += dip->alss;147 a = dip->alss;148 dip->alss = 0;149 /*150 OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;151 */152 OUT "n%d %d\n", b, a PUT; /* be nice to chuck */153 }155 int ptout0(Tchar *pi)156 {157 int j, k, w;158 int z, dx, dy, dx2, dy2, n;159 Tchar i;160 int outsize; /* size of object being printed */162 w = 0;163 outsize = 1; /* default */164 i = *pi;165 k = cbits(i);166 if (ismot(i)) {167 j = absmot(i);168 if (isnmot(i))169 j = -j;170 if (isvmot(i))171 lead += j;172 else173 esc += j;174 return(outsize);175 }176 if (k == CHARHT) {177 xpts = fbits(i); /* sneaky, font bits as size bits */178 if (xpts != mpts)179 ptps();180 OUT "x H %ld\n", sbits(i) PUT;181 return(outsize);182 }183 if (k == SLANT) {184 OUT "x S %ld\n", sfbits(i)-180 PUT;185 return(outsize);186 }187 if (k == WORDSP) {188 oput('w');189 return(outsize);190 }191 if (sfbits(i) == oldbits) {192 xfont = pfont;193 xpts = ppts;194 } else195 xbits(i, 2);196 if (k == XON) {197 extern int xon;198 ptflush(); /* guarantee that everything is out */199 if (esc)200 ptesc();201 if (xfont != mfont)202 ptfont();203 if (xpts != mpts)204 ptps();205 if (lead)206 ptlead();207 OUT "x X " PUT;208 xon++;209 for (j = 1; cbits(pi[j]) != XOFF; j++)210 outascii(pi[j]);211 oput('\n');212 xon--;213 return j+1;214 }215 if (k < 040 && k != DRAWFCN)216 return(outsize);217 j = z = 0;218 if (k != DRAWFCN) {219 if (widcache[k].fontpts == (xfont<<8) + xpts && !setwdf) {220 w = widcache[k].width;221 bd = 0;222 cs = 0;223 } else224 w = getcw(k);225 if (cs) {226 if (bd)227 w += (bd - 1) * HOR;228 j = (cs - w) / 2;229 w = cs - j;230 if (bd)231 w -= (bd - 1) * HOR;232 }233 if (iszbit(i)) {234 if (cs)235 w = -j;236 else237 w = 0;238 z = 1;239 }240 }241 esc += j;242 if (xfont != mfont)243 ptfont();244 if (xpts != mpts)245 ptps();246 if (lead)247 ptlead();248 /* put out the real character here */249 if (k == DRAWFCN) {250 if (esc)251 ptesc();252 w = 0;253 dx = absmot(pi[3]);254 if (isnmot(pi[3]))255 dx = -dx;256 dy = absmot(pi[4]);257 if (isnmot(pi[4]))258 dy = -dy;259 switch (cbits(pi[1])) {260 case DRAWCIRCLE: /* circle */261 OUT "D%c %d\n", DRAWCIRCLE, dx PUT; /* dx is diameter */262 hpos += dx;263 break;264 case DRAWELLIPSE:265 OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;266 hpos += dx;267 break;268 case DRAWBUILD:269 k = cbits(pi[2]);270 OUT "D%c %d ", DRAWBUILD, dx PUT;271 if (k < ALPHABET)272 OUT "%c\n", k PUT;273 else274 ptchname(k);275 hpos += dx;276 break;277 case DRAWLINE: /* line */278 k = cbits(pi[2]);279 OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;280 if (k < ALPHABET)281 OUT "%c\n", k PUT;282 else283 ptchname(k);284 hpos += dx;285 vpos += dy;286 break;287 case DRAWARC: /* arc */288 dx2 = absmot(pi[5]);289 if (isnmot(pi[5]))290 dx2 = -dx2;291 dy2 = absmot(pi[6]);292 if (isnmot(pi[6]))293 dy2 = -dy2;294 OUT "D%c %d %d %d %d\n", DRAWARC,295 dx, dy, dx2, dy2 PUT;296 hpos += dx + dx2;297 vpos += dy + dy2;298 break;300 case 's': /* using 's' internally to avoid .tr ~ */301 pi[1] = '~';302 case DRAWSPLINE: /* spline */303 default: /* something else; copy it like spline */304 OUT "D%c %d %d", (char)cbits(pi[1]), dx, dy PUT;305 hpos += dx;306 vpos += dy;307 if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {308 /* it was somehow defective */309 OUT "\n" PUT;310 break;311 }312 for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {313 dx = absmot(pi[n]);314 if (isnmot(pi[n]))315 dx = -dx;316 dy = absmot(pi[n+1]);317 if (isnmot(pi[n+1]))318 dy = -dy;319 OUT " %d %d", dx, dy PUT;320 hpos += dx;321 vpos += dy;322 }323 OUT "\n" PUT;324 break;325 }326 for (n = 3; cbits(pi[n]) != DRAWFCN; n++)327 ;328 outsize = n + 1;329 } else if (k < ALPHABET) {330 /* try to go faster and compress output */331 /* by printing nnc for small positive motion followed by c */332 /* kludgery; have to make sure set all the vars too */333 if (esc > 0 && esc < 100) {334 oput(esc / 10 + '0');335 oput(esc % 10 + '0');336 oput(k);337 hpos += esc;338 esc = 0;339 } else {340 if (esc)341 ptesc();342 oput('c');343 oput(k);344 oput('\n');345 }346 } else {347 if (esc)348 ptesc();349 ptchname(k);350 }351 if (bd) {352 bd -= HOR;353 if (esc += bd)354 ptesc();355 if (k < ALPHABET)356 OUT "c%c\n", k PUT;357 else358 ptchname(k);359 if (z)360 esc -= bd;361 }362 esc += w;363 return(outsize);364 }366 void ptchname(int k)367 {368 char *chn = chname(k);370 switch (chn[0]) {371 case MBchar:372 OUT "c%s\n", chn+1 PUT; /* \n not needed? */373 break;374 case Number:375 OUT "N%s\n", chn+1 PUT;376 break;377 case Troffchar:378 OUT "C%s\n", chn+1 PUT;379 break;380 default:381 ERROR "illegal char type %s", chn WARN;382 break;383 }384 }386 void ptflush(void) /* get us to a clean output state */387 {388 if (TROFF) {389 /* ptesc(); but always H, no h */390 hpos += esc;391 OUT "\nH%d\n", hpos PUT;392 esc = 0;393 ptps();394 ptfont();395 ptlead();396 }397 }399 void ptps(void)400 {401 int i, j, k;403 i = xpts;404 for (j = 0; i > (k = pstab[j]); j++)405 if (!k) {406 k = pstab[--j];407 break;408 }409 if (!ascii)410 OUT "s%d\n", k PUT; /* really should put out string rep of size */411 mpts = i;412 }414 void ptfont(void)415 {416 mfont = xfont;417 if (ascii)418 return;419 if (xfont > nfonts) {420 ptfpcmd(0, fonts[xfont].longname, 0); /* Put the desired font in the421 * fontcache of the filter */422 OUT "f0\n" PUT; /* make sure that it gets noticed */423 } else424 OUT "f%d\n", xfont PUT;425 }427 void ptfpcmd(int f, char *s, char *longname)428 {429 if (f > nfonts) /* a bit risky? */430 f = 0;431 if (longname) {432 OUT "x font %d %s %s\n", f, s, longname PUT;433 } else {434 OUT "x font %d %s\n", f, s PUT;435 }436 /* OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */437 /* which apparently believes that x font means */438 /* to set the font, not just the position. */439 }441 void t_ptlead(void)442 {443 vpos += lead;444 if (!ascii)445 OUT "V%d\n", vpos PUT;446 lead = 0;447 }449 void ptesc(void)450 {451 hpos += esc;452 if (!ascii)453 if (esc > 0) {454 oput('h');455 if (esc>=10 && esc<100) {456 oput(esc/10 + '0');457 oput(esc%10 + '0');458 } else459 OUT "%d", esc PUT;460 } else461 OUT "H%d\n", hpos PUT;462 esc = 0;463 }465 void ptpage(int n) /* called at end of each output page, we hope */466 {467 int i;469 if (NROFF)470 return;471 ptlead();472 vpos = 0;473 if (ascii)474 return;475 OUT "p%d\n", n PUT; /* new page */476 for (i = 0; i <= nfonts; i++)477 if (fontlab[i]) {478 if (fonts[i].truename)479 OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;480 else481 OUT "x font %d %s\n", i, fonts[i].longname PUT;482 }483 ptps();484 ptfont();485 }487 void pttrailer(void)488 {489 if (TROFF)490 OUT "x trailer\n" PUT;491 }493 void ptstop(void)494 {495 if (TROFF)496 OUT "x stop\n" PUT;497 }499 void t_ptpause(void)500 {501 if (ascii)502 return;503 ptlead();504 vpos = 0;505 pttrailer();506 ptlead();507 OUT "x pause\n" PUT;508 flusho();509 mpts = mfont = 0;510 ptesc();511 esc = po;512 hpos = vpos = 0; /* probably in wrong place */513 }