|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)io.c 4.2 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * io.c: font file I/O subroutines for fed. ! 7: */ ! 8: ! 9: #include "fed.h" ! 10: ! 11: getglyph(c) ! 12: char c; ! 13: { ! 14: register int i, j; ! 15: int windno; ! 16: int vertoff, horoff; ! 17: char *tmp; ! 18: ! 19: if (trace) ! 20: fprintf(trace, "\n\ngetglyph(%s)\n", rdchar(c)); ! 21: if (disptable[c].nbytes == 0) { ! 22: if (trace) ! 23: fprintf(trace, "no such char: %s\n", rdchar(c)); ! 24: sprintf(msgbuf, "no such character: %s", rdchar(c)); ! 25: message(msgbuf); ! 26: return; ! 27: } ! 28: ! 29: curchar = c; ! 30: turnofcurs(); ! 31: if (cht[curchar].wherewind >= 0) { ! 32: /* It's already in a window. Don't have to do much. */ ! 33: if (trace) ! 34: fprintf(trace, "already in %d\n", cht[curchar].wherewind); ! 35: windno = cht[curchar].wherewind; ! 36: /* Put a box around the current window */ ! 37: if (windno != curwind) { ! 38: drawbox(base[curwind].r-1, base[curwind].c-1, 0, GLROW+2, GLCOL+2); ! 39: drawbox(base[windno].r-1, base[windno].c-1, 1, GLROW+2, GLCOL+2); ! 40: } ! 41: curwind = windno; ! 42: syncwind(windno); ! 43: /* should center base */ ! 44: } else { ! 45: /* ! 46: * Not on screen. First find a suitable window, ! 47: * using round robin. ! 48: */ ! 49: windno = nextwind; ! 50: if (trace) ! 51: fprintf(trace, "chose window %d\n", windno); ! 52: if (++nextwind >= NWIND) ! 53: nextwind = 0; ! 54: #ifdef TWOWIND ! 55: /* ! 56: * This is for debugging what happens when we run out ! 57: * of windows. ! 58: */ ! 59: if (nextwind >= 2) ! 60: nextwind = 0; ! 61: #endif ! 62: ! 63: /* Put a box around the current window */ ! 64: if (windno != curwind) { ! 65: if (trace) ! 66: fprintf(trace, "drawbox (%d %d)\n", base[windno].r-1, base[windno].c-1); ! 67: drawbox(base[curwind].r-1, base[curwind].c-1, 0, GLROW+2, GLCOL+2); ! 68: drawbox(base[windno].r-1, base[windno].c-1, 1, GLROW+2, GLCOL+2); ! 69: } ! 70: ! 71: /* Print the char at the lower left of the window */ ! 72: sprintf(msgbuf, "%s", rdchar(curchar)); ! 73: dispmsg(msgbuf, base[windno].c, base[windno].r-11, 2); ! 74: ! 75: /* Now make room in the window */ ! 76: if (wind[windno].onscreen == NULL) { ! 77: /* Brand new window, have to allocate space */ ! 78: wind[windno].onscreen = newmat(GLROW, GLCOL); ! 79: } else { ! 80: /* Save prev glyph for later */ ! 81: cht[wind[windno].used].whereat = wind[windno].val; ! 82: cht[wind[windno].used].wherewind = -2; ! 83: if (trace) ! 84: fprintf(trace, "windno=%s, wind[windno].used=%d, cht[..].wherewind set to -2\n", rdchar(windno), wind[windno].used); ! 85: } ! 86: if (wind[windno].undval != NULL) { ! 87: if (trace) ! 88: fprintf(trace, "getglyph frees undo: %x\n", wind[windno].undval); ! 89: free(wind[windno].undval); ! 90: } ! 91: wind[windno].undval = NULL; ! 92: wind[windno].used = curchar; ! 93: ! 94: /* ! 95: * Vertical & horizontal offsets. Line up the baseline ! 96: * of the char at BASELINE from bottom, but center ! 97: * horizontally. ! 98: */ ! 99: vertoff = GLROW - BASELINE - disptable[curchar].up; ! 100: /* Check to see if the glyph is being nosed off the edge. */ ! 101: if (vertoff < 0) { ! 102: vertoff = 0; ! 103: } else if (vertoff + disptable[curchar].up + disptable[curchar].down >= GLROW) { ! 104: vertoff = GLROW - disptable[curchar].up - disptable[curchar].down; ! 105: } ! 106: horoff = (GLCOL-(disptable[curchar].left+disptable[curchar].right)) / 2; ! 107: wind[windno].val = findbits(curchar, GLROW, GLCOL, horoff, vertoff, &curs_r, &curs_c); ! 108: cht[curchar].rcent = curs_r; ! 109: cht[curchar].ccent = curs_c; ! 110: curwind = windno; ! 111: cht[curchar].wherewind = windno; ! 112: syncwind(windno); ! 113: } ! 114: } ! 115: ! 116: /* ! 117: * writeback: write the font back to the file at the end of editing. ! 118: * Also have to write width table. ! 119: */ ! 120: writeback() ! 121: { ! 122: writefont(fontfile); ! 123: } ! 124: ! 125: /* ! 126: * writefont: write current font on file fname. ! 127: */ ! 128: writefont(fname) ! 129: char *fname; ! 130: { ! 131: register int i, j; ! 132: register int c; ! 133: FILE *fntout; ! 134: int bytes; ! 135: bitmat tmp; ! 136: int nextoff = 0; ! 137: int charcount, bytecount; ! 138: extern char *sys_errlist[]; ! 139: extern int errno; ! 140: ! 141: if (trace) ! 142: fprintf(trace, "writefont(%s)\n", fname); ! 143: /* ! 144: * The following unlink is important because we are about to ! 145: * do an fopen( , "w") on fname. We still have fontdes open ! 146: * for reading. If we don't do the unlink the fopen will truncate ! 147: * the file and subsequent reads will fail. If we do the unlink ! 148: * the file won't go away until it is closed, so we can still ! 149: * read from the old version. ! 150: */ ! 151: if (strcmp(fname, fontfile)==0 && unlink(fname) < 0) { ! 152: sprintf(msgbuf, "unlink %s: %s", fname, sys_errlist[errno]); ! 153: error(msgbuf); ! 154: } ! 155: ! 156: fntout = fopen(fname, "w"); ! 157: if (fntout == NULL) { ! 158: sprintf(msgbuf, "%s: %s", fname, sys_errlist[errno]); ! 159: if (trace) ! 160: fprintf(trace, "%s\n", msgbuf); ! 161: error(msgbuf); ! 162: } ! 163: sprintf(msgbuf, "\"%s\"", fname); ! 164: message(msgbuf); ! 165: fflush(stdout); ! 166: ! 167: fwrite(&FontHeader, sizeof FontHeader, 1, fntout); ! 168: fwrite(&disptable[0], sizeof disptable, 1, fntout); ! 169: charcount = 0; bytecount = fbase; ! 170: for (c=0; c<256; c++) ! 171: if (disptable[c].nbytes || cht[c].wherewind != -1) { ! 172: if (trace) ! 173: fprintf(trace, "char %s, nbytes %d, wherewind %d.. ", rdchar(c), disptable[c].nbytes, cht[c].wherewind); ! 174: packmat(c, &tmp, &bytes); ! 175: disptable[c].addr = nextoff; ! 176: disptable[c].nbytes = bytes; ! 177: if (trace) ! 178: fprintf(trace, "offset %d size %d\n", nextoff, bytes); ! 179: nextoff += bytes; ! 180: fwrite(tmp, bytes, 1, fntout); ! 181: charcount++; ! 182: bytecount += bytes; ! 183: } ! 184: FontHeader.size = nextoff; ! 185: fseek(fntout, 0L, 0); ! 186: fwrite(&FontHeader, sizeof FontHeader, 1, fntout); ! 187: fwrite(&disptable[0], sizeof disptable, 1, fntout); ! 188: ! 189: /* Should fix the width tables here */ ! 190: fclose(fntout); ! 191: sprintf(msgbuf, "%s %d glyphs, %d bytes", fname, charcount, bytecount); ! 192: message(msgbuf); ! 193: changes = 0; ! 194: } ! 195: ! 196: /* ! 197: * make a packed matrix of the bits for char c. ! 198: * return the matrix ptr in result and the size in bytes in nbytes. ! 199: */ ! 200: packmat(c, result, nbytes) ! 201: int c; ! 202: bitmat *result; ! 203: int *nbytes; ! 204: { ! 205: register int i, j; ! 206: bitmat wp; ! 207: int nb, nr, nc; ! 208: int rmin, cmin, rmax, cmax; ! 209: static char tmp[WINDSIZE]; ! 210: ! 211: if (cht[c].wherewind == -1) { ! 212: /* It has never been read from file. Just copy from file. */ ! 213: nb = disptable[c].nbytes; ! 214: fseek(fontdes, (long) fbase+disptable[c].addr, 0); ! 215: fread(tmp, nb, 1, fontdes); ! 216: } else { ! 217: if (cht[c].wherewind == -2) ! 218: wp = cht[c].whereat; ! 219: else ! 220: wp = wind[cht[c].wherewind].val; ! 221: minmax(wp, GLROW, GLCOL, &rmin, &cmin, &rmax, &cmax); ! 222: nr = rmax-rmin+1; nc = cmax-cmin+1; ! 223: zermat(tmp, nr, nc); ! 224: for (i=rmin; i<=rmax; i++) ! 225: for (j=cmin; j<=cmax; j++) { ! 226: setmat(tmp, nr, nc, i-rmin, j-cmin, ! 227: mat(wp, GLROW, GLCOL, i, j)); ! 228: } ! 229: nb = ((nc + 7) >> 3) * nr; ! 230: disptable[c].up = cht[c].rcent - rmin; ! 231: disptable[c].down = rmax - cht[c].rcent + 1; ! 232: disptable[c].left = cht[c].ccent - cmin; ! 233: disptable[c].right = cmax - cht[c].ccent + 1; ! 234: if (trace) { ! 235: fprintf(trace, "rmax=%d, rcent=%d, rmin=%d, cmax=%d, ccent=%d, cmin=%d, ", rmax, cht[c].rcent, rmin, cmax, cht[c].ccent, cmin); ! 236: fprintf(trace, "up=%d, down=%d, left=%d, right=%d\n", disptable[c].up, disptable[c].down, disptable[c].left, disptable[c].right); ! 237: } ! 238: } ! 239: *result = tmp; ! 240: *nbytes = nb; ! 241: if (trace) ! 242: fprintf(trace, "nbytes = %d, ", nb); ! 243: return; ! 244: } ! 245: ! 246: /* ! 247: * editfont: make the file fname be the current focus of attention, ! 248: * including reading it into the buffer. ! 249: */ ! 250: editfont(fname) ! 251: char *fname; ! 252: { ! 253: register char *cp; ! 254: ! 255: clearfont(); ! 256: editing = 1; ! 257: truename(fname, fontfile); ! 258: fontdes = fopen(fontfile, "r"); ! 259: readfont(fontfile, 0, 255); ! 260: ! 261: /* ! 262: * Figure out the point size, and make a guess as to the ! 263: * appropriate width of the heavy pen. ! 264: */ ! 265: for (cp=fontfile; *cp && *cp!='.'; cp++) ! 266: ; ! 267: if (*cp) { ! 268: pointsize = atoi(++cp); ! 269: setpen(pointsize>30?3 : pointsize>15?2 : pointsize>8?1 : 0); ! 270: } else { ! 271: pointsize = 0; ! 272: setpen(2); ! 273: } ! 274: } ! 275: ! 276: /* ! 277: * readfont: read in a font, overlaying the current font. ! 278: * also used to edit a font by clearing first. ! 279: * ! 280: * Conflicts are handled interactively. ! 281: */ ! 282: readfont(fname, c1, c2) ! 283: char *fname; ! 284: int c1, c2; ! 285: { ! 286: register int i; ! 287: register char *cp; ! 288: struct dispatch d; ! 289: char choice, mode = 0; ! 290: FILE *hold_fontdes; ! 291: int horoff, vertoff; ! 292: long ftsave; ! 293: ! 294: hold_fontdes = fontdes; ! 295: fontdes = fopen(fname, "r"); ! 296: if (fontdes == NULL) { ! 297: sprintf(msgbuf, "%s not found", fname); ! 298: fontdes = hold_fontdes; ! 299: error(msgbuf); ! 300: } ! 301: fread(&FontHeader, sizeof FontHeader, 1, fontdes); ! 302: fseek(fontdes, c1*sizeof d, 1); /* skip over unread chars */ ! 303: ftsave = ftell(fontdes); ! 304: for (i=c1; i<=c2; i++) { ! 305: fseek(fontdes, ftsave, 0); ! 306: fread(&d, sizeof d, 1, fontdes); ! 307: ftsave = ftell(fontdes); ! 308: /* Decide which of the two to take */ ! 309: if (d.nbytes == 0) ! 310: continue; /* We take the one in the buffer */ ! 311: if (disptable[i].nbytes > 0) { ! 312: /* Conflict */ ! 313: switch(mode) { ! 314: case 'f': ! 315: /* fall through */ ! 316: break; ! 317: case 'b': ! 318: continue; ! 319: default: ! 320: sprintf(msgbuf, "%s <file> or <buffer>", rdchar(i)); ! 321: message(msgbuf); ! 322: choice = inchar(); ! 323: switch(choice) { ! 324: case 'F': ! 325: mode = 'f'; ! 326: default: ! 327: case 'f': ! 328: break; ! 329: case 'B': ! 330: mode = 'b'; ! 331: case 'b': ! 332: continue; ! 333: } ! 334: } ! 335: } ! 336: disptable[i] = d; /* We take the one in the file */ ! 337: cht[i].nrow = d.up + d.down; ! 338: cht[i].ncol = d.left + d.right; ! 339: if (!editing && disptable[i].nbytes) { ! 340: horoff = (GLCOL-(disptable[i].left+disptable[i].right))/2; ! 341: vertoff = GLROW - BASELINE - disptable[i].up; ! 342: /* Check to see if the glyph is being nosed off the edge. */ ! 343: if (vertoff < 0) { ! 344: vertoff = 0; ! 345: } else if (vertoff + disptable[curchar].up + disptable[curchar].down >= GLROW) { ! 346: vertoff = GLROW - disptable[curchar].up - disptable[curchar].down; ! 347: } ! 348: if (cht[i].wherewind >= 0) { ! 349: /* The old glyph is in a window - destroy it */ ! 350: wind[cht[i].wherewind].used = -1; ! 351: } ! 352: cht[i].wherewind = -1; ! 353: cht[i].whereat = findbits(i, GLROW, GLCOL, horoff, vertoff, &cht[i].rcent, &cht[i].ccent); ! 354: cht[i].wherewind = -2; ! 355: if (trace) ! 356: fprintf(trace, "setting cht[%d].wherewind to -2 in readfont\n", i); ! 357: } else ! 358: cht[i].wherewind = -1; ! 359: } ! 360: fbase = sizeof FontHeader + sizeof disptable; /* ftell(fontdes) */ ! 361: ! 362: sprintf(msgbuf, "\"%s\", raster data %d bytes, width %d, height %d, xtend %d", fname, FontHeader.size, FontHeader.maxx, FontHeader.maxy, FontHeader.xtend); ! 363: ! 364: fontdes = hold_fontdes; ! 365: message(msgbuf); ! 366: } ! 367: ! 368: /* ! 369: * Figure out the true name of the font file, given that ! 370: * the abbreviated name is fname. The result is placed ! 371: * in the provided buffer result. ! 372: */ ! 373: truename(fname, result) ! 374: char *fname; ! 375: char *result; ! 376: { ! 377: FILE *t; ! 378: ! 379: strcpy(result, fname); ! 380: if ((t = fopen(result, "r")) == NULL) { ! 381: sprintf(result,"/usr/lib/vfont/%s",fname); ! 382: if ((t = fopen(result, "r")) == NULL) { ! 383: strcpy(result, fname); ! 384: sprintf(msgbuf, "Can't find %s\n",fname); ! 385: error(msgbuf); ! 386: } ! 387: } ! 388: fclose(t); ! 389: } ! 390: ! 391: ! 392: /* ! 393: * clearfont: delete all characters in the current font. ! 394: */ ! 395: clearfont() ! 396: { ! 397: register int i; ! 398: ! 399: if (fontdes) ! 400: fclose(fontdes); ! 401: for (i=0; i<256; i++) { ! 402: cht[i].wherewind = -1; ! 403: disptable[i].addr = 0; ! 404: disptable[i].nbytes = 0; ! 405: disptable[i].up = 0; ! 406: disptable[i].down = 0; ! 407: disptable[i].left = 0; ! 408: disptable[i].right = 0; ! 409: disptable[i].width = 0; ! 410: } ! 411: } ! 412: ! 413: /* ! 414: * fileiocmd: do a file I/O command. These all take optional file ! 415: * names, defaulting to the current file. ! 416: */ ! 417: fileiocmd(cmd) ! 418: char cmd; ! 419: { ! 420: char fname[100], truefname[100]; ! 421: ! 422: readline("file: ", fname, sizeof fname); ! 423: if (fname[0] == 0 || fname[0] == ' ') ! 424: strcpy(fname, fontfile); ! 425: switch(cmd) { ! 426: case 'E': ! 427: confirm(); ! 428: editfont(fname); ! 429: break; ! 430: ! 431: case 'N': ! 432: if (changes) ! 433: writeback(); ! 434: editfont(fname); ! 435: break; ! 436: ! 437: case 'R': ! 438: editing = 0; ! 439: truename(fname, truefname); ! 440: readfont(truefname, 0, 255); ! 441: changes++; ! 442: break; ! 443: ! 444: case 'W': ! 445: editing = 0; ! 446: writefont(fname); ! 447: break; ! 448: } ! 449: if (editing) ! 450: changes = 0; ! 451: } ! 452: ! 453: /* ! 454: * readchars: read in a partial font (the P command). ! 455: */ ! 456: readchars() ! 457: { ! 458: int c1, c2; ! 459: char fnamebuf[100]; ! 460: char truebuf[100]; ! 461: char buf[5]; ! 462: ! 463: message("Partial read <firstchar>"); ! 464: c1 = inchar(); ! 465: sprintf(msgbuf, "Partial read %s thru <lastchar>", rdchar(c1)); ! 466: message(msgbuf); ! 467: c2 = inchar(); ! 468: strcpy(buf, rdchar(c1)); ! 469: sprintf(msgbuf, "Partial read %s thru %s from file: ", buf, rdchar(c2)); ! 470: readline(msgbuf, fnamebuf, sizeof fnamebuf); ! 471: editing = 0; ! 472: if (fnamebuf[0] == 0 || fnamebuf[0] == ' ') ! 473: strcpy(fnamebuf, fontfile); ! 474: truename(fnamebuf, truebuf); ! 475: changes++; ! 476: readfont(truebuf, c1, c2); ! 477: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.