home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / epsmanip.zoo / epsmanip.c
Encoding:
C/C++ Source or Header  |  1990-11-04  |  6.4 KB  |  247 lines

  1.  
  2. /*
  3. Use %%BoundingBox specs in PostScript file to scale to fit
  4. on an A-size sheet with 0.375" margins.
  5.  
  6. Author: Kenneth Porter (shiva@well.sf.ca.us)
  7. 1431 Madeline Rd.
  8. San Pablo, CA  94806-1259
  9.  
  10. Compiles with Turbo C 2.0.
  11. */
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16.  
  17. #define FALSE 0
  18. #define TRUE (!FALSE)
  19.  
  20. #define ERRSTRING sys_errlist[errno]    /* DOS file error description */
  21.  
  22. char copyrt[] = "Copyright 1989 Kenneth Porter, all rights reserved\n";
  23.  
  24. /* printable area in points */
  25. #define INCH 72.0
  26. #define MARGIN 0.375
  27. #define WIDTH ((8.5-(2*MARGIN)) * INCH)
  28. #define HEIGHT ((11.0-(2*MARGIN)) * INCH)
  29.  
  30. /* file variables */
  31. char *srcname = NULL, *dstname = NULL;
  32. FILE *srcfile, *dstfile;
  33. char inbuf[256];
  34.  
  35. /* Bounding Box info */
  36. char BBs[] = "%%BoundingBox:";
  37. #define BBSize (sizeof(BBs)-1)
  38. char atend[] = "(atend)";
  39. #define atSize (sizeof(atend)-1)
  40. char trailer[] = "%%Trailer";
  41. #define trailSize (sizeof(trailer)-1)
  42. int llx,lly,urx,ury;
  43.  
  44. /* function prototypes */
  45. void OpenSrcFile(char *name);
  46. void OpenDstFile(char *name);
  47. int FindBB(void);
  48. void WriteProlog(void);
  49. void CopySrcToOut(void);
  50. void WriteTrailer(void);
  51. void CloseFiles(void);
  52.  
  53. void main (int argc, char *argv[])
  54. {
  55.     /* first print title and open files */
  56.     puts("PostScript Page-Fitting Utility\n");
  57.     puts(copyrt);
  58.     if (argc != 3) {
  59.         fputs("syntax: PSFIT <source> <destination>\n",stderr);
  60.         exit(1);
  61.     }
  62.     OpenSrcFile(argv[1]);
  63.     if (!FindBB()) {
  64.         fprintf(stderr,"No %%%%BoundingBox comment in %s",srcname);
  65.         exit(1);
  66.     }
  67.     OpenDstFile(argv[2]);
  68.     WriteProlog();
  69.     CopySrcToOut();
  70.     WriteTrailer();
  71.     CloseFiles();
  72.     exit(0);
  73. }
  74.  
  75. void OpenSrcFile(char *name)
  76. {
  77.     srcname = strupr(name);
  78.     srcfile = fopen(srcname,"rt");
  79.     if (!srcfile) {
  80.         fprintf(stderr,"Failed to open %s for reading: %s\n",
  81.             srcname,ERRSTRING);
  82.         exit(1);
  83.     }
  84. }
  85.  
  86. void OpenDstFile(char *name)
  87. {
  88.     dstname = strupr(name);
  89.     if (!strcmp(srcname,dstname)) {
  90.         fputs("Source file and destination file must be different\n",stderr);
  91.         exit(1);
  92.     }
  93.     dstfile = fopen(dstname,"wt");
  94.     if (!dstfile) {
  95.         fprintf(stderr,"Failed to open %s for writing: %s\n",
  96.             dstname,ERRSTRING);
  97.         exit(1);
  98.     }
  99. }
  100.  
  101. int FindBB(void)
  102. {
  103.     /*
  104.     Scan stdin for line beginning with %%BoundingBox or not a
  105.     prolog comment.
  106.     */
  107.  
  108.     int in_prolog, in_trailer, BB_in_trailer, nargs, BB_seen;
  109.  
  110.     in_prolog = TRUE;
  111.     in_trailer = BB_in_trailer = BB_seen = FALSE;
  112.     fgets(inbuf,sizeof(inbuf),srcfile);
  113.     while (!(feof(srcfile) || ferror(srcfile))) {
  114.         if (in_prolog) {
  115.             if (inbuf[0] != '%' || (inbuf[1] != '%' && inbuf[1] != '!'))
  116.                 in_prolog = FALSE;
  117.             else {
  118.                 if (!strncmp(inbuf,BBs,BBSize)) {
  119.                     if (!strncmp(&inbuf[BBSize+1],atend,atSize)) {
  120.                         BB_in_trailer = TRUE;
  121.                     }
  122.                     else {
  123.                         nargs = sscanf(&inbuf[BBSize],
  124.                                " %d %d %d %d",
  125.                                &llx,&lly,&urx,&ury);
  126.                         if (nargs != 4) {
  127.                             fprintf(stderr,
  128.                                 "Bad %%%%BoundingBox comment in header, %d args
  129. parsed:\n",
  130.                                 nargs);
  131.                             fprintf(stderr," \"%s\"",inbuf);
  132.                             exit(1);
  133.                         }
  134.                         BB_seen = TRUE;
  135.                         in_prolog = FALSE; /* only look at first */
  136.                     }
  137.                 }
  138.             }
  139.         }
  140.         else if (BB_in_trailer) {
  141.             /* not in prolog */
  142.             if (!strncmp(inbuf,trailer,trailSize))
  143.                 in_trailer = TRUE;
  144.             if (in_trailer) {
  145.                 if (!strncmp(inbuf,BBs,BBSize)) {
  146.                     nargs = sscanf(&inbuf[BBSize],
  147.                            " %d %d %d %d",
  148.                            &llx,&lly,&urx,&ury);
  149.                     if (nargs != 4) {
  150.                         fprintf(stderr,
  151.                             "Bad %%%%BoundingBox comment in trailer, %d args
  152. parsed:\n",
  153.                             nargs);
  154.                         fprintf(stderr," \"%s\"",inbuf);
  155.                         exit(1);
  156.                     }
  157.                     BB_seen = TRUE;
  158.                 }
  159.             }
  160.         }
  161.         else break;
  162.     fgets(inbuf,sizeof(inbuf),srcfile);
  163.     } /* while (!eof) */
  164.     if (ferror(srcfile)) {
  165.         fprintf(stderr,"Error reading from %s: %s\n",srcname,ERRSTRING);
  166.         exit(1);
  167.     }
  168.     return(BB_seen);
  169. }
  170.  
  171. char prolog[] =
  172.     "%%!PS-Adobe-2.0\n"
  173.     "%%%%Creator: PSFIT\n"
  174.     "%%%%BoundingBox: %d %d %d %d\n"
  175.     "%%%%EndComments\n"
  176.     "%%%%EndProlog\n"
  177.     "%%%%BeginSetup\n"
  178.     "%f %f translate\n"
  179.     "%f %f scale\n"
  180.     "%f %f translate\n"
  181.     "%f rotate\n"
  182.     "%%%%EndSetup\n"
  183.     "%%%%BeginDocument: %s\n";
  184.  
  185. void WriteProlog(void)
  186. {
  187.     int new_llx,new_lly,new_urx,new_ury;
  188.     double scale,xscale,yscale;
  189.     int rotate;
  190.     
  191.     if (urx-llx > ury-lly) {
  192.         rotate = 90;
  193.         /* rotate BB coords around origin */
  194.         new_llx = -ury;
  195.         new_lly = llx;
  196.         new_urx = -lly;
  197.         new_ury = urx;
  198.         /* copy back into original variables */
  199.         llx = new_llx;
  200.         lly = new_lly;
  201.         urx = new_urx;
  202.         ury = new_ury;
  203.     }
  204.     else rotate = 0;
  205.     new_llx = new_lly = MARGIN*INCH;
  206.     xscale = WIDTH / (double) (urx - llx);
  207.     yscale = HEIGHT / (double) (ury - lly);
  208.     scale = min(xscale,yscale);
  209.     new_urx = new_llx + scale*(urx-llx);
  210.     new_ury = new_lly + scale*(ury-lly);
  211.     fprintf(dstfile,prolog,
  212.         new_llx,new_lly,    /* new BBox */
  213.         new_urx,new_ury,
  214.         (float)new_llx,(float)new_lly,  /* translate */
  215.         (float)scale,(float)scale,      /* scale */
  216.         (float)-llx,(float)-lly,        /* translate */
  217.         (float) rotate,                 /* rotate */
  218.         srcname);
  219. }
  220.  
  221. void CopySrcToOut(void)
  222. {
  223.     rewind(srcfile);
  224.     fgets(inbuf,sizeof(inbuf),srcfile);
  225.     while(! (feof(srcfile) /* || ferror(srcfile) */ ) ) {
  226.         fputs(inbuf,dstfile);
  227.         fgets(inbuf,sizeof(inbuf),srcfile);
  228.     }
  229.     if (ferror(srcfile)) {
  230.         fprintf(stderr,"Error reading from %s: %s\n",srcname,ERRSTRING);
  231.         exit(1);
  232.     }
  233. }
  234.  
  235. void WriteTrailer(void)
  236. {
  237.     fputs("%%EndDocument\n",dstfile);
  238. }
  239.  
  240. void CloseFiles(void)
  241. {
  242.     fclose(srcfile);
  243.     fclose(dstfile);
  244. }
  245.  
  246.  
  247.