/************************************************************************/ /* File: DVIPASTE.C */ /************************************************************************/ /* DEVELOPER: The TeXplorators Corporation */ /* PRODUCT: DVIPASTE */ /* Version: 1.21 */ /************************************************************************/ /* SOFTWARE LICENSE AGREEMENT 1. PURPOSE This agreement recites the terms and conditions under which The TeXplorators Corporation ("TEXPLORATORS") agrees to grant you a free, nonexclusive, transferable license to use the DVIPASTE software. 2. UNDERTAKINGS BY TEXPLORATORS 2A. Ownership: Ownership of the DVIPASTE software remains exclusively in TEXPLORATORS. 2B. License Fee: TEXPLORATORS makes the DVIPASTE software available to you free of any license fee. 2C. Disclaimers: TEXPLORATORS DISCLAIMS ALL EXPRESS OR IMPLIED WARRANTIES OF DVIPASTE'S MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE. 2D. Liability: TEXPLORATORS' LIABILITY, IF ANY, IS LIMITED TO THE DISTRIBUTION FEE YOU PAID, AND DOES NOT INCLUDE SPECIAL AND/OR CONSEQUENTIAL DAMAGES ARISING OUT OF, OR IN CONNECTION WITH, THE USE OF DVIPASTE. SINCE SOME STATES DISALLOW LIMITATION OR EXCLUSION OF LIABILITY, THIS LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU. 3. UNDERTAKINGS BY YOU. 3A. Proper Use: You agree to use the DVIPASTE software in compliance with the terms and conditions hereof. 3B. Notices on Authorized Copies: You agree to take reasonable precautions to preserve the propriety of the DVIPASTE software by duplicating verbatim, on all copies thereof, the notices of TEXPLORATORS' interests recited thereon. You agree to note that source code is available upon request, if you do not distribute source code with the DVIPASTE software. 3C. Distribution: You are encouraged to freely distribute the DVIPASTE software, including source code, on or through any common media including diskettes and electronic bulletin board systems. You agree to distribute this license with each and every copy so distributed, and to either distribute source code therewith or make source code available upon request. You may charge a distribution fee to cover the cost of diskettes, handling and shipping. 3D. Modifications: You are authorized to make modifications to DVIPASTE, but these modifications must be conspicuously noted and dated therewith. 3E. License Fee: You may not charge a license fee for the DVIPASTE software, either in its original or modified form. However, you may charge a license fee for your software which is broader in scope than DVIPASTE, whereby DVIPASTE is not a primary functional unit thereof. 4. SCOPE This Software License Agreement constitutes the entire agreement between TEXPLORATORS and you regarding the DVIPASTE software, and shall be construed under the laws of the State of TEXAS. The TeXplorators Corporation By: Michael Spivak, President */ /* Page*/ /* Comments: The following I/O routines may have to be changed for other architectures. GetByte(); GetWord(); GetTrio(); GetQuad(); PutByte(); PutWord(); PutTrio(); PutQuad(); GetSignedWord(); */ /* Configuration and defines for Unix 05/08/1991, P. A. MacKay */ /* System-dependent defines */ #include "config.h" /*------------------------------*/ /* includes */ /*------------------------------*/ #include #include #ifdef MICROSOFTC #include #endif #include /*------------------------------*/ /* defines */ /*------------------------------*/ #define STRINGSIZE (5124) /* maximum string size */ #define TRUE 1 #define FALSE 0 /*------------------------------*/ /* typedefs */ /*------------------------------*/ typedef long integer; #ifdef MICROSOFTC typedef int shalfword; typedef unsigned int halfword; #else typedef short shalfword; typedef unsigned short halfword; #endif typedef unsigned char quarterword; typedef float real; typedef char Boolean; typedef struct { quarterword cmd; integer k; integer checksum; integer scaledsize; integer designsize; quarterword a; quarterword l; char *name; } FontType; typedef struct { integer p; integer num; integer den; integer mag; integer l; integer u; halfword s; halfword t; } PostType; typedef struct { integer q; quarterword i; } PostPostType; typedef struct { integer fn; char *name; integer scaledsize; integer designsize; } DeclaredFontType; typedef struct { integer fn; integer new; char *name; } SubListType; typedef struct { int cmd; integer k; } FontNumType; /*------------------------------*/ /* function declarations */ /*------------------------------*/ #ifdef ANSI /* Use ANSI C prototypes */ void AddFontList(void); void AlignPara(FILE *); void beep(void); void BeginSpecial(integer); void bop(void); void DefFont(int); void DoSpecial(int); int EndSpecial(integer, int); void error(char *,char *); void FindPage(void); void FntNum(int); void FontDef(int); shalfword GetByte(FILE *); integer GetQuad(FILE *); shalfword GetSignedByte(FILE *); shalfword GetSignedWord(FILE *); integer GetTrio(FILE *); integer GetUniqueNumber(void); halfword GetWord(FILE *); void Initialize(void); int main(int argc, char *argv[]); void PopsAndPushes(int); void PutByte(int, FILE *); void PutQuad(integer, FILE *); void PutTrio(long,FILE *); void PutWord(int, FILE *); void PutFntNum( integer fn ); void ReadPostamble(void); void ReadPreamble(void); void ReadSubFile(void); void SkipOver(integer,FILE *); void SubDefFont(int); void SubFontDef(int); void SubPreamble(void); void SubPostamble(void); void TransferTable(void); void WritePostamble(void); void xxxFontDef(int); #else /* Use old-style K&R functions */ void AddFontList(); void AlignPara(); void beep(); void BeginSpecial(); void bop(); void DefFont(); void DoSpecial(); int EndSpecial(); void error(); void FindPage(); void FntNum(); void FontDef(); shalfword GetByte(); integer GetQuad(); shalfword GetSignedByte(); shalfword GetSignedWord(); integer GetTrio(); integer GetUniqueNumber(); halfword GetWord(); void Initialize(); int main(); void PopsAndPushes(); void PutByte(); void PutQuad(); void PutTrio(); void PutWord(); void PutFntNum(); void ReadPostamble(); void ReadPreamble(); void ReadSubFile(); void SkipOver(); void SubDefFont(); void SubFontDef(); void SubPreamble(); void SubPostamble(); void TransferTable(); void WritePostamble(); void xxxFontDef(); /* An ANSI string function, not guaranteed elsewhere */ char *strstr(); #endif /*------------------------------*/ /* data structures */ /*------------------------------*/ FontType *main_fontlist[256]; /* Main font list pointers */ FontType *sub_fontlist[256]; /* Sub font list pointers */ /* list of dynamically declared fonts */ DeclaredFontType declared_fonts[256]; SubListType sublist[100]; /* substitution list */ PostType post; /* postamble */ PostPostType post_post; /* post postamble */ FontNumType fnt; /* current font */ char newname[13]; /* new dvi file name */ char dviname[13]; /* dvi file name */ char subname[13]; /* sub file name */ char strings[STRINGSIZE]; /* strings buffer */ char *nextstr, *maxstr; /* string pointers */ FILE *dvifile; /* dvi file handle */ FILE *newfile; /* new file handle */ FILE *subfile; /* sub file handle */ int mfonts; /* number of fonts in main_fontlist */ int sfonts; /* number of fonts in sub_fontlist */ int dfonts; /* number of fonts in declared fonts */ integer pagenum; /* page number */ int pushes; /* current number of pushes */ int pops; /* current number of pops */ int max_stack_depth; /* max pushes over pops */ long prevbop; /* previous bop */ integer subpost_p; /* sub file postamble pointer */ int push; /* number of pushes */ int ColumnPos; /* column position */ /*------------------------------*/ /* functions */ /*------------------------------*/ /* align binary file on a 16-byte boundary */ void AlignPara(f) FILE *f; { long fpos, pad, i; fpos = ftell(f); pad = fpos%16L; if (pad!=0L) pad=16L-pad; /* put out trailer bytes */ for (i=0; i=0; i--) #else for (i=0; i<3; i++) #endif PutByte( *(p+i), f); return; } void PutQuad(quad,f) long quad; FILE *f; { int i; char *p; p = (char *)&quad; #ifdef LITTLENDIAN for (i=3; i>=0; i--) #else for (i=0; i<4; i++) #endif PutByte( *(p+i), f ); return; } void PopsAndPushes(cmd) int cmd; { int diff; switch (cmd) { case 141: pushes++; break; case 142: pops++; break; } diff = pushes - pops; if ( diff > max_stack_depth ) max_stack_depth = diff; return; } void ReadPreamble() { integer num, den, mag; int i; quarterword k; shalfword id, pre, byte; pre = GetByte(dvifile); PutByte(pre,newfile); id = GetByte(dvifile); PutByte(id,newfile); num = GetQuad(dvifile); PutQuad(num,newfile); den = GetQuad(dvifile); PutQuad(den,newfile); mag = GetQuad(dvifile); PutQuad(mag,newfile); k = (quarterword) GetByte(dvifile); PutByte(k,newfile); /* skip over TeX comment */ for (i=0; ik; if ( k < 64L ) fnt.cmd = (quarterword) (k+171L) ; else if ( k < 256L ) { fnt.cmd = 235; fnt.k = k; } else if ( k < 65536L ) { fnt.cmd = 236; fnt.k = k; } else if ( k < 16777216L ) { fnt.cmd = 237; fnt.k = k; } else { fnt.cmd = 238; fnt.k = k; } } else fnt.cmd = 171; return; } void WritePostamble() { int i,j,n; Boolean found; FontType *fp; char *p; /* set max stack depth */ post.s = max_stack_depth; PutQuad(post.p,newfile); PutQuad(post.num,newfile); PutQuad(post.den,newfile); PutQuad(post.mag,newfile); PutQuad(post.l,newfile); PutQuad(post.u,newfile); PutWord(post.s,newfile); PutWord(post.t,newfile); /* send out font defs that are actually used in the combined file */ /* - use declared_fonts list since this is the correct list. */ for (i=0; ik ) { found = TRUE; fp = main_fontlist[j]; } } if ( fp!=NULL ) { PutByte(fp->cmd,newfile); switch (fp->cmd) { case 243: PutByte((quarterword)fp->k,newfile); break; case 244: PutWord((halfword)fp->k,newfile); break; case 245: PutTrio(fp->k,newfile); break; case 246: PutQuad(fp->k,newfile); break; } PutQuad(fp->checksum,newfile); PutQuad(fp->scaledsize,newfile); PutQuad(fp->designsize,newfile); PutByte(fp->a,newfile); PutByte(fp->l,newfile); p = fp->name; /* directory */ for (n=0; na; n++) PutByte(*p++, newfile); p++; /* font name */ for (n=0; nl; n++) PutByte(*p++,newfile); } } /* now the post_post command */ PutByte(249, newfile); PutQuad(post_post.q,newfile); PutByte(2,newfile); /* put out enough trailer bytes */ for (i=0; i<4; i++) PutByte(223,newfile); AlignPara(newfile); return; } void Initialize() { int i; for (i=0; i<256; i++) main_fontlist[i] = NULL; nextstr = strings; maxstr = strings + STRINGSIZE - 1; mfonts = 0; sfonts = 0; dfonts = 0; subname[0]= 0; subfile = NULL; pops = pushes = max_stack_depth = 0; prevbop = -1L; ColumnPos = 0; return; } void FontDef(cmd) int cmd; { int i,f; integer fn; FontType *fp; quarterword found; switch (cmd) { case 243: /* fnt_def1 */ fn = GetByte(dvifile); break; case 244: /* fnt_def2 */ fn = GetWord(dvifile); break; case 245: /* fnt_def3 */ fn = GetTrio(dvifile); break; case 246: /* fnt_def4 */ fn = GetQuad(dvifile); break; } /* walk thru main_fontlist */ found = FALSE; for (f=0; fk == fn ) found=TRUE; } if ( !found ) { fp = (FontType *)malloc(sizeof(FontType)); if (fp==NULL) error("! ran out of memory",dviname); main_fontlist[mfonts++] = fp; fp->cmd = (quarterword) cmd; fp->k = fn; fp->checksum = GetQuad(dvifile); fp->scaledsize = GetQuad(dvifile); fp->designsize = GetQuad(dvifile); fp->a = (quarterword) GetByte(dvifile); fp->l = (quarterword) GetByte(dvifile); /* check strings space */ if ( ( nextstr + fp->a + fp->l ) > maxstr ) error("! out of string space",dviname); fp->name = nextstr ; for (i=0; ia; i++) *nextstr++ = (char) GetByte(dvifile); *nextstr++ = 0; for (i=0; il; i++) *nextstr++ = (char) GetByte(dvifile); *nextstr++ = 0; } /* font already defined, skip over it */ else { SkipOver(12L,dvifile); /* c[4]...n[a+l] */ i = GetByte(dvifile) + GetByte(dvifile); SkipOver((long)i,dvifile); } return; } void DefFont(cmd) int cmd; { quarterword byte, byte1; int i; integer fn; quarterword found; char name[13]; integer checksum, scaledsize, designsize; switch (cmd) { case 243: /* fnt_def1 */ fn = GetByte(dvifile); PutByte((quarterword)fn,newfile); break; case 244: /* fnt_def2 */ fn = GetWord(dvifile); PutByte((halfword)fn,newfile); break; case 245: /* fnt_def3 */ fn = GetTrio(dvifile); PutTrio(fn,newfile); break; case 246: /* fnt_def4 */ fn = GetQuad(dvifile); PutQuad(fn,newfile); break; } checksum = GetQuad(dvifile); scaledsize = GetQuad(dvifile); designsize = GetQuad(dvifile); PutQuad(checksum, newfile); PutQuad(scaledsize, newfile); PutQuad(designsize, newfile); byte = (quarterword) GetByte(dvifile); byte1 = (quarterword) GetByte(dvifile); PutByte(byte,newfile); PutByte(byte1, newfile); i = byte; for (i=0; ik == fn ) found=TRUE; } if ( !found ) { fp = (FontType *)malloc(sizeof(FontType)) ; if (fp==NULL) error("! sorry, out of memory",subname); sub_fontlist[sfonts++] = fp; fp->cmd = (quarterword) cmd; fp->k = fn; fp->checksum = GetQuad(subfile); fp->scaledsize = GetQuad(subfile); fp->designsize = GetQuad(subfile); fp->a = (quarterword) GetByte(subfile); fp->l = (quarterword) GetByte(subfile); /* check strings space */ if ( ( nextstr + fp->a + fp->l ) > maxstr ) error("! out of string space",subname); fp->name = nextstr; for (i=0; ia; i++) *nextstr++ = (char) GetByte(subfile); *nextstr++ = 0; for (i=0; il; i++) *nextstr++ = (char) GetByte(subfile) ; *nextstr++ = 0 ; } /* font already defined */ else { SkipOver(12L,subfile); /* c[4]...n[a+l] */ i = GetByte(subfile) + GetByte(subfile); SkipOver((long)i,subfile); } return; } void SubDefFont(cmd) int cmd; { quarterword byte, byte1; int i; integer fn; char name[13]; switch (cmd) { case 243: /* fnt_def1 */ fn = GetByte(subfile); break; case 244: /* fnt_def2 */ fn = GetWord(subfile); break; case 245: /* fnt_def3 */ fn = GetTrio(subfile); break; case 246: /* fnt_def4 */ fn = GetQuad(subfile); break; } for (i=0; i<12; i++) GetByte(subfile); byte = (quarterword) GetByte(subfile); byte1 = (quarterword) GetByte(subfile); i = byte; for (i=0; i= 0 && fn < 64 ) PutByte((quarterword)(171L+fn),newfile); else { if ( fn >= 64L && fn < 256L ) { PutByte(235,newfile); PutByte((quarterword)fn,newfile); } else { if ( fn >= 0 && fn < 65536L ) { PutByte(236,newfile); PutWord((halfword)fn,newfile); } else { /* combine 237 and 238 */ PutByte(238,newfile); PutQuad(fn,newfile); } } } return; } void FntNum(cmd) int cmd; { integer fn; Boolean found; char name[13]; char *p; FontType *fp; int i; integer scaledsize, designsize; switch(cmd) { case 235: /* fnt1 */ fn=GetByte(subfile); break; case 236: /* fnt2 */ fn=GetWord(subfile); break; case 237: /* fnt3 */ fn=GetTrio(subfile); break; case 238: /* fnt4 */ fn=GetQuad(subfile); break; default: fn = (long)cmd - 171L; break; } found = FALSE; for (i=0; ik ) { found = TRUE ; p = sub_fontlist[i]->name + sub_fontlist[i]->a + 1; strcpy(name,p); scaledsize = sub_fontlist[i]->scaledsize; designsize = sub_fontlist[i]->designsize; } } if ( !found ) error(" ! cannot find font name",subname); /* walk thru list of declared fonts */ found = FALSE; for (i=0; ik ) { found = TRUE; fp = main_fontlist[i]; } } if ( !found ) error(" ! fnt number not in main list",subname); /* now, we send out a fnt_def */ PutByte((quarterword)fp->cmd,newfile); switch (fp->cmd) { case 243: PutByte((quarterword)fp->k,newfile); break; case 244: PutWord((halfword)fp->k,newfile); break; case 245: PutTrio(fp->k,newfile); break; case 246: PutQuad(fp->k,newfile); break; } PutQuad(fp->checksum,newfile); PutQuad(fp->scaledsize,newfile); PutQuad(fp->designsize,newfile); PutByte(fp->a,newfile); PutByte(fp->l,newfile); for (i=0; ia; i++) PutByte(*(fp->name+i),newfile); for (i=0; il; i++) PutByte(*(fp->name+fp->a+1+i),newfile); /* now we have to send out the fnt_num cmd */ PutFntNum(fn); /* add font to declared_fonts list */ declared_fonts[dfonts].name = nextstr; for (i=0; il; i++) *nextstr++ = name[i]; *nextstr++ = 0; declared_fonts[dfonts].fn = fn; declared_fonts[dfonts].scaledsize = fp->scaledsize; declared_fonts[dfonts].designsize = fp->designsize; dfonts++; } return; } void DoSpecial(cmd) int cmd; { integer i; char str[90]; char opcode[80]; char name[80]; integer numbytes; integer offset; switch (cmd) { case 239: /* xxx1 */ numbytes=GetByte(dvifile); break; case 240: /* xxx2 */ numbytes=GetWord(dvifile); break; case 241: /* xxx3 */ numbytes=GetTrio(dvifile); break; case 242: /* xxx4 */ numbytes=GetQuad(dvifile); break; } offset = ftell(dvifile); for (i=0; i n} commands */ if (strnicmp(opcode,"dvipaste:",9)==0) { fseek(dvifile,offset,SEEK_SET); SkipOver( numbytes, dvifile ); /* read in new subfile if different */ if (stricmp(name,subname)!=0) { strcpy(subname,name); ReadSubFile(); } /* now we transfer table n from subfile */ TransferTable(); /* we must set previous fnt num before returning to dvifile */ switch( fnt.cmd ) { case 235: PutByte(fnt.cmd,newfile); PutByte((quarterword)fnt.k,newfile); break; case 236: PutByte(fnt.cmd,newfile); PutWord((halfword)fnt.k,newfile); break; case 237: PutByte(fnt.cmd,newfile); PutTrio(fnt.k,newfile); break; case 238: PutByte(fnt.cmd,newfile); PutQuad(fnt.k,newfile); break; default: PutByte(fnt.cmd,newfile); break; } } else { /* pass the special thru. not the ones we care about */ PutByte(cmd,newfile); switch (cmd) { case 239: /* xxx1 */ PutByte((quarterword)numbytes,newfile); break; case 240: /* xxx2 */ PutWord((halfword)numbytes,newfile); break; case 241: /* xxx3 */ PutTrio(numbytes,newfile); break; case 242: /* xxx4 */ PutQuad(numbytes,newfile); break; } fseek(dvifile,offset,SEEK_SET); for (i=0; i0; push--) { PutByte(142,newfile); PopsAndPushes(142); } return( TRUE ); } /* send out embedded special */ PutByte(cmd,newfile); switch( cmd ) { case 239: /* xxx1 */ PutByte((quarterword)numbytes,newfile); break; case 240: /* xxx2 */ PutWord((halfword)numbytes,newfile); break; case 241: /* xxx3 */ PutTrio(numbytes,newfile); break; case 242: /* xxx4 */ PutQuad(numbytes,newfile); break; } fseek(subfile,offset,SEEK_SET); for (i=0; i=171 && cmd<=234) { FntNum(cmd); break; } PutByte((quarterword)cmd, newfile); break; } switch( cmd ) { /* eight bytes */ case 132: /* set_rule */ case 137: /* put_rule */ PutQuad(GetQuad(subfile),newfile); /* four bytes */ case 131: /* set4 */ case 136: /* put4 */ case 146: /* right4 */ case 151: /* w4 */ case 156: /* x4 */ case 160: /* down4 */ case 165: /* y4 */ case 170: /* z4 */ PutByte(GetByte(subfile),newfile); /* three bytes */ case 130: /* set3 */ case 135: /* put3 */ case 145: /* right3 */ case 150: /* w3 */ case 155: /* x3 */ case 159: /* down3 */ case 164: /* y3 */ case 169: /* z3 */ PutByte(GetByte(subfile),newfile); /* two bytes */ case 129: /* set2 */ case 134: /* put2 */ case 144: /* right2 */ case 149: /* w2 */ case 154: /* x2 */ case 158: /* down2 */ case 163: /* y2 */ case 168: /* z2 */ PutByte(GetByte(subfile),newfile); /* one byte */ case 128: /* set1 */ case 133: /* put1 */ case 143: /* right1 */ case 148: /* w1 */ case 153: /* x1 */ case 157: /* down1 */ case 162: /* y1 */ case 167: /* z1 */ PutByte(GetByte(subfile),newfile); break; break; case 138: /* nop */ case 141: /* push */ case 142: /* pop */ case 147: /* w0 */ case 152: /* x0 */ case 161: /* y0 */ case 166: /* z0 */ break; case 239: /* xxx1 */ ii=GetByte(subfile); if ( EndSpecial(ii, cmd) ) done=TRUE; break; case 240: /* xxx2 */ ii=GetWord(subfile); if ( EndSpecial(ii, cmd) ) done=TRUE; break; case 241: /* xxx3 */ ii=GetTrio(subfile); if ( EndSpecial(ii,cmd) ) done=TRUE; break; case 242: /* xxx4 */ ii=GetQuad(subfile); if ( EndSpecial(ii,cmd) ) done=TRUE; break; /* fnt_def1...fnt_def4 */ case 243: case 244: case 245: case 246: xxxFontDef(cmd); break; case 248: /* post */ done=TRUE; break; } } /* while !done */ } /* skip over special */ else { fseek(subfile,offset,SEEK_SET); SkipOver( numbytes, subfile ); } return; } void FindPage() { int cmd; integer count,offset; Boolean found; /* position to the final bop */ fseek(subfile,subpost_p,SEEK_SET); cmd = GetByte(subfile); if ( cmd!=139 ) error(" ! cannot locate final page ",subname); count = GetQuad(subfile); if ( count == pagenum ) found = TRUE; else { offset = 0L; found=FALSE; } while ( !found && offset !=-1L ) { SkipOver(36L,subfile); offset = GetQuad(subfile); if ( offset != -1L ) { fseek(subfile,offset,SEEK_SET); cmd = GetByte(subfile); count = GetQuad(subfile); if ( count == pagenum ) found = TRUE; } } if ( !found ) { printf("\n ! cannot find page %ld in %s",pagenum,subname); exit(1); } SkipOver(40L,subfile); return; } void TransferTable() { Boolean done; integer ii; int cmd; FindPage(); done=FALSE; while ( !done ) { cmd=GetByte(subfile); /* set_char_0 thru set_char_127 */ /* cmd>=0 && cmd<=127 */ /* fnt_num_0 thru fnt_num_63 */ /* cmd>=171 && cmd<=234 ) */ if (cmd>=171 && cmd<=234) FntNum(cmd); switch (cmd) { /* eight bytes */ case 132: /* set_rule */ case 137: /* put_rule */ GetQuad(subfile); /* four bytes */ case 131: /* set4 */ case 136: /* put4 */ case 146: /* right4 */ case 151: /* w4 */ case 156: /* x4 */ case 160: /* down4 */ case 165: /* y4 */ case 170: /* z4 */ GetByte(subfile); /* three bytes */ case 130: /* set3 */ case 135: /* put3 */ case 145: /* right3 */ case 150: /* w3 */ case 155: /* x3 */ case 159: /* down3 */ case 164: /* y3 */ case 169: /* z3 */ GetByte(subfile); /* two bytes */ case 129: /* set2 */ case 134: /* put2 */ case 144: /* right2 */ case 149: /* w2 */ case 154: /* x2 */ case 158: /* down2 */ case 163: /* y2 */ case 168: /* z2 */ GetByte(subfile); /* one byte */ case 128: /* set1 */ case 133: /* put1 */ case 143: /* right1 */ case 148: /* w1 */ case 153: /* x1 */ case 157: /* down1 */ case 162: /* y1 */ case 167: /* z1 */ GetByte(subfile); break; break; case 139: /* bop */ /* filter thru c0[4]...c9[4] and p[4] */ SkipOver(44L,subfile); break; case 138: /* nop */ case 140: /* eop */ case 141: /* push */ case 142: /* pop */ case 147: /* w0 */ case 152: /* x0 */ case 161: /* y0 */ case 166: /* z0 */ break; case 235: /* fnt1 */ case 236: /* fnt2 */ case 237: /* fnt3 */ case 238: /* fnt4 */ FntNum(cmd); break; case 239: /* xxx1 */ ii=GetByte(subfile); BeginSpecial(ii); done = TRUE; break; case 240: /* xxx2 */ ii=GetWord(subfile); BeginSpecial(ii); done = TRUE; break; case 241: /* xxx3 */ ii=GetTrio(subfile); BeginSpecial(ii); done=TRUE; break; case 242: /* xxx4 */ ii=GetQuad(subfile); BeginSpecial(ii); done=TRUE; break; /* fnt_def1...fnt_def4 */ case 246: case 245: case 244: case 243: SubDefFont(cmd); break; case 248: /* post */ done=TRUE; break; } } return; } integer GetUniqueNumber() { integer fn; int i,j; Boolean found, assigned; fn = 0L; found = FALSE; for (i=0; ik) { fn++; assigned=TRUE; } } if ( !assigned ) found = TRUE; } return(fn); } void AddFontList() { Boolean found; int i,j; FontType *f1, *f2, *fp; char *p, *q; integer fn; for (i=0; iname + f1->a + 1; found = FALSE; for (j=0; jname + f2->a + 1; if ( (stricmp(p,q)==0) &&(f1->scaledsize==f2->scaledsize) &&(f1->designsize==f2->designsize) ) { found = TRUE; fn = f2->k; fp = f2; } } if ( !found ) { fp = (FontType *)malloc(sizeof(FontType)); if (fp==NULL) error("! ran out of memory",""); main_fontlist[mfonts++] = fp; fp->cmd = f1->cmd; fp->checksum = f1->checksum; fp->scaledsize = f1->scaledsize; fp->designsize = f1->designsize; fp->a = f1->a; fp->l = f1->l; fp->name = f1->name; fn = GetUniqueNumber(); fp->k = fn; } /* add to sub list */ sublist[i].fn = f1->k; sublist[i].new = fn; sublist[i].name = fp->name + fp->a + 1; } return; } void SubPostamble() { integer offset; int cmd; Boolean done; fseek(subfile,0L,SEEK_END); /* skip backwards over 223's until the id byte. */ fseek(subfile,-1L,SEEK_CUR); cmd = GetByte(subfile); while (cmd==223) { fseek(subfile,-2L,SEEK_CUR); if ( ftell(subfile)==0L ) error("\n ! error in reading postamble",subname); cmd = GetByte(subfile); } /* back up and read q */ fseek(subfile,-5L,SEEK_CUR); offset=GetQuad(subfile); fseek(subfile,offset,SEEK_SET); cmd = GetByte(subfile); /* this must be the post cmd */ if (cmd!=248) error("\n ! error in reading postamble",subname); /* skip over post parameters */ subpost_p = GetQuad(subfile); SkipOver(24L,subfile); /* font defs */ done = FALSE; while ( !done ) { cmd = GetByte(subfile); switch (cmd) { case 243: /* fnt_def1 */ case 244: /* fnt_def2 */ case 245: /* fnt_def3 */ case 246: /* fnt_def4 */ SubFontDef(cmd); break; default: done=TRUE; break; } } return; } void SubPreamble() { integer num, den, mag; quarterword pre, id, k; pre = (quarterword) GetByte(subfile); id = (quarterword) GetByte(subfile); num = GetQuad(subfile); den = GetQuad(subfile); mag = GetQuad(subfile); k = (quarterword) GetByte(subfile); /* skip over TeX comment */ SkipOver((long)k,subfile); return; } void ReadSubFile() { int i; if ( subfile!= NULL ) fclose(subfile); subfile = fopen(subname, READ_BINARY); if (subfile==NULL) error("\n ! couldn't open file",subname); for (i=0; i0 && !done; i--) { if ( pageno[i]!=0 ) { j = i; done = TRUE ; } } done = FALSE; string[0] = 0; sprintf(string,"[%ld",pageno[0]); for (i=1; i<=j; i++) { sprintf(tmp,".%ld",pageno[i]); strcat(string,tmp); } strcat(string,"]"); i = strlen( string ); if ( ( ColumnPos + i ) > 80 ) { printf("\r\n"); ColumnPos = 0; } printf("%s",string); ColumnPos += i; /* p[4] */ GetQuad(dvifile); PutQuad(prevbop,newfile); prevbop = post.p ; return; } /* 08/06/1991 PAM Give main a predictable return value for the OS */ int main(argc, argv) int argc; char *argv[]; { int cmd,i; Boolean done; if ( argc<2 ) { printf("\n\t\tUsage: dvipaste dvifile [newfile]"); printf("\n\t\tNote: newfile is optional\n"); exit(0); } printf("\nThis is DVIPASTE, Version 1.21"); printf("\nCopyright (c) 1989-91, The TeXplorators Corporation."); printf("\nAll rights reserved.\n"); strcpy(dviname,argv[1]); if (strstr(dviname,".")==NULL) strcat(dviname,".dvi"); if ( argc<=2 ) { strcpy(newname,dviname); i = strlen(newname); newname[i-1] = 'x'; } else { strcpy(newname,argv[2]); if (strstr(newname,".")==NULL) strcat(newname,".dvi"); } dvifile = fopen(dviname, READ_BINARY ) ; if (dvifile==NULL) error("! couldn't open file",dviname); newfile = fopen(newname, WRITE_BINARY); if (newfile==NULL) error("! couldn't open file",newname); Initialize(); ReadPostamble(); fseek(dvifile,0L,SEEK_SET); ReadPreamble(); done=FALSE; while ( !done ) { cmd=GetByte(dvifile); /* let's take a peek first at the current cmd before running thru it. */ switch (cmd) { /* this are specials; handle with care. */ case 239: case 240: case 241: case 242: /* don't send out cmd yet */ break; default: PutByte(cmd,newfile); break; } /* set_char_0 thru set_char_127 */ /* cmd>=0 && cmd<=127 */ /* fnt_num_0 thru fnt_num_63 */ if ( cmd>=171 && cmd<=234 ) fnt.cmd = cmd; switch (cmd) { /* eight bytes */ case 132: /* set_rule */ case 137: /* put_rule */ PutQuad(GetQuad(dvifile),newfile); /* four bytes */ case 131: /* set4 */ case 136: /* put4 */ case 146: /* right4 */ case 151: /* w4 */ case 156: /* x4 */ case 160: /* down4 */ case 165: /* y4 */ case 170: /* z4 */ PutByte(GetByte(dvifile),newfile); /* three bytes */ case 130: /* set3 */ case 135: /* put3 */ case 145: /* right3 */ case 150: /* w3 */ case 155: /* x3 */ case 159: /* down3 */ case 164: /* y3 */ case 169: /* z3 */ PutByte(GetByte(dvifile),newfile); /* two bytes */ case 129: /* set2 */ case 134: /* put2 */ case 144: /* right2 */ case 149: /* w2 */ case 154: /* x2 */ case 158: /* down2 */ case 163: /* y2 */ case 168: /* z2 */ PutByte(GetByte(dvifile),newfile); /* one byte */ case 128: /* set1 */ case 133: /* put1 */ case 143: /* right1 */ case 148: /* w1 */ case 153: /* x1 */ case 157: /* down1 */ case 162: /* y1 */ case 167: /* z1 */ PutByte(GetByte(dvifile),newfile); break; case 139: /* bop */ bop(); break; case 141: /* push */ case 142: /* pop */ PopsAndPushes(cmd); break; case 138: /* nop */ case 140: /* eop */ case 147: /* w0 */ case 152: /* x0 */ case 161: /* y0 */ case 166: /* z0 */ break; case 235: /* fnt1 */ fnt.cmd = cmd; fnt.k = GetByte(dvifile); PutByte((quarterword)fnt.k,newfile); break; case 236: /* fnt2 */ fnt.cmd = cmd; fnt.k = GetWord(dvifile); PutWord((halfword)fnt.k,newfile); break; case 237: /* fnt3 */ fnt.cmd = cmd; fnt.k = GetTrio(dvifile); PutTrio(fnt.k,newfile); break; case 238: /* fnt4 */ fnt.cmd = cmd; fnt.k = GetQuad(dvifile); PutQuad(fnt.k,newfile); break; case 239: /* xxx1 */ case 240: /* xxx2 */ case 241: /* xxx3 */ case 242: /* xxx4 */ DoSpecial(cmd); break; /* fnt_def1...fnt_def4 */ case 243: case 244: case 245: case 246: DefFont(cmd); break; case 248: /* post */ post_post.q = ftell(newfile) -1L; done=TRUE; break; } } WritePostamble(); fclose(dvifile); fclose(newfile); if ( subfile != NULL ) fclose(subfile); if ( argc<=2 ) { unlink(dviname); rename(newname,dviname); } printf("\n"); return(0); } /* Add strstr() to the strings functions. Some versions of SUN cc complain about macros in loops, but gcc has no trouble with them. Depends on how the macro is written, I suppose, but I think gcc uses the same macro text as cc in this case. */ #ifndef ANSI char * strstr(s,t) char *s,*t; { char *ss; ss = s; while ( *ss != '\0' ) { if ((strcmp(ss,t)) == 0) return ss; ss++; } return(NULL); } #endif