home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / pbmtolps.lzh / pbmtolps
Text File  |  1990-05-18  |  4KB  |  175 lines

  1.  
  2. /*
  3.  * pbmtolps -- convert a Portable BitMap into Postscript.  The
  4.  * output Postscript uses lines instead of the image operator to
  5.  * generate a (device dependent) picture which will be imaged
  6.  * much faster.
  7.  *
  8.  * The Postscript path length is constrained to be less that 1000
  9.  * points so that no limits are overrun on the Apple Laserwriter
  10.  * and (presumably) no other printers.
  11.  *
  12.  * To do:
  13.  *    make sure encapsulated format is correct
  14.  *    repitition of black-white strips
  15.  *    make it more device independent (is this possible?)
  16.  *
  17.  * Author:
  18.  *    George Phillips <phillips@cs.ubc.ca>
  19.  *    Department of Computer Science
  20.  *    University of British Columbia
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include "pbm.h"
  25.  
  26. main(argc, argv)
  27. int        argc;
  28. char*    argv[];
  29. {
  30.     FILE*    fp;
  31.     bit*    bits;
  32.     int        row;
  33.     int        col;
  34.     int        rows;
  35.     int        cols;
  36.     int        format;
  37.     int        white;
  38.     int        black;
  39.     char*    name;
  40.     float    dpi = 300.0;
  41.     float    sc_rows;
  42.     float    sc_cols;
  43.     int        i;
  44.     char*    usage = "[ -dpi n ] [ pbmfile ]";
  45.  
  46.     pm_progname = argv[0];
  47.  
  48.     i = 1;
  49.     if (i < argc && !strcmp(argv[i], "-dpi")) {
  50.         if (i == argc - 1)
  51.             pm_usage(usage);
  52.         sscanf(argv[i + 1], "%f", &dpi);
  53.         i += 2;
  54.     }
  55.  
  56.     if (i < argc - 1)
  57.         pm_usage(usage);
  58.  
  59.     if (i == argc) {
  60.         fp = stdin;
  61.         name = "noname";
  62.     }
  63.     else
  64.         fp = pm_openr(name = argv[i]);
  65.  
  66.     pbm_readpbminit(fp, &cols, &rows, &format);
  67.     bits = pbm_allocrow(cols);
  68.  
  69.     sc_rows = (float)rows / dpi * 72.0;
  70.     sc_cols = (float)cols / dpi * 72.0;
  71.     
  72.     puts("%!PS-Adobe-2.0 EPSF-2.0");
  73.     puts("%%Creator: pbmtolps");
  74.     printf("%%%%Title: %s\n", name);
  75.     printf("%%%%BoundingBox: %f %f %f %f\n",
  76.         306.0 - sc_cols / 2.0,
  77.         396.0 - sc_rows / 2.0,
  78.         306.0 + sc_cols / 2.0,
  79.         396.0 + sc_rows / 2.0);
  80.     puts("%%EndComments");
  81.     puts("%%EndProlog");
  82.     puts("gsave");
  83.  
  84.     printf("%f %f translate\n", 306.0 - sc_cols / 2.0, 396.0 + sc_rows / 2.0);
  85.     printf("72 %f div dup neg scale\n", dpi);
  86.     puts("/a { 0 rmoveto 0 rlineto } def");
  87.     puts("/b { 0 row 1 add dup /row exch def moveto } def");
  88.     puts("/c { a b } def");
  89.     puts("/m { currentpoint stroke newpath moveto a } def");
  90.     puts("/n { currentpoint stroke newpath moveto b } def");
  91.     puts("/o { currentpoint stroke newpath moveto c } def");
  92.     puts("/row 0 def");
  93.     puts("newpath 0 0 moveto");
  94.  
  95.     for (row = 0; row < rows; row++) {
  96.         pbm_readpbmrow(fp, bits, cols, format);
  97.         /* output white-strip+black-strip sequences */
  98.         for (col = 0; col < cols; ) {
  99.             for (white = 0; col < cols && bits[col] == PBM_WHITE; col++)
  100.                 white++;
  101.             for (black = 0; col < cols && bits[col] == PBM_BLACK; col++)
  102.                 black++;
  103.             
  104.             if (black != 0)
  105.                 addstrip(white, black);
  106.         }
  107.         nextline();
  108.     }
  109.     puts("stroke grestore showpage");
  110.     puts("%%Trailer");
  111.  
  112.     pm_close(fp);
  113.  
  114.     exit(0);
  115. }
  116.  
  117. static int prev_white = -1;
  118. static int prev_black = -1;
  119. static char cmd = '\0';
  120. static int run = 1;
  121.  
  122. addstrip(white, black)
  123. int white;
  124. int black;
  125. {
  126.     if (cmd) {
  127. #ifdef RUN
  128.         if (white == prev_white && black == prev_black)
  129.             run++;
  130.         else {
  131.             if (run == 1)
  132. #endif
  133.                 printf("%d %d %c ", prev_black, prev_white, morepoints(cmd, 2));
  134. #ifdef RUN
  135.             else
  136.                 /* of course, we need to give a new command */
  137.                 printf("%d %d %d %c ",
  138.                     prev_white, prev_black, run,
  139.                     morepoints(cmd + 'f' - 'a', 2 * run));
  140.             run = 1;
  141.         }
  142. #endif
  143.     }
  144.     
  145.     prev_white = white;
  146.     prev_black = black;
  147.     cmd = 'a';
  148. }
  149.  
  150. nextline()
  151. {
  152.     /* need to check run, should have an outcommand */
  153.     if (cmd)
  154.         printf("%d %d %c\n", prev_black, prev_white, morepoints('c', 3));
  155.     else
  156.         printf("%c\n", morepoints('b', 1));
  157.     cmd = '\0';
  158. }
  159.  
  160. static int pointcount = 2;
  161.  
  162. morepoints(cmd, howmany)
  163. char    cmd;
  164. int        howmany;
  165. {
  166.     pointcount += 2;
  167.     if (pointcount > 1000) {
  168.         pointcount = 2;
  169.         cmd += 'm' - 'a';
  170.     }
  171.     return(cmd);
  172. }
  173.  
  174.  
  175.