📄 gvcdll.c
字号:
static int GSDLLCALL
gsdll_stdin(void *instance, char *buf, int len)
{
char mess[MAXSTR];
sprintf(mess,"stdin callback not supported: %p %d\n", buf, len);
gs_addmess(mess);
return 0; /* EOF */
}
static int GSDLLCALL
gsdll_stdout(void *instance, const char *str, int len)
{
#ifndef VIEWONLY
#ifndef UNIX
if (callback_pstotext(str, len))
return len;
#endif
#endif
if (!pending.abort)
pdf_checktag(str, len);
gs_addmess_count(str, len);
return len;
}
static int GSDLLCALL
gsdll_stderr(void *instance, const char *str, int len)
{
gs_addmess_count(str, len);
return len;
}
/*********************************************************************/
/* called from gs_process */
int
gs_dll_init(char *devname)
{
char buf[1024];
char *p, *q;
int code;
int depth;
int i, argc;
char **argv;
/* build options list */
p = buf;
buf[0] = '\0';
buf[1] = '\0';
/* add include path */
if (option.gsinclude[0] != '\0') {
strcpy(buf, "-I");
strcat(buf, option.gsinclude);
p += strlen(p)+1;
*p = '\0';
}
/* add initial device */
if (devname) {
strcpy(p, "-sDEVICE=");
p += strlen(p);
strcpy(p, devname);
p += strlen(p)+1;
*p = '\0';
/* restrict depth to values supported by Ghostscript */
depth = display.planes * display.bitcount;
if (depth > 8)
depth = 24;
else if (depth >=8)
depth = 8;
else if (depth >=4)
depth = 4;
else
depth = 1;
strcpy(p, "-dBitsPerPixel=");
p += strlen(p);
sprintf(p, "%d", option.depth ? option.depth : depth);
p += strlen(p)+1;
*p = '\0';
}
else {
/* no device at all */
strcpy(p, "-dNODISPLAY");
p += strlen(p)+1;
*p = '\0';
}
strcpy(p, "-dNOPAUSE");
p += strlen(p)+1;
*p = '\0';
if (gsdll.revision_number > GS_UNSAFE) {
/* after selecting the initial device, we need to execute
* .locksafe
*/
strcpy(p, "-dNOSAFER");
p += strlen(p)+1;
*p = '\0';
}
else {
if (option.safer) {
strcpy(p, "-dSAFER");
p += strlen(p)+1;
*p = '\0';
}
}
if (option.alpha_text > 1) {
strcpy(p, "-dNOPLATFONTS");
p += strlen(p)+1;
*p = '\0';
}
/* Ghostscript 7.0 won't execute pdfmark for links unless
* the device has /pdfmark as a parameter. This isn't the
* case for any device other than pdfwrite, so we need
* to force it to procedd pdfmarks.
*/
strcpy(p, "-dDOPDFMARKS");
p += strlen(p)+1;
*p = '\0';
if (pending.text) {
/* pstotext needs to make some changes to the systemdict */
strcpy(p, "-dDELAYBIND");
p += strlen(p)+1;
*p = '\0';
strcpy(p, "-dWRITESYSTEMDICT");
p += strlen(p)+1;
*p = '\0';
strcpy(p, "-q");
p += strlen(p)+1;
*p = '\0';
/* GS 5.50 incorrectly allows the page size of nullpage */
/* device to be changed. We must disable this. */
strcpy(p, "-dFIXEDMEDIA");
p += strlen(p)+1;
*p = '\0';
}
/* add other options */
/* option.gsother must have options separated by one or more spaces */
/* quotes may be put around embedded spaces, but are not copied */
q = option.gsother;
while ((q = gs_argnext(q, p, FALSE)) != NULL) {
p += strlen(p)+1;
*p = '\0';
}
/* convert buf back to argv */
for (argc=1, p=buf; *p; argc++)
p += strlen(p)+1;
argv = (char **)malloc((argc+2) * sizeof(char *));
argv[0] = option.gsdll;
for (i=1, p=buf; i<=argc; i++) {
argv[i] = p;
p+=strlen(p)+1;
}
argv[i] = NULL;
if (debug & DEBUG_GENERAL) {
gs_addmess("Ghostscript options are:\n");
for (i=1; i<=argc; i++) {
gs_addmess(" ");
gs_addmess(argv[i]);
gs_addmess("\n");
}
}
if (gsdll.minst == NULL) {
code = gsdll.new_instance(&gsdll.minst, NULL);
if (code) {
sprintf(buf,"gsapi_new_instance returns %d\n", code);
gs_addmess(buf);
return code;
}
if (image.open) {
if (debug & DEBUG_GENERAL)
gs_addmess("Ghostscript didn't close display when it exited.\n");
}
gsdll.set_stdio(gsdll.minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
gsdll.set_poll(gsdll.minst, gsdll_poll);
gsdll.set_display_callback(gsdll.minst, &gsdisplay);
}
code = gsdll.init_with_args(gsdll.minst, argc, argv);
free((void *)argv);
if (code) {
sprintf(buf,"gsapi_init_with_args returns %d\n", code);
gs_addmess(buf);
}
/*
zoom = FALSE;
*/
display.epsf_clipped = FALSE;
gsdll.open = TRUE;
return code;
}
#ifndef UNIX
/******************************************************************/
/* for pstotext */
HMODULE pstotextModule;
FILE *pstotextOutfile;
void *pstotextInstance;
#ifdef __cplusplus
extern "C" {
#endif
PFN_pstotextInit pstotextInit;
PFN_pstotextFilter pstotextFilter;
PFN_pstotextExit pstotextExit;
PFN_pstotextSetCork pstotextSetCork;
#ifdef __cplusplus
}
#endif
char pstotextLine[2048];
int pstotextCount;
#ifndef VIEWONLY
int
callback_pstotext(const char *str, unsigned long count)
{
if (pstotextInstance) {
if (debug & DEBUG_GENERAL)
gs_addmess_count(str, (int)count);
if (pstotextOutfile) {
char *d, *e;
char *pre, *post;
int llx, lly, urx, ury;
int status;
char ch;
if (sizeof(pstotextLine) > count + pstotextCount) {
memcpy(pstotextLine+pstotextCount, str, (int)count);
pstotextCount += (int)count;
pstotextLine[pstotextCount] = '\0';
/* can't use strchr, because line may include null char */
e = (char *)memchr(pstotextLine, '\n', pstotextCount);
while ( e != NULL ) {
ch = *(++e); /* save character after \n */
*e = '\0';
d = pre = post = (char *)NULL;
llx = lly = urx = ury = 0;
status = pstotextFilter(pstotextInstance, pstotextLine,
&pre, &d, &post,
&llx, &lly, &urx, &ury);
*e = ch; /* restore character after \n */
memmove(pstotextLine, e, (int)(pstotextCount - (e-pstotextLine)));
pstotextCount -= (int)(e-pstotextLine);
pstotextLine[pstotextCount] = '\0';
/* can't use strchr, because line may include null char */
e = (char *)memchr(pstotextLine, '\n', pstotextCount);
if (status) {
char buf[MAXSTR];
sprintf(buf, "\npstotextFilter error %d\n", status);
gs_addmess(buf);
return 1;
}
if (d) {
if (pre) {
if (*pre == ' ')
pre++;
fputs(pre, pstotextOutfile);
}
fprintf(pstotextOutfile, "%d %d %d %d %s\n",
llx, lly, urx, ury, d);
if (post)
fputs(post, pstotextOutfile);
}
}
}
else
pstotextCount = 0; /* buffer overflow */
}
return 1;
}
return 0;
}
#endif
void
gs_error_code(int code)
{
char buf[MAXSTR];
sprintf(buf, "Ghostscript returns error code %d\n", code);
gs_addmess(buf);
}
#ifndef VIEWONLY
/* This handles extracting text from PS or PDF file */
int
gs_process_pstotext(void)
{
int code;
char buf[MAXSTR];
int angle = 0;
int len;
long lsize, ldone;
int pcdone;
int real_orientation;
if (load_pstotext())
return 1;
in_pstotext = TRUE;
if (option.pstotext == IDM_PSTOTEXTCORK - IDM_PSTOTEXTMENU - 1)
pstotextSetCork(pstotextInstance, TRUE);
gs_addmess("Extracting text using pstotext...\n");
/* open output file */
if ( (pstotextOutfile = gp_open_scratch_file(szScratch, psfile.text_name, "w")) == (FILE *)NULL) {
gs_addmess("Can't open temporary file for text extraction\n");
in_pstotext = FALSE;
unload_pstotext();
return 1;
}
if (debug & DEBUG_GENERAL)
gs_addmessf("Writing text index to \042%s\042\n", psfile.text_name);
percent_pending = FALSE;
percent_done = 0;
post_img_message(WM_GSWAIT, IDS_WAITTEXT);
switch(d_orientation(psfile.pagenum)) {
default:
case 0:
real_orientation = IDM_PORTRAIT;
break;
case 1:
real_orientation = IDM_SEASCAPE;
break;
case 2:
real_orientation = IDM_UPSIDEDOWN;
break;
case 3:
real_orientation = IDM_LANDSCAPE;
break;
}
if (psfile.ispdf)
real_orientation = pdf_orientation(psfile.pagenum);
switch (real_orientation) {
case IDM_LANDSCAPE:
angle = 270;
break;
case IDM_SEASCAPE:
angle = 90;
break;
case IDM_PORTRAIT:
angle = 0;
break;
case IDM_UPSIDEDOWN:
angle = 180;
break;
}
/* send pstotext prolog to GS */
if ((angle==270) && (code = send_pstotext_prolog(pstotextModule, 2)) != 0 ) {
gs_addmess("Error processing rot270 prolog\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
if ((angle==90) && (code = send_pstotext_prolog(pstotextModule, 3)) != 0 ) {
gs_addmess("Error processing rot90 prolog\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
if ( (code = send_pstotext_prolog(pstotextModule, 1)) != 0 ) {
gs_addmess("Error processing ocr prolog\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
/* Don't let anyone stuff around with the page size now */
gs_printf("/setpagedevice { pop } def\n");
if (option.safer && (gsdll.revision_number > GS_UNSAFE)) {
d_permitread();
gs_printf(".locksafe\n");
}
if (psfile.ispdf) {
int i;
if ( (code = pdf_head()) != 0 ) {
gs_addmess("PDF prolog failed\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
if ( psfile.dsc == (CDSC *)NULL ) {
gs_addmess("Couldn't get PDF page count\n");
in_pstotext = FALSE;
unload_pstotext();
return 1;
}
if ( (code = d_init1()) != 0) {
gs_addmess("Error creating GSview dictionary\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return 1;
}
lsize = psfile.dsc->page_count;
i = 1;
while (!pending.abort && !pending.unload && i <= (int)psfile.dsc->page_count) {
if ( (code = d_pdf_page(i)) != 0 ) {
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
pcdone = (int)(i * 100 / lsize);
if ((pcdone != percent_done) && !percent_pending) {
percent_done = pcdone;
percent_pending = TRUE;
post_img_message(WM_GSPERCENT, 0);
}
i++;
if (!multithread) {
/* peek message loop */
peek_message();
}
if (pending.now)
pending.abort = TRUE; /* user wants to do something else */
}
if ((code = pdf_trailer()) != 0) {
gs_addmess("Error in PDF trailer\n");
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
return code;
}
}
else {
if (dfreopen() != 0) {
gs_addmess("File changed or missing\n");
in_pstotext = FALSE;
unload_pstotext();
return 1;
}
/* get file length */
lsize = gfile_get_length(psfile.file);
if (lsize <= 0)
lsize = 1;
gfile_seek(psfile.file, 0, gfile_begin);
ldone = 0;
/* send document to GS */
while (!pending.abort && !pending.unload
&& ((len = gfile_read(psfile.file, buf, sizeof(buf)))!=0)) {
code = gs_execute(buf, len);
if (code) {
dfclose();
gs_error_code(code);
in_pstotext = FALSE;
unload_pstotext();
unlink(psfile.text_name);
psfile.text_name[0] = '\0';
if (pending.abort) {
gs_addmess("\n--- Aborted ---\n");
return 0;
}
else {
gs_addmess("\n--- Begin offending input ---\n");
gs_addmess_count(buf, len);
gs_addmess("\n--- End offending input ---\n");
sprintf(buf, "gsapi_run_string_continue returns %d\n", code);
gs_addmess(buf);
}
return code;
}
ldone += len;
pcdone = (int)(ldone * 100.0 / lsize);
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();
}
if (pending.now)
pending.abort = TRUE; /* user wants to do something else */
}
dfclose();
}
/* close output file */
fclose(pstotextOutfile);
/* unload pstotext DLL */
in_pstotext = FALSE;
unload_pstotext();
/* if successful, restart extract or find */
if (!pending.unload && !pending.abort) {
gs_addmess("\npstotext successful\n");
if (psfile.text_extract)
post_img_message(WM_COMMAND, IDM_TEXTEXTRACT_SLOW);
else
post_img_message(WM_COMMAND, IDM_TEXTFINDNEXT);
}
else {
gs_addmess("\npstotext aborted\n");
unlink(psfile.text_name);
psfile.text_name[0] = '\0';
}
pending.abort = TRUE; /* ignore errors */
return 0;
}
#endif
#endif /* !VIEWONLY */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -