Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
Line 36... Line 36...
36
 *	Carl D. Worth 
36
 *	Carl D. Worth 
37
 */
37
 */
Line 38... Line 38...
38
 
38
 
Line 39... Line 39...
39
#include "cairoint.h"
39
#include "cairoint.h"
-
 
40
 
40
 
41
#include "cairo-array-private.h"
-
 
42
#include "cairo-clip-inline.h"
41
#include "cairo-surface-fallback-private.h"
43
#include "cairo-clip-private.h"
42
#include "cairo-clip-private.h"
44
#include "cairo-damage-private.h"
-
 
45
#include "cairo-device-private.h"
-
 
46
#include "cairo-error-private.h"
43
#include "cairo-device-private.h"
47
#include "cairo-list-inline.h"
44
#include "cairo-error-private.h"
48
#include "cairo-image-surface-inline.h"
-
 
49
#include "cairo-recording-surface-private.h"
45
#include "cairo-recording-surface-private.h"
50
#include "cairo-region-private.h"
Line 46... Line 51...
46
#include "cairo-region-private.h"
51
#include "cairo-surface-inline.h"
47
#include "cairo-tee-surface-private.h"
52
#include "cairo-tee-surface-private.h"
48
 
53
 
Line 56... Line 61...
56
 * targets that cairo can render to.  The actual drawings are
61
 * targets that cairo can render to.  The actual drawings are
57
 * performed using a cairo context.
62
 * performed using a cairo context.
58
 *
63
 *
59
 * A cairo surface is created by using backend-specific
64
 * A cairo surface is created by using backend-specific
60
 * constructors, typically of the form
65
 * constructors, typically of the form
61
 * cairo_backend_surface_create().
66
 * cairo_backend_surface_create().
62
 *
67
 *
63
 * Most surface types allow accessing the surface without using Cairo
68
 * Most surface types allow accessing the surface without using Cairo
64
 * functions. If you do this, keep in mind that it is mandatory that you call
69
 * functions. If you do this, keep in mind that it is mandatory that you call
65
 * cairo_surface_flush() before reading from or writing to the surface and that
70
 * cairo_surface_flush() before reading from or writing to the surface and that
66
 * you must use cairo_surface_mark_dirty() after modifying it.
71
 * you must use cairo_surface_mark_dirty() after modifying it.
Line 89... Line 94...
89
 * 
94
 * 
90
 * 
95
 * 
91
 * Note that for other surface types it might be necessary to acquire the
96
 * Note that for other surface types it might be necessary to acquire the
92
 * surface's device first. See cairo_device_acquire() for a discussion of
97
 * surface's device first. See cairo_device_acquire() for a discussion of
93
 * devices.
98
 * devices.
94
 */
99
 **/
Line 95... Line 100...
95
 
100
 
96
#define DEFINE_NIL_SURFACE(status, name)			\
101
#define DEFINE_NIL_SURFACE(status, name)			\
97
const cairo_surface_t name = {					\
102
const cairo_surface_t name = {					\
98
    NULL,				/* backend */		\
103
    NULL,				/* backend */		\
99
    NULL,				/* device */		\
104
    NULL,				/* device */		\
100
    CAIRO_SURFACE_TYPE_IMAGE,		/* type */		\
105
    CAIRO_SURFACE_TYPE_IMAGE,		/* type */		\
101
    CAIRO_CONTENT_COLOR,		/* content */		\
106
    CAIRO_CONTENT_COLOR,		/* content */		\
102
    CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */		\
107
    CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */		\
103
    status,				/* status */		\
108
    status,				/* status */		\
-
 
109
    0,					/* unique id */		\
-
 
110
    0,					/* serial */		\
-
 
111
    NULL,				/* damage */		\
104
    0,					/* unique id */		\
112
    FALSE,				/* _finishing */	\
105
    FALSE,				/* finished */		\
113
    FALSE,				/* finished */		\
106
    TRUE,				/* is_clear */		\
114
    TRUE,				/* is_clear */		\
107
    FALSE,				/* has_font_options */	\
115
    FALSE,				/* has_font_options */	\
108
    FALSE,				/* owns_device */	\
116
    FALSE,				/* owns_device */	\
Line 121... Line 129...
121
    { NULL, NULL },			/* snapshot */		\
129
    { NULL, NULL },			/* snapshot */		\
122
    { CAIRO_ANTIALIAS_DEFAULT,		/* antialias */		\
130
    { CAIRO_ANTIALIAS_DEFAULT,		/* antialias */		\
123
      CAIRO_SUBPIXEL_ORDER_DEFAULT,	/* subpixel_order */	\
131
      CAIRO_SUBPIXEL_ORDER_DEFAULT,	/* subpixel_order */	\
124
      CAIRO_LCD_FILTER_DEFAULT,		/* lcd_filter */	\
132
      CAIRO_LCD_FILTER_DEFAULT,		/* lcd_filter */	\
125
      CAIRO_HINT_STYLE_DEFAULT,		/* hint_style */	\
133
      CAIRO_HINT_STYLE_DEFAULT,		/* hint_style */	\
126
      CAIRO_HINT_METRICS_DEFAULT	/* hint_metrics */	\
134
      CAIRO_HINT_METRICS_DEFAULT,	/* hint_metrics */	\
-
 
135
      CAIRO_ROUND_GLYPH_POS_DEFAULT	/* round_glyph_positions */	\
127
    }					/* font_options */	\
136
    }					/* font_options */	\
128
}
137
}
Line 129... Line 138...
129
 
138
 
Line 142... Line 151...
142
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
151
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride);
143
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size);
152
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size);
144
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch);
153
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_TYPE_MISMATCH, _cairo_surface_nil_device_type_mismatch);
145
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error);
154
static DEFINE_NIL_SURFACE(CAIRO_STATUS_DEVICE_ERROR, _cairo_surface_nil_device_error);
Line -... Line 155...
-
 
155
 
-
 
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);
146
 
161
 
147
/**
162
/**
148
 * _cairo_surface_set_error:
163
 * _cairo_surface_set_error:
149
 * @surface: a surface
164
 * @surface: a surface
150
 * @status: a status value indicating an error
165
 * @status: a status value indicating an error
Line 162... Line 177...
162
 * breakpoint in _cairo_error() to generate a stack trace for when the
177
 * breakpoint in _cairo_error() to generate a stack trace for when the
163
 * user causes cairo to detect an error.
178
 * user causes cairo to detect an error.
164
 *
179
 *
165
 * Return value: the error status.
180
 * Return value: the error status.
166
 **/
181
 **/
167
cairo_status_t
182
cairo_int_status_t
168
_cairo_surface_set_error (cairo_surface_t *surface,
183
_cairo_surface_set_error (cairo_surface_t *surface,
169
			  cairo_status_t status)
184
			  cairo_int_status_t status)
170
{
185
{
-
 
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
     */
171
    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
189
    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
172
	status = CAIRO_STATUS_SUCCESS;
190
	status = CAIRO_INT_STATUS_SUCCESS;
Line -... Line 191...
-
 
191
 
173
 
192
    if (status == CAIRO_INT_STATUS_SUCCESS ||
174
    if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED)
193
        status >= (int)CAIRO_INT_STATUS_LAST_STATUS)
Line 175... Line 194...
175
	return status;
194
        return status;
176
 
195
 
177
    /* Don't overwrite an existing error. This preserves the first
196
    /* Don't overwrite an existing error. This preserves the first
Line 178... Line 197...
178
     * error, which is the most significant. */
197
     * error, which is the most significant. */
179
    _cairo_status_set_error (&surface->status, status);
198
    _cairo_status_set_error (&surface->status, (cairo_status_t)status);
Line 180... Line 199...
180
 
199
 
Line 199... Line 218...
199
     * special "wrapper" surfaces such as cairo_paginated_surface_t
218
     * special "wrapper" surfaces such as cairo_paginated_surface_t
200
     * can override surface->type with the type of the "child"
219
     * can override surface->type with the type of the "child"
201
     * surface. */
220
     * surface. */
202
    return surface->type;
221
    return surface->type;
203
}
222
}
204
slim_hidden_def (cairo_surface_get_type);
-
 
Line 205... Line 223...
205
 
223
 
206
/**
224
/**
207
 * cairo_surface_get_content:
225
 * cairo_surface_get_content:
208
 * @surface: a #cairo_surface_t
226
 * @surface: a #cairo_surface_t
Line 218... Line 236...
218
cairo_content_t
236
cairo_content_t
219
cairo_surface_get_content (cairo_surface_t *surface)
237
cairo_surface_get_content (cairo_surface_t *surface)
220
{
238
{
221
    return surface->content;
239
    return surface->content;
222
}
240
}
223
slim_hidden_def(cairo_surface_get_content);
-
 
Line 224... Line 241...
224
 
241
 
225
/**
242
/**
226
 * cairo_surface_status:
243
 * cairo_surface_status:
227
 * @surface: a #cairo_surface_t
244
 * @surface: a #cairo_surface_t
Line 231... Line 248...
231
 *
248
 *
232
 * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
249
 * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NULL_POINTER,
233
 * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
250
 * %CAIRO_STATUS_NO_MEMORY, %CAIRO_STATUS_READ_ERROR,
234
 * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
251
 * %CAIRO_STATUS_INVALID_CONTENT, %CAIRO_STATUS_INVALID_FORMAT, or
235
 * %CAIRO_STATUS_INVALID_VISUAL.
252
 * %CAIRO_STATUS_INVALID_VISUAL.
-
 
253
 *
-
 
254
 * Since: 1.0
236
 **/
255
 **/
237
cairo_status_t
256
cairo_status_t
238
cairo_surface_status (cairo_surface_t *surface)
257
cairo_surface_status (cairo_surface_t *surface)
239
{
258
{
240
    return surface->status;
259
    return surface->status;
Line 359... Line 378...
359
    cairo_surface_t *snapshot;
378
    cairo_surface_t *snapshot;
Line 360... Line 379...
360
 
379
 
361
    cairo_list_foreach_entry (snapshot, cairo_surface_t,
380
    cairo_list_foreach_entry (snapshot, cairo_surface_t,
362
			      &surface->snapshots, snapshot)
381
			      &surface->snapshots, snapshot)
363
    {
-
 
364
	/* XXX is_similar? */
382
    {
365
	if (snapshot->backend == backend)
383
	if (snapshot->backend == backend)
366
	    return snapshot;
384
	    return snapshot;
Line 367... Line 385...
367
    }
385
    }
368
 
386
 
Line 369... Line 387...
369
    return NULL;
387
    return NULL;
370
}
-
 
371
 
-
 
372
static cairo_bool_t
-
 
373
_cairo_surface_is_writable (cairo_surface_t *surface)
-
 
374
{
-
 
375
    return ! surface->finished &&
-
 
376
	   surface->snapshot_of == NULL &&
-
 
377
	   ! _cairo_surface_has_snapshots (surface) &&
-
 
378
	   ! _cairo_surface_has_mime_data (surface);
-
 
379
}
388
}
380
 
389
 
381
static void
390
cairo_status_t
382
_cairo_surface_begin_modification (cairo_surface_t *surface)
391
_cairo_surface_begin_modification (cairo_surface_t *surface)
383
{
-
 
Line 384... Line 392...
384
    assert (surface->status == CAIRO_STATUS_SUCCESS);
392
{
385
    assert (! surface->finished);
-
 
386
    assert (surface->snapshot_of == NULL);
393
    assert (surface->status == CAIRO_STATUS_SUCCESS);
Line 387... Line 394...
387
 
394
    assert (! surface->finished);
388
    _cairo_surface_detach_snapshots (surface);
395
 
389
    _cairo_surface_detach_mime_data (surface);
396
    return _cairo_surface_flush (surface, 1);
Line 404... Line 411...
404
 
411
 
405
    CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
412
    CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
406
    surface->status = CAIRO_STATUS_SUCCESS;
413
    surface->status = CAIRO_STATUS_SUCCESS;
407
    surface->unique_id = _cairo_surface_allocate_unique_id ();
414
    surface->unique_id = _cairo_surface_allocate_unique_id ();
-
 
415
    surface->finished = FALSE;
408
    surface->finished = FALSE;
416
    surface->_finishing = FALSE;
-
 
417
    surface->is_clear = FALSE;
-
 
418
    surface->serial = 0;
409
    surface->is_clear = FALSE;
419
    surface->damage = NULL;
Line 410... Line 420...
410
    surface->owns_device = (device != NULL);
420
    surface->owns_device = (device != NULL);
411
 
421
 
Line 453... Line 463...
453
    cairo_surface_t *surface;
463
    cairo_surface_t *surface;
Line 454... Line 464...
454
 
464
 
455
    if (unlikely (other->status))
465
    if (unlikely (other->status))
Line -... Line 466...
-
 
466
	return _cairo_surface_create_in_error (other->status);
456
	return _cairo_surface_create_in_error (other->status);
467
 
-
 
468
    surface = NULL;
457
 
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,
Line 458... Line -...
458
    if (other->backend->create_similar == NULL)
-
 
459
	return NULL;
-
 
460
 
473
						      _cairo_format_from_content (content),
461
    surface = other->backend->create_similar (other,
474
						      width, height);
Line 462... Line 475...
462
					      content, width, height);
475
 
Line 463... Line 476...
463
    if (surface == NULL || surface->status)
476
    if (unlikely (surface->status))
Line 483... Line 496...
483
 * be examined with cairo_surface_get_type().
496
 * be examined with cairo_surface_get_type().
484
 *
497
 *
485
 * Initially the surface contents are all 0 (transparent if contents
498
 * Initially the surface contents are all 0 (transparent if contents
486
 * have transparency, black otherwise.)
499
 * have transparency, black otherwise.)
487
 *
500
 *
-
 
501
 * Use cairo_surface_create_similar_image() if you need an image surface
-
 
502
 * which can be painted quickly to the target surface.
-
 
503
 *
488
 * Return value: a pointer to the newly allocated surface. The caller
504
 * Return value: a pointer to the newly allocated surface. The caller
489
 * owns the surface and should call cairo_surface_destroy() when done
505
 * owns the surface and should call cairo_surface_destroy() when done
490
 * with it.
506
 * with it.
491
 *
507
 *
492
 * This function always returns a valid pointer, but it will return a
508
 * This function always returns a valid pointer, but it will return a
493
 * pointer to a "nil" surface if @other is already in an error state
509
 * pointer to a "nil" surface if @other is already in an error state
494
 * or any other error occurs.
510
 * or any other error occurs.
-
 
511
 *
-
 
512
 * Since: 1.0
495
 **/
513
 **/
496
cairo_surface_t *
514
cairo_surface_t *
497
cairo_surface_create_similar (cairo_surface_t  *other,
515
cairo_surface_create_similar (cairo_surface_t  *other,
498
			      cairo_content_t	content,
516
			      cairo_content_t	content,
499
			      int		width,
517
			      int		width,
500
			      int		height)
518
			      int		height)
501
{
519
{
-
 
520
    cairo_surface_t *surface;
-
 
521
 
502
    if (unlikely (other->status))
522
    if (unlikely (other->status))
503
	return _cairo_surface_create_in_error (other->status);
523
	return _cairo_surface_create_in_error (other->status);
504
    if (unlikely (other->finished))
524
    if (unlikely (other->finished))
505
	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
525
	return _cairo_surface_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
-
 
526
    if (unlikely (width < 0 || height < 0))
-
 
527
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE);
Line 506... Line 528...
506
 
528
 
507
    if (unlikely (! CAIRO_CONTENT_VALID (content)))
529
    if (unlikely (! CAIRO_CONTENT_VALID (content)))
Line 508... Line 530...
508
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT));
530
	return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_CONTENT);
509
 
531
 
510
    return _cairo_surface_create_similar_solid (other,
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;
-
 
538
}
-
 
539
 
-
 
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
 **/
-
 
566
cairo_surface_t *
-
 
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,
511
						content, width, height,
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);
512
						CAIRO_COLOR_TRANSPARENT,
850
    cairo_surface_finish (image);
Line 513... Line 851...
513
						TRUE);
851
    cairo_surface_destroy (image);
514
}
852
}
515
 
853
 
516
cairo_surface_t *
854
cairo_surface_t *
517
_cairo_surface_create_similar_solid (cairo_surface_t	 *other,
855
_cairo_surface_create_similar_solid (cairo_surface_t	 *other,
518
				     cairo_content_t	  content,
856
				     cairo_content_t	  content,
519
				     int		  width,
-
 
520
				     int		  height,
857
				     int		  width,
521
				     const cairo_color_t *color,
858
				     int		  height,
522
				     cairo_bool_t allow_fallback)
859
				     const cairo_color_t *color)
