diff --git a/src/Makefile.am b/src/Makefile.am index 683a28fae..2af4e5559 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -225,6 +225,7 @@ libcairo_la_SOURCES = \ cairo-wideint-private.h \ cairo-meta-surface.c \ cairo-meta-surface-private.h \ + cairo-paginated-private.h \ cairo-paginated-surface.c \ cairo-paginated-surface-private.h \ cairo-analysis-surface.c \ diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index a89636efa..26a373fa6 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -35,7 +35,7 @@ #include "cairoint.h" #include "cairo-analysis-surface-private.h" -#include "cairo-paginated-surface-private.h" +#include "cairo-paginated-private.h" typedef struct { cairo_surface_t base; diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h new file mode 100644 index 000000000..42d100b4b --- /dev/null +++ b/src/cairo-paginated-private.h @@ -0,0 +1,136 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl Worth + */ + +#ifndef CAIRO_PAGINATED_H +#define CAIRO_PAGINATED_H + +#include "cairoint.h" + +struct _cairo_paginated_surface_backend { + /* Optional. Will be called once for each page. + * + * NOTE: With respect to the order of drawing operations as seen + * by the target, this call will occur before any drawing + * operations for the relevant page. However, with respect to the + * function calls as made by the user, this call will be *after* + * any drawing operations for the page, (that is, it will occur + * during the user's call to cairo_show_page or cairo_copy_page). + */ + cairo_warn cairo_int_status_t + (*start_page) (void *surface); + + /* Required. Will be called twice for each page, once with an + * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with + * CAIRO_PAGINATED_MODE_RENDER. See more details in the + * documentation for _cairo_paginated_surface_create below. + */ + void + (*set_paginated_mode) (void *surface, + cairo_paginated_mode_t mode); +}; + +/* A cairo_paginated_surface provides a very convenient wrapper that + * is well-suited for doing the analysis common to most surfaces that + * have paginated output, (that is, things directed at printers, or + * for saving content in files such as PostScript or PDF files). + * + * To use the paginated surface, you'll first need to create your + * 'real' surface using _cairo_surface_init and the standard + * cairo_surface_backend_t. Then you also call + * _cairo_paginated_surface_create which takes its own, much simpler, + * cairo_paginated_surface_backend. You are free to return the result + * of _cairo_paginated_surface_create from your public + * cairo__surface_create. The paginated backend will be careful + * to not let the user see that they really got a "wrapped" + * surface. See test-paginated-surface.c for a fairly minimal example + * of a paginated-using surface. That should be a reasonable example + * to follow. + * + * What the paginated surface does is first save all drawing + * operations for a page into a meta-surface. Then when the user calls + * cairo_show_page, the paginated surface performs the following + * sequence of operations (using the backend functions passed to + * cairo_paginated_surface_create): + * + * 1. Calls start_page (if non NULL). At this point, it is appropriate + * for the target to emit any page-specific header information into + * its output. + * + * 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE + * + * 3. Replays the meta-surface to the target surface, (with an + * analysis surface inserted between which watches the return value + * from each operation). This analysis stage is used to decide which + * operations will require fallbacks. + * + * 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER + * + * 5. Replays a subset of the meta-surface operations to the target surface + * + * 6. Replays the remaining operations to an image surface, sets an + * appropriate clip on the target, then paints the resulting image + * surface to the target. + * + * So, the target will see drawing operations during two separate + * stages, (ANALYZE and RENDER). During the ANALYZE phase the target + * should not actually perform any rendering, (for example, if + * performing output to a file, no output should be generated during + * this stage). Instead the drawing functions simply need to return + * CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate + * whether rendering would be supported. And it should do this as + * quickly as possible. + * + * NOTE: The paginated surface layer assumes that the target surface + * is "blank" by default at the beginning of each page, without any + * need for an explicit erasea operation, (as opposed to an image + * surface, for example, which might have uninitialized content + * originally). As such, it optimizes away CLEAR operations that + * happen at the beginning of each page---the target surface will not + * even see these operations. + */ +cairo_private cairo_surface_t * +_cairo_paginated_surface_create (cairo_surface_t *target, + cairo_content_t content, + int width, + int height, + const cairo_paginated_surface_backend_t *backend); + +cairo_private cairo_surface_t * +_cairo_paginated_surface_get_target (cairo_surface_t *surface); + +cairo_private cairo_bool_t +_cairo_surface_is_paginated (cairo_surface_t *surface); + +#endif /* CAIRO_PAGINATED_H */ diff --git a/src/cairo-paginated-surface-private.h b/src/cairo-paginated-surface-private.h index 518e7f4c8..e48902601 100644 --- a/src/cairo-paginated-surface-private.h +++ b/src/cairo-paginated-surface-private.h @@ -36,101 +36,35 @@ #ifndef CAIRO_PAGINATED_SURFACE_H #define CAIRO_PAGINATED_SURFACE_H -#include "cairoint.h" +#include "cairo.h" -typedef struct _cairo_paginated_surface_backend { - /* Optional. Will be called once for each page. - * - * NOTE: With respect to the order of drawing operations as seen - * by the target, this call will occur before any drawing - * operations for the relevant page. However, with respect to the - * function calls as made by the user, this call will be *after* - * any drawing operations for the page, (that is, it will occur - * during the user's call to cairo_show_page or cairo_copy_page). - */ - cairo_warn cairo_int_status_t - (*start_page) (void *surface); +typedef struct _cairo_paginated_surface { + cairo_surface_t base; - /* Required. Will be called twice for each page, once with an - * argument of CAIRO_PAGINATED_MODE_ANALYZE and once with - * CAIRO_PAGINATED_MODE_RENDER. See more details in the - * documentation for _cairo_paginated_surface_create below. - */ - void - (*set_paginated_mode) (void *surface, - cairo_paginated_mode_t mode); -} cairo_paginated_surface_backend_t; + /* The target surface to hold the final result. */ + cairo_surface_t *target; -/* A cairo_paginated_surface provides a very convenient wrapper that - * is well-suited for doing the analysis common to most surfaces that - * have paginated output, (that is, things directed at printers, or - * for saving content in files such as PostScript or PDF files). - * - * To use the paginated surface, you'll first need to create your - * 'real' surface using _cairo_surface_init and the standard - * cairo_surface_backend_t. Then you also call - * _cairo_paginated_surface_create which takes its own, much simpler, - * cairo_paginated_surface_backend. You are free to return the result - * of _cairo_paginated_surface_create from your public - * cairo__surface_create. The paginated backend will be careful - * to not let the user see that they really got a "wrapped" - * surface. See test-paginated-surface.c for a fairly minimal example - * of a paginated-using surface. That should be a reasonable example - * to follow. - * - * What the paginated surface does is first save all drawing - * operations for a page into a meta-surface. Then when the user calls - * cairo_show_page, the paginated surface performs the following - * sequence of operations (using the backend functions passed to - * cairo_paginated_surface_create): - * - * 1. Calls start_page (if non NULL). At this point, it is appropriate - * for the target to emit any page-specific header information into - * its output. - * - * 2. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_ANALYZE - * - * 3. Replays the meta-surface to the target surface, (with an - * analysis surface inserted between which watches the return value - * from each operation). This analysis stage is used to decide which - * operations will require fallbacks. - * - * 4. Calls set_paginated_mode with an argument of CAIRO_PAGINATED_MODE_RENDER - * - * 5. Replays a subset of the meta-surface operations to the target surface - * - * 6. Replays the remaining operations to an image surface, sets an - * appropriate clip on the target, then paints the resulting image - * surface to the target. - * - * So, the target will see drawing operations during two separate - * stages, (ANALYZE and RENDER). During the ANALYZE phase the target - * should not actually perform any rendering, (for example, if - * performing output to a file, no output should be generated during - * this stage). Instead the drawing functions simply need to return - * CAIRO_STATUS_SUCCESS or CAIRO_INT_STATUS_UNSUPPORTED to indicate - * whether rendering would be supported. And it should do this as - * quickly as possible. - * - * NOTE: The paginated surface layer assumes that the target surface - * is "blank" by default at the beginning of each page, without any - * need for an explicit erasea operation, (as opposed to an image - * surface, for example, which might have uninitialized content - * originally). As such, it optimizes away CLEAR operations that - * happen at the beginning of each page---the target surface will not - * even see these operations. - */ -cairo_private cairo_surface_t * -_cairo_paginated_surface_create (cairo_surface_t *target, - cairo_content_t content, - int width, - int height, - const cairo_paginated_surface_backend_t *backend); + cairo_content_t content; -cairo_private cairo_surface_t * -_cairo_paginated_surface_get_target (cairo_surface_t *surface); + /* XXX: These shouldn't actually exist. We inherit this ugliness + * from _cairo_meta_surface_create. The width/height parameters + * from that function also should not exist. The fix that will + * allow us to remove all of these is to fix acquire_source_image + * to pass an interest rectangle. */ + int width; + int height; -cairo_private cairo_bool_t -_cairo_surface_is_paginated (cairo_surface_t *surface); + /* Paginated-surface specific functions for the target */ + const cairo_paginated_surface_backend_t *backend; + + /* A cairo_meta_surface to record all operations. To be replayed + * against target, and also against image surface as necessary for + * fallbacks. */ + cairo_surface_t *meta; + + int page_num; + cairo_bool_t page_is_blank; + +} cairo_paginated_surface_t; #endif /* CAIRO_PAGINATED_SURFACE_H */ diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index f788dc2fd..c9584b618 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -36,45 +36,17 @@ /* The paginated surface layer exists to provide as much code sharing * as possible for the various paginated surface backends in cairo - * (PostScript, PDF, etc.). See cairo-paginated-surface-private.h for + * (PostScript, PDF, etc.). See cairo-paginated-private.h for * more details on how it works and how to use it. */ #include "cairoint.h" +#include "cairo-paginated-private.h" #include "cairo-paginated-surface-private.h" #include "cairo-meta-surface-private.h" #include "cairo-analysis-surface-private.h" -typedef struct _cairo_paginated_surface { - cairo_surface_t base; - - /* The target surface to hold the final result. */ - cairo_surface_t *target; - - cairo_content_t content; - - /* XXX: These shouldn't actually exist. We inherit this ugliness - * from _cairo_meta_surface_create. The width/height parameters - * from that function also should not exist. The fix that will - * allow us to remove all of these is to fix acquire_source_image - * to pass an interest rectangle. */ - int width; - int height; - - /* Paginated-surface specific functions for the target */ - const cairo_paginated_surface_backend_t *backend; - - /* A cairo_meta_surface to record all operations. To be replayed - * against target, and also against image surface as necessary for - * fallbacks. */ - cairo_surface_t *meta; - - int page_num; - cairo_bool_t page_is_blank; - -} cairo_paginated_surface_t; - const cairo_private cairo_surface_backend_t cairo_paginated_surface_backend; static cairo_int_status_t diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 5c0330417..8899bf266 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -41,7 +41,7 @@ #include "cairo-pdf-test.h" #include "cairo-pdf-surface-private.h" #include "cairo-scaled-font-subsets-private.h" -#include "cairo-paginated-surface-private.h" +#include "cairo-paginated-private.h" #include "cairo-path-fixed-private.h" #include "cairo-output-stream-private.h" diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 520c404c2..9573f4916 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -41,7 +41,7 @@ #include "cairo-ps.h" #include "cairo-ps-test.h" #include "cairo-scaled-font-subsets-private.h" -#include "cairo-paginated-surface-private.h" +#include "cairo-paginated-private.h" #include "cairo-meta-surface-private.h" #include "cairo-output-stream-private.h" diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index a582de360..23714b478 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -43,7 +43,7 @@ #include "cairo-svg-test.h" #include "cairo-path-fixed-private.h" #include "cairo-meta-surface-private.h" -#include "cairo-paginated-surface-private.h" +#include "cairo-paginated-private.h" #include "cairo-scaled-font-subsets-private.h" #include "cairo-output-stream-private.h" diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index bb6de79ef..7f51ec172 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -61,6 +61,7 @@ typedef struct _cairo_surface_backend cairo_surface_backend_t; typedef struct _cairo_clip cairo_clip_t; typedef struct _cairo_output_stream cairo_output_stream_t; typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; +typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t; typedef struct _cairo_xlib_screen_info cairo_xlib_screen_info_t; diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c index 543422f87..53e97eba6 100644 --- a/src/test-paginated-surface.c +++ b/src/test-paginated-surface.c @@ -49,7 +49,7 @@ #include "test-paginated-surface.h" -#include "cairo-paginated-surface-private.h" +#include "cairo-paginated-private.h" typedef struct _test_paginated_surface { cairo_surface_t base;