Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1892 serge 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
3
 *
4
 * Copyright © 2002 University of Southern California
5
 * Copyright © 2005 Red Hat, Inc.
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it either under the terms of the GNU Lesser General Public
9
 * License version 2.1 as published by the Free Software Foundation
10
 * (the "LGPL") or, at your option, under the terms of the Mozilla
11
 * Public License Version 1.1 (the "MPL"). If you do not alter this
12
 * notice, a recipient may use your version of this file under either
13
 * the MPL or the LGPL.
14
 *
15
 * You should have received a copy of the LGPL along with this library
16
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18
 * You should have received a copy of the MPL along with this library
19
 * in the file COPYING-MPL-1.1
20
 *
21
 * The contents of this file are subject to the Mozilla Public License
22
 * Version 1.1 (the "License"); you may not use this file except in
23
 * compliance with the License. You may obtain a copy of the License at
24
 * http://www.mozilla.org/MPL/
25
 *
26
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28
 * the specific language governing rights and limitations.
29
 *
30
 * The Original Code is the cairo graphics library.
31
 *
32
 * The Initial Developer of the Original Code is University of Southern
33
 * California.
34
 *
35
 * Contributor(s):
36
 *	Carl D. Worth 
37
 */
38
 
39
#include "cairoint.h"
40
 
3959 Serge 41
#include "cairo-array-private.h"
42
#include "cairo-clip-inline.h"
1892 serge 43
#include "cairo-clip-private.h"
3959 Serge 44
#include "cairo-damage-private.h"
1892 serge 45
#include "cairo-device-private.h"
46
#include "cairo-error-private.h"
3959 Serge 47
#include "cairo-list-inline.h"
48
#include "cairo-image-surface-inline.h"
1892 serge 49
#include "cairo-recording-surface-private.h"
50
#include "cairo-region-private.h"
3959 Serge 51
#include "cairo-surface-inline.h"
1892 serge 52
#include "cairo-tee-surface-private.h"
53
 
54
/**
55
 * SECTION:cairo-surface
56
 * @Title: cairo_surface_t
57
 * @Short_Description: Base class for surfaces
58
 * @See_Also: #cairo_t, #cairo_pattern_t
59
 *
60
 * #cairo_surface_t is the abstract type representing all different drawing
61
 * targets that cairo can render to.  The actual drawings are
62
 * performed using a cairo context.
63
 *
64
 * A cairo surface is created by using backend-specific
65
 * constructors, typically of the form
3959 Serge 66
 * cairo_backend_surface_create().
1892 serge 67
 *
68
 * Most surface types allow accessing the surface without using Cairo
69
 * functions. If you do this, keep in mind that it is mandatory that you call
70
 * cairo_surface_flush() before reading from or writing to the surface and that
71
 * you must use cairo_surface_mark_dirty() after modifying it.
72
 * 
73
 * Directly modifying an image surface
74
 * 
75
 * void
76
 * modify_image_surface (cairo_surface_t *surface)
77
 * {
78
 *   unsigned char *data;
79
 *   int width, height, stride;
80
 *
81
 *   // flush to ensure all writing to the image was done
82
 *   cairo_surface_flush (surface);
83
 *
84
 *   // modify the image
85
 *   data = cairo_image_surface_get_data (surface);
86
 *   width = cairo_image_surface_get_width (surface);
87
 *   height = cairo_image_surface_get_height (surface);
88
 *   stride = cairo_image_surface_get_stride (surface);
89
 *   modify_image_data (data, width, height, stride);
90
 *
91
 *   // mark the image dirty so Cairo clears its caches.
92
 *   cairo_surface_mark_dirty (surface);
93
 * }
94
 * 
95
 * 
96
 * Note that for other surface types it might be necessary to acquire the
97
 * surface's device first. See cairo_device_acquire() for a discussion of
98
 * devices.
3959 Serge 99
 **/
1892 serge 100
 
101
#define DEFINE_NIL_SURFACE(status, name)			\
102
const cairo_surface_t name = {					\
103
    NULL,				/* backend */		\
104
    NULL,				/* device */		\
105
    CAIRO_SURFACE_TYPE_IMAGE,		/* type */		\
106
    CAIRO_CONTENT_COLOR,		/* content */		\
107
    CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */		\
108
    status,				/* status */		\
109
    0,					/* unique id */		\
3959 Serge 110
    0,					/* serial */		\
111
    NULL,				/* damage */		\
112
    FALSE,				/* _finishing */	\
1892 serge 113
    FALSE,				/* finished */		\
114
    TRUE,				/* is_clear */		\
115
    FALSE,				/* has_font_options */	\
116
    FALSE,				/* owns_device */	\
117
    { 0, 0, 0, NULL, },			/* user_data */		\
118
    { 0, 0, 0, NULL, },			/* mime_data */         \
119
    { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 },   /* device_transform */	\
120
    { 1.0, 0.0,	0.0, 1.0, 0.0, 0.0 },	/* device_transform_inverse */	\
121
    { NULL, NULL },			/* device_transform_observers */ \
122
    0.0,				/* x_resolution */	\
123
    0.0,				/* y_resolution */	\
124
    0.0,				/* x_fallback_resolution */	\
125
    0.0,				/* y_fallback_resolution */	\
126
    NULL,				/* snapshot_of */	\
127
    NULL,				/* snapshot_detach */	\
128
    { NULL, NULL },			/* snapshots */		\
129
    { NULL, NULL },			/* snapshot */		\
130
    { CAIRO_ANTIALIAS_DEFAULT,		/* antialias */		\
131
      CAIRO_SUBPIXEL_ORDER_DEFAULT,	/* subpixel_order */	\
132
      CAIRO_LCD_FILTER_DEFAULT,		/* lcd_filter */	\
133
      CAIRO_HINT_STYLE_DEFAULT,		/* hint_style */	\
3959 Serge 134
      CAIRO_HINT_METRICS_DEFAULT,	/* hint_metrics */	\
135
      CAIRO_ROUND_GLYPH_POS_DEFAULT	/* round_glyph_positions */	\
1892 serge 136
    }					/* font_options */	\
137
}
138
 
139
/* XXX error object! */
140
 
141
static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
142
static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch);
143
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STATUS, _cairo_surface_nil_invalid_status);
144
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
145
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
146
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual);
147
static DEFINE_NIL_SURFACE(CAIRO_STATUS_FILE_NOT_FOUND, _cairo_surface_nil_file_not_found);
148
static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_file_error);
149
static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error);
150
static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error);
151
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
152
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size);
153
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch);
154
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error);
155
 
3959 Serge 156
static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_UNSUPPORTED, _cairo_surface_nil_unsupported);
157
static DEFINE_NIL_SURFACE(CAIRO_INT_STATUS_NOTHING_TO_DO, _cairo_surface_nil_nothing_to_do);
158
 
159
static void _cairo_surface_finish_snapshots (cairo_surface_t *surface);
160
static void _cairo_surface_finish (cairo_surface_t *surface);
161
 
1892 serge 162
/**
163
 * _cairo_surface_set_error:
164
 * @surface: a surface
165
 * @status: a status value indicating an error
166
 *
167
 * Atomically sets surface->status to @status and calls _cairo_error;
168
 * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
169
 * status values.
170
 *
171
 * All assignments of an error status to surface->status should happen
172
 * through _cairo_surface_set_error(). Note that due to the nature of
173
 * the atomic operation, it is not safe to call this function on the
174
 * nil objects.
175
 *
176
 * The purpose of this function is to allow the user to set a
177
 * breakpoint in _cairo_error() to generate a stack trace for when the
178
 * user causes cairo to detect an error.
179
 *
180
 * Return value: the error status.
181
 **/
3959 Serge 182
cairo_int_status_t
1892 serge 183
_cairo_surface_set_error (cairo_surface_t *surface,
3959 Serge 184
			  cairo_int_status_t status)
1892 serge 185
{
3959 Serge 186
    /* NOTHING_TO_DO is magic. We use it to break out of the inner-most
187
     * surface function, but anything higher just sees "success".
188
     */
1892 serge 189
    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
3959 Serge 190
	status = CAIRO_INT_STATUS_SUCCESS;
1892 serge 191
 
3959 Serge 192
    if (status == CAIRO_INT_STATUS_SUCCESS ||
193
        status >= (int)CAIRO_INT_STATUS_LAST_STATUS)
194
        return status;
1892 serge 195
 
196
    /* Don't overwrite an existing error. This preserves the first
197
     * error, which is the most significant. */
3959 Serge 198
    _cairo_status_set_error (&surface->status, (cairo_status_t)status);
1892 serge 199
 
200
    return _cairo_error (status);
201
}
202
 
203
/**
204
 * cairo_surface_get_type:
205
 * @surface: a #cairo_surface_t
206
 *
207
 * This function returns the type of the backend used to create
208
 * a surface. See #cairo_surface_type_t for available types.
209
 *
210
 * Return value: The type of @surface.
211
 *
212
 * Since: 1.2
213
 **/
214
cairo_surface_type_t
215
cairo_surface_get_type (cairo_surface_t *surface)
216
{
217
    /* We don't use surface->backend->type here so that some of the
218
     * special "wrapper" surfaces such as cairo_paginated_surface_t
219
     * can override surface->type with the type of the "child"
220
     * surface. */
221
    return surface->type;
222
}
223
 
224
/**
225
 * cairo_surface_get_content:
226
 * @surface: a #cairo_surface_t
227
 *
228
 * This function returns the content type of @surface which indicates
229
 * whether the surface contains color and/or alpha information. See
230
 * #cairo_content_t.
231
 *
232
 * Return value: The content type of @surface.
233
 *
234
 * Since: 1.2
235
 **/
236
cairo_content_t
237
cairo_surface_get_content (cairo_surface_t *surface)
238
{
239
    return surface->content;
240
}
241
 
242
/**
243
 * cairo_surface_status:
244
 * @surface: a #cairo_surface_t
245
 *
246
 * Checks whether an error has previously occurred for this
247
 * surface.
248
 *
249
 * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
250
 * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
251
 * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
252
 * %CAIRO_STATUS_INVALID_VISUAL.
3959 Serge 253
 *
254
 * Since: 1.0
1892 serge 255
 **/
256
cairo_status_t
257
cairo_surface_status (cairo_surface_t *surface)
258
{
259
    return surface->status;
260
}
261
slim_hidden_def (cairo_surface_status);
262
 
263
static unsigned int
264
_cairo_surface_allocate_unique_id (void)
265
{
266
    static cairo_atomic_int_t unique_id;
267
 
268
#if CAIRO_NO_MUTEX
269
    if (++unique_id == 0)
270
	unique_id = 1;
271
    return unique_id;
272
#else
273
    cairo_atomic_int_t old, id;
274
 
275
    do {
276
	old = _cairo_atomic_uint_get (&unique_id);
277
	id = old + 1;
278
	if (id == 0)
279
	    id = 1;
280
    } while (! _cairo_atomic_uint_cmpxchg (&unique_id, old, id));
281
 
282
    return id;
283
#endif
284
}
285
 
286
/**
287
 * cairo_surface_get_device:
288
 * @surface: a #cairo_surface_t
289
 *
290
 * This function returns the device for a @surface.
291
 * See #cairo_device_t.
292
 *
293
 * Return value: The device for @surface or %NULL if the surface does
294
 *               not have an associated device.
295
 *
296
 * Since: 1.10
297
 **/
298
cairo_device_t *
299
cairo_surface_get_device (cairo_surface_t *surface)
300
{
301
    if (unlikely (surface->status))
302
	return _cairo_device_create_in_error (surface->status);
303
 
304
    return surface->device;
305
}
306
 
307
static cairo_bool_t
308
_cairo_surface_has_snapshots (cairo_surface_t *surface)
309
{
310
    return ! cairo_list_is_empty (&surface->snapshots);
311
}
312
 
313
static cairo_bool_t
314
_cairo_surface_has_mime_data (cairo_surface_t *surface)
315
{
316
    return surface->mime_data.num_elements != 0;
317
}
318
 
319
static void
320
_cairo_surface_detach_mime_data (cairo_surface_t *surface)
321
{
322
    if (! _cairo_surface_has_mime_data (surface))
323
	return;
324
 
325
    _cairo_user_data_array_fini (&surface->mime_data);
326
    _cairo_user_data_array_init (&surface->mime_data);
327
}
328
 
329
static void
330
_cairo_surface_detach_snapshots (cairo_surface_t *surface)
331
{
332
    while (_cairo_surface_has_snapshots (surface)) {
333
	_cairo_surface_detach_snapshot (cairo_list_first_entry (&surface->snapshots,
334
								cairo_surface_t,
335
								snapshot));
336
    }
337
}
338
 
