diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2023-02-19 21:10:58 +1030 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2023-04-18 18:27:12 +0930 |
commit | b53b48116e610d61cdf630c24a11b59a18345e16 (patch) | |
tree | 3bc8f3410e795ce81c1408b9d7f3a217033d29ba /src/cairo-pdf-surface-private.h | |
parent | e7ed40a71dac04cb4c608b409b04577d01f08454 (diff) | |
download | cairo-b53b48116e610d61cdf630c24a11b59a18345e16.tar.gz |
Make cairo_tag_begin/end work correctly in groups
Fixes #508
Diffstat (limited to 'src/cairo-pdf-surface-private.h')
-rw-r--r-- | src/cairo-pdf-surface-private.h | 199 |
1 files changed, 175 insertions, 24 deletions
diff --git a/src/cairo-pdf-surface-private.h b/src/cairo-pdf-surface-private.h index c97affe6b..13ccc5001 100644 --- a/src/cairo-pdf-surface-private.h +++ b/src/cairo-pdf-surface-private.h @@ -74,6 +74,10 @@ typedef struct _cairo_pdf_source_surface_entry { unsigned char *unique_id; unsigned long unique_id_length; cairo_operator_t operator; + + /* If not 0, this is the recording surface region id of the source surface. */ + int region_id; + cairo_bool_t interpolate; cairo_bool_t stencil_mask; cairo_bool_t smask; @@ -110,6 +114,9 @@ typedef struct _cairo_pdf_pattern { cairo_operator_t operator; cairo_bool_t is_shading; + /* Index into nodes array in cairo_pdf_surface_node_entry_t or -1 if not used */ + int region_id; + /* PDF pattern space is the pattern matrix concatenated with the * initial space of the parent object. If the parent object is the * page, the initial space does not include the Y-axis flipping @@ -161,38 +168,87 @@ typedef struct _cairo_pdf_jbig2_global { cairo_bool_t emitted; } cairo_pdf_jbig2_global_t; -/* cairo-pdf-interchange.c types */ +typedef struct _cairo_pdf_page_info { + double width; + double height; + cairo_pdf_resource_t page_res; + cairo_pdf_resource_t content; + cairo_pdf_resource_t resources; + cairo_pdf_resource_t thumbnail; + cairo_array_t annots; /* <cairo_pdf_resource_t> */ + int struct_parents; +} cairo_pdf_page_info_t; -struct page_mcid { - int page; - int mcid; -}; -struct tag_extents { +/* cairo-pdf-interchange.c types */ + +typedef struct _pdf_tag_extents { cairo_rectangle_int_t extents; cairo_bool_t valid; - cairo_list_t link; -}; +} cairo_pdf_tag_extents_t; + +typedef struct _pdf_page_mcid { + int order; + int page; + cairo_pdf_resource_t xobject_res; /* 0 if not in an XObject */ + int mcid; + struct _cairo_pdf_struct_tree_node *child_node; +} cairo_pdf_page_mcid_t; + +/* The non PDF_NODE_STRUCT types are excluded from the struct tree embedded in + * the PDF. */ +typedef enum _cairo_pdf_tree_node_type { + PDF_NODE_STRUCT, + PDF_NODE_CONTENT, + PDF_NODE_CONTENT_REF, + PDF_NODE_ARTIFACT, +} cairo_pdf_tree_node_type_t; typedef struct _cairo_pdf_struct_tree_node { + cairo_hash_entry_t hash; + cairo_pdf_tree_node_type_t type; char *name; cairo_pdf_resource_t res; struct _cairo_pdf_struct_tree_node *parent; cairo_list_t children; - cairo_array_t mcid; /* array of struct page_mcid */ - cairo_pdf_resource_t annot_res; /* 0 if no annot */ - struct tag_extents extents; - cairo_list_t link; + cairo_array_t mcid; /* array of cairo_pdf_page_mcid_t */ + struct _cairo_pdf_annotation *annot; + cairo_pdf_tag_extents_t extents; + + union { + cairo_content_attrs_t content; /* type == PDF_NODE_CONTENT */ + cairo_content_ref_attrs_t content_ref; /* type == PDF_NODE_CONTENT_REF */ + } attributes; + + cairo_list_t link; /* linked list of parent's children */ } cairo_pdf_struct_tree_node_t; +typedef struct _cairo_pdf_command_entry { + cairo_hash_entry_t base; + unsigned int recording_id; + unsigned int command_id; + cairo_pdf_struct_tree_node_t *node; +} cairo_pdf_command_entry_t; + +typedef struct _cairo_recording_surface_stack_entry { + cairo_bool_t ignore_surface; + cairo_pdf_struct_tree_node_t *current_node; +} cairo_recording_surface_stack_entry_t; + +typedef struct _cairo_pdf_content_tag { + cairo_hash_entry_t base; + cairo_pdf_struct_tree_node_t *node; +} cairo_pdf_content_tag_t; + typedef struct _cairo_pdf_annotation { cairo_pdf_struct_tree_node_t *node; /* node containing the annotation */ cairo_link_attrs_t link_attrs; + cairo_pdf_resource_t res; } cairo_pdf_annotation_t; typedef struct _cairo_pdf_named_dest { cairo_hash_entry_t base; - struct tag_extents extents; + cairo_pdf_tag_extents_t extents; cairo_dest_attrs_t attrs; int page; } cairo_pdf_named_dest_t; @@ -233,19 +289,65 @@ struct metadata { char *value; }; +typedef enum _cairo_pdf_operation_flags_t { + PDF_NONE = 0, + PDF_CONTENT, + PDF_BEGIN, + PDF_END, + PDF_GROUP, +} cairo_pdf_operation_flags_t; + +typedef struct _pdf_command_list { + cairo_array_t commands; + struct _pdf_command_list *parent; +} cairo_pdf_command_list_t; + +typedef struct _pdf_operation { + cairo_pdf_command_list_t *group; + cairo_pdf_struct_tree_node_t *node; + unsigned int command_id; + int mcid_index; + cairo_pdf_operation_flags_t flags; +} cairo_pdf_command_t; + +typedef struct _pdf_recording_surface_commands { + cairo_surface_t *recording_surface; + cairo_pdf_command_list_t *command_list; + unsigned int region_id; +} cairo_pdf_recording_surface_commands_t; + typedef struct _cairo_pdf_interchange { cairo_tag_stack_t analysis_tag_stack; cairo_tag_stack_t render_tag_stack; - cairo_array_t push_data; /* records analysis_tag_stack data field for each push */ - int push_data_index; cairo_pdf_struct_tree_node_t *struct_root; - cairo_pdf_struct_tree_node_t *current_node; - cairo_pdf_struct_tree_node_t *begin_page_node; - cairo_pdf_struct_tree_node_t *end_page_node; - cairo_array_t parent_tree; /* parent tree resources */ - cairo_array_t mcid_to_tree; /* mcid to tree node mapping for current page */ + + /* Current position in the tree during the analysis stage and across + * pages as each page adds to the tree */ + cairo_pdf_struct_tree_node_t *current_analyze_node; + + /* Currently open tag content containing content. NULL if no content tag open. + * A content containg tag may be open across pages */ + cairo_pdf_struct_tree_node_t *current_render_node; + cairo_pdf_struct_tree_node_t *next_page_render_node; + + cairo_array_t recording_surface_stack; /* cairo_recording_surface_stack_entry_t */ + cairo_pdf_resource_t current_recording_surface_res; + cairo_hash_table_t *command_to_node_map; /* <cairo_pdf_surface_node_entry_t> */ + cairo_bool_t ignore_current_surface; + cairo_hash_table_t *content_tag_map; /* <char*,cairo_pdf_content_tag_t> */ + + cairo_array_t parent_tree; /* <cairo_pdf_resource_t> */ cairo_array_t annots; /* array of pointers to cairo_pdf_annotation_t */ + cairo_pdf_resource_t content_parent_res; cairo_pdf_resource_t parent_tree_res; + + /* mcid to tree node for current page or group */ + cairo_array_t mcid_to_tree; /* <cairo_pdf_struct_tree_node_t *> */ + + cairo_array_t page_commands; /* <cairo_pdf_command_list_t> */ + cairo_pdf_command_list_t *current_commands; /* <cairo_pdf_command_list_t> */ + cairo_array_t recording_surface_commands; /* <cairo_pdf_recording_surface_commands_t> */ + cairo_list_t extents_list; cairo_hash_table_t *named_dests; int num_dests; @@ -255,6 +357,12 @@ typedef struct _cairo_pdf_interchange { cairo_array_t outline; /* array of pointers to cairo_pdf_outline_entry_t; */ struct docinfo docinfo; cairo_array_t custom_metadata; /* array of struct metadata */ + cairo_bool_t content_emitted; + cairo_bool_t marked_content_open; + unsigned int recording_id; + unsigned int command_id; + cairo_bool_t render_next_command_has_content; + int mcid_order; } cairo_pdf_interchange_t; @@ -283,18 +391,18 @@ struct _cairo_pdf_surface { cairo_matrix_t cairo_to_pdf; cairo_bool_t in_xobject; - cairo_array_t objects; - cairo_array_t pages; + cairo_array_t objects; /* cairo_pdf_resource_t - list of every resource in the PDF */ + cairo_array_t pages; /* <cairo_pdf_page_info_t> */ cairo_array_t rgb_linear_functions; cairo_array_t alpha_linear_functions; cairo_array_t page_patterns; /* cairo_pdf_pattern_t */ cairo_array_t page_surfaces; /* cairo_pdf_source_surface_t */ cairo_array_t doc_surfaces; /* cairo_pdf_source_surface_t */ - cairo_hash_table_t *all_surfaces; + cairo_hash_table_t *all_surfaces; /* cairo_pdf_source_surface_entry_t* */ + int duplicate_surface_number; cairo_array_t smask_groups; cairo_array_t knockout_group; cairo_array_t jbig2_global; - cairo_array_t page_heights; cairo_hash_table_t *color_glyphs; cairo_scaled_font_subsets_t *font_subsets; @@ -374,6 +482,8 @@ struct _cairo_pdf_surface { cairo_image_surface_t *thumbnail_image; cairo_surface_t *paginated_surface; + + cairo_bool_t debug; }; cairo_private cairo_pdf_resource_t @@ -410,15 +520,56 @@ _cairo_pdf_surface_object_begin (cairo_pdf_surface_t *surface, cairo_private void _cairo_pdf_surface_object_end (cairo_pdf_surface_t *surface); +cairo_private cairo_bool_t +_cairo_pdf_interchange_struct_tree_requires_recording_surface ( + cairo_pdf_surface_t *surface, + const cairo_surface_pattern_t *recording_surface, + cairo_analysis_source_t source_type); + +cairo_private cairo_int_status_t +_cairo_pdf_interchange_recording_source_surface_begin ( + cairo_pdf_surface_t *surface, + const cairo_surface_pattern_t *recording_surface_pattern, + unsigned int region_id, + cairo_analysis_source_t source_type); + +cairo_private cairo_int_status_t +_cairo_pdf_interchange_recording_source_surface_end ( + cairo_pdf_surface_t *surface, + const cairo_surface_pattern_t *recording_surface_pattern, + unsigned int region_id, + cairo_analysis_source_t source_type); + +cairo_private cairo_int_status_t +_cairo_pdf_interchange_emit_recording_surface_begin ( + cairo_pdf_surface_t *surface, + cairo_surface_t *recording_surface, + int region_id, + cairo_pdf_resource_t surface_resource, + int *struct_parents); + +cairo_private cairo_int_status_t +_cairo_pdf_interchange_emit_recording_surface_end ( + cairo_pdf_surface_t *surface, + cairo_surface_t *recording_surface); + cairo_private cairo_int_status_t _cairo_pdf_interchange_tag_end (cairo_pdf_surface_t *surface, const char *name); cairo_private cairo_int_status_t +_cairo_pdf_interchange_command_id (cairo_pdf_surface_t *surface, + unsigned int recording_id, + unsigned int command_id); + +cairo_private cairo_int_status_t _cairo_pdf_interchange_add_operation_extents (cairo_pdf_surface_t *surface, const cairo_rectangle_int_t *extents); cairo_private cairo_int_status_t +_cairo_pdf_interchange_add_content (cairo_pdf_surface_t *surface); + +cairo_private cairo_int_status_t _cairo_pdf_interchange_write_page_objects (cairo_pdf_surface_t *surface); cairo_private cairo_int_status_t |