#include long ftell(); /* Convert .v file to .press format */ #define XFUDGE 1587 /* fudges to make margins come out right */ #define YFUDGE 0 #define VVERSION 1 /* version of .v files */ #define FONTS 14 /* max number of fonts to use */ /* fonts 14 and 15 are used for special chars */ #define MATH 14 /* math10 font */ #define GREEK 15 /* greek font -- hippo10 */ #define NAMSIZ 40 /* characters/filename */ #define LINE 26 /* line width for horizontal and vertical lines */ #define HLINE 13 #define DLINE 18 /* line width for diagonals. makes intensity the same! */ #define HDLINE 9 #define MAXEL 32000 /* maximum length of EL */ #define SHOWCHAR 0360 /* various press file commands */ #define SHOWCHARSHORT 0 #define SETX 0356 #define SETY 0357 #define FONT 0160 #define SHOWRECT 0376 #define NOP 0377 char *elname = "/tmp/elaXXXXX"; /* temporary file for entity list */ char *fdname = "/tmp/fdaXXXXX"; /* temporary file for font directory */ char *pdname = "/tmp/pdaXXXXX"; /* temporary file for part directory */ char Widths[FONTS][128]; /* char widths for each font */ char Kerns[FONTS][128]; /* kerning for each character */ char BaseLine[FONTS]; /* how far to base line for each font */ char LigFlag[FONTS]; /* flag controlling character translation */ char *Names[FONTS]; /* names of defined fonts */ char Index[FONTS]; /* mapping from input font number to press font number */ struct InVec { int x1, y1; /* format of vectors in input stream */ int idx,idy; /* where dx>0 ! */ } CurIn; struct InChr { int x1, y1; int idx; char Font, Ascii; } *CurChr = &CurIn; struct { /* font directory entry */ int entrylength; char fontset,font,first,last,fam[20],face,source; int size,rotation; } fontdir = { 16, 0, 0, 0, 127, { 0 }, 0, 0, 0, 0 }; struct { /* EL trailer */ char etype,efontset; long beginbyte,bytelength; int xe,ye,eleft,ebottom,ewidth,eheight,elength; } entity = { 0, 0, 0L, 0L, 0, 0, 0, 0, 16 }; struct { /* part directory entry */ int ptype,brecord,lrecord,padding; } partdir; int NFonts = 0; /* number of fonts loaded */ int CurX = 0, CurY = 0; /* The current positions. */ int CurFont = -1; /* Current font number... */ int From = -1, To = -1; /* starting/ending pages */ int Copies = 1; /* number of copies to be made */ int CurPage = 0; /* current input page number */ int ShowCnt = 0; /* number of undisplayed chars in DL */ int ellength = 0; /* length of current EL */ long dlbegin = 0L; /* first data byte for current EL */ int firstrec = 0; /* first record number of current entity */ int nparts = 0; /* total number of parts */ char Dbg = 0; /* <>0 for debugging printout */ char FFFlag = 0; FILE *infile,*outfile,*elfile,*elread,*fdfile,*pdfile; char InName[NAMSIZ]; /* input file name */ char *OutName = ""; /* output file name */ main(argc, argv) char **argv; { char *ArgPtr, *Temp; FILE *argfile; *InName = 0; while (--argc) { ArgPtr = *++argv; if (*ArgPtr == '-') switch (*++ArgPtr) { case 'd': Dbg++; break; case 'f': From = atoi(*++argv); argc--; break; case 't': To = atoi(*++argv); argc--; break; case 'c': Copies = atoi(*++argv); argc--; break; case 'o': OutName = *++argv; argc--; break; default: fprintf(stderr,"press: unrecognized option %s\n",ArgPtr); exit(-1); } else { for (Temp=InName; *Temp++ = *ArgPtr++;); --Temp; for (ArgPtr = ".v"; *Temp++ = *ArgPtr++;); } } if (*InName) { if ((argfile = fopen(InName,"r")) == NULL) { fprintf(stderr,"press: can't read %s\n",InName); exit(-1); } } else argfile = stdin; if (*OutName==0 && *InName) { Temp -= 2; for (ArgPtr = "press"; *Temp++ = *ArgPtr++;); OutName = InName; } if (*OutName) { if ((outfile = fopen(OutName,"w")) == NULL) { fprintf(stderr,"press: can't open output file %s\n",OutName); exit(-1); } } else outfile = stdout; mktemp(elname); /* open temp files */ elfile = fopen(elname,"w"); elread = fopen(elname,"r"); mktemp(fdname); fdfile = fopen(fdname,"w"); mktemp(pdname); pdfile = fopen(pdname,"w"); if (elfile==NULL || fdfile==NULL || pdfile==NULL) { fprintf(stderr,"press: can't open temporary file\n"); Exit(-1); } /* output directory entry for MATH10 */ fontdir.entrylength = swab(16); fontdir.face = 0; fontdir.fam[0] = 4; strcpy(&fontdir.fam[1],"MATH"); fontdir.font = MATH; fontdir.size = swab(10); fontdir.rotation = swab(0); fwrite(&fontdir,sizeof(fontdir),1,fdfile); /* output directory entry for HIPPO10 */ fontdir.fam[0] = 5; strcpy(&fontdir.fam[1],"HIPPO"); fontdir.font = GREEK; fwrite(&fontdir,sizeof(fontdir),1,fdfile); readfile(argfile,0,0); /* process input file */ Finish(); /* finish off press file */ Exit(0); } Exit(n) { fclose(elfile); /* do away with temp files */ fclose(elread); fclose(fdfile); fclose(pdfile); unlink(elname); unlink(fdname); unlink(pdname); exit(n); } readfile(argfile,dx,dy) FILE *argfile; register int dx,dy; { FILE *savefile = infile; /* save old input file */ int saveindex[FONTS]; /* save old font mapping */ register int i; CurFont = -1; for (i=0; i>8)&0377)); } /* handle font defn in .v file -- sets up internal data base and outputs * font directory information. */ ReadFont() { char temp[NAMSIZ],*fname,bitmap[16]; register char *p,*q; register int i; int cnt,bline,lflag; FILE *ffile; /* get font name from .v file */ for (p=temp, cnt=0; (i=getc(infile)) != '\n'; cnt++) *p++ = i; *p = '\0'; /* skip over bit map for now */ fread(bitmap,16,1,infile); /* if we've already seen this font, just change mapping and return */ for (i=0; iFont] = i; return; } /* new font, remember name and set up mapping */ Names[NFonts] = fname = calloc(cnt+1,1); for (q=temp; *fname++ = *q++;); Index[CurChr->Font] = NFonts; BaseLine[NFonts] = LigFlag[NFonts] = 0; /* read in char widths for use by Put */ *(p-3) = 't'; *(p-2) = 'f'; if ((ffile = fopen(temp,"r")) == NULL) { fprintf(stderr,"press: can't open font file %s\n",temp); return; } else { fread(Widths[NFonts],128,1,ffile); fread(Kerns[NFonts],128,1,ffile); fclose(ffile); } /* read info from .pinfo file and stick in font directory entry */ for (p=p-3, q="pinfo"; *p++ = *q++;); if ((ffile = fopen(temp,"r")) == NULL) { fprintf(stderr,"press: can't open pinfo file %s\n",temp); Index[CurChr->Font] = -1; } else { fscanf(ffile,"%s%d%d%d%d%d", &fontdir.fam[1],&cnt,&fontdir.size,&fontdir.rotation,&bline,&lflag); BaseLine[NFonts] = bline; LigFlag[NFonts] = lflag; if (lflag!=2) { /* only if not special character font */ fontdir.entrylength = swab(16); fontdir.face = cnt; fontdir.fam[0] = strlen(&fontdir.fam[1]); fontdir.font = NFonts; fontdir.size = swab(fontdir.size); fontdir.rotation = swab(fontdir.rotation); fwrite(&fontdir,sizeof(fontdir),1,fdfile); } if (Dbg) fprintf(stderr,"Font %s, #=%d, fam=%s, face=%d, size=%d, rot=%d\n", Names[NFonts],fontdir.font,&fontdir.fam[1],fontdir.face, fontdir.size,fontdir.rotation); fclose(ffile); } NFonts++; } NewPage() { char buffer[512]; union { long dlend; struct { int hend,lend; } dwend; } end; long dllast; int bcount; long i,j; /* if nothing on page, then nothing much to do */ if (ShowCnt==0 && ellength==0) return; /* first output commands for any leftover characters */ if (ShowCnt <= 32) { putc(SHOWCHARSHORT+ShowCnt-1,elfile); ellength++; } else { putc(SHOWCHAR,elfile); putc(ShowCnt,elfile); ellength += 2; } ShowCnt = 0; /* word align outfile and put in 0 word divider */ if ((ftell(outfile) & 1L) != 0) putc(0,outfile); dllast = ftell(outfile) - 512L * firstrec; putw(0,outfile); /* word align EL */ if ((ftell(elfile) & 1L) != 0) { putc(NOP,elfile); ellength++; } /* copy EL into outfile */ fflush(elfile); j = ftell(elfile); fseek(elread,0L,0); for (i=0; i>1)+12); fwrite(&entity,sizeof(entity),1,outfile); /* pad out current block */ bcount = padfile(outfile,NOP); /* construct and output part directory entry for this page */ partdir.ptype = 0; partdir.brecord = swab(firstrec); partdir.lrecord = swab((int)((ftell(outfile)/512L) - firstrec)); partdir.padding = swab(bcount>>1); fwrite(&partdir,sizeof(partdir),1,pdfile); nparts++; /* reset sundry parameters */ fseek(elfile,0L,0); ellength = 0; dlbegin = 0; firstrec += swab(partdir.lrecord); CurX = CurY = CurFont = -1; } check_el() { union { long dlend; struct { int hend,lend; } dwend; } end; /* wait 'till EL gets too long, then write it out */ if (ellength < MAXEL) return; /* word align EL */ if ((ftell(elfile) & 1L) != 0) { putc(NOP,elfile); ellength++; } /* construct and output EL trailer */ end.dlend = dlbegin; end.dwend.hend = swab(end.dwend.hend); end.dwend.lend = swab(end.dwend.lend); entity.beginbyte = end.dlend; end.dlend = ftell(outfile) - (512L * firstrec) - dlbegin; dlbegin += end.dlend; end.dwend.hend = swab(end.dwend.hend); end.dwend.lend = swab(end.dwend.lend); entity.bytelength = end.dlend; entity.eheight = swab(27940); entity.ewidth = swab(21590); entity.elength = swab((ellength>>1)+12); fwrite(&entity,sizeof(entity),1,elfile); /* reset sundry params */ ellength = 0; CurX = CurY = CurFont = -1; } padfile(f,ch) FILE *f; register char ch; { register int i; char buffer[512]; for (i=0; i<512; i++) buffer[i] = ch; i = ftell(f) & 511; if (i) { fwrite(buffer,512-i,1,f); return(512-i); } return(0); } Put() { register char ch = CurChr->Ascii; int font = Index[CurChr->Font]; int dfont = font; int x = CurChr->x1 + Kerns[font][CurChr->Ascii]; int y = CurChr->y1 + BaseLine[font]; if (font == -1) return; /* ignore untranslatable chars */ /* do whatever character translations are needed */ if (LigFlag[font]==1) switch (ch) { case 001: ch = 024; break; /* normal translations */ case 002: ch = 025; break; case 003: ch = 006; break; case 004: ch = 021; break; case 005: ch = 022; break; case 021: ch = 0132; dfont = MATH; break; case 022: ch = 0143; dfont = MATH; break; case 023: ch = 0162; dfont = MATH; break; case 024: ch = 044; dfont = MATH; break; case 025: ch = 007; break; case 026: ch = 041; dfont = MATH; break; case 027: ch = 042; dfont = MATH; break; case 030: ch = 0175; dfont = MATH; break; case 031: ch = 0174; dfont = MATH; break; case 032: ch = 0173; dfont = MATH; break; case 035: ch = 061; dfont = MATH; break; case 036: ch = 026; break; case 037: ch = 023; break; case 0140: ch = 007; break; case 0137: Rectangle(convert(x),convert(y-2),convert(15),LINE); return; } else if (LigFlag[font]==2) { /* translate special chars here */ dfont = MATH; switch (ch) { case 013: ch = 026; dfont = 0; break; case 014: ch = 052; dfont = 0; break; case 015: ch = 053; dfont = 0; break; case 016: ch = 075; dfont = 0; break; case 017: ch = 0104; break; case 026: ch = 0120; break; case 027: ch = 0102; break; case 036: ch = 0123; break; case 041: ch = 0136; break; case 042: ch = 0156; break; case 043: ch = 0135; dfont = 0; break; case 044: ch = 072; break; case 045: ch = 0106; break; case 046: ch = 043; break; case 047: ch = 0144; break; case 050: ch = 0107; break; case 051: ch = 0112; break; case 052: ch = 0130; break; case 053: ch = 053; break; case 054: ch = 0171; break; case 055: ch = 0125; break; case 056: ch = 0137; dfont = 0; break; case 057: ch = 045; break; case 060: ch = 0137; break; case 061: ch = 075; break; case 062: ch = 051; break; case 063: ch = 074; break; case 064: ch = 076; break; case 065: ch = 0127; break; case 066: ch = 0126; break; case 067: ch = 006; break; case 075: ch = 0145; break; case 076: Rectangle(convert(x),convert(y),convert(12),LINE); return; case 077: ch = 0111; break; case 0101: Rectangle(convert(x),convert(y+21),convert(12),LINE); return; case 0102: ch = 0114; break; case 0104: case 0106: case 0107: case 0114: case 0120: case 0121: case 0123: case 0125: case 0127: case 0131: case 0141: case 0142: case 0144: case 0145: case 0146: case 0147: case 0150: case 0153: case 0154: case 0155: case 0156: case 0157: case 0160: case 0161: case 0162: case 0163: case 0164: case 0165: case 0167: case 0171: case 0172: dfont = GREEK; break; case 0130: ch = 0103; dfont = GREEK; break; case 0134: ch = 0005; dfont = 0; break; case 0135: ch = 0013; dfont = 0; break; case 0143: ch = 0170; dfont = GREEK; break; case 0166: ch = 0152; dfont = GREEK; break; case 0170: ch = 0143; dfont = GREEK; break; case 030: Rectangle(convert(x),convert(y-BaseLine[font]),LINE,convert(25)); return; case 0100: Rectangle(convert(x),convert(y-BaseLine[font]),convert(12),LINE); return; default: fprintf(stderr,"Special character 0%o on page %d ignored\n",ch,CurPage); return; } } if (Dbg) fprintf(stderr,"Put %o in font %d at (%d,%d), CurX=%d, CurY=%d, CurFont=%d\n",ch,font,x,y,CurX,CurY,CurFont); /* see if letter directly follows current position. if so, just stick it * in DL and update count of similar chars found so far. if not, output * command into EL for accumulated chars before proceeding. */ if (x==CurX && y==CurY && dfont==CurFont) { putc(ch,outfile); CurX += Widths[font][CurChr->Ascii]; if (++ShowCnt == 255) { putc(SHOWCHAR,elfile); putc(ShowCnt,elfile); ellength += 2; ShowCnt = 0; } return; } else if (ShowCnt) { if (ShowCnt <= 32) { putc(SHOWCHARSHORT+ShowCnt-1,elfile); ellength++; } else { putc(SHOWCHAR,elfile); putc(ShowCnt,elfile); ellength += 2; } ShowCnt = 0; } check_el(); /* update whatever changed and reflect change in EL */ if (x != CurX) { CurX = x; putc(SETX,elfile); putw(swab(convert(CurX)+XFUDGE),elfile); ellength += 3; } if (y != CurY) { CurY = y; putc(SETY,elfile); putw(swab(convert(CurY)+YFUDGE),elfile); ellength += 3; } if (dfont != CurFont) { CurFont = dfont; putc(FONT+dfont,elfile); ellength++; } /* finally output char to DL */ putc(ch,outfile); CurX += Widths[font][CurChr->Ascii]; ShowCnt++; } convert(n) register int n; { return((short)(((long)n * 254L)/ 20L)); } min(a,b) register int a,b; { return((ay0) ? DLINE : -DLINE; for (x=x0, y=y0; (y1>y0 && yy1); x += xinc, y += yinc) { xinc = (dx * (long)(abs(y - y0) + DLINE))/dy - (x - x0); Rectangle(x-HDLINE,y-HDLINE,min(x+xinc+DLINE,x1) - x + HDLINE,DLINE); } } else { /* verticalish lines */ if (y1 < y0) { i=x0; x0=x1; x1=i; i=y0; y0=y1; y1=i; } /* x0,y0 are bottom end */ if (Dbg) fprintf(stderr,"verticalish line from %d,%d to %d,%d\n",x0,y0,x1,y1); xinc = (x1>x0) ? DLINE : -DLINE; for (x=x0, y=y0; (x1>x0 && xx1); x += xinc, y += yinc) { yinc = (dy * (long)(abs(x - x0) + DLINE))/dx - (y - y0); Rectangle(x-HDLINE,y-HDLINE,DLINE,min(y+yinc+DLINE,y1) - y + HDLINE); } } } Rectangle(x,y,h,w) register int x,y; { if (Dbg) fprintf(stderr,"Rectangle %d by %d at (%d,%d), CurX=%d, CurY=%d\n", h,w,x,y,CurX,CurY); /* output any pending characters */ if (ShowCnt) { if (ShowCnt <= 32) { putc(SHOWCHARSHORT+ShowCnt-1,elfile); ellength++; } else { putc(SHOWCHAR,elfile); putc(ShowCnt,elfile); ellength += 2; } ShowCnt = 0; } check_el(); /* update whatever changed and reflect change in EL */ if (x != CurX) { CurX = x; putc(SETX,elfile); putw(swab(CurX+XFUDGE),elfile); ellength += 3; } if (y != CurY) { CurY = y; putc(SETY,elfile); putw(swab(CurY+YFUDGE),elfile); ellength += 3; } /* finally output rectangle to EL */ putc(SHOWRECT,elfile); putw(swab(h),elfile); putw(swab(w),elfile); ellength += 5; } Finish() { char buffer[512]; int docdir[256],flength; register int i; register char *p,*q; long tvec; /* output what's left of last page */ NewPage(); /* output font directory as a separate part */ putw(0,fdfile); padfile(fdfile,0); flength = ftell(fdfile); fclose(fdfile); fdfile = fopen(fdname,"r"); for (i=0; i