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

📄 gvcdll.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 4 页
字号:
	    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 + -