pdf: convert all document interchange features to use object streams

This commit is contained in:
Adrian Johnson 2021-07-18 07:54:30 +09:30
parent bd514f6b08
commit 90193cc3a2
2 changed files with 186 additions and 136 deletions

View file

@ -228,34 +228,36 @@ cairo_pdf_interchange_write_node_object (cairo_pdf_surface_t *surface
int i, num_mcid, first_page;
cairo_pdf_resource_t *page_res;
cairo_pdf_struct_tree_node_t *child;
cairo_int_status_t status;
_cairo_pdf_surface_update_object (surface, node->res);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, node->res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /StructElem\n"
" /S /%s\n"
" /P %d 0 R\n",
node->res.id,
node->name,
node->parent->res.id);
if (! cairo_list_is_empty (&node->children)) {
if (cairo_list_is_singular (&node->children) && node->annot_res.id == 0) {
child = cairo_list_first_entry (&node->children, cairo_pdf_struct_tree_node_t, link);
_cairo_output_stream_printf (surface->output, " /K %d 0 R\n", child->res.id);
_cairo_output_stream_printf (surface->object_stream.stream, " /K %d 0 R\n", child->res.id);
} else {
_cairo_output_stream_printf (surface->output, " /K [ ");
_cairo_output_stream_printf (surface->object_stream.stream, " /K [ ");
if (node->annot_res.id != 0) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /OBJR /Obj %d 0 R >> ",
node->annot_res.id);
}
cairo_list_foreach_entry (child, cairo_pdf_struct_tree_node_t,
&node->children, link)
{
_cairo_output_stream_printf (surface->output, "%d 0 R ", child->res.id);
_cairo_output_stream_printf (surface->object_stream.stream, "%d 0 R ", child->res.id);
}
_cairo_output_stream_printf (surface->output, "]\n");
_cairo_output_stream_printf (surface->object_stream.stream, "]\n");
}
} else {
num_mcid = _cairo_array_num_elements (&node->mcid);
@ -263,14 +265,14 @@ cairo_pdf_interchange_write_node_object (cairo_pdf_surface_t *surface
mcid_elem = _cairo_array_index (&node->mcid, 0);
first_page = mcid_elem->page;
page_res = _cairo_array_index (&surface->pages, first_page - 1);
_cairo_output_stream_printf (surface->output, " /Pg %d 0 R\n", page_res->id);
_cairo_output_stream_printf (surface->object_stream.stream, " /Pg %d 0 R\n", page_res->id);
if (num_mcid == 1 && node->annot_res.id == 0) {
_cairo_output_stream_printf (surface->output, " /K %d\n", mcid_elem->mcid);
_cairo_output_stream_printf (surface->object_stream.stream, " /K %d\n", mcid_elem->mcid);
} else {
_cairo_output_stream_printf (surface->output, " /K [ ");
_cairo_output_stream_printf (surface->object_stream.stream, " /K [ ");
if (node->annot_res.id != 0) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /OBJR /Obj %d 0 R >> ",
node->annot_res.id);
}
@ -278,23 +280,24 @@ cairo_pdf_interchange_write_node_object (cairo_pdf_surface_t *surface
mcid_elem = _cairo_array_index (&node->mcid, i);
page_res = _cairo_array_index (&surface->pages, mcid_elem->page - 1);
if (mcid_elem->page == first_page) {
_cairo_output_stream_printf (surface->output, "%d ", mcid_elem->mcid);
_cairo_output_stream_printf (surface->object_stream.stream, "%d ", mcid_elem->mcid);
} else {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"\n << /Type /MCR /Pg %d 0 R /MCID %d >> ",
page_res->id,
mcid_elem->mcid);
}
}
_cairo_output_stream_printf (surface->output, "]\n");
_cairo_output_stream_printf (surface->object_stream.stream, "]\n");
}
}
}
_cairo_output_stream_printf (surface->output,
">>\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
">>\n");
return _cairo_output_stream_get_status (surface->output);
_cairo_pdf_surface_object_end (surface);
return _cairo_output_stream_get_status (surface->object_stream.stream);
}
static void
@ -338,13 +341,13 @@ cairo_pdf_interchange_write_explicit_dest (cairo_pdf_surface_t *surface,
_cairo_array_copy_element (&surface->page_heights, page - 1, &height);
_cairo_array_copy_element (&surface->pages, page - 1, &res);
if (has_pos) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"[%d 0 R /XYZ %f %f 0]\n",
res.id,
x,
height - y);
} else {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"[%d 0 R /XYZ null null 0]\n",
res.id);
}
@ -387,7 +390,7 @@ cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
if (named_dest->attrs.y_valid)
y = named_dest->attrs.y;
_cairo_output_stream_printf (surface->output, " /Dest ");
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
status = cairo_pdf_interchange_write_explicit_dest (surface,
named_dest->page,
TRUE,
@ -401,7 +404,7 @@ cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /Dest %s\n",
dest);
free (dest);
@ -410,7 +413,7 @@ cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
return CAIRO_INT_STATUS_TAG_ERROR;
if (link_attrs->page <= (int)_cairo_array_num_elements (&surface->pages)) {
_cairo_output_stream_printf (surface->output, " /Dest ");
_cairo_output_stream_printf (surface->object_stream.stream, " /Dest ");
status = cairo_pdf_interchange_write_explicit_dest (surface,
link_attrs->page,
link_attrs->has_pos,
@ -428,7 +431,7 @@ cairo_pdf_interchange_write_dest (cairo_pdf_surface_t *surface,
if (link_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /Dest %d 0 R\n",
link_res.id);
@ -456,7 +459,7 @@ cairo_pdf_interchange_write_link_action (cairo_pdf_surface_t *surface,
return status;
} else if (link_attrs->link_type == TAG_LINK_URI) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /A <<\n"
" /Type /Action\n"
" /S /URI\n"
@ -464,7 +467,7 @@ cairo_pdf_interchange_write_link_action (cairo_pdf_surface_t *surface,
" >>\n",
link_attrs->uri);
} else if (link_attrs->link_type == TAG_LINK_FILE) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /A <<\n"
" /Type /Action\n"
" /S /GoToR\n"
@ -475,24 +478,24 @@ cairo_pdf_interchange_write_link_action (cairo_pdf_surface_t *surface,
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /D %s\n",
dest);
free (dest);
} else {
if (link_attrs->has_pos) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /D [%d %f %f 0]\n",
link_attrs->page,
link_attrs->pos.x,
link_attrs->pos.y);
} else {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /D [%d null null 0]\n",
link_attrs->page);
}
}
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" >>\n");
}
@ -522,25 +525,28 @@ cairo_pdf_interchange_write_annot (cairo_pdf_surface_t *surface,
sp = _cairo_array_num_elements (&ic->parent_tree) - 1;
node->annot_res = _cairo_pdf_surface_new_object (surface);
if (node->annot_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_array_append (&surface->page_annots, &node->annot_res);
if (unlikely (status))
return status;
_cairo_pdf_surface_update_object (surface, node->annot_res);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, node->annot_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /Annot\n"
" /Subtype /Link\n"
" /StructParent %d\n",
node->annot_res.id,
sp);
height = surface->height;
if (num_rects > 0) {
cairo_rectangle_int_t bbox_rect;
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /QuadPoints [ ");
for (i = 0; i < num_rects; i++) {
cairo_rectangle_t rectf;
@ -553,31 +559,31 @@ cairo_pdf_interchange_write_annot (cairo_pdf_surface_t *surface,
else
_cairo_rectangle_union (&bbox_rect, &recti);
write_rect_to_pdf_quad_points (surface->output, &rectf, height);
_cairo_output_stream_printf (surface->output, " ");
write_rect_to_pdf_quad_points (surface->object_stream.stream, &rectf, height);
_cairo_output_stream_printf (surface->object_stream.stream, " ");
}
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
"]\n"
" /Rect [ ");
write_rect_int_to_pdf_bbox (surface->output, &bbox_rect, height);
_cairo_output_stream_printf (surface->output, " ]\n");
write_rect_int_to_pdf_bbox (surface->object_stream.stream, &bbox_rect, height);
_cairo_output_stream_printf (surface->object_stream.stream, " ]\n");
} else {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /Rect [ ");
write_rect_int_to_pdf_bbox (surface->output, &node->extents.extents, height);
_cairo_output_stream_printf (surface->output, " ]\n");
write_rect_int_to_pdf_bbox (surface->object_stream.stream, &node->extents.extents, height);
_cairo_output_stream_printf (surface->object_stream.stream, " ]\n");
}
status = cairo_pdf_interchange_write_link_action (surface, &annot->link_attrs);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /BS << /W 0 >>"
">>\n"
"endobj\n");
">>\n");
status = _cairo_output_stream_get_status (surface->output);
_cairo_pdf_surface_object_end (surface);
status = _cairo_output_stream_get_status (surface->object_stream.stream);
}
return status;
@ -614,41 +620,47 @@ cairo_pdf_interchange_write_struct_tree (cairo_pdf_surface_t *surface)
{
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_pdf_struct_tree_node_t *child;
cairo_int_status_t status;
if (cairo_list_is_empty (&ic->struct_root->children))
return CAIRO_STATUS_SUCCESS;
surface->struct_tree_root = _cairo_pdf_surface_new_object (surface);
if (surface->struct_tree_root.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
ic->struct_root->res = surface->struct_tree_root;
cairo_pdf_interchange_walk_struct_tree (surface, ic->struct_root, cairo_pdf_interchange_write_node_object);
child = cairo_list_first_entry (&ic->struct_root->children, cairo_pdf_struct_tree_node_t, link);
_cairo_pdf_surface_update_object (surface, surface->struct_tree_root);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, surface->struct_tree_root);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /StructTreeRoot\n"
" /ParentTree %d 0 R\n",
surface->struct_tree_root.id,
ic->parent_tree_res.id);
if (cairo_list_is_singular (&ic->struct_root->children)) {
child = cairo_list_first_entry (&ic->struct_root->children, cairo_pdf_struct_tree_node_t, link);
_cairo_output_stream_printf (surface->output, " /K [ %d 0 R ]\n", child->res.id);
_cairo_output_stream_printf (surface->object_stream.stream, " /K [ %d 0 R ]\n", child->res.id);
} else {
_cairo_output_stream_printf (surface->output, " /K [ ");
_cairo_output_stream_printf (surface->object_stream.stream, " /K [ ");
cairo_list_foreach_entry (child, cairo_pdf_struct_tree_node_t,
&ic->struct_root->children, link)
{
_cairo_output_stream_printf (surface->output, "%d 0 R ", child->res.id);
_cairo_output_stream_printf (surface->object_stream.stream, "%d 0 R ", child->res.id);
}
_cairo_output_stream_printf (surface->output, "]\n");
_cairo_output_stream_printf (surface->object_stream.stream, "]\n");
}
_cairo_output_stream_printf (surface->output,
">>\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
">>\n");
_cairo_pdf_surface_object_end (surface);
return CAIRO_STATUS_SUCCESS;
}
@ -686,17 +698,23 @@ cairo_pdf_interchange_write_page_parent_elems (cairo_pdf_surface_t *surface)
num_elems = _cairo_array_num_elements (&ic->mcid_to_tree);
if (num_elems > 0) {
res = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"[\n",
res.id);
if (res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_object_begin (surface, res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"[\n");
for (i = 0; i < num_elems; i++) {
_cairo_array_copy_element (&ic->mcid_to_tree, i, &node);
_cairo_output_stream_printf (surface->output, " %d 0 R\n", node->res.id);
_cairo_output_stream_printf (surface->object_stream.stream, " %d 0 R\n", node->res.id);
}
_cairo_output_stream_printf (surface->output,
"]\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
"]\n");
_cairo_pdf_surface_object_end (surface);
status = _cairo_array_append (&ic->parent_tree, &res);
surface->page_parent_tree = _cairo_array_num_elements (&ic->parent_tree) - 1;
}
@ -710,27 +728,33 @@ cairo_pdf_interchange_write_parent_tree (cairo_pdf_surface_t *surface)
int num_elems, i;
cairo_pdf_resource_t *res;
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_int_status_t status;
num_elems = _cairo_array_num_elements (&ic->parent_tree);
if (num_elems > 0) {
ic->parent_tree_res = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"<< /Nums [\n",
ic->parent_tree_res.id);
if (ic->parent_tree_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_object_begin (surface, ic->parent_tree_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Nums [\n");
for (i = 0; i < num_elems; i++) {
res = _cairo_array_index (&ic->parent_tree, i);
if (res->id) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" %d %d 0 R\n",
i,
res->id);
}
}
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" ]\n"
">>\n"
"endobj\n");
">>\n");
_cairo_pdf_surface_object_end (surface);
}
return CAIRO_STATUS_SUCCESS;
@ -751,19 +775,24 @@ cairo_pdf_interchange_write_outline (cairo_pdf_surface_t *surface)
_cairo_array_copy_element (&ic->outline, 0, &outline);
outline->res = _cairo_pdf_surface_new_object (surface);
if (outline->res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
surface->outlines_dict_res = outline->res;
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, outline->res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Type /Outlines\n"
" /First %d 0 R\n"
" /Last %d 0 R\n"
" /Count %d\n"
">>\n"
"endobj\n",
outline->res.id,
">>\n",
outline->first_child->res.id,
outline->last_child->res.id,
outline->count);
_cairo_pdf_surface_object_end (surface);
for (i = 1; i < num_elems; i++) {
_cairo_array_copy_element (&ic->outline, i, &outline);
@ -773,29 +802,31 @@ cairo_pdf_interchange_write_outline (cairo_pdf_surface_t *surface)
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, outline->res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Title %s\n"
" /Parent %d 0 R\n",
outline->res.id,
name,
outline->parent->res.id);
free (name);
if (outline->prev) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /Prev %d 0 R\n",
outline->prev->res.id);
}
if (outline->next) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /Next %d 0 R\n",
outline->next->res.id);
}
if (outline->first_child) {
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /First %d 0 R\n"
" /Last %d 0 R\n"
" /Count %d\n",
@ -810,7 +841,7 @@ cairo_pdf_interchange_write_outline (cairo_pdf_surface_t *surface)
flags |= 1;
if (outline->flags & CAIRO_PDF_OUTLINE_FLAG_BOLD)
flags |= 2;
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" /F %d\n",
flags);
}
@ -819,9 +850,9 @@ cairo_pdf_interchange_write_outline (cairo_pdf_surface_t *surface)
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output,
">>\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
">>\n");
_cairo_pdf_surface_object_end (surface);
}
return status;
@ -887,6 +918,7 @@ cairo_pdf_interchange_write_forward_links (cairo_pdf_surface_t *surface)
{
int num_elems, i;
cairo_pdf_forward_link_t *link;
cairo_int_status_t status;
num_elems = _cairo_array_num_elements (&surface->forward_links);
for (i = 0; i < num_elems; i++) {
@ -894,10 +926,9 @@ cairo_pdf_interchange_write_forward_links (cairo_pdf_surface_t *surface)
if (link->page > (int)_cairo_array_num_elements (&surface->pages))
return CAIRO_INT_STATUS_TAG_ERROR;
_cairo_pdf_surface_update_object (surface, link->res);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n",
link->res.id);
status = _cairo_pdf_surface_object_begin (surface, link->res);
if (unlikely (status))
return status;
cairo_pdf_interchange_write_explicit_dest (surface,
link->page,
@ -905,8 +936,7 @@ cairo_pdf_interchange_write_forward_links (cairo_pdf_surface_t *surface)
link->pos.x,
link->pos.y);
_cairo_output_stream_printf (surface->output,
"endobj\n");
_cairo_pdf_surface_object_end (surface);
}
return CAIRO_STATUS_SUCCESS;
@ -938,10 +968,15 @@ cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
return CAIRO_STATUS_SUCCESS;
surface->page_labels_res = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"<< /Nums [\n",
surface->page_labels_res.id);
if (surface->page_labels_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_object_begin (surface, surface->page_labels_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Nums [\n");
prefix = NULL;
prev_prefix = NULL;
num = 0;
@ -956,10 +991,10 @@ cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
}
if (!strcmp_null (prefix, prev_prefix) || num != prev_num + 1) {
_cairo_output_stream_printf (surface->output, " %d << ", i);
_cairo_output_stream_printf (surface->object_stream.stream, " %d << ", i);
if (num)
_cairo_output_stream_printf (surface->output, "/S /D /St %d ", num);
_cairo_output_stream_printf (surface->object_stream.stream, "/S /D /St %d ", num);
if (prefix) {
char *s;
@ -967,11 +1002,11 @@ cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->output, "/P %s ", s);
_cairo_output_stream_printf (surface->object_stream.stream, "/P %s ", s);
free (s);
}
_cairo_output_stream_printf (surface->output, ">>\n");
_cairo_output_stream_printf (surface->object_stream.stream, ">>\n");
}
free (prev_prefix);
prev_prefix = prefix;
@ -980,10 +1015,10 @@ cairo_pdf_interchange_write_page_labels (cairo_pdf_surface_t *surface)
}
free (prefix);
free (prev_prefix);
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" ]\n"
">>\n"
"endobj\n");
">>\n");
_cairo_pdf_surface_object_end (surface);
return CAIRO_STATUS_SUCCESS;
}
@ -1012,6 +1047,7 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
{
int i;
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_int_status_t status;
if (ic->num_dests == 0) {
ic->dests_res.id = 0;
@ -1027,10 +1063,15 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
qsort (ic->sorted_dests, ic->num_dests, sizeof (cairo_pdf_named_dest_t *), _dest_compare);
ic->dests_res = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"<< /Names [\n",
ic->dests_res.id);
if (ic->dests_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_object_begin (surface, ic->dests_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Names [\n");
for (i = 0; i < ic->num_dests; i++) {
cairo_pdf_named_dest_t *dest = ic->sorted_dests[i];
cairo_pdf_resource_t page_res;
@ -1054,17 +1095,17 @@ _cairo_pdf_interchange_write_document_dests (cairo_pdf_surface_t *surface)
_cairo_array_copy_element (&surface->pages, dest->page - 1, &page_res);
_cairo_array_copy_element (&surface->page_heights, dest->page - 1, &height);
_cairo_output_stream_printf (surface->output,
_cairo_output_stream_printf (surface->object_stream.stream,
" (%s) [%d 0 R /XYZ %f %f 0]\n",
dest->attrs.name,
page_res.id,
x,
height - y);
}
_cairo_output_stream_printf (surface->output,
" ]\n"
">>\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
" ]\n"
">>\n");
_cairo_pdf_surface_object_end (surface);
return CAIRO_STATUS_SUCCESS;
}
@ -1082,12 +1123,17 @@ cairo_pdf_interchange_write_names_dict (cairo_pdf_surface_t *surface)
surface->names_dict_res.id = 0;
if (ic->dests_res.id != 0) {
surface->names_dict_res = _cairo_pdf_surface_new_object (surface);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
"<< /Dests %d 0 R >>\n"
"endobj\n",
surface->names_dict_res.id,
if (surface->names_dict_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
status = _cairo_pdf_surface_object_begin (surface, surface->names_dict_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Dests %d 0 R >>\n",
ic->dests_res.id);
_cairo_pdf_surface_object_end (surface);
}
return CAIRO_STATUS_SUCCESS;
@ -1097,41 +1143,44 @@ static cairo_int_status_t
cairo_pdf_interchange_write_docinfo (cairo_pdf_surface_t *surface)
{
cairo_pdf_interchange_t *ic = &surface->interchange;
cairo_int_status_t status;
surface->docinfo_res = _cairo_pdf_surface_new_object (surface);
if (surface->docinfo_res.id == 0)
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n"
status = _cairo_pdf_surface_object_begin (surface, surface->docinfo_res);
if (unlikely (status))
return status;
_cairo_output_stream_printf (surface->object_stream.stream,
"<< /Producer (cairo %s (https://cairographics.org))\n",
surface->docinfo_res.id,
cairo_version_string ());
if (ic->docinfo.title)
_cairo_output_stream_printf (surface->output, " /Title %s\n", ic->docinfo.title);
_cairo_output_stream_printf (surface->object_stream.stream, " /Title %s\n", ic->docinfo.title);
if (ic->docinfo.author)
_cairo_output_stream_printf (surface->output, " /Author %s\n", ic->docinfo.author);
_cairo_output_stream_printf (surface->object_stream.stream, " /Author %s\n", ic->docinfo.author);
if (ic->docinfo.subject)
_cairo_output_stream_printf (surface->output, " /Subject %s\n", ic->docinfo.subject);
_cairo_output_stream_printf (surface->object_stream.stream, " /Subject %s\n", ic->docinfo.subject);
if (ic->docinfo.keywords)
_cairo_output_stream_printf (surface->output, " /Keywords %s\n", ic->docinfo.keywords);
_cairo_output_stream_printf (surface->object_stream.stream, " /Keywords %s\n", ic->docinfo.keywords);
if (ic->docinfo.creator)
_cairo_output_stream_printf (surface->output, " /Creator %s\n", ic->docinfo.creator);
_cairo_output_stream_printf (surface->object_stream.stream, " /Creator %s\n", ic->docinfo.creator);
if (ic->docinfo.create_date)
_cairo_output_stream_printf (surface->output, " /CreationDate %s\n", ic->docinfo.create_date);
_cairo_output_stream_printf (surface->object_stream.stream, " /CreationDate %s\n", ic->docinfo.create_date);
if (ic->docinfo.mod_date)
_cairo_output_stream_printf (surface->output, " /ModDate %s\n", ic->docinfo.mod_date);
_cairo_output_stream_printf (surface->object_stream.stream, " /ModDate %s\n", ic->docinfo.mod_date);
_cairo_output_stream_printf (surface->output,
">>\n"
"endobj\n");
_cairo_output_stream_printf (surface->object_stream.stream,
">>\n");
_cairo_pdf_surface_object_end (surface);
return CAIRO_STATUS_SUCCESS;
}

View file

@ -2170,6 +2170,7 @@ _cairo_pdf_surface_object_begin (cairo_pdf_surface_t *surface,
object->u.compressed_obj.index = _cairo_array_num_elements (&surface->object_stream.objects) - 1;
} else {
_cairo_pdf_surface_update_object (surface, resource);
_cairo_output_stream_printf (surface->output,
"%d 0 obj\n",
resource.id);
@ -6886,7 +6887,7 @@ _cairo_pdf_surface_write_xref_stream (cairo_pdf_surface_t *surface,
if (!surface->compress_streams) {
/* Adobe Reader requires xref streams to be flate encoded (PDF
* Reference 1.7, implemenation note 20). This means
* Reference 1.7, implementation note 20). This means
* compression must always be enabled on this stream. To
* facilitate debugging when compress_stream is disabled, emit
* a human readable format of the xref stream as PDF comments.