static char sccsid
[] = "@(#)io.c 4.2 (Berkeley) 8/11/83";
* io.c: font file I/O subroutines for fed.
fprintf(trace
, "\n\ngetglyph(%s)\n", rdchar(c
));
if (disptable
[c
].nbytes
== 0) {
fprintf(trace
, "no such char: %s\n", rdchar(c
));
sprintf(msgbuf
, "no such character: %s", rdchar(c
));
if (cht
[curchar
].wherewind
>= 0) {
/* It's already in a window. Don't have to do much. */
fprintf(trace
, "already in %d\n", cht
[curchar
].wherewind
);
windno
= cht
[curchar
].wherewind
;
/* Put a box around the current window */
drawbox(base
[curwind
].r
-1, base
[curwind
].c
-1, 0, GLROW
+2, GLCOL
+2);
drawbox(base
[windno
].r
-1, base
[windno
].c
-1, 1, GLROW
+2, GLCOL
+2);
* Not on screen. First find a suitable window,
fprintf(trace
, "chose window %d\n", windno
);
* This is for debugging what happens when we run out
/* Put a box around the current window */
fprintf(trace
, "drawbox (%d %d)\n", base
[windno
].r
-1, base
[windno
].c
-1);
drawbox(base
[curwind
].r
-1, base
[curwind
].c
-1, 0, GLROW
+2, GLCOL
+2);
drawbox(base
[windno
].r
-1, base
[windno
].c
-1, 1, GLROW
+2, GLCOL
+2);
/* Print the char at the lower left of the window */
sprintf(msgbuf
, "%s", rdchar(curchar
));
dispmsg(msgbuf
, base
[windno
].c
, base
[windno
].r
-11, 2);
/* Now make room in the window */
if (wind
[windno
].onscreen
== NULL
) {
/* Brand new window, have to allocate space */
wind
[windno
].onscreen
= newmat(GLROW
, GLCOL
);
/* Save prev glyph for later */
cht
[wind
[windno
].used
].whereat
= wind
[windno
].val
;
cht
[wind
[windno
].used
].wherewind
= -2;
fprintf(trace
, "windno=%s, wind[windno].used=%d, cht[..].wherewind set to -2\n", rdchar(windno
), wind
[windno
].used
);
if (wind
[windno
].undval
!= NULL
) {
fprintf(trace
, "getglyph frees undo: %x\n", wind
[windno
].undval
);
free(wind
[windno
].undval
);
wind
[windno
].undval
= NULL
;
wind
[windno
].used
= curchar
;
* Vertical & horizontal offsets. Line up the baseline
* of the char at BASELINE from bottom, but center
vertoff
= GLROW
- BASELINE
- disptable
[curchar
].up
;
/* Check to see if the glyph is being nosed off the edge. */
} else if (vertoff
+ disptable
[curchar
].up
+ disptable
[curchar
].down
>= GLROW
) {
vertoff
= GLROW
- disptable
[curchar
].up
- disptable
[curchar
].down
;
horoff
= (GLCOL
-(disptable
[curchar
].left
+disptable
[curchar
].right
)) / 2;
wind
[windno
].val
= findbits(curchar
, GLROW
, GLCOL
, horoff
, vertoff
, &curs_r
, &curs_c
);
cht
[curchar
].rcent
= curs_r
;
cht
[curchar
].ccent
= curs_c
;
cht
[curchar
].wherewind
= windno
;
* writeback: write the font back to the file at the end of editing.
* Also have to write width table.
* writefont: write current font on file fname.
int charcount
, bytecount
;
extern char *sys_errlist
[];
fprintf(trace
, "writefont(%s)\n", fname
);
* The following unlink is important because we are about to
* do an fopen( , "w") on fname. We still have fontdes open
* for reading. If we don't do the unlink the fopen will truncate
* the file and subsequent reads will fail. If we do the unlink
* the file won't go away until it is closed, so we can still
* read from the old version.
if (strcmp(fname
, fontfile
)==0 && unlink(fname
) < 0) {
sprintf(msgbuf
, "unlink %s: %s", fname
, sys_errlist
[errno
]);
fntout
= fopen(fname
, "w");
sprintf(msgbuf
, "%s: %s", fname
, sys_errlist
[errno
]);
fprintf(trace
, "%s\n", msgbuf
);
sprintf(msgbuf
, "\"%s\"", fname
);
fwrite(&FontHeader
, sizeof FontHeader
, 1, fntout
);
fwrite(&disptable
[0], sizeof disptable
, 1, fntout
);
charcount
= 0; bytecount
= fbase
;
if (disptable
[c
].nbytes
|| cht
[c
].wherewind
!= -1) {
fprintf(trace
, "char %s, nbytes %d, wherewind %d.. ", rdchar(c
), disptable
[c
].nbytes
, cht
[c
].wherewind
);
packmat(c
, &tmp
, &bytes
);
disptable
[c
].addr
= nextoff
;
disptable
[c
].nbytes
= bytes
;
fprintf(trace
, "offset %d size %d\n", nextoff
, bytes
);
fwrite(tmp
, bytes
, 1, fntout
);
FontHeader
.size
= nextoff
;
fwrite(&FontHeader
, sizeof FontHeader
, 1, fntout
);
fwrite(&disptable
[0], sizeof disptable
, 1, fntout
);
/* Should fix the width tables here */
sprintf(msgbuf
, "%s %d glyphs, %d bytes", fname
, charcount
, bytecount
);
* make a packed matrix of the bits for char c.
* return the matrix ptr in result and the size in bytes in nbytes.
packmat(c
, result
, nbytes
)
int rmin
, cmin
, rmax
, cmax
;
static char tmp
[WINDSIZE
];
if (cht
[c
].wherewind
== -1) {
/* It has never been read from file. Just copy from file. */
nb
= disptable
[c
].nbytes
;
fseek(fontdes
, (long) fbase
+disptable
[c
].addr
, 0);
fread(tmp
, nb
, 1, fontdes
);
if (cht
[c
].wherewind
== -2)
wp
= wind
[cht
[c
].wherewind
].val
;
minmax(wp
, GLROW
, GLCOL
, &rmin
, &cmin
, &rmax
, &cmax
);
nr
= rmax
-rmin
+1; nc
= cmax
-cmin
+1;
for (i
=rmin
; i
<=rmax
; i
++)
for (j
=cmin
; j
<=cmax
; j
++) {
setmat(tmp
, nr
, nc
, i
-rmin
, j
-cmin
,
mat(wp
, GLROW
, GLCOL
, i
, j
));
nb
= ((nc
+ 7) >> 3) * nr
;
disptable
[c
].up
= cht
[c
].rcent
- rmin
;
disptable
[c
].down
= rmax
- cht
[c
].rcent
+ 1;
disptable
[c
].left
= cht
[c
].ccent
- cmin
;
disptable
[c
].right
= cmax
- cht
[c
].ccent
+ 1;
fprintf(trace
, "rmax=%d, rcent=%d, rmin=%d, cmax=%d, ccent=%d, cmin=%d, ", rmax
, cht
[c
].rcent
, rmin
, cmax
, cht
[c
].ccent
, cmin
);
fprintf(trace
, "up=%d, down=%d, left=%d, right=%d\n", disptable
[c
].up
, disptable
[c
].down
, disptable
[c
].left
, disptable
[c
].right
);
fprintf(trace
, "nbytes = %d, ", nb
);
* editfont: make the file fname be the current focus of attention,
* including reading it into the buffer.
truename(fname
, fontfile
);
fontdes
= fopen(fontfile
, "r");
readfont(fontfile
, 0, 255);
* Figure out the point size, and make a guess as to the
* appropriate width of the heavy pen.
for (cp
=fontfile
; *cp
&& *cp
!='.'; cp
++)
setpen(pointsize
>30?3 : pointsize
>15?2 : pointsize
>8?1 : 0);
* readfont: read in a font, overlaying the current font.
* also used to edit a font by clearing first.
* Conflicts are handled interactively.
fontdes
= fopen(fname
, "r");
sprintf(msgbuf
, "%s not found", fname
);
fread(&FontHeader
, sizeof FontHeader
, 1, fontdes
);
fseek(fontdes
, c1
*sizeof d
, 1); /* skip over unread chars */
fseek(fontdes
, ftsave
, 0);
fread(&d
, sizeof d
, 1, fontdes
);
/* Decide which of the two to take */
continue; /* We take the one in the buffer */
if (disptable
[i
].nbytes
> 0) {
sprintf(msgbuf
, "%s <file> or <buffer>", rdchar(i
));
disptable
[i
] = d
; /* We take the one in the file */
cht
[i
].nrow
= d
.up
+ d
.down
;
cht
[i
].ncol
= d
.left
+ d
.right
;
if (!editing
&& disptable
[i
].nbytes
) {
horoff
= (GLCOL
-(disptable
[i
].left
+disptable
[i
].right
))/2;
vertoff
= GLROW
- BASELINE
- disptable
[i
].up
;
/* Check to see if the glyph is being nosed off the edge. */
} else if (vertoff
+ disptable
[curchar
].up
+ disptable
[curchar
].down
>= GLROW
) {
vertoff
= GLROW
- disptable
[curchar
].up
- disptable
[curchar
].down
;
if (cht
[i
].wherewind
>= 0) {
/* The old glyph is in a window - destroy it */
wind
[cht
[i
].wherewind
].used
= -1;
cht
[i
].whereat
= findbits(i
, GLROW
, GLCOL
, horoff
, vertoff
, &cht
[i
].rcent
, &cht
[i
].ccent
);
fprintf(trace
, "setting cht[%d].wherewind to -2 in readfont\n", i
);
fbase
= sizeof FontHeader
+ sizeof disptable
; /* ftell(fontdes) */
sprintf(msgbuf
, "\"%s\", raster data %d bytes, width %d, height %d, xtend %d", fname
, FontHeader
.size
, FontHeader
.maxx
, FontHeader
.maxy
, FontHeader
.xtend
);
* Figure out the true name of the font file, given that
* the abbreviated name is fname. The result is placed
* in the provided buffer result.
if ((t
= fopen(result
, "r")) == NULL
) {
sprintf(result
,"/usr/lib/vfont/%s",fname
);
if ((t
= fopen(result
, "r")) == NULL
) {
sprintf(msgbuf
, "Can't find %s\n",fname
);
* clearfont: delete all characters in the current font.
* fileiocmd: do a file I/O command. These all take optional file
* names, defaulting to the current file.
char fname
[100], truefname
[100];
readline("file: ", fname
, sizeof fname
);
if (fname
[0] == 0 || fname
[0] == ' ')
truename(fname
, truefname
);
readfont(truefname
, 0, 255);
* readchars: read in a partial font (the P command).
message("Partial read <firstchar>");
sprintf(msgbuf
, "Partial read %s thru <lastchar>", rdchar(c1
));
sprintf(msgbuf
, "Partial read %s thru %s from file: ", buf
, rdchar(c2
));
readline(msgbuf
, fnamebuf
, sizeof fnamebuf
);
if (fnamebuf
[0] == 0 || fnamebuf
[0] == ' ')
strcpy(fnamebuf
, fontfile
);
truename(fnamebuf
, truebuf
);
readfont(truebuf
, c1
, c2
);