Annotation of 42BSD/ucb/fed/io.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.