📄 gvcpdf.c
字号:
(int)x0, (int)y0, (int)x1, (int)y1);
}
return TRUE;
}
}
if (psfile.ispdf && (len >= sizeof(pdf_rotate_tag)) &&
(strncmp(line, pdf_rotate_tag, strlen(pdf_rotate_tag)) == 0) ) {
i = sscanf(line+strlen(pdf_rotate_tag), "%d", &rotate);
if (i==1) {
int pdf_rotate;
if (debug)
gs_addmess("Found GSVIEW_PDF_ROTATE tag\n");
while (rotate < 0)
rotate += 360;
while (rotate >= 360)
rotate -= 360;
switch (rotate) {
case 90:
pdf_rotate = CDSC_LANDSCAPE;
break;
case 180:
pdf_rotate = CDSC_UPSIDEDOWN;
break;
case 270:
pdf_rotate = CDSC_SEASCAPE;
break;
default:
pdf_rotate = CDSC_PORTRAIT;
break;
}
/* pdf_rotate is used if orientation is auto */
if ((psfile.dsc != NULL) &&
(pdf_page_number < (int)psfile.dsc->page_count)) {
psfile.dsc->page[pdf_page_number].orientation = pdf_rotate;
}
return TRUE;
}
}
if ((len >= sizeof(pdf_mark_tag)) &&
(strncmp(line, pdf_mark_tag, strlen(pdf_mark_tag)) == 0) ) {
char *p, *key, *value;
PDFLINK link;
BOOL possibly_a_link = FALSE;
BOOL is_a_link = FALSE;
int code = FALSE;
memset(&link, 0, sizeof(link));
link.border_width = 1;
p = line+strlen(pdf_mark_tag);
if (strncmp(p, "/LNK ", 5) == 0) {
p += 5;
possibly_a_link = TRUE;
is_a_link = TRUE;
}
if (strncmp(p, "/ANN ", 5) == 0) {
p += 5;
possibly_a_link = TRUE;
}
if (possibly_a_link) {
p = pdf_parse_mark(p, &key, &value);
while (p) {
if (strcmp(key, "/Rect") == 0) {
float fllx, flly, furx, fury;
if (sscanf(value+1, "%f %f %f %f",
&fllx, &flly, &furx, &fury) == 4) {
link.bbox.llx = (int)fllx;
link.bbox.lly = (int)flly;
link.bbox.urx = (int)(furx + 0.5);
link.bbox.ury = (int)(fury + 0.5);
code = TRUE;
}
else if (debug)
gs_addmess("Invalid /Rect\n");
}
if (strcmp(key, "/Page") == 0) {
if (strcmp(value, "/NextPage") == 0) {
link.page = psfile.pagenum+1;
code = TRUE;
}
else if (strcmp(value, "/PrevPage") == 0) {
link.page = psfile.pagenum-1;
code = TRUE;
}
if (strcmp(value, "/FirstPage") == 0) {
link.page = 1;
code = TRUE;
}
else if (strcmp(value, "/LastPage") == 0) {
if (psfile.dsc)
link.page = psfile.dsc->page_count;
else
link.page = 0;
code = TRUE;
}
else if (sscanf(value, "%d", &link.page) == 1) {
code = TRUE;
}
}
if (strcmp(key, "/Border") == 0) {
if (sscanf(value+1, "%f %f %f", &link.border_xr,
&link.border_yr, &link.border_width) == 3)
code = TRUE;
else if (debug)
gs_addmess("Invalid /Border\n");
}
if (strcmp(key, "/Color") == 0) {
if (sscanf(value+1, "%f %f %f", &link.colour_red,
&link.colour_green, &link.colour_blue) == 3) {
code = TRUE;
link.colour_valid = TRUE;
}
else if (debug)
gs_addmess("Invalid /Color\n");
}
if (strcmp(key, "/Subtype") == 0) {
if (strcmp(value, "/Link") == 0) {
is_a_link = TRUE;
code = TRUE;
}
}
if ((strcmp(key, "/Action") == 0) ||
(strcmp(key, "/A") == 0)) {
if (strcmp(value, "/GoTo") == 0) {
is_a_link = TRUE;
code = TRUE;
}
else if (strncmp(value, "<<", 2) == 0) {
/* probably a named desination */
int valid = TRUE;
char *s = value;
s += 2;
while (*s && *s == ' ')
s++;
if (strncmp(s, "/Subtype ", 9) == 0)
s += 9;
else if (strncmp(s, "/S ", 3) == 0)
s += 3;
else
valid = FALSE;
while (*s && *s == ' ')
s++;
if (valid && (strncmp(s, "/Named ", 7) == 0)) {
s += 7;
while (*s && *s == ' ')
s++;
if (valid && (strncmp(s, "/N ", 3) == 0))
s += 3;
else
valid = FALSE;
while (*s && *s == ' ')
s++;
if (valid && (*s == '/')) {
s++;
if (strlen(s) < sizeof(link.action)-1) {
strncpy(link.action, s, sizeof(link.action));
s = link.action;
while (*s && (*s != ' '))
s++;
if (*s == ' ')
*s = '\0';
}
is_a_link = TRUE;
code = TRUE;
}
}
else if (strncmp(s, "/URI ", 5) == 0) {
s += 5;
while (*s && *s == ' ')
s++;
if (strncmp(s, "/URI ", 5) == 0)
s += 5;
else
valid = FALSE;
while (*s && *s == ' ')
s++;
if (valid && (*s == '(')) {
/* URL */
s++;
if (strlen(s) < sizeof(link.action)-1) {
strncpy(link.action, s,sizeof(link.action));
s = link.action;
while (*s && (*s != ')'))
s++;
if (*s == ')')
*s = '\0';
}
is_a_link = TRUE;
code = TRUE;
}
}
else
valid = FALSE;
}
}
p = pdf_parse_mark(p, &key, &value);
}
if (code && is_a_link)
pdf_add_link(link);
return code;
}
}
return FALSE;
}
/* Check stdout for tag giving page range */
int
pdf_checktag(const char *str, int len)
{
char *p;
BOOL quote_next;
BOOL inparen;
BOOL found_eol;
int code = FALSE;
unsigned int tag_len;
int count;
while (len) {
/* append to local copy */
tag_len = strlen(pdf_tag_line);
count = min(len, (int)(sizeof(pdf_tag_line) - 1 - tag_len));
len -= count;
if (count) {
memcpy(pdf_tag_line+tag_len, str, count);
tag_len += count;
pdf_tag_line[tag_len] = '\0';
}
if (tag_len == 0)
return 0;
do {
if (tag_len == 0)
return 0;
tag_len = strlen(pdf_tag_line);
/* check if line is complete */
quote_next = FALSE;
inparen = FALSE;
found_eol = FALSE;
for (p = pdf_tag_line; *p; p++) {
if (quote_next) {
quote_next = FALSE;
continue;
}
if (*p == '\\')
quote_next = TRUE;
else if (*p == '(')
inparen = TRUE;
else if (*p == ')')
inparen = FALSE;
else if ((*p == '\n') && !inparen) {
found_eol = TRUE;
break;
}
}
if (found_eol) {
if (*p)
*p++ = '\0';
if (*pdf_tag_line == '%') {
code = pdf_process_tag(pdf_tag_line);
}
memmove(pdf_tag_line, p,
pdf_tag_line+tag_len - pdf_tag_line + 1);
}
tag_len = strlen(pdf_tag_line);
if (!found_eol && (tag_len >= sizeof(pdf_tag_line)-1)) {
/* Very long line without an EOL.
* This can't be a pdf tag, so just ignore it
*/
pdf_tag_line[0] = '\0';
tag_len = 0;
}
} while (found_eol);
}
return code;
}
int
pdf_orientation(int page)
{
if (psfile.dsc == (CDSC *)NULL)
return IDM_PORTRAIT;
if ((page < 1) || (page > (int)psfile.dsc->page_count))
return IDM_PORTRAIT;
switch (psfile.dsc->page[page-1].orientation) {
case CDSC_LANDSCAPE:
return IDM_LANDSCAPE;
case CDSC_UPSIDEDOWN:
return IDM_UPSIDEDOWN;
case CDSC_SEASCAPE:
return IDM_SEASCAPE;
}
return IDM_PORTRAIT;
}
#ifndef VIEWONLY
/* Create DSC file to print selected pages of PDF file */
int
pdf_extract(FILE *f, int copies)
{
char filename[MAXSTR];
char *p, *s;
int i, page, pages;
CDSC *dsc = psfile.dsc;
BOOL reverse = psfile.page_list.reverse;
p = filename;
for (s = psfile_name(&psfile); *s; s++) {
if ((*s == '\\') || (*s == '(') || (*s == ')'))
*p++ = '\\';
*p++ = *s;
}
*p = '\0';
if (dsc->page_count == 0) {
/* unknown number of pages */
TCHAR buf[MAXSTR];
load_string(IDS_PDFEXTRACTALL, buf, sizeof(buf));
if (message_box(buf, MB_ICONASTERISK | MB_OKCANCEL) == IDCANCEL)
return FALSE;
fputs("%!\n(", f);
fputs(filename, f);
fputs(") run\n", f);
return TRUE;
}
/* count pages */
pages = 0;
for (i=0; i< (int)dsc->page_count; i++) {
if (psfile.page_list.select[i]) pages++;
}
/* Send header */
fputs("%!PS-Adobe 3.0\r\n%%Creator: GSview\r\n", f);
fputs("%%Title: Ghostscript wrapper for ", f);
fputs(psfile_name(&psfile), f);
fputs("\r\n%%Pages: ", f);
fprintf(f, "%d\r\n", pages);
fprintf(f, "%%%%PageOrder: %s\r\n", reverse ? "Descend" : "Ascend");
fputs("%%EndComments\r\n", f);
fputs("%%BeginProlog\r\n", f);
fputs("\
/Page null def\r\n\
/Page# 0 def\r\n\
/PDFSave null def\r\n\
/DSCPageCount 0 def\r\n\
/DoPDFPage {\r\n\
(Page ) print dup == flush\r\n\
dup /Page# exch store\r\n\
pdfgetpage pdfshowpage\r\n\
} def\r\n\
GS_PDF_ProcSet begin\r\n\
pdfdict begin\r\n\
", f);
fputs("%%EndProlog\r\n", f);
fputs("%%BeginSetup\r\n", f);
if (copies > 1)
add_copies(f, copies);
fprintf(f, "(%s) (r) file pdfopen begin\r\n", filename);
if (option.safer)
fprintf(f, "systemdict /.setsafe known { .setsafe } if\n");
fputs("%%EndSetup\r\n", f);
/* Send each page */
page = 1;
i = reverse ? dsc->page_count - 1 : 0;
while ( reverse ? (i >= 0) : (i < (int)dsc->page_count) ) {
if (psfile.page_list.select[i]) {
fprintf(f, "%%%%Page: %s %d\r\n", dsc->page[i].label, page);
fprintf(f, "%d DoPDFPage\r\n", i+1);
page++;
}
i += reverse ? -1 : 1;
}
/* Send trailer */
fputs("%%Trailer\r\n", f);
fputs("currentdict pdfclose\r\nend\r\nend\r\nend\r\n%%EOF\r\n", f);
return TRUE;
}
#endif
PDFLINK *pdf_link_head;
void
pdf_free_link(void)
{
PDFLINK *next, *thislink;
request_mutex();
thislink = pdf_link_head;
while (thislink != (PDFLINK *)NULL) {
next = thislink->next;
free(thislink);
thislink = next;
}
pdf_link_head = (PDFLINK *)NULL;
release_mutex();
}
void
pdf_add_link(PDFLINK newlink)
{
PDFLINK *thislink;
int temp;
if (newlink.bbox.llx > newlink.bbox.urx) {
temp = newlink.bbox.llx;
newlink.bbox.llx = newlink.bbox.urx;
newlink.bbox.urx = temp;
}
if (newlink.bbox.lly > newlink.bbox.ury) {
temp = newlink.bbox.lly;
newlink.bbox.lly = newlink.bbox.ury;
newlink.bbox.ury = temp;
}
if (debug) {
char buf[MAXSTR];
sprintf(buf, "Adding link /Page %d /Rect [%d %d %d %d] /Border [%g %g %g]",
newlink.page,
newlink.bbox.llx, newlink.bbox.lly,
newlink.bbox.urx, newlink.bbox.ury,
newlink.border_xr, newlink.border_yr, newlink.border_width);
gs_addmess(buf);
if (newlink.colour_valid) {
sprintf(buf, " /Color [%g %g %g]",
newlink.colour_red, newlink.colour_green, newlink.colour_blue);
gs_addmess(buf);
}
gs_addmess("\n");
}
request_mutex();
thislink = (PDFLINK *)malloc(sizeof(PDFLINK));
if (thislink) {
*thislink = newlink;
thislink->next = pdf_link_head;
pdf_link_head = thislink;
}
release_mutex();
}
BOOL
pdf_get_link(int index, PDFLINK *link)
{
int i;
PDFLINK *thislink = pdf_link_head;
int code = FALSE;
request_mutex();
for (i=0; (thislink!=NULL) && i < index; i++)
thislink = thislink->next;
if (thislink) {
*link = *thislink;
code = TRUE;
}
release_mutex();
return code;
}
BOOL
is_link(float x, float y, PDFLINK *link)
{
int i = 0;
while ( pdf_get_link(i, link) ) {
i++;
if ( (link->bbox.llx < x) && (link->bbox.urx > x)
&& (link->bbox.lly < y) && (link->bbox.ury > y) ) {
/* found link */
return TRUE;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -