summaryrefslogtreecommitdiff
path: root/src/cairo-pdf-surface-private.h
blob: c1fd11a9133955e5c0c550a0eae9e8065b6fb853 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
 *
 * Copyright © 2004 Red Hat, Inc
 * Copyright © 2006 Red Hat, Inc
 * Copyright © 2007, 2008 Adrian Johnson
 *
 * This library is free software; you can redistribute it and/or
 * modify it either under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * (the "LGPL") or, at your option, under the terms of the Mozilla
 * Public License Version 1.1 (the "MPL"). If you do not alter this
 * notice, a recipient may use your version of this file under either
 * the MPL or the LGPL.
 *
 * You should have received a copy of the LGPL along with this library
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
 * You should have received a copy of the MPL along with this library
 * in the file COPYING-MPL-1.1
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
 * the specific language governing rights and limitations.
 *
 * The Original Code is the cairo graphics library.
 *
 * The Initial Developer of the Original Code is University of Southern
 * California.
 *
 * Contributor(s):
 *	Kristian Høgsberg <krh@redhat.com>
 *	Carl Worth <cworth@cworth.org>
 *	Adrian Johnson <ajohnson@redneon.com>
 */

#ifndef CAIRO_PDF_SURFACE_PRIVATE_H
#define CAIRO_PDF_SURFACE_PRIVATE_H

#include "cairo-pdf.h"

#include "cairo-surface-private.h"
#include "cairo-surface-clipper-private.h"
#include "cairo-pdf-operators-private.h"
#include "cairo-path-fixed-private.h"
#include "cairo-tag-attributes-private.h"
#include "cairo-tag-stack-private.h"

typedef struct _cairo_pdf_resource {
    unsigned int id;
} cairo_pdf_resource_t;

#define CAIRO_NUM_OPERATORS (CAIRO_OPERATOR_HSL_LUMINOSITY + 1)

typedef struct _cairo_pdf_group_resources {
    cairo_bool_t  operators[CAIRO_NUM_OPERATORS];
    cairo_array_t alphas;
    cairo_array_t smasks;
    cairo_array_t patterns;
    cairo_array_t shadings;
    cairo_array_t xobjects;
    cairo_array_t fonts;
} cairo_pdf_group_resources_t;

typedef struct _cairo_pdf_source_surface_entry {
    cairo_hash_entry_t base;
    unsigned int id;
    unsigned char *unique_id;
    unsigned long unique_id_length;
    cairo_operator_t operator;
    cairo_bool_t interpolate;
    cairo_bool_t stencil_mask;
    cairo_bool_t smask;
    cairo_pdf_resource_t surface_res;
    cairo_pdf_resource_t smask_res;

    /* Extents of the source surface. If bounded is false,
     * extents is the ink extents. */
    cairo_bool_t bounded;
    cairo_rectangle_int_t extents;

    /* Union of source extents requried for all operations using this source */
    cairo_rectangle_int_t required_extents;
} cairo_pdf_source_surface_entry_t;

typedef struct _cairo_pdf_source_surface {
    cairo_pattern_type_t type;
    cairo_surface_t *surface;
    cairo_pattern_t *raster_pattern;
    cairo_pdf_source_surface_entry_t *hash_entry;
} cairo_pdf_source_surface_t;

typedef struct _cairo_pdf_pattern {
    double width;
    double height;
    cairo_rectangle_int_t extents;
    cairo_pattern_t *pattern;
    cairo_pdf_resource_t pattern_res;
    cairo_pdf_resource_t gstate_res;
    cairo_operator_t operator;
    cairo_bool_t is_shading;

    /* PDF pattern space is the pattern matrix concatenated with the
     * initial space of the parent object. If the parent object is the
     * page, the intial space does not include the Y-axis flipping
     * matrix emitted at the start of the page content stream.  If the
     * parent object is not the page content stream, the initial space
     * will have a flipped Y-axis. The inverted_y_axis flag is true
     * when the initial space of the parent object that is drawing
     * this pattern has a flipped Y-axis.
     */
    cairo_bool_t inverted_y_axis;
} cairo_pdf_pattern_t;

