utils.c 7.0 KB

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