⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvcdll.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Copyright (C) 1993-2004, Ghostgum Software Pty Ltd.  All rights reserved.
  
  This file is part of GSview.
   
  This program is distributed with NO WARRANTY OF ANY KIND.  No author
  or distributor accepts any responsibility for the consequences of using it,
  or for whether it serves any particular purpose or works at all, unless he
  or she says so in writing.  Refer to the GSview Licence (the "Licence") 
  for full details.
   
  Every copy of GSview must include a copy of the Licence, normally in a 
  plain ASCII text file named LICENCE.  The Licence grants you the right 
  to copy, modify and redistribute GSview, but only under certain conditions 
  described in the Licence.  Among other things, the Licence requires that 
  the copyright notice and this notice be preserved on all copies.
*/

/* gvcdll.c */
/* GS DLL associated routines */
#include "gvc.h"
#include <stdarg.h>

#define GS_UNSAFE 703

GSDLL gsdll;		/* the main DLL structure */
IMAGE image;		/* display device */
VIEW view;
PENDING pending;	/* operations that must wait */
int execute_code;	/* return code from gsapi_run_string_continue */
BOOL in_pstotext = FALSE;


/* forward declarations */
#ifndef VIEWONLY
int gs_process_pstotext(void);
#endif
int gsview_page_orientation(int page);
void d_calc_resize(int pagenum, float *pwidth, float *pheight, 
    int *pxoffset, int *pyoffset);
int d_resize(int pagenum);
int d_save(void);
int d_restore(void);
int d_init1(void);
int d_init2(void);
int d_permitread(void);
int d_pdf_page(int pagenum);
int get_gs_input(char *buf, int blen);
int send_trailer(void);
int send_document(void);
BOOL gs_process_trailer(void);
int gs_process_prepare_input(PENDING *ppend);
int gs_process_loop2(PENDING *ppend);
int gs_process_pending(PENDING *lpending);
int gs_process_loop1(void);

int
gs_execute(const char *str, int len)
{
    int exit_code;
    if (gsdll.run_string_continue == NULL)
	return 255;
    execute_code = gsdll.run_string_continue(gsdll.minst, str, len, 
	0, &exit_code);
    if (execute_code == e_NeedInput)
	execute_code = 0;	/* normal return */
#ifdef NOTUSED
    if (debug & DEBUG_GENERAL) {
	char buf[MAXSTR];
	gs_addmessf("\n----Begin %d bytes----\n", len);
	gs_addmess_count(str, len);
	gs_addmessf("\n----End of %d bytes----\n", len);
/*
*/
	sprintf(buf, "gsdll.run_string_continue returns %d\n", execute_code);
	gs_addmess(buf);
    }
#endif
    return execute_code;
}

/* returns error code from GS */
int
gs_printf(const char *fmt, ...)
{
va_list args;
int count;
int code;
char buf[2048];
	if (strlen(fmt) > sizeof(buf) - 256) {
	    message_box(TEXT("gs_printf buffer overrun\n"), 0);
	    return 0;
	}
	va_start(args,fmt);
	count = vsprintf(buf,fmt,args);
	if (debug & DEBUG_GENERAL)
	    gs_addmess(buf);
	code = gs_execute(buf, count);
	va_end(args);
	if (count >= (int)sizeof(buf)) {
	    debug |= DEBUG_GENERAL | DEBUG_LOG;
	    gs_addmess("gs_printf buffer overrun\n");
#ifndef VIEWONLY
	    gs_addmess(buf);
	    message_box(TEXT("Please send c:\\gsview.txt to the author"), 0);
#endif
	}
	return code;
}

/* private funtions */

/* Get auto orientation for specified page */
int
gsview_page_orientation(int page)
{
    CDSC *dsc = psfile.dsc;
    int orientation = IDM_PORTRAIT;

    if (psfile.ispdf)
	return pdf_orientation(page);

    if (dsc == (CDSC *)NULL)
	return IDM_PORTRAIT;

    if (dsc->page_orientation == CDSC_LANDSCAPE)
	orientation = IDM_LANDSCAPE;
    if ((page >=1) && (page <= (int)dsc->page_count)) {
	/* check for page orientation */
	if (dsc->page[map_page(page-1)].orientation == CDSC_PORTRAIT)
	    orientation = IDM_PORTRAIT;
	if (dsc->page[map_page(page-1)].orientation == CDSC_LANDSCAPE)
	    orientation = IDM_LANDSCAPE;
    }
    return orientation;
}