typedef enum _cairo_pdf_operation {
    PDF_PAINT,
    PDF_MASK,
    PDF_FILL,
    PDF_STROKE,
    PDF_SHOW_GLYPHS
} cairo_pdf_operation_t;

typedef struct _cairo_pdf_smask_group {
    double		  width;
    double		  height;
    cairo_rectangle_int_t extents;
    cairo_pdf_resource_t  group_res;
    cairo_pdf_operation_t operation;
    cairo_pattern_t	 *source;
    cairo_pdf_resource_t  source_res;
    cairo_pattern_t	 *mask;
    cairo_path_fixed_t	  path;
    cairo_fill_rule_t	  fill_rule;
    cairo_stroke_style_t  style;
    cairo_matrix_t	  ctm;
    cairo_matrix_t	  ctm_inverse;
    char		 *utf8;
    int                   utf8_len;
    cairo_glyph_t	 *glyphs;
    int			  num_glyphs;
    cairo_text_cluster_t *clusters;
    int                   num_clusters;
    cairo_bool_t          cluster_flags;
    cairo_scaled_font_t	 *scaled_font;
} cairo_pdf_smask_group_t;

typedef struct _cairo_pdf_jbig2_global {
    unsigned char *id;
    unsigned long id_length;
    cairo_pdf_resource_t  res;
    cairo_bool_t emitted;
} cairo_pdf_jbig2_global_t;

/* cairo-pdf-interchange.c types */

struct page_mcid {
    int page;
    int mcid;
};

struct tag_extents {
    cairo_rectangle_int_t extents;
    cairo_bool_t valid;
    cairo_list_t link;
};

typedef struct _cairo_pdf_struct_tree_node {
    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 */
    struct {
	struct tag_extents extents;
	cairo_pdf_resource_t res;
	cairo_link_attrs_t link_attrs;
	double page_height;
    } annot;
    cairo_list_t link;
} cairo_pdf_struct_tree_node_t;

typedef struct _cairo_pdf_named_dest {
    cairo_hash_entry_t base;
    struct tag_extents extents;
    cairo_dest_attrs_t attrs;
    int page;
    double page_height;
    cairo_bool_t referenced;
} cairo_pdf_named_dest_t;

typedef struct _cairo_pdf_outline_entry {
    char *name;
    char *dest;
    cairo_pdf_outline_flags_t flags;
    cairo_pdf_resource_t res;
    struct _cairo_pdf_outline_entry *parent;
    struct _cairo_pdf_outline_entry *first_child;
    struct _cairo_pdf_outline_entry *last_child;
    struct _cairo_pdf_outline_entry *next;
    struct _cairo_pdf_outline_entry *prev;
    int count;
} cairo_pdf_outline_entry_t;

struct docinfo {
    char *title;
    char *author;
    char *subject;
    char *keywords;
    char *creator;
    char *create_date;
    char *mod_date;
};

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 */
    cairo_pdf_resource_t parent_tree_res;
    cairo_list_t extents_list;
    cairo_hash_table_t *named_dests;
    int num_dests;
    cairo_pdf_named_dest_t **sorted_dests;
    cairo_pdf_resource_t dests_res;
    int annot_page;
    cairo_array_t outline; /* array of pointers to cairo_pdf_outline_entry_t; */
    struct docinfo docinfo;

} cairo_pdf_interchange_t;

/* pdf surface data */

typedef struct _cairo_pdf_surface cairo_pdf_surface_t;

struct _cairo_pdf_surface {
    cairo_surface_t base;

    /* Prefer the name "output" here to avoid confusion over the
     * structure within a PDF document known as a "stream". */
    cairo_output_stream_t *output;

    double width;
    double height;
    cairo_rectangle_int_t surface_extents;
    cairo_bool_t surface_bounded;
    cairo_matrix_t cairo_to_pdf;
    cairo_bool_t in_xobject;

