utils.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "../common/common.h"
  5. #include "tr2post.h"
  6. int hpos = 0, vpos = 0;
  7. int fontsize, fontpos;
  8. #define MAXSTR 128
  9. int trindex; /* index into trofftab of current troff font */
  10. static int expecthmot = 0;
  11. void
  12. initialize(void) {
  13. }
  14. void
  15. hgoto(int x) {
  16. hpos = x;
  17. if (pageon()) {
  18. endstring();
  19. /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
  20. }
  21. }
  22. void
  23. vgoto(int y) {
  24. vpos = y;
  25. if (pageon()) {
  26. endstring();
  27. /* Bprint(Bstdout, "%d %d m\n", hpos, vpos); */
  28. }
  29. }
  30. void
  31. hmot(int x) {
  32. int delta;
  33. if ((x<expecthmot-1) || (x>expecthmot+1)) {
  34. delta = x - expecthmot;
  35. if (curtrofffontid <0 || curtrofffontid >= troffontcnt) {
  36. fprint(2, "troffontcnt=%d curtrofffontid=%d\n",
  37. troffontcnt, curtrofffontid);
  38. exits("");
  39. }
  40. if (delta == troffontab[curtrofffontid].spacewidth*fontsize/10 &&
  41. isinstring()) {
  42. if (pageon())
  43. runeout(' ');
  44. } else {
  45. if (pageon()) {
  46. endstring();
  47. /* Bprint(Bstdout, " %d 0 rmoveto ", delta); */
  48. /* Bprint(Bstdout, " %d %d m ", hpos+x, vpos); */
  49. if (debug)
  50. fprint(2, "x=%d expecthmot=%d\n",
  51. x, expecthmot);
  52. }
  53. }
  54. }
  55. hpos += x;
  56. expecthmot = 0;
  57. }
  58. void
  59. vmot(int y) {
  60. endstring();
  61. /* Bprint(Bstdout, " 0 %d rmoveto ", -y); */
  62. vpos += y;
  63. }
  64. struct charent **
  65. findglyph(int trfid, Rune rune, char *stoken) {
  66. struct charent **cp;
  67. for (cp = &(troffontab[trfid].charent[RUNEGETGROUP(rune)][RUNEGETCHAR(rune)]); *cp != 0; cp = &((*cp)->next)) {
  68. if ((*cp)->name) {
  69. if (debug) fprint(2, "looking for <%s>, have <%s> in font %s\n", stoken, (*cp)->name, troffontab[trfid].trfontid);
  70. if (strcmp((*cp)->name, stoken) == 0)
  71. break;
  72. }
  73. }
  74. return(cp);
  75. }
  76. /* output glyph. Use first rune to look up character (hash)
  77. * then use stoken UTF string to find correct glyph in linked
  78. * list of glyphs in bucket.
  79. */
  80. void
  81. glyphout(Rune rune, char *stoken, BOOLEAN specialflag) {
  82. struct charent **cp;
  83. struct troffont *tfp;
  84. struct psfent *psfp;
  85. int i, t, mi, wid;
  86. int fontid; /* this is the troff font table index, not the mounted font table index */
  87. Rune r;
  88. mi = 0;
  89. settrfont();
  90. /* check current font for the character, special or not */
  91. fontid = curtrofffontid;
  92. if (debug)
  93. fprint(2, "\tlooking through current font: trying %s\n",
  94. troffontab[fontid].trfontid);
  95. cp = findglyph(fontid, rune, stoken);
  96. if (*cp != 0)
  97. goto foundit;
  98. if (specialflag) {
  99. if (expecthmot)
  100. hmot(0);
  101. /* check special fonts for the special character */
  102. /* cycle through the (troff) mounted fonts starting at the next font */
  103. for (mi=0; mi<fontmnt; mi++) {
  104. if (troffontab[fontid].trfontid==0)
  105. error(WARNING, "glyphout:troffontab[%d].trfontid=0x%x, botch!\n",
  106. fontid, troffontab[fontid].trfontid);
  107. if (fontmtab[mi]==0) {
  108. if (debug)
  109. fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n",
  110. mi, fontmtab[mi], fontmnt);
  111. continue;
  112. }
  113. if (strcmp(troffontab[fontid].trfontid, fontmtab[mi])==0)
  114. break;
  115. }
  116. if (mi==fontmnt)
  117. error(FATAL, "current troff font is not mounted, botch!\n");
  118. for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
  119. if (fontmtab[i]==0) {
  120. if (debug)
  121. fprint(2, "fontmtab[%d]=%#p, fontmnt=%d\n",
  122. i, fontmtab[i], fontmnt);
  123. continue;
  124. }
  125. fontid = findtfn(fontmtab[i], TRUE);
  126. if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
  127. if (troffontab[fontid].special) {
  128. cp = findglyph(fontid, rune, stoken);
  129. if (*cp != 0)
  130. goto foundit;
  131. }
  132. }
  133. /* check font 1 (if current font is not font 1) for the special character */
  134. if (mi != 1) {
  135. fontid = findtfn(fontmtab[1], TRUE);;
  136. if (debug) fprint(2, " looking through font at position 1: trying %s\n", troffontab[fontid].trfontid);
  137. cp = findglyph(fontid, rune, stoken);
  138. if (*cp != 0) goto foundit;
  139. }
  140. }
  141. if (*cp == 0) {
  142. error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n", rune, stoken,
  143. troffontab[curtrofffontid].trfontid);
  144. expecthmot = 0;
  145. }
  146. /* use the peter face in lieu of the character that we couldn't find */
  147. rune = 'p'; stoken = "pw";
  148. for (i=(mi+1)%fontmnt; i!=mi; i=(i+1)%fontmnt) {
  149. if (fontmtab[i]==0) {
  150. if (debug) fprint(2, "fontmtab[%d]=%#p\n", i, fontmtab[i]);
  151. continue;
  152. }
  153. fontid = findtfn(fontmtab[i], TRUE);
  154. if (debug) fprint(2, " looking through special fonts: trying %s\n", troffontab[fontid].trfontid);
  155. if (troffontab[fontid].special) {
  156. cp = findglyph(fontid, rune, stoken);
  157. if (*cp != 0) goto foundit;
  158. }
  159. }
  160. if (*cp == 0) {
  161. error(WARNING, "cannot find glyph, rune=0x%x stoken=<%s> troff font %s\n",
  162. rune, stoken, troffontab[curtrofffontid].trfontid);
  163. expecthmot = 0;
  164. return;
  165. }
  166. foundit:
  167. t = (((*cp)->postfontid&0xff)<<8) | ((*cp)->postcharid&0xff);
  168. if (debug)
  169. fprint(2, "runeout(0x%x)<%C> postfontid=0x%x postcharid=0x%x troffcharwidth=%d\n",
  170. rune, rune, (*cp)->postfontid, (*cp)->postcharid,
  171. (*cp)->troffcharwidth);
  172. tfp = &troffontab[fontid];
  173. psfp = nil;
  174. for (i=0; i<tfp->psfmapsize; i++) {
  175. psfp = &(tfp->psfmap[i]);
  176. if(t>=psfp->start && t<=psfp->end)
  177. break;
  178. }
  179. if (i >= tfp->psfmapsize)
  180. error(FATAL, "character <0x%x> does not have a Postscript font defined.\n", rune);
  181. setpsfont(psfp->psftid, fontsize);
  182. if (t == 0x0001) { /* character is in charlib */
  183. endstring();
  184. if (pageon()) {
  185. Bprint(Bstdout, "%d %d m ", hpos, vpos);
  186. /* if char is unicode character rather than name, clean up for postscript */
  187. wid = chartorune(&r, (*cp)->name);
  188. if(' '<r && r<0x7F)
  189. Bprint(Bstdout, "%d build_%s\n",
  190. (*cp)->troffcharwidth, (*cp)->name);
  191. else{
  192. if((*cp)->name[wid] != 0)
  193. error(FATAL, "character <%s> badly named\n", (*cp)->name);
  194. Bprint(Bstdout, "%d build_X%.4x\n",
  195. (*cp)->troffcharwidth, r);
  196. }
  197. /*
  198. * stash charent pointer in a list so that we can
  199. * print these character definitions in the prologue.
  200. */
  201. for (i=0; i<build_char_cnt; i++)
  202. if (*cp == build_char_list[i])
  203. break;
  204. if (i == build_char_cnt) {
  205. build_char_list = galloc(build_char_list,
  206. sizeof(struct charent *)*++build_char_cnt,
  207. "build_char_list");
  208. build_char_list[build_char_cnt-1] = *cp;
  209. }
  210. }
  211. expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
  212. } else if (isinstring() || rune != ' ') {
  213. startstring();
  214. if (pageon())
  215. if (rune == ' ')
  216. Bprint(Bstdout, " ");
  217. else
  218. Bprint(Bstdout, "%s", charcode[RUNEGETCHAR(t)].str);
  219. expecthmot = (*cp)->troffcharwidth * fontsize / unitwidth;
  220. }
  221. }
  222. /*
  223. * runeout puts a symbol into a string (queue) to be output.
  224. * It also has to keep track of the current and last symbol
  225. * output to check that the spacing is correct by default
  226. * or needs to be adjusted with a spacing operation.
  227. */
  228. void
  229. runeout(Rune rune) {
  230. char stoken[UTFmax+1];
  231. int i;
  232. i = runetochar(stoken, &rune);
  233. stoken[i] = '\0';
  234. glyphout(rune, stoken, TRUE);
  235. }
  236. void
  237. specialout(char *stoken) {
  238. Rune rune;
  239. chartorune(&rune, stoken);
  240. glyphout(rune, stoken, TRUE);
  241. }
  242. void
  243. graphfunc(Biobufhdr *bp) {
  244. USED(bp);
  245. }
  246. long
  247. nametorune(char *name) {
  248. USED(name);
  249. return(0);
  250. }
  251. void
  252. notavail(char *msg) {
  253. fprint(2, "%s is not available at this time.\n", msg);
  254. }