diff options
Diffstat (limited to 'devices/vector/gdevpdf.c')
-rw-r--r-- | devices/vector/gdevpdf.c | 150 |
1 files changed, 92 insertions, 58 deletions
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c index cb268f62..40beb06a 100644 --- a/devices/vector/gdevpdf.c +++ b/devices/vector/gdevpdf.c @@ -425,6 +425,7 @@ pdf_initialize_ids(gx_device_pdf * pdev) * date and time, rather than (for example) %%CreationDate from the * PostScript file. We think this is wrong, but we do the same. */ + if (!pdev->OmitInfoDate) { struct tm tms; time_t t; @@ -466,6 +467,7 @@ pdf_initialize_ids(gx_device_pdf * pdev) static int pdf_compute_fileID(gx_device_pdf * pdev) { + /* We compute a file identifier when beginning a document to allow its usage with PDF encryption. Due to that, in contradiction to the Adobe recommendation, our @@ -933,10 +935,14 @@ pdf_ferror(gx_device_pdf *pdev) { gp_fflush(pdev->file); gp_fflush(pdev->xref.file); - sflush(pdev->strm); - sflush(pdev->asides.strm); - sflush(pdev->streams.strm); - sflush(pdev->pictures.strm); + if (pdev->strm->file != NULL) + sflush(pdev->strm); + if (pdev->asides.strm->file != NULL) + sflush(pdev->asides.strm); + if (pdev->streams.strm->file != NULL) + sflush(pdev->streams.strm); + if (pdev->pictures.strm->file != NULL) + sflush(pdev->pictures.strm); return gp_ferror(pdev->file) || gp_ferror(pdev->xref.file) || gp_ferror(pdev->asides.file) || gp_ferror(pdev->streams.file) || gp_ferror(pdev->pictures.file); @@ -1139,13 +1145,14 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) pdf_page_t *page; double mediabox[4] = {0, 0}; stream *s; - const cos_value_t *v_mediabox; + const cos_value_t *v_mediabox = NULL; if (pdev->pages == NULL) return_error(gs_error_undefined); page = &pdev->pages[page_num - 1]; - v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox"); + if (page->Page != NULL) + v_mediabox = cos_dict_find_c_key(page->Page, "/MediaBox"); page_id = pdf_page_id(pdev, page_num); /* If we have not been given a MediaBox overriding pdfmark, use the current media size. */ @@ -1170,7 +1177,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) buf[l] = 0; if (sscanf(buf, "[ %g %g %g %g ]", &temp[0], &temp[1], &temp[2], &temp[3]) == 4) { - cos_dict_delete_c_key(page->Page, "/MediaBox"); + if (page->Page) + cos_dict_delete_c_key(page->Page, "/MediaBox"); } pprintg4(s, "<</Type/Page/MediaBox [%g %g %g %g]\n", temp[0], temp[1], temp[2], temp[3]); @@ -1178,13 +1186,20 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) mediabox[i] = temp[i]; } if (pdev->PDFX) { - const cos_value_t *v_trimbox = cos_dict_find_c_key(page->Page, "/TrimBox"); - const cos_value_t *v_artbox = cos_dict_find_c_key(page->Page, "/ArtBox"); - const cos_value_t *v_cropbox = cos_dict_find_c_key(page->Page, "/CropBox"); - const cos_value_t *v_bleedbox = cos_dict_find_c_key(page->Page, "/BleedBox"); - double trimbox[4] = {0, 0}, bleedbox[4] = {0, 0}; + const cos_value_t *v_trimbox = NULL; + const cos_value_t *v_artbox = NULL; + const cos_value_t *v_cropbox = NULL; + const cos_value_t *v_bleedbox = NULL; + float trimbox[4] = {0, 0}, bleedbox[4] = {0, 0}; bool print_bleedbox = false; + if (page->Page != NULL) { + v_trimbox = cos_dict_find_c_key(page->Page, "/TrimBox"); + v_artbox = cos_dict_find_c_key(page->Page, "/ArtBox"); + v_cropbox = cos_dict_find_c_key(page->Page, "/CropBox"); + v_bleedbox = cos_dict_find_c_key(page->Page, "/BleedBox"); + } + trimbox[2] = bleedbox[2] = mediabox[2]; trimbox[3] = bleedbox[3] = mediabox[3]; /* Offsets are [left right top bottom] according to the Acrobat 7.0 @@ -1203,9 +1218,10 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) trimbox[1] = temp[1]; trimbox[2] = temp[2]; trimbox[3] = temp[3]; - cos_dict_delete_c_key(page->Page, "/TrimBox"); + if (page->Page != NULL) + cos_dict_delete_c_key(page->Page, "/TrimBox"); } - if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR) + if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR && page->Page != NULL) cos_dict_delete_c_key(page->Page, "/ArtBox"); } else if (v_artbox != NULL && v_artbox->value_type == COS_VALUE_SCALAR) { @@ -1225,7 +1241,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) trimbox[1] = temp[1]; trimbox[2] = temp[2]; trimbox[3] = temp[3]; - cos_dict_delete_c_key(page->Page, "/ArtBox"); + if (page->Page != NULL) + cos_dict_delete_c_key(page->Page, "/ArtBox"); } } else { if (pdev->PDFXTrimBoxToMediaBoxOffset.size >= 4 && @@ -1267,7 +1284,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) else bleedbox[3] = temp[3]; print_bleedbox = true; - cos_dict_delete_c_key(page->Page, "/BleedBox"); + if (page->Page != NULL) + cos_dict_delete_c_key(page->Page, "/BleedBox"); } } else if (pdev->PDFXSetBleedBoxToMediaBox) print_bleedbox = true; @@ -1330,7 +1348,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) buf[l] = 0; if (sscanf(buf, "[ %g %g %g %g ]", &temp[0], &temp[1], &temp[2], &temp[3]) == 4) { - cos_dict_delete_c_key(page->Page, "/CropBox"); + if (page->Page != NULL) + cos_dict_delete_c_key(page->Page, "/CropBox"); /* Ensure that CropBox is no larger than MediaBox. The spec says *nothing* about * this, but Acrobat Preflight complains if it is larger. This can happen because * we apply 'round_box_coord' to the mediabox at the start of this rouinte. @@ -1386,14 +1405,16 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) } } - if (cos_dict_find_c_key(page->Page, "/TrimBox") == NULL && - cos_dict_find_c_key(page->Page, "/ArtBox") == NULL) - pprintg4(s, "/TrimBox [%g %g %g %g]\n", - trimbox[0], trimbox[1], trimbox[2], trimbox[3]); - if (print_bleedbox && - cos_dict_find_c_key(page->Page, "/BleedBox") == NULL) - pprintg4(s, "/BleedBox [%g %g %g %g]\n", - bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]); + if (page->Page != NULL) { + if (cos_dict_find_c_key(page->Page, "/TrimBox") == NULL && + cos_dict_find_c_key(page->Page, "/ArtBox") == NULL) + pprintg4(s, "/TrimBox [%g %g %g %g]\n", + trimbox[0], trimbox[1], trimbox[2], trimbox[3]); + if (print_bleedbox && + cos_dict_find_c_key(page->Page, "/BleedBox") == NULL) + pprintg4(s, "/BleedBox [%g %g %g %g]\n", + bleedbox[0], bleedbox[1], bleedbox[2], bleedbox[3]); + } } pdf_print_orientation(pdev, page); if (page->UserUnit != 1) @@ -1480,7 +1501,8 @@ pdf_write_page(gx_device_pdf *pdev, int page_num) /* Write any elements stored by pdfmarks. */ - cos_dict_elements_write(page->Page, pdev); + if (page->Page != NULL) + cos_dict_elements_write(page->Page, pdev); stream_puts(s, ">>\n"); pdf_end_obj(pdev, resourcePage); @@ -1906,7 +1928,11 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params * +1 for the linearisation dict and +1 for the primary hint stream. */ linear_params->FirsttrailerOffset = gp_ftell(linear_params->Lin_File.file); - gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n", + if (pdev->OmitID) + gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n", + linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, 0); + else + gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %d>>\nstartxref\r\n0\n%%%%EOF\n \n", linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, 0); gp_fwrite(LDict, strlen(LDict), 1, linear_params->Lin_File.file); @@ -2442,7 +2468,11 @@ static int pdf_linearise(gx_device_pdf *pdev, pdf_linearisation_t *linear_params if (code != 0) return_error(gs_error_ioerror); - gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n", + if (pdev->OmitID) + gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n", + linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, mainxref); + else + gs_snprintf(LDict, sizeof(LDict), "\ntrailer\n<</Size %ld/Info %d 0 R/Root %d 0 R/ID[%s%s]/Prev %"PRId64">>\nstartxref\r\n0\n%%%%EOF\n", linear_params->LastResource + 3, pdev->ResourceUsage[linear_params->Info_id].NewObjectNumber, pdev->ResourceUsage[linear_params->Catalog_id].NewObjectNumber, fileID, fileID, mainxref); gp_fwrite(LDict, strlen(LDict), 1, linear_params->sfile); @@ -2871,10 +2901,12 @@ pdf_close(gx_device * dev) COS_WRITE_OBJECT(pdev->PageLabels, pdev, resourceLabels); } - /* Write the document metadata. */ - code1 = pdf_document_metadata(pdev); - if (code >= 0) - code = code1; + if (!pdev->OmitXMP) { + /* Write the document metadata. */ + code1 = pdf_document_metadata(pdev); + if (code >= 0) + code = code1; + } /* Write the Catalog. */ @@ -3136,10 +3168,12 @@ pdf_close(gx_device * dev) stream_puts(s, "trailer\n"); pprintld3(s, "<< /Size %ld /Root %ld 0 R /Info %ld 0 R\n", pdev->next_id, Catalog_id, Info_id); - stream_puts(s, "/ID ["); - psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0); - psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0); - stream_puts(s, "]\n"); + if (!pdev->OmitID) { + stream_puts(s, "/ID ["); + psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0); + psdf_write_string(pdev->strm, pdev->fileID, sizeof(pdev->fileID), 0); + stream_puts(s, "]\n"); + } if (pdev->OwnerPassword.size > 0) { pprintld1(s, "/Encrypt %ld 0 R ", Encrypt_id); } @@ -3429,6 +3463,27 @@ error_cleanup: } } + /* Free named objects. */ + + if (pdev->NI_stack != NULL) { + cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack"); + gs_free_object(mem, pdev->NI_stack, "Free Name Index stack"); + pdev->NI_stack = 0; + } + + if (pdev->local_named_objects != NULL) { + cos_dict_objects_delete(pdev->local_named_objects); + COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)"); + pdev->local_named_objects = 0; + } + + if (pdev->global_named_objects != NULL) { + /* global resources include the Catalog object and apparently the Info dict */ + cos_dict_objects_delete(pdev->global_named_objects); + COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)"); + pdev->global_named_objects = 0; + } + code1 = pdf_free_resource_objects(pdev, resourceOther); if (code >= 0) code = code1; @@ -3477,27 +3532,6 @@ error_cleanup: pdev->last_resource = 0; } - /* Free named objects. */ - - if (pdev->NI_stack != NULL) { - cos_release((cos_object_t *)pdev->NI_stack, "Release Name Index stack"); - gs_free_object(mem, pdev->NI_stack, "Free Name Index stack"); - pdev->NI_stack = 0; - } - - if (pdev->local_named_objects != NULL) { - cos_dict_objects_delete(pdev->local_named_objects); - COS_FREE(pdev->local_named_objects, "pdf_close(local_named_objects)"); - pdev->local_named_objects = 0; - } - - if (pdev->global_named_objects != NULL) { - /* global resources include the Catalog object and apparently the Info dict */ - cos_dict_objects_delete(pdev->global_named_objects); - COS_FREE(pdev->global_named_objects, "pdf_close(global_named_objects)"); - pdev->global_named_objects = 0; - } - /* Wrap up. */ pdev->font_cache = 0; @@ -3517,7 +3551,7 @@ error_cleanup: for (i=0;i < pdev->num_pages;i++) { if (pdev->pages[i].Page != NULL) { emprintf(pdev->memory, - "Page object was reserved for an Annotation destinatio, but no such page was drawn, annotation in output will be invalid.\n"); + "Page object was reserved for an Annotation destination, but no such page was drawn, annotation in output will be invalid.\n"); gs_free_object(mem, pdev->pages[i].Page, "Free Page object"); pdev->pages[i].Page = NULL; } |