// This program will convert MetaPost output to a PDF and modify, // if desired, the Bounding Box. // // This utility is licensed under the GNU GPL. // // Author: Troy Henderson // Email : thenders@math.tamu.edu // ICQ : 4551170 #include #include #include #include //#include const char* progname; void usage (FILE* stream, int exit_code) { fprintf(stream,"Usage: %s options [ inputfile ]\n",progname); fprintf(stream, " -h --help Display this usage information.\n" " -o --output filename Write output to file.\n" " -t --tighten-bbox
[,,,
] Tighten bounding box.\n"); fprintf(stream,"\nNote:
, , , and
represent the number of (integer) PostScript\n"); fprintf(stream," points to tighten the left, bottom, right, and top, respectively. If only\n"); fprintf(stream,"
is specfied, then , , and
are all assumed to be this\n"); fprintf(stream," value of
. Furthermore, negative values of
, , , and
\n"); fprintf(stream," will actually \"loosen\" the left, bottom, right, and top, respectively.\n"); exit(exit_code); } int main(int argc,char* argv[]) { int n,nextopt,numargs=1,numcommas=0,MAXLINELEN=0,FOUNDBB=0; long int xl,yb,xr,yt,Dl=0,Db=0,Dr=0,Dt=0,width,height,tmplong; char c,*endptr,*line,*BBOX="%%BoundingBox:",BBOX2[15],*GS; char dL[80],dB[80],dR[80],dT[80]; const char* const shortopts="ho:t:"; const struct option longopts[] = { { "help" , 0, NULL, 'h' }, { "output" , 1, NULL, 'o' }, { "tighten-bbox" ,1, NULL, 't' }, { NULL , 0, NULL, 0 } }; const char* PDF = NULL; const char* PS = NULL; const char* DELTA = "0,0,0,0"; bool valid=true; FILE* fp,*pipe; progname = argv[0]; // ********************* Read in the command line arguments ******************* do { nextopt = getopt_long(argc,argv,shortopts,longopts,NULL); switch(nextopt) { case 'h': // -h or --help usage(stdout,0); case 'o': // -o or --output numargs=numargs+2; PDF=optarg; break; case 't': // -t or --tighten-bbox numargs=numargs+2; DELTA=optarg; break; case '?': // Invalid Option usage(stderr,1); case -1: // Done with options break; default: // Something else: unexpected abort(); } } while (nextopt != -1); if(argc != (numargs+1)) usage(stderr,1); PS=argv[optind]; // ******************** Read in BoundingBox changes *************************** for(n=0;n (as a string) to an integer *********** tmplong=strtol(dL,&endptr,10); if (*endptr!='\0') { fprintf(stderr,"
=%s cannot be converted to an integer\n",dL); valid=false; } else { Dl=tmplong; } // ********** Convert (as a string) to an integer *********** tmplong=strtol(dB,&endptr,10); if (*endptr!='\0') { fprintf(stderr,"=%s cannot be converted to an integer\n",dB); valid=false; } else { Db=tmplong; } // ********** Convert (as a string) to an integer ***********// tmplong=strtol(dR,&endptr,10); if (*endptr!='\0') { fprintf(stderr,"=%s cannot be converted to an integer\n",dR); valid=false; } else { Dr=tmplong; } // ********** Convert
(as a string) to an integer *********** tmplong=strtol(dT,&endptr,10); if (*endptr!='\0') { fprintf(stderr,"
=%s cannot be converted to an integer\n",dT); valid=false; } else { Dt=tmplong; } // *** If
, , , or
could not be converted ... show usage ** if(valid==false) usage(stderr,1); // ********* Make sure that the input file can be open for reading ************ // if ( access(PS,R_OK) == -1) { // fprintf(stderr,"Cannot read (or doesn't exist) file <%s>\n",PS); // exit(0); // } if ( (fp=fopen(PS,"r")) == NULL ) { fprintf(stderr,"Cannot read file <%s>\n",PS); exit(0); } // ********** Determine the length of the longest line in the input file ****** n=0; while((c=fgetc(fp)) != EOF) { if(c=='\n') { if(n>MAXLINELEN) MAXLINELEN=n; n=0; } else { n++; } } fclose(fp); // ******* Read in data and pipe it directly to the Ghostscript command. ****** // ******* If we find "%%BoundingBox", then change it (if necessary) and ****** // ******* append the PageSize. ****** fp=fopen(PS,"r"); line=(char*)malloc((MAXLINELEN+320)*sizeof(char)); GS=(char*)malloc((strlen(PDF)+61)*sizeof(char)); // sprintf(GS,"gs -q -dUseCropBox -sDEVICE=pdfwrite -sOutputFile=%s - -c quit",PDF); sprintf(GS,"gs -q -dEPSCrop -sDEVICE=pdfwrite -sOutputFile=%s - -c quit",PDF); pipe=popen(GS,"w"); free(GS); BBOX2[14]='\0'; while(fgets(line,MAXLINELEN+1,fp) != NULL) { strncpy(BBOX2,line,14); if(FOUNDBB==0 && strcmp(BBOX,BBOX2)==0) { sscanf(line,"%s %ld %ld %ld %ld",&BBOX2,&xl,&yb,&xr,&yt); width=xr-xl-Dr-Dl; height=yt-yb-Dt-Db; sprintf(line,"%s 0 0 %ld %ld\n<>setpagedevice\nmark /MediaBox [0 0 %ld %ld] /PAGE pdfmark\nmark /CropBox [0 0 %ld %ld] /PAGE pdfmark\ngsave %ld %ld translate\n",BBOX2,width,height,width,height,width,height,width,height,-xl-Dl,-yb-Db); FOUNDBB=1; } fprintf(pipe,"%s",line); } free(line); pclose(pipe); fclose(fp); }