1 /* ch2vft.c 1.4 84/04/07 2 * 3 * Font translation to vfonts (RST format) from character format. 4 * 5 * Use: ch2vft [ -i -s ] charfile > vfontfile 6 * 7 * Takes input from charfile (which must be in the format written 8 * by xxx2ch), converts to rst format and writes to stdout. If charfile 9 * is missing, stdin is read. The -i flag tells ch2rst to ignore the 10 * character codes at the start of each glyph definition, and pack the 11 * glyphs in consecutive code positions starting with 0. The -s flag 12 * forces ch2vft to include the whole bit-map that defines the glyph. 13 * Normally, it is trimmed of white space. This is usefull for making 14 * stipple patterns of fixed size. 15 */ 16 17 #include <stdio.h> 18 #include <ctype.h> 19 #include <vfont.h> 20 21 22 #define RES 200 /* for vfont, resolution is 200 */ 23 #define MAXLINE 200 24 #define GLYPHSPACE (MAXLINE * MAXLINE) 25 #define MAGICNO 0436 26 #define DIRSIZ 256 /* vfonts MUST have 256 entries */ 27 #define DIMLIMIT 128 28 29 30 char * rdchar(); 31 char * malloc(); 32 33 struct dispatch g[DIRSIZ]; /* directory of glyph definitions */ 34 struct header head; /* font file header */ 35 36 int code, codeindex; 37 int width, length, maxv, minv, maxh, minh, refv, refh; 38 int fileaddr; 39 40 int ignorecode = 0; 41 int stipple = 0; 42 FILE * filep; 43 char ibuff[MAXLINE]; 44 char ebuff[MAXLINE]; 45 char * glyphs[DIRSIZ]; 46 char charbits[GLYPHSPACE]; /* place to store bits for a glyph */ 47 48 49 main(argc,argv) 50 int argc; 51 char **argv; 52 { 53 register int i; 54 register int j; 55 register int k; 56 register char *chp; 57 register char *bitp; 58 float par; 59 60 head.magic = MAGICNO; 61 head.maxx = head.maxy = head.xtend = 0; 62 while (argc > 1 && argv[1][0] == '-') { 63 switch(argv[1][1]) { 64 case 'i': 65 ignorecode = 1; 66 break; 67 68 case 's': 69 stipple = 1; 70 break; 71 default: 72 error("%s, unknown option flag", argv[1]); 73 } 74 argc--; argv++; 75 } 76 77 if (argc == 2) { 78 if ((filep = fopen (argv[1], "r")) == NULL) 79 error("can't open file \"%s\"", argv[1]); 80 } else filep = stdin; 81 82 codeindex = 0; 83 for (i = 0; i < DIRSIZ; glyphs[i++] = (char *) 0); 84 85 fgets(ibuff, MAXLINE, filep); 86 if (strcmp(ibuff, "fontheader\n")) 87 error("not a character font file"); 88 89 while (fgets(ibuff, MAXLINE, filep) != NULL) { 90 if (index(ibuff, '\n') == 0) 91 error("input line too long"); 92 93 if (ibuff[0] != ':') { 94 sscanf (ibuff, "%s %f", ebuff, &par); 95 if (strcmp(ebuff, "size") == 0); 96 else if (strcmp(ebuff, "version") == 0) { 97 if ((int) (par + 0.5)) 98 error("wrong version (%d) for Font file.", (int)(par+0.5)); 99 } else if (strcmp(ebuff, "mag") == 0); 100 else if (strcmp(ebuff, "desiz") == 0); /*des_size = par/FIX + 0.5*/ 101 else if (strcmp(ebuff, "linesp") == 0); 102 else if (strcmp(ebuff, "wordsp") == 0); 103 else if (strcmp(ebuff, "rot") == 0); 104 else if (strcmp(ebuff, "cadv") == 0); 105 else if (strcmp(ebuff, "ladv") == 0); 106 else if (strcmp(ebuff, "id") == 0); 107 else if (strcmp(ebuff, "res") == 0) { 108 if (((int) (par + 0.5)) != RES) 109 fprintf(stderr, "ch2vft warning: wrong resolution (%d).\n", 110 (int) (par + 0.5) ); 111 } else 112 error("unknown input descriptor, \"%s\"", ebuff); 113 } else { 114 if (sscanf (ibuff, ":%d, width = %f", &code, &par) != 2) 115 error("bad glyph header, %s", ibuff); 116 if (ignorecode) i = codeindex++; else i = code; 117 if (i < 0 || i >= DIRSIZ) error("code (%d) out of range", i); 118 g[i].width = par + 0.5; 119 120 chp = &charbits[0]; 121 if (fgets(chp, MAXLINE, filep) == NULL) 122 error("unexpected end of input"); 123 width = strlen(chp) - 1; 124 minh = width; 125 maxh = 0; 126 refv = minv = -1; 127 128 for (length = 0; *chp != '\n'; length++) { 129 if ((length + 1) * width > GLYPHSPACE) 130 error ("out of glyph space"); 131 for (j = 0; j < width; j++, chp++) { 132 switch (*chp) { 133 case '.': 134 break; 135 case 'x': 136 refh = j; 137 refv = length; 138 *chp = '.'; 139 break; 140 case 'X': 141 refh = j; 142 refv = length; 143 case '@': 144 case '*': 145 maxv = length; 146 if (minv < 0) minv = length; 147 if (j < minh) minh = j; 148 if (j > maxh) maxh = j; 149 break; 150 default: 151 error("illegal character '%c' in map.", *chp); 152 } /* switch */ 153 } /* for j */ 154 if (fgets(chp, MAXLINE, filep) == NULL) 155 error("unexpected end of input"); 156 } /* for length */ 157 158 if (stipple) { /* force whole box if making stipples */ 159 minv = 0; 160 minh = 0; 161 maxv = length - 1; 162 maxh = width - 1; 163 } 164 165 if (refv < 0) error("no reference point in glyph %d.", code); 166 if (minv < 0) { 167 minv = maxv = refv; 168 minh = maxh = refh; 169 } 170 g[i].up = bound(refv - minv); 171 g[i].down = bound(maxv + 1 - refv); 172 g[i].right = bound(maxh + 1 - refh); 173 g[i].left = bound(refh - minh); 174 g[i].nbytes = (maxv + 1 - minv) * ((maxh + 8 - minh) >> 3); 175 176 /* convert from characters to bits */ 177 bitp = (glyphs[i] = malloc(g[i].nbytes)) - 1; 178 for (k = minv; k <= maxv; k++) { 179 register int bitwidth; 180 181 chp = &charbits[0] + width * k + minh; 182 bitwidth = 0; 183 for (j = minh; j <= maxh; j++, chp++) { 184 if (--bitwidth < 0) { 185 *++bitp = '\0'; 186 bitwidth = 7; 187 } 188 if (*chp != '.') *bitp |= 1 << bitwidth; 189 } 190 } /* for */ 191 } /* else */ 192 } /* while */ 193 194 fileaddr = 0; 195 for (i = 0; i < DIRSIZ; i++) { 196 if (glyphs[i] == (char *) 0) { 197 g[i].nbytes = 0; 198 } else { 199 g[i].addr = fileaddr; 200 fileaddr += g[i].nbytes; 201 if (g[i].up > head.maxy) head.maxy = g[i].up; 202 if (g[i].down > head.xtend) head.xtend = g[i].down; 203 if (((int) g[i].left + g[i].right) > head.maxx) 204 head.maxx = g[i].left + (int) g[i].right; 205 } 206 } 207 head.size = fileaddr; 208 209 vwrite((char *) &head, sizeof(head)); 210 vwrite((char *) &(g[0]), sizeof(g)); 211 for (i = 0; i < DIRSIZ; i++) 212 if (glyphs[i] != (char *) 0) 213 vwrite(glyphs[i], g[i].nbytes); 214 } 215 216 217 vwrite(buf,usize) 218 char *buf; 219 int usize; 220 { 221 int tsize = 0; 222 223 while (usize) { 224 buf += tsize; 225 tsize = usize > BUFSIZ ? BUFSIZ : usize; 226 if ((tsize = write(1, buf, tsize)) < 0) { 227 perror("ch2vft: write failed"); 228 exit(-1); 229 } 230 usize -= tsize; 231 } 232 } 233 234 235 /*VARARGS1*/ 236 error(string, a1, a2, a3, a4) 237 char *string; 238 { 239 fprintf(stderr, "ch2vft: "); 240 fprintf(stderr, string, a1, a2, a3, a4); 241 fprintf(stderr, "\n"); 242 exit(8); 243 }; 244 245 bound(i) 246 { 247 if(i < DIMLIMIT && i >= -DIMLIMIT) return i; 248 error ("dimension out of range"); 249 } 250