Tizen 2.0 Release
[profile/ivi/cairo.git] / src / test-paginated-surface.c
1 /* cairo - a vector graphics library with display and print output
2  *
3  * Copyright © 2005 Red Hat, Inc
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it either under the terms of the GNU Lesser General Public
7  * License version 2.1 as published by the Free Software Foundation
8  * (the "LGPL") or, at your option, under the terms of the Mozilla
9  * Public License Version 1.1 (the "MPL"). If you do not alter this
10  * notice, a recipient may use your version of this file under either
11  * the MPL or the LGPL.
12  *
13  * You should have received a copy of the LGPL along with this library
14  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16  * You should have received a copy of the MPL along with this library
17  * in the file COPYING-MPL-1.1
18  *
19  * The contents of this file are subject to the Mozilla Public License
20  * Version 1.1 (the "License"); you may not use this file except in
21  * compliance with the License. You may obtain a copy of the License at
22  * http://www.mozilla.org/MPL/
23  *
24  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26  * the specific language governing rights and limitations.
27  *
28  * The Original Code is the cairo graphics library.
29  *
30  * The Initial Developer of the Original Code is Red Hat, Inc.
31  *
32  * Contributor(s):
33  *      Carl Worth <cworth@cworth.org>
34  */
35
36 /* This isn't a "real" surface, but just something to be used by the
37  * test suite to help exercise the paginated-surface paths in cairo.
38  *
39  * The defining feature of this backend is that it uses a paginated
40  * surface to record all operations, and then replays everything to an
41  * image surface.
42  *
43  * It's possible that this code might serve as a good starting point
44  * for someone working on bringing up a new paginated-surface-based
45  * backend.
46  */
47
48 #include "cairoint.h"
49
50 #include "test-paginated-surface.h"
51
52 #include "cairo-default-context-private.h"
53 #include "cairo-error-private.h"
54 #include "cairo-paginated-private.h"
55 #include "cairo-surface-backend-private.h"
56
57 typedef struct _test_paginated_surface {
58     cairo_surface_t base;
59     cairo_surface_t *target;
60     cairo_paginated_mode_t paginated_mode;
61 } test_paginated_surface_t;
62
63 static const cairo_surface_backend_t test_paginated_surface_backend;
64 static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend;
65
66 cairo_surface_t *
67 _cairo_test_paginated_surface_create (cairo_surface_t *target)
68 {
69     cairo_status_t status;
70     cairo_surface_t *paginated;
71     test_paginated_surface_t *surface;
72
73     status = cairo_surface_status (target);
74     if (unlikely (status))
75         return _cairo_surface_create_in_error (status);
76
77     surface = malloc (sizeof (test_paginated_surface_t));
78     if (unlikely (surface == NULL))
79         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
80
81     _cairo_surface_init (&surface->base,
82                          &test_paginated_surface_backend,
83                          NULL, /* device */
84                          target->content);
85
86     surface->target = cairo_surface_reference (target);
87
88     paginated =  _cairo_paginated_surface_create (&surface->base,
89                                                   target->content,
90                                                   &test_paginated_surface_paginated_backend);
91     status = paginated->status;
92     if (status == CAIRO_STATUS_SUCCESS) {
93         /* paginated keeps the only reference to surface now, drop ours */
94         cairo_surface_destroy (&surface->base);
95         return paginated;
96     }
97
98     cairo_surface_destroy (target);
99     free (surface);
100     return _cairo_surface_create_in_error (status);
101 }
102
103 static cairo_status_t
104 _test_paginated_surface_finish (void *abstract_surface)
105 {
106     test_paginated_surface_t *surface = abstract_surface;
107
108     cairo_surface_destroy (surface->target);
109
110     return CAIRO_STATUS_SUCCESS;
111 }
112
113 static cairo_bool_t
114 _test_paginated_surface_get_extents (void                       *abstract_surface,
115                                      cairo_rectangle_int_t      *rectangle)
116 {
117     test_paginated_surface_t *surface = abstract_surface;
118
119     return _cairo_surface_get_extents (surface->target, rectangle);
120 }
121
122 static cairo_int_status_t
123 _test_paginated_surface_paint (void             *abstract_surface,
124                                cairo_operator_t  op,
125                                const cairo_pattern_t    *source,
126                                const cairo_clip_t       *clip)
127 {
128     test_paginated_surface_t *surface = abstract_surface;
129
130     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
131         return CAIRO_STATUS_SUCCESS;
132
133     return _cairo_surface_paint (surface->target, op, source, clip);
134 }
135
136 static cairo_int_status_t
137 _test_paginated_surface_mask (void              *abstract_surface,
138                               cairo_operator_t   op,
139                               const cairo_pattern_t     *source,
140                               const cairo_pattern_t     *mask,
141                               const cairo_clip_t        *clip)
142 {
143     test_paginated_surface_t *surface = abstract_surface;
144
145     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
146         return CAIRO_STATUS_SUCCESS;
147
148     return _cairo_surface_mask (surface->target,
149                                 op, source, mask, clip);
150 }
151
152 static cairo_int_status_t
153 _test_paginated_surface_stroke (void                            *abstract_surface,
154                                 cairo_operator_t                 op,
155                                 const cairo_pattern_t           *source,
156                                 const cairo_path_fixed_t                *path,
157                                 const cairo_stroke_style_t              *style,
158                                 const cairo_matrix_t                    *ctm,
159                                 const cairo_matrix_t                    *ctm_inverse,
160                                 double                           tolerance,
161                                 cairo_antialias_t                antialias,
162                                 const cairo_clip_t              *clip)
163 {
164     test_paginated_surface_t *surface = abstract_surface;
165
166     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
167         return CAIRO_STATUS_SUCCESS;
168
169     return _cairo_surface_stroke (surface->target, op, source,
170                                   path, style,
171                                   ctm, ctm_inverse,
172                                   tolerance, antialias,
173                                   clip);
174 }
175
176 static cairo_int_status_t
177 _test_paginated_surface_fill (void                              *abstract_surface,
178                               cairo_operator_t                   op,
179                               const cairo_pattern_t             *source,
180                               const cairo_path_fixed_t          *path,
181                               cairo_fill_rule_t                  fill_rule,
182                               double                             tolerance,
183                               cairo_antialias_t                  antialias,
184                               const cairo_clip_t                *clip)
185 {
186     test_paginated_surface_t *surface = abstract_surface;
187
188     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
189         return CAIRO_STATUS_SUCCESS;
190
191     return _cairo_surface_fill (surface->target, op, source,
192                                 path, fill_rule,
193                                 tolerance, antialias,
194                                 clip);
195 }
196
197 static cairo_bool_t
198 _test_paginated_surface_has_show_text_glyphs (void *abstract_surface)
199 {
200     test_paginated_surface_t *surface = abstract_surface;
201
202     return cairo_surface_has_show_text_glyphs (surface->target);
203 }
204
205 static cairo_int_status_t
206 _test_paginated_surface_show_text_glyphs (void                      *abstract_surface,
207                                           cairo_operator_t           op,
208                                           const cairo_pattern_t     *source,
209                                           const char                *utf8,
210                                           int                        utf8_len,
211                                           cairo_glyph_t             *glyphs,
212                                           int                        num_glyphs,
213                                           const cairo_text_cluster_t *clusters,
214                                           int                        num_clusters,
215                                           cairo_text_cluster_flags_t cluster_flags,
216                                           cairo_scaled_font_t       *scaled_font,
217                                           const cairo_clip_t        *clip)
218 {
219     test_paginated_surface_t *surface = abstract_surface;
220
221     if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
222         return CAIRO_STATUS_SUCCESS;
223
224     return _cairo_surface_show_text_glyphs (surface->target, op, source,
225                                             utf8, utf8_len,
226                                             glyphs, num_glyphs,
227                                             clusters, num_clusters,
228                                             cluster_flags,
229                                             scaled_font,
230                                             clip);
231 }
232
233
234 static void
235 _test_paginated_surface_set_paginated_mode (void                        *abstract_surface,
236                                             cairo_paginated_mode_t       mode)
237 {
238     test_paginated_surface_t *surface = abstract_surface;
239
240     surface->paginated_mode = mode;
241 }
242
243 static const cairo_surface_backend_t test_paginated_surface_backend = {
244     CAIRO_INTERNAL_SURFACE_TYPE_TEST_PAGINATED,
245     _test_paginated_surface_finish,
246     _cairo_default_context_create,
247
248     /* Since we are a paginated user, we get to regard most of the
249      * surface backend interface as historical cruft and ignore it. */
250
251     NULL, /* create_similar */
252     NULL, /* create similar image */
253     NULL, /* map to image */
254     NULL, /* unmap image */
255
256     _cairo_surface_default_source,
257     NULL, /* acquire_source_image */
258     NULL, /* release_source_image */
259     NULL, /* snapshot */
260
261     NULL, /* copy_page */
262     NULL, /* show_page */
263
264     _test_paginated_surface_get_extents,
265     NULL, /* get_font_options */
266
267     NULL, /* flush */
268     NULL, /* mark_dirty_rectangle */
269
270     /* Here is the more "modern" section of the surface backend
271      * interface which is mostly just drawing functions */
272
273     _test_paginated_surface_paint,
274     _test_paginated_surface_mask,
275     _test_paginated_surface_stroke,
276     _test_paginated_surface_fill,
277     NULL, /* fill-stroke */
278     NULL, /* replaced by show_text_glyphs */
279     _test_paginated_surface_has_show_text_glyphs,
280     _test_paginated_surface_show_text_glyphs
281 };
282
283 static const cairo_paginated_surface_backend_t test_paginated_surface_paginated_backend = {
284     NULL, /* start_page */
285     _test_paginated_surface_set_paginated_mode
286 };