shiva@well.sf.ca.us (Kenneth Porter) (11/02/90)
/* Use %%BoundingBox specs in PostScript file to scale to fit on an A-size sheet with 0.375" margins. Author: Kenneth Porter (shiva@well.sf.ca.us) 1431 Madeline Rd. San Pablo, CA 94806-1259 Compiles with Turbo C 2.0. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define FALSE 0 #define TRUE (!FALSE) #define ERRSTRING sys_errlist[errno] /* DOS file error description */ char copyrt[] = "Copyright 1989 Kenneth Porter, all rights reserved\n"; /* printable area in points */ #define INCH 72.0 #define MARGIN 0.375 #define WIDTH ((8.5-(2*MARGIN)) * INCH) #define HEIGHT ((11.0-(2*MARGIN)) * INCH) /* file variables */ char *srcname = NULL, *dstname = NULL; FILE *srcfile, *dstfile; char inbuf[256]; /* Bounding Box info */ char BBs[] = "%%BoundingBox:"; #define BBSize (sizeof(BBs)-1) char atend[] = "(atend)"; #define atSize (sizeof(atend)-1) char trailer[] = "%%Trailer"; #define trailSize (sizeof(trailer)-1) int llx,lly,urx,ury; /* function prototypes */ void OpenSrcFile(char *name); void OpenDstFile(char *name); int FindBB(void); void WriteProlog(void); void CopySrcToOut(void); void WriteTrailer(void); void CloseFiles(void); void main (int argc, char *argv[]) { /* first print title and open files */ puts("PostScript Page-Fitting Utility\n"); puts(copyrt); if (argc != 3) { fputs("syntax: PSFIT <source> <destination>\n",stderr); exit(1); } OpenSrcFile(argv[1]); if (!FindBB()) { fprintf(stderr,"No %%%%BoundingBox comment in %s",srcname); exit(1); } OpenDstFile(argv[2]); WriteProlog(); CopySrcToOut(); WriteTrailer(); CloseFiles(); exit(0); } void OpenSrcFile(char *name) { srcname = strupr(name); srcfile = fopen(srcname,"rt"); if (!srcfile) { fprintf(stderr,"Failed to open %s for reading: %s\n", srcname,ERRSTRING); exit(1); } } void OpenDstFile(char *name) { dstname = strupr(name); if (!strcmp(srcname,dstname)) { fputs("Source file and destination file must be different\n",stderr); exit(1); } dstfile = fopen(dstname,"wt"); if (!dstfile) { fprintf(stderr,"Failed to open %s for writing: %s\n", dstname,ERRSTRING); exit(1); } } int FindBB(void) { /* Scan stdin for line beginning with %%BoundingBox or not a prolog comment. */ int in_prolog, in_trailer, BB_in_trailer, nargs, BB_seen; in_prolog = TRUE; in_trailer = BB_in_trailer = BB_seen = FALSE; fgets(inbuf,sizeof(inbuf),srcfile); while (!(feof(srcfile) || ferror(srcfile))) { if (in_prolog) { if (inbuf[0] != '%' || (inbuf[1] != '%' && inbuf[1] != '!')) in_prolog = FALSE; else { if (!strncmp(inbuf,BBs,BBSize)) { if (!strncmp(&inbuf[BBSize+1],atend,atSize)) { BB_in_trailer = TRUE; } else { nargs = sscanf(&inbuf[BBSize], " %d %d %d %d", &llx,&lly,&urx,&ury); if (nargs != 4) { fprintf(stderr, "Bad %%%%BoundingBox comment in header, %d args parsed:\n", nargs); fprintf(stderr," \"%s\"",inbuf); exit(1); } BB_seen = TRUE; in_prolog = FALSE; /* only look at first */ } } } } else if (BB_in_trailer) { /* not in prolog */ if (!strncmp(inbuf,trailer,trailSize)) in_trailer = TRUE; if (in_trailer) { if (!strncmp(inbuf,BBs,BBSize)) { nargs = sscanf(&inbuf[BBSize], " %d %d %d %d", &llx,&lly,&urx,&ury); if (nargs != 4) { fprintf(stderr, "Bad %%%%BoundingBox comment in trailer, %d args parsed:\n", nargs); fprintf(stderr," \"%s\"",inbuf); exit(1); } BB_seen = TRUE; } } } else break; fgets(inbuf,sizeof(inbuf),srcfile); } /* while (!eof) */ if (ferror(srcfile)) { fprintf(stderr,"Error reading from %s: %s\n",srcname,ERRSTRING); exit(1); } return(BB_seen); } char prolog[] = "%%!PS-Adobe-2.0\n" "%%%%Creator: PSFIT\n" "%%%%BoundingBox: %d %d %d %d\n" "%%%%EndComments\n" "%%%%EndProlog\n" "%%%%BeginSetup\n" "%f %f translate\n" "%f %f scale\n" "%f %f translate\n" "%f rotate\n" "%%%%EndSetup\n" "%%%%BeginDocument: %s\n"; void WriteProlog(void) { int new_llx,new_lly,new_urx,new_ury; double scale,xscale,yscale; int rotate; if (urx-llx > ury-lly) { rotate = 90; /* rotate BB coords around origin */ new_llx = -ury; new_lly = llx; new_urx = -lly; new_ury = urx; /* copy back into original variables */ llx = new_llx; lly = new_lly; urx = new_urx; ury = new_ury; } else rotate = 0; new_llx = new_lly = MARGIN*INCH; xscale = WIDTH / (double) (urx - llx); yscale = HEIGHT / (double) (ury - lly); scale = min(xscale,yscale); new_urx = new_llx + scale*(urx-llx); new_ury = new_lly + scale*(ury-lly); fprintf(dstfile,prolog, new_llx,new_lly, /* new BBox */ new_urx,new_ury, (float)new_llx,(float)new_lly, /* translate */ (float)scale,(float)scale, /* scale */ (float)-llx,(float)-lly, /* translate */ (float) rotate, /* rotate */ srcname); } void CopySrcToOut(void) { rewind(srcfile); fgets(inbuf,sizeof(inbuf),srcfile); while(! (feof(srcfile) /* || ferror(srcfile) */ ) ) { fputs(inbuf,dstfile); fgets(inbuf,sizeof(inbuf),srcfile); } if (ferror(srcfile)) { fprintf(stderr,"Error reading from %s: %s\n",srcname,ERRSTRING); exit(1); } } void WriteTrailer(void) { fputs("%%EndDocument\n",dstfile); } void CloseFiles(void) { fclose(srcfile); fclose(dstfile); }