home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / x / gui / amiga / xfig.lha / src / x11 / f_epsobj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-26  |  10.7 KB  |  381 lines

  1. /*
  2.  * FIG : Facility for Interactive Generation of figures
  3.  * Copyright (c) 1992 by Brian Boyter
  4.  * DPS option Copyright 1992 by Dave Hale
  5.  *
  6.  * "Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both the copyright
  9.  * notice and this permission notice appear in supporting documentation. 
  10.  * No representations are made about the suitability of this software for 
  11.  * any purpose.  It is provided "as is" without express or implied warranty."
  12.  */
  13.  
  14. /* GS bitmap generation added: 13 Nov 1992, by Michael C. Grant
  15. *  (mcgrant@rascals.stanford.edu) adapted from Marc Goldburg's
  16. *  (marcg@rascals.stanford.edu) original idea and code. */
  17.  
  18. #include "fig.h"
  19. #include "resources.h"
  20. #include "object.h"
  21. #include "paintop.h"
  22. #include "u_create.h"
  23. #include "u_elastic.h"
  24. #include "w_canvas.h"
  25. #include "w_setup.h"
  26. #include "mode.h"
  27.  
  28. read_epsf(eps)
  29.     F_eps       *eps;
  30. {
  31.     int            nbitmap;
  32.     int            bitmapz;
  33.     char       *cp;
  34.     unsigned char  *mp;
  35.     unsigned int    hexnib;
  36.     int            flag,preview;
  37.     char        buf[300];
  38.     int            llx, lly, urx, ury, bad_bbox;
  39.     FILE       *epsf;
  40.     register unsigned char *last;
  41. #ifdef DPS
  42.     int dummy, useDPS;
  43. #endif
  44. #ifdef GSBIT
  45.     FILE           *ppmfile, *gsfile;
  46.     char           *ppmnam;
  47.     int            useGS;
  48. #endif
  49.     int            usePV;
  50. #ifdef DPS
  51.     useDPS = 0;
  52. #endif
  53. #ifdef GSBIT
  54.     useGS = 0;
  55. #endif
  56.     usePV = 0;
  57.  
  58.     /* don't touch the flipped flag - caller has already set it */
  59.     eps->bitmap = (unsigned char *) NULL;
  60.     eps->hw_ratio = 0.0;
  61.     eps->size_x = 0;
  62.     eps->size_y = 0;
  63.     eps->bit_size.x = 0;
  64.     eps->bit_size.y = 0;
  65.     eps->pixmap = (Pixmap) NULL;
  66.     eps->pix_rotation = 0;
  67.     eps->pix_width = 0;
  68.     eps->pix_height = 0;
  69.     eps->pix_flipped = 0;
  70.  
  71.     epsf = fopen(eps->file, "r");
  72.     if (epsf == NULL) {
  73.     file_msg("Cannot open file: %s", eps->file);
  74.     return 0;
  75.     }
  76.     while (fgets(buf, 300, epsf) != NULL) {
  77.     lower(buf);
  78.     if (!strncmp(buf, "%%boundingbox", 13)) {
  79.         /* the Encapsulated PostScript Specifications (2.0) doesn't say
  80.            that the values for the bounding box must be integers */
  81.         float rllx, rlly, rurx, rury;
  82.         if (sscanf(buf, "%%%%boundingbox: %f %f %f %f",
  83.                &rllx, &rlly, &rurx, &rury) < 4) {
  84.         file_msg("Bad EPS file: %s", eps->file);
  85.         fclose(epsf);
  86.         return 0;
  87.         }
  88.         llx = round(rllx);
  89.         lly = round(rlly);
  90.         urx = round(rurx);
  91.         ury = round(rury);
  92.         break;
  93.     }
  94.     }
  95.  
  96.     eps->hw_ratio = (float) (ury - lly) / (float) (urx - llx);
  97.     eps->size_x = (urx - llx) * PIX_PER_INCH / 72.0;
  98.     eps->size_y = (ury - lly) * PIX_PER_INCH / 72.0;
  99.  
  100.     if ( bad_bbox = ( urx <= llx || ury <= lly ) ) {
  101.     file_msg("Bad values in EPS bounding box");
  102.     }
  103.     bitmapz = 0;
  104.  
  105. #ifdef DPS
  106.     /* if Display PostScript on server */
  107.     if (XQueryExtension(tool_d,"DPSExtension",&dummy,&dummy,&dummy)) {
  108.     eps->bit_size.x = eps->size_x;
  109.     eps->bit_size.y = eps->size_y;
  110.     bitmapz = 1;
  111.     useDPS = 1;
  112.     /* else if no Display PostScript */
  113.     } else {
  114. #endif
  115.     /* look for a preview bitmap */
  116.     while (fgets(buf, 300, epsf) != NULL) {
  117.         lower(buf);
  118.         if (!strncmp(buf, "%%beginpreview", 14)) {
  119.         sscanf(buf, "%%%%beginpreview: %d %d %d",
  120.            &eps->bit_size.x, &eps->bit_size.y, &bitmapz);
  121.         bitmapz = 1;
  122.         usePV = 1;
  123.         break;
  124.         }
  125.     }
  126. #ifdef GSBIT
  127.     /* if GhostScript exists */
  128.     if (!bitmapz && !bad_bbox && (gsfile = popen("gs -sDEVICE=bit -q -","w" ))) {
  129.         ppmnam = tempnam(NULL,"xfig");
  130.         eps->bit_size.x = urx - llx + 1;
  131.         eps->bit_size.y = ury - lly + 1;
  132.         bitmapz = 1;
  133.         useGS = 1;
  134.     }
  135. #endif
  136. #ifdef DPS
  137.     }
  138. #endif
  139.     if (!bitmapz) {
  140.         file_msg("EPS object read OK, but no preview bitmap found/generated");
  141.         fclose(epsf);
  142.         return 0;
  143.     } else if ( eps->bit_size.x <= 0 || eps->bit_size.y <= 0 ) {
  144.         file_msg("Strange bounding-box/bitmap-size error, no bitmap found/generated");
  145.         fclose(epsf);
  146. #ifdef GSBIT
  147.         if ( useGS )
  148.             pclose( gsfile );
  149. #endif
  150.         return 0;
  151.     } else {
  152.     nbitmap = (eps->bit_size.x + 7) / 8 * eps->bit_size.y;
  153.     eps->bitmap = (unsigned char *) malloc(nbitmap);
  154.     if (eps->bitmap == NULL) {
  155.         file_msg("Could not allocate %d bytes of memory for EPS bitmap\n",
  156.                      nbitmap);
  157.         fclose(epsf);
  158. #ifdef GSBIT
  159.             if ( useGS )
  160.                 pclose( gsfile );
  161. #endif
  162.         return 0;
  163.     }
  164.     }
  165. #ifdef DPS
  166.     /* if Display PostScript */
  167.     if ( useDPS ) {
  168.     static int bitmapDPS (FILE*,int,int,int,int,int,int,int,unsigned char *);
  169.         if (!bitmapDPS(epsf,llx,lly,urx,ury,
  170.                        eps->size_x,eps->size_y,nbitmap,eps->bitmap)) {
  171.             file_msg("DPS extension failed to generate EPS bitmap\n");
  172.             fclose(epsf);
  173.             return 0;
  174.         }
  175.     }
  176. #endif
  177. #ifdef GSBIT
  178.     /* if GhostScript */
  179.     if ( useGS ) {
  180.         ppmnam = tempnam("/usr/tmp","xfig");
  181.      fprintf(gsfile, "[1 0 0 1 0 0] %d %d <ff 00>\n", eps->bit_size.x, 
  182.          eps->bit_size.y);
  183.      fprintf(gsfile, "makeimagedevice setdevice\n");
  184.      fprintf(gsfile, "0 %d translate 1 -1 scale\n", eps->bit_size.y);
  185.      fprintf(gsfile, "%d neg %d neg translate\n", llx, lly);
  186.      fprintf(gsfile, "/showpage {null exec} def (%s) run\n", eps->file);
  187.      fprintf(gsfile, "(%s) (w) file currentdevice writeppmfile quit\n",
  188.          ppmnam);        
  189.         if ( pclose(gsfile) != 0 || ( ppmfile = fopen(ppmnam,"r") ) == NULL ) {
  190.             put_msg( "Could not parse EPS file with GS: %s", eps->file);
  191.             free(eps->bitmap); eps->bitmap = NULL;
  192.             unlink(ppmnam);
  193.             return 0;
  194.         }
  195.         fgets(buf, 300, ppmfile);
  196.         fgets(buf, 300, ppmfile);
  197.         fgets(buf, 300, ppmfile);
  198.         if ( fread(eps->bitmap,nbitmap,1,ppmfile) != 1 ) {
  199.             put_msg("Error reading ppm file (EPS problems?): %s", ppmnam);
  200.             fclose(ppmfile); unlink(ppmnam);
  201.             free(eps->bitmap); eps->bitmap = NULL;
  202.             return 0;
  203.         }
  204.         fclose(ppmfile); unlink(ppmnam);
  205.     }
  206. #endif
  207.     if ( usePV ) {
  208.         mp = eps->bitmap;
  209.         bzero(mp, nbitmap);    /* init bitmap to zero */
  210.         last = eps->bitmap + nbitmap;
  211.         flag = True;
  212.         while (fgets(buf, 300, epsf) != NULL && mp < last) {
  213.             lower(buf);
  214.             if (!strncmp(buf, "%%endpreview", 12) ||
  215.                 !strncmp(buf, "%%endimage", 10))
  216.                 break;
  217.             cp = buf;
  218.             if (*cp != '%')
  219.                 break;
  220.             cp++;
  221.             while (*cp != '\0') {
  222.                 if (isxdigit(*cp)) {
  223.                     hexnib = hex(*cp);
  224.                     if (flag) {
  225.                         flag = False;
  226.                         *mp = hexnib << 4;
  227.                     } else {
  228.                         flag = True;
  229.                         *mp = *mp + hexnib;
  230.                         mp++;
  231.                         if (mp >= last)
  232.                             break;
  233.                     }
  234.                 }
  235.                 cp++;
  236.             }
  237.         }
  238.     }
  239.     put_msg("EPS object read OK");
  240.     fclose(epsf);
  241.     return 1;
  242. }
  243.  
  244. int
  245. hex(c)
  246.     char        c;
  247. {
  248.     if (isdigit(c))
  249.     return (c - 48);
  250.     else
  251.     return (c - 87);
  252. }
  253.  
  254. lower(buf)
  255.     char       *buf;
  256. {
  257.     while (*buf) {
  258.     if (isupper(*buf))
  259.         *buf = (char) tolower(*buf);
  260.     buf++;
  261.     }
  262. }
  263.  
  264. /* Display PostScript */
  265. #ifdef DPS
  266.  
  267. #ifdef sgi
  268. #include <X11/extensions/XDPS.h>
  269. #include <X11/extensions/XDPSlib.h>
  270. #include <X11/extensions/dpsXclient.h>
  271. #else
  272. #include <DPS/XDPS.h>
  273. #include <DPS/XDPSlib.h>
  274. #include <DPS/dpsXclient.h>
  275. #endif
  276.  
  277. #define LBUF 1000
  278.  
  279. static 
  280. int bitmapDPS (FILE *fp, int llx, int lly, int urx, int ury,
  281.     int width, int height, int nbitmap, unsigned char *bitmap)
  282. {
  283.     Display *dpy=tool_d;
  284.     int scr=tool_sn;
  285.     unsigned long black=BlackPixel(dpy,scr),white=WhitePixel(dpy,scr);
  286.     char buf[LBUF];
  287.     unsigned char *bp,*dp;
  288.     int line,byte,nbyte;
  289.     int scrwidth,scrheight,scrwidthmm,scrheightmm;
  290.     float dppi;
  291.     GC gcbit;
  292.     Colormap cm;
  293.     Pixmap bit;
  294.     XColor color;
  295.     XStandardColormap *scm;
  296.     XImage *image;
  297.     DPSContext dps;
  298.     
  299.     /* create bit pixmap and its GC */
  300.     bit = XCreatePixmap(dpy,DefaultRootWindow(dpy),width,height,
  301.                 DefaultDepthOfScreen(tool_s));
  302.         gcbit = XCreateGC(dpy,bit,0,NULL);
  303.  
  304.         /* create standard colormap for black-and-white only */
  305.         cm = XCreateColormap(dpy,RootWindow(dpy,scr),
  306.                 DefaultVisual(dpy,scr),AllocAll);
  307.         color.pixel = 0;
  308.         color.red = color.green = color.blue = 0;
  309.         color.flags = DoRed | DoGreen | DoBlue;
  310.         XStoreColor(dpy,cm,&color);
  311.         color.pixel = 1;
  312.         color.red = color.green = color.blue = 65535;
  313.         color.flags = DoRed | DoGreen | DoBlue;
  314.         XStoreColor(dpy,cm,&color);
  315.         scm = XAllocStandardColormap();
  316.         scm->colormap = cm;
  317.         scm->red_max = 1;
  318.         scm->red_mult = 1;
  319.         scm->base_pixel = 0;
  320.         scm->visualid = XVisualIDFromVisual(DefaultVisual(dpy,scr));
  321.  
  322.         /* create and set Display PostScript context for bit pixmap */
  323.         dps = XDPSCreateContext(dpy,bit,gcbit,0,height,0,scm,NULL,0,
  324.                 DPSDefaultTextBackstop,DPSDefaultErrorProc,NULL);
  325.         if (dps==NULL) {
  326.         file_msg("Cannot create Display PostScript context!");
  327.         return 0;
  328.         }
  329.         DPSPrintf(dps,"\n resyncstart\n");
  330.         DPSSetContext(dps);
  331.         DPSFlushContext(dps);
  332.         DPSWaitContext(dps);
  333.  
  334.     /* display pixels per inch */
  335.     scrwidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
  336.     scrheight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
  337.     scrwidthmm = WidthMMOfScreen(DefaultScreenOfDisplay(dpy));
  338.     scrheightmm = HeightMMOfScreen(DefaultScreenOfDisplay(dpy));
  339.     dppi = 0.5*((int)(25.4*scrwidth/scrwidthmm)+
  340.         (int)(25.4*scrheight/scrheightmm));
  341.  
  342.         /* scale */
  343.         DPSPrintf(dps,"%f %f scale\n",PIX_PER_INCH/dppi,PIX_PER_INCH/dppi);
  344.  
  345.         /* paint white background */
  346.         DPSPrintf(dps,
  347.                   "gsave\n 1 setgray\n 0 0 %d %d rectfill\n grestore\n",
  348.                   urx-llx+2,ury-lly+2);
  349.  
  350.         /* translate */
  351.         DPSPrintf(dps,"%d %d translate\n",-llx,-lly);
  352.  
  353.         /* read PostScript from standard input and render in bit pixmap */
  354.         DPSPrintf(dps,"/showpage {} def\n");
  355.         while (fgets(buf,LBUF,fp)!=NULL)
  356.                 DPSWritePostScript(dps,buf,strlen(buf));
  357.         DPSFlushContext(dps);
  358.         DPSWaitContext(dps);
  359.  
  360.     /* get image from bit pixmap */
  361.     image = XGetImage(dpy,bit,0,0,width,height,1,XYPixmap);
  362.  
  363.     /* copy bits from image to bitmap */
  364.     bzero(bitmap,nbitmap);
  365.     nbyte = (width+7)/8;
  366.     for (line=0; line<height; ++line) {
  367.         bp = bitmap+line*nbyte;
  368.         dp = (unsigned char*)(image->data+line*image->bytes_per_line);
  369.         for (byte=0; byte<nbyte; ++byte)
  370.             *bp++ = ~(*dp++);
  371.     }
  372.  
  373.     /* clean up */
  374.         DPSDestroySpace(DPSSpaceFromContext(dps));
  375.     XFreePixmap(dpy,bit);
  376.     XFreeColormap(dpy,cm);
  377.     XFreeGC(dpy,gcbit);
  378.     XDestroyImage(image);
  379. }
  380. #endif /* DPS */
  381.