523
{
860
{
Line 524... Line 861...
524
    cairo_status_t status;
861
    cairo_status_t status;
525
    cairo_surface_t *surface;
862
    cairo_surface_t *surface;
526
    cairo_solid_pattern_t pattern;
-
 
527
 
-
 
528
    surface = _cairo_surface_create_similar_scratch (other, content,
-
 
529
						     width, height);
863
    cairo_solid_pattern_t pattern;
530
    if (surface == NULL && allow_fallback)
864
 
Line 531... Line 865...
531
	surface = _cairo_image_surface_create_with_content (content,
865
    surface = _cairo_surface_create_similar_scratch (other, content,
532
							    width, height);
866
						     width, height);
533
    if (surface == NULL || surface->status)
867
    if (unlikely (surface->status))
Line 544... Line 878...
544
    }
878
    }
Line 545... Line 879...
545
 
879
 
546
    return surface;
880
    return surface;
Line 547... Line -...
547
}
-
 
548
 
-
 
549
cairo_surface_t *
-
 
550
_cairo_surface_create_solid_pattern_surface (cairo_surface_t	   *other,
-
 
551
					     const cairo_solid_pattern_t *solid_pattern)
-
 
552
{
-
 
553
    if (other->backend->create_solid_pattern_surface != NULL) {
-
 
554
	cairo_surface_t *surface;
-
 
555
 
-
 
556
	surface = other->backend->create_solid_pattern_surface (other,
-
 
557
								solid_pattern);
-
 
558
	if (surface)
-
 
559
	    return surface;
-
 
560
    }
-
 
561
 
-
 
562
    return _cairo_surface_create_similar_solid (other,
-
 
563
						_cairo_color_get_content (&solid_pattern->color),
-
 
564
						1, 1,
-
 
565
						&solid_pattern->color,
-
 
566
						FALSE);
-
 
567
}
-
 
568
 
-
 
569
cairo_int_status_t
-
 
570
_cairo_surface_repaint_solid_pattern_surface (cairo_surface_t	    *other,
-
 
571
					      cairo_surface_t       *solid_surface,
-
 
572
					      const cairo_solid_pattern_t *solid_pattern)
-
 
573
{
-
 
574
    /* Solid pattern surface for these backends are special and not trivial
-
 
575
     * to repaint.  Skip repainting.
-
 
576
     *
-
 
577
     * This does not work optimally with things like analysis surface that
-
 
578
     * are proxies.  But returning UNSUPPORTED is *safe* as it only
-
 
579
     * disables some caching.
-
 
580
     */
-
 
581
    if (other->backend->create_solid_pattern_surface != NULL &&
-
 
582
	! other->backend->can_repaint_solid_pattern_surface (solid_surface,
-
 
583
							     solid_pattern))
-
 
584
    {
-
 
585
	return CAIRO_INT_STATUS_UNSUPPORTED;
-
 
586
    }
-
 
587
 
-
 
588
    return _cairo_surface_paint (solid_surface,
-
 
589
				 CAIRO_OPERATOR_SOURCE,
-
 
590
				 &solid_pattern->base,
-
 
591
				 NULL);
-
 
592
}
881
}
593
 
882
 
594
/**
883
/**
595
 * cairo_surface_reference:
884
 * cairo_surface_reference:
596
 * @surface: a #cairo_surface_t
885
 * @surface: a #cairo_surface_t
Line 601... Line 890...
601
 *
890
 *
602
 * The number of references to a #cairo_surface_t can be get using
891
 * The number of references to a #cairo_surface_t can be get using
603
 * cairo_surface_get_reference_count().
892
 * cairo_surface_get_reference_count().
604
 *
893
 *
605
 * Return value: the referenced #cairo_surface_t.
894
 * Return value: the referenced #cairo_surface_t.
-
 
895
 *
-
 
896
 * Since: 1.0
606
 **/
897
 **/
607
cairo_surface_t *
898
cairo_surface_t *
608
cairo_surface_reference (cairo_surface_t *surface)
899
cairo_surface_reference (cairo_surface_t *surface)
609
{
900
{
610
    if (surface == NULL ||
901
    if (surface == NULL ||
Line 624... Line 915...
624
 * @surface: a #cairo_surface_t
915
 * @surface: a #cairo_surface_t
625
 *
916
 *
626
 * Decreases the reference count on @surface by one. If the result is
917
 * Decreases the reference count on @surface by one. If the result is
627
 * zero, then @surface and all associated resources are freed.  See
918
 * zero, then @surface and all associated resources are freed.  See
628
 * cairo_surface_reference().
919
 * cairo_surface_reference().
-
 
920
 *
-
 
921
 * Since: 1.0
629
 **/
922
 **/
630
void
923
void
631
cairo_surface_destroy (cairo_surface_t *surface)
924
cairo_surface_destroy (cairo_surface_t *surface)
632
{
925
{
633
    if (surface == NULL ||
926
    if (surface == NULL ||
Line 639... Line 932...
639
    if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
932
    if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
640
	return;
933
	return;
Line 641... Line 934...
641
 
934
 
Line 642... Line 935...
642
    assert (surface->snapshot_of == NULL);
935
    assert (surface->snapshot_of == NULL);
643
 
936
 
-
 
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
	 */
Line 644... Line 942...
644
    if (! surface->finished)
942
	if (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count))
-
 
943
	    return;
-
 
944
 
-
 
945
	_cairo_surface_finish (surface);
645
	cairo_surface_finish (surface);
946
    }
Line 646... Line 947...
646
 
947
 
647
    /* paranoid check that nobody took a reference whilst finishing */
948
    if (surface->damage)
Line 648... Line 949...
648
    assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count));
949
	_cairo_damage_destroy (surface->damage);
649
 
950
 
Line -... Line 951...
-
 
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);
650
    _cairo_user_data_array_fini (&surface->user_data);
956
 
651
    _cairo_user_data_array_fini (&surface->mime_data);
957
    assert (surface->snapshot_of == NULL);
652
 
958
    assert (! _cairo_surface_has_snapshots (surface));
Line 653... Line 959...
653
    if (surface->owns_device)
959
    /* paranoid check that nobody took a reference whilst finishing */
Line 676... Line 982...
676
	return 0;
982
	return 0;
Line 677... Line 983...
677
 
983
 
678
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
984
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count);
Line -... Line 985...
-
 
985
}
-
 
986
 
-
 
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));
679
}
1014
}
680
 
1015
 
681
/**
1016
/**
682
 * cairo_surface_finish:
1017
 * cairo_surface_finish:
683
 * @surface: the #cairo_surface_t to finish
1018
 * @surface: the #cairo_surface_t to finish
Line 694... Line 1029...
694
 *
1029
 *
695
 * When the last call to cairo_surface_destroy() decreases the
1030
 * When the last call to cairo_surface_destroy() decreases the
696
 * reference count to zero, cairo will call cairo_surface_finish() if
1031
 * reference count to zero, cairo will call cairo_surface_finish() if
697
 * it hasn't been called already, before freeing the resources
1032
 * it hasn't been called already, before freeing the resources
698
 * associated with the surface.
1033
 * associated with the surface.
-
 
1034
 *
-
 
1035
 * Since: 1.0
699
 **/
1036
 **/
700
void
1037
void
701
cairo_surface_finish (cairo_surface_t *surface)
1038
cairo_surface_finish (cairo_surface_t *surface)
702
{
1039
{
703
    cairo_status_t status;
-
 
704
 
-
 
705
    if (surface == NULL)
1040
    if (surface == NULL)
706
	return;
1041
	return;
Line 707... Line 1042...
707
 
1042
 
708
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
1043
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
Line 709... Line 1044...
709
	return;
1044
	return;
710
 
1045
 
Line 711... Line 1046...
711
    if (surface->finished)
1046
    if (surface->finished)
712
	return;
1047
	return;
713
 
-
 
714
    /* update the snapshots *before* we declare the surface as finished */
-
 
Line 715... Line 1048...
715
    _cairo_surface_detach_snapshots (surface);
1048
 
-
 
1049
    /* We have to be careful when decoupling potential reference cycles */
716
    if (surface->snapshot_of != NULL)
1050
    cairo_surface_reference (surface);
Line 717... Line -...
717
	_cairo_surface_detach_snapshot (surface);
-
 
718
 
-
 
719
    cairo_surface_flush (surface);
-
 
720
    surface->finished = TRUE;
-
 
721
 
1051
 
722
    /* call finish even if in error mode */
-
 
723
    if (surface->backend->finish) {
1052
    _cairo_surface_finish_snapshots (surface);
724
	status = surface->backend->finish (surface);
1053
    /* XXX need to block and wait for snapshot references */
Line 725... Line 1054...
725
	if (unlikely (status))
1054
    _cairo_surface_finish (surface);
726
	    status = _cairo_surface_set_error (surface, status);
1055
 
Line 758... Line 1087...
758
 * Return user data previously attached to @surface using the specified
1087
 * Return user data previously attached to @surface using the specified
759
 * key.  If no user data has been attached with the given key this
1088
 * key.  If no user data has been attached with the given key this
760
 * function returns %NULL.
1089
 * function returns %NULL.
761
 *
1090
 *
762
 * Return value: the user data previously attached or %NULL.
1091
 * Return value: the user data previously attached or %NULL.
-
 
1092
 *
-
 
1093
 * Since: 1.0
763
 **/
1094
 **/
764
void *
1095
void *
765
cairo_surface_get_user_data (cairo_surface_t		 *surface,
1096
cairo_surface_get_user_data (cairo_surface_t		 *surface,
766
			     const cairo_user_data_key_t *key)
1097
			     const cairo_user_data_key_t *key)
767
{
1098
{
-
 
1099
    /* Prevent reads of the array during teardown */
768
    return _cairo_user_data_array_get_data (&surface->user_data,
1100
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
769
					    key);
1101
	return NULL;
-
 
1102
 
-
 
1103
    return _cairo_user_data_array_get_data (&surface->user_data, key);
770
}
1104
}
Line 771... Line 1105...
771
 
1105
 
772
/**
1106
/**
773
 * cairo_surface_set_user_data:
1107
 * cairo_surface_set_user_data:
Line 782... Line 1116...
782
 * call this function with the key that was used to set it and %NULL
1116
 * call this function with the key that was used to set it and %NULL
783
 * for @data.
1117
 * for @data.
784
 *
1118
 *
785
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
1119
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
786
 * slot could not be allocated for the user data.
1120
 * slot could not be allocated for the user data.
-
 
1121
 *
-
 
1122
 * Since: 1.0
787
 **/
1123
 **/
788
cairo_status_t
1124
cairo_status_t
789
cairo_surface_set_user_data (cairo_surface_t		 *surface,
1125
cairo_surface_set_user_data (cairo_surface_t		 *surface,
790
			     const cairo_user_data_key_t *key,
1126
			     const cairo_user_data_key_t *key,
791
			     void			 *user_data,
1127
			     void			 *user_data,
792
			     cairo_destroy_func_t	 destroy)
1128
			     cairo_destroy_func_t	 destroy)
793
{
1129
{
794
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
1130
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&surface->ref_count))
795
	return surface->status;
1131
	return surface->status;
Line -... Line 1132...
-
 
1132
 
-
 
1133
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
-
 
1134
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
796
 
1135
 
797
    return _cairo_user_data_array_set_data (&surface->user_data,
1136
    return _cairo_user_data_array_set_data (&surface->user_data,
798
					    key, user_data, destroy);
1137
					    key, user_data, destroy);
Line 799... Line 1138...
799
}
1138
}
Line 820... Line 1159...
820
    cairo_user_data_slot_t *slots;
1159
    cairo_user_data_slot_t *slots;
821
    int i, num_slots;
1160
    int i, num_slots;
Line 822... Line 1161...
822
 
1161
 
823
    *data = NULL;
1162
    *data = NULL;
-
 
1163
    *length = 0;
-
 
1164
 
824
    *length = 0;
1165
    /* Prevent reads of the array during teardown */
825
    if (unlikely (surface->status))
1166
    if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&surface->ref_count))
Line 826... Line 1167...
826
	return;
1167
	return;
827
 
1168
 
828
    /* The number of mime-types attached to a surface is usually small,
1169
    /* The number of mime-types attached to a surface is usually small,
829
     * typically zero. Therefore it is quicker to do a strcmp() against
1170
     * typically zero. Therefore it is quicker to do a strcmp() against
830
     * each key than it is to intern the string (i.e. compute a hash,
1171
     * each key than it is to intern the string (i.e. compute a hash,
831
     * search the hash table, and do a final strcmp).
1172
     * search the hash table, and do a final strcmp).
832
     */
1173
     */
833
    num_slots = surface->mime_data.num_elements;
1174
    num_slots = surface->mime_data.num_elements;
834
    slots = _cairo_array_index (&surface->mime_data, 0);
1175
    slots = _cairo_array_index (&surface->mime_data, 0);
835
    for (i = 0; i < num_slots; i++) {
1176
    for (i = 0; i < num_slots; i++) {
Line 836... Line 1177...
836
	if (strcmp ((char *) slots[i].key, mime_type) == 0) {
1177
	if (slots[i].key != NULL && strcmp ((char *) slots[i].key, mime_type) == 0) {
837
	    cairo_mime_data_t *mime_data = slots[i].user_data;
1178
	    cairo_mime_data_t *mime_data = slots[i].user_data;
838
 
1179
 
Line 861... Line 1202...
861
/**
1202
/**
862
 * CAIRO_MIME_TYPE_JP2:
1203
 * CAIRO_MIME_TYPE_JP2:
863
 *
1204
 *
864
 * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
1205
 * The Joint Photographic Experts Group (JPEG) 2000 image coding standard (ISO/IEC 15444-1).
865
 *
1206
 *
866
 * @Since: 1.10
1207
 * Since: 1.10
867
 */
1208
 **/
Line 868... Line 1209...
868
 
1209
 
869
/**
1210
/**
870
 * CAIRO_MIME_TYPE_JPEG:
1211
 * CAIRO_MIME_TYPE_JPEG:
871
 *
1212
 *
872
 * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1).
1213
 * The Joint Photographic Experts Group (JPEG) image coding standard (ISO/IEC 10918-1).
873
 *
1214
 *
874
 * @Since: 1.10
1215
 * Since: 1.10
Line 875... Line 1216...
875
 */
1216
 **/
876
 
1217
 
877
/**
1218
/**
878
 * CAIRO_MIME_TYPE_PNG:
1219
 * CAIRO_MIME_TYPE_PNG:
879
 *
1220
 *
880
 * The Portable Network Graphics image file format (ISO/IEC 15948).
1221
 * The Portable Network Graphics image file format (ISO/IEC 15948).
881
 *
1222
 *
Line 882... Line 1223...
882
 * @Since: 1.10
1223
 * Since: 1.10
883
 */
1224
 **/
884
 
1225
 
885
/**
1226
/**
886
 * CAIRO_MIME_TYPE_URI:
1227
 * CAIRO_MIME_TYPE_URI:
887
 *
1228
 *
-
 
1229
 * URI for an image file (unofficial MIME type).
-
 
1230
 *
-
 
1231
 * Since: 1.10
-
 
1232
 **/
-
 
1233
 
-
 
1234
/**
-
 
1235
 * CAIRO_MIME_TYPE_UNIQUE_ID:
-
 
1236
 *
888
 * URI for an image file (unofficial MIME type).
1237
 * Unique identifier for a surface (cairo specific MIME type).
Line 889... Line 1238...
889
 *
1238
 *
890
 * @Since: 1.10
1239
 * Since: 1.12
891
 */
1240
 **/
892
 
1241
 
Line 910... Line 1259...
910
 * surfaces) to emit this data instead of making a snapshot of the
1259
 * surfaces) to emit this data instead of making a snapshot of the
911
 * @surface.  This approach tends to be faster and requires less
1260
 * @surface.  This approach tends to be faster and requires less
912
 * memory and disk space.
1261
 * memory and disk space.
913
 *
1262
 *
914
 * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
1263
 * The recognized MIME types are the following: %CAIRO_MIME_TYPE_JPEG,
915
 * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI.
1264
 * %CAIRO_MIME_TYPE_PNG, %CAIRO_MIME_TYPE_JP2, %CAIRO_MIME_TYPE_URI,
-
 
1265
 * %CAIRO_MIME_TYPE_UNIQUE_ID.
916
 *
1266
 *
917
 * See corresponding backend surface docs for details about which MIME
1267
 * See corresponding backend surface docs for details about which MIME
918
 * types it can handle. Caution: the associated MIME data will be
1268
 * types it can handle. Caution: the associated MIME data will be
919
 * discarded if you draw on the surface afterwards. Use this function
1269
 * discarded if you draw on the surface afterwards. Use this function
920
 * with care.
1270
 * with care.
921
 *
1271
 *
922
 * Since: 1.10
-
 
923
 *
-
 
924
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
1272
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
925
 * slot could not be allocated for the user data.
1273
 * slot could not be allocated for the user data.
-
 
1274
 *
-
 
1275
 * Since: 1.10
926
 **/
1276
 **/
927
cairo_status_t
1277
cairo_status_t
928
cairo_surface_set_mime_data (cairo_surface_t		*surface,
1278
cairo_surface_set_mime_data (cairo_surface_t		*surface,
929
                             const char			*mime_type,
1279
                             const char			*mime_type,
930
                             const unsigned char	*data,
1280
                             const unsigned char	*data,
Line 933... Line 1283...
933
			     void			*closure)
1283
			     void			*closure)
934
{
1284
{
935
    cairo_status_t status;
1285
    cairo_status_t status;
936
    cairo_mime_data_t *mime_data;
1286
    cairo_mime_data_t *mime_data;
Line -... Line 1287...
-
 
1287
 
-
 
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);
937
 
1293
 
938
    if (unlikely (surface->status))
1294
    if (unlikely (surface->status))
939
	return surface->status;
1295
	return surface->status;
940
    if (surface->finished)
1296
    if (unlikely (surface->finished))
Line 941... Line 1297...
941
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1297
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
942
 
1298
 
943
    status = _cairo_intern_string (&mime_type, -1);
1299
    status = _cairo_intern_string (&mime_type, -1);
Line 961... Line 1317...
961
    status = _cairo_user_data_array_set_data (&surface->mime_data,
1317
    status = _cairo_user_data_array_set_data (&surface->mime_data,
962
					      (cairo_user_data_key_t *) mime_type,
1318
					      (cairo_user_data_key_t *) mime_type,
963
					      mime_data,
1319
					      mime_data,
964
					      _cairo_mime_data_destroy);
1320
					      _cairo_mime_data_destroy);
965
    if (unlikely (status)) {
1321
    if (unlikely (status)) {
966
	if (mime_data != NULL)
-
 
967
	    free (mime_data);
1322
	free (mime_data);
Line 968... Line 1323...
968
 
1323
 
969
	return _cairo_surface_set_error (surface, status);
1324
	return _cairo_surface_set_error (surface, status);
Line 970... Line 1325...
970
    }
1325
    }
971
 
1326
 
972
    return CAIRO_STATUS_SUCCESS;
1327
    return CAIRO_STATUS_SUCCESS;
Line -... Line 1328...
-
 
1328
}
-
 
1329
slim_hidden_def (cairo_surface_set_mime_data);
-
 
1330
 
-
 
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;
973
}
1368
}
974
slim_hidden_def (cairo_surface_set_mime_data);
1369
slim_hidden_def (cairo_surface_supports_mime_type);
975
 
