Tizen 2.0 Release
[framework/graphics/cairo.git] / src / cairo-ps-surface.c
1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2003 University of Southern California
5  * Copyright © 2005 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  *      Carl D. Worth <cworth@cworth.org>
38  *      Kristian Høgsberg <krh@redhat.com>
39  *      Keith Packard <keithp@keithp.com>
40  *      Adrian Johnson <ajohnson@redneon.com>
41  */
42
43
44 /*
45  * Design of the PS output:
46  *
47  * The PS output is harmonised with the PDF operations using PS procedures
48  * to emulate the PDF operators.
49  *
50  * This has a number of advantages:
51  *   1. A large chunk of code is shared between the PDF and PS backends.
52  *      See cairo-pdf-operators.
53  *   2. Using gs to do PS -> PDF and PDF -> PS will always work well.
54  */
55
56 #define _BSD_SOURCE /* for ctime_r(), snprintf(), strdup() */
57 #include "cairoint.h"
58
59 #include "cairo-ps.h"
60 #include "cairo-ps-surface-private.h"
61
62 #include "cairo-pdf-operators-private.h"
63 #include "cairo-pdf-shading-private.h"
64
65 #include "cairo-array-private.h"
66 #include "cairo-composite-rectangles-private.h"
67 #include "cairo-default-context-private.h"
68 #include "cairo-error-private.h"
69 #include "cairo-image-surface-inline.h"
70 #include "cairo-list-inline.h"
71 #include "cairo-scaled-font-subsets-private.h"
72 #include "cairo-paginated-private.h"
73 #include "cairo-recording-surface-private.h"
74 #include "cairo-surface-clipper-private.h"
75 #include "cairo-surface-snapshot-inline.h"
76 #include "cairo-surface-subsurface-private.h"
77 #include "cairo-output-stream-private.h"
78 #include "cairo-type3-glyph-surface-private.h"
79 #include "cairo-image-info-private.h"
80
81 #include <stdio.h>
82 #include <ctype.h>
83 #include <time.h>
84 #include <zlib.h>
85 #include <errno.h>
86
87 #define DEBUG_PS 0
88
89 #if DEBUG_PS
90 #define DEBUG_FALLBACK(s) \
91     fprintf (stderr, "%s::%d -- %s\n", __FUNCTION__, __LINE__, (s))
92 #else
93 #define DEBUG_FALLBACK(s)
94 #endif
95
96 #ifndef HAVE_CTIME_R
97 #define ctime_r(T, BUF) ctime (T)
98 #endif
99
100 /**
101  * SECTION:cairo-ps
102  * @Title: PostScript Surfaces
103  * @Short_Description: Rendering PostScript documents
104  * @See_Also: #cairo_surface_t
105  *
106  * The PostScript surface is used to render cairo graphics to Adobe
107  * PostScript files and is a multi-page vector surface backend.
108  **/
109
110 /**
111  * CAIRO_HAS_PS_SURFACE:
112  * 
113  * Defined if the PostScript surface backend is available.
114  * This macro can be used to conditionally compile backend-specific code.
115  *
116  * Since: 1.2
117  **/
118
119 typedef enum {
120     CAIRO_PS_COMPRESS_NONE,
121     CAIRO_PS_COMPRESS_LZW,
122     CAIRO_PS_COMPRESS_DEFLATE
123  } cairo_ps_compress_t;
124
125 static const cairo_surface_backend_t cairo_ps_surface_backend;
126 static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend;
127
128 static cairo_bool_t
129 _cairo_ps_surface_get_extents (void                    *abstract_surface,
130                                cairo_rectangle_int_t   *rectangle);
131
132 static const cairo_ps_level_t _cairo_ps_levels[] =
133 {
134     CAIRO_PS_LEVEL_2,
135     CAIRO_PS_LEVEL_3
136 };
137
138 #define CAIRO_PS_LEVEL_LAST ARRAY_LENGTH (_cairo_ps_levels)
139
140 static const char * _cairo_ps_level_strings[CAIRO_PS_LEVEL_LAST] =
141 {
142     "PS Level 2",
143     "PS Level 3"
144 };
145
146 static const char *_cairo_ps_supported_mime_types[] =
147 {
148     CAIRO_MIME_TYPE_JPEG,
149     NULL
150 };
151
152 typedef struct _cairo_page_standard_media {
153     const char *name;
154     int width;
155     int height;
156 } cairo_page_standard_media_t;
157
158 static const cairo_page_standard_media_t _cairo_page_standard_media[] =
159 {
160     { "A0",       2384, 3371 },
161     { "A1",       1685, 2384 },
162     { "A2",       1190, 1684 },
163     { "A3",        842, 1190 },
164     { "A4",        595,  842 },
165     { "A5",        420,  595 },
166     { "B4",        729, 1032 },
167     { "B5",        516,  729 },
168     { "Letter",    612,  792 },
169     { "Tabloid",   792, 1224 },
170     { "Ledger",   1224,  792 },
171     { "Legal",     612, 1008 },
172     { "Statement", 396,  612 },
173     { "Executive", 540,  720 },
174     { "Folio",     612,  936 },
175     { "Quarto",    610,  780 },
176     { "10x14",     720, 1008 },
177 };
178
179 typedef struct _cairo_page_media {
180     char *name;
181     int width;
182     int height;
183     cairo_list_t link;
184 } cairo_page_media_t;
185
186 static void
187 _cairo_ps_surface_emit_header (cairo_ps_surface_t *surface)
188 {
189     char ctime_buf[26];
190     time_t now;
191     char **comments;
192     int i, num_comments;
193     int level;
194     const char *eps_header = "";
195     cairo_bool_t has_bbox;
196
197     if (surface->has_creation_date)
198         now = surface->creation_date;
199     else
200         now = time (NULL);
201
202     if (surface->ps_level_used == CAIRO_PS_LEVEL_2)
203         level = 2;
204     else
205         level = 3;
206
207     if (surface->eps)
208         eps_header = " EPSF-3.0";
209
210     _cairo_output_stream_printf (surface->final_stream,
211                                  "%%!PS-Adobe-3.0%s\n"
212                                  "%%%%Creator: cairo %s (http://cairographics.org)\n"
213                                  "%%%%CreationDate: %s"
214                                  "%%%%Pages: %d\n",
215                                  eps_header,
216                                  cairo_version_string (),
217                                  ctime_r (&now, ctime_buf),
218                                  surface->num_pages);
219
220     _cairo_output_stream_printf (surface->final_stream,
221                                  "%%%%DocumentData: Clean7Bit\n"
222                                  "%%%%LanguageLevel: %d\n",
223                                  level);
224
225     if (!cairo_list_is_empty (&surface->document_media)) {
226         cairo_page_media_t *page;
227         cairo_bool_t first = TRUE;
228
229         cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) {
230             if (first) {
231                 _cairo_output_stream_printf (surface->final_stream,
232                                              "%%%%DocumentMedia: ");
233                 first = FALSE;
234             } else {
235                 _cairo_output_stream_printf (surface->final_stream,
236                                              "%%%%+ ");
237             }
238             _cairo_output_stream_printf (surface->final_stream,
239                                          "%s %d %d 0 () ()\n",
240                                          page->name,
241                                          page->width,
242                                          page->height);
243         }
244     }
245
246     has_bbox = FALSE;
247     num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
248     comments = _cairo_array_index (&surface->dsc_header_comments, 0);
249     for (i = 0; i < num_comments; i++) {
250         _cairo_output_stream_printf (surface->final_stream,
251                                      "%s\n", comments[i]);
252         if (strncmp (comments[i], "%%BoundingBox:", 14) == 0)
253             has_bbox = TRUE;
254
255         free (comments[i]);
256         comments[i] = NULL;
257     }
258
259     if (!has_bbox) {
260         _cairo_output_stream_printf (surface->final_stream,
261                                      "%%%%BoundingBox: %d %d %d %d\n",
262                                      surface->bbox_x1,
263                                      surface->bbox_y1,
264                                      surface->bbox_x2,
265                                      surface->bbox_y2);
266     }
267
268     _cairo_output_stream_printf (surface->final_stream,
269                                  "%%%%EndComments\n");
270
271     _cairo_output_stream_printf (surface->final_stream,
272                                  "%%%%BeginProlog\n");
273
274     if (surface->eps) {
275         _cairo_output_stream_printf (surface->final_stream,
276                                      "save\n"
277                                      "50 dict begin\n");
278     } else {
279         _cairo_output_stream_printf (surface->final_stream,
280                                      "/languagelevel where\n"
281                                      "{ pop languagelevel } { 1 } ifelse\n"
282                                      "%d lt { /Helvetica findfont 12 scalefont setfont 50 500 moveto\n"
283                                      "  (This print job requires a PostScript Language Level %d printer.) show\n"
284                                      "  showpage quit } if\n",
285                                      level,
286                                      level);
287     }
288
289     _cairo_output_stream_printf (surface->final_stream,
290                                  "/q { gsave } bind def\n"
291                                  "/Q { grestore } bind def\n"
292                                  "/cm { 6 array astore concat } bind def\n"
293                                  "/w { setlinewidth } bind def\n"
294                                  "/J { setlinecap } bind def\n"
295                                  "/j { setlinejoin } bind def\n"
296                                  "/M { setmiterlimit } bind def\n"
297                                  "/d { setdash } bind def\n"
298                                  "/m { moveto } bind def\n"
299                                  "/l { lineto } bind def\n"
300                                  "/c { curveto } bind def\n"
301                                  "/h { closepath } bind def\n"
302                                  "/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto\n"
303                                  "      0 exch rlineto 0 rlineto closepath } bind def\n"
304                                  "/S { stroke } bind def\n"
305                                  "/f { fill } bind def\n"
306                                  "/f* { eofill } bind def\n"
307                                  "/n { newpath } bind def\n"
308                                  "/W { clip } bind def\n"
309                                  "/W* { eoclip } bind def\n"
310                                  "/BT { } bind def\n"
311                                  "/ET { } bind def\n"
312                                  "/pdfmark where { pop globaldict /?pdfmark /exec load put }\n"
313                                  "    { globaldict begin /?pdfmark /pop load def /pdfmark\n"
314                                  "    /cleartomark load def end } ifelse\n"
315                                  "/BDC { mark 3 1 roll /BDC pdfmark } bind def\n"
316                                  "/EMC { mark /EMC pdfmark } bind def\n"
317                                  "/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def\n"
318                                  "/Tj { show currentpoint cairo_store_point } bind def\n"
319                                  "/TJ {\n"
320                                  "  {\n"
321                                  "    dup\n"
322                                  "    type /stringtype eq\n"
323                                  "    { show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse\n"
324                                  "  } forall\n"
325                                  "  currentpoint cairo_store_point\n"
326                                  "} bind def\n"
327                                  "/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore\n"
328                                  "    cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def\n"
329                                  "/Tf { pop /cairo_font exch def /cairo_font_matrix where\n"
330                                  "      { pop cairo_selectfont } if } bind def\n"
331                                  "/Td { matrix translate cairo_font_matrix matrix concatmatrix dup\n"
332                                  "      /cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point\n"
333                                  "      /cairo_font where { pop cairo_selectfont } if } bind def\n"
334                                  "/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def\n"
335                                  "      cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def\n"
336                                  "/g { setgray } bind def\n"
337                                  "/rg { setrgbcolor } bind def\n"
338                                  "/d1 { setcachedevice } bind def\n");
339
340     _cairo_output_stream_printf (surface->final_stream,
341                                  "%%%%EndProlog\n");
342
343     num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments);
344     if (num_comments) {
345         _cairo_output_stream_printf (surface->final_stream,
346                                      "%%%%BeginSetup\n");
347
348         comments = _cairo_array_index (&surface->dsc_setup_comments, 0);
349         for (i = 0; i < num_comments; i++) {
350             _cairo_output_stream_printf (surface->final_stream,
351                                          "%s\n", comments[i]);
352             free (comments[i]);
353             comments[i] = NULL;
354         }
355
356         _cairo_output_stream_printf (surface->final_stream,
357                                      "%%%%EndSetup\n");
358     }
359 }
360
361 static cairo_status_t
362 _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t            *surface,
363                                           cairo_scaled_font_subset_t    *font_subset)
364
365
366 {
367     cairo_type1_subset_t subset;
368     cairo_status_t status;
369     int length;
370     char name[64];
371
372     snprintf (name, sizeof name, "f-%d-%d",
373               font_subset->font_id, font_subset->subset_id);
374     status = _cairo_type1_subset_init (&subset, name, font_subset, TRUE);
375     if (unlikely (status))
376         return status;
377
378     /* FIXME: Figure out document structure convention for fonts */
379
380 #if DEBUG_PS
381     _cairo_output_stream_printf (surface->final_stream,
382                                  "%% _cairo_ps_surface_emit_type1_font_subset\n");
383 #endif
384
385     length = subset.header_length + subset.data_length + subset.trailer_length;
386     _cairo_output_stream_write (surface->final_stream, subset.data, length);
387
388     _cairo_type1_subset_fini (&subset);
389
390     return CAIRO_STATUS_SUCCESS;
391 }
392
393
394 static cairo_status_t
395 _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t          *surface,
396                                             cairo_scaled_font_subset_t  *font_subset)
397 {
398     cairo_type1_subset_t subset;
399     cairo_status_t status;
400     int length;
401     char name[64];
402
403     snprintf (name, sizeof name, "f-%d-%d",
404               font_subset->font_id, font_subset->subset_id);
405     status = _cairo_type1_fallback_init_hex (&subset, name, font_subset);
406     if (unlikely (status))
407         return status;
408
409     /* FIXME: Figure out document structure convention for fonts */
410
411 #if DEBUG_PS
412     _cairo_output_stream_printf (surface->final_stream,
413                                  "%% _cairo_ps_surface_emit_type1_font_fallback\n");
414 #endif
415
416     length = subset.header_length + subset.data_length + subset.trailer_length;
417     _cairo_output_stream_write (surface->final_stream, subset.data, length);
418
419     _cairo_type1_fallback_fini (&subset);
420
421     return CAIRO_STATUS_SUCCESS;
422 }
423
424 static cairo_status_t
425 _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t         *surface,
426                                              cairo_scaled_font_subset_t *font_subset)
427
428
429 {
430     cairo_truetype_subset_t subset;
431     cairo_status_t status;
432     unsigned int i, begin, end;
433
434     status = _cairo_truetype_subset_init_ps (&subset, font_subset);
435     if (unlikely (status))
436         return status;
437
438     /* FIXME: Figure out document structure convention for fonts */
439
440 #if DEBUG_PS
441     _cairo_output_stream_printf (surface->final_stream,
442                                  "%% _cairo_ps_surface_emit_truetype_font_subset\n");
443 #endif
444
445     _cairo_output_stream_printf (surface->final_stream,
446                                  "11 dict begin\n"
447                                  "/FontType 42 def\n"
448                                  "/FontName /%s def\n"
449                                  "/PaintType 0 def\n"
450                                  "/FontMatrix [ 1 0 0 1 0 0 ] def\n"
451                                  "/FontBBox [ 0 0 0 0 ] def\n"
452                                  "/Encoding 256 array def\n"
453                                  "0 1 255 { Encoding exch /.notdef put } for\n",
454                                  subset.ps_name);
455
456     /* FIXME: Figure out how subset->x_max etc maps to the /FontBBox */
457
458     if (font_subset->is_latin) {
459         for (i = 1; i < 256; i++) {
460             if (font_subset->latin_to_subset_glyph_index[i] > 0) {
461                 if (font_subset->glyph_names != NULL) {
462                     _cairo_output_stream_printf (surface->final_stream,
463                                                  "Encoding %d /%s put\n",
464                                                  i, font_subset->glyph_names[font_subset->latin_to_subset_glyph_index[i]]);
465                 } else {
466                     _cairo_output_stream_printf (surface->final_stream,
467                                                  "Encoding %d /g%ld put\n", i, font_subset->latin_to_subset_glyph_index[i]);
468                 }
469             }
470         }
471     } else {
472         for (i = 1; i < font_subset->num_glyphs; i++) {
473             if (font_subset->glyph_names != NULL) {
474                 _cairo_output_stream_printf (surface->final_stream,
475                                              "Encoding %d /%s put\n",
476                                              i, font_subset->glyph_names[i]);
477             } else {
478                 _cairo_output_stream_printf (surface->final_stream,
479                                              "Encoding %d /g%d put\n", i, i);
480             }
481         }
482     }
483
484     _cairo_output_stream_printf (surface->final_stream,
485                                  "/CharStrings %d dict dup begin\n"
486                                  "/.notdef 0 def\n",
487                                  font_subset->num_glyphs);
488
489     for (i = 1; i < font_subset->num_glyphs; i++) {
490         if (font_subset->glyph_names != NULL) {
491             _cairo_output_stream_printf (surface->final_stream,
492                                          "/%s %d def\n",
493                                          font_subset->glyph_names[i], i);
494         } else {
495             _cairo_output_stream_printf (surface->final_stream,
496                                          "/g%d %d def\n", i, i);
497         }
498     }
499
500     _cairo_output_stream_printf (surface->final_stream,
501                                  "end readonly def\n");
502
503     _cairo_output_stream_printf (surface->final_stream,
504                                  "/sfnts [\n");
505     begin = 0;
506     end = 0;
507     for (i = 0; i < subset.num_string_offsets; i++) {
508         end = subset.string_offsets[i];
509         _cairo_output_stream_printf (surface->final_stream,"<");
510         _cairo_output_stream_write_hex_string (surface->final_stream,
511                                                subset.data + begin, end - begin);
512         _cairo_output_stream_printf (surface->final_stream,"00>\n");
513         begin = end;
514     }
515     if (subset.data_length > end) {
516         _cairo_output_stream_printf (surface->final_stream,"<");
517         _cairo_output_stream_write_hex_string (surface->final_stream,
518                                                subset.data + end, subset.data_length - end);
519         _cairo_output_stream_printf (surface->final_stream,"00>\n");
520     }
521
522     _cairo_output_stream_printf (surface->final_stream,
523                                  "] def\n"
524                                  "/f-%d-%d currentdict end definefont pop\n",
525                                  font_subset->font_id,
526                                  font_subset->subset_id);
527
528     _cairo_truetype_subset_fini (&subset);
529
530     return CAIRO_STATUS_SUCCESS;
531 }
532
533 static cairo_status_t
534 _cairo_ps_emit_imagemask (cairo_image_surface_t *image,
535                           cairo_output_stream_t *stream)
536 {
537     uint8_t *row, *byte;
538     int rows, cols;
539
540     /* The only image type supported by Type 3 fonts are 1-bit image
541      * masks */
542     assert (image->format == CAIRO_FORMAT_A1);
543
544     _cairo_output_stream_printf (stream,
545                                  "<<\n"
546                                  "   /ImageType 1\n"
547                                  "   /Width %d\n"
548                                  "   /Height %d\n"
549                                  "   /ImageMatrix [%d 0 0 %d 0 %d]\n"
550                                  "   /Decode [1 0]\n"
551                                  "   /BitsPerComponent 1\n",
552                                  image->width,
553                                  image->height,
554                                  image->width,
555                                  -image->height,
556                                  image->height);
557
558     _cairo_output_stream_printf (stream,
559                                  "   /DataSource {<\n   ");
560     for (row = image->data, rows = image->height; rows; row += image->stride, rows--) {
561         for (byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
562             uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
563             _cairo_output_stream_printf (stream, "%02x ", output_byte);
564         }
565         _cairo_output_stream_printf (stream, "\n   ");
566     }
567     _cairo_output_stream_printf (stream, ">}\n>>\n");
568
569     _cairo_output_stream_printf (stream,
570                                  "imagemask\n");
571
572     return _cairo_output_stream_get_status (stream);
573 }
574
575 static cairo_int_status_t
576 _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_subset,
577                                             void                       *closure)
578 {
579     cairo_ps_surface_t *surface = closure;
580     cairo_status_t status = CAIRO_STATUS_SUCCESS;
581     unsigned int i;
582     cairo_surface_t *type3_surface;
583
584     type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
585                                                        NULL,
586                                                        _cairo_ps_emit_imagemask,
587                                                        surface->font_subsets);
588
589     for (i = 0; i < font_subset->num_glyphs; i++) {
590         status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface,
591                                                            font_subset->glyphs[i]);
592         if (unlikely (status))
593             break;
594
595     }
596     cairo_surface_finish (type3_surface);
597     cairo_surface_destroy (type3_surface);
598
599     return status;
600 }
601
602 static cairo_status_t
603 _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t            *surface,
604                                           cairo_scaled_font_subset_t    *font_subset)
605
606
607 {
608     cairo_status_t status;
609     unsigned int i;
610     cairo_box_t font_bbox = {{0,0},{0,0}};
611     cairo_box_t bbox = {{0,0},{0,0}};
612     cairo_surface_t *type3_surface;
613     double width;
614
615     if (font_subset->num_glyphs == 0)
616         return CAIRO_STATUS_SUCCESS;
617
618 #if DEBUG_PS
619     _cairo_output_stream_printf (surface->final_stream,
620                                  "%% _cairo_ps_surface_emit_type3_font_subset\n");
621 #endif
622
623     _cairo_output_stream_printf (surface->final_stream,
624                                  "8 dict begin\n"
625                                  "/FontType 3 def\n"
626                                  "/FontMatrix [1 0 0 1 0 0] def\n"
627                                  "/Encoding 256 array def\n"
628                                  "0 1 255 { Encoding exch /.notdef put } for\n");
629
630     type3_surface = _cairo_type3_glyph_surface_create (font_subset->scaled_font,
631                                                        NULL,
632                                                        _cairo_ps_emit_imagemask,
633                                                        surface->font_subsets);
634     status = type3_surface->status;
635     if (unlikely (status))
636         return status;
637
638     for (i = 0; i < font_subset->num_glyphs; i++) {
639         if (font_subset->glyph_names != NULL) {
640             _cairo_output_stream_printf (surface->final_stream,
641                                          "Encoding %d /%s put\n",
642                                          i, font_subset->glyph_names[i]);
643         } else {
644             _cairo_output_stream_printf (surface->final_stream,
645                                          "Encoding %d /g%d put\n", i, i);
646         }
647     }
648
649     _cairo_output_stream_printf (surface->final_stream,
650                                  "/Glyphs [\n");
651
652     for (i = 0; i < font_subset->num_glyphs; i++) {
653         _cairo_output_stream_printf (surface->final_stream,
654                                      "    { %% %d\n", i);
655         status = _cairo_type3_glyph_surface_emit_glyph (type3_surface,
656                                                         surface->final_stream,
657                                                         font_subset->glyphs[i],
658                                                         &bbox,
659                                                         &width);
660         if (unlikely (status))
661             break;
662
663         _cairo_output_stream_printf (surface->final_stream,
664                                      "    }\n");
665         if (i == 0) {
666             font_bbox.p1.x = bbox.p1.x;
667             font_bbox.p1.y = bbox.p1.y;
668             font_bbox.p2.x = bbox.p2.x;
669             font_bbox.p2.y = bbox.p2.y;
670         } else {
671             if (bbox.p1.x < font_bbox.p1.x)
672                 font_bbox.p1.x = bbox.p1.x;
673             if (bbox.p1.y < font_bbox.p1.y)
674                 font_bbox.p1.y = bbox.p1.y;
675             if (bbox.p2.x > font_bbox.p2.x)
676                 font_bbox.p2.x = bbox.p2.x;
677             if (bbox.p2.y > font_bbox.p2.y)
678                 font_bbox.p2.y = bbox.p2.y;
679         }
680     }
681     cairo_surface_finish (type3_surface);
682     cairo_surface_destroy (type3_surface);
683     if (unlikely (status))
684         return status;
685
686     _cairo_output_stream_printf (surface->final_stream,
687                                  "] def\n"
688                                  "/FontBBox [%f %f %f %f] def\n"
689                                  "/BuildChar {\n"
690                                  "  exch /Glyphs get\n"
691                                  "  exch get\n"
692                                  "  10 dict begin exec end\n"
693                                  "} bind def\n"
694                                  "currentdict\n"
695                                  "end\n"
696                                  "/f-%d-%d exch definefont pop\n",
697                                  _cairo_fixed_to_double (font_bbox.p1.x),
698                                  - _cairo_fixed_to_double (font_bbox.p2.y),
699                                  _cairo_fixed_to_double (font_bbox.p2.x),
700                                  - _cairo_fixed_to_double (font_bbox.p1.y),
701                                  font_subset->font_id,
702                                  font_subset->subset_id);
703
704     return CAIRO_STATUS_SUCCESS;
705 }
706
707 static cairo_int_status_t
708 _cairo_ps_surface_emit_unscaled_font_subset (cairo_scaled_font_subset_t *font_subset,
709                                             void                        *closure)
710 {
711     cairo_ps_surface_t *surface = closure;
712     cairo_int_status_t status;
713
714     status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
715     if (_cairo_int_status_is_error (status))
716         return status;
717
718     status = _cairo_ps_surface_emit_type1_font_subset (surface, font_subset);
719     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
720         return status;
721
722     status = _cairo_ps_surface_emit_truetype_font_subset (surface, font_subset);
723     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
724         return status;
725
726     status = _cairo_ps_surface_emit_type1_font_fallback (surface, font_subset);
727     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
728         return status;
729
730     ASSERT_NOT_REACHED;
731     return CAIRO_STATUS_SUCCESS;
732 }
733
734 static cairo_int_status_t
735 _cairo_ps_surface_emit_scaled_font_subset (cairo_scaled_font_subset_t *font_subset,
736                                            void                       *closure)
737 {
738     cairo_ps_surface_t *surface = closure;
739     cairo_int_status_t status;
740
741     status = _cairo_scaled_font_subset_create_glyph_names (font_subset);
742     if (_cairo_int_status_is_error (status))
743         return status;
744
745     status = _cairo_ps_surface_emit_type3_font_subset (surface, font_subset);
746     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
747         return status;
748
749     ASSERT_NOT_REACHED;
750     return CAIRO_INT_STATUS_SUCCESS;
751 }
752
753 static cairo_status_t
754 _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface)
755 {
756     cairo_status_t status;
757
758 #if DEBUG_PS
759     _cairo_output_stream_printf (surface->final_stream,
760                                  "%% _cairo_ps_surface_emit_font_subsets\n");
761 #endif
762
763     status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
764                                                       _cairo_ps_surface_analyze_user_font_subset,
765                                                       surface);
766     if (unlikely (status))
767         return status;
768
769     status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets,
770                                                           _cairo_ps_surface_emit_unscaled_font_subset,
771                                                           surface);
772     if (unlikely (status))
773         return status;
774
775     status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets,
776                                                         _cairo_ps_surface_emit_scaled_font_subset,
777                                                         surface);
778     if (unlikely (status))
779         return status;
780
781     return _cairo_scaled_font_subsets_foreach_user (surface->font_subsets,
782                                                     _cairo_ps_surface_emit_scaled_font_subset,
783                                                     surface);
784 }
785
786 static cairo_status_t
787 _cairo_ps_surface_emit_body (cairo_ps_surface_t *surface)
788 {
789     char    buf[4096];
790     int     n;
791
792     if (ferror (surface->tmpfile) != 0)
793         return _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
794
795     rewind (surface->tmpfile);
796     while ((n = fread (buf, 1, sizeof (buf), surface->tmpfile)) > 0)
797         _cairo_output_stream_write (surface->final_stream, buf, n);
798
799     if (ferror (surface->tmpfile) != 0)
800         return _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
801
802     return CAIRO_STATUS_SUCCESS;
803 }
804
805 static void
806 _cairo_ps_surface_emit_footer (cairo_ps_surface_t *surface)
807 {
808     _cairo_output_stream_printf (surface->final_stream,
809                                  "%%%%Trailer\n");
810
811     if (surface->eps) {
812         _cairo_output_stream_printf (surface->final_stream,
813                                      "end restore\n");
814     }
815
816     _cairo_output_stream_printf (surface->final_stream,
817                                  "%%%%EOF\n");
818 }
819
820 static cairo_bool_t
821 _path_covers_bbox (cairo_ps_surface_t *surface,
822                    cairo_path_fixed_t *path)
823 {
824     cairo_box_t box;
825
826     if (_cairo_path_fixed_is_box (path, &box)) {
827         cairo_rectangle_int_t rect;
828
829         _cairo_box_round_to_rectangle (&box, &rect);
830
831         /* skip trivial whole-page clips */
832         if (_cairo_rectangle_intersect (&rect, &surface->page_bbox)) {
833             if (rect.x == surface->page_bbox.x &&
834                 rect.width == surface->page_bbox.width &&
835                 rect.y == surface->page_bbox.y &&
836                 rect.height == surface->page_bbox.height)
837             {
838                 return TRUE;
839             }
840         }
841     }
842
843     return FALSE;
844 }
845
846 static cairo_status_t
847 _cairo_ps_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
848                                                cairo_path_fixed_t *path,
849                                                cairo_fill_rule_t   fill_rule,
850                                                double               tolerance,
851                                                cairo_antialias_t   antialias)
852 {
853     cairo_ps_surface_t *surface = cairo_container_of (clipper,
854                                                       cairo_ps_surface_t,
855                                                       clipper);
856     cairo_output_stream_t *stream = surface->stream;
857     cairo_status_t status;
858
859     assert (surface->paginated_mode != CAIRO_PAGINATED_MODE_ANALYZE);
860
861 #if DEBUG_PS
862     _cairo_output_stream_printf (stream,
863                                  "%% _cairo_ps_surface_intersect_clip_path\n");
864 #endif
865
866     if (path == NULL) {
867         status = _cairo_pdf_operators_flush (&surface->pdf_operators);
868         if (unlikely (status))
869             return status;
870
871         _cairo_output_stream_printf (stream, "Q q\n");
872
873         surface->current_pattern_is_solid_color = FALSE;
874         _cairo_pdf_operators_reset (&surface->pdf_operators);
875
876         return CAIRO_STATUS_SUCCESS;
877     }
878
879     if (_path_covers_bbox (surface, path))
880         return CAIRO_STATUS_SUCCESS;
881
882     return _cairo_pdf_operators_clip (&surface->pdf_operators,
883                                       path,
884                                       fill_rule);
885 }
886
887 /* PLRM specifies a tolerance of 5 points when matching page sizes */
888 static cairo_bool_t
889 _ps_page_dimension_equal (int a, int b)
890 {
891     return (abs (a - b) < 5);
892 }
893
894 static const char *
895 _cairo_ps_surface_get_page_media (cairo_ps_surface_t     *surface)
896 {
897     int width, height, i;
898     char buf[50];
899     cairo_page_media_t *page;
900     const char *page_name;
901
902     width = _cairo_lround (surface->width);
903     height = _cairo_lround (surface->height);
904
905     /* search previously used page sizes */
906     cairo_list_foreach_entry (page, cairo_page_media_t, &surface->document_media, link) {
907         if (_ps_page_dimension_equal (width, page->width) &&
908             _ps_page_dimension_equal (height, page->height))
909             return page->name;
910     }
911
912     /* search list of standard page sizes */
913     page_name = NULL;
914     for (i = 0; i < ARRAY_LENGTH (_cairo_page_standard_media); i++) {
915         if (_ps_page_dimension_equal (width, _cairo_page_standard_media[i].width) &&
916             _ps_page_dimension_equal (height, _cairo_page_standard_media[i].height))
917         {
918             page_name = _cairo_page_standard_media[i].name;
919             width = _cairo_page_standard_media[i].width;
920             height = _cairo_page_standard_media[i].height;
921             break;
922         }
923     }
924
925     page = malloc (sizeof (cairo_page_media_t));
926     if (unlikely (page == NULL)) {
927         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
928         return NULL;
929     }
930
931     if (page_name) {
932         page->name = strdup (page_name);
933     } else {
934         snprintf (buf, sizeof (buf), "%dx%dmm",
935                   (int) _cairo_lround (surface->width * 25.4/72),
936                   (int) _cairo_lround (surface->height * 25.4/72));
937         page->name = strdup (buf);
938     }
939
940     if (unlikely (page->name == NULL)) {
941         free (page);
942         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
943         return NULL;
944     }
945
946     page->width = width;
947     page->height = height;
948     cairo_list_add_tail (&page->link, &surface->document_media);
949
950     return page->name;
951 }
952
953 static cairo_surface_t *
954 _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream,
955                                               double                 width,
956                                               double                 height)
957 {
958     cairo_status_t status, status_ignored;
959     cairo_ps_surface_t *surface;
960
961     surface = malloc (sizeof (cairo_ps_surface_t));
962     if (unlikely (surface == NULL)) {
963         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
964         goto CLEANUP;
965     }
966
967     _cairo_surface_init (&surface->base,
968                          &cairo_ps_surface_backend,
969                          NULL, /* device */
970                          CAIRO_CONTENT_COLOR_ALPHA);
971
972     surface->final_stream = stream;
973
974     surface->tmpfile = tmpfile ();
975     if (surface->tmpfile == NULL) {
976         switch (errno) {
977         case ENOMEM:
978             status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
979             break;
980         default:
981             status = _cairo_error (CAIRO_STATUS_TEMP_FILE_ERROR);
982             break;
983         }
984         goto CLEANUP_SURFACE;
985     }
986
987     surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile);
988     status = _cairo_output_stream_get_status (surface->stream);
989     if (unlikely (status))
990         goto CLEANUP_OUTPUT_STREAM;
991
992     surface->font_subsets = _cairo_scaled_font_subsets_create_simple ();
993     if (unlikely (surface->font_subsets == NULL)) {
994         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
995         goto CLEANUP_OUTPUT_STREAM;
996     }
997
998     _cairo_scaled_font_subsets_enable_latin_subset (surface->font_subsets, TRUE);
999     surface->has_creation_date = FALSE;
1000     surface->eps = FALSE;
1001     surface->ps_level = CAIRO_PS_LEVEL_3;
1002     surface->ps_level_used = CAIRO_PS_LEVEL_2;
1003     surface->width  = width;
1004     surface->height = height;
1005     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, height);
1006     surface->paginated_mode = CAIRO_PAGINATED_MODE_ANALYZE;
1007     surface->force_fallbacks = FALSE;
1008     surface->content = CAIRO_CONTENT_COLOR_ALPHA;
1009     surface->use_string_datasource = FALSE;
1010     surface->current_pattern_is_solid_color = FALSE;
1011
1012     surface->page_bbox.x = 0;
1013     surface->page_bbox.y = 0;
1014     surface->page_bbox.width  = width;
1015     surface->page_bbox.height = height;
1016
1017     _cairo_surface_clipper_init (&surface->clipper,
1018                                  _cairo_ps_surface_clipper_intersect_clip_path);
1019
1020     _cairo_pdf_operators_init (&surface->pdf_operators,
1021                                surface->stream,
1022                                &surface->cairo_to_ps,
1023                                surface->font_subsets);
1024     surface->num_pages = 0;
1025
1026     cairo_list_init (&surface->document_media);
1027     _cairo_array_init (&surface->dsc_header_comments, sizeof (char *));
1028     _cairo_array_init (&surface->dsc_setup_comments, sizeof (char *));
1029     _cairo_array_init (&surface->dsc_page_setup_comments, sizeof (char *));
1030
1031     surface->dsc_comment_target = &surface->dsc_header_comments;
1032
1033     surface->paginated_surface = _cairo_paginated_surface_create (
1034                                            &surface->base,
1035                                            CAIRO_CONTENT_COLOR_ALPHA,
1036                                            &cairo_ps_surface_paginated_backend);
1037     status = surface->paginated_surface->status;
1038     if (status == CAIRO_STATUS_SUCCESS) {
1039         /* paginated keeps the only reference to surface now, drop ours */
1040         cairo_surface_destroy (&surface->base);
1041         return surface->paginated_surface;
1042     }
1043
1044     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
1045  CLEANUP_OUTPUT_STREAM:
1046     status_ignored = _cairo_output_stream_destroy (surface->stream);
1047     fclose (surface->tmpfile);
1048  CLEANUP_SURFACE:
1049     free (surface);
1050  CLEANUP:
1051     /* destroy stream on behalf of caller */
1052     status_ignored = _cairo_output_stream_destroy (stream);
1053
1054     return _cairo_surface_create_in_error (status);
1055 }
1056
1057 /**
1058  * cairo_ps_surface_create:
1059  * @filename: a filename for the PS output (must be writable), %NULL may be
1060  *            used to specify no output. This will generate a PS surface that
1061  *            may be queried and used as a source, without generating a
1062  *            temporary file.
1063  * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
1064  * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
1065  *
1066  * Creates a PostScript surface of the specified size in points to be
1067  * written to @filename. See cairo_ps_surface_create_for_stream() for
1068  * a more flexible mechanism for handling the PostScript output than
1069  * simply writing it to a named file.
1070  *
1071  * Note that the size of individual pages of the PostScript output can
1072  * vary. See cairo_ps_surface_set_size().
1073  *
1074  * Return value: a pointer to the newly created surface. The caller
1075  * owns the surface and should call cairo_surface_destroy() when done
1076  * with it.
1077  *
1078  * This function always returns a valid pointer, but it will return a
1079  * pointer to a "nil" surface if an error such as out of memory
1080  * occurs. You can use cairo_surface_status() to check for this.
1081  *
1082  * Since: 1.2
1083  **/
1084 cairo_surface_t *
1085 cairo_ps_surface_create (const char             *filename,
1086                          double                  width_in_points,
1087                          double                  height_in_points)
1088 {
1089     cairo_output_stream_t *stream;
1090
1091     stream = _cairo_output_stream_create_for_filename (filename);
1092     if (_cairo_output_stream_get_status (stream))
1093         return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
1094
1095     return _cairo_ps_surface_create_for_stream_internal (stream,
1096                                                          width_in_points,
1097                                                          height_in_points);
1098 }
1099
1100 /**
1101  * cairo_ps_surface_create_for_stream:
1102  * @write_func: a #cairo_write_func_t to accept the output data, may be %NULL
1103  *              to indicate a no-op @write_func. With a no-op @write_func,
1104  *              the surface may be queried or used as a source without
1105  *              generating any temporary files.
1106  * @closure: the closure argument for @write_func
1107  * @width_in_points: width of the surface, in points (1 point == 1/72.0 inch)
1108  * @height_in_points: height of the surface, in points (1 point == 1/72.0 inch)
1109  *
1110  * Creates a PostScript surface of the specified size in points to be
1111  * written incrementally to the stream represented by @write_func and
1112  * @closure. See cairo_ps_surface_create() for a more convenient way
1113  * to simply direct the PostScript output to a named file.
1114  *
1115  * Note that the size of individual pages of the PostScript
1116  * output can vary. See cairo_ps_surface_set_size().
1117  *
1118  * Return value: a pointer to the newly created surface. The caller
1119  * owns the surface and should call cairo_surface_destroy() when done
1120  * with it.
1121  *
1122  * This function always returns a valid pointer, but it will return a
1123  * pointer to a "nil" surface if an error such as out of memory
1124  * occurs. You can use cairo_surface_status() to check for this.
1125  *
1126  * Since: 1.2
1127  **/
1128 cairo_surface_t *
1129 cairo_ps_surface_create_for_stream (cairo_write_func_t  write_func,
1130                                     void               *closure,
1131                                     double              width_in_points,
1132                                     double              height_in_points)
1133 {
1134     cairo_output_stream_t *stream;
1135
1136     stream = _cairo_output_stream_create (write_func, NULL, closure);
1137     if (_cairo_output_stream_get_status (stream))
1138         return _cairo_surface_create_in_error (_cairo_output_stream_destroy (stream));
1139
1140     return _cairo_ps_surface_create_for_stream_internal (stream,
1141                                                          width_in_points,
1142                                                          height_in_points);
1143 }
1144
1145 static cairo_bool_t
1146 _cairo_surface_is_ps (cairo_surface_t *surface)
1147 {
1148     return surface->backend == &cairo_ps_surface_backend;
1149 }
1150
1151 /* If the abstract_surface is a paginated surface, and that paginated
1152  * surface's target is a ps_surface, then set ps_surface to that
1153  * target. Otherwise return FALSE.
1154  */
1155 static cairo_bool_t
1156 _extract_ps_surface (cairo_surface_t     *surface,
1157                      cairo_bool_t         set_error_on_failure,
1158                      cairo_ps_surface_t **ps_surface)
1159 {
1160     cairo_surface_t *target;
1161
1162     if (surface->status)
1163         return FALSE;
1164     if (surface->finished) {
1165         if (set_error_on_failure)
1166             _cairo_surface_set_error (surface,
1167                                       _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1168         return FALSE;
1169     }
1170
1171     if (! _cairo_surface_is_paginated (surface)) {
1172         if (set_error_on_failure)
1173             _cairo_surface_set_error (surface,
1174                                       _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
1175         return FALSE;
1176     }
1177
1178     target = _cairo_paginated_surface_get_target (surface);
1179     if (target->status) {
1180         if (set_error_on_failure)
1181             _cairo_surface_set_error (surface, target->status);
1182         return FALSE;
1183     }
1184     if (target->finished) {
1185         if (set_error_on_failure)
1186             _cairo_surface_set_error (surface,
1187                                       _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1188         return FALSE;
1189     }
1190
1191     if (! _cairo_surface_is_ps (target)) {
1192         if (set_error_on_failure)
1193             _cairo_surface_set_error (surface,
1194                                       _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
1195         return FALSE;
1196     }
1197
1198     *ps_surface = (cairo_ps_surface_t *) target;
1199     return TRUE;
1200 }
1201
1202 /**
1203  * cairo_ps_surface_restrict_to_level:
1204  * @surface: a PostScript #cairo_surface_t
1205  * @level: PostScript level
1206  *
1207  * Restricts the generated PostSript file to @level. See
1208  * cairo_ps_get_levels() for a list of available level values that
1209  * can be used here.
1210  *
1211  * This function should only be called before any drawing operations
1212  * have been performed on the given surface. The simplest way to do
1213  * this is to call this function immediately after creating the
1214  * surface.
1215  *
1216  * Since: 1.6
1217  **/
1218 void
1219 cairo_ps_surface_restrict_to_level (cairo_surface_t  *surface,
1220                                     cairo_ps_level_t  level)
1221 {
1222     cairo_ps_surface_t *ps_surface = NULL;
1223
1224     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1225         return;
1226
1227     if (level < CAIRO_PS_LEVEL_LAST)
1228         ps_surface->ps_level = level;
1229 }
1230
1231 /**
1232  * cairo_ps_get_levels:
1233  * @levels: supported level list
1234  * @num_levels: list length
1235  *
1236  * Used to retrieve the list of supported levels. See
1237  * cairo_ps_surface_restrict_to_level().
1238  *
1239  * Since: 1.6
1240  **/
1241 void
1242 cairo_ps_get_levels (cairo_ps_level_t const     **levels,
1243                      int                         *num_levels)
1244 {
1245     if (levels != NULL)
1246         *levels = _cairo_ps_levels;
1247
1248     if (num_levels != NULL)
1249         *num_levels = CAIRO_PS_LEVEL_LAST;
1250 }
1251
1252 /**
1253  * cairo_ps_level_to_string:
1254  * @level: a level id
1255  *
1256  * Get the string representation of the given @level id. This function
1257  * will return %NULL if @level id isn't valid. See cairo_ps_get_levels()
1258  * for a way to get the list of valid level ids.
1259  *
1260  * Return value: the string associated to given level.
1261  *
1262  * Since: 1.6
1263  **/
1264 const char *
1265 cairo_ps_level_to_string (cairo_ps_level_t level)
1266 {
1267     if (level >= CAIRO_PS_LEVEL_LAST)
1268         return NULL;
1269
1270     return _cairo_ps_level_strings[level];
1271 }
1272
1273 /**
1274  * cairo_ps_surface_set_eps:
1275  * @surface: a PostScript #cairo_surface_t
1276  * @eps: %TRUE to output EPS format PostScript
1277  *
1278  * If @eps is %TRUE, the PostScript surface will output Encapsulated
1279  * PostScript.
1280  *
1281  * This function should only be called before any drawing operations
1282  * have been performed on the current page. The simplest way to do
1283  * this is to call this function immediately after creating the
1284  * surface. An Encapsulated PostScript file should never contain more
1285  * than one page.
1286  *
1287  * Since: 1.6
1288  **/
1289 void
1290 cairo_ps_surface_set_eps (cairo_surface_t       *surface,
1291                           cairo_bool_t           eps)
1292 {
1293     cairo_ps_surface_t *ps_surface = NULL;
1294
1295     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1296         return;
1297
1298     ps_surface->eps = eps;
1299 }
1300
1301 /**
1302  * cairo_ps_surface_get_eps:
1303  * @surface: a PostScript #cairo_surface_t
1304  *
1305  * Check whether the PostScript surface will output Encapsulated PostScript.
1306  *
1307  * Return value: %TRUE if the surface will output Encapsulated PostScript.
1308  *
1309  * Since: 1.6
1310  **/
1311 cairo_public cairo_bool_t
1312 cairo_ps_surface_get_eps (cairo_surface_t       *surface)
1313 {
1314     cairo_ps_surface_t *ps_surface = NULL;
1315
1316     if (! _extract_ps_surface (surface, FALSE, &ps_surface))
1317         return FALSE;
1318
1319     return ps_surface->eps;
1320 }
1321
1322 /**
1323  * cairo_ps_surface_set_size:
1324  * @surface: a PostScript #cairo_surface_t
1325  * @width_in_points: new surface width, in points (1 point == 1/72.0 inch)
1326  * @height_in_points: new surface height, in points (1 point == 1/72.0 inch)
1327  *
1328  * Changes the size of a PostScript surface for the current (and
1329  * subsequent) pages.
1330  *
1331  * This function should only be called before any drawing operations
1332  * have been performed on the current page. The simplest way to do
1333  * this is to call this function immediately after creating the
1334  * surface or immediately after completing a page with either
1335  * cairo_show_page() or cairo_copy_page().
1336  *
1337  * Since: 1.2
1338  **/
1339 void
1340 cairo_ps_surface_set_size (cairo_surface_t      *surface,
1341                            double                width_in_points,
1342                            double                height_in_points)
1343 {
1344     cairo_ps_surface_t *ps_surface = NULL;
1345     cairo_status_t status;
1346
1347     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1348         return;
1349
1350     ps_surface->width = width_in_points;
1351     ps_surface->height = height_in_points;
1352     cairo_matrix_init (&ps_surface->cairo_to_ps, 1, 0, 0, -1, 0, height_in_points);
1353     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&ps_surface->pdf_operators,
1354                                                   &ps_surface->cairo_to_ps);
1355     status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface,
1356                                                 width_in_points,
1357                                                 height_in_points);
1358     if (status)
1359         status = _cairo_surface_set_error (surface, status);
1360 }
1361
1362 /**
1363  * cairo_ps_surface_dsc_comment:
1364  * @surface: a PostScript #cairo_surface_t
1365  * @comment: a comment string to be emitted into the PostScript output
1366  *
1367  * Emit a comment into the PostScript output for the given surface.
1368  *
1369  * The comment is expected to conform to the PostScript Language
1370  * Document Structuring Conventions (DSC). Please see that manual for
1371  * details on the available comments and their meanings. In
1372  * particular, the \%\%IncludeFeature comment allows a
1373  * device-independent means of controlling printer device features. So
1374  * the PostScript Printer Description Files Specification will also be
1375  * a useful reference.
1376  *
1377  * The comment string must begin with a percent character (\%) and the
1378  * total length of the string (including any initial percent
1379  * characters) must not exceed 255 characters. Violating either of
1380  * these conditions will place @surface into an error state. But
1381  * beyond these two conditions, this function will not enforce
1382  * conformance of the comment with any particular specification.
1383  *
1384  * The comment string should not have a trailing newline.
1385  *
1386  * The DSC specifies different sections in which particular comments
1387  * can appear. This function provides for comments to be emitted
1388  * within three sections: the header, the Setup section, and the
1389  * PageSetup section.  Comments appearing in the first two sections
1390  * apply to the entire document while comments in the BeginPageSetup
1391  * section apply only to a single page.
1392  *
1393  * For comments to appear in the header section, this function should
1394  * be called after the surface is created, but before a call to
1395  * cairo_ps_surface_dsc_begin_setup().
1396  *
1397  * For comments to appear in the Setup section, this function should
1398  * be called after a call to cairo_ps_surface_dsc_begin_setup() but
1399  * before a call to cairo_ps_surface_dsc_begin_page_setup().
1400  *
1401  * For comments to appear in the PageSetup section, this function
1402  * should be called after a call to
1403  * cairo_ps_surface_dsc_begin_page_setup().
1404  *
1405  * Note that it is only necessary to call
1406  * cairo_ps_surface_dsc_begin_page_setup() for the first page of any
1407  * surface. After a call to cairo_show_page() or cairo_copy_page()
1408  * comments are unambiguously directed to the PageSetup section of the
1409  * current page. But it doesn't hurt to call this function at the
1410  * beginning of every page as that consistency may make the calling
1411  * code simpler.
1412  *
1413  * As a final note, cairo automatically generates several comments on
1414  * its own. As such, applications must not manually generate any of
1415  * the following comments:
1416  *
1417  * Header section: \%!PS-Adobe-3.0, \%\%Creator, \%\%CreationDate, \%\%Pages,
1418  * \%\%BoundingBox, \%\%DocumentData, \%\%LanguageLevel, \%\%EndComments.
1419  *
1420  * Setup section: \%\%BeginSetup, \%\%EndSetup
1421  *
1422  * PageSetup section: \%\%BeginPageSetup, \%\%PageBoundingBox, \%\%EndPageSetup.
1423  *
1424  * Other sections: \%\%BeginProlog, \%\%EndProlog, \%\%Page, \%\%Trailer, \%\%EOF
1425  *
1426  * Here is an example sequence showing how this function might be used:
1427  *
1428  * <informalexample><programlisting>
1429  * cairo_surface_t *surface = cairo_ps_surface_create (filename, width, height);
1430  * ...
1431  * cairo_ps_surface_dsc_comment (surface, "%%Title: My excellent document");
1432  * cairo_ps_surface_dsc_comment (surface, "%%Copyright: Copyright (C) 2006 Cairo Lover")
1433  * ...
1434  * cairo_ps_surface_dsc_begin_setup (surface);
1435  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor White");
1436  * ...
1437  * cairo_ps_surface_dsc_begin_page_setup (surface);
1438  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A3");
1439  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *InputSlot LargeCapacity");
1440  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaType Glossy");
1441  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *MediaColor Blue");
1442  * ... draw to first page here ..
1443  * cairo_show_page (cr);
1444  * ...
1445  * cairo_ps_surface_dsc_comment (surface, "%%IncludeFeature: *PageSize A5");
1446  * ...
1447  * </programlisting></informalexample>
1448  *
1449  * Since: 1.2
1450  **/
1451 void
1452 cairo_ps_surface_dsc_comment (cairo_surface_t   *surface,
1453                               const char        *comment)
1454 {
1455     cairo_ps_surface_t *ps_surface = NULL;
1456     cairo_status_t status;
1457     char *comment_copy;
1458
1459     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1460         return;
1461
1462     /* A couple of sanity checks on the comment value. */
1463     if (comment == NULL) {
1464         status = _cairo_surface_set_error (surface, CAIRO_STATUS_NULL_POINTER);
1465         return;
1466     }
1467
1468     if (comment[0] != '%' || strlen (comment) > 255) {
1469         status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_DSC_COMMENT);
1470         return;
1471     }
1472
1473     /* Then, copy the comment and store it in the appropriate array. */
1474     comment_copy = strdup (comment);
1475     if (unlikely (comment_copy == NULL)) {
1476         status = _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
1477         return;
1478     }
1479
1480     status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy);
1481     if (unlikely (status)) {
1482         free (comment_copy);
1483         status = _cairo_surface_set_error (surface, status);
1484         return;
1485     }
1486 }
1487
1488 /**
1489  * cairo_ps_surface_dsc_begin_setup:
1490  * @surface: a PostScript #cairo_surface_t
1491  *
1492  * This function indicates that subsequent calls to
1493  * cairo_ps_surface_dsc_comment() should direct comments to the Setup
1494  * section of the PostScript output.
1495  *
1496  * This function should be called at most once per surface, and must
1497  * be called before any call to cairo_ps_surface_dsc_begin_page_setup()
1498  * and before any drawing is performed to the surface.
1499  *
1500  * See cairo_ps_surface_dsc_comment() for more details.
1501  *
1502  * Since: 1.2
1503  **/
1504 void
1505 cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface)
1506 {
1507     cairo_ps_surface_t *ps_surface = NULL;
1508
1509     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1510         return;
1511
1512     if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments)
1513         ps_surface->dsc_comment_target = &ps_surface->dsc_setup_comments;
1514 }
1515
1516 /**
1517  * cairo_ps_surface_dsc_begin_page_setup:
1518  * @surface: a PostScript #cairo_surface_t
1519  *
1520  * This function indicates that subsequent calls to
1521  * cairo_ps_surface_dsc_comment() should direct comments to the
1522  * PageSetup section of the PostScript output.
1523  *
1524  * This function call is only needed for the first page of a
1525  * surface. It should be called after any call to
1526  * cairo_ps_surface_dsc_begin_setup() and before any drawing is
1527  * performed to the surface.
1528  *
1529  * See cairo_ps_surface_dsc_comment() for more details.
1530  *
1531  * Since: 1.2
1532  **/
1533 void
1534 cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface)
1535 {
1536     cairo_ps_surface_t *ps_surface = NULL;
1537
1538     if (! _extract_ps_surface (surface, TRUE, &ps_surface))
1539         return;
1540
1541     if (ps_surface->dsc_comment_target == &ps_surface->dsc_header_comments ||
1542         ps_surface->dsc_comment_target == &ps_surface->dsc_setup_comments)
1543     {
1544         ps_surface->dsc_comment_target = &ps_surface->dsc_page_setup_comments;
1545     }
1546 }
1547
1548 static cairo_status_t
1549 _cairo_ps_surface_finish (void *abstract_surface)
1550 {
1551     cairo_status_t status, status2;
1552     cairo_ps_surface_t *surface = abstract_surface;
1553     int i, num_comments;
1554     char **comments;
1555
1556     status = surface->base.status;
1557     if (unlikely (status))
1558         goto CLEANUP;
1559
1560     _cairo_ps_surface_emit_header (surface);
1561
1562     status = _cairo_ps_surface_emit_font_subsets (surface);
1563     if (unlikely (status))
1564         goto CLEANUP;
1565
1566     status = _cairo_ps_surface_emit_body (surface);
1567     if (unlikely (status))
1568         goto CLEANUP;
1569
1570     _cairo_ps_surface_emit_footer (surface);
1571
1572 CLEANUP:
1573     _cairo_scaled_font_subsets_destroy (surface->font_subsets);
1574
1575     status2 = _cairo_output_stream_destroy (surface->stream);
1576     if (status == CAIRO_STATUS_SUCCESS)
1577         status = status2;
1578
1579     fclose (surface->tmpfile);
1580
1581     status2 = _cairo_output_stream_destroy (surface->final_stream);
1582     if (status == CAIRO_STATUS_SUCCESS)
1583         status = status2;
1584
1585     while (! cairo_list_is_empty (&surface->document_media)) {
1586         cairo_page_media_t *page;
1587
1588         page = cairo_list_first_entry (&surface->document_media,
1589                                        cairo_page_media_t,
1590                                        link);
1591         cairo_list_del (&page->link);
1592         free (page->name);
1593         free (page);
1594     }
1595
1596     num_comments = _cairo_array_num_elements (&surface->dsc_header_comments);
1597     comments = _cairo_array_index (&surface->dsc_header_comments, 0);
1598     for (i = 0; i < num_comments; i++)
1599         free (comments[i]);
1600     _cairo_array_fini (&surface->dsc_header_comments);
1601
1602     num_comments = _cairo_array_num_elements (&surface->dsc_setup_comments);
1603     comments = _cairo_array_index (&surface->dsc_setup_comments, 0);
1604     for (i = 0; i < num_comments; i++)
1605         free (comments[i]);
1606     _cairo_array_fini (&surface->dsc_setup_comments);
1607
1608     num_comments = _cairo_array_num_elements (&surface->dsc_page_setup_comments);
1609     comments = _cairo_array_index (&surface->dsc_page_setup_comments, 0);
1610     for (i = 0; i < num_comments; i++)
1611         free (comments[i]);
1612     _cairo_array_fini (&surface->dsc_page_setup_comments);
1613
1614     _cairo_surface_clipper_reset (&surface->clipper);
1615
1616     return status;
1617 }
1618
1619 static cairo_int_status_t
1620 _cairo_ps_surface_start_page (void *abstract_surface)
1621 {
1622     cairo_ps_surface_t *surface = abstract_surface;
1623
1624     /* Increment before print so page numbers start at 1. */
1625     surface->num_pages++;
1626
1627     return CAIRO_STATUS_SUCCESS;
1628 }
1629
1630 static cairo_int_status_t
1631 _cairo_ps_surface_show_page (void *abstract_surface)
1632 {
1633     cairo_ps_surface_t *surface = abstract_surface;
1634     cairo_int_status_t status;
1635
1636     if (surface->clipper.clip != NULL)
1637         _cairo_surface_clipper_reset (&surface->clipper);
1638
1639     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
1640     if (unlikely (status))
1641         return status;
1642
1643     _cairo_output_stream_printf (surface->stream,
1644                                  "Q Q\n"
1645                                  "showpage\n");
1646
1647     return CAIRO_STATUS_SUCCESS;
1648 }
1649
1650 static cairo_bool_t
1651 color_is_gray (double red, double green, double blue)
1652 {
1653     const double epsilon = 0.00001;
1654
1655     return (fabs (red - green) < epsilon &&
1656             fabs (red - blue) < epsilon);
1657 }
1658
1659 /**
1660  * _cairo_ps_surface_acquire_source_surface_from_pattern:
1661  * @surface: the ps surface
1662  * @pattern: A #cairo_pattern_t of type SURFACE or RASTER_SOURCE to use as the source
1663  * @extents: extents of the operation that is using this source
1664  * @width: returns width of surface
1665  * @height: returns height of surface
1666  * @x_offset: returns x offset of surface
1667  * @y_offset: returns y offset of surface
1668  * @surface: returns surface of type image surface or recording surface
1669  * @image_extra: returns image extra for image type surface
1670  *
1671  * Acquire source surface or raster source pattern.
1672  **/
1673 static cairo_status_t
1674 _cairo_ps_surface_acquire_source_surface_from_pattern (cairo_ps_surface_t           *surface,
1675                                                        const cairo_pattern_t        *pattern,
1676                                                        const cairo_rectangle_int_t  *extents,
1677                                                        int                          *width,
1678                                                        int                          *height,
1679                                                        double                       *x_offset,
1680                                                        double                       *y_offset,
1681                                                        cairo_surface_t             **source_surface,
1682                                                        void                        **image_extra)
1683 {
1684     cairo_status_t          status;
1685     cairo_image_surface_t  *image;
1686
1687     *x_offset = *y_offset = 0;
1688     switch (pattern->type) {
1689     case CAIRO_PATTERN_TYPE_SURFACE: {
1690         cairo_surface_t *surf = ((cairo_surface_pattern_t *) pattern)->surface;
1691
1692         if (surf->type == CAIRO_SURFACE_TYPE_RECORDING) {
1693             if (surf->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
1694                 cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) surf;
1695
1696                 *width  = sub->extents.width;
1697                 *height = sub->extents.height;
1698             } else {
1699                 cairo_surface_t *free_me = NULL;
1700                 cairo_recording_surface_t *recording_surface;
1701                 cairo_box_t bbox;
1702                 cairo_rectangle_int_t extents;
1703
1704                 recording_surface = (cairo_recording_surface_t *) surf;
1705                 if (_cairo_surface_is_snapshot (&recording_surface->base)) {
1706                     free_me = _cairo_surface_snapshot_get_target (&recording_surface->base);
1707                     recording_surface = (cairo_recording_surface_t *) free_me;
1708                 }
1709
1710                 status = _cairo_recording_surface_get_bbox (recording_surface, &bbox, NULL);
1711                 cairo_surface_destroy (free_me);
1712                 if (unlikely (status))
1713                     return status;
1714
1715                 _cairo_box_round_to_rectangle (&bbox, &extents);
1716                 *width  = extents.width;
1717                 *height = extents.height;
1718             }
1719             *source_surface = surf;
1720
1721             return CAIRO_STATUS_SUCCESS;
1722         } else {
1723             status =  _cairo_surface_acquire_source_image (surf, &image, image_extra);
1724             if (unlikely (status))
1725                 return status;
1726         }
1727     } break;
1728
1729     case CAIRO_PATTERN_TYPE_RASTER_SOURCE: {
1730         cairo_surface_t *surf;
1731         cairo_box_t box;
1732         cairo_rectangle_int_t rect;
1733
1734         /* get the operation extents in pattern space */
1735         _cairo_box_from_rectangle (&box, extents);
1736         _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL);
1737         _cairo_box_round_to_rectangle (&box, &rect);
1738         surf = _cairo_raster_source_pattern_acquire (pattern, &surface->base, &rect);
1739         if (!surf)
1740             return CAIRO_INT_STATUS_UNSUPPORTED;
1741         assert (_cairo_surface_is_image (surf));
1742         image = (cairo_image_surface_t *) surf;
1743     } break;
1744
1745     case CAIRO_PATTERN_TYPE_SOLID:
1746     case CAIRO_PATTERN_TYPE_LINEAR:
1747     case CAIRO_PATTERN_TYPE_RADIAL:
1748     case CAIRO_PATTERN_TYPE_MESH:
1749     default:
1750         ASSERT_NOT_REACHED;
1751         break;
1752     }
1753
1754     *width = image->width;
1755     *height = image->height;
1756     *source_surface = &image->base;
1757     return CAIRO_STATUS_SUCCESS;
1758 }
1759
1760 static void
1761 _cairo_ps_surface_release_source_surface_from_pattern (cairo_ps_surface_t           *surface,
1762                                                        const cairo_pattern_t        *pattern,
1763                                                        cairo_surface_t              *source,
1764                                                        void                         *image_extra)
1765 {
1766     switch (pattern->type) {
1767     case CAIRO_PATTERN_TYPE_SURFACE: {
1768         cairo_surface_pattern_t *surf_pat = (cairo_surface_pattern_t *) pattern;
1769         if (surf_pat->surface->type != CAIRO_SURFACE_TYPE_RECORDING) {
1770             cairo_image_surface_t *image  = (cairo_image_surface_t *) source;
1771             _cairo_surface_release_source_image (surf_pat->surface, image, image_extra);
1772         }
1773     } break;
1774
1775     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
1776         _cairo_raster_source_pattern_release (pattern, source);
1777         break;
1778
1779     case CAIRO_PATTERN_TYPE_SOLID:
1780     case CAIRO_PATTERN_TYPE_LINEAR:
1781     case CAIRO_PATTERN_TYPE_RADIAL:
1782     case CAIRO_PATTERN_TYPE_MESH:
1783     default:
1784
1785         ASSERT_NOT_REACHED;
1786         break;
1787     }
1788 }
1789
1790 /**
1791  * _cairo_ps_surface_create_padded_image_from_image:
1792  * @surface: the ps surface
1793  * @source: The source image
1794  * @extents: extents of the operation that is using this source
1795  * @width: returns width of padded image
1796  * @height: returns height of padded image
1797  * @x_offset: returns x offset of padded image
1798  * @y_offset: returns y offset of padded image
1799  * @image: returns the padded image or NULL if padding not required to fill @extents
1800  *
1801  * Creates a padded image if the source image does not fill the extents.
1802  **/
1803 static cairo_status_t
1804 _cairo_ps_surface_create_padded_image_from_image (cairo_ps_surface_t           *surface,
1805                                                   cairo_image_surface_t        *source,
1806                                                   const cairo_matrix_t         *source_matrix,
1807                                                   const cairo_rectangle_int_t  *extents,
1808                                                   int                          *width,
1809                                                   int                          *height,
1810                                                   double                       *x_offset,
1811                                                   double                       *y_offset,
1812                                                   cairo_image_surface_t       **image)
1813 {
1814     cairo_box_t box;
1815     cairo_rectangle_int_t rect;
1816     cairo_surface_t        *pad_image;
1817     cairo_surface_pattern_t pad_pattern;
1818     int w, h;
1819     cairo_int_status_t      status;
1820
1821     /* get the operation extents in pattern space */
1822     _cairo_box_from_rectangle (&box, extents);
1823     _cairo_matrix_transform_bounding_box_fixed (source_matrix, &box, NULL);
1824     _cairo_box_round_to_rectangle (&box, &rect);
1825
1826     /* Check if image needs padding to fill extents. */
1827     w = source->width;
1828     h = source->height;
1829     if (_cairo_fixed_integer_ceil(box.p1.x) < 0 ||
1830         _cairo_fixed_integer_ceil(box.p1.y) < 0 ||
1831         _cairo_fixed_integer_floor(box.p2.y) > w ||
1832         _cairo_fixed_integer_floor(box.p2.y) > h)
1833     {
1834         pad_image =
1835             _cairo_image_surface_create_with_pixman_format (NULL,
1836                                                             source->pixman_format,
1837                                                             rect.width, rect.height,
1838                                                             0);
1839         if (pad_image->status)
1840             return pad_image->status;
1841
1842         _cairo_pattern_init_for_surface (&pad_pattern, &source->base);
1843         cairo_matrix_init_translate (&pad_pattern.base.matrix, rect.x, rect.y);
1844         pad_pattern.base.extend = CAIRO_EXTEND_PAD;
1845         status = _cairo_surface_paint (pad_image,
1846                                        CAIRO_OPERATOR_SOURCE,
1847                                        &pad_pattern.base,
1848                                        NULL);
1849         _cairo_pattern_fini (&pad_pattern.base);
1850         *image = (cairo_image_surface_t *) pad_image;
1851         *width = rect.width;
1852         *height = rect.height;
1853         *x_offset = rect.x;
1854         *y_offset = rect.y;
1855     } else {
1856         *image = NULL;
1857         status = CAIRO_STATUS_SUCCESS;
1858     }
1859
1860     return status;
1861 }
1862
1863 static cairo_int_status_t
1864 _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t            *surface,
1865                                                         const cairo_pattern_t         *pattern,
1866                                                         const cairo_rectangle_int_t   *extents)
1867 {
1868     int width, height;
1869     double x_offset, y_offset;
1870     cairo_surface_t *source;
1871     cairo_image_surface_t *image;
1872     void *image_extra;
1873     cairo_int_status_t      status;
1874     cairo_image_transparency_t transparency;
1875
1876     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
1877                                                                     pattern,
1878                                                                     extents,
1879                                                                     &width,
1880                                                                     &height,
1881                                                                     &x_offset,
1882                                                                     &y_offset,
1883                                                                     &source,
1884                                                                     &image_extra);
1885     if (unlikely (status))
1886         return status;
1887
1888     image = (cairo_image_surface_t *) source;
1889     if (image->base.status)
1890         return image->base.status;
1891
1892     transparency = _cairo_image_analyze_transparency (image);
1893     switch (transparency) {
1894     case CAIRO_IMAGE_IS_OPAQUE:
1895         status = CAIRO_STATUS_SUCCESS;
1896         break;
1897
1898     case CAIRO_IMAGE_HAS_BILEVEL_ALPHA:
1899         if (surface->ps_level == CAIRO_PS_LEVEL_2) {
1900             status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
1901         } else {
1902             surface->ps_level_used = CAIRO_PS_LEVEL_3;
1903             status = CAIRO_STATUS_SUCCESS;
1904         }
1905         break;
1906
1907     case CAIRO_IMAGE_HAS_ALPHA:
1908         status = CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
1909         break;
1910
1911     case CAIRO_IMAGE_UNKNOWN:
1912         ASSERT_NOT_REACHED;
1913     }
1914
1915     _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
1916
1917     return status;
1918 }
1919
1920 static cairo_bool_t
1921 surface_pattern_supported (const cairo_surface_pattern_t *pattern)
1922 {
1923     if (pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING)
1924         return TRUE;
1925
1926     if (pattern->surface->backend->acquire_source_image == NULL)
1927         return FALSE;
1928
1929     /* Does an ALPHA-only source surface even make sense? Maybe, but I
1930      * don't think it's worth the extra code to support it. */
1931
1932 /* XXX: Need to write this function here...
1933     content = pattern->surface->content;
1934     if (content == CAIRO_CONTENT_ALPHA)
1935         return FALSE;
1936 */
1937
1938     return TRUE;
1939 }
1940
1941 static cairo_bool_t
1942 _gradient_pattern_supported (cairo_ps_surface_t    *surface,
1943                              const cairo_pattern_t *pattern)
1944 {
1945     double min_alpha, max_alpha;
1946
1947     if (surface->ps_level == CAIRO_PS_LEVEL_2)
1948         return FALSE;
1949
1950     /* Alpha gradients are only supported (by flattening the alpha)
1951      * if there is no variation in the alpha across the gradient. */
1952     _cairo_pattern_alpha_range (pattern, &min_alpha, &max_alpha);
1953     if (min_alpha != max_alpha)
1954         return FALSE;
1955
1956     surface->ps_level_used = CAIRO_PS_LEVEL_3;
1957
1958     return TRUE;
1959 }
1960
1961 static cairo_bool_t
1962 pattern_supported (cairo_ps_surface_t *surface, const cairo_pattern_t *pattern)
1963 {
1964     switch (pattern->type) {
1965     case CAIRO_PATTERN_TYPE_SOLID:
1966         return TRUE;
1967
1968     case CAIRO_PATTERN_TYPE_LINEAR:
1969     case CAIRO_PATTERN_TYPE_RADIAL:
1970     case CAIRO_PATTERN_TYPE_MESH:
1971         return _gradient_pattern_supported (surface, pattern);
1972
1973     case CAIRO_PATTERN_TYPE_SURFACE:
1974         return surface_pattern_supported ((cairo_surface_pattern_t *) pattern);
1975
1976     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
1977         return TRUE;
1978
1979     default:
1980         ASSERT_NOT_REACHED;
1981         return FALSE;
1982     }
1983 }
1984
1985 static cairo_bool_t
1986 mask_supported (cairo_ps_surface_t *surface,
1987                 const cairo_pattern_t *mask,
1988                 const cairo_rectangle_int_t *extents)
1989 {
1990     if (surface->ps_level == CAIRO_PS_LEVEL_2)
1991         return FALSE;
1992
1993     if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
1994         cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
1995         if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
1996             /* check if mask if opaque or bilevel alpha */
1997             if (_cairo_ps_surface_analyze_surface_pattern_transparency (surface, mask, extents) == CAIRO_INT_STATUS_SUCCESS) {
1998                 surface->ps_level_used = CAIRO_PS_LEVEL_3;
1999                 return TRUE;
2000             }
2001         }
2002     }
2003
2004     return FALSE;
2005 }
2006
2007 static cairo_int_status_t
2008 _cairo_ps_surface_analyze_operation (cairo_ps_surface_t    *surface,
2009                                      cairo_operator_t       op,
2010                                      const cairo_pattern_t       *pattern,
2011                                      const cairo_pattern_t       *mask,
2012                                      const cairo_rectangle_int_t *extents)
2013 {
2014     double min_alpha;
2015
2016     if (surface->force_fallbacks &&
2017         surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
2018     {
2019         return CAIRO_INT_STATUS_UNSUPPORTED;
2020     }
2021
2022     if (! pattern_supported (surface, pattern))
2023         return CAIRO_INT_STATUS_UNSUPPORTED;
2024
2025     if (! (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_OVER))
2026         return CAIRO_INT_STATUS_UNSUPPORTED;
2027
2028     /* Mask is only supported when the mask is an image with opaque or bilevel alpha. */
2029     if (mask && !mask_supported (surface, mask, extents))
2030         return CAIRO_INT_STATUS_UNSUPPORTED;
2031
2032     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
2033         cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) pattern;
2034
2035         if (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
2036             if (pattern->extend == CAIRO_EXTEND_PAD) {
2037                 cairo_box_t box;
2038                 cairo_rectangle_int_t rect;
2039                 cairo_rectangle_int_t rec_extents;
2040
2041                 /* get the operation extents in pattern space */
2042                 _cairo_box_from_rectangle (&box, extents);
2043                 _cairo_matrix_transform_bounding_box_fixed (&pattern->matrix, &box, NULL);
2044                 _cairo_box_round_to_rectangle (&box, &rect);
2045
2046                 /* Check if surface needs padding to fill extents */
2047                 if (_cairo_surface_get_extents (surface_pattern->surface, &rec_extents)) {
2048                     if (_cairo_fixed_integer_ceil(box.p1.x) < rec_extents.x ||
2049                         _cairo_fixed_integer_ceil(box.p1.y) < rec_extents.y ||
2050                         _cairo_fixed_integer_floor(box.p2.y) > rec_extents.x + rec_extents.width ||
2051                         _cairo_fixed_integer_floor(box.p2.y) > rec_extents.y + rec_extents.height)
2052                     {
2053                         return CAIRO_INT_STATUS_UNSUPPORTED;
2054                     }
2055                 }
2056             }
2057             return CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN;
2058         }
2059     }
2060
2061     if (op == CAIRO_OPERATOR_SOURCE) {
2062         if (mask)
2063             return CAIRO_INT_STATUS_UNSUPPORTED;
2064         else
2065             return CAIRO_STATUS_SUCCESS;
2066     }
2067
2068     /* CAIRO_OPERATOR_OVER is only supported for opaque patterns. If
2069      * the pattern contains transparency, we return
2070      * CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY to the analysis
2071      * surface. If the analysis surface determines that there is
2072      * anything drawn under this operation, a fallback image will be
2073      * used. Otherwise the operation will be replayed during the
2074      * render stage and we blend the transparency into the white
2075      * background to convert the pattern to opaque.
2076      */
2077     if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE || pattern->type == CAIRO_PATTERN_TYPE_RASTER_SOURCE)
2078         return _cairo_ps_surface_analyze_surface_pattern_transparency (surface, pattern, extents);
2079
2080     /* Patterns whose drawn part is opaque are directly supported;
2081        those whose drawn part is partially transparent can be
2082        supported by flattening the alpha. */
2083     _cairo_pattern_alpha_range (pattern, &min_alpha, NULL);
2084     if (CAIRO_ALPHA_IS_OPAQUE (min_alpha))
2085         return CAIRO_STATUS_SUCCESS;
2086
2087     return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
2088 }
2089
2090 static cairo_bool_t
2091 _cairo_ps_surface_operation_supported (cairo_ps_surface_t    *surface,
2092                                        cairo_operator_t       op,
2093                                        const cairo_pattern_t       *pattern,
2094                                        const cairo_pattern_t       *mask,
2095                                        const cairo_rectangle_int_t *extents)
2096 {
2097     return _cairo_ps_surface_analyze_operation (surface, op, pattern, mask, extents) != CAIRO_INT_STATUS_UNSUPPORTED;
2098 }
2099
2100 /* The "standard" implementation limit for PostScript string sizes is
2101  * 65535 characters (see PostScript Language Reference, Appendix
2102  * B). We go one short of that because we sometimes need two
2103  * characters in a string to represent a single ASCII85 byte, (for the
2104  * escape sequences "\\", "\(", and "\)") and we must not split these
2105  * across two strings. So we'd be in trouble if we went right to the
2106  * limit and one of these escape sequences just happened to land at
2107  * the end.
2108  */
2109 #define STRING_ARRAY_MAX_STRING_SIZE (65535-1)
2110 #define STRING_ARRAY_MAX_COLUMN      72
2111
2112 typedef struct _string_array_stream {
2113     cairo_output_stream_t base;
2114     cairo_output_stream_t *output;
2115     int column;
2116     int string_size;
2117     cairo_bool_t use_strings;
2118 } string_array_stream_t;
2119
2120 static cairo_status_t
2121 _string_array_stream_write (cairo_output_stream_t *base,
2122                             const unsigned char   *data,
2123                             unsigned int           length)
2124 {
2125     string_array_stream_t *stream = (string_array_stream_t *) base;
2126     unsigned char c;
2127     const unsigned char backslash = '\\';
2128
2129     if (length == 0)
2130         return CAIRO_STATUS_SUCCESS;
2131
2132     while (length--) {
2133         if (stream->string_size == 0 && stream->use_strings) {
2134             _cairo_output_stream_printf (stream->output, "(");
2135             stream->column++;
2136         }
2137
2138         c = *data++;
2139         if (stream->use_strings) {
2140             switch (c) {
2141             case '\\':
2142             case '(':
2143             case ')':
2144                 _cairo_output_stream_write (stream->output, &backslash, 1);
2145                 stream->column++;
2146                 stream->string_size++;
2147                 break;
2148             }
2149         }
2150         /* Have to be careful to never split the final ~> sequence. */
2151         if (c == '~') {
2152             _cairo_output_stream_write (stream->output, &c, 1);
2153             stream->column++;
2154             stream->string_size++;
2155
2156             if (length-- == 0)
2157                 break;
2158
2159             c = *data++;
2160         }
2161         _cairo_output_stream_write (stream->output, &c, 1);
2162         stream->column++;
2163         stream->string_size++;
2164
2165         if (stream->use_strings &&
2166             stream->string_size >= STRING_ARRAY_MAX_STRING_SIZE)
2167         {
2168             _cairo_output_stream_printf (stream->output, ")\n");
2169             stream->string_size = 0;
2170             stream->column = 0;
2171         }
2172         if (stream->column >= STRING_ARRAY_MAX_COLUMN) {
2173             _cairo_output_stream_printf (stream->output, "\n ");
2174             stream->string_size += 2;
2175             stream->column = 1;
2176         }
2177     }
2178
2179     return _cairo_output_stream_get_status (stream->output);
2180 }
2181
2182 static cairo_status_t
2183 _string_array_stream_close (cairo_output_stream_t *base)
2184 {
2185     cairo_status_t status;
2186     string_array_stream_t *stream = (string_array_stream_t *) base;
2187
2188     if (stream->use_strings)
2189         _cairo_output_stream_printf (stream->output, ")\n");
2190
2191     status = _cairo_output_stream_get_status (stream->output);
2192
2193     return status;
2194 }
2195
2196 /* A string_array_stream wraps an existing output stream. It takes the
2197  * data provided to it and output one or more consecutive string
2198  * objects, each within the standard PostScript implementation limit
2199  * of 65k characters.
2200  *
2201  * The strings are each separated by a space character for easy
2202  * inclusion within an array object, (but the array delimiters are not
2203  * added by the string_array_stream).
2204  *
2205  * The string array stream is also careful to wrap the output within
2206  * STRING_ARRAY_MAX_COLUMN columns (+/- 1). The stream also adds
2207  * necessary escaping for special characters within a string,
2208  * (specifically '\', '(', and ')').
2209  */
2210 static cairo_output_stream_t *
2211 _string_array_stream_create (cairo_output_stream_t *output)
2212 {
2213     string_array_stream_t *stream;
2214
2215     stream = malloc (sizeof (string_array_stream_t));
2216     if (unlikely (stream == NULL)) {
2217         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2218         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
2219     }
2220
2221     _cairo_output_stream_init (&stream->base,
2222                                _string_array_stream_write,
2223                                NULL,
2224                                _string_array_stream_close);
2225     stream->output = output;
2226     stream->column = 0;
2227     stream->string_size = 0;
2228     stream->use_strings = TRUE;
2229
2230     return &stream->base;
2231 }
2232
2233 /* A base85_array_stream wraps an existing output stream. It wraps the
2234  * output within STRING_ARRAY_MAX_COLUMN columns (+/- 1). The output
2235  * is not enclosed in strings like string_array_stream.
2236  */
2237 static cairo_output_stream_t *
2238 _base85_array_stream_create (cairo_output_stream_t *output)
2239 {
2240     string_array_stream_t *stream;
2241
2242     stream = malloc (sizeof (string_array_stream_t));
2243     if (unlikely (stream == NULL)) {
2244         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2245         return (cairo_output_stream_t *) &_cairo_output_stream_nil;
2246     }
2247
2248     _cairo_output_stream_init (&stream->base,
2249                                _string_array_stream_write,
2250                                NULL,
2251                                _string_array_stream_close);
2252     stream->output = output;
2253     stream->column = 0;
2254     stream->string_size = 0;
2255     stream->use_strings = FALSE;
2256
2257     return &stream->base;
2258 }
2259
2260
2261 /* PS Output - this section handles output of the parts of the recording
2262  * surface we can render natively in PS. */
2263
2264 static cairo_status_t
2265 _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t    *surface,
2266                                               cairo_image_surface_t *image,
2267                                               cairo_image_surface_t **opaque_image)
2268 {
2269     cairo_surface_t *opaque;
2270     cairo_surface_pattern_t pattern;
2271     cairo_status_t status;
2272
2273     opaque = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
2274                                          image->width,
2275                                          image->height);
2276     if (unlikely (opaque->status))
2277         return opaque->status;
2278
2279     if (surface->content == CAIRO_CONTENT_COLOR_ALPHA) {
2280         status = _cairo_surface_paint (opaque,
2281                                        CAIRO_OPERATOR_SOURCE,
2282                                        &_cairo_pattern_white.base,
2283                                        NULL);
2284         if (unlikely (status)) {
2285             cairo_surface_destroy (opaque);
2286             return status;
2287         }
2288     }
2289
2290     _cairo_pattern_init_for_surface (&pattern, &image->base);
2291     pattern.base.filter = CAIRO_FILTER_NEAREST;
2292     status = _cairo_surface_paint (opaque, CAIRO_OPERATOR_OVER, &pattern.base, NULL);
2293     _cairo_pattern_fini (&pattern.base);
2294     if (unlikely (status)) {
2295         cairo_surface_destroy (opaque);
2296         return status;
2297     }
2298
2299     *opaque_image = (cairo_image_surface_t *) opaque;
2300     return CAIRO_STATUS_SUCCESS;
2301 }
2302
2303 static cairo_status_t
2304 _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t    *surface,
2305                                       const unsigned char   *data,
2306                                       unsigned long          length,
2307                                       cairo_ps_compress_t    compress,
2308                                       cairo_bool_t           use_strings)
2309 {
2310     cairo_output_stream_t *base85_stream, *string_array_stream, *deflate_stream;
2311     unsigned char *data_compressed;
2312     unsigned long data_compressed_size;
2313     cairo_status_t status, status2;
2314
2315     if (use_strings)
2316         string_array_stream = _string_array_stream_create (surface->stream);
2317     else
2318         string_array_stream = _base85_array_stream_create (surface->stream);
2319
2320     status = _cairo_output_stream_get_status (string_array_stream);
2321     if (unlikely (status))
2322         return _cairo_output_stream_destroy (string_array_stream);
2323
2324     base85_stream = _cairo_base85_stream_create (string_array_stream);
2325     status = _cairo_output_stream_get_status (base85_stream);
2326     if (unlikely (status)) {
2327         status2 = _cairo_output_stream_destroy (string_array_stream);
2328         return _cairo_output_stream_destroy (base85_stream);
2329     }
2330
2331     switch (compress) {
2332         case CAIRO_PS_COMPRESS_NONE:
2333             _cairo_output_stream_write (base85_stream, data, length);
2334             break;
2335
2336         case CAIRO_PS_COMPRESS_LZW:
2337             /* XXX: Should fix cairo-lzw to provide a stream-based interface
2338              * instead. */
2339             data_compressed_size = length;
2340             data_compressed = _cairo_lzw_compress ((unsigned char*)data, &data_compressed_size);
2341             if (unlikely (data_compressed == NULL)) {
2342                 status = _cairo_output_stream_destroy (string_array_stream);
2343                 status = _cairo_output_stream_destroy (base85_stream);
2344                 return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2345             }
2346             _cairo_output_stream_write (base85_stream, data_compressed, data_compressed_size);
2347             free (data_compressed);
2348             break;
2349
2350         case CAIRO_PS_COMPRESS_DEFLATE:
2351             deflate_stream = _cairo_deflate_stream_create (base85_stream);
2352             if (_cairo_output_stream_get_status (deflate_stream)) {
2353                 return _cairo_output_stream_destroy (deflate_stream);
2354             }
2355             _cairo_output_stream_write (deflate_stream, data, length);
2356             status = _cairo_output_stream_destroy (deflate_stream);
2357             if (unlikely (status)) {
2358                 status2 = _cairo_output_stream_destroy (string_array_stream);
2359                 status2 = _cairo_output_stream_destroy (base85_stream);
2360                 return _cairo_output_stream_destroy (deflate_stream);
2361             }
2362             break;
2363     }
2364     status = _cairo_output_stream_destroy (base85_stream);
2365
2366     /* Mark end of base85 data */
2367     _cairo_output_stream_printf (string_array_stream, "~>");
2368     status2 = _cairo_output_stream_destroy (string_array_stream);
2369     if (status == CAIRO_STATUS_SUCCESS)
2370         status = status2;
2371
2372     return status;
2373 }
2374
2375 static cairo_status_t
2376 _cairo_ps_surface_emit_image (cairo_ps_surface_t    *surface,
2377                               cairo_image_surface_t *image_surf,
2378                               cairo_operator_t       op,
2379                               cairo_filter_t         filter,
2380                               cairo_bool_t           stencil_mask)
2381 {
2382     cairo_status_t status;
2383     unsigned char *data;
2384     unsigned long data_size;
2385     cairo_image_surface_t *ps_image;
2386     int x, y, i, a;
2387     cairo_image_transparency_t transparency;
2388     cairo_bool_t use_mask;
2389     uint32_t *pixel32;
2390     uint8_t *pixel8;
2391     int bit;
2392     cairo_image_color_t color;
2393     const char *interpolate;
2394     cairo_ps_compress_t compress;
2395     const char *compress_filter;
2396     cairo_image_surface_t *image;
2397
2398     if (image_surf->base.status)
2399         return image_surf->base.status;
2400
2401     image  = image_surf;
2402     if (image->format != CAIRO_FORMAT_RGB24 &&
2403         image->format != CAIRO_FORMAT_ARGB32 &&
2404         image->format != CAIRO_FORMAT_A8 &&
2405         image->format != CAIRO_FORMAT_A1)
2406     {
2407         cairo_surface_t *surf;
2408         cairo_surface_pattern_t pattern;
2409
2410         surf = _cairo_image_surface_create_with_content (image_surf->base.content,
2411                                                          image_surf->width,
2412                                                          image_surf->height);
2413         image = (cairo_image_surface_t *) surf;
2414         if (surf->status) {
2415             status = surf->status;
2416             goto bail0;
2417         }
2418
2419         _cairo_pattern_init_for_surface (&pattern, &image_surf->base);
2420         status = _cairo_surface_paint (surf,
2421                                        CAIRO_OPERATOR_SOURCE, &pattern.base,
2422                                        NULL);
2423         _cairo_pattern_fini (&pattern.base);
2424         if (unlikely (status))
2425             goto bail0;
2426     }
2427     ps_image = image;
2428
2429     switch (filter) {
2430     default:
2431     case CAIRO_FILTER_GOOD:
2432     case CAIRO_FILTER_BEST:
2433     case CAIRO_FILTER_BILINEAR:
2434         interpolate = "true";
2435         break;
2436     case CAIRO_FILTER_FAST:
2437     case CAIRO_FILTER_NEAREST:
2438     case CAIRO_FILTER_GAUSSIAN:
2439         interpolate = "false";
2440         break;
2441     }
2442
2443     if (stencil_mask) {
2444         use_mask = FALSE;
2445         color = CAIRO_IMAGE_IS_MONOCHROME;
2446         transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA;
2447     } else {
2448         transparency = _cairo_image_analyze_transparency (image);
2449
2450         /* PostScript can not represent the alpha channel, so we blend the
2451            current image over a white (or black for CONTENT_COLOR
2452            surfaces) RGB surface to eliminate it. */
2453
2454         if (op == CAIRO_OPERATOR_SOURCE ||
2455             transparency == CAIRO_IMAGE_HAS_ALPHA ||
2456             (transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA &&
2457              surface->ps_level == CAIRO_PS_LEVEL_2))
2458         {
2459             status = _cairo_ps_surface_flatten_image_transparency (surface,
2460                                                                    image,
2461                                                                    &ps_image);
2462             if (unlikely (status))
2463                 return status;
2464
2465             use_mask = FALSE;
2466         } else if (transparency == CAIRO_IMAGE_IS_OPAQUE) {
2467             use_mask = FALSE;
2468         } else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA */
2469             use_mask = TRUE;
2470         }
2471
2472         color = _cairo_image_analyze_color (ps_image);
2473     }
2474
2475     /* Type 2 (mask and image interleaved) has the mask and image
2476      * samples interleaved by row.  The mask row is first, one bit per
2477      * pixel with (bit 7 first). The row is padded to byte
2478      * boundaries. The image data is 3 bytes per pixel RGB format. */
2479     switch (color) {
2480     default:
2481     case CAIRO_IMAGE_UNKNOWN_COLOR:
2482         ASSERT_NOT_REACHED;
2483     case CAIRO_IMAGE_IS_COLOR:
2484         data_size = ps_image->width * 3;
2485         break;
2486     case CAIRO_IMAGE_IS_GRAYSCALE:
2487         data_size = ps_image->width;
2488         break;
2489     case CAIRO_IMAGE_IS_MONOCHROME:
2490         data_size = (ps_image->width + 7)/8;
2491         break;
2492     }
2493     if (use_mask)
2494         data_size += (ps_image->width + 7)/8;
2495     data_size *= ps_image->height;
2496     data = malloc (data_size);
2497     if (unlikely (data == NULL)) {
2498         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2499         goto bail1;
2500     }
2501
2502     i = 0;
2503     for (y = 0; y < ps_image->height; y++) {
2504         if (stencil_mask || use_mask) {
2505             /* mask row */
2506             if (ps_image->format == CAIRO_FORMAT_A1) {
2507                 pixel8 = (uint8_t *) (ps_image->data + y * ps_image->stride);
2508
2509                 for (x = 0; x < (ps_image->width + 7) / 8; x++, pixel8++) {
2510                     a = *pixel8;
2511                     a = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (a);
2512                     data[i++] = a;
2513                 }
2514             } else {
2515                 pixel8 = (uint8_t *) (ps_image->data + y * ps_image->stride);
2516                 pixel32 = (uint32_t *) (ps_image->data + y * ps_image->stride);
2517                 bit = 7;
2518                 for (x = 0; x < ps_image->width; x++) {
2519                     if (ps_image->format == CAIRO_FORMAT_ARGB32) {
2520                         a = (*pixel32 & 0xff000000) >> 24;
2521                         pixel32++;
2522                     } else {
2523                         a = *pixel8;
2524                         pixel8++;
2525                     }
2526
2527                     if (transparency == CAIRO_IMAGE_HAS_ALPHA) {
2528                         data[i++] = a;
2529                     } else { /* transparency == CAIRO_IMAGE_HAS_BILEVEL_ALPHA or CAIRO_IMAGE_IS_OPAQUE */
2530                         if (bit == 7)
2531                             data[i] = 0;
2532                         if (a != 0)
2533                             data[i] |= (1 << bit);
2534                         bit--;
2535                         if (bit < 0) {
2536                             bit = 7;
2537                             i++;
2538                         }
2539                     }
2540                 }
2541                 if (bit != 7)
2542                     i++;
2543             }
2544         }
2545         if (stencil_mask)
2546             continue;
2547
2548         /* image row*/
2549         pixel32 = (uint32_t *) (ps_image->data + y * ps_image->stride);
2550         bit = 7;
2551         for (x = 0; x < ps_image->width; x++, pixel32++) {
2552             int r, g, b;
2553
2554             if (ps_image->format == CAIRO_FORMAT_ARGB32) {
2555                 /* At this point ARGB32 images are either opaque or
2556                  * bilevel alpha so we don't need to unpremultiply. */
2557                 if (((*pixel32 & 0xff000000) >> 24) == 0) {
2558                     r = g = b = 0;
2559                 } else {
2560                     r = (*pixel32 & 0x00ff0000) >> 16;
2561                     g = (*pixel32 & 0x0000ff00) >>  8;
2562                     b = (*pixel32 & 0x000000ff) >>  0;
2563                 }
2564             } else if (ps_image->format == CAIRO_FORMAT_RGB24) {
2565                 r = (*pixel32 & 0x00ff0000) >> 16;
2566                 g = (*pixel32 & 0x0000ff00) >>  8;
2567                 b = (*pixel32 & 0x000000ff) >>  0;
2568             } else {
2569                 r = g = b = 0;
2570             }
2571
2572             switch (color) {
2573                 case CAIRO_IMAGE_IS_COLOR:
2574                 case CAIRO_IMAGE_UNKNOWN_COLOR:
2575                     data[i++] = r;
2576                     data[i++] = g;
2577                     data[i++] = b;
2578                     break;
2579
2580                 case CAIRO_IMAGE_IS_GRAYSCALE:
2581                     data[i++] = r;
2582                     break;
2583
2584                 case CAIRO_IMAGE_IS_MONOCHROME:
2585                     if (bit == 7)
2586                         data[i] = 0;
2587                     if (r != 0)
2588                         data[i] |= (1 << bit);
2589                     bit--;
2590                     if (bit < 0) {
2591                         bit = 7;
2592                         i++;
2593                     }
2594                     break;
2595             }
2596         }
2597         if (bit != 7)
2598             i++;
2599     }
2600
2601     if (surface->ps_level == CAIRO_PS_LEVEL_2) {
2602         compress = CAIRO_PS_COMPRESS_LZW;
2603         compress_filter = "LZWDecode";
2604     } else {
2605         compress = CAIRO_PS_COMPRESS_DEFLATE;
2606         compress_filter = "FlateDecode";
2607         surface->ps_level_used = CAIRO_PS_LEVEL_3;
2608     }
2609
2610     if (surface->use_string_datasource) {
2611         /* Emit the image data as a base85-encoded string which will
2612          * be used as the data source for the image operator later. */
2613         _cairo_output_stream_printf (surface->stream,
2614                                      "/CairoImageData [\n");
2615
2616         status = _cairo_ps_surface_emit_base85_string (surface,
2617                                                        data,
2618                                                        data_size,
2619                                                        compress,
2620                                                        TRUE);
2621         if (unlikely (status))
2622             goto bail2;
2623
2624         _cairo_output_stream_printf (surface->stream,
2625                                      "] def\n");
2626         _cairo_output_stream_printf (surface->stream,
2627                                      "/CairoImageDataIndex 0 def\n");
2628     }
2629
2630     if (use_mask) {
2631         _cairo_output_stream_printf (surface->stream,
2632                                      "%s setcolorspace\n"
2633                                      "5 dict dup begin\n"
2634                                      "  /ImageType 3 def\n"
2635                                      "  /InterleaveType 2 def\n"
2636                                      "  /DataDict 8 dict def\n"
2637                                      "    DataDict begin\n"
2638                                      "    /ImageType 1 def\n"
2639                                      "    /Width %d def\n"
2640                                      "    /Height %d def\n"
2641                                      "    /Interpolate %s def\n"
2642                                      "    /BitsPerComponent %d def\n"
2643                                      "    /Decode [ %s ] def\n",
2644                                      color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray",
2645                                      ps_image->width,
2646                                      ps_image->height,
2647                                      interpolate,
2648                                      color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8,
2649                                      color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1");
2650
2651         if (surface->use_string_datasource) {
2652             _cairo_output_stream_printf (surface->stream,
2653                                          "    /DataSource {\n"
2654                                          "      CairoImageData CairoImageDataIndex get\n"
2655                                          "      /CairoImageDataIndex CairoImageDataIndex 1 add def\n"
2656                                          "      CairoImageDataIndex CairoImageData length 1 sub gt\n"
2657                                          "       { /CairoImageDataIndex 0 def } if\n"
2658                                          "    } /ASCII85Decode filter /%s filter def\n",
2659                                          compress_filter);
2660         } else {
2661             _cairo_output_stream_printf (surface->stream,
2662                                          "    /DataSource currentfile /ASCII85Decode filter /%s filter def\n",
2663                                          compress_filter);
2664         }
2665
2666         _cairo_output_stream_printf (surface->stream,
2667                                      "    /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
2668                                      "  end\n"
2669                                      "  /MaskDict 8 dict def\n"
2670                                      "     MaskDict begin\n"
2671                                      "    /ImageType 1 def\n"
2672                                      "    /Width %d def\n"
2673                                      "    /Height %d def\n"
2674                                      "    /Interpolate %s def\n"
2675                                      "    /BitsPerComponent 1 def\n"
2676                                      "    /Decode [ 1 0 ] def\n"
2677                                      "    /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
2678                                      "  end\n"
2679                                      "end\n"
2680                                      "image\n",
2681                                      ps_image->height,
2682                                      ps_image->width,
2683                                      ps_image->height,
2684                                      interpolate,
2685                                      ps_image->height);
2686     } else {
2687         if (!stencil_mask) {
2688             _cairo_output_stream_printf (surface->stream,
2689                                          "%s setcolorspace\n",
2690                                          color == CAIRO_IMAGE_IS_COLOR ? "/DeviceRGB" : "/DeviceGray");
2691         }
2692         _cairo_output_stream_printf (surface->stream,
2693                                      "8 dict dup begin\n"
2694                                      "  /ImageType 1 def\n"
2695                                      "  /Width %d def\n"
2696                                      "  /Height %d def\n"
2697                                      "  /Interpolate %s def\n"
2698                                      "  /BitsPerComponent %d def\n"
2699                                      "  /Decode [ %s ] def\n",
2700                                      ps_image->width,
2701                                      ps_image->height,
2702                                      interpolate,
2703                                      color == CAIRO_IMAGE_IS_MONOCHROME ? 1 : 8,
2704                                      stencil_mask ? "1 0" : color == CAIRO_IMAGE_IS_COLOR ? "0 1 0 1 0 1" : "0 1");
2705         if (surface->use_string_datasource) {
2706             _cairo_output_stream_printf (surface->stream,
2707                                          "  /DataSource {\n"
2708                                          "    CairoImageData CairoImageDataIndex get\n"
2709                                          "    /CairoImageDataIndex CairoImageDataIndex 1 add def\n"
2710                                          "    CairoImageDataIndex CairoImageData length 1 sub gt\n"
2711                                          "     { /CairoImageDataIndex 0 def } if\n"
2712                                          "  } /ASCII85Decode filter /%s filter def\n",
2713                                          compress_filter);
2714         } else {
2715             _cairo_output_stream_printf (surface->stream,
2716                                          "  /DataSource currentfile /ASCII85Decode filter /%s filter def\n",
2717                                          compress_filter);
2718         }
2719
2720         _cairo_output_stream_printf (surface->stream,
2721                                      "  /Interpolate %s def\n"
2722                                      "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
2723                                      "end\n"
2724                                      "%s\n",
2725                                      interpolate,
2726                                      ps_image->height,
2727                                      stencil_mask ? "imagemask" : "image");
2728     }
2729
2730     if (!surface->use_string_datasource) {
2731         /* Emit the image data as a base85-encoded string which will
2732          * be used as the data source for the image operator. */
2733         status = _cairo_ps_surface_emit_base85_string (surface,
2734                                                        data,
2735                                                        data_size,
2736                                                        compress,
2737                                                        FALSE);
2738         _cairo_output_stream_printf (surface->stream, "\n");
2739     } else {
2740         status = CAIRO_STATUS_SUCCESS;
2741     }
2742
2743 bail2:
2744     free (data);
2745
2746 bail1:
2747     if (!use_mask && ps_image != image)
2748         cairo_surface_destroy (&ps_image->base);
2749
2750 bail0:
2751     if (image != image_surf)
2752         cairo_surface_destroy (&image->base);
2753
2754     return status;
2755 }
2756
2757 static cairo_status_t
2758 _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t    *surface,
2759                                    cairo_surface_t       *source,
2760                                    int                    width,
2761                                    int                    height)
2762 {
2763     cairo_status_t status;
2764     const unsigned char *mime_data;
2765     unsigned long mime_data_length;
2766     cairo_image_info_t info;
2767     const char *colorspace;
2768     const char *decode;
2769
2770     cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
2771                                  &mime_data, &mime_data_length);
2772     if (unlikely (source->status))
2773         return source->status;
2774     if (mime_data == NULL)
2775         return CAIRO_INT_STATUS_UNSUPPORTED;
2776
2777     status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length);
2778     if (unlikely (status))
2779         return status;
2780
2781     switch (info.num_components) {
2782         case 1:
2783             colorspace = "/DeviceGray";
2784             decode = "0 1";
2785             break;
2786         case 3:
2787             colorspace = "/DeviceRGB";
2788             decode =  "0 1 0 1 0 1";
2789             break;
2790         case 4:
2791             colorspace = "/DeviceCMYK";
2792             decode =  "0 1 0 1 0 1 0 1";
2793             break;
2794         default:
2795             return CAIRO_INT_STATUS_UNSUPPORTED;
2796     }
2797
2798     if (surface->use_string_datasource) {
2799         /* Emit the image data as a base85-encoded string which will
2800          * be used as the data source for the image operator later. */
2801         _cairo_output_stream_printf (surface->stream,
2802                                      "/CairoImageData [\n");
2803
2804         status = _cairo_ps_surface_emit_base85_string (surface,
2805                                                        mime_data,
2806                                                        mime_data_length,
2807                                                        CAIRO_PS_COMPRESS_NONE,
2808                                                        TRUE);
2809         if (unlikely (status))
2810             return status;
2811
2812         _cairo_output_stream_printf (surface->stream,
2813                                      "] def\n");
2814         _cairo_output_stream_printf (surface->stream,
2815                                      "/CairoImageDataIndex 0 def\n");
2816     }
2817
2818     _cairo_output_stream_printf (surface->stream,
2819                                  "%s setcolorspace\n"
2820                                  "8 dict dup begin\n"
2821                                  "  /ImageType 1 def\n"
2822                                  "  /Width %d def\n"
2823                                  "  /Height %d def\n"
2824                                  "  /BitsPerComponent %d def\n"
2825                                  "  /Decode [ %s ] def\n",
2826                                  colorspace,
2827                                  info.width,
2828                                  info.height,
2829                                  info.bits_per_component,
2830                                  decode);
2831
2832     if (surface->use_string_datasource) {
2833         _cairo_output_stream_printf (surface->stream,
2834                                      "  /DataSource {\n"
2835                                      "    CairoImageData CairoImageDataIndex get\n"
2836                                      "    /CairoImageDataIndex CairoImageDataIndex 1 add def\n"
2837                                      "    CairoImageDataIndex CairoImageData length 1 sub gt\n"
2838                                      "     { /CairoImageDataIndex 0 def } if\n"
2839                                      "  } /ASCII85Decode filter /DCTDecode filter def\n");
2840     } else {
2841         _cairo_output_stream_printf (surface->stream,
2842                                      "  /DataSource currentfile /ASCII85Decode filter /DCTDecode filter def\n");
2843     }
2844
2845     _cairo_output_stream_printf (surface->stream,
2846                                  "  /ImageMatrix [ 1 0 0 -1 0 %d ] def\n"
2847                                  "end\n"
2848                                  "image\n",
2849                                  info.height);
2850
2851     if (!surface->use_string_datasource) {
2852         /* Emit the image data as a base85-encoded string which will
2853          * be used as the data source for the image operator. */
2854         status = _cairo_ps_surface_emit_base85_string (surface,
2855                                                        mime_data,
2856                                                        mime_data_length,
2857                                                        CAIRO_PS_COMPRESS_NONE,
2858                                                        FALSE);
2859     }
2860
2861     return status;
2862 }
2863
2864 static cairo_status_t
2865 _cairo_ps_surface_emit_recording_surface (cairo_ps_surface_t *surface,
2866                                           cairo_surface_t    *recording_surface)
2867 {
2868     double old_width, old_height;
2869     cairo_matrix_t old_cairo_to_ps;
2870     cairo_content_t old_content;
2871     cairo_rectangle_int_t old_page_bbox;
2872     cairo_surface_t *free_me = NULL;
2873     cairo_surface_clipper_t old_clipper;
2874     cairo_box_t bbox;
2875     cairo_int_status_t status;
2876
2877     old_content = surface->content;
2878     old_width = surface->width;
2879     old_height = surface->height;
2880     old_page_bbox = surface->page_bbox;
2881     old_cairo_to_ps = surface->cairo_to_ps;
2882     old_clipper = surface->clipper;
2883     _cairo_surface_clipper_init (&surface->clipper,
2884                                  _cairo_ps_surface_clipper_intersect_clip_path);
2885
2886     if (_cairo_surface_is_snapshot (recording_surface))
2887         free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
2888
2889     status =
2890         _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
2891                                            &bbox,
2892                                            NULL);
2893     if (unlikely (status))
2894         goto err;
2895
2896 #if DEBUG_PS
2897     _cairo_output_stream_printf (surface->stream,
2898                                  "%% _cairo_ps_surface_emit_recording_surface (%f, %f), (%f, %f)\n",
2899                                  _cairo_fixed_to_double (bbox.p1.x),
2900                                  _cairo_fixed_to_double (bbox.p1.y),
2901                                  _cairo_fixed_to_double (bbox.p2.x),
2902                                  _cairo_fixed_to_double (bbox.p2.y));
2903 #endif
2904
2905     surface->width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x);
2906     surface->height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
2907     _cairo_box_round_to_rectangle (&bbox, &surface->page_bbox);
2908
2909     surface->current_pattern_is_solid_color = FALSE;
2910     _cairo_pdf_operators_reset (&surface->pdf_operators);
2911     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
2912     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
2913                                                   &surface->cairo_to_ps);
2914     _cairo_output_stream_printf (surface->stream, "  q\n");
2915
2916     if (recording_surface->content == CAIRO_CONTENT_COLOR) {
2917         surface->content = CAIRO_CONTENT_COLOR;
2918         _cairo_output_stream_printf (surface->stream,
2919                                      "  0 g %d %d %d %d rectfill\n",
2920                                      surface->page_bbox.x,
2921                                      surface->page_bbox.y,
2922                                      surface->page_bbox.width,
2923                                      surface->page_bbox.height);
2924     }
2925
2926     status = _cairo_recording_surface_replay_region (recording_surface,
2927                                                      NULL,
2928                                                      &surface->base,
2929                                                      CAIRO_RECORDING_REGION_NATIVE);
2930     assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
2931     if (unlikely (status))
2932         goto err;
2933
2934     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
2935     if (unlikely (status))
2936         goto err;
2937
2938     _cairo_output_stream_printf (surface->stream, "  Q\n");
2939
2940     _cairo_surface_clipper_reset (&surface->clipper);
2941     surface->clipper = old_clipper;
2942     surface->content = old_content;
2943     surface->width = old_width;
2944     surface->height = old_height;
2945     surface->page_bbox = old_page_bbox;
2946     surface->current_pattern_is_solid_color = FALSE;
2947     _cairo_pdf_operators_reset (&surface->pdf_operators);
2948     surface->cairo_to_ps = old_cairo_to_ps;
2949
2950     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
2951                                                   &surface->cairo_to_ps);
2952
2953 err:
2954     cairo_surface_destroy (free_me);
2955     return status;
2956 }
2957
2958 static cairo_int_status_t
2959 _cairo_ps_surface_emit_recording_subsurface (cairo_ps_surface_t *surface,
2960                                              cairo_surface_t    *recording_surface,
2961                                              const cairo_rectangle_int_t *extents)
2962 {
2963     double old_width, old_height;
2964     cairo_matrix_t old_cairo_to_ps;
2965     cairo_content_t old_content;
2966     cairo_rectangle_int_t old_page_bbox;
2967     cairo_surface_clipper_t old_clipper;
2968     cairo_surface_t *free_me = NULL;
2969     cairo_int_status_t status;
2970
2971     old_content = surface->content;
2972     old_width = surface->width;
2973     old_height = surface->height;
2974     old_page_bbox = surface->page_bbox;
2975     old_cairo_to_ps = surface->cairo_to_ps;
2976     old_clipper = surface->clipper;
2977     _cairo_surface_clipper_init (&surface->clipper,
2978                                  _cairo_ps_surface_clipper_intersect_clip_path);
2979
2980 #if DEBUG_PS
2981     _cairo_output_stream_printf (surface->stream,
2982                                  "%% _cairo_ps_surface_emit_recording_subsurface (%d, %d), (%d, %d)\n",
2983                                  extents->x, extents->y,
2984                                  extents->width, extents->height);
2985 #endif
2986
2987     surface->page_bbox.x = surface->page_bbox.y = 0;
2988     surface->page_bbox.width = surface->width  = extents->width;
2989     surface->page_bbox.height = surface->height = extents->height;
2990
2991     surface->current_pattern_is_solid_color = FALSE;
2992     _cairo_pdf_operators_reset (&surface->pdf_operators);
2993     cairo_matrix_init (&surface->cairo_to_ps, 1, 0, 0, -1, 0, surface->height);
2994     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
2995                                                   &surface->cairo_to_ps);
2996     _cairo_output_stream_printf (surface->stream, "  q\n");
2997
2998     if (_cairo_surface_is_snapshot (recording_surface))
2999         free_me = recording_surface = _cairo_surface_snapshot_get_target (recording_surface);
3000
3001     if (recording_surface->content == CAIRO_CONTENT_COLOR) {
3002         surface->content = CAIRO_CONTENT_COLOR;
3003         _cairo_output_stream_printf (surface->stream,
3004                                      "  0 g %d %d %d %d rectfill\n",
3005                                      surface->page_bbox.x,
3006                                      surface->page_bbox.y,
3007                                      surface->page_bbox.width,
3008                                      surface->page_bbox.height);
3009     }
3010
3011     status = _cairo_recording_surface_replay_region (recording_surface,
3012                                                      extents,
3013                                                      &surface->base,
3014                                                      CAIRO_RECORDING_REGION_NATIVE);
3015     assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
3016     if (unlikely (status))
3017         goto err;
3018
3019     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
3020     if (unlikely (status))
3021         goto err;
3022
3023     _cairo_output_stream_printf (surface->stream, "  Q\n");
3024
3025     _cairo_surface_clipper_reset (&surface->clipper);
3026     surface->clipper = old_clipper;
3027     surface->content = old_content;
3028     surface->width = old_width;
3029     surface->height = old_height;
3030     surface->page_bbox = old_page_bbox;
3031     surface->current_pattern_is_solid_color = FALSE;
3032     _cairo_pdf_operators_reset (&surface->pdf_operators);
3033     surface->cairo_to_ps = old_cairo_to_ps;
3034
3035     _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators,
3036                                                   &surface->cairo_to_ps);
3037
3038 err:
3039     cairo_surface_destroy (free_me);
3040     return status;
3041 }
3042
3043 static void
3044 _cairo_ps_surface_flatten_transparency (cairo_ps_surface_t      *surface,
3045                                         const cairo_color_t     *color,
3046                                         double                  *red,
3047                                         double                  *green,
3048                                         double                  *blue)
3049 {
3050     *red   = color->red;
3051     *green = color->green;
3052     *blue  = color->blue;
3053
3054     if (! CAIRO_COLOR_IS_OPAQUE (color)) {
3055         *red   *= color->alpha;
3056         *green *= color->alpha;
3057         *blue  *= color->alpha;
3058         if (surface->content == CAIRO_CONTENT_COLOR_ALPHA) {
3059             double one_minus_alpha = 1. - color->alpha;
3060             *red   += one_minus_alpha;
3061             *green += one_minus_alpha;
3062             *blue  += one_minus_alpha;
3063         }
3064     }
3065 }
3066
3067 static void
3068 _cairo_ps_surface_emit_solid_pattern (cairo_ps_surface_t    *surface,
3069                                       cairo_solid_pattern_t *pattern)
3070 {
3071     double red, green, blue;
3072
3073     _cairo_ps_surface_flatten_transparency (surface, &pattern->color, &red, &green, &blue);
3074
3075     if (color_is_gray (red, green, blue))
3076         _cairo_output_stream_printf (surface->stream,
3077                                      "%f g\n",
3078                                      red);
3079     else
3080         _cairo_output_stream_printf (surface->stream,
3081                                      "%f %f %f rg\n",
3082                                      red, green, blue);
3083 }
3084
3085 static cairo_status_t
3086 _cairo_ps_surface_emit_surface (cairo_ps_surface_t      *surface,
3087                                 cairo_pattern_t         *source_pattern,
3088                                 cairo_surface_t         *source_surface,
3089                                 cairo_operator_t         op,
3090                                 int                      width,
3091                                 int                      height,
3092                                 cairo_bool_t             stencil_mask)
3093 {
3094     cairo_int_status_t status;
3095
3096     if (source_surface->type == CAIRO_SURFACE_TYPE_RECORDING) {
3097         if (source_surface->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
3098             cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source_surface;
3099             status = _cairo_ps_surface_emit_recording_subsurface (surface, sub->target, &sub->extents);
3100         } else {
3101             status = _cairo_ps_surface_emit_recording_surface (surface, source_surface);
3102         }
3103     } else {
3104         cairo_image_surface_t *image = (cairo_image_surface_t *) source_surface;
3105         if (source_pattern->extend != CAIRO_EXTEND_PAD) {
3106             status = _cairo_ps_surface_emit_jpeg_image (surface, source_surface,
3107                                                         width, height);
3108             if (status != CAIRO_INT_STATUS_UNSUPPORTED)
3109                 return status;
3110         }
3111
3112         status = _cairo_ps_surface_emit_image (surface, image,
3113                                                op, source_pattern->filter, stencil_mask);
3114     }
3115
3116     return status;
3117 }
3118
3119
3120 static void
3121 _path_fixed_init_rectangle (cairo_path_fixed_t *path,
3122                             cairo_rectangle_int_t *rect)
3123 {
3124     cairo_status_t status;
3125
3126     _cairo_path_fixed_init (path);
3127
3128     status = _cairo_path_fixed_move_to (path,
3129                                         _cairo_fixed_from_int (rect->x),
3130                                         _cairo_fixed_from_int (rect->y));
3131     assert (status == CAIRO_STATUS_SUCCESS);
3132     status = _cairo_path_fixed_rel_line_to (path,
3133                                             _cairo_fixed_from_int (rect->width),
3134                                             _cairo_fixed_from_int (0));
3135     assert (status == CAIRO_STATUS_SUCCESS);
3136     status = _cairo_path_fixed_rel_line_to (path,
3137                                             _cairo_fixed_from_int (0),
3138                                             _cairo_fixed_from_int (rect->height));
3139     assert (status == CAIRO_STATUS_SUCCESS);
3140     status = _cairo_path_fixed_rel_line_to (path,
3141                                             _cairo_fixed_from_int (-rect->width),
3142                                             _cairo_fixed_from_int (0));
3143     assert (status == CAIRO_STATUS_SUCCESS);
3144
3145     status = _cairo_path_fixed_close_path (path);
3146     assert (status == CAIRO_STATUS_SUCCESS);
3147 }
3148
3149 static cairo_status_t
3150 _cairo_ps_surface_paint_surface (cairo_ps_surface_t     *surface,
3151                                  cairo_pattern_t        *pattern,
3152                                  cairo_rectangle_int_t  *extents,
3153                                  cairo_operator_t        op,
3154                                  cairo_bool_t            stencil_mask)
3155 {
3156     cairo_status_t status;
3157     int width, height;
3158     cairo_matrix_t cairo_p2d, ps_p2d;
3159     cairo_path_fixed_t path;
3160     double x_offset, y_offset;
3161     cairo_surface_t *source;
3162     cairo_image_surface_t *image = NULL;
3163     void *image_extra;
3164
3165     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
3166     if (unlikely (status))
3167         return status;
3168
3169     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
3170                                                                     pattern,
3171                                                                     extents,
3172                                                                     &width, &height,
3173                                                                     &x_offset, &y_offset,
3174                                                                     &source,
3175                                                                     &image_extra);
3176     if (unlikely (status))
3177         return status;
3178
3179     if (pattern->extend == CAIRO_EXTEND_PAD &&
3180         pattern->type == CAIRO_PATTERN_TYPE_SURFACE &&
3181         ((cairo_surface_pattern_t *)pattern)->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
3182         cairo_image_surface_t *img;
3183
3184         img = (cairo_image_surface_t *) source;
3185         status = _cairo_ps_surface_create_padded_image_from_image (surface,
3186                                                                    img,
3187                                                                    &pattern->matrix,
3188                                                                    extents,
3189                                                                    &width, &height,
3190                                                                    &x_offset, &y_offset,
3191                                                                    &image);
3192         if (unlikely (status))
3193             goto release_source;
3194     }
3195
3196     _path_fixed_init_rectangle (&path, extents);
3197     status = _cairo_pdf_operators_clip (&surface->pdf_operators,
3198                                         &path,
3199                                         CAIRO_FILL_RULE_WINDING);
3200     _cairo_path_fixed_fini (&path);
3201     if (unlikely (status))
3202         goto release_source;
3203
3204     cairo_p2d = pattern->matrix;
3205
3206     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) {
3207         double x_scale = cairo_p2d.xx;
3208         double y_scale = cairo_p2d.yy;
3209
3210         _cairo_output_stream_printf (surface->stream,
3211                                      "%% Fallback Image: x=%f y=%f w=%d h=%d ",
3212                                      -cairo_p2d.x0/x_scale,
3213                                      -cairo_p2d.y0/y_scale,
3214                                      (int)(width/x_scale),
3215                                      (int)(height/y_scale));
3216         if (x_scale == y_scale) {
3217             _cairo_output_stream_printf (surface->stream,
3218                                          "res=%fppi ",
3219                                          x_scale*72);
3220         } else {
3221             _cairo_output_stream_printf (surface->stream,
3222                                          "res=%fx%fppi ",
3223                                          x_scale*72,
3224                                          y_scale*72);
3225         }
3226         _cairo_output_stream_printf (surface->stream,
3227                                      "size=%ld\n",
3228                                      (long)width*height*3);
3229     } else {
3230         if (op == CAIRO_OPERATOR_SOURCE) {
3231             _cairo_output_stream_printf (surface->stream,
3232                                          "%d g 0 0 %f %f rectfill\n",
3233                                          surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
3234                                          surface->width,
3235                                          surface->height);
3236         }
3237     }
3238
3239     status = cairo_matrix_invert (&cairo_p2d);
3240     /* cairo_pattern_set_matrix ensures the matrix is invertible */
3241     assert (status == CAIRO_STATUS_SUCCESS);
3242
3243     ps_p2d = surface->cairo_to_ps;
3244     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
3245     cairo_matrix_translate (&ps_p2d, x_offset, y_offset);
3246     cairo_matrix_translate (&ps_p2d, 0.0, height);
3247     cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
3248
3249     if (! _cairo_matrix_is_identity (&ps_p2d)) {
3250         _cairo_output_stream_printf (surface->stream,
3251                                      "[ %f %f %f %f %f %f ] concat\n",
3252                                      ps_p2d.xx, ps_p2d.yx,
3253                                      ps_p2d.xy, ps_p2d.yy,
3254                                      ps_p2d.x0, ps_p2d.y0);
3255     }
3256
3257     status = _cairo_ps_surface_emit_surface (surface,
3258                                              pattern,
3259                                              image ? &image->base : source,
3260                                              op,
3261                                              width, height,
3262                                              stencil_mask);
3263
3264   release_source:
3265     if (image)
3266         cairo_surface_destroy (&image->base);
3267
3268     _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
3269
3270     return status;
3271 }
3272
3273 static cairo_status_t
3274 _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t      *surface,
3275                                         cairo_pattern_t         *pattern,
3276                                         cairo_rectangle_int_t   *extents,
3277                                         cairo_operator_t         op)
3278 {
3279     cairo_status_t status;
3280     int pattern_width = 0; /* squelch bogus compiler warning */
3281     int pattern_height = 0; /* squelch bogus compiler warning */
3282     double xstep, ystep;
3283     cairo_matrix_t cairo_p2d, ps_p2d;
3284     cairo_bool_t old_use_string_datasource;
3285     double x_offset, y_offset;
3286     cairo_surface_t *source;
3287     cairo_image_surface_t *image = NULL;
3288     void *image_extra;
3289
3290     cairo_p2d = pattern->matrix;
3291     status = cairo_matrix_invert (&cairo_p2d);
3292     /* cairo_pattern_set_matrix ensures the matrix is invertible */
3293     assert (status == CAIRO_STATUS_SUCCESS);
3294
3295     status = _cairo_ps_surface_acquire_source_surface_from_pattern (surface,
3296                                                                     pattern,
3297                                                                     extents,
3298                                                                     &pattern_width, &pattern_height,
3299                                                                     &x_offset, &y_offset,
3300                                                                     &source,
3301                                                                     &image_extra);
3302     if (unlikely (status))
3303         return status;
3304
3305     if (pattern->extend == CAIRO_EXTEND_PAD) {
3306         cairo_image_surface_t *img;
3307
3308         assert (source->type == CAIRO_SURFACE_TYPE_IMAGE);
3309         img = (cairo_image_surface_t *) source;
3310         status = _cairo_ps_surface_create_padded_image_from_image (surface,
3311                                                                    img,
3312                                                                    &pattern->matrix,
3313                                                                    extents,
3314                                                                    &pattern_width, &pattern_height,
3315                                                                    &x_offset, &y_offset,
3316                                                                    &image);
3317         if (unlikely (status))
3318             goto release_source;
3319     }
3320     if (unlikely (status))
3321         goto release_source;
3322
3323     switch (pattern->extend) {
3324     case CAIRO_EXTEND_PAD:
3325     case CAIRO_EXTEND_NONE:
3326     {
3327         /* In PS/PDF, (as far as I can tell), all patterns are
3328          * repeating. So we support cairo's EXTEND_NONE semantics
3329          * by setting the repeat step size to a size large enough
3330          * to guarantee that no more than a single occurrence will
3331          * be visible.
3332          *
3333          * First, map the surface extents into pattern space (since
3334          * xstep and ystep are in pattern space).  Then use an upper
3335          * bound on the length of the diagonal of the pattern image
3336          * and the surface as repeat size.  This guarantees to never
3337          * repeat visibly.
3338          */
3339         double x1 = 0.0, y1 = 0.0;
3340         double x2 = surface->width, y2 = surface->height;
3341         _cairo_matrix_transform_bounding_box (&pattern->matrix,
3342                                               &x1, &y1, &x2, &y2,
3343                                               NULL);
3344
3345         /* Rather than computing precise bounds of the union, just
3346          * add the surface extents unconditionally. We only
3347          * required an answer that's large enough, we don't really
3348          * care if it's not as tight as possible.*/
3349         xstep = ystep = ceil ((x2 - x1) + (y2 - y1) +
3350                               pattern_width + pattern_height);
3351         break;
3352     }
3353     case CAIRO_EXTEND_REPEAT:
3354         xstep = pattern_width;
3355         ystep = pattern_height;
3356         break;
3357     case CAIRO_EXTEND_REFLECT:
3358         xstep = pattern_width*2;
3359         ystep = pattern_height*2;
3360         break;
3361         /* All the rest (if any) should have been analyzed away, so these
3362          * cases should be unreachable. */
3363     default:
3364         ASSERT_NOT_REACHED;
3365         xstep = 0;
3366         ystep = 0;
3367     }
3368
3369     _cairo_output_stream_printf (surface->stream,
3370                                  "/CairoPattern {\n");
3371
3372     old_use_string_datasource = surface->use_string_datasource;
3373     surface->use_string_datasource = TRUE;
3374     if (op == CAIRO_OPERATOR_SOURCE) {
3375         _cairo_output_stream_printf (surface->stream,
3376                                      "%d g 0 0 %f %f rectfill\n",
3377                                      surface->content == CAIRO_CONTENT_COLOR ? 0 : 1,
3378                                      xstep, ystep);
3379     }
3380     status = _cairo_ps_surface_emit_surface (surface,
3381                                              pattern,
3382                                              image ? &image->base : source,
3383                                              op,
3384                                              pattern_width, pattern_height, FALSE);
3385     if (unlikely (status))
3386         goto release_source;
3387
3388     surface->use_string_datasource = old_use_string_datasource;
3389     _cairo_output_stream_printf (surface->stream,
3390                                  "} bind def\n");
3391
3392     _cairo_output_stream_printf (surface->stream,
3393                                  "<< /PatternType 1\n"
3394                                  "   /PaintType 1\n"
3395                                  "   /TilingType 1\n");
3396     _cairo_output_stream_printf (surface->stream,
3397                                  "   /XStep %f /YStep %f\n",
3398                                  xstep, ystep);
3399
3400     if (pattern->extend == CAIRO_EXTEND_REFLECT) {
3401         _cairo_output_stream_printf (surface->stream,
3402                                      "   /BBox [0 0 %d %d]\n"
3403                                      "   /PaintProc {\n"
3404                                      "      CairoPattern\n"
3405                                      "      [-1 0 0  1 %d 0] concat CairoPattern\n"
3406                                      "      [ 1 0 0 -1 0 %d] concat CairoPattern\n"
3407                                      "      [-1 0 0  1 %d 0] concat CairoPattern\n"
3408                                      "      CairoPattern\n"
3409                                      "   } bind\n",
3410                                      pattern_width*2, pattern_height*2,
3411                                      pattern_width*2,
3412                                      pattern_height*2,
3413                                      pattern_width*2);
3414     } else {
3415         if (op == CAIRO_OPERATOR_SOURCE) {
3416             _cairo_output_stream_printf (surface->stream,
3417                                          "   /BBox [0 0 %f %f]\n",
3418                                          xstep, ystep);
3419         } else {
3420             _cairo_output_stream_printf (surface->stream,
3421                                          "   /BBox [0 0 %d %d]\n",
3422                                          pattern_width, pattern_height);
3423         }
3424         _cairo_output_stream_printf (surface->stream,
3425                                      "   /PaintProc { CairoPattern }\n");
3426     }
3427
3428     _cairo_output_stream_printf (surface->stream,
3429                                  ">>\n");
3430
3431     cairo_p2d = pattern->matrix;
3432     status = cairo_matrix_invert (&cairo_p2d);
3433     /* cairo_pattern_set_matrix ensures the matrix is invertible */
3434     assert (status == CAIRO_STATUS_SUCCESS);
3435
3436     cairo_matrix_init_identity (&ps_p2d);
3437     cairo_matrix_translate (&ps_p2d, 0.0, surface->height);
3438     cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
3439     cairo_matrix_multiply (&ps_p2d, &cairo_p2d, &ps_p2d);
3440     cairo_matrix_translate (&ps_p2d, 0.0, pattern_height);
3441     cairo_matrix_scale (&ps_p2d, 1.0, -1.0);
3442
3443     _cairo_output_stream_printf (surface->stream,
3444                                  "[ %f %f %f %f %f %f ]\n",
3445                                  ps_p2d.xx, ps_p2d.yx,
3446                                  ps_p2d.xy, ps_p2d.yy,
3447                                  ps_p2d.x0, ps_p2d.y0);
3448     _cairo_output_stream_printf (surface->stream,
3449                                  "makepattern setpattern\n");
3450
3451   release_source:
3452     if (image)
3453         cairo_surface_destroy (&image->base);
3454
3455     _cairo_ps_surface_release_source_surface_from_pattern (surface, pattern, source, image_extra);
3456
3457     return status;
3458 }
3459
3460 typedef struct _cairo_ps_color_stop {
3461     double offset;
3462     double color[4];
3463 } cairo_ps_color_stop_t;
3464
3465 static void
3466 _cairo_ps_surface_emit_linear_colorgradient (cairo_ps_surface_t     *surface,
3467                                              cairo_ps_color_stop_t  *stop1,
3468                                              cairo_ps_color_stop_t  *stop2)
3469 {
3470     _cairo_output_stream_printf (surface->stream,
3471                                  "   << /FunctionType 2\n"
3472                                  "      /Domain [ 0 1 ]\n"
3473                                  "      /C0 [ %f %f %f ]\n"
3474                                  "      /C1 [ %f %f %f ]\n"
3475                                  "      /N 1\n"
3476                                  "   >>\n",
3477                                  stop1->color[0],
3478                                  stop1->color[1],
3479                                  stop1->color[2],
3480                                  stop2->color[0],
3481                                  stop2->color[1],
3482                                  stop2->color[2]);
3483 }
3484
3485 static void
3486 _cairo_ps_surface_emit_stitched_colorgradient (cairo_ps_surface_t    *surface,
3487                                                unsigned int           n_stops,
3488                                                cairo_ps_color_stop_t  stops[])
3489 {
3490     unsigned int i;
3491
3492     _cairo_output_stream_printf (surface->stream,
3493                                  "<< /FunctionType 3\n"
3494                                  "   /Domain [ 0 1 ]\n"
3495                                  "   /Functions [\n");
3496     for (i = 0; i < n_stops - 1; i++)
3497         _cairo_ps_surface_emit_linear_colorgradient (surface, &stops[i], &stops[i+1]);
3498
3499     _cairo_output_stream_printf (surface->stream, "   ]\n");
3500
3501     _cairo_output_stream_printf (surface->stream, "   /Bounds [ ");
3502     for (i = 1; i < n_stops-1; i++)
3503         _cairo_output_stream_printf (surface->stream, "%f ", stops[i].offset);
3504     _cairo_output_stream_printf (surface->stream, "]\n");
3505
3506     _cairo_output_stream_printf (surface->stream, "   /Encode [ 1 1 %d { pop 0 1 } for ]\n",
3507                                  n_stops - 1);
3508
3509     _cairo_output_stream_printf (surface->stream, ">>\n");
3510 }
3511
3512 static void
3513 calc_gradient_color (cairo_ps_color_stop_t *new_stop,
3514                      cairo_ps_color_stop_t *stop1,
3515                      cairo_ps_color_stop_t *stop2)
3516 {
3517     int i;
3518     double offset = stop1->offset / (stop1->offset + 1.0 - stop2->offset);
3519
3520     for (i = 0; i < 4; i++)
3521         new_stop->color[i] = stop1->color[i] + offset*(stop2->color[i] - stop1->color[i]);
3522 }
3523
3524 #define COLOR_STOP_EPSILON 1e-6
3525
3526 static cairo_status_t
3527 _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t       *surface,
3528                                       cairo_gradient_pattern_t *pattern)
3529 {
3530     cairo_ps_color_stop_t *allstops, *stops;
3531     unsigned int i, n_stops;
3532
3533     allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_ps_color_stop_t));
3534     if (unlikely (allstops == NULL))
3535         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
3536
3537     stops = &allstops[1];
3538     n_stops = pattern->n_stops;
3539
3540     for (i = 0; i < n_stops; i++) {
3541         cairo_gradient_stop_t *stop = &pattern->stops[i];
3542
3543         stops[i].color[0] = stop->color.red;
3544         stops[i].color[1] = stop->color.green;
3545         stops[i].color[2] = stop->color.blue;
3546         stops[i].color[3] = stop->color.alpha;
3547         stops[i].offset = pattern->stops[i].offset;
3548     }
3549
3550     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3551         pattern->base.extend == CAIRO_EXTEND_REFLECT)
3552     {
3553         if (stops[0].offset > COLOR_STOP_EPSILON) {
3554             if (pattern->base.extend == CAIRO_EXTEND_REFLECT)
3555                 memcpy (allstops, stops, sizeof (cairo_ps_color_stop_t));
3556             else
3557                 calc_gradient_color (&allstops[0], &stops[0], &stops[n_stops-1]);
3558             stops = allstops;
3559             n_stops++;
3560         }
3561         stops[0].offset = 0.0;
3562
3563         if (stops[n_stops-1].offset < 1.0 - COLOR_STOP_EPSILON) {
3564             if (pattern->base.extend == CAIRO_EXTEND_REFLECT) {
3565                 memcpy (&stops[n_stops],
3566                         &stops[n_stops - 1],
3567                         sizeof (cairo_ps_color_stop_t));
3568             } else {
3569                 calc_gradient_color (&stops[n_stops], &stops[0], &stops[n_stops-1]);
3570             }
3571             n_stops++;
3572         }
3573         stops[n_stops-1].offset = 1.0;
3574     }
3575
3576     for (i = 0; i < n_stops; i++) {
3577         double red, green, blue;
3578         cairo_color_t color;
3579
3580         _cairo_color_init_rgba (&color,
3581                                 stops[i].color[0],
3582                                 stops[i].color[1],
3583                                 stops[i].color[2],
3584                                 stops[i].color[3]);
3585         _cairo_ps_surface_flatten_transparency (surface, &color,
3586                                                 &red, &green, &blue);
3587         stops[i].color[0] = red;
3588         stops[i].color[1] = green;
3589         stops[i].color[2] = blue;
3590     }
3591
3592     _cairo_output_stream_printf (surface->stream,
3593                                  "/CairoFunction\n");
3594     if (stops[0].offset == stops[n_stops - 1].offset) {
3595         /*
3596          * The first and the last stops have the same offset, but we
3597          * don't want a function with an empty domain, because that
3598          * would provoke underdefined behaviour from rasterisers.
3599          * This can only happen with EXTEND_PAD, because EXTEND_NONE
3600          * is optimised into a clear pattern in cairo-gstate, and
3601          * REFLECT/REPEAT are always transformed to have the first
3602          * stop at t=0 and the last stop at t=1.  Thus we want a step
3603          * function going from the first color to the last one.
3604          *
3605          * This can be accomplished by stitching three functions:
3606          *  - a constant first color function,
3607          *  - a step from the first color to the last color (with empty domain)
3608          *  - a constant last color function
3609          */
3610         cairo_ps_color_stop_t pad_stops[4];
3611
3612         assert (pattern->base.extend == CAIRO_EXTEND_PAD);
3613
3614         pad_stops[0] = pad_stops[1] = stops[0];
3615         pad_stops[2] = pad_stops[3] = stops[n_stops - 1];
3616
3617         pad_stops[0].offset = 0;
3618         pad_stops[3].offset = 1;
3619
3620         _cairo_ps_surface_emit_stitched_colorgradient (surface, 4, pad_stops);
3621     } else if (n_stops == 2) {
3622         /* no need for stitched function */
3623         _cairo_ps_surface_emit_linear_colorgradient (surface, &stops[0], &stops[1]);
3624     } else {
3625         /* multiple stops: stitch. XXX possible optimization: regulary spaced
3626          * stops do not require stitching. XXX */
3627         _cairo_ps_surface_emit_stitched_colorgradient (surface, n_stops, stops);
3628     }
3629     _cairo_output_stream_printf (surface->stream,
3630                                  "def\n");
3631
3632     free (allstops);
3633
3634     return CAIRO_STATUS_SUCCESS;
3635 }
3636
3637 static cairo_status_t
3638 _cairo_ps_surface_emit_repeating_function (cairo_ps_surface_t       *surface,
3639                                            cairo_gradient_pattern_t *pattern,
3640                                            int                       begin,
3641                                            int                       end)
3642 {
3643     _cairo_output_stream_printf (surface->stream,
3644                                  "/CairoFunction\n"
3645                                  "<< /FunctionType 3\n"
3646                                  "   /Domain [ %d %d ]\n"
3647                                  "   /Functions [ %d {CairoFunction} repeat ]\n"
3648                                  "   /Bounds [ %d 1 %d {} for ]\n",
3649                                  begin,
3650                                  end,
3651                                  end - begin,
3652                                  begin + 1,
3653                                  end - 1);
3654
3655     if (pattern->base.extend == CAIRO_EXTEND_REFLECT) {
3656         _cairo_output_stream_printf (surface->stream, "   /Encode [ %d 1 %d { 2 mod 0 eq {0 1} {1 0} ifelse } for ]\n",
3657                                      begin,
3658                                      end - 1);
3659     } else {
3660         _cairo_output_stream_printf (surface->stream, "   /Encode [ %d 1 %d { pop 0 1 } for ]\n",
3661                                      begin,
3662                                      end - 1);
3663     }
3664
3665     _cairo_output_stream_printf (surface->stream, ">> def\n");
3666
3667     return CAIRO_STATUS_SUCCESS;
3668 }
3669
3670 static cairo_status_t
3671 _cairo_ps_surface_emit_gradient (cairo_ps_surface_t       *surface,
3672                                  cairo_gradient_pattern_t *pattern,
3673                                  cairo_bool_t              is_ps_pattern)
3674 {
3675     cairo_matrix_t pat_to_ps;
3676     cairo_circle_double_t start, end;
3677     double domain[2];
3678     cairo_status_t status;
3679
3680     assert (pattern->n_stops != 0);
3681
3682     status = _cairo_ps_surface_emit_pattern_stops (surface, pattern);
3683     if (unlikely (status))
3684         return status;
3685
3686     pat_to_ps = pattern->base.matrix;
3687     status = cairo_matrix_invert (&pat_to_ps);
3688     /* cairo_pattern_set_matrix ensures the matrix is invertible */
3689     assert (status == CAIRO_STATUS_SUCCESS);
3690     cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
3691
3692     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3693         pattern->base.extend == CAIRO_EXTEND_REFLECT)
3694     {
3695         double bounds_x1, bounds_x2, bounds_y1, bounds_y2;
3696         double x_scale, y_scale, tolerance;
3697
3698         /* TODO: use tighter extents */
3699         bounds_x1 = 0;
3700         bounds_y1 = 0;
3701         bounds_x2 = surface->width;
3702         bounds_y2 = surface->height;
3703         _cairo_matrix_transform_bounding_box (&pattern->base.matrix,
3704                                               &bounds_x1, &bounds_y1,
3705                                               &bounds_x2, &bounds_y2,
3706                                               NULL);
3707
3708         x_scale = surface->base.x_resolution / surface->base.x_fallback_resolution;
3709         y_scale = surface->base.y_resolution / surface->base.y_fallback_resolution;
3710
3711         tolerance = fabs (_cairo_matrix_compute_determinant (&pattern->base.matrix));
3712         tolerance /= _cairo_matrix_transformed_circle_major_axis (&pattern->base.matrix, 1);
3713         tolerance *= MIN (x_scale, y_scale);
3714
3715         _cairo_gradient_pattern_box_to_parameter (pattern,
3716                                                   bounds_x1, bounds_y1,
3717                                                   bounds_x2, bounds_y2,
3718                                                   tolerance, domain);
3719     } else if (pattern->stops[0].offset == pattern->stops[pattern->n_stops - 1].offset) {
3720         /*
3721          * If the first and the last stop offset are the same, then
3722          * the color function is a step function.
3723          * _cairo_ps_surface_emit_pattern_stops emits it as a stitched
3724          * function no matter how many stops the pattern has.  The
3725          * domain of the stitched function will be [0 1] in this case.
3726          *
3727          * This is done to avoid emitting degenerate gradients for
3728          * EXTEND_PAD patterns having a step color function.
3729          */
3730         domain[0] = 0.0;
3731         domain[1] = 1.0;
3732
3733         assert (pattern->base.extend == CAIRO_EXTEND_PAD);
3734     } else {
3735         domain[0] = pattern->stops[0].offset;
3736         domain[1] = pattern->stops[pattern->n_stops - 1].offset;
3737     }
3738
3739     /* PS requires the first and last stop to be the same as the
3740      * extreme coordinates. For repeating patterns this moves the
3741      * extreme coordinates out to the begin/end of the repeating
3742      * function. For non repeating patterns this may move the extreme
3743      * coordinates in if there are not stops at offset 0 and 1. */
3744     _cairo_gradient_pattern_interpolate (pattern, domain[0], &start);
3745     _cairo_gradient_pattern_interpolate (pattern, domain[1], &end);
3746
3747     if (pattern->base.extend == CAIRO_EXTEND_REPEAT ||
3748         pattern->base.extend == CAIRO_EXTEND_REFLECT)
3749     {
3750         int repeat_begin, repeat_end;
3751
3752         repeat_begin = floor (domain[0]);
3753         repeat_end = ceil (domain[1]);
3754
3755         status = _cairo_ps_surface_emit_repeating_function (surface,
3756                                                             pattern,
3757                                                             repeat_begin,
3758                                                             repeat_end);
3759         if (unlikely (status))
3760             return status;
3761     } else if (pattern->n_stops <= 2) {
3762         /* For EXTEND_NONE and EXTEND_PAD if there are only two stops a
3763          * Type 2 function is used by itself without a stitching
3764          * function. Type 2 functions always have the domain [0 1] */
3765         domain[0] = 0.0;
3766         domain[1] = 1.0;
3767     }
3768
3769     if (is_ps_pattern) {
3770         _cairo_output_stream_printf (surface->stream,
3771                                      "<< /PatternType 2\n"
3772                                      "   /Shading\n");
3773     }
3774
3775     if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) {
3776         _cairo_output_stream_printf (surface->stream,
3777                                      "   << /ShadingType 2\n"
3778                                      "      /ColorSpace /DeviceRGB\n"
3779                                      "      /Coords [ %f %f %f %f ]\n",
3780                                      start.center.x, start.center.y,
3781                                      end.center.x, end.center.y);
3782     } else {
3783         _cairo_output_stream_printf (surface->stream,
3784                                      "   << /ShadingType 3\n"
3785                                      "      /ColorSpace /DeviceRGB\n"
3786                                      "      /Coords [ %f %f %f %f %f %f ]\n",
3787                                      start.center.x, start.center.y,
3788                                      MAX (start.radius, 0),
3789                                      end.center.x, end.center.y,
3790                                      MAX (end.radius, 0));
3791     }
3792
3793     if (pattern->base.extend != CAIRO_EXTEND_NONE) {
3794         _cairo_output_stream_printf (surface->stream,
3795                                      "      /Extend [ true true ]\n");
3796     } else {
3797         _cairo_output_stream_printf (surface->stream,
3798                                      "      /Extend [ false false ]\n");
3799     }
3800
3801     if (domain[0] == 0.0 && domain[1] == 1.0) {
3802         _cairo_output_stream_printf (surface->stream,
3803                                      "      /Function CairoFunction\n");
3804     } else {
3805         _cairo_output_stream_printf (surface->stream,
3806                                      "      /Function <<\n"
3807                                      "         /FunctionType 3\n"
3808                                      "         /Domain [ 0 1 ]\n"
3809                                      "         /Bounds [ ]\n"
3810                                      "         /Encode [ %f %f ]\n"
3811                                      "         /Functions [ CairoFunction ]\n"
3812                                      "      >>\n",
3813                                      domain[0], domain[1]);
3814     }
3815
3816     _cairo_output_stream_printf (surface->stream,
3817                                  "   >>\n");
3818
3819     if (is_ps_pattern) {
3820         _cairo_output_stream_printf (surface->stream,
3821                                      ">>\n"
3822                                      "[ %f %f %f %f %f %f ]\n"
3823                                      "makepattern setpattern\n",
3824                                      pat_to_ps.xx, pat_to_ps.yx,
3825                                      pat_to_ps.xy, pat_to_ps.yy,
3826                                      pat_to_ps.x0, pat_to_ps.y0);
3827     } else {
3828         _cairo_output_stream_printf (surface->stream,
3829                                      "shfill\n");
3830     }
3831
3832     return status;
3833 }
3834
3835 static cairo_status_t
3836 _cairo_ps_surface_emit_mesh_pattern (cairo_ps_surface_t     *surface,
3837                                      cairo_mesh_pattern_t   *pattern,
3838                                      cairo_bool_t            is_ps_pattern)
3839 {
3840     cairo_matrix_t pat_to_ps;
3841     cairo_status_t status;
3842     cairo_pdf_shading_t shading;
3843     int i;
3844
3845     if (_cairo_array_num_elements (&pattern->patches) == 0)
3846         return CAIRO_INT_STATUS_NOTHING_TO_DO;
3847
3848     pat_to_ps = pattern->base.matrix;
3849     status = cairo_matrix_invert (&pat_to_ps);
3850     /* cairo_pattern_set_matrix ensures the matrix is invertible */
3851     assert (status == CAIRO_STATUS_SUCCESS);
3852
3853     cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
3854
3855     status = _cairo_pdf_shading_init_color (&shading, pattern);
3856     if (unlikely (status))
3857         return status;
3858
3859     _cairo_output_stream_printf (surface->stream,
3860                                  "currentfile\n"
3861                                  "/ASCII85Decode filter /FlateDecode filter /ReusableStreamDecode filter\n");
3862
3863     status = _cairo_ps_surface_emit_base85_string (surface,
3864                                                    shading.data,
3865                                                    shading.data_length,
3866                                                    CAIRO_PS_COMPRESS_DEFLATE,
3867                                                    FALSE);
3868     if (status)
3869         return status;
3870
3871     _cairo_output_stream_printf (surface->stream,
3872                                  "\n"
3873                                  "/CairoData exch def\n");
3874
3875     if (is_ps_pattern) {
3876         _cairo_output_stream_printf (surface->stream,
3877                                      "<< /PatternType 2\n"
3878                                      "   /Shading\n");
3879     }
3880
3881     _cairo_output_stream_printf (surface->stream,
3882                                  "   << /ShadingType %d\n"
3883                                  "      /ColorSpace /DeviceRGB\n"
3884                                  "      /DataSource CairoData\n"
3885                                  "      /BitsPerCoordinate %d\n"
3886                                  "      /BitsPerComponent %d\n"
3887                                  "      /BitsPerFlag %d\n"
3888                                  "      /Decode [",
3889                                  shading.shading_type,
3890                                  shading.bits_per_coordinate,
3891                                  shading.bits_per_component,
3892                                  shading.bits_per_flag);
3893
3894     for (i = 0; i < shading.decode_array_length; i++)
3895         _cairo_output_stream_printf (surface->stream, "%f ", shading.decode_array[i]);
3896
3897     _cairo_output_stream_printf (surface->stream,
3898                                  "]\n"
3899                                  "   >>\n");
3900
3901     if (is_ps_pattern) {
3902         _cairo_output_stream_printf (surface->stream,
3903                                      ">>\n"
3904                                      "[ %f %f %f %f %f %f ]\n",
3905                                      pat_to_ps.xx, pat_to_ps.yx,
3906                                      pat_to_ps.xy, pat_to_ps.yy,
3907                                      pat_to_ps.x0, pat_to_ps.y0);
3908         _cairo_output_stream_printf (surface->stream,
3909                                      "makepattern\n"
3910                                      "setpattern\n");
3911     } else {
3912         _cairo_output_stream_printf (surface->stream, "shfill\n");
3913     }
3914
3915     _cairo_output_stream_printf (surface->stream,
3916                                  "currentdict /CairoData undef\n");
3917
3918     _cairo_pdf_shading_fini (&shading);
3919
3920     return status;
3921 }
3922
3923 static cairo_status_t
3924 _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface,
3925                                 const cairo_pattern_t *pattern,
3926                                 cairo_rectangle_int_t *extents,
3927                                 cairo_operator_t       op)
3928 {
3929     cairo_status_t status;
3930
3931     if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
3932         cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
3933
3934         if (surface->current_pattern_is_solid_color == FALSE ||
3935             ! _cairo_color_equal (&surface->current_color, &solid->color))
3936         {
3937             status = _cairo_pdf_operators_flush (&surface->pdf_operators);
3938             if (unlikely (status))
3939                 return status;
3940
3941             _cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
3942
3943             surface->current_pattern_is_solid_color = TRUE;
3944             surface->current_color = solid->color;
3945         }
3946
3947         return CAIRO_STATUS_SUCCESS;
3948     }
3949
3950     surface->current_pattern_is_solid_color = FALSE;
3951     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
3952     if (unlikely (status))
3953             return status;
3954
3955     switch (pattern->type) {
3956     case CAIRO_PATTERN_TYPE_SOLID:
3957
3958         _cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern);
3959         break;
3960
3961     case CAIRO_PATTERN_TYPE_SURFACE:
3962     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
3963         status = _cairo_ps_surface_emit_surface_pattern (surface,
3964                                                          (cairo_pattern_t *)pattern,
3965                                                          extents,
3966                                                          op);
3967         if (unlikely (status))
3968             return status;
3969         break;
3970
3971     case CAIRO_PATTERN_TYPE_LINEAR:
3972     case CAIRO_PATTERN_TYPE_RADIAL:
3973         status = _cairo_ps_surface_emit_gradient (surface,
3974                                                   (cairo_gradient_pattern_t *) pattern,
3975                                                   TRUE);
3976         if (unlikely (status))
3977             return status;
3978         break;
3979
3980     case CAIRO_PATTERN_TYPE_MESH:
3981         status = _cairo_ps_surface_emit_mesh_pattern (surface,
3982                                                       (cairo_mesh_pattern_t *) pattern,
3983                                                       TRUE);
3984         if (unlikely (status))
3985             return status;
3986         break;
3987     }
3988
3989     return CAIRO_STATUS_SUCCESS;
3990 }
3991
3992 static cairo_status_t
3993 _cairo_ps_surface_paint_gradient (cairo_ps_surface_t          *surface,
3994                                   const cairo_pattern_t       *source,
3995                                   const cairo_rectangle_int_t *extents)
3996 {
3997     cairo_matrix_t pat_to_ps;
3998     cairo_status_t status;
3999
4000     pat_to_ps = source->matrix;
4001     status = cairo_matrix_invert (&pat_to_ps);
4002     /* cairo_pattern_set_matrix ensures the matrix is invertible */
4003     assert (status == CAIRO_STATUS_SUCCESS);
4004     cairo_matrix_multiply (&pat_to_ps, &pat_to_ps, &surface->cairo_to_ps);
4005
4006     if (! _cairo_matrix_is_identity (&pat_to_ps)) {
4007         _cairo_output_stream_printf (surface->stream,
4008                                      "[%f %f %f %f %f %f] concat\n",
4009                                      pat_to_ps.xx, pat_to_ps.yx,
4010                                      pat_to_ps.xy, pat_to_ps.yy,
4011                                      pat_to_ps.x0, pat_to_ps.y0);
4012     }
4013
4014     if (source->type == CAIRO_PATTERN_TYPE_MESH) {
4015         status = _cairo_ps_surface_emit_mesh_pattern (surface,
4016                                                       (cairo_mesh_pattern_t *)source,
4017                                                       FALSE);
4018         if (unlikely (status))
4019             return status;
4020     } else {
4021         status = _cairo_ps_surface_emit_gradient (surface,
4022                                                   (cairo_gradient_pattern_t *)source,
4023                                                   FALSE);
4024         if (unlikely (status))
4025             return status;
4026     }
4027
4028     return status;
4029 }
4030
4031 static cairo_status_t
4032 _cairo_ps_surface_paint_pattern (cairo_ps_surface_t           *surface,
4033                                  const cairo_pattern_t        *source,
4034                                  cairo_rectangle_int_t        *extents,
4035                                  cairo_operator_t              op,
4036                                  cairo_bool_t                  stencil_mask)
4037 {
4038     switch (source->type) {
4039     case CAIRO_PATTERN_TYPE_SURFACE:
4040     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
4041        return _cairo_ps_surface_paint_surface (surface,
4042                                                (cairo_pattern_t *)source,
4043                                                extents,
4044                                                op,
4045                                                stencil_mask);
4046
4047     case CAIRO_PATTERN_TYPE_LINEAR:
4048     case CAIRO_PATTERN_TYPE_RADIAL:
4049     case CAIRO_PATTERN_TYPE_MESH:
4050         return _cairo_ps_surface_paint_gradient (surface,
4051                                                   source,
4052                                                   extents);
4053
4054     case CAIRO_PATTERN_TYPE_SOLID:
4055     default:
4056        ASSERT_NOT_REACHED;
4057        return CAIRO_STATUS_SUCCESS;
4058     }
4059 }
4060
4061 static cairo_bool_t
4062 _can_paint_pattern (const cairo_pattern_t *pattern)
4063 {
4064     switch (pattern->type) {
4065     case CAIRO_PATTERN_TYPE_SOLID:
4066         return FALSE;
4067
4068     case CAIRO_PATTERN_TYPE_SURFACE:
4069     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
4070         return (pattern->extend == CAIRO_EXTEND_NONE ||
4071                 pattern->extend == CAIRO_EXTEND_PAD);
4072
4073     case CAIRO_PATTERN_TYPE_LINEAR:
4074     case CAIRO_PATTERN_TYPE_RADIAL:
4075     case CAIRO_PATTERN_TYPE_MESH:
4076         return TRUE;
4077
4078     default:
4079         ASSERT_NOT_REACHED;
4080         return FALSE;
4081     }
4082 }
4083
4084 static cairo_bool_t
4085 _cairo_ps_surface_get_extents (void                    *abstract_surface,
4086                                cairo_rectangle_int_t   *rectangle)
4087 {
4088     cairo_ps_surface_t *surface = abstract_surface;
4089
4090     rectangle->x = 0;
4091     rectangle->y = 0;
4092
4093     /* XXX: The conversion to integers here is pretty bogus, (not to
4094      * mention the aribitray limitation of width to a short(!). We
4095      * may need to come up with a better interface for get_extents.
4096      */
4097     rectangle->width  = ceil (surface->width);
4098     rectangle->height = ceil (surface->height);
4099
4100     return TRUE;
4101 }
4102
4103 static void
4104 _cairo_ps_surface_get_font_options (void                  *abstract_surface,
4105                                     cairo_font_options_t  *options)
4106 {
4107     _cairo_font_options_init_default (options);
4108
4109     cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_NONE);
4110     cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
4111     cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_GRAY);
4112     _cairo_font_options_set_round_glyph_positions (options, CAIRO_ROUND_GLYPH_POS_OFF);
4113 }
4114
4115 static cairo_int_status_t
4116 _cairo_ps_surface_set_clip (cairo_ps_surface_t *surface,
4117                             cairo_composite_rectangles_t *composite)
4118 {
4119     cairo_clip_t *clip = composite->clip;
4120
4121     if (_cairo_composite_rectangles_can_reduce_clip (composite, clip))
4122         clip = NULL;
4123
4124     if (clip == NULL) {
4125         if (_cairo_composite_rectangles_can_reduce_clip (composite,
4126                                                          surface->clipper.clip))
4127             return CAIRO_STATUS_SUCCESS;
4128     }
4129
4130     return _cairo_surface_clipper_set_clip (&surface->clipper, clip);
4131 }
4132
4133 static cairo_int_status_t
4134 _cairo_ps_surface_paint (void                   *abstract_surface,
4135                          cairo_operator_t        op,
4136                          const cairo_pattern_t  *source,
4137                          const cairo_clip_t     *clip)
4138 {
4139     cairo_ps_surface_t *surface = abstract_surface;
4140     cairo_output_stream_t *stream = surface->stream;
4141     cairo_composite_rectangles_t extents;
4142     cairo_status_t status;
4143
4144     status = _cairo_composite_rectangles_init_for_paint (&extents,
4145                                                          &surface->base,
4146                                                          op, source, clip);
4147     if (unlikely (status))
4148         return status;
4149
4150     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
4151         status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded);
4152         goto cleanup_composite;
4153     }
4154
4155     assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded));
4156
4157 #if DEBUG_PS
4158     _cairo_output_stream_printf (stream,
4159                                  "%% _cairo_ps_surface_paint\n");
4160 #endif
4161
4162     status = _cairo_ps_surface_set_clip (surface, &extents);
4163     if (unlikely (status))
4164         goto cleanup_composite;
4165
4166     if (_can_paint_pattern (source)) {
4167         status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4168         if (unlikely (status))
4169             goto cleanup_composite;
4170
4171         _cairo_output_stream_printf (stream, "q\n");
4172         status = _cairo_ps_surface_paint_pattern (surface,
4173                                                   source,
4174                                                   &extents.bounded, op, FALSE);
4175         if (unlikely (status))
4176             goto cleanup_composite;
4177
4178         _cairo_output_stream_printf (stream, "Q\n");
4179     } else {
4180         status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op);
4181         if (unlikely (status))
4182             goto cleanup_composite;
4183
4184         _cairo_output_stream_printf (stream, "0 0 %f %f rectfill\n",
4185                                      surface->width, surface->height);
4186     }
4187
4188 cleanup_composite:
4189     _cairo_composite_rectangles_fini (&extents);
4190     return status;
4191 }
4192
4193 static cairo_int_status_t
4194 _cairo_ps_surface_mask (void                    *abstract_surface,
4195                         cairo_operator_t         op,
4196                         const cairo_pattern_t   *source,
4197                         const cairo_pattern_t   *mask,
4198                         const cairo_clip_t      *clip)
4199 {
4200     cairo_ps_surface_t *surface = abstract_surface;
4201     cairo_output_stream_t *stream = surface->stream;
4202     cairo_composite_rectangles_t extents;
4203     cairo_status_t status;
4204
4205     status = _cairo_composite_rectangles_init_for_mask (&extents,
4206                                                         &surface->base,
4207                                                         op, source, mask, clip);
4208     if (unlikely (status))
4209         return status;
4210
4211     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
4212         status = _cairo_ps_surface_analyze_operation (surface, op, source, mask, &extents.bounded);
4213         goto cleanup_composite;
4214     }
4215
4216     assert (_cairo_ps_surface_operation_supported (surface, op, source, mask, &extents.bounded));
4217
4218 #if DEBUG_PS
4219     _cairo_output_stream_printf (stream,
4220                                  "%% _cairo_ps_surface_mask\n");
4221 #endif
4222
4223     status = _cairo_ps_surface_set_clip (surface, &extents);
4224     if (unlikely (status))
4225         goto cleanup_composite;
4226
4227     status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op);
4228     if (unlikely (status))
4229         goto cleanup_composite;
4230
4231     _cairo_output_stream_printf (stream, "q\n");
4232     status = _cairo_ps_surface_paint_pattern (surface,
4233                                               mask,
4234                                               &extents.bounded, op, TRUE);
4235     if (unlikely (status))
4236         goto cleanup_composite;
4237
4238     _cairo_output_stream_printf (stream, "Q\n");
4239
4240 cleanup_composite:
4241     _cairo_composite_rectangles_fini (&extents);
4242     return status;
4243 }
4244
4245 static cairo_int_status_t
4246 _cairo_ps_surface_stroke (void                  *abstract_surface,
4247                           cairo_operator_t       op,
4248                           const cairo_pattern_t *source,
4249                           const cairo_path_fixed_t      *path,
4250                           const cairo_stroke_style_t    *style,
4251                           const cairo_matrix_t  *ctm,
4252                           const cairo_matrix_t  *ctm_inverse,
4253                           double                 tolerance,
4254                           cairo_antialias_t      antialias,
4255                           const cairo_clip_t            *clip)
4256 {
4257     cairo_ps_surface_t *surface = abstract_surface;
4258     cairo_composite_rectangles_t extents;
4259     cairo_int_status_t status;
4260
4261     status = _cairo_composite_rectangles_init_for_stroke (&extents,
4262                                                           &surface->base,
4263                                                           op, source,
4264                                                           path, style, ctm,
4265                                                           clip);
4266     if (unlikely (status))
4267         return status;
4268
4269     /* use the more accurate extents */
4270     {
4271         cairo_rectangle_int_t r;
4272         cairo_box_t b;
4273
4274         status = _cairo_path_fixed_stroke_extents (path, style,
4275                                                    ctm, ctm_inverse,
4276                                                    tolerance,
4277                                                    &r);
4278         if (unlikely (status))
4279             goto cleanup_composite;
4280
4281         _cairo_box_from_rectangle (&b, &r);
4282         status = _cairo_composite_rectangles_intersect_mask_extents (&extents, &b);
4283         if (unlikely (status))
4284             goto cleanup_composite;
4285     }
4286
4287     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
4288         status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded);
4289         goto cleanup_composite;
4290     }
4291
4292     assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded));
4293
4294 #if DEBUG_PS
4295     _cairo_output_stream_printf (surface->stream,
4296                                  "%% _cairo_ps_surface_stroke\n");
4297 #endif
4298
4299     status = _cairo_ps_surface_set_clip (surface, &extents);
4300     if (unlikely (status))
4301         goto cleanup_composite;
4302
4303     status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op);
4304     if (unlikely (status))
4305         goto cleanup_composite;
4306
4307     status = _cairo_pdf_operators_stroke (&surface->pdf_operators,
4308                                           path,
4309                                           style,
4310                                           ctm,
4311                                           ctm_inverse);
4312
4313 cleanup_composite:
4314     _cairo_composite_rectangles_fini (&extents);
4315     return status;
4316 }
4317
4318 static cairo_int_status_t
4319 _cairo_ps_surface_fill (void            *abstract_surface,
4320                         cairo_operator_t         op,
4321                         const cairo_pattern_t   *source,
4322                         const cairo_path_fixed_t*path,
4323                         cairo_fill_rule_t        fill_rule,
4324                         double                   tolerance,
4325                         cairo_antialias_t        antialias,
4326                         const cairo_clip_t              *clip)
4327 {
4328     cairo_ps_surface_t *surface = abstract_surface;
4329     cairo_composite_rectangles_t extents;
4330     cairo_int_status_t status;
4331
4332     status = _cairo_composite_rectangles_init_for_fill (&extents,
4333                                                         &surface->base,
4334                                                         op, source, path,
4335                                                         clip);
4336     if (unlikely (status))
4337         return status;
4338
4339     /* use the more accurate extents */
4340     {
4341         cairo_rectangle_int_t r;
4342         cairo_box_t b;
4343
4344         _cairo_path_fixed_fill_extents (path,
4345                                         fill_rule,
4346                                         tolerance,
4347                                         &r);
4348
4349         _cairo_box_from_rectangle (&b, &r);
4350         status = _cairo_composite_rectangles_intersect_mask_extents (&extents, &b);
4351         if (unlikely (status))
4352             goto cleanup_composite;
4353     }
4354
4355     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
4356         status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded);
4357         goto cleanup_composite;
4358     }
4359
4360     assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded));
4361
4362 #if DEBUG_PS
4363     _cairo_output_stream_printf (surface->stream,
4364                                  "%% _cairo_ps_surface_fill\n");
4365 #endif
4366
4367     status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4368     if (unlikely (status))
4369         goto cleanup_composite;
4370
4371     status = _cairo_ps_surface_set_clip (surface, &extents);
4372     if (unlikely (status))
4373         goto cleanup_composite;
4374
4375     if (_can_paint_pattern (source)) {
4376         _cairo_output_stream_printf (surface->stream, "q\n");
4377
4378         status =  _cairo_pdf_operators_clip (&surface->pdf_operators,
4379                                              path,
4380                                              fill_rule);
4381         if (unlikely (status))
4382             goto cleanup_composite;
4383
4384         status = _cairo_ps_surface_paint_pattern (surface,
4385                                                   source,
4386                                                   &extents.bounded, op, FALSE);
4387         if (unlikely (status))
4388             goto cleanup_composite;
4389
4390         _cairo_output_stream_printf (surface->stream, "Q\n");
4391         _cairo_pdf_operators_reset (&surface->pdf_operators);
4392     } else {
4393         status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op);
4394         if (unlikely (status))
4395             goto cleanup_composite;
4396
4397         status = _cairo_pdf_operators_fill (&surface->pdf_operators,
4398                                             path,
4399                                             fill_rule);
4400     }
4401
4402 cleanup_composite:
4403     _cairo_composite_rectangles_fini (&extents);
4404     return status;
4405 }
4406
4407 static cairo_bool_t
4408 _cairo_ps_surface_has_show_text_glyphs  (void                   *abstract_surface)
4409 {
4410     return TRUE;
4411 }
4412
4413 static cairo_int_status_t
4414 _cairo_ps_surface_show_text_glyphs (void                       *abstract_surface,
4415                                     cairo_operator_t            op,
4416                                     const cairo_pattern_t      *source,
4417                                     const char                 *utf8,
4418                                     int                         utf8_len,
4419                                     cairo_glyph_t              *glyphs,
4420                                     int                         num_glyphs,
4421                                     const cairo_text_cluster_t *clusters,
4422                                     int                         num_clusters,
4423                                     cairo_text_cluster_flags_t  cluster_flags,
4424                                     cairo_scaled_font_t        *scaled_font,
4425                                     const cairo_clip_t         *clip)
4426 {
4427     cairo_ps_surface_t *surface = abstract_surface;
4428     cairo_composite_rectangles_t extents;
4429     cairo_bool_t overlap;
4430     cairo_status_t status;
4431
4432     status = _cairo_composite_rectangles_init_for_glyphs (&extents,
4433                                                           &surface->base,
4434                                                           op, source,
4435                                                           scaled_font,
4436                                                           glyphs, num_glyphs,
4437                                                           clip,
4438                                                           &overlap);
4439     if (unlikely (status))
4440         return status;
4441
4442     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE) {
4443         status = _cairo_ps_surface_analyze_operation (surface, op, source, NULL, &extents.bounded);
4444         goto cleanup_composite;
4445     }
4446
4447     assert (_cairo_ps_surface_operation_supported (surface, op, source, NULL, &extents.bounded));
4448
4449 #if DEBUG_PS
4450     _cairo_output_stream_printf (surface->stream,
4451                                  "%% _cairo_ps_surface_show_glyphs\n");
4452 #endif
4453
4454     status = _cairo_ps_surface_set_clip (surface, &extents);
4455     if (unlikely (status))
4456         goto cleanup_composite;
4457
4458     status = _cairo_ps_surface_emit_pattern (surface, source, &extents.bounded, op);
4459     if (unlikely (status))
4460         goto cleanup_composite;
4461
4462     status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
4463                                                     utf8, utf8_len,
4464                                                     glyphs, num_glyphs,
4465                                                     clusters, num_clusters,
4466                                                     cluster_flags,
4467                                                     scaled_font);
4468
4469 cleanup_composite:
4470     _cairo_composite_rectangles_fini (&extents);
4471     return status;
4472 }
4473
4474 static const char **
4475 _cairo_ps_surface_get_supported_mime_types (void                 *abstract_surface)
4476 {
4477     return _cairo_ps_supported_mime_types;
4478 }
4479
4480 static void
4481 _cairo_ps_surface_set_paginated_mode (void                      *abstract_surface,
4482                                       cairo_paginated_mode_t     paginated_mode)
4483 {
4484     cairo_ps_surface_t *surface = abstract_surface;
4485     cairo_status_t status;
4486
4487     surface->paginated_mode = paginated_mode;
4488
4489     if (surface->clipper.clip != NULL) {
4490         status = _cairo_pdf_operators_flush (&surface->pdf_operators);
4491
4492         _cairo_output_stream_printf (surface->stream, "Q q\n");
4493         _cairo_surface_clipper_reset (&surface->clipper);
4494     }
4495 }
4496
4497 static cairo_int_status_t
4498 _cairo_ps_surface_set_bounding_box (void                *abstract_surface,
4499                                     cairo_box_t         *bbox)
4500 {
4501     cairo_ps_surface_t *surface = abstract_surface;
4502     int i, num_comments;
4503     char **comments;
4504     int x1, y1, x2, y2;
4505     cairo_bool_t has_page_media, has_page_bbox;
4506     const char *page_media;
4507
4508     x1 = floor (_cairo_fixed_to_double (bbox->p1.x));
4509     y1 = floor (surface->height - _cairo_fixed_to_double (bbox->p2.y));
4510     x2 = ceil (_cairo_fixed_to_double (bbox->p2.x));
4511     y2 = ceil (surface->height - _cairo_fixed_to_double (bbox->p1.y));
4512
4513     surface->page_bbox.x = x1;
4514     surface->page_bbox.y = y1;
4515     surface->page_bbox.width  = x2 - x1;
4516     surface->page_bbox.height = y2 - y1;
4517
4518     _cairo_output_stream_printf (surface->stream,
4519                                  "%%%%Page: %d %d\n",
4520                                  surface->num_pages,
4521                                  surface->num_pages);
4522
4523     _cairo_output_stream_printf (surface->stream,
4524                                  "%%%%BeginPageSetup\n");
4525
4526     has_page_media = FALSE;
4527     has_page_bbox = FALSE;
4528     num_comments = _cairo_array_num_elements (&surface->dsc_page_setup_comments);
4529     comments = _cairo_array_index (&surface->dsc_page_setup_comments, 0);
4530     for (i = 0; i < num_comments; i++) {
4531         _cairo_output_stream_printf (surface->stream,
4532                                      "%s\n", comments[i]);
4533         if (strncmp (comments[i], "%%PageMedia:", 11) == 0)
4534             has_page_media = TRUE;
4535
4536         if (strncmp (comments[i], "%%PageBoundingBox:", 18) == 0)
4537             has_page_bbox = TRUE;
4538
4539         free (comments[i]);
4540         comments[i] = NULL;
4541     }
4542     _cairo_array_truncate (&surface->dsc_page_setup_comments, 0);
4543
4544     if (!has_page_media && !surface->eps) {
4545         page_media = _cairo_ps_surface_get_page_media (surface);
4546         if (unlikely (page_media == NULL))
4547             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
4548
4549         _cairo_output_stream_printf (surface->stream,
4550                                      "%%%%PageMedia: %s\n",
4551                                      page_media);
4552     }
4553
4554     if (!has_page_bbox) {
4555         _cairo_output_stream_printf (surface->stream,
4556                                      "%%%%PageBoundingBox: %d %d %d %d\n",
4557                                      x1, y1, x2, y2);
4558     }
4559
4560     _cairo_output_stream_printf (surface->stream,
4561                                  "%%%%EndPageSetup\n"
4562                                  "q %d %d %d %d rectclip q\n",
4563                                  surface->page_bbox.x,
4564                                  surface->page_bbox.y,
4565                                  surface->page_bbox.width,
4566                                  surface->page_bbox.height);
4567
4568     if (surface->num_pages == 1) {
4569         surface->bbox_x1 = x1;
4570         surface->bbox_y1 = y1;
4571         surface->bbox_x2 = x2;
4572         surface->bbox_y2 = y2;
4573     } else {
4574         if (x1 < surface->bbox_x1)
4575             surface->bbox_x1 = x1;
4576         if (y1 < surface->bbox_y1)
4577             surface->bbox_y1 = y1;
4578         if (x2 > surface->bbox_x2)
4579             surface->bbox_x2 = x2;
4580         if (y2 > surface->bbox_y2)
4581             surface->bbox_y2 = y2;
4582     }
4583     surface->current_pattern_is_solid_color = FALSE;
4584     _cairo_pdf_operators_reset (&surface->pdf_operators);
4585
4586     return _cairo_output_stream_get_status (surface->stream);
4587 }
4588
4589 static cairo_bool_t
4590 _cairo_ps_surface_supports_fine_grained_fallbacks (void     *abstract_surface)
4591 {
4592     return TRUE;
4593 }
4594
4595 static const cairo_surface_backend_t cairo_ps_surface_backend = {
4596     CAIRO_SURFACE_TYPE_PS,
4597     _cairo_ps_surface_finish,
4598
4599     _cairo_default_context_create,
4600
4601     NULL, /* create similar: handled by wrapper */
4602     NULL, /* create similar image */
4603     NULL, /* map to image */
4604     NULL, /* unmap image */
4605
4606     _cairo_surface_default_source,
4607     NULL, /* acquire_source_image */
4608     NULL, /* release_source_image */
4609     NULL, /* snapshot */
4610
4611     NULL, /* cairo_ps_surface_copy_page */
4612     _cairo_ps_surface_show_page,
4613
4614     _cairo_ps_surface_get_extents,
4615     _cairo_ps_surface_get_font_options,
4616
4617     NULL, /* flush */
4618     NULL, /* mark_dirty_rectangle */
4619
4620     /* Here are the drawing functions */
4621
4622     _cairo_ps_surface_paint, /* paint */
4623     _cairo_ps_surface_mask,
4624     _cairo_ps_surface_stroke,
4625     _cairo_ps_surface_fill,
4626     NULL, /* fill-stroke */
4627     NULL, /* show_glyphs */
4628     _cairo_ps_surface_has_show_text_glyphs,
4629     _cairo_ps_surface_show_text_glyphs,
4630     _cairo_ps_surface_get_supported_mime_types,
4631 };
4632
4633 static const cairo_paginated_surface_backend_t cairo_ps_surface_paginated_backend = {
4634     _cairo_ps_surface_start_page,
4635     _cairo_ps_surface_set_paginated_mode,
4636     _cairo_ps_surface_set_bounding_box,
4637     NULL, /* _cairo_ps_surface_has_fallback_images, */
4638     _cairo_ps_surface_supports_fine_grained_fallbacks,
4639 };