/* * Look up a named object as for pdf_find_named. If the object does not * exist, create it (as a dictionary if it is one of the predefined names * {ThisPage}, {NextPage}, {PrevPage}, or {Page<#>}, otherwise as a * generic object) and return 1. */ int pdf_refer_named(gx_device_pdf * pdev, const gs_param_string * pname_orig, cos_object_t **ppco) { const gs_param_string *pname = pname_orig; int code = pdf_find_named(pdev, pname, ppco); char page_name_chars[6 + 10 + 2]; /* {Page<n>}, enough for an int */ gs_param_string pnstr; int page_number; if (code != gs_error_undefined) return code; /* * Check for a predefined name. Map ThisPage, PrevPage, and NextPage * to the appropriate Page<#> name. */ if (pname->size >= 7 && pname->size < sizeof(page_name_chars)) { memcpy(page_name_chars, pname->data, pname->size); page_name_chars[pname->size] = 0; if (sscanf(page_name_chars, "{Page%d}", &page_number) == 1) goto cpage; } if (pdf_key_eq(pname, "{ThisPage}")) page_number = pdev->next_page + 1; else if (pdf_key_eq(pname, "{NextPage}")) page_number = pdev->next_page + 2; else if (pdf_key_eq(pname, "{PrevPage}")) page_number = pdev->next_page; else { code = pdf_create_named(pdev, pname, cos_type_generic, ppco, 0L); return (code < 0 ? code : 1); } if (page_number <= 0) return code; sprintf(page_name_chars, "{Page%d}", page_number); param_string_from_string(pnstr, page_name_chars); pname = &pnstr; code = pdf_find_named(pdev, pname, ppco); if (code != gs_error_undefined) return code; cpage: if (pdf_page_id(pdev, page_number) <= 0) return_error(gs_error_rangecheck); *ppco = COS_OBJECT(pdev->pages[page_number - 1].Page); return 0; }
static int pdf_dsc_process(gx_device_pdf * pdev, const gs_param_string_array * pma) { /* * The Adobe "Distiller Parameters" documentation says that Distiller * looks at DSC comments, but it doesn't say which ones. We look at * the ones that we see how to map directly to obvious PDF constructs. */ int code = 0; uint i; /* * If ParseDSCComments is false, all DSC comments are ignored, even if * ParseDSCComentsForDocInfo or PreserveEPSInfo is true. */ if (!pdev->ParseDSCComments) return 0; for (i = 0; i + 1 < pma->size && code >= 0; i += 2) { const gs_param_string *pkey = &pma->data[i]; const gs_param_string *pvalue = &pma->data[i + 1]; const char *key; int code; /* * %%For, %%Creator, and %%Title are recognized only if either * ParseDSCCommentsForDocInfo or PreserveEPSInfo is true. * The other DSC comments are always recognized. * * Acrobat Distiller sets CreationDate and ModDate to the current * time, not the value of %%CreationDate. We think this is wrong, * but we do the same -- we ignore %%CreationDate here. */ if (pdf_key_eq(pkey, "Creator")) key = "/Creator"; else if (pdf_key_eq(pkey, "Title")) key = "/Title"; else if (pdf_key_eq(pkey, "For")) key = "/Author"; else { pdf_page_dsc_info_t *ppdi; char scan_buf[200]; /* arbitrary */ if ((ppdi = &pdev->doc_dsc_info, pdf_key_eq(pkey, "Orientation")) || (ppdi = &pdev->page_dsc_info, pdf_key_eq(pkey, "PageOrientation")) ) { if (pvalue->size == 1 && pvalue->data[0] >= '0' && pvalue->data[0] <= '3' ) ppdi->orientation = pvalue->data[0] - '0'; else ppdi->orientation = -1; } else if ((ppdi = &pdev->doc_dsc_info, pdf_key_eq(pkey, "ViewingOrientation")) || (ppdi = &pdev->page_dsc_info, pdf_key_eq(pkey, "PageViewingOrientation")) ) { gs_matrix mat; int orient; if(pvalue->size >= sizeof(scan_buf) - 1) continue; /* error */ memcpy(scan_buf, pvalue->data, pvalue->size); scan_buf[pvalue->size] = 0; if (sscanf(scan_buf, "[%g %g %g %g]", &mat.xx, &mat.xy, &mat.yx, &mat.yy) != 4 ) continue; /* error */ for (orient = 0; orient < 4; ++orient) { if (mat.xx == 1 && mat.xy == 0 && mat.yx == 0 && mat.yy == 1) break; gs_matrix_rotate(&mat, -90.0, &mat); } if (orient == 4) /* error */ orient = -1; ppdi->viewing_orientation = orient; } else { gs_rect box; if (pdf_key_eq(pkey, "EPSF")) { pdev->is_EPS = (pvalue->size >= 1 && pvalue->data[0] != '0'); continue; } /* * We only parse the BoundingBox for the sake of * AutoPositionEPSFiles. */ if (pdf_key_eq(pkey, "BoundingBox")) ppdi = &pdev->doc_dsc_info; else if (pdf_key_eq(pkey, "PageBoundingBox")) ppdi = &pdev->page_dsc_info; else continue; if(pvalue->size >= sizeof(scan_buf) - 1) continue; /* error */ memcpy(scan_buf, pvalue->data, pvalue->size); scan_buf[pvalue->size] = 0; if (sscanf(scan_buf, "[%lg %lg %lg %lg]", &box.p.x, &box.p.y, &box.q.x, &box.q.y) != 4 ) continue; /* error */ ppdi->bounding_box = box; } continue; } if (pdev->ParseDSCCommentsForDocInfo || pdev->PreserveEPSInfo) code = cos_dict_put_c_key_string(pdev->Info, key, pvalue->data, pvalue->size); } return code; }