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

📄 dscparse.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:
		return CDSC_OK;	/* ignore duplicate comments in header */
	    case CDSC_RESPONSE_IGNORE_ALL:
		return CDSC_NOTDSC;
	}
    }
    if ((dsc->page_order != CDSC_ORDER_UNKNOWN) && 
	(dsc->scan_section == scan_trailer)) {
	int rc = dsc_error(dsc, CDSC_MESSAGE_DUP_TRAILER, dsc->line, 
		dsc->line_length);
	switch (rc) {
	    case CDSC_RESPONSE_OK:
	    case CDSC_RESPONSE_CANCEL:
		break;		/* use duplicate comments in trailer */
	    case CDSC_RESPONSE_IGNORE_ALL:
		return CDSC_NOTDSC;
	}
    }

    p = dsc->line + (IS_DSC(dsc->line, "%%+") ? 3 : 13);
    while (IS_WHITE(*p))
	p++;
    if (COMPARE(p, "atend")) {
	if (dsc->scan_section == scan_trailer)
	    dsc_unknown(dsc);
	else {
	    int rc = dsc_error(dsc, CDSC_MESSAGE_ATEND, dsc->line, 
		    dsc->line_length);
	    switch (rc) {
		case CDSC_RESPONSE_OK:
		    /* assume (atend) */
		    /* we should mark it as deferred */
		    break;
		case CDSC_RESPONSE_CANCEL:
		    /* ignore it */
		    break;
		case CDSC_RESPONSE_IGNORE_ALL:
		    return CDSC_NOTDSC;
	    }
	}
    }
    else if (COMPARE(p, "(atend)")) {
	if (dsc->scan_section == scan_trailer)
	    dsc_unknown(dsc);
	/* do nothing */
	/* we should mark it as deferred */
    }
    else if (COMPARE(p, "Ascend")) {
	dsc->page_order = CDSC_ASCEND;
    }
    else if (COMPARE(p, "Descend")) {
	dsc->page_order = CDSC_DESCEND;
    }
    else if (COMPARE(p, "Special")) {
	dsc->page_order = CDSC_SPECIAL;
    }
    else {
	dsc_unknown(dsc);
    }
    return CDSC_OK;
}


dsc_private int 
dsc_parse_media(CDSC *dsc, const CDSCMEDIA **page_media)
{
    char media_name[MAXSTR];
    int n = IS_DSC(dsc->line, "%%+") ? 3 : 12; /* %%PageMedia: */
    unsigned int i;

    if (dsc_copy_string(media_name, sizeof(media_name)-1, 
	dsc->line+n, dsc->line_length-n, NULL)) {
	for (i=0; i<dsc->media_count; i++) {
	    if (dsc->media[i]->name && 
		(dsc_stricmp(media_name, dsc->media[i]->name) == 0)) {
		*page_media = dsc->media[i];
		return CDSC_OK;
	    }
	}
    }
    dsc_unknown(dsc);
    
    return CDSC_OK;
}


dsc_private int 
dsc_parse_document_media(CDSC *dsc)
{
    unsigned int i, n;
    CDSCMEDIA lmedia;
    GSBOOL blank_line;

    if (IS_DSC(dsc->line, "%%DocumentMedia:"))
	n = 16;
    else if (IS_DSC(dsc->line, "%%+"))
	n = 3;
    else
	return CDSC_ERROR;	/* error */

    /* check for blank remainder of line */
    blank_line = TRUE;
    for (i=n; i<dsc->line_length; i++) {
	if (!IS_WHITE_OR_EOL(dsc->line[i])) {
	    blank_line = FALSE;
	    break;
	}
    }

    if (!blank_line) {
	char name[MAXSTR];
	char colour[MAXSTR];
	char type[MAXSTR];
	lmedia.name = lmedia.colour = lmedia.type = (char *)NULL;
	lmedia.width = lmedia.height = lmedia.weight = 0;
	lmedia.mediabox = (CDSCBBOX *)NULL;
	lmedia.name = dsc_copy_string(name, sizeof(name),
		dsc->line+n, dsc->line_length-n, &i);
	n+=i;
	if (i)
	    lmedia.width = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
	n+=i;
	if (i)
	    lmedia.height = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
	n+=i;
	if (i)
	    lmedia.weight = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
	n+=i;
	if (i)
	    lmedia.colour = dsc_copy_string(colour, sizeof(colour),
		dsc->line+n, dsc->line_length-n, &i);
	n+=i;
	if (i)
	    lmedia.type = dsc_copy_string(type, sizeof(type),
		dsc->line+n, dsc->line_length-n, &i);

	if (i==0)
	    dsc_unknown(dsc); /* we didn't get all fields */
	else {
	    if (dsc_add_media(dsc, &lmedia))
		return CDSC_ERROR;	/* out of memory */
	}
    }
    return CDSC_OK;
}

/* viewing orientation is believed to be the first four elements of
 * a CTM matrix
 */
dsc_private int 
dsc_parse_viewing_orientation(CDSC *dsc, CDSCCTM **pctm)
{
    CDSCCTM ctm;
    unsigned int i, n;

    if (*pctm != NULL) {
	dsc_memfree(dsc, *pctm);
	*pctm = NULL;
    }

    n = IS_DSC(dsc->line, "%%+") ? 3 : 21;  /* %%ViewingOrientation: */
    while (IS_WHITE(dsc->line[n]))
	n++;

    /* ctm.xx = */ ctm.xy = ctm.yx = ctm.yy = 0.0;
    ctm.xx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
    n += i;
    if (i)
        ctm.xy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
    n += i;
    if (i)
        ctm.yx = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
    n += i;
    if (i)
        ctm.yy = dsc_get_real(dsc->line+n, dsc->line_length-n, &i);
    if (i==0) {
	dsc_unknown(dsc); /* we didn't get all fields */
    }
    else {
	*pctm = (CDSCCTM *)dsc_memalloc(dsc, sizeof(CDSCCTM));
	if (*pctm == NULL)
	    return CDSC_ERROR;	/* no memory */
	**pctm = ctm;
    }
    return CDSC_OK;
}
   

/* This is called before dsc_read_line(), since we may
 * need to skip a binary header which contains a new line
 * character
 */
