/* * This is the DVI related part of TeXtool */ /* * This code has quite a long history. * The header comment from the dvi2ps driver from the TeX tape I * received about August 86 is shown below */ /* * * AUTHOR(s) * Mark Senn wrote the early versions of this program for the * BBN BitGraph. Stephan Bechtolsheim, Bob Brown, Richard * Furuta, James Schaad and Robert Wells improved it. Norm * Hutchinson ported the program to the Sun. Neal Holtz ported * it to the Apollo, and from there to producing PostScript * output. Scott Jones added intelligent font substitution. * */ /* * This version presumably diverged from the dvi2ps line before the * move to Apollo and was then modified by Y. Ledru (yl@lln-cs) * to work with SunView. * A bugfix from dvi2ps to do with marking font files closed when they * are removed from the cache has been "bought back" into this version. * The font data structures have also been changed so they are * cross-linked so no searching has to be done except to find the * least used cache entry. * Extra tests for valid data values have been put into LoadAChar() * as a bogus PXL file was causing havoc by overfilling a character * pixrect. * Much other tidying up and removal of code which was no longer used * has also been done * Peter Ilieve - peter@memex.co.uk */ #include "defs.h" #include "commands.h" #include #include #include #include char *index(); char *calloc(); char *rindex(); char *sprintf(); char *strcpy(); /* procedures in sunstuff */ extern void BatchStart(); extern void BatchEnd(); extern void Fatal(); extern void SetBop(); extern void SetChar(); extern void SetRule(); extern void Warning(); /* procedures in pxlstuff or pkstuff */ extern void FindFontFile(); extern void LoadAChar(); extern void ReadCharDefs(); /* procedures here */ float ActualFactor(); FILE* BINARYOPEN(); void CloseDviFile(); int DoConv(); void DoPage(); Boolean DviFileChanged(); void FindPostAmblePtr(); void FreeFontStorage(); void GetBytes(); int NoSignExtend(); void OpenDviFile(); FILE *OpenFontFile(); int ReadFontDef(); void ReadPagePointers(); void ReadPreAmble(); void ReadPostAmble(); void SetFntNum(); int SignExtend(); void SkipFontDef(); #ifdef DEBUG void ShowPxlCache(); void ShowPxlFd(); #endif /* a few global variables and data structures */ #include "globals.h" struct pixel_list { FILE *pixel_file_id; /* file identifier */ struct font_entry *feptr; /* font_entry for this cache slot */ int use_count; /* count of "opens" */ }; struct font_entry *fontptr; /* font_entry pointer */ struct font_entry *hfontptr=NULL;/* font_entry pointer to head of chain */ struct font_entry *pfontptr = NULL; /* previous font_entry pointer */ int nopen = 0; /* number of open font files */ struct pixel_list pixel_files[MAXOPEN+1]; /* list of open font file identifiers */ /* slot 0 not used */ /* * DVI file related data structures */ /* pagepointers moved to globals to let sunstuff get at count_0 */ /* two structs to hold pre and postamble */ /* a lot of this is not used */ struct Preamble { unsigned int num; unsigned int den; unsigned int mag; } preamble; struct Postamble { long last_page_ptr; unsigned int num; unsigned int den; unsigned int mag; unsigned int maxheight; unsigned int maxwidth; unsigned short maxstack; unsigned short totalpages; } postamble; FILE *dvifp; /* DVI file pointer */ static time_t dvimodtime; struct stack_entry { /* stack entry */ int h, v, w, x, y, z; /* what's on stack */ }; struct stack_entry stack[STACKSIZE]; /* stack */ int sp; /* stack pointer */ /* h and v are global */ int w; /* current horizontal spacing */ int x; /* current horizontal spacing */ int y; /* current vertical spacing */ int z; /* current vertical spacing */ /* display related stuff */ int hconv, vconv; /* converts DVI units to pixels */ /* now to the real code */ /*-->ActualFactor*/ /**********************************************************************/ /************************** ActualFactor ****************************/ /**********************************************************************/ float /* compute the actual size factor given the approximation */ 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); } /*-->CloseDviFile*/ /**********************************************************************/ /************************** CloseDviFile ******************************/ /**********************************************************************/ void CloseDviFile() { if (dvifp != NULL) fclose(dvifp); if (pagepointers != NULL) { free (pagepointers); pagepointers = NULL; } } /*-->DoConv*/ /**********************************************************************/ /****************************** DoConv ******************************/ /**********************************************************************/ int DoConv(num, den, mag, convResolution) { register float conv; conv = ((float)num/(float)den) * #ifdef USEGLOBALMAG ActualFactor(mag) * #endif ((float)convResolution/254000.0); return((int) (1.0 / conv + 0.5)); } /*-->DoPage*/ /**********************************************************************/ /****************************** DoPage ******************************/ /**********************************************************************/ void DoPage(pagenumber) int pagenumber; { unsigned char command; int val, val2; int k; #ifdef DEBUG if (Debug) fprintf(stderr,"DoPage(%d)\n", pagenumber); #endif if (!(main_state & SB_INTERPRET)) return; h = v = w = x = y = z = 0; /* zero position */ sp = 0; /* empty stack */ fontptr = NULL; /* no font */ fseek(dvifp, pagepointers[pagenumber].page_ptr, 0); /* go to correct page */ SetBop(); /* clear canvas */ if (Batching) BatchStart(); while (main_state & SB_INTERPRET) /* interpret DVI file */ /* we use getc here for speed */ /* also force a complete jump table */ switch (command=getc(dvifp)) { case SETC_000: case SETC_001: case SETC_002: case SETC_003: case SETC_004: case SETC_005: case SETC_006: case SETC_007: case SETC_008: case SETC_009: case SETC_010: case SETC_011: case SETC_012: case SETC_013: case SETC_014: case SETC_015: case SETC_016: case SETC_017: case SETC_018: case SETC_019: case SETC_020: case SETC_021: case SETC_022: case SETC_023: case SETC_024: case SETC_025: case SETC_026: case SETC_027: case SETC_028: case SETC_029: case SETC_030: case SETC_031: case SETC_032: case SETC_033: case SETC_034: case SETC_035: case SETC_036: case SETC_037: case SETC_038: case SETC_039: case SETC_040: case SETC_041: case SETC_042: case SETC_043: case SETC_044: case SETC_045: case SETC_046: case SETC_047: case SETC_048: case SETC_049: case SETC_050: case SETC_051: case SETC_052: case SETC_053: case SETC_054: case SETC_055: case SETC_056: case SETC_057: case SETC_058: case SETC_059: case SETC_060: case SETC_061: case SETC_062: case SETC_063: case SETC_064: case SETC_065: case SETC_066: case SETC_067: case SETC_068: case SETC_069: case SETC_070: case SETC_071: case SETC_072: case SETC_073: case SETC_074: case SETC_075: case SETC_076: case SETC_077: case SETC_078: case SETC_079: case SETC_080: case SETC_081: case SETC_082: case SETC_083: case SETC_084: case SETC_085: case SETC_086: case SETC_087: case SETC_088: case SETC_089: case SETC_090: case SETC_091: case SETC_092: case SETC_093: case SETC_094: case SETC_095: case SETC_096: case SETC_097: case SETC_098: case SETC_099: case SETC_100: case SETC_101: case SETC_102: case SETC_103: case SETC_104: case SETC_105: case SETC_106: case SETC_107: case SETC_108: case SETC_109: case SETC_110: case SETC_111: case SETC_112: case SETC_113: case SETC_114: case SETC_115: case SETC_116: case SETC_117: case SETC_118: case SETC_119: case SETC_120: case SETC_121: case SETC_122: case SETC_123: case SETC_124: case SETC_125: case SETC_126: case SETC_127: SetChar(&(fontptr->ch[command - SETC_000]), SETCMD); break; case SET1:case SET2:case SET3:case SET4: val = NoSignExtend(dvifp, command-SET1+1); SetChar(&(fontptr->ch[val]), SETCMD); break; case SET_RULE: val = NoSignExtend(dvifp, 4); val2 = NoSignExtend(dvifp, 4); SetRule(val, val2, SETCMD); break; case PUT1:case PUT2:case PUT3:case PUT4: val = NoSignExtend(dvifp,command-PUT1+1); SetChar(&(fontptr->ch[val]), PUTCMD); break; case PUT_RULE: val = NoSignExtend(dvifp, 4); val2 = NoSignExtend(dvifp, 4); SetRule(val, val2, PUTCMD); break; case NOP: break; case BOP: Fatal("BOP encountered in page"); break; case EOP: if (Batching) BatchEnd(); #ifdef DEBUG if (Debug) fprintf(stderr,"DoPage return after EOP found\n"); #endif return; case PUSH: if (sp >= STACKSIZE) Fatal("stack overflow"); else { 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"); else { 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: val = SignExtend(dvifp,command-RIGHT1+1); MoveOver(val); break; case W0: MoveOver(w); break; case W1:case W2:case W3:case W4: w = SignExtend(dvifp,command-W1+1); MoveOver(w); break; case X0: MoveOver(x); break; case X1:case X2:case X3:case X4: x = SignExtend(dvifp,command-X1+1); MoveOver(x); break; case DOWN1:case DOWN2:case DOWN3:case DOWN4: val = SignExtend(dvifp,command-DOWN1+1); MoveDown(val); break; case Y0: MoveDown(y); break; case Y1:case Y2:case Y3:case Y4: y = SignExtend(dvifp,command-Y1+1); MoveDown(y); break; case Z0: MoveDown(z); break; case Z1:case Z2:case Z3:case Z4: z = SignExtend(dvifp,command-Z1+1); MoveDown(z); break; case FONT_00: case FONT_01: case FONT_02: case FONT_03: case FONT_04: case FONT_05: case FONT_06: case FONT_07: case FONT_08: case FONT_09: case FONT_10: case FONT_11: case FONT_12: case FONT_13: case FONT_14: case FONT_15: case FONT_16: case FONT_17: case FONT_18: case FONT_19: case FONT_20: case FONT_21: case FONT_22: case FONT_23: case FONT_24: case FONT_25: case FONT_26: case FONT_27: case FONT_28: case FONT_29: case FONT_30: case FONT_31: case FONT_32: case FONT_33: case FONT_34: case FONT_35: case FONT_36: case FONT_37: case FONT_38: case FONT_39: case FONT_40: case FONT_41: case FONT_42: case FONT_43: case FONT_44: case FONT_45: case FONT_46: case FONT_47: case FONT_48: case FONT_49: case FONT_50: case FONT_51: case FONT_52: case FONT_53: case FONT_54: case FONT_55: case FONT_56: case FONT_57: case FONT_58: case FONT_59: case FONT_60: case FONT_61: case FONT_62: case FONT_63: SetFntNum(command - FONT_00); break; case FNT1:case FNT2:case FNT3:case FNT4: SetFntNum(NoSignExtend(dvifp, command-FNT1+1)); break; case XXX1:case XXX2:case XXX3:case XXX4: k = NoSignExtend(dvifp,command-XXX1+1); while (k--) getc(dvifp); break; case FNT_DEF1:case FNT_DEF2:case FNT_DEF3:case FNT_DEF4: k = NoSignExtend(dvifp, command-FNT_DEF1+1); SkipFontDef (k); /* always read from postamble */ break; case PRE: Fatal("PRE occurs within file"); break; case POST: Fatal("POST found before EOP"); break; case POST_POST: Fatal("POST_POST with no preceding POST"); break; case UNDEF_00: case UNDEF_01: case UNDEF_02: case UNDEF_03: case UNDEF_04: case UNDEF_05: default: Fatal("%d is an undefined command", command); break; } if (Batching) BatchEnd(); /* to catch cases when stop in mid page */ } /*-->DviFileChanged*/ /**********************************************************************/ /************************ DviFileChanged ****************************/ /**********************************************************************/ Boolean DviFileChanged() { struct stat statbuf; if (main_state & (SB_NOFILE | SB_NODVIFILE)) /* can't do fstat */ return (FALSE); fstat(fileno(dvifp), &statbuf); if (statbuf.st_mtime > dvimodtime) { dvimodtime = statbuf.st_mtime; return (TRUE); } else return (FALSE); } /*-->FindPostAmblePtr*/ /**********************************************************************/ /************************ FindPostAmblePtr **************************/ /**********************************************************************/ void FindPostAmblePtr(postambleptr) long *postambleptr; /* 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"); return; } if (i == DVIFORMAT) break; } fseek (dvifp, (*postambleptr) - 4, 0); (*postambleptr) = NoSignExtend(dvifp, 4); fseek (dvifp, *postambleptr, 0); } /*-->FreeFontStorage*/ /**********************************************************************/ /**************************** FreeFontStorage ***********************/ /**********************************************************************/ void FreeFontStorage() { register struct font_entry *tfontptr; register struct char_entry *tcharptr; register int i; while (hfontptr != NULL) { tfontptr = hfontptr->next; /* close open font file */ if (hfontptr->cache_slot != NOTCACHED) fclose(pixel_files[hfontptr->cache_slot].pixel_file_id); /* free all memory pixrects for chars */ if (hfontptr->has_been_opened == TRUE) { for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) { tcharptr = &(hfontptr->ch[i]); if (tcharptr->where.isloaded == TRUE) pr_destroy(tcharptr->where.address.pixrectptr); } } /* free font_entry struct */ free(hfontptr); hfontptr = tfontptr; } pfontptr = NULL; nopen = 0; /* zero font cache count */ } /*-->GetBytes*/ /**********************************************************************/ /***************************** GetBytes *****************************/ /**********************************************************************/ 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); } /*-->NoSignExtend*/ /**********************************************************************/ /*************************** NoSignExtend ***************************/ /**********************************************************************/ int NoSignExtend(fp, n) /* return n byte quantity from file fd */ 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); } /*-->OpenDviFile*/ /**********************************************************************/ /************************** OpenDviFile ******************************/ /**********************************************************************/ void OpenDviFile(dviname) char *dviname; { if (main_state & (SB_NOFILE | SB_NODVIFILE)) return; /* don't even try */ if ((dvifp=BINARYOPEN(dviname,"r")) == NULL) { Fatal("Can't open \"%s\"", dviname); return; } ReadPreAmble(); #ifdef USEGLOBALMAG if (Mflag) preamble.mag = user_mag; #endif ReadPostAmble(); #ifdef USEGLOBALMAG if (Mflag) postamble.mag = user_mag; #endif ReadPagePointers(); if (postamble.maxstack >= STACKSIZE) { Fatal ("Stack size is too small for \"%s\"", dviname); return; } if ((preamble.num != postamble.num) || (preamble.den != postamble.den) || (preamble.mag != postamble.mag)) { Fatal("Preamble-Postamble mismatch in \"%s\"", dviname); return; } totalpages = postamble.totalpages; hconv = DoConv(preamble.num, preamble.den, preamble.mag, RESOLUTION); vconv = DoConv(preamble.num, preamble.den, preamble.mag, RESOLUTION); dvimodtime = 0; /* to force DviFileChanged() to set it */ (void)DviFileChanged(); #ifdef DEBUG if (Debug) fprintf(stderr,"DVI file open OK, total pages = %d\n", totalpages); #endif } /*-->OpenFontFile*/ /**********************************************************************/ /************************** OpenFontFile *****************************/ /**********************************************************************/ FILE * 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 returned 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; FILE *fontfp; #ifdef DEBUG if (ExtraDebug) fprintf(stderr,"Open Font file:\n"); #endif if (pfontptr == fontptr) { pixel_files[fontptr->cache_slot].use_count++; /* update reference count */ #ifdef DEBUG if (ExtraDebug) fprintf(stderr,"quick return (k = %d)\n", fontptr->k); #endif return (pixel_files[fontptr->cache_slot].pixel_file_id); } if ((current = fontptr->cache_slot) != NOTCACHED) /* it is already in cache */ { fontfp = pixel_files[current].pixel_file_id; fseek(fontfp,0,0); /* reposition to start of file */ #ifdef DEBUG if (ExtraDebug) fprintf(stderr, "reposition font file position %d (k = %d)\n", current, fontptr->k); #endif } else /* file not in cache */ { 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; (pixel_files[least_used].feptr)->cache_slot = NOTCACHED; /* flag font_entry as no longer cached */ fclose(pixel_files[least_used].pixel_file_id); /* close it */ #ifdef DEBUG if (ExtraDebug) fprintf(stderr, "font file %s, slot %d closed (k = %d)\n", (pixel_files[least_used].feptr)->name, least_used, (pixel_files[least_used].feptr)->k); #endif current = least_used; } if (!fontptr->has_been_opened) FindFontFile(fontptr, preamble.mag); if (ExtraDebug) printf("Trying to open file %s\n", fontptr->name); if ((fontfp=BINARYOPEN(fontptr->name,"r")) == NULL) { if (ExtraDebug) printf("Failed to open file %s\n", fontptr->name); Fatal("font file %s could not be opened; %d font files are open", fontptr->name,nopen); return (NULL); } #ifdef DEBUG if (ExtraDebug) fprintf(stderr,"font file %s opened, position %d, (k = %d)\n", fontptr->name, current, fontptr->k); #endif pixel_files[current].pixel_file_id = fontfp; pixel_files[current].use_count = 0; pixel_files[current].feptr = fontptr; /* make cross links */ fontptr->cache_slot = current; if (!fontptr->has_been_opened) { ReadCharDefs(fontptr, fontfp); fontptr->has_been_opened = TRUE; } } pfontptr = fontptr; /* make previous = current font */ pixel_files[current].use_count++; /* update reference count */ return (fontfp); } /*-->ReadFontDef*/ /**********************************************************************/ /**************************** ReadFontDef ***************************/ /**********************************************************************/ int ReadFontDef(k) int k; { register struct font_entry *tfontptr; /* temporary font_entry pointer */ if ((tfontptr = NEW(1, struct font_entry)) == NULL) { Fatal("can't malloc space for font_entry"); return; } tfontptr->next = hfontptr; fontptr = hfontptr = tfontptr; 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->cache_slot = NOTCACHED; tfontptr->has_been_opened = FALSE; if (PreLoad || BigPreLoad) (void)OpenFontFile(); } /*-->ReadPagePointers*/ /**********************************************************************/ /************************** ReadPagePointers ************************/ /**********************************************************************/ void ReadPagePointers() { long temp_ptr; int index; int k; if (main_state & (SB_NOFILE | SB_NODVIFILE)) return; #ifdef DEBUG if (Debug) fprintf (stderr, "now reading page pointers\n"); #endif pagepointers = NEW(postamble.totalpages ,struct page_entry); if (pagepointers == NULL) { Fatal("can't malloc space for page pointers"); return; } index = postamble.totalpages; temp_ptr = postamble.last_page_ptr; while (--index >= 0) { fseek(dvifp, temp_ptr, 0); if(NoSignExtend(dvifp, 1) != BOP) { Fatal("Couldn't find BOP"); return; } pagepointers[index].count_0 = NoSignExtend(dvifp, 4); k = 36; while (k--) getc(dvifp); pagepointers[index].page_ptr = temp_ptr+45; temp_ptr = (long)NoSignExtend(dvifp, 4); } } /*-->ReadPreAmble*/ /**********************************************************************/ /************************** ReadPreAmble ****************************/ /**********************************************************************/ void ReadPreAmble() { int k; if (main_state & (SB_NOFILE | SB_NODVIFILE)) return; if (NoSignExtend(dvifp, 2) != ((PRE << 8) | DVIFORMAT)) { Fatal("This doesn't look like a DVI file, it doesn't start with PRE, %d", DVIFORMAT); return; } preamble.num = NoSignExtend(dvifp, 4); preamble.den = NoSignExtend(dvifp, 4); preamble.mag = NoSignExtend(dvifp, 4); k = NoSignExtend(dvifp, 1); while (k--) getc(dvifp); } /*-->ReadPostAmble*/ /**********************************************************************/ /************************** ReadPostAmble ***************************/ /**********************************************************************/ void ReadPostAmble() { long postambleptr; int command; Boolean foundPOST_POST; if (main_state & (SB_NOFILE | SB_NODVIFILE)) return; FindPostAmblePtr (&postambleptr); if (NoSignExtend(dvifp, 1) != POST) { Fatal ("POST missing at head of postamble"); return; } #ifdef DEBUG if (Debug) fprintf (stderr, "got POST command\n"); #endif postamble.last_page_ptr = NoSignExtend(dvifp, 4); postamble.num = NoSignExtend(dvifp, 4); postamble.den = NoSignExtend(dvifp, 4); postamble.mag = NoSignExtend(dvifp, 4); postamble.maxheight = NoSignExtend(dvifp, 4); postamble.maxheight = NoSignExtend(dvifp, 4); postamble.maxstack = NoSignExtend(dvifp, 2); postamble.totalpages = NoSignExtend(dvifp, 2); #ifdef DEBUG if (Debug) fprintf (stderr, "now reading font defs\n"); #endif foundPOST_POST = FALSE; while (!foundPOST_POST) { switch (command = NoSignExtend(dvifp, 1)) { case FNT_DEF1: case FNT_DEF2: case FNT_DEF3: case FNT_DEF4: ReadFontDef(NoSignExtend(dvifp, command-FNT_DEF1+1)); break; case NOP: break; case POST_POST: foundPOST_POST = TRUE; #ifdef DEBUG if (Debug) fprintf (stderr, "got POST_POST command\n"); #endif break; default: Fatal ("Bad command in postamble font defs"); return; } } } /*-->SetFntNum*/ /**********************************************************************/ /**************************** SetFntNum *****************************/ /**********************************************************************/ void SetFntNum(k) int k; /* * This sets the global fontptr from the DVI font number k. * This font is then used for all subsequent characters until the next * SetFntNum */ { fontptr = hfontptr; while ((fontptr!=NULL) && (fontptr->k!=k)) fontptr = fontptr->next; if (fontptr == NULL) Fatal("font %d undefined", k); } /*-->SignExtend*/ /**********************************************************************/ /**************************** SignExtend ****************************/ /**********************************************************************/ int SignExtend(fp, n) /* return n byte quantity from file fd */ 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 */ if ((x & 0x80) != 0) /* it is negative */ x |= 0xFFFFFF00; /* fill upper bits with ones */ n1 = n--; while (n--) { x <<= 8; x |= getc(fp); } return(x); } /*-->SkipFontDef*/ /**********************************************************************/ /**************************** SkipFontDef ***************************/ /**********************************************************************/ void SkipFontDef() { short n; n = 12; /* for c, s and d params */ while (n--) getc(dvifp); n = getc(dvifp); /* a param */ n += getc(dvifp); /* l param, form a+l */ while (n--) getc(dvifp); /* throw away name */ } #ifdef DEBUG /*-->ShowPxlFd*/ /**********************************************************************/ /**************************** ShowPxlCache **************************/ /**********************************************************************/ void ShowPxlCache() { short i; fprintf(stderr, "Font file cache contents:\n"); for(i=1; i<=nopen; i++) { fprintf(stderr,"Slot %d: Name %s.%dpxl: Use count %d\n", i, (pixel_files[i].feptr)->n, (pixel_files[i].feptr)->font_mag, pixel_files[i].use_count); } } /*-->ShowPxlFd*/ /**********************************************************************/ /**************************** ShowPxlFd *****************************/ /**********************************************************************/ void ShowPxlFd() { short i; if (dvifp) fprintf(stderr,"\ndvi file %d\n\n", fileno(dvifp)); fprintf(stderr,"number of pxl files open = %d\n", nopen); for (i=1; i<=nopen; i++) if ((pixel_files[i].feptr)->cache_slot != NOTCACHED) fprintf(stderr,"pixel_files[%d]: fd %d, name %s\n", i, fileno(pixel_files[i].pixel_file_id), (pixel_files[i].feptr)->n); } #endif