beta-0.89.2
[luatex.git] / source / libs / cairo / cairo-src / src / cairo-raster-source-pattern.c
blob64520feae5228ff82cd7caed0cda40680e5e2660
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
4 * Copyright © 2011 Intel Corporation
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.
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
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/
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.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is Red Hat, Inc.
33 * Contributor(s):
34 * Chris Wilson <chris@chris-wilson.co.uk>
37 #include "cairoint.h"
38 #include "cairo-error-private.h"
39 #include "cairo-pattern-private.h"
41 /**
42 * SECTION:cairo-raster-source
43 * @Title: Raster Sources
44 * @Short_Description: Supplying arbitrary image data
45 * @See_Also: #cairo_pattern_t
47 * The raster source provides the ability to supply arbitrary pixel data
48 * whilst rendering. The pixels are queried at the time of rasterisation
49 * by means of user callback functions, allowing for the ultimate
50 * flexibility. For example, in handling compressed image sources, you
51 * may keep a MRU cache of decompressed images and decompress sources on the
52 * fly and discard old ones to conserve memory.
54 * For the raster source to be effective, you must at least specify
55 * the acquire and release callbacks which are used to retrieve the pixel
56 * data for the region of interest and demark when it can be freed afterwards.
57 * Other callbacks are provided for when the pattern is copied temporarily
58 * during rasterisation, or more permanently as a snapshot in order to keep
59 * the pixel data available for printing.
60 **/
62 cairo_surface_t *
63 _cairo_raster_source_pattern_acquire (const cairo_pattern_t *abstract_pattern,
64 cairo_surface_t *target,
65 const cairo_rectangle_int_t *extents)
67 cairo_raster_source_pattern_t *pattern =
68 (cairo_raster_source_pattern_t *) abstract_pattern;
70 if (pattern->acquire == NULL)
71 return NULL;
73 if (extents == NULL)
74 extents = &pattern->extents;
76 return pattern->acquire (&pattern->base, pattern->user_data,
77 target, extents);
80 void
81 _cairo_raster_source_pattern_release (const cairo_pattern_t *abstract_pattern,
82 cairo_surface_t *surface)
84 cairo_raster_source_pattern_t *pattern =
85 (cairo_raster_source_pattern_t *) abstract_pattern;
87 if (pattern->release == NULL)
88 return;
90 pattern->release (&pattern->base, pattern->user_data, surface);
93 cairo_status_t
94 _cairo_raster_source_pattern_init_copy (cairo_pattern_t *abstract_pattern,
95 const cairo_pattern_t *other)
97 cairo_raster_source_pattern_t *pattern =
98 (cairo_raster_source_pattern_t *) abstract_pattern;
99 cairo_status_t status;
101 VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_raster_source_pattern_t)));
102 memcpy(pattern, other, sizeof (cairo_raster_source_pattern_t));
104 status = CAIRO_STATUS_SUCCESS;
105 if (pattern->copy)
106 status = pattern->copy (&pattern->base, pattern->user_data, other);
108 return status;
111 cairo_status_t
112 _cairo_raster_source_pattern_snapshot (cairo_pattern_t *abstract_pattern)
114 cairo_raster_source_pattern_t *pattern =
115 (cairo_raster_source_pattern_t *) abstract_pattern;
117 if (pattern->snapshot == NULL)
118 return CAIRO_STATUS_SUCCESS;
120 return pattern->snapshot (&pattern->base, pattern->user_data);
123 void
124 _cairo_raster_source_pattern_finish (cairo_pattern_t *abstract_pattern)
126 cairo_raster_source_pattern_t *pattern =
127 (cairo_raster_source_pattern_t *) abstract_pattern;
129 if (pattern->finish == NULL)
130 return;
132 pattern->finish (&pattern->base, pattern->user_data);
135 /* Public interface */
138 * cairo_pattern_create_raster_source:
139 * @user_data: the user data to be passed to all callbacks
140 * @content: content type for the pixel data that will be returned. Knowing
141 * the content type ahead of time is used for analysing the operation and
142 * picking the appropriate rendering path.
143 * @width: maximum size of the sample area
144 * @height: maximum size of the sample area
146 * Creates a new user pattern for providing pixel data.
148 * Use the setter functions to associate callbacks with the returned
149 * pattern. The only mandatory callback is acquire.
151 * Return value: a newly created #cairo_pattern_t. Free with
152 * cairo_pattern_destroy() when you are done using it.
154 * Since: 1.12
156 cairo_pattern_t *
157 cairo_pattern_create_raster_source (void *user_data,
158 cairo_content_t content,
159 int width, int height)
161 cairo_raster_source_pattern_t *pattern;
163 CAIRO_MUTEX_INITIALIZE ();
165 if (width < 0 || height < 0)
166 return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_SIZE);
168 if (! CAIRO_CONTENT_VALID (content))
169 return _cairo_pattern_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
171 pattern = calloc (1, sizeof (*pattern));
172 if (unlikely (pattern == NULL))
173 return _cairo_pattern_create_in_error (CAIRO_STATUS_NO_MEMORY);
175 _cairo_pattern_init (&pattern->base,
176 CAIRO_PATTERN_TYPE_RASTER_SOURCE);
177 CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1);
179 pattern->content = content;
181 pattern->extents.x = 0;
182 pattern->extents.y = 0;
183 pattern->extents.width = width;
184 pattern->extents.height = height;
186 pattern->user_data = user_data;
188 return &pattern->base;
192 * cairo_raster_source_pattern_set_callback_data:
193 * @pattern: the pattern to update
194 * @data: the user data to be passed to all callbacks
196 * Updates the user data that is provided to all callbacks.
198 * Since: 1.12
200 void
201 cairo_raster_source_pattern_set_callback_data (cairo_pattern_t *abstract_pattern,
202 void *data)
204 cairo_raster_source_pattern_t *pattern;
206 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
207 return;
209 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
210 pattern->user_data = data;
214 * cairo_raster_source_pattern_get_callback_data:
215 * @pattern: the pattern to update
217 * Queries the current user data.
219 * Return value: the current user-data passed to each callback
221 * Since: 1.12
223 void *
224 cairo_raster_source_pattern_get_callback_data (cairo_pattern_t *abstract_pattern)
226 cairo_raster_source_pattern_t *pattern;
228 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
229 return NULL;
231 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
232 return pattern->user_data;
236 * cairo_raster_source_pattern_set_acquire:
237 * @pattern: the pattern to update
238 * @acquire: acquire callback
239 * @release: release callback
241 * Specifies the callbacks used to generate the image surface for a rendering
242 * operation (acquire) and the function used to cleanup that surface afterwards.
244 * The @acquire callback should create a surface (preferably an image
245 * surface created to match the target using
246 * cairo_surface_create_similar_image()) that defines at least the region
247 * of interest specified by extents. The surface is allowed to be the entire
248 * sample area, but if it does contain a subsection of the sample area,
249 * the surface extents should be provided by setting the device offset (along
250 * with its width and height) using cairo_surface_set_device_offset().
252 * Since: 1.12
254 void
255 cairo_raster_source_pattern_set_acquire (cairo_pattern_t *abstract_pattern,
256 cairo_raster_source_acquire_func_t acquire,
257 cairo_raster_source_release_func_t release)
259 cairo_raster_source_pattern_t *pattern;
261 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
262 return;
264 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
265 pattern->acquire = acquire;
266 pattern->release = release;
270 * cairo_raster_source_pattern_get_acquire:
271 * @pattern: the pattern to query
272 * @acquire: return value for the current acquire callback
273 * @release: return value for the current release callback
275 * Queries the current acquire and release callbacks.
277 * Since: 1.12
279 void
280 cairo_raster_source_pattern_get_acquire (cairo_pattern_t *abstract_pattern,
281 cairo_raster_source_acquire_func_t *acquire,
282 cairo_raster_source_release_func_t *release)
284 cairo_raster_source_pattern_t *pattern;
286 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
287 return;
289 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
290 if (acquire)
291 *acquire = pattern->acquire;
292 if (release)
293 *release = pattern->release;
297 * cairo_raster_source_pattern_set_snapshot:
298 * @pattern: the pattern to update
299 * @snapshot: snapshot callback
301 * Sets the callback that will be used whenever a snapshot is taken of the
302 * pattern, that is whenever the current contents of the pattern should be
303 * preserved for later use. This is typically invoked whilst printing.
305 * Since: 1.12
307 void
308 cairo_raster_source_pattern_set_snapshot (cairo_pattern_t *abstract_pattern,
309 cairo_raster_source_snapshot_func_t snapshot)
311 cairo_raster_source_pattern_t *pattern;
313 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
314 return;
316 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
317 pattern->snapshot = snapshot;
321 * cairo_raster_source_pattern_get_snapshot:
322 * @pattern: the pattern to query
324 * Queries the current snapshot callback.
326 * Return value: the current snapshot callback
328 * Since: 1.12
330 cairo_raster_source_snapshot_func_t
331 cairo_raster_source_pattern_get_snapshot (cairo_pattern_t *abstract_pattern)
333 cairo_raster_source_pattern_t *pattern;
335 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
336 return NULL;
338 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
339 return pattern->snapshot;
343 * cairo_raster_source_pattern_set_copy:
344 * @pattern: the pattern to update
345 * @copy: the copy callback
347 * Updates the copy callback which is used whenever a temporary copy of the
348 * pattern is taken.
350 * Since: 1.12
352 void
353 cairo_raster_source_pattern_set_copy (cairo_pattern_t *abstract_pattern,
354 cairo_raster_source_copy_func_t copy)
356 cairo_raster_source_pattern_t *pattern;
358 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
359 return;
361 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
362 pattern->copy = copy;
366 * cairo_raster_source_pattern_get_copy:
367 * @pattern: the pattern to query
369 * Queries the current copy callback.
371 * Return value: the current copy callback
373 * Since: 1.12
375 cairo_raster_source_copy_func_t
376 cairo_raster_source_pattern_get_copy (cairo_pattern_t *abstract_pattern)
378 cairo_raster_source_pattern_t *pattern;
380 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
381 return NULL;
383 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
384 return pattern->copy;
388 * cairo_raster_source_pattern_set_finish:
389 * @pattern: the pattern to update
390 * @finish: the finish callback
392 * Updates the finish callback which is used whenever a pattern (or a copy
393 * thereof) will no longer be used.
395 * Since: 1.12
397 void
398 cairo_raster_source_pattern_set_finish (cairo_pattern_t *abstract_pattern,
399 cairo_raster_source_finish_func_t finish)
401 cairo_raster_source_pattern_t *pattern;
403 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
404 return;
406 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
407 pattern->finish = finish;
411 * cairo_raster_source_pattern_get_finish:
412 * @pattern: the pattern to query
414 * Queries the current finish callback.
416 * Return value: the current finish callback
418 * Since: 1.12
420 cairo_raster_source_finish_func_t
421 cairo_raster_source_pattern_get_finish (cairo_pattern_t *abstract_pattern)
423 cairo_raster_source_pattern_t *pattern;
425 if (abstract_pattern->type != CAIRO_PATTERN_TYPE_RASTER_SOURCE)
426 return NULL;
428 pattern = (cairo_raster_source_pattern_t *) abstract_pattern;
429 return pattern->finish;