339
void
340
_cairo_surface_detach_snapshot (cairo_surface_t *snapshot)
341
{
342
    assert (snapshot->snapshot_of != NULL);
343
 
344
    snapshot->snapshot_of = NULL;
345
    cairo_list_del (&snapshot->snapshot);
346
 
347
    if (snapshot->snapshot_detach != NULL)
348
	snapshot->snapshot_detach (snapshot);
349
 
350
    cairo_surface_destroy (snapshot);
351
}
352
 
353
void
354
_cairo_surface_attach_snapshot (cairo_surface_t *surface,
355
				 cairo_surface_t *snapshot,
356
				 cairo_surface_func_t detach_func)
357
{
358
    assert (surface != snapshot);
359
    assert (snapshot->snapshot_of != surface);
360
 
361
    cairo_surface_reference (snapshot);
362
 
363
    if (snapshot->snapshot_of != NULL)
364
	_cairo_surface_detach_snapshot (snapshot);
365
 
366
    snapshot->snapshot_of = surface;
367
    snapshot->snapshot_detach = detach_func;
368
 
369
    cairo_list_add (&snapshot->snapshot, &surface->snapshots);
370
 
371
    assert (_cairo_surface_has_snapshot (surface, snapshot->backend) == snapshot);
372
}
373
 
374
cairo_surface_t *
375
_cairo_surface_has_snapshot (cairo_surface_t *surface,
376
			     const cairo_surface_backend_t *backend)
377
{
378
    cairo_surface_t *snapshot;
379
 
380
    cairo_list_foreach_entry (snapshot, cairo_surface_t,
381
			      &surface->snapshots, snapshot)
382
    {
383
	if (snapshot->backend == backend)
384
	    return snapshot;
385
    }
386
 
387
    return NULL;
388
}
389
 
3959 Serge 390
cairo_status_t
1892 serge 391
_cairo_surface_begin_modification (cairo_surface_t *surface)
392
{
393
    assert (surface->status == CAIRO_STATUS_SUCCESS);
394
    assert (! surface->finished);
395
 
3959 Serge 396
    return _cairo_surface_flush (surface, 1);
1892 serge 397
}
398
 
399
void
400
_cairo_surface_init (cairo_surface_t			*surface,
401
		     const cairo_surface_backend_t	*backend,
402
		     cairo_device_t			*device,
403
		     cairo_content_t			 content)
404
{
405
    CAIRO_MUTEX_INITIALIZE ();
406
 
407
    surface->backend = backend;
408
    surface->device = cairo_device_reference (device);
409
    surface->content = content;
410
    surface->type = backend->type;
411
 
412
    CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
413
    surface->status = CAIRO_STATUS_SUCCESS;
414
    surface->unique_id = _cairo_surface_allocate_unique_id ();
415
    surface->finished = FALSE;
3959 Serge 416
    surface->_finishing = FALSE;
1892 serge 417
    surface->is_clear = FALSE;
3959 Serge 418
    surface->serial = 0;
419
    surface->damage = NULL;
1892 serge 420
    surface->owns_device = (device != NULL);
421
 
422
    _cairo_user_data_array_init (&surface->user_data);
423
    _cairo_user_data_array_init (&surface->mime_data);
424
 
425
    cairo_matrix_init_identity (&surface->device_transform);
426
    cairo_matrix_init_identity (&surface->device_transform_inverse);
427
    cairo_list_init (&surface->device_transform_observers);
428
 
429
    surface->x_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
430
    surface->y_resolution = CAIRO_SURFACE_RESOLUTION_DEFAULT;
431
 
432
    surface->x_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
433
    surface->y_fallback_resolution = CAIRO_SURFACE_FALLBACK_RESOLUTION_DEFAULT;
434
 
435
    cairo_list_init (&surface->snapshots);
436
    surface->snapshot_of = NULL;
437
 
438
    surface->has_font_options = FALSE;
439
}
440
 
441
static void
442
_cairo_surface_copy_similar_properties (cairo_surface_t *surface,
443
					cairo_surface_t *other)
444
{
445
    if (other->has_font_options || other->backend != surface->backend) {
446
	cairo_font_options_t options;
447
 
448
	cairo_surface_get_font_options (other, &options);
449
	_cairo_surface_set_font_options (surface, &options);
450
    }
451
 
452
    cairo_surface_set_fallback_resolution (surface,
453
					   other->x_fallback_resolution,
454
					   other->y_fallback_resolution);
455
}
456
 
457
cairo_surface_t *
458
_cairo_surface_create_similar_scratch (cairo_surface_t *other,
459
				       cairo_content_t	content,
460
				       int		width,
461
				       int		height)
462
{
463
    cairo_surface_t *surface;
464
 
465
    if (unlikely (other->status))
466
	return _cairo_surface_create_in_error (other->status);
467
 
3959 Serge 468
    surface = NULL;
469
    if (other->backend->create_similar)
470
	surface = other->backend->create_similar (other, content, width, height);
471
    if (surface == NULL)
472
	surface = cairo_surface_create_similar_image (other,
473
						      _cairo_format_from_content (content),
474
						      width, height);
1892 serge 475
 
3959 Serge 476
    if (unlikely (surface->status))
1892 serge 477
	return surface;
478
 
479
    _cairo_surface_copy_similar_properties (surface, other);
480
 
481
    return surface;
482
}
483
 
484
/**
485
 * cairo_surface_create_similar:
486
 * @other: an existing surface used to select the backend of the new surface
487
 * @content: the content for the new surface
488
 * @width: width of the new surface, (in device-space units)
489
 * @height: height of the new surface (in device-space units)
490
 *
491
 * Create a new surface that is as compatible as possible with an
492
 * existing surface. For example the new surface will have the same
493
 * fallback resolution and font options as @other. Generally, the new
494
 * surface will also use the same backend as @other, unless that is
495
 * not possible for some reason. The type of the returned surface may
496
 * be examined with cairo_surface_get_type().
497
 *
498
 * Initially the surface contents are all 0 (transparent if contents
499
 * have transparency, black otherwise.)
500
 *
3959 Serge 501
 * Use cairo_surface_create_similar_image() if you need an image surface
502
 * which can be painted quickly to the target surface.
503
 *
1892 serge 504
 * Return value: a pointer to the newly allocated surface. The caller
505
 * owns the surface and should call cairo_surface_destroy() when done
506
 * with it.
507
 *
508
 * This function always returns a valid pointer, but it will return a
509
 * pointer to a "nil" surface if @other is already in an error state
510
 * or any other error occurs.
3959 Serge 511
 *
512
 * Since: 1.0
1892 serge 513
 **/
514
cairo_surface_t *
515
cairo_surface_create_similar (cairo_surface_t  *other,
516
			      cairo_content_t	content,
517
			      int		width,
518
			      int		height)
519
{
3959 Serge 520
    cairo_surface_t *surface;
521
 
1892 serge 522
    if (unlikely (other->status))
523
	return _cairo_surface_create_in_error (other->status);
524
    if (unlikely (other->finished))
525
	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
3959 Serge 526
    if (unlikely (width < 0 || height < 0))
527
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
1892 serge 528
 
529
    if (unlikely (! CAIRO_CONTENT_VALID (content)))
3959 Serge 530
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
1892 serge 531
 
3959 Serge 532
    surface = _cairo_surface_create_similar_solid (other,
533
						   content, width, height,
534
						   CAIRO_COLOR_TRANSPARENT);
535
    assert (surface->is_clear);
536
 
537
    return surface;
1892 serge 538
}
539
 
3959 Serge 540
/**
541
 * cairo_surface_create_similar_image:
542
 * @other: an existing surface used to select the preference of the new surface
543
 * @format: the format for the new surface
544
 * @width: width of the new surface, (in device-space units)
545
 * @height: height of the new surface (in device-space units)
546
 *
547
 * Create a new image surface that is as compatible as possible for uploading
548
 * to and the use in conjunction with an existing surface. However, this surface
549
 * can still be used like any normal image surface.
550
 *
551
 * Initially the surface contents are all 0 (transparent if contents
552
 * have transparency, black otherwise.)
553
 *
554
 * Use cairo_surface_create_similar() if you don't need an image surface.
555
 *
556
 * Return value: a pointer to the newly allocated image surface. The caller
557
 * owns the surface and should call cairo_surface_destroy() when done
558
 * with it.
559
 *
560
 * This function always returns a valid pointer, but it will return a
561
 * pointer to a "nil" surface if @other is already in an error state
562
 * or any other error occurs.
563
 *
564
 * Since: 1.12
565
 **/
1892 serge 566
cairo_surface_t *
3959 Serge 567
cairo_surface_create_similar_image (cairo_surface_t  *other,
568
				    cairo_format_t    format,
569
				    int		width,
570
				    int		height)
571
{
572
    cairo_surface_t *image;
573
 
574
    if (unlikely (other->status))
575
	return _cairo_surface_create_in_error (other->status);
576
    if (unlikely (other->finished))
577
	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
578
 
579
    if (unlikely (width < 0 || height < 0))
580
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
581
    if (unlikely (! CAIRO_FORMAT_VALID (format)))
582
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_FORMAT);
583
 
584
    image = NULL;
585
    if (other->backend->create_similar_image)
586
	image = other->backend->create_similar_image (other,
587
						      format, width, height);
588
    if (image == NULL)
589
	image = cairo_image_surface_create (format, width, height);
590
 
591
    assert (image->is_clear);
592
 
593
    return image;
594
}
595
slim_hidden_def (cairo_surface_create_similar_image);
596
 
597
/**
598
 * _cairo_surface_map_to_image:
599
 * @surface: an existing surface used to extract the image from
600
 * @extents: limit the extraction to an rectangular region
601
 *
602
 * Returns an image surface that is the most efficient mechanism for
603
 * modifying the backing store of the target surface. The region
604
 * retrieved is limited to @extents.
605
 *
606
 * Note, the use of the original surface as a target or source whilst
607
 * it is mapped is undefined. The result of mapping the surface
608
 * multiple times is undefined. Calling cairo_surface_destroy() or
609
 * cairo_surface_finish() on the resulting image surface results in
610
 * undefined behavior. Changing the device transform of the image
611
 * surface or of @surface before the image surface is unmapped results
612
 * in undefined behavior.
613
 *
614
 * Assumes that @surface is valid (CAIRO_STATUS_SUCCESS,
615
 * non-finished).
616
 *
617
 * Return value: a pointer to the newly allocated image surface. The
618
 * caller must use _cairo_surface_unmap_image() to destroy this image
619
 * surface.
620
 *
621
 * This function always returns a valid pointer, but it will return a
622
 * pointer to a "nil" surface if @other is already in an error state
623
 * or any other error occurs.
624
 *
625
 * The returned image might have a %CAIRO_FORMAT_INVALID format.
626
 **/
627
cairo_image_surface_t *
628
_cairo_surface_map_to_image (cairo_surface_t  *surface,
629
			     const cairo_rectangle_int_t *extents)
630
{
631
    cairo_image_surface_t *image = NULL;
632
 
633
    assert (extents != NULL);
634
 
635
    /* TODO: require map_to_image != NULL */
636
    if (surface->backend->map_to_image)
637
	image = surface->backend->map_to_image (surface, extents);
638
 
639
    if (image == NULL)
640
	image = _cairo_image_surface_clone_subimage (surface, extents);
641
 
642
    return image;
643
}
644
 
645
/**
646
 * _cairo_surface_unmap_image:
647
 * @surface: the surface passed to _cairo_surface_map_to_image().
648
 * @image: the currently mapped image
649
 *
650
 * Unmaps the image surface as returned from
651
 * _cairo_surface_map_to_image().
652
 *
653
 * The content of the image will be uploaded to the target surface.
654
 * Afterwards, the image is destroyed.
655
 *
656
 * Using an image surface which wasn't returned by
657
 * _cairo_surface_map_to_image() results in undefined behavior.
658
 *
659
 * An image surface in error status can be passed to
660
 * _cairo_surface_unmap_image().
661
 *
662
 * Return value: the unmap status.
663
 *
664
 * Even if the unmap status is not successful, @image is destroyed.
665
 **/
666
cairo_int_status_t
667
_cairo_surface_unmap_image (cairo_surface_t       *surface,
668
			    cairo_image_surface_t *image)