    cairo_array_t objects;
    cairo_array_t pages;
    cairo_array_t rgb_linear_functions;
    cairo_array_t alpha_linear_functions;
    cairo_array_t page_patterns;
    cairo_array_t page_surfaces;
    cairo_hash_table_t *all_surfaces;
    cairo_array_t smask_groups;
    cairo_array_t knockout_group;
    cairo_array_t jbig2_global;

    cairo_scaled_font_subsets_t *font_subsets;
    cairo_array_t fonts;

    cairo_pdf_resource_t next_available_resource;
    cairo_pdf_resource_t pages_resource;
    cairo_pdf_resource_t struct_tree_root;

    cairo_pdf_version_t pdf_version;
    cairo_bool_t compress_content;

    cairo_pdf_resource_t content;
    cairo_pdf_resource_t content_resources;
    cairo_pdf_group_resources_t resources;
    cairo_bool_t has_fallback_images;
    cairo_bool_t header_emitted;

    struct {
	cairo_bool_t active;
	cairo_pdf_resource_t self;
	cairo_pdf_resource_t length;
	long start_offset;
	cairo_bool_t compressed;
	cairo_output_stream_t *old_output;
    } pdf_stream;

    struct {
	cairo_bool_t active;
	cairo_output_stream_t *stream;
	cairo_output_stream_t *mem_stream;
	cairo_output_stream_t *old_output;
	cairo_pdf_resource_t   resource;
	cairo_box_double_t     bbox;
	cairo_bool_t is_knockout;
    } group_stream;

    cairo_surface_clipper_t clipper;

    cairo_pdf_operators_t pdf_operators;
    cairo_paginated_mode_t paginated_mode;
    cairo_bool_t select_pattern_gstate_saved;

    cairo_bool_t force_fallbacks;

    cairo_operator_t current_operator;
    cairo_bool_t current_pattern_is_solid_color;
    cairo_bool_t current_color_is_stroke;
    double current_color_red;
    double current_color_green;
    double current_color_blue;
    double current_color_alpha;

    cairo_pdf_interchange_t interchange;
    int page_parent_tree; /* -1 if not used */
    cairo_array_t page_annots;
    cairo_bool_t tagged;
    char *current_page_label;
    cairo_array_t page_labels;
    cairo_pdf_resource_t outlines_dict_res;
    cairo_pdf_resource_t names_dict_res;
    cairo_pdf_resource_t docinfo_res;
    cairo_pdf_resource_t page_labels_res;

    int thumbnail_width;
    int thumbnail_height;
    cairo_image_surface_t *thumbnail_image;

    cairo_surface_t *paginated_surface;
};

cairo_private cairo_pdf_resource_t
_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);

cairo_private void
_cairo_pdf_surface_update_object (cairo_pdf_surface_t	*surface,
				  cairo_pdf_resource_t	 resource);

cairo_int_status_t
_cairo_utf8_to_pdf_string (const char *utf8, char **str_out);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_init (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_fini (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_begin_page_content (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_end_page_content (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_tag_begin (cairo_pdf_surface_t    *surface,
				  const char             *name,
				  const char             *attributes);

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_add_operation_extents (cairo_pdf_surface_t         *surface,
					      const cairo_rectangle_int_t *extents);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_write_page_objects (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_write_document_objects (cairo_pdf_surface_t *surface);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_add_outline (cairo_pdf_surface_t        *surface,
				    int                         parent_id,
				    const char                 *name,
				    const char                 *dest,
				    cairo_pdf_outline_flags_t   flags,
				    int                        *id);

cairo_private cairo_int_status_t
_cairo_pdf_interchange_set_metadata (cairo_pdf_surface_t  *surface,
				     cairo_pdf_metadata_t  metadata,
				     const char           *utf8);

#endif /* CAIRO_PDF_SURFACE_PRIVATE_H */