home *** CD-ROM | disk | FTP | other *** search
/ swCHIP 1991 January / swCHIP_95-1.bin / utility / gsview13 / src / gvcdisp.c < prev    next >
C/C++ Source or Header  |  1995-12-09  |  24KB  |  891 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(FALSE);
  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.     load_string(IDS_WAITREAD, szWait, sizeof(szWait));
  324.     info_wait(TRUE);
  325.     psfile.pagenum = 1;
  326.     page_extra = 0;
  327.     if (dsc_scan(filename)) {
  328.         /* found DSC comments */
  329.         if (doc->orientation == PORTRAIT)
  330.         gsview_orientation(IDM_PORTRAIT);
  331.         if (doc->orientation == LANDSCAPE)
  332.         gsview_orientation(IDM_LANDSCAPE);
  333.         if (doc->default_page_media) {
  334.         char thismedia[20];
  335.         for (i=IDM_LETTER; i<IDM_USERSIZE; i++) {
  336.             get_menu_string(IDM_MEDIAMENU, i, thismedia, sizeof(thismedia));
  337.             if (!stricmp(thismedia, doc->default_page_media->name)) {
  338.                 gsview_media(i);
  339.                 break;
  340.             }
  341.         }
  342.         if (i == IDM_USERSIZE) {
  343.             gsview_media(IDM_USERSIZE);
  344.             option.user_width  = doc->default_page_media->width;
  345.             option.user_height = doc->default_page_media->height;
  346.             gsview_check_usersize();
  347.         }
  348.         }
  349.     }
  350. }
  351.  
  352.  
  353. /* get filename then open new file for printing or extract */
  354. void 
  355. gsview_select()
  356. {
  357. char buf[MAXSTR];
  358.     strcpy(buf, previous_filename);
  359.     if (get_filename(buf, FALSE, FILTER_PSALL, 0, IDS_TOPICOPEN))
  360.         gsview_selectfile(buf);
  361. }
  362.  
  363. /* open new file for printing or extract */
  364. void
  365. gsview_selectfile(char *filename)
  366. {
  367.     if (gsprog.valid)
  368.         gsview_endfile();
  369.     while (*filename && *filename==' ')
  370.          filename++;
  371.     gsview_openfile(filename);
  372.     strcpy(previous_filename, filename);
  373.     info_wait(FALSE);
  374. }
  375.  
  376. /* get filename then open a new document and display it */
  377. void 
  378. gsview_display()
  379. {
  380. char buf[MAXSTR];
  381.     strcpy(buf, previous_filename);
  382.     if (get_filename(buf, FALSE, FILTER_PSALL, 0, IDS_TOPICOPEN))
  383.         gsview_displayfile(buf);
  384. }
  385.  
  386. /* open a new document and display it */
  387. void
  388. gsview_displayfile(char *filename)
  389. {
  390.     gsview_endfile();
  391.     gsview_openfile(filename);
  392.     strcpy(previous_filename, filename);
  393.     if (display.epsf_clipped || ((doc != (PSDOC *)NULL) 
  394.         && doc->epsf && option.epsf_clip))
  395.         gs_resize();
  396.     display.do_display = TRUE;
  397. }
  398.  
  399.  
  400. /* add Ghostscript code to change orientation */
  401. void
  402. fix_orientation(FILE *f)
  403. {
  404. int real_orientation;
  405. char buf[MAXSTR];
  406.     /* save interpreter state */
  407.     gs_puts("clear cleardictstack save /gsview_save exch def\r\n",f);
  408.     display.saved = TRUE;
  409.     /* provide zoom or epsf offset */
  410.         if (zoom) {
  411.         sprintf(buf,"/gsview_offset {%d %d translate} def\r\n",
  412.             -display.zoom_xoffset, -display.zoom_yoffset);
  413.     }
  414.     else if (display.epsf_clipped)
  415.         sprintf(buf,"/gsview_offset {%d %d translate} def\r\n",
  416.             -doc->boundingbox[LLX], -doc->boundingbox[LLY]);
  417.     else
  418.         sprintf(buf,"/gsview_offset {} def\r\n");
  419.     gs_puts(buf, f);
  420.     real_orientation = option.orientation;
  421.     if (option.swap_landscape) {
  422.         if (option.orientation == IDM_LANDSCAPE)
  423.         real_orientation = IDM_SEASCAPE;
  424.         else if (option.orientation == IDM_SEASCAPE)
  425.         real_orientation = IDM_LANDSCAPE;
  426.     }
  427.     sprintf(buf,"/gsview_landscape  %s def\r\n",
  428.         real_orientation == IDM_LANDSCAPE ? "true" : "false");
  429.     gs_puts(buf, f);
  430.     sprintf(buf,"/gsview_upsidedown %s def\r\n",
  431.         real_orientation ==  IDM_UPSIDEDOWN ? "true" : "false");
  432.     gs_puts(buf, f);
  433.     sprintf(buf,"/gsview_seascape   %s def\r\n",
  434.         real_orientation == IDM_SEASCAPE ? "true" : "false");
  435.     gs_puts(buf, f);
  436.     sprintf(buf,"/gsview_zoom %s def\r\n", zoom ? "true" : "false");
  437.     gs_puts(buf, f);
  438.     send_prolog(f, IDR_ORIENT);
  439. #if !defined(__WIN32__) && defined(GS261)
  440.     if (option.gsversion != IDM_GS261)
  441. #endif
  442.         send_prolog(f, IDR_ORIENT3);
  443.     if (option.epsf_warn)
  444.         send_prolog(f, IDR_EPSFWARN);
  445. }
  446.  
  447. /* Create and open a scratch file with a given name prefix. */
  448. /* Write the actual file name at fname. */
  449. FILE *
  450. gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
  451. {    char *temp;
  452.     if ( (temp = getenv("TEMP")) == NULL )
  453.         _getcwd(fname, MAXSTR);
  454.     else
  455.         strcpy(fname, temp);
  456.  
  457.     /* Prevent X's in path from being converted by mktemp. */
  458.     for ( temp = fname; *temp; temp++ ) {
  459.         *temp = (char)tolower(*temp);
  460.         if (*temp == '/')
  461.             *temp = '\\';
  462.     }
  463.     if ( strlen(fname) && (fname[strlen(fname)-1] != '\\') )
  464.         strcat(fname, "\\");
  465.  
  466.     strcat(fname, prefix);
  467.     strcat(fname, "XXXXXX");
  468.     mktemp(fname);
  469.     return fopen(fname, mode);
  470. }
  471.  
  472. /* reopen psfile */
  473. /* if psfile time/date or length has changed, kill gs and rescan the file */
  474. BOOL
  475. dfreopen()
  476. {
  477. char *filename;
  478.     if (psfile.ispdf) 
  479.         filename = psfile.pdftemp;
  480.     else
  481.         filename = psfile.name;
  482.     if (doc == (PSDOC *)NULL)
  483.         return TRUE;
  484.     dfclose();
  485.     if (filename[0] == '\0')
  486.         return TRUE;
  487.     if ( (psfile.file = fopen(filename, "rb")) == (FILE *)NULL ) {
  488.         if (debug)
  489.         message_box("dfreopen: file missing",0);
  490.         filename[0] = '\0';
  491.         return FALSE;
  492.     }
  493.     if (psfile_changed()) {  /* doesn't cope with pdf file changing */
  494.         if (debug)
  495.         message_box("dfreopen: file changed",0);
  496.         /* file may have changed beyond recognition so we must kill gs */
  497.         gs_close();
  498.         if (dsc_scan(psfile.name))
  499.         if (psfile.ispdf) 
  500.             filename = psfile.pdftemp;
  501.         else
  502.             filename = psfile.name;
  503.             if ( (psfile.file = fopen(filename, "rb")) == (FILE *)NULL ) {
  504.                 psfile.name[0] = '\0';
  505.                 return FALSE;
  506.             }
  507.     }
  508.     return TRUE;
  509. }
  510.  
  511. void
  512. dfclose()
  513. {
  514.     if (psfile.file != (FILE *)NULL)
  515.         fclose(psfile.file);
  516.     psfile.file = (FILE *)NULL;
  517. }
  518.  
  519. /* take a PDF file, process it with gs to produce a DSC index file */
  520. /* then use the index file as a DSC document */
  521. BOOL
  522. dsc_pdf(void)
  523. {
  524. #ifdef OS2
  525.     int flag;
  526.     char command[MAXSTR+MAXSTR];
  527.     char progname[256];
  528.     char *args;
  529.     FILE *tempfile;
  530.     char temp[MAXSTR];
  531.     int i;
  532.     
  533.     /* change directory separators from \ to / */
  534.     strcpy(temp, psfile.name);
  535.     for (args=temp; *args; args++) {
  536.         if (*args == '\\')
  537.         *args = '/';
  538.     }
  539.  
  540.     args = strchr(option.gscommand, ' ');
  541.     if (args) {
  542.         strncpy(progname, option.gscommand, (int)(args-option.gscommand));
  543.         progname[(int)(args-option.gscommand)] = '\0';
  544.         args++;
  545.     }
  546.     else {
  547.         strncpy(progname, option.gscommand, MAXSTR);
  548.         args = "";
  549.     }
  550.  
  551.     /* get a temporary filename for pdf DSC index */
  552.     if ( (tempfile = gp_open_scratch_file(szScratch, psfile.pdftemp, "wb")) == (FILE *)NULL)
  553.         return FALSE;
  554.     fclose(tempfile);
  555.     
  556.     sprintf(command,"%s -dNODISPLAY -sPDFname=%s -sDSCname=%s pdf2dsc.ps", args, temp, psfile.pdftemp);
  557.  
  558.     if (strlen(command) > MAXSTR-1) {
  559.         /* command line too long */
  560.         gserror(IDS_TOOLONG, command, MB_ICONHAND, SOUND_ERROR);
  561.         if (!debug)
  562.             unlink(psfile.pdftemp);
  563.         psfile.pdftemp[0] = '\0';
  564.         return FALSE;
  565.     }
  566.  
  567.     load_string(IDS_WAIT, szWait, sizeof(szWait));
  568.     info_wait(TRUE);
  569.  
  570.     flag = pdf_convert(progname, command, &pdfconv);
  571.     if (!flag) {
  572.         gserror(IDS_CANNOTRUN, command, MB_ICONHAND, SOUND_ERROR);
  573.         if (!debug)
  574.             unlink(psfile.pdftemp);
  575.         psfile.pdftemp[0] = '\0';
  576.         info_wait(FALSE);
  577.         return FALSE;
  578.     }
  579.     /* open DSC index file */
  580.     if ( (psfile.file = fopen(psfile.pdftemp, "rb")) == (FILE *)NULL ) {
  581.         psfile.name[0] = '\0';
  582.         return FALSE;
  583.     }
  584.     psfile.ispdf = TRUE;
  585.     return TRUE;
  586. #else
  587.     message_box("Can't handle PDF files", 0);
  588.     return FALSE;
  589. #endif
  590. }
  591.  
  592. /* scan file for PostScript Document Structuring Conventions */
  593. /* return TRUE if valid DSC comments found */
  594. BOOL
  595. dsc_scan(char *filename)
  596. {
  597. char line[MAXSTR];
  598.     dfclose();
  599.     if (psfile.ispdf && psfile.name[0] && psfile.pdftemp[0])
  600.         unlink(psfile.pdftemp);  /* remove temporary DSC file */
  601.     strcpy(psfile.name, filename);
  602.     if ( (psfile.file = fopen(psfile.name, "rb")) == (FILE *)NULL ) {
  603.         psfile.name[0] = '\0';
  604.         return FALSE;
  605.     }
  606.     /* check for PDF */
  607.     psfile.ispdf = FALSE;
  608.     fgets(line, sizeof(line)-1, psfile.file);
  609.         rewind(psfile.file);
  610.     if ( strncmp("%PDF-", line, 5) == 0 ) {
  611.         dfclose();
  612.         if (!dsc_pdf())
  613.         return FALSE;
  614.     }
  615.     /* save file */
  616.     psfile_savestat();
  617.     if (page_list.select)
  618.         free(page_list.select);
  619.     page_list.select = NULL;
  620.     if (doc)
  621.         psfree(doc);
  622.     psfile.preview = 0;
  623.     /* check for documents that start with Ctrl-D */
  624.     psfile.ctrld = (line[0] == '\004');
  625.     if (option.ignore_dsc)
  626.         doc = (PSDOC *)NULL;
  627.     else 
  628.         doc = psscan(psfile.file);
  629.     if (doc == (PSDOC *)NULL) {
  630.         dfclose();
  631.         return FALSE;
  632.     }
  633.     if (doc->doseps) {
  634.         if (doc->doseps->tiff_begin)
  635.         psfile.preview = IDS_EPST;
  636.         if (doc->doseps->mf_begin)
  637.         psfile.preview = IDS_EPSW;
  638.     }
  639.     if (!psfile.preview && (doc->beginpreview != doc->endpreview))
  640.         psfile.preview = IDS_EPSI;
  641.     page_list.select = (BOOL *)malloc( doc->numpages * sizeof(BOOL) );
  642.     return TRUE;
  643. }
  644.  
  645.  
  646.  
  647. /* Copy specified pages from psfile.file to file f */
  648. void
  649. dsc_getpages(FILE *f, int first, int last)
  650. {
  651. int i, page;
  652. char buf[MAXSTR];
  653.     for (i=first-1; i<last; i++) {
  654.         page = map_page(i);
  655.         if (doc->pages) {
  656.             sprintf(buf,"(Page: %s %d\\n) print flush\r\n", doc->pages[page].label ? doc->pages[page].label : " ", page+1);
  657.         gs_puts(buf, f);
  658.             if (debug)
  659.             gs_puts("%GSview beginpage\r\n", gsprog.input);
  660.         gs_copy(psfile.file, f, doc->pages[page].begin, doc->pages[page].end);
  661.             if (debug)
  662.             gs_puts("%GSview endpage\r\n", gsprog.input);
  663.         }
  664.         else {
  665.             sprintf(buf,"(Page: %d\\n) print flush\r\n",page); 
  666.         gs_puts(buf, f);
  667.             if (debug)
  668.             gs_puts("%GSview endsetup\r\n", gsprog.input);
  669.         gs_copy(psfile.file, f, doc->endsetup, doc->endtrailer);
  670.             if (debug)
  671.             gs_puts("\n%GSview endtrailer\r\n", gsprog.input);
  672.         }
  673.     }
  674. }
  675.  
  676.  
  677. /* Copy dsc header to file f */
  678. void
  679. dsc_header(FILE *f)
  680. {
  681. char *p, *d;
  682. char buf[MAXSTR];
  683.     d = buf;
  684.     gs_puts("(Displaying ",f);
  685.     for (p=psfile.name; *p; p++) {
  686.         if (*p != '\\')
  687.         *d++ = *p;
  688.         else
  689.             *d++ = '/';
  690.     }
  691.     *d = '\0';
  692.     gs_puts(buf, f);
  693.     gs_puts("\\n) print flush\r\n", f);
  694.     if (debug)
  695.         gs_puts("%GSview beginheader\r\n", gsprog.input);
  696.     gs_copy(psfile.file, f, doc->beginheader, doc->endheader);
  697.     if (debug)
  698.         gs_puts("%GSview endheader\r\n%GSview begindefaults\r\n", gsprog.input);
  699.     gs_copy(psfile.file, f, doc->begindefaults, doc->enddefaults);
  700.     if (debug)
  701.         gs_puts("%GSview enddefaults\r\n%GSview beginprolog\r\n", gsprog.input);
  702.     gs_copy(psfile.file, f, doc->beginprolog, doc->endprolog);
  703.     if (debug)
  704.         gs_puts("%GSview endprolog\r\n%GSview beginsetup\r\n", gsprog.input);
  705.     gs_copy(psfile.file, f, doc->beginsetup, doc->endsetup);
  706.     if (debug)
  707.         gs_puts("%GSview endsetup\r\n", gsprog.input);
  708. }
  709.  
  710.  
  711. /* Send commands to gs to display page */
  712. void
  713. dsc_dopage(void)
  714. {
  715.     load_string(IDS_WAITDRAW, szWait, sizeof(szWait));
  716.     info_wait(TRUE);
  717.     display.do_display = TRUE;
  718. }
  719.  
  720. /* skip pages */
  721. void
  722. dsc_skip(int skip)
  723. {
  724.     if ( (skip == 0)
  725.       || ((skip > 0) && (psfile.pagenum == doc->numpages))
  726.       || ((skip < 0) && (psfile.pagenum == 1))
  727.       || (doc->numpages == 0) ) {
  728.         play_sound(SOUND_NOPAGE);
  729.         info_wait(FALSE);
  730.         return;
  731.     }
  732.     psfile.pagenum += skip;
  733.     if (psfile.pagenum > (int)doc->numpages)
  734.          psfile.pagenum = doc->numpages;
  735.     if (psfile.pagenum < 1)
  736.         psfile.pagenum = 1;
  737.     load_string(IDS_WAIT, szWait, sizeof(szWait));
  738.     info_wait(TRUE);
  739.     if (display.page)
  740.         next_page();
  741.     if (gs_open())
  742.         dsc_dopage();
  743. }
  744.  
  745. /* reverse zero based page number if needed */
  746. int
  747. map_page(int page)
  748. {
  749.         if (doc->pageorder == DESCEND) 
  750.         return (doc->numpages - 1) - page;
  751.     return page;
  752. }
  753.  
  754. /* Send necessary output to display Ghostscript */
  755. /* This must not be called from thread 1 because it is lengthy */
  756. /* Functions called from here must NOT create windows since this */
  757. /* thread does not have an anchor block or message queue */
  758. /* returns TRUE if OK, FALSE if aborted */
  759. BOOL
  760. do_output()
  761. {
  762.     char *p, *d;
  763.     char debug_filename[MAXSTR];
  764.     char buf[256];
  765.  
  766.     if (debug_file != (FILE *)NULL)
  767.     fclose(debug_file);
  768.     if (debug)
  769.         debug_file = gp_open_scratch_file(szScratch, debug_filename, "wb");
  770.  
  771.     if (gsprog.valid && display.page)
  772.     next_page();
  773.  
  774. #if !defined(__WIN32__) && defined(GS261)
  775.     if (option.gsversion != IDM_GS261) {
  776. #endif
  777.     /* Cause a GS_BEGIN message to be sent to GSview */
  778. /*
  779.     gs_puts("(Begin\\n) print flush\r\n", gsprog.input);
  780. */
  781.     gs_puts("-1 false .outputpage\r\n", gsprog.input);
  782. #if !defined(__WIN32__) && defined(GS261)
  783.     }
  784. #endif
  785.  
  786.     if (display.do_endfile && gsprog.valid) {
  787.     if ((display.saved) && (psfile.previous_was_dsc)) {
  788.         /* send trailer if needed */
  789.         FILE *f;
  790.         if ( (f = fopen(psfile.previous_name, "rb")) != (FILE *)NULL ) {
  791.             if (debug)
  792.             gs_puts("%GSview begintrailer\r\n", gsprog.input);
  793.             gs_copy(f, gsprog.input, psfile.previous_begintrailer, psfile.previous_endtrailer);
  794.             if (debug)
  795.             gs_puts("%GSview endtrailer\r\n", gsprog.input);
  796.         fclose(f);
  797.         }
  798.     }
  799.     if (display.saved) {
  800.         /* restore interpreter state */
  801.         gs_puts("gsview_cleanup\r\ngsview_save restore\r\n", gsprog.input);
  802.     }
  803.     else
  804.         gs_puts("clear cleardictstack\r\n", gsprog.input);
  805.     gs_puts("erasepage\r\n", gsprog.input); /* needed for documents that don't use showpage */
  806.     display.saved = FALSE;
  807.     }
  808.  
  809.     if (display.abort)
  810.     return FALSE;
  811.  
  812.     if (display.do_resize && gsprog.valid) {
  813.     sprintf(buf, "mark /HWSize [%u %u]\r\n",display.width,display.height);
  814.     gs_puts(buf, gsprog.input);
  815.     if (zoom)
  816.             sprintf(buf,"/HWResolution [%g %g]\r\n",option.zoom_xdpi,option.zoom_ydpi);
  817.         else
  818.             sprintf(buf,"/HWResolution [%g %g]\r\n",option.xdpi,option.ydpi);
  819.     gs_puts(buf, gsprog.input);
  820.         sprintf(buf,"currentdevice putdeviceprops pop initgraphics erasepage\r\n");
  821.     gs_puts(buf, gsprog.input);
  822.     }
  823.  
  824.     if (display.abort)
  825.     return FALSE;
  826.  
  827.     if (display.do_display) {
  828.     if (doc != (PSDOC *)NULL) {
  829.         /* found DSC comments */
  830.         if (!display.saved) {
  831.             fix_orientation(gsprog.input);
  832.             dsc_header(gsprog.input);
  833.         }
  834.             if (display.abort)
  835.             return FALSE;
  836.         dsc_getpages(gsprog.input,psfile.pagenum,psfile.pagenum);
  837.     }
  838.     else {
  839.         if (!display.saved) {
  840.             fix_orientation(gsprog.input);
  841.         }
  842.         /* non conformant file - send unmodified */
  843.         gs_puts("(Displaying ",gsprog.input);
  844.         d = buf;
  845.         for (p=psfile.name; *p; p++) {
  846.         if (*p != '\\')
  847.             *d++ = *p;
  848.         else
  849.             *d++ = '/';
  850.         }
  851.         *d = '\0';
  852.         gs_puts(buf, gsprog.input);
  853.         gs_puts("\\n) print flush\r\n",gsprog.input);
  854.         d = buf;
  855.         *d++ = '(';
  856.         for (p=psfile.name; *p; p++) {
  857.         if (*p != '\\')
  858.             *d++ = *p;
  859.         else
  860.             *d++ = '/';
  861.         }
  862.         *d = '\0';
  863.         gs_puts(buf, gsprog.input);
  864.         gs_puts(") run\r\n",gsprog.input);
  865.     }
  866.     }
  867.  
  868. #if !defined(__WIN32__) && defined(GS261)
  869.     if (option.gsversion != IDM_GS261) {
  870. #endif
  871.     /* Cause a GS_END message to be sent to GSview */
  872. /*
  873.     gs_puts("(End\\n) print flush\r\n", gsprog.input);
  874. */
  875.     gs_puts("-2 false .outputpage\r\n", gsprog.input);
  876. #if !defined(__WIN32__) && defined(GS261)
  877.     }
  878. #endif
  879.  
  880.     if (gsprog.valid)
  881.         gs_puts("flushpage\r\n",gsprog.input);
  882.  
  883.     dfclose();
  884.     if (debug_file)
  885.         fclose(debug_file);
  886.     debug_file = (FILE *)NULL;
  887.  
  888.  
  889.     return TRUE;    /* all done */
  890. }
  891.