📄 gvcdll.c
字号:
DEVICENAME, dmode, &view);
if (!code && option.safer && (gsdll.revision_number > GS_UNSAFE))
code = gs_printf("/.LockSafetyParams true\n");
if (!code)
code = send_prolog(IDR_VIEWER);
if (!code)
code = gs_printf(">> setpagedevice\n");
if (!code) /* local/global bug in GS, see note above */
code = gs_printf("setglobal\n");
if (!code && option.safer && (gsdll.revision_number > GS_UNSAFE)) {
if (gsdll.revision_number == 704) {
/* There is a local/global allocation problem in GS 7.04 */
/* which we try to avoid with the following */
code = gs_printf(
"currentglobal true setglobal .locksafe setglobal\n");
/* .locksafe disabled ViewerPreProcess */
/* Put it back again */
if (!code)
code = gs_printf("currentglobal true setglobal\n");
if (!code)
code = gs_printf(
"currentpagedevice /ViewerPreProcess known not { <<\n");
if (!code)
code = send_prolog(IDR_VIEWER);
if (!code)
code = gs_printf(">> setpagedevice } if\n");
if (!code)
code = gs_printf("setglobal\n");
}
else {
/* code = gs_printf(".locksafe\n"); */
/* local/global bug in GS, see note above */
code = gs_printf(
"currentglobal true setglobal .locksafe setglobal\n");
/* FIX: .locksafe in 7.06 pre-release is buggy and leaves items on the stack */
if (!code)
code = gs_printf("clear\n");
}
}
if (code) {
char buf[256];
sprintf(buf,"Failed to open device or install ViewerPreProcess hook: returns %d\n", code);
gs_addmess(buf);
pending.unload = TRUE;
if ( (code == e_limitcheck)
|| (code == e_invalidexit)
|| (code == e_VMerror)
) {
gs_addmess("Page size may have been too large or resolution too high.\nResetting page size and resolution\n");
if (option.xdpi > DEFAULT_RESOLUTION)
option.xdpi = option.ydpi = DEFAULT_RESOLUTION;
if (zoom)
option.zoom_xdpi = option.zoom_ydpi = 300;
post_img_message(WM_COMMAND, IDM_A4);
}
}
if (!code)
/* run Ghostscript with a stopped */
code = gs_printf("\
/GSview_stopped\n\
{\n\
{ currentfile run } stopped\n\
{ $error /errorname get /VMerror eq\n\
{ $error begin command errorname end signalerror }\n\
{ handleerror quit }\n\
ifelse\n\
}\n\
if\n\
}\n\
def\n\
GSview_stopped\n");
if (!code)
display.init = TRUE;
return code;
}
int
d_pdf_page(int pagenum)
{
int code;
code = pdf_page_init(pagenum);
if (code)
gs_addmess("pdf_page_init failed\n");
if (!zoom) {
if (!code) {
code = d_resize(pagenum);
if (code)
gs_addmess("d_resize failed\n");
}
if (!code) {
/* local/global bug in GS, see note above */
code = gs_printf("currentglobal true setglobal\n");
if (!code) {
if (in_pstotext)
code = gs_printf("<< >> setpagedevice\n");
else
code = gs_printf("<< >> //systemdict /setpagedevice get exec\n");
}
if (!code) /* local/global bug in GS, see note above */
code = gs_printf("setglobal\n");
if (code)
gs_addmess("setpagedevice failed\n");
}
}
if (!code) {
code = pdf_page();
if (code)
gs_addmess("pdf_page failed\n");
}
return code;
}
/* input for Ghostscript DLL */
/* get_gs_input() copies/reads from gs_input[] to the supplied buffer */
/* copy/read at most blen bytes */
/* returns number of bytes copied to buffer */
int
get_gs_input(char *buf, int blen)
{
unsigned long len;
GSINPUT *entry;
GSDLL_INPUT *input = &view.input;
if (input->index >= input->count) {
return 0; /* no more */
}
entry = &input->section[input->index];
len = entry->end - entry->ptr;
len = min(len, (unsigned long)blen);
if (entry->seek) {
gfile_seek(psfile.file, entry->ptr, gfile_begin);
entry->seek = FALSE;
}
len = gfile_read(psfile.file, buf, (int)len);
entry->ptr += len;
/* check if we need to move to next item */
if (entry->ptr >= entry->end) {
input->index++;
/* do initial seek */
if (input->index < input->count) {
gfile_seek(psfile.file, input->section[input->index].ptr,
gfile_begin);
input->section[input->index].seek = FALSE;
}
}
return (int)len;
}
/* assume this is quick - don't check message loop */
int
send_trailer(void)
{
char buf[MAXSTR];
unsigned long len;
unsigned long ptr;
int code = 0;
int prevlen = 0;
CDSC *dsc = psfile.dsc;
if (psfile.file == NULL)
return 0; /* file has been deleted */
ptr = dsc->begintrailer;
gfile_seek(psfile.file, ptr, gfile_begin);
len = dsc->endtrailer - ptr;
len = min(len, sizeof(buf));
if (debug & DEBUG_GENERAL)
gs_addmess("send_trailer\n");
while (!code && len && (len = gfile_read(psfile.file, buf, (int)len))!=0) {
code = gs_execute(buf, (int)len);
prevlen = (int)len;
ptr += len;
len = dsc->endtrailer - ptr;
len = min(len, sizeof(buf));
}
#ifndef VIEWONLY
if (code) {
gs_addmess("\n---Error in document trailer---\n-------\n");
gs_addmess_count(buf, prevlen);
gs_addmess("\n-------\n");
}
#endif
return code;
}
/* This doesn't actually send anything to Ghostscript */
/* Instead it prepares a list of what will be sent */
int
send_document(void)
{
char filename[MAXSTR];
char buf[MAXSTR];
char *p;
CDSC *dsc = psfile.dsc;
GSDLL_INPUT *input = &view.input;
if (debug & DEBUG_GENERAL)
gs_addmess("send_document:\n");
if (psfile.file == NULL)
return -1;
strcpy(filename, psfile.name);
for (p=filename; *p; p++)
if (*p == '\\')
*p = '/';
if (dsc != (CDSC *)NULL) {
if (dsc->page_count && (dsc->page != 0)) {
int i, page;
i = 0;
page = map_page(psfile.pagenum-1);
if (display.need_header) {
sprintf(buf, "Displaying DSC file %s\n", filename);
gs_addmess(buf);
/* add header */
if (dsc->endcomments - dsc->begincomments != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding header %ld %ld\n",
(long)(dsc->begincomments), (long)(dsc->endcomments));
gs_addmess(buf);
}
input->section[i].ptr = dsc->begincomments;
input->section[i].end = dsc->endcomments;
input->section[i].seek = TRUE;
i++;
}
/* add defaults */
if (dsc->enddefaults - dsc->begindefaults != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding defaults %ld %ld\n",
(long)(dsc->begindefaults), (long)(dsc->enddefaults));
gs_addmess(buf);
}
input->section[i].ptr = dsc->begindefaults;
input->section[i].end = dsc->enddefaults;
input->section[i].seek = TRUE;
i++;
}
/* add prolog */
if (dsc->endprolog - dsc->beginprolog != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding prolog %ld %ld\n",
(long)(dsc->beginprolog), (long)(dsc->endprolog));
gs_addmess(buf);
}
input->section[i].ptr = dsc->beginprolog;
input->section[i].end = dsc->endprolog;
input->section[i].seek = TRUE;
i++;
}
/* add setup */
if (dsc->endsetup - dsc->beginsetup != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding setup %ld %ld\n",
(long)(dsc->beginsetup), (long)(dsc->endsetup));
gs_addmess(buf);
}
input->section[i].ptr = dsc->beginsetup;
input->section[i].end = dsc->endsetup;
input->section[i].seek = TRUE;
i++;
}
display.need_header = FALSE;
/* remember if we need trailer later */
if (dsc->endtrailer - dsc->begintrailer != 0)
display.need_trailer = TRUE;
}
/* add page */
sprintf(buf, "Displaying page %d\n", psfile.pagenum);
gs_addmess(buf);
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding page %d %ld %ld\n", page,
(long)(dsc->page[page].begin), (long)(dsc->page[page].end));
gs_addmess(buf);
}
input->section[i].ptr = dsc->page[page].begin;
input->section[i].end = dsc->page[page].end;
if (dsc->epsf && !dsc->dcs2) {
int j;
/* add everything except trailer */
input->section[i].ptr = dsc->page[0].begin;
for (j=0; j<(int)dsc->page_count; j++)
if (dsc->page[j].end)
input->section[i].end = dsc->page[j].end;
display.need_trailer = FALSE;
if (dsc->endtrailer - dsc->begintrailer != 0)
display.need_trailer = TRUE;
}
input->section[i].seek = TRUE;
i++;
input->count = i;
input->index = 0;
}
else {
/* add complete file */
int i = 0;
sprintf(buf, "Displaying DSC file %s without pages\n", filename);
gs_addmess(buf);
/* add header */
if (dsc->endcomments - dsc->begincomments != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding header %ld %ld\n",
(long)(dsc->begincomments), (long)(dsc->endcomments));
gs_addmess(buf);
}
input->section[i].ptr = dsc->begincomments;
input->section[i].end = dsc->endcomments;
input->section[i].seek = TRUE;
i++;
}
/* add defaults */
if (dsc->enddefaults - dsc->begindefaults != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding defaults %ld %ld\n",
(long)(dsc->begindefaults), (long)(dsc->enddefaults));
gs_addmess(buf);
}
input->section[i].ptr = dsc->begindefaults;
input->section[i].end = dsc->enddefaults;
input->section[i].seek = TRUE;
i++;
}
/* add prolog */
if (dsc->endprolog - dsc->beginprolog != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding prolog %ld %ld\n",
(long)(dsc->beginprolog), (long)(dsc->endprolog));
gs_addmess(buf);
}
input->section[i].ptr = dsc->beginprolog;
input->section[i].end = dsc->endprolog;
input->section[i].seek = TRUE;
i++;
}
/* add setup */
if (dsc->endsetup - dsc->beginsetup != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding setup %ld %ld\n",
(long)(dsc->beginsetup), (long)(dsc->endsetup));
gs_addmess(buf);
}
input->section[i].ptr = dsc->beginsetup;
input->section[i].end = dsc->endsetup;
input->section[i].seek = TRUE;
i++;
}
/* add trailer */
if (dsc->endtrailer - dsc->begintrailer != 0) {
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding trailer %ld %ld\n",
(long)(dsc->begintrailer), (long)(dsc->endtrailer));
gs_addmess(buf);
}
input->section[i].ptr = dsc->begintrailer;
input->section[i].end = dsc->endtrailer;
input->section[i].seek = TRUE;
i++;
}
display.need_header = FALSE;
display.need_trailer = FALSE;
input->count = i;
input->index = 0;
}
}
else {
/* add complete file */
sprintf(buf, "Displaying non DSC file %s\n", filename);
gs_addmess(buf);
input->section[0].ptr = 0;
input->section[0].end = gfile_get_length(psfile.file);
input->section[0].seek = TRUE;
if (debug & DEBUG_GENERAL) {
sprintf(buf, "adding complete file %ld %ld\n",
(long)0, (long)(input->section[0].end));
gs_addmess(buf);
}
input->count = 1;
input->index = 0;
display.need_trailer = FALSE;
}
/* this is done by get_gs_input
gfile_seek(psfile.file, input->section[0].ptr, gfile_begin);
*/
return 0;
}
BOOL
gs_process_trailer(void)
{
if (display.need_trailer) {
/* assume trailer is short, don't check message loop */
post_img_message(WM_GSWAIT, IDS_WAIT);
if (!psfile.ispdf && (dfreopen() != 0)) {
pending.abort = TRUE;
return TRUE;
}
if (psfile.ispdf) {
if (pdf_trailer())
return FALSE;
}
else {
BOOL old_now = pending.now;
pdf_free_link();
/* don't wait if we execute showpage in trailer */
pending.now = TRUE;
if (send_trailer()) {
dfclose();
pending.now = old_now;
return FALSE;
}
dfclose();
pending.now = old_now;
}
display.need_trailer = FALSE;
}
return FALSE;
}
/* Prepare input to be written to Ghostscript (Unix)
* or write header and prepare input (Windows)
* Return code is 0 for OK, +ve for OK but exit enclosing loop,
* -ve for Ghostscript error
*/
int
gs_process_prepare_input(PENDING *ppend)
{
int code;
int i;
char buf[MAXSTR];
GSDLL_INPUT *input = &view.input;
code = dfreopen();
if (code < 0) {
/* file could not be opened */
/* beep only */
return 1; /* error */
}
else if (code > 0) {
/* document changed, so force a rescan */
/* Cause the rescan to occur on main thread */
request_mutex();
pending.now = FALSE;
pending.redisplay = TRUE; /* cause a redisplay after abort complete */
pending.abort = TRUE;
release_mutex();
return 1;
}
code = 0; /* GS return code */
/* move to desired page */
if (psfile.dsc != (CDSC *)NULL) {
if (ppend->pagenum < 0)
ppend->pagenum = psfile.pagenum;
if (psfile.dsc->page_count
&& (ppend->pagenum > (int)psfile.dsc->page_count))
ppend->pagenum = psfile.dsc->page_count;
if (ppend->pagenum < 0)
ppend->pagenum = 1;
}
if (ppend->pagenum > 0)
psfile.pagenum = ppend->pagenum;
ppend->pagenum = 0;
if (!display.init) {
if (!code)
code = d_init1(); /* create GSview dict */
if (!code)
code = d_resize(psfile.pagenum); /* Set GSview dict entries */
if (!code)
code = d_init2(); /* add ViewerPreProcess then setpagedevice */
}
else {
if (ppend->resize) {
if (!code)
code = d_resize(psfile.pagenum);
view.img->ignore_sync = TRUE; /* ignore next sync */
if (!code) /* local/global bug in GS, see note above */
code = gs_printf("currentglobal true setglobal\n");
if (!code) {
if (in_pstotext)
code = gs_printf("<< >> setpagedevice\n");
else
code = gs_printf("<< >> //systemdict /setpagedevice get exec\n");
}
if (!code) /* local/global bug in GS, see note above */
code = gs_printf("setglobal\n");
}
}
if (!code && option.epsf_warn)
code = send_prolog(IDR_EPSFWARN);
if (code) {
/* error initializing GS */
if (!psfile.ispdf)
dfclose();
return code;
}
/* highlight search word if needed */
if (psfile.text_bbox.valid) {
display.show_find = TRUE;
psfile.text_bbox.valid = FALSE; /* don't do it on following pages */
}
else
display.show_find = FALSE;
if (psfile.ispdf) {
post_img_message(WM_GSTEXTINDEX, 0);
{
if (display.need_header) {
gs_addmess("Scanning PDF file\n");
if ( (code = pdf_head()) != 0 )
return code;
}
display.need_header = FALSE;
display.need_trailer = TRUE;
if (ppend->pagenum > 0)
psfile.pagenum = ppend->pagenum;
ppend->pagenum = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -