|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 25711 (0x646f) Types: TextFile Names: »dvisuntool.c-«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦this⟧ »./DVIware/crt-viewers/dviapollo/dvisuntool.c-« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/crt-viewers/dviapollo/dvisuntool.c-«
/* @(#)dvisuntool.c 1.17 2/19/87 */ #include "header.h" #include "genwindow.h" #define NEW(A) ((A *) malloc(sizeof(A))) /* #define DEBUG 1*/ /* for massive printing of input */ /* trace information; select by -d */ /* option before filename. */ #ifdef DEBUG int Debug = 0; #endif #define USEGLOBALMAG 1 /* when defined, the dvi global magnification is applied */ #define FIRSTPXLCHAR 0 #define LASTPXLCHAR 127 #define NPXLCHARS 128 #define PXLID 1001 #define READ 4 /* for access() */ #define hconvRESOLUTION RESOLUTION /* These numbers are right for my */ #define vconvRESOLUTION RESOLUTION /* particular sun3 display. TSF */ #define BORDER_BLACK 3 /* Width of border, in pixels.*/ #define PAGE_HEIGHT 11 /* Height of page, in inches. */ #define PAGE_WIDTH 8.5 /* Width of page, in inches. */ #define STACKSIZE 100 /* This is bogus. The DVI file gives */ /* us a stacksize, we should use it.*/ #define MAXOPEN 10 /* _NFILES limit on number of open PXL files */ float ActualFactor(); FILE* fopen(); void draw_borders(); void fatal(); void FindPostAmblePtr(); void GetBytes(); void getfontdef(); void MoveDown(); void MoveOver(); void OpenFontFile(); int PixRound(); int ReadFontDef(); int readpostamble(); void SetChar(); void SetFntNum(); void SetRule(); void SkipFontDef(); CharImage read_char(); void show_char(); struct char_entry { /* character entry */ unsigned short width, height;/* width and height in pixels */ short xOffset, yOffset; /* x offset and y offset in pixels */ struct { int isloaded; union { int fileOffset; CharImage pixrectptr; /* Not a pixrect if we're using X! */ } address; } where; int tfmw; /* TFM width */ }; struct font_entry { /* font entry */ int k, c, s, d, a, l; char n[STRSIZE]; /* FNT_DEF command parameters */ int font_space; /* computed from FNT_DEF s parameter */ int font_mag; /* computed from FNT_DEF s and d parameters */ char name[STRSIZE]; /* full name of PXL file */ FILE *font_file_id; /* file identifier (0 if none) */ int magnification; /* magnification read from PXL file */ int designsize; /* design size read from PXL file */ struct char_entry ch[NPXLCHARS];/* character information */ struct font_entry *next; }; struct pixel_list { FILE *pixel_file_id; /* file identifier */ int use_count; /* count of "opens" */ struct font_entry *fptr /* ptr to its font entry */ }; int hconv; /* DVI units per pixel */ int vconv; int den; /* denominator specified in preamble */ struct font_entry *fontptr; /* font_entry pointer for current font */ struct font_entry *hfontptr=NULL;/* font_entry pointer for all fonts */ struct font_entry *closedfonts=NULL; /* font_entry pointer for list of */ /* closed fonts. Hfontptr gets */ /* put here when a file is */ /* closed. */ int h; /* current horizontal position */ int v; /* current vertical position */ int mag; /* magnification specified in preamble */ int nopen = 0; /* number of open PXL files */ int num; /* numerator specified in preamble */ struct font_entry *pfontptr = NULL; /* most recent font_entry pointer returned from OpenFontFile. */ struct pixel_list pixel_files[MAXOPEN+1]; /* list of open PXL file identifiers */ long postambleptr; /* Pointer to the postamble */ FILE *pxlfp; /* PXL file pointer */ /* This is called when a DVI file is closed. It resets *hfontptr to */ /* NULL, and sets closedfonts to the old linked list stored in */ /* closedfonts appended with the value of hfontptr. */ void close_fonts () { if (closedfonts == NULL) { closedfonts = hfontptr; } else { struct font_entry *scanner; for (scanner = closedfonts; scanner -> next != NULL; scanner = scanner -> next); scanner -> next = hfontptr; }; hfontptr = NULL; } int Nosignextend(fp, n) /* return n byte quantity from file fp */ register FILE *fp; /* file pointer */ register int n; /* number of bytes */ { register int x; /* number being constructed */ x = 0; while (n--) { x <<= 8; x |= getc(fp); } return(x); } int signextend(fp, n) /* return n byte quantity from file fp */ register FILE *fp; /* file pointer */ register int n; /* number of bytes */ { int n1; /* number of bytes */ register int x; /* number being constructed */ x = getc(fp); /* get first (high-order) byte */ n1 = n--; while (n--) { x <<= 8; x |= getc(fp); } /* NOTE: This code assumes that the right-shift is an arithmetic, rather than logical, shift which will propagate the sign bit right. According to Kernighan and Ritchie, this is compiler dependent! */ /* Also, assuming sizeof(int) == 4 is machine dependent (32-bit ints) */ x<<=32-8*n1; x>>=32-8*n1; /* sign extend */ #ifdef DEBUG if (Debug) { fprintf(stderr,"\tsignextend(fp,%d)=%X\n",n1,x); } #endif return(x); } /* This reads the stuff between the front of the dvi file and the */ /* start of the first page. It returns the number of pages in the */ /* document. */ int start_reading_dvi_file(dvifp) FILE *dvifp; { int pages; fseek (dvifp, (long) 0, 0); if ((Nosignextend(dvifp, 1)) != PRE) { fatal("PRE doesn't occur first. Are you sure this is a DVI file?"); } { int i; i = signextend(dvifp, 1); if (i != DVIFORMAT) { fatal ("DVI format = %d, can only process DVI format %d files\n\n", i, DVIFORMAT); } } pages = readpostamble (dvifp); if (preload) getfontdef (dvifp); fseek(dvifp, (long) 14, 0); { char n[STRSIZE]; GetBytes(dvifp, n, Nosignextend(dvifp, 1)); }; return (pages); } /* Draw borders around the page. Knuth says that the (0,0) point in */ /* DVI units should be one inch from the top and from the left edges */ /* of the page. The page is 8.5 by 11 inches, of course. The borders */ /* are BORDER_BLACK pixels wide, and it lies just barely outside of the page.*/ void draw_borders(xscreen, yscreen) int xscreen, yscreen; { int height = PAGE_HEIGHT * RESOLUTION; /* These are in pixels. */ int width = PAGE_WIDTH * RESOLUTION; int x = - RESOLUTION - xscreen; int y = - RESOLUTION - yscreen; /* top horizontal */ black_box (x - BORDER_BLACK, y - BORDER_BLACK, width + 2 * BORDER_BLACK, BORDER_BLACK); /* bottom horizontal */ black_box (x - BORDER_BLACK, y + height, width + 2 * BORDER_BLACK, BORDER_BLACK); /* left vertical */ black_box (x - BORDER_BLACK, y - BORDER_BLACK, BORDER_BLACK, height + 2 * BORDER_BLACK); /* right vertical */ black_box (x + width, y - BORDER_BLACK, BORDER_BLACK, height + 2 * BORDER_BLACK); } void showpage (cpagep, ppagep, SkipMode, PagesLeft, borders, dvifp, xscreen, yscreen) long *cpagep, *ppagep; int SkipMode, PagesLeft; BOOLEAN borders; /* Whether to draw borders.*/ FILE *dvifp; int xscreen, yscreen; { int w; /* current horizontal spacing */ int x; /* current horizontal spacing */ int y; /* current vertical spacing */ int z; /* current vertical spacing */ int sp; /* stack pointer */ struct stack_entry { /* stack entry */ int h, v, w, x, y, z; /* what's on stack */ }; struct stack_entry stack[STACKSIZE]; /* stack */ int SkipEOP = FALSE; /* input is waiting from the terminal, skip to EOP */ int command; /* current command */ w = x = y = z = 0; /*Let's hope that each page specifies values for */ /*w,x,y,and z before it uses them. Sincx Knuth */ /*says that DVI format should be readable from */ /*back to front, this seems reasonable.*/ do { command = Nosignextend(dvifp, 1); switch (command) { case SET1:case SET2:case SET3:case SET4: {int val; val = Nosignextend(dvifp, command-SET1+1); if (!SkipMode) SetChar(val, command, xscreen, yscreen);} break; case SET_RULE: {int val, val2; val = Nosignextend(dvifp, 4); val2 = Nosignextend(dvifp, 4); if (!SkipMode) SetRule(val, val2, 1, xscreen, yscreen);} break; case PUT1:case PUT2:case PUT3:case PUT4: {int val; val = Nosignextend(dvifp,command-PUT1+1); if (!SkipMode) SetChar(val, command, xscreen, yscreen);} break; case PUT_RULE: {int val, val2; val = Nosignextend(dvifp, 4); val2 = Nosignextend(dvifp, 4); if (!SkipMode) SetRule(val, val2, 0, xscreen, yscreen);} break; case NOP: break; case BOP: (*cpagep) = ftell(dvifp) - 1; {int i; for (i=0; i<=9; i++) Nosignextend(dvifp, 4);} (*ppagep) = Nosignextend(dvifp, 4); h = v = w = x = y = z = 0; sp = 0; fontptr = NULL; if (PagesLeft) { PagesLeft--; if (PagesLeft <= 0) SkipMode = FALSE; }; break; case EOP: if (borders && !SkipMode && !SkipEOP) draw_borders(xscreen, yscreen); if (SkipEOP) { SkipMode = FALSE; SkipEOP = FALSE; } break; case PUSH: if (sp >= STACKSIZE) fatal("stack overflow"); stack[sp].h = h; stack[sp].v = v; stack[sp].w = w; stack[sp].x = x; stack[sp].y = y; stack[sp].z = z; sp++; break; case POP: --sp; if (sp < 0) fatal("stack underflow"); h = stack[sp].h; v = stack[sp].v; w = stack[sp].w; x = stack[sp].x; y = stack[sp].y; z = stack[sp].z; break; case RIGHT1:case RIGHT2:case RIGHT3:case RIGHT4: {int val; val = signextend(dvifp,command-RIGHT1+1); if (!SkipMode) MoveOver(val);} break; case W0: if (!SkipMode) MoveOver(w); break; case W1:case W2:case W3:case W4: w = signextend(dvifp,command-W1+1); if (!SkipMode) MoveOver(w); break; case X0: if (!SkipMode) MoveOver(x); break; case X1:case X2:case X3:case X4: x = signextend(dvifp,command-X1+1); if (!SkipMode) MoveOver(x); break; case DOWN1:case DOWN2:case DOWN3:case DOWN4: {int val; val = signextend(dvifp,command-DOWN1+1); if (!SkipMode) MoveDown(val);} break; case Y0: if (!SkipMode) MoveDown(y); break; case Y1:case Y2:case Y3:case Y4: y = signextend(dvifp,command-Y1+1); if (!SkipMode) MoveDown(y); break; case Z0: if (!SkipMode) MoveDown(z); break; case Z1:case Z2:case Z3:case Z4: z = signextend(dvifp,command-Z1+1); if (!SkipMode) MoveDown(z); break; case FNT1:case FNT2:case FNT3:case FNT4: if (!SkipMode) SetFntNum(Nosignextend(dvifp,command-FNT1+1)); break; case XXX1:case XXX2:case XXX3:case XXX4: {int k; k = Nosignextend(dvifp,command-XXX1+1); while (k--) Nosignextend(dvifp, 1);} break; case FNT_DEF1:case FNT_DEF2:case FNT_DEF3:case FNT_DEF4: if (preload) { SkipFontDef (Nosignextend(dvifp, command-FNT_DEF1+1), dvifp); } else { ReadFontDef (Nosignextend(dvifp, command-FNT_DEF1+1), dvifp); } break; case PRE: fatal("PRE occurs within file"); break; case POST: fseek(dvifp, (*cpagep), 0); SkipMode = FALSE; PagesLeft = 0; break; case POST_POST: fatal("POST_POST with no preceding POST"); break; default: if (command >= FONT_00 && command <= FONT_63) {if (!SkipMode) SetFntNum(command - FONT_00);} else if (command >= SETC_000 && command <= SETC_127) {if (!SkipMode) SetChar(command - SETC_000, command, xscreen, yscreen);} else fatal("%d is an undefined command", command); break; } /* case */ } while (command != EOP || SkipMode); } /* compute the actual size factor given the approximation */ float ActualFactor(unmodsize) int unmodsize; /* actually factor * 1000 */ { float realsize; /* the actual magnification factor */ realsize = (float)unmodsize / 1000.0; /* a real hack to correct for rounding in some cases--rkf */ if(unmodsize==1095) realsize = 1.095445; /*stephalf*/ else if(unmodsize==1315) realsize=1.314534; /*stepihalf*/ else if(unmodsize==2074) realsize=2.0736; /*stepiv*/ else if(unmodsize==2488) realsize=2.48832; /*stepv*/ else if(unmodsize==2986) realsize=2.985984; /*stepiv*/ /* the remaining magnification steps are represented with sufficient accuracy already */ return(realsize); } int DoConv(num, den, convResolution) { register float conv; conv = ((float)num/(float)den) * #ifdef USEGLOBALMAG ActualFactor(mag) * /* put back in by clp, 8/22/84 */ /* ((float) mag/1000.0) * and this taken out... */ #endif ((float)convResolution/254000.0); return((int) (1.0 / conv + 0.5)); } void fatal(fmt, args)/* issue a fatal error message */ char *fmt; /* format */ char *args; /* arguments */ { fprintf(stderr, "Fatal error. "); _doprnt(fmt, &args, stderr); fprintf(stderr, "\n"); exit(1); } void FindPostAmblePtr(postambleptr, dvifp) long *postambleptr; FILE *dvifp; /* this routine will move to the end of the file and find the start of the postamble */ { int i; fseek (dvifp, (long) 0, 2); /* goto end of file */ *postambleptr = ftell (dvifp) - 4; fseek (dvifp, *postambleptr, 0); while (TRUE) { fseek (dvifp, --(*postambleptr), 0); if (((i = Nosignextend(dvifp, 1)) != 223) && (i != DVIFORMAT)) fatal ("Bad end of DVI file"); if (i == DVIFORMAT) break; } fseek (dvifp, (*postambleptr) - 4, 0); *postambleptr = Nosignextend(dvifp, 4); fseek (dvifp, *postambleptr, 0); } void GetBytes(fp, cp, n) /* get n bytes from file fp */ register FILE *fp; /* file pointer */ register char *cp; /* character pointer */ register int n; /* number of bytes */ { while (n--) *cp++ = getc(fp); } void getfontdef(dvifp) FILE *dvifp; /* Read the font definitions as they are in the postamble of the DVI file. Note that the font directory is not yet loaded. In order to adapt ourselves to the existing "verser" the following font paramters are copied onto output fontno (4 bytes), chksum, fontmag, fontnamelength (1 byte), fontname. At the end, a -1 is put onto the file.*/ { char str[50], *calloc (); unsigned char byte; int i, fnamelen; while (((byte = Nosignextend(dvifp, 1)) >= FNT_DEF1) && (byte <= FNT_DEF4)) { switch (byte) { case FNT_DEF1: ReadFontDef (Nosignextend(dvifp, 1), dvifp); break; case FNT_DEF2: ReadFontDef (Nosignextend(dvifp, 2), dvifp); break; case FNT_DEF3: ReadFontDef (Nosignextend(dvifp, 3), dvifp); break; case FNT_DEF4: ReadFontDef (Nosignextend(dvifp, 4), dvifp); break; default: fatal ("Bad byte value in font defs"); break; } } if (byte != POST_POST) fatal ("POST_POST missing after fontdefs"); } void MoveDown(a) int a; { v += a; } void MoveOver(b) int b; { h += b; } void OpenFontFile() /* The original version of this dvi driver reopened the font file each time the font changed, resulting in an enormous number of relatively expensive file openings. This version keeps a cache of up to MAXOPEN open files, so that when a font change is made, the file pointer, pxlfp, can usually be updated from the cache. When the file is not found in the cache, it must be opened. In this case, the next empty slot in the cache is assigned, or if the cache is full, the least used font file is closed and its slot reassigned for the new file. Identification of the least used file is based on the counts of the number of times each file has been "opened" by this routine. On return, the file pointer is always repositioned to the beginning of the file.*/ { register int i,least_used,current; #ifdef DEBUG if (Debug) printf("Open Font file\n"); #endif if (pfontptr == fontptr) return; /* we need not have been called */ for (current = 1; (current <= nopen) && (pixel_files[current].pixel_file_id != fontptr->font_file_id); ++current); /* try to find file in open list */ if (current <= nopen) { /* file already open */ pxlfp = pixel_files[current].pixel_file_id; fseek(pxlfp,0,0); /* reposition to start of file */ } else { /* file not in open list */ if (nopen < MAXOPEN) /* just add it to list */ current = ++nopen; else {/* list full -- find least used file, close it, and */ /* reuse slot for new file */ least_used = 1; for (i = 2; i <= MAXOPEN; ++i) if (pixel_files[least_used].use_count > pixel_files[i].use_count) least_used = i; fclose(pixel_files[least_used].pixel_file_id); pixel_files[least_used].fptr -> font_file_id = 0; current = least_used; } if ((pxlfp=fopen(fontptr->name,"r")) == NULL) { perror (""); fatal("PXL file \"%s\" could not be opened; %d PXL files are open", fontptr->name,nopen); }; pixel_files[current].pixel_file_id = pxlfp; pixel_files[current].fptr = fontptr; pixel_files[current].use_count = 0; } pfontptr = fontptr; /* make previous = current font */ fontptr->font_file_id = pxlfp; /* set file identifier */ pixel_files[current].use_count++; /* update reference count */ } int PixRound(x, conv) /* return rounded number of pixels */ register int x; /* in DVI units */ int conv; /* conversion factor */ { return((int)((x + (conv >> 1)) / conv)); } /* Put the given font pointer on the global list of font pointers and */ /* make it the current font. */ void installfontptr (tfontptr) struct font_entry *tfontptr; { tfontptr->next = hfontptr; fontptr = hfontptr = tfontptr; } int ReadFontDef(k, dvifp) int k; FILE *dvifp; { int t, i; register struct font_entry *tfontptr; /* temporary font_entry pointer */ register struct char_entry *tcharptr; /* temporary char_entry pointer */ char *direct, *tcp, *tcp1; int found; char curarea[STRSIZE]; if ((tfontptr = NEW(struct font_entry)) == NULL) fatal("can't malloc space for font_entry"); tfontptr->k = k; tfontptr->c = Nosignextend(dvifp, 4); /* checksum */ tfontptr->s = Nosignextend(dvifp, 4); /* space size */ tfontptr->d = Nosignextend(dvifp, 4); /* design size */ tfontptr->a = Nosignextend(dvifp, 1); /* area length for font name */ tfontptr->l = Nosignextend(dvifp, 1); /* device length */ GetBytes(dvifp, tfontptr->n, tfontptr->a+tfontptr->l); tfontptr->n[tfontptr->a+tfontptr->l] = '\0'; tfontptr->font_space = tfontptr->s/6; /* never used */ tfontptr->font_mag = (int)((ActualFactor((int)(((float)tfontptr->s/ (float)tfontptr->d)*1000.0 + 0.5)) * #ifdef USEGLOBALMAG ActualFactor(mag) * #endif (float)RESOLUTION * 5.0) + 0.5); #ifdef DEBUG printf ("Trying to open font %s, mag %d.\n", tfontptr -> n, tfontptr -> font_mag); #endif /* Look for a font with the same file name as tfontptr in */ /* closedfonts. */ { struct font_entry *prevptr=NULL; /* Follows curptr in the closed */ /* fonts list. */ struct font_entry *curptr; for (curptr = closedfonts; (curptr != NULL) && !((curptr->font_mag == tfontptr -> font_mag) && (strcmp (curptr -> n, tfontptr -> n) == 0)); prevptr = curptr,curptr = curptr -> next); if (curptr != NULL) { #ifdef DEBUG printf ("Re-opening closed font %s, mag %d, filename is %s.\n", tfontptr -> n, tfontptr -> font_mag, curptr -> name); #endif /* We found a font with the same name in the list of closed */ /* fonts. Now delete it from the list of closed fonts. */ if (prevptr == NULL) { /* curptr was the first font on the list of closed fonts. */ closedfonts = closedfonts -> next; } else { /* curptr wasn't first. */ prevptr -> next = curptr -> next; }; /* Verify that all of the relevant font parameters are the */ /* same. */ if ((tfontptr -> c != curptr -> c) || (tfontptr -> s != curptr -> s) || (tfontptr -> d != curptr -> d)) { fatal ("Font %s at magnification %d reencountered with different parameters.", tfontptr -> n, tfontptr -> font_mag); }; curptr -> k = tfontptr -> k; /* The following is somewhat bogus. I should fix the above */ /* code so that no mallocs happen if the font is in the closed */ /* list. Oh well, spaghetti code begats spaghetti code. */ free (tfontptr); installfontptr (curptr); } else { /* Opening a new font. */ if (tfontptr->a != 0) { sprintf(tfontptr->name, "%s.%dpxl", tfontptr->n, tfontptr->font_mag); } else { direct = PXLpath; found = FALSE; do { tcp = index(direct, ':'); if (tcp == NULL) tcp = strlen(direct) + direct; strncpy(curarea, direct, tcp-direct); tcp1 = curarea + (tcp - direct); *tcp1++ = '/'; *tcp1++ = '\0'; sprintf(tfontptr->name, "%s%s.%dpxl", curarea, tfontptr->n, tfontptr->font_mag); found = (access(tfontptr->name, READ) == 0); if (*tcp) direct = tcp + 1; else direct = tcp; } while ( !found && *direct != '\0'); }; #ifdef DEBUG printf ("Filename is %s.\n", tfontptr -> name); #endif installfontptr (tfontptr); OpenFontFile(); if ((t = Nosignextend(pxlfp, 4)) != PXLID) fatal("PXL ID = %d, can only process PXL ID = %d files", t, PXLID); fseek(pxlfp, -20, 2); t = Nosignextend(pxlfp, 4); if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t)) fatal("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d", tfontptr->name, tfontptr->c, t); tfontptr->magnification = Nosignextend(pxlfp, 4); tfontptr->designsize = Nosignextend(pxlfp, 4); fseek(pxlfp, Nosignextend(pxlfp, 4) * 4, 0); for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) { tcharptr = &(tfontptr->ch[i]); tcharptr->width = Nosignextend(pxlfp, 2); tcharptr->height = Nosignextend(pxlfp, 2); tcharptr->xOffset= signextend(pxlfp, 2); tcharptr->yOffset = signextend(pxlfp, 2); tcharptr->where.isloaded = FALSE; tcharptr->where.address.fileOffset = Nosignextend(pxlfp, 4) * 4; tcharptr->tfmw = ((float)Nosignextend(pxlfp, 4)*(float)tfontptr->s) / (float)(1<<20); } } } } int readpostamble (dvifp) FILE *dvifp; /* This routine is used to read in the postamble values. It initializes the magnification and checks the stack height prior to starting printing the document. It returns the number of pages in the document. */ { FindPostAmblePtr (&postambleptr, dvifp); if (Nosignextend(dvifp, 1) != POST) fatal ("POST missing at head of postamble"); #ifdef DEBUG if (Debug) fprintf (stderr, "got POST command\n"); #endif /* lastpageptr = */ Nosignextend(dvifp, 4); num = Nosignextend(dvifp, 4); den = Nosignextend(dvifp, 4); mag = Nosignextend(dvifp, 4); hconv = DoConv(num, den, hconvRESOLUTION); vconv = DoConv(num, den, vconvRESOLUTION); Nosignextend(dvifp, 4); /* height-plus-depth of tallest page */ Nosignextend(dvifp, 4); /* width of widest page */ if (Nosignextend(dvifp, 2) >= STACKSIZE) fatal ("Stack size is too small"); return (Nosignextend(dvifp, 2)); /* this reads the number of pages in */ /* the DVI file */ } void LoadAChar(ptr) register struct char_entry *ptr; { if (ptr->where.address.fileOffset == 0) { ptr->where.address.pixrectptr = NULL; return; } OpenFontFile(); fseek(pxlfp, ptr->where.address.fileOffset, 0); ptr->where.address.pixrectptr = read_char (pxlfp, ptr -> width, ptr -> height); ptr->where.isloaded = TRUE; } /* Display a character.*/ void SetChar(c, command, xscreen, yscreen) int c; /* Character to display */ int command; /* Command we are doing */ int xscreen, yscreen; { register struct char_entry *ptr; /* temporary char_entry pointer */ int k; int hh; /* current horizontal position in pixels */ int vv; /* current vertical position in pixels */ ptr = &(fontptr->ch[c]); hh = PixRound(h, hconv); vv = PixRound(v, vconv); if (!ptr->where.isloaded) LoadAChar(ptr); show_char (hh-ptr->xOffset-xscreen, vv-ptr->yOffset-yscreen, ptr->width, ptr->height, ptr->where.address.pixrectptr); if (command <= SET4) h += ptr->tfmw; } void SetFntNum(k) int k; /* this routine is used to specify the font to be used in printing future characters */ { fontptr = hfontptr; while ((fontptr!=NULL) && (fontptr->k!=k)) fontptr = fontptr->next; if (fontptr == NULL) fatal("font %d undefined", k); } void SetRule(a, b, Set, xscreen, yscreen) int a, b; BOOLEAN Set; int xscreen, yscreen; { /* this routine will draw a rule on the screen */ int ehh, evv; int hh; /* current horizontal position in pixels */ int vv; /* current vertical position in pixels */ hh = PixRound(h, hconv); vv = PixRound(v-a, vconv); ehh = PixRound(h + b, hconv); evv = PixRound(v, vconv); if (hh == ehh) ehh++; if (vv == evv) vv--; if ((a > 0) && (b > 0)) black_box (hh-xscreen, vv-yscreen, ehh-hh, evv-vv); if (Set) { h += b; /* v += a; */ } } void SkipFontDef(k, dvifp) int k; FILE *dvifp; { int a, l; char n[STRSIZE]; Nosignextend(dvifp, 4); Nosignextend(dvifp, 4); Nosignextend(dvifp, 4); a = Nosignextend(dvifp, 1); l = Nosignextend(dvifp, 1); GetBytes(dvifp, n, a+l); }