669
{
670
    cairo_surface_pattern_t pattern;
671
    cairo_rectangle_int_t extents;
672
    cairo_clip_t *clip;
673
    cairo_int_status_t status;
674
 
675
    /* map_to_image can return error surfaces */
676
    if (unlikely (image->base.status)) {
677
	status = image->base.status;
678
	goto destroy;
679
    }
680
 
681
    /* If the image is untouched just skip the update */
682
    if (image->base.serial == 0) {
683
	status = CAIRO_STATUS_SUCCESS;
684
	goto destroy;
685
    }
686
 
687
    /* TODO: require unmap_image != NULL */
688
    if (surface->backend->unmap_image &&
689
	! _cairo_image_surface_is_clone (image))
690
    {
691
	status = surface->backend->unmap_image (surface, image);
692
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
693
	    return status;
694
    }
695
 
696
    _cairo_pattern_init_for_surface (&pattern, &image->base);
697
    pattern.base.filter = CAIRO_FILTER_NEAREST;
698
 
699
    /* We have to apply the translate from map_to_image's extents.x and .y */
700
    cairo_matrix_init_translate (&pattern.base.matrix,
701
				 image->base.device_transform.x0,
702
				 image->base.device_transform.y0);
703
 
704
    /* And we also have to clip the operation to the image's extents */
705
    extents.x = image->base.device_transform_inverse.x0;
706
    extents.y = image->base.device_transform_inverse.y0;
707
    extents.width  = image->width;
708
    extents.height = image->height;
709
    clip = _cairo_clip_intersect_rectangle (NULL, &extents);
710
 
711
    status = _cairo_surface_paint (surface,
712
				   CAIRO_OPERATOR_SOURCE,
713
				   &pattern.base,
714
				   clip);
715
 
716
    _cairo_pattern_fini (&pattern.base);
717
    _cairo_clip_destroy (clip);
718
 
719
destroy:
720
    cairo_surface_finish (&image->base);
721
    cairo_surface_destroy (&image->base);
722
 
723
    return status;
724
}
725
 
726
/**
727
 * cairo_surface_map_to_image:
728
 * @surface: an existing surface used to extract the image from
729
 * @extents: limit the extraction to an rectangular region
730
 *
731
 * Returns an image surface that is the most efficient mechanism for
732
 * modifying the backing store of the target surface. The region retrieved
733
 * may be limited to the @extents or %NULL for the whole surface
734
 *
735
 * Note, the use of the original surface as a target or source whilst
736
 * it is mapped is undefined. The result of mapping the surface
737
 * multiple times is undefined. Calling cairo_surface_destroy() or
738
 * cairo_surface_finish() on the resulting image surface results in
739
 * undefined behavior. Changing the device transform of the image
740
 * surface or of @surface before the image surface is unmapped results
741
 * in undefined behavior.
742
 *
743
 * Return value: a pointer to the newly allocated image surface. The caller
744
 * must use cairo_surface_unmap_image() to destroy this image surface.
745
 *
746
 * This function always returns a valid pointer, but it will return a
747
 * pointer to a "nil" surface if @other is already in an error state
748
 * or any other error occurs. If the returned pointer does not have an
749
 * error status, it is guaranteed to be an image surface whose format
750
 * is not %CAIRO_FORMAT_INVALID.
751
 *
752
 * Since: 1.12
753
 **/
754
cairo_surface_t *
755
cairo_surface_map_to_image (cairo_surface_t  *surface,
756
			    const cairo_rectangle_int_t *extents)
757
{
758
    cairo_rectangle_int_t rect;
759
    cairo_image_surface_t *image;
760
    cairo_status_t status;
761
 
762
    if (unlikely (surface->status))
763
	return _cairo_surface_create_in_error (surface->status);
764
    if (unlikely (surface->finished))
765
	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
766
 
767
    if (extents == NULL) {
768
	if (unlikely (! surface->backend->get_extents (surface, &rect)))
769
	    return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
770
 
771
	extents = ▭
772
    } else {
773
	cairo_rectangle_int_t surface_extents;
774
 
775
	/* If this surface is bounded, we can't map parts
776
	 * that are outside of it. */
777
	if (likely (surface->backend->get_extents (surface, &surface_extents))) {
778
	    if (unlikely (! _cairo_rectangle_contains_rectangle (&surface_extents, extents)))
779
		return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
780
	}
781
    }
782
 
783
    image = _cairo_surface_map_to_image (surface, extents);
784
 
785
    status = image->base.status;
786
    if (unlikely (status)) {
787
	cairo_surface_destroy (&image->base);
788
	return _cairo_surface_create_in_error (status);
789
    }
790
 
791
    if (image->format == CAIRO_FORMAT_INVALID) {
792
	cairo_surface_destroy (&image->base);
793
	image = _cairo_image_surface_clone_subimage (surface, extents);
794
    }
795
 
796
    return &image->base;
797
}
798
 
799
/**
800
 * cairo_surface_unmap_image:
801
 * @surface: the surface passed to cairo_surface_map_to_image().
802
 * @image: the currently mapped image
803
 *
804
 * Unmaps the image surface as returned from #cairo_surface_map_to_image().
805
 *
806
 * The content of the image will be uploaded to the target surface.
807
 * Afterwards, the image is destroyed.
808
 *
809
 * Using an image surface which wasn't returned by cairo_surface_map_to_image()
810
 * results in undefined behavior.
811
 *
812
 * Since: 1.12
813
 **/
814
void
815
cairo_surface_unmap_image (cairo_surface_t *surface,
816
			   cairo_surface_t *image)
817
{
818
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
819
 
820
    if (unlikely (surface->status)) {
821
	status = surface->status;
822
	goto error;
823
    }
824
    if (unlikely (surface->finished)) {
825
	status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
826
	goto error;
827
    }
828
    if (unlikely (image->status)) {
829
	status = image->status;
830
	goto error;
831
    }
832
    if (unlikely (image->finished)) {
833
	status = _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
834
	goto error;
835
    }
836
    if (unlikely (! _cairo_surface_is_image (image))) {
837
	status = _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
838
	goto error;
839
    }
840
 
841
    status = _cairo_surface_unmap_image (surface,
842
					 (cairo_image_surface_t *) image);
843
    if (unlikely (status))
844
	_cairo_surface_set_error (surface, status);
845
 
846
    return;
847
 
848
error:
849
    _cairo_surface_set_error (surface, status);
850
    cairo_surface_finish (image);
851
    cairo_surface_destroy (image);
852
}
853
 
854
cairo_surface_t *
1892 serge 855
_cairo_surface_create_similar_solid (cairo_surface_t	 *other,
856
				     cairo_content_t	  content,
857
				     int		  width,
858
				     int		  height,
3959 Serge 859
				     const cairo_color_t *color)
1892 serge 860
{
861
    cairo_status_t status;
862
    cairo_surface_t *surface;
863
    cairo_solid_pattern_t pattern;
864
 
865
    surface = _cairo_surface_create_similar_scratch (other, content,
866
						     width, height);
3959 Serge 867
    if (unlikely (surface->status))
1892 serge 868
	return surface;
869
 
870
    _cairo_pattern_init_solid (&pattern, color);
871
    status = _cairo_surface_paint (surface,
872
				   color == CAIRO_COLOR_TRANSPARENT ?
873
				   CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_SOURCE,
874
				   &pattern.base, NULL);
875
    if (unlikely (status)) {
876
	cairo_surface_destroy (surface);
877
	surface = _cairo_surface_create_in_error (status);
878
    }
879
 
880
    return surface;
881
}
882
 
883
/**
884
 * cairo_surface_reference:
885
 * @surface: a #cairo_surface_t
886
 *
887
 * Increases the reference count on @surface by one. This prevents
888
 * @surface from being destroyed until a matching call to
889
 * cairo_surface_destroy() is made.
890
 *
891
 * The number of references to a #cairo_surface_t can be get using
892
 * cairo_surface_get_reference_count().
893
 *
894
 * Return value: the referenced #cairo_surface_t.
3959 Serge 895
 *
896
 * Since: 1.0
1892 serge 897
 **/
898
cairo_surface_t *
899
cairo_surface_reference (cairo_surface_t *surface)
900
{
901
    if (surface == NULL ||
902
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
903
	return surface;
904
 
905
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
906
 
907
    _cairo_reference_count_inc (&surface->ref_count);
908
 
909
    return surface;
910
}
911
slim_hidden_def (cairo_surface_reference);
912
 
913
/**
914
 * cairo_surface_destroy:
915
 * @surface: a #cairo_surface_t
916
 *
917
 * Decreases the reference count on @surface by one. If the result is
918
 * zero, then @surface and all associated resources are freed.  See
919
 * cairo_surface_reference().
3959 Serge 920
 *
921
 * Since: 1.0
1892 serge 922
 **/
923
void
924
cairo_surface_destroy (cairo_surface_t *surface)
925
{
926
    if (surface == NULL ||
927
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
928
	return;
929
 
930
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
931
 
932
    if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
933
	return;
934
 
935
    assert (surface->snapshot_of == NULL);
936
 
3959 Serge 937
    if (! surface->finished) {
938
	_cairo_surface_finish_snapshots (surface);
939
	/* We may have been referenced by a snapshot prior to have
940
	 * detaching it with the copy-on-write.
941
	 */
942
	if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count))
943
	    return;
1892 serge 944
 
3959 Serge 945
	_cairo_surface_finish (surface);
946
    }
1892 serge 947
 
3959 Serge 948
    if (surface->damage)
949
	_cairo_damage_destroy (surface->damage);
950
 
1892 serge 951
    _cairo_user_data_array_fini (&surface->user_data);
952
    _cairo_user_data_array_fini (&surface->mime_data);
953
 
954
    if (surface->owns_device)
955
        cairo_device_destroy (surface->device);
956
 
3959 Serge 957
    assert (surface->snapshot_of == NULL);
958
    assert (! _cairo_surface_has_snapshots (surface));
959
    /* paranoid check that nobody took a reference whilst finishing */
960
    assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
961
 
1892 serge 962
    free (surface);
963
}
964
slim_hidden_def(cairo_surface_destroy);
965
 
966
/**
967
 * cairo_surface_get_reference_count:
968
 * @surface: a #cairo_surface_t
969
 *
970
 * Returns the current reference count of @surface.
971
 *
972
 * Return value: the current reference count of @surface.  If the
973
 * object is a nil object, 0 will be returned.
974
 *
975
 * Since: 1.4
976
 **/
977
unsigned int
978
cairo_surface_get_reference_count (cairo_surface_t *surface)
979
{
980
    if (surface == NULL ||
981
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
982
	return 0;
983
 
984
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
985
}
986
 
3959 Serge 987
static void
988
_cairo_surface_finish_snapshots (cairo_surface_t *surface)
989
{
990
    cairo_status_t status;
991
 
992
    /* update the snapshots *before* we declare the surface as finished */
993
    surface->_finishing = TRUE;
994
    status = _cairo_surface_flush (surface, 0);
995
    (void) status;
996
}
997
 
998
static void
999
_cairo_surface_finish (cairo_surface_t *surface)
1000
{
1001
    cairo_status_t status;
1002
 
1003
    surface->finished = TRUE;
1004
 
1005
    /* call finish even if in error mode */
1006
    if (surface->backend->finish) {
1007
	status = surface->backend->finish (surface);
1008
	if (unlikely (status))
1009
	    _cairo_surface_set_error (surface, status);
1010
    }
1011
 
1012
    assert (surface->snapshot_of == NULL);
1013
    assert (!_cairo_surface_has_snapshots (surface));
1014
}
1015
 
1892 serge 1016
/**
1017
 * cairo_surface_finish:
1018
 * @surface: the #cairo_surface_t to finish
1019
 *
1020
 * This function finishes the surface and drops all references to
1021
 * external resources.  For example, for the Xlib backend it means
1022
 * that cairo will no longer access the drawable, which can be freed.
1023
 * After calling cairo_surface_finish() the only valid operations on a
1024
 * surface are getting and setting user, referencing and
1025
 * destroying, and flushing and finishing it.
1026
 * Further drawing to the surface will not affect the
1027
 * surface but will instead trigger a %CAIRO_STATUS_SURFACE_FINISHED
1028
 * error.
1029
 *
1030
 * When the last call to cairo_surface_destroy() decreases the
1031
 * reference count to zero, cairo will call cairo_surface_finish() if
1032
 * it hasn't been called already, before freeing the resources
1033
 * associated with the surface.
3959 Serge 1034
 *
1035
 * Since: 1.0
1892 serge 1036
 **/
1037
void
1038
cairo_surface_finish (cairo_surface_t *surface)
1039
{
1040
    if (surface == NULL)
1041
	return;
1042
 
1043
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
1044
	return;
1045
 
1046
    if (surface->finished)
1047
	return;
1048
 
3959 Serge 1049
    /* We have to be careful when decoupling potential reference cycles */
1050
    cairo_surface_reference (surface);
1892 serge 1051
 
3959 Serge 1052
    _cairo_surface_finish_snapshots (surface);
1053
    /* XXX need to block and wait for snapshot references */
1054
    _cairo_surface_finish (surface);
1892 serge 1055
 
3959 Serge 1056
    cairo_surface_destroy (surface);
1892 serge 1057
}
1058
slim_hidden_def (cairo_surface_finish);
1059
 
1060
/**
1061
 * _cairo_surface_release_device_reference:
1062
 * @surface: a #cairo_surface_t
1063
 *
1064
 * This function makes @surface release the reference to its device. The
1065
 * function is intended to be used for avoiding cycling references for
1066
 * surfaces that are owned by their device, for example cache surfaces.
1067
 * Note that the @surface will still assume that the device is available.
1068
 * So it is the caller's responsibility to ensure the device stays around
1069
 * until the @surface is destroyed. Just calling cairo_surface_finish() is
1070
 * not enough.
1071
 **/
1072
void
1073
_cairo_surface_release_device_reference (cairo_surface_t *surface)
1074
{
1075
    assert (surface->owns_device);
1076
 
1077
    cairo_device_destroy (surface->device);
1078
    surface->owns_device = FALSE;
1079
}
1080
 
1081
/**
1082
 * cairo_surface_get_user_data:
1083
 * @surface: a #cairo_surface_t
1084
 * @key: the address of the #cairo_user_data_key_t the user data was
1085
 * attached to
1086
 *
1087
 * Return user data previously attached to @surface using the specified
1088
 * key.  If no user data has been attached with the given key this
1089
 * function returns %NULL.
1090
 *
1091
 * Return value: the user data previously attached or %NULL.
3959 Serge 1092
 *
1093
 * Since: 1.0
1892 serge 1094
 **/
1095
void *
1096
cairo_surface_get_user_data (cairo_surface_t		 *surface,
1097
			     const cairo_user_data_key_t *key)
1098
{
3959 Serge 1099
    /* Prevent reads of the array during teardown */
1100
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
1101
	return NULL;
1102
 
1103
    return _cairo_user_data_array_get_data (&surface->user_data, key);
1892 serge 1104
}
1105
 
1106
/**
1107
 * cairo_surface_set_user_data:
1108
 * @surface: a #cairo_surface_t
1109
 * @key: the address of a #cairo_user_data_key_t to attach the user data to
1110
 * @user_data: the user data to attach to the surface
1111
 * @destroy: a #cairo_destroy_func_t which will be called when the
1112
 * surface is destroyed or when new user data is attached using the
1113
 * same key.
1114
 *
1115
 * Attach user data to @surface.  To remove user data from a surface,
1116
 * call this function with the key that was used to set it and %NULL
1117
 * for @data.
1118
 *
1119
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
1120
 * slot could not be allocated for the user data.
3959 Serge 1121
 *
1122
 * Since: 1.0
1892 serge 1123
 **/
1124
cairo_status_t
1125
cairo_surface_set_user_data (cairo_surface_t		 *surface,
1126
			     const cairo_user_data_key_t *key,
1127
			     void			 *user_data,
1128
			     cairo_destroy_func_t	 destroy)
1129
{
1130
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
1131
	return surface->status;
1132
 
3959 Serge 1133
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
1134
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
1135
 
1892 serge 1136
    return _cairo_user_data_array_set_data (&surface->user_data,
1137
					    key, user_data, destroy);
1138
}
1139
 
1140
/**
1141
 * cairo_surface_get_mime_data:
1142
 * @surface: a #cairo_surface_t
1143
 * @mime_type: the mime type of the image data
1144
 * @data: the image data to attached to the surface
1145
 * @length: the length of the image data
1146
 *
1147
 * Return mime data previously attached to @surface using the
1148
 * specified mime type.  If no data has been attached with the given
1149
 * mime type, @data is set %NULL.
1150
 *
1151
 * Since: 1.10
1152
 **/
1153
void
1154
cairo_surface_get_mime_data (cairo_surface_t		*surface,
1155
                             const char			*mime_type,
1156
                             const unsigned char       **data,
1157
                             unsigned long		*length)
1158
{
1159
    cairo_user_data_slot_t *slots;
1160
    int i, num_slots;
1161
 
1162
    *data = NULL;
1163
    *length = 0;
3959 Serge 1164
 
1165
    /* Prevent reads of the array during teardown */
1166
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
1892 serge 1167
	return;
1168
 
1169
    /* The number of mime-types attached to a surface is usually small,
1170
     * typically zero. Therefore it is quicker to do a strcmp() against
1171
     * each key than it is to intern the string (i.e. compute a hash,
1172
     * search the hash table, and do a final strcmp).
1173
     */
1174
    num_slots = surface->mime_data.num_elements;
1175
    slots = _cairo_array_index (&surface->mime_data, 0);
1176
    for (i = 0; i < num_slots; i++) {
3959 Serge 1177
	if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) {
1892 serge 1178
	    cairo_mime_data_t *mime_data = slots[i].user_data;
1179
 
1180
	    *data = mime_data->data;
1181
	    *length = mime_data->length;
1182
	    return;
1183
	}
1184
    }
1185
}
1186
slim_hidden_def (cairo_surface_get_mime_data);
1187
 
1188
static void
1189
_cairo_mime_data_destroy (void *ptr)
1190
{
1191
    cairo_mime_data_t *mime_data = ptr;
1192
 
1193
    if (! _cairo_reference_count_dec_and_test (&mime_data->ref_count))
1194
	return;
1195
 
1196
    if (mime_data->destroy && mime_data->closure)
1197
	mime_data->destroy (mime_data->closure);
1198
 
1199
    free (mime_data);
1200
}
1201
 
1202
/**
1203
 * CAIRO_MIME_TYPE_JP2:
1204
 *
1205
 * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
1206
 *
3959 Serge 1207
 * Since: 1.10
1208
 **/
1892 serge 1209
 
1210
/**
1211
 * CAIRO_MIME_TYPE_JPEG:
1212
 *
1213
 * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1).
1214
 *
3959 Serge 1215
 * Since: 1.10
1216
 **/
1892 serge 1217
 
1218
/**
1219
 * CAIRO_MIME_TYPE_PNG:
1220
 *
1221
 * The Portable Network Graphics image file format (ISO/IEC 15948).
1222
 *
3959 Serge 1223
 * Since: 1.10
1224
 **/
1892 serge 1225
 
1226
/**
1227
 * CAIRO_MIME_TYPE_URI:
1228
 *
1229
 * URI for an image file (unofficial MIME type).
1230
 *
3959 Serge 1231
 * Since: 1.10
1232
 **/
1892 serge 1233
 
1234
/**
3959 Serge 1235
 * CAIRO_MIME_TYPE_UNIQUE_ID:
1236
 *
1237
 * Unique identifier for a surface (cairo specific MIME type).
1238
 *
1239
 * Since: 1.12
1240
 **/
1241
 
1242
/**
1892 serge 1243
 * cairo_surface_set_mime_data:
1244
 * @surface: a #cairo_surface_t
1245
 * @mime_type: the MIME type of the image data
1246
 * @data: the image data to attach to the surface
1247
 * @length: the length of the image data
1248
 * @destroy: a #cairo_destroy_func_t which will be called when the
1249
 * surface is destroyed or when new image data is attached using the
1250
 * same mime type.
1251
 * @closure: the data to be passed to the @destroy notifier
1252
 *
1253
 * Attach an image in the format @mime_type to @surface. To remove
1254
 * the data from a surface, call this function with same mime type
1255
 * and %NULL for @data.
1256
 *
1257
 * The attached image (or filename) data can later be used by backends
1258
 * which support it (currently: PDF, PS, SVG and Win32 Printing
1259
 * surfaces) to emit this data instead of making a snapshot of the
1260
 * @surface.  This approach tends to be faster and requires less
1261
 * memory and disk space.
1262
 *
1263
 * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
3959 Serge 1264
 * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI,
1265
 * %CAIRO_MIME_TYPE_UNIQUE_ID.
1892 serge 1266
 *
1267
 * See corresponding backend surface docs for details about which MIME
1268
 * types it can handle. Caution: the associated MIME data will be
1269
 * discarded if you draw on the surface afterwards. Use this function
1270
 * with care.
1271
 *
1272
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
1273
 * slot could not be allocated for the user data.
3959 Serge 1274
 *
1275
 * Since: 1.10
1892 serge 1276
 **/
1277
cairo_status_t
1278
cairo_surface_set_mime_data (cairo_surface_t		*surface,
1279
                             const char			*mime_type,
1280
                             const unsigned char	*data,
1281
                             unsigned long		 length,
1282
			     cairo_destroy_func_t	 destroy,
1283
			     void			*closure)
1284
{
1285
    cairo_status_t status;
1286
    cairo_mime_data_t *mime_data;
1287
 
3959 Serge 1288
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
1289
	return surface->status;
1290
 
1291
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
1292
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
1293
 
1892 serge 1294
    if (unlikely (surface->status))
1295
	return surface->status;
3959 Serge 1296
    if (unlikely (surface->finished))
1892 serge 1297
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1298
 
1299
    status = _cairo_intern_string (&mime_type, -1);
1300
    if (unlikely (status))
1301
	return _cairo_surface_set_error (surface, status);
1302
 
1303
    if (data != NULL) {
1304
	mime_data = malloc (sizeof (cairo_mime_data_t));
1305
	if (unlikely (mime_data == NULL))
1306
	    return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY));
1307
 
1308
	CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1);
1309
 
1310
	mime_data->data = (unsigned char *) data;
1311
	mime_data->length = length;
1312
	mime_data->destroy = destroy;
1313
	mime_data->closure = closure;
1314
    } else
1315
	mime_data = NULL;
1316
 
1317
    status = _cairo_user_data_array_set_data (&surface->mime_data,
1318
					      (cairo_user_data_key_t *) mime_type,
1319
					      mime_data,
1320
					      _cairo_mime_data_destroy);
1321
    if (unlikely (status)) {
3959 Serge 1322
	free (mime_data);
1892 serge 1323
 
1324
	return _cairo_surface_set_error (surface, status);
1325
    }
1326
 
1327
    return CAIRO_STATUS_SUCCESS;
1328
}
1329
slim_hidden_def (cairo_surface_set_mime_data);
1330
 
3959 Serge 1331
/**
1332
 * cairo_surface_supports_mime_type:
1333
 * @surface: a #cairo_surface_t
1334
 * @mime_type: the mime type
1335
 *
1336
 * Return whether @surface supports @mime_type.
1337
 *
1338
 * Return value: %TRUE if @surface supports
1339
 *               @mime_type, %FALSE otherwise
1340
 *
1341
 * Since: 1.12
1342
 **/
1343
cairo_bool_t
1344
cairo_surface_supports_mime_type (cairo_surface_t		*surface,
1345
				  const char			*mime_type)
1346
{
1347
    const char **types;
1348
 
1349
    if (unlikely (surface->status))
1350
	return FALSE;
1351
    if (unlikely (surface->finished)) {
1352
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1353
	return FALSE;
1354
    }
1355
 
1356
    if (surface->backend->get_supported_mime_types) {
1357
	types = surface->backend->get_supported_mime_types (surface);
1358
	if (types) {
1359
	    while (*types) {
1360
		if (strcmp (*types, mime_type) == 0)
1361
		    return TRUE;
1362
		types++;
1363
	    }
1364
	}
1365
    }
1366
 
1367
    return FALSE;
1368
}
1369
slim_hidden_def (cairo_surface_supports_mime_type);
1370
 
1892 serge 1371
static void
1372
_cairo_mime_data_reference (const void *key, void *elt, void *closure)
1373
{
1374
    cairo_mime_data_t *mime_data = elt;
1375
 
1376
    _cairo_reference_count_inc (&mime_data->ref_count);
1377
}
1378
 
1379
cairo_status_t
1380
_cairo_surface_copy_mime_data (cairo_surface_t *dst,
1381
			       cairo_surface_t *src)
1382
{
1383
    cairo_status_t status;
1384
 
1385
    if (dst->status)
1386
	return dst->status;
1387
 
1388
    if (src->status)
1389
	return _cairo_surface_set_error (dst, src->status);
1390
 
1391
    /* first copy the mime-data, discarding any already set on dst */
1392
    status = _cairo_user_data_array_copy (&dst->mime_data, &src->mime_data);
1393
    if (unlikely (status))
1394
	return _cairo_surface_set_error (dst, status);
1395
 
1396
    /* now increment the reference counters for the copies */
1397
    _cairo_user_data_array_foreach (&dst->mime_data,
1398
				    _cairo_mime_data_reference,
1399
				    NULL);
1400
 
1401
    return CAIRO_STATUS_SUCCESS;
1402
}
1403
 
1404
/**
1405
 * _cairo_surface_set_font_options:
1406
 * @surface: a #cairo_surface_t
1407
 * @options: a #cairo_font_options_t object that contains the
1408
 *   options to use for this surface instead of backend's default
1409
 *   font options.
1410
 *
1411
 * Sets the default font rendering options for the surface.
1412
 * This is useful to correctly propagate default font options when
1413
 * falling back to an image surface in a backend implementation.
1414
 * This affects the options returned in cairo_surface_get_font_options().
1415
 *
1416
 * If @options is %NULL the surface options are reset to those of
1417
 * the backend default.
1418
 **/
1419
void
1420
_cairo_surface_set_font_options (cairo_surface_t       *surface,
1421
				 cairo_font_options_t  *options)
1422
{
1423
    if (surface->status)
1424
	return;
1425
 
1426
    assert (surface->snapshot_of == NULL);
1427
 
1428
    if (surface->finished) {
3959 Serge 1429
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 1430
	return;
1431
    }
1432
 
1433
    if (options) {
1434
	surface->has_font_options = TRUE;
1435
	_cairo_font_options_init_copy (&surface->font_options, options);
1436
    } else {
1437
	surface->has_font_options = FALSE;
1438
    }
1439
}
1440
 
1441
/**
1442
 * cairo_surface_get_font_options:
1443
 * @surface: a #cairo_surface_t
1444
 * @options: a #cairo_font_options_t object into which to store
1445
 *   the retrieved options. All existing values are overwritten
1446
 *
1447
 * Retrieves the default font rendering options for the surface.
1448
 * This allows display surfaces to report the correct subpixel order
1449
 * for rendering on them, print surfaces to disable hinting of
1450
 * metrics and so forth. The result can then be used with
1451
 * cairo_scaled_font_create().
3959 Serge 1452
 *
1453
 * Since: 1.0
1892 serge 1454
 **/
1455
void
1456
cairo_surface_get_font_options (cairo_surface_t       *surface,
1457
				cairo_font_options_t  *options)
1458
{
1459
    if (cairo_font_options_status (options))
1460
	return;
1461
 
1462
    if (surface->status) {
1463
	_cairo_font_options_init_default (options);
1464
	return;
1465
    }
1466
 
1467
    if (! surface->has_font_options) {
1468
	surface->has_font_options = TRUE;
1469
 
1470
	_cairo_font_options_init_default (&surface->font_options);
1471
 
1472
	if (!surface->finished && surface->backend->get_font_options) {
1473
	    surface->backend->get_font_options (surface, &surface->font_options);
1474
	}
1475
    }
1476
 
1477
    _cairo_font_options_init_copy (options, &surface->font_options);
1478
}
1479
slim_hidden_def (cairo_surface_get_font_options);
1480
 
3959 Serge 1481
cairo_status_t
1482
_cairo_surface_flush (cairo_surface_t *surface, unsigned flags)
1483
{
1484
    /* update the current snapshots *before* the user updates the surface */
1485
    _cairo_surface_detach_snapshots (surface);
1486
    if (surface->snapshot_of != NULL)
1487
	_cairo_surface_detach_snapshot (surface);
1488
    _cairo_surface_detach_mime_data (surface);
1489
 
1490
    return __cairo_surface_flush (surface, flags);
1491
}
1492
 
1892 serge 1493
/**
1494
 * cairo_surface_flush:
1495
 * @surface: a #cairo_surface_t
1496
 *
1497
 * Do any pending drawing for the surface and also restore any
1498
 * temporary modifications cairo has made to the surface's
1499
 * state. This function must be called before switching from
1500
 * drawing on the surface with cairo to drawing on it directly
1501
 * with native APIs. If the surface doesn't support direct access,
1502
 * then this function does nothing.
3959 Serge 1503
 *
1504
 * Since: 1.0
1892 serge 1505
 **/
1506
void
1507
cairo_surface_flush (cairo_surface_t *surface)
1508
{
1509
    cairo_status_t status;
1510
 
1511
    if (surface->status)
1512
	return;
1513
 
1514
    if (surface->finished)
1515
	return;
1516
 
3959 Serge 1517
    status = _cairo_surface_flush (surface, 0);
1518
    if (unlikely (status))
1519
	_cairo_surface_set_error (surface, status);
1892 serge 1520
}
1521
slim_hidden_def (cairo_surface_flush);
1522
 
1523
/**
1524
 * cairo_surface_mark_dirty:
1525
 * @surface: a #cairo_surface_t
1526
 *
1527
 * Tells cairo that drawing has been done to surface using means other
1528
 * than cairo, and that cairo should reread any cached areas. Note
1529
 * that you must call cairo_surface_flush() before doing such drawing.
3959 Serge 1530
 *
1531
 * Since: 1.0
1532
 **/
1892 serge 1533
void
1534
cairo_surface_mark_dirty (cairo_surface_t *surface)
1535
{
3959 Serge 1536
    cairo_rectangle_int_t extents;
1537
 
1538
    if (unlikely (surface->status))
1539
	return;
1540
    if (unlikely (surface->finished)) {
1541
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1542
	return;
1543
    }
1544
 
1545
    _cairo_surface_get_extents (surface, &extents);
1546
    cairo_surface_mark_dirty_rectangle (surface,
1547
					extents.x, extents.y,
1548
					extents.width, extents.height);
1892 serge 1549
}
1550
slim_hidden_def (cairo_surface_mark_dirty);
1551
 
1552
/**
1553
 * cairo_surface_mark_dirty_rectangle:
1554
 * @surface: a #cairo_surface_t
1555
 * @x: X coordinate of dirty rectangle
1556
 * @y: Y coordinate of dirty rectangle
1557
 * @width: width of dirty rectangle
1558
 * @height: height of dirty rectangle
1559
 *
1560
 * Like cairo_surface_mark_dirty(), but drawing has been done only to
1561
 * the specified rectangle, so that cairo can retain cached contents
1562
 * for other parts of the surface.
1563
 *
1564
 * Any cached clip set on the surface will be reset by this function,
1565
 * to make sure that future cairo calls have the clip set that they
1566
 * expect.
3959 Serge 1567
 *
1568
 * Since: 1.0
1569
 **/
1892 serge 1570
void
1571
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
1572
				    int              x,
1573
				    int              y,
1574
				    int              width,
1575
				    int              height)
1576
{
1577
    cairo_status_t status;
1578
 
3959 Serge 1579
    if (unlikely (surface->status))
1892 serge 1580
	return;
1581
 
1582
    assert (surface->snapshot_of == NULL);
1583
 
3959 Serge 1584
    if (unlikely (surface->finished)) {
1585
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 1586
	return;
1587
    }
1588
 
1589
    /* The application *should* have called cairo_surface_flush() before
1590
     * modifying the surface independently of cairo (and thus having to
1591
     * call mark_dirty()). */
1592
    assert (! _cairo_surface_has_snapshots (surface));
1593
    assert (! _cairo_surface_has_mime_data (surface));
1594
 
1595
    surface->is_clear = FALSE;
3959 Serge 1596
    surface->serial++;
1892 serge 1597
 
3959 Serge 1598
    if (surface->damage) {
1599
	cairo_box_t box;
1600
 
1601
	box.p1.x = x;
1602
	box.p1.y = y;
1603
	box.p2.x = x + width;
1604
	box.p2.y = y + height;
1605
 
1606
	surface->damage = _cairo_damage_add_box (surface->damage, &box);
1607
    }
1608
 
1892 serge 1609
    if (surface->backend->mark_dirty_rectangle != NULL) {
1610
	/* XXX: FRAGILE: We're ignoring the scaling component of
1611
	 * device_transform here. I don't know what the right thing to
1612
	 * do would actually be if there were some scaling here, but
1613
	 * we avoid this since device_transfom scaling is not exported
1614
	 * publicly and mark_dirty is not used internally. */
1615
	status = surface->backend->mark_dirty_rectangle (surface,
1616
                                                         x + surface->device_transform.x0,
1617
                                                         y + surface->device_transform.y0,
1618
							 width, height);
1619
 
1620
	if (unlikely (status))
3959 Serge 1621
	    _cairo_surface_set_error (surface, status);
1892 serge 1622
    }
1623
}
1624
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
1625
 
1626
/**
1627
 * _cairo_surface_set_device_scale:
1628
 * @surface: a #cairo_surface_t
1629
 * @sx: a scale factor in the X direction
1630
 * @sy: a scale factor in the Y direction
1631
 *
1632
 * Private function for setting an extra scale factor to affect all
1633
 * drawing to a surface. This is used, for example, when replaying a
1634
 * recording surface to an image fallback intended for an eventual
1635
 * vector-oriented backend. Since the recording surface will record
1636
 * coordinates in one backend space, but the image fallback uses a
1637
 * different backend space, (differing by the fallback resolution
1638
 * scale factors), we need a scale factor correction.
1639
 *
1640
 * Caution: Not all places we use device transform correctly handle
1641
 * both a translate and a scale.  An audit would be nice.
1642
 **/
1643
void
1644
_cairo_surface_set_device_scale (cairo_surface_t *surface,
1645
				 double		  sx,
1646
				 double		  sy)
1647
{
1648
    cairo_status_t status;
1649
 
3959 Serge 1650
    if (unlikely (surface->status))
1892 serge 1651
	return;
1652
 
1653
    assert (surface->snapshot_of == NULL);
1654
 
3959 Serge 1655
    if (unlikely (surface->finished)) {
1656
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 1657
	return;
1658
    }
1659
 
3959 Serge 1660
    status = _cairo_surface_begin_modification (surface);
1661
    if (unlikely (status)) {
1662
	_cairo_surface_set_error (surface, status);
1663
	return;
1664
    }
1892 serge 1665
 
1666
    surface->device_transform.xx = sx;
1667
    surface->device_transform.yy = sy;
1668
    surface->device_transform.xy = 0.0;
1669
    surface->device_transform.yx = 0.0;
1670
 
1671
    surface->device_transform_inverse = surface->device_transform;
1672
    status = cairo_matrix_invert (&surface->device_transform_inverse);
1673
    /* should always be invertible unless given pathological input */
1674
    assert (status == CAIRO_STATUS_SUCCESS);
1675
 
1676
    _cairo_observers_notify (&surface->device_transform_observers, surface);
1677
}
1678
 
1679
/**
1680
 * cairo_surface_set_device_offset:
1681
 * @surface: a #cairo_surface_t
1682
 * @x_offset: the offset in the X direction, in device units
1683
 * @y_offset: the offset in the Y direction, in device units
1684
 *
1685
 * Sets an offset that is added to the device coordinates determined
1686
 * by the CTM when drawing to @surface. One use case for this function
1687
 * is when we want to create a #cairo_surface_t that redirects drawing
1688
 * for a portion of an onscreen surface to an offscreen surface in a
1689
 * way that is completely invisible to the user of the cairo
1690
 * API. Setting a transformation via cairo_translate() isn't
1691
 * sufficient to do this, since functions like
1692
 * cairo_device_to_user() will expose the hidden offset.
1693
 *
1694
 * Note that the offset affects drawing to the surface as well as
1695
 * using the surface in a source pattern.
3959 Serge 1696
 *
1697
 * Since: 1.0
1892 serge 1698
 **/
1699
void
1700
cairo_surface_set_device_offset (cairo_surface_t *surface,
1701
				 double           x_offset,
1702
				 double           y_offset)
1703
{
1704
    cairo_status_t status;
1705
 
3959 Serge 1706
    if (unlikely (surface->status))
1892 serge 1707
	return;
1708
 
1709
    assert (surface->snapshot_of == NULL);
1710
 
3959 Serge 1711
    if (unlikely (surface->finished)) {
1712
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 1713
	return;
1714
    }
1715
 
3959 Serge 1716
    status = _cairo_surface_begin_modification (surface);
1717
    if (unlikely (status)) {
1718
	_cairo_surface_set_error (surface, status);
1719
	return;
1720
    }
1892 serge 1721
 
1722
    surface->device_transform.x0 = x_offset;
1723
    surface->device_transform.y0 = y_offset;
1724
 
1725
    surface->device_transform_inverse = surface->device_transform;
1726
    status = cairo_matrix_invert (&surface->device_transform_inverse);
1727
    /* should always be invertible unless given pathological input */
1728
    assert (status == CAIRO_STATUS_SUCCESS);
1729
 
1730
    _cairo_observers_notify (&surface->device_transform_observers, surface);
1731
}
1732
slim_hidden_def (cairo_surface_set_device_offset);
1733
 
1734
/**
1735
 * cairo_surface_get_device_offset:
1736
 * @surface: a #cairo_surface_t
1737
 * @x_offset: the offset in the X direction, in device units
1738
 * @y_offset: the offset in the Y direction, in device units
1739
 *
1740
 * This function returns the previous device offset set by
1741
 * cairo_surface_set_device_offset().
1742
 *
1743
 * Since: 1.2
1744
 **/
1745
void
1746
cairo_surface_get_device_offset (cairo_surface_t *surface,
1747
				 double          *x_offset,
1748
				 double          *y_offset)
