home *** CD-ROM | disk | FTP | other *** search
- /*
- * FIG : Facility for Interactive Generation of figures
- * Copyright (c) 1992 by Brian Boyter
- * DPS option Copyright 1992 by Dave Hale
- *
- * "Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both the copyright
- * notice and this permission notice appear in supporting documentation.
- * No representations are made about the suitability of this software for
- * any purpose. It is provided "as is" without express or implied warranty."
- */
-
- /* GS bitmap generation added: 13 Nov 1992, by Michael C. Grant
- * (mcgrant@rascals.stanford.edu) adapted from Marc Goldburg's
- * (marcg@rascals.stanford.edu) original idea and code. */
-
- #include "fig.h"
- #include "resources.h"
- #include "object.h"
- #include "paintop.h"
- #include "u_create.h"
- #include "u_elastic.h"
- #include "w_canvas.h"
- #include "w_setup.h"
- #include "mode.h"
-
- read_epsf(eps)
- F_eps *eps;
- {
- int nbitmap;
- int bitmapz;
- char *cp;
- unsigned char *mp;
- unsigned int hexnib;
- int flag,preview;
- char buf[300];
- int llx, lly, urx, ury, bad_bbox;
- FILE *epsf;
- register unsigned char *last;
- #ifdef DPS
- int dummy, useDPS;
- #endif
- #ifdef GSBIT
- FILE *ppmfile, *gsfile;
- char *ppmnam;
- int useGS;
- #endif
- int usePV;
- #ifdef DPS
- useDPS = 0;
- #endif
- #ifdef GSBIT
- useGS = 0;
- #endif
- usePV = 0;
-
- /* don't touch the flipped flag - caller has already set it */
- eps->bitmap = (unsigned char *) NULL;
- eps->hw_ratio = 0.0;
- eps->size_x = 0;
- eps->size_y = 0;
- eps->bit_size.x = 0;
- eps->bit_size.y = 0;
- eps->pixmap = (Pixmap) NULL;
- eps->pix_rotation = 0;
- eps->pix_width = 0;
- eps->pix_height = 0;
- eps->pix_flipped = 0;
-
- epsf = fopen(eps->file, "r");
- if (epsf == NULL) {
- file_msg("Cannot open file: %s", eps->file);
- return 0;
- }
- while (fgets(buf, 300, epsf) != NULL) {
- lower(buf);
- if (!strncmp(buf, "%%boundingbox", 13)) {
- /* the Encapsulated PostScript Specifications (2.0) doesn't say
- that the values for the bounding box must be integers */
- float rllx, rlly, rurx, rury;
- if (sscanf(buf, "%%%%boundingbox: %f %f %f %f",
- &rllx, &rlly, &rurx, &rury) < 4) {
- file_msg("Bad EPS file: %s", eps->file);
- fclose(epsf);
- return 0;
- }
- llx = round(rllx);
- lly = round(rlly);
- urx = round(rurx);
- ury = round(rury);
- break;
- }
- }
-
- eps->hw_ratio = (float) (ury - lly) / (float) (urx - llx);
- eps->size_x = (urx - llx) * PIX_PER_INCH / 72.0;
- eps->size_y = (ury - lly) * PIX_PER_INCH / 72.0;
-
- if ( bad_bbox = ( urx <= llx || ury <= lly ) ) {
- file_msg("Bad values in EPS bounding box");
- }
- bitmapz = 0;
-
- #ifdef DPS
- /* if Display PostScript on server */
- if (XQueryExtension(tool_d,"DPSExtension",&dummy,&dummy,&dummy)) {
- eps->bit_size.x = eps->size_x;
- eps->bit_size.y = eps->size_y;
- bitmapz = 1;
- useDPS = 1;
- /* else if no Display PostScript */
- } else {
- #endif
- /* look for a preview bitmap */
- while (fgets(buf, 300, epsf) != NULL) {
- lower(buf);
- if (!strncmp(buf, "%%beginpreview", 14)) {
- sscanf(buf, "%%%%beginpreview: %d %d %d",
- &eps->bit_size.x, &eps->bit_size.y, &bitmapz);
- bitmapz = 1;
- usePV = 1;
- break;
- }
- }
- #ifdef GSBIT
- /* if GhostScript exists */
- if (!bitmapz && !bad_bbox && (gsfile = popen("gs -sDEVICE=bit -q -","w" ))) {
- ppmnam = tempnam(NULL,"xfig");
- eps->bit_size.x = urx - llx + 1;
- eps->bit_size.y = ury - lly + 1;
- bitmapz = 1;
- useGS = 1;
- }
- #endif
- #ifdef DPS
- }
- #endif
- if (!bitmapz) {
- file_msg("EPS object read OK, but no preview bitmap found/generated");
- fclose(epsf);
- return 0;
- } else if ( eps->bit_size.x <= 0 || eps->bit_size.y <= 0 ) {
- file_msg("Strange bounding-box/bitmap-size error, no bitmap found/generated");
- fclose(epsf);
- #ifdef GSBIT
- if ( useGS )
- pclose( gsfile );
- #endif
- return 0;
- } else {
- nbitmap = (eps->bit_size.x + 7) / 8 * eps->bit_size.y;
- eps->bitmap = (unsigned char *) malloc(nbitmap);
- if (eps->bitmap == NULL) {
- file_msg("Could not allocate %d bytes of memory for EPS bitmap\n",
- nbitmap);
- fclose(epsf);
- #ifdef GSBIT
- if ( useGS )
- pclose( gsfile );
- #endif
- return 0;
- }
- }
- #ifdef DPS
- /* if Display PostScript */
- if ( useDPS ) {
- static int bitmapDPS (FILE*,int,int,int,int,int,int,int,unsigned char *);
- if (!bitmapDPS(epsf,llx,lly,urx,ury,
- eps->size_x,eps->size_y,nbitmap,eps->bitmap)) {
- file_msg("DPS extension failed to generate EPS bitmap\n");
- fclose(epsf);
- return 0;
- }
- }
- #endif
- #ifdef GSBIT
- /* if GhostScript */
- if ( useGS ) {
- ppmnam = tempnam("/usr/tmp","xfig");
- fprintf(gsfile, "[1 0 0 1 0 0] %d %d <ff 00>\n", eps->bit_size.x,
- eps->bit_size.y);
- fprintf(gsfile, "makeimagedevice setdevice\n");
- fprintf(gsfile, "0 %d translate 1 -1 scale\n", eps->bit_size.y);
- fprintf(gsfile, "%d neg %d neg translate\n", llx, lly);
- fprintf(gsfile, "/showpage {null exec} def (%s) run\n", eps->file);
- fprintf(gsfile, "(%s) (w) file currentdevice writeppmfile quit\n",
- ppmnam);
- if ( pclose(gsfile) != 0 || ( ppmfile = fopen(ppmnam,"r") ) == NULL ) {
- put_msg( "Could not parse EPS file with GS: %s", eps->file);
- free(eps->bitmap); eps->bitmap = NULL;
- unlink(ppmnam);
- return 0;
- }
- fgets(buf, 300, ppmfile);
- fgets(buf, 300, ppmfile);
- fgets(buf, 300, ppmfile);
- if ( fread(eps->bitmap,nbitmap,1,ppmfile) != 1 ) {
- put_msg("Error reading ppm file (EPS problems?): %s", ppmnam);
- fclose(ppmfile); unlink(ppmnam);
- free(eps->bitmap); eps->bitmap = NULL;
- return 0;
- }
- fclose(ppmfile); unlink(ppmnam);
- }
- #endif
- if ( usePV ) {
- mp = eps->bitmap;
- bzero(mp, nbitmap); /* init bitmap to zero */
- last = eps->bitmap + nbitmap;
- flag = True;
- while (fgets(buf, 300, epsf) != NULL && mp < last) {
- lower(buf);
- if (!strncmp(buf, "%%endpreview", 12) ||
- !strncmp(buf, "%%endimage", 10))
- break;
- cp = buf;
- if (*cp != '%')
- break;
- cp++;
- while (*cp != '\0') {
- if (isxdigit(*cp)) {
- hexnib = hex(*cp);
- if (flag) {
- flag = False;
- *mp = hexnib << 4;
- } else {
- flag = True;
- *mp = *mp + hexnib;
- mp++;
- if (mp >= last)
- break;
- }
- }
- cp++;
- }
- }
- }
- put_msg("EPS object read OK");
- fclose(epsf);
- return 1;
- }
-
- int
- hex(c)
- char c;
- {
- if (isdigit(c))
- return (c - 48);
- else
- return (c - 87);
- }
-
- lower(buf)
- char *buf;
- {
- while (*buf) {
- if (isupper(*buf))
- *buf = (char) tolower(*buf);
- buf++;
- }
- }
-
- /* Display PostScript */
- #ifdef DPS
-
- #ifdef sgi
- #include <X11/extensions/XDPS.h>
- #include <X11/extensions/XDPSlib.h>
- #include <X11/extensions/dpsXclient.h>
- #else
- #include <DPS/XDPS.h>
- #include <DPS/XDPSlib.h>
- #include <DPS/dpsXclient.h>
- #endif
-
- #define LBUF 1000
-
- static
- int bitmapDPS (FILE *fp, int llx, int lly, int urx, int ury,
- int width, int height, int nbitmap, unsigned char *bitmap)
- {
- Display *dpy=tool_d;
- int scr=tool_sn;
- unsigned long black=BlackPixel(dpy,scr),white=WhitePixel(dpy,scr);
- char buf[LBUF];
- unsigned char *bp,*dp;
- int line,byte,nbyte;
- int scrwidth,scrheight,scrwidthmm,scrheightmm;
- float dppi;
- GC gcbit;
- Colormap cm;
- Pixmap bit;
- XColor color;
- XStandardColormap *scm;
- XImage *image;
- DPSContext dps;
-
- /* create bit pixmap and its GC */
- bit = XCreatePixmap(dpy,DefaultRootWindow(dpy),width,height,
- DefaultDepthOfScreen(tool_s));
- gcbit = XCreateGC(dpy,bit,0,NULL);
-
- /* create standard colormap for black-and-white only */
- cm = XCreateColormap(dpy,RootWindow(dpy,scr),
- DefaultVisual(dpy,scr),AllocAll);
- color.pixel = 0;
- color.red = color.green = color.blue = 0;
- color.flags = DoRed | DoGreen | DoBlue;
- XStoreColor(dpy,cm,&color);
- color.pixel = 1;
- color.red = color.green = color.blue = 65535;
- color.flags = DoRed | DoGreen | DoBlue;
- XStoreColor(dpy,cm,&color);
- scm = XAllocStandardColormap();
- scm->colormap = cm;
- scm->red_max = 1;
- scm->red_mult = 1;
- scm->base_pixel = 0;
- scm->visualid = XVisualIDFromVisual(DefaultVisual(dpy,scr));
-
- /* create and set Display PostScript context for bit pixmap */
- dps = XDPSCreateContext(dpy,bit,gcbit,0,height,0,scm,NULL,0,
- DPSDefaultTextBackstop,DPSDefaultErrorProc,NULL);
- if (dps==NULL) {
- file_msg("Cannot create Display PostScript context!");
- return 0;
- }
- DPSPrintf(dps,"\n resyncstart\n");
- DPSSetContext(dps);
- DPSFlushContext(dps);
- DPSWaitContext(dps);
-
- /* display pixels per inch */
- scrwidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
- scrheight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
- scrwidthmm = WidthMMOfScreen(DefaultScreenOfDisplay(dpy));
- scrheightmm = HeightMMOfScreen(DefaultScreenOfDisplay(dpy));
- dppi = 0.5*((int)(25.4*scrwidth/scrwidthmm)+
- (int)(25.4*scrheight/scrheightmm));
-
- /* scale */
- DPSPrintf(dps,"%f %f scale\n",PIX_PER_INCH/dppi,PIX_PER_INCH/dppi);
-
- /* paint white background */
- DPSPrintf(dps,
- "gsave\n 1 setgray\n 0 0 %d %d rectfill\n grestore\n",
- urx-llx+2,ury-lly+2);
-
- /* translate */
- DPSPrintf(dps,"%d %d translate\n",-llx,-lly);
-
- /* read PostScript from standard input and render in bit pixmap */
- DPSPrintf(dps,"/showpage {} def\n");
- while (fgets(buf,LBUF,fp)!=NULL)
- DPSWritePostScript(dps,buf,strlen(buf));
- DPSFlushContext(dps);
- DPSWaitContext(dps);
-
- /* get image from bit pixmap */
- image = XGetImage(dpy,bit,0,0,width,height,1,XYPixmap);
-
- /* copy bits from image to bitmap */
- bzero(bitmap,nbitmap);
- nbyte = (width+7)/8;
- for (line=0; line<height; ++line) {
- bp = bitmap+line*nbyte;
- dp = (unsigned char*)(image->data+line*image->bytes_per_line);
- for (byte=0; byte<nbyte; ++byte)
- *bp++ = ~(*dp++);
- }
-
- /* clean up */
- DPSDestroySpace(DPSSpaceFromContext(dps));
- XFreePixmap(dpy,bit);
- XFreeColormap(dpy,cm);
- XFreeGC(dpy,gcbit);
- XDestroyImage(image);
- }
- #endif /* DPS */
-