1 /*
2  * Author:      William Chia-Wei Cheng (bill.cheng@acm.org)
3  *
4  * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5  *
6  * This file may be distributed under the terms of the Q Public License
7  * as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11  * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  * @(#)$Header: /mm2/home/cvs/bc-src/tgif/eps.c,v 1.9 2011/05/16 16:21:57 william Exp $
19  */
20 
21 #define _INCLUDE_FROM_EPS_C_
22 
23 #include "tgifdefs.h"
24 
25 #include "cmd.e"
26 #include "color.e"
27 #include "cursor.e"
28 #include "dialog.e"
29 #include "drawing.e"
30 #include "dup.e"
31 #include "eps.e"
32 #include "file.e"
33 #include "grid.e"
34 #include "mark.e"
35 #include "msg.e"
36 #include "names.e"
37 #include "obj.e"
38 #include "pattern.e"
39 #include "ps.e"
40 #include "rect.e"
41 #include "select.e"
42 #include "setup.e"
43 #include "special.e"
44 #include "strtbl.e"
45 #include "util.e"
46 #include "xbitmap.e"
47 
48 #ifndef SEEK_SET
49 #define SEEK_SET 0
50 #endif /* ~SEEK_SET */
51 
52 typedef struct EPSLineRec {
53    char *s;
54    struct EPSLineRec *next, *prev;
55 } *EPSLineRecPtr;
56 
57 float	defaultEPSScaling=1.0;
58 char	defaultEPSScalingStr[80];
59 
60 int	autoEPSPreviewBitmap=FALSE;
61 
62 static struct EPSLineRec *topLine=NULL, *botLine=NULL;
63 static int numLines=0;
64 
65 static char tiffToXbmCmd[MAXSTRING+1];
66 static int tiffToXbmCmdInitialized=FALSE;
67 static char psToXbmCmd[MAXSTRING+1];
68 
69 /* do not translate -- program constants */
70 static char hexValue[]="0123456789abcdef";
71 static char flippedHexValue[]="084c2a6e195d3b7f";
72 
73 static char defTiffToXbmCmd[]="tifftopnm %s | pgmtopbm | pbmtoxbm";
74 static char defPsToXbmCmd[] =
75       "gs -q -dNOPAUSE -sDEVICE=pbm -sOutputFile=- -- \"%s\" | pbmtoxbm";
76 
77 static float bitmapThresholdFor8bpsPreviewBitmap=(float)0.5;
78 
InitEPS()79 void InitEPS()
80 {
81    char *c_ptr=NULL;
82 
83    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ForceClearAfterEPS")) !=
84          NULL) {
85       fprintf(stderr, TgLoadString(STID_NAMED_XDEF_IS_OBSOLETE), TOOL_NAME,
86             "ForceClearAfterEPS");
87       fprintf(stderr, "\n");
88    }
89    defaultEPSScaling = 1.0;
90    strcpy(defaultEPSScalingStr, "1");
91    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"DefaultEPSScaling")) != NULL) {
92       strcpy(defaultEPSScalingStr, c_ptr);
93       defaultEPSScaling = (float)atof(c_ptr);
94       if (defaultEPSScaling <= 0.0) {
95          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
96                TOOL_NAME, "DefaultEPSScaling", c_ptr, 1);
97          defaultEPSScaling = 1.0;
98          strcpy(defaultEPSScalingStr, "1");
99       } else if (strcmp(defaultEPSScalingStr,"1")==0 ||
100             strcmp(defaultEPSScalingStr,"1.0")==0) {
101          defaultEPSScaling = 1.0;
102          strcpy(defaultEPSScalingStr, "1");
103       }
104    }
105    tiffToXbmCmdInitialized = TRUE;
106    /* do not translate -- program constants */
107    strcpy(tiffToXbmCmd, defTiffToXbmCmd);
108    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"TiffToXbm")) != NULL) {
109       int count=0;
110 
111       strcpy(tiffToXbmCmd, c_ptr);
112       for (c_ptr=strstr(tiffToXbmCmd,"%s"); c_ptr!=NULL;
113             c_ptr=strstr(++c_ptr,"%s")) {
114          count++;
115       }
116       if (count != 1) {
117          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
118                TOOL_NAME, "TiffToXbm", tiffToXbmCmd, defTiffToXbmCmd);
119          strcpy(tiffToXbmCmd, defTiffToXbmCmd);
120       }
121    }
122    /* do not translate -- program constants */
123    strcpy(psToXbmCmd, defPsToXbmCmd);
124    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PsToXbm")) != NULL) {
125       int count=0;
126 
127       strcpy(psToXbmCmd, c_ptr);
128       for (c_ptr=strstr(psToXbmCmd,"%s"); c_ptr!=NULL;
129             c_ptr=strstr(++c_ptr,"%s")) {
130          count++;
131       }
132       if (count != 1) {
133          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
134                TOOL_NAME, "PsToXbm", psToXbmCmd, defPsToXbmCmd);
135          strcpy(psToXbmCmd, defPsToXbmCmd);
136       }
137    }
138    autoEPSPreviewBitmap = FALSE;
139    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AutoEPSPreviewBitmap")) !=
140          NULL && UtilStrICmp(c_ptr, "true") == 0) {
141       autoEPSPreviewBitmap = TRUE;
142    }
143    bitmapThresholdFor8bpsPreviewBitmap = (float)0.5;
144    if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"BitmapThreshold"))!=NULL) {
145       bitmapThresholdFor8bpsPreviewBitmap = (float) atof(c_ptr);
146       if (bitmapThresholdFor8bpsPreviewBitmap < ((float)0) ||
147             bitmapThresholdFor8bpsPreviewBitmap > (((float)1)+INT_TOL)) {
148          fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
149                TOOL_NAME, "BitmapThreshold", c_ptr, "0.5");
150          fprintf(stderr, "\n");
151          bitmapThresholdFor8bpsPreviewBitmap = (float)0.5;
152       }
153    }
154 }
155 
156 static
CleanUpLines()157 void CleanUpLines()
158 {
159    struct EPSLineRec *line_ptr, *next_line;
160 
161    for (line_ptr=topLine; line_ptr != NULL; line_ptr=next_line) {
162       next_line = line_ptr->next;
163       if (line_ptr->s != NULL) free(line_ptr->s);
164       free(line_ptr);
165    }
166    topLine = botLine = NULL;
167    numLines = 0;
168 }
169 
CleanUpEPS()170 void CleanUpEPS()
171 {
172    CleanUpLines();
173    stripEPSComments = FALSE;
174 }
175 
176 static
DumpXBmByte(fp,num_nibbles,image_h,nibble_index,row_index,byte_data,pn_out_byte_count)177 void DumpXBmByte(fp, num_nibbles, image_h, nibble_index, row_index,
178       byte_data, pn_out_byte_count)
179    FILE *fp;
180    int num_nibbles, image_h, nibble_index, row_index;
181    int byte_data, *pn_out_byte_count;
182 {
183    if ((*pn_out_byte_count)++ == 12) {
184       (*pn_out_byte_count) = 1;
185       if (fprintf(fp, "\n   ") == EOF) writeFileFailed = TRUE;
186    }
187    if (fprintf(fp, "0x%c", flippedHexValue[(byte_data>>4) & 0xf]) == EOF) {
188       writeFileFailed = TRUE;
189    }
190    if (row_index == image_h-1 && nibble_index == num_nibbles-1) {
191       if (fprintf(fp, "%c};\n", flippedHexValue[byte_data & 0xf]) == EOF) {
192          writeFileFailed = TRUE;
193       }
194    } else {
195       if (fprintf(fp, "%c, ", flippedHexValue[byte_data & 0xf]) == EOF) {
196          writeFileFailed = TRUE;
197       }
198    }
199 }
200 
201 static
UpdateEndDetectState(c,p_end_detect_state,p_line_count)202 int UpdateEndDetectState(c, p_end_detect_state, p_line_count)
203    char c;
204    int *p_end_detect_state;
205    int *p_line_count;
206 {
207    int end_detect_state=(*p_end_detect_state);
208 
209    if (c == '\n') {
210       (*p_line_count)++;
211       *p_end_detect_state = 0;
212 
213       return FALSE;
214    }
215    switch (end_detect_state) {
216    case 0: *p_end_detect_state = ((c == '%') ? 1 : 0); break;
217    case 1: *p_end_detect_state = ((c == '%') ? 2 : 0); break;
218    case 2: *p_end_detect_state = ((c == 'E' || c == 'e') ? 3 : 0); break;
219    case 3: *p_end_detect_state = ((c == 'n') ? 4 : 0); break;
220    case 4: *p_end_detect_state = ((c == 'd') ? 5 : 0); break;
221    default: *p_end_detect_state = 0; break;
222    }
223    return (*p_end_detect_state == 5);
224 }
225 
226 static
ReadPreviewBitmap(fp,file_name,image_w,image_h,bps,bitmap,image)227 int ReadPreviewBitmap(fp, file_name, image_w, image_h, bps, bitmap, image)
228    FILE *fp;
229    char *file_name;
230    int image_w, image_h, bps;
231    Pixmap *bitmap;
232    XImage **image;
233 {
234    int k=0, j=0, i=0, num_nibbles=0, bit_count=0, out_byte_count=0, line_sz=0;
235    int line_count=0, end_detect_state=0; /* detecting "%%End..." */
236    char *line=NULL, *c_ptr=NULL;
237 
238    switch (bps) {
239    case 1:
240       num_nibbles = ((image_w & 0x3)==0) ? (int)(image_w>>2) :
241             (int)(image_w>>2)+1;
242       if (num_nibbles & 0x1) num_nibbles++;
243       break;
244    case 8:
245       num_nibbles = (image_w<<1);
246       break;
247    default:
248       sprintf(gszMsgBox, TgLoadString(STID_GIVEN_BPS_PREVIEW_NOT_SUP), bps);
249       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
250       return FALSE;
251    }
252    line_sz = (num_nibbles+10)*sizeof(char);
253    line = (char*)malloc(line_sz);
254    if (line == NULL) FailAllocMessage();
255    if (cmdLineDosEpsFilter && cmdLinePreviewOnly) {
256       *bitmap = None;
257       *image = NULL;
258       /* do not translate -- program constants */
259       printf("#define noname_width %1d\n", image_w);
260       printf("#define noname_height %1d\n", image_h);
261       printf("#define noname_x_hot 0\n");
262       printf("#define noname_y_hot 0\n");
263       printf("static char noname_bits[] = {\n   ");
264    } else {
265       *bitmap = XCreatePixmap(mainDisplay, dummyBitmap, image_w, image_h, 1);
266       XFillRectangle(mainDisplay, *bitmap, xbmGC, 0, 0, image_w, image_h);
267       *image = XGetImage(mainDisplay,*bitmap,0,0,image_w,image_h,1,ZPixmap);
268    }
269    for (i=0; i < image_h; i++) {
270       int byte_data=0;
271 
272       for (j=0, c_ptr=line; j < num_nibbles; j++, c_ptr++) {
273          while (TRUE) {
274             int c=getc(fp);
275 
276             if (c == EOF) {
277                sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BMP_IN_EPS),
278                      file_name);
279                MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
280                free(line);
281                if (*bitmap != None) {
282                   XFreePixmap(mainDisplay, *bitmap);
283                   *bitmap = None;
284                }
285                if (*image != NULL) {
286                   XDestroyImage(*image);
287                   *image = NULL;
288                }
289                return FALSE;
290             }
291             *c_ptr = (char)c;
292             if (UpdateEndDetectState(*c_ptr, &end_detect_state, &line_count)) {
293                /* %%End... detected */
294                sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BMP_IN_EPS),
295                      file_name);
296                MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
297                free(line);
298                if (*bitmap != None) {
299                   XFreePixmap(mainDisplay, *bitmap);
300                   *bitmap = None;
301                }
302                if (*image != NULL) {
303                   XDestroyImage(*image);
304                   *image = NULL;
305                }
306                return FALSE;
307             }
308             if ((*c_ptr >= '0' && *c_ptr <= '9') ||
309                   (*c_ptr >= 'a' && *c_ptr <= 'f') ||
310                   (*c_ptr >= 'A' && *c_ptr <= 'F')) {
311                break;
312             }
313          }
314       }
315       *c_ptr = '\0';
316       bit_count = 0;
317       c_ptr = line;
318       for (j=0; j<num_nibbles && *c_ptr!='\0'; j++, c_ptr++) {
319          int data=0;
320 
321          if (*c_ptr >= '0' && *c_ptr <= '9') {
322             data = (int)(*c_ptr) - (int)('0');
323          } else if (*c_ptr >= 'a' && *c_ptr <= 'f') {
324             data = (int)(*c_ptr) - (int)('a') + 10;
325          } else if (*c_ptr >= 'A' && *c_ptr <= 'F') {
326             data = (int)(*c_ptr) - (int)('A') + 10;
327          } else {
328             break;
329          }
330          if (cmdLineDosEpsFilter && cmdLinePreviewOnly) {
331             if (j & 0x1) {
332                byte_data |= (data<<4);
333                DumpXBmByte(stdout, num_nibbles, image_h, j, i,
334                      byte_data, &out_byte_count);
335             } else {
336                byte_data = data;
337             }
338          } else {
339             switch (bps) {
340             case 1:
341                for (k = 0; k < 4; k++) {
342                   if (bit_count++ == image_w) break;
343 
344                   if (data & (1<<(3-k))) {
345                      XPutPixel(*image, j*4+k, i, 1);
346                   }
347                }
348                break;
349             case 8:
350                if (j & 0x1) {
351                   double dval=(double)0;
352 
353                   byte_data |= (data<<4);
354                   dval = (((double)byte_data) / ((double)255));
355                   if (dval > ((double)bitmapThresholdFor8bpsPreviewBitmap)) {
356                      XPutPixel(*image, (j>>1), i, 1);
357                   }
358                } else {
359                   byte_data = data;
360                }
361                break;
362             default: /* should not get here */ break;
363             }
364          }
365       }
366       if (cmdLineDosEpsFilter && cmdLinePreviewOnly) {
367          if (num_nibbles & 0x1) {
368             DumpXBmByte(stdout, num_nibbles, image_h, j, i,
369                   byte_data, &out_byte_count);
370          }
371       }
372    }
373    if (fgets(line, line_sz, fp) == NULL) {
374       sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BMP_IN_EPS),
375             file_name);
376       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
377       free(line);
378       if (*bitmap != None) {
379          XFreePixmap(mainDisplay, *bitmap);
380          *bitmap = None;
381       }
382       if (*image != NULL) {
383          XDestroyImage(*image);
384          *image = NULL;
385       }
386       return FALSE;
387    }
388    if (cmdLineDosEpsFilter && cmdLinePreviewOnly) {
389    } else {
390       XPutImage(mainDisplay,*bitmap,xbmGC,*image,0,0,0,0,image_w,image_h);
391    }
392    free(line);
393    return TRUE;
394 }
395 
396 static
AddLine(s)397 void AddLine(s)
398    char *s;
399 {
400    struct EPSLineRec *line_ptr;
401 
402    line_ptr = (struct EPSLineRec *)malloc(sizeof(struct EPSLineRec));
403    if (line_ptr == NULL) FailAllocMessage();
404    line_ptr->s = s;
405 
406    line_ptr->next = NULL;
407    line_ptr->prev = botLine;
408    if (botLine == NULL) {
409       topLine = line_ptr;
410    } else {
411       botLine->next = line_ptr;
412    }
413    botLine = line_ptr;
414 
415    numLines++;
416 }
417 
418 static
ReadDoubleWord(buf)419 unsigned long ReadDoubleWord(buf)
420    char *buf;
421 {
422    unsigned long lval, total=0L;
423    unsigned char *c_ptr=(unsigned char *)buf;
424 
425    lval = (unsigned long)(*c_ptr++);
426    total += lval;
427    lval = (unsigned long)(*c_ptr++);
428    total += (lval<<8);
429    lval = (unsigned long)(*c_ptr++);
430    total += (lval<<16);
431    lval = (unsigned long)(*c_ptr++);
432    total += (lval<<24);
433    return total;
434 }
435 
436 static
XbmToPreviewBitmap(FP,xbm_fname)437 int XbmToPreviewBitmap(FP, xbm_fname)
438    FILE *FP;
439    char *xbm_fname;
440 {
441    unsigned int image_w, image_h;
442    int rc, x_hot, y_hot, **data, num_image_bytes_per_row, num_lines;
443    int row, col;
444    Pixmap bitmap;
445    XImage *image;
446 
447    if ((rc=XReadBitmapFile(mainDisplay, mainWindow, xbm_fname, &image_w,
448          &image_h, &bitmap, &x_hot, &y_hot)) != BitmapSuccess) {
449       return FALSE;
450    }
451    image = XGetImage(mainDisplay, bitmap, 0, 0, image_w, image_h, 1, ZPixmap);
452    if (image == NULL) {
453       XFreePixmap(mainDisplay, bitmap);
454       return FALSE;
455    }
456    num_image_bytes_per_row = ((image_w & 0x7) ? (image_w>>3)+1 : (image_w>>3));
457    num_lines = ((image_w & 0x7) ? (((image_w>>3)+1)<<1) : ((image_w>>3)<<1));
458    num_lines = ((num_lines & 0x3f) ? (num_lines>>6)+1 : (num_lines>>6));
459 
460    if ((data=(int**)malloc(image_h*sizeof(int*))) == NULL) {
461       XFreePixmap(mainDisplay, bitmap);
462       XDestroyImage(image);
463       return FailAllocMessage();
464    }
465    for (row=0; row < image_h; row++) {
466       if ((data[row]=(int*)malloc(num_image_bytes_per_row*sizeof(int))) ==
467             NULL) {
468          int i;
469 
470          for (i=0; i < row; i++) free(data[i]);
471          free(data);
472          XFreePixmap(mainDisplay, bitmap);
473          XDestroyImage(image);
474          return FailAllocMessage();
475       } else {
476          for (col=0; col<num_image_bytes_per_row; col++) {
477             data[row][col] = 0;
478          }
479       }
480    }
481    /* do not translate -- program constants */
482    fprintf(FP, "%%!\n");
483    fprintf(FP, "%%%%BeginPreview: %1d %1d 1 %1d\n", image_w, image_h,
484          num_lines*image_h);
485    for (row=0; row < image_h; row++) {
486       for (col=0; col < image_w; col++) {
487          if (XGetPixel(image, col, row) != 0) {
488             data[row][col>>3] |= (1<<(7 - (col & 0x7)));
489          }
490       }
491    }
492    for (row=0; row < image_h; row++) {
493       int byte_count=0;
494 
495       fprintf(FP, "%% ");
496       for (col=0; col < num_image_bytes_per_row; col++) {
497          if (byte_count++ == 32) {
498             byte_count = 1;
499             fprintf(FP, "\n%% ");
500          }
501          fprintf(FP, "%c", hexValue[(data[row][col]>>4) & 0xf]);
502          fprintf(FP, "%c", hexValue[data[row][col] & 0xf]);
503       }
504       fprintf(FP, "\n");
505    }
506    fprintf(FP, "%%%%EndImage\n");
507    fprintf(FP, "%%%%EndPreview\n");
508 
509    for (row=0; row < image_h; row++) free(data[row]);
510    free(data);
511    XDestroyImage(image);
512    XFreePixmap(mainDisplay, bitmap);
513    return TRUE;
514 }
515 
516 static
ErrorInConvertTiffToXbm(fp,tiff_fp,xbm_fp,fname)517 int ErrorInConvertTiffToXbm(fp, tiff_fp, xbm_fp, fname)
518    FILE *fp, *tiff_fp, *xbm_fp;
519    char *fname;
520 {
521    if (fp != NULL) fclose(fp);
522    if (tiff_fp != NULL) fclose(tiff_fp);
523    if (xbm_fp != NULL) fclose(xbm_fp);
524    if (fname != NULL) {
525       if (writeFileFailed) {
526          FailToWriteFileMessage(fname);
527       }
528       unlink(fname);
529    }
530    return FALSE;
531 }
532 
533 static
ConvertTiffToXbm(fp,tiff_offset,tiff_sz,xbm_fname,xbm_sz)534 int ConvertTiffToXbm(fp, tiff_offset, tiff_sz, xbm_fname, xbm_sz)
535    FILE *fp;
536    int tiff_offset, tiff_sz, xbm_sz;
537    char *xbm_fname;
538 {
539    FILE *tiff_fp=NULL, *xbm_fp=NULL, *pfp;
540    int bytes_to_read, bytes_read;
541    char tiff_fname[MAXPATHLENGTH+1];
542    char cmd[(MAXSTRING<<1)+1];
543 
544    *tiff_fname = *xbm_fname = '\0';
545    /* extract TIFF into a file */
546    if (fseek(fp, tiff_offset, SEEK_SET) != 0) {
547       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
548    }
549    if (MkTempFile(tiff_fname, sizeof(tiff_fname), tmpDir, TOOL_NAME) == NULL) {
550       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
551    }
552    /* do not translate -- program constants */
553    if ((tiff_fp=fopen(tiff_fname, "w")) == NULL) {
554       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
555    }
556    while (tiff_sz > 0) {
557       bytes_to_read = min(tiff_sz, sizeof(gszMsgBox));
558       if (bytes_to_read !=
559             (int)fread(gszMsgBox, sizeof(char), bytes_to_read, fp)) {
560          return ErrorInConvertTiffToXbm(fp, tiff_fp, NULL, tiff_fname);
561       }
562       if ((int)fwrite(gszMsgBox, sizeof(char), bytes_to_read, tiff_fp) <= 0) {
563          writeFileFailed = TRUE;
564          return ErrorInConvertTiffToXbm(fp, tiff_fp, NULL, tiff_fname);
565       }
566       tiff_sz -= bytes_to_read;
567    }
568    fclose(tiff_fp);
569    tiff_fp = NULL;
570 
571    /* convert TIFF to XBM */
572    if (MkTempFile(xbm_fname, xbm_sz, tmpDir, TOOL_NAME) == NULL) {
573       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
574    }
575    if (!tiffToXbmCmdInitialized) {
576       strcpy(tiffToXbmCmd, "tifftopnm %s | pgmtopbm | pbmtoxbm");
577    }
578    sprintf(cmd, tiffToXbmCmd, tiff_fname);
579    if (!FindProgramInPath(cmd, NULL, FALSE)) {
580       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
581    }
582    if ((xbm_fp=fopen(xbm_fname, "w")) == NULL) {
583       return ErrorInConvertTiffToXbm(fp, NULL, NULL, NULL);
584    }
585    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM), cmd);
586    SetStringStatus(gszMsgBox);
587    if (mainDisplay != NULL) XSync(mainDisplay, False);
588    if ((pfp=(FILE*)popen(cmd,"r")) == NULL) {
589       unlink(tiff_fname);
590       return ErrorInConvertTiffToXbm(fp, NULL, xbm_fp, xbm_fname);
591    }
592    while ((bytes_read=(int)fread(gszMsgBox, sizeof(char), sizeof(gszMsgBox),
593          pfp)) > 0) {
594       if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, xbm_fp) <= 0) {
595          writeFileFailed = TRUE;
596          break;
597       }
598    }
599    pclose(pfp);
600    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
601    fclose(xbm_fp);
602    xbm_fp = NULL;
603    unlink(tiff_fname);
604    *tiff_fname = '\0';
605    if (writeFileFailed) {
606       return ErrorInConvertTiffToXbm(fp, NULL, xbm_fp, xbm_fname);
607    }
608    return TRUE;
609 }
610 
611 static
ErrorInGetTiffEPSIInfo(fp,eps_fp,fname)612 FILE *ErrorInGetTiffEPSIInfo(fp, eps_fp, fname)
613    FILE *fp, *eps_fp;
614    char *fname;
615 {
616    if (fp != NULL) fclose(fp);
617    if (eps_fp != NULL) fclose(eps_fp);
618    if (fname != NULL) {
619       if (writeFileFailed) {
620          FailToWriteFileMessage(fname);
621       }
622       unlink(fname);
623    }
624    return NULL;
625 }
626 
627 static
GetTiffEPSIInfo(fp,pszEPS,file_buf_sz,pnPreviewOK)628 FILE *GetTiffEPSIInfo(fp, pszEPS, file_buf_sz, pnPreviewOK)
629    FILE *fp;
630    char *pszEPS;
631    int file_buf_sz, *pnPreviewOK;
632 {
633    int bytes_to_read=0x1e, tiff_sz, tiff_offset, eps_sz;
634    int need_to_check_ps=TRUE;
635    char buf[0x20], xbm_fname[MAXPATHLENGTH+1];
636    FILE *eps_fp=NULL;
637 
638    writeFileFailed = FALSE;
639    *xbm_fname = '\0';
640    *pszEPS = '\0';
641    rewind(fp);
642    if (fread(buf, sizeof(char), bytes_to_read, fp) != bytes_to_read) {
643       return ErrorInGetTiffEPSIInfo(fp, eps_fp, NULL);
644    }
645    eps_sz = ReadDoubleWord(&buf[0x08]);
646    tiff_offset = ReadDoubleWord(&buf[0x14]);
647    tiff_sz = ReadDoubleWord(&buf[0x18]);
648 
649    if (cmdLineDosEpsFilter) {
650       if (cmdLinePreviewOnly) {
651          FILE *xbm_fp=NULL;
652          int bytes_read=0;
653 
654          *pnPreviewOK = ConvertTiffToXbm(fp, tiff_offset, tiff_sz, xbm_fname,
655                sizeof(xbm_fname));
656          if (fseek(fp, 0x1e, SEEK_SET) != 0) {
657             return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
658          }
659          if ((xbm_fp=fopen(xbm_fname,"r")) == NULL) {
660             unlink(xbm_fname);
661             *xbm_fname = '\0';
662             return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
663          }
664          while ((bytes_read=(int)fread(gszMsgBox, sizeof(char),
665                sizeof(gszMsgBox), xbm_fp)) > 0) {
666             if ((int)fwrite(gszMsgBox, sizeof(char), bytes_read, stdout) <= 0) {
667                writeFileFailed = TRUE;
668                break;
669             }
670          }
671          fclose(xbm_fp);
672          if (writeFileFailed) {
673             fprintf(stderr, TgLoadString(STID_FAIL_TO_WRITE_TO_STDOUT));
674          }
675          unlink(xbm_fname);
676          *xbm_fname = '\0';
677          return ((FILE*)TRUE);
678       } else {
679          *pnPreviewOK = TRUE;
680          if (fseek(fp, 0x1e, SEEK_SET) != 0) {
681             return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
682          }
683       }
684    } else {
685       *pnPreviewOK = ConvertTiffToXbm(fp, tiff_offset, tiff_sz, xbm_fname,
686             sizeof(xbm_fname));
687       if (fseek(fp, 0x1e, SEEK_SET) != 0) {
688          return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
689       }
690       if (MkTempFile(pszEPS, file_buf_sz, tmpDir, TOOL_NAME) == NULL) {
691          return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
692       }
693       if ((eps_fp=fopen(pszEPS, "w")) == NULL) {
694          return ErrorInGetTiffEPSIInfo(fp, NULL, NULL);
695       }
696       if (*pnPreviewOK && !XbmToPreviewBitmap(eps_fp, xbm_fname)) {
697          *pnPreviewOK = FALSE;
698       }
699       unlink(xbm_fname);
700       *xbm_fname = '\0';
701    }
702 
703    /* copy the EPS content from the original file to the new EPS file */
704    while (eps_sz > 0) {
705       bytes_to_read = min(eps_sz, sizeof(gszMsgBox));
706       if (bytes_to_read !=
707             (int)fread(gszMsgBox, sizeof(char), bytes_to_read, fp)) {
708          return ErrorInGetTiffEPSIInfo(fp, eps_fp, pszEPS);
709       }
710       if (need_to_check_ps) {
711          need_to_check_ps = FALSE;
712          if (!(bytes_to_read>=2 && gszMsgBox[0]=='%' && gszMsgBox[1]=='!')) {
713             fclose(fp);
714             fclose(eps_fp);
715             unlink(pszEPS);
716             return NULL;
717          }
718       }
719       if (cmdLineDosEpsFilter) {
720          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_to_read, stdout) <= 0) {
721             writeFileFailed = TRUE;
722             return ErrorInGetTiffEPSIInfo(fp, eps_fp, pszEPS);
723          }
724       } else {
725          if ((int)fwrite(gszMsgBox, sizeof(char), bytes_to_read, eps_fp) <= 0) {
726             writeFileFailed = TRUE;
727             return ErrorInGetTiffEPSIInfo(fp, eps_fp, pszEPS);
728          }
729       }
730       eps_sz -= bytes_to_read;
731    }
732    if (fp != NULL) fclose(fp);
733    if (eps_fp != NULL) fclose(eps_fp);
734    if (cmdLineDosEpsFilter) {
735       return ((FILE*)TRUE);
736    }
737    return fopen(pszEPS, "r");
738 }
739 
740 static
GetEPSFullPath(file_name,full_path,buf_sz)741 void GetEPSFullPath(file_name, full_path, buf_sz)
742    char *file_name, *full_path;
743    int buf_sz;
744 {
745    if (*file_name == DIR_SEP) {
746       UtilStrCpyN(full_path, buf_sz, file_name);
747    } else {
748       char *c_ptr=NULL;
749 
750       if (PRTGIF && !cmdLineOpenDisplay && *cmdLineOpenFile != '\0') {
751          UtilStrCpyN(full_path, buf_sz, cmdLineOpenFile);
752       } else if (*scanFileFullPath == DIR_SEP) {
753          UtilStrCpyN(full_path, buf_sz, scanFileFullPath);
754       } else {
755          sprintf(full_path, "%s%c%s", curDir, DIR_SEP, scanFileFullPath);
756       }
757       if ((c_ptr=UtilStrRChr(full_path, (int)DIR_SEP)) != NULL) {
758          strcpy(++c_ptr, file_name);
759       } else {
760          /* Umm... this should not happen */
761          UtilStrCpyN(full_path, buf_sz, file_name);
762       }
763    }
764 }
765 
766 static
ConvertPsToXbm(pszPsPath,pszXbmPath,file_buf_sz)767 int ConvertPsToXbm(pszPsPath, pszXbmPath, file_buf_sz)
768    char *pszPsPath, *pszXbmPath;
769    int file_buf_sz;
770 {
771    FILE *pFile=NULL, *pPipe=NULL;
772    char *pszCmd=NULL, szBuf[MAXSTRING];
773    int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
774 
775    if (MkTempFile(pszXbmPath, file_buf_sz, tmpDir, TOOL_NAME) == NULL) {
776       return FALSE;
777    }
778    pszCmd = (char*)malloc(
779          (strlen(psToXbmCmd)+strlen(pszPsPath)+10)*sizeof(char));
780    if (pszCmd == NULL) {
781       FailAllocMessage();
782       return FALSE;
783    }
784    sprintf(pszCmd, psToXbmCmd, pszPsPath);
785    if (!FindProgramInPath(pszCmd, NULL, FALSE)) {
786       free(pszCmd);
787       return FALSE;
788    }
789    if ((pFile=fopen(pszXbmPath,"w")) == NULL) {
790       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
791             pszXbmPath);
792       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
793       free(pszCmd);
794       return FALSE;
795    }
796    sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
797          pszCmd);
798    SetStringStatus(gszMsgBox);
799    XSync(mainDisplay, False);
800    if ((pPipe=(FILE*)popen(pszCmd,"r")) == NULL) {
801       sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), pszCmd);
802       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
803       free(pszCmd);
804       fclose(pFile);
805       unlink(pszXbmPath);
806       return FALSE;
807    }
808    if (!watch_cursor) {
809       SetWatchCursor(drawWindow);
810       SetWatchCursor(mainWindow);
811    }
812    writeFileFailed = FALSE;
813    while ((bytes_read=fread(szBuf, sizeof(char), sizeof(szBuf), pPipe)) > 0) {
814       if ((int)fwrite(szBuf, sizeof(char), bytes_read, pFile) <= 0) {
815          writeFileFailed = TRUE;
816          break;
817       }
818    }
819    pclose(pPipe);
820    if (!watch_cursor) {
821       SetDefaultCursor(mainWindow);
822       ShowCursor();
823    }
824    SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
825    free(pszCmd);
826    fclose(pFile);
827    if (writeFileFailed) {
828       FailToWriteFileMessage(pszXbmPath);
829       unlink(pszXbmPath);
830       return FALSE;
831    }
832    return TRUE;
833 }
834 
835 static
AutoGeneratePreviewBitmap(pszPsPath,pBitmap,pImage,pnImageW,pnImageH)836 int AutoGeneratePreviewBitmap(pszPsPath, pBitmap, pImage, pnImageW, pnImageH)
837    char *pszPsPath;
838    Pixmap *pBitmap;
839    XImage **pImage;
840    int *pnImageW, *pnImageH;
841 {
842    char xbm_fname[MAXPATHLENGTH+1];
843    unsigned int tmp_w=0, tmp_h=0;
844    int rc=0, x_hot=0, y_hot=0, empty_image=FALSE, dont_free_orig_bitmap=FALSE;
845    Pixmap orig_bitmap=None;
846 
847    SetWatchCursor(drawWindow);
848    SetWatchCursor(mainWindow);
849    SaveStatusStrings();
850    rc = ConvertPsToXbm(pszPsPath, xbm_fname, sizeof(xbm_fname));
851    RestoreStatusStrings();
852    SetDefaultCursor(mainWindow);
853    ShowCursor();
854    if (!rc) {
855       return FALSE;
856    }
857    SetWatchCursor(drawWindow);
858    SetWatchCursor(mainWindow);
859    rc = XReadBitmapFile(mainDisplay, mainWindow, xbm_fname, &tmp_w, &tmp_h,
860          &orig_bitmap, &x_hot, &y_hot);
861    SetDefaultCursor(mainWindow);
862    ShowCursor();
863    unlink(xbm_fname);
864    if (rc != BitmapSuccess) {
865       sprintf(gszMsgBox, TgLoadString(STID_CANT_GEN_PREVIEW_FOR_PS),
866             pszPsPath);
867       MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
868       return FALSE;
869    }
870    *pnImageW = (int)tmp_w;
871    *pnImageH = (int)tmp_h;
872    rc = AutoTrimBitmap(orig_bitmap, pnImageW, pnImageH, pBitmap, pImage,
873          &empty_image, &dont_free_orig_bitmap);
874    if (!dont_free_orig_bitmap) {
875       XFreePixmap(mainDisplay, orig_bitmap);
876    }
877    if (!rc) {
878       if (empty_image) {
879          sprintf(gszMsgBox, TgLoadString(STID_CANT_GEN_PREVIEW_FOR_EMPTY_PS),
880                pszPsPath);
881          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
882       }
883       return FALSE;
884    }
885    return rc;
886 }
887 
888 static
DoMyReadEPSFile(file_name,pn_image_w,pn_image_h,p_bitmap,p_image,pn_num_lines,ppsz_epsflines,pn_epsf_level,pf_llx,pf_lly,pf_urx,pf_ury,psz_write_date)889 int DoMyReadEPSFile(file_name, pn_image_w, pn_image_h, p_bitmap, p_image,
890       pn_num_lines, ppsz_epsflines, pn_epsf_level, pf_llx, pf_lly,
891       pf_urx, pf_ury, psz_write_date)
892    char *file_name;
893    int *pn_image_w, *pn_image_h, *pn_num_lines, *pn_epsf_level;
894    Pixmap *p_bitmap;
895    XImage **p_image;
896    char ***ppsz_epsflines, *psz_write_date;
897    float *pf_llx, *pf_lly, *pf_urx, *pf_ury;
898 {
899    struct EPSLineRec *line_ptr, *next_line;
900    int i;
901    char *line=NULL, *c_ptr, loc_time[MAXSTRING+1];
902    char tiff_eps_fname[MAXPATHLENGTH+1];
903    char real_fname[MAXPATHLENGTH+1];
904    int first_line=TRUE, image_w=0, image_h=0, epsf_level=0;
905    int boundingbox_found=FALSE, preview_found=FALSE, found;
906    int boundingbox_atend=FALSE, tiff_preview_ok=FALSE;
907    int boundingbox_image_w=0, boundingbox_image_h=0;
908    FILE *fp=NULL;
909    struct stat stat_buf;
910    Pixmap bitmap=None;
911    XImage *image=NULL;
912    float llx=0.0, lly=0.0, urx=0.0, ury=0.0;
913 
914    if (!cmdLineDosEpsFilter) {
915       *pn_image_w = *pn_image_h = *pn_epsf_level = 0;
916       *p_bitmap = None;
917       *p_image = NULL;
918       if (pn_num_lines != NULL) *pn_num_lines = 0;
919       if (ppsz_epsflines != NULL) *ppsz_epsflines = NULL;
920       *pn_epsf_level = 0;
921       *pf_llx = llx; *pf_lly = lly; *pf_urx = urx; *pf_ury = ury;
922       *psz_write_date = '\0';
923    }
924    *real_fname = '\0';
925    GetEPSFullPath(file_name, real_fname, sizeof(real_fname));
926 
927    if ((fp=fopen(real_fname, "r")) == NULL) return BitmapOpenFailed;
928 
929    CleanUpLines();
930 
931    *tiff_eps_fname = '\0';
932    while ((line=UtilGetALine(fp)) != NULL) {
933       int need_to_free_line=TRUE;
934 
935       if (first_line) {
936          if (line[0] == ((char)0xc5) && line[1] == ((char)0xd0) &&
937                line[2] == ((char)0xd3) && line[3] == ((char)0xc6) &&
938                line[4] == ((char)0x1e) && line[5] == '\0') {
939             free(line);
940             if (cmdLineDosEpsFilter) {
941                if ((fp=GetTiffEPSIInfo(fp, tiff_eps_fname,
942                      sizeof(tiff_eps_fname), &tiff_preview_ok)) == NULL) {
943                   sprintf(gszMsgBox,
944                         TgLoadString(STID_FAIL_TO_PARSE_WINEPS_FILE),
945                         real_fname);
946                   if (PRTGIF || mainWindow==None) {
947                      fprintf(stderr, "%s\n", gszMsgBox);
948                   } else {
949                      MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
950                   }
951                   if (fp != NULL) fclose(fp);
952                   if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
953                   CleanUpLines();
954                   return BitmapFileInvalid;
955                }
956                fp = NULL;
957                return BitmapSuccess;
958             } else if ((fp=GetTiffEPSIInfo(fp, tiff_eps_fname,
959                   sizeof(tiff_eps_fname), &tiff_preview_ok)) == NULL ||
960                   (line=UtilGetALine(fp)) == NULL) {
961                sprintf(gszMsgBox,
962                      TgLoadString(STID_FAIL_TO_PARSE_WINEPS_FILE), real_fname);
963                if (PRTGIF || mainWindow==None) {
964                   fprintf(stderr, "%s\n", gszMsgBox);
965                } else {
966                   MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
967                }
968                if (fp != NULL) fclose(fp);
969                if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
970                CleanUpLines();
971                return BitmapFileInvalid;
972             }
973          } else if (cmdLineDosEpsFilter && !cmdLinePreviewOnly) {
974             printf("%s\n", line);
975             free(line);
976             while ((line=UtilGetALine(fp)) != NULL) {
977                printf("%s\n", line);
978                free(line);
979             }
980             fclose(fp);
981             return BitmapSuccess;
982          }
983          first_line = FALSE;
984          if (line[0] != '%' || line[1] != '!') {
985             free(line);
986             fclose(fp);
987             if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
988             CleanUpLines();
989             return BitmapFileInvalid;
990          }
991          if (cmdLineDosEpsFilter) {
992             if (!cmdLinePreviewOnly) {
993                printf("%s\n", line);
994             }
995          } else {
996             AddLine(line);
997          }
998          need_to_free_line = FALSE;
999       } else if (!cmdLineDosEpsFilter && (!boundingbox_found ||
1000             boundingbox_atend) && strncmp(line, "%%BoundingBox:", 14) == 0) {
1001          if (sscanf(&(line[14]), "%f %f %f %f", &llx, &lly, &urx, &ury) == 4) {
1002             boundingbox_found = TRUE;
1003             boundingbox_image_w = abs(round(urx-llx));
1004             boundingbox_image_h = abs(round(ury-lly));
1005          } else if (!boundingbox_found) {
1006             c_ptr = FindChar((int)'(', &(line[14]));
1007             if (strncmp(c_ptr, "atend)", 6) == 0) {
1008                boundingbox_atend = TRUE;
1009             }
1010          }
1011       } else if (!(cmdLineDosEpsFilter && !cmdLinePreviewOnly) &&
1012             !preview_found && strncmp(line, "%%BeginPreview:", 15) == 0) {
1013          int bps=1;
1014          char *preview_line=NULL;
1015 
1016          /*
1017           * The 4th argument to %%BeginPreview is the number of lines
1018           *         in the preview image.  It's probably a good idea
1019           *         to handle it or have a way not to read beyond
1020           *         %%EndImage or %%EndPreview.
1021           */
1022          if (sscanf(&(line[15]), "%d %d %d", &image_w, &image_h, &bps) != 3) {
1023             sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BOX_IN_EPS),
1024                   real_fname);
1025             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1026             if (need_to_free_line) free(line);
1027             fclose(fp);
1028             if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1029             CleanUpLines();
1030             return BitmapFileInvalid;
1031          } else {
1032             switch (bps) {
1033             case 1: break;
1034             case 8: break;
1035             default:
1036                sprintf(gszMsgBox, TgLoadString(STID_GIVEN_BPS_PREVIEW_NOT_SUP),
1037                      bps);
1038                MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1039                if (need_to_free_line) free(line);
1040                fclose(fp);
1041                if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1042                CleanUpLines();
1043                return BitmapFileInvalid;
1044             }
1045          }
1046          if (boundingbox_found) {
1047             /*
1048              * If the width and height information in the boundingbox and
1049              *     the preview bitmap are differ only by one, we consider
1050              *     this a round-off error and adjust the boundingbox so
1051              *     that they become identical!
1052              */
1053             int diff=0;
1054 
1055             diff = image_w - boundingbox_image_w;
1056             if (diff == 1 || diff == (-1)) {
1057                if (urx >= llx) {
1058                   urx += (float)diff;
1059                } else {
1060                   urx -= (float)diff;
1061                }
1062             }
1063             diff = image_h - boundingbox_image_h;
1064             if (diff == 1 || diff == (-1)) {
1065                if (ury >= lly) {
1066                   ury += (float)diff;
1067                } else {
1068                   ury -= (float)diff;
1069                }
1070             }
1071          }
1072          preview_found = TRUE;
1073          if (!ReadPreviewBitmap(fp, real_fname, image_w, image_h, bps, &bitmap,
1074                &image)) {
1075             /* error message already displayed in ReadPreviewBitmap() */
1076             if (need_to_free_line) free(line);
1077             fclose(fp);
1078             if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1079             CleanUpLines();
1080             return BitmapFileInvalid;
1081          }
1082          found = FALSE;
1083          while ((preview_line=UtilGetALine(fp)) != NULL) {
1084             if (strncmp(preview_line, "%%EndPreview", 12) == 0) {
1085                found = TRUE;
1086                free(preview_line);
1087                break;
1088             }
1089             free(preview_line);
1090          }
1091          if (!found) {
1092             sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BOX_IN_EPS),
1093                   real_fname);
1094             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1095             if (need_to_free_line) free(line);
1096             if (bitmap != None) {
1097                XFreePixmap(mainDisplay, bitmap);
1098                bitmap = None;
1099             }
1100             if (image != NULL) {
1101                XDestroyImage(image);
1102                image = NULL;
1103             }
1104             fclose(fp);
1105             if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1106             CleanUpLines();
1107             return BitmapFileInvalid;
1108          }
1109       } else {
1110          if (line[0] == '%' && line[1] == '!') epsf_level++;
1111          if (line[0] == '%' && line[1] == '%' && line[2] != '%') {
1112             /* Actaully, need to check DCS conformance! */
1113          } else if (!stripEPSComments || line[0] != '%') {
1114             if (cmdLineDosEpsFilter) {
1115                if (!cmdLinePreviewOnly) {
1116                   printf("%s\n", line);
1117                }
1118             } else {
1119                AddLine(line);
1120             }
1121             need_to_free_line = FALSE;
1122          }
1123       }
1124       if (need_to_free_line) free(line);
1125    }
1126    if (fp != NULL) fclose(fp);
1127    if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1128    if (!cmdLineDosEpsFilter) {
1129       if (!boundingbox_found) {
1130          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_BBOX_IN_GIVEN_FILE),
1131                real_fname);
1132          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1133          if (bitmap != None) {
1134             XFreePixmap(mainDisplay, bitmap);
1135             bitmap = None;
1136          }
1137          if (image != NULL) {
1138             XDestroyImage(image);
1139             image = NULL;
1140          }
1141          CleanUpLines();
1142          return BitmapFileInvalid;
1143       }
1144       if (*tiff_eps_fname != '\0' && !tiff_preview_ok) {
1145          sprintf(gszMsgBox, TgLoadString(STID_CANNOT_CONVERT_WINEPS_PREVIEW),
1146                real_fname);
1147          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1148       }
1149       if (autoEPSPreviewBitmap && image == NULL && bitmap == None &&
1150             !preview_found && !(*tiff_eps_fname != '\0' && tiff_preview_ok)) {
1151          if (AutoGeneratePreviewBitmap(real_fname, &bitmap, &image,
1152                &image_w, &image_h)) {
1153          }
1154       }
1155       if (stat(real_fname, &stat_buf) == 0) {
1156          strcpy(loc_time, ctime (&(stat_buf.st_mtime)));
1157          loc_time[24] = '\0';
1158       } else {
1159          /* do not translate -- program constants */
1160          strcpy(loc_time, "(unknown)");
1161       }
1162       *pn_image_w = image_w;
1163       *pn_image_h = image_h;
1164       *p_bitmap = bitmap;
1165       *p_image = image;
1166       if (pn_num_lines != NULL) *pn_num_lines = numLines;
1167       if (ppsz_epsflines != NULL) {
1168          *ppsz_epsflines = (char**)malloc(numLines*sizeof(char*));
1169          if (*ppsz_epsflines == NULL) FailAllocMessage();
1170       }
1171       for (i=0, line_ptr=topLine; line_ptr != NULL; line_ptr = next_line, i++) {
1172          next_line = line_ptr->next;
1173          if (ppsz_epsflines != NULL) {
1174             (*ppsz_epsflines)[i] = UtilStrDup(line_ptr->s);
1175             if ((*ppsz_epsflines)[i] == NULL) FailAllocMessage();
1176          }
1177          free(line_ptr->s);
1178          free(line_ptr);
1179       }
1180       *pn_epsf_level = epsf_level;
1181       *pf_llx = llx; *pf_lly = lly; *pf_urx = urx; *pf_ury = ury;
1182       strcpy(psz_write_date, loc_time);
1183    } else {
1184       for (i=0, line_ptr=topLine; line_ptr != NULL; line_ptr = next_line, i++) {
1185          next_line = line_ptr->next;
1186          free(line_ptr->s);
1187          free(line_ptr);
1188       }
1189    }
1190    topLine = botLine = NULL;
1191    numLines = 0;
1192    return BitmapSuccess;
1193 }
1194 
MyReadEPSFile(file_name,image_w,image_h,bitmap,image,num_lines,epsflines,epsf_level,llx,lly,urx,ury,write_date)1195 int MyReadEPSFile(file_name, image_w, image_h, bitmap, image, num_lines,
1196       epsflines, epsf_level, llx, lly, urx, ury, write_date)
1197    char *file_name;
1198    int *image_w, *image_h, *num_lines, *epsf_level;
1199    Pixmap *bitmap;
1200    XImage **image;
1201    char ***epsflines, *write_date;
1202    float *llx, *lly, *urx, *ury;
1203 {
1204    int rc;
1205 
1206    SaveStatusStrings();
1207    rc = DoMyReadEPSFile(file_name, image_w, image_h, bitmap, image,
1208          num_lines, epsflines, epsf_level, llx, lly, urx, ury, write_date);
1209    RestoreStatusStrings();
1210    return rc;
1211 }
1212 
1213 static
JustGetTiffEPSIInfo(fp,pszEPS,file_buf_sz)1214 FILE *JustGetTiffEPSIInfo(fp, pszEPS, file_buf_sz)
1215    FILE *fp;
1216    char *pszEPS;
1217    int file_buf_sz;
1218 {
1219    int bytes_to_read=0x1e, eps_sz, need_to_check_ps=TRUE;
1220    char buf[0x20];
1221    FILE *eps_fp=NULL;
1222 
1223    writeFileFailed = FALSE;
1224    *pszEPS = '\0';
1225    rewind(fp);
1226    if (fread(buf, sizeof(char), bytes_to_read, fp) != bytes_to_read) {
1227       fclose(fp);
1228       fclose(eps_fp);
1229       return NULL;
1230    }
1231    eps_sz = ReadDoubleWord(&buf[0x08]);
1232 
1233    if (MkTempFile(pszEPS, file_buf_sz, tmpDir, TOOL_NAME) == NULL) {
1234       fclose(fp);
1235       unlink(pszEPS);
1236       return NULL;
1237    }
1238    if ((eps_fp=fopen(pszEPS, "w")) == NULL) {
1239       fclose(fp);
1240       unlink(pszEPS);
1241       return NULL;
1242    }
1243    /* copy the EPS content from the original file to the new EPS file */
1244    while (eps_sz > 0) {
1245       bytes_to_read = min(eps_sz, sizeof(gszMsgBox));
1246       if (bytes_to_read !=
1247             (int)fread(gszMsgBox, sizeof(char), bytes_to_read, fp)) {
1248          fclose(fp);
1249          fclose(eps_fp);
1250          unlink(pszEPS);
1251          return NULL;
1252       }
1253       if (need_to_check_ps) {
1254          need_to_check_ps = FALSE;
1255          if (!(bytes_to_read>=2 && gszMsgBox[0]=='%' && gszMsgBox[1]=='!')) {
1256             fclose(fp);
1257             fclose(eps_fp);
1258             unlink(pszEPS);
1259             return NULL;
1260          }
1261       }
1262       if ((int)fwrite(gszMsgBox, sizeof(char), bytes_to_read, eps_fp) <= 0) {
1263          writeFileFailed = TRUE;
1264          fclose(fp);
1265          fclose(eps_fp);
1266          unlink(pszEPS);
1267          return NULL;
1268       }
1269       eps_sz -= bytes_to_read;
1270    }
1271    fclose(fp);
1272    fclose(eps_fp);
1273    return fopen(pszEPS, "r");
1274 }
1275 
1276 static
JustReadEPSLines(xbm_ptr)1277 int JustReadEPSLines(xbm_ptr)
1278    struct XBmRec *xbm_ptr;
1279 {
1280    struct EPSLineRec *line_ptr, *next_line;
1281    int i=0;
1282    char *c_ptr, *line, loc_time[MAXSTRING+1];
1283    char tiff_eps_fname[MAXPATHLENGTH+1];
1284    char real_fname[MAXPATHLENGTH+1];
1285    int first_line=TRUE, propagated_eps_status=INVALID;
1286    int boundingbox_found=FALSE, preview_found=FALSE, found;
1287    int boundingbox_atend=FALSE;
1288    float llx, lly, urx, ury;
1289    char *file_name=xbm_ptr->filename;
1290    FILE *fp=NULL;
1291    struct stat stat_buf;
1292 
1293    *real_fname = '\0';
1294    GetEPSFullPath(file_name, real_fname, sizeof(real_fname));
1295 
1296    if ((fp=fopen(real_fname, "r")) == NULL) {
1297       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_EPS_FILE_FOR_READ),
1298             real_fname);
1299       if (PRTGIF) {
1300          fprintf(stderr, "%s\n", gszMsgBox);
1301          fprintf(stderr, "   %s\n",
1302                TgLoadString(STID_EPS_OBJ_SKIPPED_FOR_PRINT));
1303       } else {
1304          char msg1[MAXSTRING];
1305 
1306          sprintf(msg1, "   %s", TgLoadString(STID_EPS_OBJ_SKIPPED_FOR_PRINT));
1307          TwoLineMsg(gszMsgBox, msg1);
1308       }
1309       return FALSE;
1310    }
1311 
1312    if (xbm_ptr->epsflines != NULL) {
1313       for (i = 0; i < xbm_ptr->num_epsf_lines; i++) {
1314          if (xbm_ptr->epsflines[i] != NULL) {
1315             free(xbm_ptr->epsflines[i]);
1316          }
1317       }
1318       free(xbm_ptr->epsflines);
1319       xbm_ptr->epsflines = NULL;
1320    }
1321    CleanUpLines();
1322 
1323    *tiff_eps_fname = '\0';
1324    while ((line=UtilGetALine(fp)) != NULL) {
1325       int need_to_free_line=TRUE;
1326 
1327       if (first_line) {
1328          if (line[0] == ((char)0xc5) && line[1] == ((char)0xd0) &&
1329                line[2] == ((char)0xd3) && line[3] == ((char)0xc6) &&
1330                line[4] == ((char)0x1e)) {
1331             free(line);
1332             if ((fp=JustGetTiffEPSIInfo(fp, tiff_eps_fname,
1333                   sizeof(tiff_eps_fname))) == NULL ||
1334                   (line=UtilGetALine(fp)) == NULL) {
1335                if (fp != NULL) fclose(fp);
1336                if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1337                CleanUpLines();
1338                return FALSE;
1339             }
1340          }
1341          first_line = FALSE;
1342          if (line[0] != '%' || line[1] != '!') {
1343             if (need_to_free_line) free(line);
1344             fclose (fp);
1345             CleanUpLines();
1346             return FALSE;
1347          }
1348          AddLine(line);
1349          need_to_free_line = FALSE;
1350          propagated_eps_status = INVALID;
1351       } else if ((!boundingbox_found || boundingbox_atend) &&
1352             strncmp(line, "%%BoundingBox:", 14) == 0) {
1353          if (sscanf(&(line[14]), "%f %f %f %f", &llx, &lly, &urx, &ury) == 4) {
1354             boundingbox_found = TRUE;
1355          } else if (!boundingbox_found) {
1356             c_ptr = FindChar((int)'(', &(line[14]));
1357             if (strncmp(c_ptr, "atend)", 6) == 0) {
1358                boundingbox_atend = TRUE;
1359             }
1360          }
1361          propagated_eps_status = INVALID;
1362       } else if (!preview_found && strncmp(line, "%%BeginPreview:", 15) == 0) {
1363          char *preview_line=NULL;
1364 
1365          preview_found = TRUE;
1366          found = FALSE;
1367          while ((preview_line=UtilGetALine(fp)) != NULL) {
1368             if (strncmp(preview_line, "%%EndPreview", 12) == 0) {
1369                found = TRUE;
1370                free(preview_line);
1371                break;
1372             }
1373             free(preview_line);
1374          }
1375          if (!found) {
1376             if (PRTGIF) {
1377                fprintf(stderr, TgLoadString(STID_INVALID_PREVIEW_BMP_IN_EPS),
1378                      real_fname);
1379             } else {
1380                sprintf(gszMsgBox, TgLoadString(STID_INVALID_PREVIEW_BMP_IN_EPS),
1381                      real_fname);
1382                MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1383             }
1384             free(line);
1385             if (need_to_free_line) free(line);
1386             fclose(fp);
1387             CleanUpLines();
1388             return FALSE;
1389          }
1390          propagated_eps_status = INVALID;
1391       } else if (line[0] == '%' && line[1] == '%' && line[2] != '%') {
1392          /* Actaully, need to check DCS conformance! */
1393          if (propagated_eps_status != INVALID && line[2] != '+') {
1394             propagated_eps_status = INVALID;
1395          }
1396          UpdatePropagatedEPSInfo(line, &propagated_eps_status);
1397       } else {
1398          if (line[0] == '%' && line[1] == '!') {
1399             (xbm_ptr->epsf_level)++;
1400          } else if (!stripEPSComments || line[0] != '%') {
1401             AddLine(line);
1402             need_to_free_line = FALSE;
1403          }
1404          propagated_eps_status = INVALID;
1405       }
1406       if (need_to_free_line) free(line);
1407    }
1408    fclose(fp);
1409    if (*tiff_eps_fname != '\0') unlink(tiff_eps_fname);
1410    if (!boundingbox_found) {
1411       sprintf(gszMsgBox, TgLoadString(STID_CANNOT_BBOX_IN_GIVEN_FILE),
1412             real_fname);
1413       if (PRTGIF) {
1414          fprintf(stderr, "%s\n", gszMsgBox);
1415       } else {
1416          MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1417       }
1418       CleanUpLines();
1419       return FALSE;
1420    }
1421    if (stat(real_fname, &stat_buf) == 0) {
1422       strcpy(loc_time, ctime(&(stat_buf.st_mtime)));
1423       loc_time[24] = '\0';
1424    } else {
1425       /* do not translate -- program constants */
1426       strcpy(loc_time, "(unknown)");
1427    }
1428    if (strcmp(xbm_ptr->write_date, loc_time) != 0) {
1429       sprintf(gszMsgBox, TgLoadString(STID_EPS_FILE_NEWER_THAN_EPS_OBJ),
1430             real_fname);
1431       if (PRTGIF) {
1432          fprintf(stderr, "%s\n", gszMsgBox);
1433       } else {
1434          Msg(gszMsgBox);
1435       }
1436    }
1437    xbm_ptr->epsflines = (char**)malloc(numLines*sizeof(char*));
1438    if (xbm_ptr->epsflines == NULL) FailAllocMessage();
1439    xbm_ptr->num_epsf_lines = numLines;
1440 
1441    for (i=0, line_ptr=topLine; line_ptr != NULL; line_ptr = next_line, i++) {
1442       next_line = line_ptr->next;
1443       (xbm_ptr->epsflines)[i] = UtilStrDup(line_ptr->s);
1444       free(line_ptr->s);
1445       free(line_ptr);
1446    }
1447    topLine = botLine = NULL;
1448    numLines = 0;
1449 
1450    return TRUE;
1451 }
1452 
DumpEPSObj(FP,ObjPtr)1453 void DumpEPSObj(FP, ObjPtr)
1454    FILE *FP;
1455    struct ObjRec *ObjPtr;
1456 {
1457    int i;
1458    float scale=0, llx_psu, lly_psu, urx_psu, ury_psu, x_psu=0, y_psu=0;
1459    float w_psu, h_psu, bbox_w_psu, bbox_h_psu, dx_psu, dy_psu, ltx_psu, rby_psu;
1460    struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
1461    struct MtrxRec mtrx;
1462    int no_rotate=(ObjPtr->ctm==NULL), need_to_free_epsflines=FALSE;
1463          /* (ObjPtr->ctm->m[CTM_SIN]== 0 && ObjPtr->ctm->m[CTM_MSIN] == 0); */
1464 
1465    if (!xbm_ptr->save_epsf) {
1466       if (xbm_ptr->bitmap == None || xbm_ptr->epsflines == NULL) {
1467          if (!JustReadEPSLines(xbm_ptr)) {
1468             return;
1469          }
1470          need_to_free_epsflines = TRUE;
1471       } else {
1472          char loc_time[MAXSTRING+1], real_fname[MAXPATHLENGTH+1];
1473          struct stat stat_buf;
1474 
1475          *real_fname = '\0';
1476          GetEPSFullPath(xbm_ptr->filename, real_fname, sizeof(real_fname));
1477 
1478          if (stat(real_fname, &stat_buf) == 0) {
1479             strcpy(loc_time, ctime(&(stat_buf.st_mtime)));
1480             loc_time[24] = '\0';
1481          } else {
1482             /* do not translate -- program constants */
1483             strcpy(loc_time, "(unknown)");
1484          }
1485          if (strcmp(xbm_ptr->write_date, loc_time) != 0) {
1486             sprintf(gszMsgBox, TgLoadString(STID_EPS_FILE_NEWER_THAN_EPS_OBJ),
1487                   xbm_ptr->filename);
1488             if (PRTGIF) {
1489                fprintf(stderr, "%s\n", gszMsgBox);
1490             } else {
1491                Msg(gszMsgBox);
1492             }
1493          }
1494       }
1495    }
1496    /*
1497     * psu is PostScript Unit (72 psu/inch) and px be pixel.
1498     * scale's unit is psu/px.
1499     */
1500    scale = ((float)psDotsPerInch)/((float)PIX_PER_INCH*100.0)*printMag;
1501 
1502    llx_psu = (float)(((float)xbm_ptr->llx) / 1000.0);
1503    lly_psu = (float)(((float)xbm_ptr->lly) / 1000.0);
1504    urx_psu = (float)(((float)xbm_ptr->urx) / 1000.0);
1505    ury_psu = (float)(((float)xbm_ptr->ury) / 1000.0);
1506 
1507    if (no_rotate) {
1508       w_psu = (float)((float)(ObjPtr->obbox.rbx-ObjPtr->obbox.ltx) * scale);
1509       h_psu = (float)((float)(ObjPtr->obbox.rby-ObjPtr->obbox.lty) * scale);
1510    } else {
1511       w_psu = (float)((float)(ObjPtr->orig_obbox.rbx-ObjPtr->orig_obbox.ltx) *
1512             scale);
1513       h_psu = (float)((float)(ObjPtr->orig_obbox.rby-ObjPtr->orig_obbox.lty) *
1514             scale);
1515    }
1516    bbox_w_psu = urx_psu - llx_psu;
1517    bbox_h_psu = ury_psu - lly_psu;
1518 
1519    memset(&mtrx, 0, sizeof(struct MtrxRec));
1520    mtrx.image_w = (float)bbox_w_psu; mtrx.image_h = (float)bbox_h_psu;
1521    mtrx.w = w_psu; mtrx.h = h_psu;
1522    mtrx.rotate = ROTATE0; mtrx.flip = xbm_ptr->flip;
1523 
1524    CalcTransform(&mtrx);
1525 
1526    dx_psu = llx_psu*mtrx.m[0][0] + lly_psu*mtrx.m[1][0];
1527    dy_psu = llx_psu*mtrx.m[0][1] + lly_psu*mtrx.m[1][1];
1528 
1529    if (no_rotate) {
1530       ltx_psu = (float)((float)(ObjPtr->obbox.ltx) * scale);
1531       rby_psu = (float)(((float)psDotsPerInch)*psYOff[pageStyle] -
1532             ((float)(ObjPtr->obbox.rby) * scale));
1533       x_psu = (mtrx.transformed_w >= 0.0) ?
1534             (ltx_psu)-dx_psu : (ltx_psu+w_psu)-dx_psu;
1535       y_psu = (mtrx.transformed_h >= 0.0) ?
1536             (rby_psu)-dy_psu : (rby_psu+h_psu)-dy_psu;
1537    } else {
1538       float tmp_dx, tmp_dy;
1539       int dx, dy, ltx, rby, x, y, tmp_x, tmp_y;
1540 
1541       if (llx_psu == 0 && lly_psu == 0) {
1542          tmp_dx = dx_psu / scale;
1543          tmp_dy = dy_psu / scale;
1544       } else {
1545          tmp_dx = dx_psu / mtrx.dump_h_scale; /* tmp_dx = llx_psu */
1546          tmp_dy = dy_psu / mtrx.dump_v_scale; /* tmp_dy = lly_psu */
1547       }
1548       dx = round(tmp_dx);
1549       dy = round(tmp_dy);
1550       ltx = ObjPtr->orig_obbox.ltx;
1551       rby = ObjPtr->orig_obbox.rby;
1552       x = ltx - dx;
1553       y = rby + dy;
1554       TransformPointThroughCTM(x-ObjPtr->x, y-ObjPtr->y, ObjPtr->ctm,
1555             &tmp_x, &tmp_y);
1556       tmp_x += ObjPtr->x;
1557       tmp_y += ObjPtr->y;
1558       if (llx_psu == 0 && lly_psu == 0) {
1559          x_psu = (float)(((float)tmp_x) * scale);
1560          y_psu = (float)(((float)psDotsPerInch)*psYOff[pageStyle] -
1561                (((float)tmp_y) * scale));
1562       } else {
1563          x_psu = (float)(((float)tmp_x) * mtrx.dump_h_scale);
1564          y_psu = (float)(((float)psDotsPerInch)*psYOff[pageStyle] -
1565                (((float)tmp_y) * mtrx.dump_v_scale));
1566       }
1567    }
1568    /* do not translate -- program constants */
1569    fprintf(FP, "%% EPS\n");
1570    fprintf(FP, "end\n");
1571    fprintf(FP, "/tgiflevel%1d save def\n", xbm_ptr->epsf_level);
1572    fprintf(FP, "/tgifdictcount%1d countdictstack def\n", xbm_ptr->epsf_level);
1573    fprintf(FP, "/tgifopcount%1d count 1 sub def\n", xbm_ptr->epsf_level);
1574    fprintf(FP, "userdict begin\n");
1575    fprintf(FP, "/showpage {} def\n");
1576    fprintf(FP, "/letter {} def\n");
1577    fprintf(FP, "/legal {} def\n");
1578    fprintf(FP, "/a4 {} def\n");
1579    fprintf(FP, "/setpagedevice {pop} def\n");
1580    fprintf(FP, "/erasepage {} def\n");
1581    fprintf(FP, "/bop-hook {} def\n");
1582    fprintf(FP, "/eop-hook {} def\n");
1583    fprintf(FP, "/start-hook {} def\n");
1584    fprintf(FP, "/end-hook {} def\n");
1585    fprintf(FP, "0 setgray 0 setlinecap 1 setlinewidth\n");
1586    fprintf(FP, "0 setlinejoin 10 setmiterlimit [] 0 setdash newpath\n");
1587    fprintf(FP, "1 %1d %1d div %.3f mul 100 div div dup neg scale\n",
1588          psDotsPerInch, PIX_PER_INCH, printMag);
1589    fprintf(FP, "%1d %s mul neg %1d %s mul neg translate\n", psDotsPerInch,
1590          psXOffStr[pageStyle], psDotsPerInch, psYOffStr[pageStyle]);
1591    fprintf(FP, "\n");
1592    if (no_rotate) {
1593       fprintf(FP, "%.3f %.3f translate %.3f %.3f scale %1d rotate\n",
1594             x_psu, y_psu, mtrx.dump_h_scale, mtrx.dump_v_scale, (-mtrx.degree));
1595    } else {
1596       float m[6], ftmp_x, ftmp_y;
1597       int abs_ltx=ABS_X(ObjPtr->rotated_obbox[0].x);
1598       int abs_lty=ABS_Y(ObjPtr->rotated_obbox[0].y);
1599       int tmp_x, tmp_y;
1600 
1601       ReverseTransformPointThroughCTM(abs_ltx-ObjPtr->x, abs_lty-ObjPtr->y,
1602             ObjPtr->ctm, &tmp_x, &tmp_y);
1603       tmp_x += ObjPtr->x;
1604       tmp_y += ObjPtr->y;
1605       ftmp_x = ((float)tmp_x) - llx_psu;
1606       ftmp_y = ((float)tmp_y) - ury_psu;
1607       abs_ltx = round(ftmp_x);
1608       abs_lty = round(ftmp_y);
1609       TransformPointThroughCTM(abs_ltx-ObjPtr->x, abs_lty-ObjPtr->y,
1610             ObjPtr->ctm, &tmp_x, &tmp_y);
1611       ftmp_x = ((float)tmp_x) + ObjPtr->x;
1612       ftmp_y = ((float)tmp_y) + ObjPtr->y;
1613 
1614       fprintf(FP, "%.3f %.3f translate %.3f %.3f scale %1d rotate\n",
1615             x_psu, y_psu, mtrx.dump_h_scale, mtrx.dump_v_scale, (-mtrx.degree));
1616 
1617       m[CTM_SX] = ((float)ObjPtr->ctm->m[CTM_SX])/((float)1000.0);
1618       m[CTM_SY] = ((float)ObjPtr->ctm->m[CTM_SY])/((float)1000.0);
1619       m[CTM_SIN] = ((float)ObjPtr->ctm->m[CTM_SIN])/((float)1000.0);
1620       m[CTM_MSIN] = ((float)ObjPtr->ctm->m[CTM_MSIN])/((float)1000.0);
1621       fprintf(FP, "[%.3f %.3f %.3f %.3f 0 0] concat\n",
1622             m[CTM_SX], -m[CTM_SIN], -m[CTM_MSIN], m[CTM_SY]);
1623    }
1624    fprintf(FP, "\n");
1625    fprintf(FP, "%%%%BeginDocument: %s\n", xbm_ptr->filename);
1626 
1627    for (i = 0; i < xbm_ptr->num_epsf_lines; i++) {
1628       fprintf(FP, "%s\n", xbm_ptr->epsflines[i]);
1629    }
1630    fprintf(FP, "%%%%EndDocument\n");
1631    fprintf(FP, "count tgifopcount%1d sub dup 0 gt %s\n",
1632          xbm_ptr->epsf_level, "{{pop} repeat} {pop} ifelse");
1633    fprintf(FP, "countdictstack tgifdictcount%1d sub dup 0 gt %s\n",
1634          xbm_ptr->epsf_level, "{{end} repeat} {pop} ifelse");
1635    fprintf(FP, "tgiflevel%1d restore\n", xbm_ptr->epsf_level);
1636    fprintf(FP, "tgifdict begin\n");
1637    fprintf(FP, "\n");
1638 
1639    if (need_to_free_epsflines && xbm_ptr->epsflines != NULL) {
1640       for (i=0; i < xbm_ptr->num_epsf_lines; i++) {
1641          if (xbm_ptr->epsflines[i] != NULL) {
1642             free(xbm_ptr->epsflines[i]);
1643          }
1644       }
1645       if (xbm_ptr->epsflines != NULL) free(xbm_ptr->epsflines);
1646       xbm_ptr->num_epsf_lines = 0;
1647       xbm_ptr->epsflines = NULL;
1648    }
1649 }
1650 
SetEPSObjCTM(obj_ptr,p_orig_obbox)1651 void SetEPSObjCTM(obj_ptr, p_orig_obbox)
1652    struct ObjRec *obj_ptr;
1653    struct BBRec *p_orig_obbox;
1654 {
1655    struct XBmRec *xbm_ptr=obj_ptr->detail.xbm;
1656    int w=(p_orig_obbox->rbx-p_orig_obbox->ltx);
1657    int h=(p_orig_obbox->rby-p_orig_obbox->lty), image_w=0, image_h=0;
1658 
1659    if (obj_ptr->ctm != NULL) return;
1660 
1661    if (xbm_ptr->real_type == XBM_XBM) {
1662       image_w = xbm_ptr->image_w;
1663       image_h = xbm_ptr->image_h;
1664    } else {
1665       image_w = xbm_ptr->eps_w;
1666       image_h = xbm_ptr->eps_h;
1667    }
1668    if (image_w != w || image_h != h) {
1669       float fval=(float)0;
1670       struct XfrmMtrxRec ctm;
1671 
1672       memset(&ctm, 0, sizeof(struct XfrmMtrxRec));
1673       obj_ptr->orig_obbox.ltx = p_orig_obbox->ltx;
1674       obj_ptr->orig_obbox.lty = p_orig_obbox->lty;
1675       obj_ptr->orig_obbox.rbx = p_orig_obbox->rbx;
1676       obj_ptr->orig_obbox.rby = p_orig_obbox->rby;
1677       fval = ((float)w)/((float)image_w)*((float)1000.0);
1678       ctm.m[CTM_SX] = (double)fval;
1679       fval = ((float)h)/((float)image_h)*((float)1000.0);
1680       ctm.m[CTM_SY] = (double)fval;
1681       obj_ptr->obbox.rbx = obj_ptr->bbox.rbx = p_orig_obbox->ltx+image_w;
1682       obj_ptr->obbox.rby = obj_ptr->bbox.rby = p_orig_obbox->lty+image_h;
1683       SetCTM(obj_ptr, &ctm);
1684       AdjObjBBox(obj_ptr);
1685    }
1686 }
1687 
CreateEPSObj(FileName,ImageW,ImageH,bitmap,image,num_lines,lines,epsf_level,llx,lly,urx,ury,write_date)1688 struct ObjRec *CreateEPSObj(FileName, ImageW, ImageH, bitmap, image,
1689       num_lines, lines, epsf_level, llx, lly, urx, ury, write_date)
1690    char *FileName, **lines, *write_date;
1691    int ImageW, ImageH, num_lines, epsf_level;
1692    Pixmap bitmap;
1693    XImage *image;
1694    float *llx, *lly, *urx, *ury;
1695 {
1696    struct XBmRec *xbm_ptr=NULL;
1697    struct ObjRec *obj_ptr=NULL;
1698    struct BBRec orig_obbox;
1699    int len=strlen(FileName), w=0, h=0;
1700    char *name=NULL;
1701 
1702    name = (char*)malloc((len+1)*sizeof(char));
1703    if (name == NULL) FailAllocMessage();
1704    strcpy(name, FileName);
1705 
1706    xbm_ptr = (struct XBmRec *)malloc(sizeof(struct XBmRec));
1707    if (xbm_ptr == NULL) FailAllocMessage();
1708    memset(xbm_ptr, 0, sizeof(struct XBmRec));
1709 
1710    xbm_ptr->image = image;
1711    xbm_ptr->image_w = ImageW;
1712    xbm_ptr->image_h = ImageH;
1713    xbm_ptr->bitmap = bitmap;
1714    xbm_ptr->data = NULL;
1715 
1716    if (bitmap == None) {
1717       xbm_ptr->eps_w = w = ((*urx) >= (*llx)) ? (int)((*urx)-(*llx)) :
1718             (int)((*llx)-(*urx));
1719       xbm_ptr->eps_h = h = ((*ury) >= (*lly)) ? (int)((*ury)-(*lly)) :
1720             (int)((*lly)-(*ury));
1721    } else {
1722       /* same as above! */
1723       xbm_ptr->eps_w = w = ((*urx) >= (*llx)) ? (int)((*urx)-(*llx)) :
1724             (int)((*llx)-(*urx));
1725       xbm_ptr->eps_h = h = ((*ury) >= (*lly)) ? (int)((*ury)-(*lly)) :
1726             (int)((*lly)-(*ury));
1727       w = ImageW;
1728       h = ImageH;
1729    }
1730    xbm_ptr->fill = objFill;
1731    xbm_ptr->flip = xbm_ptr->cached_flip = 0;
1732    xbm_ptr->llx = (int)((*llx)*1000.0);
1733    xbm_ptr->lly = (int)((*lly)*1000.0);
1734    xbm_ptr->urx = (int)((*urx)*1000.0);
1735    xbm_ptr->ury = (int)((*ury)*1000.0);
1736    xbm_ptr->cached_zoom = 0;
1737    xbm_ptr->cached_bitmap = None;
1738    xbm_ptr->cached_w = xbm_ptr->cached_h = 0;
1739 
1740    xbm_ptr->real_type = XBM_EPS;
1741    xbm_ptr->filename = name;
1742    strcpy(xbm_ptr->write_date, write_date);
1743    xbm_ptr->epsflines = lines;
1744    xbm_ptr->num_epsf_lines = num_lines;
1745    xbm_ptr->epsf_level = epsf_level;
1746    xbm_ptr->save_epsf = saveEPSLines;
1747 
1748    obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
1749    if (obj_ptr == NULL) FailAllocMessage();
1750    memset(obj_ptr, 0, sizeof(struct ObjRec));
1751 
1752    obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = drawOrigX;
1753    obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = drawOrigY;
1754    obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = w + drawOrigX;
1755    obj_ptr->bbox.rby = obj_ptr->obbox.rby = h + drawOrigY;
1756    obj_ptr->type = OBJ_XBM;
1757    obj_ptr->color = colorIndex;
1758    if (mainDisplay != NULL) {
1759       UtilStrCpyN(obj_ptr->color_str, sizeof(obj_ptr->color_str),
1760             colorMenuItems[colorIndex]);
1761    }
1762    obj_ptr->id = objId++;
1763    obj_ptr->dirty = FALSE;
1764    obj_ptr->rotation = 0;
1765    obj_ptr->locked = FALSE;
1766    obj_ptr->detail.xbm = xbm_ptr;
1767    obj_ptr->fattr = obj_ptr->lattr = NULL;
1768    obj_ptr->ctm = NULL;
1769 
1770    memcpy(&orig_obbox, &obj_ptr->obbox, sizeof(struct BBRec));
1771    SetEPSObjCTM(obj_ptr, &orig_obbox);
1772 
1773    return obj_ptr;
1774 }
1775 
UpdateEPS()1776 void UpdateEPS()
1777 {
1778    struct SelRec *sel_ptr;
1779    int count=0;
1780 
1781    for (sel_ptr=topSel; sel_ptr != NULL; sel_ptr=sel_ptr->next) {
1782       if (sel_ptr->obj->type == OBJ_XBM &&
1783             sel_ptr->obj->detail.xbm->real_type == XBM_EPS) {
1784          count++;
1785       }
1786    }
1787    if (count == 0) {
1788       MsgBox(TgLoadString(STID_NO_TOP_LEVEL_EPS_SELECTED), TOOL_NAME, INFO_MB);
1789       return;
1790    }
1791    HighLightReverse();
1792 
1793    StartCompositeCmd();
1794    count = 0;
1795    for (sel_ptr=topSel; sel_ptr != NULL; sel_ptr=sel_ptr->next) {
1796       if (sel_ptr->obj->type == OBJ_XBM &&
1797             sel_ptr->obj->detail.xbm->real_type == XBM_EPS) {
1798          struct XBmRec *xbm_ptr, *new_xbm_ptr;
1799          struct ObjRec *obj_ptr, *new_obj_ptr;
1800          char write_date[32], **lines=NULL;
1801          int rc, num_lines=0, epsf_level, image_w, image_h, save_epsf;
1802          int transformed;
1803          float llx, lly, urx, ury;
1804          Pixmap bitmap;
1805          XImage *image=NULL;
1806 
1807          obj_ptr = sel_ptr->obj;
1808          xbm_ptr = obj_ptr->detail.xbm;
1809          transformed = (obj_ptr->ctm!=NULL);
1810 
1811          save_epsf = xbm_ptr->save_epsf;
1812 
1813          importingFile = TRUE;
1814          SetWatchCursor(drawWindow);
1815          SetWatchCursor(mainWindow);
1816          rc = MyReadEPSFile(xbm_ptr->filename, &image_w, &image_h, &bitmap,
1817                &image, (save_epsf ? &num_lines : NULL),
1818                (save_epsf ? &lines : NULL), &epsf_level, &llx, &lly, &urx, &ury,
1819                write_date);
1820          SetDefaultCursor(mainWindow);
1821          ShowCursor();
1822 
1823          if (rc != BitmapSuccess) {
1824             sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_GIVEN_EPS),
1825                   xbm_ptr->filename);
1826             MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1827             importingFile = FALSE;
1828             return;
1829          }
1830          importingFile = FALSE;
1831          PrepareToReplaceAnObj(obj_ptr);
1832          if (save_epsf) saveEPSLines = TRUE;
1833          new_obj_ptr = CreateEPSObj(xbm_ptr->filename, image_w, image_h, bitmap,
1834                image, num_lines, lines, epsf_level, &llx, &lly, &urx, &ury,
1835                write_date);
1836          saveEPSLines = FALSE;
1837 
1838          if (!save_epsf && lines != NULL) {
1839             int i=0;
1840 
1841             for (i=0; i < num_lines; i++) {
1842                if (lines[i] != NULL) free(lines[i]);
1843             }
1844             free(lines);
1845          }
1846          new_obj_ptr->x = obj_ptr->x;
1847          new_obj_ptr->y = obj_ptr->y;
1848          if (transformed) {
1849             new_obj_ptr->obbox.ltx = obj_ptr->orig_obbox.ltx;
1850             new_obj_ptr->obbox.lty = obj_ptr->orig_obbox.lty;
1851             new_obj_ptr->obbox.rbx = obj_ptr->orig_obbox.rbx;
1852             new_obj_ptr->obbox.rby = obj_ptr->orig_obbox.rby;
1853             new_obj_ptr->obbox.rby = obj_ptr->orig_obbox.rby;
1854             SetCTM(new_obj_ptr, obj_ptr->ctm);
1855             AdjObjBBox(new_obj_ptr);
1856          } else {
1857             new_obj_ptr->bbox.ltx = obj_ptr->bbox.ltx;
1858             new_obj_ptr->bbox.lty = obj_ptr->bbox.lty;
1859             new_obj_ptr->bbox.rbx = obj_ptr->bbox.rbx;
1860             new_obj_ptr->bbox.rby = obj_ptr->bbox.rby;
1861             new_obj_ptr->obbox.ltx = obj_ptr->obbox.ltx;
1862             new_obj_ptr->obbox.lty = obj_ptr->obbox.lty;
1863             new_obj_ptr->obbox.rbx = obj_ptr->obbox.rbx;
1864             new_obj_ptr->obbox.rby = obj_ptr->obbox.rby;
1865          }
1866          new_xbm_ptr = new_obj_ptr->detail.xbm;
1867          new_xbm_ptr->flip = xbm_ptr->flip;
1868 
1869          ReplaceObj(obj_ptr, new_obj_ptr);
1870          sel_ptr->obj = new_obj_ptr;
1871          RecordReplaceAnObj(new_obj_ptr);
1872          FreeObj(obj_ptr);
1873 
1874          count++;
1875       }
1876    }
1877    EndCompositeCmd();
1878 
1879    if (count > 0) {
1880       UpdSelBBox();
1881       RedrawAnArea(botObj, selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
1882             selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
1883       SetFileModified(TRUE);
1884       justDupped = FALSE;
1885       Msg(TgLoadString(STID_EPS_OBJECT_UPDATED));
1886    }
1887    HighLightForward();
1888 }
1889