📄 gvcdll.c
字号:
sprintf(buf, "Displaying PDF page %d\n", psfile.pagenum);
gs_addmess(buf);
if ( (code = d_pdf_page(psfile.pagenum)) != 0)
return code;
}
} else {
post_img_message(WM_GSTEXTINDEX, 0);
pdf_free_link();
if (display.need_header)
pdf_add_pdfmark();
/* calculate document length */
/* prepare list of PostScript sections to send */
if ( (code = send_document()) != 0 ) {
dfclose();
return code;
}
gsbytes_done = 0;
gsbytes_size = 0;
for (i=0; i<input->count; i++)
gsbytes_size += (input->section[i].end - input->section[i].ptr);
percent_pending = FALSE;
percent_done = 0;
}
return code;
}
/* process current page or non-DSC file */
/* returns 0 if OK, else GS error code */
int
gs_process_loop2(PENDING *ppend)
{
char buf[1024];
int len;
int code;
int pcdone;
if ((code = gs_process_prepare_input(ppend)) > 0) {
/* Need to rescan file */
return 0;
}
if (code)
return code;
if (!psfile.ispdf) {
/* send postscript */
post_img_message(WM_GSWAIT, IDS_WAITDRAW_PC);
while (!pending.abort && !pending.unload
&& ((len = get_gs_input(buf, sizeof(buf)))!=0)) {
code = gs_execute(buf, len);
if (code) {
if (psfile.file)
dfclose();
if (pending.abort) {
gs_addmess("\n--- Aborted ---\n");
return 0;
}
else {
#ifndef VIEWONLY
gs_addmess("\n--- Begin offending input ---\n");
gs_addmess_count(buf, len);
gs_addmess("\n--- End offending input ---\n");
/* a file offset of 0 really means that it reached the end of the data */
/* need to fix this eventually */
sprintf(buf, "file offset = %ld\n", view.input.section[view.input.index].ptr);
gs_addmess(buf);
#endif
sprintf(buf, "gsapi_run_string_continue returns %d\n", code);
gs_addmess(buf);
}
return code;
}
gsbytes_done += len;
if (gsbytes_size > 100)
pcdone = (int)(gsbytes_done / (gsbytes_size / 100));
else
pcdone = 0;
if ((pcdone != percent_done) && !percent_pending) {
percent_done = pcdone;
percent_pending = TRUE;
post_img_message(WM_GSPERCENT, 0);
}
if (!multithread) {
/* peek message loop */
peek_message();
}
}
gs_printf("\n");
dfclose();
}
if (psfile.dsc == (CDSC *)NULL) {
/* We are at the end of the file */
/* Do not allow more pages to be displayed */
request_mutex();
pending.pagenum = 0;
pending.restart = TRUE;
release_mutex();
}
if (pending.abort)
gs_addmess("\n--- Aborted ---\n");
return 0;
}
/* Find out exactly what is pending.
* Copy and reset pending.
* Return copy of what is needed in lpending
*/
int
gs_process_pending(PENDING *lpending)
{
int code = 0;
/* block other threads while we take a snapshort of pending */
request_mutex();
*lpending = pending;
pending.now = FALSE;
pending.next = FALSE;
pending.abort = FALSE;
pending.psfile = NULL;
pending.pagenum = 0;
pending.resize = FALSE;
pending.text = FALSE;
pending.restart = FALSE;
release_mutex();
if (option.auto_orientation && !lpending->psfile && lpending->pagenum) {
/* If moving to another page in the same document
* and new page orientation doesn't match the current,
* then we need to resize.
*/
if (display.orientation != d_orientation(lpending->pagenum))
lpending->resize = TRUE;
/* If we are changing file then resize will occur automatically.
* If we are redisplaying the current page then we don't need
* to force a resize.
*/
}
if (lpending->psfile && display.init)
lpending->restart = TRUE;
if (lpending->resize && display.init)
lpending->restart = TRUE;
if (lpending->text && display.init)
lpending->restart = TRUE;
if (lpending->restart || (lpending->resize && !psfile.ispdf)
|| lpending->psfile) {
/* if size or document changed, need to restart document */
if (display.need_trailer)
gs_process_trailer(); /* send trailer to clean up */
display.need_header = TRUE;
if (display.saved)
code = d_restore();
if (code)
lpending->restart = TRUE;
}
if (lpending->psfile) {
request_mutex();
zoom = FALSE;
psfile_free(&psfile);
psfile = *(lpending->psfile);
post_img_message(WM_GSTITLE, 0);
free(lpending->psfile);
release_mutex();
}
return code;
}
/* loop while Ghostscript loaded, document unchanged and no errors */
/* return 0 if OK, or GS error code */
int
gs_process_loop1(void)
{
PENDING lpending;
int code;
while (!pending.unload && !pending.abort) {
if (!pending.now) {
if (szWait[0] != '\0')
post_img_message(WM_GSWAIT, IDS_NOWAIT);
if (multithread)
wait_event(); /* wait for event semaphore */
else
get_message(); /* process one message */
}
if (pending.now && !pending.unload && !pending.abort) {
gsdll.state = GS_BUSY;
post_img_message(WM_GSWAIT, IDS_WAIT);
code = gs_process_pending(&lpending);
if (code)
return code;
if (psfile.name[0] == '\0') {
/* no new file */
gsdll.state = GS_IDLE;
post_img_message(WM_GSWAIT, IDS_NOWAIT);
/* notify in case CLOSE was caused by IDM_SELECT */
post_img_message(WM_COMMAND, IDM_CLOSE_DONE);
break;
}
if (lpending.restart && display.init) {
request_mutex();
/* restore pending operations */
pending.pagenum = lpending.pagenum;
pending.abort = TRUE; /* ignore errors */
pending.text = lpending.text;
pending.now = TRUE;
release_mutex();
return 0; /* restart interpreter */
}
#ifndef VIEWONLY
if (lpending.text) {
code = gs_process_pstotext();
gsdll.state = GS_IDLE;
return code;
}
#endif
if ( (code = gs_process_loop2(&lpending)) != 0 ) {
gsdll.state = GS_IDLE;
if (psfile.dsc == (CDSC *)NULL)
psfile.pagenum = 1;
post_img_message(WM_GSWAIT, IDS_NOWAIT);
return code;
}
if (pending.abort)
return 0;
if (pending.unload) {
post_img_message(WM_GSWAIT, IDS_WAITGSCLOSE);
}
else {
gsdll.state = GS_IDLE;
if (psfile.dsc == (CDSC *)NULL)
psfile.pagenum = 1;
post_img_message(WM_GSWAIT, IDS_NOWAIT);
}
post_img_message(WM_GSSYNC, 0); /* redraw display */
}
}
return 0;
}
/********************************************************/
/* public functions */
/* In single thread mode, the main message loop is only used
* when the GS DLL is unloaded */
/* This is the second message loop, or second thread */
/* It loads the GS DLL and returns when GS DLL is unloaded */
/* The third message loop is in the GS DLL callback gsdll.state = GS_PAGE */
void
gs_process(void)
{
int code;
int exit_code;
#ifndef VIEWONLY
if (pending.pstoedit) {
post_img_message(WM_GSWAIT, IDS_WAIT);
gsdll_free(&gsdll); /* pstoedit is going to load it */
if (debug & DEBUG_GENERAL)
gs_addmess("Ghostscript unloaded\n");
process_pstoedit(NULL);
post_img_message(WM_GSWAIT, IDS_NOWAIT);
pending.pstoedit = FALSE;
pending.now = FALSE;
return;
}
#endif /* !VIEWONLY */
/* gsdll.state = UNLOADED; */
gsdll.state = GS_BUSY; /* skip IDLE state */
pending.abort = FALSE;
post_img_message(WM_GSWAIT, IDS_WAITGSOPEN);
if (gsdll_load(&gsdll, option.gsdll)) {
gsdll.state = GS_UNINIT;
request_mutex();
pending.now = FALSE;
pending.next = FALSE;
pending.unload = FALSE;
pending.abort = FALSE;
pending.redisplay = FALSE;
pending.pstoedit = FALSE;
pending.text = FALSE;
if (pending.psfile) {
psfile_free(&psfile);
psfile = *pending.psfile;
free(pending.psfile);
pending.psfile = NULL;
}
release_mutex();
post_img_message(WM_GSWAIT, IDS_NOWAIT);
post_img_message(WM_GSSHOWMESS, 0);
return;
}
/*
post_img_message(WM_GSWAIT, IDS_WAIT);
*/
/* send stuff to Ghostscript */
while (!pending.unload) {
display.saved = FALSE;
display.init = FALSE;
display.need_header = TRUE;
display.need_trailer = FALSE;
pending.restart = FALSE;
if (!pending.now) {
if (szWait[0] != '\0')
post_img_message(WM_GSWAIT, IDS_NOWAIT);
if (multithread)
wait_event(); /* wait for event semaphore */
else
get_message(); /* process one message */
}
if ( (code = gs_dll_init(NULL)) != 0 ) {
/*
delayed_message_box(IDS_PROCESS_INIT_FAIL, 0);
*/
if ((pending.abort == TRUE) && (code == e_interrupt))
gs_addmess("Ignoring error on abort\n");
else
post_img_message(WM_GSSHOWMESS, 0);
pending.unload = TRUE;
break;
}
if (!code) {
if (gsdll.run_string_begin == NULL)
break;
if ( (code = gsdll.run_string_begin(
gsdll.minst, 0, &exit_code)) != 0 ) {
char buf[256];
sprintf(buf,"gsdll.run_string_begin returns %d\n", code);
gs_addmess(buf);
pending.unload = TRUE;
post_img_message(WM_GSSHOWMESS, 0);
}
execute_code = 0;
}
if (!code) {
code = gs_process_loop1();
if (code) {
if (!pending.abort) {
pending.now = FALSE;
pending.resize = FALSE;
pending.next = FALSE;
post_img_message(WM_GSSHOWMESS, 0);
post_img_message(WM_GSWAIT, IDS_NOWAIT); /* shouldn't be needed */
}
}
if (execute_code >= 0)
gsdll.run_string_end(gsdll.minst, 0, &exit_code);
}
pending.abort = FALSE; /* don't interrupt cleanup */
if (gsdll.exit != NULL) {
char buf[256];
code = gsdll.exit(gsdll.minst);
if ((debug & DEBUG_GENERAL)|| code) {
sprintf(buf,"gsapi_exit returns %d\n", code);
gs_addmess(buf);
}
gs_addmess("\n\n");
}
if (pending.redisplay) {
pending.redisplay = FALSE;
post_img_message(WM_GSREDISPLAY, 0); /* will set pending.now */
}
pending.abort = FALSE;
}
post_img_message(WM_GSWAIT, IDS_WAITGSCLOSE);
gsdll.state = GS_UNINIT;
gsdll_free(&gsdll);
if (debug & DEBUG_GENERAL)
gs_addmess("Ghostscript unloaded\n");
display.need_header = TRUE;
display.need_trailer = FALSE;
display.saved = FALSE;
pending.now = FALSE;
pending.next = FALSE;
pending.unload = FALSE;
pending.abort = FALSE;
if (pending.psfile) {
request_mutex();
psfile_free(&psfile);
psfile = *pending.psfile;
free(pending.psfile);
pending.psfile = NULL;
release_mutex();
}
/* close document also */
gsview_unzoom();
if (pending.pstoedit)
pending.now = TRUE;
post_img_message(WM_GSWAIT, IDS_NOWAIT);
post_img_message(WM_GSTITLE, 0);
}
/* next page */
int
gs_page_skip(int skip)
{
CDSC *dsc = psfile.dsc;
if (dsc == (CDSC *)NULL) {
/* NOT DSC, can only go forward one page at a time */
if (skip != 1) {
play_sound(SOUND_NOPAGE);
return FALSE;
}
if (gsdll.state == GS_IDLE) {
/* at end of file */
play_sound(SOUND_NOPAGE);
return FALSE; /* nothing to do */
}
else {
request_mutex();
gsview_unzoom(); /* should never be zoomed anyway */
pending.next = TRUE;
release_mutex();
}
return TRUE;
}
/* Must be DSC */
if ( (skip == 0)
|| ((skip > 0) && (psfile.pagenum == (int)dsc->page_count))
|| ((skip < 0) && (psfile.pagenum == 1))
|| (dsc->page_count == 0) ) {
play_sound(SOUND_NOPAGE);
return FALSE;
}
request_mutex();
pending.pagenum = psfile.pagenum + skip;
if (pending.pagenum > (int)dsc->page_count)
pending.pagenum = dsc->page_count;
if (pending.pagenum < 1)
pending.pagenum = 1;
gsview_unzoom();
pending.now = TRUE;
release_mutex();
/* add to history */
history_add(pending.pagenum);
return TRUE;
}
/* Parse argline looking for argument
* If argument found, copy to arg and return pointer to next argument.
* If no argument found, return NULL.
* To get next argument, call again with return value as argline.
* If copyquotes is TRUE, quotes will copied to the output, otherwise
* they will be omitted.
*/
char *
gs_argnext(char *argline, char *arg, BOOL copyquotes)
{
/* quotes may be put around embedded spaces and are copied */
while ((*argline) && (*argline==' '))
argline++; /* skip over leading spaces */
if (*argline=='\0')
return NULL; /* no more arguments */
while (*argline) {
if (*argline == ' ') {
/* end of argument */
*arg = '\0';
while (*argline && (*argline==' '))
argline++;
return argline;
}
else if (*argline == '"') {
/* quoted argument */
/* copy until closing quote or end of string */
if (copyquotes)
*arg++ = *argline; /* copy opening quote */
argline++;
while ((*argline) && (*argline != '"')) {
*arg++ = *argline;
argline++;
}
if ((*argline) && (*argline == '"')) {
/* copy closing quote */
if (copyquotes)
*arg++ = *argline;
argline++;
}
}
else {
*arg++ = *argline;
argline++;
}
}
*arg = '\0';
return argline;
}
/*********************************************************************/
/* stdio functions */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -