home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / POSTSCPT / GSVIEW / SRC / GVCDISP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-27  |  24.1 KB  |  925 lines

  1. /* Copyright (C) 1993, 1994, Russell Lang.  All rights reserved.
  2.   
  3.   This file is part of GSview.
  4.   
  5.   This program is distributed with NO WARRANTY OF ANY KIND.  No author
  6.   or distributor accepts any responsibility for the consequences of using it,
  7.   or for whether it serves any particular purpose or works at all, unless he
  8.   or she says so in writing.  Refer to the GSview Free Public Licence 
  9.   (the "Licence") for full details.
  10.   
  11.   Every copy of GSview must include a copy of the Licence, normally in a 
  12.   plain ASCII text file named LICENCE.  The Licence grants you the right 
  13.   to copy, modify and redistribute GSview, but only under certain conditions 
  14.   described in the Licence.  Among other things, the Licence requires that 
  15.   the copyright notice and this notice be preserved on all copies.
  16. */
  17.  
  18. /* gvcdisp.c */
  19. /* Display GSview routines common to Windows and PM */
  20. #ifdef _Windows
  21. #include "gvwin.h"
  22. #else
  23. #include "gvpm.h"
  24. #endif
  25.  
  26. FILE *debug_file;
  27.  
  28. void
  29. gs_puts(char *str, FILE *f)
  30. {
  31.     if (str != NULL) {
  32.     fputs(str, f);
  33.     if (debug_file != (FILE *)NULL)
  34.        fputs(str, debug_file);
  35.     }
  36. }
  37.  
  38. void 
  39. gs_copy(FILE *from, FILE *to, long begin, long end)
  40. {
  41.     pscopyuntil(from, to, begin, end, NULL);
  42.     if (debug_file != (FILE *)NULL)
  43.        pscopyuntil(from, debug_file, begin, end, NULL);
  44. }
  45.  
  46. /* transform cursor position from device coordinates to points */
  47. /* taking into account rotated pages */
  48. void
  49. transform_cursorpos(float *x, float *y)
  50. {
  51.       if (zoom) {
  52.             /* first figure out number of pixels to zoom origin point */
  53.         *x = *x * 72.0/option.xdpi;
  54.         *y = *y * 72.0/option.ydpi;
  55.         transform_point(x,y);
  56.         *x = *x * option.xdpi/72;
  57.         *y = *y * option.ydpi/72;
  58.         /* now convert to pts and offset it */
  59.         *x = *x * 72/option.zoom_xdpi + display.zoom_xoffset;
  60.         *y = *y * 72/option.zoom_ydpi + display.zoom_yoffset;
  61.       }
  62.       else {
  63.         *x = *x * 72.0/option.xdpi 
  64.         + (display.epsf_clipped ? doc->boundingbox[LLX] : 0);
  65.         *y = *y * 72.0/option.ydpi
  66.         + (display.epsf_clipped ? doc->boundingbox[LLY] : 0);
  67.         transform_point(x,y);
  68.       }
  69. }
  70.  
  71.  
  72. /* transform point from coordinates relative to bottom left
  73.  * corner of paper to bottom left corner of rotated coordinate
  74.  * system
  75.  */
  76. void
  77. transform_point(float *x, float *y)
  78. {
  79. float oldx, oldy;
  80. int real_orientation;
  81. int width, height;
  82.     oldx = *x;
  83.     oldy = *y;
  84.     width  = (unsigned int)(display.width  * 72.0 / option.xdpi);
  85.     height = (unsigned int)(display.height * 72.0 / option.ydpi);
  86.     real_orientation = option.orientation;
  87.     if (option.swap_landscape) {
  88.         if (option.orientation == IDM_LANDSCAPE)
  89.         real_orientation = IDM_SEASCAPE;
  90.         else if (option.orientation == IDM_SEASCAPE)
  91.         real_orientation = IDM_LANDSCAPE;
  92.     }
  93.     switch (real_orientation) {
  94.         case IDM_PORTRAIT:
  95.         break;
  96.         case IDM_LANDSCAPE:
  97.             *x = height - oldy;
  98.             *y = oldx;
  99.             break;
  100.         case IDM_UPSIDEDOWN:
  101.             *x = width - oldx;
  102.             *y = height - oldy;
  103.         break;
  104.         case IDM_SEASCAPE:
  105.             *x = oldy;
  106.             *y = width - oldx;
  107.             break;
  108.     }
  109.     return;
  110. }
  111.  
  112. /* inverse transform point from coordinates relative 
  113.  * to bottom left corner of rotated coordinate system
  114.  * to bottom left corner of paper 
  115.  */
  116. void
  117. itransform_point(float *x, float *y)
  118. {
  119. float oldx, oldy;
  120. int real_orientation;
  121. int width, height;
  122.     oldx = *x;
  123.     oldy = *y;
  124.     width  = (unsigned int)(display.width  * 72.0 / option.xdpi);
  125.     height = (unsigned int)(display.height * 72.0 / option.ydpi);
  126.     real_orientation = option.orientation;
  127.     if (option.swap_landscape) {
  128.         if (option.orientation == IDM_LANDSCAPE)
  129.         real_orientation = IDM_SEASCAPE;
  130.         else if (option.orientation == IDM_SEASCAPE)
  131.         real_orientation = IDM_LANDSCAPE;
  132.     }
  133.     switch (real_orientation) {
  134.         case IDM_PORTRAIT:
  135.         break;
  136.         case IDM_LANDSCAPE:
  137.             *y = height - oldx;
  138.             *x = oldy;
  139.             break;
  140.         case IDM_UPSIDEDOWN:
  141.             *x = width - oldx;
  142.             *y = height - oldy;
  143.         break;
  144.         case IDM_SEASCAPE:
  145.             *y = oldx;
  146.             *x = width - oldy;
  147.             break;
  148.     }
  149.     return;
  150. }
  151.  
  152. /* get current media index to paper_size[], or -1 if no match */
  153. int
  154. get_paper_size_index(void)
  155. {
  156. int i;
  157.     for (i=0; papersizes[i].name != (char *)NULL; i++) {
  158.         if (!stricmp(papersizes[i].name, option.medianame))
  159.         return i;
  160.     }
  161.     return -1;
  162. }
  163.  
  164. /* calculate bitmap size for gs */
  165. void
  166. gs_size(void)
  167. {
  168. int i = get_paper_size_index();
  169.     if ( (option.xdpi == 0.0) || (option.ydpi == 0.0) )
  170.         option.xdpi = option.ydpi = DEFAULT_RESOLUTION;
  171.     display.epsf_clipped = FALSE;
  172.     switch (option.orientation) {
  173.         case IDM_LANDSCAPE:
  174.         case IDM_SEASCAPE:
  175.         if (i < 0) {
  176.             display.width = option.user_height;
  177.             display.height = option.user_width;
  178.         }
  179.         else {
  180.             display.width = papersizes[i].height;
  181.             display.height = papersizes[i].width;
  182.         }
  183.         break;
  184.         default:
  185.         if ((doc != (PSDOC *)NULL) && doc->epsf
  186.             && option.epsf_clip) {
  187.             display.epsf_clipped = TRUE;
  188.             display.width = doc->boundingbox[URX] - doc->boundingbox[LLX];
  189.             display.height = doc->boundingbox[URY] - doc->boundingbox[LLY];
  190.         }
  191.         else if (i < 0) {
  192.             display.width = option.user_width;
  193.             display.height = option.user_height;
  194.         }
  195.         else {
  196.             display.width = papersizes[i].width;
  197.             display.height = papersizes[i].height;
  198.         }
  199.     }
  200.     display.width  = (unsigned int)(display.width  / 72.0 * option.xdpi);
  201.     display.height = (unsigned int)(display.height / 72.0 * option.ydpi);
  202. }
  203.  
  204. /* change the size of the gs image if open */
  205. void
  206. gs_resize(void)
  207. {
  208.     gs_size();
  209.     if (!gsprog.valid)
  210.         return;
  211.     if ( (psfile.file == (FILE *)NULL) && (doc != (PSDOC *)NULL) )
  212.         dfreopen();
  213.  
  214.     if (option.redisplay && display.page && (doc != (PSDOC *)NULL))
  215.         display.do_display = TRUE;
  216.  
  217.     gsview_endfile();
  218.     display.do_resize = TRUE;
  219. }
  220.  
  221. void
  222. gs_magnify(float scale)
  223. {
  224. int xtemp, ytemp;
  225.     xtemp = (int)(option.xdpi * scale + 0.5);
  226.     ytemp = (int)(option.ydpi * scale + 0.5);
  227.     if ( (xtemp == option.xdpi) && (scale > 1.0) ) {
  228.         option.xdpi++;    /* force magnification if requested */
  229.         option.ydpi++;
  230.     }
  231.     else {
  232.         option.xdpi = xtemp;
  233.         option.ydpi = ytemp;
  234.     }
  235.     dfreopen();
  236.     gs_resize();
  237.     zoom = FALSE;
  238.     dfclose();
  239. }
  240.  
  241. void
  242. gsview_orientation(int new_orientation)
  243. {
  244.     if (new_orientation == option.orientation)
  245.         return;
  246.     if (new_orientation == IDM_SWAPLANDSCAPE) {
  247.         option.swap_landscape = !option.swap_landscape;
  248.         if (option.swap_landscape) 
  249.             check_menu_item(IDM_ORIENTMENU, IDM_SWAPLANDSCAPE, TRUE);
  250.         else
  251.             check_menu_item(IDM_ORIENTMENU, IDM_SWAPLANDSCAPE, FALSE);
  252.         if ((option.orientation != IDM_LANDSCAPE) && (option.orientation != IDM_SEASCAPE))
  253.             return;
  254.     }
  255.     else {
  256.         check_menu_item(IDM_ORIENTMENU, option.orientation, FALSE);
  257.         option.orientation = new_orientation;
  258.         check_menu_item(IDM_ORIENTMENU, option.orientation, TRUE);
  259.     }
  260.     gs_resize();
  261.         zoom = FALSE;
  262.     return;
  263. }
  264.  
  265. void
  266. gsview_media(int new_media)
  267. {
  268.     if ( (new_media == option.media) && (new_media != IDM_USERSIZE) )
  269.         return;
  270.     check_menu_item(IDM_MEDIAMENU, option.media, FALSE);
  271.     option.media = new_media;
  272.     check_menu_item(IDM_MEDIAMENU, option.media, TRUE);
  273.     get_menu_string(IDM_MEDIAMENU, option.media, option.medianame, sizeof(option.medianame));
  274.     gs_resize();
  275.         zoom = FALSE;
  276.     return;
  277. }
  278.  
  279. void
  280. gsview_unit(int new_unit)
  281. {
  282.     check_menu_item(IDM_UNITMENU, option.unit, FALSE);
  283.     option.unit = new_unit;
  284.     check_menu_item(IDM_UNITMENU, option.unit, TRUE);
  285.     info_wait(IDS_NOWAIT);
  286.     return;
  287. }
  288.  
  289. void
  290. gsview_endfile()
  291. {
  292.     if (!gsprog.valid)
  293.         return;
  294.     if (!option.quick ||
  295.              ((doc == (PSDOC *)NULL) && !is_pipe_done())) {
  296.         gs_close();
  297.         return;
  298.     }
  299.  
  300.     if (display.page)
  301.         next_page();
  302.  
  303.     display.do_endfile = TRUE;
  304.     psfile.previous_was_dsc = (doc != (PSDOC *)NULL) && doc->pages;
  305.     if (psfile.previous_was_dsc) {
  306.         strcpy(psfile.previous_name, psfile.name);
  307.         psfile.previous_begintrailer = doc->begintrailer;
  308.         psfile.previous_endtrailer = doc->endtrailer;
  309.     }
  310.     else {
  311.         psfile.previous_name[0] = '\0';
  312.         psfile.previous_begintrailer = 0;
  313.         psfile.previous_endtrailer = 0;
  314.     }
  315.  
  316. }
  317.  
  318. /* open a new document */
  319. void
  320. gsview_openfile(char *filename)
  321. {
  322. int i;
  323.     info_wait(IDS_WAITREAD);
  324.     psfile.pagenum = 1;
  325.     page_extra = 0;
  326.     if (dsc_scan(filename)) {
  327.         /* found DSC comments */
  328.         if (doc->orientation == PORTRAIT)
  329.         gsview_orientation(IDM_PORTRAIT);
  330.         if (doc->orientation == LANDSCAPE)
  331.         gsview_orientation(IDM_LANDSCAPE);
  332.         if (doc->default_page_media) {
  333.         char thismedia[20];
  334.         for (i=IDM_LETTER; i<IDM_USERSIZE; i++) {
  335.             get_menu_string(IDM_MEDIAMENU, i, thismedia, sizeof(thismedia));
  336.             if (!stricmp(thismedia, doc->default_page_media->name)) {
  337.                 gsview_media(i);
  338.                 break;
  339.             }
  340.         }
  341.         if (i == IDM_USERSIZE) {
  342.             gsview_media(IDM_USERSIZE);
  343.             option.user_width  = doc->default_page_media->width;
  344.             option.user_height = doc->default_page_media->height;
  345.             gsview_check_usersize();
  346.         }
  347.         }
  348.     }
  349. }
  350.  
  351.  
  352. /* get filename then open new file for printing or extract */
  353. void 
  354. gsview_select()
  355. {
  356. char buf[MAXSTR];
  357.     strcpy(buf, previous_filename);
  358.     if (get_filename(buf, FALSE, FILTER_PSALL, 0, IDS_TOPICOPEN))
  359.         gsview_selectfile(buf);
  360. }
  361.  
  362. /* open new file for printing or extract */
  363. void
  364. gsview_selectfile(char *filename)
  365. {
  366.     if (gsprog.valid)
  367.         gsview_endfile();
  368.     while (*filename && *filename==' ')
  369.          filename++;
  370.     gsview_openfile(filename);
  371.     strcpy(previous_filename, filename);
  372.     info_wait(IDS_NOWAIT);
  373. }
  374.  
  375. /* get filename then open a new document and display it */
  376. void 
  377. gsview_display()
  378. {
  379. char buf[MAXSTR];
  380.     strcpy(buf, previous_filename);
  381.     if (get_filename(buf, FALSE, FILTER_PSALL, 0, IDS_TOPICOPEN))
  382.         gsview_displayfile(buf);
  383. }
  384.  
  385. /* open a new document and display it */
  386. void
  387. gsview_displayfile(char *filename)
  388. {
  389.     gsview_endfile();
  390.     gsview_openfile(filename);
  391.     strcpy(previous_filename, filename);
  392.     if (display.epsf_clipped || ((doc != (PSDOC *)NULL) 
  393.         && doc->epsf && option.epsf_clip))
  394.         gs_resize();
  395.     display.do_display = TRUE;
  396. }
  397.  
  398.  
  399. /* add Ghostscript code to change orientation */
  400. void
  401. fix_orientation(FILE *f)
  402. {
  403. int real_orientation;
  404. char buf[MAXSTR];
  405.     /* save interpreter state */
  406.     gs_puts("clear cleardictstack save /gsview_save exch def\r\n",f);
  407.     display.saved = TRUE;
  408.     /* provide zoom or epsf offset */
  409.         if (zoom) {
  410.         sprintf(buf,"/gsview_offset {%d %d translate} def\r\n",
  411.             -display.zoom_xoffset, -display.zoom_yoffset);
  412.     }
  413.     else if (display.epsf_clipped)
  414.         sprintf(buf,"/gsview_offset {%d %d translate} def\r\n",
  415.             -doc->boundingbox[LLX], -doc->boundingbox[LLY]);
  416.     else
  417.         sprintf(buf,"/gsview_offset {} def\r\n");
  418.     gs_puts(buf, f);
  419.     real_orientation = option.orientation;
  420.     if (option.swap_landscape) {
  421.         if (option.orientation == IDM_LANDSCAPE)
  422.         real_orientation = IDM_SEASCAPE;
  423.         else if (option.orientation == IDM_SEASCAPE)
  424.         real_orientation = IDM_LANDSCAPE;
  425.     }
  426.     sprintf(buf,"/gsview_landscape  %s def\r\n",
  427.         real_orientation == IDM_LANDSCAPE ? "true" : "false");
  428.     gs_puts(buf, f);
  429.     sprintf(buf,"/gsview_upsidedown %s def\r\n",
  430.         real_orientation ==  IDM_UPSIDEDOWN ? "true" : "false");
  431.     gs_puts(buf, f);
  432.     sprintf(buf,"/gsview_seascape   %s def\r\n",
  433.         real_orientation == IDM_SEASCAPE ? "true" : "false");
  434.     gs_puts(buf, f);
  435.     sprintf(buf,"/gsview_zoom %s def\r\n", zoom ? "true" : "false");
  436.     gs_puts(buf, f);
  437.     send_prolog(f, IDR_ORIENT);
  438. #if !defined(__WIN32__) && defined(GS261)
  439.     if (option.gsversion != IDM_GS261)
  440. #endif
  441.         send_prolog(f, IDR_ORIENT3);
  442.     if (option.epsf_warn)
  443.         send_prolog(f, IDR_EPSFWARN);
  444. }
  445.  
  446. /* Create and open a scratch file with a given name prefix. */
  447. /* Write the actual file name at fname. */
  448. FILE *
  449. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  450. {    char *temp;
  451.     if ( (temp = getenv("TEMP")) == NULL )
  452.         gs_getcwd(fname, MAXSTR);
  453.     else
  454.         strcpy(fname, temp);
  455.  
  456.     /* Prevent X's in path from being converted by mktemp. */
  457.     for ( temp = fname; *temp; temp++ ) {
  458.         *temp = (char)tolower(*temp);
  459.         if (*temp == '/')
  460.             *temp = '\\';
  461.     }
  462.     if ( strlen(fname) && (fname[strlen(fname)-1] != '\\') )
  463.         strcat(fname, "\\");
  464.  
  465.     strcat(fname, prefix);
  466.     strcat(fname, "XXXXXX");
  467.     mktemp(fname);
  468.     return fopen(fname, mode);
  469. }
  470.  
  471. /* reopen psfile */
  472. /* if psfile time/date or length has changed, kill gs and rescan the file */
  473. BOOL
  474. dfreopen()
  475. {
  476. char *filename;
  477.     if (psfile.ispdf) 
  478.         filename = psfile.pdftemp;
  479.     else
  480.         filename = psfile.name;
  481. /*
  482.     if (doc == (PSDOC *)NULL)
  483.         return TRUE;
  484. */
  485.     dfclose();
  486.     if (filename[0] == '\0')
  487.         return FALSE;
  488.     if ( (psfile.file = fopen(filename, "rb")) == (FILE *)NULL ) {
  489.         if (debug)
  490.         message_box("dfreopen: file missing",0);
  491.         filename[0] = '\0';
  492.         return FALSE;
  493.     }
  494.     if (psfile_changed()) {  /* doesn't cope with pdf file changing */
  495.         if (debug)
  496.         message_box("dfreopen: file changed",0);
  497.         /* file may have changed beyond recognition so we must kill gs */
  498.         gs_close();
  499.         if (dsc_scan(psfile.name))
  500.         if (psfile.ispdf) 
  501.             filename = psfile.pdftemp;
  502.         else
  503.             filename = psfile.name;
  504.         dfclose();
  505.             if ( (psfile.file = fopen(filename, "rb")) == (FILE *)NULL ) {
  506.                 psfile.name[0] = '\0';
  507.                 return FALSE;
  508.             }
  509.     }
  510.     return TRUE;
  511. }
  512.  
  513. void
  514. dfclose()
  515. {
  516.     if (psfile.file != (FILE *)NULL)
  517.         fclose(psfile.file);
  518.     psfile.file = (FILE *)NULL;
  519. }
  520.  
  521. /* take a PDF file, process it with gs to produce a DSC index file */
  522. /* then use the index file as a DSC document */
  523. BOOL
  524. dsc_pdf(void)
  525. {
  526. #ifdef OS2
  527.     int flag;
  528.     char command[MAXSTR+MAXSTR];
  529.     char progname[256];
  530.     char *args;
  531.     FILE *tempfile;
  532.     char temp[MAXSTR];
  533.     int i;
  534.     
  535.     gs_close();  /* kill GS to avoid termination queue problems */
  536.  
  537.     /* change directory separators from \ to / */
  538.     strcpy(temp, psfile.name);
  539.     for (args=temp; *args; args++) {
  540.         if (*args == '\\')
  541.         *args = '/';
  542.     }
  543.  
  544.     /* get a temporary filename for pdf DSC index */
  545.     if ( (tempfile = gp_open_scratch_file(szScratch, psfile.pdftemp, "wb")) == (FILE *)NULL)
  546.         return FALSE;
  547.     fclose(tempfile);
  548.     
  549.         if (option.gsversion == IDM_GS351)
  550.         sprintf(command,"-I\042%s\042 %s -dNODISPLAY -sPDFname=\042%s\042 -sDSCname=\042%s\042 pdf2dsc.ps", 
  551.         option.gsinclude, option.gsother, temp, psfile.pdftemp);
  552.     else
  553.         sprintf(command,"-I%s %s -dNODISPLAY -sPDFname=%s -sDSCname=%s pdf2dsc.ps", 
  554.         option.gsinclude, option.gsother, temp, psfile.pdftemp);
  555.  
  556.     if (strlen(command) > MAXSTR-1) {
  557.         /* command line too long */
  558.         gserror(IDS_TOOLONG, command, MB_ICONHAND, SOUND_ERROR);
  559.         if (!debug)
  560.             unlink(psfile.pdftemp);
  561.         psfile.pdftemp[0] = '\0';
  562.         return FALSE;
  563.     }
  564.  
  565.     info_wait(IDS_WAIT);
  566.  
  567.     flag = pdf_convert(option.gsexe, command, &pdfconv);
  568.     if (!flag) {
  569.         gserror(IDS_CANNOTRUN, command, MB_ICONHAND, SOUND_ERROR);
  570.         if (!debug)
  571.             unlink(psfile.pdftemp);
  572.         psfile.pdftemp[0] = '\0';
  573.         info_wait(IDS_NOWAIT);
  574.         return FALSE;
  575.     }
  576.     /* open DSC index file */
  577.     if ( (psfile.file = fopen(psfile.pdftemp, "rb")) == (FILE *)NULL ) {
  578.         psfile.name[0] = '\0';
  579.         return FALSE;
  580.     }
  581.     psfile.ispdf = TRUE;
  582.     return TRUE;
  583. #else
  584.     message_box("Can't handle PDF files", 0);
  585.     return FALSE;
  586. #endif
  587. }
  588.  
  589. /* scan file for PostScript Document Structuring Conventions */
  590. /* return TRUE if valid DSC comments found */
  591. BOOL
  592. dsc_scan(char *filename)
  593. {
  594. char line[MAXSTR];
  595.     dfclose();
  596.     if (psfile.ispdf && psfile.name[0] && psfile.pdftemp[0])
  597.         unlink(psfile.pdftemp);  /* remove temporary DSC file */
  598.     strcpy(psfile.name, filename);
  599.     if ( (psfile.file = fopen(psfile.name, "rb")) == (FILE *)NULL ) {
  600.         psfile.name[0] = '\0';
  601.         return FALSE;
  602.     }
  603.     /* check for PDF */
  604.     psfile.ispdf = FALSE;
  605.     fgets(line, sizeof(line)-1, psfile.file);
  606.         rewind(psfile.file);
  607.     if ( strncmp("%PDF-", line, 5) == 0 ) {
  608.         dfclose();
  609.         if (!dsc_pdf())
  610.         return FALSE;
  611.     }
  612.     /* save file */
  613.     psfile_savestat();
  614.     if (page_list.select)
  615.         free(page_list.select);
  616.     page_list.select = NULL;
  617.     if (doc)
  618.         psfree(doc);
  619.     psfile.preview = 0;
  620.     /* check for documents that start with Ctrl-D */
  621.     psfile.ctrld = (line[0] == '\004');
  622.     if (option.ignore_dsc)
  623.         doc = (PSDOC *)NULL;
  624.     else 
  625.         doc = psscan(psfile.file);
  626.     if (doc == (PSDOC *)NULL) {
  627.         dfclose();
  628.         return FALSE;
  629.     }
  630.     if (doc->doseps) {
  631.         if (doc->doseps->tiff_begin)
  632.         psfile.preview = IDS_EPST;
  633.         if (doc->doseps->mf_begin)
  634.         psfile.preview = IDS_EPSW;
  635.     }
  636.     if (!psfile.preview && (doc->beginpreview != doc->endpreview))
  637.         psfile.preview = IDS_EPSI;
  638.     page_list.select = (BOOL *)malloc( doc->numpages * sizeof(BOOL) );
  639.     if (doc->numpages) {
  640.         int i;
  641.         char *label;
  642.         for (i=0; i<doc->numpages; i++) {
  643.         if ( (label = doc->pages[i].label) != NULL)  {
  644.             if (strlen(label)==0) {    /* remove old empty label */
  645.             free(label);
  646.             sprintf(line, "%d", i+1);
  647.             label = malloc(strlen(line)+1);
  648.             if (label)
  649.                 strcpy(label, line);
  650.             doc->pages[i].label = label;
  651.             }
  652.         }
  653.         }
  654.         page_list.select = (BOOL *)malloc( doc->numpages * sizeof(BOOL) );
  655.     }
  656.     if (doc->epsf) {
  657.         /* warn if bounding box off the page */
  658.         int i = get_paper_size_index();
  659.         int width, height;
  660.         if (i < 0) {
  661.             width = option.user_width;
  662.             height = option.user_height;
  663.         }
  664.         else {
  665.             width = papersizes[i].width;
  666.             height = papersizes[i].height;
  667.         }
  668.         if (!option.epsf_clip &&
  669.             ((doc->boundingbox[LLX] > width) || 
  670.          (doc->boundingbox[LLY] > height) ||
  671.              (doc->boundingbox[URX] < 0) || 
  672.          (doc->boundingbox[URY] < 0))
  673.            ) {
  674.         load_string(IDS_EPS_OFF_PAGE, line, sizeof(line));
  675.         message_box(line, 0);
  676.         }
  677.     }
  678.     return TRUE;
  679. }
  680.  
  681.  
  682.  
  683. /* Copy specified pages from psfile.file to file f */
  684. void
  685. dsc_getpages(FILE *f, int first, int last)
  686. {
  687. int i, page;
  688. char buf[MAXSTR];
  689.     for (i=first-1; i<last; i++) {
  690.         page = map_page(i);
  691.         if (doc->pages) {
  692.             sprintf(buf,"(Page: %s %d\\n) print flush\r\n", doc->pages[page].label ? doc->pages[page].label : " ", page+1);
  693.         gs_puts(buf, f);
  694.             if (debug)
  695.             gs_puts("%GSview beginpage\r\n", gsprog.input);
  696.         gs_copy(psfile.file, f, doc->pages[page].begin, doc->pages[page].end);
  697.             if (debug)
  698.             gs_puts("%GSview endpage\r\n", gsprog.input);
  699.         }
  700.         else {
  701.             sprintf(buf,"(Page: %d\\n) print flush\r\n",page); 
  702.         gs_puts(buf, f);
  703.             if (debug)
  704.             gs_puts("%GSview endsetup\r\n", gsprog.input);
  705.         gs_copy(psfile.file, f, doc->endsetup, doc->endtrailer);
  706.             if (debug)
  707.             gs_puts("\n%GSview endtrailer\r\n", gsprog.input);
  708.         }
  709.     }
  710. }
  711.  
  712.  
  713. /* Copy dsc header to file f */
  714. void
  715. dsc_header(FILE *f)
  716. {
  717. char *p, *d;
  718. char buf[MAXSTR];
  719.     d = buf;
  720.     gs_puts("(Displaying ",f);
  721.     for (p=psfile.name; *p; p++) {
  722.         if (*p != '\\')
  723.         *d++ = *p;
  724.         else
  725.             *d++ = '/';
  726.     }
  727.     *d = '\0';
  728.     gs_puts(buf, f);
  729.     gs_puts("\\n) print flush\r\n", f);
  730.     if (debug)
  731.         gs_puts("%GSview beginheader\r\n", gsprog.input);
  732.     gs_copy(psfile.file, f, doc->beginheader, doc->endheader);
  733.     if (debug)
  734.         gs_puts("%GSview endheader\r\n%GSview begindefaults\r\n", gsprog.input);
  735.     gs_copy(psfile.file, f, doc->begindefaults, doc->enddefaults);
  736.     if (debug)
  737.         gs_puts("%GSview enddefaults\r\n%GSview beginprolog\r\n", gsprog.input);
  738.     gs_copy(psfile.file, f, doc->beginprolog, doc->endprolog);
  739.     if (debug)
  740.         gs_puts("%GSview endprolog\r\n%GSview beginsetup\r\n", gsprog.input);
  741.     gs_copy(psfile.file, f, doc->beginsetup, doc->endsetup);
  742.     if (debug)
  743.         gs_puts("%GSview endsetup\r\n", gsprog.input);
  744. }
  745.  
  746.  
  747. /* Send commands to gs to display page */
  748. void
  749. dsc_dopage(void)
  750. {
  751.     info_wait(IDS_WAITDRAW);
  752.     display.do_display = TRUE;
  753. }
  754.  
  755. /* skip pages */
  756. void
  757. dsc_skip(int skip)
  758. {
  759.     if ( (skip == 0)
  760.       || ((skip > 0) && (psfile.pagenum == doc->numpages))
  761.       || ((skip < 0) && (psfile.pagenum == 1))
  762.       || (doc->numpages == 0) ) {
  763.         play_sound(SOUND_NOPAGE);
  764.         info_wait(IDS_NOWAIT);
  765.         return;
  766.     }
  767.     psfile.pagenum += skip;
  768.     if (psfile.pagenum > (int)doc->numpages)
  769.          psfile.pagenum = doc->numpages;
  770.     if (psfile.pagenum < 1)
  771.         psfile.pagenum = 1;
  772.     info_wait(IDS_WAIT);
  773.     if (display.page)
  774.         next_page();
  775.     if (gs_open())
  776.         dsc_dopage();
  777. }
  778.  
  779. /* reverse zero based page number if needed */
  780. int
  781. map_page(int page)
  782. {
  783.         if (doc->pageorder == DESCEND) 
  784.         return (doc->numpages - 1) - page;
  785.     return page;
  786. }
  787.  
  788. /* Send necessary output to display Ghostscript */
  789. /* This must not be called from thread 1 because it is lengthy */
  790. /* Functions called from here must NOT create windows since this */
  791. /* thread does not have an anchor block or message queue */
  792. /* returns TRUE if OK, FALSE if aborted */
  793. BOOL
  794. do_output()
  795. {
  796.     char *p, *d;
  797.     char debug_filename[MAXSTR];
  798.     char buf[256];
  799.  
  800.     if (debug_file != (FILE *)NULL)
  801.     fclose(debug_file);
  802.     if (debug)
  803.         debug_file = gp_open_scratch_file(szScratch, debug_filename, "wb");
  804.  
  805.     if (gsprog.valid && display.page)
  806.     next_page();
  807.  
  808. #if !defined(__WIN32__) && defined(GS261)
  809.     if (option.gsversion != IDM_GS261) {
  810. #endif
  811.     /* Cause a GS_BEGIN message to be sent to GSview */
  812. /*
  813.     gs_puts("(Begin\\n) print flush\r\n", gsprog.input);
  814. */
  815.     gs_puts("-1 false .outputpage\r\n", gsprog.input);
  816. #if !defined(__WIN32__) && defined(GS261)
  817.     }
  818. #endif
  819.  
  820.     if (display.do_endfile && gsprog.valid) {
  821.     if ((display.saved) && (psfile.previous_was_dsc)) {
  822.         /* send trailer if needed */
  823.         FILE *f;
  824.         if ( (f = fopen(psfile.previous_name, "rb")) != (FILE *)NULL ) {
  825.             if (debug)
  826.             gs_puts("%GSview begintrailer\r\n", gsprog.input);
  827.             gs_copy(f, gsprog.input, psfile.previous_begintrailer, psfile.previous_endtrailer);
  828.             if (debug)
  829.             gs_puts("%GSview endtrailer\r\n", gsprog.input);
  830.         fclose(f);
  831.         }
  832.     }
  833.     if (display.saved) {
  834.         /* restore interpreter state */
  835.         gs_puts("gsview_cleanup\r\ngsview_save restore\r\n", gsprog.input);
  836.     }
  837.     else
  838.         gs_puts("clear cleardictstack\r\n", gsprog.input);
  839.     gs_puts("erasepage\r\n", gsprog.input); /* needed for documents that don't use showpage */
  840.     display.saved = FALSE;
  841.     }
  842.  
  843.     if (display.abort)
  844.     return FALSE;
  845.  
  846.     if (display.do_resize && gsprog.valid) {
  847.     sprintf(buf, "mark /HWSize [%u %u]\r\n",display.width,display.height);
  848.     gs_puts(buf, gsprog.input);
  849.     if (zoom)
  850.             sprintf(buf,"/HWResolution [%g %g]\r\n",option.zoom_xdpi,option.zoom_ydpi);
  851.         else
  852.             sprintf(buf,"/HWResolution [%g %g]\r\n",option.xdpi,option.ydpi);
  853.     gs_puts(buf, gsprog.input);
  854.         sprintf(buf,"currentdevice putdeviceprops pop initgraphics erasepage\r\n");
  855.     gs_puts(buf, gsprog.input);
  856.     }
  857.  
  858.     if (display.abort)
  859.     return FALSE;
  860.  
  861.     if (display.do_display) {
  862.     if (doc != (PSDOC *)NULL) {
  863.         /* found DSC comments */
  864.         if (!display.saved) {
  865.             fix_orientation(gsprog.input);
  866.             dsc_header(gsprog.input);
  867.         }
  868.             if (display.abort)
  869.             return FALSE;
  870.         dsc_getpages(gsprog.input,psfile.pagenum,psfile.pagenum);
  871.     }
  872.     else {
  873.         if (!display.saved) {
  874.             fix_orientation(gsprog.input);
  875.         }
  876.         /* non conformant file - send unmodified */
  877.         gs_puts("(Displaying ",gsprog.input);
  878.         d = buf;
  879.         for (p=psfile.name; *p; p++) {
  880.         if (*p != '\\')
  881.             *d++ = *p;
  882.         else
  883.             *d++ = '/';
  884.         }
  885.         *d = '\0';
  886.         gs_puts(buf, gsprog.input);
  887.         gs_puts("\\n) print flush\r\n",gsprog.input);
  888.         d = buf;
  889.         *d++ = '(';
  890.         for (p=psfile.name; *p; p++) {
  891.         if (*p != '\\')
  892.             *d++ = *p;
  893.         else
  894.             *d++ = '/';
  895.         }
  896.         *d = '\0';
  897.         gs_puts(buf, gsprog.input);
  898.         gs_puts(") run\r\n",gsprog.input);
  899.     }
  900.     }
  901.  
  902. #if !defined(__WIN32__) && defined(GS261)
  903.     if (option.gsversion != IDM_GS261) {
  904. #endif
  905.     /* Cause a GS_END message to be sent to GSview */
  906. /*
  907.     gs_puts("(End\\n) print flush\r\n", gsprog.input);
  908. */
  909.     gs_puts("-2 false .outputpage\r\n", gsprog.input);
  910. #if !defined(__WIN32__) && defined(GS261)
  911.     }
  912. #endif
  913.  
  914.     if (gsprog.valid)
  915.         gs_puts("flushpage\r\n",gsprog.input);
  916.  
  917.     dfclose();
  918.     if (debug_file)
  919.         fclose(debug_file);
  920.     debug_file = (FILE *)NULL;
  921.  
  922.  
  923.     return TRUE;    /* all done */
  924. }
  925.