1370
 
976
static void
1371
static void
Line 1023... Line 1418...
1023
 **/
1418
 **/
1024
void
1419
void
1025
_cairo_surface_set_font_options (cairo_surface_t       *surface,
1420
_cairo_surface_set_font_options (cairo_surface_t       *surface,
1026
				 cairo_font_options_t  *options)
1421
				 cairo_font_options_t  *options)
1027
{
1422
{
1028
    cairo_status_t status;
-
 
1029
 
-
 
1030
    if (surface->status)
1423
    if (surface->status)
1031
	return;
1424
	return;
Line 1032... Line 1425...
1032
 
1425
 
Line 1033... Line 1426...
1033
    assert (surface->snapshot_of == NULL);
1426
    assert (surface->snapshot_of == NULL);
1034
 
-
 
1035
    if (surface->finished) {
1427
 
1036
	status = _cairo_surface_set_error (surface,
1428
    if (surface->finished) {
1037
		                           _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1429
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
Line 1038... Line 1430...
1038
	return;
1430
	return;
1039
    }
1431
    }
Line 1055... Line 1447...
1055
 * Retrieves the default font rendering options for the surface.
1447
 * Retrieves the default font rendering options for the surface.
1056
 * This allows display surfaces to report the correct subpixel order
1448
 * This allows display surfaces to report the correct subpixel order
1057
 * for rendering on them, print surfaces to disable hinting of
1449
 * for rendering on them, print surfaces to disable hinting of
1058
 * metrics and so forth. The result can then be used with
1450
 * metrics and so forth. The result can then be used with
1059
 * cairo_scaled_font_create().
1451
 * cairo_scaled_font_create().
-
 
1452
 *
-
 
1453
 * Since: 1.0
1060
 **/
1454
 **/
1061
void
1455
void
1062
cairo_surface_get_font_options (cairo_surface_t       *surface,
1456
cairo_surface_get_font_options (cairo_surface_t       *surface,
1063
				cairo_font_options_t  *options)
1457
				cairo_font_options_t  *options)
1064
{
1458
{
Line 1082... Line 1476...
1082
 
1476
 
1083
    _cairo_font_options_init_copy (options, &surface->font_options);
1477
    _cairo_font_options_init_copy (options, &surface->font_options);
1084
}
1478
}
Line -... Line 1479...
-
 
1479
slim_hidden_def (cairo_surface_get_font_options);
-
 
1480
 
-
 
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);
1085
slim_hidden_def (cairo_surface_get_font_options);
1491
}
1086
 
1492
 
1087
/**
1493
/**
1088
 * cairo_surface_flush:
1494
 * cairo_surface_flush:
1089
 * @surface: a #cairo_surface_t
1495
 * @surface: a #cairo_surface_t
1090
 *
1496
 *
1091
 * Do any pending drawing for the surface and also restore any
1497
 * Do any pending drawing for the surface and also restore any
1092
 * temporary modifications cairo has made to the surface's
1498
 * temporary modifications cairo has made to the surface's
1093
 * state. This function must be called before switching from
1499
 * state. This function must be called before switching from
1094
 * drawing on the surface with cairo to drawing on it directly
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.
1095
 * with native APIs. If the surface doesn't support direct access,
1503
 *
1096
 * then this function does nothing.
1504
 * Since: 1.0
1097
 **/
1505
 **/
1098
void
1506
void
1099
cairo_surface_flush (cairo_surface_t *surface)
1507
cairo_surface_flush (cairo_surface_t *surface)
Line 1104... Line 1512...
1104
	return;
1512
	return;
Line 1105... Line 1513...
1105
 
1513
 
1106
    if (surface->finished)
1514
    if (surface->finished)
Line 1107... Line -...
1107
	return;
-
 
1108
 
-
 
1109
    /* update the current snapshots *before* the user updates the surface */
-
 
1110
    _cairo_surface_detach_snapshots (surface);
-
 
1111
 
1515
	return;
1112
    if (surface->backend->flush) {
1516
 
1113
	status = surface->backend->flush (surface);
1517
    status = _cairo_surface_flush (surface, 0);
1114
	if (unlikely (status))
-
 
1115
	    status = _cairo_surface_set_error (surface, status);
1518
    if (unlikely (status))
1116
    }
1519
	_cairo_surface_set_error (surface, status);
Line 1117... Line 1520...
1117
}
1520
}
1118
slim_hidden_def (cairo_surface_flush);
1521
slim_hidden_def (cairo_surface_flush);
1119
 
1522
 
1120
/**
1523
/**
1121
 * cairo_surface_mark_dirty:
1524
 * cairo_surface_mark_dirty:
1122
 * @surface: a #cairo_surface_t
1525
 * @surface: a #cairo_surface_t
1123
 *
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
1124
 * Tells cairo that drawing has been done to surface using means other
1529
 * that you must call cairo_surface_flush() before doing such drawing.
1125
 * than cairo, and that cairo should reread any cached areas. Note
1530
 *
1126
 * that you must call cairo_surface_flush() before doing such drawing.
1531
 * Since: 1.0
1127
 */
1532
 **/
-
 
1533
void
-
 
1534
cairo_surface_mark_dirty (cairo_surface_t *surface)
-
 
1535
{
-
 
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;
1128
void
1543
    }
-
 
1544
 
-
 
1545
    _cairo_surface_get_extents (surface, &extents);
1129
cairo_surface_mark_dirty (cairo_surface_t *surface)
1546
    cairo_surface_mark_dirty_rectangle (surface,
1130
{
1547
					extents.x, extents.y,
Line 1131... Line 1548...
1131
    cairo_surface_mark_dirty_rectangle (surface, 0, 0, -1, -1);
1548
					extents.width, extents.height);
1132
}
1549
}
Line 1145... Line 1562...
1145
 * for other parts of the surface.
1562
 * for other parts of the surface.
1146
 *
1563
 *
1147
 * Any cached clip set on the surface will be reset by this function,
1564
 * Any cached clip set on the surface will be reset by this function,
1148
 * to make sure that future cairo calls have the clip set that they
1565
 * to make sure that future cairo calls have the clip set that they
1149
 * expect.
1566
 * expect.
-
 
1567
 *
-
 
1568
 * Since: 1.0
1150
 */
1569
 **/
1151
void
1570
void
1152
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
1571
cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
1153
				    int              x,
1572
				    int              x,
1154
				    int              y,
1573
				    int              y,
1155
				    int              width,
1574
				    int              width,
1156
				    int              height)
1575
				    int              height)
1157
{
1576
{
1158
    cairo_status_t status;
1577
    cairo_status_t status;
Line 1159... Line 1578...
1159
 
1578
 
1160
    if (surface->status)
1579
    if (unlikely (surface->status))
Line 1161... Line 1580...
1161
	return;
1580
	return;
Line 1162... Line 1581...
1162
 
1581
 
1163
    assert (surface->snapshot_of == NULL);
1582
    assert (surface->snapshot_of == NULL);
1164
 
1583
 
1165
    if (surface->finished) {
1584
    if (unlikely (surface->finished)) {
Line 1166... Line 1585...
1166
	status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1585
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1167
	return;
1586
	return;
1168
    }
1587
    }
1169
 
1588
 
1170
    /* The application *should* have called cairo_surface_flush() before
1589
    /* The application *should* have called cairo_surface_flush() before
Line 1171... Line 1590...
1171
     * modifying the surface independently of cairo (and thus having to
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;
-
 
1596
    surface->serial++;
-
 
1597
 
-
 
1598
    if (surface->damage) {
-
 
1599
	cairo_box_t box;
-
 
1600
 
-
 
1601
	box.p1.x = x;
-
 
1602
	box.p1.y = y;
Line 1172... Line 1603...
1172
     * call mark_dirty()). */
1603
	box.p2.x = x + width;
1173
    assert (! _cairo_surface_has_snapshots (surface));
1604
	box.p2.y = y + height;
1174
    assert (! _cairo_surface_has_mime_data (surface));
1605
 
1175
 
1606
	surface->damage = _cairo_damage_add_box (surface->damage, &box);
Line 1185... Line 1616...
1185
                                                         x + surface->device_transform.x0,
1616
                                                         x + surface->device_transform.x0,
1186
                                                         y + surface->device_transform.y0,
1617
                                                         y + surface->device_transform.y0,
1187
							 width, height);
1618
							 width, height);
Line 1188... Line 1619...
1188
 
1619
 
1189
	if (unlikely (status))
1620
	if (unlikely (status))
1190
	    status = _cairo_surface_set_error (surface, status);
1621
	    _cairo_surface_set_error (surface, status);
1191
    }
1622
    }
1192
}
1623
}
Line 1193... Line 1624...
1193
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
1624
slim_hidden_def (cairo_surface_mark_dirty_rectangle);
Line 1214... Line 1645...
1214
				 double		  sx,
1645
				 double		  sx,
1215
				 double		  sy)
1646
				 double		  sy)
1216
{
1647
{
1217
    cairo_status_t status;
1648
    cairo_status_t status;
Line 1218... Line 1649...
1218
 
1649
 
1219
    if (surface->status)
1650
    if (unlikely (surface->status))
Line 1220... Line 1651...
1220
	return;
1651
	return;
Line 1221... Line 1652...
1221
 
1652
 
1222
    assert (surface->snapshot_of == NULL);
1653
    assert (surface->snapshot_of == NULL);
1223
 
1654
 
1224
    if (surface->finished) {
1655
    if (unlikely (surface->finished)) {
Line 1225... Line 1656...
1225
	status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1656
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-
 
1657
	return;
-
 
1658
    }
-
 
1659
 
-
 
1660
    status = _cairo_surface_begin_modification (surface);
Line 1226... Line 1661...
1226
	return;
1661
    if (unlikely (status)) {
1227
    }
1662
	_cairo_surface_set_error (surface, status);
1228
 
1663
	return;
1229
    _cairo_surface_begin_modification (surface);
1664
    }
Line 1256... Line 1691...
1256
 * sufficient to do this, since functions like
1691
 * sufficient to do this, since functions like
1257
 * cairo_device_to_user() will expose the hidden offset.
1692
 * cairo_device_to_user() will expose the hidden offset.
1258
 *
1693
 *
1259
 * Note that the offset affects drawing to the surface as well as
1694
 * Note that the offset affects drawing to the surface as well as
1260
 * using the surface in a source pattern.
1695
 * using the surface in a source pattern.
-
 
1696
 *
-
 
1697
 * Since: 1.0
1261
 **/
1698
 **/
1262
void
1699
void
1263
cairo_surface_set_device_offset (cairo_surface_t *surface,
1700
cairo_surface_set_device_offset (cairo_surface_t *surface,
1264
				 double           x_offset,
1701
				 double           x_offset,
1265
				 double           y_offset)
1702
				 double           y_offset)
1266
{
1703
{
1267
    cairo_status_t status;
1704
    cairo_status_t status;
Line 1268... Line 1705...
1268
 
1705
 
1269
    if (surface->status)
1706
    if (unlikely (surface->status))
Line 1270... Line 1707...
1270
	return;
1707
	return;
Line 1271... Line 1708...
1271
 
1708
 
1272
    assert (surface->snapshot_of == NULL);
1709
    assert (surface->snapshot_of == NULL);
1273
 
1710
 
1274
    if (surface->finished) {
1711
    if (unlikely (surface->finished)) {
Line 1275... Line 1712...
1275
	status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1712
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-
 
1713
	return;
-
 
1714
    }
-
 
1715
 
-
 
1716
    status = _cairo_surface_begin_modification (surface);
Line 1276... Line 1717...
1276
	return;
1717
    if (unlikely (status)) {
1277
    }
1718
	_cairo_surface_set_error (surface, status);
Line 1278... Line 1719...
1278
 
1719
	return;
Line 1351... Line 1792...
1351
				       double		 x_pixels_per_inch,
1792
				       double		 x_pixels_per_inch,
1352
				       double		 y_pixels_per_inch)
1793
				       double		 y_pixels_per_inch)
1353
{
1794
{
1354
    cairo_status_t status;
1795
    cairo_status_t status;
Line 1355... Line 1796...
1355
 
1796
 
1356
    if (surface->status)
1797
    if (unlikely (surface->status))
Line 1357... Line 1798...
1357
	return;
1798
	return;
Line 1358... Line 1799...
1358
 
1799
 
1359
    assert (surface->snapshot_of == NULL);
1800
    assert (surface->snapshot_of == NULL);
1360
 
1801
 
1361
    if (surface->finished) {
1802
    if (unlikely (surface->finished)) {
Line 1362... Line 1803...
1362
	status = _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1803
	_cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
1363
	return;
1804
	return;
1364
    }
1805
    }
1365
 
1806
 
1366
    if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) {
1807
    if (x_pixels_per_inch <= 0 || y_pixels_per_inch <= 0) {
1367
	/* XXX Could delay raising the error until we fallback, but throwing
1808
	/* XXX Could delay raising the error until we fallback, but throwing
1368
	 * the error here means that we can catch the real culprit.
1809
	 * the error here means that we can catch the real culprit.
Line 1369... Line 1810...
1369
	 */
1810
	 */
-
 
1811
	_cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX);
-
 
1812
	return;
-
 
1813
    }
-
 
1814
 
Line 1370... Line 1815...
1370
	status = _cairo_surface_set_error (surface, CAIRO_STATUS_INVALID_MATRIX);
1815
    status = _cairo_surface_begin_modification (surface);
1371
	return;
1816
    if (unlikely (status)) {
1372
    }
1817
	_cairo_surface_set_error (surface, status);
1373
 
1818
	return;
Line 1429... Line 1874...
1429
				     cairo_image_surface_t  **image_out,
1874
				     cairo_image_surface_t  **image_out,
1430
				     void                   **image_extra)
1875
				     void                   **image_extra)
1431
{
1876
{
1432
    cairo_status_t status;
1877
    cairo_status_t status;
Line 1433... Line 1878...
1433
 
1878
 
1434
    if (surface->status)
1879
    if (unlikely (surface->status))
Line 1435... Line 1880...
1435
	return surface->status;
1880
	return surface->status;
Line 1436... Line 1881...
1436
 
1881
 
Line 1447... Line 1892...
1447
    _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
1892
    _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
Line 1448... Line 1893...
1448
 
1893
 
1449
    return CAIRO_STATUS_SUCCESS;
1894
    return CAIRO_STATUS_SUCCESS;
Line -... Line 1895...
-
 
1895
}
-
 
1896
 
-
 
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;
1450
}
1911
}
1451
 
1912
 
1452
/**
1913
/**
1453
 * _cairo_surface_release_source_image:
1914
 * _cairo_surface_release_source_image:
1454
 * @surface: a #cairo_surface_t
1915
 * @surface: a #cairo_surface_t
Line 1465... Line 1926...
1465
 
1926
 
1466
    if (surface->backend->release_source_image)
1927
    if (surface->backend->release_source_image)
1467
	surface->backend->release_source_image (surface, image, image_extra);
1928
	surface->backend->release_source_image (surface, image, image_extra);
Line 1468... Line -...
1468
}
-
 
1469
 
-
 
1470
/**
-
 
1471
 * _cairo_surface_acquire_dest_image:
-
 
1472
 * @surface: a #cairo_surface_t
-
 
1473
 * @interest_rect: area of @surface for which fallback drawing is being done.
-
 
1474
 *    A value of %NULL indicates that the entire surface is desired.
-
 
1475
 *    XXXX I'd like to get rid of being able to pass %NULL here (nothing seems to)
-
 
1476
 * @image_out: location to store a pointer to an image surface that includes at least
-
 
1477
 *    the intersection of @interest_rect with the visible area of @surface.
-
 
1478
 *    This surface could be @surface itself, a surface held internal to @surface,
-
 
1479
 *    or it could be a new surface with a copy of the relevant portion of @surface.
-
 
1480
 *    If a new surface is created, it should have the same channels and depth
-
 
1481
 *    as @surface so that copying to and from it is exact.
-
 
1482
 * @image_rect: location to store area of the original surface occupied
-
 
1483
 *    by the surface stored in @image.
-
 
1484
 * @image_extra: location to store image specific backend data
-
 
1485
 *
-
 
1486
 * Retrieves a local image for a surface for implementing a fallback drawing
-
 
1487
 * operation. After calling this function, the implementation of the fallback
-
 
1488
 * drawing operation draws the primitive to the surface stored in @image_out
-
 
1489
 * then calls _cairo_surface_release_dest_image(),
-
 
1490
 * which, if a temporary surface was created, copies the bits back to the
-
 
1491
 * main surface and frees the temporary surface.
-
 
1492
 *
-
 
1493
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY.
-
 
1494
 *  %CAIRO_INT_STATUS_UNSUPPORTED can be returned but this will mean that
-
 
1495
 *  the backend can't draw with fallbacks. It's possible for the routine
-
 
1496
 *  to store %NULL in @local_out and return %CAIRO_STATUS_SUCCESS;
-
 
1497
 *  that indicates that no part of @interest_rect is visible, so no drawing
-
 
1498
 *  is necessary. _cairo_surface_release_dest_image() should not be called in that
-
 
1499
 *  case.
-
 
1500
 **/
-
 
1501
cairo_status_t
-
 
1502
_cairo_surface_acquire_dest_image (cairo_surface_t         *surface,
-
 
1503
				   cairo_rectangle_int_t   *interest_rect,
-
 
1504
				   cairo_image_surface_t  **image_out,
-
 
1505
				   cairo_rectangle_int_t   *image_rect,
-
 
1506
				   void                   **image_extra)
-
 
1507
{
-
 
1508
    cairo_status_t status;
-
 
1509
 
-
 
1510
    if (surface->status)
-
 
1511
	return surface->status;
-
 
1512
 
-
 
1513
    assert (_cairo_surface_is_writable (surface));
-
 
1514
 
-
 
1515
    if (surface->backend->acquire_dest_image == NULL)
-
 
1516
	return CAIRO_INT_STATUS_UNSUPPORTED;
-
 
1517
 
-
 
1518
    status = surface->backend->acquire_dest_image (surface,
-
 
1519
						   interest_rect,
-
 
1520
						   image_out,
-
 
1521
						   image_rect,
-
 
1522
						   image_extra);
-
 
1523
    if (unlikely (status))
-
 
1524
	return _cairo_surface_set_error (surface, status);
-
 
1525
 
-
 
1526
    _cairo_debug_check_image_surface_is_defined (&(*image_out)->base);
-
 
1527
 
-
 
1528
    return CAIRO_STATUS_SUCCESS;
-
 
1529
}
-
 
1530
 
-
 
1531
/**
-
 
1532
 * _cairo_surface_release_dest_image:
-
 
1533
 * @surface: a #cairo_surface_t
-
 
1534
 * @interest_rect: same as passed to the matching _cairo_surface_acquire_dest_image()
-
 
1535
 * @image: same as returned from the matching _cairo_surface_acquire_dest_image()
-
 
1536
 * @image_rect: same as returned from the matching _cairo_surface_acquire_dest_image()
-
 
1537
 * @image_extra: same as return from the matching _cairo_surface_acquire_dest_image()
-
 
1538
 *
-
 
1539
 * Finishes the operation started with _cairo_surface_acquire_dest_image(), by, if
-
 
1540
 * necessary, copying the image from @image back to @surface and freeing any
-
 
1541
 * resources that were allocated.
1929
}
1542
 **/
1930
 
1543
void
-
 
1544
_cairo_surface_release_dest_image (cairo_surface_t         *surface,
1931
void
1545
				   cairo_rectangle_int_t   *interest_rect,
-
 
1546
				   cairo_image_surface_t   *image,
1932
_cairo_surface_default_release_source_image (void                   *surface,
1547
				   cairo_rectangle_int_t   *image_rect,
1933
					     cairo_image_surface_t  *image,
1548
				   void                    *image_extra)
-
 
1549
{
-
 
1550
    assert (_cairo_surface_is_writable (surface));
-
 
1551
 
-
 
1552
    if (surface->backend->release_dest_image)
-
 
1553
	surface->backend->release_dest_image (surface, interest_rect,
-
 
1554
					      image, image_rect, image_extra);
-
 
1555
}
-
 
1556
 
-
 
1557
static cairo_status_t
-
 
1558
_cairo_recording_surface_clone_similar (cairo_surface_t  *surface,
-
 
1559
					cairo_surface_t  *src,
-
 
1560
					int               src_x,
-
 
1561
					int               src_y,
-
 
1562
					int               width,
-
 
1563
					int               height,
-
 
1564
					int              *clone_offset_x,
-
 
1565
					int              *clone_offset_y,
-
 
1566
					cairo_surface_t **clone_out)
-
 
1567
{
-
 
1568
    cairo_recording_surface_t *recorder = (cairo_recording_surface_t *) src;
1934
					     void                   *image_extra)
1569
    cairo_surface_t *similar;
-
 
1570
    cairo_status_t status;
-
 
1571
 
-
 
1572
    similar = _cairo_surface_has_snapshot (src, surface->backend);
-
 
1573
    if (similar != NULL) {
-
 
1574
	*clone_out = cairo_surface_reference (similar);
-
 
1575
	*clone_offset_x = 0;
-
 
1576
	*clone_offset_y = 0;
-
 
1577
	return CAIRO_STATUS_SUCCESS;
-
 
1578
    }
-
 
1579
 
-
 
1580
    if (recorder->unbounded ||
-
 
1581
	width*height*8 < recorder->extents.width*recorder->extents.height)
-
 
1582
    {
-
 
1583
	similar = _cairo_surface_create_similar_solid (surface,
-
 
1584
						       src->content,
-
 
1585
						       width, height,
-
 
1586
                                                       CAIRO_COLOR_TRANSPARENT,
-
 
1587
                                                       FALSE);
-
 
1588
	if (similar == NULL)
-
 
1589
	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
 
1590
	if (unlikely (similar->status))
-
 
1591
	    return similar->status;
-
 
1592
 
-
 
1593
	cairo_surface_set_device_offset (similar, -src_x, -src_y);
-
 
1594
 
-
 
1595
	status = _cairo_recording_surface_replay (src, similar);
-
 
1596
	if (unlikely (status)) {
-
 
1597
	    cairo_surface_destroy (similar);
-
 
1598
	    return status;
-
 
1599
	}
-
 
1600
    } else {
-
 
1601
	similar = _cairo_surface_create_similar_scratch (surface,
-
 
1602
							 src->content,
-
 
1603
							 recorder->extents.width,
-
 
1604
							 recorder->extents.height);
-
 
1605
	if (similar == NULL)
-
 
1606
	    return CAIRO_INT_STATUS_UNSUPPORTED;
-
 
1607
	if (unlikely (similar->status))
-
 
1608
	    return similar->status;
-
 
1609
 
-
 
1610
	status = _cairo_recording_surface_replay (src, similar);
-
 
1611
	if (unlikely (status)) {
-
 
1612
	    cairo_surface_destroy (similar);
-
 
1613
	    return status;
-
 
1614
	}
-
 
1615
 
-
 
1616
	_cairo_surface_attach_snapshot (src, similar, NULL);
-
 
1617
 
-
 
1618
	src_x = src_y = 0;
-
 
1619
    }
-
 
1620
 
-
 
1621
    *clone_out = similar;
-
 
1622
    *clone_offset_x = src_x;
-
 
1623
    *clone_offset_y = src_y;
-
 
1624
    return CAIRO_STATUS_SUCCESS;
-
 
1625
}
-
 
1626
 
-
 
1627
/**
-
 
1628
 * _cairo_surface_clone_similar:
-
 
1629
 * @surface: a #cairo_surface_t
-
 
1630
 * @src: the source image
-
 
1631
 * @content: target content mask
-
 
1632
 * @src_x: extent for the rectangle in src we actually care about
-
 
1633
 * @src_y: extent for the rectangle in src we actually care about
-
 
1634
 * @width: extent for the rectangle in src we actually care about
-
 
1635
 * @height: extent for the rectangle in src we actually care about
-
 
1636
 * @clone_out: location to store a surface compatible with @surface
-
 
1637
 *   and with contents identical to @src. The caller must call
-
 
1638
 *   cairo_surface_destroy() on the result.
-
 
1639
 *
-
 
1640
 * Creates a surface with contents identical to @src but that
-
 
1641
 *   can be used efficiently with @surface. If @surface and @src are
-
 
1642
 *   already compatible then it may return a new reference to @src.
-
 
1643
 *
-
 
1644
 * Return value: %CAIRO_STATUS_SUCCESS if a surface was created and stored
-
 
1645
 *   in @clone_out. Otherwise %CAIRO_INT_STATUS_UNSUPPORTED or another
-
 
1646
 *   error like %CAIRO_STATUS_NO_MEMORY.
-
 
1647
 **/
-
 
1648
cairo_status_t
-
 
1649
_cairo_surface_clone_similar (cairo_surface_t  *surface,
-
 
1650
			      cairo_surface_t  *src,
-
 
1651
			      int               src_x,
-
 
1652
			      int               src_y,
-
 
1653
			      int               width,
-
 
1654
			      int               height,
-
 
1655
			      int              *clone_offset_x,
-
 
1656
			      int              *clone_offset_y,
-
 
1657
			      cairo_surface_t **clone_out)
-
 
1658
{
-
 
1659
    cairo_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
-
 
1660
    cairo_image_surface_t *image;
-
 
1661
    void *image_extra;
-
 
1662
 
-
 
1663
    if (unlikely (surface->status))
-
 
1664
	return surface->status;
-
 
1665
 
-
 
1666
    if (unlikely (surface->finished))
-
 
1667
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
-
 
1668
 
-
 
1669
#if CAIRO_HAS_TEE_SURFACE
-
 
1670
 
-
 
1671
    if (src->type == CAIRO_SURFACE_TYPE_TEE) {
-
 
1672
	cairo_surface_t *match;
-
 
1673
 
-
 
1674
	match = _cairo_tee_surface_find_match (src,
-
 
1675
					       surface->backend,
-
 
1676
					       src->content);
-
 
1677
	if (match != NULL)
-
 
1678
	    src = match;
-
 
1679
    }
-
 
1680
 
-
 
1681
#endif
-
 
1682
 
-
 
1683
    if (surface->backend->clone_similar != NULL) {
-
 
1684
	status = surface->backend->clone_similar (surface, src,
-
 
1685
						  src_x, src_y,
-
 
1686
						  width, height,
-
 
1687
						  clone_offset_x,
-
 
1688
						  clone_offset_y,
-
 
1689
						  clone_out);
-
 
1690
	if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-
 
1691
	    if (_cairo_surface_is_image (src))
-
 
1692
		return CAIRO_INT_STATUS_UNSUPPORTED;
-
 
1693
 
-
 
1694
	    /* First check to see if we can replay to a similar surface */
-
 
1695
	    if (_cairo_surface_is_recording (src)) {
-
 
1696
		return _cairo_recording_surface_clone_similar (surface, src,
-
 
1697
							       src_x, src_y,
-
 
1698
							       width, height,
-
 
1699
							       clone_offset_x,
-
 
1700
							       clone_offset_y,
-
 
1701
							       clone_out);
-
 
1702
	    }
-
 
1703
 
-
 
1704
	    /* If we failed, try again with an image surface */
-
 
1705
	    status = _cairo_surface_acquire_source_image (src, &image, &image_extra);
-
 
1706
	    if (status == CAIRO_STATUS_SUCCESS) {
-
 
1707
		status =
-
 
1708
		    surface->backend->clone_similar (surface, &image->base,
-
 
1709
						     src_x, src_y,
-
 
1710
						     width, height,
-
 
1711
						     clone_offset_x,
-
 
1712
						     clone_offset_y,
-
 
1713
						     clone_out);
-
 
1714
 
-
 
1715
		_cairo_surface_release_source_image (src, image, image_extra);
-
 
1716
	    }
-
 
1717
	}
-
 
1718
    }
-
 
1719
 
-
 
1720
    /* If we're still unsupported, hit our fallback path to get a clone */
-
 
1721
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-
 
1722
	status =
-
 
1723
	    _cairo_surface_fallback_clone_similar (surface, src,
-
 
1724
						   src_x, src_y,
-
 
1725
						   width, height,
-
 
1726
						   clone_offset_x,
-
 
1727
						   clone_offset_y,
-
 
1728
						   clone_out);
-
 
1729
    }
-
 
1730
 
-
 
1731
    if (unlikely (status))
-
 
1732
	return status;
-
 
1733
 
-
 
1734
    /* Update the clone's device_transform (which the underlying surface
-
 
1735
     * backend knows nothing about) */
-
 
1736
    if (*clone_out != src) {
-
 
1737
	(*clone_out)->device_transform = src->device_transform;
-
 
1738
	(*clone_out)->device_transform_inverse = src->device_transform_inverse;
-
 
1739
    }
-
 
1740
 
-
 
1741
    return status;
-
 
1742
}
-
 
1743
 
-
 
1744
/**
-
 
1745
 * _cairo_surface_is_similar
-
 
1746
 * @surface_a: a #cairo_surface_t
-
 
1747
 * @surface_b: a #cairo_surface_t
-
 
1748
 * @content: a #cairo_content_t
-
 
1749
 *
-
 
1750
 * Find out whether the given surfaces share the same backend,
-
 
1751
 * and if so, whether they can be considered similar.
-
 
1752
 *
-
 
1753
 * The definition of "similar" depends on the backend. In
-
 
1754
 * general, it means that the surface is equivalent to one
-
 
1755
 * that would have been generated by a call to cairo_surface_create_similar().
-
 
1756
 *
-
 
1757
 * Return value: %TRUE if the surfaces are similar.
-
 
1758
 **/
-
 
1759
cairo_bool_t
-
 
1760
_cairo_surface_is_similar (cairo_surface_t *surface_a,
-
 
1761
	                   cairo_surface_t *surface_b)
-
 
1762
{
-
 
1763
    if (surface_a->backend != surface_b->backend)
-
 
1764
	return FALSE;
-
 
1765
 
-
 
1766
    if (surface_a->backend->is_similar != NULL)
-
 
1767
	return surface_a->backend->is_similar (surface_a, surface_b);
-
 
1768
 
-
 
1769
    return TRUE;
-
 
1770
}
-
 
1771
 
-
 
1772
cairo_status_t
-
 
1773
_cairo_surface_composite (cairo_operator_t	op,
-
 
1774
			  const cairo_pattern_t	*src,
-
 
1775
			  const cairo_pattern_t	*mask,
-
 
1776
			  cairo_surface_t	*dst,
-
 
1777
			  int			src_x,
-
 
1778
			  int			src_y,
-
 
1779
			  int			mask_x,
-
 
1780
			  int			mask_y,
-
 
1781
			  int			dst_x,
-
 
1782
			  int			dst_y,
-
 
1783
			  unsigned int		width,
-
 
1784
			  unsigned int		height,
-
 
1785
			  cairo_region_t	*clip_region)
-
 
1786
{
-
 
1787
    cairo_int_status_t status;
-
 
1788
 
-
 
1789
    if (unlikely (dst->status))
-
 
1790
	return dst->status;
-
 
1791
 
-
 
1792
    assert (_cairo_surface_is_writable (dst));
-
 
1793
 
-
 
1794
    if (mask) {
-
 
1795
	/* These operators aren't interpreted the same way by the backends;
-
 
1796
	 * they are implemented in terms of other operators in cairo-gstate.c
-
 
1797
	 */
-
 
1798
	assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
-
 
1799
    }
-
 
1800
 
-
 
1801
    if (dst->backend->composite) {
-
 
1802
	status = dst->backend->composite (op,
-
 
1803
					  src, mask, dst,
-
 
1804
                                          src_x, src_y,
-
 
1805
                                          mask_x, mask_y,
-
 
1806
                                          dst_x, dst_y,
-
 
1807
					  width, height,
-
 
1808
					  clip_region);
-
 
1809
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-
 
1810
	    return _cairo_surface_set_error (dst, status);
-
 
1811
    }
-
 
1812
 
-
 
1813
    return _cairo_surface_set_error (dst,
-
 
1814
	    _cairo_surface_fallback_composite (op,
-
 
1815
					      src, mask, dst,
-
 
1816
					      src_x, src_y,
-
 
1817
					      mask_x, mask_y,
-
 
1818
					      dst_x, dst_y,
-
 
1819
					      width, height,
-
 
1820
					      clip_region));
-
 
1821
}
-
 
1822
 
-
 
1823
/**
-
 
1824
 * _cairo_surface_fill_rectangle:
-
 
1825
 * @surface: a #cairo_surface_t
-
 
1826
 * @op: the operator to apply to the rectangle
-
 
1827
 * @color: the source color
-
 
1828
 * @x: X coordinate of rectangle, in backend coordinates
-
 
1829
 * @y: Y coordinate of rectangle, in backend coordinates
-
 
1830
 * @width: width of rectangle, in backend coordinates
-
 
1831
 * @height: height of rectangle, in backend coordinates
-
 
1832
 *
-
 
1833
 * Applies an operator to a rectangle using a solid color as the source.
-
 
1834
 * See _cairo_surface_fill_rectangles() for full details.
-
 
1835
 *
-
 
1836
 * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
-
 
1837
 **/
-
 
1838
cairo_status_t
-
 
1839
_cairo_surface_fill_rectangle (cairo_surface_t	   *surface,
-
 
1840
			       cairo_operator_t	    op,
-
 
1841
			       const cairo_color_t *color,
-
 
1842
			       int		    x,
-
 
1843
			       int		    y,
-
 
1844
			       int		    width,
-
 
1845
			       int		    height)
-
 
1846
{
-
 
1847
    cairo_rectangle_int_t rect;
-
 
1848
 
-
 
1849
    if (surface->status)
-
 
1850
	return surface->status;
-
 
1851
 
-
 
1852
    assert (_cairo_surface_is_writable (surface));
-
 
1853
 
-
 
1854
    rect.x = x;
-
 
1855
    rect.y = y;
-
 
Line 1856... Line 1935...
1856
    rect.width = width;
1935
{
-
 
1936
    cairo_status_t ignored;
1857
    rect.height = height;
1937
 
Line 1858... Line -...
1858
 
-
 
1859
    return _cairo_surface_fill_rectangles (surface, op, color, &rect, 1);
-
 
1860
}
-
 
1861
 
-
 
1862
/**
-
 
1863
 * _cairo_surface_fill_region:
-
 
1864
 * @surface: a #cairo_surface_t
-
 
1865
 * @op: the operator to apply to the region
-
 
1866
 * @color: the source color
-
 
1867
 * @region: the region to modify, in backend coordinates
-
 
1868
 *
-
 
1869
 * Applies an operator to a set of rectangles specified as a
-
 
1870
 * #cairo_region_t using a solid color as the source.
-
 
1871
 * See _cairo_surface_fill_rectangles() for full details.
-
 
1872
 *
-
 
1873
 * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
-
 
1874
 **/
-
 
1875
cairo_status_t
-
 
1876
_cairo_surface_fill_region (cairo_surface_t	   *surface,
-
 
1877
			    cairo_operator_t	    op,
-
 
1878
			    const cairo_color_t    *color,
-
 
1879
			    cairo_region_t         *region)
-
 
1880
{
-
 
1881
    int num_rects;
-
 
1882
    cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
-
 
1883
    cairo_rectangle_int_t *rects = stack_rects;
-
 
1884
    cairo_status_t status;
-
 
1885
    int i;
-
 
1886
 
-
 
1887
    if (surface->status)
-
 
1888
	return surface->status;
-
 
1889
 
-
 
1890
    assert (_cairo_surface_is_writable (surface));
-
 
Line 1891... Line 1938...
1891
 
1938
    ignored = _cairo_surface_unmap_image (surface, image);
1892
    num_rects = cairo_region_num_rectangles (region);
1939
    (void)ignored;
1893
    if (num_rects == 0)
1940
}
1894
	return CAIRO_STATUS_SUCCESS;
1941
 
1895
 
-
 
1896
    /* catch a common reduction of _cairo_clip_combine_with_surface() */
-
 
1897
    if (op == CAIRO_OPERATOR_IN &&
-
 
1898
	_cairo_color_equal (color, CAIRO_COLOR_WHITE))
-
 
1899
    {
-
 
1900
	return CAIRO_STATUS_SUCCESS;
1942
 
1901
    }
-
 
1902
 
1943
cairo_surface_t *
1903
    if (num_rects > ARRAY_LENGTH (stack_rects)) {
-
 
1904
	rects = _cairo_malloc_ab (num_rects,
-
 
1905
				  sizeof (cairo_rectangle_int_t));
1944
_cairo_surface_get_source (cairo_surface_t *surface,
Line 1906... Line -...
1906
	if (rects == NULL) {
-
 
1907
	    return _cairo_surface_set_error (surface,
-
 
1908
					     _cairo_error (CAIRO_STATUS_NO_MEMORY));
-
 
1909
	}
-
 
1910
    }
-
 
1911
 
-
 
1912
    for (i = 0; i < num_rects; i++)
-
 
1913
	cairo_region_get_rectangle (region, i, &rects[i]);
-
 
1914
 
-
 
1915
    status =  _cairo_surface_fill_rectangles (surface,
-
 
1916
					      op, color, rects, num_rects);
-
 
1917
 
-
 
1918
    if (rects != stack_rects)
-
 
1919
	free (rects);
-
 
1920
 
-
 
1921
    return _cairo_surface_set_error (surface, status);
-
 
1922
}
-
 
1923
 
-
 
1924
/**
-
 
1925
 * _cairo_surface_fill_rectangles:
-
 
1926
 * @surface: a #cairo_surface_t
-
 
1927
 * @op: the operator to apply to the region
-
 
1928
 * @color: the source color
-
 
1929
 * @rects: the rectangles to modify, in backend coordinates
-
 
1930
 * @num_rects: the number of rectangles in @rects
-
 
1931
 *
-
 
1932
 * Applies an operator to a set of rectangles using a solid color
-
 
1933
 * as the source. Note that even if the operator is an unbounded operator
-
 
1934
 * such as %CAIRO_OPERATOR_IN, only the given set of rectangles
1945
			   cairo_rectangle_int_t *extents)
1935
 * is affected. This differs from _cairo_surface_composite_trapezoids()
1946
{
1936
 * where the entire destination rectangle is cleared.
-
 
1937
 *
-
 
1938
 * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
1947
    assert (surface->backend->source);
1939
 **/
-
 
1940
cairo_status_t
1948
    return surface->backend->source (surface, extents);
1941
_cairo_surface_fill_rectangles (cairo_surface_t		*surface,
-
 
1942
				cairo_operator_t         op,
-
 
1943
				const cairo_color_t	*color,
-
 
1944
				cairo_rectangle_int_t	*rects,
-
 
1945
				int			 num_rects)
-
 
1946
{
-
 
1947
    cairo_int_status_t status;
-
 
1948
 
1949
}
1949
    if (surface->status)
-
 
1950
	return surface->status;
-
 
1951
 
-
 
1952
    assert (_cairo_surface_is_writable (surface));
-
 
1953
 
-
 
1954
    if (num_rects == 0)
-
 
1955
	return CAIRO_STATUS_SUCCESS;
-
 
1956
 
1950
 
1957
    if (surface->backend->fill_rectangles) {
-
 
1958
	status = surface->backend->fill_rectangles (surface,
-
 
1959
						    op, color,
-
 
1960
						    rects, num_rects);
-
 
1961
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-
 
1962
	    return _cairo_surface_set_error (surface, status);
1951
cairo_surface_t *
1963
    }
1952
_cairo_surface_default_source (void *surface,
Line 1964... Line 1953...
1964
 
1953
			       cairo_rectangle_int_t *extents)
1965
    return _cairo_surface_set_error (surface,
1954
{
1966
	    _cairo_surface_fallback_fill_rectangles (surface,
1955
    if (extents)
Line 1987... Line 1976...
1987
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
1976
	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
Line 1988... Line 1977...
1988
 
1977
 
1989
    return CAIRO_STATUS_SUCCESS;
1978
    return CAIRO_STATUS_SUCCESS;
Line -... Line 1979...
-
 
1979
}
-
 
1980
 
-
 
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;
1990
}
2001
}
1991
 
2002
 
1992
cairo_status_t
2003
cairo_status_t
1993
_cairo_surface_paint (cairo_surface_t	*surface,
2004
_cairo_surface_paint (cairo_surface_t		*surface,
1994
		      cairo_operator_t	 op,
2005
		      cairo_operator_t		 op,
1995
		      const cairo_pattern_t *source,
2006
		      const cairo_pattern_t	*source,
1996
		      cairo_clip_t	    *clip)
2007
		      const cairo_clip_t	*clip)
Line -... Line 2008...
-
 
2008
{
1997
{
2009
    cairo_int_status_t status;
1998
    cairo_status_t status;
2010
 
-
 
2011
    TRACE ((stderr, "%s\n", __FUNCTION__));
-
 
2012
    if (unlikely (surface->status))
Line 1999... Line 2013...
1999
 
2013
	return surface->status;
2000
    if (unlikely (surface->status))
2014
    if (unlikely (surface->finished))
Line 2001... Line 2015...
2001
	return surface->status;
2015
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
-
 
2016
 
2002
 
2017
    if (_cairo_clip_is_all_clipped (clip))
Line 2003... Line -...
2003
    if (clip && clip->all_clipped)
-
 
2004
	return CAIRO_STATUS_SUCCESS;
2018
	return CAIRO_STATUS_SUCCESS;
2005
 
-
 
2006
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
2019
 
2007
	return CAIRO_STATUS_SUCCESS;
-
 
Line 2008... Line 2020...
2008
 
2020
    status = _pattern_has_error (source);
2009
    if (op == CAIRO_OPERATOR_OVER &&
2021
    if (unlikely (status))
2010
	_cairo_pattern_is_clear (source))
2022
	return status;
Line 2011... Line -...
2011
    {
-
 
2012
	return CAIRO_STATUS_SUCCESS;
-
 
2013
    }
-
 
2014
 
2023
 
2015
    status = _pattern_has_error (source);
2024
    if (nothing_to_do (surface, op, source))
2016
    if (unlikely (status))
-
 
2017
	return status;
-
 
2018
 
-
 
2019
    _cairo_surface_begin_modification (surface);
-
 
2020
 
-
 
2021
    if (surface->backend->paint != NULL) {
-
 
2022
	status = surface->backend->paint (surface, op, source, clip);
2025
	return CAIRO_STATUS_SUCCESS;
-
 
2026
 
-
 
2027
    status = _cairo_surface_begin_modification (surface);
Line 2023... Line 2028...
2023
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
2028
    if (unlikely (status))
2024
            goto FINISH;
2029
	return status;
Line 2025... Line 2030...
2025
    }
2030
 
2026
 
2031
    status = surface->backend->paint (surface, op, source, clip);
2027
    status = _cairo_surface_fallback_paint (surface, op, source, clip);
2032
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2028
 
2033
	surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
2029
 FINISH:
2034
	surface->serial++;
2030
    surface->is_clear = op == CAIRO_OPERATOR_CLEAR && clip == NULL;
2035
    }
2031
 
2036
 
2032
    return _cairo_surface_set_error (surface, status);
2037
    return _cairo_surface_set_error (surface, status);
Line -... Line 2038...
-
 
2038
}
2033
}
2039
 
2034
 
2040
cairo_status_t
-
 
2041
_cairo_surface_mask (cairo_surface_t		*surface,
-
 
2042
		     cairo_operator_t		 op,
Line 2035... Line 2043...
2035
cairo_status_t
2043
		     const cairo_pattern_t	*source,
2036
_cairo_surface_mask (cairo_surface_t		*surface,
-
 
2037
		     cairo_operator_t		 op,
-
 
2038
		     const cairo_pattern_t	*source,
-
 
2039
		     const cairo_pattern_t	*mask,
2044
		     const cairo_pattern_t	*mask,
Line 2040... Line 2045...
2040
		     cairo_clip_t		*clip)
2045
		     const cairo_clip_t		*clip)
2041
{
2046
{
2042
    cairo_status_t status;
2047
    cairo_int_status_t status;
2043
 
2048
 
2044
    if (unlikely (surface->status))
2049
    TRACE ((stderr, "%s\n", __FUNCTION__));
2045
	return surface->status;
2050
    if (unlikely (surface->status))
Line 2046... Line -...
2046
 
-
 
2047
    if (clip && clip->all_clipped)
-
 
2048
	return CAIRO_STATUS_SUCCESS;
-
 
2049
 
-
 
2050
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
-
 
2051
	return CAIRO_STATUS_SUCCESS;
-
 
2052
 
2051
	return surface->status;
2053
    /* If the mask is blank, this is just an expensive no-op */
2052
    if (unlikely (surface->finished))
2054
    if (_cairo_pattern_is_clear (mask) &&
2053
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
Line 2055... Line 2054...
2055
	_cairo_operator_bounded_by_mask (op))
2054
 
2056
    {
2055
    if (_cairo_clip_is_all_clipped (clip))
2057
	return CAIRO_STATUS_SUCCESS;
2056
	return CAIRO_STATUS_SUCCESS;
Line 2058... Line 2057...
2058
    }
2057
 
2059
 
-
 
2060
    if (op == CAIRO_OPERATOR_OVER &&
-
 
2061
	_cairo_pattern_is_clear (source))
-
 
2062
    {
2058
    /* If the mask is blank, this is just an expensive no-op */
2063
	return CAIRO_STATUS_SUCCESS;
-
 
2064
    }
-
 
Line 2065... Line 2059...
2065
 
2059
    if (_cairo_pattern_is_clear (mask) &&
-
 
2060
	_cairo_operator_bounded_by_mask (op))
-
 
2061
    {
Line -... Line 2062...
-
 
2062
	return CAIRO_STATUS_SUCCESS;
2066
    status = _pattern_has_error (source);
2063
    }
2067
    if (unlikely (status))
2064
 
-
 
2065
    status = _pattern_has_error (source);
-
 
2066
    if (unlikely (status))
Line 2068... Line 2067...
2068
	return status;
2067
	return status;
2069
 
2068
 
Line 2070... Line 2069...
2070
    status = _pattern_has_error (mask);
2069
    status = _pattern_has_error (mask);
Line 2100... Line 2099...
2100
			    const cairo_stroke_style_t    *stroke_style,
2099
			    const cairo_stroke_style_t    *stroke_style,
2101
			    const cairo_matrix_t	    *stroke_ctm,
2100
			    const cairo_matrix_t	    *stroke_ctm,
2102
			    const cairo_matrix_t	    *stroke_ctm_inverse,
2101
			    const cairo_matrix_t	    *stroke_ctm_inverse,
2103
			    double		     stroke_tolerance,
2102
			    double		     stroke_tolerance,
2104
			    cairo_antialias_t	     stroke_antialias,
2103
			    cairo_antialias_t	     stroke_antialias,
2105
			    cairo_clip_t	    *clip)
2104
			    const cairo_clip_t	    *clip)
2106
{
2105
{
2107
    cairo_status_t status;
2106
    cairo_int_status_t status;
Line -... Line 2107...
-
 
2107
 
2108
 
2108
    TRACE ((stderr, "%s\n", __FUNCTION__));
2109
    if (unlikely (surface->status))
2109
    if (unlikely (surface->status))
-
 
2110
	return surface->status;
-
 
2111
    if (unlikely (surface->finished))
Line 2110... Line 2112...
2110
	return surface->status;
2112
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2111
 
2113
 
Line 2112... Line 2114...
2112
    if (clip && clip->all_clipped)
2114
    if (_cairo_clip_is_all_clipped (clip))
2113
	return CAIRO_STATUS_SUCCESS;
2115
	return CAIRO_STATUS_SUCCESS;
2114
 
2116
 
Line 2125... Line 2127...
2125
 
2127
 
2126
    status = _pattern_has_error (stroke_source);
2128
    status = _pattern_has_error (stroke_source);
2127
    if (unlikely (status))
2129
    if (unlikely (status))
Line 2128... Line 2130...
2128
	return status;
2130
	return status;
-
 
2131
 
-
 
2132
    status = _cairo_surface_begin_modification (surface);
Line 2129... Line 2133...
2129
 
2133
    if (unlikely (status))
2130
    _cairo_surface_begin_modification (surface);
2134
	return status;
2131
 
2135
 
Line 2159... Line 2163...
2159
				    clip);
2163
				    clip);
2160
    if (unlikely (status))
2164
    if (unlikely (status))
2161
	goto FINISH;
2165
	goto FINISH;
Line 2162... Line 2166...
2162
 
2166
 
-
 
2167
  FINISH:
2163
  FINISH:
2168
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
-
 
2169
	surface->is_clear = FALSE;
-
 
2170
	surface->serial++;
Line 2164... Line 2171...
2164
    surface->is_clear = FALSE;
2171
    }
2165
 
2172
 
Line 2166... Line 2173...
2166
    return _cairo_surface_set_error (surface, status);
2173
    return _cairo_surface_set_error (surface, status);
2167
}
2174
}
2168
 
2175
 
2169
cairo_status_t
2176
cairo_status_t
2170
_cairo_surface_stroke (cairo_surface_t		*surface,
2177
_cairo_surface_stroke (cairo_surface_t			*surface,
2171
		       cairo_operator_t		 op,
2178
		       cairo_operator_t			 op,
2172
		       const cairo_pattern_t	*source,
2179
		       const cairo_pattern_t		*source,
2173
		       cairo_path_fixed_t	*path,
2180
		       const cairo_path_fixed_t		*path,
2174
		       const cairo_stroke_style_t	*stroke_style,
2181
		       const cairo_stroke_style_t	*stroke_style,
2175
		       const cairo_matrix_t		*ctm,
2182
		       const cairo_matrix_t		*ctm,
2176
		       const cairo_matrix_t		*ctm_inverse,
2183
		       const cairo_matrix_t		*ctm_inverse,
2177
		       double			 tolerance,
2184
		       double				 tolerance,
2178
		       cairo_antialias_t	 antialias,
2185
		       cairo_antialias_t		 antialias,
Line -... Line 2186...
-
 
2186
		       const cairo_clip_t		*clip)
2179
		       cairo_clip_t		*clip)
2187
{
2180
{
2188
    cairo_int_status_t status;
-
 
2189
 
-
 
2190
    TRACE ((stderr, "%s\n", __FUNCTION__));
Line 2181... Line 2191...
2181
    cairo_status_t status;
2191
    if (unlikely (surface->status))
2182
 
2192
	return surface->status;
Line 2183... Line 2193...
2183
    if (unlikely (surface->status))
2193
    if (unlikely (surface->finished))
-
 
2194
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2184
	return surface->status;
2195
 
Line 2185... Line -...
2185
 
-
 
2186
    if (clip && clip->all_clipped)
2196
    if (_cairo_clip_is_all_clipped (clip))
2187
	return CAIRO_STATUS_SUCCESS;
-
 
2188
 
2197
	return CAIRO_STATUS_SUCCESS;
2189
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
-
 
Line 2190... Line 2198...
2190
	return CAIRO_STATUS_SUCCESS;
2198
 
2191
 
2199
    status = _pattern_has_error (source);
2192
    if (op == CAIRO_OPERATOR_OVER &&
2200
    if (unlikely (status))
Line 2193... Line -...
2193
	_cairo_pattern_is_clear (source))
-
 
2194
    {
-
 
2195
	return CAIRO_STATUS_SUCCESS;
-
 
2196
    }
2201
	return status;
2197
 
2202
 
2198
    status = _pattern_has_error (source);
2203
    if (nothing_to_do (surface, op, source))
2199
    if (unlikely (status))
2204
	return CAIRO_STATUS_SUCCESS;
2200
	return status;
2205
 
2201
 
-
 
2202
    _cairo_surface_begin_modification (surface);
2206
    status = _cairo_surface_begin_modification (surface);
2203
 
-
 
2204
    if (surface->backend->stroke != NULL) {
-
 
2205
	status = surface->backend->stroke (surface, op, source,
-
 
2206
					   path, stroke_style,
-
 
2207
					   ctm, ctm_inverse,
-
 
2208
					   tolerance, antialias,
-
 
2209
					   clip);
-
 
2210
 
-
 
2211
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-
 
2212
            goto FINISH;
-
 
2213
    }
2207
    if (unlikely (status))
-
 
2208
	return status;
-
 
2209
 
Line 2214... Line 2210...
2214
 
2210
    status = surface->backend->stroke (surface, op, source,
2215
    status = _cairo_surface_fallback_stroke (surface, op, source,
2211
				       path, stroke_style,
Line 2216... Line 2212...
2216
                                             path, stroke_style,
2212
				       ctm, ctm_inverse,
2217
                                             ctm, ctm_inverse,
2213
				       tolerance, antialias,
2218
                                             tolerance, antialias,
2214
				       clip);
2219
					     clip);
2215
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2220
 
2216
	surface->is_clear = FALSE;
2221
 FINISH:
2217
	surface->serial++;
2222
    surface->is_clear = FALSE;
2218
    }
2223
 
2219
 
2224
    return _cairo_surface_set_error (surface, status);
2220
    return _cairo_surface_set_error (surface, status);
2225
}
2221
}
2226
 
2222
 
Line -... Line 2223...
-
 
2223
cairo_status_t
2227
cairo_status_t
2224
_cairo_surface_fill (cairo_surface_t		*surface,
2228
_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,
Line 2229... Line 2228...
2229
		     cairo_operator_t	 op,
2228
		     cairo_fill_rule_t		 fill_rule,
2230
		     const cairo_pattern_t *source,
2229
		     double			 tolerance,
Line 2231... Line 2230...
2231
		     cairo_path_fixed_t	*path,
2230
		     cairo_antialias_t		 antialias,
-
 
2231
		     const cairo_clip_t		*clip)
2232
		     cairo_fill_rule_t	 fill_rule,
2232
{
Line 2233... Line -...
2233
		     double		 tolerance,
-
 
2234
		     cairo_antialias_t	 antialias,
2233
    cairo_int_status_t status;
2235
		     cairo_clip_t	*clip)
-
 
2236
{
2234
 
2237
    cairo_status_t status;
-
 
Line 2238... Line 2235...
2238
 
2235
    TRACE ((stderr, "%s\n", __FUNCTION__));
2239
    if (unlikely (surface->status))
2236
    if (unlikely (surface->status))
2240
	return surface->status;
2237
	return surface->status;
Line 2241... Line -...
2241
 
-
 
2242
    if (clip && clip->all_clipped)
-
 
2243
	return CAIRO_STATUS_SUCCESS;
-
 
2244
 
2238
    if (unlikely (surface->finished))
2245
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
2239
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2246
	return CAIRO_STATUS_SUCCESS;
2240
 
2247
 
2241
    if (_cairo_clip_is_all_clipped (clip))
2248
    if (op == CAIRO_OPERATOR_OVER &&
-
 
2249
	_cairo_pattern_is_clear (source))
2242
	return CAIRO_STATUS_SUCCESS;
2250
    {
-
 
2251
	return CAIRO_STATUS_SUCCESS;
-
 
2252
    }
-
 
2253
 
-
 
2254
    status = _pattern_has_error (source);
-
 
2255
    if (unlikely (status))
-
 
2256
	return status;
-
 
2257
 
-
 
2258
    _cairo_surface_begin_modification (surface);
-
 
2259
 
2243
 
2260
    if (surface->backend->fill != NULL) {
-
 
2261
	status = surface->backend->fill (surface, op, source,
2244
    status = _pattern_has_error (source);
2262
					 path, fill_rule,
2245
    if (unlikely (status))
Line 2263... Line -...
2263
					 tolerance, antialias,
-
 
2264
					 clip);
-
 
2265
 
-
 
2266
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-
 
2267
            goto FINISH;
-
 
2268
    }
-
 
2269
 
-
 
2270
    status = _cairo_surface_fallback_fill (surface, op, source,
-
 
2271
                                           path, fill_rule,
-
 
2272
                                           tolerance, antialias,
-
 
2273
					   clip);
-
 
2274
 
-
 
2275
 FINISH:
-
 
2276
    surface->is_clear = FALSE;
-
 
2277
 
-
 
2278
    return _cairo_surface_set_error (surface, status);
-
 
2279
}
-
 
2280
 
-
 
2281
cairo_status_t
-
 
2282
_cairo_surface_composite_trapezoids (cairo_operator_t		op,
-
 
2283
				     const cairo_pattern_t	*pattern,
-
 
2284
				     cairo_surface_t		*dst,
-
 
2285
				     cairo_antialias_t		antialias,
-
 
2286
				     int			src_x,
-
 
2287
				     int			src_y,
-
 
2288
				     int			dst_x,
-
 
2289
				     int			dst_y,
-
 
2290
				     unsigned int		width,
-
 
2291
				     unsigned int		height,
-
 
2292
				     cairo_trapezoid_t		*traps,
-
 
2293
				     int			num_traps,
-
 
2294
				     cairo_region_t		*clip_region)
-
 
2295
{
-
 
2296
    cairo_int_status_t status;
-
 
2297
 
-
 
2298
    if (dst->status)
-
 
2299
	return dst->status;
-
 
2300
 
2246
	return status;
2301
    assert (_cairo_surface_is_writable (dst));
-
 
2302
 
-
 
2303
    /* These operators aren't interpreted the same way by the backends;
-
 
2304
     * they are implemented in terms of other operators in cairo-gstate.c
-
 
2305
     */
-
 
2306
    assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
-
 
2307
 
-
 
2308
    if (dst->backend->composite_trapezoids) {
-
 
2309
	status = dst->backend->composite_trapezoids (op,
-
 
2310
						     pattern, dst,
-
 
2311
						     antialias,
-
 
2312
						     src_x, src_y,
-
 
2313
                                                     dst_x, dst_y,
-
 
2314
						     width, height,
-
 
2315
						     traps, num_traps,
-
 
2316
						     clip_region);
-
 
2317
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
-
 
2318
	    return _cairo_surface_set_error (dst, status);
-
 
2319
    }
-
 
2320
 
-
 
2321
    return  _cairo_surface_set_error (dst,
-
 
2322
	    _cairo_surface_fallback_composite_trapezoids (op, pattern, dst,
-
 
2323
							  antialias,
-
 
2324
							  src_x, src_y,
-
 
2325
							  dst_x, dst_y,
-
 
2326
							  width, height,
-
 
2327
							  traps, num_traps,
-
 
2328
							  clip_region));
-
 
2329
}
-
 
2330
 
-
 
2331
cairo_span_renderer_t *
-
 
2332
_cairo_surface_create_span_renderer (cairo_operator_t		 op,
-
 
2333
				     const cairo_pattern_t	*pattern,
-
 
2334
				     cairo_surface_t		*dst,
-
 
2335
				     cairo_antialias_t	         antialias,
-
 
2336
				     const cairo_composite_rectangles_t *rects,
-
 
2337
				     cairo_region_t		*clip_region)
-
 
2338
{
-
 
2339
    assert (dst->snapshot_of == NULL);
-
 
2340
 
-
 
2341
    if (unlikely (dst->status))
-
 
2342
	return _cairo_span_renderer_create_in_error (dst->status);
-
 
2343
 
-
 
2344
    if (unlikely (dst->finished))
-
 
2345
	return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED);
-
 
2346
 
-
 
2347
    if (dst->backend->create_span_renderer) {
-
 
2348
	return dst->backend->create_span_renderer (op,
-
 
2349
						   pattern, dst,
-
 
2350
						   antialias,
-
 
2351
						   rects,
-
 
2352
						   clip_region);
-
 
2353
    }
-
 
2354
    ASSERT_NOT_REACHED;
-
 
2355
    return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED);
-
 
2356
}
-
 
2357
 
-
 
2358
cairo_bool_t
2247
 
Line 2359... Line 2248...
2359
_cairo_surface_check_span_renderer (cairo_operator_t		 op,
2248
    if (nothing_to_do (surface, op, source))
2360
				    const cairo_pattern_t	*pattern,
2249
	return CAIRO_STATUS_SUCCESS;
2361
				    cairo_surface_t		*dst,
2250
 
Line 2386... Line 2275...
2386
 *
2275
 *
2387
 * There is a convenience function for this that takes a #cairo_t,
2276
 * There is a convenience function for this that takes a #cairo_t,
2388
 * namely cairo_copy_page().
2277
 * namely cairo_copy_page().
2389
 *
2278
 *
2390
 * Since: 1.6
2279
 * Since: 1.6
2391
 */
2280
 **/
2392
void
2281
void
2393
cairo_surface_copy_page (cairo_surface_t *surface)
2282
cairo_surface_copy_page (cairo_surface_t *surface)
2394
{
2283
{
2395
    cairo_status_t status_ignored;
-
 
2396
 
-
 
2397
    if (surface->status)
2284
    if (unlikely (surface->status))
2398
	return;
2285
	return;
Line 2399... Line 2286...
2399
 
2286
 
Line 2400... Line 2287...
2400
    assert (surface->snapshot_of == NULL);
2287
    assert (surface->snapshot_of == NULL);
2401
 
-
 
2402
    if (surface->finished) {
2288
 
2403
	status_ignored = _cairo_surface_set_error (surface,
2289
    if (unlikely (surface->finished)) {
2404
		                                 CAIRO_STATUS_SURFACE_FINISHED);
2290
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
Line 2405... Line 2291...
2405
	return;
2291
	return;
2406
    }
2292
    }
2407
 
2293
 
Line 2408... Line -...
2408
    /* It's fine if some backends don't implement copy_page */
-
 
2409
    if (surface->backend->copy_page == NULL)
2294
    /* It's fine if some backends don't implement copy_page */
2410
	return;
2295
    if (surface->backend->copy_page == NULL)
2411
 
2296
	return;
Line 2412... Line 2297...
2412
    status_ignored = _cairo_surface_set_error (surface,
2297
 
2413
			                 surface->backend->copy_page (surface));
2298
    _cairo_surface_set_error (surface, surface->backend->copy_page (surface));
Line 2427... Line 2312...
2427
 * Since: 1.6
2312
 * Since: 1.6
2428
 **/
2313
 **/
2429
void
2314
void
2430
cairo_surface_show_page (cairo_surface_t *surface)
2315
cairo_surface_show_page (cairo_surface_t *surface)
2431
{
2316
{
2432
    cairo_status_t status_ignored;
2317
    cairo_status_t status;
Line 2433... Line 2318...
2433
 
2318
 
2434
    if (surface->status)
2319
    if (unlikely (surface->status))
Line 2435... Line 2320...
2435
	return;
2320
	return;
2436
 
-
 
2437
    if (surface->finished) {
2321
 
2438
	status_ignored = _cairo_surface_set_error (surface,
2322
    if (unlikely (surface->finished)) {
2439
		                                 CAIRO_STATUS_SURFACE_FINISHED);
2323
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
Line 2440... Line 2324...
2440
	return;
2324
	return;
-
 
2325
    }
-
 
2326
 
-
 
2327
    status = _cairo_surface_begin_modification (surface);
-
 
2328
    if (unlikely (status)) {
Line 2441... Line 2329...
2441
    }
2329
	_cairo_surface_set_error (surface, status);
2442
 
2330
	return;
2443
    _cairo_surface_begin_modification (surface);
2331
    }
Line 2444... Line -...
2444
 
-
 
2445
    /* It's fine if some backends don't implement show_page */
2332
 
2446
    if (surface->backend->show_page == NULL)
2333
    /* It's fine if some backends don't implement show_page */
2447
	return;
2334
    if (surface->backend->show_page == NULL)
Line 2448... Line 2335...
2448
 
2335
	return;
2449
    status_ignored = _cairo_surface_set_error (surface,
2336
 
Line 2472... Line 2359...
2472
 * current callers are within the surface layer where backend space is
2359
 * current callers are within the surface layer where backend space is
2473
 * desired.
2360
 * desired.
2474
 *
2361
 *
2475
 * This behavior would have to be changed is we ever exported a public
2362
 * This behavior would have to be changed is we ever exported a public
2476
 * variant of this function.
2363
 * variant of this function.
2477
 */
2364
 **/
2478
cairo_bool_t
2365
cairo_bool_t
2479
_cairo_surface_get_extents (cairo_surface_t         *surface,
2366
_cairo_surface_get_extents (cairo_surface_t         *surface,
2480
			    cairo_rectangle_int_t   *extents)
2367
			    cairo_rectangle_int_t   *extents)
2481
{
2368
{
2482
    cairo_bool_t bounded;
2369
    cairo_bool_t bounded;
Line -... Line 2370...
-
 
2370
 
-
 
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
    }
2483
 
2377
 
2484
    bounded = FALSE;
2378
    bounded = FALSE;
2485
    if (surface->backend->get_extents != NULL)
2379
    if (surface->backend->get_extents != NULL)
Line 2486... Line 2380...
2486
	bounded = surface->backend->get_extents (surface, extents);
2380
	bounded = surface->backend->get_extents (surface, extents);
2487
 
2381
 
Line 2488... Line 2382...
2488
    if (! bounded)
2382
    if (! bounded)
-
 
2383
	_cairo_unbounded_rectangle_init (extents);
-
 
2384
 
-
 
2385
    return bounded;
-
 
2386
 
-
 
2387
zero_extents:
2489
	_cairo_unbounded_rectangle_init (extents);
2388
    extents->x = extents->y = 0;
Line 2490... Line 2389...
2490
 
2389
    extents->width = extents->height = 0;
2491
    return bounded;
2390
    return TRUE;
2492
}
2391
}
Line 2513... Line 2412...
2513
 * Since: 1.8
2412
 * Since: 1.8
2514
 **/
2413
 **/
2515
cairo_bool_t
2414
cairo_bool_t
2516
cairo_surface_has_show_text_glyphs (cairo_surface_t	    *surface)
2415
cairo_surface_has_show_text_glyphs (cairo_surface_t	    *surface)
2517
{
2416
{
2518
    cairo_status_t status_ignored;
-
 
2519
 
-
 
2520
    if (surface->status)
2417
    if (unlikely (surface->status))
2521
	return FALSE;
2418
	return FALSE;
Line 2522... Line 2419...
2522
 
2419
 
2523
    if (surface->finished) {
-
 
2524
	status_ignored = _cairo_surface_set_error (surface,
2420
    if (unlikely (surface->finished)) {
2525
						   CAIRO_STATUS_SURFACE_FINISHED);
2421
	_cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
2526
	return FALSE;
2422
	return FALSE;
Line 2527... Line 2423...
2527
    }
2423
    }
2528
 
2424
 
Line 2558... Line 2454...
2558
				 int			     num_glyphs,
2454
				 int			     num_glyphs,
2559
				 const cairo_text_cluster_t *clusters,
2455
				 const cairo_text_cluster_t *clusters,
2560
				 int			     num_clusters,
2456
				 int			     num_clusters,
2561
				 cairo_text_cluster_flags_t  cluster_flags,
2457
				 cairo_text_cluster_flags_t  cluster_flags,
2562
				 cairo_scaled_font_t	    *scaled_font,
2458
				 cairo_scaled_font_t	    *scaled_font,
2563
				 cairo_clip_t		    *clip)
2459
				 const cairo_clip_t		*clip)
2564
{
2460
{
2565
    cairo_status_t status;
2461
    cairo_int_status_t status;
2566
    cairo_scaled_font_t *dev_scaled_font = scaled_font;
2462
    cairo_scaled_font_t *dev_scaled_font = scaled_font;
Line -... Line 2463...
-
 
2463
 
2567
 
2464
    TRACE ((stderr, "%s\n", __FUNCTION__));
2568
    if (unlikely (surface->status))
2465
    if (unlikely (surface->status))
-
 
2466
	return surface->status;
-
 
2467
    if (unlikely (surface->finished))
Line 2569... Line 2468...
2569
	return surface->status;
2468
	return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
2570
 
2469
 
Line 2571... Line 2470...
2571
    if (num_glyphs == 0 && utf8_len == 0)
2470
    if (num_glyphs == 0 && utf8_len == 0)
2572
	return CAIRO_STATUS_SUCCESS;
-
 
2573
 
-
 
2574
    if (clip && clip->all_clipped)
-
 
2575
	return CAIRO_STATUS_SUCCESS;
2471
	return CAIRO_STATUS_SUCCESS;
Line 2576... Line 2472...
2576
 
2472
 
2577
    if (op == CAIRO_OPERATOR_CLEAR && surface->is_clear)
2473
    if (_cairo_clip_is_all_clipped (clip))
2578
	return CAIRO_STATUS_SUCCESS;
2474
	return CAIRO_STATUS_SUCCESS;
Line -... Line 2475...
-
 
2475
 
-
 
2476
    status = _pattern_has_error (source);
-
 
2477
    if (unlikely (status))
2579
 
2478
	return status;
-
 
2479
 
-
 
2480
    if (nothing_to_do (surface, op, source))
Line 2580... Line 2481...
2580
    status = _pattern_has_error (source);
2481
	return CAIRO_STATUS_SUCCESS;
2581
    if (unlikely (status))
2482
 
2582
	return status;
2483
    status = _cairo_surface_begin_modification (surface);
2583
 
2484
    if (unlikely (status))
Line 2619... Line 2520...
2619
							 clip);
2520
							 clip);
2620
	}
2521
	}
2621
	if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
2522
	if (status == CAIRO_INT_STATUS_UNSUPPORTED &&
2622
	    surface->backend->show_glyphs)
2523
	    surface->backend->show_glyphs)
2623
	{
2524
	{
2624
	    int remaining_glyphs = num_glyphs;
-
 
2625
	    status = surface->backend->show_glyphs (surface, op,
2525
	    status = surface->backend->show_glyphs (surface, op,
2626
						    source,
2526
						    source,
2627
						    glyphs, num_glyphs,
2527
						    glyphs, num_glyphs,
2628
						    dev_scaled_font,
2528
						    dev_scaled_font,
2629
						    clip,
2529
						    clip);
2630
						    &remaining_glyphs);
-
 
2631
	    glyphs += num_glyphs - remaining_glyphs;
-
 
2632
	    num_glyphs = remaining_glyphs;
-
 
2633
	    if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
-
 
2634
		status = CAIRO_STATUS_SUCCESS;
-
 
2635
	}
2530
	}
2636
    } else {
2531
    } else {
2637
	/* A mere show_glyphs call.  Try show_glyphs backend method first */
2532
	/* A mere show_glyphs call.  Try show_glyphs backend method first */
2638
	if (surface->backend->show_glyphs != NULL) {
2533
	if (surface->backend->show_glyphs != NULL) {
2639
	    int remaining_glyphs = num_glyphs;
-
 
2640
	    status = surface->backend->show_glyphs (surface, op,
2534
	    status = surface->backend->show_glyphs (surface, op,
2641
						    source,
2535
						    source,
2642
						    glyphs, num_glyphs,
2536
						    glyphs, num_glyphs,
2643
						    dev_scaled_font,
2537
						    dev_scaled_font,
2644
						    clip,
2538
						    clip);
2645
						    &remaining_glyphs);
-
 
2646
	    glyphs += num_glyphs - remaining_glyphs;
-
 
2647
	    num_glyphs = remaining_glyphs;
-
 
2648
	    if (status == CAIRO_INT_STATUS_UNSUPPORTED && remaining_glyphs == 0)
-
 
2649
		status = CAIRO_STATUS_SUCCESS;
-
 
2650
	} else if (surface->backend->show_text_glyphs != NULL) {
2539
	} else if (surface->backend->show_text_glyphs != NULL) {
2651
	    /* Intentionally only try show_text_glyphs method for show_glyphs
2540
	    /* Intentionally only try show_text_glyphs method for show_glyphs
2652
	     * calls if backend does not have show_glyphs.  If backend has
2541
	     * calls if backend does not have show_glyphs.  If backend has
2653
	     * both methods implemented, we don't fallback from show_glyphs to
2542
	     * both methods implemented, we don't fallback from show_glyphs to
2654
	     * show_text_glyphs, and hence the backend can assume in its
2543
	     * show_text_glyphs, and hence the backend can assume in its
Line 2664... Line 2553...
2664
							 dev_scaled_font,
2553
							 dev_scaled_font,
2665
							 clip);
2554
							 clip);
2666
	}
2555
	}
2667
    }
2556
    }
Line 2668... Line -...
2668
 
-
 
2669
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
-
 
2670
	status = _cairo_surface_fallback_show_glyphs (surface, op,
-
 
2671
						      source,
-
 
2672
						      glyphs, num_glyphs,
-
 
2673
						      dev_scaled_font,
-
 
2674
						      clip);
-
 
2675
    }
-
 
2676
 
2557
 
2677
    if (dev_scaled_font != scaled_font)
2558
    if (dev_scaled_font != scaled_font)
Line -... Line 2559...
-
 
2559
	cairo_scaled_font_destroy (dev_scaled_font);
2678
	cairo_scaled_font_destroy (dev_scaled_font);
2560
 
2679
 
-
 
2680
    surface->is_clear = FALSE;
2561
    if (status != CAIRO_INT_STATUS_NOTHING_TO_DO) {
2681
 
2562
	surface->is_clear = FALSE;
Line 2682... Line -...
2682
    return _cairo_surface_set_error (surface, status);
-
 
2683
}
-
 
2684
 
-
 
2685
/* XXX: Previously, we had a function named _cairo_surface_show_glyphs
-
 
2686
 * with not-so-useful semantics. We've now got a
-
 
2687
 * _cairo_surface_show_text_glyphs with the proper semantics, and its
-
 
2688
 * fallback still uses this old function (which still needs to be
-
 
2689
 * cleaned up in terms of both semantics and naming). */
-
 
2690
cairo_status_t
-
 
2691
_cairo_surface_old_show_glyphs (cairo_scaled_font_t	*scaled_font,
-
 
2692
				cairo_operator_t	 op,
-
 
2693
				const cairo_pattern_t	*pattern,
-
 
2694
				cairo_surface_t		*dst,
-
 
2695
				int			 source_x,
-
 
2696
				int			 source_y,
-
 
2697
				int			 dest_x,
-
 
2698
				int			 dest_y,
-
 
2699
				unsigned int		 width,
-
 
2700
				unsigned int		 height,
-
 
2701
				cairo_glyph_t		*glyphs,
-
 
2702
				int			 num_glyphs,
-
 
2703
				cairo_region_t		*clip_region)
-
 
2704
{
-
 
2705
    cairo_status_t status;
-
 
2706
 
-
 
2707
    if (dst->status)
-
 
2708
	return dst->status;
-
 
2709
 
-
 
2710
    assert (_cairo_surface_is_writable (dst));
-
 
2711
 
-
 
2712
    if (dst->backend->old_show_glyphs) {
-
 
2713
	status = dst->backend->old_show_glyphs (scaled_font,
-
 
2714
						op, pattern, dst,
-
 
2715
						source_x, source_y,
-
 
2716
                                                dest_x, dest_y,
-
 
2717
						width, height,
-
 
2718
						glyphs, num_glyphs,
-
 
2719
						clip_region);
-
 
2720
    } else
-
 
2721
	status = CAIRO_INT_STATUS_UNSUPPORTED;
-
 
2722
 
-
 
2723
    return _cairo_surface_set_error (dst, status);
-
 
2724
}
-
 
2725
 
-
 
2726
static cairo_status_t
-
 
2727
_cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t         *dst,
-
 
2728
						   cairo_rectangle_int_t   *src_rectangle,
-
 
2729
						   cairo_rectangle_int_t   *mask_rectangle,
-
 
2730
						   int			    dst_x,
-
 
2731
						   int			    dst_y,
-
 
2732
						   unsigned int		    width,
-
 
2733
						   unsigned int		    height,
-
 
2734
						   cairo_region_t	    *clip_region)
-
 
2735
{
-
 
2736
    cairo_rectangle_int_t dst_rectangle;
-
 
2737
    cairo_region_t clear_region;
-
 
2738
    cairo_status_t status;
-
 
2739
 
-
 
2740
    /* The area that was drawn is the area in the destination rectangle but
-
 
2741
     * not within the source or the mask.
-
 
2742
     */
-
 
2743
    dst_rectangle.x = dst_x;
-
 
2744
    dst_rectangle.y = dst_y;
-
 
2745
    dst_rectangle.width = width;
-
 
2746
    dst_rectangle.height = height;
-
 
2747
 
-
 
2748
    _cairo_region_init_rectangle (&clear_region, &dst_rectangle);
-
 
2749
 
-
 
2750
    if (clip_region != NULL) {
-
 
2751
	status = cairo_region_intersect (&clear_region, clip_region);
-
 
2752
	if (unlikely (status))
-
 
2753
	    goto CLEANUP_REGIONS;
-
 
2754
    }
-
 
2755
 
-
 
2756
    if (src_rectangle != NULL) {
-
 
2757
        if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle))
-
 
2758
	    goto EMPTY;
-
 
2759
    }
-
 
2760
 
-
 
2761
    if (mask_rectangle != NULL) {
-
 
2762
        if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle))
-
 
2763
	    goto EMPTY;
-
 
2764
    }
-
 
2765
 
-
 
2766
    /* Now compute the area that is in dst but not drawn */
-
 
2767
    status = cairo_region_subtract_rectangle (&clear_region, &dst_rectangle);
-
 
2768
    if (unlikely (status) || cairo_region_is_empty (&clear_region))
-
 
2769
        goto CLEANUP_REGIONS;
-
 
2770
 
-
 
2771
  EMPTY:
-
 
2772
    status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
-
 
2773
                                         CAIRO_COLOR_TRANSPARENT,
-
 
2774
                                         &clear_region);
-
 
2775
 
-
 
2776
  CLEANUP_REGIONS:
2563
	surface->serial++;
2777
    _cairo_region_fini (&clear_region);
-
 
2778
 
-
 
2779
    return _cairo_surface_set_error (dst, status);
-
 
2780
}
-
 
2781
 
-
 
2782
/**
-
 
2783
 * _cairo_surface_composite_fixup_unbounded:
-
 
2784
 * @dst: the destination surface
-
 
2785
 * @src_attr: source surface attributes (from _cairo_pattern_acquire_surface())
-
 
2786
 * @src_width: width of source surface
-
 
2787
 * @src_height: height of source surface
-
 
2788
 * @mask_attr: mask surface attributes or %NULL if no mask
-
 
2789
 * @mask_width: width of mask surface
-
 
2790
 * @mask_height: height of mask surface
-
 
2791
 * @src_x: @src_x from _cairo_surface_composite()
-
 
2792
 * @src_y: @src_y from _cairo_surface_composite()
-
 
2793
 * @mask_x: @mask_x from _cairo_surface_composite()
-
 
2794
 * @mask_y: @mask_y from _cairo_surface_composite()
-
 
2795
 * @dst_x: @dst_x from _cairo_surface_composite()
-
 
2796
 * @dst_y: @dst_y from _cairo_surface_composite()
-
 
2797
 * @width: @width from _cairo_surface_composite()
-
 
2798
 * @height: @height_x from _cairo_surface_composite()
-
 
2799
 *
-
 
2800
 * Eeek! Too many parameters! This is a helper function to take care of fixing
-
 
2801
 * up for bugs in libpixman and RENDER where, when asked to composite an
-
 
2802
 * untransformed surface with an unbounded operator (like CLEAR or SOURCE)
-
 
2803
 * only the region inside both the source and the mask is affected.
-
 
2804
 * This function clears the region that should have been drawn but was wasn't.
-
 
2805
 **/
-
 
2806
cairo_status_t
-
 
2807
_cairo_surface_composite_fixup_unbounded (cairo_surface_t            *dst,
-
 
2808
					  cairo_surface_attributes_t *src_attr,
-
 
2809
					  int                         src_width,
-
 
2810
					  int                         src_height,
-
 
2811
					  cairo_surface_attributes_t *mask_attr,
-
 
2812
					  int                         mask_width,
-
 
2813
					  int                         mask_height,
-
 
2814
					  int			      src_x,
-
 
2815
					  int			      src_y,
-
 
2816
					  int			      mask_x,
-
 
2817
					  int			      mask_y,
-
 
2818
					  int			      dst_x,
-
 
2819
					  int			      dst_y,
-
 
2820
					  unsigned int		      width,
-
 
2821
					  unsigned int		      height,
-
 
2822
					  cairo_region_t	     *clip_region)
-
 
2823
{
-
 
2824
    cairo_rectangle_int_t src_tmp, mask_tmp;
-
 
2825
    cairo_rectangle_int_t *src_rectangle = NULL;
-
 
2826
    cairo_rectangle_int_t *mask_rectangle = NULL;
-
 
2827
 
-
 
2828
    if (unlikely (dst->status))
-
 
2829
	return dst->status;
-
 
2830
 
-
 
2831
    assert (_cairo_surface_is_writable (dst));
-
 
2832
 
-
 
2833
    /* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
-
 
2834
     * non-repeating sources and masks. Other sources and masks can be ignored.
-
 
2835
     */
-
 
2836
    if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
-
 
2837
	src_attr->extend == CAIRO_EXTEND_NONE)
-
 
2838
    {
-
 
2839
	src_tmp.x = (dst_x - (src_x + src_attr->x_offset));
-
 
2840
	src_tmp.y = (dst_y - (src_y + src_attr->y_offset));
-
 
2841
	src_tmp.width = src_width;
-
 
2842
	src_tmp.height = src_height;
-
 
2843
 
-
 
2844
	src_rectangle = &src_tmp;
-
 
2845
    }
-
 
2846
 
-
 
2847
    if (mask_attr &&
-
 
2848
	_cairo_matrix_is_integer_translation (&mask_attr->matrix, NULL, NULL) &&
-
 
2849
	mask_attr->extend == CAIRO_EXTEND_NONE)
-
 
2850
    {
-
 
2851
	mask_tmp.x = (dst_x - (mask_x + mask_attr->x_offset));
-
 
2852
	mask_tmp.y = (dst_y - (mask_y + mask_attr->y_offset));
-
 
2853
	mask_tmp.width = mask_width;
-
 
2854
	mask_tmp.height = mask_height;
-
 
2855
 
-
 
2856
	mask_rectangle = &mask_tmp;
-
 
2857
    }
-
 
2858
 
-
 
2859
    return _cairo_surface_composite_fixup_unbounded_internal (dst, src_rectangle, mask_rectangle,
-
 
2860
							      dst_x, dst_y, width, height,
-
 
2861
							      clip_region);
-
 
2862
}
-
 
2863
 
-
 
2864
/**
-
 
2865
 * _cairo_surface_composite_shape_fixup_unbounded:
-
 
2866
 * @dst: the destination surface
-
 
2867
 * @src_attr: source surface attributes (from _cairo_pattern_acquire_surface())
-
 
2868
 * @src_width: width of source surface
-
 
2869
 * @src_height: height of source surface
-
 
2870
 * @mask_width: width of mask surface
-
 
2871
 * @mask_height: height of mask surface
-
 
2872
 * @src_x: @src_x from _cairo_surface_composite()
-
 
2873
 * @src_y: @src_y from _cairo_surface_composite()
-
 
2874
 * @mask_x: @mask_x from _cairo_surface_composite()
-
 
2875
 * @mask_y: @mask_y from _cairo_surface_composite()
-
 
2876
 * @dst_x: @dst_x from _cairo_surface_composite()
-
 
2877
 * @dst_y: @dst_y from _cairo_surface_composite()
-
 
2878
 * @width: @width from _cairo_surface_composite()
-
 
2879
 * @height: @height_x from _cairo_surface_composite()
-
 
2880
 *
-
 
2881
 * Like _cairo_surface_composite_fixup_unbounded(), but instead of
-
 
2882
 * handling the case where we have a source pattern and a mask
-
 
2883
 * pattern, handle the case where we are compositing a source pattern
-
 
2884
 * using a mask we create ourselves, as in
-
 
2885
 * _cairo_surface_composite_glyphs() or _cairo_surface_composite_trapezoids()
-
 
2886
 **/
-
 
2887
cairo_status_t
-
 
2888
_cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t            *dst,
-
 
2889
						cairo_surface_attributes_t *src_attr,
-
 
2890
						int                         src_width,
-
 
2891
						int                         src_height,
-
 
2892
						int                         mask_width,
-
 
2893
						int                         mask_height,
-
 
2894
						int			    src_x,
-
 
2895
						int			    src_y,
-
 
2896
						int			    mask_x,
-
 
2897
						int			    mask_y,
-
 
2898
						int			    dst_x,
-
 
2899
						int			    dst_y,
-
 
2900
						unsigned int		    width,
-
 
2901
						unsigned int		    height,
-
 
2902
						cairo_region_t	    *clip_region)
-
 
2903
{
-
 
2904
    cairo_rectangle_int_t src_tmp, *src= NULL;
-
 
2905
    cairo_rectangle_int_t mask;
-
 
2906
 
-
 
2907
    if (dst->status)
-
 
2908
	return dst->status;
-
 
2909
 
-
 
2910
    assert (_cairo_surface_is_writable (dst));
-
 
2911
 
-
 
2912
    /* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
-
 
2913
     * non-repeating sources and masks. Other sources and masks can be ignored.
-
 
2914
     */
-
 
2915
    if (_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
-
 
2916
	src_attr->extend == CAIRO_EXTEND_NONE)
-
 
2917
    {
-
 
2918
	src_tmp.x = (dst_x - (src_x + src_attr->x_offset));
-
 
2919
	src_tmp.y = (dst_y - (src_y + src_attr->y_offset));
-
 
2920
	src_tmp.width  = src_width;
-
 
2921
	src_tmp.height = src_height;
-
 
2922
 
-
 
2923
	src = &src_tmp;
-
 
2924
    }
-
 
2925
 
-
 
2926
    mask.x = dst_x - mask_x;
-
 
2927
    mask.y = dst_y - mask_y;
-
 
2928
    mask.width  = mask_width;
-
 
2929
    mask.height = mask_height;
-
 
2930
 
-
 
2931
    return _cairo_surface_composite_fixup_unbounded_internal (dst, src, &mask,
2564
    }
Line 2932... Line 2565...
2932
							      dst_x, dst_y, width, height,
2565
 
2933
							      clip_region);
2566
    return _cairo_surface_set_error (surface, status);
2934
}
2567
}
2935
 
2568
 
2936
/**
2569
/**
2937
 * _cairo_surface_set_resolution
2570
 * _cairo_surface_set_resolution:
2938
 * @surface: the surface
2571
 * @surface: the surface
2939
 * @x_res: x resolution, in dpi
2572
 * @x_res: x resolution, in dpi
2940
 * @y_res: y resolution, in dpi
2573
 * @y_res: y resolution, in dpi
2941
 *
2574
 *
2942
 * Set the actual surface resolution of @surface to the given x and y DPI.
2575
 * Set the actual surface resolution of @surface to the given x and y DPI.
2943
 * Mainly used for correctly computing the scale factor when fallback
2576
 * Mainly used for correctly computing the scale factor when fallback
2944
 * rendering needs to take place in the paginated surface.
2577
 * rendering needs to take place in the paginated surface.
2945
 */
2578
 **/
2946
void
2579
void
Line 2953... Line 2586...
2953
 
2586
 
2954
    surface->x_resolution = x_res;
2587
    surface->x_resolution = x_res;
2955
    surface->y_resolution = y_res;
2588
    surface->y_resolution = y_res;
Line 2956... Line -...
2956
}
-
 
2957
 
-
 
2958
/* Generic methods for determining operation extents. */
-
 
2959
 
-
 
2960
static void
-
 
2961
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
-
 
2962
{
-
 
2963
    const cairo_rectangle_int_t *clip_extents;
-
 
2964
    cairo_bool_t is_empty;
-
 
2965
 
-
 
2966
    clip_extents = NULL;
-
 
2967
    if (clip != NULL)
-
 
2968
	clip_extents = _cairo_clip_get_extents (clip);
-
 
2969
 
-
 
2970
    if (clip_extents != NULL)
-
 
2971
	is_empty = _cairo_rectangle_intersect (extents, clip_extents);
-
 
2972
}
-
 
2973
 
-
 
2974
static void
-
 
2975
_cairo_surface_operation_extents (cairo_surface_t *surface,
-
 
2976
				  cairo_operator_t op,
-
 
2977
				  const cairo_pattern_t *source,
-
 
2978
				  cairo_clip_t *clip,
-
 
2979
				  cairo_rectangle_int_t *extents)
-
 
2980
{
-
 
2981
    cairo_bool_t is_empty;
-
 
2982
 
-
 
2983
    is_empty = _cairo_surface_get_extents (surface, extents);
-
 
2984
 
-
 
2985
    if (_cairo_operator_bounded_by_source (op)) {
-
 
2986
	cairo_rectangle_int_t source_extents;
-
 
2987
 
-
 
2988
	_cairo_pattern_get_extents (source, &source_extents);
-
 
2989
	is_empty = _cairo_rectangle_intersect (extents, &source_extents);
-
 
2990
    }
-
 
2991
 
-
 
2992
    _rectangle_intersect_clip (extents, clip);
-
 
2993
}
-
 
2994
 
-
 
2995
cairo_status_t
-
 
2996
_cairo_surface_paint_extents (cairo_surface_t *surface,
-
 
2997
			      cairo_operator_t		op,
-
 
2998
			      const cairo_pattern_t	*source,
-
 
2999
			      cairo_clip_t		*clip,
-
 
3000
			      cairo_rectangle_int_t	*extents)
-
 
3001
{
-
 
3002
    _cairo_surface_operation_extents (surface, op, source, clip, extents);
-
 
3003
    return CAIRO_STATUS_SUCCESS;
-
 
3004
}
-
 
3005
 
-
 
3006
cairo_status_t
-
 
3007
_cairo_surface_mask_extents (cairo_surface_t *surface,
-
 
3008
			     cairo_operator_t		 op,
-
 
3009
			     const cairo_pattern_t	*source,
-
 
3010
			     const cairo_pattern_t	*mask,
-
 
3011
			     cairo_clip_t		*clip,
-
 
3012
			     cairo_rectangle_int_t	*extents)
-
 
3013
{
-
 
3014
    cairo_bool_t is_empty;
-
 
3015
 
-
 
3016
    _cairo_surface_operation_extents (surface, op, source, clip, extents);
-
 
3017
 
-
 
3018
    if (_cairo_operator_bounded_by_mask (op)) {
-
 
3019
	cairo_rectangle_int_t mask_extents;
-
 
3020
 
-
 
3021
	_cairo_pattern_get_extents (mask, &mask_extents);
-
 
3022
	is_empty = _cairo_rectangle_intersect (extents, &mask_extents);
-
 
3023
    }
-
 
3024
 
-
 
3025
    return CAIRO_STATUS_SUCCESS;
-
 
3026
}
-
 
3027
 
-
 
3028
cairo_status_t
-
 
3029
_cairo_surface_stroke_extents (cairo_surface_t *surface,
-
 
3030
			       cairo_operator_t op,
-
 
3031
			       const cairo_pattern_t *source,
-
 
3032
			       cairo_path_fixed_t	*path,
-
 
3033
			       const cairo_stroke_style_t *style,
-
 
3034
			       const cairo_matrix_t *ctm,
-
 
3035
			       const cairo_matrix_t *ctm_inverse,
-
 
3036
			       double tolerance,
-
 
3037
			       cairo_antialias_t	 antialias,
-
 
3038
			       cairo_clip_t *clip,
-
 
3039
			       cairo_rectangle_int_t *extents)
-
 
3040
{
-
 
3041
    cairo_status_t status;
-
 
3042
    cairo_bool_t is_empty;
-
 
3043
 
-
 
3044
    _cairo_surface_operation_extents (surface, op, source, clip, extents);
-
 
3045
 
-
 
3046
    if (_cairo_operator_bounded_by_mask (op)) {
-
 
3047
	cairo_rectangle_int_t mask_extents;
-
 
3048
 
-
 
3049
	status = _cairo_path_fixed_stroke_extents (path, style,
-
 
3050
						   ctm, ctm_inverse,
-
 
3051
						   tolerance,
-
 
3052
						   &mask_extents);
-
 
3053
	if (unlikely (status))
-
 
3054
	    return status;
-
 
3055
 
-
 
3056
	is_empty = _cairo_rectangle_intersect (extents, &mask_extents);
-
 
3057
    }
-
 
3058
 
-
 
3059
    return CAIRO_STATUS_SUCCESS;
-
 
3060
}
-
 
3061
 
-
 
3062
cairo_status_t
-
 
3063
_cairo_surface_fill_extents (cairo_surface_t		*surface,
-
 
3064
			     cairo_operator_t		 op,
-
 
3065
			     const cairo_pattern_t	*source,
-
 
3066
			     cairo_path_fixed_t		*path,
-
 
3067
			     cairo_fill_rule_t		 fill_rule,
-
 
3068
			     double			 tolerance,
-
 
3069
			     cairo_antialias_t		 antialias,
-
 
3070
			     cairo_clip_t		*clip,
-
 
3071
			     cairo_rectangle_int_t	*extents)
-
 
3072
{
-
 
3073
    cairo_bool_t is_empty;
-
 
3074
 
-
 
3075
    _cairo_surface_operation_extents (surface, op, source, clip, extents);
-
 
3076
 
-
 
3077
    if (_cairo_operator_bounded_by_mask (op)) {
-
 
3078
	cairo_rectangle_int_t mask_extents;
-
 
3079
 
-
 
3080
	_cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
-
 
3081
					&mask_extents);
-
 
3082
	is_empty = _cairo_rectangle_intersect (extents, &mask_extents);
-
 
3083
    }
-
 
3084
 
-
 
3085
    return CAIRO_STATUS_SUCCESS;
-
 
3086
}
-
 
3087
 
-
 
3088
cairo_status_t
-
 
3089
_cairo_surface_glyphs_extents (cairo_surface_t *surface,
-
 
3090
			       cairo_operator_t	   op,
-
 
3091
			       const cairo_pattern_t *source,
-
 
3092
			       cairo_glyph_t	  *glyphs,
-
 
3093
			       int		   num_glyphs,
-
 
3094
			       cairo_scaled_font_t  *scaled_font,
-
 
3095
			       cairo_clip_t         *clip,
-
 
3096
			       cairo_rectangle_int_t *extents)
-
 
3097
{
-
 
3098
    cairo_status_t	     status;
-
 
3099
    cairo_bool_t             is_empty;
-
 
3100
 
-
 
3101
    _cairo_surface_operation_extents (surface, op, source, clip, extents);
-
 
3102
 
-
 
3103
    if (_cairo_operator_bounded_by_mask (op)) {
-
 
3104
	cairo_rectangle_int_t glyph_extents;
-
 
3105
 
-
 
3106
	status = _cairo_scaled_font_glyph_device_extents (scaled_font,
-
 
3107
							  glyphs,
-
 
3108
							  num_glyphs,
-
 
3109
							  &glyph_extents,
-
 
3110
							  NULL);
-
 
3111
	if (unlikely (status))
-
 
3112
	    return status;
-
 
3113
 
-
 
3114
	is_empty = _cairo_rectangle_intersect (extents, &glyph_extents);
-
 
3115
    }
-
 
3116
 
-
 
3117
    return CAIRO_STATUS_SUCCESS;
-
 
3118
}
2589
}
3119
 
2590
 
3120
cairo_surface_t *
2591
cairo_surface_t *
-
 
2592
_cairo_surface_create_in_error (cairo_status_t status)
3121
_cairo_surface_create_in_error (cairo_status_t status)
2593
{
3122
{
2594
    assert (status < CAIRO_STATUS_LAST_STATUS);
3123
    switch (status) {
2595
    switch (status) {
3124
    case CAIRO_STATUS_NO_MEMORY:
2596
    case CAIRO_STATUS_NO_MEMORY:
3125
	return (cairo_surface_t *) &_cairo_surface_nil;
2597
	return (cairo_surface_t *) &_cairo_surface_nil;
Line 3172... Line 2644...
3172
    case CAIRO_STATUS_NEGATIVE_COUNT:
2644
    case CAIRO_STATUS_NEGATIVE_COUNT:
3173
    case CAIRO_STATUS_INVALID_CLUSTERS:
2645
    case CAIRO_STATUS_INVALID_CLUSTERS:
3174
    case CAIRO_STATUS_INVALID_SLANT:
2646
    case CAIRO_STATUS_INVALID_SLANT:
3175
    case CAIRO_STATUS_INVALID_WEIGHT:
2647
    case CAIRO_STATUS_INVALID_WEIGHT:
3176
    case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
2648
    case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
-
 
2649
    case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
-
 
2650
    case CAIRO_STATUS_DEVICE_FINISHED:
-
 
2651
    default:
-
 
2652
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-
 
2653
	return (cairo_surface_t *) &_cairo_surface_nil;
-
 
2654
    }
-
 
2655
}
-
 
2656
 
-
 
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;
3177
    default:
2668
    default:
3178
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
2669
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
3179
	return (cairo_surface_t *) &_cairo_surface_nil;
2670
	return (cairo_surface_t *) &_cairo_surface_nil;
3180
    }
2671
    }
3181
}
2672
}