tizen 2.3.1 release
[framework/graphics/cairo.git] / src / cairo-paginated-surface.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2005 Red Hat, Inc
4  * Copyright © 2007 Adrian Johnson
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 Red Hat, Inc.
32  *
33  * Contributor(s):
34  *      Carl Worth <cworth@cworth.org>
35  *      Keith Packard <keithp@keithp.com>
36  *      Adrian Johnson <ajohnson@redneon.com>
37  */
38
39 /* The paginated surface layer exists to provide as much code sharing
40  * as possible for the various paginated surface backends in cairo
41  * (PostScript, PDF, etc.). See cairo-paginated-private.h for
42  * more details on how it works and how to use it.
43  */
44
45 #include "cairoint.h"
46
47 #include "cairo-paginated-private.h"
48 #include "cairo-paginated-surface-private.h"
49 #include "cairo-recording-surface-private.h"
50 #include "cairo-analysis-surface-private.h"
51 #include "cairo-error-private.h"
52 #include "cairo-image-surface-private.h"
53 #include "cairo-surface-subsurface-inline.h"
54
55 static const cairo_surface_backend_t cairo_paginated_surface_backend;
56
57 static cairo_int_status_t
58 _cairo_paginated_surface_show_page (void *abstract_surface);
59
60 static cairo_surface_t *
61 _cairo_paginated_surface_create_similar (void                   *abstract_surface,
62                                          cairo_content_t         content,
63                                          int                     width,
64                                          int                     height)
65 {
66     cairo_rectangle_t rect;
67     rect.x = rect.y = 0.;
68     rect.width = width;
69     rect.height = height;
70     return cairo_recording_surface_create (content, &rect);
71 }
72
73 static cairo_surface_t *
74 _create_recording_surface_for_target (cairo_surface_t *target,
75                                       cairo_content_t content)
76 {
77     cairo_rectangle_int_t rect;
78
79     if (_cairo_surface_get_extents (target, &rect)) {
80         cairo_rectangle_t recording_extents;
81
82         recording_extents.x = rect.x;
83         recording_extents.y = rect.y;
84         recording_extents.width = rect.width;
85         recording_extents.height = rect.height;
86
87         return cairo_recording_surface_create (content, &recording_extents);
88     } else {
89         return cairo_recording_surface_create (content, NULL);
90     }
91 }
92
93 cairo_surface_t *
94 _cairo_paginated_surface_create (cairo_surface_t                                *target,
95                                  cairo_content_t                                 content,
96                                  const cairo_paginated_surface_backend_t        *backend)
97 {
98     cairo_paginated_surface_t *surface;
99     cairo_status_t status;
100
101     surface = malloc (sizeof (cairo_paginated_surface_t));
102     if (unlikely (surface == NULL)) {
103         status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
104         goto FAIL;
105     }
106
107     _cairo_surface_init (&surface->base,
108                          &cairo_paginated_surface_backend,
109                          NULL, /* device */
110                          content);
111
112     /* Override surface->base.type with target's type so we don't leak
113      * evidence of the paginated wrapper out to the user. */
114     surface->base.type = target->type;
115
116     surface->target = cairo_surface_reference (target);
117
118     surface->content = content;
119     surface->backend = backend;
120
121     surface->recording_surface = _create_recording_surface_for_target (target, content);
122     status = surface->recording_surface->status;
123     if (unlikely (status))
124         goto FAIL_CLEANUP_SURFACE;
125
126     surface->page_num = 1;
127     surface->base.is_clear = TRUE;
128
129     return &surface->base;
130
131   FAIL_CLEANUP_SURFACE:
132     cairo_surface_destroy (target);
133     cairo_surface_destroy (surface->recording_surface);
134     free (surface);
135   FAIL:
136     return _cairo_surface_create_in_error (status);
137 }
138
139 cairo_bool_t
140 _cairo_surface_is_paginated (cairo_surface_t *surface)
141 {
142     return surface->backend == &cairo_paginated_surface_backend;
143 }
144
145 cairo_surface_t *
146 _cairo_paginated_surface_get_target (cairo_surface_t *surface)
147 {
148     cairo_paginated_surface_t *paginated_surface;
149
150     assert (_cairo_surface_is_paginated (surface));
151
152     paginated_surface = (cairo_paginated_surface_t *) surface;
153     return paginated_surface->target;
154 }
155
156 cairo_surface_t *
157 _cairo_paginated_surface_get_recording (cairo_surface_t *surface)
158 {
159     cairo_paginated_surface_t *paginated_surface;
160
161     assert (_cairo_surface_is_paginated (surface));
162
163     paginated_surface = (cairo_paginated_surface_t *) surface;
164     return paginated_surface->recording_surface;
165 }
166
167 cairo_status_t
168 _cairo_paginated_surface_set_size (cairo_surface_t      *surface,
169                                    int                   width,
170                                    int                   height)
171 {
172     cairo_paginated_surface_t *paginated_surface;
173     cairo_status_t status;
174     cairo_rectangle_t recording_extents;
175
176     assert (_cairo_surface_is_paginated (surface));
177
178     paginated_surface = (cairo_paginated_surface_t *) surface;
179
180     recording_extents.x = 0;
181     recording_extents.y = 0;
182     recording_extents.width = width;
183     recording_extents.height = height;
184
185     cairo_surface_destroy (paginated_surface->recording_surface);
186     paginated_surface->recording_surface = cairo_recording_surface_create (paginated_surface->content,
187                                                                            &recording_extents);
188     status = paginated_surface->recording_surface->status;
189     if (unlikely (status))
190         return _cairo_surface_set_error (surface, status);
191
192     return CAIRO_STATUS_SUCCESS;
193 }
194
195 static cairo_status_t
196 _cairo_paginated_surface_finish (void *abstract_surface)
197 {
198     cairo_paginated_surface_t *surface = abstract_surface;
199     cairo_status_t status = CAIRO_STATUS_SUCCESS;
200
201     if (! surface->base.is_clear || surface->page_num == 1) {
202         /* Bypass some of the sanity checking in cairo-surface.c, as we
203          * know that the surface is finished...
204          */
205         status = _cairo_paginated_surface_show_page (surface);
206     }
207
208      /* XXX We want to propagate any errors from destroy(), but those are not
209       * returned via the api. So we need to explicitly finish the target,
210       * and check the status afterwards. However, we can only call finish()
211       * on the target, if we own it.
212       */
213     if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->target->ref_count) == 1)
214         cairo_surface_finish (surface->target);
215     if (status == CAIRO_STATUS_SUCCESS)
216         status = cairo_surface_status (surface->target);
217     cairo_surface_destroy (surface->target);
218
219     cairo_surface_finish (surface->recording_surface);
220     if (status == CAIRO_STATUS_SUCCESS)
221         status = cairo_surface_status (surface->recording_surface);
222     cairo_surface_destroy (surface->recording_surface);
223
224     return status;
225 }
226
227 static cairo_surface_t *
228 _cairo_paginated_surface_create_image_surface (void            *abstract_surface,
229                                                int              width,
230                                                int              height)
231 {
232     cairo_paginated_surface_t *surface = abstract_surface;
233     cairo_surface_t *image;
234     cairo_font_options_t options;
235
236     image = _cairo_image_surface_create_with_content (surface->content,
237                                                       width,
238                                                       height);
239
240     cairo_surface_get_font_options (&surface->base, &options);
241     _cairo_surface_set_font_options (image, &options);
242
243     return image;
244 }
245
246 static cairo_surface_t *
247 _cairo_paginated_surface_source (void          *abstract_surface,
248                                  cairo_rectangle_int_t *extents)
249 {
250     cairo_paginated_surface_t *surface = abstract_surface;
251     return _cairo_surface_get_source (surface->target, extents);
252 }
253
254 static cairo_status_t
255 _cairo_paginated_surface_acquire_source_image (void            *abstract_surface,
256                                                cairo_image_surface_t **image_out,
257                                                void                **image_extra)
258 {
259     cairo_paginated_surface_t *surface = abstract_surface;
260     cairo_bool_t is_bounded;
261     cairo_surface_t *image;
262     cairo_status_t status;
263     cairo_rectangle_int_t extents;
264
265     is_bounded = _cairo_surface_get_extents (surface->target, &extents);
266     if (! is_bounded)
267         return CAIRO_INT_STATUS_UNSUPPORTED;
268
269     image = _cairo_paginated_surface_create_image_surface (surface,
270                                                            extents.width,
271                                                            extents.height);
272
273     status = _cairo_recording_surface_replay (surface->recording_surface, image);
274     if (unlikely (status)) {
275         cairo_surface_destroy (image);
276         return status;
277     }
278
279     *image_out = (cairo_image_surface_t*) image;
280     *image_extra = NULL;
281
282     return CAIRO_STATUS_SUCCESS;
283 }
284
285 static void
286 _cairo_paginated_surface_release_source_image (void       *abstract_surface,
287                                                cairo_image_surface_t *image,
288                                                void            *image_extra)
289 {
290     cairo_surface_destroy (&image->base);
291 }
292
293 static cairo_int_status_t
294 _paint_fallback_image (cairo_paginated_surface_t *surface,
295                        cairo_rectangle_int_t     *rect)
296 {
297     double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
298     double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
299     int x, y, width, height;
300     cairo_status_t status;
301     cairo_surface_t *image;
302     cairo_surface_pattern_t pattern;
303     cairo_clip_t *clip;
304
305     x = rect->x;
306     y = rect->y;
307     width = rect->width;
308     height = rect->height;
309     image = _cairo_paginated_surface_create_image_surface (surface,
310                                                            ceil (width  * x_scale),
311                                                            ceil (height * y_scale));
312     _cairo_surface_set_device_scale (image, x_scale, y_scale);
313     /* set_device_offset just sets the x0/y0 components of the matrix;
314      * so we have to do the scaling manually. */
315     cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
316
317     status = _cairo_recording_surface_replay (surface->recording_surface, image);
318     if (unlikely (status))
319         goto CLEANUP_IMAGE;
320
321     _cairo_pattern_init_for_surface (&pattern, image);
322     cairo_matrix_init (&pattern.base.matrix,
323                        x_scale, 0, 0, y_scale, -x*x_scale, -y*y_scale);
324     /* the fallback should be rendered at native resolution, so disable
325      * filtering (if possible) to avoid introducing potential artifacts. */
326     pattern.base.filter = CAIRO_FILTER_NEAREST;
327
328     clip = _cairo_clip_intersect_rectangle (NULL, rect);
329     status = _cairo_surface_paint (surface->target,
330                                    CAIRO_OPERATOR_SOURCE,
331                                    &pattern.base, clip);
332     _cairo_clip_destroy (clip);
333     _cairo_pattern_fini (&pattern.base);
334
335 CLEANUP_IMAGE:
336     cairo_surface_destroy (image);
337
338     return status;
339 }
340
341 static cairo_int_status_t
342 _paint_page (cairo_paginated_surface_t *surface)
343 {
344     cairo_surface_t *analysis;
345     cairo_int_status_t status;
346     cairo_bool_t has_supported, has_page_fallback, has_finegrained_fallback;
347
348     if (unlikely (surface->target->status))
349         return surface->target->status;
350
351     analysis = _cairo_analysis_surface_create (surface->target);
352     if (unlikely (analysis->status)) {
353         status = analysis->status;
354         goto FAIL;
355     }
356
357     surface->backend->set_paginated_mode (surface->target,
358                                           CAIRO_PAGINATED_MODE_ANALYZE);
359     status = _cairo_recording_surface_replay_and_create_regions (surface->recording_surface,
360                                                                  analysis);
361     if (status)
362         goto FAIL;
363
364     assert (analysis->status == CAIRO_STATUS_SUCCESS);
365
366      if (surface->backend->set_bounding_box) {
367          cairo_box_t bbox;
368
369          _cairo_analysis_surface_get_bounding_box (analysis, &bbox);
370          status = surface->backend->set_bounding_box (surface->target, &bbox);
371          if (unlikely (status))
372              goto FAIL;
373      }
374
375     if (surface->backend->set_fallback_images_required) {
376         cairo_bool_t has_fallbacks = _cairo_analysis_surface_has_unsupported (analysis);
377
378         status = surface->backend->set_fallback_images_required (surface->target,
379                                                                  has_fallbacks);
380         if (unlikely (status))
381             goto FAIL;
382     }
383
384     /* Finer grained fallbacks are currently only supported for some
385      * surface types */
386     if (surface->backend->supports_fine_grained_fallbacks != NULL &&
387         surface->backend->supports_fine_grained_fallbacks (surface->target))
388     {
389         has_supported = _cairo_analysis_surface_has_supported (analysis);
390         has_page_fallback = FALSE;
391         has_finegrained_fallback = _cairo_analysis_surface_has_unsupported (analysis);
392     }
393     else
394     {
395         if (_cairo_analysis_surface_has_unsupported (analysis)) {
396             has_supported = FALSE;
397             has_page_fallback = TRUE;
398         } else {
399             has_supported = TRUE;
400             has_page_fallback = FALSE;
401         }
402         has_finegrained_fallback = FALSE;
403     }
404
405     if (has_supported) {
406         surface->backend->set_paginated_mode (surface->target,
407                                               CAIRO_PAGINATED_MODE_RENDER);
408
409         status = _cairo_recording_surface_replay_region (surface->recording_surface,
410                                                          NULL,
411                                                          surface->target,
412                                                          CAIRO_RECORDING_REGION_NATIVE);
413         assert (status != CAIRO_INT_STATUS_UNSUPPORTED);
414         if (unlikely (status))
415             goto FAIL;
416     }
417
418     if (has_page_fallback) {
419         cairo_rectangle_int_t extents;
420         cairo_bool_t is_bounded;
421
422         surface->backend->set_paginated_mode (surface->target,
423                                               CAIRO_PAGINATED_MODE_FALLBACK);
424
425         is_bounded = _cairo_surface_get_extents (surface->target, &extents);
426         if (! is_bounded) {
427             status = CAIRO_INT_STATUS_UNSUPPORTED;
428             goto FAIL;
429         }
430
431         status = _paint_fallback_image (surface, &extents);
432         if (unlikely (status))
433             goto FAIL;
434     }
435
436     if (has_finegrained_fallback) {
437         cairo_region_t *region;
438         int num_rects, i;
439
440         surface->backend->set_paginated_mode (surface->target,
441                                               CAIRO_PAGINATED_MODE_FALLBACK);
442
443         region = _cairo_analysis_surface_get_unsupported (analysis);
444
445         num_rects = cairo_region_num_rectangles (region);
446         for (i = 0; i < num_rects; i++) {
447             cairo_rectangle_int_t rect;
448
449             cairo_region_get_rectangle (region, i, &rect);
450             status = _paint_fallback_image (surface, &rect);
451             if (unlikely (status))
452                 goto FAIL;
453         }
454     }
455
456   FAIL:
457     cairo_surface_destroy (analysis);
458
459     return _cairo_surface_set_error (surface->target, status);
460 }
461
462 static cairo_status_t
463 _start_page (cairo_paginated_surface_t *surface)
464 {
465     if (surface->target->status)
466         return surface->target->status;
467
468     if (! surface->backend->start_page)
469         return CAIRO_STATUS_SUCCESS;
470
471     return _cairo_surface_set_error (surface->target,
472                                 surface->backend->start_page (surface->target));
473 }
474
475 static cairo_int_status_t
476 _cairo_paginated_surface_copy_page (void *abstract_surface)
477 {
478     cairo_status_t status;
479     cairo_paginated_surface_t *surface = abstract_surface;
480
481     status = _start_page (surface);
482     if (unlikely (status))
483         return status;
484
485     status = _paint_page (surface);
486     if (unlikely (status))
487         return status;
488
489     surface->page_num++;
490
491     /* XXX: It might make sense to add some support here for calling
492      * cairo_surface_copy_page on the target surface. It would be an
493      * optimization for the output, but the interaction with image
494      * fallbacks gets tricky. For now, we just let the target see a
495      * show_page and we implement the copying by simply not destroying
496      * the recording-surface. */
497
498     cairo_surface_show_page (surface->target);
499     return cairo_surface_status (surface->target);
500 }
501
502 static cairo_int_status_t
503 _cairo_paginated_surface_show_page (void *abstract_surface)
504 {
505     cairo_status_t status;
506     cairo_paginated_surface_t *surface = abstract_surface;
507
508     status = _start_page (surface);
509     if (unlikely (status))
510         return status;
511
512     status = _paint_page (surface);
513     if (unlikely (status))
514         return status;
515
516     cairo_surface_show_page (surface->target);
517     status = surface->target->status;
518     if (unlikely (status))
519         return status;
520
521     status = surface->recording_surface->status;
522     if (unlikely (status))
523         return status;
524
525     if (! surface->base.finished) {
526         cairo_surface_destroy (surface->recording_surface);
527
528         surface->recording_surface = _create_recording_surface_for_target (surface->target,
529                                                                            surface->content);
530         status = surface->recording_surface->status;
531         if (unlikely (status))
532             return status;
533
534         surface->page_num++;
535         surface->base.is_clear = TRUE;
536     }
537
538     return CAIRO_STATUS_SUCCESS;
539 }
540
541 static cairo_bool_t
542 _cairo_paginated_surface_get_extents (void                    *abstract_surface,
543                                       cairo_rectangle_int_t   *rectangle)
544 {
545     cairo_paginated_surface_t *surface = abstract_surface;
546
547     return _cairo_surface_get_extents (surface->target, rectangle);
548 }
549
550 static void
551 _cairo_paginated_surface_get_font_options (void                  *abstract_surface,
552                                            cairo_font_options_t  *options)
553 {
554     cairo_paginated_surface_t *surface = abstract_surface;
555
556     cairo_surface_get_font_options (surface->target, options);
557 }
558
559 static cairo_int_status_t
560 _cairo_paginated_surface_paint (void                    *abstract_surface,
561                                 cairo_operator_t         op,
562                                 const cairo_pattern_t   *source,
563                                 const cairo_clip_t      *clip)
564 {
565     cairo_paginated_surface_t *surface = abstract_surface;
566
567     return _cairo_surface_paint (surface->recording_surface, op, source, clip);
568 }
569
570 static cairo_int_status_t
571 _cairo_paginated_surface_mask (void             *abstract_surface,
572                                cairo_operator_t  op,
573                                const cairo_pattern_t    *source,
574                                const cairo_pattern_t    *mask,
575                                const cairo_clip_t               *clip)
576 {
577     cairo_paginated_surface_t *surface = abstract_surface;
578
579     return _cairo_surface_mask (surface->recording_surface, op, source, mask, clip);
580 }
581
582 static cairo_int_status_t
583 _cairo_paginated_surface_stroke (void                   *abstract_surface,
584                                  cairo_operator_t        op,
585                                  const cairo_pattern_t  *source,
586                                  const cairo_path_fixed_t       *path,
587                                  const cairo_stroke_style_t     *style,
588                                  const cairo_matrix_t           *ctm,
589                                  const cairo_matrix_t           *ctm_inverse,
590                                  double                  tolerance,
591                                  cairo_antialias_t       antialias,
592                                  const cairo_clip_t             *clip)
593 {
594     cairo_paginated_surface_t *surface = abstract_surface;
595
596     return _cairo_surface_stroke (surface->recording_surface, op, source,
597                                   path, style,
598                                   ctm, ctm_inverse,
599                                   tolerance, antialias,
600                                   clip);
601 }
602
603 static cairo_int_status_t
604 _cairo_paginated_surface_fill (void                     *abstract_surface,
605                                cairo_operator_t          op,
606                                const cairo_pattern_t    *source,
607                                const cairo_path_fixed_t *path,
608                                cairo_fill_rule_t         fill_rule,
609                                double                    tolerance,
610                                cairo_antialias_t         antialias,
611                                const cairo_clip_t               *clip)
612 {
613     cairo_paginated_surface_t *surface = abstract_surface;
614
615     return _cairo_surface_fill (surface->recording_surface, op, source,
616                                 path, fill_rule,
617                                 tolerance, antialias,
618                                 clip);
619 }
620
621 static cairo_bool_t
622 _cairo_paginated_surface_has_show_text_glyphs (void *abstract_surface)
623 {
624     cairo_paginated_surface_t *surface = abstract_surface;
625
626     return cairo_surface_has_show_text_glyphs (surface->target);
627 }
628
629 static cairo_int_status_t
630 _cairo_paginated_surface_show_text_glyphs (void                       *abstract_surface,
631                                            cairo_operator_t            op,
632                                            const cairo_pattern_t      *source,
633                                            const char                 *utf8,
634                                            int                         utf8_len,
635                                            cairo_glyph_t              *glyphs,
636                                            int                         num_glyphs,
637                                            const cairo_text_cluster_t *clusters,
638                                            int                         num_clusters,
639                                            cairo_text_cluster_flags_t  cluster_flags,
640                                            cairo_scaled_font_t        *scaled_font,
641                                            const cairo_clip_t                 *clip)
642 {
643     cairo_paginated_surface_t *surface = abstract_surface;
644
645     return _cairo_surface_show_text_glyphs (surface->recording_surface, op, source,
646                                             utf8, utf8_len,
647                                             glyphs, num_glyphs,
648                                             clusters, num_clusters,
649                                             cluster_flags,
650                                             scaled_font,
651                                             clip);
652 }
653
654 static const char **
655 _cairo_paginated_surface_get_supported_mime_types (void *abstract_surface)
656 {
657     cairo_paginated_surface_t *surface = abstract_surface;
658
659     if (surface->target->backend->get_supported_mime_types)
660         return surface->target->backend->get_supported_mime_types (surface->target);
661
662     return NULL;
663 }
664
665 static cairo_surface_t *
666 _cairo_paginated_surface_snapshot (void *abstract_other)
667 {
668     cairo_paginated_surface_t *other = abstract_other;
669
670     return other->recording_surface->backend->snapshot (other->recording_surface);
671 }
672
673 static cairo_t *
674 _cairo_paginated_context_create (void *target)
675 {
676     cairo_paginated_surface_t *surface = target;
677
678     if (_cairo_surface_is_subsurface (&surface->base))
679         surface = (cairo_paginated_surface_t *)
680             _cairo_surface_subsurface_get_target (&surface->base);
681
682     return surface->recording_surface->backend->create_context (target);
683 }
684
685 static const cairo_surface_backend_t cairo_paginated_surface_backend = {
686     CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
687     _cairo_paginated_surface_finish,
688
689     _cairo_paginated_context_create,
690
691     _cairo_paginated_surface_create_similar,
692     NULL, /* create simlar image */
693     NULL, /* map to image */
694     NULL, /* unmap image */
695
696     _cairo_paginated_surface_source,
697     _cairo_paginated_surface_acquire_source_image,
698     _cairo_paginated_surface_release_source_image,
699     _cairo_paginated_surface_snapshot,
700
701     _cairo_paginated_surface_copy_page,
702     _cairo_paginated_surface_show_page,
703
704     _cairo_paginated_surface_get_extents,
705     _cairo_paginated_surface_get_font_options,
706
707     NULL, /* flush */
708     NULL, /* mark_dirty_rectangle */
709
710     _cairo_paginated_surface_paint,
711     _cairo_paginated_surface_mask,
712     _cairo_paginated_surface_stroke,
713     _cairo_paginated_surface_fill,
714     NULL, /* fill_stroke */
715     NULL, /* show_glyphs */
716     _cairo_paginated_surface_has_show_text_glyphs,
717     _cairo_paginated_surface_show_text_glyphs,
718     _cairo_paginated_surface_get_supported_mime_types,
719 };