📄 gvctext.c
字号:
/* Copyright (C) 1993-2002, 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.
*/
/* gvctext.c */
/* Text Extract and Search module of PM and Windows GSview */
#include "gvc.h"
/* forward declarations */
void gsview_text_extract_slow(void);
void gsview_text_extract_quick(void);
void gsview_text_findnext_slow(void);
void gsview_text_findnext_quick(void);
char toupper_latin1(char ch);
char tolower_latin1(char ch);
int text_extract_line(char *dest, FILE *inf);
void text_extract(FILE *outf, FILE *inf, unsigned long end);
char * text_find_string(char *str, char *find, int flen);
char * text_find_section(FILE *inf, unsigned long end, char *str);
char * text_grab_word(char *line);
void text_extract_slow(FILE *outfile, FILE *infile, BOOL all);
BOOL text_find_slow(FILE *infile, char *str, BOOL all);
BOOL in_word(PSBBOX *bbox, int x, int y);
char
toupper_latin1(char ch)
{
if ((ch >= 'a') && (ch <= 'z'))
return (char)(ch - ('a' - 'A'));
if ((ch >= '\340') && (ch <= '\377')) /* Latin-1 accented chars */
return (char)(ch - ('\340' - '\300'));
return ch;
}
char
tolower_latin1(char ch)
{
if ((ch >= 'A') && (ch <= 'Z'))
return (char)(ch + ('a' - 'A'));
if ((ch >= '\300') && (ch <= '\337')) /* Latin-1 accented chars */
return (char)(ch + ('\340' - '\300'));
return ch;
}
/* extract text from next line of ps file */
/* return count of characters written to dest */
int
text_extract_line(char *dest, FILE *inf)
{
char linebuf[DSC_LINE_LENGTH];
unsigned int count = 0;
char *p;
char ch;
int instring;
*dest = '\0';
if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
return 0;
/* skip over binary sections */
if (strncmp(linebuf, "%%BeginBinary:",14)==0) {
unsigned long lcount = 0;
int read;
char buf[1024];
if (sscanf(linebuf+14, "%ld", &lcount) != 1)
lcount = 0;
while (lcount) {
read = fread(buf, 1, min(lcount, sizeof(buf)), inf);
lcount -= read;
if (read == 0)
lcount = 0;
}
if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
return 0;
}
if (strncmp(linebuf, "%%BeginData:",12)==0) {
unsigned long lcount;
int read;
char buf[DSC_LINE_LENGTH];
if (sscanf(linebuf+12, "%ld %*s %s", &lcount, buf) != 2)
lcount = 0;
if (strncmp(buf, "Lines", 5) == 0) {
while (lcount) {
lcount--;
if (fgets(buf, sizeof(buf), inf) == (char *)NULL)
lcount = 0;
}
}
else {
while (lcount) {
read = fread(buf, 1, min(lcount, (unsigned)sizeof(buf)), inf);
lcount -= read;
if (read == 0)
lcount = 0;
}
}
if ( (p=fgets(linebuf, sizeof(linebuf), inf)) == (char *)NULL )
return 0;
}
instring = FALSE;
while ((ch = *p)!='\0') {
if (!instring && (ch=='%'))
break; /* comment until EOL */
if (ch == '(') {
if (instring) {
*dest++ = ch;
count++;
}
instring++;
}
else if (ch == ')') {
instring--;
if (instring) {
*dest++ = ch;
count++;
}
else {
*dest++ = ' '; /* may need to be changed */
count++;
}
}
else if (instring && (ch == '\\')) {
ch = *++p;
if (ch == '\0') {
p--;
}
else {
if ((ch != '(') && (ch != ')') && (ch !='\\')) {
*dest++ = '\\';
count++;
}
*dest++ = ch;
count++;
}
}
else if (instring) {
*dest++ = ch;
count++;
}
p++;
}
*dest = '\0';
return count;
}
void
text_extract(FILE *outf, FILE *inf, unsigned long end)
{
char outline[DSC_LINE_LENGTH];
while (ftell(inf) < (long)end) {
if (text_extract_line(outline, inf)) {
fputs(outline, outf);
fputc('\n', outf);
}
}
}
void
gsview_text_extract_quick()
{
FILE *f;
FILE *infile;
static char output[MAXSTR];
if (!get_filename(output, TRUE, FILTER_TXT, 0, IDS_TOPICTEXT))
return;
if ((f = fopen(output, "w")) == (FILE *)NULL) {
return;
}
if ( (infile = fopen(psfile_name(&psfile), "rb")) == (FILE *)NULL ) {
fclose(f);
return;
}
info_wait(IDS_WAITWRITE);
if (psfile.dsc == (CDSC *)NULL) {
/* scan whole document */
unsigned long end;
fseek(infile, 0L, SEEK_END);
end = ftell(infile);
fseek(infile, 0L, SEEK_SET);
text_extract(f, infile, end);
dfclose();
}
else {
if (psfile.dsc->page_count != 0) {
int i;
for (i = 0; i < (int)psfile.dsc->page_count; i++) {
if (psfile.page_list.select[map_page(i)]) {
fseek(infile, psfile.dsc->page[map_page(i)].begin, SEEK_SET);
text_extract(f, infile, psfile.dsc->page[map_page(i)].end);
fputc('\f', f);
fputc('\n', f);
}
}
}
else {
long end = psfile.dsc->begincomments;
fseek(infile, psfile.dsc->begincomments, SEEK_SET);
if (psfile.dsc->endcomments)
end = psfile.dsc->endcomments;
if (psfile.dsc->enddefaults)
end = psfile.dsc->enddefaults;
if (psfile.dsc->endprolog)
end = psfile.dsc->endprolog;
if (psfile.dsc->endsetup)
end = psfile.dsc->endsetup;
if (psfile.dsc->endtrailer)
end = psfile.dsc->endtrailer;
text_extract(f, infile, end);
}
}
fclose(infile);
fclose(f);
info_wait(IDS_NOWAIT);
return;
}
void
gsview_text_extract()
{
int thispage = psfile.pagenum;
if (psfile.ispdf && (option.pstotext == 0)) {
TCHAR buf[MAXSTR];
load_string(IDS_NOPDFQUICKTEXT, buf, sizeof(buf)-1);
message_box(buf, 0);
return;
}
if (psfile.name[0] == '\0') {
gserror(IDS_NOTOPEN, NULL, MB_ICONEXCLAMATION, SOUND_NOTOPEN);
return;
}
if (pstotextOutfile != (FILE *)NULL) {
play_sound(SOUND_BUSY);
return; /* busy creating text index file */
}
nHelpTopic = IDS_TOPICTEXT;
if ((psfile.dsc != (CDSC *)NULL) && (psfile.dsc->page_count != 0))
if (!get_page(&thispage, TRUE, FALSE))
return;
if (option.pstotext == 0) {
if (dfreopen() != 0)
return;
gsview_text_extract_quick();
dfclose();
}
else {
/* check if text_name exists, create if necessary */
if (psfile.text_name[0] == '\0') {
pending.text = TRUE;
pending.now = TRUE;
/* set flag to come back here after text_name created */
psfile.text_extract = TRUE;
return;
}
else {
gsview_text_extract_slow();
}
}
}
char *
text_find_string(char *str, char *find, int flen)
{
char *p, *last;
int mcount = 0;
last = p = str;
while (*p) {
if (*p == ' ') {
p++;
continue; /* ignore white space */
}
if (mcount) {
if (toupper_latin1(*p) == find[mcount])
mcount++; /* matched one more character */
else {
mcount = 0;
p = last+1; /* retrace to just past last partial match */
}
}
else {
if (toupper_latin1(*p) == *find) {
last = p;
mcount++; /* start of partial match */
}
}
if (mcount == flen)
return last;
p++;
}
return (char *)NULL;
}
/* if str found return malloc'd string containing match */
char *
text_find_section(FILE *inf, unsigned long end, char *str)
{
char dbuf[DSC_LINE_LENGTH+DSC_LINE_LENGTH];
char sbuf[DSC_LINE_LENGTH/4];
int dlength;
int slength;
int count;
/* copy str to uppercase, removing spaces */
slength = 0;
for (count=0; str[count]; count++) {
if (slength > DSC_LINE_LENGTH/4)
return NULL;
if (str[count] != ' ') /* ignore spaces */
sbuf[slength++] = (char)toupper_latin1(str[count]); /* searches are case insensitive */
}
sbuf[slength] = '\0';
if (slength==0)
return NULL;
dlength = 0;
while (ftell(inf) < (long)end) {
while ((ftell(inf) < (long)end) && (dlength < DSC_LINE_LENGTH)) {
count = text_extract_line(dbuf+dlength, inf);
dlength += count;
if (count) { /* separate lines by spaces */
dbuf[dlength++] = ' ';
dbuf[dlength] = '\0';
}
}
if (text_find_string(dbuf, sbuf, slength)) {
str = (char *)malloc(dlength+1);
if (str)
strcpy(str, dbuf);
return str;
}
if (dlength > slength) {
memmove(dbuf, dbuf+dlength-slength, slength+1);
dlength = slength;
}
else
dlength = 0;
}
return NULL;
}
void
gsview_text_find()
{
TCHAR prompt[MAXSTR]; /* input dialog box prompt and message box string */
char answer[MAXSTR]; /* input dialog box answer string */
int thispage = psfile.pagenum;
/* can relax some of these restrictions if don't display */
if (not_dsc())
return;
if (psfile.ispdf && (option.pstotext == 0)) {
TCHAR buf[MAXSTR];
load_string(IDS_NOPDFQUICKTEXT, buf, sizeof(buf)-1);
message_box(buf, 0);
return;
}
if (order_is_special())
return;
if (pstotextOutfile != (FILE *)NULL) {
play_sound(SOUND_BUSY);
return; /* busy creating text index file */
}
if (psfile.dsc->page_count == 0) {
gserror(IDS_NOPAGE, NULL, MB_ICONEXCLAMATION, SOUND_NONUMBER);
return;
}
load_string(IDS_TEXTFIND, prompt, sizeof(prompt));
strcpy(answer, szFindText);
nHelpTopic = IDS_TOPICTEXT;
if (!query_string(prompt,answer))
return;
strcpy(szFindText, answer);
if (!get_page(&thispage, TRUE, TRUE)) /* search all pages */
return;
if (option.pstotext == 0) {
gsview_text_findnext_quick();
}
else {
psfile.text_offset = 0;
psfile.text_page = 0;
/* check if text_name exists, create if necessary */
if (psfile.text_name[0] == '\0') {
pending.text = TRUE;
pending.now = TRUE;
/* set flag to come back here after text_name created */
psfile.text_extract = FALSE;
return;
}
else {
gsview_text_findnext_slow();
}
}
}
void
gsview_text_findnext()
{
if (option.pstotext == 0)
gsview_text_findnext_quick();
else
gsview_text_findnext_slow();
}
void
gsview_text_findnext_quick()
{
int i;
char *p;
FILE *infile;
if (not_dsc())
return;
if (psfile.ispdf && (option.pstotext == 0)) {
TCHAR buf[MAXSTR];
load_string(IDS_NOPDFQUICKTEXT, buf, sizeof(buf)-1);
message_box(buf, 0);
return;
}
if (strlen(szFindText)==0) {
gserror(IDS_TEXTNOTFIND, NULL, MB_ICONEXCLAMATION, 0);
return;
}
if ( (infile = fopen(psfile_name(&psfile), "rb")) == (FILE *)NULL )
return;
info_wait(IDS_WAITSEARCH);
for (i = 0; i < (int)psfile.dsc->page_count; i++) {
if (psfile.page_list.select[map_page(i)]) {
psfile.page_list.select[map_page(i)] = FALSE;
fseek(infile, psfile.dsc->page[map_page(i)].begin, SEEK_SET);
p = text_find_section(infile,
psfile.dsc->page[map_page(i)].end, szFindText);
if (p) { /* found it */
info_wait(IDS_NOWAIT);
free(p);
dfclose();
request_mutex();
pending.pagenum = i+1;
history_add(pending.pagenum);
pending.now = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -