home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xv310a / xvps.c < prev    next >
Text File  |  1995-06-12  |  49KB  |  1,715 lines

  1. /* 
  2.  * xvps.c - Postscript dialog box, file output functions
  3.  *
  4.  * callable functions:
  5.  *
  6.  *   CreatePSD(geom)           -  creates the psW window.  Doesn't map it.
  7.  *   PSDialog()                -  maps psW
  8.  *   PSCheckEvent(event)       -  called by event handler
  9.  *   PSSaveParams(str,int)     -  tells PSDialog what to do when 'Ok' clicked
  10.  *   PSResize()                -  called whenever ePic changes size
  11.  *   LoadPS()                  -  attempts to load PS files using Ghostscript
  12.  */
  13.  
  14. #include "copyright.h"
  15.  
  16. #define NEEDSDIR
  17. #include "xv.h"
  18.  
  19. #define PSWIDE 431
  20. #define PSHIGH 350
  21. #define PMAX   200    /* size of square that a 'page' has to fit into */
  22.  
  23. #define PS_BOK    0
  24. #define PS_BCANC  1
  25. #define PS_BCENT  2
  26. #define PS_BORG   3
  27. #define PS_BMAX   4
  28. #define PS_BPOSX  5
  29. #define PS_BPOSY  6
  30. #define PS_NBUTTS 7
  31.  
  32.  
  33. /* paperRB indicies */
  34. #define PSZ_NORM  0
  35. #define PSZ_A4    1
  36. #define PSZ_B5    2
  37. #define PSZ_A3    3
  38. #define PSZ_LEGAL 4
  39. #define PSZ_BSIZE 5
  40. #define PSZ_4BY5  6
  41. #define PSZ_35MM  7
  42.  
  43. /* orientRB indicies */
  44. #define ORNT_PORT 0
  45. #define ORNT_LAND 1
  46.  
  47. #define BUTTH 24
  48.  
  49. #define IN2CM 2.54
  50.  
  51. #define PIX2INCH 72.0   /* # of pixels per inch, at 100% scaling */
  52.  
  53. static void drawPSD        PARM((int, int, int, int));
  54. static void drawPosStr     PARM((void));
  55. static void drawSizeStr    PARM((void));
  56. static void drawResStr     PARM((void));
  57. static void drawPage       PARM((void));
  58. static void clickPSD       PARM((int, int));
  59. static void clickPage      PARM((int, int));
  60. static void doCmd          PARM((int));
  61. static void changedScale   PARM((void));
  62. static void setScale       PARM((void));
  63. static void changedPaper   PARM((void));
  64. static void setPaper       PARM((void));
  65. static void drawIRect      PARM((int));
  66. static void centerImage    PARM((void));
  67. static void maxImage       PARM((void));
  68. static void moveImage      PARM((double, double));
  69. static void writePS        PARM((void));
  70. static int  rle_encode     PARM((byte *, byte *, int));
  71. static void psColorImage   PARM((FILE *));
  72. static void psColorMap     PARM((FILE *fp, int, int, byte *, byte *, byte *));
  73. static void psRleCmapImage PARM((FILE *, int));
  74. static void epsPreview     PARM((FILE *, byte *, int, int, int, int, 
  75.                  byte *, byte *, byte *, int));
  76. static int  writeBWStip    PARM((FILE *, byte *, char *, int, int, int));
  77.  
  78.  
  79.  
  80. /* local variables */
  81. static Window pageF;
  82. static DIAL   xsDial, ysDial;
  83. static RBUTT *orientRB, *paperRB;
  84. static CBUTT  lockCB;
  85. static BUTT   psbut[PS_NBUTTS];
  86. static double sz_inx, sz_iny;     /* image size, in inches */
  87. static double pos_inx, pos_iny;   /* top-left offset of image, in inches */
  88. static int    dpix, dpiy;         /* # of image pixels per inch */
  89. static int    tracking=0;         /* used in changedScale */
  90. static int    posxType, posyType;
  91.  
  92. /* sizes of pages in inches */
  93. static double paperSize[8][2] = { { 8.500, 11.000},   /* US NORMAL */
  94.                   { 8.268, 11.693},   /* A4 210mm x 297mm */
  95.                   { 7.205, 10.118},   /* B5 183mm x 257mm */
  96.                   {11.693, 16.535},   /* A3 297mm x 420mm */
  97.                   { 8.500, 14.000},   /* US LEGAL */
  98.                   {11.000, 17.000},   /* B-size */
  99.                   { 3.875,  4.875},   /* 4 by 5 */
  100.                   { 0.945,  1.417}};  /* 35mm (24x36) */
  101.  
  102. /* size of l+r margin and t+b margin.  image is centered */
  103. static double margins[8][2] = { { 1.000, 1.000},   /* US NORMAL */
  104.                 { 1.000, 1.000},   /* A4 */
  105.                 { 1.000, 1.000},   /* B5 */
  106.                 { 1.000, 1.000},   /* A3 */
  107.                 { 1.000, 1.000},   /* US LEGAL */
  108.                 { 1.000, 1.000},   /* B-size */
  109.                 { 0.275, 0.275},   /* 4 by 5 */
  110.                 { 0.078, 0.078}};  /* 35mm (24x36) */
  111.  
  112.  
  113. static double psizex, psizey;   /* current paper size, in inches */
  114. static double in2pix;           /* inch to pixels in 'pageF' */
  115. static XRectangle pageRect;     /* bounding rect of page, in screen coords */
  116.  
  117. static char *filename;          /* filename to save to */
  118. static int   colorType;         /* value of 'Colors' rbutt in dir box */
  119. static int   firsttime=1;       /* first time PSDialog being opened ? */
  120.  
  121.  
  122. /***************************************************/
  123. void CreatePSD(geom)
  124. char *geom;
  125. {
  126.   psW = CreateWindow("xv postscript", "XVps", geom, 
  127.              PSWIDE, PSHIGH, infofg, infobg, 0);
  128.   if (!psW) FatalError("can't create postscript window!");
  129.  
  130.   pageF = XCreateSimpleWindow(theDisp, psW, 20,30, PMAX+1,PMAX+1,
  131.                   1,infofg,infobg);
  132.   if (!pageF) FatalError("couldn't create frame windows");
  133.  
  134.   XSetWindowBackgroundPixmap(theDisp, pageF, grayTile);
  135.  
  136.   XSelectInput(theDisp, pageF, ExposureMask | ButtonPressMask);
  137.   XSelectInput(theDisp, psW,   ExposureMask | ButtonPressMask | KeyPressMask);
  138.  
  139.   CBCreate(&encapsCB, psW, 240, 7, "preview", infofg, infobg, hicol, locol);
  140.   CBCreate(&pscompCB, psW, 331, 7, "compress", infofg, infobg, hicol, locol);
  141.  
  142.   DCreate(&xsDial, psW, 240, 30, 80, 100, 10, 800, 100, 5, 
  143.       infofg, infobg, hicol, locol, "Width", "%");
  144.   DCreate(&ysDial, psW, 331, 30, 80, 100, 10, 800, 100, 5, 
  145.       infofg, infobg, hicol, locol, "Height", "%");
  146.   xsDial.drawobj = changedScale;
  147.   ysDial.drawobj = changedScale;
  148.  
  149.   CBCreate(&lockCB, psW, 318, 134, "", infofg, infobg, hicol, locol);
  150.   lockCB.val = 1;
  151.  
  152.   orientRB = RBCreate(NULL, psW, 36, 240+18, "Portrait", infofg, infobg,
  153.               hicol, locol);
  154.   RBCreate(orientRB, psW, 36+80, 240+18, "Landscape", infofg, infobg,
  155.        hicol, locol);
  156.  
  157.   paperRB = RBCreate(NULL, psW,36, 240+18+36, "8.5\"x11\"", 
  158.              infofg, infobg, hicol, locol);
  159.   RBCreate(paperRB, psW, 36+80,    240+18+36, "A4",
  160.        infofg, infobg, hicol, locol);
  161.   RBCreate(paperRB, psW, 36+122,   240+18+36, "B5",         
  162.        infofg, infobg, hicol, locol);
  163.   RBCreate(paperRB, psW, 36+164,   240+18+36, "A3",         
  164.        infofg, infobg, hicol, locol);
  165.   RBCreate(paperRB, psW, 36,       240+36+36, "8.5\"x14\"",
  166.        infofg, infobg, hicol, locol);
  167.   RBCreate(paperRB, psW, 36+80,    240+36+36, "11\"x17\"",  
  168.        infofg, infobg, hicol, locol);
  169.   RBCreate(paperRB, psW, 36,       240+54+36, "4\"x5\"",    
  170.        infofg, infobg, hicol, locol);
  171.   RBCreate(paperRB, psW, 36+80,    240+54+36, "35mm slide", 
  172.        infofg, infobg, hicol, locol);
  173.  
  174.   BTCreate(&psbut[PS_BOK], psW, PSWIDE-180, PSHIGH-10-BUTTH, 80, BUTTH, 
  175.        "Ok", infofg, infobg, hicol, locol);
  176.   BTCreate(&psbut[PS_BCANC], psW, PSWIDE-90, PSHIGH-10-BUTTH, 80, BUTTH, 
  177.        "Cancel", infofg, infobg, hicol, locol);
  178.  
  179.   BTCreate(&psbut[PS_BCENT], psW, 240, 154, 55, BUTTH-2, 
  180.        "Center", infofg, infobg, hicol, locol);
  181.   BTCreate(&psbut[PS_BORG], psW,  298, 154, 55, BUTTH-2, 
  182.        "Origin", infofg, infobg, hicol, locol);
  183.   BTCreate(&psbut[PS_BMAX], psW,  356, 154, 55, BUTTH-2, 
  184.        "Max",    infofg, infobg, hicol, locol);
  185.  
  186.   BTCreate(&psbut[PS_BPOSX], psW, 256-14, 190+13-8, 8,8, "", 
  187.        infofg, infobg, hicol, locol);
  188.   BTCreate(&psbut[PS_BPOSY], psW, 256-14, 190+26-8, 8,8, "", 
  189.        infofg, infobg, hicol, locol);
  190.  
  191.   posxType = posyType = 0;
  192.   pos_inx = 1.0;  pos_iny = 1.0;   /* temporary bootstrapping... */
  193.   setPaper();
  194.   setScale();
  195.  
  196.  
  197.   /*** handle PS dialog resources ***/
  198.  
  199.   if (rd_str("pspaper")) {                /* xv.pspaper:  default paper size */
  200.     char buf[256];
  201.     strcpy(buf, def_str);
  202.     lower_str(buf);
  203.  
  204.     if      (!strcmp(buf, "8.5x11")) RBSelect(paperRB, PSZ_NORM);
  205.     else if (!strcmp(buf, "a4"))     RBSelect(paperRB, PSZ_A4);
  206.     else if (!strcmp(buf, "b5"))     RBSelect(paperRB, PSZ_B5);
  207.     else if (!strcmp(buf, "a3"))     RBSelect(paperRB, PSZ_A3);
  208.     else if (!strcmp(buf, "8.5x14")) RBSelect(paperRB, PSZ_LEGAL);
  209.     else if (!strcmp(buf, "11x17"))  RBSelect(paperRB, PSZ_BSIZE);
  210.     else if (!strcmp(buf, "4x5"))    RBSelect(paperRB, PSZ_4BY5);
  211.     else if (!strcmp(buf, "35mm"))   RBSelect(paperRB, PSZ_35MM);
  212.     else {
  213.       fprintf(stderr,"%s: unknown 'pspaper' value:  %s\n",cmd,def_str);
  214.       fprintf(stderr,
  215.           "\tValid choices:  8.5x11 A4 B5 A3 8.5x14 11x17 4x5 35mm\n");
  216.     }
  217.  
  218.     setPaper();
  219.   }
  220.  
  221.   if (rd_str("psorient")) {             /* xv.psorient:  default paper ornt. */
  222.     char buf[256];
  223.     strcpy(buf, def_str);
  224.     lower_str(buf);
  225.  
  226.     if      (!strcmp(buf, "portrait"))  RBSelect(orientRB, ORNT_PORT);
  227.     else if (!strcmp(buf, "landscape")) RBSelect(orientRB, ORNT_LAND);
  228.     else {
  229.       fprintf(stderr,"%s: unknown 'psorient' value:  %s\n",cmd,def_str);
  230.       fprintf(stderr,
  231.           "\tValid choices:  portrait landscape\n");
  232.     }
  233.  
  234.     setPaper();
  235.   }
  236.  
  237.   if (rd_int("psres")) {             /* xv.psres:  default paper resolution */
  238.     if (def_int >= 10 && def_int <= 720) {
  239.       int i = (int) ((PIX2INCH * 100) / def_int);
  240.  
  241.       DSetVal(&xsDial, i);
  242.       DSetVal(&ysDial, i);
  243.     }
  244.   }
  245.  
  246.  
  247.   XMapSubwindows(theDisp, psW);
  248. }
  249.   
  250.  
  251. /***************************************************/
  252. void PSDialog(vis)
  253. int vis;
  254. {
  255.   if (vis) {
  256.     if (picType == PIC24) {  /* no comp in 24-bit mode */
  257.       pscompCB.val = 0;
  258.       CBSetActive(&pscompCB, 0);
  259.     }
  260.     else CBSetActive(&pscompCB, 1);
  261.  
  262.     setScale();
  263.     if (firsttime) centerImage();
  264.     firsttime = 0;
  265.     CenterMapWindow(psW, psbut[PS_BOK].x + (int) psbut[PS_BOK].w/2,
  266.                  psbut[PS_BOK].y + (int) psbut[PS_BOK].h/2,
  267.             PSWIDE, PSHIGH);
  268.   }
  269.   else XUnmapWindow(theDisp, psW);
  270.   psUp = vis;
  271. }
  272.  
  273.  
  274. /***************************************************/
  275. int PSCheckEvent(xev)
  276. XEvent *xev;
  277. {
  278.   /* check event to see if it's for one of our subwindows.  If it is,
  279.      deal accordingly, and return '1'.  Otherwise, return '0' */
  280.  
  281.   int rv;
  282.   rv = 1;
  283.  
  284.   if (!psUp) return 0;
  285.  
  286.   if (xev->type == Expose) {
  287.     int x,y,w,h;
  288.     XExposeEvent *e = (XExposeEvent *) xev;
  289.     x = e->x;  y = e->y;  w = e->width;  h = e->height;
  290.  
  291.     /* throw away excess expose events for 'dumb' windows */
  292.     if (e->count > 0 && 
  293.     (e->window == xsDial.win || e->window == ysDial.win ||
  294.      e->window == pageF)) {}
  295.  
  296.     else if (e->window == psW)         drawPSD(x, y, w, h);
  297.     else if (e->window == xsDial.win)  DRedraw(&xsDial);
  298.     else if (e->window == ysDial.win)  DRedraw(&ysDial);
  299.     else if (e->window == pageF)       drawPage();
  300.     else rv = 0;
  301.   }
  302.  
  303.   else if (xev->type == ButtonPress) {
  304.     XButtonEvent *e = (XButtonEvent *) xev;
  305.     int x,y;
  306.     x = e->x;  y = e->y;
  307.  
  308.     if (e->button == Button1) {
  309.       if      (e->window == psW)   clickPSD(x,y);
  310.       else if (e->window == pageF) clickPage(x,y);
  311.  
  312.       else if (e->window == xsDial.win || e->window == ysDial.win) {
  313.     if (e->window == xsDial.win) {
  314.       tracking = 1;
  315.       DTrack(&xsDial, x,y);
  316.       tracking = 0;
  317.     }
  318.  
  319.     else if (e->window == ysDial.win) {
  320.       tracking = 2;
  321.       DTrack(&ysDial, x,y);
  322.       tracking = 0;
  323.     }
  324.       }
  325.       else rv = 0;
  326.     }  /* button1 */
  327.     else rv = 0;
  328.   }  /* button press */
  329.  
  330.  
  331.   else if (xev->type == KeyPress) {
  332.     XKeyEvent *e = (XKeyEvent *) xev;
  333.     char buf[128];  KeySym ks;
  334.     int  stlen, shift, ck;
  335.     
  336.     stlen = XLookupString(e,buf,128,&ks,(XComposeStatus *) NULL);
  337.     shift = e->state & ShiftMask;
  338.     ck    = CursorKey(ks, shift, 0);
  339.     buf[stlen] = '\0';
  340.  
  341.     RemapKeyCheck(ks, buf, &stlen);
  342.  
  343.     if (e->window == psW) {
  344.       double dx, dy;
  345.       int movekey;
  346.  
  347.       movekey = 0;  dx = dy = 0.0;
  348.  
  349.       if      (ck==CK_LEFT)  { dx = -0.001;  movekey = 1; }
  350.       else if (ck==CK_RIGHT) { dx =  0.001;  movekey = 1; }
  351.       else if (ck==CK_UP)    { dy = -0.001;  movekey = 1; }
  352.       else if (ck==CK_DOWN)  { dy =  0.001;  movekey = 1; }
  353.  
  354.       else if (stlen) {
  355.     if (buf[0] == '\r' || buf[0] == '\n') { /* enter */
  356.       FakeButtonPress(&psbut[PS_BOK]);
  357.     }
  358.     else if (buf[0] == '\033') {            /* ESC */
  359.       FakeButtonPress(&psbut[PS_BCANC]);
  360.     }
  361.       }
  362.  
  363.       if (movekey) {
  364.     if (e->state & ShiftMask) { dx *= 10.0;  dy *= 10.0; }
  365.     moveImage(pos_inx+dx, pos_iny+dy);
  366.       }
  367.     }
  368.     else rv = 0;
  369.   }
  370.   else rv = 0;
  371.  
  372.   if (rv==0 && (xev->type == ButtonPress || xev->type == KeyPress)) {
  373.     XBell(theDisp, 50);
  374.     rv = 1;   /* eat it */
  375.   }
  376.  
  377.   return rv;
  378. }
  379.  
  380.  
  381. /***************************************************/
  382. void PSSaveParams(fname, col)
  383.      char *fname;
  384.      int col;
  385. {
  386.   filename = fname;
  387.   colorType = col;
  388. }
  389.  
  390.  
  391. /***************************************************/
  392. void PSResize()
  393. {
  394.   changedScale();
  395. }
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402. /***************************************************/
  403. static void drawPSD(x,y,w,h)
  404. int x,y,w,h;
  405. {
  406.   char *title = "Save PostScript File...";
  407.   int  i,cx;
  408.   XRectangle xr;
  409.  
  410.   xr.x = x;  xr.y = y;  xr.width = w;  xr.height = h;
  411.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  412.  
  413.   XSetForeground(theDisp, theGC, infofg);
  414.   XSetBackground(theDisp, theGC, infobg);
  415.  
  416.   RBRedraw(orientRB,-1);
  417.   RBRedraw(paperRB,-1);
  418.  
  419.   for (i=0; i<PS_NBUTTS; i++) BTRedraw(&psbut[i]);
  420.  
  421.   CBRedraw(&encapsCB);
  422.   if (colorType != F_BWDITHER && picType!=PIC24) CBRedraw(&pscompCB);
  423.   CBRedraw(&lockCB);
  424.  
  425.   ULineString(psW, orientRB->x-16, orientRB->y-3-DESCENT, "Orientation:");
  426.   ULineString(psW, paperRB->x-16,   paperRB->y-3-DESCENT, "Paper Size:");
  427.  
  428.   /* draw 'lock' arrows */
  429.   cx = 240 + 40;  /* center of xsDial */
  430.   XDrawLine(theDisp, psW, theGC, lockCB.x, lockCB.y+6,  cx+2, lockCB.y+6);
  431.   XDrawLine(theDisp, psW, theGC, cx+2, lockCB.y+6, cx+2, lockCB.y-2);
  432.  
  433.   XDrawLine(theDisp, psW, theGC, lockCB.x, lockCB.y+10,  cx-2, lockCB.y+10);
  434.   XDrawLine(theDisp, psW, theGC, cx-2, lockCB.y+10, cx-2, lockCB.y-2);
  435.  
  436.   XDrawLine(theDisp, psW, theGC, cx-2-3, lockCB.y-2+3, cx, lockCB.y-2-2);
  437.   XDrawLine(theDisp, psW, theGC, cx+2+3, lockCB.y-2+3, cx, lockCB.y-2-2);
  438.  
  439.   cx = 330 + 40;  /* center of ysDial */
  440.   XDrawLine(theDisp, psW, theGC, lockCB.x+17, lockCB.y+6,  cx-2, lockCB.y+6);
  441.   XDrawLine(theDisp, psW, theGC, cx-2, lockCB.y+6, cx-2, lockCB.y-2);
  442.  
  443.   XDrawLine(theDisp, psW, theGC, lockCB.x+17, lockCB.y+10,  cx+2, lockCB.y+10);
  444.   XDrawLine(theDisp, psW, theGC, cx+2, lockCB.y+10, cx+2, lockCB.y-2);
  445.  
  446.   XDrawLine(theDisp, psW, theGC, cx-2-3, lockCB.y-2+3, cx, lockCB.y-2-2);
  447.   XDrawLine(theDisp, psW, theGC, cx+2+3, lockCB.y-2+3, cx, lockCB.y-2-2);
  448.  
  449.   DrawString(psW, 10, 19, title);
  450.  
  451.   ULineString(psW, 240, 190,    "Position:");
  452.   drawPosStr();
  453.   ULineString(psW, 240, 190+45, "Size:");
  454.   drawSizeStr();
  455.   ULineString(psW, 240, 190+90, "Resolution:");
  456.   drawResStr();
  457.  
  458.  
  459.   XSetClipMask(theDisp, theGC, None);
  460. }
  461.  
  462.  
  463. /***************************************************/
  464. static void drawPosStr()
  465. {
  466.   int x,y;
  467.   double cmx, cmy, inx, iny;
  468.   char   str[64], str1[64], *xst, *yst;
  469.  
  470.   x = 256;  y = 190 + 13;
  471.   inx = iny = 0;  xst = yst = (char *) NULL;
  472.  
  473.   switch (posxType) {
  474.   case 0:  xst = "Left: ";  inx = pos_inx;                      break;
  475.   case 1:  xst = "Right:";  inx = psizex - (pos_inx + sz_inx);  break;
  476.   case 2:  xst = "X Mid:";  inx = pos_inx + sz_inx/2;           break;
  477.   }
  478.  
  479.   switch (posyType) {
  480.   case 0:  yst = "Top:  ";  iny = pos_iny;                      break;
  481.   case 1:  yst = "Bot:  ";  iny = psizey - (pos_iny + sz_iny);  break;
  482.   case 2:  yst = "Y Mid:";  iny = pos_iny + sz_iny/2;           break;
  483.   }
  484.  
  485.   cmx = inx * IN2CM;
  486.   cmy = iny * IN2CM;
  487.  
  488.   sprintf(str,  "%s %.3f\" (%.2fcm)       ", xst, inx, cmx);
  489.   sprintf(str1, "%s %.3f\" (%.2fcm)       ", yst, iny, cmy);
  490.  
  491.   XSetForeground(theDisp, theGC, infofg);
  492.   XSetBackground(theDisp, theGC, infobg);
  493.  
  494.   XSetFont(theDisp, theGC, monofont);
  495.   XDrawImageString(theDisp, psW, theGC, x, y,    str,  (int) strlen(str));
  496.   XDrawImageString(theDisp, psW, theGC, x, y+13, str1, (int) strlen(str1));
  497.   XSetFont(theDisp, theGC, mfont);
  498. }
  499.  
  500.   
  501. /***************************************************/
  502. static void drawSizeStr()
  503. {
  504.   int x,y;
  505.   double cmx, cmy;
  506.   char   str[64], str1[64];
  507.  
  508.   x = 256;  y = 190+13+45;
  509.  
  510.   cmx = sz_inx * IN2CM;
  511.   cmy = sz_iny * IN2CM;
  512.  
  513.   sprintf(str,  "%.3f\" x %.3f\"        ", sz_inx, sz_iny);
  514.   sprintf(str1, "%.2fcm x %.2fcm        ", cmx, cmy);
  515.  
  516.   XSetForeground(theDisp, theGC, infofg);
  517.   XSetBackground(theDisp, theGC, infobg);
  518.   XSetFont(theDisp, theGC, monofont);
  519.  
  520.   XDrawImageString(theDisp, psW, theGC, x, y,    str,  (int) strlen(str));
  521.   XDrawImageString(theDisp, psW, theGC, x, y+13, str1, (int) strlen(str1));
  522.   XSetFont(theDisp, theGC, mfont);
  523. }
  524.  
  525.   
  526. /***************************************************/
  527. static void drawResStr()
  528. {
  529.   int x,y;
  530.   char   str[64];
  531.  
  532.   x = 256;  y = 190 + 13 + 90;
  533.  
  534.   sprintf(str,  "%ddpi x %ddpi        ", dpix, dpiy);
  535.  
  536.   XSetForeground(theDisp, theGC, infofg);
  537.   XSetBackground(theDisp, theGC, infobg);
  538.   XSetFont(theDisp, theGC, monofont);
  539.   XDrawImageString(theDisp, psW, theGC, x, y, str, (int) strlen(str));
  540.   XSetFont(theDisp, theGC, mfont);
  541. }
  542.  
  543.   
  544.   
  545.   
  546. /***************************************************/
  547. static void drawPage()
  548. {
  549.   /* draw page */
  550.   XSetForeground(theDisp, theGC, infobg);
  551.   XFillRectangle(theDisp, pageF, theGC, pageRect.x+1, pageRect.y+1,
  552.          (u_int) pageRect.width-1, (u_int) pageRect.height-1);
  553.  
  554.   XSetForeground(theDisp, theGC, infofg);
  555.   XDrawRectangle(theDisp, pageF, theGC, pageRect.x, pageRect.y,
  556.          (u_int) pageRect.width, (u_int) pageRect.height);
  557.   
  558.   drawIRect(1);
  559. }
  560.  
  561.  
  562. /***************************************************/
  563. static void clickPSD(x,y)
  564. int x,y;
  565. {
  566.   int i;
  567.   BUTT *bp;
  568.  
  569.   /* check BUTTs */
  570.  
  571.   for (i=0; i<PS_NBUTTS; i++) {
  572.     bp = &psbut[i];
  573.     if (PTINRECT(x, y, bp->x, bp->y, bp->w, bp->h)) break;
  574.   }
  575.  
  576.   if (i<PS_NBUTTS) {  /* found one */
  577.     if (BTTrack(bp)) doCmd(i);
  578.   }
  579.  
  580.   /* check RBUTTs */
  581.  
  582.   else if ((i=RBClick(orientRB,x,y)) >= 0) {
  583.     if (RBTrack(orientRB, i)) changedPaper();
  584.   }
  585.  
  586.   else if ((i=RBClick(paperRB,x,y)) >= 0) {
  587.     if (RBTrack(paperRB, i)) changedPaper();
  588.   }
  589.  
  590.   /* check CBUTTs */
  591.  
  592.   else if (CBClick(&lockCB,x,y)) {
  593.     if (CBTrack(&lockCB) && lockCB.val) {  /* turned on lock */
  594.       DSetVal(&ysDial, xsDial.val);        /* copy xsDial.val to ysDial */
  595.       changedScale();
  596.     }
  597.   }
  598.  
  599.   else if (CBClick(&encapsCB,x,y)) CBTrack(&encapsCB);
  600.   else if (CBClick(&pscompCB,x,y)) CBTrack(&pscompCB);
  601. }
  602.  
  603.  
  604.  
  605. /***************************************************/
  606. static void clickPage(mx,my)
  607. int mx,my;
  608. {
  609.   Window       rW,cW;
  610.   int          rx,ry,x,y;
  611.   unsigned int mask;
  612.   double       offx, offy, newx, newy;
  613.  
  614.   /* compute offset (in inches) between 'drag point' and 
  615.      the top-left corner of the image */
  616.  
  617.   offx = ((mx - pageRect.x) / in2pix) - pos_inx;
  618.   offy = ((my - pageRect.y) / in2pix) - pos_iny;
  619.  
  620.   /* if clicked outside of image rectangle, ignore */
  621.   if (offx<0.0 || offy < 0.0 || offx>=sz_inx || offy >= sz_iny) return;
  622.  
  623.   while (1) {
  624.     if (XQueryPointer(theDisp,pageF,&rW,&cW,&rx,&ry,&x,&y,&mask)) {
  625.       if (!(mask & Button1Mask)) break;    /* button released */
  626.  
  627.       /* compute new pos_inx, pos_iny based on x,y coords */
  628.       newx = ((x-pageRect.x) / in2pix) - offx;
  629.       newy = ((y-pageRect.y) / in2pix) - offy;
  630.  
  631.       moveImage(newx, newy);
  632.     }
  633.   }
  634. }
  635.  
  636.  
  637.  
  638. /***************************************************/
  639. static void doCmd(cmd)
  640.      int cmd;
  641. {
  642.   char *fullname;
  643.  
  644.   switch (cmd) {
  645.   case PS_BOK:    writePS();    
  646.                   PSDialog(0);
  647.                   fullname = GetDirFullName();
  648.                   if (!ISPIPE(fullname[0])) {
  649.             XVCreatedFile(fullname);
  650.             StickInCtrlList(0);
  651.           }
  652.                   break;
  653.  
  654.   case PS_BCANC:  PSDialog(0);  break;
  655.  
  656.   case PS_BCENT:  drawIRect(0);
  657.                   centerImage();
  658.                   drawIRect(1);
  659.                   drawPosStr();
  660.                   break;
  661.  
  662.   case PS_BORG:   drawIRect(0);
  663.                   pos_inx = 0.0;
  664.                   pos_iny = (psizey - sz_iny);
  665.                   drawIRect(1);
  666.                   drawPosStr();
  667.                   break;
  668.  
  669.   case PS_BMAX:   drawIRect(0);
  670.                   maxImage();
  671.                   drawIRect(1);
  672.                   drawPosStr();
  673.                   drawSizeStr();
  674.                   drawResStr();
  675.                   break;
  676.  
  677.   case PS_BPOSX:  posxType = (posxType + 1) % 3;
  678.                   drawPosStr();
  679.                   break;
  680.  
  681.   case PS_BPOSY:  posyType = (posyType + 1) % 3;
  682.                   drawPosStr();
  683.                   break;
  684.  
  685.   default:        break;
  686.   }
  687. }
  688.  
  689.  
  690. /***************************************************/
  691. static void changedScale()
  692. {
  693.   double oldx,oldy;
  694.  
  695.   drawIRect(0);
  696.  
  697.   if (lockCB.val) {
  698.     if      (tracking == 1) DSetVal(&ysDial, xsDial.val);
  699.     else if (tracking == 2) DSetVal(&xsDial, ysDial.val);
  700.   }
  701.  
  702.   oldx = pos_inx;  oldy = pos_iny;
  703.   setScale();
  704.  
  705.   drawIRect(1);
  706.  
  707.   if (pos_inx != oldx || pos_iny != oldy ||
  708.       posxType != 0 || posyType != 0) drawPosStr();
  709.   drawSizeStr();
  710.   drawResStr();
  711.   XFlush(theDisp);
  712. }
  713.  
  714.  
  715. /***************************************************/
  716. static void setScale()
  717. {
  718.   double hsx, hsy;
  719.  
  720.   int w,h;
  721.  
  722.   GetSaveSize(&w, &h);
  723.  
  724.   sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
  725.   sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);  
  726.  
  727.   /* round to integer .001ths of an inch */
  728.   sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
  729.   sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
  730.  
  731.   dpix = (int) (PIX2INCH / (xsDial.val / 100.0));  
  732.   dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));  
  733.  
  734.   /* make sure 'center' of image is still on page */
  735.   hsx = sz_inx/2;  hsy = sz_iny/2;
  736.   RANGE(pos_inx, -hsx, psizex-hsx);
  737.   RANGE(pos_iny, -hsy, psizey-hsy);
  738.  
  739.   /* round to integer .001ths of an inch */
  740.   pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
  741.   pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
  742.  
  743. }
  744.  
  745.  
  746. /***************************************************/
  747. static void changedPaper()
  748. {
  749.   setPaper();
  750.   XClearWindow(theDisp, pageF);
  751.   centerImage();
  752.   drawPosStr();
  753.   drawPage();
  754. }
  755.  
  756.  
  757. /***************************************************/
  758. static void setPaper()
  759. {
  760.   int    i;
  761.   double tmp;
  762.  
  763.   i = RBWhich(paperRB);
  764.   psizex = paperSize[i][0];
  765.   psizey = paperSize[i][1];
  766.  
  767.   in2pix = (double) PMAX / psizey;
  768.  
  769.   if (RBWhich(orientRB)==ORNT_LAND) {
  770.     tmp = psizex;  psizex = psizey;  psizey = tmp;
  771.   }
  772.  
  773.   pageRect.x = (int) ((PMAX/2) - ((psizex/2.0) * in2pix));
  774.   pageRect.y = (int) ((PMAX/2) - ((psizey/2.0) * in2pix));
  775.   pageRect.width  = (int) (psizex * in2pix);
  776.   pageRect.height = (int) (psizey * in2pix);
  777. }
  778.  
  779.  
  780. /***************************************************/
  781. static void drawIRect(draw)
  782.      int draw;
  783. {
  784.   int x,y,w,h;
  785.   XRectangle xr;
  786.   
  787.   x = pageRect.x + (int) (pos_inx * in2pix);
  788.   y = pageRect.y + (int) (pos_iny * in2pix);
  789.   w = sz_inx * in2pix;
  790.   h = sz_iny * in2pix;
  791.   
  792.   xr.x = pageRect.x + 1;
  793.   xr.y = pageRect.y + 1;
  794.   xr.width  = pageRect.width - 1;
  795.   xr.height = pageRect.height - 1;
  796.   
  797.   if (draw) XSetForeground(theDisp, theGC, infofg);
  798.        else XSetForeground(theDisp, theGC, infobg);
  799.   
  800.   XSetClipRectangles(theDisp, theGC, 0,0, &xr, 1, Unsorted);
  801.   XDrawRectangle(theDisp, pageF, theGC, x, y, (u_int) w, (u_int) h);
  802.   XDrawLine(theDisp, pageF, theGC, x, y, x+w, y+h);
  803.   XDrawLine(theDisp, pageF, theGC, x, y+h, x+w, y);
  804.   XSetClipMask(theDisp, theGC, None);
  805. }
  806.  
  807.  
  808.  
  809. /***************************************************/
  810. static void centerImage()
  811. {
  812.   pos_inx = psizex/2 - sz_inx/2;
  813.   pos_iny = psizey/2 - sz_iny/2;
  814.  
  815.   /* round to integer .001ths of an inch */
  816.   pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
  817.   pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
  818. }
  819.  
  820.  
  821. /***************************************************/
  822. static void maxImage()
  823. {
  824.   double scx, scy;
  825.   int w,h;
  826.  
  827.   GetSaveSize(&w, &h);
  828.  
  829.   sz_inx = psizex - margins[RBWhich(paperRB)][0];
  830.   sz_iny = psizey - margins[RBWhich(paperRB)][1];
  831.  
  832.   /* choose the smaller scaling factor */
  833.   scx = sz_inx / w;
  834.   scy = sz_iny / h;
  835.  
  836.   if (scx < scy) { sz_iny = h * scx; }
  837.             else { sz_inx = w * scy; }
  838.  
  839.   DSetVal(&xsDial, (int) ((100 * (sz_inx * PIX2INCH) / w) + .5));
  840.   DSetVal(&ysDial, xsDial.val);
  841.  
  842.   sz_inx = (double) w / PIX2INCH * (xsDial.val / 100.0);  
  843.   sz_iny = (double) h / PIX2INCH * (ysDial.val / 100.0);  
  844.  
  845.   /* round to integer .001ths of an inch */
  846.   sz_inx = floor(sz_inx * 1000.0 + 0.5) / 1000.0;
  847.   sz_iny = floor(sz_iny * 1000.0 + 0.5) / 1000.0;
  848.  
  849.   dpix = (int) (PIX2INCH / (xsDial.val / 100.0));  
  850.   dpiy = (int) (PIX2INCH / (ysDial.val / 100.0));  
  851.  
  852.   pos_inx = psizex/2 - sz_inx/2;
  853.   pos_iny = psizey/2 - sz_iny/2;
  854.  
  855.   /* round to integer .001ths of an inch */
  856.   pos_inx = floor(pos_inx * 1000.0 + 0.5) / 1000.0;
  857.   pos_iny = floor(pos_iny * 1000.0 + 0.5) / 1000.0;
  858. }
  859.  
  860.  
  861. /***************************************************/
  862. static void moveImage(newx,newy)
  863. double newx, newy;
  864. {
  865.   double hsx, hsy;
  866.  
  867.   hsx = sz_inx/2;  hsy = sz_iny/2;
  868.  
  869.   /* round to integer .001ths of an inch */
  870.   newx = floor(newx * 1000.0 + 0.5) / 1000.0;
  871.   newy = floor(newy * 1000.0 + 0.5) / 1000.0;
  872.  
  873.   /* keep center of image within page limits */
  874.   RANGE(newx, -hsx, psizex-hsx);
  875.   RANGE(newy, -hsy, psizey-hsy);
  876.  
  877.   if (newx != pos_inx || newy != pos_iny) {  /* moved */
  878.     drawIRect(0);
  879.     pos_inx = newx;
  880.     pos_iny = newy;
  881.     drawIRect(1);
  882.     drawPosStr();
  883.   }
  884. }
  885.  
  886.  
  887. /***************************************************/
  888. static void writePS()
  889. {
  890.   FILE *fp;
  891.   int   i, j, q, err, rpix, gpix, bpix, nc, ptype;
  892.   int   iw, ih, ox, oy, slen, lwidth, bits, colorps, w, h, pfree;
  893.   double iwf, ihf;
  894.   byte *inpix, *rmap, *gmap, *bmap;
  895.  
  896.   slen = bits = colorps = 0;
  897.  
  898.  
  899.   fp = OpenOutFile(filename);
  900.   if (!fp) return;
  901.  
  902.   WaitCursor();
  903.   
  904.   inpix = GenSavePic(&ptype, &w, &h, &pfree, &nc, &rmap, &gmap, &bmap);
  905.  
  906.     
  907.   /* printed image will have size iw,ih (in picas) */
  908.   iw = (int) (sz_inx * 72.0 + 0.5);
  909.   ih = (int) (sz_iny * 72.0 + 0.5);   
  910.   iwf = sz_inx * 72.0;
  911.   ihf = sz_iny * 72.0;
  912.  
  913.   /* compute offset to bottom-left of image (in picas) */
  914.   ox = (int) (pos_inx * 72.0 + 0.5);
  915.   oy = (int) ((psizey - (pos_iny + sz_iny)) * 72.0 + 0.5);
  916.  
  917.  
  918.   /*** write PostScript header ***/
  919.  
  920.  
  921.   fprintf(fp,"%%!PS-Adobe-2.0 EPSF-2.0\n");
  922.   fprintf(fp,"%%%%Title: %s\n",filename);
  923.   fprintf(fp,"%%%%Creator: XV %s  -  by John Bradley\n",REVDATE);
  924.  
  925.   if (RBWhich(orientRB)==ORNT_LAND)   /* Landscape mode */
  926.     fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", 
  927.         (int) (pos_iny * 72.0 + 0.5),
  928.         (int) (pos_inx * 72.0 + 0.5),
  929.         (int) (pos_iny * 72.0 + 0.5) + ih,
  930.         (int) (pos_inx * 72.0 + 0.5) + iw);
  931.   else 
  932.     fprintf(fp,"%%%%BoundingBox: %d %d %d %d\n", ox, oy, ox+iw, oy+ih);
  933.  
  934.   fprintf(fp,"%%%%Pages: 1\n");
  935.   fprintf(fp,"%%%%DocumentFonts:\n");
  936.   fprintf(fp,"%%%%EndComments\n");
  937.  
  938.  
  939.   switch (colorType) {
  940.   case F_FULLCOLOR:
  941.   case F_REDUCED:   slen = w*3;      bits = 8;  colorps = 1;  break;
  942.   case F_GREYSCALE: slen = w;        bits = 8;  colorps = 0;  break;
  943.   case F_BWDITHER:  slen = (w+7)/8;  bits = 1;  colorps = 0;  break;
  944.   default:  FatalError("unknown colorType in writePS()");   break;
  945.   }
  946.   
  947.   if (encapsCB.val) epsPreview(fp, inpix, ptype, colorType, w, h,
  948.                    rmap,gmap,bmap, 
  949.                    (RBWhich(orientRB)==ORNT_LAND) );
  950.  
  951.   fprintf(fp,"%%%%EndProlog\n\n");
  952.  
  953.   fprintf(fp,"%%%%Page: 1 1\n\n");
  954.  
  955.   fprintf(fp,"%% remember original state\n");
  956.   fprintf(fp,"/origstate save def\n\n");
  957.  
  958.   fprintf(fp,"%% build a temporary dictionary\n");
  959.   fprintf(fp,"20 dict begin\n\n");
  960.  
  961.   if (colorType == F_BWDITHER || ptype==PIC24 || !pscompCB.val) {
  962.     fprintf(fp,"%% define string to hold a scanline's worth of data\n");
  963.     fprintf(fp,"/pix %d string def\n\n", slen);
  964.   }
  965.  
  966.   /*
  967.    * Add loop invariant strings that should not be defined
  968.    * over and over again inside a loop
  969.    * K. Schnepper DLR FF-DR Oberpfaffenhofen, Mai 12. 1993
  970.    */
  971.   fprintf(fp,"%% define space for color conversions\n");
  972.   fprintf(fp,"/grays %d string def  %% space for gray scale line\n", w);
  973.   fprintf(fp,"/npixls 0 def\n");
  974.   fprintf(fp,"/rgbindx 0 def\n\n");
  975.  
  976.  
  977.   if (RBWhich(orientRB)==ORNT_LAND) {   /* Landscape mode */
  978.     fprintf(fp,"%% print in landscape mode\n");
  979.     fprintf(fp,"90 rotate 0 %d translate\n\n",(int) (-psizey*72.0));
  980.   }
  981.     
  982.   if (RBWhich(paperRB) == PSZ_4BY5 ||
  983.       RBWhich(paperRB) == PSZ_35MM) {
  984.     fprintf(fp,"%% we're going to a 4x5 or a 35mm film recorder.\n");
  985.     fprintf(fp,"%% clear page to black to avoid registration problems\n");
  986.     fprintf(fp,"newpath\n");
  987.     fprintf(fp,"  0 0 moveto\n");
  988.     fprintf(fp,"  0 %d rlineto\n", (int) (psizey * 72.0));
  989.     fprintf(fp,"  %d 0 rlineto\n", (int) (psizex * 72.0));
  990.     fprintf(fp,"  0 %d rlineto\n", (int) (-psizey * 72.0));
  991.     fprintf(fp,"  closepath\n");
  992.     fprintf(fp,"  0 setgray\n");
  993.     fprintf(fp,"  fill\n\n");
  994.   }
  995.  
  996.  
  997.   fprintf(fp,"%% lower left corner\n");
  998.   fprintf(fp,"%d %d translate\n\n",ox,oy);
  999.  
  1000.   fprintf(fp,"%% size of image (on paper, in 1/72inch coords)\n");
  1001.   fprintf(fp,"%.5f %.5f scale\n\n",iwf,ihf);
  1002.  
  1003.   if (colorType == F_BWDITHER) {   /* 1-bit dither code uses 'image' */
  1004.     int flipbw;
  1005.  
  1006.     /* set if color#0 is white */
  1007.     flipbw = (MONO(rmap[0],gmap[0],bmap[0]) > MONO(rmap[1],gmap[1],bmap[1]));
  1008.  
  1009.     fprintf(fp,"%% dimensions of data\n");
  1010.     fprintf(fp,"%d %d %d\n\n",w,h,bits);
  1011.  
  1012.     fprintf(fp,"%% mapping matrix\n");
  1013.     fprintf(fp,"[%d 0 0 %d 0 %d]\n\n", w, -h, h);
  1014.  
  1015.     fprintf(fp,"{currentfile pix readhexstring pop}\n");
  1016.     fprintf(fp,"image\n");
  1017.  
  1018.     /* write the actual image data */
  1019.  
  1020.     err = writeBWStip(fp, inpix, "", w, h, flipbw);
  1021.   }
  1022.  
  1023.   else {      /* all other formats */
  1024.     byte *rleline = (byte *) NULL;
  1025.     unsigned long outbytes = 0;
  1026.  
  1027.     /* if we're using color, make sure 'colorimage' is defined */
  1028.     if (colorps) psColorImage(fp);
  1029.  
  1030.     if (ptype==PIC8 && pscompCB.val) {  /* write cmap & rle-cmapped image fn */
  1031.       psColorMap(fp, colorps, nc, rmap, gmap, bmap);
  1032.       psRleCmapImage(fp, colorps);
  1033.     }
  1034.  
  1035.     fprintf(fp,"%d %d %d\t\t\t%% dimensions of data\n",w,h,bits);
  1036.     fprintf(fp,"[%d 0 0 %d 0 %d]\t\t%% mapping matrix\n", w, -h, h);
  1037.  
  1038.     if (ptype==PIC8 && pscompCB.val) fprintf(fp,"rlecmapimage\n");
  1039.     else {
  1040.       fprintf(fp,"{currentfile pix readhexstring pop}\n");
  1041.       if (colorps) fprintf(fp,"false 3 colorimage\n");
  1042.               else fprintf(fp,"image\n");
  1043.     }
  1044.  
  1045.     /* dump the image data to the file */
  1046.     err = 0;
  1047.  
  1048.     if (ptype==PIC8 && pscompCB.val) {
  1049.       rleline  = (byte *) malloc((size_t) w * 2);  /* worst-case */
  1050.       if (!rleline) FatalError("unable to malloc rleline in writePS()\n");
  1051.     }
  1052.  
  1053.     for (i=0; i<h && err != EOF; i++) {
  1054.       int rlen;
  1055.       lwidth = 0;
  1056.       putc('\n',fp);
  1057.  
  1058.       if ((i&0x1f) == 0) WaitCursor();
  1059.  
  1060.       if (ptype==PIC8 && pscompCB.val) { /* write rle-encoded cmapped image */
  1061.     rlen = rle_encode(inpix, rleline, w);
  1062.     inpix += w;
  1063.     outbytes += rlen;
  1064.  
  1065.     for (j=0; j<rlen && err != EOF; j++) {
  1066.       err = fprintf(fp,"%02x", rleline[j]);
  1067.       lwidth += 2;
  1068.  
  1069.       if (lwidth>70) { putc('\n',fp); lwidth = 0; }
  1070.     }
  1071.       }
  1072.  
  1073.       else {  /* write non-rle raw (gray/rgb) image data */
  1074.     for (j=0; j<w && err != EOF; j++) {
  1075.  
  1076.       if (ptype == PIC8) {
  1077.         rpix = rmap[*inpix];
  1078.         gpix = gmap[*inpix];
  1079.         bpix = bmap[*inpix];
  1080.       }
  1081.       else {  /* PIC24 */
  1082.         rpix = inpix[0];
  1083.         gpix = inpix[1];
  1084.         bpix = inpix[2];
  1085.       }
  1086.       
  1087.       if (colorps) { 
  1088.         err = fprintf(fp,"%02x%02x%02x",rpix,gpix,bpix);
  1089.         lwidth+=6;
  1090.       }
  1091.       
  1092.       else {  /* greyscale */
  1093.         err = fprintf(fp,"%02x", MONO(rpix,gpix,bpix));
  1094.         lwidth+=2;
  1095.       }
  1096.  
  1097.       if (lwidth>70) { putc('\n',fp); lwidth = 0; }
  1098.  
  1099.       inpix += (ptype==PIC24) ? 3 : 1;
  1100.     }
  1101.       }
  1102.     }
  1103.  
  1104.     if (ptype==PIC8 && pscompCB.val) {
  1105.       free(rleline);
  1106.       fprintf(fp,"\n\n");
  1107.       fprintf(fp,"%%\n");
  1108.       fprintf(fp,"%% Compression made this file %.2f%% %s\n",
  1109.           100.0 * ((double) outbytes) / 
  1110.           ((double) eWIDE * eHIGH * ((colorps) ? 3 : 1)),
  1111.           "of the uncompressed size.");
  1112.       fprintf(fp,"%%\n");
  1113.     }
  1114.   }
  1115.  
  1116.  
  1117.   fprintf(fp,"\n\nshowpage\n\n");
  1118.  
  1119.   fprintf(fp,"%% stop using temporary dictionary\n");
  1120.   fprintf(fp,"end\n\n");
  1121.  
  1122.   fprintf(fp,"%% restore original state\n");
  1123.   fprintf(fp,"origstate restore\n\n");
  1124.   fprintf(fp,"%%%%Trailer\n");
  1125.  
  1126.   if (pfree) free(inpix);
  1127.  
  1128.   if (CloseOutFile(fp, filename, (err==EOF)) == 0) {
  1129.     DirBox(0);
  1130.   }
  1131.  
  1132.   SetCursors(-1);
  1133. }
  1134.  
  1135.  
  1136. /**********************************************/
  1137. static int rle_encode(scanline, rleline, wide)
  1138.      byte *scanline, *rleline;
  1139.      int wide;
  1140. {
  1141.   /* generates a rle-compressed version of the scan line.
  1142.    * rle is encoded as such:
  1143.    *    <count> <value>                      # 'run' of count+1 equal pixels
  1144.    *    <count | 0x80> <count+1 data bytes>  # count+1 non-equal pixels
  1145.    *
  1146.    * count can range between 0 and 127
  1147.    *
  1148.    * returns length of the rleline vector
  1149.    */
  1150.   
  1151.   int  i, j, blocklen, isrun, rlen;
  1152.   byte block[256], pix;
  1153.   
  1154.   blocklen = isrun = rlen = 0;
  1155.  
  1156.   for (i=0; i<wide; i++) {
  1157.     /* there are 5 possible states:
  1158.      *   0: block empty.
  1159.      *   1: block not empty, block is  a run, current pix == previous pix
  1160.      *   2: block not empty, block is  a run, current pix != previous pix
  1161.      *   3: block not empty, block not a run, current pix == previous pix
  1162.      *   4: block not empty, block not a run, current pix != previous pix
  1163.      */
  1164.  
  1165.     pix = scanline[i];
  1166.  
  1167.     if (!blocklen) {                    /* case 0:  empty */
  1168.       block[blocklen++] = pix;
  1169.       isrun = 1;
  1170.     }
  1171.  
  1172.     else if (isrun) {
  1173.       if (pix == block[blocklen-1]) {   /* case 1:  isrun, prev==cur */
  1174.     block[blocklen++] = pix;
  1175.       }
  1176.       else {                            /* case 2:  isrun, prev!=cur */
  1177.     if (blocklen>1) {               /*   we have a run block to flush */
  1178.       rleline[rlen++] = blocklen-1;
  1179.       rleline[rlen++] = block[0];
  1180.       block[0] = pix;               /*   start new run block with pix */
  1181.       blocklen = 1;
  1182.     }
  1183.     else {
  1184.       isrun = 0;                    /*   blocklen<=1, turn into non-run */
  1185.       block[blocklen++] = pix;
  1186.     }
  1187.       }
  1188.     }
  1189.     
  1190.     else {   /* not a run */
  1191.       if (pix == block[blocklen-1]) {   /* case 3:  non-run, prev==cur */
  1192.     if (blocklen>1) {               /*  have a non-run block to flush */
  1193.       rleline[rlen++] = (blocklen-1) | 0x80;
  1194.       for (j=0; j<blocklen; j++)
  1195.         rleline[rlen++] = block[j];
  1196.  
  1197.       block[0] = pix;               /*  start new run block with pix */
  1198.       blocklen = isrun = 1;
  1199.     }
  1200.     else {
  1201.       isrun = 1;                    /*  blocklen<=1 turn into a run */
  1202.       block[blocklen++] = pix;
  1203.     }
  1204.       }
  1205.       else {                            /* case 4:  non-run, prev!=cur */
  1206.     block[blocklen++] = pix;
  1207.       }
  1208.     }
  1209.  
  1210.     if (blocklen == 128) {   /* max block length.  flush */
  1211.       if (isrun) {
  1212.     rleline[rlen++] = blocklen-1;
  1213.     rleline[rlen++] = block[0];
  1214.       }
  1215.  
  1216.       else {
  1217.     rleline[rlen++] = (blocklen-1) | 0x80;
  1218.     for (j=0; j<blocklen; j++) 
  1219.       rleline[rlen++] = block[j];
  1220.       }
  1221.  
  1222.       blocklen = 0;
  1223.     }
  1224.   }
  1225.  
  1226.   if (blocklen) {   /* flush last block */
  1227.     if (isrun) {
  1228.       rleline[rlen++] = blocklen-1;
  1229.       rleline[rlen++] = block[0];
  1230.     }
  1231.  
  1232.     else {
  1233.       rleline[rlen++] = (blocklen-1) | 0x80;
  1234.       for (j=0; j<blocklen; j++) 
  1235.     rleline[rlen++] = block[j];
  1236.     }
  1237.   }
  1238.  
  1239.   return rlen;
  1240. }
  1241.       
  1242.         
  1243. /**********************************************/
  1244. static void psColorImage(fp)
  1245. FILE *fp;
  1246. {
  1247.   /* spits out code that checks if the PostScript device in question
  1248.      knows about the 'colorimage' operator.  If it doesn't, it defines
  1249.      'colorimage' in terms of image (ie, generates a greyscale image from
  1250.      RGB data) */
  1251.  
  1252.  
  1253.   fprintf(fp,"%% define 'colorimage' if it isn't defined\n");
  1254.   fprintf(fp,"%%   ('colortogray' and 'mergeprocs' come from xwd2ps\n");
  1255.   fprintf(fp,"%%     via xgrab)\n");
  1256.   fprintf(fp,"/colorimage where   %% do we know about 'colorimage'?\n");
  1257.   fprintf(fp,"  { pop }           %% yes: pop off the 'dict' returned\n");
  1258.   fprintf(fp,"  {                 %% no:  define one\n");
  1259.   fprintf(fp,"    /colortogray {  %% define an RGB->I function\n");
  1260.   fprintf(fp,"      /rgbdata exch store    %% call input 'rgbdata'\n");
  1261.   fprintf(fp,"      rgbdata length 3 idiv\n");
  1262.   fprintf(fp,"      /npixls exch store\n");
  1263.   fprintf(fp,"      /rgbindx 0 store\n");
  1264.   fprintf(fp,"      0 1 npixls 1 sub {\n");
  1265.   fprintf(fp,"        grays exch\n");
  1266.   fprintf(fp,"        rgbdata rgbindx       get 20 mul    %% Red\n");
  1267.   fprintf(fp,"        rgbdata rgbindx 1 add get 32 mul    %% Green\n");
  1268.   fprintf(fp,"        rgbdata rgbindx 2 add get 12 mul    %% Blue\n");
  1269.   fprintf(fp,"        add add 64 idiv      %% I = .5G + .31R + .18B\n");
  1270.   fprintf(fp,"        put\n");
  1271.   fprintf(fp,"        /rgbindx rgbindx 3 add store\n");
  1272.   fprintf(fp,"      } for\n");
  1273.   fprintf(fp,"      grays 0 npixls getinterval\n");
  1274.   fprintf(fp,"    } bind def\n\n");
  1275.  
  1276.   fprintf(fp,"    %% Utility procedure for colorimage operator.\n");
  1277.   fprintf(fp,"    %% This procedure takes two procedures off the\n");
  1278.   fprintf(fp,"    %% stack and merges them into a single procedure.\n\n");
  1279.   
  1280.   fprintf(fp,"    /mergeprocs { %% def\n");
  1281.   fprintf(fp,"      dup length\n");
  1282.   fprintf(fp,"      3 -1 roll\n");
  1283.   fprintf(fp,"      dup\n");
  1284.   fprintf(fp,"      length\n");
  1285.   fprintf(fp,"      dup\n");
  1286.   fprintf(fp,"      5 1 roll\n");
  1287.   fprintf(fp,"      3 -1 roll\n");
  1288.   fprintf(fp,"      add\n");
  1289.   fprintf(fp,"      array cvx\n");
  1290.   fprintf(fp,"      dup\n");
  1291.   fprintf(fp,"      3 -1 roll\n");
  1292.   fprintf(fp,"      0 exch\n");
  1293.   fprintf(fp,"      putinterval\n");
  1294.   fprintf(fp,"      dup\n");
  1295.   fprintf(fp,"      4 2 roll\n");
  1296.   fprintf(fp,"      putinterval\n");
  1297.   fprintf(fp,"    } bind def\n\n");
  1298.  
  1299.   fprintf(fp,"    /colorimage { %% def\n");
  1300.   fprintf(fp,"      pop pop     %% remove 'false 3' operands\n");
  1301.   fprintf(fp,"      {colortogray} mergeprocs\n");
  1302.   fprintf(fp,"      image\n");
  1303.   fprintf(fp,"    } bind def\n");
  1304.   fprintf(fp,"  } ifelse          %% end of 'false' case\n");
  1305.   fprintf(fp,"\n\n\n");
  1306. }
  1307.  
  1308.  
  1309. /**********************************************/
  1310. static void psColorMap(fp, color, nc, rmap, gmap, bmap)
  1311.      FILE *fp;
  1312.      int color, nc;
  1313.      byte *rmap, *gmap, *bmap;
  1314. {
  1315.   /* spits out code for the colormap of the following image
  1316.      if !color, it spits out a mono-ized graymap */
  1317.  
  1318.   int i;
  1319.  
  1320.   fprintf(fp,"%% define the colormap\n");
  1321.   fprintf(fp,"/cmap %d string def\n\n\n", nc * ((color) ? 3 : 1));
  1322.  
  1323.   fprintf(fp,"%% load up the colormap\n");
  1324.   fprintf(fp,"currentfile cmap readhexstring\n");
  1325.  
  1326.   for (i=0; i<nc; i++) {
  1327.     if (color) fprintf(fp,"%02x%02x%02x ", rmap[i],gmap[i],bmap[i]);
  1328.     else fprintf(fp,"%02x ", MONO(rmap[i],gmap[i],bmap[i]));
  1329.     
  1330.     if ((i%10) == 9) fprintf(fp,"\n");
  1331.   }
  1332.   if (i%10) fprintf(fp,"\n");
  1333.   fprintf(fp,"pop pop   %% lose return values from readhexstring\n\n\n");
  1334.          
  1335. }
  1336.  
  1337.  
  1338. /**********************************************/
  1339. static void psRleCmapImage(fp, color)
  1340. FILE *fp;
  1341. int   color;
  1342. {
  1343.   /* spits out code that defines the 'rlecmapimage' operator */
  1344.  
  1345.   fprintf(fp,"%% rlecmapimage expects to have 'w h bits matrix' on stack\n");
  1346.   fprintf(fp,"/rlecmapimage {\n");
  1347.   fprintf(fp,"  /buffer 1 string def\n");
  1348.   fprintf(fp,"  /rgbval 3 string def\n");
  1349.   fprintf(fp,"  /block  384 string def\n\n");
  1350.  
  1351.   fprintf(fp,"  %% proc to read a block from file, and return RGB data\n");
  1352.   fprintf(fp,"  { currentfile buffer readhexstring pop\n");
  1353.   fprintf(fp,"    /bcount exch 0 get store\n");
  1354.   fprintf(fp,"    bcount 128 ge\n");
  1355.   fprintf(fp,"    {  %% it's a non-run block\n");
  1356.   fprintf(fp,"      0 1 bcount 128 sub\n");
  1357.   fprintf(fp,"      { currentfile buffer readhexstring pop pop\n\n");
  1358.  
  1359.   if (color) {
  1360.     fprintf(fp,"        %% look up value in color map\n");
  1361.     fprintf(fp,"%s/rgbval cmap buffer 0 get 3 mul 3 getinterval store\n\n",
  1362.         "        ");
  1363.     fprintf(fp,"        %% and put it in position i*3 in block\n");
  1364.     fprintf(fp,"        block exch 3 mul rgbval putinterval\n");
  1365.     fprintf(fp,"      } for\n");
  1366.     fprintf(fp,"      block  0  bcount 127 sub 3 mul  getinterval\n");
  1367.     fprintf(fp,"    }\n\n");
  1368.   }
  1369.   else {
  1370.     fprintf(fp,"        %% look up value in gray map\n");
  1371.     fprintf(fp,"%s/rgbval cmap buffer 0 get 1 getinterval store\n\n",
  1372.         "        ");
  1373.     fprintf(fp,"        %% and put it in position i in block\n");
  1374.     fprintf(fp,"        block exch rgbval putinterval\n");
  1375.     fprintf(fp,"      } for\n");
  1376.     fprintf(fp,"      block  0  bcount 127 sub  getinterval\n");
  1377.     fprintf(fp,"    }\n\n");
  1378.   }
  1379.  
  1380.   fprintf(fp,"    { %% else it's a run block\n");
  1381.   fprintf(fp,"      currentfile buffer readhexstring pop pop\n\n");
  1382.  
  1383.   if (color) {
  1384.     fprintf(fp,"      %% look up value in colormap\n");
  1385.     fprintf(fp,"%s/rgbval cmap buffer 0 get 3 mul 3 getinterval store\n\n",
  1386.         "      ");
  1387.     fprintf(fp,"%s0 1 bcount { block exch 3 mul rgbval putinterval } for\n\n",
  1388.         "      ");
  1389.     fprintf(fp,"      block 0 bcount 1 add 3 mul getinterval\n");
  1390.   }
  1391.   else {
  1392.     fprintf(fp,"      %% look up value in graymap\n");
  1393.     fprintf(fp,"      /rgbval cmap buffer 0 get 1 getinterval store\n\n");
  1394.     fprintf(fp,"      0 1 bcount { block exch rgbval putinterval } for\n\n");
  1395.     fprintf(fp,"      block 0 bcount 1 add getinterval\n");
  1396.   }
  1397.  
  1398.   fprintf(fp,"    } ifelse\n");
  1399.   fprintf(fp,"  } %% end of proc\n");
  1400.  
  1401.   if (color) fprintf(fp,"  false 3 colorimage\n");
  1402.         else fprintf(fp,"  image\n");
  1403.  
  1404.   fprintf(fp,"} bind def\n\n\n");
  1405. }
  1406.  
  1407.  
  1408.  
  1409. /**********************************************/
  1410. static void epsPreview(fp, pic, ptype, colorType, w, h, rmap,gmap,bmap, 
  1411.                landscape)
  1412.      FILE *fp;
  1413.      byte *pic;
  1414.      int   ptype, colorType;
  1415.      int   w, h, landscape;
  1416.      byte *rmap, *gmap, *bmap;
  1417. {
  1418.   byte *prev;
  1419.   int flipbw;
  1420.  
  1421.  
  1422.   if (landscape) {  /* generate a rotated version of the pic */
  1423.     int bperpix;
  1424.     byte *lpic;
  1425.  
  1426.     bperpix = (ptype == PIC8) ? 1 : 3;
  1427.     lpic = (byte *) malloc((size_t) w * h * bperpix);
  1428.     if (!lpic) FatalError("can't alloc mem to rotate image in epsPreview");
  1429.  
  1430.     xvbcopy((char *) pic, (char *) lpic, (size_t) w * h * bperpix);
  1431.     RotatePic(lpic, ptype, &w, &h, 0);
  1432.     pic = lpic;
  1433.   }
  1434.     
  1435.  
  1436.   /* put in an EPSI preview */
  1437.   
  1438.   if (colorType != F_BWDITHER) { /* have to generate a preview */
  1439.     prev = FSDither(pic, ptype, w, h, rmap,gmap,bmap, 0, 1);
  1440.  
  1441.     if (!prev) {
  1442.       fprintf(stderr,"Unable to malloc in epsPreview\n");
  1443.       return;
  1444.     }
  1445.  
  1446.     flipbw = 0;
  1447.   }
  1448.   else {
  1449.     prev = pic;
  1450.     /* set if color#0 is white */
  1451.     flipbw = (MONO(rmap[0],gmap[0],bmap[0]) > MONO(rmap[1],gmap[1],bmap[1]));
  1452.   }
  1453.  
  1454.  
  1455.   fprintf(fp,"%%%%BeginPreview: %d %d %d %d\n", w, h, 1, 
  1456.       (w/(72*4) + 1) * h);
  1457.  
  1458.   writeBWStip(fp, prev, "% ", w, h, !flipbw);
  1459.  
  1460.   fprintf(fp,"%%%%EndPreview\n");
  1461.  
  1462.   if (colorType != F_BWDITHER) free(prev);
  1463.   if (landscape) free(pic);  /* lpic, actually... */
  1464. }
  1465.  
  1466.  
  1467. /***********************************/
  1468. static int writeBWStip(fp, pic, prompt, w, h, flipbw)
  1469.      FILE *fp;
  1470.      byte *pic;
  1471.      char *prompt;
  1472.      int  w, h, flipbw;
  1473. {
  1474.   /* write the given 'pic' (B/W stippled, 1 byte per pixel, 0=blk,1=wht) 
  1475.      out as hexadecimal, max of 72 hex chars per line.
  1476.  
  1477.      if 'flipbw', then 0=white, 1=black
  1478.  
  1479.      returns '0' if everythings fine, 'EOF' if writing failed */
  1480.  
  1481.   int err, i, j, lwidth;
  1482.   byte outbyte, bitnum, bit;
  1483.  
  1484.   err = 0;
  1485.  
  1486.   for (i=0; i<h && err != EOF; i++) {
  1487.     fprintf(fp, "%s", prompt);
  1488.  
  1489.     outbyte = bitnum = lwidth = 0;
  1490.  
  1491.     if ((i&0x3f) == 0) WaitCursor();
  1492.  
  1493.     for (j=0; j<w && err != EOF; j++) {
  1494.       bit = *pic;
  1495.       outbyte = (outbyte<<1) | ((bit)&0x01);
  1496.       bitnum++;
  1497.  
  1498.       if (bitnum==8) {
  1499.     if (flipbw) outbyte = ~outbyte & 0xff;
  1500.     err = fprintf(fp,"%02x",outbyte);
  1501.     lwidth+=2;
  1502.     outbyte = bitnum = 0;
  1503.       }
  1504.  
  1505.       if (lwidth>=72 && j+1<w) { fprintf(fp, "\n%s", prompt); lwidth = 0; }
  1506.       pic++;
  1507.     }
  1508.  
  1509.     if (bitnum) {   /* few bits left over... */
  1510.       for ( ; bitnum<8; bitnum++) outbyte <<= 1;
  1511.       if (flipbw) outbyte = ~outbyte & 0xff;
  1512.       err = fprintf(fp,"%02x",outbyte);
  1513.       lwidth+=2;
  1514.     }
  1515.  
  1516.     fprintf(fp, "\n");
  1517.   }
  1518.  
  1519.   return err;
  1520. }
  1521.  
  1522.  
  1523.  
  1524.  
  1525.  
  1526.  
  1527. /***********************************/
  1528. int LoadPS(fname, pinfo, quick)
  1529.      char    *fname;
  1530.      PICINFO *pinfo;
  1531.      int      quick;
  1532. {
  1533.   /* returns '1' if successful.  If the document is a single page, the
  1534.      a temporary PNM file is created, loaded, and deleted.  If the
  1535.      document is multiple pages, a series of PNM files are created, and
  1536.      the first one is loaded (but not deleted) */
  1537.  
  1538.  
  1539.   char tmp[512], tmp1[512], tmpname[64];
  1540.   int  gsresult, nump, i, filetype;
  1541.   char *rld;
  1542.  
  1543.   pinfo->pic     = (byte *) NULL;
  1544.   pinfo->comment = (char *) NULL;
  1545.  
  1546.  
  1547. #ifdef GS_PATH
  1548.  
  1549. #ifndef VMS
  1550.   sprintf(tmpname, "%s/xvpgXXXXXX", tmpdir);
  1551. #else
  1552.   sprintf(tmpname, "Sys$Scratch:xvpgXXXXXX");
  1553. #endif
  1554.  
  1555.   mktemp(tmpname);
  1556.   if (tmpname[0] == '\0') {   /* mktemp() blew up */
  1557.     sprintf(str,"LoadPS: Unable to create temporary filename???");
  1558.     ErrPopUp(str, "\nHow unlikely!");
  1559.     return 0;
  1560.   }
  1561.   strcat(tmpname,".");
  1562.  
  1563.  
  1564.   /* build command string */
  1565.  
  1566. #ifndef VMS  /* VMS needs quotes around mixed case command lines */
  1567.   sprintf(tmp, "%s -sDEVICE=%s -r%d -q -dNOPAUSE -sOutputFile=%s%%d ",
  1568.       GS_PATH, gsDev, gsRes, tmpname);
  1569. #else
  1570.   sprintf(tmp, 
  1571.       "%s \"-sDEVICE=%s\" -r%d -q \"-dNOPAUSE\" \"-sOutputFile=%s%%d\" ",
  1572.       GS_PATH, gsDev, gsRes, tmpname);
  1573. #endif
  1574.  
  1575.  
  1576. #ifdef GS_LIB
  1577. #  ifndef VMS
  1578.      sprintf(tmp1, "-I%s ", GS_LIB);
  1579. #  else
  1580.      sprintf(tmp1, "\"-I%s\"", GS_LIB);
  1581. #  endif
  1582.    strcat(tmp, tmp1);
  1583. #endif
  1584.  
  1585.   if (gsGeomStr) {
  1586.     sprintf(tmp1, "-g%s ", gsGeomStr);
  1587.     strcat(tmp, tmp1);
  1588.   }
  1589.  
  1590.   /* if 'quick' is set, stop processing after first page by tacking
  1591.      some PostScript commands that break the 'showpage' operator onto
  1592.      the front of the stream passed to the ghostscript interpreter */
  1593.  
  1594. #ifndef VMS
  1595.   if (quick) {
  1596.     sprintf(tmp1, "echo '%s' | cat - %s | %s -",
  1597.         "/showpage { showpage quit } bind def",   /* mk showpage exit */
  1598.         fname,  tmp);
  1599.     strcpy(tmp, tmp1);
  1600.   }
  1601.   else {
  1602.     strcat(tmp, " -- ");
  1603.     strcat(tmp, fname);
  1604.   }
  1605. #else /* VMS */
  1606.   /* VMS doesn't have pipes or an 'echo' command and GS doesn't like
  1607.      Unix-style file names as input files in the VMS version */
  1608.   strcat(tmp, " -- ");
  1609.   rld = strrchr(fname, '/');     /* Pointer to last '/' */
  1610.   if (rld) rld++;                /* Pointer to filename */
  1611.       else rld = fname;          /* No path - use original string */
  1612.   strcat(tmp, rld);
  1613. #endif
  1614.  
  1615.  
  1616.  
  1617.  
  1618.   WaitCursor();
  1619.  
  1620.   if (DEBUG) fprintf(stderr,"LoadPS:  executing command '%s'\n", tmp);
  1621.   SetISTR(ISTR_INFO, "Running '%s'...", GS_PATH);
  1622.  
  1623.   sprintf(tmp1, "Running %s", tmp);
  1624.   if (!quick && !ctrlUp && !infoUp) OpenAlert(tmp1);
  1625.  
  1626. #ifndef VMS
  1627.   gsresult = system(tmp);
  1628. #else
  1629.   gsresult = !system(tmp);
  1630. #endif
  1631.  
  1632.   WaitCursor();
  1633.  
  1634.   if (!quick && !ctrlUp && !infoUp) CloseAlert();
  1635.  
  1636.   /* figure out how many page files were created, by stating files. 
  1637.      breaks out on first failure, assuming there won't be any more after
  1638.      that, and it would complicate matters too much anyhow... */
  1639.  
  1640.   for (i=1; i<1000; i++) {
  1641.     struct stat st;
  1642.     sprintf(tmp, "%s%d", tmpname, i);
  1643.     if (stat(tmp, &st)!=0) break;
  1644.   }
  1645.   nump = i-1;
  1646.  
  1647.   WaitCursor();
  1648.  
  1649.   if (DEBUG) fprintf(stderr,"%s: %d pages found\n", fname, nump);
  1650.  
  1651.   if (gsresult) {
  1652.     SetISTR(ISTR_INFO, "");
  1653.     SetISTR(ISTR_WARNING,"Ghostscript interpreter returned error code %d.",
  1654.         gsresult);
  1655.     KillPageFiles(tmpname, nump);
  1656.     SetCursors(-1);
  1657.     return 0;
  1658.   }
  1659.   else {
  1660.     if (nump<1) {
  1661.       SetISTR(ISTR_INFO, "Ghostscript: No pages produced.");
  1662.       if (!quick) Warning();
  1663.       SetCursors(-1);
  1664.       return 0;
  1665.     }
  1666.  
  1667.     SetISTR(ISTR_INFO, "Running '%s'...  Done.  (%d page%s)", 
  1668.         GS_PATH, nump, (nump==1) ? "" : "s");
  1669.   }
  1670.  
  1671.  
  1672.   /* from this point on, the 'gs' command was successful, and page files
  1673.      were produced.  Try to load the first (or only) page image created.
  1674.      Note that if there is only one page, the page file is deleted,
  1675.      as it won't be needed. */
  1676.  
  1677.  
  1678.   sprintf(tmp, "%s%d", tmpname, 1);
  1679.   filetype = ReadFileType(tmp);
  1680.   
  1681.   if (filetype == RFT_ERROR || filetype == RFT_UNKNOWN || 
  1682.       filetype == RFT_COMPRESS) {  /* shouldn't happen */
  1683.     SetISTR(ISTR_WARNING, "Couldn't load first page '%s'", tmp);
  1684.     KillPageFiles(tmpname, nump);
  1685.     SetCursors(-1);
  1686.     return 0;
  1687.   }
  1688.  
  1689.  
  1690.   i = ReadPicFile(tmp, filetype, pinfo, quick);
  1691.   if (nump == 1) unlink(tmp);
  1692.  
  1693.   if (!i) {  /* failed to read page 1 */
  1694.     SetISTR(ISTR_WARNING, "Couldn't load first page '%s'", tmp);
  1695.     KillPageFiles(tmpname, nump);
  1696.     SetCursors(-1);
  1697.     return 0;
  1698.   }    
  1699.  
  1700.  
  1701.   /* SUCCESS! */
  1702.  
  1703.   if (nump>1) {
  1704.     strcpy(pinfo->pagebname, tmpname);
  1705.   }
  1706.   pinfo->numpages = nump;
  1707.  
  1708. #endif  /* GS_PATH */
  1709.  
  1710.  
  1711.   return 1;   /* can safely return '1' as this should never be called if
  1712.          we don't have 'gs' package */
  1713. }
  1714.