Annotation of 43BSD/old/fed/io.c, revision 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.