dsc_private int 
dsc_scan_type(CDSC *dsc)
{
    unsigned char *p;
    unsigned char *line = (unsigned char *)(dsc->data + dsc->data_index);
    int length = dsc->data_length - dsc->data_index;

    /* Types that should be known:
     *   DSC
     *   EPSF
     *   PJL + any of above
     *   ^D + any of above
     *   DOS EPS
     *   PDF
     *   non-DSC
     */

    /* First process any non PostScript headers */
    /* At this stage we do not have a complete line */

    if (length == 0)
	return CDSC_NEEDMORE;

    /* If we have already found a DOS EPS header, */
    /* ignore all until the PostScript section */
    if (dsc->skip_bytes) {
	int cnt = min(dsc->skip_bytes,
		     (int)(dsc->data_length - dsc->data_index));
	dsc->skip_bytes -= cnt;
	dsc->data_index += cnt;
	length -= cnt;
	line += cnt;
	if (dsc->skip_bytes != 0)
	    return CDSC_NEEDMORE;
    }

    if (dsc->skip_pjl) {
	/* skip until first PostScript comment */
	while (length >= 2) {
	    while (length && !IS_EOL(line[0])) {
		/* skip until EOL character */
		line++;
		dsc->data_index++;
		length--;
	    }
	    while ((length >= 2) && IS_EOL(line[0]) && IS_EOL(line[1])) {
		/* skip until EOL followed by non-EOL */
		line++;
		dsc->data_index++;
		length--;
	    }
	    if (length < 2)
		return CDSC_NEEDMORE;

	    if (IS_EOL(line[0]) && line[1]=='%') {
		line++;
		dsc->data_index++;
		length--;
		dsc->skip_pjl = FALSE;
		break;
	    }
	    else {
		line++;
		dsc->data_index++;
		length--;
	    }
	}
	if (dsc->skip_pjl)
	    return CDSC_NEEDMORE;
    }

    if (length == 0)
	return CDSC_NEEDMORE;

    if (line[0] == '\004') {
	line++;
	dsc->data_index++;
	length--;
	dsc->ctrld = TRUE;
    }

    if (line[0] == '\033') {
	/* possibly PJL */
	if (length < 9)
	    return CDSC_NEEDMORE;
	if (COMPARE(line, "\033%-12345X")) {
	    dsc->skip_pjl = TRUE;  /* skip until first PostScript comment */
	    dsc->pjl = TRUE;
	    dsc->data_index += 9;
	    return dsc_scan_type(dsc);
	}
    }

    if ((line[0]==0x0) && (length < 2))
	return CDSC_NEEDMORE;	/* Could be Mac Binary EPSF */
    if ((line[0]==0x0) && (line[1] >= 1) && (line[1] <= 63) && (length < 128))
	return CDSC_NEEDMORE;	/* Could be Mac Binary EPSF */
    if ((line[0]==0x0) && (line[1] == 0x5) && (length < 4))
	return CDSC_NEEDMORE;	/* Could be Mac AppleSingle/AppleDouble */
    if ((line[0]==0xc5) && (length < 4))
	return CDSC_NEEDMORE;	/* Could be DOS EPS */

    if ((line[0]==0xc5) && (line[1]==0xd0) && 
	 (line[2]==0xd3) && (line[3]==0xc6) ) {
	/* id is "EPSF" with bit 7 set */
	/* read DOS EPS header, then ignore all bytes until the PS section */
	if (length < 30)
	    return CDSC_NEEDMORE;
	dsc->line = (char *)line;
	if (dsc_read_doseps(dsc))
	    return CDSC_ERROR;
    }
    else if ((line[0]==0x0) && (line[1]==0x05) && 
	 (line[2]==0x16) && ((line[3]==0x0) || (line[3] == 0x07))) {
	/* Mac AppleSingle or AppleDouble */
	GSDWORD version;
	GSWORD entries;
	if (length < 26)
	    return CDSC_NEEDMORE;
	version = dsc_get_bigendian_dword(line+4);
	entries = dsc_get_bigendian_word(line+24);
	if ((version == 0x00010000) || (version == 0x00020000)) {
	    if (length < (int)(26 + entries * 12))
		return CDSC_NEEDMORE;
	    dsc->line = (char *)line;
	    if (dsc_read_applesingle(dsc))
		return CDSC_ERROR;
	}
    }
    else if ((line[0]==0x0) && 
	(line[1] >= 1) && (line[1] <= 63) && 
        (line[74]==0x0) && 
        (line[65]=='E') && (line[66]=='P') && 
        (line[67]=='S') && (line[68]=='F')) {
	/* Mac Binary EPSF */
	dsc->line = (char *)line;
	if (dsc_read_macbin(dsc))
	    return CDSC_ERROR;
    }
    else {
	if (length < 2)
	    return CDSC_NEEDMORE;
	if ((line[0] == '%') && (line[1] == 'P')) {
	    if (length < 5)
	        return CDSC_NEEDMORE;
	    if (COMPARE(line, "%PDF-")) {
		dsc->pdf = TRUE;
		dsc->scan_section = scan_comments;
		return CDSC_OK;
	    }
	}
    }

    /* Finally process PostScript headers */

    if (dsc_read_line(dsc) <= 0)
	return CDSC_NEEDMORE;
	
    dsc->dsc_version = dsc_add_line(dsc, dsc->line, dsc->line_length);
    if (COMPARE(dsc->line, "%!PS-Adobe")) {
	dsc->dsc = TRUE;
	dsc->begincomments = DSC_START(dsc);
	if (dsc->dsc_version == NULL)
	    return CDSC_ERROR;	/* no memory */
	p = (unsigned char *)dsc->line + 14;
	while (IS_WHITE(*p))
	    p++;
	if (COMPARE(p, "EPSF-"))
	    dsc->epsf = TRUE;
	dsc->scan_section = scan_comments;
	return CDSC_PSADOBE;
    }
    if (COMPARE(dsc->line, "%!")) {
	dsc->scan_section = scan_comments;
	return CDSC_NOTDSC;
    }

    dsc->scan_section = scan_comments;
    return CDSC_NOTDSC;	/* unrecognised */
}



dsc_private int 
dsc_scan_comments(CDSC *dsc)
{
    /* Comments section ends at */
    /*  %%EndComments */
    /*  another section */
    /*  line that does not start with %% */
    /* Save a few important lines */

    char *line = dsc->line;
    GSBOOL continued = FALSE;
    dsc->id = CDSC_OK;
    if (IS_DSC(line, "%%EndComments")) {
	dsc->id = CDSC_ENDCOMMENTS;
	dsc->endcomments = DSC_END(dsc);
	dsc->scan_section = scan_pre_preview;
	return CDSC_OK;
    }
    else if (IS_DSC(line, "%%BeginComments")) {
	/* ignore because we are in this section */
	dsc->id = CDSC_BEGINCOMMENTS;
    }
    else if (dsc_is_section(line)) {
	dsc->endcomments = DSC_START(dsc);
	dsc->scan_section = scan_pre_preview;
	return CDSC_PROPAGATE;
    }
    else if (line[0] == '%' && IS_WHITE_OR_EOL(line[1])) {
	dsc->endcomments = DSC_START(dsc);
	dsc->scan_section = scan_pre_preview;
	return CDSC_PROPAGATE;
    }
    else if (line[0] != '%') {
	dsc->id = CDSC_OK;
	dsc->endcomments = DSC_START(dsc);
	dsc->scan_section = scan_pre_preview;
	return CDSC_PROPAGATE;
    }
    else if (IS_DSC(line, "%%Begin")) {
	dsc->endcomments = DSC_START(dsc);
	dsc->scan_section = scan_pre_preview;
	return CDSC_PROPAGATE;
    }

    /* Handle continuation lines.
     * To simply processing, we assume that contination lines 
     * will only occur if repeat parameters are allowed and that 
     * a complete set of these parameters appears on each line.  
     * This is more restrictive than the DSC specification, but
     * is valid for the DSC comments understood by this parser
     * for all documents that we have seen.
     */
    if (IS_DSC(line, "%%+")) {
	line = dsc->last_line;
	continued = TRUE;
    }
    else
	dsc_save_line(dsc);

    if (IS_DSC(line, "%%Pages:")) {
	dsc->id = CDSC_PAGES;
	if (dsc_parse_pages(dsc) != 0)
	    return CDSC_ERROR;
    }
    else if (IS_DSC(line, "%%Creator:")) {
	dsc->id = CDSC_CREATOR;
	dsc->dsc_creator = dsc_add_line(dsc, dsc->line+10, dsc->line_length-10);
	if (dsc->dsc_creator==NULL)
	    return CDSC_ERROR;
    }
    else if (IS_DSC(line, "%%CreationDate:")) {
	dsc->id = CDSC_CREATIONDATE;
	dsc->dsc_date = dsc_add_line(dsc, dsc->line+15, dsc->line_length-15);
	if (dsc->dsc_date==NULL)
	    return CDSC_ERROR;
    }
    else if (IS_DSC(line, "%%Title:")) {
	dsc->id = CDSC_TITLE;
	dsc->dsc_title = dsc_add_line(dsc, dsc->line+8, dsc->line_length-8);
	if (dsc->dsc_title==NULL)
	    return CDSC_ERROR;
    }
    else if (IS_DSC(line, "%%For:")) {
	dsc->id = CDSC_FOR;
	dsc->dsc_for = d

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -