Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2004 Red Hat, Inc
5
 * Copyright © 2006 Red Hat, Inc
6
 * Copyright © 2007, 2008 Adrian Johnson
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it either under the terms of the GNU Lesser General Public
10
 * License version 2.1 as published by the Free Software Foundation
11
 * (the "LGPL") or, at your option, under the terms of the Mozilla
12
 * Public License Version 1.1 (the "MPL"). If you do not alter this
13
 * notice, a recipient may use your version of this file under either
14
 * the MPL or the LGPL.
15
 *
16
 * You should have received a copy of the LGPL along with this library
17
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
19
 * You should have received a copy of the MPL along with this library
20
 * in the file COPYING-MPL-1.1
21
 *
22
 * The contents of this file are subject to the Mozilla Public License
23
 * Version 1.1 (the "License"); you may not use this file except in
24
 * compliance with the License. You may obtain a copy of the License at
25
 * http://www.mozilla.org/MPL/
26
 *
27
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29
 * the specific language governing rights and limitations.
30
 *
31
 * The Original Code is the cairo graphics library.
32
 *
33
 * The Initial Developer of the Original Code is University of Southern
34
 * California.
35
 *
36
 * Contributor(s):
37
 *	Kristian Høgsberg 
38
 *	Carl Worth 
39
 *	Adrian Johnson 
40
 */
41
 
42
#define _BSD_SOURCE /* for snprintf() */
43
#include "cairoint.h"
44
 
45
#include "cairo-pdf.h"
46
#include "cairo-pdf-surface-private.h"
47
#include "cairo-pdf-operators-private.h"
48
#include "cairo-pdf-shading-private.h"
49
 
50
#include "cairo-array-private.h"
51
#include "cairo-analysis-surface-private.h"
52
#include "cairo-composite-rectangles-private.h"
53
#include "cairo-default-context-private.h"
54
#include "cairo-error-private.h"
55
#include "cairo-image-surface-inline.h"
56
#include "cairo-image-info-private.h"
57
#include "cairo-recording-surface-private.h"
58
#include "cairo-output-stream-private.h"
59
#include "cairo-paginated-private.h"
60
#include "cairo-scaled-font-subsets-private.h"
61
#include "cairo-surface-clipper-private.h"
62
#include "cairo-surface-snapshot-inline.h"
63
#include "cairo-surface-subsurface-private.h"
64
#include "cairo-type3-glyph-surface-private.h"
65
 
66
#include 
67
#include 
68
 
69
/* Issues:
70
 *
71
 * - We embed an image in the stream each time it's composited.  We
72
 *   could add generation counters to surfaces and remember the stream
73
 *   ID for a particular generation for a particular surface.
74
 *
75
 * - Backend specific meta data.
76
 */
77
 
78
/*
79
 * Page Structure of the Generated PDF:
80
 *
81
 * Each page requiring fallbacks images contains a knockout group at
82
 * the top level. The first operation of the knockout group paints a
83
 * group containing all the supported drawing operations. Fallback
84
 * images (if any) are painted in the knockout group. This ensures
85
 * that fallback images do not composite with any content under the
86
 * fallback images.
87
 *
88
 * Streams:
89
 *
90
 * This PDF surface has three types of streams:
91
 *  - PDF Stream
92
 *  - Content Stream
93
 *  - Group Stream
94
 *
95
 * Calling _cairo_output_stream_printf (surface->output, ...) will
96
 * write to the currently open stream.
97
 *
98
 * PDF Stream:
99
 *   A PDF Stream may be opened and closed with the following functions:
100
 *     _cairo_pdf_surface_open stream ()
101
 *     _cairo_pdf_surface_close_stream ()
102
 *
103
 *   PDF Streams are written directly to the PDF file. They are used for
104
 *   fonts, images and patterns.
105
 *
106
 * Content Stream:
107
 *   The Content Stream is opened and closed with the following functions:
108
 *     _cairo_pdf_surface_open_content_stream ()
109
 *     _cairo_pdf_surface_close_content_stream ()
110
 *
111
 *   The Content Stream contains the text and graphics operators.
112
 *
113
 * Group Stream:
114
 *   A Group Stream may be opened and closed with the following functions:
115
 *     _cairo_pdf_surface_open_group ()
116
 *     _cairo_pdf_surface_close_group ()
117
 *
118
 *   A Group Stream is a Form XObject. It is used for short sequences
119
 *   of operators. As the content is very short the group is stored in
120
 *   memory until it is closed. This allows some optimization such as
121
 *   including the Resource dictionary and stream length inside the
122
 *   XObject instead of using an indirect object.
123
 */
124
 
125
/**
126
 * SECTION:cairo-pdf
127
 * @Title: PDF Surfaces
128
 * @Short_Description: Rendering PDF documents
129
 * @See_Also: #cairo_surface_t
130
 *
131
 * The PDF surface is used to render cairo graphics to Adobe
132
 * PDF files and is a multi-page vector surface backend.
133
 **/
134
 
135
static cairo_bool_t
136
_cairo_pdf_surface_get_extents (void		        *abstract_surface,
137
				cairo_rectangle_int_t   *rectangle);
138
 
139
/**
140
 * CAIRO_HAS_PDF_SURFACE:
141
 *
142
 * Defined if the PDF surface backend is available.
143
 * This macro can be used to conditionally compile backend-specific code.
144
 *
145
 * Since: 1.2
146
 **/
147
 
148
static const cairo_pdf_version_t _cairo_pdf_versions[] =
149
{
150
    CAIRO_PDF_VERSION_1_4,
151
    CAIRO_PDF_VERSION_1_5
152
};
153
 
154
#define CAIRO_PDF_VERSION_LAST ARRAY_LENGTH (_cairo_pdf_versions)
155
 
156
static const char * _cairo_pdf_version_strings[CAIRO_PDF_VERSION_LAST] =
157
{
158
    "PDF 1.4",
159
    "PDF 1.5"
160
};
161
 
162
static const char *_cairo_pdf_supported_mime_types[] =
163
{
164
    CAIRO_MIME_TYPE_JPEG,
165
    CAIRO_MIME_TYPE_JP2,
166
    CAIRO_MIME_TYPE_UNIQUE_ID,
167
    NULL
168
};
169
 
170
typedef struct _cairo_pdf_object {
171
    long offset;
172
} cairo_pdf_object_t;
173
 
174
typedef struct _cairo_pdf_font {
175
    unsigned int font_id;
176
    unsigned int subset_id;
177
    cairo_pdf_resource_t subset_resource;
178
} cairo_pdf_font_t;
179
 
180
typedef struct _cairo_pdf_rgb_linear_function {
181
    cairo_pdf_resource_t resource;
182
    double               color1[3];
183
    double               color2[3];
184
} cairo_pdf_rgb_linear_function_t;
185
 
186
typedef struct _cairo_pdf_alpha_linear_function {
187
    cairo_pdf_resource_t resource;
188
    double               alpha1;
189
    double               alpha2;
190
} cairo_pdf_alpha_linear_function_t;
191
 
192
static cairo_pdf_resource_t
193
_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface);
194
 
195
static void
196
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface);
197
 
198
static void
199
_cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group);
200
 
201
static cairo_int_status_t
202
_cairo_pdf_surface_add_font (unsigned int        font_id,
203
			     unsigned int        subset_id,
204
			     void		*closure);
205
 
206
static void
207
_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res);
208
 
209
static cairo_int_status_t
210
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t	*surface,
211
				cairo_pdf_resource_t    *resource,
212
                                cairo_bool_t             compressed,
213
				const char		*fmt,
214
				...) CAIRO_PRINTF_FORMAT(4, 5);
215
static cairo_int_status_t
216
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t	*surface);
217
 
218
static cairo_int_status_t
219
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
220
 
221
static void
222
_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface);
223
 
224
static cairo_pdf_resource_t
225
_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface);
226
 
227
static cairo_pdf_resource_t
228
_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface);
229
 
230
static long
231
_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface);
232
 
233
static cairo_int_status_t
234
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
235
 
236
static cairo_int_status_t
237
_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface);
238
 
239
static cairo_bool_t
240
_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b);
241
 
242
static const cairo_surface_backend_t cairo_pdf_surface_backend;
243
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend;
244
 
245
static cairo_pdf_resource_t
246
_cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface)
247
{
248
    cairo_pdf_resource_t resource;
249
    cairo_int_status_t status;
250
    cairo_pdf_object_t object;
251
 
252
    object.offset = _cairo_output_stream_get_position (surface->output);
253
 
254
    status = _cairo_array_append (&surface->objects, &object);
255
    if (unlikely (status)) {
256
	resource.id = 0;
257
	return resource;
258
    }
259
 
260
    resource = surface->next_available_resource;
261
    surface->next_available_resource.id++;
262
 
263
    return resource;
264
}
265
 
266
static void
267
_cairo_pdf_surface_update_object (cairo_pdf_surface_t	*surface,
268
				  cairo_pdf_resource_t	 resource)
269
{
270
    cairo_pdf_object_t *object;
271
 
272
    object = _cairo_array_index (&surface->objects, resource.id - 1);
273
    object->offset = _cairo_output_stream_get_position (surface->output);
274
}
275
 
276
static void
277
_cairo_pdf_surface_set_size_internal (cairo_pdf_surface_t *surface,
278
				      double		  width,
279
				      double		  height)
280
{
281
    surface->width = width;
282
    surface->height = height;
283
    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
284
    _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
285
						  &surface->cairo_to_pdf);
286
}
287
 
288
static cairo_bool_t
289
_path_covers_bbox (cairo_pdf_surface_t *surface,
290
		   cairo_path_fixed_t *path)
291
{
292
    cairo_box_t box;
293
 
294
    return _cairo_path_fixed_is_box (path, &box) &&
295
	   box.p1.x <= 0 &&
296
	   box.p1.y <= 0 &&
297
	   box.p2.x >= _cairo_fixed_from_double (surface->width) &&
298
	   box.p2.y >= _cairo_fixed_from_double (surface->height);
299
}
300
 
301
static cairo_status_t
302
_cairo_pdf_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
303
						cairo_path_fixed_t	*path,
304
						cairo_fill_rule_t	fill_rule,
305
						double			tolerance,
306
						cairo_antialias_t	antialias)
307
{
308
    cairo_pdf_surface_t *surface = cairo_container_of (clipper,
309
						       cairo_pdf_surface_t,
310
						       clipper);
311
    cairo_int_status_t status;
312
 
313
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
314
    if (unlikely (status))
315
	return status;
316
 
317
    if (path == NULL) {
318
	_cairo_output_stream_printf (surface->output, "Q q\n");
319
 
320
	surface->current_pattern_is_solid_color = FALSE;
321
	_cairo_pdf_operators_reset (&surface->pdf_operators);
322
 
323
	return CAIRO_STATUS_SUCCESS;
324
    }
325
 
326
    if (_path_covers_bbox (surface, path))
327
	return CAIRO_STATUS_SUCCESS;
328
 
329
    return _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule);
330
}
331
 
332
static cairo_surface_t *
333
_cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t	*output,
334
					       double			 width,
335
					       double			 height)
336
{
337
    cairo_pdf_surface_t *surface;
338
    cairo_status_t status, status_ignored;
339
 
340
    surface = malloc (sizeof (cairo_pdf_surface_t));
341
    if (unlikely (surface == NULL)) {
342
	/* destroy stream on behalf of caller */
343
	status = _cairo_output_stream_destroy (output);
344
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
345
    }
346
 
347
    _cairo_surface_init (&surface->base,
348
			 &cairo_pdf_surface_backend,
349
			 NULL, /* device */
350
			 CAIRO_CONTENT_COLOR_ALPHA);
351
 
352
    surface->output = output;
353
    surface->width = width;
354
    surface->height = height;
355
    cairo_matrix_init (&surface->cairo_to_pdf, 1, 0, 0, -1, 0, height);
356
 
357
    _cairo_array_init (&surface->objects, sizeof (cairo_pdf_object_t));
358
    _cairo_array_init (&surface->pages, sizeof (cairo_pdf_resource_t));
359
    _cairo_array_init (&surface->rgb_linear_functions, sizeof (cairo_pdf_rgb_linear_function_t));
360
    _cairo_array_init (&surface->alpha_linear_functions, sizeof (cairo_pdf_alpha_linear_function_t));
361
    _cairo_array_init (&surface->fonts, sizeof (cairo_pdf_font_t));
362
    _cairo_array_init (&surface->smask_groups, sizeof (cairo_pdf_smask_group_t *));
363
    _cairo_array_init (&surface->knockout_group, sizeof (cairo_pdf_resource_t));
364
 
365
    _cairo_array_init (&surface->page_patterns, sizeof (cairo_pdf_pattern_t));
366
    _cairo_array_init (&surface->page_surfaces, sizeof (cairo_pdf_source_surface_t));
367
    surface->all_surfaces = _cairo_hash_table_create (_cairo_pdf_source_surface_equal);
368
    if (unlikely (surface->all_surfaces == NULL)) {
369
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
370
	goto BAIL0;
371
    }
372
 
373
    _cairo_pdf_group_resources_init (&surface->resources);
374
 
375
    surface->font_subsets = _cairo_scaled_font_subsets_create_composite ();
376
    if (! surface->font_subsets) {
377
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
378
	goto BAIL1;
379
    }
380
 
381
    _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE);
382
 
383
    surface->next_available_resource.id = 1;
384
    surface->pages_resource = _cairo_pdf_surface_new_object (surface);
385
    if (surface->pages_resource.id == 0) {
386
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
387
        goto BAIL2;
388
    }
389
 
390
    surface->pdf_version = CAIRO_PDF_VERSION_1_5;
391
    surface->compress_content = TRUE;
392
    surface->pdf_stream.active = FALSE;
393
    surface->pdf_stream.old_output = NULL;
394
    surface->group_stream.active = FALSE;
395
    surface->group_stream.stream = NULL;
396
    surface->group_stream.mem_stream = NULL;
397
 
398
    surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
399
 
400
    surface->force_fallbacks = FALSE;
401
    surface->select_pattern_gstate_saved = FALSE;
402
    surface->current_pattern_is_solid_color = FALSE;
403
    surface->current_operator = CAIRO_OPERATOR_OVER;
404
    surface->header_emitted = FALSE;
405
 
406
    _cairo_surface_clipper_init (&surface->clipper,
407
				 _cairo_pdf_surface_clipper_intersect_clip_path);
408
 
409
    _cairo_pdf_operators_init (&surface->pdf_operators,
410
			       surface->output,
411
			       &surface->cairo_to_pdf,
412
			       surface->font_subsets);
413
    _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
414
						    _cairo_pdf_surface_add_font,
415
						    surface);
416
    _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators, TRUE);
417
 
418
    surface->paginated_surface =  _cairo_paginated_surface_create (
419
	                                  &surface->base,
420
					  CAIRO_CONTENT_COLOR_ALPHA,
421
					  &cairo_pdf_surface_paginated_backend);
422
 
423
    status = surface->paginated_surface->status;
424
    if (status == CAIRO_STATUS_SUCCESS) {
425
	/* paginated keeps the only reference to surface now, drop ours */
426
	cairo_surface_destroy (&surface->base);
427
	return surface->paginated_surface;
428
    }
429
 
430
BAIL2:
431
    _cairo_scaled_font_subsets_destroy (surface->font_subsets);
432
BAIL1:
433
    _cairo_hash_table_destroy (surface->all_surfaces);
434
BAIL0:
435
    _cairo_array_fini (&surface->objects);
436
    free (surface);
437
 
438
    /* destroy stream on behalf of caller */
439
    status_ignored = _cairo_output_stream_destroy (output);
440
 
441
    return _cairo_surface_create_in_error (status);
442
}
443
 
444
/**
445
 * cairo_pdf_surface_create_for_stream:
446
 * @write_func: a #cairo_write_func_t to accept the output data, may be %NULL
447
 *              to indicate a no-op @write_func. With a no-op @write_func,
448
 *              the surface may be queried or used as a source without
449
 *              generating any temporary files.
450
 * @closure: the closure argument for @write_func
451
 * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
452
 * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
453
 *
454
 * Creates a PDF surface of the specified size in points to be written
455
 * incrementally to the stream represented by @write_func and @closure.
456
 *
457
 * Return value: a pointer to the newly created surface. The caller
458
 * owns the surface and should call cairo_surface_destroy() when done
459
 * with it.
460
 *
461
 * This function always returns a valid pointer, but it will return a
462
 * pointer to a "nil" surface if an error such as out of memory
463
 * occurs. You can use cairo_surface_status() to check for this.
464
 *
465
 * Since: 1.2
466
 **/
467
cairo_surface_t *
468
cairo_pdf_surface_create_for_stream (cairo_write_func_t		 write_func,
469
				     void			*closure,
470
				     double			 width_in_points,
471
				     double			 height_in_points)
472
{
473
    cairo_output_stream_t *output;
474
 
475
    output = _cairo_output_stream_create (write_func, NULL, closure);
476
    if (_cairo_output_stream_get_status (output))
477
	return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
478
 
479
    return _cairo_pdf_surface_create_for_stream_internal (output,
480
							  width_in_points,
481
							  height_in_points);
482
}
483
 
484
/**
485
 * cairo_pdf_surface_create:
486
 * @filename: a filename for the PDF output (must be writable), %NULL may be
487
 *            used to specify no output. This will generate a PDF surface that
488
 *            may be queried and used as a source, without generating a
489
 *            temporary file.
490
 * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
491
 * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
492
 *
493
 * Creates a PDF surface of the specified size in points to be written
494
 * to @filename.
495
 *
496
 * Return value: a pointer to the newly created surface. The caller
497
 * owns the surface and should call cairo_surface_destroy() when done
498
 * with it.
499
 *
500
 * This function always returns a valid pointer, but it will return a
501
 * pointer to a "nil" surface if an error such as out of memory
502
 * occurs. You can use cairo_surface_status() to check for this.
503
 *
504
 * Since: 1.2
505
 **/
506
cairo_surface_t *
507
cairo_pdf_surface_create (const char		*filename,
508
			  double		 width_in_points,
509
			  double		 height_in_points)
510
{
511
    cairo_output_stream_t *output;
512
 
513
    output = _cairo_output_stream_create_for_filename (filename);
514
    if (_cairo_output_stream_get_status (output))
515
	return _cairo_surface_create_in_error (_cairo_output_stream_destroy (output));
516
 
517
    return _cairo_pdf_surface_create_for_stream_internal (output,
518
							  width_in_points,
519
							  height_in_points);
520
}
521
 
522
static cairo_bool_t
523
_cairo_surface_is_pdf (cairo_surface_t *surface)
524
{
525
    return surface->backend == &cairo_pdf_surface_backend;
526
}
527
 
528
/* If the abstract_surface is a paginated surface, and that paginated
529
 * surface's target is a pdf_surface, then set pdf_surface to that
530
 * target. Otherwise return FALSE.
531
 */
532
static cairo_bool_t
533
_extract_pdf_surface (cairo_surface_t		 *surface,
534
		      cairo_pdf_surface_t	**pdf_surface)
535
{
536
    cairo_surface_t *target;
537
    cairo_status_t status_ignored;
538
 
539
    if (surface->status)
540
	return FALSE;
541
    if (surface->finished) {
542
	status_ignored = _cairo_surface_set_error (surface,
543
						   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
544
        return FALSE;
545
    }
546
 
547
    if (! _cairo_surface_is_paginated (surface)) {
548
	status_ignored = _cairo_surface_set_error (surface,
549
						   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
550
	return FALSE;
551
    }
552
 
553
    target = _cairo_paginated_surface_get_target (surface);
554
    if (target->status) {
555
	status_ignored = _cairo_surface_set_error (surface,
556
						   target->status);
557
	return FALSE;
558
    }
559
    if (target->finished) {
560
	status_ignored = _cairo_surface_set_error (surface,
561
						   _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
562
	return FALSE;
563
    }
564
 
565
    if (! _cairo_surface_is_pdf (target)) {
566
	status_ignored = _cairo_surface_set_error (surface,
567
						   _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
568
	return FALSE;
569
    }
570
 
571
    *pdf_surface = (cairo_pdf_surface_t *) target;
572
    return TRUE;
573
}
574
 
575
/**
576
 * cairo_pdf_surface_restrict_to_version:
577
 * @surface: a PDF #cairo_surface_t
578
 * @version: PDF version
579
 *
580
 * Restricts the generated PDF file to @version. See cairo_pdf_get_versions()
581
 * for a list of available version values that can be used here.
582
 *
583
 * This function should only be called before any drawing operations
584
 * have been performed on the given surface. The simplest way to do
585
 * this is to call this function immediately after creating the
586
 * surface.
587
 *
588
 * Since: 1.10
589
 **/
590
void
591
cairo_pdf_surface_restrict_to_version (cairo_surface_t 		*abstract_surface,
592
				       cairo_pdf_version_t  	 version)
593
{
594
    cairo_pdf_surface_t *surface = NULL; /* hide compiler warning */
595
 
596
    if (! _extract_pdf_surface (abstract_surface, &surface))
597
	return;
598
 
599
    if (version < CAIRO_PDF_VERSION_LAST)
600
	surface->pdf_version = version;
601
 
602
    _cairo_pdf_operators_enable_actual_text(&surface->pdf_operators,
603
					    version >= CAIRO_PDF_VERSION_1_5);
604
}
605
 
606
/**
607
 * cairo_pdf_get_versions:
608
 * @versions: supported version list
609
 * @num_versions: list length
610
 *
611
 * Used to retrieve the list of supported versions. See
612
 * cairo_pdf_surface_restrict_to_version().
613
 *
614
 * Since: 1.10
615
 **/
616
void
617
cairo_pdf_get_versions (cairo_pdf_version_t const	**versions,
618
                        int                     	 *num_versions)
619
{
620
    if (versions != NULL)
621
	*versions = _cairo_pdf_versions;
622
 
623
    if (num_versions != NULL)
624
	*num_versions = CAIRO_PDF_VERSION_LAST;
625
}
626
 
627
/**
628
 * cairo_pdf_version_to_string:
629
 * @version: a version id
630
 *
631
 * Get the string representation of the given @version id. This function
632
 * will return %NULL if @version isn't valid. See cairo_pdf_get_versions()
633
 * for a way to get the list of valid version ids.
634
 *
635
 * Return value: the string associated to given version.
636
 *
637
 * Since: 1.10
638
 **/
639
const char *
640
cairo_pdf_version_to_string (cairo_pdf_version_t version)
641
{
642
    if (version >= CAIRO_PDF_VERSION_LAST)
643
	return NULL;
644
 
645
    return _cairo_pdf_version_strings[version];
646
}
647
 
648
/**
649
 * cairo_pdf_surface_set_size:
650
 * @surface: a PDF #cairo_surface_t
651
 * @width_in_points: new surface width, in points (1 point == 1/72.0 inch)
652
 * @height_in_points: new surface height, in points (1 point == 1/72.0 inch)
653
 *
654
 * Changes the size of a PDF surface for the current (and
655
 * subsequent) pages.
656
 *
657
 * This function should only be called before any drawing operations
658
 * have been performed on the current page. The simplest way to do
659
 * this is to call this function immediately after creating the
660
 * surface or immediately after completing a page with either
661
 * cairo_show_page() or cairo_copy_page().
662
 *
663
 * Since: 1.2
664
 **/
665
void
666
cairo_pdf_surface_set_size (cairo_surface_t	*surface,
667
			    double		 width_in_points,
668
			    double		 height_in_points)
669
{
670
    cairo_pdf_surface_t *pdf_surface = NULL; /* hide compiler warning */
671
    cairo_status_t status;
672
 
673
    if (! _extract_pdf_surface (surface, &pdf_surface))
674
	return;
675
 
676
    _cairo_pdf_surface_set_size_internal (pdf_surface,
677
					  width_in_points,
678
					  height_in_points);
679
    status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface,
680
						width_in_points,
681
						height_in_points);
682
    if (status)
683
	status = _cairo_surface_set_error (surface, status);
684
}
685
 
686
static void
687
_cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
688
{
689
    int i, size;
690
    cairo_pdf_pattern_t *pattern;
691
    cairo_pdf_source_surface_t *src_surface;
692
    cairo_pdf_smask_group_t *group;
693
 
694
    size = _cairo_array_num_elements (&surface->page_patterns);
695
    for (i = 0; i < size; i++) {
696
	pattern = (cairo_pdf_pattern_t *) _cairo_array_index (&surface->page_patterns, i);
697
	cairo_pattern_destroy (pattern->pattern);
698
    }
699
    _cairo_array_truncate (&surface->page_patterns, 0);
700
 
701
    size = _cairo_array_num_elements (&surface->page_surfaces);
702
    for (i = 0; i < size; i++) {
703
	src_surface = (cairo_pdf_source_surface_t *) _cairo_array_index (&surface->page_surfaces, i);
704
	cairo_surface_destroy (src_surface->surface);
705
    }
706
    _cairo_array_truncate (&surface->page_surfaces, 0);
707
 
708
    size = _cairo_array_num_elements (&surface->smask_groups);
709
    for (i = 0; i < size; i++) {
710
	_cairo_array_copy_element (&surface->smask_groups, i, &group);
711
	_cairo_pdf_smask_group_destroy (group);
712
    }
713
    _cairo_array_truncate (&surface->smask_groups, 0);
714
    _cairo_array_truncate (&surface->knockout_group, 0);
715
}
716
 
717
static void
718
_cairo_pdf_group_resources_init (cairo_pdf_group_resources_t *res)
719
{
720
    int i;
721
 
722
    for (i = 0; i < CAIRO_NUM_OPERATORS; i++)
723
	res->operators[i] = FALSE;
724
 
725
    _cairo_array_init (&res->alphas, sizeof (double));
726
    _cairo_array_init (&res->smasks, sizeof (cairo_pdf_resource_t));
727
    _cairo_array_init (&res->patterns, sizeof (cairo_pdf_resource_t));
728
    _cairo_array_init (&res->shadings, sizeof (cairo_pdf_resource_t));
729
    _cairo_array_init (&res->xobjects, sizeof (cairo_pdf_resource_t));
730
    _cairo_array_init (&res->fonts, sizeof (cairo_pdf_font_t));
731
}
732
 
733
static void
734
_cairo_pdf_group_resources_fini (cairo_pdf_group_resources_t *res)
735
{
736
    _cairo_array_fini (&res->alphas);
737
    _cairo_array_fini (&res->smasks);
738
    _cairo_array_fini (&res->patterns);
739
    _cairo_array_fini (&res->shadings);
740
    _cairo_array_fini (&res->xobjects);
741
    _cairo_array_fini (&res->fonts);
742
}
743
 
744
static void
745
_cairo_pdf_group_resources_clear (cairo_pdf_group_resources_t *res)
746
{
747
    int i;
748
 
749
    for (i = 0; i < CAIRO_NUM_OPERATORS; i++)
750
	res->operators[i] = FALSE;
751
 
752
    _cairo_array_truncate (&res->alphas, 0);
753
    _cairo_array_truncate (&res->smasks, 0);
754
    _cairo_array_truncate (&res->patterns, 0);
755
    _cairo_array_truncate (&res->shadings, 0);
756
    _cairo_array_truncate (&res->xobjects, 0);
757
    _cairo_array_truncate (&res->fonts, 0);
758
}
759
 
760
static void
761
_cairo_pdf_surface_add_operator (cairo_pdf_surface_t *surface,
762
				 cairo_operator_t     op)
763
{
764
    cairo_pdf_group_resources_t *res = &surface->resources;
765
 
766
    res->operators[op] = TRUE;
767
}
768
 
769
static cairo_int_status_t
770
_cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface,
771
			      double               alpha,
772
			      int                 *index)
773
{
774
    int num_alphas, i;
775
    double other;
776
    cairo_int_status_t status;
777
    cairo_pdf_group_resources_t *res = &surface->resources;
778
 
779
    num_alphas = _cairo_array_num_elements (&res->alphas);
780
    for (i = 0; i < num_alphas; i++) {
781
	_cairo_array_copy_element (&res->alphas, i, &other);
782
	if (alpha == other) {
783
	    *index = i;
784
	    return CAIRO_STATUS_SUCCESS;
785
	}
786
    }
787
 
788
    status = _cairo_array_append (&res->alphas, &alpha);
789
    if (unlikely (status))
790
	return status;
791
 
792
    *index = _cairo_array_num_elements (&res->alphas) - 1;
793
 
794
    return CAIRO_STATUS_SUCCESS;
795
}
796
 
797
static cairo_int_status_t
798
_cairo_pdf_surface_add_smask (cairo_pdf_surface_t  *surface,
799
			      cairo_pdf_resource_t  smask)
800
{
801
    return _cairo_array_append (&(surface->resources.smasks), &smask);
802
}
803
 
804
static cairo_int_status_t
805
_cairo_pdf_surface_add_pattern (cairo_pdf_surface_t  *surface,
806
				cairo_pdf_resource_t  pattern)
807
{
808
    return _cairo_array_append (&(surface->resources.patterns), &pattern);
809
}
810
 
811
static cairo_int_status_t
812
_cairo_pdf_surface_add_shading (cairo_pdf_surface_t  *surface,
813
				cairo_pdf_resource_t  shading)
814
{
815
    return _cairo_array_append (&(surface->resources.shadings), &shading);
816
}
817
 
818
 
819
static cairo_int_status_t
820
_cairo_pdf_surface_add_xobject (cairo_pdf_surface_t  *surface,
821
				cairo_pdf_resource_t  xobject)
822
{
823
    return _cairo_array_append (&(surface->resources.xobjects), &xobject);
824
}
825
 
826
static cairo_int_status_t
827
_cairo_pdf_surface_add_font (unsigned int        font_id,
828
			     unsigned int        subset_id,
829
			     void		*closure)
830
{
831
    cairo_pdf_surface_t *surface = closure;
832
    cairo_pdf_font_t font;
833
    int num_fonts, i;
834
    cairo_int_status_t status;
835
    cairo_pdf_group_resources_t *res = &surface->resources;
836
 
837
    num_fonts = _cairo_array_num_elements (&res->fonts);
838
    for (i = 0; i < num_fonts; i++) {
839
	_cairo_array_copy_element (&res->fonts, i, &font);
840
	if (font.font_id == font_id &&
841
	    font.subset_id == subset_id)
842
	    return CAIRO_STATUS_SUCCESS;
843
    }
844
 
845
    num_fonts = _cairo_array_num_elements (&surface->fonts);
846
    for (i = 0; i < num_fonts; i++) {
847
	_cairo_array_copy_element (&surface->fonts, i, &font);
848
	if (font.font_id == font_id &&
849
	    font.subset_id == subset_id)
850
	    return _cairo_array_append (&res->fonts, &font);
851
    }
852
 
853
    font.font_id = font_id;
854
    font.subset_id = subset_id;
855
    font.subset_resource = _cairo_pdf_surface_new_object (surface);
856
    if (font.subset_resource.id == 0)
857
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
858
 
859
    status = _cairo_array_append (&surface->fonts, &font);
860
    if (unlikely (status))
861
	return status;
862
 
863
    return _cairo_array_append (&res->fonts, &font);
864
}
865
 
866
static cairo_pdf_resource_t
867
_cairo_pdf_surface_get_font_resource (cairo_pdf_surface_t *surface,
868
				      unsigned int         font_id,
869
				      unsigned int         subset_id)
870
{
871
    cairo_pdf_font_t font;
872
    int num_fonts, i;
873
 
874
    num_fonts = _cairo_array_num_elements (&surface->fonts);
875
    for (i = 0; i < num_fonts; i++) {
876
	_cairo_array_copy_element (&surface->fonts, i, &font);
877
	if (font.font_id == font_id && font.subset_id == subset_id)
878
	    return font.subset_resource;
879
    }
880
 
881
    font.subset_resource.id = 0;
882
    return font.subset_resource;
883
}
884
 
885
static const char *
886
_cairo_operator_to_pdf_blend_mode (cairo_operator_t op)
887
{
888
    switch (op) {
889
    /* The extend blend mode operators */
890
    case CAIRO_OPERATOR_MULTIPLY:       return "Multiply";
891
    case CAIRO_OPERATOR_SCREEN:         return "Screen";
892
    case CAIRO_OPERATOR_OVERLAY:        return "Overlay";
893
    case CAIRO_OPERATOR_DARKEN:         return "Darken";
894
    case CAIRO_OPERATOR_LIGHTEN:        return "Lighten";
895
    case CAIRO_OPERATOR_COLOR_DODGE:    return "ColorDodge";
896
    case CAIRO_OPERATOR_COLOR_BURN:     return "ColorBurn";
897
    case CAIRO_OPERATOR_HARD_LIGHT:     return "HardLight";
898
    case CAIRO_OPERATOR_SOFT_LIGHT:     return "SoftLight";
899
    case CAIRO_OPERATOR_DIFFERENCE:     return "Difference";
900
    case CAIRO_OPERATOR_EXCLUSION:      return "Exclusion";
901
    case CAIRO_OPERATOR_HSL_HUE:        return "Hue";
902
    case CAIRO_OPERATOR_HSL_SATURATION: return "Saturation";
903
    case CAIRO_OPERATOR_HSL_COLOR:      return "Color";
904
    case CAIRO_OPERATOR_HSL_LUMINOSITY: return "Luminosity";
905
 
906
    default:
907
    /* The original Porter-Duff set */
908
    case CAIRO_OPERATOR_CLEAR:
909
    case CAIRO_OPERATOR_SOURCE:
910
    case CAIRO_OPERATOR_OVER:
911
    case CAIRO_OPERATOR_IN:
912
    case CAIRO_OPERATOR_OUT:
913
    case CAIRO_OPERATOR_ATOP:
914
    case CAIRO_OPERATOR_DEST:
915
    case CAIRO_OPERATOR_DEST_OVER:
916
    case CAIRO_OPERATOR_DEST_IN:
917
    case CAIRO_OPERATOR_DEST_OUT:
918
    case CAIRO_OPERATOR_DEST_ATOP:
919
    case CAIRO_OPERATOR_XOR:
920
    case CAIRO_OPERATOR_ADD:
921
    case CAIRO_OPERATOR_SATURATE:
922
	return "Normal";
923
    }
924
}
925
 
926
static void
927
_cairo_pdf_surface_emit_group_resources (cairo_pdf_surface_t         *surface,
928
					 cairo_pdf_group_resources_t *res)
929
{
930
    int num_alphas, num_smasks, num_resources, i;
931
    double alpha;
932
    cairo_pdf_resource_t *smask, *pattern, *shading, *xobject;
933
    cairo_pdf_font_t *font;
934
 
935
    _cairo_output_stream_printf (surface->output, "<<\n");
936
 
937
    num_alphas = _cairo_array_num_elements (&res->alphas);
938
    num_smasks = _cairo_array_num_elements (&res->smasks);
939
    if (num_alphas > 0 || num_smasks > 0) {
940
	_cairo_output_stream_printf (surface->output,
941
				     "   /ExtGState <<\n");
942
 
943
	for (i = 0; i < CAIRO_NUM_OPERATORS; i++) {
944
	    if (res->operators[i]) {
945
		_cairo_output_stream_printf (surface->output,
946
					     "      /b%d << /BM /%s >>\n",
947
					     i, _cairo_operator_to_pdf_blend_mode(i));
948
	    }
949
	}
950
 
951
	for (i = 0; i < num_alphas; i++) {
952
	    _cairo_array_copy_element (&res->alphas, i, &alpha);
953
	    _cairo_output_stream_printf (surface->output,
954
					 "      /a%d << /CA %f /ca %f >>\n",
955
					 i, alpha, alpha);
956
	}
957
 
958
	for (i = 0; i < num_smasks; i++) {
959
	    smask = _cairo_array_index (&res->smasks, i);
960
	    _cairo_output_stream_printf (surface->output,
961
					 "      /s%d %d 0 R\n",
962
					 smask->id, smask->id);
963
	}
964
 
965
	_cairo_output_stream_printf (surface->output,
966
				     "   >>\n");
967
    }
968
 
969
    num_resources = _cairo_array_num_elements (&res->patterns);
970
    if (num_resources > 0) {
971
	_cairo_output_stream_printf (surface->output,
972
				     "   /Pattern <<");
973
	for (i = 0; i < num_resources; i++) {
974
	    pattern = _cairo_array_index (&res->patterns, i);
975
	    _cairo_output_stream_printf (surface->output,
976
					 " /p%d %d 0 R",
977
					 pattern->id, pattern->id);
978
	}
979
 
980
	_cairo_output_stream_printf (surface->output,
981
				     " >>\n");
982
    }
983
 
984
    num_resources = _cairo_array_num_elements (&res->shadings);
985
    if (num_resources > 0) {
986
	_cairo_output_stream_printf (surface->output,
987
				     "   /Shading <<");
988
	for (i = 0; i < num_resources; i++) {
989
	    shading = _cairo_array_index (&res->shadings, i);
990
	    _cairo_output_stream_printf (surface->output,
991
					 " /sh%d %d 0 R",
992
					 shading->id, shading->id);
993
	}
994
 
995
	_cairo_output_stream_printf (surface->output,
996
				     " >>\n");
997
    }
998
 
999
    num_resources = _cairo_array_num_elements (&res->xobjects);
1000
    if (num_resources > 0) {
1001
	_cairo_output_stream_printf (surface->output,
1002
				     "   /XObject <<");
1003
 
1004
	for (i = 0; i < num_resources; i++) {
1005
	    xobject = _cairo_array_index (&res->xobjects, i);
1006
	    _cairo_output_stream_printf (surface->output,
1007
					 " /x%d %d 0 R",
1008
					 xobject->id, xobject->id);
1009
	}
1010
 
1011
	_cairo_output_stream_printf (surface->output,
1012
				     " >>\n");
1013
    }
1014
 
1015
    num_resources = _cairo_array_num_elements (&res->fonts);
1016
    if (num_resources > 0) {
1017
	_cairo_output_stream_printf (surface->output,"   /Font <<\n");
1018
	for (i = 0; i < num_resources; i++) {
1019
	    font = _cairo_array_index (&res->fonts, i);
1020
	    _cairo_output_stream_printf (surface->output,
1021
					 "      /f-%d-%d %d 0 R\n",
1022
					 font->font_id,
1023
					 font->subset_id,
1024
					 font->subset_resource.id);
1025
	}
1026
	_cairo_output_stream_printf (surface->output, "   >>\n");
1027
    }
1028
 
1029
    _cairo_output_stream_printf (surface->output,
1030
				 ">>\n");
1031
}
1032
 
1033
static cairo_pdf_smask_group_t *
1034
_cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t	    *surface,
1035
				       const cairo_rectangle_int_t  *extents)
1036
{
1037
    cairo_pdf_smask_group_t	*group;
1038
 
1039
    group = calloc (1, sizeof (cairo_pdf_smask_group_t));
1040
    if (unlikely (group == NULL)) {
1041
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
1042
	return NULL;
1043
    }
1044
 
1045
    group->group_res = _cairo_pdf_surface_new_object (surface);
1046
    if (group->group_res.id == 0) {
1047
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
1048
	free (group);
1049
	return NULL;
1050
    }
1051
    group->width = surface->width;
1052
    group->height = surface->height;
1053
    if (extents != NULL) {
1054
	group->extents = *extents;
1055
    } else {
1056
	group->extents.x = 0;
1057
	group->extents.y = 0;
1058
	group->extents.width = surface->width;
1059
	group->extents.height = surface->height;
1060
    }
1061
    group->extents = *extents;
1062
 
1063
    return group;
1064
}
1065
 
1066
static void
1067
_cairo_pdf_smask_group_destroy (cairo_pdf_smask_group_t *group)
1068
{
1069
    if (group->operation == PDF_FILL ||	group->operation == PDF_STROKE)
1070
	_cairo_path_fixed_fini (&group->path);
1071
    if (group->source)
1072
	cairo_pattern_destroy (group->source);
1073
    if (group->mask)
1074
	cairo_pattern_destroy (group->mask);
1075
    free (group->utf8);
1076
    free (group->glyphs);
1077
    free (group->clusters);
1078
    if (group->scaled_font)
1079
	cairo_scaled_font_destroy (group->scaled_font);
1080
    free (group);
1081
}
1082
 
1083
static cairo_int_status_t
1084
_cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t     *surface,
1085
				    cairo_pdf_smask_group_t *group)
1086
{
1087
    return _cairo_array_append (&surface->smask_groups, &group);
1088
}
1089
 
1090
static cairo_bool_t
1091
_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b)
1092
{
1093
    const cairo_pdf_source_surface_entry_t *a = key_a;
1094
    const cairo_pdf_source_surface_entry_t *b = key_b;
1095
 
1096
    if (a->interpolate != b->interpolate)
1097
	return FALSE;
1098
 
1099
    if (a->unique_id && b->unique_id && a->unique_id_length == b->unique_id_length)
1100
	return (memcmp (a->unique_id, b->unique_id, a->unique_id_length) == 0);
1101
 
1102
    return (a->id == b->id);
1103
}
1104
 
1105
static void
1106
_cairo_pdf_source_surface_init_key (cairo_pdf_source_surface_entry_t *key)
1107
{
1108
    if (key->unique_id && key->unique_id_length > 0) {
1109
	key->base.hash = _cairo_hash_bytes (_CAIRO_HASH_INIT_VALUE,
1110
					    key->unique_id, key->unique_id_length);
1111
    } else {
1112
	key->base.hash = key->id;
1113
    }
1114
}
1115
 
1116
static cairo_int_status_t
1117
_cairo_pdf_surface_acquire_source_image_from_pattern (cairo_pdf_surface_t          *surface,
1118
						      const cairo_pattern_t        *pattern,
1119
						      cairo_image_surface_t       **image,
1120
						      void                        **image_extra)
1121
{
1122
    switch (pattern->type) {
1123
    case CAIRO_PATTERN_TYPE_SURFACE: {
1124
	cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern;
1125
	return _cairo_surface_acquire_source_image (surf_pat->surface, image, image_extra);
1126
    } break;
1127
 
1128
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE: {
1129
	cairo_surface_t *surf;
1130
	surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, NULL);
1131
	if (!surf)
1132
	    return CAIRO_INT_STATUS_UNSUPPORTED;
1133
	assert (_cairo_surface_is_image (surf));
1134
	*image = (cairo_image_surface_t *) surf;
1135
    } break;
1136
 
1137
    case CAIRO_PATTERN_TYPE_SOLID:
1138
    case CAIRO_PATTERN_TYPE_LINEAR:
1139
    case CAIRO_PATTERN_TYPE_RADIAL:
1140
    case CAIRO_PATTERN_TYPE_MESH:
1141
    default:
1142
	ASSERT_NOT_REACHED;
1143
	break;
1144
    }
1145
 
1146
    return CAIRO_STATUS_SUCCESS;
1147
}
1148
 
1149
static void
1150
_cairo_pdf_surface_release_source_image_from_pattern (cairo_pdf_surface_t          *surface,
1151
						      const cairo_pattern_t        *pattern,
1152
						      cairo_image_surface_t        *image,
1153
						      void                         *image_extra)
1154
{
1155
    switch (pattern->type) {
1156
    case CAIRO_PATTERN_TYPE_SURFACE: {
1157
	cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern;
1158
	_cairo_surface_release_source_image (surf_pat->surface, image, image_extra);
1159
    } break;
1160
 
1161
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
1162
	_cairo_raster_source_pattern_release (pattern, &image->base);
1163
	break;
1164
 
1165
    case CAIRO_PATTERN_TYPE_SOLID:
1166
    case CAIRO_PATTERN_TYPE_LINEAR:
1167
    case CAIRO_PATTERN_TYPE_RADIAL:
1168
    case CAIRO_PATTERN_TYPE_MESH:
1169
    default:
1170
 
1171
	ASSERT_NOT_REACHED;
1172
	break;
1173
    }
1174
}
1175
 
1176
static cairo_int_status_t
1177
_get_jpx_image_info (cairo_surface_t		 *source,
1178
		     cairo_image_info_t		*info,
1179
		     const unsigned char	**mime_data,
1180
		     unsigned long		 *mime_data_length)
1181
{
1182
    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
1183
				 mime_data, mime_data_length);
1184
    if (*mime_data == NULL)
1185
	return CAIRO_INT_STATUS_UNSUPPORTED;
1186
 
1187
    return _cairo_image_info_get_jpx_info (info, *mime_data, *mime_data_length);
1188
}
1189
 
1190
static cairo_int_status_t
1191
_get_jpeg_image_info (cairo_surface_t		 *source,
1192
		      cairo_image_info_t	 *info,
1193
		      const unsigned char	**mime_data,
1194
		      unsigned long		 *mime_data_length)
1195
{
1196
    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
1197
				 mime_data, mime_data_length);
1198
    if (*mime_data == NULL)
1199
	return CAIRO_INT_STATUS_UNSUPPORTED;
1200
 
1201
    return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length);
1202
}
1203
 
1204
static cairo_int_status_t
1205
_get_source_surface_size (cairo_surface_t         *source,
1206
			  int                     *width,
1207
			  int                     *height,
1208
			  cairo_rectangle_int_t   *extents)
1209
{
1210
    cairo_int_status_t status;
1211
    cairo_image_info_t info;
1212
    const unsigned char *mime_data;
1213
    unsigned long mime_data_length;
1214
 
1215
    if (source->type == CAIRO_SURFACE_TYPE_RECORDING) {
1216
	if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
1217
	     cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
1218
 
1219
	     *extents = sub->extents;
1220
	     *width  = extents->width;
1221
	     *height = extents->height;
1222
	} else {
1223
	    cairo_surface_t *free_me = NULL;
1224
	    cairo_rectangle_int_t surf_extents;
1225
	    cairo_box_t box;
1226
	    cairo_bool_t bounded;
1227
 
1228
	    if (_cairo_surface_is_snapshot (source))
1229
		free_me = source = _cairo_surface_snapshot_get_target (source);
1230
 
1231
	    status = _cairo_recording_surface_get_ink_bbox ((cairo_recording_surface_t *)source,
1232
							    &box, NULL);
1233
	    if (unlikely (status)) {
1234
		cairo_surface_destroy (free_me);
1235
		return status;
1236
	    }
1237
 
1238
	    bounded = _cairo_surface_get_extents (source, &surf_extents);
1239
	    cairo_surface_destroy (free_me);
1240
 
1241
	    *width = surf_extents.width;
1242
	    *height = surf_extents.height;
1243
 
1244
	    _cairo_box_round_to_rectangle (&box, extents);
1245
	}
1246
 
1247
	return CAIRO_STATUS_SUCCESS;
1248
    }
1249
 
1250
    extents->x = 0;
1251
    extents->y = 0;
1252
 
1253
    status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
1254
    if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
1255
	*width = info.width;
1256
	*height = info.height;
1257
	extents->width = info.width;
1258
	extents->height = info.height;
1259
	return status;
1260
    }
1261
 
1262
    status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
1263
    if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
1264
	*width = info.width;
1265
	*height = info.height;
1266
	extents->width = info.width;
1267
	extents->height = info.height;
1268
	return status;
1269
    }
1270
 
1271
    if (! _cairo_surface_get_extents (source, extents))
1272
	return CAIRO_INT_STATUS_UNSUPPORTED;
1273
 
1274
    *width = extents->width;
1275
    *height = extents->height;
1276
 
1277
    return CAIRO_STATUS_SUCCESS;
1278
}
1279
 
1280
/**
1281
 * _cairo_pdf_surface_add_source_surface:
1282
 * @surface: the pdf surface
1283
 * @source_surface: A #cairo_surface_t to use as the source surface
1284
 * @source_pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
1285
 * @filter: filter type of the source pattern
1286
 * @stencil_mask: if true, the surface will be written to the PDF as an /ImageMask
1287
 * @extents: extents of the operation that is using this source
1288
 * @surface_res: return PDF resource number of the surface
1289
 * @width: returns width of surface
1290
 * @height: returns height of surface
1291
 * @x_offset: x offset of surface
1292
 * @t_offset: y offset of surface
1293
 * @source_extents: returns extents of source (either ink extents or extents needed to cover @extents)
1294
 *
1295
 * Add surface or raster_source pattern to list of surfaces to be
1296
 * written to the PDF file when the current page is finished. Returns
1297
 * a PDF resource to reference the image. A hash table of all images
1298
 * in the PDF files (keyed by CAIRO_MIME_TYPE_UNIQUE_ID or surface
1299
 * unique_id) to ensure surfaces with the same id are only written
1300
 * once to the PDF file.
1301
 *
1302
 * Only one of @source_pattern or @source_surface is to be
1303
 * specified. Set the other to NULL.
1304
 **/
1305
static cairo_int_status_t
1306
_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t	    *surface,
1307
				       cairo_surface_t	            *source_surface,
1308
				       const cairo_pattern_t	    *source_pattern,
1309
				       cairo_filter_t		     filter,
1310
				       cairo_bool_t                  stencil_mask,
1311
				       const cairo_rectangle_int_t  *extents,
1312
				       cairo_pdf_resource_t	    *surface_res,
1313
				       int                          *width,
1314
				       int                          *height,
1315
				       double                       *x_offset,
1316
				       double                       *y_offset,
1317
				       cairo_rectangle_int_t        *source_extents)
1318
{
1319
    cairo_pdf_source_surface_t src_surface;
1320
    cairo_pdf_source_surface_entry_t surface_key;
1321
    cairo_pdf_source_surface_entry_t *surface_entry;
1322
    cairo_int_status_t status;
1323
    cairo_bool_t interpolate;
1324
    unsigned char *unique_id = NULL;
1325
    unsigned long unique_id_length = 0;
1326
    cairo_image_surface_t *image;
1327
    void *image_extra;
1328
 
1329
    switch (filter) {
1330
    default:
1331
    case CAIRO_FILTER_GOOD:
1332
    case CAIRO_FILTER_BEST:
1333
    case CAIRO_FILTER_BILINEAR:
1334
	interpolate = TRUE;
1335
	break;
1336
    case CAIRO_FILTER_FAST:
1337
    case CAIRO_FILTER_NEAREST:
1338
    case CAIRO_FILTER_GAUSSIAN:
1339
	interpolate = FALSE;
1340
	break;
1341
    }
1342
 
1343
    *x_offset = 0;
1344
    *y_offset = 0;
1345
    if (source_pattern) {
1346
	if (source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
1347
	    status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source_pattern,
1348
									   &image, &image_extra);
1349
	    if (unlikely (status))
1350
		return status;
1351
	    source_surface = &image->base;
1352
	    cairo_surface_get_device_offset (source_surface, x_offset, y_offset);
1353
	} else {
1354
	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) source_pattern;
1355
	    source_surface = surface_pattern->surface;
1356
	}
1357
    }
1358
 
1359
    surface_key.id  = source_surface->unique_id;
1360
    surface_key.interpolate = interpolate;
1361
    cairo_surface_get_mime_data (source_surface, CAIRO_MIME_TYPE_UNIQUE_ID,
1362
				 (const unsigned char **) &surface_key.unique_id,
1363
				 &surface_key.unique_id_length);
1364
    _cairo_pdf_source_surface_init_key (&surface_key);
1365
    surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base);
1366
    if (surface_entry) {
1367
	*surface_res = surface_entry->surface_res;
1368
	*width = surface_entry->width;
1369
	*height = surface_entry->height;
1370
	*source_extents = surface_entry->extents;
1371
	status = CAIRO_STATUS_SUCCESS;
1372
    } else {
1373
	status = _get_source_surface_size (source_surface,
1374
					   width,
1375
					   height,
1376
					   source_extents);
1377
	if (unlikely(status))
1378
	    goto release_source;
1379
 
1380
	if (surface_key.unique_id && surface_key.unique_id_length > 0) {
1381
	    unique_id = _cairo_malloc (surface_key.unique_id_length);
1382
	    if (unique_id == NULL) {
1383
		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1384
		goto release_source;
1385
	    }
1386
 
1387
	    unique_id_length = surface_key.unique_id_length;
1388
	    memcpy (unique_id, surface_key.unique_id, unique_id_length);
1389
	} else {
1390
	    unique_id = NULL;
1391
	    unique_id_length = 0;
1392
	}
1393
    }
1394
 
1395
release_source:
1396
    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
1397
	_cairo_pdf_surface_release_source_image_from_pattern (surface, source_pattern, image, image_extra);
1398
 
1399
    if (status || surface_entry)
1400
	return status;
1401
 
1402
    surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t));
1403
    if (surface_entry == NULL) {
1404
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1405
	goto fail1;
1406
    }
1407
 
1408
    surface_entry->id = surface_key.id;
1409
    surface_entry->interpolate = interpolate;
1410
    surface_entry->stencil_mask = stencil_mask;
1411
    surface_entry->unique_id_length = unique_id_length;
1412
    surface_entry->unique_id = unique_id;
1413
    surface_entry->width = *width;
1414
    surface_entry->height = *height;
1415
    surface_entry->extents = *source_extents;
1416
    _cairo_pdf_source_surface_init_key (surface_entry);
1417
 
1418
    src_surface.hash_entry = surface_entry;
1419
    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE) {
1420
	src_surface.type = CAIRO_PATTERN_TYPE_RASTER_SOURCE;
1421
	src_surface.surface = NULL;
1422
	status = _cairo_pattern_create_copy (&src_surface.raster_pattern, source_pattern);
1423
	if (unlikely (status))
1424
	    goto fail2;
1425
 
1426
    } else {
1427
	src_surface.type = CAIRO_PATTERN_TYPE_SURFACE;
1428
	src_surface.surface = cairo_surface_reference (source_surface);
1429
	src_surface.raster_pattern = NULL;
1430
    }
1431
 
1432
    surface_entry->surface_res = _cairo_pdf_surface_new_object (surface);
1433
    if (surface_entry->surface_res.id == 0) {
1434
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1435
	goto fail3;
1436
    }
1437
 
1438
    status = _cairo_array_append (&surface->page_surfaces, &src_surface);
1439
    if (unlikely (status))
1440
	goto fail3;
1441
 
1442
    status = _cairo_hash_table_insert (surface->all_surfaces,
1443
				       &surface_entry->base);
1444
    if (unlikely(status))
1445
	goto fail3;
1446
 
1447
    *surface_res = surface_entry->surface_res;
1448
 
1449
    return status;
1450
 
1451
fail3:
1452
    if (source_pattern && source_pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
1453
	cairo_pattern_destroy (src_surface.raster_pattern);
1454
    else
1455
	cairo_surface_destroy (src_surface.surface);
1456
 
1457
fail2:
1458
    free (surface_entry);
1459
 
1460
fail1:
1461
    free (unique_id);
1462
 
1463
    return status;
1464
}
1465
 
1466
static cairo_int_status_t
1467
_cairo_pdf_surface_add_pdf_pattern_or_shading (cairo_pdf_surface_t	   *surface,
1468
					       const cairo_pattern_t	   *pattern,
1469
					       const cairo_rectangle_int_t *extents,
1470
					       cairo_bool_t                 is_shading,
1471
					       cairo_pdf_resource_t	   *pattern_res,
1472
					       cairo_pdf_resource_t	   *gstate_res)
1473
{
1474
    cairo_pdf_pattern_t pdf_pattern;
1475
    cairo_int_status_t status;
1476
 
1477
    pdf_pattern.is_shading = is_shading;
1478
 
1479
    /* Solid colors are emitted into the content stream */
1480
    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
1481
	pattern_res->id = 0;
1482
	gstate_res->id = 0;
1483
	return CAIRO_INT_STATUS_SUCCESS;
1484
    }
1485
 
1486
    status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern);
1487
    if (unlikely (status))
1488
	return status;
1489
 
1490
    pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface);
1491
    if (pdf_pattern.pattern_res.id == 0) {
1492
	cairo_pattern_destroy (pdf_pattern.pattern);
1493
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1494
    }
1495
 
1496
    pdf_pattern.gstate_res.id = 0;
1497
 
1498
    /* gradient patterns require an smask object to implement transparency */
1499
    if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR ||
1500
	pattern->type == CAIRO_PATTERN_TYPE_RADIAL ||
1501
	pattern->type == CAIRO_PATTERN_TYPE_MESH)
1502
    {
1503
	double min_alpha;
1504
 
1505
	_cairo_pattern_alpha_range (pattern, &min_alpha, NULL);
1506
	if (! CAIRO_ALPHA_IS_OPAQUE (min_alpha)) {
1507
            pdf_pattern.gstate_res = _cairo_pdf_surface_new_object (surface);
1508
	    if (pdf_pattern.gstate_res.id == 0) {
1509
		cairo_pattern_destroy (pdf_pattern.pattern);
1510
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1511
	    }
1512
        }
1513
    }
1514
 
1515
    pdf_pattern.width  = surface->width;
1516
    pdf_pattern.height = surface->height;
1517
    if (extents != NULL) {
1518
	pdf_pattern.extents = *extents;
1519
    } else {
1520
	pdf_pattern.extents.x = 0;
1521
	pdf_pattern.extents.y = 0;
1522
	pdf_pattern.extents.width  = surface->width;
1523
	pdf_pattern.extents.height = surface->height;
1524
    }
1525
 
1526
    *pattern_res = pdf_pattern.pattern_res;
1527
    *gstate_res = pdf_pattern.gstate_res;
1528
 
1529
    status = _cairo_array_append (&surface->page_patterns, &pdf_pattern);
1530
    if (unlikely (status)) {
1531
	cairo_pattern_destroy (pdf_pattern.pattern);
1532
	return status;
1533
    }
1534
 
1535
    return CAIRO_INT_STATUS_SUCCESS;
1536
}
1537
 
1538
/* Get BBox in PDF coordinates from extents in cairo coordinates */
1539
static void
1540
_get_bbox_from_extents (double                       surface_height,
1541
		       const cairo_rectangle_int_t *extents,
1542
		       cairo_box_double_t          *bbox)
1543
{
1544
    bbox->p1.x = extents->x;
1545
    bbox->p1.y = surface_height - (extents->y + extents->height);
1546
    bbox->p2.x = extents->x + extents->width;
1547
    bbox->p2.y = surface_height - extents->y;
1548
}
1549
 
1550
static cairo_int_status_t
1551
_cairo_pdf_surface_add_pdf_shading (cairo_pdf_surface_t		*surface,
1552
				    const cairo_pattern_t	*pattern,
1553
				    const cairo_rectangle_int_t	*extents,
1554
				    cairo_pdf_resource_t	*shading_res,
1555
				    cairo_pdf_resource_t	*gstate_res)
1556
{
1557
    return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
1558
							  pattern,
1559
							  extents,
1560
							  TRUE,
1561
							  shading_res,
1562
							  gstate_res);
1563
}
1564
 
1565
static cairo_int_status_t
1566
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t		*surface,
1567
				    const cairo_pattern_t	*pattern,
1568
				    const cairo_rectangle_int_t	*extents,
1569
				    cairo_pdf_resource_t	*pattern_res,
1570
				    cairo_pdf_resource_t	*gstate_res)
1571
{
1572
    return _cairo_pdf_surface_add_pdf_pattern_or_shading (surface,
1573
							  pattern,
1574
							  extents,
1575
							  FALSE,
1576
							  pattern_res,
1577
							  gstate_res);
1578
}
1579
 
1580
static cairo_int_status_t
1581
_cairo_pdf_surface_open_stream (cairo_pdf_surface_t	*surface,
1582
				cairo_pdf_resource_t    *resource,
1583
				cairo_bool_t             compressed,
1584
				const char		*fmt,
1585
				...)
1586
{
1587
    va_list ap;
1588
    cairo_pdf_resource_t self, length;
1589
    cairo_output_stream_t *output = NULL;
1590
 
1591
    if (resource) {
1592
	self = *resource;
1593
	_cairo_pdf_surface_update_object (surface, self);
1594
    } else {
1595
	self = _cairo_pdf_surface_new_object (surface);
1596
	if (self.id == 0)
1597
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1598
    }
1599
 
1600
    length = _cairo_pdf_surface_new_object (surface);
1601
    if (length.id == 0)
1602
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1603
 
1604
    if (compressed) {
1605
	output = _cairo_deflate_stream_create (surface->output);
1606
	if (_cairo_output_stream_get_status (output))
1607
	    return _cairo_output_stream_destroy (output);
1608
    }
1609
 
1610
    surface->pdf_stream.active = TRUE;
1611
    surface->pdf_stream.self = self;
1612
    surface->pdf_stream.length = length;
1613
    surface->pdf_stream.compressed = compressed;
1614
    surface->current_pattern_is_solid_color = FALSE;
1615
    surface->current_operator = CAIRO_OPERATOR_OVER;
1616
    _cairo_pdf_operators_reset (&surface->pdf_operators);
1617
 
1618
    _cairo_output_stream_printf (surface->output,
1619
				 "%d 0 obj\n"
1620
				 "<< /Length %d 0 R\n",
1621
				 surface->pdf_stream.self.id,
1622
				 surface->pdf_stream.length.id);
1623
    if (compressed)
1624
	_cairo_output_stream_printf (surface->output,
1625
				     "   /Filter /FlateDecode\n");
1626
 
1627
    if (fmt != NULL) {
1628
	va_start (ap, fmt);
1629
	_cairo_output_stream_vprintf (surface->output, fmt, ap);
1630
	va_end (ap);
1631
    }
1632
 
1633
    _cairo_output_stream_printf (surface->output,
1634
				 ">>\n"
1635
				 "stream\n");
1636
 
1637
    surface->pdf_stream.start_offset = _cairo_output_stream_get_position (surface->output);
1638
 
1639
    if (compressed) {
1640
	assert (surface->pdf_stream.old_output == NULL);
1641
        surface->pdf_stream.old_output = surface->output;
1642
        surface->output = output;
1643
	_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
1644
    }
1645
 
1646
    return _cairo_output_stream_get_status (surface->output);
1647
}
1648
 
1649
static cairo_int_status_t
1650
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
1651
{
1652
    cairo_int_status_t status;
1653
    long length;
1654
 
1655
    if (! surface->pdf_stream.active)
1656
	return CAIRO_INT_STATUS_SUCCESS;
1657
 
1658
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
1659
 
1660
    if (surface->pdf_stream.compressed) {
1661
	cairo_int_status_t status2;
1662
 
1663
	status2 = _cairo_output_stream_destroy (surface->output);
1664
	if (likely (status == CAIRO_INT_STATUS_SUCCESS))
1665
	    status = status2;
1666
 
1667
	surface->output = surface->pdf_stream.old_output;
1668
	_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
1669
	surface->pdf_stream.old_output = NULL;
1670
    }
1671
 
1672
    length = _cairo_output_stream_get_position (surface->output) -
1673
	surface->pdf_stream.start_offset;
1674
    _cairo_output_stream_printf (surface->output,
1675
				 "\n"
1676
				 "endstream\n"
1677
				 "endobj\n");
1678
 
1679
    _cairo_pdf_surface_update_object (surface,
1680
				      surface->pdf_stream.length);
1681
    _cairo_output_stream_printf (surface->output,
1682
				 "%d 0 obj\n"
1683
				 "   %ld\n"
1684
				 "endobj\n",
1685
				 surface->pdf_stream.length.id,
1686
				 length);
1687
 
1688
    surface->pdf_stream.active = FALSE;
1689
 
1690
    if (likely (status == CAIRO_INT_STATUS_SUCCESS))
1691
	status = _cairo_output_stream_get_status (surface->output);
1692
 
1693
    return status;
1694
}
1695
 
1696
static void
1697
_cairo_pdf_surface_write_memory_stream (cairo_pdf_surface_t         *surface,
1698
					cairo_output_stream_t       *mem_stream,
1699
					cairo_pdf_resource_t         resource,
1700
					cairo_pdf_group_resources_t *resources,
1701
					cairo_bool_t                 is_knockout_group,
1702
					const cairo_box_double_t    *bbox)
1703
{
1704
    _cairo_pdf_surface_update_object (surface, resource);
1705
 
1706
    _cairo_output_stream_printf (surface->output,
1707
				 "%d 0 obj\n"
1708
				 "<< /Type /XObject\n"
1709
				 "   /Length %d\n",
1710
				 resource.id,
1711
				 _cairo_memory_stream_length (mem_stream));
1712
 
1713
    if (surface->compress_content) {
1714
	_cairo_output_stream_printf (surface->output,
1715
				     "   /Filter /FlateDecode\n");
1716
    }
1717
 
1718
    _cairo_output_stream_printf (surface->output,
1719
				 "   /Subtype /Form\n"
1720
				 "   /BBox [ %f %f %f %f ]\n"
1721
				 "   /Group <<\n"
1722
				 "      /Type /Group\n"
1723
				 "      /S /Transparency\n"
1724
				 "      /I true\n"
1725
				 "      /CS /DeviceRGB\n",
1726
				 bbox->p1.x, bbox->p1.y, bbox->p2.x, bbox->p2.y);
1727
 
1728
    if (is_knockout_group)
1729
        _cairo_output_stream_printf (surface->output,
1730
                                     "      /K true\n");
1731
 
1732
    _cairo_output_stream_printf (surface->output,
1733
				 "   >>\n"
1734
				 "   /Resources\n");
1735
    _cairo_pdf_surface_emit_group_resources (surface, resources);
1736
    _cairo_output_stream_printf (surface->output,
1737
				 ">>\n"
1738
				 "stream\n");
1739
    _cairo_memory_stream_copy (mem_stream, surface->output);
1740
    _cairo_output_stream_printf (surface->output,
1741
				 "endstream\n"
1742
				 "endobj\n");
1743
}
1744
 
1745
static cairo_int_status_t
1746
_cairo_pdf_surface_open_group (cairo_pdf_surface_t         *surface,
1747
			       const cairo_box_double_t    *bbox,
1748
			       cairo_pdf_resource_t        *resource)
1749
{
1750
    cairo_int_status_t status;
1751
 
1752
    assert (surface->pdf_stream.active == FALSE);
1753
    assert (surface->group_stream.active == FALSE);
1754
 
1755
    surface->group_stream.active = TRUE;
1756
    surface->current_pattern_is_solid_color = FALSE;
1757
    surface->current_operator = CAIRO_OPERATOR_OVER;
1758
    _cairo_pdf_operators_reset (&surface->pdf_operators);
1759
 
1760
    surface->group_stream.mem_stream = _cairo_memory_stream_create ();
1761
 
1762
    if (surface->compress_content) {
1763
	surface->group_stream.stream =
1764
	    _cairo_deflate_stream_create (surface->group_stream.mem_stream);
1765
    } else {
1766
	surface->group_stream.stream = surface->group_stream.mem_stream;
1767
    }
1768
    status = _cairo_output_stream_get_status (surface->group_stream.stream);
1769
 
1770
    surface->group_stream.old_output = surface->output;
1771
    surface->output = surface->group_stream.stream;
1772
    _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
1773
    _cairo_pdf_group_resources_clear (&surface->resources);
1774
 
1775
    if (resource) {
1776
	surface->group_stream.resource = *resource;
1777
    } else {
1778
	surface->group_stream.resource = _cairo_pdf_surface_new_object (surface);
1779
	if (surface->group_stream.resource.id == 0)
1780
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1781
    }
1782
    surface->group_stream.is_knockout = FALSE;
1783
    surface->group_stream.bbox = *bbox;
1784
 
1785
    return status;
1786
}
1787
 
1788
static cairo_int_status_t
1789
_cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t         *surface,
1790
					const cairo_box_double_t    *bbox)
1791
{
1792
    cairo_int_status_t status;
1793
 
1794
    status = _cairo_pdf_surface_open_group (surface, bbox, NULL);
1795
    if (unlikely (status))
1796
	return status;
1797
 
1798
    surface->group_stream.is_knockout = TRUE;
1799
 
1800
    return CAIRO_INT_STATUS_SUCCESS;
1801
}
1802
 
1803
static cairo_int_status_t
1804
_cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
1805
				cairo_pdf_resource_t *group)
1806
{
1807
    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS, status2;
1808
 
1809
    assert (surface->pdf_stream.active == FALSE);
1810
    assert (surface->group_stream.active == TRUE);
1811
 
1812
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
1813
    if (unlikely (status))
1814
	return status;
1815
 
1816
    if (surface->compress_content) {
1817
	status = _cairo_output_stream_destroy (surface->group_stream.stream);
1818
	surface->group_stream.stream = NULL;
1819
 
1820
	_cairo_output_stream_printf (surface->group_stream.mem_stream,
1821
				     "\n");
1822
    }
1823
    surface->output = surface->group_stream.old_output;
1824
    _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
1825
    surface->group_stream.active = FALSE;
1826
    _cairo_pdf_surface_write_memory_stream (surface,
1827
					    surface->group_stream.mem_stream,
1828
					    surface->group_stream.resource,
1829
					    &surface->resources,
1830
					    surface->group_stream.is_knockout,
1831
					    &surface->group_stream.bbox);
1832
    if (group)
1833
	*group = surface->group_stream.resource;
1834
 
1835
    status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream);
1836
    if (status == CAIRO_INT_STATUS_SUCCESS)
1837
	status = status2;
1838
 
1839
    surface->group_stream.mem_stream = NULL;
1840
    surface->group_stream.stream = NULL;
1841
 
1842
    return status;
1843
}
1844
 
1845
static cairo_int_status_t
1846
_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t       *surface,
1847
					const cairo_box_double_t  *bbox,
1848
					cairo_pdf_resource_t      *resource,
1849
					cairo_bool_t               is_form)
1850
{
1851
    cairo_int_status_t status;
1852
 
1853
    assert (surface->pdf_stream.active == FALSE);
1854
    assert (surface->group_stream.active == FALSE);
1855
 
1856
    surface->content_resources = _cairo_pdf_surface_new_object (surface);
1857
    if (surface->content_resources.id == 0)
1858
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1859
 
1860
    if (is_form) {
1861
	assert (bbox != NULL);
1862
 
1863
	status =
1864
	    _cairo_pdf_surface_open_stream (surface,
1865
					    resource,
1866
					    surface->compress_content,
1867
					    "   /Type /XObject\n"
1868
					    "   /Subtype /Form\n"
1869
					    "   /BBox [ %f %f %f %f ]\n"
1870
					    "   /Group <<\n"
1871
					    "      /Type /Group\n"
1872
					    "      /S /Transparency\n"
1873
					    "      /I true\n"
1874
					    "      /CS /DeviceRGB\n"
1875
					    "   >>\n"
1876
					    "   /Resources %d 0 R\n",
1877
					    bbox->p1.x,
1878
					    bbox->p1.y,
1879
					    bbox->p2.x,
1880
					    bbox->p2.y,
1881
					    surface->content_resources.id);
1882
    } else {
1883
	status =
1884
	    _cairo_pdf_surface_open_stream (surface,
1885
					    resource,
1886
					    surface->compress_content,
1887
					    NULL);
1888
    }
1889
    if (unlikely (status))
1890
	return status;
1891
 
1892
    surface->content = surface->pdf_stream.self;
1893
 
1894
    _cairo_output_stream_printf (surface->output, "q\n");
1895
 
1896
    return _cairo_output_stream_get_status (surface->output);
1897
}
1898
 
1899
static cairo_int_status_t
1900
_cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface)
1901
{
1902
    cairo_int_status_t status;
1903
 
1904
    assert (surface->pdf_stream.active == TRUE);
1905
    assert (surface->group_stream.active == FALSE);
1906
 
1907
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
1908
    if (unlikely (status))
1909
	return status;
1910
 
1911
    _cairo_output_stream_printf (surface->output, "Q\n");
1912
    status = _cairo_pdf_surface_close_stream (surface);
1913
    if (unlikely (status))
1914
	return status;
1915
 
1916
    _cairo_pdf_surface_update_object (surface, surface->content_resources);
1917
    _cairo_output_stream_printf (surface->output,
1918
				 "%d 0 obj\n",
1919
				 surface->content_resources.id);
1920
    _cairo_pdf_surface_emit_group_resources (surface, &surface->resources);
1921
    _cairo_output_stream_printf (surface->output,
1922
				 "endobj\n");
1923
 
1924
    return _cairo_output_stream_get_status (surface->output);
1925
}
1926
 
1927
static void
1928
_cairo_pdf_source_surface_entry_pluck (void *entry, void *closure)
1929
{
1930
    cairo_pdf_source_surface_entry_t *surface_entry = entry;
1931
    cairo_hash_table_t *patterns = closure;
1932
 
1933
    _cairo_hash_table_remove (patterns, &surface_entry->base);
1934
    free (surface_entry->unique_id);
1935
 
1936
    free (surface_entry);
1937
}
1938
 
1939
static cairo_status_t
1940
_cairo_pdf_surface_finish (void *abstract_surface)
1941
{
1942
    cairo_pdf_surface_t *surface = abstract_surface;
1943
    long offset;
1944
    cairo_pdf_resource_t info, catalog;
1945
    cairo_status_t status, status2;
1946
 
1947
    status = surface->base.status;
1948
    if (status == CAIRO_STATUS_SUCCESS)
1949
	status = _cairo_pdf_surface_emit_font_subsets (surface);
1950
 
1951
    _cairo_pdf_surface_write_pages (surface);
1952
 
1953
    info = _cairo_pdf_surface_write_info (surface);
1954
    if (info.id == 0 && status == CAIRO_STATUS_SUCCESS)
1955
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1956
 
1957
    catalog = _cairo_pdf_surface_write_catalog (surface);
1958
    if (catalog.id == 0 && status == CAIRO_STATUS_SUCCESS)
1959
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1960
 
1961
    offset = _cairo_pdf_surface_write_xref (surface);
1962
 
1963
    _cairo_output_stream_printf (surface->output,
1964
				 "trailer\n"
1965
				 "<< /Size %d\n"
1966
				 "   /Root %d 0 R\n"
1967
				 "   /Info %d 0 R\n"
1968
				 ">>\n",
1969
				 surface->next_available_resource.id,
1970
				 catalog.id,
1971
				 info.id);
1972
 
1973
    _cairo_output_stream_printf (surface->output,
1974
				 "startxref\n"
1975
				 "%ld\n"
1976
				 "%%%%EOF\n",
1977
				 offset);
1978
 
1979
    /* pdf_operators has already been flushed when the last stream was
1980
     * closed so we should never be writing anything here - however,
1981
     * the stream may itself be in an error state. */
1982
    status2 = _cairo_pdf_operators_fini (&surface->pdf_operators);
1983
    if (status == CAIRO_STATUS_SUCCESS)
1984
	status = status2;
1985
 
1986
    /* close any active streams still open due to fatal errors */
1987
    status2 = _cairo_pdf_surface_close_stream (surface);
1988
    if (status == CAIRO_STATUS_SUCCESS)
1989
	status = status2;
1990
 
1991
    if (surface->group_stream.stream != NULL) {
1992
	status2 = _cairo_output_stream_destroy (surface->group_stream.stream);
1993
	if (status == CAIRO_STATUS_SUCCESS)
1994
	    status = status2;
1995
    }
1996
    if (surface->group_stream.mem_stream != NULL) {
1997
	status2 = _cairo_output_stream_destroy (surface->group_stream.mem_stream);
1998
	if (status == CAIRO_STATUS_SUCCESS)
1999
	    status = status2;
2000
    }
2001
    if (surface->pdf_stream.active)
2002
	surface->output = surface->pdf_stream.old_output;
2003
    if (surface->group_stream.active)
2004
	surface->output = surface->group_stream.old_output;
2005
 
2006
    /* and finish the pdf surface */
2007
    status2 = _cairo_output_stream_destroy (surface->output);
2008
    if (status == CAIRO_STATUS_SUCCESS)
2009
	status = status2;
2010
 
2011
    _cairo_pdf_surface_clear (surface);
2012
    _cairo_pdf_group_resources_fini (&surface->resources);
2013
 
2014
    _cairo_array_fini (&surface->objects);
2015
    _cairo_array_fini (&surface->pages);
2016
    _cairo_array_fini (&surface->rgb_linear_functions);
2017
    _cairo_array_fini (&surface->alpha_linear_functions);
2018
    _cairo_array_fini (&surface->page_patterns);
2019
    _cairo_array_fini (&surface->page_surfaces);
2020
    _cairo_hash_table_foreach (surface->all_surfaces,
2021
			       _cairo_pdf_source_surface_entry_pluck,
2022
			       surface->all_surfaces);
2023
    _cairo_hash_table_destroy (surface->all_surfaces);
2024
    _cairo_array_fini (&surface->smask_groups);
2025
    _cairo_array_fini (&surface->fonts);
2026
    _cairo_array_fini (&surface->knockout_group);
2027
 
2028
    if (surface->font_subsets) {
2029
	_cairo_scaled_font_subsets_destroy (surface->font_subsets);
2030
	surface->font_subsets = NULL;
2031
    }
2032
 
2033
    _cairo_surface_clipper_reset (&surface->clipper);
2034
 
2035
    return status;
2036
}
2037
 
2038
static cairo_int_status_t
2039
_cairo_pdf_surface_start_page (void *abstract_surface)
2040
{
2041
    cairo_pdf_surface_t *surface = abstract_surface;
2042
 
2043
    /* Document header */
2044
    if (! surface->header_emitted) {
2045
	const char *version;
2046
 
2047
	switch (surface->pdf_version) {
2048
	case CAIRO_PDF_VERSION_1_4:
2049
	    version = "1.4";
2050
	    break;
2051
	default:
2052
	case CAIRO_PDF_VERSION_1_5:
2053
	    version = "1.5";
2054
	    break;
2055
	}
2056
 
2057
	_cairo_output_stream_printf (surface->output,
2058
				     "%%PDF-%s\n", version);
2059
	_cairo_output_stream_printf (surface->output,
2060
				     "%%%c%c%c%c\n", 181, 237, 174, 251);
2061
	surface->header_emitted = TRUE;
2062
    }
2063
 
2064
    _cairo_pdf_group_resources_clear (&surface->resources);
2065
 
2066
    return CAIRO_STATUS_SUCCESS;
2067
}
2068
 
2069
static cairo_int_status_t
2070
_cairo_pdf_surface_has_fallback_images (void		*abstract_surface,
2071
					cairo_bool_t	 has_fallbacks)
2072
{
2073
    cairo_int_status_t status;
2074
    cairo_pdf_surface_t *surface = abstract_surface;
2075
    cairo_box_double_t bbox;
2076
 
2077
    surface->has_fallback_images = has_fallbacks;
2078
    bbox.p1.x = 0;
2079
    bbox.p1.y = 0;
2080
    bbox.p2.x = surface->width;
2081
    bbox.p2.y = surface->height;
2082
    status = _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, has_fallbacks);
2083
    if (unlikely (status))
2084
	return status;
2085
 
2086
    return CAIRO_STATUS_SUCCESS;
2087
}
2088
 
2089
static cairo_bool_t
2090
_cairo_pdf_surface_supports_fine_grained_fallbacks (void *abstract_surface)
2091
{
2092
    return TRUE;
2093
}
2094
 
2095
static cairo_int_status_t
2096
_cairo_pdf_surface_add_padded_image_surface (cairo_pdf_surface_t          *surface,
2097
					     const cairo_pattern_t        *source,
2098
					     const cairo_rectangle_int_t  *extents,
2099
					     cairo_pdf_resource_t         *surface_res,
2100
					     int                          *width,
2101
					     int                          *height,
2102
					     double                       *x_offset,
2103
					     double                       *y_offset)
2104
{
2105
    cairo_image_surface_t *image;
2106
    cairo_surface_t *pad_image;
2107
    void *image_extra;
2108
    cairo_int_status_t status;
2109
    int w, h;
2110
    cairo_rectangle_int_t extents2;
2111
    cairo_box_t box;
2112
    cairo_rectangle_int_t rect;
2113
    cairo_surface_pattern_t pad_pattern;
2114
 
2115
    status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source,
2116
								   &image, &image_extra);
2117
    if (unlikely (status))
2118
        return status;
2119
 
2120
    pad_image = &image->base;
2121
 
2122
    /* get the operation extents in pattern space */
2123
    _cairo_box_from_rectangle (&box, extents);
2124
    _cairo_matrix_transform_bounding_box_fixed (&source->matrix, &box, NULL);
2125
    _cairo_box_round_to_rectangle (&box, &rect);
2126
 
2127
    /* Check if image needs padding to fill extents */
2128
    w = image->width;
2129
    h = image->height;
2130
    if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
2131
	_cairo_fixed_integer_ceil(box.p1.y) < 0 ||
2132
	_cairo_fixed_integer_floor(box.p2.x) > w ||
2133
	_cairo_fixed_integer_floor(box.p2.y) > h)
2134
    {
2135
	pad_image = _cairo_image_surface_create_with_content (image->base.content,
2136
							      rect.width,
2137
							      rect.height);
2138
	if (pad_image->status) {
2139
	    status = pad_image->status;
2140
	    goto BAIL;
2141
	}
2142
 
2143
	_cairo_pattern_init_for_surface (&pad_pattern, &image->base);
2144
	cairo_matrix_init_translate (&pad_pattern.base.matrix, rect.x, rect.y);
2145
	pad_pattern.base.extend = CAIRO_EXTEND_PAD;
2146
	status = _cairo_surface_paint (pad_image,
2147
				       CAIRO_OPERATOR_SOURCE, &pad_pattern.base,
2148
				       NULL);
2149
        _cairo_pattern_fini (&pad_pattern.base);
2150
        if (unlikely (status))
2151
            goto BAIL;
2152
    }
2153
 
2154
    status = _cairo_pdf_surface_add_source_surface (surface,
2155
						    pad_image,
2156
						    NULL,
2157
						    source->filter,
2158
						    FALSE,
2159
						    extents,
2160
						    surface_res,
2161
						    width,
2162
						    height,
2163
						    x_offset,
2164
						    y_offset,
2165
						    &extents2);
2166
    if (unlikely (status))
2167
        goto BAIL;
2168
 
2169
    if (pad_image != &image->base) {
2170
	/* If using a padded image, replace _add_source_surface
2171
	 * x/y_offset with padded image offset. Note:
2172
	 * _add_source_surface only sets a non zero x/y_offset for
2173
	 * RASTER_SOURCE patterns. _add_source_surface will always set
2174
	 * x/y_offset to 0 for surfaces so we can ignore the returned
2175
	 * offset and replace it with the offset required for the
2176
	 * padded image */
2177
	*x_offset = rect.x;
2178
	*y_offset = rect.y;
2179
    }
2180
 
2181
BAIL:
2182
    if (pad_image != &image->base)
2183
        cairo_surface_destroy (pad_image);
2184
 
2185
    _cairo_pdf_surface_release_source_image_from_pattern (surface, source, image, image_extra);
2186
 
2187
    return status;
2188
}
2189
 
2190
/* Emit alpha channel from the image into the given data, providing
2191
 * an id that can be used to reference the resulting SMask object.
2192
 *
2193
 * In the case that the alpha channel happens to be all opaque, then
2194
 * no SMask object will be emitted and *id_ret will be set to 0.
2195
 *
2196
 * When stencil_mask is TRUE, stream_res is an an input specifying the
2197
 * resource to use. When stencil_mask is FALSE, a new resource will be
2198
 * created and returned in stream_res.
2199
 */
2200
static cairo_int_status_t
2201
_cairo_pdf_surface_emit_smask (cairo_pdf_surface_t	*surface,
2202
			       cairo_image_surface_t	*image,
2203
			       cairo_bool_t              stencil_mask,
2204
			       const char               *interpolate,
2205
			       cairo_pdf_resource_t	*stream_res)
2206
{
2207
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
2208
    char *alpha;
2209
    unsigned long alpha_size;
2210
    uint32_t *pixel32;
2211
    uint8_t *pixel8;
2212
    int i, x, y, bit, a;
2213
    cairo_image_transparency_t transparency;
2214
 
2215
    /* This is the only image format we support, which simplifies things. */
2216
    assert (image->format == CAIRO_FORMAT_ARGB32 ||
2217
	    image->format == CAIRO_FORMAT_A8 ||
2218
	    image->format == CAIRO_FORMAT_A1 );
2219
 
2220
    transparency = _cairo_image_analyze_transparency (image);
2221
    if (stencil_mask) {
2222
	assert (transparency == CAIRO_IMAGE_IS_OPAQUE ||
2223
		transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA);
2224
    } else {
2225
	if (transparency == CAIRO_IMAGE_IS_OPAQUE)
2226
	    return status;
2227
    }
2228
 
2229
    if (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA) {
2230
	alpha_size = (image->width + 7) / 8 * image->height;
2231
	alpha = _cairo_malloc_ab ((image->width+7) / 8, image->height);
2232
    } else {
2233
	alpha_size = image->height * image->width;
2234
	alpha = _cairo_malloc_ab (image->height, image->width);
2235
    }
2236
 
2237
    if (unlikely (alpha == NULL)) {
2238
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2239
	goto CLEANUP;
2240
    }
2241
 
2242
    i = 0;
2243
    for (y = 0; y < image->height; y++) {
2244
	if (image->format == CAIRO_FORMAT_A1) {
2245
	    pixel8 = (uint8_t *) (image->data + y * image->stride);
2246
 
2247
	    for (x = 0; x < (image->width + 7) / 8; x++, pixel8++) {
2248
		a = *pixel8;
2249
		a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
2250
		alpha[i++] = a;
2251
	    }
2252
	} else {
2253
	    pixel8 = (uint8_t *) (image->data + y * image->stride);
2254
	    pixel32 = (uint32_t *) (image->data + y * image->stride);
2255
	    bit = 7;
2256
	    for (x = 0; x < image->width; x++) {
2257
		if (image->format == CAIRO_FORMAT_ARGB32) {
2258
		    a = (*pixel32 & 0xff000000) >> 24;
2259
		    pixel32++;
2260
		} else {
2261
		    a = *pixel8;
2262
		    pixel8++;
2263
		}
2264
 
2265
		if (transparency == CAIRO_IMAGE_HAS_ALPHA) {
2266
		    alpha[i++] = a;
2267
		} else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA or CAIRO_IMAGE_IS_OPAQUE */
2268
		    if (bit == 7)
2269
			alpha[i] = 0;
2270
		    if (a != 0)
2271
			alpha[i] |= (1 << bit);
2272
		    bit--;
2273
		    if (bit < 0) {
2274
			bit = 7;
2275
			i++;
2276
		    }
2277
		}
2278
	    }
2279
	    if (bit != 7)
2280
		i++;
2281
	}
2282
    }
2283
 
2284
    if (stencil_mask) {
2285
	status = _cairo_pdf_surface_open_stream (surface,
2286
						 stream_res,
2287
						 TRUE,
2288
						 "   /Type /XObject\n"
2289
						 "   /Subtype /Image\n"
2290
						 "   /ImageMask true\n"
2291
						 "   /Width %d\n"
2292
						 "   /Height %d\n"
2293
						 "   /Interpolate %s\n"
2294
						 "   /BitsPerComponent 1\n"
2295
						 "   /Decode [1 0]\n",
2296
						 image->width, image->height, interpolate);
2297
    } else {
2298
	stream_res->id = 0;
2299
	status = _cairo_pdf_surface_open_stream (surface,
2300
						 NULL,
2301
						 TRUE,
2302
						 "   /Type /XObject\n"
2303
						 "   /Subtype /Image\n"
2304
						 "   /Width %d\n"
2305
						 "   /Height %d\n"
2306
						 "   /ColorSpace /DeviceGray\n"
2307
						 "   /Interpolate %s\n"
2308
						 "   /BitsPerComponent %d\n",
2309
						 image->width, image->height, interpolate,
2310
						 transparency == CAIRO_IMAGE_HAS_ALPHA ? 8 : 1);
2311
    }
2312
    if (unlikely (status))
2313
	goto CLEANUP_ALPHA;
2314
 
2315
    if (!stencil_mask)
2316
	*stream_res = surface->pdf_stream.self;
2317
 
2318
    _cairo_output_stream_write (surface->output, alpha, alpha_size);
2319
    status = _cairo_pdf_surface_close_stream (surface);
2320
 
2321
 CLEANUP_ALPHA:
2322
    free (alpha);
2323
 CLEANUP:
2324
    return status;
2325
}
2326
 
2327
/* Emit image data into the given surface, providing a resource that
2328
 * can be used to reference the data in image_ret. */
2329
static cairo_int_status_t
2330
_cairo_pdf_surface_emit_image (cairo_pdf_surface_t     *surface,
2331
                               cairo_image_surface_t   *image_surf,
2332
                               cairo_pdf_resource_t    *image_res,
2333
			       cairo_filter_t           filter,
2334
			       cairo_bool_t             stencil_mask)
2335
{
2336
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
2337
    char *data;
2338
    unsigned long data_size;
2339
    uint32_t *pixel;
2340
    int i, x, y, bit;
2341
    cairo_pdf_resource_t smask = {0}; /* squelch bogus compiler warning */
2342
    cairo_bool_t need_smask;
2343
    const char *interpolate = "true";
2344
    cairo_image_color_t color;
2345
    cairo_image_surface_t *image;
2346
 
2347
    image  = image_surf;
2348
    if (image->format != CAIRO_FORMAT_RGB24 &&
2349
	image->format != CAIRO_FORMAT_ARGB32 &&
2350
	image->format != CAIRO_FORMAT_A8 &&
2351
	image->format != CAIRO_FORMAT_A1)
2352
    {
2353
	cairo_surface_t *surf;
2354
	cairo_surface_pattern_t pattern;
2355
 
2356
	surf = _cairo_image_surface_create_with_content (image_surf->base.content,
2357
							 image_surf->width,
2358
							 image_surf->height);
2359
	image = (cairo_image_surface_t *) surf;
2360
	if (surf->status) {
2361
	    status = surf->status;
2362
	    goto CLEANUP;
2363
	}
2364
 
2365
	_cairo_pattern_init_for_surface (&pattern, &image_surf->base);
2366
	status = _cairo_surface_paint (surf,
2367
				       CAIRO_OPERATOR_SOURCE, &pattern.base,
2368
				       NULL);
2369
        _cairo_pattern_fini (&pattern.base);
2370
        if (unlikely (status))
2371
            goto CLEANUP;
2372
    }
2373
 
2374
    switch (filter) {
2375
    case CAIRO_FILTER_GOOD:
2376
    case CAIRO_FILTER_BEST:
2377
    case CAIRO_FILTER_BILINEAR:
2378
	interpolate = "true";
2379
	break;
2380
    case CAIRO_FILTER_FAST:
2381
    case CAIRO_FILTER_NEAREST:
2382
    case CAIRO_FILTER_GAUSSIAN:
2383
	interpolate = "false";
2384
	break;
2385
    }
2386
 
2387
    if (stencil_mask)
2388
	return _cairo_pdf_surface_emit_smask (surface, image, stencil_mask, interpolate, image_res);
2389
 
2390
    color = _cairo_image_analyze_color (image);
2391
    switch (color) {
2392
        default:
2393
	case CAIRO_IMAGE_UNKNOWN_COLOR:
2394
	    ASSERT_NOT_REACHED;
2395
	case CAIRO_IMAGE_IS_COLOR:
2396
	    data_size = image->height * image->width * 3;
2397
	    data = _cairo_malloc_abc (image->width, image->height, 3);
2398
	    break;
2399
 
2400
	case CAIRO_IMAGE_IS_GRAYSCALE:
2401
	    data_size = image->height * image->width;
2402
	    data = _cairo_malloc_ab (image->width, image->height);
2403
	    break;
2404
	case CAIRO_IMAGE_IS_MONOCHROME:
2405
	    data_size = (image->width + 7) / 8 * image->height;
2406
	    data = _cairo_malloc_ab ((image->width+7) / 8, image->height);
2407
	    break;
2408
    }
2409
    if (unlikely (data == NULL)) {
2410
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2411
	goto CLEANUP;
2412
    }
2413
 
2414
    i = 0;
2415
    for (y = 0; y < image->height; y++) {
2416
	pixel = (uint32_t *) (image->data + y * image->stride);
2417
 
2418
	bit = 7;
2419
	for (x = 0; x < image->width; x++, pixel++) {
2420
	    int r, g, b;
2421
 
2422
	    /* XXX: We're un-premultiplying alpha here. My reading of the PDF
2423
	     * specification suggests that we should be able to avoid having
2424
	     * to do this by filling in the SMask's Matte dictionary
2425
	     * appropriately, but my attempts to do that so far have
2426
	     * failed. */
2427
	    if (image->format == CAIRO_FORMAT_ARGB32) {
2428
		uint8_t a;
2429
		a = (*pixel & 0xff000000) >> 24;
2430
		if (a == 0) {
2431
		    r = g = b = 0;
2432
		} else {
2433
		    r = (((*pixel & 0xff0000) >> 16) * 255 + a / 2) / a;
2434
		    g = (((*pixel & 0x00ff00) >>  8) * 255 + a / 2) / a;
2435
		    b = (((*pixel & 0x0000ff) >>  0) * 255 + a / 2) / a;
2436
		}
2437
	    } else if (image->format == CAIRO_FORMAT_RGB24) {
2438
		r = (*pixel & 0x00ff0000) >> 16;
2439
		g = (*pixel & 0x0000ff00) >>  8;
2440
		b = (*pixel & 0x000000ff) >>  0;
2441
	    } else {
2442
		r = g = b = 0;
2443
	    }
2444
 
2445
	    switch (color) {
2446
		case CAIRO_IMAGE_IS_COLOR:
2447
		case CAIRO_IMAGE_UNKNOWN_COLOR:
2448
		    data[i++] = r;
2449
		    data[i++] = g;
2450
		    data[i++] = b;
2451
		    break;
2452
 
2453
		case CAIRO_IMAGE_IS_GRAYSCALE:
2454
		    data[i++] = r;
2455
		    break;
2456
 
2457
		case CAIRO_IMAGE_IS_MONOCHROME:
2458
		    if (bit == 7)
2459
			data[i] = 0;
2460
		    if (r != 0)
2461
			data[i] |= (1 << bit);
2462
		    bit--;
2463
		    if (bit < 0) {
2464
			bit = 7;
2465
			i++;
2466
		    }
2467
		    break;
2468
	    }
2469
	}
2470
	if (bit != 7)
2471
	    i++;
2472
    }
2473
 
2474
    need_smask = FALSE;
2475
    if (image->format == CAIRO_FORMAT_ARGB32 ||
2476
	image->format == CAIRO_FORMAT_A8 ||
2477
	image->format == CAIRO_FORMAT_A1) {
2478
	status = _cairo_pdf_surface_emit_smask (surface, image, FALSE, interpolate, &smask);
2479
	if (unlikely (status))
2480
	    goto CLEANUP_RGB;
2481
 
2482
	if (smask.id)
2483
	    need_smask = TRUE;
2484
    }
2485
 
2486
#define IMAGE_DICTIONARY	"   /Type /XObject\n"		\
2487
				"   /Subtype /Image\n"	\
2488
				"   /Width %d\n"		\
2489
				"   /Height %d\n"		\
2490
				"   /ColorSpace %s\n"	\
2491
	                        "   /Interpolate %s\n" \
2492
				"   /BitsPerComponent %d\n"
2493
 
2494
    if (need_smask)
2495
	status = _cairo_pdf_surface_open_stream (surface,
2496
						 image_res,
2497
						 TRUE,
2498
						 IMAGE_DICTIONARY
2499
						 "   /SMask %d 0 R\n",
2500
						 image->width, image->height,
2501
						 color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
2502
						 interpolate,
2503
						 color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8,
2504
						 smask.id);
2505
    else
2506
	status = _cairo_pdf_surface_open_stream (surface,
2507
						 image_res,
2508
						 TRUE,
2509
						 IMAGE_DICTIONARY,
2510
						 image->width, image->height,
2511
						 color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
2512
						 interpolate,
2513
						 color == CAIRO_IMAGE_IS_MONOCHROME? 1 : 8);
2514
    if (unlikely (status))
2515
	goto CLEANUP_RGB;
2516
 
2517
#undef IMAGE_DICTIONARY
2518
 
2519
    _cairo_output_stream_write (surface->output, data, data_size);
2520
    status = _cairo_pdf_surface_close_stream (surface);
2521
 
2522
CLEANUP_RGB:
2523
    free (data);
2524
CLEANUP:
2525
    if (image != image_surf)
2526
	cairo_surface_destroy (&image->base);
2527
 
2528
    return status;
2529
}
2530
 
2531
static cairo_int_status_t
2532
_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t   *surface,
2533
				   cairo_surface_t	 *source,
2534
				   cairo_pdf_resource_t   res)
2535
{
2536
    cairo_int_status_t status;
2537
    const unsigned char *mime_data;
2538
    unsigned long mime_data_length;
2539
    cairo_image_info_t info;
2540
 
2541
    if (surface->pdf_version < CAIRO_PDF_VERSION_1_5)
2542
	return CAIRO_INT_STATUS_UNSUPPORTED;
2543
 
2544
    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
2545
				 &mime_data, &mime_data_length);
2546
    if (mime_data == NULL)
2547
	return CAIRO_INT_STATUS_UNSUPPORTED;
2548
 
2549
    status = _cairo_image_info_get_jpx_info (&info, mime_data, mime_data_length);
2550
    if (status)
2551
	return status;
2552
 
2553
    status = _cairo_pdf_surface_open_stream (surface,
2554
					     &res,
2555
					     FALSE,
2556
					     "   /Type /XObject\n"
2557
					     "   /Subtype /Image\n"
2558
					     "   /Width %d\n"
2559
					     "   /Height %d\n"
2560
					     "   /Filter /JPXDecode\n",
2561
					     info.width,
2562
					     info.height);
2563
    if (status)
2564
	return status;
2565
 
2566
    _cairo_output_stream_write (surface->output, mime_data, mime_data_length);
2567
    status = _cairo_pdf_surface_close_stream (surface);
2568
 
2569
    return status;
2570
}
2571
 
2572
static cairo_int_status_t
2573
_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t   *surface,
2574
				    cairo_surface_t	  *source,
2575
				    cairo_pdf_resource_t   res)
2576
{
2577
    cairo_int_status_t status;
2578
    const unsigned char *mime_data;
2579
    unsigned long mime_data_length;
2580
    cairo_image_info_t info;
2581
    const char *colorspace;
2582
 
2583
    cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
2584
				 &mime_data, &mime_data_length);
2585
    if (unlikely (source->status))
2586
	return source->status;
2587
    if (mime_data == NULL)
2588
	return CAIRO_INT_STATUS_UNSUPPORTED;
2589
 
2590
    status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length);
2591
    if (unlikely (status))
2592
	return status;
2593
 
2594
    switch (info.num_components) {
2595
	case 1:
2596
	    colorspace = "/DeviceGray";
2597
	    break;
2598
	case 3:
2599
	    colorspace = "/DeviceRGB";
2600
	    break;
2601
	case 4:
2602
	    colorspace = "/DeviceCMYK";
2603
	    break;
2604
	default:
2605
	    return CAIRO_INT_STATUS_UNSUPPORTED;
2606
    }
2607
 
2608
    status = _cairo_pdf_surface_open_stream (surface,
2609
					     &res,
2610
					     FALSE,
2611
					     "   /Type /XObject\n"
2612
					     "   /Subtype /Image\n"
2613
					     "   /Width %d\n"
2614
					     "   /Height %d\n"
2615
					     "   /ColorSpace %s\n"
2616
					     "   /BitsPerComponent %d\n"
2617
					     "   /Filter /DCTDecode\n",
2618
					     info.width,
2619
					     info.height,
2620
					     colorspace,
2621
					     info.bits_per_component);
2622
    if (unlikely (status))
2623
	return status;
2624
 
2625
    _cairo_output_stream_write (surface->output, mime_data, mime_data_length);
2626
    status = _cairo_pdf_surface_close_stream (surface);
2627
 
2628
    return status;
2629
}
2630
 
2631
static cairo_int_status_t
2632
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t        *surface,
2633
				       cairo_pdf_source_surface_t *source)
2634
{
2635
    cairo_image_surface_t *image;
2636
    void *image_extra;
2637
    cairo_int_status_t status;
2638
 
2639
    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
2640
	status = _cairo_surface_acquire_source_image (source->surface, &image, &image_extra);
2641
    } else {
2642
	status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, source->raster_pattern,
2643
								       &image, &image_extra);
2644
    }
2645
    if (unlikely (status))
2646
	return status;
2647
 
2648
    if (!source->hash_entry->stencil_mask) {
2649
	status = _cairo_pdf_surface_emit_jpx_image (surface, &image->base, source->hash_entry->surface_res);
2650
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
2651
	    goto release_source;
2652
 
2653
	status = _cairo_pdf_surface_emit_jpeg_image (surface, &image->base, source->hash_entry->surface_res);
2654
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
2655
	    goto release_source;
2656
    }
2657
 
2658
    status = _cairo_pdf_surface_emit_image (surface, image,
2659
					    &source->hash_entry->surface_res,
2660
					    source->hash_entry->interpolate,
2661
					    source->hash_entry->stencil_mask);
2662
 
2663
release_source:
2664
    if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
2665
	_cairo_surface_release_source_image (source->surface, image, image_extra);
2666
    else
2667
	_cairo_pdf_surface_release_source_image_from_pattern (surface, source->raster_pattern,
2668
							      image, image_extra);
2669
 
2670
    return status;
2671
}
2672
 
2673
static cairo_int_status_t
2674
_cairo_pdf_surface_emit_recording_surface (cairo_pdf_surface_t        *surface,
2675
					   cairo_pdf_source_surface_t *pdf_source)
2676
{
2677
    double old_width, old_height;
2678
    cairo_paginated_mode_t old_paginated_mode;
2679
    cairo_surface_clipper_t old_clipper;
2680
    cairo_box_double_t bbox;
2681
    cairo_int_status_t status;
2682
    int alpha = 0;
2683
    cairo_surface_t *free_me = NULL;
2684
    cairo_surface_t *source;
2685
    const cairo_rectangle_int_t *extents;
2686
    int width;
2687
    int height;
2688
    cairo_bool_t is_subsurface;
2689
 
2690
    assert (pdf_source->type == CAIRO_PATTERN_TYPE_SURFACE);
2691
    extents = &pdf_source->hash_entry->extents;
2692
    width = pdf_source->hash_entry->width;
2693
    height = pdf_source->hash_entry->height;
2694
    is_subsurface = FALSE;
2695
    source = pdf_source->surface;
2696
    if (_cairo_surface_is_snapshot (source)) {
2697
	free_me = source = _cairo_surface_snapshot_get_target (source);
2698
    } else if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
2699
	cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
2700
 
2701
	source = sub->target;
2702
	extents = &sub->extents;
2703
	width = extents->width;
2704
	height = extents->height;
2705
	is_subsurface = TRUE;
2706
    }
2707
 
2708
    old_width = surface->width;
2709
    old_height = surface->height;
2710
    old_paginated_mode = surface->paginated_mode;
2711
    old_clipper = surface->clipper;
2712
    _cairo_surface_clipper_init (&surface->clipper,
2713
				 _cairo_pdf_surface_clipper_intersect_clip_path);
2714
 
2715
    _cairo_pdf_surface_set_size_internal (surface, width, height);
2716
 
2717
    /* Patterns are emitted after fallback images. The paginated mode
2718
     * needs to be set to _RENDER while the recording surface is replayed
2719
     * back to this surface.
2720
     */
2721
    surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER;
2722
    _cairo_pdf_group_resources_clear (&surface->resources);
2723
    _get_bbox_from_extents (height, extents, &bbox);
2724
    status = _cairo_pdf_surface_open_content_stream (surface, &bbox, &pdf_source->hash_entry->surface_res, TRUE);
2725
    if (unlikely (status))
2726
	goto err;
2727
 
2728
    if (source->content == CAIRO_CONTENT_COLOR) {
2729
	status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
2730
	if (unlikely (status))
2731
	    goto err;
2732
 
2733
	_cairo_output_stream_printf (surface->output,
2734
				     "q /a%d gs 0 0 0 rg 0 0 %f %f re f Q\n",
2735
				     alpha,
2736
				     surface->width,
2737
				     surface->height);
2738
    }
2739
 
2740
    status = _cairo_recording_surface_replay_region (source,
2741
						     is_subsurface ? extents : NULL,
2742
						     &surface->base,
2743
						     CAIRO_RECORDING_REGION_NATIVE);
2744
    assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
2745
    if (unlikely (status))
2746
	goto err;
2747
 
2748
    status = _cairo_pdf_surface_close_content_stream (surface);
2749
 
2750
    _cairo_surface_clipper_reset (&surface->clipper);
2751
    surface->clipper = old_clipper;
2752
    _cairo_pdf_surface_set_size_internal (surface,
2753
					  old_width,
2754
					  old_height);
2755
    surface->paginated_mode = old_paginated_mode;
2756
 
2757
err:
2758
    cairo_surface_destroy (free_me);
2759
    return status;
2760
}
2761
 
2762
static cairo_int_status_t
2763
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t        *surface,
2764
				 cairo_pdf_source_surface_t *src_surface)
2765
{
2766
    if (src_surface->type == CAIRO_PATTERN_TYPE_SURFACE &&
2767
	src_surface->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
2768
	return _cairo_pdf_surface_emit_recording_surface (surface, src_surface);
2769
 
2770
    return _cairo_pdf_surface_emit_image_surface (surface, src_surface);
2771
}
2772
 
2773
static cairo_int_status_t
2774
_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t	*surface,
2775
					 cairo_pdf_pattern_t	*pdf_pattern)
2776
{
2777
    cairo_pattern_t *pattern = pdf_pattern->pattern;
2778
    cairo_int_status_t status;
2779
    cairo_pdf_resource_t pattern_resource = {0};
2780
    cairo_matrix_t cairo_p2d, pdf_p2d;
2781
    cairo_extend_t extend = cairo_pattern_get_extend (pattern);
2782
    double xstep, ystep;
2783
    cairo_rectangle_int_t pattern_extents;
2784
    int pattern_width = 0; /* squelch bogus compiler warning */
2785
    int pattern_height = 0; /* squelch bogus compiler warning */
2786
    double x_offset;
2787
    double y_offset;
2788
    char draw_surface[200];
2789
    cairo_box_double_t     bbox;
2790
 
2791
    if (pattern->extend == CAIRO_EXTEND_PAD) {
2792
	status = _cairo_pdf_surface_add_padded_image_surface (surface,
2793
							      pattern,
2794
							      &pdf_pattern->extents,
2795
							      &pattern_resource,
2796
							      &pattern_width,
2797
							      &pattern_height,
2798
							      &x_offset,
2799
							      &y_offset);
2800
	pattern_extents.x = 0;
2801
	pattern_extents.y = 0;
2802
	pattern_extents.width = pattern_width;
2803
	pattern_extents.height = pattern_height;
2804
    } else {
2805
	status = _cairo_pdf_surface_add_source_surface (surface,
2806
							NULL,
2807
							pattern,
2808
							pattern->filter,
2809
							FALSE,
2810
							&pdf_pattern->extents,
2811
							&pattern_resource,
2812
							&pattern_width,
2813
							&pattern_height,
2814
							&x_offset,
2815
							&y_offset,
2816
							&pattern_extents);
2817
    }
2818
    if (unlikely (status))
2819
	return status;
2820
 
2821
    switch (extend) {
2822
    case CAIRO_EXTEND_PAD:
2823
    case CAIRO_EXTEND_NONE:
2824
    {
2825
	/* In PS/PDF, (as far as I can tell), all patterns are
2826
	 * repeating. So we support cairo's EXTEND_NONE semantics
2827
	 * by setting the repeat step size to a size large enough
2828
	 * to guarantee that no more than a single occurrence will
2829
	 * be visible.
2830
	 *
2831
	 * First, map the surface extents into pattern space (since
2832
	 * xstep and ystep are in pattern space).  Then use an upper
2833
	 * bound on the length of the diagonal of the pattern image
2834
	 * and the surface as repeat size.  This guarantees to never
2835
	 * repeat visibly.
2836
	 */
2837
	double x1 = 0.0, y1 = 0.0;
2838
	double x2 = surface->width, y2 = surface->height;
2839
	_cairo_matrix_transform_bounding_box (&pattern->matrix,
2840
					      &x1, &y1, &x2, &y2,
2841
					      NULL);
2842
 
2843
	/* Rather than computing precise bounds of the union, just
2844
	 * add the surface extents unconditionally. We only
2845
	 * required an answer that's large enough, we don't really
2846
	 * care if it's not as tight as possible.*/
2847
	xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
2848
			      pattern_width + pattern_height);
2849
    }
2850
    break;
2851
    case CAIRO_EXTEND_REPEAT:
2852
	xstep = pattern_width;
2853
	ystep = pattern_height;
2854
	break;
2855
    case CAIRO_EXTEND_REFLECT:
2856
	pattern_extents.x = 0;
2857
	pattern_extents.y = 0;
2858
	pattern_extents.width = pattern_width*2;
2859
	pattern_extents.height = pattern_height*2;
2860
	xstep = pattern_width*2;
2861
	ystep = pattern_height*2;
2862
	break;
2863
	/* All the rest (if any) should have been analyzed away, so this
2864
	 * case should be unreachable. */
2865
    default:
2866
	ASSERT_NOT_REACHED;
2867
	xstep = 0;
2868
	ystep = 0;
2869
    }
2870
 
2871
    /* At this point, (that is, within the surface backend interface),
2872
     * the pattern's matrix maps from cairo's device space to cairo's
2873
     * pattern space, (both with their origin at the upper-left, and
2874
     * cairo's pattern space of size width,height).
2875
     *
2876
     * Then, we must emit a PDF pattern object that maps from its own
2877
     * pattern space, (which has a size that we establish in the BBox
2878
     * dictionary entry), to the PDF page's *initial* space, (which
2879
     * does not benefit from the Y-axis flipping matrix that we emit
2880
     * on each page). So the PDF patterns matrix maps from a
2881
     * (width,height) pattern space to a device space with the origin
2882
     * in the lower-left corner.
2883
     *
2884
     * So to handle all of that, we start with an identity matrix for
2885
     * the PDF pattern to device matrix. We translate it up by the
2886
     * image height then flip it in the Y direction, (moving us from
2887
     * the PDF origin to cairo's origin). We then multiply in the
2888
     * inverse of the cairo pattern matrix, (since it maps from device
2889
     * to pattern, while we're setting up pattern to device). Finally,
2890
     * we translate back down by the image height and flip again to
2891
     * end up at the lower-left origin that PDF expects.
2892
     *
2893
     * Additionally, within the stream that paints the pattern itself,
2894
     * we are using a PDF image object that has a size of (1,1) so we
2895
     * have to scale it up by the image width and height to fill our
2896
     * pattern cell.
2897
     */
2898
    cairo_p2d = pattern->matrix;
2899
    status = cairo_matrix_invert (&cairo_p2d);
2900
    /* cairo_pattern_set_matrix ensures the matrix is invertible */
2901
    assert (status == CAIRO_INT_STATUS_SUCCESS);
2902
 
2903
    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &surface->cairo_to_pdf);
2904
    cairo_matrix_translate (&pdf_p2d, -x_offset, -y_offset);
2905
    cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
2906
    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
2907
 
2908
    _get_bbox_from_extents (pattern_height, &pattern_extents, &bbox);
2909
    _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
2910
    status = _cairo_pdf_surface_open_stream (surface,
2911
				             &pdf_pattern->pattern_res,
2912
					     FALSE,
2913
					     "   /PatternType 1\n"
2914
					     "   /BBox [ %f %f %f %f ]\n"
2915
					     "   /XStep %f\n"
2916
					     "   /YStep %f\n"
2917
					     "   /TilingType 1\n"
2918
					     "   /PaintType 1\n"
2919
					     "   /Matrix [ %f %f %f %f %f %f ]\n"
2920
					     "   /Resources << /XObject << /x%d %d 0 R >> >>\n",
2921
					     bbox.p1.x, bbox.p1.y, bbox.p2.x, bbox.p2.y,
2922
					     xstep, ystep,
2923
					     pdf_p2d.xx, pdf_p2d.yx,
2924
					     pdf_p2d.xy, pdf_p2d.yy,
2925
					     pdf_p2d.x0, pdf_p2d.y0,
2926
					     pattern_resource.id,
2927
					     pattern_resource.id);
2928
    if (unlikely (status))
2929
	return status;
2930
 
2931
    if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
2932
	((cairo_surface_pattern_t *) pattern)->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
2933
	snprintf(draw_surface,
2934
		 sizeof (draw_surface),
2935
		 "/x%d Do\n",
2936
		 pattern_resource.id);
2937
    } else {
2938
	snprintf(draw_surface,
2939
		 sizeof (draw_surface),
2940
		 "q %d 0 0 %d 0 0 cm /x%d Do Q",
2941
		 pattern_width,
2942
		 pattern_height,
2943
		 pattern_resource.id);
2944
    }
2945
 
2946
    if (extend == CAIRO_EXTEND_REFLECT) {
2947
	_cairo_output_stream_printf (surface->output,
2948
				     "q 0 0 %d %d re W n %s Q\n"
2949
				     "q -1 0 0 1 %d 0 cm 0 0 %d %d re W n %s Q\n"
2950
				     "q 1 0 0 -1 0 %d cm 0 0 %d %d re W n %s Q\n"
2951
				     "q -1 0 0 -1 %d %d cm 0 0 %d %d re W n %s Q\n",
2952
				     pattern_width, pattern_height,
2953
				     draw_surface,
2954
				     pattern_width*2, pattern_width, pattern_height,
2955
				     draw_surface,
2956
				     pattern_height*2, pattern_width, pattern_height,
2957
				     draw_surface,
2958
				     pattern_width*2, pattern_height*2, pattern_width, pattern_height,
2959
				     draw_surface);
2960
    } else {
2961
	_cairo_output_stream_printf (surface->output,
2962
				     " %s \n",
2963
				     draw_surface);
2964
    }
2965
 
2966
    status = _cairo_pdf_surface_close_stream (surface);
2967
    if (unlikely (status))
2968
	return status;
2969
 
2970
    return _cairo_output_stream_get_status (surface->output);
2971
}
2972
 
2973
typedef struct _cairo_pdf_color_stop {
2974
    double offset;
2975
    double color[4];
2976
    cairo_pdf_resource_t resource;
2977
} cairo_pdf_color_stop_t;
2978
 
2979
static cairo_int_status_t
2980
cairo_pdf_surface_emit_rgb_linear_function (cairo_pdf_surface_t    *surface,
2981
                                            cairo_pdf_color_stop_t *stop1,
2982
                                            cairo_pdf_color_stop_t *stop2,
2983
                                            cairo_pdf_resource_t   *function)
2984
{
2985
    int num_elems, i;
2986
    cairo_pdf_rgb_linear_function_t elem;
2987
    cairo_pdf_resource_t res;
2988
    cairo_int_status_t status;
2989
 
2990
    num_elems = _cairo_array_num_elements (&surface->rgb_linear_functions);
2991
    for (i = 0; i < num_elems; i++) {
2992
	_cairo_array_copy_element (&surface->rgb_linear_functions, i, &elem);
2993
        if (memcmp (&elem.color1[0], &stop1->color[0], sizeof (double)*3) != 0)
2994
            continue;
2995
        if (memcmp (&elem.color2[0], &stop2->color[0], sizeof (double)*3) != 0)
2996
            continue;
2997
        *function =  elem.resource;
2998
        return CAIRO_STATUS_SUCCESS;
2999
    }
3000
 
3001
    res = _cairo_pdf_surface_new_object (surface);
3002
    if (res.id == 0)
3003
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3004
 
3005
    _cairo_output_stream_printf (surface->output,
3006
				 "%d 0 obj\n"
3007
				 "<< /FunctionType 2\n"
3008
				 "   /Domain [ 0 1 ]\n"
3009
				 "   /C0 [ %f %f %f ]\n"
3010
				 "   /C1 [ %f %f %f ]\n"
3011
				 "   /N 1\n"
3012
				 ">>\n"
3013
				 "endobj\n",
3014
				 res.id,
3015
                                 stop1->color[0],
3016
                                 stop1->color[1],
3017
                                 stop1->color[2],
3018
                                 stop2->color[0],
3019
                                 stop2->color[1],
3020
                                 stop2->color[2]);
3021
 
3022
    elem.resource = res;
3023
    memcpy (&elem.color1[0], &stop1->color[0], sizeof (double)*3);
3024
    memcpy (&elem.color2[0], &stop2->color[0], sizeof (double)*3);
3025
 
3026
    status = _cairo_array_append (&surface->rgb_linear_functions, &elem);
3027
    *function = res;
3028
 
3029
    return status;
3030
}
3031
 
3032
static cairo_int_status_t
3033
cairo_pdf_surface_emit_alpha_linear_function (cairo_pdf_surface_t    *surface,
3034
                                              cairo_pdf_color_stop_t *stop1,
3035
                                              cairo_pdf_color_stop_t *stop2,
3036
                                              cairo_pdf_resource_t   *function)
3037
{
3038
    int num_elems, i;
3039
    cairo_pdf_alpha_linear_function_t elem;
3040
    cairo_pdf_resource_t res;
3041
    cairo_int_status_t status;
3042
 
3043
    num_elems = _cairo_array_num_elements (&surface->alpha_linear_functions);
3044
    for (i = 0; i < num_elems; i++) {
3045
	_cairo_array_copy_element (&surface->alpha_linear_functions, i, &elem);
3046
        if (elem.alpha1 != stop1->color[3])
3047
            continue;
3048
        if (elem.alpha2 != stop2->color[3])
3049
            continue;
3050
        *function =  elem.resource;
3051
        return CAIRO_STATUS_SUCCESS;
3052
    }
3053
 
3054
    res = _cairo_pdf_surface_new_object (surface);
3055
    if (res.id == 0)
3056
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3057
 
3058
    _cairo_output_stream_printf (surface->output,
3059
				 "%d 0 obj\n"
3060
				 "<< /FunctionType 2\n"
3061
				 "   /Domain [ 0 1 ]\n"
3062
				 "   /C0 [ %f ]\n"
3063
				 "   /C1 [ %f ]\n"
3064
				 "   /N 1\n"
3065
				 ">>\n"
3066
				 "endobj\n",
3067
				 res.id,
3068
                                 stop1->color[3],
3069
                                 stop2->color[3]);
3070
 
3071
    elem.resource = res;
3072
    elem.alpha1 = stop1->color[3];
3073
    elem.alpha2 = stop2->color[3];
3074
 
3075
    status = _cairo_array_append (&surface->alpha_linear_functions, &elem);
3076
    *function = res;
3077
 
3078
    return status;
3079
}
3080
 
3081
static cairo_int_status_t
3082
_cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t    *surface,
3083
                                                unsigned int	        n_stops,
3084
                                                cairo_pdf_color_stop_t *stops,
3085
                                                cairo_bool_t	        is_alpha,
3086
                                                cairo_pdf_resource_t   *function)
3087
{
3088
    cairo_pdf_resource_t res;
3089
    unsigned int i;
3090
    cairo_int_status_t status;
3091
 
3092
    /* emit linear gradients between pairs of subsequent stops... */
3093
    for (i = 0; i < n_stops-1; i++) {
3094
        if (is_alpha) {
3095
            status = cairo_pdf_surface_emit_alpha_linear_function (surface,
3096
                                                                   &stops[i],
3097
                                                                   &stops[i+1],
3098
                                                                   &stops[i].resource);
3099
            if (unlikely (status))
3100
                return status;
3101
        } else {
3102
            status = cairo_pdf_surface_emit_rgb_linear_function (surface,
3103
                                                                 &stops[i],
3104
                                                                 &stops[i+1],
3105
                                                                 &stops[i].resource);
3106
            if (unlikely (status))
3107
                return status;
3108
        }
3109
    }
3110
 
3111
    /* ... and stitch them together */
3112
    res = _cairo_pdf_surface_new_object (surface);
3113
    if (res.id == 0)
3114
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3115
 
3116
    _cairo_output_stream_printf (surface->output,
3117
				 "%d 0 obj\n"
3118
				 "<< /FunctionType 3\n"
3119
				 "   /Domain [ %f %f ]\n",
3120
				 res.id,
3121
                                 stops[0].offset,
3122
                                 stops[n_stops - 1].offset);
3123
 
3124
    _cairo_output_stream_printf (surface->output,
3125
				 "   /Functions [ ");
3126
    for (i = 0; i < n_stops-1; i++)
3127
        _cairo_output_stream_printf (surface->output,
3128
                                     "%d 0 R ", stops[i].resource.id);
3129
    _cairo_output_stream_printf (surface->output,
3130
				 "]\n");
3131
 
3132
    _cairo_output_stream_printf (surface->output,
3133
				 "   /Bounds [ ");
3134
    for (i = 1; i < n_stops-1; i++)
3135
        _cairo_output_stream_printf (surface->output,
3136
				     "%f ", stops[i].offset);
3137
    _cairo_output_stream_printf (surface->output,
3138
				 "]\n");
3139
 
3140
    _cairo_output_stream_printf (surface->output,
3141
				 "   /Encode [ ");
3142
    for (i = 1; i < n_stops; i++)
3143
        _cairo_output_stream_printf (surface->output,
3144
				     "0 1 ");
3145
    _cairo_output_stream_printf (surface->output,
3146
				 "]\n");
3147
 
3148
    _cairo_output_stream_printf (surface->output,
3149
				 ">>\n"
3150
				 "endobj\n");
3151
 
3152
    *function = res;
3153
 
3154
    return _cairo_output_stream_get_status (surface->output);
3155
}
3156
 
3157
 
3158
static void
3159
calc_gradient_color (cairo_pdf_color_stop_t *new_stop,
3160
		     cairo_pdf_color_stop_t *stop1,
3161
		     cairo_pdf_color_stop_t *stop2)
3162
{
3163
    int i;
3164
    double offset = stop1->offset / (stop1->offset + 1.0 - stop2->offset);
3165
 
3166
    for (i = 0; i < 4; i++)
3167
	new_stop->color[i] = stop1->color[i] + offset*(stop2->color[i] - stop1->color[i]);
3168
}
3169
 
3170
#define COLOR_STOP_EPSILON 1e-6
3171
 
3172
static cairo_int_status_t
3173
_cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t      *surface,
3174
                                       cairo_gradient_pattern_t *pattern,
3175
                                       cairo_pdf_resource_t     *color_function,
3176
                                       cairo_pdf_resource_t     *alpha_function)
3177
{
3178
    cairo_pdf_color_stop_t *allstops, *stops;
3179
    unsigned int n_stops;
3180
    unsigned int i;
3181
    cairo_bool_t emit_alpha = FALSE;
3182
    cairo_int_status_t status;
3183
 
3184
    color_function->id = 0;
3185
    alpha_function->id = 0;
3186
 
3187
    allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t));
3188
    if (unlikely (allstops == NULL))
3189
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3190
 
3191
    stops = &allstops[1];
3192
    n_stops = pattern->n_stops;
3193
 
3194
    for (i = 0; i < n_stops; i++) {
3195
	stops[i].color[0] = pattern->stops[i].color.red;
3196
	stops[i].color[1] = pattern->stops[i].color.green;
3197
	stops[i].color[2] = pattern->stops[i].color.blue;
3198
	stops[i].color[3] = pattern->stops[i].color.alpha;
3199
        if (!CAIRO_ALPHA_IS_OPAQUE (stops[i].color[3]))
3200
            emit_alpha = TRUE;
3201
	stops[i].offset = pattern->stops[i].offset;
3202
    }
3203
 
3204
    if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3205
	pattern->base.extend == CAIRO_EXTEND_REFLECT) {
3206
	if (stops[0].offset > COLOR_STOP_EPSILON) {
3207
	    if (pattern->base.extend == CAIRO_EXTEND_REFLECT)
3208
		memcpy (allstops, stops, sizeof (cairo_pdf_color_stop_t));
3209
	    else
3210
		calc_gradient_color (&allstops[0], &stops[0], &stops[n_stops-1]);
3211
	    stops = allstops;
3212
	    n_stops++;
3213
	}
3214
	stops[0].offset = 0.0;
3215
 
3216
	if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) {
3217
	    if (pattern->base.extend == CAIRO_EXTEND_REFLECT) {
3218
		memcpy (&stops[n_stops],
3219
			&stops[n_stops - 1],
3220
			sizeof (cairo_pdf_color_stop_t));
3221
	    } else {
3222
		calc_gradient_color (&stops[n_stops], &stops[0], &stops[n_stops-1]);
3223
	    }
3224
	    n_stops++;
3225
	}
3226
	stops[n_stops-1].offset = 1.0;
3227
    }
3228
 
3229
    if (stops[0].offset == stops[n_stops - 1].offset) {
3230
	/*
3231
	 * The first and the last stops have the same offset, but we
3232
	 * don't want a function with an empty domain, because that
3233
	 * would provoke underdefined behaviour from rasterisers.
3234
	 * This can only happen with EXTEND_PAD, because EXTEND_NONE
3235
	 * is optimised into a clear pattern in cairo-gstate, and
3236
	 * REFLECT/REPEAT are always transformed to have the first
3237
	 * stop at t=0 and the last stop at t=1.  Thus we want a step
3238
	 * function going from the first color to the last one.
3239
	 *
3240
	 * This can be accomplished by stitching three functions:
3241
	 *  - a constant first color function,
3242
	 *  - a step from the first color to the last color (with empty domain)
3243
	 *  - a constant last color function
3244
	 */
3245
	cairo_pdf_color_stop_t pad_stops[4];
3246
 
3247
	assert (pattern->base.extend == CAIRO_EXTEND_PAD);
3248
 
3249
	pad_stops[0] = pad_stops[1] = stops[0];
3250
	pad_stops[2] = pad_stops[3] = stops[n_stops - 1];
3251
 
3252
	pad_stops[0].offset = 0;
3253
	pad_stops[3].offset = 1;
3254
 
3255
        status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
3256
                                                                 4,
3257
                                                                 pad_stops,
3258
                                                                 FALSE,
3259
                                                                 color_function);
3260
        if (unlikely (status))
3261
            goto BAIL;
3262
 
3263
        if (emit_alpha) {
3264
            status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
3265
                                                                     4,
3266
                                                                     pad_stops,
3267
                                                                     TRUE,
3268
                                                                     alpha_function);
3269
            if (unlikely (status))
3270
                goto BAIL;
3271
        }
3272
    } else if (n_stops == 2) {
3273
        /* no need for stitched function */
3274
        status = cairo_pdf_surface_emit_rgb_linear_function (surface,
3275
                                                             &stops[0],
3276
                                                             &stops[n_stops - 1],
3277
                                                             color_function);
3278
        if (unlikely (status))
3279
            goto BAIL;
3280
 
3281
        if (emit_alpha) {
3282
            status = cairo_pdf_surface_emit_alpha_linear_function (surface,
3283
                                                                   &stops[0],
3284
                                                                   &stops[n_stops - 1],
3285
                                                                   alpha_function);
3286
            if (unlikely (status))
3287
                goto BAIL;
3288
        }
3289
    } else {
3290
        /* multiple stops: stitch. XXX possible optimization: regularly spaced
3291
         * stops do not require stitching. XXX */
3292
        status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
3293
                                                                 n_stops,
3294
                                                                 stops,
3295
                                                                 FALSE,
3296
                                                                 color_function);
3297
        if (unlikely (status))
3298
            goto BAIL;
3299
 
3300
        if (emit_alpha) {
3301
            status = _cairo_pdf_surface_emit_stitched_colorgradient (surface,
3302
                                                                     n_stops,
3303
                                                                     stops,
3304
                                                                     TRUE,
3305
                                                                     alpha_function);
3306
            if (unlikely (status))
3307
                goto BAIL;
3308
        }
3309
    }
3310
 
3311
BAIL:
3312
    free (allstops);
3313
    return status;
3314
}
3315
 
3316
static cairo_int_status_t
3317
_cairo_pdf_surface_emit_repeating_function (cairo_pdf_surface_t      *surface,
3318
					    cairo_gradient_pattern_t *pattern,
3319
					    cairo_pdf_resource_t     *function,
3320
					    int                       begin,
3321
					    int                       end)
3322
{
3323
    cairo_pdf_resource_t res;
3324
    int i;
3325
 
3326
    res = _cairo_pdf_surface_new_object (surface);
3327
    if (res.id == 0)
3328
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3329
 
3330
    _cairo_output_stream_printf (surface->output,
3331
				 "%d 0 obj\n"
3332
				 "<< /FunctionType 3\n"
3333
				 "   /Domain [ %d %d ]\n",
3334
				 res.id,
3335
                                 begin,
3336
                                 end);
3337
 
3338
    _cairo_output_stream_printf (surface->output,
3339
				 "   /Functions [ ");
3340
    for (i = begin; i < end; i++)
3341
        _cairo_output_stream_printf (surface->output,
3342
                                     "%d 0 R ", function->id);
3343
    _cairo_output_stream_printf (surface->output,
3344
				 "]\n");
3345
 
3346
    _cairo_output_stream_printf (surface->output,
3347
				 "   /Bounds [ ");
3348
    for (i = begin + 1; i < end; i++)
3349
        _cairo_output_stream_printf (surface->output,
3350
				     "%d ", i);
3351
    _cairo_output_stream_printf (surface->output,
3352
				 "]\n");
3353
 
3354
    _cairo_output_stream_printf (surface->output,
3355
				 "   /Encode [ ");
3356
    for (i = begin; i < end; i++) {
3357
	if ((i % 2) && pattern->base.extend == CAIRO_EXTEND_REFLECT) {
3358
	    _cairo_output_stream_printf (surface->output,
3359
					 "1 0 ");
3360
	} else {
3361
	    _cairo_output_stream_printf (surface->output,
3362
					 "0 1 ");
3363
	}
3364
    }
3365
    _cairo_output_stream_printf (surface->output,
3366
				 "]\n");
3367
 
3368
    _cairo_output_stream_printf (surface->output,
3369
				 ">>\n"
3370
				 "endobj\n");
3371
 
3372
    *function = res;
3373
 
3374
    return _cairo_output_stream_get_status (surface->output);
3375
}
3376
 
3377
static cairo_int_status_t
3378
cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t  *surface,
3379
					   cairo_pdf_pattern_t  *pdf_pattern,
3380
					   cairo_pdf_resource_t  gstate_resource,
3381
					   cairo_pdf_resource_t  gradient_mask)
3382
{
3383
    cairo_pdf_resource_t smask_resource;
3384
    cairo_int_status_t status;
3385
    char buf[100];
3386
    double x1, y1, x2, y2;
3387
 
3388
    if (pdf_pattern->is_shading) {
3389
	snprintf(buf, sizeof(buf),
3390
		 "         /Shading\n"
3391
		 "            << /sh%d %d 0 R >>\n",
3392
		 gradient_mask.id,
3393
		 gradient_mask.id);
3394
    } else {
3395
	snprintf(buf, sizeof(buf),
3396
		 "         /Pattern\n"
3397
		 "            << /p%d %d 0 R >>\n",
3398
		 gradient_mask.id,
3399
		 gradient_mask.id);
3400
    }
3401
 
3402
    if (pdf_pattern->is_shading) {
3403
	cairo_box_t box;
3404
 
3405
	/* When emitting a shading operator we are in cairo pattern
3406
	 * coordinates. _cairo_pdf_surface_paint_gradient has set the
3407
	 * ctm to the pattern matrix (including the convertion from
3408
	 * pdf to cairo coordinates) */
3409
	_cairo_box_from_rectangle (&box, &pdf_pattern->extents);
3410
	_cairo_box_to_doubles (&box, &x1, &y1, &x2, &y2);
3411
	_cairo_matrix_transform_bounding_box (&pdf_pattern->pattern->matrix, &x1, &y1, &x2, &y2, NULL);
3412
    } else {
3413
	cairo_box_double_t box;
3414
 
3415
	/* When emitting a shading pattern we are in pdf page
3416
	 * coordinates. The color and alpha shading patterns painted
3417
	 * in the XObject below contain the cairo pattern to pdf page
3418
	 * matrix in the /Matrix entry of the pattern. */
3419
	_get_bbox_from_extents (pdf_pattern->height, &pdf_pattern->extents, &box);
3420
	x1 = box.p1.x;
3421
	y1 = box.p1.y;
3422
	x2 = box.p2.x;
3423
	y2 = box.p2.y;
3424
    }
3425
    status = _cairo_pdf_surface_open_stream (surface,
3426
					     NULL,
3427
					     surface->compress_content,
3428
					     "   /Type /XObject\n"
3429
					     "   /Subtype /Form\n"
3430
					     "   /FormType 1\n"
3431
					     "   /BBox [ %f %f %f %f ]\n"
3432
					     "   /Resources\n"
3433
					     "      << /ExtGState\n"
3434
					     "            << /a0 << /ca 1 /CA 1 >>"
3435
					     "      >>\n"
3436
					     "%s"
3437
					     "      >>\n"
3438
					     "   /Group\n"
3439
					     "      << /Type /Group\n"
3440
					     "         /S /Transparency\n"
3441
					     "         /I true\n"
3442
					     "         /CS /DeviceGray\n"
3443
					     "      >>\n",
3444
					     x1,y1,x2,y2,
3445
					     buf);
3446
    if (unlikely (status))
3447
	return status;
3448
 
3449
    if (pdf_pattern->is_shading) {
3450
	_cairo_output_stream_printf (surface->output,
3451
				     "/a0 gs /sh%d sh\n",
3452
				     gradient_mask.id);
3453
    } else {
3454
	_cairo_output_stream_printf (surface->output,
3455
				     "q\n"
3456
				     "/a0 gs\n"
3457
				     "/Pattern cs /p%d scn\n"
3458
				     "0 0 %f %f re\n"
3459
				     "f\n"
3460
				     "Q\n",
3461
				     gradient_mask.id,
3462
				     surface->width,
3463
				     surface->height);
3464
    }
3465
 
3466
    status = _cairo_pdf_surface_close_stream (surface);
3467
    if (unlikely (status))
3468
	return status;
3469
 
3470
    smask_resource = _cairo_pdf_surface_new_object (surface);
3471
    if (smask_resource.id == 0)
3472
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3473
 
3474
    _cairo_output_stream_printf (surface->output,
3475
                                 "%d 0 obj\n"
3476
                                 "<< /Type /Mask\n"
3477
                                 "   /S /Luminosity\n"
3478
                                 "   /G %d 0 R\n"
3479
                                 ">>\n"
3480
                                 "endobj\n",
3481
                                 smask_resource.id,
3482
                                 surface->pdf_stream.self.id);
3483
 
3484
    /* Create GState which uses the transparency group as an SMask. */
3485
    _cairo_pdf_surface_update_object (surface, gstate_resource);
3486
 
3487
    _cairo_output_stream_printf (surface->output,
3488
                                 "%d 0 obj\n"
3489
                                 "<< /Type /ExtGState\n"
3490
                                 "   /SMask %d 0 R\n"
3491
                                 "   /ca 1\n"
3492
                                 "   /CA 1\n"
3493
                                 "   /AIS false\n"
3494
                                 ">>\n"
3495
                                 "endobj\n",
3496
                                 gstate_resource.id,
3497
                                 smask_resource.id);
3498
 
3499
    return _cairo_output_stream_get_status (surface->output);
3500
}
3501
 
3502
static void
3503
_cairo_pdf_surface_output_gradient (cairo_pdf_surface_t        *surface,
3504
				    const cairo_pdf_pattern_t  *pdf_pattern,
3505
				    cairo_pdf_resource_t        pattern_resource,
3506
				    const cairo_matrix_t       *pat_to_pdf,
3507
				    const cairo_circle_double_t*start,
3508
				    const cairo_circle_double_t*end,
3509
				    const double               *domain,
3510
				    const char                 *colorspace,
3511
				    cairo_pdf_resource_t        color_function)
3512
{
3513
    _cairo_output_stream_printf (surface->output,
3514
                                 "%d 0 obj\n",
3515
				 pattern_resource.id);
3516
 
3517
    if (!pdf_pattern->is_shading) {
3518
	_cairo_output_stream_printf (surface->output,
3519
				     "<< /Type /Pattern\n"
3520
				     "   /PatternType 2\n"
3521
				     "   /Matrix [ %f %f %f %f %f %f ]\n"
3522
				     "   /Shading\n",
3523
				     pat_to_pdf->xx, pat_to_pdf->yx,
3524
				     pat_to_pdf->xy, pat_to_pdf->yy,
3525
				     pat_to_pdf->x0, pat_to_pdf->y0);
3526
    }
3527
 
3528
    if (pdf_pattern->pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
3529
	_cairo_output_stream_printf (surface->output,
3530
				     "      << /ShadingType 2\n"
3531
				     "         /ColorSpace %s\n"
3532
				     "         /Coords [ %f %f %f %f ]\n",
3533
				     colorspace,
3534
				     start->center.x, start->center.y,
3535
				     end->center.x, end->center.y);
3536
    } else {
3537
	_cairo_output_stream_printf (surface->output,
3538
				     "      << /ShadingType 3\n"
3539
				     "         /ColorSpace %s\n"
3540
				     "         /Coords [ %f %f %f %f %f %f ]\n",
3541
				     colorspace,
3542
				     start->center.x, start->center.y,
3543
				     MAX (start->radius, 0),
3544
				     end->center.x, end->center.y,
3545
				     MAX (end->radius, 0));
3546
    }
3547
 
3548
    _cairo_output_stream_printf (surface->output,
3549
				 "         /Domain [ %f %f ]\n",
3550
				 domain[0], domain[1]);
3551
 
3552
    if (pdf_pattern->pattern->extend != CAIRO_EXTEND_NONE) {
3553
        _cairo_output_stream_printf (surface->output,
3554
                                     "         /Extend [ true true ]\n");
3555
    } else {
3556
        _cairo_output_stream_printf (surface->output,
3557
                                     "         /Extend [ false false ]\n");
3558
    }
3559
 
3560
    _cairo_output_stream_printf (surface->output,
3561
				 "         /Function %d 0 R\n"
3562
                                 "      >>\n",
3563
				 color_function.id);
3564
 
3565
    if (!pdf_pattern->is_shading) {
3566
	_cairo_output_stream_printf (surface->output,
3567
				     ">>\n");
3568
    }
3569
 
3570
    _cairo_output_stream_printf (surface->output,
3571
				     "endobj\n");
3572
}
3573
 
3574
static cairo_int_status_t
3575
_cairo_pdf_surface_emit_gradient (cairo_pdf_surface_t    *surface,
3576
				  cairo_pdf_pattern_t    *pdf_pattern)
3577
{
3578
    cairo_gradient_pattern_t *pattern = (cairo_gradient_pattern_t *) pdf_pattern->pattern;
3579
    cairo_pdf_resource_t color_function, alpha_function;
3580
    cairo_matrix_t pat_to_pdf;
3581
    cairo_circle_double_t start, end;
3582
    double domain[2];
3583
    cairo_int_status_t status;
3584
 
3585
    assert (pattern->n_stops != 0);
3586
 
3587
    status = _cairo_pdf_surface_emit_pattern_stops (surface,
3588
                                                    pattern,
3589
                                                    &color_function,
3590
                                                    &alpha_function);
3591
    if (unlikely (status))
3592
	return status;
3593
 
3594
    pat_to_pdf = pattern->base.matrix;
3595
    status = cairo_matrix_invert (&pat_to_pdf);
3596
    /* cairo_pattern_set_matrix ensures the matrix is invertible */
3597
    assert (status == CAIRO_INT_STATUS_SUCCESS);
3598
    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
3599
 
3600
    if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3601
	pattern->base.extend == CAIRO_EXTEND_REFLECT)
3602
    {
3603
	double bounds_x1, bounds_x2, bounds_y1, bounds_y2;
3604
	double x_scale, y_scale, tolerance;
3605
 
3606
	/* TODO: use tighter extents */
3607
	bounds_x1 = 0;
3608
	bounds_y1 = 0;
3609
	bounds_x2 = surface->width;
3610
	bounds_y2 = surface->height;
3611
	_cairo_matrix_transform_bounding_box (&pattern->base.matrix,
3612
					      &bounds_x1, &bounds_y1,
3613
					      &bounds_x2, &bounds_y2,
3614
					      NULL);
3615
 
3616
	x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution;
3617
	y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution;
3618
 
3619
	tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix));
3620
	tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1);
3621
	tolerance *= MIN (x_scale, y_scale);
3622
 
3623
	_cairo_gradient_pattern_box_to_parameter (pattern,
3624
						  bounds_x1, bounds_y1,
3625
						  bounds_x2, bounds_y2,
3626
						  tolerance, domain);
3627
    } else if (pattern->stops[0].offset == pattern->stops[pattern->n_stops - 1].offset) {
3628
	/*
3629
	 * If the first and the last stop offset are the same, then
3630
	 * the color function is a step function.
3631
	 * _cairo_ps_surface_emit_pattern_stops emits it as a stitched
3632
	 * function no matter how many stops the pattern has.  The
3633
	 * domain of the stitched function will be [0 1] in this case.
3634
	 *
3635
	 * This is done to avoid emitting degenerate gradients for
3636
	 * EXTEND_PAD patterns having a step color function.
3637
	 */
3638
	domain[0] = 0.0;
3639
	domain[1] = 1.0;
3640
 
3641
	assert (pattern->base.extend == CAIRO_EXTEND_PAD);
3642
    } else {
3643
	domain[0] = pattern->stops[0].offset;
3644
	domain[1] = pattern->stops[pattern->n_stops - 1].offset;
3645
    }
3646
 
3647
    /* PDF requires the first and last stop to be the same as the
3648
     * extreme coordinates. For repeating patterns this moves the
3649
     * extreme coordinates out to the begin/end of the repeating
3650
     * function. For non repeating patterns this may move the extreme
3651
     * coordinates in if there are not stops at offset 0 and 1. */
3652
    _cairo_gradient_pattern_interpolate (pattern, domain[0], &start);
3653
    _cairo_gradient_pattern_interpolate (pattern, domain[1], &end);
3654
 
3655
    if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3656
	pattern->base.extend == CAIRO_EXTEND_REFLECT)
3657
    {
3658
	int repeat_begin, repeat_end;
3659
 
3660
	repeat_begin = floor (domain[0]);
3661
	repeat_end = ceil (domain[1]);
3662
 
3663
	status = _cairo_pdf_surface_emit_repeating_function (surface,
3664
							     pattern,
3665
							     &color_function,
3666
							     repeat_begin,
3667
							     repeat_end);
3668
	if (unlikely (status))
3669
	    return status;
3670
 
3671
	if (alpha_function.id != 0) {
3672
	    status = _cairo_pdf_surface_emit_repeating_function (surface,
3673
								 pattern,
3674
								 &alpha_function,
3675
								 repeat_begin,
3676
								 repeat_end);
3677
	    if (unlikely (status))
3678
		return status;
3679
	}
3680
    } else if (pattern->n_stops <= 2) {
3681
	/* For EXTEND_NONE and EXTEND_PAD if there are only two stops a
3682
	 * Type 2 function is used by itself without a stitching
3683
	 * function. Type 2 functions always have the domain [0 1] */
3684
	domain[0] = 0.0;
3685
	domain[1] = 1.0;
3686
    }
3687
 
3688
    _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
3689
    _cairo_pdf_surface_output_gradient (surface, pdf_pattern,
3690
					pdf_pattern->pattern_res,
3691
					&pat_to_pdf, &start, &end, domain,
3692
					"/DeviceRGB", color_function);
3693
 
3694
    if (alpha_function.id != 0) {
3695
	cairo_pdf_resource_t mask_resource;
3696
 
3697
	assert (pdf_pattern->gstate_res.id != 0);
3698
 
3699
        /* Create pattern for SMask. */
3700
        mask_resource = _cairo_pdf_surface_new_object (surface);
3701
	if (mask_resource.id == 0)
3702
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3703
 
3704
	_cairo_pdf_surface_output_gradient (surface, pdf_pattern,
3705
					    mask_resource,
3706
					    &pat_to_pdf, &start, &end, domain,
3707
					    "/DeviceGray", alpha_function);
3708
 
3709
	status = cairo_pdf_surface_emit_transparency_group (surface,
3710
							    pdf_pattern,
3711
						            pdf_pattern->gstate_res,
3712
							    mask_resource);
3713
	if (unlikely (status))
3714
	    return status;
3715
    }
3716
 
3717
    return _cairo_output_stream_get_status (surface->output);
3718
}
3719
 
3720
static cairo_int_status_t
3721
_cairo_pdf_surface_emit_mesh_pattern (cairo_pdf_surface_t    *surface,
3722
				      cairo_pdf_pattern_t    *pdf_pattern)
3723
{
3724
    cairo_matrix_t pat_to_pdf;
3725
    cairo_int_status_t status;
3726
    cairo_pattern_t *pattern = pdf_pattern->pattern;
3727
    cairo_pdf_shading_t shading;
3728
    int i;
3729
    cairo_pdf_resource_t res;
3730
 
3731
    pat_to_pdf = pattern->matrix;
3732
    status = cairo_matrix_invert (&pat_to_pdf);
3733
    /* cairo_pattern_set_matrix ensures the matrix is invertible */
3734
    assert (status == CAIRO_INT_STATUS_SUCCESS);
3735
 
3736
    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
3737
 
3738
    status = _cairo_pdf_shading_init_color (&shading, (cairo_mesh_pattern_t *) pattern);
3739
    if (unlikely (status))
3740
	return status;
3741
 
3742
    res = _cairo_pdf_surface_new_object (surface);
3743
    if (unlikely (res.id == 0))
3744
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3745
 
3746
    _cairo_output_stream_printf (surface->output,
3747
				 "%d 0 obj\n"
3748
                                 "<< /ShadingType %d\n"
3749
                                 "   /ColorSpace /DeviceRGB\n"
3750
				 "   /BitsPerCoordinate %d\n"
3751
				 "   /BitsPerComponent %d\n"
3752
				 "   /BitsPerFlag %d\n"
3753
				 "   /Decode [",
3754
				 res.id,
3755
				 shading.shading_type,
3756
				 shading.bits_per_coordinate,
3757
				 shading.bits_per_component,
3758
				 shading.bits_per_flag);
3759
 
3760
    for (i = 0; i < shading.decode_array_length; i++)
3761
	_cairo_output_stream_printf (surface->output, "%f ", shading.decode_array[i]);
3762
 
3763
    _cairo_output_stream_printf (surface->output,
3764
				 "]\n"
3765
				 "   /Length %ld\n"
3766
				 ">>\n"
3767
				 "stream\n",
3768
				 shading.data_length);
3769
 
3770
    _cairo_output_stream_write (surface->output, shading.data, shading.data_length);
3771
 
3772
    _cairo_output_stream_printf (surface->output,
3773
				 "\nendstream\n"
3774
				 "endobj\n");
3775
 
3776
    _cairo_pdf_shading_fini (&shading);
3777
 
3778
    _cairo_pdf_surface_update_object (surface, pdf_pattern->pattern_res);
3779
    _cairo_output_stream_printf (surface->output,
3780
                                 "%d 0 obj\n"
3781
                                 "<< /Type /Pattern\n"
3782
                                 "   /PatternType 2\n"
3783
                                 "   /Matrix [ %f %f %f %f %f %f ]\n"
3784
                                 "   /Shading %d 0 R\n"
3785
				 ">>\n"
3786
				 "endobj\n",
3787
				 pdf_pattern->pattern_res.id,
3788
                                 pat_to_pdf.xx, pat_to_pdf.yx,
3789
                                 pat_to_pdf.xy, pat_to_pdf.yy,
3790
                                 pat_to_pdf.x0, pat_to_pdf.y0,
3791
				 res.id);
3792
 
3793
    if (pdf_pattern->gstate_res.id != 0) {
3794
	cairo_pdf_resource_t mask_resource;
3795
 
3796
	/* Create pattern for SMask. */
3797
        res = _cairo_pdf_surface_new_object (surface);
3798
	if (unlikely (res.id == 0))
3799
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3800
 
3801
	status = _cairo_pdf_shading_init_alpha (&shading, (cairo_mesh_pattern_t *) pattern);
3802
	if (unlikely (status))
3803
	    return status;
3804
 
3805
	_cairo_output_stream_printf (surface->output,
3806
				 "%d 0 obj\n"
3807
                                 "<< /ShadingType %d\n"
3808
                                 "   /ColorSpace /DeviceGray\n"
3809
				 "   /BitsPerCoordinate %d\n"
3810
				 "   /BitsPerComponent %d\n"
3811
				 "   /BitsPerFlag %d\n"
3812
				 "   /Decode [",
3813
				 res.id,
3814
				 shading.shading_type,
3815
				 shading.bits_per_coordinate,
3816
				 shading.bits_per_component,
3817
				 shading.bits_per_flag);
3818
 
3819
	for (i = 0; i < shading.decode_array_length; i++)
3820
	    _cairo_output_stream_printf (surface->output, "%f ", shading.decode_array[i]);
3821
 
3822
	_cairo_output_stream_printf (surface->output,
3823
				     "]\n"
3824
				     "   /Length %ld\n"
3825
				     ">>\n"
3826
				     "stream\n",
3827
				     shading.data_length);
3828
 
3829
	_cairo_output_stream_write (surface->output, shading.data, shading.data_length);
3830
 
3831
	_cairo_output_stream_printf (surface->output,
3832
				     "\nendstream\n"
3833
				     "endobj\n");
3834
	_cairo_pdf_shading_fini (&shading);
3835
 
3836
        mask_resource = _cairo_pdf_surface_new_object (surface);
3837
	if (unlikely (mask_resource.id == 0))
3838
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3839
 
3840
	_cairo_output_stream_printf (surface->output,
3841
				     "%d 0 obj\n"
3842
				     "<< /Type /Pattern\n"
3843
				     "   /PatternType 2\n"
3844
				     "   /Matrix [ %f %f %f %f %f %f ]\n"
3845
				     "   /Shading %d 0 R\n"
3846
				     ">>\n"
3847
				     "endobj\n",
3848
				     mask_resource.id,
3849
				     pat_to_pdf.xx, pat_to_pdf.yx,
3850
				     pat_to_pdf.xy, pat_to_pdf.yy,
3851
				     pat_to_pdf.x0, pat_to_pdf.y0,
3852
				     res.id);
3853
 
3854
	status = cairo_pdf_surface_emit_transparency_group (surface,
3855
							    pdf_pattern,
3856
						            pdf_pattern->gstate_res,
3857
							    mask_resource);
3858
	if (unlikely (status))
3859
	    return status;
3860
    }
3861
 
3862
    return _cairo_output_stream_get_status (surface->output);
3863
}
3864
 
3865
static cairo_int_status_t
3866
_cairo_pdf_surface_emit_pattern (cairo_pdf_surface_t *surface, cairo_pdf_pattern_t *pdf_pattern)
3867
{
3868
    double old_width, old_height;
3869
    cairo_int_status_t status;
3870
 
3871
    old_width = surface->width;
3872
    old_height = surface->height;
3873
    _cairo_pdf_surface_set_size_internal (surface,
3874
					  pdf_pattern->width,
3875
					  pdf_pattern->height);
3876
 
3877
    switch (pdf_pattern->pattern->type) {
3878
    case CAIRO_PATTERN_TYPE_SOLID:
3879
	ASSERT_NOT_REACHED;
3880
	status = _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
3881
	break;
3882
 
3883
    case CAIRO_PATTERN_TYPE_SURFACE:
3884
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
3885
	status = _cairo_pdf_surface_emit_surface_pattern (surface, pdf_pattern);
3886
	break;
3887
 
3888
    case CAIRO_PATTERN_TYPE_LINEAR:
3889
    case CAIRO_PATTERN_TYPE_RADIAL:
3890
	status = _cairo_pdf_surface_emit_gradient (surface, pdf_pattern);
3891
	break;
3892
 
3893
    case CAIRO_PATTERN_TYPE_MESH:
3894
	status = _cairo_pdf_surface_emit_mesh_pattern (surface, pdf_pattern);
3895
	break;
3896
 
3897
    default:
3898
	ASSERT_NOT_REACHED;
3899
	status = _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
3900
	break;
3901
    }
3902
 
3903
    _cairo_pdf_surface_set_size_internal (surface,
3904
					  old_width,
3905
					  old_height);
3906
 
3907
    return status;
3908
}
3909
 
3910
static cairo_int_status_t
3911
_cairo_pdf_surface_paint_surface_pattern (cairo_pdf_surface_t          *surface,
3912
					  const cairo_pattern_t        *source,
3913
					  const cairo_rectangle_int_t  *extents,
3914
					  cairo_bool_t                  stencil_mask)
3915
{
3916
    cairo_pdf_resource_t surface_res;
3917
    int width, height;
3918
    cairo_matrix_t cairo_p2d, pdf_p2d;
3919
    cairo_int_status_t status;
3920
    int alpha;
3921
    cairo_rectangle_int_t extents2;
3922
    double x_offset;
3923
    double y_offset;
3924
 
3925
    if (source->extend == CAIRO_EXTEND_PAD &&
3926
	!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
3927
	  ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
3928
    {
3929
	status = _cairo_pdf_surface_add_padded_image_surface (surface,
3930
							      source,
3931
							      extents,
3932
							      &surface_res,
3933
							      &width,
3934
							      &height,
3935
							      &x_offset,
3936
							      &y_offset);
3937
    } else {
3938
	status = _cairo_pdf_surface_add_source_surface (surface,
3939
							NULL,
3940
							source,
3941
							source->filter,
3942
							stencil_mask,
3943
							extents,
3944
							&surface_res,
3945
							&width,
3946
							&height,
3947
							&x_offset,
3948
							&y_offset,
3949
							&extents2);
3950
    }
3951
    if (unlikely (status))
3952
	return status;
3953
 
3954
    cairo_p2d = source->matrix;
3955
    status = cairo_matrix_invert (&cairo_p2d);
3956
    /* cairo_pattern_set_matrix ensures the matrix is invertible */
3957
    assert (status == CAIRO_INT_STATUS_SUCCESS);
3958
 
3959
    pdf_p2d = surface->cairo_to_pdf;
3960
    cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
3961
    cairo_matrix_translate (&pdf_p2d, x_offset, y_offset);
3962
    cairo_matrix_translate (&pdf_p2d, 0.0, height);
3963
    cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
3964
    if (!(source->type == CAIRO_PATTERN_TYPE_SURFACE &&
3965
	  ((cairo_surface_pattern_t *)source)->surface->type == CAIRO_SURFACE_TYPE_RECORDING))
3966
    {
3967
	cairo_matrix_scale (&pdf_p2d, width, height);
3968
    }
3969
 
3970
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
3971
    if (unlikely (status))
3972
	return status;
3973
 
3974
    if (! _cairo_matrix_is_identity (&pdf_p2d)) {
3975
	_cairo_output_stream_printf (surface->output,
3976
				     "%f %f %f %f %f %f cm\n",
3977
				     pdf_p2d.xx, pdf_p2d.yx,
3978
				     pdf_p2d.xy, pdf_p2d.yy,
3979
				     pdf_p2d.x0, pdf_p2d.y0);
3980
    }
3981
 
3982
    status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
3983
    if (unlikely (status))
3984
	return status;
3985
 
3986
    if (stencil_mask) {
3987
	_cairo_output_stream_printf (surface->output,
3988
				     "/x%d Do\n",
3989
				     surface_res.id);
3990
    } else {
3991
	_cairo_output_stream_printf (surface->output,
3992
				     "/a%d gs /x%d Do\n",
3993
				     alpha,
3994
				     surface_res.id);
3995
    }
3996
 
3997
    return _cairo_pdf_surface_add_xobject (surface, surface_res);
3998
}
3999
 
4000
static cairo_int_status_t
4001
_cairo_pdf_surface_paint_gradient (cairo_pdf_surface_t         *surface,
4002
				   const cairo_pattern_t       *source,
4003
				   const cairo_rectangle_int_t *extents)
4004
{
4005
    cairo_pdf_resource_t shading_res, gstate_res;
4006
    cairo_matrix_t pat_to_pdf;
4007
    cairo_int_status_t status;
4008
    int alpha;
4009
 
4010
    status = _cairo_pdf_surface_add_pdf_shading (surface, source,
4011
						 extents,
4012
						 &shading_res, &gstate_res);
4013
    if (unlikely (status == CAIRO_INT_STATUS_NOTHING_TO_DO))
4014
	return CAIRO_INT_STATUS_SUCCESS;
4015
    if (unlikely (status))
4016
	return status;
4017
 
4018
    pat_to_pdf = source->matrix;
4019
    status = cairo_matrix_invert (&pat_to_pdf);
4020
    /* cairo_pattern_set_matrix ensures the matrix is invertible */
4021
    assert (status == CAIRO_INT_STATUS_SUCCESS);
4022
    cairo_matrix_multiply (&pat_to_pdf, &pat_to_pdf, &surface->cairo_to_pdf);
4023
 
4024
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4025
    if (unlikely (status))
4026
	return status;
4027
 
4028
    if (! _cairo_matrix_is_identity (&pat_to_pdf)) {
4029
	_cairo_output_stream_printf (surface->output,
4030
				     "%f %f %f %f %f %f cm\n",
4031
				     pat_to_pdf.xx, pat_to_pdf.yx,
4032
				     pat_to_pdf.xy, pat_to_pdf.yy,
4033
				     pat_to_pdf.x0, pat_to_pdf.y0);
4034
    }
4035
 
4036
    status = _cairo_pdf_surface_add_shading (surface, shading_res);
4037
    if (unlikely (status))
4038
	return status;
4039
 
4040
    if (gstate_res.id != 0) {
4041
	status = _cairo_pdf_surface_add_smask (surface, gstate_res);
4042
	if (unlikely (status))
4043
	    return status;
4044
 
4045
	_cairo_output_stream_printf (surface->output,
4046
				     "/s%d gs /sh%d sh\n",
4047
				     gstate_res.id,
4048
				     shading_res.id);
4049
    } else {
4050
	status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
4051
	if (unlikely (status))
4052
	    return status;
4053
 
4054
	_cairo_output_stream_printf (surface->output,
4055
				     "/a%d gs /sh%d sh\n",
4056
				     alpha,
4057
				     shading_res.id);
4058
    }
4059
 
4060
    return status;
4061
}
4062
 
4063
static cairo_int_status_t
4064
_cairo_pdf_surface_paint_pattern (cairo_pdf_surface_t          *surface,
4065
				  const cairo_pattern_t        *source,
4066
				  const cairo_rectangle_int_t  *extents,
4067
				  cairo_bool_t                  mask)
4068
{
4069
    switch (source->type) {
4070
    case CAIRO_PATTERN_TYPE_SURFACE:
4071
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
4072
	return _cairo_pdf_surface_paint_surface_pattern (surface,
4073
							 source,
4074
							 extents,
4075
							 mask);
4076
    case CAIRO_PATTERN_TYPE_LINEAR:
4077
    case CAIRO_PATTERN_TYPE_RADIAL:
4078
    case CAIRO_PATTERN_TYPE_MESH:
4079
	return _cairo_pdf_surface_paint_gradient (surface,
4080
						  source,
4081
						  extents);
4082
 
4083
    case CAIRO_PATTERN_TYPE_SOLID:
4084
    default:
4085
	ASSERT_NOT_REACHED;
4086
	return CAIRO_STATUS_SUCCESS;
4087
    }
4088
}
4089
 
4090
static cairo_bool_t
4091
_can_paint_pattern (const cairo_pattern_t *pattern)
4092
{
4093
    switch (pattern->type) {
4094
    case CAIRO_PATTERN_TYPE_SOLID:
4095
	return FALSE;
4096
 
4097
    case CAIRO_PATTERN_TYPE_SURFACE:
4098
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
4099
	return (pattern->extend == CAIRO_EXTEND_NONE ||
4100
		pattern->extend == CAIRO_EXTEND_PAD);
4101
 
4102
    case CAIRO_PATTERN_TYPE_LINEAR:
4103
    case CAIRO_PATTERN_TYPE_RADIAL:
4104
	return TRUE;
4105
 
4106
    case CAIRO_PATTERN_TYPE_MESH:
4107
	return FALSE;
4108
 
4109
    default:
4110
	ASSERT_NOT_REACHED;
4111
	return FALSE;
4112
    }
4113
}
4114
 
4115
static cairo_int_status_t
4116
_cairo_pdf_surface_select_operator (cairo_pdf_surface_t *surface,
4117
				    cairo_operator_t     op)
4118
{
4119
    cairo_int_status_t status;
4120
 
4121
    if (op == surface->current_operator)
4122
	return CAIRO_STATUS_SUCCESS;
4123
 
4124
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4125
    if (unlikely (status))
4126
	return status;
4127
 
4128
    _cairo_output_stream_printf (surface->output,
4129
				 "/b%d gs\n", op);
4130
    surface->current_operator = op;
4131
    _cairo_pdf_surface_add_operator (surface, op);
4132
 
4133
    return CAIRO_STATUS_SUCCESS;
4134
}
4135
 
4136
static cairo_int_status_t
4137
_cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface,
4138
				   const cairo_pattern_t     *pattern,
4139
				   cairo_pdf_resource_t pattern_res,
4140
				   cairo_bool_t         is_stroke)
4141
{
4142
    cairo_int_status_t status;
4143
    int alpha;
4144
    const cairo_color_t *solid_color = NULL;
4145
 
4146
    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
4147
	const cairo_solid_pattern_t *solid = (const cairo_solid_pattern_t *) pattern;
4148
 
4149
	solid_color = &solid->color;
4150
    }
4151
 
4152
    if (solid_color != NULL) {
4153
	if (surface->current_pattern_is_solid_color == FALSE ||
4154
	    surface->current_color_red != solid_color->red ||
4155
	    surface->current_color_green != solid_color->green ||
4156
	    surface->current_color_blue != solid_color->blue ||
4157
	    surface->current_color_is_stroke != is_stroke)
4158
	{
4159
	    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4160
	    if (unlikely (status))
4161
		return status;
4162
 
4163
	    _cairo_output_stream_printf (surface->output,
4164
					 "%f %f %f ",
4165
					 solid_color->red,
4166
					 solid_color->green,
4167
					 solid_color->blue);
4168
 
4169
	    if (is_stroke)
4170
		_cairo_output_stream_printf (surface->output, "RG ");
4171
	    else
4172
		_cairo_output_stream_printf (surface->output, "rg ");
4173
 
4174
	    surface->current_color_red = solid_color->red;
4175
	    surface->current_color_green = solid_color->green;
4176
	    surface->current_color_blue = solid_color->blue;
4177
	    surface->current_color_is_stroke = is_stroke;
4178
	}
4179
 
4180
	if (surface->current_pattern_is_solid_color == FALSE ||
4181
	    surface->current_color_alpha != solid_color->alpha)
4182
	{
4183
	    status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha);
4184
	    if (unlikely (status))
4185
		return status;
4186
 
4187
	    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4188
	    if (unlikely (status))
4189
		return status;
4190
 
4191
	    _cairo_output_stream_printf (surface->output,
4192
					 "/a%d gs\n",
4193
					 alpha);
4194
	    surface->current_color_alpha = solid_color->alpha;
4195
	}
4196
 
4197
	surface->current_pattern_is_solid_color = TRUE;
4198
    } else {
4199
	status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha);
4200
	if (unlikely (status))
4201
	    return status;
4202
 
4203
	status = _cairo_pdf_surface_add_pattern (surface, pattern_res);
4204
	if (unlikely (status))
4205
	    return status;
4206
 
4207
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4208
	if (unlikely (status))
4209
	    return status;
4210
 
4211
	/* fill-stroke calls select_pattern twice. Don't save if the
4212
	 * gstate is already saved. */
4213
	if (!surface->select_pattern_gstate_saved)
4214
	    _cairo_output_stream_printf (surface->output, "q ");
4215
 
4216
	if (is_stroke) {
4217
	    _cairo_output_stream_printf (surface->output,
4218
					 "/Pattern CS /p%d SCN ",
4219
					 pattern_res.id);
4220
	} else {
4221
	    _cairo_output_stream_printf (surface->output,
4222
					 "/Pattern cs /p%d scn ",
4223
					 pattern_res.id);
4224
	}
4225
	_cairo_output_stream_printf (surface->output,
4226
				     "/a%d gs\n",
4227
				     alpha);
4228
	surface->select_pattern_gstate_saved = TRUE;
4229
	surface->current_pattern_is_solid_color = FALSE;
4230
    }
4231
 
4232
    return _cairo_output_stream_get_status (surface->output);
4233
}
4234
 
4235
static cairo_int_status_t
4236
_cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface)
4237
{
4238
    cairo_int_status_t status;
4239
 
4240
    if (surface->select_pattern_gstate_saved) {
4241
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4242
	if (unlikely (status))
4243
	    return status;
4244
 
4245
	_cairo_output_stream_printf (surface->output, "Q\n");
4246
	_cairo_pdf_operators_reset (&surface->pdf_operators);
4247
	surface->current_pattern_is_solid_color = FALSE;
4248
    }
4249
    surface->select_pattern_gstate_saved = FALSE;
4250
 
4251
    return CAIRO_STATUS_SUCCESS;
4252
}
4253
 
4254
static cairo_int_status_t
4255
_cairo_pdf_surface_show_page (void *abstract_surface)
4256
{
4257
    cairo_pdf_surface_t *surface = abstract_surface;
4258
    cairo_int_status_t status;
4259
 
4260
    status = _cairo_pdf_surface_close_content_stream (surface);
4261
    if (unlikely (status))
4262
	return status;
4263
 
4264
    _cairo_surface_clipper_reset (&surface->clipper);
4265
 
4266
    status = _cairo_pdf_surface_write_page (surface);
4267
    if (unlikely (status))
4268
	return status;
4269
 
4270
    _cairo_pdf_surface_clear (surface);
4271
 
4272
    return CAIRO_STATUS_SUCCESS;
4273
}
4274
 
4275
static cairo_bool_t
4276
_cairo_pdf_surface_get_extents (void		        *abstract_surface,
4277
				cairo_rectangle_int_t   *rectangle)
4278
{
4279
    cairo_pdf_surface_t *surface = abstract_surface;
4280
 
4281
    rectangle->x = 0;
4282
    rectangle->y = 0;
4283
 
4284
    /* XXX: The conversion to integers here is pretty bogus, (not to
4285
     * mention the arbitrary limitation of width to a short(!). We
4286
     * may need to come up with a better interface for get_size.
4287
     */
4288
    rectangle->width  = ceil (surface->width);
4289
    rectangle->height = ceil (surface->height);
4290
 
4291
    return TRUE;
4292
}
4293
 
4294
static void
4295
_cairo_pdf_surface_get_font_options (void                  *abstract_surface,
4296
				     cairo_font_options_t  *options)
4297
{
4298
    _cairo_font_options_init_default (options);
4299
 
4300
    cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
4301
    cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
4302
    cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
4303
    _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF);
4304
}
4305
 
4306
static cairo_pdf_resource_t
4307
_cairo_pdf_surface_write_info (cairo_pdf_surface_t *surface)
4308
{
4309
    cairo_pdf_resource_t info;
4310
 
4311
    info = _cairo_pdf_surface_new_object (surface);
4312
    if (info.id == 0)
4313
	return info;
4314
 
4315
    _cairo_output_stream_printf (surface->output,
4316
				 "%d 0 obj\n"
4317
				 "<< /Creator (cairo %s (http://cairographics.org))\n"
4318
				 "   /Producer (cairo %s (http://cairographics.org))\n"
4319
				 ">>\n"
4320
				 "endobj\n",
4321
				 info.id,
4322
                                 cairo_version_string (),
4323
                                 cairo_version_string ());
4324
 
4325
    return info;
4326
}
4327
 
4328
static void
4329
_cairo_pdf_surface_write_pages (cairo_pdf_surface_t *surface)
4330
{
4331
    cairo_pdf_resource_t page;
4332
    int num_pages, i;
4333
 
4334
    _cairo_pdf_surface_update_object (surface, surface->pages_resource);
4335
    _cairo_output_stream_printf (surface->output,
4336
				 "%d 0 obj\n"
4337
				 "<< /Type /Pages\n"
4338
				 "   /Kids [ ",
4339
				 surface->pages_resource.id);
4340
 
4341
    num_pages = _cairo_array_num_elements (&surface->pages);
4342
    for (i = 0; i < num_pages; i++) {
4343
	_cairo_array_copy_element (&surface->pages, i, &page);
4344
	_cairo_output_stream_printf (surface->output, "%d 0 R ", page.id);
4345
    }
4346
 
4347
    _cairo_output_stream_printf (surface->output, "]\n");
4348
    _cairo_output_stream_printf (surface->output, "   /Count %d\n", num_pages);
4349
 
4350
 
4351
    /* TODO: Figure out which other defaults to be inherited by /Page
4352
     * objects. */
4353
    _cairo_output_stream_printf (surface->output,
4354
				 ">>\n"
4355
				 "endobj\n");
4356
}
4357
 
4358
static cairo_int_status_t
4359
_utf8_to_pdf_string (const char *utf8, char **str_out)
4360
{
4361
    int i;
4362
    int len;
4363
    cairo_bool_t ascii;
4364
    char *str;
4365
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
4366
 
4367
    ascii = TRUE;
4368
    len = strlen (utf8);
4369
    for (i = 0; i < len; i++) {
4370
	unsigned c = utf8[i];
4371
	if (c < 32 || c > 126 || c == '(' || c == ')' || c == '\\') {
4372
	    ascii = FALSE;
4373
	    break;
4374
	}
4375
    }
4376
 
4377
    if (ascii) {
4378
	str = malloc (len + 3);
4379
	if (str == NULL)
4380
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4381
 
4382
	str[0] = '(';
4383
	for (i = 0; i < len; i++)
4384
	    str[i+1] = utf8[i];
4385
	str[i+1] = ')';
4386
	str[i+2] = 0;
4387
    } else {
4388
	uint16_t *utf16 = NULL;
4389
	int utf16_len = 0;
4390
 
4391
	status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
4392
	if (unlikely (status))
4393
	    return status;
4394
 
4395
	str = malloc (utf16_len*4 + 7);
4396
	if (str == NULL) {
4397
	    free (utf16);
4398
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4399
	}
4400
 
4401
	strcpy (str, "
4402
	for (i = 0; i < utf16_len; i++)
4403
	    snprintf (str + 4*i + 5, 5, "%04X", utf16[i]);
4404
 
4405
	strcat (str, ">");
4406
	free (utf16);
4407
    }
4408
    *str_out = str;
4409
 
4410
    return status;
4411
}
4412
 
4413
static cairo_int_status_t
4414
_cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t	*surface,
4415
					   const char 		*utf8)
4416
{
4417
    uint16_t *utf16 = NULL;
4418
    int utf16_len = 0;
4419
    cairo_int_status_t status;
4420
    int i;
4421
 
4422
    if (utf8 && *utf8) {
4423
	status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
4424
	if (unlikely (status))
4425
	    return status;
4426
    }
4427
 
4428
    _cairo_output_stream_printf (surface->output, "<");
4429
    if (utf16 == NULL || utf16_len == 0) {
4430
	/* According to the "ToUnicode Mapping File Tutorial"
4431
	 * http://www.adobe.com/devnet/acrobat/pdfs/5411.ToUnicode.pdf
4432
	 *
4433
	 * Glyphs that do not map to a Unicode code point must be
4434
	 * mapped to 0xfffd "REPLACEMENT CHARACTER".
4435
	 */
4436
	_cairo_output_stream_printf (surface->output,
4437
				     "fffd");
4438
    } else {
4439
	for (i = 0; i < utf16_len; i++)
4440
	    _cairo_output_stream_printf (surface->output,
4441
					 "%04x", (int) (utf16[i]));
4442
    }
4443
    _cairo_output_stream_printf (surface->output, ">");
4444
 
4445
    free (utf16);
4446
 
4447
    return CAIRO_STATUS_SUCCESS;
4448
}
4449
 
4450
/* Bob Jenkins hash
4451
 *
4452
 * Public domain code from:
4453
 *   http://burtleburtle.net/bob/hash/doobs.html
4454
 */
4455
 
4456
#define HASH_MIX(a,b,c) 		\
4457
{ 					\
4458
    a -= b; a -= c; a ^= (c>>13);	\
4459
    b -= c; b -= a; b ^= (a<<8);	\
4460
    c -= a; c -= b; c ^= (b>>13);	\
4461
    a -= b; a -= c; a ^= (c>>12);	\
4462
    b -= c; b -= a; b ^= (a<<16);	\
4463
    c -= a; c -= b; c ^= (b>>5);	\
4464
    a -= b; a -= c; a ^= (c>>3);	\
4465
    b -= c; b -= a; b ^= (a<<10);	\
4466
    c -= a; c -= b; c ^= (b>>15);	\
4467
}
4468
 
4469
static uint32_t
4470
_hash_data (const unsigned char *data, int length, uint32_t initval)
4471
{
4472
    uint32_t a, b, c, len;
4473
 
4474
    len = length;
4475
    a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
4476
    c = initval;         /* the previous hash value */
4477
 
4478
    while (len >= 12) {
4479
	a += (data[0] + ((uint32_t)data[1]<<8) + ((uint32_t)data[2]<<16) + ((uint32_t)data[3]<<24));
4480
	b += (data[4] + ((uint32_t)data[5]<<8) + ((uint32_t)data[6]<<16) + ((uint32_t)data[7]<<24));
4481
	c += (data[8] + ((uint32_t)data[9]<<8) + ((uint32_t)data[10]<<16)+ ((uint32_t)data[11]<<24));
4482
	HASH_MIX (a,b,c);
4483
	data += 12;
4484
	len -= 12;
4485
    }
4486
 
4487
    c += length;
4488
    switch(len) {
4489
    case 11: c+= ((uint32_t) data[10] << 24);
4490
    case 10: c+= ((uint32_t) data[9] << 16);
4491
    case 9 : c+= ((uint32_t) data[8] << 8);
4492
    case 8 : b+= ((uint32_t) data[7] << 24);
4493
    case 7 : b+= ((uint32_t) data[6] << 16);
4494
    case 6 : b+= ((uint32_t) data[5] << 8);
4495
    case 5 : b+= data[4];
4496
    case 4 : a+= ((uint32_t) data[3] << 24);
4497
    case 3 : a+= ((uint32_t) data[2] << 16);
4498
    case 2 : a+= ((uint32_t) data[1] << 8);
4499
    case 1 : a+= data[0];
4500
    }
4501
    HASH_MIX (a,b,c);
4502
 
4503
    return c;
4504
}
4505
 
4506
static void
4507
_create_font_subset_tag (cairo_scaled_font_subset_t	*font_subset,
4508
			 const char 			*font_name,
4509
			 char				*tag)
4510
{
4511
    uint32_t hash;
4512
    int i;
4513
    long numerator;
4514
    ldiv_t d;
4515
 
4516
    hash = _hash_data ((unsigned char *) font_name, strlen(font_name), 0);
4517
    hash = _hash_data ((unsigned char *) (font_subset->glyphs),
4518
		       font_subset->num_glyphs * sizeof(unsigned long), hash);
4519
 
4520
    numerator = abs (hash);
4521
    for (i = 0; i < 6; i++) {
4522
	d = ldiv (numerator, 26);
4523
	numerator = d.quot;
4524
        tag[i] = 'A' + d.rem;
4525
    }
4526
    tag[i] = 0;
4527
}
4528
 
4529
static cairo_int_status_t
4530
_cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t		*surface,
4531
					   cairo_scaled_font_subset_t	*font_subset,
4532
					   cairo_pdf_resource_t         *stream)