1749
{
1750
    if (x_offset)
1751
	*x_offset = surface->device_transform.x0;
1752
    if (y_offset)
1753
	*y_offset = surface->device_transform.y0;
1754
}
1755
slim_hidden_def (cairo_surface_get_device_offset);
1756
 
1757
/**
1758
 * cairo_surface_set_fallback_resolution:
1759
 * @surface: a #cairo_surface_t
1760
 * @x_pixels_per_inch: horizontal setting for pixels per inch
1761
 * @y_pixels_per_inch: vertical setting for pixels per inch
1762
 *
1763
 * Set the horizontal and vertical resolution for image fallbacks.
1764
 *
1765
 * When certain operations aren't supported natively by a backend,
1766
 * cairo will fallback by rendering operations to an image and then
1767
 * overlaying that image onto the output. For backends that are
1768
 * natively vector-oriented, this function can be used to set the
1769
 * resolution used for these image fallbacks, (larger values will
1770
 * result in more detailed images, but also larger file sizes).
1771
 *
1772
 * Some examples of natively vector-oriented backends are the ps, pdf,
1773
 * and svg backends.
1774
 *
1775
 * For backends that are natively raster-oriented, image fallbacks are
1776
 * still possible, but they are always performed at the native
1777
 * device resolution. So this function has no effect on those
1778
 * backends.
1779
 *
1780
 * Note: The fallback resolution only takes effect at the time of
1781
 * completing a page (with cairo_show_page() or cairo_copy_page()) so
1782
 * there is currently no way to have more than one fallback resolution
1783
 * in effect on a single page.
1784
 *
1785
 * The default fallback resoultion is 300 pixels per inch in both
1786
 * dimensions.
1787
 *
1788
 * Since: 1.2
1789
 **/
1790
void
1791
cairo_surface_set_fallback_resolution (cairo_surface_t	*surface,
1792
				       double		 x_pixels_per_inch,
1793
				       double		 y_pixels_per_inch)
1794
{
1795
    cairo_status_t status;
1796
 
3959 Serge 1797
    if (unlikely (surface->status))
1892 serge 1798
	return;
1799
 
1800
    assert (surface->snapshot_of == NULL);
1801
 
3959 Serge 1802
    if (unlikely (surface->finished)) {
1803
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 1804
	return;
1805
    }
1806
 
1807
    if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) {
1808
	/* XXX Could delay raising the error until we fallback, but throwing
1809
	 * the error here means that we can catch the real culprit.
1810
	 */
3959 Serge 1811
	_cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX);
1892 serge 1812
	return;
1813
    }
1814
 
3959 Serge 1815
    status = _cairo_surface_begin_modification (surface);
1816
    if (unlikely (status)) {
1817
	_cairo_surface_set_error (surface, status);
1818
	return;
1819
    }
1892 serge 1820
 
1821
    surface->x_fallback_resolution = x_pixels_per_inch;
1822
    surface->y_fallback_resolution = y_pixels_per_inch;
1823
}
1824
slim_hidden_def (cairo_surface_set_fallback_resolution);
1825
 
1826
/**
1827
 * cairo_surface_get_fallback_resolution:
1828
 * @surface: a #cairo_surface_t
1829
 * @x_pixels_per_inch: horizontal pixels per inch
1830
 * @y_pixels_per_inch: vertical pixels per inch
1831
 *
1832
 * This function returns the previous fallback resolution set by
1833
 * cairo_surface_set_fallback_resolution(), or default fallback
1834
 * resolution if never set.
1835
 *
1836
 * Since: 1.8
1837
 **/
1838
void
1839
cairo_surface_get_fallback_resolution (cairo_surface_t	*surface,
1840
				       double		*x_pixels_per_inch,
1841
				       double		*y_pixels_per_inch)
1842
{
1843
    if (x_pixels_per_inch)
1844
	*x_pixels_per_inch = surface->x_fallback_resolution;
1845
    if (y_pixels_per_inch)
1846
	*y_pixels_per_inch = surface->y_fallback_resolution;
1847
}
1848
 
1849
cairo_bool_t
1850
_cairo_surface_has_device_transform (cairo_surface_t *surface)
1851
{
1852
    return ! _cairo_matrix_is_identity (&surface->device_transform);
1853
}
1854
 
1855
/**
1856
 * _cairo_surface_acquire_source_image:
1857
 * @surface: a #cairo_surface_t
1858
 * @image_out: location to store a pointer to an image surface that
1859
 *    has identical contents to @surface. This surface could be @surface
1860
 *    itself, a surface held internal to @surface, or it could be a new
1861
 *    surface with a copy of the relevant portion of @surface.
1862
 * @image_extra: location to store image specific backend data
1863
 *
1864
 * Gets an image surface to use when drawing as a fallback when drawing with
1865
 * @surface as a source. _cairo_surface_release_source_image() must be called
1866
 * when finished.
1867
 *
1868
 * Return value: %CAIRO_STATUS_SUCCESS if an image was stored in @image_out.
1869
 * %CAIRO_INT_STATUS_UNSUPPORTED if an image cannot be retrieved for the specified
1870
 * surface. Or %CAIRO_STATUS_NO_MEMORY.
1871
 **/
1872
cairo_status_t
1873
_cairo_surface_acquire_source_image (cairo_surface_t         *surface,
1874
				     cairo_image_surface_t  **image_out,
1875
				     void                   **image_extra)
1876
{
1877
    cairo_status_t status;
1878
 
3959 Serge 1879
    if (unlikely (surface->status))
1892 serge 1880
	return surface->status;
1881
 
1882
    assert (!surface->finished);
1883
 
1884
    if (surface->backend->acquire_source_image == NULL)
1885
	return CAIRO_INT_STATUS_UNSUPPORTED;
1886
 
1887
    status = surface->backend->acquire_source_image (surface,
1888
						     image_out, image_extra);
1889
    if (unlikely (status))
1890
	return _cairo_surface_set_error (surface, status);
1891
 
1892
    _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
1893
 
1894
    return CAIRO_STATUS_SUCCESS;
1895
}
1896
 
3959 Serge 1897
cairo_status_t
1898
_cairo_surface_default_acquire_source_image (void                    *_surface,
1899
					     cairo_image_surface_t  **image_out,
1900
					     void                   **image_extra)
1901
{
1902
    cairo_surface_t *surface = _surface;
1903
    cairo_rectangle_int_t extents;
1904
 
1905
    if (unlikely (! surface->backend->get_extents (surface, &extents)))
1906
	return _cairo_error (CAIRO_STATUS_INVALID_SIZE);
1907
 
1908
    *image_out = _cairo_surface_map_to_image (surface, &extents);
1909
    *image_extra = NULL;
1910
    return (*image_out)->base.status;
1911
}
1912
 
1892 serge 1913
/**
1914
 * _cairo_surface_release_source_image:
1915
 * @surface: a #cairo_surface_t
1916
 * @image_extra: same as return from the matching _cairo_surface_acquire_source_image()
1917
 *
1918
 * Releases any resources obtained with _cairo_surface_acquire_source_image()
1919
 **/
1920
void
1921
_cairo_surface_release_source_image (cairo_surface_t        *surface,
1922
				     cairo_image_surface_t  *image,
1923
				     void                   *image_extra)
1924
{
1925
    assert (!surface->finished);
1926
 
1927
    if (surface->backend->release_source_image)
1928
	surface->backend->release_source_image (surface, image, image_extra);
1929
}
1930
 
1931
void
3959 Serge 1932
_cairo_surface_default_release_source_image (void                   *surface,
1933
					     cairo_image_surface_t  *image,
1934
					     void                   *image_extra)
1892 serge 1935
{
3959 Serge 1936
    cairo_status_t ignored;
1892 serge 1937
 
3959 Serge 1938
    ignored = _cairo_surface_unmap_image (surface, image);
1939
    (void)ignored;
1892 serge 1940
}
1941
 
1942
 
3959 Serge 1943
cairo_surface_t *
1944
_cairo_surface_get_source (cairo_surface_t *surface,
1945
			   cairo_rectangle_int_t *extents)
1892 serge 1946
{
3959 Serge 1947
    assert (surface->backend->source);
1948
    return surface->backend->source (surface, extents);
1892 serge 1949
}
1950
 
3959 Serge 1951
cairo_surface_t *
1952
_cairo_surface_default_source (void *surface,
1953
			       cairo_rectangle_int_t *extents)
1892 serge 1954
{
3959 Serge 1955
    if (extents)
1956
	_cairo_surface_get_extents(surface, extents);
1957
    return surface;
1892 serge 1958
}
1959
 
1960
static cairo_status_t
1961
_pattern_has_error (const cairo_pattern_t *pattern)
1962
{
1963
    const cairo_surface_pattern_t *spattern;
1964
 
1965
    if (unlikely (pattern->status))
1966
	return pattern->status;
1967
 
1968
    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
1969
	return CAIRO_STATUS_SUCCESS;
1970
 
1971
    spattern = (const cairo_surface_pattern_t *) pattern;
1972
    if (unlikely (spattern->surface->status))
1973
	return spattern->surface->status;
1974
 
1975
    if (unlikely (spattern->surface->finished))
1976
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
1977
 
1978
    return CAIRO_STATUS_SUCCESS;
1979
}
1980
 
3959 Serge 1981
static cairo_bool_t
1982
nothing_to_do (cairo_surface_t *surface,
1983
	       cairo_operator_t op,
1984
	       const cairo_pattern_t *source)
1985
{
1986
    if (_cairo_pattern_is_clear (source)) {
1987
	if (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD)
1988
	    return TRUE;
1989
 
1990
	if (op == CAIRO_OPERATOR_SOURCE)
1991
	    op = CAIRO_OPERATOR_CLEAR;
1992
    }
1993
 
1994
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
1995
	return TRUE;
1996
 
1997
    if (op == CAIRO_OPERATOR_ATOP && (surface->content & CAIRO_CONTENT_COLOR) ==0)
1998
	return TRUE;
1999
 
2000
    return FALSE;
2001
}
2002
 
1892 serge 2003
cairo_status_t
3959 Serge 2004
_cairo_surface_paint (cairo_surface_t		*surface,
2005
		      cairo_operator_t		 op,
2006
		      const cairo_pattern_t	*source,
2007
		      const cairo_clip_t	*clip)
1892 serge 2008
{
3959 Serge 2009
    cairo_int_status_t status;
1892 serge 2010
 
3959 Serge 2011
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2012
    if (unlikely (surface->status))
2013
	return surface->status;
3959 Serge 2014
    if (unlikely (surface->finished))
2015
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2016
 
3959 Serge 2017
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2018
	return CAIRO_STATUS_SUCCESS;
2019
 
3959 Serge 2020
    status = _pattern_has_error (source);
2021
    if (unlikely (status))
2022
	return status;
1892 serge 2023
 
3959 Serge 2024
    if (nothing_to_do (surface, op, source))
1892 serge 2025
	return CAIRO_STATUS_SUCCESS;
2026
 
3959 Serge 2027
    status = _cairo_surface_begin_modification (surface);
1892 serge 2028
    if (unlikely (status))
2029
	return status;
2030
 
3959 Serge 2031
    status = surface->backend->paint (surface, op, source, clip);
2032
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2033
	surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
2034
	surface->serial++;
1892 serge 2035
    }
2036
 
2037
    return _cairo_surface_set_error (surface, status);
2038
}
2039
 
2040
cairo_status_t
2041
_cairo_surface_mask (cairo_surface_t		*surface,
2042
		     cairo_operator_t		 op,
2043
		     const cairo_pattern_t	*source,
2044
		     const cairo_pattern_t	*mask,
3959 Serge 2045
		     const cairo_clip_t		*clip)
1892 serge 2046
{
3959 Serge 2047
    cairo_int_status_t status;
1892 serge 2048
 
3959 Serge 2049
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2050
    if (unlikely (surface->status))
2051
	return surface->status;
3959 Serge 2052
    if (unlikely (surface->finished))
2053
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2054
 
3959 Serge 2055
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2056
	return CAIRO_STATUS_SUCCESS;
2057
 
2058
    /* If the mask is blank, this is just an expensive no-op */
2059
    if (_cairo_pattern_is_clear (mask) &&
2060
	_cairo_operator_bounded_by_mask (op))
2061
    {
2062
	return CAIRO_STATUS_SUCCESS;
2063
    }
2064
 
2065
    status = _pattern_has_error (source);
2066
    if (unlikely (status))
2067
	return status;
2068
 
2069
    status = _pattern_has_error (mask);
2070
    if (unlikely (status))
2071
	return status;
2072
 
3959 Serge 2073
    if (nothing_to_do (surface, op, source))
2074
	return CAIRO_STATUS_SUCCESS;
1892 serge 2075
 
3959 Serge 2076
    status = _cairo_surface_begin_modification (surface);
2077
    if (unlikely (status))
2078
	return status;
2079
 
2080
    status = surface->backend->mask (surface, op, source, mask, clip);
2081
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2082
	surface->is_clear = FALSE;
2083
	surface->serial++;
1892 serge 2084
    }
