home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume39 / psutils / part02 / epsffit.c next >
Encoding:
C/C++ Source or Header  |  1993-09-20  |  4.6 KB  |  166 lines

  1. /* epsffit.c
  2.  * AJCD 6 Dec 90
  3.  * fit epsf file into constrained size
  4.  * Usage:
  5.  *       epsffit [-c] [-r] [-a] [-s] llx lly urx ury [file]
  6.  *               -c centres the image in the bounding box given
  7.  *               -r rotates the image by 90 degrees anti-clockwise
  8.  *               -a alters the aspect ratio to fit the bounding box
  9.  *               -s adds a showpage at the end of the image
  10.  *
  11.  * Added filename spec (from Larry Weissman) 5 Feb 93
  12.  * Accepts double %%BoundingBox input, outputs proper BB, 4 Jun 93. (I don't
  13.  * like this; developers should read the Big Red Book before writing code which
  14.  * outputs PostScript.
  15.  */
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include "patchlevel.h"
  20.  
  21. #define min(x,y) ((x) > (y) ? (y) : (x))
  22. #define max(x,y) ((x) > (y) ? (x) : (y))
  23.  
  24. static char *prog;
  25.  
  26. void usage()
  27. {
  28.    fprintf(stderr, "%s release %d patchlevel %d\n", prog, RELEASE, PATCHLEVEL);
  29.    fprintf(stderr, "Usage: %s [-c] [-r] [-a] [-s] llx lly urx ury [file]\n",
  30.        prog);
  31.    exit(1);
  32. }
  33.  
  34. main(argc, argv)
  35.      int argc;
  36.      char **argv;
  37. {
  38.    int bbfound = 0;              /* %%BoundingBox: found */
  39.    int urx, ury, llx, lly;
  40.    int furx, fury, fllx, flly;
  41.    int showpage = 0, centre = 0, rotate = 0, aspect = 0, maximise = 0;
  42.    char buf[BUFSIZ];
  43.    FILE *input = stdin;
  44.  
  45.    prog = *argv++; argc--;
  46.  
  47.    while (argc > 0 && argv[0][0] == '-') {
  48.       switch (argv[0][1]) {
  49.       case 'c': centre = 1; break;
  50.       case 's': showpage = 1; break;
  51.       case 'r': rotate = 1; break;
  52.       case 'a': aspect = 1; break;
  53.       case 'm': maximise = 1; break;
  54.       case 'v':
  55.       default:  usage();
  56.       }
  57.       argc--;
  58.       argv++;
  59.    }
  60.  
  61.    if (argc < 4) usage();
  62.    fllx = atoi(argv[0]);
  63.    flly = atoi(argv[1]);
  64.    furx = atoi(argv[2]);
  65.    fury = atoi(argv[3]);
  66.  
  67.    if (argc > 4) {
  68.       if(!(input = fopen(argv[4],"r"))) {
  69.      fprintf(stderr, "%s: Cannot open %s\n", prog, argv[4]);
  70.      exit(1);
  71.       }
  72.    }
  73.  
  74.    while (fgets(buf, BUFSIZ, input)) {
  75.       if (buf[0] == '%' && (buf[1] == '%' || buf[1] == '!')) {
  76.      /* still in comment section */
  77.      if (!strncmp(buf, "%%BoundingBox:", 14)) {
  78.         double illx, illy, iurx, iury;    /* input bbox parameters */
  79.         if (sscanf(buf, "%%%%BoundingBox:%lf %lf %lf %lf\n",
  80.                &illx, &illy, &iurx, &iury) == 4) {
  81.            bbfound = 1;
  82.            llx = (int)illx;    /* accept doubles, but convert to int */
  83.            lly = (int)illy;
  84.            urx = (int)(iurx+0.5);
  85.            ury = (int)(iury+0.5);
  86.         }
  87.      } else if (!strncmp(buf, "%%EndComments", 13)) {
  88.         strcpy(buf, "\n"); /* don't repeat %%EndComments */
  89.         break;
  90.      } else fputs(buf,stdout);
  91.       } else break;
  92.    }
  93.  
  94.    if (bbfound) { /* put BB, followed by scale&translate */
  95.       int fwidth, fheight;
  96.       double xscale, yscale;
  97.       double xoffset = fllx, yoffset = flly;
  98.       double width = urx-llx, height = ury-lly;
  99.  
  100.       if (maximise)
  101.      if ((width > height && fury-flly > furx-fllx) ||
  102.          (width < height && fury-flly < furx-fllx)) 
  103.         rotate = 1;
  104.  
  105.       if (rotate) {
  106.      fwidth = fury - flly;
  107.      fheight = furx - fllx;
  108.       } else {
  109.      fwidth = furx - fllx;
  110.      fheight = fury - flly;
  111.       }
  112.  
  113.       xscale = fwidth/width;
  114.       yscale = fheight/height;
  115.  
  116.       if (!aspect) {       /* preserve aspect ratio ? */
  117.      xscale = yscale = min(xscale,yscale);
  118.       }
  119.       width *= xscale;     /* actual width and height after scaling */
  120.       height *= yscale;
  121.       if (centre) {
  122.      if (rotate) {
  123.         xoffset += (fheight - height)/2;
  124.         yoffset += (fwidth - width)/2;
  125.      } else {
  126.         xoffset += (fwidth - width)/2;
  127.         yoffset += (fheight - height)/2;
  128.      }
  129.       }
  130.       printf("%%%%BoundingBox: %d %d %d %d\n", (int)xoffset, (int)yoffset,
  131.          (int)(xoffset+(rotate ? height : width)),
  132.          (int)(yoffset+(rotate ? width : height)));
  133.       if (rotate) {  /* compensate for original image shift */
  134.      xoffset += height + lly * yscale;  /* displacement for rotation */
  135.      yoffset -= llx * xscale;
  136.       } else {
  137.      xoffset -= llx * xscale;
  138.      yoffset -= lly * yscale;
  139.       }
  140.       puts("%%EndComments");
  141.       if (showpage)
  142.      puts("save /showpage{}def /copypage{}def /erasepage{}def");
  143.       else
  144.      puts("%%BeginProcSet: epsffit 1 0");
  145.       puts("gsave");
  146.       printf("%.3lf %.3lf translate\n", xoffset, yoffset);
  147.       if (rotate)
  148.      puts("90 rotate");
  149.       printf("%.3lf %.3lf scale\n", xscale, yscale);
  150.       if (!showpage)
  151.      puts("%%EndProcSet");
  152.    }
  153.    do {
  154.       fputs(buf,stdout);
  155.    } while (fgets(buf, BUFSIZ, input));
  156.    if (bbfound) {
  157.       puts("grestore");
  158.       if (showpage)
  159.      puts("restore showpage"); /* just in case */
  160.    } else {
  161.       fprintf(stderr, "%s: no %%%%BoundingBox:\n", prog);
  162.       exit(1);
  163.    }
  164.    exit(0);
  165. }
  166.