/* get orientation for display of given page */
int
d_orientation(int pagenum)
{
int orientation;
    if (option.auto_orientation == TRUE)
	orientation = gsview_page_orientation(pagenum);
    else
	orientation = option.orientation;
    switch (orientation) {
	case IDM_LANDSCAPE:
	    if (option.swap_landscape)
		return 1;
	    return 3;
	case IDM_SEASCAPE:
	    if (option.swap_landscape)
		return 3;
	    return 1;
	case IDM_PORTRAIT:
	    return 0;
	case IDM_UPSIDEDOWN:
	    return 2;
    }
    return 0;
}

void
d_calc_resize(int pagenum, float *pwidth, float *pheight, int *pxoffset, int *pyoffset)
{
    CDSC *dsc;

    float	width;		  /* page width in 1/72" */
    float	height;		  /* page height in 1/72" */
    int		xoffset;	  /* page origin offset in 1/72" */
    int		yoffset;	  /* page origin offset in 1/72" */

    dsc = psfile.dsc;
    if (dsc != (CDSC *)NULL) {
	if (pagenum < 0)
	    pagenum = psfile.pagenum;
	if (dsc->page_count && (pagenum > (int)dsc->page_count))
	     pagenum = dsc->page_count;
	if (pagenum < 1)
	    pagenum = 1;
    }

    /* calculate new size */
    if ( (option.xdpi == 0.0) || (option.ydpi == 0.0) )
	    option.xdpi = option.ydpi = DEFAULT_RESOLUTION;
    display.epsf_clipped = FALSE;

    display.xdpi = option.xdpi;
    display.ydpi = option.ydpi;

    if (zoom && (dsc!=(CDSC *)NULL)) {
	if (debug & DEBUG_GENERAL)
	    gs_addmess("d_calc_resize: zoomed\n");
	display.xdpi = option.zoom_xdpi;
	display.ydpi = option.zoom_ydpi;
	width = (float)(display.width * 72.0 / display.xdpi);
	height = (float)(display.height * 72.0 / display.ydpi);
	xoffset = display.zoom_xoffset;
	yoffset = display.zoom_yoffset;
    }
    else if ( (dsc != (CDSC *)NULL) && 
	       ((dsc->epsf || psfile.ispdf) && option.epsf_clip) ) {
	if (debug & DEBUG_GENERAL)
	    gs_addmess("d_calc_resize: cropped EPS or PDF\n");
	display.epsf_clipped = TRUE;
	if (psfile.ispdf) {
	    /* PDF crop box is stored in page bbox */
	    CDSCBBOX *bbox = NULL;
	    /* PDF media size is stored in page media mediabox */
	    CDSCBBOX *mediabox = NULL;
	    if ( (pagenum >= 1) &&
	         (pagenum <= (int)psfile.dsc->page_count) ) {
		bbox = psfile.dsc->page[pagenum-1].bbox;
	        if (psfile.dsc->page[pagenum-1].media)
	            mediabox = psfile.dsc->page[pagenum-1].media->mediabox;
	    }
	    if (bbox) {
		width = (float)(bbox->urx - bbox->llx);
		height = (float)(bbox->ury - bbox->lly);
		xoffset = bbox->llx;
		yoffset = bbox->lly;
	    }
	    else if (mediabox) {
		width = (float)(mediabox->urx - mediabox->llx);
		height = (float)(mediabox->ury - mediabox->lly);
		xoffset = mediabox->llx;
		yoffset = mediabox->lly;
	    }
	    else {
		width = (float)get_paper_width();
		height = (float)get_paper_height();
		xoffset = 0;
		yoffset = 0;
	    }
	}
	else {
	    if (dsc->bbox != (CDSCBBOX *)NULL) {
		width = (float)(dsc->bbox->urx - dsc->bbox->llx);
		height = (float)(dsc->bbox->ury - dsc->bbox->lly);
		xoffset = dsc->bbox->llx;
		yoffset = dsc->bbox->lly;
	    }
	    else {
		width = (float)get_paper_width();
		height = (float)get_paper_height();
		xoffset = 0;
		yoffset = 0;
	    }
	}
	if (width <= 0)
	    display.epsf_clipped = FALSE;
	if (height <= 0)
	    display.epsf_clipped = FALSE;
    }
    else if ((dsc != (CDSC *)NULL) && psfile.ispdf) {
	CDSCBBOX *mediabox = NULL;
	if (debug & DEBUG_GENERAL)
	    gs_addmess("d_calc_resize: PDF\n");
	/* PDF media size is stored in page media mediabox */
	if ( (pagenum >= 1) &&
	     (pagenum <= (int)psfile.dsc->page_count) &&
	     (psfile.dsc->page[pagenum-1].media) &&
	     (psfile.dsc->page[pagenum-1].media->mediabox) )
	    mediabox = psfile.dsc->page[pagenum-1].media->mediabox;

	if (mediabox) {
	    width = (float)(mediabox->urx - mediabox->llx);
	    height = (float)(mediabox->ury - mediabox->lly);
	    xoffset = mediabox->llx;
	    yoffset = mediabox->lly;
	}
	else {
	    width = (float)get_paper_width();
	    height = (float)get_paper_height();
	    xoffset = 0;
	    yoffset = 0;
	}
    }
    else {
	/* !zooming && !display.epsf_clipped && !ispdf */
	if (debug & DEBUG_GENERAL)
	    gs_addmess("d_resize: other\n");
	xoffset = 0;
	yoffset = 0;
	width = (float)get_paper_width();
	height = (float)get_paper_height();
    }

    *pwidth = width;
    *pheight = height;
    *pxoffset = xoffset;
    *pyoffset = yoffset;
}

