/old/fcvt/fcvt.c

https://bitbucket.org/okuoku/csrg · C · 233 lines · 189 code · 18 blank · 26 comment · 30 complexity · c116b49d3340e61fbf404308185cbffc MD5 · raw file

  1. #ifndef lint
  2. static char sccsid[] = "@(#)fcvt.c 4.1 (Berkeley) 03/29/83";
  3. #endif not lint
  4. /*
  5. * Convert from the SAIL font format to the Unix font format.
  6. * Usage: fcvt sailfile unixfile
  7. */
  8. long left(), right();
  9. int sws; /* sail word size in 36 bit words */
  10. char b[40000], u[2000];
  11. #include <stdio.h>
  12. #include <vfont.h>
  13. struct header vheader;
  14. struct dispatch disptable[256];
  15. long rightbits[19] = {
  16. 0, 1, 03, 07, 017, 037,
  17. 077, 0177, 0377, 0777, 01777, 03777,
  18. 07777, 017777, 037777, 077777, 0177777,0377777,0777777
  19. };
  20. main(argc, argv)
  21. char **argv;
  22. {
  23. int infd = open(argv[1], 0);
  24. int outfd = creat(argv[2], 0666);
  25. int n;
  26. long lh, rh;
  27. int base, nb, ncol, nleft, r, i;
  28. int c, p;
  29. /* Sail counters and things */
  30. int height, maxwidth, baseline;
  31. int charwidth, rastwidth, charcode, wordcount;
  32. int leftkern, rowsfromtop, datarowcount;
  33. /* Unix counters and things */
  34. int rastrows, rastcols;
  35. int curaddr;
  36. int packed; /* true if sail packed format for this glyph */
  37. int nperword;
  38. if (infd < 0 || outfd < 0) {
  39. printf("Usage: fcvt sailfile unixfile\n");
  40. exit(1);
  41. }
  42. n = read(infd, b, sizeof b);
  43. sws = 2 * n / 9;
  44. if (n == sizeof b) {
  45. printf("Font larger than %d bytes - recompile me\n", n);
  46. exit(1);
  47. }
  48. close(infd);
  49. height = right(0201);
  50. maxwidth = right(0202);
  51. baseline = right(0203);
  52. vheader.magic = 0436;
  53. /* size gets done later */
  54. vheader.maxx = height;
  55. vheader.maxy = maxwidth;
  56. /* I don't know what xtnd would map to */
  57. lseek(outfd, (long) sizeof vheader + sizeof disptable, 0);
  58. curaddr = 0;
  59. /* Look at each char */
  60. for (c=0; c<0200; c++) {
  61. /* Find Sail info */
  62. base = right(c);
  63. if (base == 0)
  64. continue;
  65. charwidth = left(c);
  66. rastwidth = (left(base) >> 9) & 0777;
  67. if (rastwidth == 0)
  68. rastwidth = charwidth;
  69. charcode = left(base) & 0777;
  70. if (charcode != c)
  71. printf("bad char code %o(%c) != %o(%c)\n", charcode, charcode, c, c);
  72. wordcount = right(base);
  73. if (base+wordcount > sws) {
  74. printf("Bad range %o-%o > %o glyph %o\n", base, base+wordcount, sws, c);
  75. continue;
  76. }
  77. leftkern = (left(base+1) >> 9) & 0777;
  78. rowsfromtop = left(base+1) & 0777;
  79. datarowcount = right(base+1);
  80. rastrows = datarowcount;
  81. rastcols = (rastwidth + 35) / 36 * 36;
  82. /* Unix disptable stuff */
  83. disptable[c].addr = curaddr;
  84. nb = rastrows * ((rastcols + 7) >> 3);
  85. disptable[c].nbytes = nb;
  86. curaddr += nb;
  87. disptable[c].left = leftkern;
  88. disptable[c].right = rastcols - leftkern;
  89. disptable[c].up = baseline - rowsfromtop;
  90. disptable[c].down = rastrows - disptable[c].up;
  91. disptable[c].width = charwidth;
  92. packed = (datarowcount > wordcount);
  93. nperword = 36 / rastwidth;
  94. /* Now get the raster rows themselves */
  95. p = 0;
  96. ncol = rastcols / 36;
  97. nleft = ((rastwidth-1) % 36 + 1);
  98. base += 2;
  99. for (r=0; r<rastrows; r++) {
  100. if (!packed) {
  101. for (i=0; i<ncol; i++) {
  102. lh = left(base); rh = right(base++);
  103. /* compensate for garbage in SAIL fonts */
  104. if (i == ncol-1) {
  105. if (nleft <= 18) {
  106. rh = 0;
  107. lh &= ~rightbits[18-nleft];
  108. } else
  109. rh &= ~rightbits[36-nleft];
  110. }
  111. if (i%2) {
  112. u[p-1] |= (lh>>14) & 017;
  113. u[p++] = lh >> 6;
  114. u[p++] = ((lh&077)<<2) | ((rh>>16)&03);
  115. u[p++] = rh >> 8;
  116. u[p++] = rh;
  117. } else {
  118. u[p++] = lh >> 10;
  119. u[p++] = lh >> 2;
  120. u[p++] = ((lh&03)<<6) | (rh>>12);
  121. u[p++] = rh >> 4;
  122. u[p++] = (rh & 017) << 4;
  123. }
  124. }
  125. } else {
  126. put(r % nperword, rastwidth, left(base+r/nperword), right(base+r/nperword), u+p);
  127. p += 5; /* 5 8 bit bytes per 36 bit word */
  128. }
  129. }
  130. write(outfd, u, p);
  131. }
  132. lseek(outfd, 0, 0);
  133. vheader.size = curaddr;
  134. write(outfd, &vheader, sizeof vheader);
  135. write(outfd, disptable, sizeof disptable);
  136. close(outfd);
  137. exit(0);
  138. }
  139. /*
  140. * put a pdp-10 style variable size byte into 8 bit Unix bytes starting
  141. * at location dest. The byte is bytesize bits, and is the bytenumth byte
  142. * in the 36 bit word (lh,,rh).
  143. */
  144. put(bytenum, bytesize, lh, rh, dest)
  145. int bytenum, bytesize;
  146. long lh, rh;
  147. char *dest;
  148. {
  149. register int i;
  150. for (i=0; i<5; i++)
  151. dest[i] = 0;
  152. for (i=0; i<bytenum; i++) {
  153. lh <<= bytesize;
  154. lh |= (rh >> 18-bytesize) & rightbits[bytesize];
  155. rh <<= bytesize;
  156. }
  157. lh &= ~rightbits[18-bytesize];
  158. /* We now have the byte we want left justified in lh */
  159. lh <<= 14;
  160. /* lh is now the byte we want, left justified in 32 bit word */
  161. for (i=0; i<bytesize; i += 8) {
  162. *dest++ = (lh >> 24) & 0377;
  163. lh <<= 8;
  164. }
  165. }
  166. /*
  167. * Return the left half (18 bits) of pdp-10 word p.
  168. */
  169. long
  170. left(p)
  171. int p;
  172. {
  173. register int lp, odd;
  174. register long retval;
  175. odd = p%2;
  176. lp = 9*p/2;
  177. if (p >= sws) {
  178. return(0);
  179. }
  180. if (odd) {
  181. retval = (b[lp++] & 0017) << 14;
  182. retval |= (b[lp++] & 0377) << 6;
  183. retval |= (b[lp] >> 2) & 63;
  184. } else {
  185. retval = (b[lp++] & 0377) << 10;
  186. retval |= (b[lp++] & 0377) << 2;
  187. retval |= (b[lp] >> 6) & 3;
  188. }
  189. return retval;
  190. }
  191. /*
  192. * Return the right half of 36 bit word #p.
  193. */
  194. long
  195. right(p)
  196. int p;
  197. {
  198. register int lp, odd;
  199. register long retval;
  200. odd = p%2;
  201. lp = 9*p/2 + 2;
  202. if (p >= sws) {
  203. return(0);
  204. }
  205. if (odd) {
  206. retval = (b[lp++] & 0003) << 16;
  207. retval |= (b[lp++] & 0377) << 8;
  208. retval |= (b[lp] & 0377);
  209. } else {
  210. retval = (b[lp++] & 0077) << 12;
  211. retval |= (b[lp++] & 0377) << 4;
  212. retval |= (b[lp] >> 4) & 017;
  213. }
  214. return retval;
  215. }