2149e7e60e4be369f307c2e0bfbb466a8b5b58d0
[framework/graphics/cairo.git] / src / cairo-script-surface.c
1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
3  *
4  * Copyright © 2008 Chris Wilson
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it either under the terms of the GNU Lesser General Public
8  * License version 2.1 as published by the Free Software Foundation
9  * (the "LGPL") or, at your option, under the terms of the Mozilla
10  * Public License Version 1.1 (the "MPL"). If you do not alter this
11  * notice, a recipient may use your version of this file under either
12  * the MPL or the LGPL.
13  *
14  * You should have received a copy of the LGPL along with this library
15  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17  * You should have received a copy of the MPL along with this library
18  * in the file COPYING-MPL-1.1
19  *
20  * The contents of this file are subject to the Mozilla Public License
21  * Version 1.1 (the "License"); you may not use this file except in
22  * compliance with the License. You may obtain a copy of the License at
23  * http://www.mozilla.org/MPL/
24  *
25  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27  * the specific language governing rights and limitations.
28  *
29  * The Original Code is the cairo graphics library.
30  *
31  * The Initial Developer of the Original Code is Chris Wilson.
32  *
33  * Contributor(s):
34  *      Chris Wilson <chris@chris-wilson.co.uk>
35  */
36
37 /* The script surface is one that records all operations performed on
38  * it in the form of a procedural script, similar in fashion to
39  * PostScript but using Cairo's imaging model. In essence, this is
40  * equivalent to the recording-surface, but as there is no impedance mismatch
41  * between Cairo and CairoScript, we can generate output immediately
42  * without having to copy and hold the data in memory.
43  */
44
45 /**
46  * SECTION:cairo-script
47  * @Title: Script Surfaces
48  * @Short_Description: Rendering to replayable scripts
49  * @See_Also: #cairo_surface_t
50  *
51  * The script surface provides the ability to render to a native
52  * script that matches the cairo drawing model. The scripts can
53  * be replayed using tools under the util/cairo-script directoriy,
54  * or with cairo-perf-trace.
55  **/
56
57 /**
58  * CAIRO_HAS_SCRIPT_SURFACE:
59  *
60  * Defined if the script surface backend is available.
61  * The script surface backend is always built in since 1.12.
62  *
63  * Since: 1.12
64  **/
65
66
67 #include "cairoint.h"
68
69 #include "cairo-script.h"
70 #include "cairo-script-private.h"
71
72 #include "cairo-analysis-surface-private.h"
73 #include "cairo-default-context-private.h"
74 #include "cairo-device-private.h"
75 #include "cairo-error-private.h"
76 #include "cairo-list-inline.h"
77 #include "cairo-image-surface-private.h"
78 #include "cairo-output-stream-private.h"
79 #include "cairo-pattern-private.h"
80 #include "cairo-recording-surface-inline.h"
81 #include "cairo-scaled-font-private.h"
82 #include "cairo-surface-clipper-private.h"
83 #include "cairo-surface-snapshot-inline.h"
84 #include "cairo-surface-subsurface-private.h"
85 #include "cairo-surface-wrapper-private.h"
86
87 #if CAIRO_HAS_FT_FONT
88 #include "cairo-ft-private.h"
89 #endif
90
91 #include <ctype.h>
92
93 #ifdef WORDS_BIGENDIAN
94 #define to_be32(x) x
95 #else
96 #define to_be32(x) bswap_32(x)
97 #endif
98
99 #define _cairo_output_stream_puts(S, STR) \
100     _cairo_output_stream_write ((S), (STR), strlen (STR))
101
102 #define static cairo_warn static
103
104 typedef struct _cairo_script_context cairo_script_context_t;
105 typedef struct _cairo_script_surface cairo_script_surface_t;
106 typedef struct _cairo_script_implicit_context cairo_script_implicit_context_t;
107 typedef struct _cairo_script_font cairo_script_font_t;
108
109 typedef struct _operand {
110     enum {
111         SURFACE,
112         DEFERRED,
113     } type;
114     cairo_list_t link;
115 } operand_t;
116
117
118 struct deferred_finish {
119     cairo_list_t link;
120     operand_t operand;
121 };
122
123 struct _cairo_script_context {
124     cairo_device_t base;
125
126     int active;
127     int attach_snapshots;
128
129     cairo_bool_t owns_stream;
130     cairo_output_stream_t *stream;
131     cairo_script_mode_t mode;
132
133     struct _bitmap {
134         unsigned long min;
135         unsigned long count;
136         unsigned int map[64];
137         struct _bitmap *next;
138     } surface_id, font_id;
139
140     cairo_list_t operands;
141     cairo_list_t deferred;
142
143     cairo_list_t fonts;
144     cairo_list_t defines;
145 };
146
147 struct _cairo_script_font {
148     cairo_scaled_font_private_t base;
149
150     cairo_bool_t has_sfnt;
151     unsigned long id;
152     unsigned long subset_glyph_index;
153     cairo_list_t link;
154     cairo_scaled_font_t *parent;
155 };
156
157 struct _cairo_script_implicit_context {
158     cairo_operator_t current_operator;
159     cairo_fill_rule_t current_fill_rule;
160     double current_tolerance;
161     cairo_antialias_t current_antialias;
162     cairo_stroke_style_t current_style;
163     cairo_pattern_union_t current_source;
164     cairo_matrix_t current_ctm;
165     cairo_matrix_t current_stroke_matrix;
166     cairo_matrix_t current_font_matrix;
167     cairo_font_options_t current_font_options;
168     cairo_scaled_font_t *current_scaled_font;
169     cairo_path_fixed_t current_path;
170     cairo_bool_t has_clip;
171 };
172
173 struct _cairo_script_surface {
174     cairo_surface_t base;
175
176     cairo_surface_wrapper_t wrapper;
177
178     cairo_surface_clipper_t clipper;
179
180     operand_t operand;
181     cairo_bool_t emitted;
182     cairo_bool_t defined;
183     cairo_bool_t active;
184
185     double width, height;
186
187     /* implicit flattened context */
188     cairo_script_implicit_context_t cr;
189 };
190
191 static const cairo_surface_backend_t _cairo_script_surface_backend;
192
193 static cairo_script_surface_t *
194 _cairo_script_surface_create_internal (cairo_script_context_t *ctx,
195                                        cairo_content_t content,
196                                        cairo_rectangle_t *extents,
197                                        cairo_surface_t *passthrough);
198
199 static void
200 _cairo_script_scaled_font_fini (cairo_scaled_font_private_t *abstract_private,
201                                 cairo_scaled_font_t *scaled_font);
202
203 static void
204 _cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr);
205
206 static void
207 _cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr);
208
209 static void
210 _bitmap_release_id (struct _bitmap *b, unsigned long token)
211 {
212     struct _bitmap **prev = NULL;
213
214     do {
215         if (token < b->min + sizeof (b->map) * CHAR_BIT) {
216             unsigned int bit, elem;
217
218             token -= b->min;
219             elem = token / (sizeof (b->map[0]) * CHAR_BIT);
220             bit  = token % (sizeof (b->map[0]) * CHAR_BIT);
221             b->map[elem] &= ~(1 << bit);
222             if (! --b->count && prev) {
223                 *prev = b->next;
224                 free (b);
225             }
226             return;
227         }
228         prev = &b->next;
229         b = b->next;
230     } while (b != NULL);
231 }
232
233 static cairo_status_t
234 _bitmap_next_id (struct _bitmap *b,
235                  unsigned long *id)
236 {
237     struct _bitmap *bb, **prev = NULL;
238     unsigned long min = 0;
239
240     do {
241         if (b->min != min)
242             break;
243
244         if (b->count < sizeof (b->map) * CHAR_BIT) {
245             unsigned int n, m, bit;
246             for (n = 0; n < ARRAY_LENGTH (b->map); n++) {
247                 if (b->map[n] == (unsigned int) -1)
248                     continue;
249
250                 for (m=0, bit=1; m<sizeof (b->map[0])*CHAR_BIT; m++, bit<<=1) {
251                     if ((b->map[n] & bit) == 0) {
252                         b->map[n] |= bit;
253                         b->count++;
254                         *id = n * sizeof (b->map[0])*CHAR_BIT + m + b->min;
255                         return CAIRO_STATUS_SUCCESS;
256                     }
257                 }
258             }
259         }
260         min += sizeof (b->map) * CHAR_BIT;
261
262         prev = &b->next;
263         b = b->next;
264     } while (b != NULL);
265
266     bb = malloc (sizeof (struct _bitmap));
267     if (unlikely (bb == NULL))
268         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
269
270     *prev = bb;
271     bb->next = b;
272     bb->min = min;
273     bb->count = 1;
274     bb->map[0] = 0x1;
275     memset (bb->map + 1, 0, sizeof (bb->map) - sizeof (bb->map[0]));
276     *id = min;
277
278     return CAIRO_STATUS_SUCCESS;
279 }
280
281 static void
282 _bitmap_fini (struct _bitmap *b)
283 {
284     while (b != NULL) {
285         struct _bitmap *next = b->next;
286         free (b);
287         b = next;
288     }
289 }
290
291 static const char *
292 _direction_to_string (cairo_bool_t backward)
293 {
294     static const char *names[] = {
295         "FORWARD",
296         "BACKWARD"
297     };
298     assert (backward < ARRAY_LENGTH (names));
299     return names[backward];
300 }
301
302 static const char *
303 _operator_to_string (cairo_operator_t op)
304 {
305     static const char *names[] = {
306         "CLEAR",        /* CAIRO_OPERATOR_CLEAR */
307
308         "SOURCE",       /* CAIRO_OPERATOR_SOURCE */
309         "OVER",         /* CAIRO_OPERATOR_OVER */
310         "IN",           /* CAIRO_OPERATOR_IN */
311         "OUT",          /* CAIRO_OPERATOR_OUT */
312         "ATOP",         /* CAIRO_OPERATOR_ATOP */
313
314         "DEST",         /* CAIRO_OPERATOR_DEST */
315         "DEST_OVER",    /* CAIRO_OPERATOR_DEST_OVER */
316         "DEST_IN",      /* CAIRO_OPERATOR_DEST_IN */
317         "DEST_OUT",     /* CAIRO_OPERATOR_DEST_OUT */
318         "DEST_ATOP",    /* CAIRO_OPERATOR_DEST_ATOP */
319
320         "XOR",          /* CAIRO_OPERATOR_XOR */
321         "ADD",          /* CAIRO_OPERATOR_ADD */
322         "SATURATE",     /* CAIRO_OPERATOR_SATURATE */
323
324         "MULTIPLY",     /* CAIRO_OPERATOR_MULTIPLY */
325         "SCREEN",       /* CAIRO_OPERATOR_SCREEN */
326         "OVERLAY",      /* CAIRO_OPERATOR_OVERLAY */
327         "DARKEN",       /* CAIRO_OPERATOR_DARKEN */
328         "LIGHTEN",      /* CAIRO_OPERATOR_LIGHTEN */
329         "DODGE",        /* CAIRO_OPERATOR_COLOR_DODGE */
330         "BURN",         /* CAIRO_OPERATOR_COLOR_BURN */
331         "HARD_LIGHT",   /* CAIRO_OPERATOR_HARD_LIGHT */
332         "SOFT_LIGHT",   /* CAIRO_OPERATOR_SOFT_LIGHT */
333         "DIFFERENCE",   /* CAIRO_OPERATOR_DIFFERENCE */
334         "EXCLUSION",    /* CAIRO_OPERATOR_EXCLUSION */
335         "HSL_HUE",      /* CAIRO_OPERATOR_HSL_HUE */
336         "HSL_SATURATION", /* CAIRO_OPERATOR_HSL_SATURATION */
337         "HSL_COLOR",    /* CAIRO_OPERATOR_HSL_COLOR */
338         "HSL_LUMINOSITY" /* CAIRO_OPERATOR_HSL_LUMINOSITY */
339     };
340     assert (op < ARRAY_LENGTH (names));
341     return names[op];
342 }
343
344 static const char *
345 _extend_to_string (cairo_extend_t extend)
346 {
347     static const char *names[] = {
348         "EXTEND_NONE",          /* CAIRO_EXTEND_NONE */
349         "EXTEND_REPEAT",        /* CAIRO_EXTEND_REPEAT */
350         "EXTEND_REFLECT",       /* CAIRO_EXTEND_REFLECT */
351         "EXTEND_PAD"            /* CAIRO_EXTEND_PAD */
352     };
353     assert (extend < ARRAY_LENGTH (names));
354     return names[extend];
355 }
356
357 static const char *
358 _filter_to_string (cairo_filter_t filter)
359 {
360     static const char *names[] = {
361         "FILTER_FAST",          /* CAIRO_FILTER_FAST */
362         "FILTER_GOOD",          /* CAIRO_FILTER_GOOD */
363         "FILTER_BEST",          /* CAIRO_FILTER_BEST */
364         "FILTER_NEAREST",       /* CAIRO_FILTER_NEAREST */
365         "FILTER_BILINEAR",      /* CAIRO_FILTER_BILINEAR */
366         "FILTER_GAUSSIAN",      /* CAIRO_FILTER_GAUSSIAN */
367     };
368     assert (filter < ARRAY_LENGTH (names));
369     return names[filter];
370 }
371
372 static const char *
373 _fill_rule_to_string (cairo_fill_rule_t rule)
374 {
375     static const char *names[] = {
376         "WINDING",      /* CAIRO_FILL_RULE_WINDING */
377         "EVEN_ODD"      /* CAIRO_FILL_RILE_EVEN_ODD */
378     };
379     assert (rule < ARRAY_LENGTH (names));
380     return names[rule];
381 }
382
383 static const char *
384 _antialias_to_string (cairo_antialias_t antialias)
385 {
386     static const char *names[] = {
387         "ANTIALIAS_DEFAULT",    /* CAIRO_ANTIALIAS_DEFAULT */
388         "ANTIALIAS_NONE",       /* CAIRO_ANTIALIAS_NONE */
389         "ANTIALIAS_GRAY",       /* CAIRO_ANTIALIAS_GRAY */
390         "ANTIALIAS_SUBPIXEL",   /* CAIRO_ANTIALIAS_SUBPIXEL */
391         "ANTIALIAS_FAST",       /* CAIRO_ANTIALIAS_FAST */
392         "ANTIALIAS_GOOD",       /* CAIRO_ANTIALIAS_GOOD */
393         "ANTIALIAS_BEST"        /* CAIRO_ANTIALIAS_BEST */
394     };
395     assert (antialias < ARRAY_LENGTH (names));
396     return names[antialias];
397 }
398
399 static const char *
400 _line_cap_to_string (cairo_line_cap_t line_cap)
401 {
402     static const char *names[] = {
403         "LINE_CAP_BUTT",        /* CAIRO_LINE_CAP_BUTT */
404         "LINE_CAP_ROUND",       /* CAIRO_LINE_CAP_ROUND */
405         "LINE_CAP_SQUARE"       /* CAIRO_LINE_CAP_SQUARE */
406     };
407     assert (line_cap < ARRAY_LENGTH (names));
408     return names[line_cap];
409 }
410
411 static const char *
412 _line_join_to_string (cairo_line_join_t line_join)
413 {
414     static const char *names[] = {
415         "LINE_JOIN_MITER",      /* CAIRO_LINE_JOIN_MITER */
416         "LINE_JOIN_ROUND",      /* CAIRO_LINE_JOIN_ROUND */
417         "LINE_JOIN_BEVEL",      /* CAIRO_LINE_JOIN_BEVEL */
418     };
419     assert (line_join < ARRAY_LENGTH (names));
420     return names[line_join];
421 }
422
423 static inline cairo_script_context_t *
424 to_context (cairo_script_surface_t *surface)
425 {
426     return (cairo_script_context_t *) surface->base.device;
427 }
428
429 static cairo_bool_t
430 target_is_active (cairo_script_surface_t *surface)
431 {
432     return cairo_list_is_first (&surface->operand.link,
433                                 &to_context (surface)->operands);
434 }
435
436 static void
437 target_push (cairo_script_surface_t *surface)
438 {
439     cairo_list_move (&surface->operand.link, &to_context (surface)->operands);
440 }
441
442 static int
443 target_depth (cairo_script_surface_t *surface)
444 {
445     cairo_list_t *link;
446     int depth = 0;
447
448     cairo_list_foreach (link, &to_context (surface)->operands) {
449         if (link == &surface->operand.link)
450             break;
451         depth++;
452     }
453
454     return depth;
455 }
456
457 static void
458 _get_target (cairo_script_surface_t *surface)
459 {
460     cairo_script_context_t *ctx = to_context (surface);
461
462     if (target_is_active (surface)) {
463         _cairo_output_stream_puts (ctx->stream, "dup ");
464         return;
465     }
466
467     if (surface->defined) {
468         _cairo_output_stream_printf (ctx->stream, "s%u ",
469                                      surface->base.unique_id);
470     } else {
471         int depth = target_depth (surface);
472
473         assert (! cairo_list_is_empty (&surface->operand.link));
474         assert (! target_is_active (surface));
475
476         if (ctx->active) {
477             _cairo_output_stream_printf (ctx->stream, "%d index ", depth);
478             _cairo_output_stream_puts (ctx->stream, "/target get exch pop ");
479         } else {
480             if (depth == 1) {
481                 _cairo_output_stream_puts (ctx->stream, "exch ");
482             } else {
483                 _cairo_output_stream_printf (ctx->stream,
484                                              "%d -1 roll ", depth);
485             }
486             target_push (surface);
487             _cairo_output_stream_puts (ctx->stream, "dup ");
488         }
489     }
490 }
491
492 static const char *
493 _content_to_string (cairo_content_t content)
494 {
495     switch (content) {
496     case CAIRO_CONTENT_ALPHA: return "ALPHA";
497     case CAIRO_CONTENT_COLOR: return "COLOR";
498     default:
499     case CAIRO_CONTENT_COLOR_ALPHA: return "COLOR_ALPHA";
500     }
501 }
502
503 static cairo_status_t
504 _emit_surface (cairo_script_surface_t *surface)
505 {
506     cairo_script_context_t *ctx = to_context (surface);
507
508     _cairo_output_stream_printf (ctx->stream,
509                                  "<< /content //%s",
510                                  _content_to_string (surface->base.content));
511     if (surface->width != -1 && surface->height != -1) {
512         _cairo_output_stream_printf (ctx->stream,
513                                      " /width %f /height %f",
514                                      surface->width,
515                                      surface->height);
516     }
517
518     if (surface->base.x_fallback_resolution !=
519         CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT ||
520         surface->base.y_fallback_resolution !=
521         CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT)
522     {
523         _cairo_output_stream_printf (ctx->stream,
524                                      " /fallback-resolution [%f %f]",
525                                      surface->base.x_fallback_resolution,
526                                      surface->base.y_fallback_resolution);
527     }
528
529     if (surface->base.device_transform.x0 != 0. ||
530         surface->base.device_transform.y0 != 0.)
531     {
532         /* XXX device offset is encoded into the pattern matrices etc. */
533         if (0) {
534         _cairo_output_stream_printf (ctx->stream,
535                                      " /device-offset [%f %f]",
536                                      surface->base.device_transform.x0,
537                                      surface->base.device_transform.y0);
538         }
539     }
540
541     _cairo_output_stream_puts (ctx->stream, " >> surface context\n");
542     surface->emitted = TRUE;
543     return CAIRO_STATUS_SUCCESS;
544 }
545
546 static cairo_status_t
547 _emit_context (cairo_script_surface_t *surface)
548 {
549     cairo_script_context_t *ctx = to_context (surface);
550
551     if (target_is_active (surface))
552         return CAIRO_STATUS_SUCCESS;
553
554     while (! cairo_list_is_empty (&ctx->operands)) {
555         operand_t *op;
556         cairo_script_surface_t *old;
557
558         op = cairo_list_first_entry (&ctx->operands,
559                                      operand_t,
560                                      link);
561         if (op->type == DEFERRED)
562             break;
563
564         old = cairo_container_of (op, cairo_script_surface_t, operand);
565         if (old == surface)
566             break;
567         if (old->active)
568             break;
569
570         if (! old->defined) {
571             assert (old->emitted);
572             _cairo_output_stream_printf (ctx->stream,
573                                          "/target get /s%u exch def pop\n",
574                                          old->base.unique_id);
575             old->defined = TRUE;
576         } else {
577             _cairo_output_stream_puts (ctx->stream, "pop\n");
578         }
579
580         cairo_list_del (&old->operand.link);
581     }
582
583     if (target_is_active (surface))
584         return CAIRO_STATUS_SUCCESS;
585
586     if (! surface->emitted) {
587         cairo_status_t status;
588
589         status = _emit_surface (surface);
590         if (unlikely (status))
591             return status;
592     } else if (cairo_list_is_empty (&surface->operand.link)) {
593         assert (surface->defined);
594         _cairo_output_stream_printf (ctx->stream,
595                                      "s%u context\n",
596                                      surface->base.unique_id);
597         _cairo_script_implicit_context_reset (&surface->cr);
598         _cairo_surface_clipper_reset (&surface->clipper);
599     } else {
600         int depth = target_depth (surface);
601         if (depth == 1) {
602             _cairo_output_stream_puts (ctx->stream, "exch\n");
603         } else {
604             _cairo_output_stream_printf (ctx->stream,
605                                          "%d -1 roll\n",
606                                          depth);
607         }
608     }
609     target_push (surface);
610
611     return CAIRO_STATUS_SUCCESS;
612 }
613
614 static cairo_status_t
615 _emit_operator (cairo_script_surface_t *surface,
616                 cairo_operator_t op)
617 {
618     assert (target_is_active (surface));
619
620     if (surface->cr.current_operator == op)
621         return CAIRO_STATUS_SUCCESS;
622
623     surface->cr.current_operator = op;
624
625     _cairo_output_stream_printf (to_context (surface)->stream,
626                                  "//%s set-operator\n",
627                                  _operator_to_string (op));
628     return CAIRO_STATUS_SUCCESS;
629 }
630
631 static cairo_status_t
632 _emit_fill_rule (cairo_script_surface_t *surface,
633                  cairo_fill_rule_t fill_rule)
634 {
635     assert (target_is_active (surface));
636
637     if (surface->cr.current_fill_rule == fill_rule)
638         return CAIRO_STATUS_SUCCESS;
639
640     surface->cr.current_fill_rule = fill_rule;
641
642     _cairo_output_stream_printf (to_context (surface)->stream,
643                                  "//%s set-fill-rule\n",
644                                  _fill_rule_to_string (fill_rule));
645     return CAIRO_STATUS_SUCCESS;
646 }
647
648 static cairo_status_t
649 _emit_tolerance (cairo_script_surface_t *surface,
650                  double tolerance,
651                  cairo_bool_t force)
652 {
653     assert (target_is_active (surface));
654
655     if ((! force ||
656          fabs (tolerance - CAIRO_GSTATE_TOLERANCE_DEFAULT) < 1e-5) &&
657         surface->cr.current_tolerance == tolerance)
658     {
659         return CAIRO_STATUS_SUCCESS;
660     }
661
662     surface->cr.current_tolerance = tolerance;
663
664     _cairo_output_stream_printf (to_context (surface)->stream,
665                                  "%f set-tolerance\n",
666                                  tolerance);
667     return CAIRO_STATUS_SUCCESS;
668 }
669
670 static cairo_status_t
671 _emit_antialias (cairo_script_surface_t *surface,
672                  cairo_antialias_t antialias)
673 {
674     assert (target_is_active (surface));
675
676     if (surface->cr.current_antialias == antialias)
677         return CAIRO_STATUS_SUCCESS;
678
679     surface->cr.current_antialias = antialias;
680
681     _cairo_output_stream_printf (to_context (surface)->stream,
682                                  "//%s set-antialias\n",
683                                  _antialias_to_string (antialias));
684
685     return CAIRO_STATUS_SUCCESS;
686 }
687
688 static cairo_status_t
689 _emit_line_width (cairo_script_surface_t *surface,
690                  double line_width,
691                  cairo_bool_t force)
692 {
693     assert (target_is_active (surface));
694
695     if ((! force ||
696          fabs (line_width - CAIRO_GSTATE_LINE_WIDTH_DEFAULT) < 1e-5) &&
697         surface->cr.current_style.line_width == line_width)
698     {
699         return CAIRO_STATUS_SUCCESS;
700     }
701
702     surface->cr.current_style.line_width = line_width;
703
704     _cairo_output_stream_printf (to_context (surface)->stream,
705                                  "%f set-line-width\n",
706                                  line_width);
707     return CAIRO_STATUS_SUCCESS;
708 }
709
710 static cairo_status_t
711 _emit_line_cap (cairo_script_surface_t *surface,
712                 cairo_line_cap_t line_cap)
713 {
714     assert (target_is_active (surface));
715
716     if (surface->cr.current_style.line_cap == line_cap)
717         return CAIRO_STATUS_SUCCESS;
718
719     surface->cr.current_style.line_cap = line_cap;
720
721     _cairo_output_stream_printf (to_context (surface)->stream,
722                                  "//%s set-line-cap\n",
723                                  _line_cap_to_string (line_cap));
724     return CAIRO_STATUS_SUCCESS;
725 }
726
727 static cairo_status_t
728 _emit_line_join (cairo_script_surface_t *surface,
729                  cairo_line_join_t line_join)
730 {
731     assert (target_is_active (surface));
732
733     if (surface->cr.current_style.line_join == line_join)
734         return CAIRO_STATUS_SUCCESS;
735
736     surface->cr.current_style.line_join = line_join;
737
738     _cairo_output_stream_printf (to_context (surface)->stream,
739                                  "//%s set-line-join\n",
740                                  _line_join_to_string (line_join));
741     return CAIRO_STATUS_SUCCESS;
742 }
743
744 static cairo_status_t
745 _emit_miter_limit (cairo_script_surface_t *surface,
746                    double miter_limit,
747                    cairo_bool_t force)
748 {
749     assert (target_is_active (surface));
750
751     if ((! force ||
752          fabs (miter_limit - CAIRO_GSTATE_MITER_LIMIT_DEFAULT) < 1e-5) &&
753         surface->cr.current_style.miter_limit == miter_limit)
754     {
755         return CAIRO_STATUS_SUCCESS;
756     }
757
758     surface->cr.current_style.miter_limit = miter_limit;
759
760     _cairo_output_stream_printf (to_context (surface)->stream,
761                                  "%f set-miter-limit\n",
762                                  miter_limit);
763     return CAIRO_STATUS_SUCCESS;
764 }
765
766 static cairo_bool_t
767 _dashes_equal (const double *a, const double *b, int num_dashes)
768 {
769     while (num_dashes--) {
770         if (fabs (*a - *b) > 1e-5)
771             return FALSE;
772         a++, b++;
773     }
774
775     return TRUE;
776 }
777
778 static cairo_status_t
779 _emit_dash (cairo_script_surface_t *surface,
780             const double *dash,
781             unsigned int num_dashes,
782             double offset,
783             cairo_bool_t force)
784 {
785     unsigned int n;
786
787     assert (target_is_active (surface));
788
789     if (force &&
790         num_dashes == 0 &&
791         surface->cr.current_style.num_dashes == 0)
792     {
793         return CAIRO_STATUS_SUCCESS;
794     }
795
796     if (! force &&
797         (surface->cr.current_style.num_dashes == num_dashes &&
798          (num_dashes == 0 ||
799           (fabs (surface->cr.current_style.dash_offset - offset) < 1e-5 &&
800            _dashes_equal (surface->cr.current_style.dash, dash, num_dashes)))))
801     {
802         return CAIRO_STATUS_SUCCESS;
803     }
804
805
806     if (num_dashes) {
807         surface->cr.current_style.dash = _cairo_realloc_ab
808             (surface->cr.current_style.dash, num_dashes, sizeof (double));
809         if (unlikely (surface->cr.current_style.dash == NULL))
810             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
811
812         memcpy (surface->cr.current_style.dash, dash,
813                 sizeof (double) * num_dashes);
814     } else {
815         free (surface->cr.current_style.dash);
816         surface->cr.current_style.dash = NULL;
817     }
818
819     surface->cr.current_style.num_dashes = num_dashes;
820     surface->cr.current_style.dash_offset = offset;
821
822     _cairo_output_stream_puts (to_context (surface)->stream, "[");
823     for (n = 0; n < num_dashes; n++) {
824         _cairo_output_stream_printf (to_context (surface)->stream, "%f", dash[n]);
825         if (n < num_dashes-1)
826             _cairo_output_stream_puts (to_context (surface)->stream, " ");
827     }
828     _cairo_output_stream_printf (to_context (surface)->stream,
829                                  "] %f set-dash\n",
830                                  offset);
831
832     return CAIRO_STATUS_SUCCESS;
833 }
834
835 static cairo_status_t
836 _emit_stroke_style (cairo_script_surface_t *surface,
837                     const cairo_stroke_style_t *style,
838                     cairo_bool_t force)
839 {
840     cairo_status_t status;
841
842     assert (target_is_active (surface));
843
844     status = _emit_line_width (surface, style->line_width, force);
845     if (unlikely (status))
846         return status;
847
848     status = _emit_line_cap (surface, style->line_cap);
849     if (unlikely (status))
850         return status;
851
852     status = _emit_line_join (surface, style->line_join);
853     if (unlikely (status))
854         return status;
855
856     status = _emit_miter_limit (surface, style->miter_limit, force);
857     if (unlikely (status))
858         return status;
859
860     status = _emit_dash (surface,
861                          style->dash, style->num_dashes, style->dash_offset,
862                          force);
863     if (unlikely (status))
864         return status;
865
866     return CAIRO_STATUS_SUCCESS;
867 }
868
869 static const char *
870 _format_to_string (cairo_format_t format)
871 {
872     switch (format) {
873     case CAIRO_FORMAT_ARGB32:  return "ARGB32";
874     case CAIRO_FORMAT_RGB30:   return "RGB30";
875     case CAIRO_FORMAT_RGB24:   return "RGB24";
876     case CAIRO_FORMAT_RGB16_565: return "RGB16_565";
877     case CAIRO_FORMAT_A8:      return "A8";
878     case CAIRO_FORMAT_A1:      return "A1";
879     case CAIRO_FORMAT_INVALID: return "INVALID";
880     }
881     ASSERT_NOT_REACHED;
882     return "INVALID";
883 }
884
885 static cairo_status_t
886 _emit_solid_pattern (cairo_script_surface_t *surface,
887                      const cairo_pattern_t *pattern)
888 {
889     cairo_solid_pattern_t *solid = (cairo_solid_pattern_t *) pattern;
890     cairo_script_context_t *ctx = to_context (surface);
891
892     if (! CAIRO_COLOR_IS_OPAQUE (&solid->color))
893     {
894         if (! (surface->base.content & CAIRO_CONTENT_COLOR) ||
895             ((solid->color.red_short   == 0 || solid->color.red_short   == 0xffff) &&
896              (solid->color.green_short == 0 || solid->color.green_short == 0xffff) &&
897              (solid->color.blue_short  == 0 || solid->color.blue_short  == 0xffff) ))
898         {
899             _cairo_output_stream_printf (ctx->stream,
900                                          "%f a",
901                                          solid->color.alpha);
902         }
903         else
904         {
905             _cairo_output_stream_printf (ctx->stream,
906                                          "%f %f %f %f rgba",
907                                          solid->color.red,
908                                          solid->color.green,
909                                          solid->color.blue,
910                                          solid->color.alpha);
911         }
912     }
913     else
914     {
915         if (solid->color.red_short == solid->color.green_short &&
916             solid->color.red_short == solid->color.blue_short)
917         {
918             _cairo_output_stream_printf (ctx->stream,
919                                          "%f g",
920                                          solid->color.red);
921         }
922         else
923         {
924             _cairo_output_stream_printf (ctx->stream,
925                                          "%f %f %f rgb",
926                                          solid->color.red,
927                                          solid->color.green,
928                                          solid->color.blue);
929         }
930     }
931
932     return CAIRO_STATUS_SUCCESS;
933 }
934
935
936 static cairo_status_t
937 _emit_gradient_color_stops (cairo_gradient_pattern_t *gradient,
938                             cairo_output_stream_t *output)
939 {
940     unsigned int n;
941
942     for (n = 0; n < gradient->n_stops; n++) {
943         _cairo_output_stream_printf (output,
944                                      "\n  %f %f %f %f %f add-color-stop",
945                                      gradient->stops[n].offset,
946                                      gradient->stops[n].color.red,
947                                      gradient->stops[n].color.green,
948                                      gradient->stops[n].color.blue,
949                                      gradient->stops[n].color.alpha);
950     }
951
952     return CAIRO_STATUS_SUCCESS;
953 }
954
955 static cairo_status_t
956 _emit_linear_pattern (cairo_script_surface_t *surface,
957                       const cairo_pattern_t *pattern)
958 {
959     cairo_script_context_t *ctx = to_context (surface);
960     cairo_linear_pattern_t *linear;
961
962     linear = (cairo_linear_pattern_t *) pattern;
963
964     _cairo_output_stream_printf (ctx->stream,
965                                  "%f %f %f %f linear",
966                                  linear->pd1.x, linear->pd1.y,
967                                  linear->pd2.x, linear->pd2.y);
968     return _emit_gradient_color_stops (&linear->base, ctx->stream);
969 }
970
971 static cairo_status_t
972 _emit_radial_pattern (cairo_script_surface_t *surface,
973                       const cairo_pattern_t *pattern)
974 {
975     cairo_script_context_t *ctx = to_context (surface);
976     cairo_radial_pattern_t *radial;
977
978     radial = (cairo_radial_pattern_t *) pattern;
979
980     _cairo_output_stream_printf (ctx->stream,
981                                  "%f %f %f %f %f %f radial",
982                                  radial->cd1.center.x,
983                                  radial->cd1.center.y,
984                                  radial->cd1.radius,
985                                  radial->cd2.center.x,
986                                  radial->cd2.center.y,
987                                  radial->cd2.radius);
988     return _emit_gradient_color_stops (&radial->base, ctx->stream);
989 }
990
991 static cairo_status_t
992 _emit_mesh_pattern (cairo_script_surface_t *surface,
993                     const cairo_pattern_t *pattern)
994 {
995     cairo_script_context_t *ctx = to_context (surface);
996     cairo_pattern_t *mesh;
997     cairo_status_t status;
998     unsigned int i, n;
999
1000     mesh = (cairo_pattern_t *) pattern;
1001     status = cairo_mesh_pattern_get_patch_count (mesh, &n);
1002     if (unlikely (status))
1003         return status;
1004
1005     _cairo_output_stream_printf (ctx->stream, "mesh");
1006     for (i = 0; i < n; i++) {
1007         cairo_path_t *path;
1008         cairo_path_data_t *data;
1009         int j;
1010
1011         _cairo_output_stream_printf (ctx->stream, "\n  begin-patch");
1012
1013         path = cairo_mesh_pattern_get_path (mesh, i);
1014         if (unlikely (path->status))
1015             return path->status;
1016
1017         for (j = 0; j < path->num_data; j+=data[0].header.length) {
1018             data = &path->data[j];
1019             switch (data->header.type) {
1020             case CAIRO_PATH_MOVE_TO:
1021                 _cairo_output_stream_printf (ctx->stream,
1022                                              "\n  %f %f m",
1023                                              data[1].point.x, data[1].point.y);
1024                 break;
1025             case CAIRO_PATH_LINE_TO:
1026                 _cairo_output_stream_printf (ctx->stream,
1027                                              "\n  %f %f l",
1028                                              data[1].point.x, data[1].point.y);
1029                 break;
1030             case CAIRO_PATH_CURVE_TO:
1031                 _cairo_output_stream_printf (ctx->stream,
1032                                              "\n  %f %f %f %f %f %f c",
1033                                              data[1].point.x, data[1].point.y,
1034                                              data[2].point.x, data[2].point.y,
1035                                              data[3].point.x, data[3].point.y);
1036                 break;
1037             case CAIRO_PATH_CLOSE_PATH:
1038                 break;
1039             }
1040         }
1041         cairo_path_destroy (path);
1042
1043         for (j = 0; j < 4; j++) {
1044             double x, y;
1045
1046             status = cairo_mesh_pattern_get_control_point (mesh, i, j, &x, &y);
1047             if (unlikely (status))
1048                 return status;
1049             _cairo_output_stream_printf (ctx->stream,
1050                                          "\n  %d %f %f set-control-point",
1051                                          j, x, y);
1052         }
1053
1054         for (j = 0; j < 4; j++) {
1055             double r, g, b, a;
1056
1057             status = cairo_mesh_pattern_get_corner_color_rgba (mesh, i, j, &r, &g, &b, &a);
1058             if (unlikely (status))
1059                 return status;
1060
1061             _cairo_output_stream_printf (ctx->stream,
1062                                          "\n  %d %f %f %f %f set-corner-color",
1063                                          j, r, g, b, a);
1064         }
1065
1066         _cairo_output_stream_printf (ctx->stream, "\n  end-patch");
1067     }
1068
1069     return CAIRO_STATUS_SUCCESS;
1070 }
1071
1072 struct script_snapshot {
1073     cairo_surface_t base;
1074 };
1075
1076 static cairo_status_t
1077 script_snapshot_finish (void *abstract_surface)
1078 {
1079     return CAIRO_STATUS_SUCCESS;
1080 }
1081
1082 static const cairo_surface_backend_t script_snapshot_backend = {
1083     CAIRO_SURFACE_TYPE_SCRIPT,
1084     script_snapshot_finish,
1085 };
1086
1087 static void
1088 detach_snapshot (cairo_surface_t *abstract_surface)
1089 {
1090     cairo_script_surface_t *surface = (cairo_script_surface_t *)abstract_surface;
1091     cairo_script_context_t *ctx = to_context (surface);
1092
1093     _cairo_output_stream_printf (ctx->stream,
1094                                  "/s%d undef\n",
1095                                  surface->base.unique_id);
1096 }
1097
1098 static void
1099 attach_snapshot (cairo_script_context_t *ctx,
1100                  cairo_surface_t *source)
1101 {
1102     struct script_snapshot *surface;
1103
1104     if (! ctx->attach_snapshots)
1105         return;
1106
1107     surface = malloc (sizeof (*surface));
1108     if (unlikely (surface == NULL))
1109         return;
1110
1111     _cairo_surface_init (&surface->base,
1112                          &script_snapshot_backend,
1113                          &ctx->base,
1114                          source->content);
1115
1116     _cairo_output_stream_printf (ctx->stream,
1117                                  "dup /s%d exch def ",
1118                                  surface->base.unique_id);
1119
1120     _cairo_surface_attach_snapshot (source, &surface->base, detach_snapshot);
1121     cairo_surface_destroy (&surface->base);
1122 }
1123
1124 static cairo_status_t
1125 _emit_recording_surface_pattern (cairo_script_surface_t *surface,
1126                                  cairo_recording_surface_t *source)
1127 {
1128     cairo_script_implicit_context_t old_cr;
1129     cairo_script_context_t *ctx = to_context (surface);
1130     cairo_script_surface_t *similar;
1131     cairo_surface_t *snapshot;
1132     cairo_rectangle_t r, *extents;
1133     cairo_status_t status;
1134
1135     snapshot = _cairo_surface_has_snapshot (&source->base, &script_snapshot_backend);
1136     if (snapshot) {
1137         _cairo_output_stream_printf (ctx->stream, "s%d", snapshot->unique_id);
1138         return CAIRO_INT_STATUS_SUCCESS;
1139     }
1140
1141     extents = NULL;
1142     if (_cairo_recording_surface_get_bounds (&source->base, &r))
1143         extents = &r;
1144
1145     similar = _cairo_script_surface_create_internal (ctx,
1146                                                      source->base.content,
1147                                                      extents,
1148                                                      NULL);
1149     if (unlikely (similar->base.status))
1150         return similar->base.status;
1151
1152     similar->base.is_clear = TRUE;
1153
1154     _cairo_output_stream_printf (ctx->stream, "//%s ",
1155                                  _content_to_string (source->base.content));
1156     if (extents) {
1157         _cairo_output_stream_printf (ctx->stream, "[%f %f %f %f]",
1158                                      extents->x, extents->y,
1159                                      extents->width, extents->height);
1160     } else
1161         _cairo_output_stream_puts (ctx->stream, "[]");
1162     _cairo_output_stream_puts (ctx->stream, " record\n");
1163
1164     attach_snapshot (ctx, &source->base);
1165
1166     _cairo_output_stream_puts (ctx->stream, "dup context\n");
1167
1168     target_push (similar);
1169     similar->emitted = TRUE;
1170
1171
1172     old_cr = surface->cr;
1173     _cairo_script_implicit_context_init (&surface->cr);
1174     status = _cairo_recording_surface_replay (&source->base, &similar->base);
1175     surface->cr = old_cr;
1176
1177     if (unlikely (status)) {
1178         cairo_surface_destroy (&similar->base);
1179         return status;
1180     }
1181
1182     cairo_list_del (&similar->operand.link);
1183     assert (target_is_active (surface));
1184
1185     _cairo_output_stream_puts (ctx->stream, "pop ");
1186     cairo_surface_destroy (&similar->base);
1187
1188     return CAIRO_STATUS_SUCCESS;
1189 }
1190
1191 static cairo_status_t
1192 _emit_script_surface_pattern (cairo_script_surface_t *surface,
1193                               cairo_script_surface_t *source)
1194 {
1195     _get_target (source);
1196
1197     return CAIRO_STATUS_SUCCESS;
1198 }
1199
1200 static cairo_status_t
1201 _write_image_surface (cairo_output_stream_t *output,
1202                       const cairo_image_surface_t *image)
1203 {
1204     int stride, row, width;
1205     uint8_t row_stack[CAIRO_STACK_BUFFER_SIZE];
1206     uint8_t *rowdata;
1207     uint8_t *data;
1208
1209     stride = image->stride;
1210     width = image->width;
1211     data = image->data;
1212 #if WORDS_BIGENDIAN
1213     switch (image->format) {
1214     case CAIRO_FORMAT_A1:
1215         for (row = image->height; row--; ) {
1216             _cairo_output_stream_write (output, data, (width+7)/8);
1217             data += stride;
1218         }
1219         break;
1220     case CAIRO_FORMAT_A8:
1221         for (row = image->height; row--; ) {
1222             _cairo_output_stream_write (output, data, width);
1223             data += stride;
1224         }
1225         break;
1226     case CAIRO_FORMAT_RGB16_565:
1227         for (row = image->height; row--; ) {
1228             _cairo_output_stream_write (output, data, 2*width);
1229             data += stride;
1230         }
1231         break;
1232     case CAIRO_FORMAT_RGB24:
1233         for (row = image->height; row--; ) {
1234             int col;
1235             rowdata = data;
1236             for (col = width; col--; ) {
1237                 _cairo_output_stream_write (output, rowdata, 3);
1238                 rowdata+=4;
1239             }
1240             data += stride;
1241         }
1242         break;
1243     case CAIRO_FORMAT_ARGB32:
1244         for (row = image->height; row--; ) {
1245             _cairo_output_stream_write (output, data, 4*width);
1246             data += stride;
1247         }
1248         break;
1249     case CAIRO_FORMAT_INVALID:
1250     default:
1251         ASSERT_NOT_REACHED;
1252         break;
1253     }
1254 #else
1255     if (stride > ARRAY_LENGTH (row_stack)) {
1256         rowdata = malloc (stride);
1257         if (unlikely (rowdata == NULL))
1258             return _cairo_error (CAIRO_STATUS_NO_MEMORY);
1259     } else
1260         rowdata = row_stack;
1261
1262     switch (image->format) {
1263     case CAIRO_FORMAT_A1:
1264         for (row = image->height; row--; ) {
1265             int col;
1266             for (col = 0; col < (width + 7)/8; col++)
1267                 rowdata[col] = CAIRO_BITSWAP8 (data[col]);
1268             _cairo_output_stream_write (output, rowdata, (width+7)/8);
1269             data += stride;
1270         }
1271         break;
1272     case CAIRO_FORMAT_A8:
1273         for (row = image->height; row--; ) {
1274             _cairo_output_stream_write (output, data, width);
1275             data += stride;
1276         }
1277         break;
1278     case CAIRO_FORMAT_RGB16_565:
1279         for (row = image->height; row--; ) {
1280             uint16_t *src = (uint16_t *) data;
1281             uint16_t *dst = (uint16_t *) rowdata;
1282             int col;
1283             for (col = 0; col < width; col++)
1284                 dst[col] = bswap_16 (src[col]);
1285             _cairo_output_stream_write (output, rowdata, 2*width);
1286             data += stride;
1287         }
1288         break;
1289     case CAIRO_FORMAT_RGB24:
1290         for (row = image->height; row--; ) {
1291             uint8_t *src = data;
1292             int col;
1293             for (col = 0; col < width; col++) {
1294                 rowdata[3*col+2] = *src++;
1295                 rowdata[3*col+1] = *src++;
1296                 rowdata[3*col+0] = *src++;
1297                 src++;
1298             }
1299             _cairo_output_stream_write (output, rowdata, 3*width);
1300             data += stride;
1301         }
1302         break;
1303     case CAIRO_FORMAT_RGB30:
1304     case CAIRO_FORMAT_ARGB32:
1305         for (row = image->height; row--; ) {
1306             uint32_t *src = (uint32_t *) data;
1307             uint32_t *dst = (uint32_t *) rowdata;
1308             int col;
1309             for (col = 0; col < width; col++)
1310                 dst[col] = bswap_32 (src[col]);
1311             _cairo_output_stream_write (output, rowdata, 4*width);
1312             data += stride;
1313         }
1314         break;
1315     case CAIRO_FORMAT_INVALID:
1316     default:
1317         ASSERT_NOT_REACHED;
1318         break;
1319     }
1320     if (rowdata != row_stack)
1321         free (rowdata);
1322 #endif
1323
1324     return CAIRO_STATUS_SUCCESS;
1325 }
1326
1327 static cairo_int_status_t
1328 _emit_png_surface (cairo_script_surface_t *surface,
1329                    cairo_image_surface_t *image)
1330 {
1331     cairo_script_context_t *ctx = to_context (surface);
1332     cairo_output_stream_t *base85_stream;
1333     cairo_status_t status;
1334     const uint8_t *mime_data;
1335     unsigned long mime_data_length;
1336
1337     cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_PNG,
1338                                  &mime_data, &mime_data_length);
1339     if (mime_data == NULL)
1340         return CAIRO_INT_STATUS_UNSUPPORTED;
1341
1342     _cairo_output_stream_printf (ctx->stream,
1343                                  "<< "
1344                                  "/width %d "
1345                                  "/height %d "
1346                                  "/format //%s "
1347                                  "/mime-type (image/png) "
1348                                  "/source <~",
1349                                  image->width, image->height,
1350                                  _format_to_string (image->format));
1351
1352     base85_stream = _cairo_base85_stream_create (ctx->stream);
1353     _cairo_output_stream_write (base85_stream, mime_data, mime_data_length);
1354     status = _cairo_output_stream_destroy (base85_stream);
1355     if (unlikely (status))
1356         return status;
1357
1358     _cairo_output_stream_puts (ctx->stream, "~> >> image ");
1359     return CAIRO_STATUS_SUCCESS;
1360 }
1361
1362 static cairo_int_status_t
1363 _emit_image_surface (cairo_script_surface_t *surface,
1364                      cairo_image_surface_t *image)
1365 {
1366     cairo_script_context_t *ctx = to_context (surface);
1367     cairo_output_stream_t *base85_stream;
1368     cairo_output_stream_t *zlib_stream;
1369     cairo_int_status_t status, status2;
1370     cairo_surface_t *snapshot;
1371     const uint8_t *mime_data;
1372     unsigned long mime_data_length;
1373
1374     snapshot = _cairo_surface_has_snapshot (&image->base,
1375                                             &script_snapshot_backend);
1376     if (snapshot) {
1377         _cairo_output_stream_printf (ctx->stream, "s%u ", snapshot->unique_id);
1378         return CAIRO_INT_STATUS_SUCCESS;
1379     }
1380
1381     status = _emit_png_surface (surface, image);
1382     if (_cairo_int_status_is_error (status)) {
1383         return status;
1384     } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
1385         cairo_image_surface_t *clone;
1386         uint32_t len;
1387
1388         if (image->format == CAIRO_FORMAT_INVALID) {
1389             clone = _cairo_image_surface_coerce (image);
1390         } else {
1391             clone = (cairo_image_surface_t *)
1392                 cairo_surface_reference (&image->base);
1393         }
1394
1395         _cairo_output_stream_printf (ctx->stream,
1396                                      "<< "
1397                                      "/width %d "
1398                                      "/height %d "
1399                                      "/format //%s "
1400                                      "/source ",
1401                                      clone->width, clone->height,
1402                                      _format_to_string (clone->format));
1403
1404         switch (clone->format) {
1405         case CAIRO_FORMAT_A1:
1406             len = (clone->width + 7)/8;
1407             break;
1408         case CAIRO_FORMAT_A8:
1409             len = clone->width;
1410             break;
1411         case CAIRO_FORMAT_RGB16_565:
1412             len = clone->width * 2;
1413             break;
1414         case CAIRO_FORMAT_RGB24:
1415             len = clone->width * 3;
1416             break;
1417         case CAIRO_FORMAT_RGB30:
1418         case CAIRO_FORMAT_ARGB32:
1419             len = clone->width * 4;
1420             break;
1421         case CAIRO_FORMAT_INVALID:
1422         default:
1423             ASSERT_NOT_REACHED;
1424             len = 0;
1425             break;
1426         }
1427         len *= clone->height;
1428
1429         if (len > 24) {
1430             _cairo_output_stream_puts (ctx->stream, "<|");
1431
1432             base85_stream = _cairo_base85_stream_create (ctx->stream);
1433
1434             len = to_be32 (len);
1435             _cairo_output_stream_write (base85_stream, &len, sizeof (len));
1436
1437             zlib_stream = _cairo_deflate_stream_create (base85_stream);
1438             status = _write_image_surface (zlib_stream, clone);
1439
1440             status2 = _cairo_output_stream_destroy (zlib_stream);
1441             if (status == CAIRO_INT_STATUS_SUCCESS)
1442                 status = status2;
1443             status2 = _cairo_output_stream_destroy (base85_stream);
1444             if (status == CAIRO_INT_STATUS_SUCCESS)
1445                 status = status2;
1446             if (unlikely (status))
1447                 return status;
1448         } else {
1449             _cairo_output_stream_puts (ctx->stream, "<~");
1450
1451             base85_stream = _cairo_base85_stream_create (ctx->stream);
1452             status = _write_image_surface (base85_stream, clone);
1453             status2 = _cairo_output_stream_destroy (base85_stream);
1454             if (status == CAIRO_INT_STATUS_SUCCESS)
1455                 status = status2;
1456             if (unlikely (status))
1457                 return status;
1458         }
1459         _cairo_output_stream_puts (ctx->stream, "~> >> image ");
1460
1461         cairo_surface_destroy (&clone->base);
1462     }
1463
1464     cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JPEG,
1465                                  &mime_data, &mime_data_length);
1466     if (mime_data != NULL) {
1467         _cairo_output_stream_printf (ctx->stream,
1468                                      "\n  (%s) <~",
1469                                      CAIRO_MIME_TYPE_JPEG);
1470
1471         base85_stream = _cairo_base85_stream_create (ctx->stream);
1472         _cairo_output_stream_write (base85_stream, mime_data, mime_data_length);
1473         status = _cairo_output_stream_destroy (base85_stream);
1474         if (unlikely (status))
1475             return status;
1476
1477         _cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n");
1478     }
1479
1480     cairo_surface_get_mime_data (&image->base, CAIRO_MIME_TYPE_JP2,
1481                                  &mime_data, &mime_data_length);
1482     if (mime_data != NULL) {
1483         _cairo_output_stream_printf (ctx->stream,
1484                                      "\n  (%s) <~",
1485                                      CAIRO_MIME_TYPE_JP2);
1486
1487         base85_stream = _cairo_base85_stream_create (ctx->stream);
1488         _cairo_output_stream_write (base85_stream, mime_data, mime_data_length);
1489         status = _cairo_output_stream_destroy (base85_stream);
1490         if (unlikely (status))
1491             return status;
1492
1493         _cairo_output_stream_puts (ctx->stream, "~> set-mime-data\n");
1494     }
1495
1496     return CAIRO_INT_STATUS_SUCCESS;
1497 }
1498
1499 static cairo_int_status_t
1500 _emit_image_surface_pattern (cairo_script_surface_t *surface,
1501                              cairo_surface_t *source)
1502 {
1503     cairo_image_surface_t *image;
1504     cairo_status_t status;
1505     void *extra;
1506
1507     status = _cairo_surface_acquire_source_image (source, &image, &extra);
1508     if (likely (status == CAIRO_STATUS_SUCCESS)) {
1509         status = _emit_image_surface (surface, image);
1510         _cairo_surface_release_source_image (source, image, extra);
1511     }
1512
1513     return status;
1514 }
1515
1516 static cairo_int_status_t
1517 _emit_subsurface_pattern (cairo_script_surface_t *surface,
1518                           cairo_surface_subsurface_t *sub)
1519 {
1520     cairo_surface_t *source = sub->target;
1521     cairo_int_status_t status;
1522
1523     switch ((int) source->backend->type) {
1524     case CAIRO_SURFACE_TYPE_RECORDING:
1525         status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source);
1526         break;
1527     case CAIRO_SURFACE_TYPE_SCRIPT:
1528         status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source);
1529         break;
1530     default:
1531         status = _emit_image_surface_pattern (surface, source);
1532         break;
1533     }
1534     if (unlikely (status))
1535         return status;
1536
1537     _cairo_output_stream_printf (to_context (surface)->stream,
1538                                  "%d %d %d %d subsurface ",
1539                                  sub->extents.x,
1540                                  sub->extents.y,
1541                                  sub->extents.width,
1542                                  sub->extents.height);
1543     return CAIRO_INT_STATUS_SUCCESS;
1544 }
1545
1546 static cairo_int_status_t
1547 _emit_surface_pattern (cairo_script_surface_t *surface,
1548                        const cairo_pattern_t *pattern)
1549 {
1550     cairo_script_context_t *ctx = to_context (surface);
1551     cairo_surface_pattern_t *surface_pattern;
1552     cairo_surface_t *source, *snapshot, *free_me = NULL;
1553     cairo_surface_t *take_snapshot = NULL;
1554     cairo_int_status_t status;
1555
1556     surface_pattern = (cairo_surface_pattern_t *) pattern;
1557     source = surface_pattern->surface;
1558
1559     if (_cairo_surface_is_snapshot (source)) {
1560         snapshot = _cairo_surface_has_snapshot (source, &script_snapshot_backend);
1561         if (snapshot) {
1562             _cairo_output_stream_printf (ctx->stream,
1563                                          "s%d pattern ",
1564                                          snapshot->unique_id);
1565             return CAIRO_INT_STATUS_SUCCESS;
1566         }
1567
1568         if (_cairo_surface_snapshot_is_reused (source))
1569             take_snapshot = source;
1570
1571         free_me = source = _cairo_surface_snapshot_get_target (source);
1572     }
1573
1574     switch ((int) source->backend->type) {
1575     case CAIRO_SURFACE_TYPE_RECORDING:
1576         status = _emit_recording_surface_pattern (surface, (cairo_recording_surface_t *) source);
1577         break;
1578     case CAIRO_SURFACE_TYPE_SCRIPT:
1579         status = _emit_script_surface_pattern (surface, (cairo_script_surface_t *) source);
1580         break;
1581     case CAIRO_SURFACE_TYPE_SUBSURFACE:
1582         status = _emit_subsurface_pattern (surface, (cairo_surface_subsurface_t *) source);
1583         break;
1584     default:
1585         status = _emit_image_surface_pattern (surface, source);
1586         break;
1587     }
1588     cairo_surface_destroy (free_me);
1589     if (unlikely (status))
1590         return status;
1591
1592     if (take_snapshot)
1593         attach_snapshot (ctx, take_snapshot);
1594
1595     _cairo_output_stream_puts (ctx->stream, "pattern");
1596     return CAIRO_INT_STATUS_SUCCESS;
1597 }
1598
1599 static cairo_int_status_t
1600 _emit_raster_pattern (cairo_script_surface_t *surface,
1601                       const cairo_pattern_t *pattern)
1602 {
1603     cairo_surface_t *source;
1604     cairo_int_status_t status;
1605
1606     source = _cairo_raster_source_pattern_acquire (pattern, &surface->base, NULL);
1607     if (unlikely (source == NULL)) {
1608         ASSERT_NOT_REACHED;
1609         return CAIRO_INT_STATUS_UNSUPPORTED;
1610     }
1611     if (unlikely (source->status))
1612         return source->status;
1613
1614     status = _emit_image_surface_pattern (surface, source);
1615     _cairo_raster_source_pattern_release (pattern, source);
1616     if (unlikely (status))
1617         return status;
1618
1619     _cairo_output_stream_puts (to_context(surface)->stream, "pattern");
1620     return CAIRO_INT_STATUS_SUCCESS;
1621 }
1622
1623 static cairo_int_status_t
1624 _emit_pattern (cairo_script_surface_t *surface,
1625                const cairo_pattern_t *pattern)
1626 {
1627     cairo_script_context_t *ctx = to_context (surface);
1628     cairo_int_status_t status;
1629     cairo_bool_t is_default_extend;
1630     cairo_bool_t need_newline = TRUE;
1631
1632     switch (pattern->type) {
1633     case CAIRO_PATTERN_TYPE_SOLID:
1634         /* solid colors do not need filter/extend/matrix */
1635         return _emit_solid_pattern (surface, pattern);
1636
1637     case CAIRO_PATTERN_TYPE_LINEAR:
1638         status = _emit_linear_pattern (surface, pattern);
1639         is_default_extend = pattern->extend == CAIRO_EXTEND_GRADIENT_DEFAULT;
1640         break;
1641     case CAIRO_PATTERN_TYPE_RADIAL:
1642         status = _emit_radial_pattern (surface, pattern);
1643         is_default_extend = pattern->extend == CAIRO_EXTEND_GRADIENT_DEFAULT;
1644         break;
1645     case CAIRO_PATTERN_TYPE_MESH:
1646         status = _emit_mesh_pattern (surface, pattern);
1647         is_default_extend = TRUE;
1648         break;
1649     case CAIRO_PATTERN_TYPE_SURFACE:
1650         status = _emit_surface_pattern (surface, pattern);
1651         is_default_extend = pattern->extend == CAIRO_EXTEND_SURFACE_DEFAULT;
1652         break;
1653     case CAIRO_PATTERN_TYPE_RASTER_SOURCE:
1654         status = _emit_raster_pattern (surface, pattern);
1655         is_default_extend = pattern->extend == CAIRO_EXTEND_SURFACE_DEFAULT;
1656         break;
1657
1658     default:
1659         ASSERT_NOT_REACHED;
1660         status = CAIRO_INT_STATUS_UNSUPPORTED;
1661     }
1662     if (unlikely (status))
1663         return status;
1664
1665     if (! _cairo_matrix_is_identity (&pattern->matrix)) {
1666         if (need_newline) {
1667             _cairo_output_stream_puts (ctx->stream, "\n ");
1668             need_newline = FALSE;
1669         }
1670
1671         _cairo_output_stream_printf (ctx->stream,
1672                                      " [%f %f %f %f %f %f] set-matrix\n ",
1673                                      pattern->matrix.xx, pattern->matrix.yx,
1674                                      pattern->matrix.xy, pattern->matrix.yy,
1675                                      pattern->matrix.x0, pattern->matrix.y0);
1676     }
1677
1678     /* XXX need to discriminate the user explicitly setting the default */
1679     if (pattern->filter != CAIRO_FILTER_DEFAULT) {
1680         if (need_newline) {
1681             _cairo_output_stream_puts (ctx->stream, "\n ");
1682             need_newline = FALSE;
1683         }
1684
1685         _cairo_output_stream_printf (ctx->stream,
1686                                      " //%s set-filter\n ",
1687                                      _filter_to_string (pattern->filter));
1688     }
1689     if (! is_default_extend ){
1690         if (need_newline) {
1691             _cairo_output_stream_puts (ctx->stream, "\n ");
1692             need_newline = FALSE;
1693         }
1694
1695         _cairo_output_stream_printf (ctx->stream,
1696                                      " //%s set-extend\n ",
1697                                      _extend_to_string (pattern->extend));
1698     }
1699
1700     if (need_newline)
1701         _cairo_output_stream_puts (ctx->stream, "\n ");
1702
1703     return CAIRO_INT_STATUS_SUCCESS;
1704 }
1705
1706 static cairo_int_status_t
1707 _emit_identity (cairo_script_surface_t *surface,
1708                 cairo_bool_t *matrix_updated)
1709 {
1710     assert (target_is_active (surface));
1711
1712     if (_cairo_matrix_is_identity (&surface->cr.current_ctm))
1713         return CAIRO_INT_STATUS_SUCCESS;
1714
1715     _cairo_output_stream_puts (to_context (surface)->stream,
1716                                "identity set-matrix\n");
1717
1718     *matrix_updated = TRUE;
1719     cairo_matrix_init_identity (&surface->cr.current_ctm);
1720
1721     return CAIRO_INT_STATUS_SUCCESS;
1722 }
1723
1724 static cairo_int_status_t
1725 _emit_source (cairo_script_surface_t *surface,
1726               cairo_operator_t op,
1727               const cairo_pattern_t *source)
1728 {
1729     cairo_bool_t matrix_updated = FALSE;
1730     cairo_int_status_t status;
1731
1732     assert (target_is_active (surface));
1733
1734     if (op == CAIRO_OPERATOR_CLEAR) {
1735         /* the source is ignored, so don't change it */
1736         return CAIRO_INT_STATUS_SUCCESS;
1737     }
1738
1739     if (_cairo_pattern_equal (&surface->cr.current_source.base, source))
1740         return CAIRO_INT_STATUS_SUCCESS;
1741
1742     _cairo_pattern_fini (&surface->cr.current_source.base);
1743     status = _cairo_pattern_init_copy (&surface->cr.current_source.base,
1744                                        source);
1745     if (unlikely (status))
1746         return status;
1747
1748     status = _emit_identity (surface, &matrix_updated);
1749     if (unlikely (status))
1750         return status;
1751
1752     status = _emit_pattern (surface, source);
1753     if (unlikely (status))
1754         return status;
1755
1756     assert (target_is_active (surface));
1757     _cairo_output_stream_puts (to_context (surface)->stream,
1758                                " set-source\n");
1759     return CAIRO_INT_STATUS_SUCCESS;
1760 }
1761
1762 static cairo_status_t
1763 _path_move_to (void *closure,
1764                const cairo_point_t *point)
1765 {
1766     _cairo_output_stream_printf (closure,
1767                                  " %f %f m",
1768                                  _cairo_fixed_to_double (point->x),
1769                                  _cairo_fixed_to_double (point->y));
1770
1771     return CAIRO_STATUS_SUCCESS;
1772 }
1773
1774 static cairo_status_t
1775 _path_line_to (void *closure,
1776                const cairo_point_t *point)
1777 {
1778     _cairo_output_stream_printf (closure,
1779                                  " %f %f l",
1780                                  _cairo_fixed_to_double (point->x),
1781                                  _cairo_fixed_to_double (point->y));
1782
1783     return CAIRO_STATUS_SUCCESS;
1784 }
1785
1786 static cairo_status_t
1787 _path_curve_to (void *closure,
1788                 const cairo_point_t *p1,
1789                 const cairo_point_t *p2,
1790                 const cairo_point_t *p3)
1791 {
1792     _cairo_output_stream_printf (closure,
1793                                  " %f %f %f %f %f %f c",
1794                                  _cairo_fixed_to_double (p1->x),
1795                                  _cairo_fixed_to_double (p1->y),
1796                                  _cairo_fixed_to_double (p2->x),
1797                                  _cairo_fixed_to_double (p2->y),
1798                                  _cairo_fixed_to_double (p3->x),
1799                                  _cairo_fixed_to_double (p3->y));
1800
1801     return CAIRO_STATUS_SUCCESS;
1802 }
1803
1804 static cairo_status_t
1805 _path_close (void *closure)
1806 {
1807     _cairo_output_stream_printf (closure,
1808                                  " h");
1809
1810     return CAIRO_STATUS_SUCCESS;
1811 }
1812
1813 static cairo_status_t
1814 _emit_path_boxes (cairo_script_surface_t *surface,
1815                   const cairo_path_fixed_t *path)
1816 {
1817     cairo_script_context_t *ctx = to_context (surface);
1818     cairo_path_fixed_iter_t iter;
1819     cairo_status_t status;
1820     struct _cairo_boxes_chunk *chunk;
1821     cairo_boxes_t boxes;
1822     cairo_box_t box;
1823     int i;
1824
1825     _cairo_boxes_init (&boxes);
1826     _cairo_path_fixed_iter_init (&iter, path);
1827     while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) {
1828         if (box.p1.y == box.p2.y || box.p1.x == box.p2.x)
1829             continue;
1830
1831         status = _cairo_boxes_add (&boxes, CAIRO_ANTIALIAS_DEFAULT, &box);
1832         if (unlikely (status)) {
1833             _cairo_boxes_fini (&boxes);
1834             return status;
1835         }
1836     }
1837
1838     if (! _cairo_path_fixed_iter_at_end (&iter)) {
1839         _cairo_boxes_fini (&boxes);
1840         return FALSE;
1841     }
1842
1843     for (chunk = &boxes.chunks; chunk; chunk = chunk->next) {
1844         for (i = 0; i < chunk->count; i++) {
1845             const cairo_box_t *b = &chunk->base[i];
1846             double x1 = _cairo_fixed_to_double (b->p1.x);
1847             double y1 = _cairo_fixed_to_double (b->p1.y);
1848             double x2 = _cairo_fixed_to_double (b->p2.x);
1849             double y2 = _cairo_fixed_to_double (b->p2.y);
1850
1851             _cairo_output_stream_printf (ctx->stream,
1852                                          "\n  %f %f %f %f rectangle",
1853                                          x1, y1, x2 - x1, y2 - y1);
1854         }
1855     }
1856
1857     _cairo_boxes_fini (&boxes);
1858     return status;
1859 }
1860
1861 static cairo_status_t
1862 _emit_path (cairo_script_surface_t *surface,
1863             const cairo_path_fixed_t *path,
1864             cairo_bool_t is_fill)
1865 {
1866     cairo_script_context_t *ctx = to_context (surface);
1867     cairo_box_t box;
1868     cairo_int_status_t status;
1869
1870     assert (target_is_active (surface));
1871     assert (_cairo_matrix_is_identity (&surface->cr.current_ctm));
1872
1873     if (_cairo_path_fixed_equal (&surface->cr.current_path, path))
1874         return CAIRO_STATUS_SUCCESS;
1875
1876     _cairo_path_fixed_fini (&surface->cr.current_path);
1877
1878     _cairo_output_stream_puts (ctx->stream, "n");
1879
1880     if (path == NULL) {
1881         _cairo_path_fixed_init (&surface->cr.current_path);
1882         _cairo_output_stream_puts (ctx->stream, "\n");
1883         return CAIRO_STATUS_SUCCESS;
1884     }
1885
1886     status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path);
1887     if (unlikely (status))
1888         return status;
1889
1890     status = CAIRO_INT_STATUS_UNSUPPORTED;
1891     if (_cairo_path_fixed_is_rectangle (path, &box)) {
1892         double x1 = _cairo_fixed_to_double (box.p1.x);
1893         double y1 = _cairo_fixed_to_double (box.p1.y);
1894         double x2 = _cairo_fixed_to_double (box.p2.x);
1895         double y2 = _cairo_fixed_to_double (box.p2.y);
1896
1897         assert (x1 > -9999);
1898
1899         _cairo_output_stream_printf (ctx->stream,
1900                                      " %f %f %f %f rectangle",
1901                                      x1, y1, x2 - x1, y2 - y1);
1902         status = CAIRO_INT_STATUS_SUCCESS;
1903     } else if (is_fill && _cairo_path_fixed_fill_is_rectilinear (path)) {
1904         status = _emit_path_boxes (surface, path);
1905     }
1906
1907     if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
1908         status = _cairo_path_fixed_interpret (path,
1909                                               _path_move_to,
1910                                               _path_line_to,
1911                                               _path_curve_to,
1912                                               _path_close,
1913                                               ctx->stream);
1914     }
1915
1916     _cairo_output_stream_puts (ctx->stream, "\n");
1917
1918     return status;
1919 }
1920 static cairo_bool_t
1921 _scaling_matrix_equal (const cairo_matrix_t *a,
1922                        const cairo_matrix_t *b)
1923 {
1924     return fabs (a->xx - b->xx) < 1e-5 &&
1925            fabs (a->xy - b->xy) < 1e-5 &&
1926            fabs (a->yx - b->yx) < 1e-5 &&
1927            fabs (a->yy - b->yy) < 1e-5;
1928 }
1929
1930 static cairo_status_t
1931 _emit_scaling_matrix (cairo_script_surface_t *surface,
1932                       const cairo_matrix_t *ctm,
1933                       cairo_bool_t *matrix_updated)
1934 {
1935     cairo_script_context_t *ctx = to_context (surface);
1936     cairo_bool_t was_identity;
1937     assert (target_is_active (surface));
1938
1939     if (_scaling_matrix_equal (&surface->cr.current_ctm, ctm))
1940         return CAIRO_STATUS_SUCCESS;
1941
1942     was_identity = _cairo_matrix_is_identity (&surface->cr.current_ctm);
1943
1944     *matrix_updated = TRUE;
1945     surface->cr.current_ctm = *ctm;
1946     surface->cr.current_ctm.x0 = 0.;
1947     surface->cr.current_ctm.y0 = 0.;
1948
1949     if (_cairo_matrix_is_identity (&surface->cr.current_ctm)) {
1950         _cairo_output_stream_puts (ctx->stream,
1951                                    "identity set-matrix\n");
1952     } else if (was_identity && fabs (ctm->yx) < 1e-5 && fabs (ctm->xy) < 1e-5) {
1953         _cairo_output_stream_printf (ctx->stream,
1954                                      "%f %f scale\n",
1955                                      ctm->xx, ctm->yy);
1956     } else {
1957         _cairo_output_stream_printf (ctx->stream,
1958                                      "[%f %f %f %f 0 0] set-matrix\n",
1959                                      ctm->xx, ctm->yx,
1960                                      ctm->xy, ctm->yy);
1961     }
1962
1963     return CAIRO_STATUS_SUCCESS;
1964 }
1965
1966 static cairo_status_t
1967 _emit_font_matrix (cairo_script_surface_t *surface,
1968                    const cairo_matrix_t *font_matrix)
1969 {
1970     cairo_script_context_t *ctx = to_context (surface);
1971     assert (target_is_active (surface));
1972
1973     if (memcmp (&surface->cr.current_font_matrix,
1974                 font_matrix,
1975                 sizeof (cairo_matrix_t)) == 0)
1976     {
1977         return CAIRO_STATUS_SUCCESS;
1978     }
1979
1980     surface->cr.current_font_matrix = *font_matrix;
1981
1982     if (_cairo_matrix_is_identity (font_matrix)) {
1983         _cairo_output_stream_puts (ctx->stream,
1984                                    "identity set-font-matrix\n");
1985     } else {
1986         _cairo_output_stream_printf (ctx->stream,
1987                                      "[%f %f %f %f %f %f] set-font-matrix\n",
1988                                      font_matrix->xx, font_matrix->yx,
1989                                      font_matrix->xy, font_matrix->yy,
1990                                      font_matrix->x0, font_matrix->y0);
1991     }
1992
1993     return CAIRO_STATUS_SUCCESS;
1994 }
1995
1996 static cairo_surface_t *
1997 _cairo_script_surface_create_similar (void             *abstract_surface,
1998                                       cairo_content_t   content,
1999                                       int               width,
2000                                       int               height)
2001 {
2002     cairo_script_surface_t *surface, *other = abstract_surface;
2003     cairo_surface_t *passthrough = NULL;
2004     cairo_script_context_t *ctx;
2005     cairo_rectangle_t extents;
2006     cairo_status_t status;
2007
2008     ctx = to_context (other);
2009
2010     status = cairo_device_acquire (&ctx->base);
2011     if (unlikely (status))
2012         return _cairo_surface_create_in_error (status);
2013
2014     if (! other->emitted) {
2015         status = _emit_surface (other);
2016         if (unlikely (status)) {
2017             cairo_device_release (&ctx->base);
2018             return _cairo_surface_create_in_error (status);
2019         }
2020
2021         target_push (other);
2022     }
2023
2024     if (_cairo_surface_wrapper_is_active (&other->wrapper)) {
2025         passthrough =
2026             _cairo_surface_wrapper_create_similar (&other->wrapper,
2027                                                    content, width, height);
2028         if (unlikely (passthrough->status)) {
2029             cairo_device_release (&ctx->base);
2030             return passthrough;
2031         }
2032     }
2033
2034     extents.x = extents.y = 0;
2035     extents.width = width;
2036     extents.height = height;
2037     surface = _cairo_script_surface_create_internal (ctx, content,
2038                                                      &extents, passthrough);
2039     cairo_surface_destroy (passthrough);
2040
2041     if (unlikely (surface->base.status)) {
2042         cairo_device_release (&ctx->base);
2043         return &surface->base;
2044     }
2045
2046     _get_target (other);
2047     _cairo_output_stream_printf (ctx->stream,
2048                                  "%u %u //%s similar dup /s%u exch def context\n",
2049                                  width, height,
2050                                  _content_to_string (content),
2051                                  surface->base.unique_id);
2052
2053     surface->emitted = TRUE;
2054     surface->defined = TRUE;
2055     surface->base.is_clear = TRUE;
2056     target_push (surface);
2057
2058     cairo_device_release (&ctx->base);
2059     return &surface->base;
2060 }
2061
2062 static cairo_status_t
2063 _device_flush (void *abstract_device)
2064 {
2065     cairo_script_context_t *ctx = abstract_device;
2066
2067     return _cairo_output_stream_flush (ctx->stream);
2068 }
2069
2070 static void
2071 _device_destroy (void *abstract_device)
2072 {
2073     cairo_script_context_t *ctx = abstract_device;
2074     cairo_status_t status;
2075
2076     while (! cairo_list_is_empty (&ctx->fonts)) {
2077         cairo_script_font_t *font;
2078
2079         font = cairo_list_first_entry (&ctx->fonts, cairo_script_font_t, link);
2080         cairo_list_del (&font->base.link);
2081         cairo_list_del (&font->link);
2082         free (font);
2083     }
2084
2085     _bitmap_fini (ctx->surface_id.next);
2086     _bitmap_fini (ctx->font_id.next);
2087
2088     if (ctx->owns_stream)
2089         status = _cairo_output_stream_destroy (ctx->stream);
2090
2091     free (ctx);
2092 }
2093
2094 static cairo_surface_t *
2095 _cairo_script_surface_source (void                    *abstract_surface,
2096                               cairo_rectangle_int_t     *extents)
2097 {
2098     cairo_script_surface_t *surface = abstract_surface;
2099
2100     if (extents) {
2101         extents->x = extents->y = 0;
2102         extents->width  = surface->width;
2103         extents->height = surface->height;
2104     }
2105
2106     return &surface->base;
2107 }
2108
2109 static cairo_status_t
2110 _cairo_script_surface_acquire_source_image (void                    *abstract_surface,
2111                                             cairo_image_surface_t  **image_out,
2112                                             void                   **image_extra)
2113 {
2114     cairo_script_surface_t *surface = abstract_surface;
2115
2116     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
2117         return _cairo_surface_wrapper_acquire_source_image (&surface->wrapper,
2118                                                             image_out,
2119                                                             image_extra);
2120     }
2121
2122     return CAIRO_INT_STATUS_UNSUPPORTED;
2123 }
2124
2125 static void
2126 _cairo_script_surface_release_source_image (void                   *abstract_surface,
2127                                            cairo_image_surface_t  *image,
2128                                            void                   *image_extra)
2129 {
2130     cairo_script_surface_t *surface = abstract_surface;
2131
2132     assert (_cairo_surface_wrapper_is_active (&surface->wrapper));
2133     _cairo_surface_wrapper_release_source_image (&surface->wrapper,
2134                                                  image,
2135                                                  image_extra);
2136 }
2137
2138 static cairo_status_t
2139 _cairo_script_surface_finish (void *abstract_surface)
2140 {
2141     cairo_script_surface_t *surface = abstract_surface;
2142     cairo_script_context_t *ctx = to_context (surface);
2143     cairo_status_t status = CAIRO_STATUS_SUCCESS, status2;
2144
2145     _cairo_surface_wrapper_fini (&surface->wrapper);
2146
2147     free (surface->cr.current_style.dash);
2148     surface->cr.current_style.dash = NULL;
2149
2150     _cairo_pattern_fini (&surface->cr.current_source.base);
2151     _cairo_path_fixed_fini (&surface->cr.current_path);
2152     _cairo_surface_clipper_reset (&surface->clipper);
2153
2154     status = cairo_device_acquire (&ctx->base);
2155     if (unlikely (status))
2156         return status;
2157
2158     if (surface->emitted) {
2159         assert (! surface->active);
2160
2161         if (! cairo_list_is_empty (&surface->operand.link)) {
2162             if (! ctx->active) {
2163                 if (target_is_active (surface)) {
2164                     _cairo_output_stream_printf (ctx->stream,
2165                                                  "pop\n");
2166                 } else {
2167                     int depth = target_depth (surface);
2168                     if (depth == 1) {
2169                         _cairo_output_stream_printf (ctx->stream,
2170                                                      "exch pop\n");
2171                     } else {
2172                         _cairo_output_stream_printf (ctx->stream,
2173                                                      "%d -1 roll pop\n",
2174                                                      depth);
2175                     }
2176                 }
2177                 cairo_list_del (&surface->operand.link);
2178             } else {
2179                 struct deferred_finish *link = malloc (sizeof (*link));
2180                 if (link == NULL) {
2181                     status2 = _cairo_error (CAIRO_STATUS_NO_MEMORY);
2182                     if (status == CAIRO_STATUS_SUCCESS)
2183                         status = status2;
2184                     cairo_list_del (&surface->operand.link);
2185                 } else {
2186                     link->operand.type = DEFERRED;
2187                     cairo_list_swap (&link->operand.link,
2188                                      &surface->operand.link);
2189                     cairo_list_add (&link->link, &ctx->deferred);
2190                 }
2191             }
2192         }
2193
2194         if (surface->defined) {
2195             _cairo_output_stream_printf (ctx->stream,
2196                                          "/s%u undef\n",
2197                                          surface->base.unique_id);
2198         }
2199     }
2200
2201     if (status == CAIRO_STATUS_SUCCESS)
2202         status = _cairo_output_stream_flush (to_context (surface)->stream);
2203
2204     cairo_device_release (&ctx->base);
2205
2206     return status;
2207 }
2208
2209 static cairo_int_status_t
2210 _cairo_script_surface_copy_page (void *abstract_surface)
2211 {
2212     cairo_script_surface_t *surface = abstract_surface;
2213     cairo_status_t status;
2214
2215     status = cairo_device_acquire (surface->base.device);
2216     if (unlikely (status))
2217         return status;
2218
2219     status = _emit_context (surface);
2220     if (unlikely (status))
2221         goto BAIL;
2222
2223     _cairo_output_stream_puts (to_context (surface)->stream, "copy-page\n");
2224
2225 BAIL:
2226     cairo_device_release (surface->base.device);
2227     return status;
2228 }
2229
2230 static cairo_int_status_t
2231 _cairo_script_surface_show_page (void *abstract_surface)
2232 {
2233     cairo_script_surface_t *surface = abstract_surface;
2234     cairo_status_t status;
2235
2236     status = cairo_device_acquire (surface->base.device);
2237     if (unlikely (status))
2238         return status;
2239
2240     status = _emit_context (surface);
2241     if (unlikely (status))
2242         goto BAIL;
2243
2244     _cairo_output_stream_puts (to_context (surface)->stream, "show-page\n");
2245
2246 BAIL:
2247     cairo_device_release (surface->base.device);
2248     return status;
2249 }
2250
2251 static cairo_status_t
2252 _cairo_script_surface_clipper_intersect_clip_path (cairo_surface_clipper_t *clipper,
2253                                                    cairo_path_fixed_t   *path,
2254                                                    cairo_fill_rule_t     fill_rule,
2255                                                    double                tolerance,
2256                                                    cairo_antialias_t     antialias)
2257 {
2258     cairo_script_surface_t *surface = cairo_container_of (clipper,
2259                                                           cairo_script_surface_t,
2260                                                           clipper);
2261     cairo_script_context_t *ctx = to_context (surface);
2262     cairo_bool_t matrix_updated = FALSE;
2263     cairo_status_t status;
2264     cairo_box_t box;
2265
2266     status = _emit_context (surface);
2267     if (unlikely (status))
2268         return status;
2269
2270     if (path == NULL) {
2271         if (surface->cr.has_clip) {
2272             _cairo_output_stream_puts (ctx->stream, "reset-clip\n");
2273             surface->cr.has_clip = FALSE;
2274         }
2275         return CAIRO_STATUS_SUCCESS;
2276     }
2277
2278     /* skip the trivial clip covering the surface extents */
2279     if (surface->width >= 0 && surface->height >= 0 &&
2280         _cairo_path_fixed_is_box (path, &box))
2281     {
2282         if (box.p1.x <= 0 && box.p1.y <= 0 &&
2283             box.p2.x >= _cairo_fixed_from_double (surface->width) &&
2284             box.p2.y >= _cairo_fixed_from_double (surface->height))
2285         {
2286             return CAIRO_STATUS_SUCCESS;
2287         }
2288     }
2289
2290     status = _emit_identity (surface, &matrix_updated);
2291     if (unlikely (status))
2292         return status;
2293
2294     status = _emit_fill_rule (surface, fill_rule);
2295     if (unlikely (status))
2296         return status;
2297
2298     if (path->has_curve_to) {
2299         status = _emit_tolerance (surface, tolerance, matrix_updated);
2300         if (unlikely (status))
2301             return status;
2302     }
2303
2304     if (! _cairo_path_fixed_fill_maybe_region (path)) {
2305         status = _emit_antialias (surface, antialias);
2306         if (unlikely (status))
2307             return status;
2308     }
2309
2310     status = _emit_path (surface, path, TRUE);
2311     if (unlikely (status))
2312         return status;
2313
2314     _cairo_output_stream_puts (ctx->stream, "clip+\n");
2315     surface->cr.has_clip = TRUE;
2316
2317     return CAIRO_STATUS_SUCCESS;
2318 }
2319
2320 static cairo_status_t
2321 active (cairo_script_surface_t *surface)
2322 {
2323     cairo_status_t status;
2324
2325     status = cairo_device_acquire (surface->base.device);
2326     if (unlikely (status))
2327         return status;
2328
2329     if (surface->active++ == 0)
2330         to_context (surface)->active++;
2331
2332     return CAIRO_STATUS_SUCCESS;
2333 }
2334
2335 static void
2336 inactive (cairo_script_surface_t *surface)
2337 {
2338     cairo_script_context_t *ctx = to_context (surface);
2339     cairo_list_t sorted;
2340
2341     assert (surface->active > 0);
2342     if (--surface->active)
2343         goto DONE;
2344
2345     assert (ctx->active > 0);
2346     if (--ctx->active)
2347         goto DONE;
2348
2349     cairo_list_init (&sorted);
2350     while (! cairo_list_is_empty (&ctx->deferred)) {
2351         struct deferred_finish *df;
2352         cairo_list_t *operand;
2353         int depth;
2354
2355         df = cairo_list_first_entry (&ctx->deferred,
2356                                      struct deferred_finish,
2357                                      link);
2358
2359         depth = 0;
2360         cairo_list_foreach (operand, &ctx->operands) {
2361             if (operand == &df->operand.link)
2362                 break;
2363             depth++;
2364         }
2365
2366         df->operand.type = depth;
2367
2368         if (cairo_list_is_empty (&sorted)) {
2369             cairo_list_move (&df->link, &sorted);
2370         } else {
2371             struct deferred_finish *pos;
2372
2373             cairo_list_foreach_entry (pos, struct deferred_finish,
2374                                       &sorted,
2375                                       link)
2376             {
2377                 if (df->operand.type < pos->operand.type)
2378                     break;
2379             }
2380             cairo_list_move_tail (&df->link, &pos->link);
2381         }
2382     }
2383
2384     while (! cairo_list_is_empty (&sorted)) {
2385         struct deferred_finish *df;
2386         cairo_list_t *operand;
2387         int depth;
2388
2389         df = cairo_list_first_entry (&sorted,
2390                                      struct deferred_finish,
2391                                      link);
2392
2393         depth = 0;
2394         cairo_list_foreach (operand, &ctx->operands) {
2395             if (operand == &df->operand.link)
2396                 break;
2397             depth++;
2398         }
2399
2400         if (depth == 0) {
2401             _cairo_output_stream_printf (ctx->stream,
2402                                          "pop\n");
2403         } else if (depth == 1) {
2404             _cairo_output_stream_printf (ctx->stream,
2405                                          "exch pop\n");
2406         } else {
2407             _cairo_output_stream_printf (ctx->stream,
2408                                          "%d -1 roll pop\n",
2409                                          depth);
2410         }
2411
2412         cairo_list_del (&df->operand.link);
2413         cairo_list_del (&df->link);
2414         free (df);
2415     }
2416
2417 DONE:
2418     cairo_device_release (surface->base.device);
2419 }
2420
2421 static cairo_int_status_t
2422 _cairo_script_surface_paint (void                       *abstract_surface,
2423                              cairo_operator_t            op,
2424                              const cairo_pattern_t      *source,
2425                              const cairo_clip_t         *clip)
2426 {
2427     cairo_script_surface_t *surface = abstract_surface;
2428     cairo_status_t status;
2429
2430     status = active (surface);
2431     if (unlikely (status))
2432         return status;
2433
2434     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
2435     if (unlikely (status))
2436         goto BAIL;
2437
2438     status = _emit_context (surface);
2439     if (unlikely (status))
2440         goto BAIL;
2441
2442     status = _emit_source (surface, op, source);
2443     if (unlikely (status))
2444         goto BAIL;
2445
2446     status = _emit_operator (surface, op);
2447     if (unlikely (status))
2448         goto BAIL;
2449
2450     _cairo_output_stream_puts (to_context (surface)->stream,
2451                                "paint\n");
2452
2453     inactive (surface);
2454
2455     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
2456         return _cairo_surface_wrapper_paint (&surface->wrapper,
2457                                              op, source, clip);
2458     }
2459
2460     return CAIRO_STATUS_SUCCESS;
2461
2462 BAIL:
2463     inactive (surface);
2464     return status;
2465 }
2466
2467 static cairo_int_status_t
2468 _cairo_script_surface_mask (void                        *abstract_surface,
2469                             cairo_operator_t             op,
2470                             const cairo_pattern_t       *source,
2471                             const cairo_pattern_t       *mask,
2472                             const cairo_clip_t          *clip)
2473 {
2474     cairo_script_surface_t *surface = abstract_surface;
2475     cairo_status_t status;
2476
2477     status = active (surface);
2478     if (unlikely (status))
2479         return status;
2480
2481     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
2482     if (unlikely (status))
2483         goto BAIL;
2484
2485     status = _emit_context (surface);
2486     if (unlikely (status))
2487         goto BAIL;
2488
2489     status = _emit_source (surface, op, source);
2490     if (unlikely (status))
2491         goto BAIL;
2492
2493     status = _emit_operator (surface, op);
2494     if (unlikely (status))
2495         goto BAIL;
2496
2497     if (_cairo_pattern_equal (source, mask)) {
2498         _cairo_output_stream_puts (to_context (surface)->stream, "/source get");
2499     } else {
2500         status = _emit_pattern (surface, mask);
2501         if (unlikely (status))
2502             goto BAIL;
2503     }
2504
2505     assert (surface->cr.current_operator == op);
2506
2507     _cairo_output_stream_puts (to_context (surface)->stream,
2508                                " mask\n");
2509
2510     inactive (surface);
2511
2512     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
2513         return _cairo_surface_wrapper_mask (&surface->wrapper,
2514                                             op, source, mask, clip);
2515     }
2516
2517     return CAIRO_STATUS_SUCCESS;
2518
2519 BAIL:
2520     inactive (surface);
2521     return status;
2522 }
2523
2524 static cairo_int_status_t
2525 _cairo_script_surface_stroke (void                              *abstract_surface,
2526                               cairo_operator_t                   op,
2527                               const cairo_pattern_t             *source,
2528                               const cairo_path_fixed_t          *path,
2529                               const cairo_stroke_style_t        *style,
2530                               const cairo_matrix_t              *ctm,
2531                               const cairo_matrix_t              *ctm_inverse,
2532                               double                             tolerance,
2533                               cairo_antialias_t                  antialias,
2534                               const cairo_clip_t                *clip)
2535 {
2536     cairo_script_surface_t *surface = abstract_surface;
2537     cairo_bool_t matrix_updated = FALSE;
2538     cairo_status_t status;
2539
2540     status = active (surface);
2541     if (unlikely (status))
2542         return status;
2543
2544     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
2545     if (unlikely (status))
2546         goto BAIL;
2547
2548     status = _emit_context (surface);
2549     if (unlikely (status))
2550         goto BAIL;
2551
2552     status = _emit_identity (surface, &matrix_updated);
2553     if (unlikely (status))
2554         goto BAIL;
2555
2556     status = _emit_path (surface, path, FALSE);
2557     if (unlikely (status))
2558         goto BAIL;
2559
2560     status = _emit_source (surface, op, source);
2561     if (unlikely (status))
2562         goto BAIL;
2563
2564     status = _emit_scaling_matrix (surface, ctm, &matrix_updated);
2565     if (unlikely (status))
2566         goto BAIL;
2567
2568     status = _emit_operator (surface, op);
2569     if (unlikely (status))
2570         goto BAIL;
2571
2572     if (_scaling_matrix_equal (&surface->cr.current_ctm,
2573                                &surface->cr.current_stroke_matrix))
2574     {
2575         matrix_updated = FALSE;
2576     }
2577     else
2578     {
2579         matrix_updated = TRUE;
2580         surface->cr.current_stroke_matrix = surface->cr.current_ctm;
2581     }
2582
2583     status = _emit_stroke_style (surface, style, matrix_updated);
2584     if (unlikely (status))
2585         goto BAIL;
2586
2587     status = _emit_tolerance (surface, tolerance, matrix_updated);
2588     if (unlikely (status))
2589         goto BAIL;
2590
2591     status = _emit_antialias (surface, antialias);
2592     if (unlikely (status))
2593         goto BAIL;
2594
2595     _cairo_output_stream_puts (to_context (surface)->stream, "stroke+\n");
2596
2597     inactive (surface);
2598
2599     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
2600         return _cairo_surface_wrapper_stroke (&surface->wrapper,
2601                                               op, source, path,
2602                                               style,
2603                                               ctm, ctm_inverse,
2604                                               tolerance, antialias,
2605                                               clip);
2606     }
2607
2608     return CAIRO_STATUS_SUCCESS;
2609
2610 BAIL:
2611     inactive (surface);
2612     return status;
2613 }
2614
2615 static cairo_int_status_t
2616 _cairo_script_surface_fill (void                        *abstract_surface,
2617                             cairo_operator_t             op,
2618                             const cairo_pattern_t       *source,
2619                             const cairo_path_fixed_t    *path,
2620                             cairo_fill_rule_t            fill_rule,
2621                             double                       tolerance,
2622                             cairo_antialias_t            antialias,
2623                             const cairo_clip_t          *clip)
2624 {
2625     cairo_script_surface_t *surface = abstract_surface;
2626     cairo_bool_t matrix_updated = FALSE;
2627     cairo_status_t status;
2628     cairo_box_t box;
2629
2630     status = active (surface);
2631     if (unlikely (status))
2632         return status;
2633
2634     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
2635     if (unlikely (status))
2636         goto BAIL;
2637
2638     status = _emit_context (surface);
2639     if (unlikely (status))
2640         goto BAIL;
2641
2642     status = _emit_identity (surface, &matrix_updated);
2643     if (unlikely (status))
2644         goto BAIL;
2645
2646     status = _emit_source (surface, op, source);
2647     if (unlikely (status))
2648         goto BAIL;
2649
2650     if (! _cairo_path_fixed_is_box (path, &box)) {
2651         status = _emit_fill_rule (surface, fill_rule);
2652         if (unlikely (status))
2653             goto BAIL;
2654     }
2655
2656     if (path->has_curve_to) {
2657         status = _emit_tolerance (surface, tolerance, matrix_updated);
2658         if (unlikely (status))
2659             goto BAIL;
2660     }
2661
2662     if (! _cairo_path_fixed_fill_maybe_region (path)) {
2663         status = _emit_antialias (surface, antialias);
2664         if (unlikely (status))
2665             goto BAIL;
2666     }
2667
2668     status = _emit_path (surface, path, TRUE);
2669     if (unlikely (status))
2670         goto BAIL;
2671
2672     status = _emit_operator (surface, op);
2673     if (unlikely (status))
2674         goto BAIL;
2675
2676     _cairo_output_stream_puts (to_context (surface)->stream, "fill+\n");
2677
2678     inactive (surface);
2679
2680     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
2681         return _cairo_surface_wrapper_fill (&surface->wrapper,
2682                                             op, source, path,
2683                                             fill_rule,
2684                                             tolerance,
2685                                             antialias,
2686                                             clip);
2687     }
2688
2689     return CAIRO_STATUS_SUCCESS;
2690
2691 BAIL:
2692     inactive (surface);
2693     return status;
2694 }
2695
2696 static cairo_surface_t *
2697 _cairo_script_surface_snapshot (void *abstract_surface)
2698 {
2699     cairo_script_surface_t *surface = abstract_surface;
2700
2701     if (_cairo_surface_wrapper_is_active (&surface->wrapper))
2702         return _cairo_surface_wrapper_snapshot (&surface->wrapper);
2703
2704     return NULL;
2705 }
2706
2707 static cairo_bool_t
2708 _cairo_script_surface_has_show_text_glyphs (void *abstract_surface)
2709 {
2710     return TRUE;
2711 }
2712
2713 static const char *
2714 _subpixel_order_to_string (cairo_subpixel_order_t subpixel_order)
2715 {
2716     static const char *names[] = {
2717         "SUBPIXEL_ORDER_DEFAULT",       /* CAIRO_SUBPIXEL_ORDER_DEFAULT */
2718         "SUBPIXEL_ORDER_RGB",           /* CAIRO_SUBPIXEL_ORDER_RGB */
2719         "SUBPIXEL_ORDER_BGR",           /* CAIRO_SUBPIXEL_ORDER_BGR */
2720         "SUBPIXEL_ORDER_VRGB",          /* CAIRO_SUBPIXEL_ORDER_VRGB */
2721         "SUBPIXEL_ORDER_VBGR"           /* CAIRO_SUBPIXEL_ORDER_VBGR */
2722     };
2723     return names[subpixel_order];
2724 }
2725 static const char *
2726 _hint_style_to_string (cairo_hint_style_t hint_style)
2727 {
2728     static const char *names[] = {
2729         "HINT_STYLE_DEFAULT",   /* CAIRO_HINT_STYLE_DEFAULT */
2730         "HINT_STYLE_NONE",      /* CAIRO_HINT_STYLE_NONE */
2731         "HINT_STYLE_SLIGHT",    /* CAIRO_HINT_STYLE_SLIGHT */
2732         "HINT_STYLE_MEDIUM",    /* CAIRO_HINT_STYLE_MEDIUM */
2733         "HINT_STYLE_FULL"       /* CAIRO_HINT_STYLE_FULL */
2734     };
2735     return names[hint_style];
2736 }
2737 static const char *
2738 _hint_metrics_to_string (cairo_hint_metrics_t hint_metrics)
2739 {
2740     static const char *names[] = {
2741          "HINT_METRICS_DEFAULT",        /* CAIRO_HINT_METRICS_DEFAULT */
2742          "HINT_METRICS_OFF",            /* CAIRO_HINT_METRICS_OFF */
2743          "HINT_METRICS_ON"              /* CAIRO_HINT_METRICS_ON */
2744     };
2745     return names[hint_metrics];
2746 }
2747
2748 static cairo_status_t
2749 _emit_font_options (cairo_script_surface_t *surface,
2750                     cairo_font_options_t *font_options)
2751 {
2752     cairo_script_context_t *ctx = to_context (surface);
2753
2754     if (cairo_font_options_equal (&surface->cr.current_font_options,
2755                                   font_options))
2756     {
2757         return CAIRO_STATUS_SUCCESS;
2758     }
2759
2760     _cairo_output_stream_printf (ctx->stream, "<<");
2761
2762     if (font_options->antialias != surface->cr.current_font_options.antialias) {
2763         _cairo_output_stream_printf (ctx->stream,
2764                                      " /antialias //%s",
2765                                      _antialias_to_string (font_options->antialias));
2766     }
2767
2768     if (font_options->subpixel_order !=
2769         surface->cr.current_font_options.subpixel_order)
2770     {
2771         _cairo_output_stream_printf (ctx->stream,
2772                                      " /subpixel-order //%s",
2773                                      _subpixel_order_to_string (font_options->subpixel_order));
2774     }
2775
2776     if (font_options->hint_style !=
2777         surface->cr.current_font_options.hint_style)
2778     {
2779         _cairo_output_stream_printf (ctx->stream,
2780                                      " /hint-style //%s",
2781                                      _hint_style_to_string (font_options->hint_style));
2782     }
2783
2784     if (font_options->hint_metrics !=
2785         surface->cr.current_font_options.hint_metrics)
2786     {
2787         _cairo_output_stream_printf (ctx->stream,
2788                                      " /hint-metrics //%s",
2789                                      _hint_metrics_to_string (font_options->hint_metrics));
2790     }
2791
2792     _cairo_output_stream_printf (ctx->stream,
2793                                  " >> set-font-options\n");
2794
2795     surface->cr.current_font_options = *font_options;
2796     return CAIRO_STATUS_SUCCESS;
2797 }
2798
2799 static void
2800 _cairo_script_scaled_font_fini (cairo_scaled_font_private_t *abstract_private,
2801                                 cairo_scaled_font_t *scaled_font)
2802 {
2803     cairo_script_font_t *priv = (cairo_script_font_t *)abstract_private;
2804     cairo_script_context_t *ctx = (cairo_script_context_t *)abstract_private->key;
2805     cairo_status_t status;
2806
2807     status = cairo_device_acquire (&ctx->base);
2808     if (likely (status == CAIRO_STATUS_SUCCESS)) {
2809         _cairo_output_stream_printf (ctx->stream,
2810                                      "/f%lu undef /sf%lu undef\n",
2811                                      priv->id,
2812                                      priv->id);
2813
2814         _bitmap_release_id (&ctx->font_id, priv->id);
2815         cairo_device_release (&ctx->base);
2816     }
2817
2818     cairo_list_del (&priv->link);
2819     cairo_list_del (&priv->base.link);
2820     free (priv);
2821 }
2822
2823 static cairo_script_font_t *
2824 _cairo_script_font_get (cairo_script_context_t *ctx, cairo_scaled_font_t *font)
2825 {
2826     return (cairo_script_font_t *) _cairo_scaled_font_find_private (font, ctx);
2827 }
2828
2829 static long unsigned
2830 _cairo_script_font_id (cairo_script_context_t *ctx, cairo_scaled_font_t *font)
2831 {
2832     return _cairo_script_font_get (ctx, font)->id;
2833 }
2834
2835 static cairo_status_t
2836 _emit_type42_font (cairo_script_surface_t *surface,
2837                    cairo_scaled_font_t *scaled_font)
2838 {
2839     cairo_script_context_t *ctx = to_context (surface);
2840     const cairo_scaled_font_backend_t *backend;
2841     cairo_output_stream_t *base85_stream;
2842     cairo_output_stream_t *zlib_stream;
2843     cairo_status_t status, status2;
2844     unsigned long size;
2845     unsigned int load_flags;
2846     uint32_t len;
2847     uint8_t *buf;
2848
2849     backend = scaled_font->backend;
2850     if (backend->load_truetype_table == NULL)
2851         return CAIRO_INT_STATUS_UNSUPPORTED;
2852
2853     size = 0;
2854     status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size);
2855     if (unlikely (status))
2856         return status;
2857
2858     buf = malloc (size);
2859     if (unlikely (buf == NULL))
2860         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2861
2862     status = backend->load_truetype_table (scaled_font, 0, 0, buf, &size);
2863     if (unlikely (status)) {
2864         free (buf);
2865         return status;
2866     }
2867
2868 #if CAIRO_HAS_FT_FONT
2869     load_flags = _cairo_ft_scaled_font_get_load_flags (scaled_font);
2870 #else
2871     load_flags = 0;
2872 #endif
2873     _cairo_output_stream_printf (ctx->stream,
2874                                  "<< "
2875                                  "/type 42 "
2876                                  "/index 0 "
2877                                  "/flags %d "
2878                                  "/source <|",
2879                                  load_flags);
2880
2881     base85_stream = _cairo_base85_stream_create (ctx->stream);
2882     len = to_be32 (size);
2883     _cairo_output_stream_write (base85_stream, &len, sizeof (len));
2884
2885     zlib_stream = _cairo_deflate_stream_create (base85_stream);
2886
2887     _cairo_output_stream_write (zlib_stream, buf, size);
2888     free (buf);
2889
2890     status2 = _cairo_output_stream_destroy (zlib_stream);
2891     if (status == CAIRO_STATUS_SUCCESS)
2892         status = status2;
2893
2894     status2 = _cairo_output_stream_destroy (base85_stream);
2895     if (status == CAIRO_STATUS_SUCCESS)
2896         status = status2;
2897
2898     _cairo_output_stream_printf (ctx->stream,
2899                                  "~> >> font dup /f%lu exch def set-font-face",
2900                                  _cairo_script_font_id (ctx, scaled_font));
2901
2902     return status;
2903 }
2904
2905 static cairo_status_t
2906 _emit_scaled_font_init (cairo_script_surface_t *surface,
2907                         cairo_scaled_font_t *scaled_font,
2908                         cairo_script_font_t **font_out)
2909 {
2910     cairo_script_context_t *ctx = to_context (surface);
2911     cairo_script_font_t *font_private;
2912     cairo_int_status_t status;
2913
2914     font_private = malloc (sizeof (cairo_script_font_t));
2915     if (unlikely (font_private == NULL))
2916         return _cairo_error (CAIRO_STATUS_NO_MEMORY);
2917
2918     _cairo_scaled_font_attach_private (scaled_font, &font_private->base, ctx,
2919                                        _cairo_script_scaled_font_fini);
2920
2921     font_private->parent = scaled_font;
2922     font_private->subset_glyph_index = 0;
2923     font_private->has_sfnt = TRUE;
2924
2925     cairo_list_add (&font_private->link, &ctx->fonts);
2926
2927     status = _bitmap_next_id (&ctx->font_id,
2928                               &font_private->id);
2929     if (unlikely (status)) {
2930         free (font_private);
2931         return status;
2932     }
2933
2934     status = _emit_context (surface);
2935     if (unlikely (status)) {
2936         free (font_private);
2937         return status;
2938     }
2939
2940     status = _emit_type42_font (surface, scaled_font);
2941     if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
2942         *font_out = font_private;
2943         return status;
2944     }
2945
2946     font_private->has_sfnt = FALSE;
2947     _cairo_output_stream_printf (ctx->stream,
2948                                  "dict\n"
2949                                  "  /type 3 set\n"
2950                                  "  /metrics [%f %f %f %f %f] set\n"
2951                                  "  /glyphs array set\n"
2952                                  "  font dup /f%lu exch def set-font-face",
2953                                  scaled_font->fs_extents.ascent,
2954                                  scaled_font->fs_extents.descent,
2955                                  scaled_font->fs_extents.height,
2956                                  scaled_font->fs_extents.max_x_advance,
2957                                  scaled_font->fs_extents.max_y_advance,
2958                                  font_private->id);
2959
2960     *font_out = font_private;
2961     return CAIRO_STATUS_SUCCESS;
2962 }
2963
2964 static cairo_status_t
2965 _emit_scaled_font (cairo_script_surface_t *surface,
2966                    cairo_scaled_font_t *scaled_font)
2967 {
2968     cairo_script_context_t *ctx = to_context (surface);
2969     cairo_matrix_t matrix;
2970     cairo_font_options_t options;
2971     cairo_bool_t matrix_updated = FALSE;
2972     cairo_status_t status;
2973     cairo_script_font_t *font_private;
2974
2975     cairo_scaled_font_get_ctm (scaled_font, &matrix);
2976     status = _emit_scaling_matrix (surface, &matrix, &matrix_updated);
2977     if (unlikely (status))
2978         return status;
2979
2980     if (! matrix_updated && surface->cr.current_scaled_font == scaled_font)
2981         return CAIRO_STATUS_SUCCESS;
2982
2983     surface->cr.current_scaled_font = scaled_font;
2984
2985     font_private = _cairo_script_font_get (ctx, scaled_font);
2986     if (font_private == NULL) {
2987         cairo_scaled_font_get_font_matrix (scaled_font, &matrix);
2988         status = _emit_font_matrix (surface, &matrix);
2989         if (unlikely (status))
2990             return status;
2991
2992         cairo_scaled_font_get_font_options (scaled_font, &options);
2993         status = _emit_font_options (surface, &options);
2994         if (unlikely (status))
2995             return status;
2996
2997         status = _emit_scaled_font_init (surface, scaled_font, &font_private);
2998         if (unlikely (status))
2999             return status;
3000
3001         assert (target_is_active (surface));
3002         _cairo_output_stream_printf (ctx->stream,
3003                                      " /scaled-font get /sf%lu exch def\n",
3004                                      font_private->id);
3005     } else {
3006         _cairo_output_stream_printf (ctx->stream,
3007                                      "sf%lu set-scaled-font\n",
3008                                      font_private->id);
3009     }
3010
3011     return CAIRO_STATUS_SUCCESS;
3012 }
3013
3014 static cairo_status_t
3015 _emit_scaled_glyph_vector (cairo_script_surface_t *surface,
3016                            cairo_scaled_font_t *scaled_font,
3017                            cairo_script_font_t *font_private,
3018                            cairo_scaled_glyph_t *scaled_glyph)
3019 {
3020     cairo_script_context_t *ctx = to_context (surface);
3021     cairo_script_implicit_context_t old_cr;
3022     cairo_status_t status;
3023     unsigned long index;
3024
3025     index = ++font_private->subset_glyph_index;
3026     scaled_glyph->dev_private_key = ctx;
3027     scaled_glyph->dev_private = (void *) index;
3028
3029     _cairo_output_stream_printf (ctx->stream,
3030                                  "%lu <<\n"
3031                                  "  /metrics [%f %f %f %f %f %f]\n"
3032                                  "  /render {\n",
3033                                  index,
3034                                  scaled_glyph->fs_metrics.x_bearing,
3035                                  scaled_glyph->fs_metrics.y_bearing,
3036                                  scaled_glyph->fs_metrics.width,
3037                                  scaled_glyph->fs_metrics.height,
3038                                  scaled_glyph->fs_metrics.x_advance,
3039                                  scaled_glyph->fs_metrics.y_advance);
3040
3041     if (! _cairo_matrix_is_identity (&scaled_font->scale_inverse)) {
3042         _cairo_output_stream_printf (ctx->stream,
3043                                      "[%f %f %f %f %f %f] transform\n",
3044                                      scaled_font->scale_inverse.xx,
3045                                      scaled_font->scale_inverse.yx,
3046                                      scaled_font->scale_inverse.xy,
3047                                      scaled_font->scale_inverse.yy,
3048                                      scaled_font->scale_inverse.x0,
3049                                      scaled_font->scale_inverse.y0);
3050     }
3051
3052     old_cr = surface->cr;
3053     _cairo_script_implicit_context_init (&surface->cr);
3054     status = _cairo_recording_surface_replay (scaled_glyph->recording_surface,
3055                                               &surface->base);
3056     surface->cr = old_cr;
3057
3058     _cairo_output_stream_puts (ctx->stream, "} >> set\n");
3059
3060     return status;
3061 }
3062
3063 static cairo_status_t
3064 _emit_scaled_glyph_bitmap (cairo_script_surface_t *surface,
3065                            cairo_scaled_font_t *scaled_font,
3066                            cairo_script_font_t *font_private,
3067                            cairo_scaled_glyph_t *scaled_glyph)
3068 {
3069     cairo_script_context_t *ctx = to_context (surface);
3070     cairo_status_t status;
3071     unsigned long index;
3072
3073     index = ++font_private->subset_glyph_index;
3074     scaled_glyph->dev_private_key = ctx;
3075     scaled_glyph->dev_private = (void *) index;
3076
3077     _cairo_output_stream_printf (ctx->stream,
3078                                  "%lu <<\n"
3079                                  "  /metrics [%f %f %f %f %f %f]\n"
3080                                  "  /render {\n"
3081                                  "%f %f translate\n",
3082                                  index,
3083                                  scaled_glyph->fs_metrics.x_bearing,
3084                                  scaled_glyph->fs_metrics.y_bearing,
3085                                  scaled_glyph->fs_metrics.width,
3086                                  scaled_glyph->fs_metrics.height,
3087                                  scaled_glyph->fs_metrics.x_advance,
3088                                  scaled_glyph->fs_metrics.y_advance,
3089                                  scaled_glyph->fs_metrics.x_bearing,
3090                                  scaled_glyph->fs_metrics.y_bearing);
3091
3092     status = _emit_image_surface (surface, scaled_glyph->surface);
3093     if (unlikely (status))
3094         return status;
3095
3096     _cairo_output_stream_puts (ctx->stream, "pattern ");
3097
3098     if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) {
3099         _cairo_output_stream_printf (ctx->stream,
3100                                      "\n  [%f %f %f %f %f %f] set-matrix\n",
3101                                      scaled_font->font_matrix.xx,
3102                                      scaled_font->font_matrix.yx,
3103                                      scaled_font->font_matrix.xy,
3104                                      scaled_font->font_matrix.yy,
3105                                      scaled_font->font_matrix.x0,
3106                                      scaled_font->font_matrix.y0);
3107     }
3108     _cairo_output_stream_puts (ctx->stream,
3109                                  "mask\n} >> set\n");
3110
3111     return CAIRO_STATUS_SUCCESS;
3112 }
3113
3114 static cairo_status_t
3115 _emit_scaled_glyph_prologue (cairo_script_surface_t *surface,
3116                              cairo_scaled_font_t *scaled_font)
3117 {
3118     cairo_script_context_t *ctx = to_context (surface);
3119
3120     _cairo_output_stream_printf (ctx->stream, "f%lu /glyphs get\n",
3121                                  _cairo_script_font_id (ctx, scaled_font));
3122
3123     return CAIRO_STATUS_SUCCESS;
3124 }
3125
3126 static cairo_status_t
3127 _emit_scaled_glyphs (cairo_script_surface_t *surface,
3128                      cairo_scaled_font_t *scaled_font,
3129                      cairo_glyph_t *glyphs,
3130                      unsigned int num_glyphs)
3131 {
3132     cairo_script_context_t *ctx = to_context (surface);
3133     cairo_script_font_t *font_private;
3134     cairo_status_t status;
3135     unsigned int n;
3136     cairo_bool_t have_glyph_prologue = FALSE;
3137
3138     if (num_glyphs == 0)
3139         return CAIRO_STATUS_SUCCESS;
3140
3141     font_private = _cairo_script_font_get (ctx, scaled_font);
3142     if (font_private->has_sfnt)
3143         return CAIRO_STATUS_SUCCESS;
3144
3145     _cairo_scaled_font_freeze_cache (scaled_font);
3146     for (n = 0; n < num_glyphs; n++) {
3147         cairo_scaled_glyph_t *scaled_glyph;
3148
3149         status = _cairo_scaled_glyph_lookup (scaled_font,
3150                                              glyphs[n].index,
3151                                              CAIRO_SCALED_GLYPH_INFO_METRICS,
3152                                              &scaled_glyph);
3153         if (unlikely (status))
3154             break;
3155
3156         if (scaled_glyph->dev_private_key == ctx)
3157             continue;
3158
3159         status = _cairo_scaled_glyph_lookup (scaled_font,
3160                                              glyphs[n].index,
3161                                              CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE,
3162                                              &scaled_glyph);
3163         if (_cairo_status_is_error (status))
3164             break;
3165
3166         if (status == CAIRO_STATUS_SUCCESS) {
3167             if (! have_glyph_prologue) {
3168                 status = _emit_scaled_glyph_prologue (surface, scaled_font);
3169                 if (unlikely (status))
3170                     break;
3171
3172                 have_glyph_prologue = TRUE;
3173             }
3174
3175             status = _emit_scaled_glyph_vector (surface,
3176                                                 scaled_font, font_private,
3177                                                 scaled_glyph);
3178             if (unlikely (status))
3179                 break;
3180
3181             continue;
3182         }
3183
3184         status = _cairo_scaled_glyph_lookup (scaled_font,
3185                                              glyphs[n].index,
3186                                              CAIRO_SCALED_GLYPH_INFO_SURFACE,
3187                                              &scaled_glyph);
3188         if (_cairo_status_is_error (status))
3189             break;
3190
3191         if (status == CAIRO_STATUS_SUCCESS) {
3192             if (! have_glyph_prologue) {
3193                 status = _emit_scaled_glyph_prologue (surface, scaled_font);
3194                 if (unlikely (status))
3195                     break;
3196
3197                 have_glyph_prologue = TRUE;
3198             }
3199
3200             status = _emit_scaled_glyph_bitmap (surface,
3201                                                 scaled_font,
3202                                                 font_private,
3203                                                 scaled_glyph);
3204             if (unlikely (status))
3205                 break;
3206
3207             continue;
3208         }
3209     }
3210     _cairo_scaled_font_thaw_cache (scaled_font);
3211
3212     if (have_glyph_prologue) {
3213         _cairo_output_stream_puts (to_context (surface)->stream, "pop pop\n");
3214     }
3215
3216     return status;
3217 }
3218
3219 static void
3220 to_octal (int value, char *buf, size_t size)
3221 {
3222     do {
3223         buf[--size] = '0' + (value & 7);
3224         value >>= 3;
3225     } while (size);
3226 }
3227
3228 static void
3229 _emit_string_literal (cairo_script_surface_t *surface,
3230                       const char *utf8, int len)
3231 {
3232     cairo_script_context_t *ctx = to_context (surface);
3233     char c;
3234     const char *end;
3235
3236     _cairo_output_stream_puts (ctx->stream, "(");
3237
3238     if (utf8 == NULL) {
3239         end = utf8;
3240     } else {
3241         if (len < 0)
3242             len = strlen (utf8);
3243         end = utf8 + len;
3244     }
3245
3246     while (utf8 < end) {
3247         switch ((c = *utf8++)) {
3248         case '\n':
3249             c = 'n';
3250             goto ESCAPED_CHAR;
3251         case '\r':
3252             c = 'r';
3253             goto ESCAPED_CHAR;
3254         case '\t':
3255             c = 't';
3256             goto ESCAPED_CHAR;
3257         case '\b':
3258             c = 'b';
3259             goto ESCAPED_CHAR;
3260         case '\f':
3261             c = 'f';
3262             goto ESCAPED_CHAR;
3263         case '\\':
3264         case '(':
3265         case ')':
3266 ESCAPED_CHAR:
3267             _cairo_output_stream_printf (ctx->stream, "\\%c", c);
3268             break;
3269         default:
3270             if (isprint (c) || isspace (c)) {
3271                 _cairo_output_stream_printf (ctx->stream, "%c", c);
3272             } else {
3273                 char buf[4] = { '\\' };
3274
3275                 to_octal (c, buf+1, 3);
3276                 _cairo_output_stream_write (ctx->stream, buf, 4);
3277             }
3278             break;
3279         }
3280     }
3281     _cairo_output_stream_puts (ctx->stream, ")");
3282 }
3283
3284 static cairo_int_status_t
3285 _cairo_script_surface_show_text_glyphs (void                        *abstract_surface,
3286                                         cairo_operator_t             op,
3287                                         const cairo_pattern_t       *source,
3288                                         const char                  *utf8,
3289                                         int                          utf8_len,
3290                                         cairo_glyph_t               *glyphs,
3291                                         int                          num_glyphs,
3292                                         const cairo_text_cluster_t  *clusters,
3293                                         int                          num_clusters,
3294                                         cairo_text_cluster_flags_t   backward,
3295                                         cairo_scaled_font_t         *scaled_font,
3296                                         const cairo_clip_t          *clip)
3297 {
3298     cairo_script_surface_t *surface = abstract_surface;
3299     cairo_script_context_t *ctx = to_context (surface);
3300     cairo_script_font_t *font_private;
3301     cairo_scaled_glyph_t *scaled_glyph;
3302     cairo_matrix_t matrix;
3303     cairo_status_t status;
3304     double x, y, ix, iy;
3305     int n;
3306     cairo_output_stream_t *base85_stream = NULL;
3307
3308     status = active (surface);
3309     if (unlikely (status))
3310         return status;
3311
3312     status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
3313     if (unlikely (status))
3314         goto BAIL;
3315
3316     status = _emit_context (surface);
3317     if (unlikely (status))
3318         goto BAIL;
3319
3320     status = _emit_source (surface, op, source);
3321     if (unlikely (status))
3322         goto BAIL;
3323
3324     status = _emit_scaled_font (surface, scaled_font);
3325     if (unlikely (status))
3326         goto BAIL;
3327
3328     status = _emit_operator (surface, op);
3329     if (unlikely (status))
3330         goto BAIL;
3331
3332     status = _emit_scaled_glyphs (surface, scaled_font, glyphs, num_glyphs);
3333     if (unlikely (status))
3334         goto BAIL;
3335
3336     /* (utf8) [cx cy [glyphs]] [clusters] backward show_text_glyphs */
3337     /* [cx cy [glyphs]] show_glyphs */
3338
3339     if (utf8 != NULL && clusters != NULL) {
3340         _emit_string_literal (surface, utf8, utf8_len);
3341         _cairo_output_stream_puts (ctx->stream, " ");
3342     }
3343
3344     matrix = surface->cr.current_ctm;
3345     status = cairo_matrix_invert (&matrix);
3346     assert (status == CAIRO_STATUS_SUCCESS);
3347
3348     ix = x = glyphs[0].x;
3349     iy = y = glyphs[0].y;
3350     cairo_matrix_transform_point (&matrix, &ix, &iy);
3351     ix -= scaled_font->font_matrix.x0;
3352     iy -= scaled_font->font_matrix.y0;
3353
3354     _cairo_scaled_font_freeze_cache (scaled_font);
3355     font_private = _cairo_script_font_get (ctx, scaled_font);
3356
3357     _cairo_output_stream_printf (ctx->stream,
3358                                  "[%f %f ",
3359                                  ix, iy);
3360
3361     for (n = 0; n < num_glyphs; n++) {
3362         if (font_private->has_sfnt) {
3363             if (glyphs[n].index > 256)
3364                 break;
3365         } else {
3366             status = _cairo_scaled_glyph_lookup (scaled_font,
3367                                                  glyphs[n].index,
3368                                                  CAIRO_SCALED_GLYPH_INFO_METRICS,
3369                                                  &scaled_glyph);
3370             if (unlikely (status)) {
3371                 _cairo_scaled_font_thaw_cache (scaled_font);
3372                 goto BAIL;
3373             }
3374
3375             if ((long unsigned) scaled_glyph->dev_private > 256)
3376                 break;
3377         }
3378     }
3379
3380     if (n == num_glyphs) {
3381         _cairo_output_stream_puts (ctx->stream, "<~");
3382         base85_stream = _cairo_base85_stream_create (ctx->stream);
3383     } else
3384         _cairo_output_stream_puts (ctx->stream, "[");
3385
3386     for (n = 0; n < num_glyphs; n++) {
3387         double dx, dy;
3388
3389         status = _cairo_scaled_glyph_lookup (scaled_font,
3390                                              glyphs[n].index,
3391                                              CAIRO_SCALED_GLYPH_INFO_METRICS,
3392                                              &scaled_glyph);
3393         if (unlikely (status))
3394             goto BAIL;
3395
3396         if (fabs (glyphs[n].x - x) > 1e-5 || fabs (glyphs[n].y - y) > 1e-5) {
3397             if (fabs (glyphs[n].y - y) < 1e-5) {
3398                 if (base85_stream != NULL) {
3399                     status = _cairo_output_stream_destroy (base85_stream);
3400                     if (unlikely (status)) {
3401                         base85_stream = NULL;
3402                         break;
3403                     }
3404
3405                     _cairo_output_stream_printf (ctx->stream,
3406                                                  "~> %f <~", glyphs[n].x - x);
3407                     base85_stream = _cairo_base85_stream_create (ctx->stream);
3408                 } else {
3409                     _cairo_output_stream_printf (ctx->stream,
3410                                                  " ] %f [ ", glyphs[n].x - x);
3411                 }
3412
3413                 x = glyphs[n].x;
3414             } else {
3415                 ix = x = glyphs[n].x;
3416                 iy = y = glyphs[n].y;
3417                 cairo_matrix_transform_point (&matrix, &ix, &iy);
3418                 ix -= scaled_font->font_matrix.x0;
3419                 iy -= scaled_font->font_matrix.y0;
3420                 if (base85_stream != NULL) {
3421                     status = _cairo_output_stream_destroy (base85_stream);
3422                     if (unlikely (status)) {
3423                         base85_stream = NULL;
3424                         break;
3425                     }
3426
3427                     _cairo_output_stream_printf (ctx->stream,
3428                                                  "~> %f %f <~",
3429                                                  ix, iy);
3430                     base85_stream = _cairo_base85_stream_create (ctx->stream);
3431                 } else {
3432                     _cairo_output_stream_printf (ctx->stream,
3433                                                  " ] %f %f [ ",
3434                                                  ix, iy);
3435                 }
3436             }
3437         }
3438         if (base85_stream != NULL) {
3439             uint8_t c;
3440
3441             if (font_private->has_sfnt)
3442                 c = glyphs[n].index;
3443             else
3444                 c = (uint8_t) (long unsigned) scaled_glyph->dev_private;
3445
3446             _cairo_output_stream_write (base85_stream, &c, 1);
3447         } else {
3448             if (font_private->has_sfnt)
3449                 _cairo_output_stream_printf (ctx->stream, " %lu",
3450                                              glyphs[n].index);
3451             else
3452                 _cairo_output_stream_printf (ctx->stream, " %lu",
3453                                              (long unsigned) scaled_glyph->dev_private);
3454         }
3455
3456         dx = scaled_glyph->metrics.x_advance;
3457         dy = scaled_glyph->metrics.y_advance;
3458         cairo_matrix_transform_distance (&scaled_font->ctm, &dx, &dy);
3459         x += dx;
3460         y += dy;
3461     }
3462     _cairo_scaled_font_thaw_cache (scaled_font);
3463
3464     if (base85_stream != NULL) {
3465         cairo_status_t status2;
3466
3467         status2 = _cairo_output_stream_destroy (base85_stream);
3468         if (status == CAIRO_STATUS_SUCCESS)
3469             status = status2;
3470
3471         _cairo_output_stream_printf (ctx->stream, "~>");
3472     } else {
3473         _cairo_output_stream_puts (ctx->stream, " ]");
3474     }
3475     if (unlikely (status))
3476         return status;
3477
3478     if (utf8 != NULL && clusters != NULL) {
3479         for (n = 0; n < num_clusters; n++) {
3480             if (clusters[n].num_bytes > UCHAR_MAX ||
3481                 clusters[n].num_glyphs > UCHAR_MAX)
3482             {
3483                 break;
3484             }
3485         }
3486
3487         if (n < num_clusters) {
3488             _cairo_output_stream_puts (ctx->stream, "] [ ");
3489             for (n = 0; n < num_clusters; n++) {
3490                 _cairo_output_stream_printf (ctx->stream,
3491                                              "%d %d ",
3492                                              clusters[n].num_bytes,
3493                                              clusters[n].num_glyphs);
3494             }
3495             _cairo_output_stream_puts (ctx->stream, "]");
3496         }
3497         else
3498         {
3499             _cairo_output_stream_puts (ctx->stream, "] <~");
3500             base85_stream = _cairo_base85_stream_create (ctx->stream);
3501             for (n = 0; n < num_clusters; n++) {
3502                 uint8_t c[2];
3503                 c[0] = clusters[n].num_bytes;
3504                 c[1] = clusters[n].num_glyphs;
3505                 _cairo_output_stream_write (base85_stream, c, 2);
3506             }
3507             status = _cairo_output_stream_destroy (base85_stream);
3508             if (unlikely (status))
3509                 goto BAIL;
3510
3511             _cairo_output_stream_puts (ctx->stream, "~>");
3512         }
3513
3514         _cairo_output_stream_printf (ctx->stream,
3515                                      " //%s show-text-glyphs\n",
3516                                      _direction_to_string (backward));
3517     } else {
3518         _cairo_output_stream_puts (ctx->stream,
3519                                    "] show-glyphs\n");
3520     }
3521
3522     inactive (surface);
3523
3524     if (_cairo_surface_wrapper_is_active (&surface->wrapper)){
3525         return _cairo_surface_wrapper_show_text_glyphs (&surface->wrapper,
3526                                                         op, source,
3527                                                         utf8, utf8_len,
3528                                                         glyphs, num_glyphs,
3529                                                         clusters, num_clusters,
3530                                                         backward,
3531                                                         scaled_font,
3532                                                         clip);
3533     }
3534
3535     return CAIRO_STATUS_SUCCESS;
3536
3537 BAIL:
3538     inactive (surface);
3539     return status;
3540 }
3541
3542 static cairo_bool_t
3543 _cairo_script_surface_get_extents (void *abstract_surface,
3544                                    cairo_rectangle_int_t *rectangle)
3545 {
3546     cairo_script_surface_t *surface = abstract_surface;
3547
3548     if (_cairo_surface_wrapper_is_active (&surface->wrapper)) {
3549         return _cairo_surface_wrapper_get_extents (&surface->wrapper,
3550                                                    rectangle);
3551     }
3552
3553     if (surface->width < 0 || surface->height < 0)
3554         return FALSE;
3555
3556     rectangle->x = 0;
3557     rectangle->y = 0;
3558     rectangle->width = surface->width;
3559     rectangle->height = surface->height;
3560
3561     return TRUE;
3562 }
3563
3564 static const cairo_surface_backend_t
3565 _cairo_script_surface_backend = {
3566     CAIRO_SURFACE_TYPE_SCRIPT,
3567     _cairo_script_surface_finish,
3568
3569     _cairo_default_context_create,
3570
3571     _cairo_script_surface_create_similar,
3572     NULL, /* create similar image */
3573     NULL, /* map to image */
3574     NULL, /* unmap image */
3575
3576     _cairo_script_surface_source,
3577     _cairo_script_surface_acquire_source_image,
3578     _cairo_script_surface_release_source_image,
3579     _cairo_script_surface_snapshot,
3580
3581     _cairo_script_surface_copy_page,
3582     _cairo_script_surface_show_page,
3583
3584     _cairo_script_surface_get_extents,
3585     NULL, /* get_font_options */
3586
3587     NULL, /* flush */
3588     NULL, /* mark_dirty_rectangle */
3589
3590     _cairo_script_surface_paint,
3591     _cairo_script_surface_mask,
3592     _cairo_script_surface_stroke,
3593     _cairo_script_surface_fill,
3594     NULL, /* fill/stroke */
3595     NULL, /* glyphs */
3596     _cairo_script_surface_has_show_text_glyphs,
3597     _cairo_script_surface_show_text_glyphs
3598 };
3599
3600 static void
3601 _cairo_script_implicit_context_init (cairo_script_implicit_context_t *cr)
3602 {
3603     cr->current_operator = CAIRO_GSTATE_OPERATOR_DEFAULT;
3604     cr->current_fill_rule = CAIRO_GSTATE_FILL_RULE_DEFAULT;
3605     cr->current_tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
3606     cr->current_antialias = CAIRO_ANTIALIAS_DEFAULT;
3607     _cairo_stroke_style_init (&cr->current_style);
3608     _cairo_pattern_init_solid (&cr->current_source.solid,
3609                                CAIRO_COLOR_BLACK);
3610     _cairo_path_fixed_init (&cr->current_path);
3611     cairo_matrix_init_identity (&cr->current_ctm);
3612     cairo_matrix_init_identity (&cr->current_stroke_matrix);
3613     cairo_matrix_init_identity (&cr->current_font_matrix);
3614     _cairo_font_options_init_default (&cr->current_font_options);
3615     cr->current_scaled_font = NULL;
3616     cr->has_clip = FALSE;
3617 }
3618
3619 static void
3620 _cairo_script_implicit_context_reset (cairo_script_implicit_context_t *cr)
3621 {
3622     free (cr->current_style.dash);
3623     cr->current_style.dash = NULL;
3624
3625     _cairo_pattern_fini (&cr->current_source.base);
3626     _cairo_path_fixed_fini (&cr->current_path);
3627
3628     _cairo_script_implicit_context_init (cr);
3629 }
3630
3631 static cairo_script_surface_t *
3632 _cairo_script_surface_create_internal (cairo_script_context_t *ctx,
3633                                        cairo_content_t content,
3634                                        cairo_rectangle_t *extents,
3635                                        cairo_surface_t *passthrough)
3636 {
3637     cairo_script_surface_t *surface;
3638
3639     if (unlikely (ctx == NULL))
3640         return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NULL_POINTER));
3641
3642     surface = malloc (sizeof (cairo_script_surface_t));
3643     if (unlikely (surface == NULL))
3644         return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
3645
3646     _cairo_surface_init (&surface->base,
3647                          &_cairo_script_surface_backend,
3648                          &ctx->base,
3649                          content);
3650
3651     _cairo_surface_wrapper_init (&surface->wrapper, passthrough);
3652
3653     _cairo_surface_clipper_init (&surface->clipper,
3654                                  _cairo_script_surface_clipper_intersect_clip_path);
3655
3656     surface->width = surface->height = -1;
3657     if (extents) {
3658         surface->width = extents->width;
3659         surface->height = extents->height;
3660         cairo_surface_set_device_offset (&surface->base,
3661                                          -extents->x, -extents->y);
3662     }
3663
3664     surface->emitted = FALSE;
3665     surface->defined = FALSE;
3666     surface->active = FALSE;
3667     surface->operand.type = SURFACE;
3668     cairo_list_init (&surface->operand.link);
3669
3670     _cairo_script_implicit_context_init (&surface->cr);
3671
3672     return surface;
3673 }
3674
3675 static const cairo_device_backend_t _cairo_script_device_backend = {
3676     CAIRO_DEVICE_TYPE_SCRIPT,
3677
3678     NULL, NULL, /* lock, unlock */
3679
3680     _device_flush,  /* flush */
3681     NULL,  /* finish */
3682     _device_destroy
3683 };
3684
3685 cairo_device_t *
3686 _cairo_script_context_create_internal (cairo_output_stream_t *stream)
3687 {
3688     cairo_script_context_t *ctx;
3689
3690     ctx = malloc (sizeof (cairo_script_context_t));
3691     if (unlikely (ctx == NULL))
3692         return _cairo_device_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
3693
3694     memset (ctx, 0, sizeof (cairo_script_context_t));
3695
3696     _cairo_device_init (&ctx->base, &_cairo_script_device_backend);
3697
3698     cairo_list_init (&ctx->operands);
3699     cairo_list_init (&ctx->deferred);
3700     ctx->stream = stream;
3701     ctx->mode = CAIRO_SCRIPT_MODE_ASCII;
3702
3703     cairo_list_init (&ctx->fonts);
3704     cairo_list_init (&ctx->defines);
3705
3706     ctx->attach_snapshots = TRUE;
3707
3708     return &ctx->base;
3709 }
3710
3711 void
3712 _cairo_script_context_attach_snapshots (cairo_device_t *device,
3713                                         cairo_bool_t enable)
3714 {
3715     cairo_script_context_t *ctx;
3716
3717     ctx = (cairo_script_context_t *) device;
3718     ctx->attach_snapshots = enable;
3719 }
3720
3721 static cairo_device_t *
3722 _cairo_script_context_create (cairo_output_stream_t *stream)
3723 {
3724     cairo_script_context_t *ctx;
3725
3726     ctx = (cairo_script_context_t *)
3727         _cairo_script_context_create_internal (stream);
3728     if (unlikely (ctx->base.status))
3729         return &ctx->base;
3730
3731     ctx->owns_stream = TRUE;
3732     _cairo_output_stream_puts (ctx->stream, "%!CairoScript\n");
3733     return &ctx->base;
3734 }
3735
3736 /**
3737  * cairo_script_create:
3738  * @filename: the name (path) of the file to write the script to
3739  *
3740  * Creates a output device for emitting the script, used when
3741  * creating the individual surfaces.
3742  *
3743  * Return value: a pointer to the newly created device. The caller
3744  * owns the surface and should call cairo_device_destroy() when done
3745  * with it.
3746  *
3747  * This function always returns a valid pointer, but it will return a
3748  * pointer to a "nil" device if an error such as out of memory
3749  * occurs. You can use cairo_device_status() to check for this.
3750  *
3751  * Since: 1.12
3752  **/
3753 cairo_device_t *
3754 cairo_script_create (const char *filename)
3755 {
3756     cairo_output_stream_t *stream;
3757     cairo_status_t status;
3758
3759     stream = _cairo_output_stream_create_for_filename (filename);
3760     if ((status = _cairo_output_stream_get_status (stream)))
3761         return _cairo_device_create_in_error (status);
3762
3763     return _cairo_script_context_create (stream);
3764 }
3765
3766 /**
3767  * cairo_script_create_for_stream:
3768  * @write_func: callback function passed the bytes written to the script
3769  * @closure: user data to be passed to the callback
3770  *
3771  * Creates a output device for emitting the script, used when
3772  * creating the individual surfaces.
3773  *
3774  * Return value: a pointer to the newly created device. The caller
3775  * owns the surface and should call cairo_device_destroy() when done
3776  * with it.
3777  *
3778  * This function always returns a valid pointer, but it will return a
3779  * pointer to a "nil" device if an error such as out of memory
3780  * occurs. You can use cairo_device_status() to check for this.
3781  *
3782  * Since: 1.12
3783  **/
3784 cairo_device_t *
3785 cairo_script_create_for_stream (cairo_write_func_t       write_func,
3786                                 void                    *closure)
3787 {
3788     cairo_output_stream_t *stream;
3789     cairo_status_t status;
3790
3791     stream = _cairo_output_stream_create (write_func, NULL, closure);
3792     if ((status = _cairo_output_stream_get_status (stream)))
3793         return _cairo_device_create_in_error (status);
3794
3795     return _cairo_script_context_create (stream);
3796 }
3797
3798 /**
3799  * cairo_script_write_comment:
3800  * @script: the script (output device)
3801  * @comment: the string to emit
3802  * @len:the length of the sting to write, or -1 to use strlen()
3803  *
3804  * Emit a string verbatim into the script.
3805  *
3806  * Since: 1.12
3807  **/
3808 void
3809 cairo_script_write_comment (cairo_device_t *script,
3810                             const char *comment,
3811                             int len)
3812 {
3813     cairo_script_context_t *context = (cairo_script_context_t *) script;
3814
3815     if (len < 0)
3816         len = strlen (comment);
3817
3818     _cairo_output_stream_puts (context->stream, "% ");
3819     _cairo_output_stream_write (context->stream, comment, len);
3820     _cairo_output_stream_puts (context->stream, "\n");
3821 }
3822
3823 /**
3824  * cairo_script_set_mode:
3825  * @script: The script (output device)
3826  * @mode: the new mode
3827  *
3828  * Change the output mode of the script
3829  *
3830  * Since: 1.12
3831  **/
3832 void
3833 cairo_script_set_mode (cairo_device_t *script,
3834                        cairo_script_mode_t mode)
3835 {
3836     cairo_script_context_t *context = (cairo_script_context_t *) script;
3837
3838     context->mode = mode;
3839 }
3840
3841 /**
3842  * cairo_script_get_mode:
3843  * @script: The script (output device) to query
3844  *
3845  * Queries the script for its current output mode.
3846  *
3847  * Return value: the current output mode of the script
3848  *
3849  * Since: 1.12
3850  **/
3851 cairo_script_mode_t
3852 cairo_script_get_mode (cairo_device_t *script)
3853 {
3854     cairo_script_context_t *context = (cairo_script_context_t *) script;
3855
3856     return context->mode;
3857 }
3858
3859 /**
3860  * cairo_script_surface_create:
3861  * @script: the script (output device)
3862  * @content: the content of the surface
3863  * @width: width in pixels
3864  * @height: height in pixels
3865  *
3866  * Create a new surface that will emit its rendering through @script
3867  *
3868  * Return value: a pointer to the newly created surface. The caller
3869  * owns the surface and should call cairo_surface_destroy() when done
3870  * with it.
3871  *
3872  * This function always returns a valid pointer, but it will return a
3873  * pointer to a "nil" surface if an error such as out of memory
3874  * occurs. You can use cairo_surface_status() to check for this.
3875  *
3876  * Since: 1.12
3877  **/
3878 cairo_surface_t *
3879 cairo_script_surface_create (cairo_device_t *script,
3880                              cairo_content_t content,
3881                              double width,
3882                              double height)
3883 {
3884     cairo_rectangle_t *extents, r;
3885
3886     if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT))
3887         return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
3888
3889     if (unlikely (script->status))
3890         return _cairo_surface_create_in_error (script->status);
3891
3892     extents = NULL;
3893     if (width > 0 && height > 0) {
3894         r.x = r.y = 0;
3895         r.width  = width;
3896         r.height = height;
3897         extents = &r;
3898     }
3899     return &_cairo_script_surface_create_internal ((cairo_script_context_t *) script,
3900                                                    content, extents,
3901                                                    NULL)->base;
3902 }
3903 slim_hidden_def (cairo_script_surface_create);
3904
3905 /**
3906  * cairo_script_surface_create_for_target:
3907  * @script: the script (output device)
3908  * @target: a target surface to wrap
3909  *
3910  * Create a pxoy surface that will render to @target and record
3911  * the operations to @device.
3912  *
3913  * Return value: a pointer to the newly created surface. The caller
3914  * owns the surface and should call cairo_surface_destroy() when done
3915  * with it.
3916  *
3917  * This function always returns a valid pointer, but it will return a
3918  * pointer to a "nil" surface if an error such as out of memory
3919  * occurs. You can use cairo_surface_status() to check for this.
3920  *
3921  * Since: 1.12
3922  **/
3923 cairo_surface_t *
3924 cairo_script_surface_create_for_target (cairo_device_t *script,
3925                                         cairo_surface_t *target)
3926 {
3927     cairo_rectangle_int_t extents;
3928     cairo_rectangle_t rect, *r;
3929
3930     if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT))
3931         return _cairo_surface_create_in_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
3932
3933     if (unlikely (script->status))
3934         return _cairo_surface_create_in_error (script->status);
3935
3936     if (unlikely (target->status))
3937         return _cairo_surface_create_in_error (target->status);
3938
3939     r = NULL;
3940     if (_cairo_surface_get_extents (target, &extents)) {
3941         rect.x = rect.y = 0;
3942         rect.width = extents.width;
3943         rect.height = extents.height;
3944         r= &rect;
3945     }
3946     return &_cairo_script_surface_create_internal ((cairo_script_context_t *) script,
3947                                                    target->content, r,
3948                                                    target)->base;
3949 }
3950
3951 /**
3952  * cairo_script_from_recording_surface:
3953  * @script: the script (output device)
3954  * @recording_surface: the recording surface to replay
3955  *
3956  * Converts the record operations in @recording_surface into a script.
3957  *
3958  * Return value: #CAIRO_STATUS_SUCCESS on successful completion or an error code.
3959  *
3960  * Since: 1.12
3961  **/
3962 cairo_status_t
3963 cairo_script_from_recording_surface (cairo_device_t *script,
3964                                      cairo_surface_t *recording_surface)
3965 {
3966     cairo_rectangle_t r, *extents;
3967     cairo_surface_t *surface;
3968     cairo_status_t status;
3969
3970     if (unlikely (script->backend->type != CAIRO_DEVICE_TYPE_SCRIPT))
3971         return _cairo_error (CAIRO_STATUS_DEVICE_TYPE_MISMATCH);
3972
3973     if (unlikely (script->status))
3974         return _cairo_error (script->status);
3975
3976     if (unlikely (recording_surface->status))
3977         return recording_surface->status;
3978
3979     if (unlikely (! _cairo_surface_is_recording (recording_surface)))
3980         return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
3981
3982     extents = NULL;
3983     if (_cairo_recording_surface_get_bounds (recording_surface, &r))
3984         extents = &r;
3985
3986     surface = &_cairo_script_surface_create_internal ((cairo_script_context_t *) script,
3987                                                       recording_surface->content,
3988                                                       extents,
3989                                                       NULL)->base;
3990     if (unlikely (surface->status))
3991         return surface->status;
3992
3993     status = _cairo_recording_surface_replay (recording_surface, surface);
3994     cairo_surface_destroy (surface);
3995
3996     return status;
3997 }