summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'devices/vector/gdevpdf.c')
-rw-r--r--devices/vector/gdevpdf.c150
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;
}