/* calculate new size then set it */
int
d_resize(int pagenum)
{
int code = 0;
float	width;		  /* page width in 1/72" */
float	height;		  /* page height in 1/72" */
int	xoffset;	  /* page origin offset in 1/72" */
int	yoffset;	  /* page origin offset in 1/72" */

    d_calc_resize(pagenum, &width, &height, &xoffset, &yoffset);
    if (debug & DEBUG_GENERAL)
	gs_addmessf("d_resize: width=%f height=%f\n", width, height);

    display.orientation = d_orientation(psfile.pagenum);

    display.width  = (unsigned int)(width  * display.xdpi / 72.0 + 0.5);
    display.height = (unsigned int)(height * display.ydpi / 72.0 + 0.5);

    display.xoffset = (unsigned int)(xoffset * display.xdpi / 72.0);
    display.yoffset = (unsigned int)(yoffset * display.ydpi / 72.0);

    /* set new size */

    /* There is a local/global allocation problem in GS 7.04,
     * 7.05, 8.00 which we try to avoid by always calling setuserparams, 
     * .locksafe and setpagedevice with global objects.  
     * The problem is that you can insert a local object with 
     * setpagedevice, but if you later call currentpagedevice while 
     * in global allocation, it will fail trying to put the local 
     * object into a global dictionary.
     */
    if (!code) 	/* local/global bug in GS, see note above */
	code = gs_printf("currentglobal true setglobal\n");
    if (!code)
	code = gs_printf("GSview /HWResolution [%f %f] put\n", display.xdpi, display.ydpi);
    if (!code)   /* need to improve this for PDF - need page bbox */
	code = gs_printf("GSview /PageSize [%f %f] put\n", width, height);
    if ((xoffset!=0) || (yoffset!=0)) {
	if (!code)
	    code = gs_printf("GSview /ImagingBBox [%d %d %f %f] put\n", 
		xoffset, yoffset, xoffset + width, yoffset + height);
    }
    else {
	if (!code)
	    code = gs_printf("GSview /ImagingBBox null put\n"); 
    }
    if (!code)
	code = gs_printf("GSview /Orientation %d put\n", display.orientation);
    if (!code)
	code = gs_printf("GSview /TextAlphaBits %d put\n", real_depth(option.depth) >= 8 ? option.alpha_text : 1);
    if (!code)
	code = gs_printf("GSview /GraphicsAlphaBits %d put\n", real_depth(option.depth) >= 8 ?  option.alpha_graphics : 1);
    if (!code) 	/* local/global bug in GS, see note above */
	code = gs_printf("setglobal\n");

    return code;
}


/* save GSview state */
int
d_save(void)
{
int code;
    code = gs_printf("/GSview_Save save def\n");
    display.saved = TRUE;
    return code;
}

/* restore GS */
/* assume restore is quick - don't check message loop */
int
d_restore(void)
{
int code;
    code = gs_printf("userdict /gsview_eps_countcheck known {gsview_eps_countcheck} if flush\n");
    if (!code)
        code = gs_printf("//systemdict /clear get exec //systemdict /cleardictstack get exec\n");
    if (!code)
        code = gs_printf("GSview_Save restore\n");
    display.saved = FALSE;
    return code;
}


