📄 dscparse.c
字号:
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 + -