2085
 
2086
    return _cairo_surface_set_error (surface, status);
2087
}
2088
 
2089
cairo_status_t
2090
_cairo_surface_fill_stroke (cairo_surface_t	    *surface,
2091
			    cairo_operator_t	     fill_op,
2092
			    const cairo_pattern_t   *fill_source,
2093
			    cairo_fill_rule_t	     fill_rule,
2094
			    double		     fill_tolerance,
2095
			    cairo_antialias_t	     fill_antialias,
2096
			    cairo_path_fixed_t	    *path,
2097
			    cairo_operator_t	     stroke_op,
2098
			    const cairo_pattern_t   *stroke_source,
2099
			    const cairo_stroke_style_t    *stroke_style,
2100
			    const cairo_matrix_t	    *stroke_ctm,
2101
			    const cairo_matrix_t	    *stroke_ctm_inverse,
2102
			    double		     stroke_tolerance,
2103
			    cairo_antialias_t	     stroke_antialias,
3959 Serge 2104
			    const cairo_clip_t	    *clip)
1892 serge 2105
{
3959 Serge 2106
    cairo_int_status_t status;
1892 serge 2107
 
3959 Serge 2108
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2109
    if (unlikely (surface->status))
2110
	return surface->status;
3959 Serge 2111
    if (unlikely (surface->finished))
2112
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2113
 
3959 Serge 2114
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2115
	return CAIRO_STATUS_SUCCESS;
2116
 
2117
    if (surface->is_clear &&
2118
	fill_op == CAIRO_OPERATOR_CLEAR &&
2119
	stroke_op == CAIRO_OPERATOR_CLEAR)
2120
    {
2121
	return CAIRO_STATUS_SUCCESS;
2122
    }
2123
 
2124
    status = _pattern_has_error (fill_source);
2125
    if (unlikely (status))
2126
	return status;
2127
 
2128
    status = _pattern_has_error (stroke_source);
2129
    if (unlikely (status))
2130
	return status;
2131
 
3959 Serge 2132
    status = _cairo_surface_begin_modification (surface);
2133
    if (unlikely (status))
2134
	return status;
1892 serge 2135
 
2136
    if (surface->backend->fill_stroke) {
2137
	cairo_matrix_t dev_ctm = *stroke_ctm;
2138
	cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
2139
 
2140
	status = surface->backend->fill_stroke (surface,
2141
						fill_op, fill_source, fill_rule,
2142
						fill_tolerance, fill_antialias,
2143
						path,
2144
						stroke_op, stroke_source,
2145
						stroke_style,
2146
						&dev_ctm, &dev_ctm_inverse,
2147
						stroke_tolerance, stroke_antialias,
2148
						clip);
2149
 
2150
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
2151
	    goto FINISH;
2152
    }
2153
 
2154
    status = _cairo_surface_fill (surface, fill_op, fill_source, path,
2155
				  fill_rule, fill_tolerance, fill_antialias,
2156
				  clip);
2157
    if (unlikely (status))
2158
	goto FINISH;
2159
 
2160
    status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path,
2161
				    stroke_style, stroke_ctm, stroke_ctm_inverse,
2162
				    stroke_tolerance, stroke_antialias,
2163
				    clip);
2164
    if (unlikely (status))
2165
	goto FINISH;
2166
 
2167
  FINISH:
3959 Serge 2168
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2169
	surface->is_clear = FALSE;
2170
	surface->serial++;
2171
    }
1892 serge 2172
 
2173
    return _cairo_surface_set_error (surface, status);
2174
}
2175
 
2176
cairo_status_t
3959 Serge 2177
_cairo_surface_stroke (cairo_surface_t			*surface,
2178
		       cairo_operator_t			 op,
2179
		       const cairo_pattern_t		*source,
2180
		       const cairo_path_fixed_t		*path,
1892 serge 2181
		       const cairo_stroke_style_t	*stroke_style,
2182
		       const cairo_matrix_t		*ctm,
2183
		       const cairo_matrix_t		*ctm_inverse,
3959 Serge 2184
		       double				 tolerance,
2185
		       cairo_antialias_t		 antialias,
2186
		       const cairo_clip_t		*clip)
1892 serge 2187
{
3959 Serge 2188
    cairo_int_status_t status;
1892 serge 2189
 
3959 Serge 2190
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2191
    if (unlikely (surface->status))
2192
	return surface->status;
3959 Serge 2193
    if (unlikely (surface->finished))
2194
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2195
 
3959 Serge 2196
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2197
	return CAIRO_STATUS_SUCCESS;
2198
 
3959 Serge 2199
    status = _pattern_has_error (source);
2200
    if (unlikely (status))
2201
	return status;
1892 serge 2202
 
3959 Serge 2203
    if (nothing_to_do (surface, op, source))
1892 serge 2204
	return CAIRO_STATUS_SUCCESS;
2205
 
3959 Serge 2206
    status = _cairo_surface_begin_modification (surface);
1892 serge 2207
    if (unlikely (status))
2208
	return status;
2209
 
3959 Serge 2210
    status = surface->backend->stroke (surface, op, source,
2211
				       path, stroke_style,
2212
				       ctm, ctm_inverse,
2213
				       tolerance, antialias,
2214
				       clip);
2215
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2216
	surface->is_clear = FALSE;
2217
	surface->serial++;
1892 serge 2218
    }
2219
 
2220
    return _cairo_surface_set_error (surface, status);
2221
}
2222
 
2223
cairo_status_t
3959 Serge 2224
_cairo_surface_fill (cairo_surface_t		*surface,
2225
		     cairo_operator_t		 op,
2226
		     const cairo_pattern_t	 *source,
2227
		     const cairo_path_fixed_t	*path,
2228
		     cairo_fill_rule_t		 fill_rule,
2229
		     double			 tolerance,
2230
		     cairo_antialias_t		 antialias,
2231
		     const cairo_clip_t		*clip)
1892 serge 2232
{
3959 Serge 2233
    cairo_int_status_t status;
1892 serge 2234
 
3959 Serge 2235
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2236
    if (unlikely (surface->status))
2237
	return surface->status;
3959 Serge 2238
    if (unlikely (surface->finished))
2239
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2240
 
3959 Serge 2241
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2242
	return CAIRO_STATUS_SUCCESS;
2243
 
3959 Serge 2244
    status = _pattern_has_error (source);
2245
    if (unlikely (status))
2246
	return status;
1892 serge 2247
 
3959 Serge 2248
    if (nothing_to_do (surface, op, source))
1892 serge 2249
	return CAIRO_STATUS_SUCCESS;
2250
 
3959 Serge 2251
    status = _cairo_surface_begin_modification (surface);
1892 serge 2252
    if (unlikely (status))
2253
	return status;
2254
 
3959 Serge 2255
    status = surface->backend->fill (surface, op, source,
2256
				     path, fill_rule,
2257
				     tolerance, antialias,
2258
				     clip);
2259
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2260
	surface->is_clear = FALSE;
2261
	surface->serial++;
1892 serge 2262
    }
2263
 
2264
    return _cairo_surface_set_error (surface, status);
2265
}
2266
 
2267
/**
2268
 * cairo_surface_copy_page:
2269
 * @surface: a #cairo_surface_t
2270
 *
2271
 * Emits the current page for backends that support multiple pages,
2272
 * but doesn't clear it, so that the contents of the current page will
2273
 * be retained for the next page.  Use cairo_surface_show_page() if you
2274
 * want to get an empty page after the emission.
2275
 *
2276
 * There is a convenience function for this that takes a #cairo_t,
2277
 * namely cairo_copy_page().
2278
 *
2279
 * Since: 1.6
3959 Serge 2280
 **/
1892 serge 2281
void
2282
cairo_surface_copy_page (cairo_surface_t *surface)
2283
{
3959 Serge 2284
    if (unlikely (surface->status))
1892 serge 2285
	return;
2286
 
2287
    assert (surface->snapshot_of == NULL);
2288
 
3959 Serge 2289
    if (unlikely (surface->finished)) {
2290
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
1892 serge 2291
	return;
2292
    }
2293
 
2294
    /* It's fine if some backends don't implement copy_page */
2295
    if (surface->backend->copy_page == NULL)
2296
	return;
2297
 
3959 Serge 2298
    _cairo_surface_set_error (surface, surface->backend->copy_page (surface));
1892 serge 2299
}
2300
slim_hidden_def (cairo_surface_copy_page);
2301
 
2302
/**
2303
 * cairo_surface_show_page:
2304
 * @surface: a #cairo_Surface_t
2305
 *
2306
 * Emits and clears the current page for backends that support multiple
2307
 * pages.  Use cairo_surface_copy_page() if you don't want to clear the page.
2308
 *
2309
 * There is a convenience function for this that takes a #cairo_t,
2310
 * namely cairo_show_page().
2311
 *
2312
 * Since: 1.6
2313
 **/
2314
void
2315
cairo_surface_show_page (cairo_surface_t *surface)
2316
{
3959 Serge 2317
    cairo_status_t status;
1892 serge 2318
 
3959 Serge 2319
    if (unlikely (surface->status))
1892 serge 2320
	return;
2321
 
3959 Serge 2322
    if (unlikely (surface->finished)) {
2323
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
1892 serge 2324
	return;
2325
    }
2326
 
3959 Serge 2327
    status = _cairo_surface_begin_modification (surface);
2328
    if (unlikely (status)) {
2329
	_cairo_surface_set_error (surface, status);
2330
	return;
2331
    }
1892 serge 2332
 
2333
    /* It's fine if some backends don't implement show_page */
2334
    if (surface->backend->show_page == NULL)
2335
	return;
2336
 
3959 Serge 2337
    _cairo_surface_set_error (surface, surface->backend->show_page (surface));
1892 serge 2338
}
2339
slim_hidden_def (cairo_surface_show_page);
2340
 
2341
/**
2342
 * _cairo_surface_get_extents:
2343
 * @surface: the #cairo_surface_t to fetch extents for
2344
 *
2345
 * This function returns a bounding box for the surface.  The surface
2346
 * bounds are defined as a region beyond which no rendering will
2347
 * possibly be recorded, in other words, it is the maximum extent of
2348
 * potentially usable coordinates.
2349
 *
2350
 * For vector surfaces, (PDF, PS, SVG and recording-surfaces), the surface
2351
 * might be conceived as unbounded, but we force the user to provide a
2352
 * maximum size at the time of surface_create. So get_extents uses
2353
 * that size.
2354
 *
2355
 * Note: The coordinates returned are in "backend" space rather than
2356
 * "surface" space. That is, they are relative to the true (0,0)
2357
 * origin rather than the device_transform origin. This might seem a
2358
 * bit inconsistent with other #cairo_surface_t interfaces, but all
2359
 * current callers are within the surface layer where backend space is
2360
 * desired.
2361
 *
2362
 * This behavior would have to be changed is we ever exported a public
2363
 * variant of this function.
3959 Serge 2364
 **/
1892 serge 2365
cairo_bool_t
2366
_cairo_surface_get_extents (cairo_surface_t         *surface,
2367
			    cairo_rectangle_int_t   *extents)
2368
{
2369
    cairo_bool_t bounded;
2370
 
3959 Serge 2371
    if (unlikely (surface->status))
2372
	goto zero_extents;
2373
    if (unlikely (surface->finished)) {
2374
	_cairo_surface_set_error(surface, CAIRO_STATUS_SURFACE_FINISHED);
2375
	goto zero_extents;
2376
    }
2377
 
1892 serge 2378
    bounded = FALSE;
2379
    if (surface->backend->get_extents != NULL)
2380
	bounded = surface->backend->get_extents (surface, extents);
2381
 
2382
    if (! bounded)
2383
	_cairo_unbounded_rectangle_init (extents);
2384
 
2385
    return bounded;
3959 Serge 2386
 
2387
zero_extents:
2388
    extents->x = extents->y = 0;
2389
    extents->width = extents->height = 0;
2390
    return TRUE;
1892 serge 2391
}
2392
 
