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

📄 gvcpdf.c

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