4533
{
4534
    unsigned int i, num_bfchar;
4535
    cairo_int_status_t status;
4536
 
4537
    stream->id = 0;
4538
 
4539
    status = _cairo_pdf_surface_open_stream (surface,
4540
					      NULL,
4541
					      surface->compress_content,
4542
					      NULL);
4543
    if (unlikely (status))
4544
	return status;
4545
 
4546
    _cairo_output_stream_printf (surface->output,
4547
                                 "/CIDInit /ProcSet findresource begin\n"
4548
                                 "12 dict begin\n"
4549
                                 "begincmap\n"
4550
                                 "/CIDSystemInfo\n"
4551
                                 "<< /Registry (Adobe)\n"
4552
                                 "   /Ordering (UCS)\n"
4553
                                 "   /Supplement 0\n"
4554
                                 ">> def\n"
4555
                                 "/CMapName /Adobe-Identity-UCS def\n"
4556
                                 "/CMapType 2 def\n"
4557
                                 "1 begincodespacerange\n");
4558
 
4559
    if (font_subset->is_composite && !font_subset->is_latin) {
4560
        _cairo_output_stream_printf (surface->output,
4561
                                     "<0000> \n");
4562
    } else {
4563
        _cairo_output_stream_printf (surface->output,
4564
                                     "<00> \n");
4565
    }
4566
 
4567
    _cairo_output_stream_printf (surface->output,
4568
                                  "endcodespacerange\n");
4569
 
4570
    if (font_subset->is_scaled) {
4571
	/* Type 3 fonts include glyph 0 in the subset */
4572
	num_bfchar = font_subset->num_glyphs;
4573
 
4574
	/* The CMap specification has a limit of 100 characters per beginbfchar operator */
4575
	_cairo_output_stream_printf (surface->output,
4576
				     "%d beginbfchar\n",
4577
				     num_bfchar > 100 ? 100 : num_bfchar);
4578
 
4579
	for (i = 0; i < num_bfchar; i++) {
4580
	    if (i != 0 && i % 100 == 0) {
4581
		_cairo_output_stream_printf (surface->output,
4582
					     "endbfchar\n"
4583
					     "%d beginbfchar\n",
4584
					     num_bfchar - i > 100 ? 100 : num_bfchar - i);
4585
	    }
4586
	    _cairo_output_stream_printf (surface->output, "<%02x> ", i);
4587
	    status = _cairo_pdf_surface_emit_unicode_for_glyph (surface,
4588
								font_subset->utf8[i]);
4589
	    if (unlikely (status))
4590
		return status;
4591
 
4592
	    _cairo_output_stream_printf (surface->output,
4593
					 "\n");
4594
	}
4595
    } else {
4596
	/* Other fonts reserve glyph 0 for .notdef. Omit glyph 0 from the /ToUnicode map */
4597
	num_bfchar = font_subset->num_glyphs - 1;
4598
 
4599
	/* The CMap specification has a limit of 100 characters per beginbfchar operator */
4600
	_cairo_output_stream_printf (surface->output,
4601
				     "%d beginbfchar\n",
4602
				     num_bfchar > 100 ? 100 : num_bfchar);
4603
 
4604
	for (i = 0; i < num_bfchar; i++) {
4605
	    if (i != 0 && i % 100 == 0) {
4606
		_cairo_output_stream_printf (surface->output,
4607
					     "endbfchar\n"
4608
					     "%d beginbfchar\n",
4609
					     num_bfchar - i > 100 ? 100 : num_bfchar - i);
4610
	    }
4611
	    if (font_subset->is_latin)
4612
		_cairo_output_stream_printf (surface->output, "<%02x> ", font_subset->to_latin_char[i + 1]);
4613
	    else if (font_subset->is_composite)
4614
		_cairo_output_stream_printf (surface->output, "<%04x> ", i + 1);
4615
	    else
4616
		_cairo_output_stream_printf (surface->output, "<%02x> ", i + 1);
4617
 
4618
	    status = _cairo_pdf_surface_emit_unicode_for_glyph (surface,
4619
								font_subset->utf8[i + 1]);
4620
	    if (unlikely (status))
4621
		return status;
4622
 
4623
	    _cairo_output_stream_printf (surface->output,
4624
					 "\n");
4625
	}
4626
    }
4627
 
4628
    _cairo_output_stream_printf (surface->output,
4629
                                 "endbfchar\n");
4630
 
4631
    _cairo_output_stream_printf (surface->output,
4632
                                 "endcmap\n"
4633
                                 "CMapName currentdict /CMap defineresource pop\n"
4634
                                 "end\n"
4635
                                 "end\n");
4636
 
4637
    *stream = surface->pdf_stream.self;
4638
    return _cairo_pdf_surface_close_stream (surface);
4639
}
4640
 
4641
#define PDF_UNITS_PER_EM 1000
4642
 
4643
static cairo_int_status_t
4644
_cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t		*surface,
4645
                                  cairo_scaled_font_subset_t	*font_subset,
4646
                                  cairo_cff_subset_t            *subset)
4647
{
4648
    cairo_pdf_resource_t stream, descriptor, cidfont_dict;
4649
    cairo_pdf_resource_t subset_resource, to_unicode_stream;
4650
    cairo_pdf_font_t font;
4651
    unsigned int i, last_glyph;
4652
    cairo_int_status_t status;
4653
    char tag[10];
4654
 
4655
    _create_font_subset_tag (font_subset, subset->ps_name, tag);
4656
 
4657
    subset_resource = _cairo_pdf_surface_get_font_resource (surface,
4658
							    font_subset->font_id,
4659
							    font_subset->subset_id);
4660
    if (subset_resource.id == 0)
4661
	return CAIRO_STATUS_SUCCESS;
4662
 
4663
    status = _cairo_pdf_surface_open_stream (surface,
4664
					     NULL,
4665
					     TRUE,
4666
					     font_subset->is_latin ?
4667
					     "   /Subtype /Type1C\n" :
4668
					     "   /Subtype /CIDFontType0C\n");
4669
    if (unlikely (status))
4670
	return status;
4671
 
4672
    stream = surface->pdf_stream.self;
4673
    _cairo_output_stream_write (surface->output,
4674
				subset->data, subset->data_length);
4675
    status = _cairo_pdf_surface_close_stream (surface);
4676
    if (unlikely (status))
4677
	return status;
4678
 
4679
    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
4680
	                                                font_subset,
4681
							&to_unicode_stream);
4682
    if (_cairo_int_status_is_error (status))
4683
	return status;
4684
 
4685
    descriptor = _cairo_pdf_surface_new_object (surface);
4686
    if (descriptor.id == 0)
4687
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4688
 
4689
    _cairo_output_stream_printf (surface->output,
4690
				 "%d 0 obj\n"
4691
				 "<< /Type /FontDescriptor\n"
4692
				 "   /FontName /%s+%s\n",
4693
				 descriptor.id,
4694
				 tag,
4695
				 subset->ps_name);
4696
 
4697
    if (subset->family_name_utf8) {
4698
	char *pdf_str;
4699
 
4700
	status = _utf8_to_pdf_string (subset->family_name_utf8, &pdf_str);
4701
	if (unlikely (status))
4702
	    return status;
4703
 
4704
	_cairo_output_stream_printf (surface->output,
4705
				     "   /FontFamily %s\n",
4706
				     pdf_str);
4707
	free (pdf_str);
4708
    }
4709
 
4710
    _cairo_output_stream_printf (surface->output,
4711
				 "   /Flags 4\n"
4712
				 "   /FontBBox [ %ld %ld %ld %ld ]\n"
4713
				 "   /ItalicAngle 0\n"
4714
				 "   /Ascent %ld\n"
4715
				 "   /Descent %ld\n"
4716
				 "   /CapHeight %ld\n"
4717
				 "   /StemV 80\n"
4718
				 "   /StemH 80\n"
4719
				 "   /FontFile3 %u 0 R\n"
4720
				 ">>\n"
4721
				 "endobj\n",
4722
				 (long)(subset->x_min*PDF_UNITS_PER_EM),
4723
				 (long)(subset->y_min*PDF_UNITS_PER_EM),
4724
				 (long)(subset->x_max*PDF_UNITS_PER_EM),
4725
				 (long)(subset->y_max*PDF_UNITS_PER_EM),
4726
				 (long)(subset->ascent*PDF_UNITS_PER_EM),
4727
				 (long)(subset->descent*PDF_UNITS_PER_EM),
4728
				 (long)(subset->y_max*PDF_UNITS_PER_EM),
4729
				 stream.id);
4730
 
4731
    if (font_subset->is_latin) {
4732
	/* find last glyph used */
4733
	for (i = 255; i >= 32; i--)
4734
	    if (font_subset->latin_to_subset_glyph_index[i] > 0)
4735
		break;
4736
 
4737
	last_glyph = i;
4738
	_cairo_pdf_surface_update_object (surface, subset_resource);
4739
	_cairo_output_stream_printf (surface->output,
4740
				     "%d 0 obj\n"
4741
				     "<< /Type /Font\n"
4742
				     "   /Subtype /Type1\n"
4743
				     "   /BaseFont /%s+%s\n"
4744
				     "   /FirstChar 32\n"
4745
				     "   /LastChar %d\n"
4746
				     "   /FontDescriptor %d 0 R\n"
4747
				     "   /Encoding /WinAnsiEncoding\n"
4748
				     "   /Widths [",
4749
				     subset_resource.id,
4750
				     tag,
4751
				     subset->ps_name,
4752
				     last_glyph,
4753
				     descriptor.id);
4754
 
4755
	for (i = 32; i < last_glyph + 1; i++) {
4756
	    int glyph = font_subset->latin_to_subset_glyph_index[i];
4757
	    if (glyph > 0) {
4758
		_cairo_output_stream_printf (surface->output,
4759
					     " %ld",
4760
					     (long)(subset->widths[glyph]*PDF_UNITS_PER_EM));
4761
	    } else {
4762
		_cairo_output_stream_printf (surface->output, " 0");
4763
	    }
4764
	}
4765
 
4766
	_cairo_output_stream_printf (surface->output,
4767
				     " ]\n");
4768
 
4769
	if (to_unicode_stream.id != 0)
4770
	    _cairo_output_stream_printf (surface->output,
4771
					 "    /ToUnicode %d 0 R\n",
4772
					 to_unicode_stream.id);
4773
 
4774
	_cairo_output_stream_printf (surface->output,
4775
				     ">>\n"
4776
				     "endobj\n");
4777
    } else {
4778
	cidfont_dict = _cairo_pdf_surface_new_object (surface);
4779
	if (cidfont_dict.id == 0)
4780
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4781
 
4782
	_cairo_output_stream_printf (surface->output,
4783
				     "%d 0 obj\n"
4784
				     "<< /Type /Font\n"
4785
				     "   /Subtype /CIDFontType0\n"
4786
				     "   /BaseFont /%s+%s\n"
4787
				     "   /CIDSystemInfo\n"
4788
				     "   << /Registry (Adobe)\n"
4789
				     "      /Ordering (Identity)\n"
4790
				     "      /Supplement 0\n"
4791
				     "   >>\n"
4792
				     "   /FontDescriptor %d 0 R\n"
4793
				     "   /W [0 [",
4794
				     cidfont_dict.id,
4795
				     tag,
4796
				     subset->ps_name,
4797
				     descriptor.id);
4798
 
4799
	for (i = 0; i < font_subset->num_glyphs; i++)
4800
	    _cairo_output_stream_printf (surface->output,
4801
					 " %ld",
4802
					 (long)(subset->widths[i]*PDF_UNITS_PER_EM));
4803
 
4804
	_cairo_output_stream_printf (surface->output,
4805
				     " ]]\n"
4806
				     ">>\n"
4807
				     "endobj\n");
4808
 
4809
	_cairo_pdf_surface_update_object (surface, subset_resource);
4810
	_cairo_output_stream_printf (surface->output,
4811
				     "%d 0 obj\n"
4812
				     "<< /Type /Font\n"
4813
				     "   /Subtype /Type0\n"
4814
				     "   /BaseFont /%s+%s\n"
4815
				     "   /Encoding /Identity-H\n"
4816
				     "   /DescendantFonts [ %d 0 R]\n",
4817
				     subset_resource.id,
4818
				     tag,
4819
				     subset->ps_name,
4820
				     cidfont_dict.id);
4821
 
4822
	if (to_unicode_stream.id != 0)
4823
	    _cairo_output_stream_printf (surface->output,
4824
					 "   /ToUnicode %d 0 R\n",
4825
					 to_unicode_stream.id);
4826
 
4827
	_cairo_output_stream_printf (surface->output,
4828
				     ">>\n"
4829
				     "endobj\n");
4830
    }
4831
 
4832
    font.font_id = font_subset->font_id;
4833
    font.subset_id = font_subset->subset_id;
4834
    font.subset_resource = subset_resource;
4835
    status = _cairo_array_append (&surface->fonts, &font);
4836
 
4837
    return status;
4838
}
4839
 
4840
static cairo_int_status_t
4841
_cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t	     *surface,
4842
                                         cairo_scaled_font_subset_t  *font_subset)
4843
{
4844
    cairo_int_status_t status;
4845
    cairo_cff_subset_t subset;
4846
    char name[64];
4847
 
4848
    snprintf (name, sizeof name, "CairoFont-%d-%d",
4849
              font_subset->font_id, font_subset->subset_id);
4850
    status = _cairo_cff_subset_init (&subset, name, font_subset);
4851
    if (unlikely (status))
4852
        return status;
4853
 
4854
    status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
4855
 
4856
    _cairo_cff_subset_fini (&subset);
4857
 
4858
    return status;
4859
}
4860
 
4861
static cairo_int_status_t
4862
_cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t	       *surface,
4863
                                           cairo_scaled_font_subset_t  *font_subset)
4864
{
4865
    cairo_int_status_t status;
4866
    cairo_cff_subset_t subset;
4867
    char name[64];
4868
 
4869
    /* CFF fallback subsetting does not work with 8-bit glyphs unless
4870
     * they are a latin subset */
4871
    if (!font_subset->is_composite && !font_subset->is_latin)
4872
	return CAIRO_INT_STATUS_UNSUPPORTED;
4873
 
4874
    snprintf (name, sizeof name, "CairoFont-%d-%d",
4875
              font_subset->font_id, font_subset->subset_id);
4876
    status = _cairo_cff_fallback_init (&subset, name, font_subset);
4877
    if (unlikely (status))
4878
        return status;
4879
 
4880
    status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset);
4881
 
4882
    _cairo_cff_fallback_fini (&subset);
4883
 
4884
    return status;
4885
}
4886
 
4887
static cairo_int_status_t
4888
_cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t		*surface,
4889
                                    cairo_scaled_font_subset_t	*font_subset,
4890
                                    cairo_type1_subset_t        *subset)
4891
{
4892
    cairo_pdf_resource_t stream, descriptor, subset_resource, to_unicode_stream;
4893
    cairo_pdf_font_t font;
4894
    cairo_int_status_t status;
4895
    unsigned long length;
4896
    unsigned int i, last_glyph;
4897
    char tag[10];
4898
 
4899
    _create_font_subset_tag (font_subset, subset->base_font, tag);
4900
 
4901
    subset_resource = _cairo_pdf_surface_get_font_resource (surface,
4902
							    font_subset->font_id,
4903
							    font_subset->subset_id);
4904
    if (subset_resource.id == 0)
4905
	return CAIRO_STATUS_SUCCESS;
4906
 
4907
    length = subset->header_length + subset->data_length + subset->trailer_length;
4908
    status = _cairo_pdf_surface_open_stream (surface,
4909
					     NULL,
4910
					     TRUE,
4911
					     "   /Length1 %lu\n"
4912
					     "   /Length2 %lu\n"
4913
					     "   /Length3 %lu\n",
4914
					     subset->header_length,
4915
					     subset->data_length,
4916
					     subset->trailer_length);
4917
    if (unlikely (status))
4918
	return status;
4919
 
4920
    stream = surface->pdf_stream.self;
4921
    _cairo_output_stream_write (surface->output, subset->data, length);
4922
    status = _cairo_pdf_surface_close_stream (surface);
4923
    if (unlikely (status))
4924
	return status;
4925
 
4926
    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
4927
	                                                font_subset,
4928
							&to_unicode_stream);
4929
    if (_cairo_int_status_is_error (status))
4930
	return status;
4931
 
4932
    last_glyph = font_subset->num_glyphs - 1;
4933
    if (font_subset->is_latin) {
4934
	/* find last glyph used */
4935
	for (i = 255; i >= 32; i--)
4936
	    if (font_subset->latin_to_subset_glyph_index[i] > 0)
4937
		break;
4938
 
4939
	last_glyph = i;
4940
    }
4941
 
4942
    descriptor = _cairo_pdf_surface_new_object (surface);
4943
    if (descriptor.id == 0)
4944
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4945
 
4946
    _cairo_output_stream_printf (surface->output,
4947
				 "%d 0 obj\n"
4948
				 "<< /Type /FontDescriptor\n"
4949
				 "   /FontName /%s+%s\n"
4950
				 "   /Flags 4\n"
4951
				 "   /FontBBox [ %ld %ld %ld %ld ]\n"
4952
				 "   /ItalicAngle 0\n"
4953
				 "   /Ascent %ld\n"
4954
				 "   /Descent %ld\n"
4955
				 "   /CapHeight %ld\n"
4956
				 "   /StemV 80\n"
4957
				 "   /StemH 80\n"
4958
				 "   /FontFile %u 0 R\n"
4959
				 ">>\n"
4960
				 "endobj\n",
4961
				 descriptor.id,
4962
				 tag,
4963
				 subset->base_font,
4964
				 (long)(subset->x_min*PDF_UNITS_PER_EM),
4965
				 (long)(subset->y_min*PDF_UNITS_PER_EM),
4966
				 (long)(subset->x_max*PDF_UNITS_PER_EM),
4967
				 (long)(subset->y_max*PDF_UNITS_PER_EM),
4968
				 (long)(subset->ascent*PDF_UNITS_PER_EM),
4969
				 (long)(subset->descent*PDF_UNITS_PER_EM),
4970
				 (long)(subset->y_max*PDF_UNITS_PER_EM),
4971
				 stream.id);
4972
 
4973
    _cairo_pdf_surface_update_object (surface, subset_resource);
4974
    _cairo_output_stream_printf (surface->output,
4975
				 "%d 0 obj\n"
4976
				 "<< /Type /Font\n"
4977
				 "   /Subtype /Type1\n"
4978
				 "   /BaseFont /%s+%s\n"
4979
				 "   /FirstChar %d\n"
4980
				 "   /LastChar %d\n"
4981
				 "   /FontDescriptor %d 0 R\n",
4982
				 subset_resource.id,
4983
				 tag,
4984
				 subset->base_font,
4985
				 font_subset->is_latin ? 32 : 0,
4986
				 last_glyph,
4987
				 descriptor.id);
4988
 
4989
    if (font_subset->is_latin)
4990
	_cairo_output_stream_printf (surface->output, "   /Encoding /WinAnsiEncoding\n");
4991
 
4992
    _cairo_output_stream_printf (surface->output, "   /Widths [");
4993
    if (font_subset->is_latin) {
4994
	for (i = 32; i < last_glyph + 1; i++) {
4995
	    int glyph = font_subset->latin_to_subset_glyph_index[i];
4996
	    if (glyph > 0) {
4997
		_cairo_output_stream_printf (surface->output,
4998
					     " %ld",
4999
					     (long)(subset->widths[glyph]*PDF_UNITS_PER_EM));
5000
	    } else {
5001
		_cairo_output_stream_printf (surface->output, " 0");
5002
	    }
5003
	}
5004
    } else {
5005
	for (i = 0; i < font_subset->num_glyphs; i++)
5006
	    _cairo_output_stream_printf (surface->output,
5007
					 " %ld",
5008
					 (long)(subset->widths[i]*PDF_UNITS_PER_EM));
5009
    }
5010
 
5011
    _cairo_output_stream_printf (surface->output,
5012
				 " ]\n");
5013
 
5014
    if (to_unicode_stream.id != 0)
5015
        _cairo_output_stream_printf (surface->output,
5016
                                     "    /ToUnicode %d 0 R\n",
5017
                                     to_unicode_stream.id);
5018
 
5019
    _cairo_output_stream_printf (surface->output,
5020
				 ">>\n"
5021
				 "endobj\n");
5022
 
5023
    font.font_id = font_subset->font_id;
5024
    font.subset_id = font_subset->subset_id;
5025
    font.subset_resource = subset_resource;
5026
    return _cairo_array_append (&surface->fonts, &font);
5027
}
5028
 
5029
static cairo_int_status_t
5030
_cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t		*surface,
5031
					   cairo_scaled_font_subset_t	*font_subset)
5032
{
5033
    cairo_int_status_t status;
5034
    cairo_type1_subset_t subset;
5035
    char name[64];
5036
 
5037
    /* 16-bit glyphs not compatible with Type 1 fonts */
5038
    if (font_subset->is_composite && !font_subset->is_latin)
5039
	return CAIRO_INT_STATUS_UNSUPPORTED;
5040
 
5041
    snprintf (name, sizeof name, "CairoFont-%d-%d",
5042
	      font_subset->font_id, font_subset->subset_id);
5043
    status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE);
5044
    if (unlikely (status))
5045
	return status;
5046
 
5047
    status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
5048
 
5049
    _cairo_type1_subset_fini (&subset);
5050
    return status;
5051
}
5052
 
5053
static cairo_int_status_t
5054
_cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t	*surface,
5055
                                             cairo_scaled_font_subset_t	*font_subset)
5056
{
5057
    cairo_int_status_t status;
5058
    cairo_type1_subset_t subset;
5059
    char name[64];
5060
 
5061
    /* 16-bit glyphs not compatible with Type 1 fonts */
5062
    if (font_subset->is_composite && !font_subset->is_latin)
5063
	return CAIRO_INT_STATUS_UNSUPPORTED;
5064
 
5065
    snprintf (name, sizeof name, "CairoFont-%d-%d",
5066
	      font_subset->font_id, font_subset->subset_id);
5067
    status = _cairo_type1_fallback_init_binary (&subset, name, font_subset);
5068
    if (unlikely (status))
5069
	return status;
5070
 
5071
    status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset);
5072
 
5073
    _cairo_type1_fallback_fini (&subset);
5074
    return status;
5075
}
5076
 
5077
static cairo_int_status_t
5078
_cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t		*surface,
5079
					      cairo_scaled_font_subset_t	*font_subset)
5080
{
5081
    cairo_pdf_resource_t stream, descriptor, cidfont_dict;
5082
    cairo_pdf_resource_t subset_resource, to_unicode_stream;
5083
    cairo_int_status_t status;
5084
    cairo_pdf_font_t font;
5085
    cairo_truetype_subset_t subset;
5086
    unsigned int i, last_glyph;
5087
    char tag[10];
5088
 
5089
    subset_resource = _cairo_pdf_surface_get_font_resource (surface,
5090
							    font_subset->font_id,
5091
							    font_subset->subset_id);
5092
    if (subset_resource.id == 0)
5093
	return CAIRO_STATUS_SUCCESS;
5094
 
5095
    status = _cairo_truetype_subset_init_pdf (&subset, font_subset);
5096
    if (unlikely (status))
5097
	return status;
5098
 
5099
    _create_font_subset_tag (font_subset, subset.ps_name, tag);
5100
 
5101
    status = _cairo_pdf_surface_open_stream (surface,
5102
					     NULL,
5103
					     TRUE,
5104
					     "   /Length1 %lu\n",
5105
					     subset.data_length);
5106
    if (unlikely (status)) {
5107
	_cairo_truetype_subset_fini (&subset);
5108
	return status;
5109
    }
5110
 
5111
    stream = surface->pdf_stream.self;
5112
    _cairo_output_stream_write (surface->output,
5113
				subset.data, subset.data_length);
5114
    status = _cairo_pdf_surface_close_stream (surface);
5115
    if (unlikely (status)) {
5116
	_cairo_truetype_subset_fini (&subset);
5117
	return status;
5118
    }
5119
 
5120
    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
5121
	                                                font_subset,
5122
							&to_unicode_stream);
5123
    if (_cairo_int_status_is_error (status)) {
5124
	_cairo_truetype_subset_fini (&subset);
5125
	return status;
5126
    }
5127
 
5128
    descriptor = _cairo_pdf_surface_new_object (surface);
5129
    if (descriptor.id == 0) {
5130
	_cairo_truetype_subset_fini (&subset);
5131
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5132
    }
5133
 
5134
    _cairo_output_stream_printf (surface->output,
5135
				 "%d 0 obj\n"
5136
				 "<< /Type /FontDescriptor\n"
5137
				 "   /FontName /%s+%s\n",
5138
				 descriptor.id,
5139
				 tag,
5140
				 subset.ps_name);
5141
 
5142
    if (subset.family_name_utf8) {
5143
	char *pdf_str;
5144
 
5145
	status = _utf8_to_pdf_string (subset.family_name_utf8, &pdf_str);
5146
	if (unlikely (status))
5147
	    return status;
5148
 
5149
	_cairo_output_stream_printf (surface->output,
5150
				     "   /FontFamily %s\n",
5151
				     pdf_str);
5152
	free (pdf_str);
5153
    }
5154
 
5155
    _cairo_output_stream_printf (surface->output,
5156
				 "   /Flags %d\n"
5157
				 "   /FontBBox [ %ld %ld %ld %ld ]\n"
5158
				 "   /ItalicAngle 0\n"
5159
				 "   /Ascent %ld\n"
5160
				 "   /Descent %ld\n"
5161
				 "   /CapHeight %ld\n"
5162
				 "   /StemV 80\n"
5163
				 "   /StemH 80\n"
5164
				 "   /FontFile2 %u 0 R\n"
5165
				 ">>\n"
5166
				 "endobj\n",
5167
				 font_subset->is_latin ? 32 : 4,
5168
				 (long)(subset.x_min*PDF_UNITS_PER_EM),
5169
				 (long)(subset.y_min*PDF_UNITS_PER_EM),
5170
                                 (long)(subset.x_max*PDF_UNITS_PER_EM),
5171
				 (long)(subset.y_max*PDF_UNITS_PER_EM),
5172
				 (long)(subset.ascent*PDF_UNITS_PER_EM),
5173
				 (long)(subset.descent*PDF_UNITS_PER_EM),
5174
				 (long)(subset.y_max*PDF_UNITS_PER_EM),
5175
				 stream.id);
5176
 
5177
    if (font_subset->is_latin) {
5178
	/* find last glyph used */
5179
	for (i = 255; i >= 32; i--)
5180
	    if (font_subset->latin_to_subset_glyph_index[i] > 0)
5181
		break;
5182
 
5183
	last_glyph = i;
5184
	_cairo_pdf_surface_update_object (surface, subset_resource);
5185
	_cairo_output_stream_printf (surface->output,
5186
				     "%d 0 obj\n"
5187
				     "<< /Type /Font\n"
5188
				     "   /Subtype /TrueType\n"
5189
				     "   /BaseFont /%s+%s\n"
5190
				     "   /FirstChar 32\n"
5191
				     "   /LastChar %d\n"
5192
				     "   /FontDescriptor %d 0 R\n"
5193
				     "   /Encoding /WinAnsiEncoding\n"
5194
				     "   /Widths [",
5195
				     subset_resource.id,
5196
				     tag,
5197
				     subset.ps_name,
5198
				     last_glyph,
5199
				     descriptor.id);
5200
 
5201
	for (i = 32; i < last_glyph + 1; i++) {
5202
	    int glyph = font_subset->latin_to_subset_glyph_index[i];
5203
	    if (glyph > 0) {
5204
		_cairo_output_stream_printf (surface->output,
5205
					     " %ld",
5206
					     (long)(subset.widths[glyph]*PDF_UNITS_PER_EM));
5207
	    } else {
5208
		_cairo_output_stream_printf (surface->output, " 0");
5209
	    }
5210
	}
5211
 
5212
	_cairo_output_stream_printf (surface->output,
5213
				     " ]\n");
5214
 
5215
	if (to_unicode_stream.id != 0)
5216
	    _cairo_output_stream_printf (surface->output,
5217
					 "    /ToUnicode %d 0 R\n",
5218
					 to_unicode_stream.id);
5219
 
5220
	_cairo_output_stream_printf (surface->output,
5221
				     ">>\n"
5222
				     "endobj\n");
5223
    } else {
5224
	cidfont_dict = _cairo_pdf_surface_new_object (surface);
5225
	if (cidfont_dict.id == 0) {
5226
	    _cairo_truetype_subset_fini (&subset);
5227
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5228
	}
5229
 
5230
	_cairo_output_stream_printf (surface->output,
5231
				     "%d 0 obj\n"
5232
				     "<< /Type /Font\n"
5233
				     "   /Subtype /CIDFontType2\n"
5234
				     "   /BaseFont /%s+%s\n"
5235
				     "   /CIDSystemInfo\n"
5236
				     "   << /Registry (Adobe)\n"
5237
				     "      /Ordering (Identity)\n"
5238
				     "      /Supplement 0\n"
5239
				     "   >>\n"
5240
				     "   /FontDescriptor %d 0 R\n"
5241
				     "   /W [0 [",
5242
				     cidfont_dict.id,
5243
				     tag,
5244
				     subset.ps_name,
5245
				     descriptor.id);
5246
 
5247
	for (i = 0; i < font_subset->num_glyphs; i++)
5248
	    _cairo_output_stream_printf (surface->output,
5249
					 " %ld",
5250
					 (long)(subset.widths[i]*PDF_UNITS_PER_EM));
5251
 
5252
	_cairo_output_stream_printf (surface->output,
5253
				     " ]]\n"
5254
				     ">>\n"
5255
				     "endobj\n");
5256
 
5257
	_cairo_pdf_surface_update_object (surface, subset_resource);
5258
	_cairo_output_stream_printf (surface->output,
5259
				     "%d 0 obj\n"
5260
				     "<< /Type /Font\n"
5261
				     "   /Subtype /Type0\n"
5262
				     "   /BaseFont /%s+%s\n"
5263
				     "   /Encoding /Identity-H\n"
5264
				     "   /DescendantFonts [ %d 0 R]\n",
5265
				     subset_resource.id,
5266
				     tag,
5267
				     subset.ps_name,
5268
				     cidfont_dict.id);
5269
 
5270
	if (to_unicode_stream.id != 0)
5271
	    _cairo_output_stream_printf (surface->output,
5272
					 "   /ToUnicode %d 0 R\n",
5273
					 to_unicode_stream.id);
5274
 
5275
	_cairo_output_stream_printf (surface->output,
5276
				     ">>\n"
5277
				     "endobj\n");
5278
    }
5279
 
5280
    font.font_id = font_subset->font_id;
5281
    font.subset_id = font_subset->subset_id;
5282
    font.subset_resource = subset_resource;
5283
    status = _cairo_array_append (&surface->fonts, &font);
5284
 
5285
    _cairo_truetype_subset_fini (&subset);
5286
 
5287
    return status;
5288
}
5289
 
5290
static cairo_int_status_t
5291
_cairo_pdf_emit_imagemask (cairo_image_surface_t *image,
5292
			     cairo_output_stream_t *stream)
5293
{
5294
    uint8_t *byte, output_byte;
5295
    int row, col, num_cols;
5296
 
5297
    /* The only image type supported by Type 3 fonts are 1-bit image
5298
     * masks */
5299
    assert (image->format == CAIRO_FORMAT_A1);
5300
 
5301
    _cairo_output_stream_printf (stream,
5302
				 "BI\n"
5303
				 "/IM true\n"
5304
				 "/W %d\n"
5305
				 "/H %d\n"
5306
				 "/BPC 1\n"
5307
				 "/D [1 0]\n",
5308
				 image->width,
5309
				 image->height);
5310
 
5311
    _cairo_output_stream_printf (stream,
5312
				 "ID ");
5313
 
5314
    num_cols = (image->width + 7) / 8;
5315
    for (row = 0; row < image->height; row++) {
5316
	byte = image->data + row * image->stride;
5317
	for (col = 0; col < num_cols; col++) {
5318
	    output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
5319
	    _cairo_output_stream_write (stream, &output_byte, 1);
5320
	    byte++;
5321
	}
5322
    }
5323
 
5324
    _cairo_output_stream_printf (stream,
5325
				 "\nEI\n");
5326
 
5327
    return _cairo_output_stream_get_status (stream);
5328
}
5329
 
5330
static cairo_int_status_t
5331
_cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
5332
					     void		        *closure)
5333
{
5334
    cairo_pdf_surface_t *surface = closure;
5335
    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
5336
    cairo_int_status_t status2;
5337
    unsigned int i;
5338
    cairo_surface_t *type3_surface;
5339
    cairo_output_stream_t *null_stream;
5340
 
5341
    null_stream = _cairo_null_stream_create ();
5342
    type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
5343
						       null_stream,
5344
						       _cairo_pdf_emit_imagemask,
5345
						       surface->font_subsets);
5346
    if (unlikely (type3_surface->status)) {
5347
	status2 = _cairo_output_stream_destroy (null_stream);
5348
	return type3_surface->status;
5349
    }
5350
 
5351
    _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
5352
							  _cairo_pdf_surface_add_font,
5353
							  surface);
5354
 
5355
    for (i = 0; i < font_subset->num_glyphs; i++) {
5356
	status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
5357
							   font_subset->glyphs[i]);
5358
	if (unlikely (status))
5359
	    break;
5360
    }
5361
 
5362
    cairo_surface_destroy (type3_surface);
5363
    status2 = _cairo_output_stream_destroy (null_stream);
5364
    if (status == CAIRO_INT_STATUS_SUCCESS)
5365
	status = status2;
5366
 
5367
    return status;
5368
}
5369
 
5370
static cairo_int_status_t
5371
_cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t		*surface,
5372
					   cairo_scaled_font_subset_t	*font_subset)
5373
{
5374
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
5375
    cairo_pdf_resource_t *glyphs, encoding, char_procs, subset_resource, to_unicode_stream;
5376
    cairo_pdf_font_t font;
5377
    double *widths;
5378
    unsigned int i;
5379
    cairo_box_t font_bbox = {{0,0},{0,0}};
5380
    cairo_box_t bbox = {{0,0},{0,0}};
5381
    cairo_surface_t *type3_surface;
5382
 
5383
    if (font_subset->num_glyphs == 0)
5384
	return CAIRO_STATUS_SUCCESS;
5385
 
5386
    subset_resource = _cairo_pdf_surface_get_font_resource (surface,
5387
							    font_subset->font_id,
5388
							    font_subset->subset_id);
5389
    if (subset_resource.id == 0)
5390
	return CAIRO_STATUS_SUCCESS;
5391
 
5392
    glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t));
5393
    if (unlikely (glyphs == NULL))
5394
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5395
 
5396
    widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double));
5397
    if (unlikely (widths == NULL)) {
5398
        free (glyphs);
5399
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5400
    }
5401
 
5402
    _cairo_pdf_group_resources_clear (&surface->resources);
5403
    type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
5404
						       NULL,
5405
						       _cairo_pdf_emit_imagemask,
5406
						       surface->font_subsets);
5407
    if (unlikely (type3_surface->status)) {
5408
        free (glyphs);
5409
        free (widths);
5410
	return type3_surface->status;
5411
    }
5412
 
5413
    _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
5414
							  _cairo_pdf_surface_add_font,
5415
							  surface);
5416
 
5417
    for (i = 0; i < font_subset->num_glyphs; i++) {
5418
	status = _cairo_pdf_surface_open_stream (surface,
5419
						 NULL,
5420
						 surface->compress_content,
5421
						 NULL);
5422
	if (unlikely (status))
5423
	    break;
5424
 
5425
	glyphs[i] = surface->pdf_stream.self;
5426
	status = _cairo_type3_glyph_surface_emit_glyph (type3_surface,
5427
							surface->output,
5428
							font_subset->glyphs[i],
5429
							&bbox,
5430
							&widths[i]);
5431
	if (unlikely (status))
5432
	    break;
5433
 
5434
	status = _cairo_pdf_surface_close_stream (surface);
5435
	if (unlikely (status))
5436
	    break;
5437
 
5438
        if (i == 0) {
5439
            font_bbox.p1.x = bbox.p1.x;
5440
            font_bbox.p1.y = bbox.p1.y;
5441
            font_bbox.p2.x = bbox.p2.x;
5442
            font_bbox.p2.y = bbox.p2.y;
5443
        } else {
5444
            if (bbox.p1.x < font_bbox.p1.x)
5445
                font_bbox.p1.x = bbox.p1.x;
5446
            if (bbox.p1.y < font_bbox.p1.y)
5447
                font_bbox.p1.y = bbox.p1.y;
5448
            if (bbox.p2.x > font_bbox.p2.x)
5449
                font_bbox.p2.x = bbox.p2.x;
5450
            if (bbox.p2.y > font_bbox.p2.y)
5451
                font_bbox.p2.y = bbox.p2.y;
5452
        }
5453
    }
5454
    cairo_surface_destroy (type3_surface);
5455
    if (unlikely (status)) {
5456
	free (glyphs);
5457
	free (widths);
5458
	return status;
5459
    }
5460
 
5461
    encoding = _cairo_pdf_surface_new_object (surface);
5462
    if (encoding.id == 0) {
5463
	free (glyphs);
5464
	free (widths);
5465
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5466
    }
5467
 
5468
    _cairo_output_stream_printf (surface->output,
5469
				 "%d 0 obj\n"
5470
				 "<< /Type /Encoding\n"
5471
				 "   /Differences [0", encoding.id);
5472
    for (i = 0; i < font_subset->num_glyphs; i++)
5473
	_cairo_output_stream_printf (surface->output,
5474
				     " /%d", i);
5475
    _cairo_output_stream_printf (surface->output,
5476
				 "]\n"
5477
				 ">>\n"
5478
				 "endobj\n");