2393
/**
2394
 * cairo_surface_has_show_text_glyphs:
2395
 * @surface: a #cairo_surface_t
2396
 *
2397
 * Returns whether the surface supports
2398
 * sophisticated cairo_show_text_glyphs() operations.  That is,
2399
 * whether it actually uses the provided text and cluster data
2400
 * to a cairo_show_text_glyphs() call.
2401
 *
2402
 * Note: Even if this function returns %FALSE, a
2403
 * cairo_show_text_glyphs() operation targeted at @surface will
2404
 * still succeed.  It just will
2405
 * act like a cairo_show_glyphs() operation.  Users can use this
2406
 * function to avoid computing UTF-8 text and cluster mapping if the
2407
 * target surface does not use it.
2408
 *
2409
 * Return value: %TRUE if @surface supports
2410
 *               cairo_show_text_glyphs(), %FALSE otherwise
2411
 *
2412
 * Since: 1.8
2413
 **/
2414
cairo_bool_t
2415
cairo_surface_has_show_text_glyphs (cairo_surface_t	    *surface)
2416
{
3959 Serge 2417
    if (unlikely (surface->status))
1892 serge 2418
	return FALSE;
2419
 
3959 Serge 2420
    if (unlikely (surface->finished)) {
2421
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
1892 serge 2422
	return FALSE;
2423
    }
2424
 
2425
    if (surface->backend->has_show_text_glyphs)
2426
	return surface->backend->has_show_text_glyphs (surface);
2427
    else
2428
	return surface->backend->show_text_glyphs != NULL;
2429
}
2430
slim_hidden_def (cairo_surface_has_show_text_glyphs);
2431
 
2432
/* Note: the backends may modify the contents of the glyph array as long as
2433
 * they do not return %CAIRO_INT_STATUS_UNSUPPORTED. This makes it possible to
2434
 * avoid copying the array again and again, and edit it in-place.
2435
 * Backends are in fact free to use the array as a generic buffer as they
2436
 * see fit.
2437
 *
2438
 * For show_glyphs backend method, and NOT for show_text_glyphs method,
2439
 * when they do return UNSUPPORTED, they may adjust remaining_glyphs to notify
2440
 * that they have successfully rendered some of the glyphs (from the beginning
2441
 * of the array), but not all.  If they don't touch remaining_glyphs, it
2442
 * defaults to all glyphs.
2443
 *
2444
 * See commits 5a9642c5746fd677aed35ce620ce90b1029b1a0c and
2445
 * 1781e6018c17909311295a9cc74b70500c6b4d0a for the rationale.
2446
 */
2447
cairo_status_t
2448
_cairo_surface_show_text_glyphs (cairo_surface_t	    *surface,
2449
				 cairo_operator_t	     op,
2450
				 const cairo_pattern_t	    *source,
2451
				 const char		    *utf8,
2452
				 int			     utf8_len,
2453
				 cairo_glyph_t		    *glyphs,
2454
				 int			     num_glyphs,
2455
				 const cairo_text_cluster_t *clusters,
2456
				 int			     num_clusters,
2457
				 cairo_text_cluster_flags_t  cluster_flags,
2458
				 cairo_scaled_font_t	    *scaled_font,
3959 Serge 2459
				 const cairo_clip_t		*clip)
1892 serge 2460
{
3959 Serge 2461
    cairo_int_status_t status;
1892 serge 2462
    cairo_scaled_font_t *dev_scaled_font = scaled_font;
2463
 
3959 Serge 2464
    TRACE ((stderr, "%s\n", __FUNCTION__));
1892 serge 2465
    if (unlikely (surface->status))
2466
	return surface->status;
3959 Serge 2467
    if (unlikely (surface->finished))
2468
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1892 serge 2469
 
2470
    if (num_glyphs == 0 && utf8_len == 0)
2471
	return CAIRO_STATUS_SUCCESS;
2472
 
3959 Serge 2473
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 2474
	return CAIRO_STATUS_SUCCESS;
2475
 
3959 Serge 2476
    status = _pattern_has_error (source);
2477
    if (unlikely (status))
2478
	return status;
2479
 
2480
    if (nothing_to_do (surface, op, source))
1892 serge 2481
	return CAIRO_STATUS_SUCCESS;
2482
 
3959 Serge 2483
    status = _cairo_surface_begin_modification (surface);
1892 serge 2484
    if (unlikely (status))
2485
	return status;
2486
 
2487
    if (_cairo_surface_has_device_transform (surface) &&
2488
	! _cairo_matrix_is_integer_translation (&surface->device_transform, NULL, NULL))
2489
    {
2490
	cairo_font_options_t font_options;
2491
	cairo_matrix_t dev_ctm, font_matrix;
2492
 
2493
	cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix);
2494
	cairo_scaled_font_get_ctm (scaled_font, &dev_ctm);
2495
	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &surface->device_transform);
2496
	cairo_scaled_font_get_font_options (scaled_font, &font_options);
2497
	dev_scaled_font = cairo_scaled_font_create (cairo_scaled_font_get_font_face (scaled_font),
2498
						    &font_matrix,
2499
						    &dev_ctm,
2500
						    &font_options);
2501
    }
2502
    status = cairo_scaled_font_status (dev_scaled_font);
2503
    if (unlikely (status))
2504
	return _cairo_surface_set_error (surface, status);
2505
 
2506
    status = CAIRO_INT_STATUS_UNSUPPORTED;
2507
 
2508
    /* The logic here is duplicated in _cairo_analysis_surface show_glyphs and
2509
     * show_text_glyphs.  Keep in synch. */
2510
    if (clusters) {
2511
	/* A real show_text_glyphs call.  Try show_text_glyphs backend
2512
	 * method first */
2513
	if (surface->backend->show_text_glyphs != NULL) {
2514
	    status = surface->backend->show_text_glyphs (surface, op,
2515
							 source,
2516
							 utf8, utf8_len,
2517
							 glyphs, num_glyphs,
2518
							 clusters, num_clusters, cluster_flags,
2519
							 dev_scaled_font,
2520
							 clip);
2521
	}
2522
	if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
2523
	    surface->backend->show_glyphs)
2524
	{
2525
	    status = surface->backend->show_glyphs (surface, op,
2526
						    source,
2527
						    glyphs, num_glyphs,
2528
						    dev_scaled_font,
3959 Serge 2529
						    clip);
1892 serge 2530
	}
2531
    } else {
2532
	/* A mere show_glyphs call.  Try show_glyphs backend method first */
2533
	if (surface->backend->show_glyphs != NULL) {
2534
	    status = surface->backend->show_glyphs (surface, op,
2535
						    source,
2536
						    glyphs, num_glyphs,
2537
						    dev_scaled_font,
3959 Serge 2538
						    clip);
1892 serge 2539
	} else if (surface->backend->show_text_glyphs != NULL) {
2540
	    /* Intentionally only try show_text_glyphs method for show_glyphs
2541
	     * calls if backend does not have show_glyphs.  If backend has
2542
	     * both methods implemented, we don't fallback from show_glyphs to
2543
	     * show_text_glyphs, and hence the backend can assume in its
2544
	     * show_text_glyphs call that clusters is not NULL (which also
2545
	     * implies that UTF-8 is not NULL, unless the text is
2546
	     * zero-length).
2547
	     */
2548
	    status = surface->backend->show_text_glyphs (surface, op,
2549
							 source,
2550
							 utf8, utf8_len,
2551
							 glyphs, num_glyphs,
2552
							 clusters, num_clusters, cluster_flags,
2553
							 dev_scaled_font,
2554
							 clip);
2555
	}
2556
    }
2557
 
2558
    if (dev_scaled_font != scaled_font)
2559
	cairo_scaled_font_destroy (dev_scaled_font);
2560
 
3959 Serge 2561
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2562
	surface->is_clear = FALSE;
2563
	surface->serial++;
2564
    }
1892 serge 2565
 
2566
    return _cairo_surface_set_error (surface, status);
2567
}
2568
 
2569
/**
3959 Serge 2570
 * _cairo_surface_set_resolution:
1892 serge 2571
 * @surface: the surface
2572
 * @x_res: x resolution, in dpi
2573
 * @y_res: y resolution, in dpi
2574
 *
2575
 * Set the actual surface resolution of @surface to the given x and y DPI.
2576
 * Mainly used for correctly computing the scale factor when fallback
2577
 * rendering needs to take place in the paginated surface.
3959 Serge 2578
 **/
1892 serge 2579
void
2580
_cairo_surface_set_resolution (cairo_surface_t *surface,
2581
			       double x_res,
2582
			       double y_res)
2583
{
2584
    if (surface->status)
2585
	return;
2586
 
2587
    surface->x_resolution = x_res;
2588
    surface->y_resolution = y_res;
2589
}
2590
 
2591
cairo_surface_t *
2592
_cairo_surface_create_in_error (cairo_status_t status)
2593
{
3959 Serge 2594
    assert (status < CAIRO_STATUS_LAST_STATUS);
1892 serge 2595
    switch (status) {
2596
    case CAIRO_STATUS_NO_MEMORY:
2597
	return (cairo_surface_t *) &_cairo_surface_nil;
2598
    case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
2599
	return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch;
2600
    case CAIRO_STATUS_INVALID_STATUS:
2601
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_status;
2602
    case CAIRO_STATUS_INVALID_CONTENT:
2603
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_content;
2604
    case CAIRO_STATUS_INVALID_FORMAT:
2605
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_format;
2606
    case CAIRO_STATUS_INVALID_VISUAL:
2607
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_visual;
2608
    case CAIRO_STATUS_READ_ERROR:
2609
	return (cairo_surface_t *) &_cairo_surface_nil_read_error;
2610
    case CAIRO_STATUS_WRITE_ERROR:
2611
	return (cairo_surface_t *) &_cairo_surface_nil_write_error;
2612
    case CAIRO_STATUS_FILE_NOT_FOUND:
2613
	return (cairo_surface_t *) &_cairo_surface_nil_file_not_found;
2614
    case CAIRO_STATUS_TEMP_FILE_ERROR:
2615
	return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error;
2616
    case CAIRO_STATUS_INVALID_STRIDE:
2617
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
2618
    case CAIRO_STATUS_INVALID_SIZE:
2619
	return (cairo_surface_t *) &_cairo_surface_nil_invalid_size;
2620
    case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
2621
	return (cairo_surface_t *) &_cairo_surface_nil_device_type_mismatch;
2622
    case CAIRO_STATUS_DEVICE_ERROR:
2623
	return (cairo_surface_t *) &_cairo_surface_nil_device_error;
2624
    case CAIRO_STATUS_SUCCESS:
2625
    case CAIRO_STATUS_LAST_STATUS:
2626
	ASSERT_NOT_REACHED;
2627
	/* fall-through */
2628
    case CAIRO_STATUS_INVALID_RESTORE:
2629
    case CAIRO_STATUS_INVALID_POP_GROUP:
2630
    case CAIRO_STATUS_NO_CURRENT_POINT:
2631
    case CAIRO_STATUS_INVALID_MATRIX:
2632
    case CAIRO_STATUS_NULL_POINTER:
2633
    case CAIRO_STATUS_INVALID_STRING:
2634
    case CAIRO_STATUS_INVALID_PATH_DATA:
2635
    case CAIRO_STATUS_SURFACE_FINISHED:
2636
    case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
2637
    case CAIRO_STATUS_INVALID_DASH:
2638
    case CAIRO_STATUS_INVALID_DSC_COMMENT:
2639
    case CAIRO_STATUS_INVALID_INDEX:
2640
    case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
2641
    case CAIRO_STATUS_FONT_TYPE_MISMATCH:
2642
    case CAIRO_STATUS_USER_FONT_IMMUTABLE:
2643
    case CAIRO_STATUS_USER_FONT_ERROR:
2644
    case CAIRO_STATUS_NEGATIVE_COUNT:
2645
    case CAIRO_STATUS_INVALID_CLUSTERS:
2646
    case CAIRO_STATUS_INVALID_SLANT:
2647
    case CAIRO_STATUS_INVALID_WEIGHT:
2648
    case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
3959 Serge 2649
    case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
2650
    case CAIRO_STATUS_DEVICE_FINISHED:
1892 serge 2651
    default:
2652
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2653
	return (cairo_surface_t *) &_cairo_surface_nil;
2654
    }
2655
}
2656
 
3959 Serge 2657
cairo_surface_t *
2658
_cairo_int_surface_create_in_error (cairo_int_status_t status)
2659
{
2660
    if (status < CAIRO_INT_STATUS_LAST_STATUS)
2661
	return _cairo_surface_create_in_error (status);
2662
 
2663
    switch ((int)status) {
2664
    case CAIRO_INT_STATUS_UNSUPPORTED:
2665
	return (cairo_surface_t *) &_cairo_surface_nil_unsupported;
2666
    case CAIRO_INT_STATUS_NOTHING_TO_DO:
2667
	return (cairo_surface_t *) &_cairo_surface_nil_nothing_to_do;
2668
    default:
2669
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2670
	return (cairo_surface_t *) &_cairo_surface_nil;
2671
    }
2672
}
2673
 
1892 serge 2674
/*  LocalWords:  rasterized
2675
 */