/* create GSview dictionary */
int
d_init1(void)
{
    /* create GSview dictionary */
    /* local/global bug in GS, see note above */
    return gs_printf("currentglobal true setglobal\n\
/GSview 8 dict def GSview begin\n/PageSize [612 792] def\n\
/ImagingBBox null def\n/Orientation 0 def\n/HWResolution [96.0 96.0] def\n\
/Size PageSize def\n/PageOffset [0 0] def\n\
/TextAlphaBits 1 def /GraphicsAlphaBits 1 def\nend\n\
setglobal\n");
}

#ifdef UNIX
long dmode1 = 
     DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST; /* not used */
long dmode4 = 
     DISPLAY_COLORS_GRAY | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST; /* not used */
long dmode8 = 
     DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST;
long dmode24 = 
     DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_BIGENDIAN | DISPLAY_TOPFIRST;
#else
long dmode1 = 
     DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_1 | 
     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
long dmode4 = 
     DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
long dmode8 = 
     DISPLAY_COLORS_NATIVE | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
long dmode24 = 
     DISPLAY_COLORS_RGB | DISPLAY_ALPHA_NONE | DISPLAY_DEPTH_8 | 
     DISPLAY_LITTLEENDIAN | DISPLAY_BOTTOMFIRST;
#endif

int
d_permitread(void)
{
int code = 0;
char filename[MAXSTR+MAXSTR];
int i;
const char *p;
    /* Allow document files to be opened */
    if (option.safer && (gsdll.revision_number > GS_UNSAFE)) {
 	/* local/global bug in GS, see note above */
	code = gs_printf( "currentglobal true setglobal\n");
	if (!code)
	    code = gs_printf("<<\n");
	if (!code)
	    code = gs_printf(" /PermitFileReading [\n");
	if (!code && psfile.name[0]) {
	    for (p=psfile.name, i=0; *p && i < sizeof(filename)-2; p++) {
		if (*p == '\\') {
		    filename[i++] = '\\';
		    filename[i++] = '\\';
		    filename[i++] = '\\';
		}
		if ((*p == '(') || (*p == ')'))
		    filename[i++] = '\\';
		filename[i++] = *p;
	    }
	    filename[i] = '\0';
	    code = gs_printf("  (%s)\n", filename);
	    while (--i) {
		if ((filename[i] == '\\') || (filename[i] == '/')) {
		    filename[++i] = '*';
		    filename[++i] = '\0';
		    break;
		}
	    }
	    if (i)
	        code = gs_printf("  (%s)\n", filename);
	}
	if (!code && psfile.tname[0]) {
	    for (p=psfile.tname, i=0; *p && i < sizeof(filename)-2; p++) {
		if (*p == '\\') {
		    filename[i++] = '\\';
		    filename[i++] = '\\';
		    filename[i++] = '\\';
		}
		if ((*p == '(') || (*p == ')'))
		    filename[i++] = '\\';
		filename[i++] = *p;
	    }
	    filename[i] = '\0';
	    code = gs_printf("  (%s)\n", filename);
	}

	if (!code)
	    code = gs_printf(" ]\n");
	if (!code)
	    code = gs_printf(" /PermitFileWriting []\n");
	if (!code)
	    code = gs_printf(" /PermitFileControl []\n");
	if (!code)
	    code = gs_printf(" >> setuserparams\n");
	if (!code) 	/* local/global bug in GS, see note above */
	    code = gs_printf( "setglobal\n");
    }
    if (code)
	gs_addmessf("Failed to setuserparams for SAFER\n");
    return code;
}


/* open device and install viewer hooks */
int
d_init2(void)
{
int code = 0;
int depth;
long dmode;

    if (!code)
        code = d_permitread();

    /* calculate depth */
    depth = real_depth(option.depth);

    /* set the device depth and size */
    /* open device */
    view.img->ignore_sync = TRUE;	 /* ignore GSDLL_SYNC from this setpagedevice */
    switch (depth) {
	case 1:
	    dmode = dmode1;
	    break;
	case 4:
	    dmode = dmode4;
	    break;
	case 8:
	    dmode = dmode8;
	    break;
	default:
	case 24:
	    dmode = dmode24;
	    break;
    }

    if (!code) 	/* local/global bug in GS, see note above */
	code = gs_printf("currentglobal true setglobal\n");
    if (!code)
	code = gs_printf("<< /OutputDevice /%s /DisplayFormat %ld /DisplayHandle %ld\n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -