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: }

Defined functions

clearfont defined in line 395; used 1 times
editfont defined in line 250; used 3 times
fileiocmd defined in line 417; used 1 times
getglyph defined in line 11; used 2 times
packmat defined in line 200; used 1 times
readchars defined in line 456; used 1 times
readfont defined in line 282; used 3 times
truename defined in line 373; used 3 times
writeback defined in line 120; used 2 times
writefont defined in line 128; used 2 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1983-08-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1957
Valid CSS Valid XHTML 1.0 Strict