5479
 
5480
    char_procs = _cairo_pdf_surface_new_object (surface);
5481
    if (char_procs.id == 0) {
5482
	free (glyphs);
5483
	free (widths);
5484
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5485
    }
5486
 
5487
    _cairo_output_stream_printf (surface->output,
5488
				 "%d 0 obj\n"
5489
				 "<<\n", char_procs.id);
5490
    for (i = 0; i < font_subset->num_glyphs; i++)
5491
	_cairo_output_stream_printf (surface->output,
5492
				     " /%d %d 0 R\n",
5493
				     i, glyphs[i].id);
5494
    _cairo_output_stream_printf (surface->output,
5495
				 ">>\n"
5496
				 "endobj\n");
5497
 
5498
    free (glyphs);
5499
 
5500
    status = _cairo_pdf_surface_emit_to_unicode_stream (surface,
5501
	                                                font_subset,
5502
							&to_unicode_stream);
5503
    if (_cairo_int_status_is_error (status)) {
5504
	free (widths);
5505
	return status;
5506
    }
5507
 
5508
    _cairo_pdf_surface_update_object (surface, subset_resource);
5509
    _cairo_output_stream_printf (surface->output,
5510
				 "%d 0 obj\n"
5511
				 "<< /Type /Font\n"
5512
				 "   /Subtype /Type3\n"
5513
				 "   /FontBBox [%f %f %f %f]\n"
5514
				 "   /FontMatrix [ 1 0 0 1 0 0 ]\n"
5515
				 "   /Encoding %d 0 R\n"
5516
				 "   /CharProcs %d 0 R\n"
5517
				 "   /FirstChar 0\n"
5518
				 "   /LastChar %d\n",
5519
				 subset_resource.id,
5520
				 _cairo_fixed_to_double (font_bbox.p1.x),
5521
				 - _cairo_fixed_to_double (font_bbox.p2.y),
5522
				 _cairo_fixed_to_double (font_bbox.p2.x),
5523
				 - _cairo_fixed_to_double (font_bbox.p1.y),
5524
				 encoding.id,
5525
				 char_procs.id,
5526
				 font_subset->num_glyphs - 1);
5527
 
5528
    _cairo_output_stream_printf (surface->output,
5529
				 "   /Widths [");
5530
    for (i = 0; i < font_subset->num_glyphs; i++)
5531
	_cairo_output_stream_printf (surface->output, " %f", widths[i]);
5532
    _cairo_output_stream_printf (surface->output,
5533
				 "]\n");
5534
    free (widths);
5535
 
5536
    _cairo_output_stream_printf (surface->output,
5537
				 "   /Resources\n");
5538
    _cairo_pdf_surface_emit_group_resources (surface, &surface->resources);
5539
 
5540
    if (to_unicode_stream.id != 0)
5541
        _cairo_output_stream_printf (surface->output,
5542
                                     "    /ToUnicode %d 0 R\n",
5543
                                     to_unicode_stream.id);
5544
 
5545
    _cairo_output_stream_printf (surface->output,
5546
				 ">>\n"
5547
				 "endobj\n");
5548
 
5549
    font.font_id = font_subset->font_id;
5550
    font.subset_id = font_subset->subset_id;
5551
    font.subset_resource = subset_resource;
5552
    return _cairo_array_append (&surface->fonts, &font);
5553
}
5554
 
5555
static cairo_int_status_t
5556
_cairo_pdf_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
5557
                                              void			 *closure)
5558
{
5559
    cairo_pdf_surface_t *surface = closure;
5560
    cairo_int_status_t status;
5561
 
5562
    status = _cairo_pdf_surface_emit_cff_font_subset (surface, font_subset);
5563
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5564
	return status;
5565
 
5566
    status = _cairo_pdf_surface_emit_truetype_font_subset (surface, font_subset);
5567
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5568
	return status;
5569
 
5570
    status = _cairo_pdf_surface_emit_type1_font_subset (surface, font_subset);
5571
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5572
	return status;
5573
 
5574
    status = _cairo_pdf_surface_emit_cff_fallback_font (surface, font_subset);
5575
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5576
	return status;
5577
 
5578
    status = _cairo_pdf_surface_emit_type1_fallback_font (surface, font_subset);
5579
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5580
	return status;
5581
 
5582
    ASSERT_NOT_REACHED;
5583
    return CAIRO_INT_STATUS_SUCCESS;
5584
}
5585
 
5586
static cairo_int_status_t
5587
_cairo_pdf_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
5588
                                            void		       *closure)
5589
{
5590
    cairo_pdf_surface_t *surface = closure;
5591
    cairo_int_status_t status;
5592
 
5593
    status = _cairo_pdf_surface_emit_type3_font_subset (surface, font_subset);
5594
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
5595
	return status;
5596
 
5597
    ASSERT_NOT_REACHED;
5598
    return CAIRO_INT_STATUS_SUCCESS;
5599
}
5600
 
5601
static cairo_int_status_t
5602
_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface)
5603
{
5604
    cairo_int_status_t status;
5605
 
5606
    status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
5607
						      _cairo_pdf_surface_analyze_user_font_subset,
5608
						      surface);
5609
    if (unlikely (status))
5610
	goto BAIL;
5611
 
5612
    status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
5613
                                                          _cairo_pdf_surface_emit_unscaled_font_subset,
5614
                                                          surface);
5615
    if (unlikely (status))
5616
	goto BAIL;
5617
 
5618
    status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
5619
                                                        _cairo_pdf_surface_emit_scaled_font_subset,
5620
                                                        surface);
5621
    if (unlikely (status))
5622
	goto BAIL;
5623
 
5624
    status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
5625
						      _cairo_pdf_surface_emit_scaled_font_subset,
5626
						      surface);
5627
 
5628
BAIL:
5629
    _cairo_scaled_font_subsets_destroy (surface->font_subsets);
5630
    surface->font_subsets = NULL;
5631
 
5632
    return status;
5633
}
5634
 
5635
static cairo_pdf_resource_t
5636
_cairo_pdf_surface_write_catalog (cairo_pdf_surface_t *surface)
5637
{
5638
    cairo_pdf_resource_t catalog;
5639
 
5640
    catalog = _cairo_pdf_surface_new_object (surface);
5641
    if (catalog.id == 0)
5642
	return catalog;
5643
 
5644
    _cairo_output_stream_printf (surface->output,
5645
				 "%d 0 obj\n"
5646
				 "<< /Type /Catalog\n"
5647
				 "   /Pages %d 0 R\n"
5648
				 ">>\n"
5649
				 "endobj\n",
5650
				 catalog.id,
5651
				 surface->pages_resource.id);
5652
 
5653
    return catalog;
5654
}
5655
 
5656
static long
5657
_cairo_pdf_surface_write_xref (cairo_pdf_surface_t *surface)
5658
{
5659
    cairo_pdf_object_t *object;
5660
    int num_objects, i;
5661
    long offset;
5662
    char buffer[11];
5663
 
5664
    num_objects = _cairo_array_num_elements (&surface->objects);
5665
 
5666
    offset = _cairo_output_stream_get_position (surface->output);
5667
    _cairo_output_stream_printf (surface->output,
5668
				 "xref\n"
5669
				 "%d %d\n",
5670
				 0, num_objects + 1);
5671
 
5672
    _cairo_output_stream_printf (surface->output,
5673
				 "0000000000 65535 f \n");
5674
    for (i = 0; i < num_objects; i++) {
5675
	object = _cairo_array_index (&surface->objects, i);
5676
	snprintf (buffer, sizeof buffer, "%010ld", object->offset);
5677
	_cairo_output_stream_printf (surface->output,
5678
				     "%s 00000 n \n", buffer);
5679
    }
5680
 
5681
    return offset;
5682
}
5683
 
5684
static cairo_int_status_t
5685
_cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t	*surface,
5686
				     cairo_pdf_smask_group_t	*group)
5687
{
5688
    cairo_pdf_resource_t mask_group;
5689
    cairo_pdf_resource_t smask;
5690
    cairo_pdf_smask_group_t *smask_group;
5691
    cairo_pdf_resource_t pattern_res, gstate_res;
5692
    cairo_int_status_t status;
5693
    cairo_box_double_t bbox;
5694
 
5695
    /* Create mask group */
5696
    _get_bbox_from_extents (group->height, &group->extents, &bbox);
5697
    status = _cairo_pdf_surface_open_group (surface, &bbox, NULL);
5698
    if (unlikely (status))
5699
	return status;
5700
 
5701
    if (_can_paint_pattern (group->mask)) {
5702
	_cairo_output_stream_printf (surface->output, "q\n");
5703
	status = _cairo_pdf_surface_paint_pattern (surface,
5704
						   group->mask,
5705
						   &group->extents,
5706
						   FALSE);
5707
	if (unlikely (status))
5708
	    return status;
5709
 
5710
	_cairo_output_stream_printf (surface->output, "Q\n");
5711
    } else {
5712
	pattern_res.id = 0;
5713
	gstate_res.id = 0;
5714
	status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL,
5715
						     &pattern_res, &gstate_res);
5716
	if (unlikely (status))
5717
	    return status;
5718
 
5719
	if (gstate_res.id != 0) {
5720
	    smask_group = _cairo_pdf_surface_create_smask_group (surface, &group->extents);
5721
	    if (unlikely (smask_group == NULL))
5722
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5723
 
5724
	    smask_group->width = group->width;
5725
	    smask_group->height = group->height;
5726
	    smask_group->operation = PDF_PAINT;
5727
	    smask_group->source = cairo_pattern_reference (group->mask);
5728
	    smask_group->source_res = pattern_res;
5729
	    status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
5730
	    if (unlikely (status)) {
5731
		_cairo_pdf_smask_group_destroy (smask_group);
5732
		return status;
5733
	    }
5734
 
5735
	    status = _cairo_pdf_surface_add_smask (surface, gstate_res);
5736
	    if (unlikely (status))
5737
		return status;
5738
 
5739
	    status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
5740
	    if (unlikely (status))
5741
		return status;
5742
 
5743
	    _cairo_output_stream_printf (surface->output,
5744
					 "q /s%d gs /x%d Do Q\n",
5745
					 gstate_res.id,
5746
					 smask_group->group_res.id);
5747
	} else {
5748
	    status = _cairo_pdf_surface_select_pattern (surface, group->mask, pattern_res, FALSE);
5749
	    if (unlikely (status))
5750
		return status;
5751
 
5752
	    _cairo_output_stream_printf (surface->output,
5753
					 "%f %f %f %f re f\n",
5754
					 bbox.p1.x,
5755
					 bbox.p1.y,
5756
					 bbox.p2.x - bbox.p1.x,
5757
					 bbox.p2.y - bbox.p1.y);
5758
 
5759
	    status = _cairo_pdf_surface_unselect_pattern (surface);
5760
	    if (unlikely (status))
5761
		return status;
5762
	}
5763
    }
5764
 
5765
    status = _cairo_pdf_surface_close_group (surface, &mask_group);
5766
    if (unlikely (status))
5767
	return status;
5768
 
5769
    /* Create source group */
5770
    status = _cairo_pdf_surface_open_group (surface, &bbox, &group->source_res);
5771
    if (unlikely (status))
5772
	return status;
5773
 
5774
    if (_can_paint_pattern (group->source)) {
5775
	_cairo_output_stream_printf (surface->output, "q\n");
5776
	status = _cairo_pdf_surface_paint_pattern (surface,
5777
						   group->source,
5778
						   &group->extents,
5779
						   FALSE);
5780
	if (unlikely (status))
5781
	    return status;
5782
 
5783
	_cairo_output_stream_printf (surface->output, "Q\n");
5784
    } else {
5785
	pattern_res.id = 0;
5786
	gstate_res.id = 0;
5787
	status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL,
5788
						     &pattern_res, &gstate_res);
5789
	if (unlikely (status))
5790
	    return status;
5791
 
5792
	if (gstate_res.id != 0) {
5793
	    smask_group = _cairo_pdf_surface_create_smask_group (surface, &group->extents);
5794
	    if (unlikely (smask_group == NULL))
5795
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5796
 
5797
	    smask_group->operation = PDF_PAINT;
5798
	    smask_group->source = cairo_pattern_reference (group->source);
5799
	    smask_group->source_res = pattern_res;
5800
	    status = _cairo_pdf_surface_add_smask_group (surface, smask_group);
5801
	    if (unlikely (status)) {
5802
		_cairo_pdf_smask_group_destroy (smask_group);
5803
		return status;
5804
	    }
5805
 
5806
	    status = _cairo_pdf_surface_add_smask (surface, gstate_res);
5807
	    if (unlikely (status))
5808
		return status;
5809
 
5810
	    status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res);
5811
	    if (unlikely (status))
5812
		return status;
5813
 
5814
	    _cairo_output_stream_printf (surface->output,
5815
					 "q /s%d gs /x%d Do Q\n",
5816
					 gstate_res.id,
5817
					 smask_group->group_res.id);
5818
	} else {
5819
	    status = _cairo_pdf_surface_select_pattern (surface, group->source, pattern_res, FALSE);
5820
	    if (unlikely (status))
5821
		return status;
5822
 
5823
	    _cairo_output_stream_printf (surface->output,
5824
					 "%f %f %f %f re f\n",
5825
					 bbox.p1.x,
5826
					 bbox.p1.y,
5827
					 bbox.p2.x - bbox.p1.x,
5828
					 bbox.p2.y - bbox.p1.y);
5829
 
5830
	    status = _cairo_pdf_surface_unselect_pattern (surface);
5831
	    if (unlikely (status))
5832
		return status;
5833
	}
5834
    }
5835
 
5836
    status = _cairo_pdf_surface_close_group (surface, NULL);
5837
    if (unlikely (status))
5838
	return status;
5839
 
5840
    /* Create an smask based on the alpha component of mask_group */
5841
    smask = _cairo_pdf_surface_new_object (surface);
5842
    if (smask.id == 0)
5843
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
5844
 
5845
    _cairo_output_stream_printf (surface->output,
5846
				 "%d 0 obj\n"
5847
				 "<< /Type /Mask\n"
5848
				 "   /S /Alpha\n"
5849
				 "   /G %d 0 R\n"
5850
				 ">>\n"
5851
				 "endobj\n",
5852
				 smask.id,
5853
				 mask_group.id);
5854
 
5855
    /* Create a GState that uses the smask */
5856
    _cairo_pdf_surface_update_object (surface, group->group_res);
5857
    _cairo_output_stream_printf (surface->output,
5858
				 "%d 0 obj\n"
5859
				 "<< /Type /ExtGState\n"
5860
				 "   /SMask %d 0 R\n"
5861
				 "   /ca 1\n"
5862
				 "   /CA 1\n"
5863
				 "   /AIS false\n"
5864
				 ">>\n"
5865
				 "endobj\n",
5866
				 group->group_res.id,
5867
				 smask.id);
5868
 
5869
    return _cairo_output_stream_get_status (surface->output);
5870
}
5871
 
5872
static cairo_int_status_t
5873
_cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t     *surface,
5874
				      cairo_pdf_smask_group_t *group)
5875
{
5876
    double old_width, old_height;
5877
    cairo_int_status_t status;
5878
    cairo_box_double_t bbox;
5879
 
5880
    old_width = surface->width;
5881
    old_height = surface->height;
5882
    _cairo_pdf_surface_set_size_internal (surface,
5883
					  group->width,
5884
					  group->height);
5885
    /* _mask is a special case that requires two groups - source
5886
     * and mask as well as a smask and gstate dictionary */
5887
    if (group->operation == PDF_MASK) {
5888
	status = _cairo_pdf_surface_write_mask_group (surface, group);
5889
	goto RESTORE_SIZE;
5890
    }
5891
 
5892
    _get_bbox_from_extents (group->height, &group->extents, &bbox);
5893
    status = _cairo_pdf_surface_open_group (surface, &bbox, &group->group_res);
5894
    if (unlikely (status))
5895
	return status;
5896
 
5897
    status = _cairo_pdf_surface_select_pattern (surface,
5898
						group->source,
5899
						group->source_res,
5900
						group->operation == PDF_STROKE);
5901
    if (unlikely (status))
5902
	return status;
5903
 
5904
    switch (group->operation) {
5905
    case PDF_PAINT:
5906
	_cairo_output_stream_printf (surface->output,
5907
				     "0 0 %f %f re f\n",
5908
				     surface->width, surface->height);
5909
	break;
5910
    case PDF_MASK:
5911
	ASSERT_NOT_REACHED;
5912
	break;
5913
    case PDF_FILL:
5914
	status = _cairo_pdf_operators_fill (&surface->pdf_operators,
5915
					    &group->path,
5916
					    group->fill_rule);
5917
	break;
5918
    case PDF_STROKE:
5919
	status = _cairo_pdf_operators_stroke (&surface->pdf_operators,
5920
					      &group->path,
5921
					      &group->style,
5922
					      &group->ctm,
5923
					      &group->ctm_inverse);
5924
	break;
5925
    case PDF_SHOW_GLYPHS:
5926
	status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
5927
							group->utf8, group->utf8_len,
5928
							group->glyphs, group->num_glyphs,
5929
							group->clusters, group->num_clusters,
5930
							group->cluster_flags,
5931
							group->scaled_font);
5932
	break;
5933
    }
5934
    if (unlikely (status))
5935
	return status;
5936
 
5937
    status = _cairo_pdf_surface_unselect_pattern (surface);
5938
    if (unlikely (status))
5939
	return status;
5940
 
5941
    status = _cairo_pdf_surface_close_group (surface, NULL);
5942
 
5943
RESTORE_SIZE:
5944
    _cairo_pdf_surface_set_size_internal (surface,
5945
					  old_width,
5946
					  old_height);
5947
 
5948
    return status;
5949
}
5950
 
5951
static cairo_int_status_t
5952
_cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface)
5953
{
5954
    cairo_pdf_pattern_t pattern;
5955
    cairo_pdf_smask_group_t *group;
5956
    cairo_pdf_source_surface_t src_surface;
5957
    unsigned int pattern_index, group_index, surface_index;
5958
    cairo_int_status_t status;
5959
 
5960
    /* Writing out PDF_MASK groups will cause additional smask groups
5961
     * to be appended to surface->smask_groups. Additional patterns
5962
     * may also be appended to surface->patterns.
5963
     *
5964
     * Writing recording surface patterns will cause additional patterns
5965
     * and groups to be appended.
5966
     */
5967
    pattern_index = 0;
5968
    group_index = 0;
5969
    surface_index = 0;
5970
    while ((pattern_index < _cairo_array_num_elements (&surface->page_patterns)) ||
5971
	   (group_index < _cairo_array_num_elements (&surface->smask_groups)) ||
5972
	   (surface_index < _cairo_array_num_elements (&surface->page_surfaces)))
5973
    {
5974
	for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) {
5975
	    _cairo_array_copy_element (&surface->smask_groups, group_index, &group);
5976
	    status = _cairo_pdf_surface_write_smask_group (surface, group);
5977
	    if (unlikely (status))
5978
		return status;
5979
	}
5980
 
5981
	for (; pattern_index < _cairo_array_num_elements (&surface->page_patterns); pattern_index++) {
5982
	    _cairo_array_copy_element (&surface->page_patterns, pattern_index, &pattern);
5983
	    status = _cairo_pdf_surface_emit_pattern (surface, &pattern);
5984
	    if (unlikely (status))
5985
		return status;
5986
	}
5987
 
5988
	for (; surface_index < _cairo_array_num_elements (&surface->page_surfaces); surface_index++) {
5989
	    _cairo_array_copy_element (&surface->page_surfaces, surface_index, &src_surface);
5990
	    status = _cairo_pdf_surface_emit_surface (surface, &src_surface);
5991
	    if (unlikely (status))
5992
		return status;
5993
	}
5994
    }
5995
 
5996
    return CAIRO_STATUS_SUCCESS;
5997
}
5998
 
5999
static cairo_int_status_t
6000
_cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
6001
{
6002
    cairo_pdf_resource_t page, knockout, res;
6003
    cairo_int_status_t status;
6004
    unsigned int i, len;
6005
 
6006
    _cairo_pdf_group_resources_clear (&surface->resources);
6007
    if (surface->has_fallback_images) {
6008
	cairo_rectangle_int_t extents;
6009
	cairo_box_double_t    bbox;
6010
 
6011
	extents.x = 0;
6012
	extents.y = 0;
6013
	extents.width = ceil (surface->width);
6014
	extents.height = ceil (surface->height);
6015
	_get_bbox_from_extents (surface->height, &extents, &bbox);
6016
	status = _cairo_pdf_surface_open_knockout_group (surface, &bbox);
6017
	if (unlikely (status))
6018
	    return status;
6019
 
6020
	len = _cairo_array_num_elements (&surface->knockout_group);
6021
	for (i = 0; i < len; i++) {
6022
	    _cairo_array_copy_element (&surface->knockout_group, i, &res);
6023
	    _cairo_output_stream_printf (surface->output,
6024
					 "/x%d Do\n",
6025
					 res.id);
6026
	    status = _cairo_pdf_surface_add_xobject (surface, res);
6027
	    if (unlikely (status))
6028
		return status;
6029
	}
6030
	_cairo_output_stream_printf (surface->output,
6031
				     "/x%d Do\n",
6032
				     surface->content.id);
6033
	status = _cairo_pdf_surface_add_xobject (surface, surface->content);
6034
	if (unlikely (status))
6035
	    return status;
6036
 
6037
	status = _cairo_pdf_surface_close_group (surface, &knockout);
6038
	if (unlikely (status))
6039
	    return status;
6040
 
6041
	_cairo_pdf_group_resources_clear (&surface->resources);
6042
	status = _cairo_pdf_surface_open_content_stream (surface, NULL, NULL, FALSE);
6043
	if (unlikely (status))
6044
	    return status;
6045
 
6046
	_cairo_output_stream_printf (surface->output,
6047
				     "/x%d Do\n",
6048
				     knockout.id);
6049
	status = _cairo_pdf_surface_add_xobject (surface, knockout);
6050
	if (unlikely (status))
6051
	    return status;
6052
 
6053
	status = _cairo_pdf_surface_close_content_stream (surface);
6054
	if (unlikely (status))
6055
	    return status;
6056
    }
6057
 
6058
    page = _cairo_pdf_surface_new_object (surface);
6059
    if (page.id == 0)
6060
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
6061
 
6062
    _cairo_output_stream_printf (surface->output,
6063
				 "%d 0 obj\n"
6064
				 "<< /Type /Page\n"
6065
				 "   /Parent %d 0 R\n"
6066
				 "   /MediaBox [ 0 0 %f %f ]\n"
6067
				 "   /Contents %d 0 R\n"
6068
				 "   /Group <<\n"
6069
				 "      /Type /Group\n"
6070
				 "      /S /Transparency\n"
6071
				 "      /I true\n"
6072
				 "      /CS /DeviceRGB\n"
6073
				 "   >>\n"
6074
				 "   /Resources %d 0 R\n"
6075
				 ">>\n"
6076
				 "endobj\n",
6077
				 page.id,
6078
				 surface->pages_resource.id,
6079
				 surface->width,
6080
				 surface->height,
6081
				 surface->content.id,
6082
				 surface->content_resources.id);
6083
 
6084
    status = _cairo_array_append (&surface->pages, &page);
6085
    if (unlikely (status))
6086
	return status;
6087
 
6088
    status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface);
6089
    if (unlikely (status))
6090
	return status;
6091
 
6092
    return CAIRO_STATUS_SUCCESS;
6093
}
6094
 
6095
static cairo_int_status_t
6096
_cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t      *surface,
6097
							 cairo_surface_pattern_t *pattern)
6098
{
6099
    cairo_image_surface_t  *image;
6100
    void		   *image_extra;
6101
    cairo_int_status_t      status;
6102
    cairo_image_transparency_t transparency;
6103
 
6104
    status = _cairo_surface_acquire_source_image (pattern->surface,
6105
						  &image,
6106
						  &image_extra);
6107
    if (unlikely (status))
6108
	return status;
6109
 
6110
    if (image->base.status)
6111
	return image->base.status;
6112
 
6113
    transparency = _cairo_image_analyze_transparency (image);
6114
    if (transparency == CAIRO_IMAGE_IS_OPAQUE)
6115
	status = CAIRO_STATUS_SUCCESS;
6116
    else
6117
	status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
6118
 
6119
    _cairo_surface_release_source_image (pattern->surface, image, image_extra);
6120
 
6121
    return status;
6122
}
6123
 
6124
static cairo_bool_t
6125
_surface_pattern_supported (cairo_surface_pattern_t *pattern)
6126
{
6127
    cairo_extend_t extend;
6128
 
6129
    if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
6130
	return TRUE;
6131
 
6132
    if (pattern->surface->backend->acquire_source_image == NULL)
6133
	return FALSE;
6134
 
6135
    /* Does an ALPHA-only source surface even make sense? Maybe, but I
6136
     * don't think it's worth the extra code to support it. */
6137
 
6138
/* XXX: Need to write this function here...
6139
    if (pattern->surface->content == CAIRO_CONTENT_ALPHA)
6140
	return FALSE;
6141
*/
6142
 
6143
    extend = cairo_pattern_get_extend (&pattern->base);
6144
    switch (extend) {
6145
    case CAIRO_EXTEND_NONE:
6146
    case CAIRO_EXTEND_REPEAT:
6147
    case CAIRO_EXTEND_REFLECT:
6148
    /* There's no point returning FALSE for EXTEND_PAD, as the image
6149
     * surface does not currently implement it either */
6150
    case CAIRO_EXTEND_PAD:
6151
	return TRUE;
6152
    }
6153
 
6154
    ASSERT_NOT_REACHED;
6155
    return FALSE;
6156
}
6157
 
6158
static cairo_bool_t
6159
_pattern_supported (const cairo_pattern_t *pattern)
6160
{
6161
    switch (pattern->type) {
6162
    case CAIRO_PATTERN_TYPE_SOLID:
6163
    case CAIRO_PATTERN_TYPE_LINEAR:
6164
    case CAIRO_PATTERN_TYPE_RADIAL:
6165
    case CAIRO_PATTERN_TYPE_MESH:
6166
    case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
6167
	return TRUE;
6168
 
6169
    case CAIRO_PATTERN_TYPE_SURFACE:
6170
	return _surface_pattern_supported ((cairo_surface_pattern_t *) pattern);
6171
 
6172
    default:
6173
	ASSERT_NOT_REACHED;
6174
	return FALSE;
6175
    }
6176
}
6177
 
6178
static cairo_bool_t
6179
_pdf_operator_supported (cairo_operator_t op)
6180
{
6181
    switch (op) {
6182
    case CAIRO_OPERATOR_OVER:
6183
    case CAIRO_OPERATOR_MULTIPLY:
6184
    case CAIRO_OPERATOR_SCREEN:
6185
    case CAIRO_OPERATOR_OVERLAY:
6186
    case CAIRO_OPERATOR_DARKEN:
6187
    case CAIRO_OPERATOR_LIGHTEN:
6188
    case CAIRO_OPERATOR_COLOR_DODGE:
6189
    case CAIRO_OPERATOR_COLOR_BURN:
6190
    case CAIRO_OPERATOR_HARD_LIGHT:
6191
    case CAIRO_OPERATOR_SOFT_LIGHT:
6192
    case CAIRO_OPERATOR_DIFFERENCE:
6193
    case CAIRO_OPERATOR_EXCLUSION:
6194
    case CAIRO_OPERATOR_HSL_HUE:
6195
    case CAIRO_OPERATOR_HSL_SATURATION:
6196
    case CAIRO_OPERATOR_HSL_COLOR:
6197
    case CAIRO_OPERATOR_HSL_LUMINOSITY:
6198
	return TRUE;
6199
 
6200
    default:
6201
    case CAIRO_OPERATOR_CLEAR:
6202
    case CAIRO_OPERATOR_SOURCE:
6203
    case CAIRO_OPERATOR_IN:
6204
    case CAIRO_OPERATOR_OUT:
6205
    case CAIRO_OPERATOR_ATOP:
6206
    case CAIRO_OPERATOR_DEST:
6207
    case CAIRO_OPERATOR_DEST_OVER:
6208
    case CAIRO_OPERATOR_DEST_IN:
6209
    case CAIRO_OPERATOR_DEST_OUT:
6210
    case CAIRO_OPERATOR_DEST_ATOP:
6211
    case CAIRO_OPERATOR_XOR:
6212
    case CAIRO_OPERATOR_ADD:
6213
    case CAIRO_OPERATOR_SATURATE:
6214
	return FALSE;
6215
    }
6216
}
6217
 
6218
static cairo_int_status_t
6219
_cairo_pdf_surface_analyze_operation (cairo_pdf_surface_t  *surface,
6220
				      cairo_operator_t      op,
6221
				      const cairo_pattern_t      *pattern,
6222
				      const cairo_rectangle_int_t	 *extents)
6223
{
6224
    if (surface->force_fallbacks &&
6225
	surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
6226
    {
6227
	return CAIRO_INT_STATUS_UNSUPPORTED;
6228
    }
6229
 
6230
    if (! _pattern_supported (pattern))
6231
	return CAIRO_INT_STATUS_UNSUPPORTED;
6232
 
6233
    if (_pdf_operator_supported (op)) {
6234
	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
6235
	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
6236
 
6237
	    if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
6238
		if (pattern->extend == CAIRO_EXTEND_PAD) {
6239
		    cairo_box_t box;
6240
		    cairo_rectangle_int_t rect;
6241
		    cairo_rectangle_int_t rec_extents;
6242
 
6243
		    /* get the operation extents in pattern space */
6244
		    _cairo_box_from_rectangle (&box, extents);
6245
		    _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL);
6246
		    _cairo_box_round_to_rectangle (&box, &rect);
6247
 
6248
		    /* Check if surface needs padding to fill extents */
6249
		    if (_cairo_surface_get_extents (surface_pattern->surface, &rec_extents)) {
6250
			if (_cairo_fixed_integer_ceil(box.p1.x) < rec_extents.x ||
6251
			    _cairo_fixed_integer_ceil(box.p1.y) < rec_extents.y ||
6252
			    _cairo_fixed_integer_floor(box.p2.y) > rec_extents.x + rec_extents.width ||
6253
			    _cairo_fixed_integer_floor(box.p2.y) > rec_extents.y + rec_extents.height)
6254
			{
6255
			    return CAIRO_INT_STATUS_UNSUPPORTED;
6256
			}
6257
		    }
6258
		}
6259
		return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
6260
	    }
6261
	}
6262
 
6263
	return CAIRO_STATUS_SUCCESS;
6264
    }
6265
 
6266
 
6267
    /* The SOURCE operator is supported if the pattern is opaque or if
6268
     * there is nothing painted underneath. */
6269
    if (op == CAIRO_OPERATOR_SOURCE) {
6270
	if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
6271
	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
6272
 
6273
	    if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
6274
		if (_cairo_pattern_is_opaque (pattern, extents)) {
6275
		    return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
6276
		} else {
6277
		    /* FIXME: The analysis surface does not yet have
6278
		     * the capability to analyze a non opaque recording
6279
		     * surface and mark it supported if there is
6280
		     * nothing underneath. For now recording surfaces of
6281
		     * type CONTENT_COLOR_ALPHA painted with
6282
		     * OPERATOR_SOURCE will result in a fallback
6283
		     * image. */
6284
 
6285
		    return CAIRO_INT_STATUS_UNSUPPORTED;
6286
		}
6287
	    } else {
6288
		return _cairo_pdf_surface_analyze_surface_pattern_transparency (surface,
6289
										surface_pattern);
6290
	    }
6291
	}
6292
 
6293
	if (_cairo_pattern_is_opaque (pattern, extents))
6294
	    return CAIRO_STATUS_SUCCESS;
6295
	else
6296
	    return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
6297
    }
6298
 
6299
    return CAIRO_INT_STATUS_UNSUPPORTED;
6300
}
6301
 
6302
static cairo_bool_t
6303
_cairo_pdf_surface_operation_supported (cairo_pdf_surface_t  *surface,
6304
					cairo_operator_t      op,
6305
					const cairo_pattern_t      *pattern,
6306
					const cairo_rectangle_int_t *extents)
6307
{
6308
    return _cairo_pdf_surface_analyze_operation (surface, op, pattern, extents) != CAIRO_INT_STATUS_UNSUPPORTED;
6309
}
6310
 
6311
static cairo_int_status_t
6312
_cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
6313
{
6314
    cairo_box_double_t bbox;
6315
    cairo_int_status_t status;
6316
 
6317
    status = _cairo_pdf_surface_close_content_stream (surface);
6318
    if (unlikely (status))
6319
	return status;
6320
 
6321
    status = _cairo_array_append (&surface->knockout_group, &surface->content);
6322
    if (unlikely (status))
6323
	return status;
6324
 
6325
    _cairo_pdf_group_resources_clear (&surface->resources);
6326
    bbox.p1.x = 0;
6327
    bbox.p1.y = 0;
6328
    bbox.p2.x = surface->width;
6329
    bbox.p2.y = surface->height;
6330
    return _cairo_pdf_surface_open_content_stream (surface, &bbox, NULL, TRUE);
6331
}
6332
 
6333
/* A PDF stencil mask is an A1 mask used with the current color */
6334
static cairo_int_status_t
6335
_cairo_pdf_surface_emit_stencil_mask (cairo_pdf_surface_t         *surface,
6336
				      const cairo_pattern_t       *source,
6337
				      const cairo_pattern_t       *mask,
6338
				      const cairo_rectangle_int_t *extents)
6339
{
6340
    cairo_int_status_t status;
6341
    cairo_image_surface_t  *image;
6342
    void		   *image_extra;
6343
    cairo_image_transparency_t transparency;
6344
    cairo_pdf_resource_t pattern_res = {0};
6345
 
6346
    if (! (source->type == CAIRO_PATTERN_TYPE_SOLID &&
6347
	   (mask->type == CAIRO_PATTERN_TYPE_SURFACE || mask->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)))
6348
	return CAIRO_INT_STATUS_UNSUPPORTED;
6349
 
6350
    if (mask->type == CAIRO_PATTERN_TYPE_SURFACE &&
6351
	((cairo_surface_pattern_t *) mask)->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
6352
    {
6353
	return CAIRO_INT_STATUS_UNSUPPORTED;
6354
    }
6355
 
6356
    status = _cairo_pdf_surface_acquire_source_image_from_pattern (surface, mask,
6357
								   &image, &image_extra);
6358
    if (unlikely (status))
6359
	return status;
6360
 
6361
    if (image->base.status)
6362
	return image->base.status;
6363
 
6364
    transparency = _cairo_image_analyze_transparency (image);
6365
    if (transparency != CAIRO_IMAGE_IS_OPAQUE &&
6366
	transparency != CAIRO_IMAGE_HAS_BILEVEL_ALPHA)
6367
    {
6368
	status = CAIRO_INT_STATUS_UNSUPPORTED;
6369
	goto cleanup;
6370
    }
6371
 
6372
    status = _cairo_pdf_surface_select_pattern (surface, source,
6373
						pattern_res, FALSE);
6374
    if (unlikely (status))
6375
	return status;
6376
 
6377
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6378
    if (unlikely (status))
6379
	return status;
6380
 
6381
    _cairo_output_stream_printf (surface->output, "q\n");
6382
    status = _cairo_pdf_surface_paint_surface_pattern (surface, mask, extents, TRUE);
6383
    if (unlikely (status))
6384
	return status;
6385
 
6386
    _cairo_output_stream_printf (surface->output, "Q\n");
6387
 
6388
    status = _cairo_output_stream_get_status (surface->output);
6389
 
6390
cleanup:
6391
    _cairo_pdf_surface_release_source_image_from_pattern (surface, mask, image, image_extra);
6392
 
6393
    return status;
6394
}
6395
 
6396
static cairo_int_status_t
6397
_cairo_pdf_surface_set_clip (cairo_pdf_surface_t *surface,
6398
			     cairo_composite_rectangles_t *composite)
6399
{
6400
    cairo_clip_t *clip = composite->clip;
6401
 
6402
    if (_cairo_composite_rectangles_can_reduce_clip (composite, clip))
6403
	clip = NULL;
6404
 
6405
    if (clip == NULL) {
6406
	if (_cairo_composite_rectangles_can_reduce_clip (composite,
6407
							 surface->clipper.clip))
6408
	    return CAIRO_STATUS_SUCCESS;
6409
    }
6410
 
6411
    return _cairo_surface_clipper_set_clip (&surface->clipper, clip);
6412
}
6413
 
6414
static cairo_int_status_t
6415
_cairo_pdf_surface_paint (void			*abstract_surface,
6416
			  cairo_operator_t	 op,
6417
			  const cairo_pattern_t	*source,
6418
			  const cairo_clip_t	*clip)
6419
{
6420
    cairo_pdf_surface_t *surface = abstract_surface;
6421
    cairo_pdf_smask_group_t *group;
6422
    cairo_pdf_resource_t pattern_res, gstate_res;
6423
    cairo_composite_rectangles_t extents;
6424
    cairo_int_status_t status;
6425
 
6426
    status = _cairo_composite_rectangles_init_for_paint (&extents,
6427
							 &surface->base,
6428
							 op, source, clip);
6429
    if (unlikely (status))
6430
	return status;
6431
 
6432
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
6433
	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
6434
	goto cleanup;
6435
    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
6436
	status = _cairo_pdf_surface_start_fallback (surface);
6437
	if (unlikely (status))
6438
	    goto cleanup;
6439
    }
6440
 
6441
    assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded));
