Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3959 Serge 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 
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
};