t10.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "tdef.h"
  10. #include "fns.h"
  11. #include "ext.h"
  12. /*
  13. * troff10.c
  14. *
  15. * typesetter interface
  16. */
  17. int vpos = 0; /* absolute vertical position on page */
  18. int hpos = 0; /* ditto horizontal */
  19. extern Font fonts[MAXFONTS+1];
  20. int Inch;
  21. int Hor;
  22. int Vert;
  23. int Unitwidth;
  24. int nfonts;
  25. void t_ptinit(void)
  26. {
  27. int i;
  28. 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;
  47. /* open table for device, */
  48. /* read in resolution, size info, font info, etc., set params */
  49. if ((p = getenv("TYPESETTER")) != 0){
  50. strncpy(devname, p, sizeof devname);
  51. devname[sizeof devname-1] = 0;
  52. }
  53. if (termtab[0] == 0)
  54. strcpy(termtab, DWBfontdir);
  55. if (fontdir[0] == 0)
  56. strcpy(fontdir, DWBfontdir);
  57. if (devname[0] == 0)
  58. strcpy(devname, TDEVNAME);
  59. hyf = 1;
  60. lg = 1;
  61. snprintf(buf, sizeof 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-1] = 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. }
  86. void t_specnames(void)
  87. {
  88. int i;
  89. for (i = 0; spnames[i].n; i++)
  90. *spnames[i].n = chadd(spnames[i].v, Troffchar, Install);
  91. }
  92. void t_ptout(Tchar i)
  93. {
  94. int dv;
  95. Tchar *k;
  96. int temp, a, b;
  97. int diff;
  98. if (cbits(i) != '\n') {
  99. if (olinep >= oline + olnsize) {
  100. diff = olinep - oline;
  101. olnsize += OLNSIZE;
  102. if ((oline = (Tchar *)realloc((char *)oline, olnsize * sizeof(Tchar))) != NULL) {
  103. if (diff && olinep)
  104. olinep = oline + diff;
  105. } else {
  106. ERROR "Output line overflow." WARN;
  107. done(2);
  108. }
  109. }
  110. *olinep++ = i;
  111. return;
  112. }
  113. if (olinep == oline) {
  114. lead += lss;
  115. return;
  116. }
  117. hpos = po; /* ??? */
  118. esc = 0; /* ??? */
  119. ptesc(); /* the problem is to get back to the left end of the line */
  120. dv = 0;
  121. for (k = oline; k < olinep; k++) {
  122. if (ismot(*k) && isvmot(*k)) {
  123. temp = absmot(*k);
  124. if (isnmot(*k))
  125. temp = -temp;
  126. dv += temp;
  127. }
  128. }
  129. if (dv) {
  130. vflag++;
  131. *olinep++ = makem(-dv);
  132. vflag = 0;
  133. }
  134. b = dip->blss + lss;
  135. lead += dip->blss + lss;
  136. dip->blss = 0;
  137. for (k = oline; k < olinep; )
  138. k += ptout0(k); /* now passing a pointer! */
  139. olinep = oline;
  140. lead += dip->alss;
  141. a = dip->alss;
  142. dip->alss = 0;
  143. /*
  144. OUT "x xxx end of line: hpos=%d, vpos=%d\n", hpos, vpos PUT;
  145. */
  146. OUT "n%d %d\n", b, a PUT; /* be nice to chuck */
  147. }
  148. int ptout0(Tchar *pi)
  149. {
  150. int j, k, w, z, dx, dy, dx2, dy2, n;
  151. int outsize; /* size of object being printed */
  152. Tchar i;
  153. w = 0;
  154. outsize = 1; /* default */
  155. i = *pi;
  156. k = cbits(i);
  157. if (ismot(i)) {
  158. j = absmot(i);
  159. if (isnmot(i))
  160. j = -j;
  161. if (isvmot(i))
  162. lead += j;
  163. else
  164. esc += j;
  165. return(outsize);
  166. }
  167. if (k == CHARHT) {
  168. xpts = fbits(i); /* sneaky, font bits as size bits */
  169. if (xpts != mpts)
  170. ptps();
  171. OUT "x H %d\n", sbits(i) PUT;
  172. return(outsize);
  173. }
  174. if (k == SLANT) {
  175. OUT "x S %d\n", sfbits(i)-180 PUT;
  176. return(outsize);
  177. }
  178. if (k == WORDSP) {
  179. oput('w');
  180. return(outsize);
  181. }
  182. if (sfbits(i) == oldbits) {
  183. xfont = pfont;
  184. xpts = ppts;
  185. } else
  186. xbits(i, 2);
  187. if (k == XON) {
  188. extern int xon;
  189. ptflush(); /* guarantee that everything is out */
  190. if (esc)
  191. ptesc();
  192. if (xfont != mfont)
  193. ptfont();
  194. if (xpts != mpts)
  195. ptps();
  196. if (lead)
  197. ptlead();
  198. OUT "x X " PUT;
  199. xon++;
  200. for (j = 1; cbits(pi[j]) != XOFF; j++)
  201. outascii(pi[j]);
  202. oput('\n');
  203. xon--;
  204. return j+1;
  205. }
  206. if (k < 040 && k != DRAWFCN)
  207. return(outsize);
  208. j = z = 0;
  209. if (k != DRAWFCN) {
  210. if (widcache[k].fontpts == (xfont<<8) + xpts && !setwdf) {
  211. w = widcache[k].width;
  212. bd = 0;
  213. cs = 0;
  214. } else
  215. w = getcw(k);
  216. if (cs) {
  217. if (bd)
  218. w += (bd - 1) * HOR;
  219. j = (cs - w) / 2;
  220. w = cs - j;
  221. if (bd)
  222. w -= (bd - 1) * HOR;
  223. }
  224. if (iszbit(i)) {
  225. if (cs)
  226. w = -j;
  227. else
  228. w = 0;
  229. z = 1;
  230. }
  231. }
  232. esc += j;
  233. if (xfont != mfont)
  234. ptfont();
  235. if (xpts != mpts)
  236. ptps();
  237. if (lead)
  238. ptlead();
  239. /* put out the real character here */
  240. if (k == DRAWFCN) {
  241. if (esc)
  242. ptesc();
  243. w = 0;
  244. dx = absmot(pi[3]);
  245. if (isnmot(pi[3]))
  246. dx = -dx;
  247. dy = absmot(pi[4]);
  248. if (isnmot(pi[4]))
  249. dy = -dy;
  250. switch (cbits(pi[1])) {
  251. case DRAWCIRCLE: /* circle */
  252. OUT "D%c %d\n", DRAWCIRCLE, dx PUT; /* dx is diameter */
  253. hpos += dx;
  254. break;
  255. case DRAWELLIPSE:
  256. OUT "D%c %d %d\n", DRAWELLIPSE, dx, dy PUT;
  257. hpos += dx;
  258. break;
  259. case DRAWBUILD:
  260. k = cbits(pi[2]);
  261. OUT "D%c %d ", DRAWBUILD, dx PUT;
  262. if (k < ALPHABET)
  263. OUT "%c\n", k PUT;
  264. else
  265. ptchname(k);
  266. hpos += dx;
  267. break;
  268. case DRAWLINE: /* line */
  269. k = cbits(pi[2]);
  270. OUT "D%c %d %d ", DRAWLINE, dx, dy PUT;
  271. if (k < ALPHABET)
  272. OUT "%c\n", k PUT;
  273. else
  274. ptchname(k);
  275. hpos += dx;
  276. vpos += dy;
  277. break;
  278. case DRAWARC: /* arc */
  279. dx2 = absmot(pi[5]);
  280. if (isnmot(pi[5]))
  281. dx2 = -dx2;
  282. dy2 = absmot(pi[6]);
  283. if (isnmot(pi[6]))
  284. dy2 = -dy2;
  285. OUT "D%c %d %d %d %d\n", DRAWARC,
  286. dx, dy, dx2, dy2 PUT;
  287. hpos += dx + dx2;
  288. vpos += dy + dy2;
  289. break;
  290. case 's': /* using 's' internally to avoid .tr ~ */
  291. pi[1] = '~';
  292. case DRAWSPLINE: /* spline */
  293. default: /* something else; copy it like spline */
  294. OUT "D%c %d %d", cbits(pi[1]), dx, dy PUT;
  295. hpos += dx;
  296. vpos += dy;
  297. if (cbits(pi[3]) == DRAWFCN || cbits(pi[4]) == DRAWFCN) {
  298. /* it was somehow defective */
  299. OUT "\n" PUT;
  300. break;
  301. }
  302. for (n = 5; cbits(pi[n]) != DRAWFCN; n += 2) {
  303. dx = absmot(pi[n]);
  304. if (isnmot(pi[n]))
  305. dx = -dx;
  306. dy = absmot(pi[n+1]);
  307. if (isnmot(pi[n+1]))
  308. dy = -dy;
  309. OUT " %d %d", dx, dy PUT;
  310. hpos += dx;
  311. vpos += dy;
  312. }
  313. OUT "\n" PUT;
  314. break;
  315. }
  316. for (n = 3; cbits(pi[n]) != DRAWFCN; n++)
  317. ;
  318. outsize = n + 1;
  319. } else if (k < ALPHABET) {
  320. /* try to go faster and compress output */
  321. /* by printing nnc for small positive motion followed by c */
  322. /* kludgery; have to make sure set all the vars too */
  323. if (esc > 0 && esc < 100) {
  324. oput(esc / 10 + '0');
  325. oput(esc % 10 + '0');
  326. oput(k);
  327. hpos += esc;
  328. esc = 0;
  329. } else {
  330. if (esc)
  331. ptesc();
  332. oput('c');
  333. oput(k);
  334. oput('\n');
  335. }
  336. } else {
  337. if (esc)
  338. ptesc();
  339. ptchname(k);
  340. }
  341. if (bd) {
  342. bd -= HOR;
  343. if (esc += bd)
  344. ptesc();
  345. if (k < ALPHABET)
  346. OUT "c%c\n", k PUT;
  347. else
  348. ptchname(k);
  349. if (z)
  350. esc -= bd;
  351. }
  352. esc += w;
  353. return(outsize);
  354. }
  355. void ptchname(int k)
  356. {
  357. char *chn = chname(k);
  358. switch (chn[0]) {
  359. case MBchar:
  360. OUT "c%s\n", chn+1 PUT; /* \n not needed? */
  361. break;
  362. case Number:
  363. OUT "N%s\n", chn+1 PUT;
  364. break;
  365. case Troffchar:
  366. OUT "C%s\n", chn+1 PUT;
  367. break;
  368. default:
  369. ERROR "illegal char type %s", chn WARN;
  370. break;
  371. }
  372. }
  373. void ptflush(void) /* get us to a clean output state */
  374. {
  375. if (TROFF) {
  376. /* ptesc(); but always H, no h */
  377. hpos += esc;
  378. OUT "\nH%d\n", hpos PUT;
  379. esc = 0;
  380. ptps();
  381. ptfont();
  382. ptlead();
  383. }
  384. }
  385. void ptps(void)
  386. {
  387. int i, j, k;
  388. i = xpts;
  389. for (j = 0; i > (k = pstab[j]); j++)
  390. if (!k) {
  391. k = pstab[--j];
  392. break;
  393. }
  394. if (!ascii)
  395. OUT "s%d\n", k PUT; /* really should put out string rep of size */
  396. mpts = i;
  397. }
  398. void ptfont(void)
  399. {
  400. mfont = xfont;
  401. if (ascii)
  402. return;
  403. if (xfont > nfonts) {
  404. ptfpcmd(0, fonts[xfont].longname, 0); /* Put the desired font in the
  405. * fontcache of the filter */
  406. OUT "f0\n" PUT; /* make sure that it gets noticed */
  407. } else
  408. OUT "f%d\n", xfont PUT;
  409. }
  410. void ptfpcmd(int f, char *s, char *longname)
  411. {
  412. if (f > nfonts) /* a bit risky? */
  413. f = 0;
  414. if (longname) {
  415. OUT "x font %d %s %s\n", f, s, longname PUT;
  416. } else {
  417. OUT "x font %d %s\n", f, s PUT;
  418. }
  419. /* OUT "f%d\n", xfont PUT; /* need this for buggy version of adobe transcript */
  420. /* which apparently believes that x font means */
  421. /* to set the font, not just the position. */
  422. }
  423. void t_ptlead(void)
  424. {
  425. vpos += lead;
  426. if (!ascii)
  427. OUT "V%d\n", vpos PUT;
  428. lead = 0;
  429. }
  430. void ptesc(void)
  431. {
  432. hpos += esc;
  433. if (!ascii)
  434. if (esc > 0) {
  435. oput('h');
  436. if (esc>=10 && esc<100) {
  437. oput(esc/10 + '0');
  438. oput(esc%10 + '0');
  439. } else
  440. OUT "%d", esc PUT;
  441. } else
  442. OUT "H%d\n", hpos PUT;
  443. esc = 0;
  444. }
  445. void ptpage(int n) /* called at end of each output page, we hope */
  446. {
  447. int i;
  448. if (NROFF)
  449. return;
  450. ptlead();
  451. vpos = 0;
  452. if (ascii)
  453. return;
  454. OUT "p%d\n", n PUT; /* new page */
  455. for (i = 0; i <= nfonts; i++)
  456. if (fontlab[i]) {
  457. if (fonts[i].truename)
  458. OUT "x font %d %s %s\n", i, fonts[i].longname, fonts[i].truename PUT;
  459. else
  460. OUT "x font %d %s\n", i, fonts[i].longname PUT;
  461. }
  462. ptps();
  463. ptfont();
  464. }
  465. void pttrailer(void)
  466. {
  467. if (TROFF)
  468. OUT "x trailer\n" PUT;
  469. }
  470. void ptstop(void)
  471. {
  472. if (TROFF)
  473. OUT "x stop\n" PUT;
  474. }
  475. void t_ptpause(void)
  476. {
  477. if (ascii)
  478. return;
  479. ptlead();
  480. vpos = 0;
  481. pttrailer();
  482. ptlead();
  483. OUT "x pause\n" PUT;
  484. flusho();
  485. mpts = mfont = 0;
  486. ptesc();
  487. esc = po;
  488. hpos = vpos = 0; /* probably in wrong place */
  489. }