6442
 
6443
    status = _cairo_pdf_surface_set_clip (surface, &extents);
6444
    if (unlikely (status))
6445
	goto cleanup;
6446
 
6447
    status = _cairo_pdf_surface_select_operator (surface, op);
6448
    if (unlikely (status))
6449
	goto cleanup;
6450
 
6451
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6452
    if (unlikely (status))
6453
	goto cleanup;
6454
 
6455
    if (_can_paint_pattern (source)) {
6456
	_cairo_output_stream_printf (surface->output, "q\n");
6457
	status = _cairo_pdf_surface_paint_pattern (surface,
6458
						   source,
6459
						   &extents.bounded,
6460
						   FALSE);
6461
	if (unlikely (status))
6462
	    goto cleanup;
6463
 
6464
	_cairo_output_stream_printf (surface->output, "Q\n");
6465
	_cairo_composite_rectangles_fini (&extents);
6466
	return _cairo_output_stream_get_status (surface->output);
6467
    }
6468
 
6469
    pattern_res.id = 0;
6470
    gstate_res.id = 0;
6471
    status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
6472
						 &extents.bounded,
6473
						 &pattern_res, &gstate_res);
6474
    if (unlikely (status))
6475
	goto cleanup;
6476
 
6477
    if (gstate_res.id != 0) {
6478
	group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
6479
	if (unlikely (group == NULL)) {
6480
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
6481
	    goto cleanup;
6482
	}
6483
 
6484
	group->operation = PDF_PAINT;
6485
	status = _cairo_pattern_create_copy (&group->source, source);
6486
	if (unlikely (status)) {
6487
	    _cairo_pdf_smask_group_destroy (group);
6488
	    goto cleanup;
6489
	}
6490
	group->source_res = pattern_res;
6491
	status = _cairo_pdf_surface_add_smask_group (surface, group);
6492
	if (unlikely (status)) {
6493
	    _cairo_pdf_smask_group_destroy (group);
6494
	    goto cleanup;
6495
	}
6496
 
6497
	status = _cairo_pdf_surface_add_smask (surface, gstate_res);
6498
	if (unlikely (status))
6499
	    goto cleanup;
6500
 
6501
	status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
6502
	if (unlikely (status))
6503
	    goto cleanup;
6504
 
6505
	_cairo_output_stream_printf (surface->output,
6506
				     "q /s%d gs /x%d Do Q\n",
6507
				     gstate_res.id,
6508
				     group->group_res.id);
6509
    } else {
6510
	status = _cairo_pdf_surface_select_pattern (surface, source,
6511
						    pattern_res, FALSE);
6512
	if (unlikely (status))
6513
	    goto cleanup;
6514
 
6515
	_cairo_output_stream_printf (surface->output,
6516
				     "0 0 %f %f re f\n",
6517
				     surface->width, surface->height);
6518
 
6519
	status = _cairo_pdf_surface_unselect_pattern (surface);
6520
	if (unlikely (status))
6521
	    goto cleanup;
6522
    }
6523
 
6524
    _cairo_composite_rectangles_fini (&extents);
6525
    return _cairo_output_stream_get_status (surface->output);
6526
 
6527
cleanup:
6528
    _cairo_composite_rectangles_fini (&extents);
6529
    return status;
6530
}
6531
 
6532
static cairo_int_status_t
6533
_cairo_pdf_surface_mask (void			*abstract_surface,
6534
			 cairo_operator_t	 op,
6535
			 const cairo_pattern_t	*source,
6536
			 const cairo_pattern_t	*mask,
6537
			 const cairo_clip_t	*clip)
6538
{
6539
    cairo_pdf_surface_t *surface = abstract_surface;
6540
    cairo_pdf_smask_group_t *group;
6541
    cairo_composite_rectangles_t extents;
6542
    cairo_int_status_t status;
6543
    cairo_rectangle_int_t r;
6544
    cairo_box_t box;
6545
 
6546
    status = _cairo_composite_rectangles_init_for_mask (&extents,
6547
							&surface->base,
6548
							op, source, mask, clip);
6549
    if (unlikely (status))
6550
	return status;
6551
 
6552
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
6553
	cairo_int_status_t source_status, mask_status;
6554
 
6555
	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
6556
	if (_cairo_int_status_is_error (status))
6557
	    goto cleanup;
6558
	source_status = status;
6559
 
6560
	if (mask->has_component_alpha) {
6561
	    status = CAIRO_INT_STATUS_UNSUPPORTED;
6562
	} else {
6563
	    status = _cairo_pdf_surface_analyze_operation (surface, op, mask, &extents.bounded);
6564
	    if (_cairo_int_status_is_error (status))
6565
		goto cleanup;
6566
	}
6567
	mask_status = status;
6568
 
6569
	_cairo_composite_rectangles_fini (&extents);
6570
	return _cairo_analysis_surface_merge_status (source_status,
6571
						     mask_status);
6572
    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
6573
	status = _cairo_pdf_surface_start_fallback (surface);
6574
	if (unlikely (status))
6575
	    goto cleanup;
6576
    }
6577
 
6578
    assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded));
6579
    assert (_cairo_pdf_surface_operation_supported (surface, op, mask, &extents.bounded));
6580
 
6581
    /* get the accurate extents */
6582
    status = _cairo_pattern_get_ink_extents (source, &r);
6583
    if (unlikely (status))
6584
	goto cleanup;
6585
 
6586
    /* XXX slight impedance mismatch */
6587
    _cairo_box_from_rectangle (&box, &r);
6588
    status = _cairo_composite_rectangles_intersect_source_extents (&extents,
6589
								   &box);
6590
    if (unlikely (status))
6591
	goto cleanup;
6592
 
6593
    status = _cairo_pattern_get_ink_extents (mask, &r);
6594
    if (unlikely (status))
6595
	goto cleanup;
6596
 
6597
    _cairo_box_from_rectangle (&box, &r);
6598
    status = _cairo_composite_rectangles_intersect_mask_extents (&extents,
6599
								 &box);
6600
    if (unlikely (status))
6601
	goto cleanup;
6602
 
6603
    status = _cairo_pdf_surface_set_clip (surface, &extents);
6604
    if (unlikely (status))
6605
	goto cleanup;
6606
 
6607
    status = _cairo_pdf_surface_select_operator (surface, op);
6608
    if (unlikely (status))
6609
	goto cleanup;
6610
 
6611
    /* Check if we can use a stencil mask */
6612
    status = _cairo_pdf_surface_emit_stencil_mask (surface, source, mask, &extents.bounded);
6613
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
6614
	goto cleanup;
6615
 
6616
    group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
6617
    if (unlikely (group == NULL)) {
6618
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
6619
	goto cleanup;
6620
    }
6621
 
6622
    group->operation = PDF_MASK;
6623
    status = _cairo_pattern_create_copy (&group->source, source);
6624
    if (unlikely (status)) {
6625
	_cairo_pdf_smask_group_destroy (group);
6626
	goto cleanup;
6627
    }
6628
    status = _cairo_pattern_create_copy (&group->mask, mask);
6629
    if (unlikely (status)) {
6630
	_cairo_pdf_smask_group_destroy (group);
6631
	goto cleanup;
6632
    }
6633
    group->source_res = _cairo_pdf_surface_new_object (surface);
6634
    if (group->source_res.id == 0) {
6635
	_cairo_pdf_smask_group_destroy (group);
6636
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
6637
	goto cleanup;
6638
    }
6639
 
6640
    status = _cairo_pdf_surface_add_smask_group (surface, group);
6641
    if (unlikely (status)) {
6642
	_cairo_pdf_smask_group_destroy (group);
6643
	goto cleanup;
6644
    }
6645
 
6646
    status = _cairo_pdf_surface_add_smask (surface, group->group_res);
6647
    if (unlikely (status))
6648
	goto cleanup;
6649
 
6650
    status = _cairo_pdf_surface_add_xobject (surface, group->source_res);
6651
    if (unlikely (status))
6652
	goto cleanup;
6653
 
6654
    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6655
    if (unlikely (status))
6656
	goto cleanup;
6657
 
6658
    _cairo_output_stream_printf (surface->output,
6659
				 "q /s%d gs /x%d Do Q\n",
6660
				 group->group_res.id,
6661
				 group->source_res.id);
6662
 
6663
    _cairo_composite_rectangles_fini (&extents);
6664
    return _cairo_output_stream_get_status (surface->output);
6665
 
6666
cleanup:
6667
    _cairo_composite_rectangles_fini (&extents);
6668
    return status;
6669
}
6670
 
6671
static cairo_int_status_t
6672
_cairo_pdf_surface_stroke (void			*abstract_surface,
6673
			   cairo_operator_t	 op,
6674
			   const cairo_pattern_t *source,
6675
			   const cairo_path_fixed_t	*path,
6676
			   const cairo_stroke_style_t	*style,
6677
			   const cairo_matrix_t	*ctm,
6678
			   const cairo_matrix_t	*ctm_inverse,
6679
			   double		 tolerance,
6680
			   cairo_antialias_t	 antialias,
6681
			   const cairo_clip_t	*clip)
6682
{
6683
    cairo_pdf_surface_t *surface = abstract_surface;
6684
    cairo_pdf_smask_group_t *group;
6685
    cairo_pdf_resource_t pattern_res, gstate_res;
6686
    cairo_composite_rectangles_t extents;
6687
    cairo_int_status_t status;
6688
 
6689
    status = _cairo_composite_rectangles_init_for_stroke (&extents,
6690
							  &surface->base,
6691
							  op, source,
6692
							  path, style, ctm,
6693
							  clip);
6694
    if (unlikely (status))
6695
	return status;
6696
 
6697
    /* use the more accurate extents */
6698
    if (extents.is_bounded) {
6699
	cairo_rectangle_int_t mask;
6700
	cairo_box_t box;
6701
 
6702
	status = _cairo_path_fixed_stroke_extents (path, style,
6703
						   ctm, ctm_inverse,
6704
						   tolerance,
6705
						   &mask);
6706
	if (unlikely (status))
6707
	    goto cleanup;
6708
 
6709
	_cairo_box_from_rectangle (&box, &mask);
6710
	status = _cairo_composite_rectangles_intersect_mask_extents (&extents,
6711
								     &box);
6712
	if (unlikely (status))
6713
	    goto cleanup;
6714
    }
6715
 
6716
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
6717
	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
6718
	goto cleanup;
6719
    }
6720
 
6721
    assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded));
6722
 
6723
    status = _cairo_pdf_surface_set_clip (surface, &extents);
6724
    if (unlikely (status))
6725
	goto cleanup;
6726
 
6727
    pattern_res.id = 0;
6728
    gstate_res.id = 0;
6729
    status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
6730
						 &extents.bounded,
6731
						 &pattern_res, &gstate_res);
6732
    if (unlikely (status))
6733
	goto cleanup;
6734
 
6735
    status = _cairo_pdf_surface_select_operator (surface, op);
6736
    if (unlikely (status))
6737
	goto cleanup;
6738
 
6739
    if (gstate_res.id != 0) {
6740
	group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
6741
	if (unlikely (group == NULL)) {
6742
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
6743
	    goto cleanup;
6744
	}
6745
 
6746
	group->operation = PDF_STROKE;
6747
	status = _cairo_pattern_create_copy (&group->source, source);
6748
	if (unlikely (status)) {
6749
	    _cairo_pdf_smask_group_destroy (group);
6750
	    goto cleanup;
6751
	}
6752
	group->source_res = pattern_res;
6753
	status = _cairo_path_fixed_init_copy (&group->path, path);
6754
	if (unlikely (status)) {
6755
	    _cairo_pdf_smask_group_destroy (group);
6756
	    goto cleanup;
6757
	}
6758
 
6759
	group->style = *style;
6760
	group->ctm = *ctm;
6761
	group->ctm_inverse = *ctm_inverse;
6762
	status = _cairo_pdf_surface_add_smask_group (surface, group);
6763
	if (unlikely (status)) {
6764
	    _cairo_pdf_smask_group_destroy (group);
6765
	    goto cleanup;
6766
	}
6767
 
6768
	status = _cairo_pdf_surface_add_smask (surface, gstate_res);
6769
	if (unlikely (status))
6770
	    goto cleanup;
6771
 
6772
	status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
6773
	if (unlikely (status))
6774
	    goto cleanup;
6775
 
6776
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6777
	if (unlikely (status))
6778
	    goto cleanup;
6779
 
6780
	_cairo_output_stream_printf (surface->output,
6781
				     "q /s%d gs /x%d Do Q\n",
6782
				     gstate_res.id,
6783
				     group->group_res.id);
6784
    } else {
6785
	status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE);
6786
	if (unlikely (status))
6787
	    goto cleanup;
6788
 
6789
	status = _cairo_pdf_operators_stroke (&surface->pdf_operators,
6790
					      path,
6791
					      style,
6792
					      ctm,
6793
					      ctm_inverse);
6794
	if (unlikely (status))
6795
	    goto cleanup;
6796
 
6797
	status = _cairo_pdf_surface_unselect_pattern (surface);
6798
	if (unlikely (status))
6799
	    goto cleanup;
6800
    }
6801
 
6802
    _cairo_composite_rectangles_fini (&extents);
6803
    return _cairo_output_stream_get_status (surface->output);
6804
 
6805
cleanup:
6806
    _cairo_composite_rectangles_fini (&extents);
6807
    return status;
6808
}
6809
 
6810
static cairo_int_status_t
6811
_cairo_pdf_surface_fill (void			*abstract_surface,
6812
			 cairo_operator_t	 op,
6813
			 const cairo_pattern_t	*source,
6814
			 const cairo_path_fixed_t*path,
6815
			 cairo_fill_rule_t	 fill_rule,
6816
			 double			 tolerance,
6817
			 cairo_antialias_t	 antialias,
6818
			 const cairo_clip_t	*clip)
6819
{
6820
    cairo_pdf_surface_t *surface = abstract_surface;
6821
    cairo_int_status_t status;
6822
    cairo_pdf_smask_group_t *group;
6823
    cairo_pdf_resource_t pattern_res, gstate_res;
6824
    cairo_composite_rectangles_t extents;
6825
 
6826
    status = _cairo_composite_rectangles_init_for_fill (&extents,
6827
							&surface->base,
6828
							op, source, path,
6829
							clip);
6830
    if (unlikely (status))
6831
	return status;
6832
 
6833
    /* use the more accurate extents */
6834
    if (extents.is_bounded) {
6835
	cairo_rectangle_int_t mask;
6836
	cairo_box_t box;
6837
 
6838
	_cairo_path_fixed_fill_extents (path,
6839
					fill_rule,
6840
					tolerance,
6841
					&mask);
6842
 
6843
	_cairo_box_from_rectangle (&box, &mask);
6844
	status = _cairo_composite_rectangles_intersect_mask_extents (&extents,
6845
								     &box);
6846
	if (unlikely (status))
6847
	    goto cleanup;
6848
    }
6849
 
6850
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
6851
	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
6852
	goto cleanup;
6853
    } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
6854
	status = _cairo_pdf_surface_start_fallback (surface);
6855
	if (unlikely (status))
6856
	    goto cleanup;
6857
    }
6858
 
6859
    assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded));
6860
 
6861
    status = _cairo_pdf_surface_set_clip (surface, &extents);
6862
    if (unlikely (status))
6863
	goto cleanup;
6864
 
6865
    status = _cairo_pdf_surface_select_operator (surface, op);
6866
    if (unlikely (status))
6867
	goto cleanup;
6868
 
6869
    if (_can_paint_pattern (source)) {
6870
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6871
	if (unlikely (status))
6872
	    goto cleanup;
6873
 
6874
	_cairo_output_stream_printf (surface->output, "q\n");
6875
	status =  _cairo_pdf_operators_clip (&surface->pdf_operators,
6876
					     path,
6877
					     fill_rule);
6878
	if (unlikely (status))
6879
	    goto cleanup;
6880
 
6881
	status = _cairo_pdf_surface_paint_pattern (surface,
6882
						   source,
6883
						   &extents.bounded,
6884
						   FALSE);
6885
	if (unlikely (status))
6886
	    goto cleanup;
6887
 
6888
	_cairo_output_stream_printf (surface->output, "Q\n");
6889
	status = _cairo_output_stream_get_status (surface->output);
6890
	goto cleanup;
6891
    }
6892
 
6893
    pattern_res.id = 0;
6894
    gstate_res.id = 0;
6895
    status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
6896
						 &extents.bounded,
6897
						 &pattern_res, &gstate_res);
6898
    if (unlikely (status))
6899
	goto cleanup;
6900
 
6901
    if (gstate_res.id != 0) {
6902
	group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
6903
	if (unlikely (group == NULL)) {
6904
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
6905
	    goto cleanup;
6906
	}
6907
 
6908
	group->operation = PDF_FILL;
6909
	status = _cairo_pattern_create_copy (&group->source, source);
6910
	if (unlikely (status)) {
6911
	    _cairo_pdf_smask_group_destroy (group);
6912
	    goto cleanup;
6913
	}
6914
	group->source_res = pattern_res;
6915
	status = _cairo_path_fixed_init_copy (&group->path, path);
6916
	if (unlikely (status)) {
6917
	    _cairo_pdf_smask_group_destroy (group);
6918
	    goto cleanup;
6919
	}
6920
 
6921
	group->fill_rule = fill_rule;
6922
	status = _cairo_pdf_surface_add_smask_group (surface, group);
6923
	if (unlikely (status)) {
6924
	    _cairo_pdf_smask_group_destroy (group);
6925
	    goto cleanup;
6926
	}
6927
 
6928
	status = _cairo_pdf_surface_add_smask (surface, gstate_res);
6929
	if (unlikely (status))
6930
	    goto cleanup;
6931
 
6932
	status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
6933
	if (unlikely (status))
6934
	    goto cleanup;
6935
 
6936
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
6937
	if (unlikely (status))
6938
	    goto cleanup;
6939
 
6940
	_cairo_output_stream_printf (surface->output,
6941
				     "q /s%d gs /x%d Do Q\n",
6942
				     gstate_res.id,
6943
				     group->group_res.id);
6944
    } else {
6945
	status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
6946
	if (unlikely (status))
6947
	    goto cleanup;
6948
 
6949
	status = _cairo_pdf_operators_fill (&surface->pdf_operators,
6950
					    path,
6951
					    fill_rule);
6952
	if (unlikely (status))
6953
	    goto cleanup;
6954
 
6955
	status = _cairo_pdf_surface_unselect_pattern (surface);
6956
	if (unlikely (status))
6957
	    goto cleanup;
6958
    }
6959
 
6960
    _cairo_composite_rectangles_fini (&extents);
6961
    return _cairo_output_stream_get_status (surface->output);
6962
 
6963
cleanup:
6964
    _cairo_composite_rectangles_fini (&extents);
6965
    return status;
6966
}
6967
 
6968
static cairo_int_status_t
6969
_cairo_pdf_surface_fill_stroke (void			*abstract_surface,
6970
				cairo_operator_t	 fill_op,
6971
				const cairo_pattern_t	*fill_source,
6972
				cairo_fill_rule_t	 fill_rule,
6973
				double			 fill_tolerance,
6974
				cairo_antialias_t	 fill_antialias,
6975
				const cairo_path_fixed_t*path,
6976
				cairo_operator_t	 stroke_op,
6977
				const cairo_pattern_t	*stroke_source,
6978
				const cairo_stroke_style_t *stroke_style,
6979
				const cairo_matrix_t	*stroke_ctm,
6980
				const cairo_matrix_t	*stroke_ctm_inverse,
6981
				double			 stroke_tolerance,
6982
				cairo_antialias_t	 stroke_antialias,
6983
				const cairo_clip_t	*clip)
6984
{
6985
    cairo_pdf_surface_t *surface = abstract_surface;
6986
    cairo_int_status_t status;
6987
    cairo_pdf_resource_t fill_pattern_res, stroke_pattern_res, gstate_res;
6988
    cairo_composite_rectangles_t extents;
6989
 
6990
    /* During analysis we return unsupported and let the _fill and
6991
     * _stroke functions that are on the fallback path do the analysis
6992
     * for us. During render we may still encounter unsupported
6993
     * combinations of fill/stroke patterns. However we can return
6994
     * unsupported anytime to let the _fill and _stroke functions take
6995
     * over.
6996
     */
6997
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
6998
	return CAIRO_INT_STATUS_UNSUPPORTED;
6999
 
7000
    /* PDF rendering of fill-stroke is not the same as cairo when
7001
     * either the fill or stroke is not opaque.
7002
     */
7003
    if ( !_cairo_pattern_is_opaque (fill_source, NULL) ||
7004
	 !_cairo_pattern_is_opaque (stroke_source, NULL))
7005
    {
7006
	return CAIRO_INT_STATUS_UNSUPPORTED;
7007
    }
7008
 
7009
    if (fill_op != stroke_op)
7010
	return CAIRO_INT_STATUS_UNSUPPORTED;
7011
 
7012
    /* Compute the operation extents using the stroke which will naturally
7013
     * be larger than the fill extents.
7014
     */
7015
    status = _cairo_composite_rectangles_init_for_stroke (&extents,
7016
							  &surface->base,
7017
							  stroke_op, stroke_source,
7018
							  path, stroke_style, stroke_ctm,
7019
							  clip);
7020
    if (unlikely (status))
7021
	return status;
7022
 
7023
    /* use the more accurate extents */
7024
    if (extents.is_bounded) {
7025
	cairo_rectangle_int_t mask;
7026
	cairo_box_t box;
7027
 
7028
	status = _cairo_path_fixed_stroke_extents (path, stroke_style,
7029
						   stroke_ctm, stroke_ctm_inverse,
7030
						   stroke_tolerance,
7031
						   &mask);
7032
	if (unlikely (status))
7033
	    goto cleanup;
7034
 
7035
	_cairo_box_from_rectangle (&box, &mask);
7036
	status = _cairo_composite_rectangles_intersect_mask_extents (&extents,
7037
								     &box);
7038
	if (unlikely (status))
7039
	    goto cleanup;
7040
    }
7041
 
7042
    status = _cairo_pdf_surface_set_clip (surface, &extents);
7043
    if (unlikely (status))
7044
	goto cleanup;
7045
 
7046
    status = _cairo_pdf_surface_select_operator (surface, fill_op);
7047
    if (unlikely (status))
7048
	goto cleanup;
7049
 
7050
    /* use the more accurate extents */
7051
    if (extents.is_bounded) {
7052
	cairo_rectangle_int_t mask;
7053
	cairo_box_t box;
7054
 
7055
	_cairo_path_fixed_fill_extents (path,
7056
					fill_rule,
7057
					fill_tolerance,
7058
					&mask);
7059
 
7060
	_cairo_box_from_rectangle (&box, &mask);
7061
	status = _cairo_composite_rectangles_intersect_mask_extents (&extents,
7062
								     &box);
7063
	if (unlikely (status))
7064
	    goto cleanup;
7065
    }
7066
 
7067
    fill_pattern_res.id = 0;
7068
    gstate_res.id = 0;
7069
    status = _cairo_pdf_surface_add_pdf_pattern (surface, fill_source,
7070
						 &extents.bounded,
7071
						 &fill_pattern_res,
7072
						 &gstate_res);
7073
    if (unlikely (status))
7074
	goto cleanup;
7075
 
7076
    assert (gstate_res.id == 0);
7077
 
7078
    stroke_pattern_res.id = 0;
7079
    gstate_res.id = 0;
7080
    status = _cairo_pdf_surface_add_pdf_pattern (surface,
7081
						 stroke_source,
7082
						 &extents.bounded,
7083
						 &stroke_pattern_res,
7084
						 &gstate_res);
7085
    if (unlikely (status))
7086
	goto cleanup;
7087
 
7088
    assert (gstate_res.id == 0);
7089
 
7090
    /* As PDF has separate graphics state for fill and stroke we can
7091
     * select both at the same time */
7092
    status = _cairo_pdf_surface_select_pattern (surface, fill_source,
7093
						fill_pattern_res, FALSE);
7094
    if (unlikely (status))
7095
	goto cleanup;
7096
 
7097
    status = _cairo_pdf_surface_select_pattern (surface, stroke_source,
7098
						stroke_pattern_res, TRUE);
7099
    if (unlikely (status))
7100
	goto cleanup;
7101
 
7102
    status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators,
7103
					       path,
7104
					       fill_rule,
7105
					       stroke_style,
7106
					       stroke_ctm,
7107
					       stroke_ctm_inverse);
7108
    if (unlikely (status))
7109
	goto cleanup;
7110
 
7111
    status = _cairo_pdf_surface_unselect_pattern (surface);
7112
    if (unlikely (status))
7113
	goto cleanup;
7114
 
7115
    _cairo_composite_rectangles_fini (&extents);
7116
    return _cairo_output_stream_get_status (surface->output);
7117
 
7118
cleanup:
7119
    _cairo_composite_rectangles_fini (&extents);
7120
    return status;
7121
}
7122
 
7123
static cairo_bool_t
7124
_cairo_pdf_surface_has_show_text_glyphs	(void			*abstract_surface)
7125
{
7126
    return TRUE;
7127
}
7128
 
7129
static cairo_int_status_t
7130
_cairo_pdf_surface_show_text_glyphs (void			*abstract_surface,
7131
				     cairo_operator_t		 op,
7132
				     const cairo_pattern_t	*source,
7133
				     const char                 *utf8,
7134
				     int                         utf8_len,
7135
				     cairo_glyph_t		*glyphs,
7136
				     int			 num_glyphs,
7137
				     const cairo_text_cluster_t *clusters,
7138
				     int                         num_clusters,
7139
				     cairo_text_cluster_flags_t  cluster_flags,
7140
				     cairo_scaled_font_t	*scaled_font,
7141
				     const cairo_clip_t		*clip)
7142
{
7143
    cairo_pdf_surface_t *surface = abstract_surface;
7144
    cairo_pdf_smask_group_t *group;
7145
    cairo_pdf_resource_t pattern_res, gstate_res;
7146
    cairo_composite_rectangles_t extents;
7147
    cairo_bool_t overlap;
7148
    cairo_int_status_t status;
7149
 
7150
    status = _cairo_composite_rectangles_init_for_glyphs (&extents,
7151
							  &surface->base,
7152
							  op, source,
7153
							  scaled_font,
7154
							  glyphs, num_glyphs,
7155
							  clip,
7156
							  &overlap);
7157
    if (unlikely (status))
7158
	return status;
7159
 
7160
    if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
7161
	status = _cairo_pdf_surface_analyze_operation (surface, op, source, &extents.bounded);
7162
	goto cleanup;
7163
    }
7164
 
7165
    assert (_cairo_pdf_surface_operation_supported (surface, op, source, &extents.bounded));
7166
 
7167
    status = _cairo_pdf_surface_set_clip (surface, &extents);
7168
    if (unlikely (status))
7169
	goto cleanup;
7170
 
7171
    pattern_res.id = 0;
7172
    gstate_res.id = 0;
7173
    status = _cairo_pdf_surface_add_pdf_pattern (surface, source,
7174
						 &extents.bounded,
7175
						 &pattern_res, &gstate_res);
7176
    if (unlikely (status))
7177
	goto cleanup;
7178
 
7179
    status = _cairo_pdf_surface_select_operator (surface, op);
7180
    if (unlikely (status))
7181
	goto cleanup;
7182
 
7183
    if (gstate_res.id != 0) {
7184
	group = _cairo_pdf_surface_create_smask_group (surface, &extents.bounded);
7185
	if (unlikely (group == NULL)) {
7186
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
7187
	    goto cleanup;
7188
	}
7189
 
7190
	group->operation = PDF_SHOW_GLYPHS;
7191
	status = _cairo_pattern_create_copy (&group->source, source);
7192
	if (unlikely (status)) {
7193
	    _cairo_pdf_smask_group_destroy (group);
7194
	    goto cleanup;
7195
	}
7196
	group->source_res = pattern_res;
7197
 
7198
	if (utf8_len) {
7199
	    group->utf8 = malloc (utf8_len);
7200
	    if (unlikely (group->utf8 == NULL)) {
7201
		_cairo_pdf_smask_group_destroy (group);
7202
		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
7203
		goto cleanup;
7204
	    }
7205
	    memcpy (group->utf8, utf8, utf8_len);
7206
	}
7207
	group->utf8_len = utf8_len;
7208
 
7209
	if (num_glyphs) {
7210
	    group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
7211
	    if (unlikely (group->glyphs == NULL)) {
7212
		_cairo_pdf_smask_group_destroy (group);
7213
		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
7214
		goto cleanup;
7215
	    }
7216
	    memcpy (group->glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
7217
	}
7218
	group->num_glyphs = num_glyphs;
7219
 
7220
	if (num_clusters) {
7221
	    group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t));
7222
	    if (unlikely (group->clusters == NULL)) {
7223
		_cairo_pdf_smask_group_destroy (group);
7224
		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
7225
		goto cleanup;
7226
	    }
7227
	    memcpy (group->clusters, clusters, sizeof (cairo_text_cluster_t) * num_clusters);
7228
	}
7229
	group->num_clusters = num_clusters;
7230
 
7231
	group->scaled_font = cairo_scaled_font_reference (scaled_font);
7232
	status = _cairo_pdf_surface_add_smask_group (surface, group);
7233
	if (unlikely (status)) {
7234
	    _cairo_pdf_smask_group_destroy (group);
7235
	    goto cleanup;
7236
	}
7237
 
7238
	status = _cairo_pdf_surface_add_smask (surface, gstate_res);
7239
	if (unlikely (status))
7240
	    goto cleanup;
7241
 
7242
	status = _cairo_pdf_surface_add_xobject (surface, group->group_res);
7243
	if (unlikely (status))
7244
	    goto cleanup;
7245
 
7246
	status = _cairo_pdf_operators_flush (&surface->pdf_operators);
7247
	if (unlikely (status))
7248
	    goto cleanup;
7249
 
7250
	_cairo_output_stream_printf (surface->output,
7251
				     "q /s%d gs /x%d Do Q\n",
7252
				     gstate_res.id,
7253
				     group->group_res.id);
7254
    } else {
7255
	status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE);
7256
	if (unlikely (status))
7257
	    goto cleanup;
7258
 
7259
	/* Each call to show_glyphs() with a transclucent pattern must
7260
	 * be in a separate text object otherwise overlapping text
7261
	 * from separate calls to show_glyphs will not composite with
7262
	 * each other. */
7263
	if (! _cairo_pattern_is_opaque (source, &extents.bounded)) {
7264
	    status = _cairo_pdf_operators_flush (&surface->pdf_operators);
7265
	    if (unlikely (status))
7266
		goto cleanup;
7267
	}
7268
 
7269
	status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
7270
							utf8, utf8_len,
7271
							glyphs, num_glyphs,
7272
							clusters, num_clusters,
7273
							cluster_flags,
7274
							scaled_font);
7275
	if (unlikely (status))
7276
	    goto cleanup;
7277
 
7278
	status = _cairo_pdf_surface_unselect_pattern (surface);
7279
	if (unlikely (status))
7280
	    goto cleanup;
7281
    }
7282
 
7283
    _cairo_composite_rectangles_fini (&extents);
7284
    return _cairo_output_stream_get_status (surface->output);
7285
 
7286
cleanup:
7287
    _cairo_composite_rectangles_fini (&extents);
7288
    return status;
7289
}
7290
 
7291
static const char **
7292
_cairo_pdf_surface_get_supported_mime_types (void		 *abstract_surface)
7293
{
7294
    return _cairo_pdf_supported_mime_types;
7295
}
7296
 
7297
static void
7298
_cairo_pdf_surface_set_paginated_mode (void			*abstract_surface,
7299
				       cairo_paginated_mode_t	 paginated_mode)
7300
{
7301
    cairo_pdf_surface_t *surface = abstract_surface;
7302
 
7303
    surface->paginated_mode = paginated_mode;
7304
}
7305
 
7306
static const cairo_surface_backend_t cairo_pdf_surface_backend = {
7307
    CAIRO_SURFACE_TYPE_PDF,
7308
    _cairo_pdf_surface_finish,
7309
 
7310
    _cairo_default_context_create,
7311
 
7312
    NULL, /* create similar: handled by wrapper */
7313
    NULL, /* create similar image */
7314
    NULL, /* map to image */
7315
    NULL, /* unmap image */
7316
 
7317
    _cairo_surface_default_source,
7318
    NULL, /* acquire_source_image */
7319
    NULL, /* release_source_image */
7320
    NULL, /* snapshot */
7321
 
7322
    NULL,  /* _cairo_pdf_surface_copy_page */
7323
    _cairo_pdf_surface_show_page,
7324
 
7325
    _cairo_pdf_surface_get_extents,
7326
    _cairo_pdf_surface_get_font_options,
7327
 
7328
    NULL, /* flush */
7329
    NULL, /* mark_dirty_rectangle */
7330
 
7331
    /* Here are the drawing functions */
7332
    _cairo_pdf_surface_paint,
7333
    _cairo_pdf_surface_mask,
7334
    _cairo_pdf_surface_stroke,
7335
    _cairo_pdf_surface_fill,
7336
    _cairo_pdf_surface_fill_stroke,
7337
    NULL, /* show_glyphs */
7338
    _cairo_pdf_surface_has_show_text_glyphs,
7339
    _cairo_pdf_surface_show_text_glyphs,
7340
    _cairo_pdf_surface_get_supported_mime_types,
7341
};
7342
 
7343
static const cairo_paginated_surface_backend_t
7344
cairo_pdf_surface_paginated_backend = {
7345
    _cairo_pdf_surface_start_page,
7346
    _cairo_pdf_surface_set_paginated_mode,
7347
    NULL, /* set_bounding_box */
7348
    _cairo_pdf_surface_has_fallback_images,
7349
    _cairo_pdf_surface_supports_fine_grained_fallbacks,
7350
};