1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2003 University of Southern California
5 * Copyright © 2009,2010,2011 Intel Corporation
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is University of Southern
36 * Carl D. Worth <cworth@cworth.org>
37 * Chris Wilson <chris@chris-wilson.co.uk>
42 #include "cairo-boxes-private.h"
43 #include "cairo-clip-private.h"
44 #include "cairo-composite-rectangles-private.h"
45 #include "cairo-compositor-private.h"
46 #include "cairo-default-context-private.h"
47 #include "cairo-error-private.h"
48 #include "cairo-image-surface-inline.h"
49 #include "cairo-paginated-private.h"
50 #include "cairo-pattern-private.h"
51 #include "cairo-pixman-private.h"
52 #include "cairo-recording-surface-private.h"
53 #include "cairo-region-private.h"
54 #include "cairo-scaled-font-private.h"
55 #include "cairo-surface-snapshot-private.h"
56 #include "cairo-surface-subsurface-private.h"
58 /* Limit on the width / height of an image surface in pixels. This is
59 * mainly determined by coordinates of things sent to pixman at the
60 * moment being in 16.16 format. */
61 #define MAX_IMAGE_SIZE 32767
65 * @Title: Image Surfaces
66 * @Short_Description: Rendering to memory buffers
67 * @See_Also: #cairo_surface_t
69 * Image surfaces provide the ability to render to memory buffers
70 * either allocated by cairo or by the calling code. The supported
71 * image formats are those defined in #cairo_format_t.
75 * CAIRO_HAS_IMAGE_SURFACE:
77 * Defined if the image surface backend is available.
78 * The image surface backend is always built in.
79 * This macro was added for completeness in cairo 1.8.
85 _cairo_image_surface_is_size_valid (int width
, int height
)
87 return 0 <= width
&& width
<= MAX_IMAGE_SIZE
&&
88 0 <= height
&& height
<= MAX_IMAGE_SIZE
;
92 _cairo_format_from_pixman_format (pixman_format_code_t pixman_format
)
94 switch (pixman_format
) {
96 return CAIRO_FORMAT_ARGB32
;
97 case PIXMAN_x2r10g10b10
:
98 return CAIRO_FORMAT_RGB30
;
100 return CAIRO_FORMAT_RGB24
;
102 return CAIRO_FORMAT_A8
;
104 return CAIRO_FORMAT_A1
;
106 return CAIRO_FORMAT_RGB16_565
;
107 #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
108 case PIXMAN_r8g8b8a8
: case PIXMAN_r8g8b8x8
:
110 #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
111 case PIXMAN_a8r8g8b8_sRGB
:
113 case PIXMAN_a8b8g8r8
: case PIXMAN_x8b8g8r8
: case PIXMAN_r8g8b8
:
114 case PIXMAN_b8g8r8
: case PIXMAN_b5g6r5
:
115 case PIXMAN_a1r5g5b5
: case PIXMAN_x1r5g5b5
: case PIXMAN_a1b5g5r5
:
116 case PIXMAN_x1b5g5r5
: case PIXMAN_a4r4g4b4
: case PIXMAN_x4r4g4b4
:
117 case PIXMAN_a4b4g4r4
: case PIXMAN_x4b4g4r4
: case PIXMAN_r3g3b2
:
118 case PIXMAN_b2g3r3
: case PIXMAN_a2r2g2b2
: case PIXMAN_a2b2g2r2
:
119 case PIXMAN_c8
: case PIXMAN_g8
: case PIXMAN_x4a4
:
120 case PIXMAN_a4
: case PIXMAN_r1g2b1
: case PIXMAN_b1g2r1
:
121 case PIXMAN_a1r1g1b1
: case PIXMAN_a1b1g1r1
: case PIXMAN_c4
:
122 case PIXMAN_g4
: case PIXMAN_g1
:
123 case PIXMAN_yuy2
: case PIXMAN_yv12
:
124 case PIXMAN_b8g8r8x8
:
125 case PIXMAN_b8g8r8a8
:
126 case PIXMAN_a2b10g10r10
:
127 case PIXMAN_x2b10g10r10
:
128 case PIXMAN_a2r10g10b10
:
129 #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
130 case PIXMAN_x14r6g6b6
:
133 return CAIRO_FORMAT_INVALID
;
136 return CAIRO_FORMAT_INVALID
;
140 _cairo_content_from_pixman_format (pixman_format_code_t pixman_format
)
142 cairo_content_t content
;
145 if (PIXMAN_FORMAT_RGB (pixman_format
))
146 content
|= CAIRO_CONTENT_COLOR
;
147 if (PIXMAN_FORMAT_A (pixman_format
))
148 content
|= CAIRO_CONTENT_ALPHA
;
154 _cairo_image_surface_init (cairo_image_surface_t
*surface
,
155 pixman_image_t
*pixman_image
,
156 pixman_format_code_t pixman_format
)
158 surface
->parent
= NULL
;
159 surface
->pixman_image
= pixman_image
;
161 surface
->pixman_format
= pixman_format
;
162 surface
->format
= _cairo_format_from_pixman_format (pixman_format
);
163 surface
->data
= (uint8_t *) pixman_image_get_data (pixman_image
);
164 surface
->owns_data
= FALSE
;
165 surface
->transparency
= CAIRO_IMAGE_UNKNOWN
;
166 surface
->color
= CAIRO_IMAGE_UNKNOWN_COLOR
;
168 surface
->width
= pixman_image_get_width (pixman_image
);
169 surface
->height
= pixman_image_get_height (pixman_image
);
170 surface
->stride
= pixman_image_get_stride (pixman_image
);
171 surface
->depth
= pixman_image_get_depth (pixman_image
);
173 surface
->base
.is_clear
= surface
->width
== 0 || surface
->height
== 0;
175 surface
->compositor
= _cairo_image_spans_compositor_get ();
179 _cairo_image_surface_create_for_pixman_image (pixman_image_t
*pixman_image
,
180 pixman_format_code_t pixman_format
)
182 cairo_image_surface_t
*surface
;
184 surface
= malloc (sizeof (cairo_image_surface_t
));
185 if (unlikely (surface
== NULL
))
186 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY
));
188 _cairo_surface_init (&surface
->base
,
189 &_cairo_image_surface_backend
,
191 _cairo_content_from_pixman_format (pixman_format
));
193 _cairo_image_surface_init (surface
, pixman_image
, pixman_format
);
195 return &surface
->base
;
199 _pixman_format_from_masks (cairo_format_masks_t
*masks
,
200 pixman_format_code_t
*format_ret
)
202 pixman_format_code_t format
;
205 cairo_format_masks_t format_masks
;
207 a
= _cairo_popcount (masks
->alpha_mask
);
208 r
= _cairo_popcount (masks
->red_mask
);
209 g
= _cairo_popcount (masks
->green_mask
);
210 b
= _cairo_popcount (masks
->blue_mask
);
212 if (masks
->red_mask
) {
213 if (masks
->red_mask
> masks
->blue_mask
)
214 format_type
= PIXMAN_TYPE_ARGB
;
216 format_type
= PIXMAN_TYPE_ABGR
;
217 } else if (masks
->alpha_mask
) {
218 format_type
= PIXMAN_TYPE_A
;
223 format
= PIXMAN_FORMAT (masks
->bpp
, format_type
, a
, r
, g
, b
);
225 if (! pixman_format_supported_destination (format
))
228 /* Sanity check that we got out of PIXMAN_FORMAT exactly what we
229 * expected. This avoid any problems from something bizarre like
230 * alpha in the least-significant bits, or insane channel order,
232 if (!_pixman_format_to_masks (format
, &format_masks
) ||
233 masks
->bpp
!= format_masks
.bpp
||
234 masks
->red_mask
!= format_masks
.red_mask
||
235 masks
->green_mask
!= format_masks
.green_mask
||
236 masks
->blue_mask
!= format_masks
.blue_mask
)
241 *format_ret
= format
;
245 /* A mask consisting of N bits set to 1. */
246 #define MASK(N) ((1UL << (N))-1)
249 _pixman_format_to_masks (pixman_format_code_t format
,
250 cairo_format_masks_t
*masks
)
254 masks
->bpp
= PIXMAN_FORMAT_BPP (format
);
256 /* Number of bits in each channel */
257 a
= PIXMAN_FORMAT_A (format
);
258 r
= PIXMAN_FORMAT_R (format
);
259 g
= PIXMAN_FORMAT_G (format
);
260 b
= PIXMAN_FORMAT_B (format
);
262 switch (PIXMAN_FORMAT_TYPE (format
)) {
263 case PIXMAN_TYPE_ARGB
:
264 masks
->alpha_mask
= MASK (a
) << (r
+ g
+ b
);
265 masks
->red_mask
= MASK (r
) << (g
+ b
);
266 masks
->green_mask
= MASK (g
) << (b
);
267 masks
->blue_mask
= MASK (b
);
269 case PIXMAN_TYPE_ABGR
:
270 masks
->alpha_mask
= MASK (a
) << (b
+ g
+ r
);
271 masks
->blue_mask
= MASK (b
) << (g
+ r
);
272 masks
->green_mask
= MASK (g
) << (r
);
273 masks
->red_mask
= MASK (r
);
275 #ifdef PIXMAN_TYPE_BGRA
276 case PIXMAN_TYPE_BGRA
:
277 masks
->blue_mask
= MASK (b
) << (masks
->bpp
- b
);
278 masks
->green_mask
= MASK (g
) << (masks
->bpp
- b
- g
);
279 masks
->red_mask
= MASK (r
) << (masks
->bpp
- b
- g
- r
);
280 masks
->alpha_mask
= MASK (a
);
284 masks
->alpha_mask
= MASK (a
);
286 masks
->green_mask
= 0;
287 masks
->blue_mask
= 0;
289 case PIXMAN_TYPE_OTHER
:
290 case PIXMAN_TYPE_COLOR
:
291 case PIXMAN_TYPE_GRAY
:
292 case PIXMAN_TYPE_YUY2
:
293 case PIXMAN_TYPE_YV12
:
295 masks
->alpha_mask
= 0;
297 masks
->green_mask
= 0;
298 masks
->blue_mask
= 0;
304 _cairo_format_to_pixman_format_code (cairo_format_t format
)
306 pixman_format_code_t ret
;
308 case CAIRO_FORMAT_A1
:
311 case CAIRO_FORMAT_A8
:
314 case CAIRO_FORMAT_RGB24
:
315 ret
= PIXMAN_x8r8g8b8
;
317 case CAIRO_FORMAT_RGB30
:
318 ret
= PIXMAN_x2r10g10b10
;
320 case CAIRO_FORMAT_RGB16_565
:
323 case CAIRO_FORMAT_ARGB32
:
324 case CAIRO_FORMAT_INVALID
:
326 ret
= PIXMAN_a8r8g8b8
;
333 _cairo_image_surface_create_with_pixman_format (unsigned char *data
,
334 pixman_format_code_t pixman_format
,
339 cairo_surface_t
*surface
;
340 pixman_image_t
*pixman_image
;
342 if (! _cairo_image_surface_is_size_valid (width
, height
))
344 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
347 pixman_image
= pixman_image_create_bits (pixman_format
, width
, height
,
348 (uint32_t *) data
, stride
);
350 if (unlikely (pixman_image
== NULL
))
351 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY
));
353 surface
= _cairo_image_surface_create_for_pixman_image (pixman_image
,
355 if (unlikely (surface
->status
)) {
356 pixman_image_unref (pixman_image
);
360 /* we can not make any assumptions about the initial state of user data */
361 surface
->is_clear
= data
== NULL
;
366 * cairo_image_surface_create:
367 * @format: format of pixels in the surface to create
368 * @width: width of the surface, in pixels
369 * @height: height of the surface, in pixels
371 * Creates an image surface of the specified format and
372 * dimensions. Initially the surface contents are all
373 * 0. (Specifically, within each pixel, each color or alpha channel
374 * belonging to format will be 0. The contents of bits within a pixel,
375 * but not belonging to the given format are undefined).
377 * Return value: a pointer to the newly created surface. The caller
378 * owns the surface and should call cairo_surface_destroy() when done
381 * This function always returns a valid pointer, but it will return a
382 * pointer to a "nil" surface if an error such as out of memory
383 * occurs. You can use cairo_surface_status() to check for this.
388 cairo_image_surface_create (cairo_format_t format
,
392 pixman_format_code_t pixman_format
;
394 if (! CAIRO_FORMAT_VALID (format
))
395 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT
));
397 pixman_format
= _cairo_format_to_pixman_format_code (format
);
399 return _cairo_image_surface_create_with_pixman_format (NULL
, pixman_format
,
402 slim_hidden_def (cairo_image_surface_create
);
405 _cairo_image_surface_create_with_content (cairo_content_t content
,
409 return cairo_image_surface_create (_cairo_format_from_content (content
),
414 * cairo_format_stride_for_width:
415 * @format: A #cairo_format_t value
416 * @width: The desired width of an image surface to be created.
418 * This function provides a stride value that will respect all
419 * alignment requirements of the accelerated image-rendering code
420 * within cairo. Typical usage will be of the form:
422 * <informalexample><programlisting>
424 * unsigned char *data;
425 * cairo_surface_t *surface;
427 * stride = cairo_format_stride_for_width (format, width);
428 * data = malloc (stride * height);
429 * surface = cairo_image_surface_create_for_data (data, format,
432 * </programlisting></informalexample>
434 * Return value: the appropriate stride to use given the desired
435 * format and width, or -1 if either the format is invalid or the width
441 cairo_format_stride_for_width (cairo_format_t format
,
446 if (! CAIRO_FORMAT_VALID (format
)) {
447 _cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT
);
451 bpp
= _cairo_format_bits_per_pixel (format
);
452 if ((unsigned) (width
) >= (INT32_MAX
- 7) / (unsigned) (bpp
))
455 return CAIRO_STRIDE_FOR_WIDTH_BPP (width
, bpp
);
457 slim_hidden_def (cairo_format_stride_for_width
);
460 * cairo_image_surface_create_for_data:
461 * @data: a pointer to a buffer supplied by the application in which
462 * to write contents. This pointer must be suitably aligned for any
463 * kind of variable, (for example, a pointer returned by malloc).
464 * @format: the format of pixels in the buffer
465 * @width: the width of the image to be stored in the buffer
466 * @height: the height of the image to be stored in the buffer
467 * @stride: the number of bytes between the start of rows in the
468 * buffer as allocated. This value should always be computed by
469 * cairo_format_stride_for_width() before allocating the data
472 * Creates an image surface for the provided pixel data. The output
473 * buffer must be kept around until the #cairo_surface_t is destroyed
474 * or cairo_surface_finish() is called on the surface. The initial
475 * contents of @data will be used as the initial image contents; you
476 * must explicitly clear the buffer, using, for example,
477 * cairo_rectangle() and cairo_fill() if you want it cleared.
479 * Note that the stride may be larger than
480 * width*bytes_per_pixel to provide proper alignment for each pixel
481 * and row. This alignment is required to allow high-performance rendering
482 * within cairo. The correct way to obtain a legal stride value is to
483 * call cairo_format_stride_for_width() with the desired format and
484 * maximum image width value, and then use the resulting stride value
485 * to allocate the data and to create the image surface. See
486 * cairo_format_stride_for_width() for example code.
488 * Return value: a pointer to the newly created surface. The caller
489 * owns the surface and should call cairo_surface_destroy() when done
492 * This function always returns a valid pointer, but it will return a
493 * pointer to a "nil" surface in the case of an error such as out of
494 * memory or an invalid stride value. In case of invalid stride value
495 * the error status of the returned surface will be
496 * %CAIRO_STATUS_INVALID_STRIDE. You can use
497 * cairo_surface_status() to check for this.
499 * See cairo_surface_set_user_data() for a means of attaching a
500 * destroy-notification fallback to the surface if necessary.
505 cairo_image_surface_create_for_data (unsigned char *data
,
506 cairo_format_t format
,
511 pixman_format_code_t pixman_format
;
514 if (! CAIRO_FORMAT_VALID (format
))
515 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT
));
517 if ((stride
& (CAIRO_STRIDE_ALIGNMENT
-1)) != 0)
518 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE
));
520 if (! _cairo_image_surface_is_size_valid (width
, height
))
521 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
523 minstride
= cairo_format_stride_for_width (format
, width
);
525 if (stride
> -minstride
) {
526 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE
));
529 if (stride
< minstride
) {
530 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE
));
534 pixman_format
= _cairo_format_to_pixman_format_code (format
);
535 return _cairo_image_surface_create_with_pixman_format (data
,
540 slim_hidden_def (cairo_image_surface_create_for_data
);
543 * cairo_image_surface_get_data:
544 * @surface: a #cairo_image_surface_t
546 * Get a pointer to the data of the image surface, for direct
547 * inspection or modification.
549 * A call to cairo_surface_flush() is required before accessing the
550 * pixel data to ensure that all pending drawing operations are
551 * finished. A call to cairo_surface_mark_dirty() is required after
552 * the data is modified.
554 * Return value: a pointer to the image data of this surface or %NULL
555 * if @surface is not an image surface, or if cairo_surface_finish()
561 cairo_image_surface_get_data (cairo_surface_t
*surface
)
563 cairo_image_surface_t
*image_surface
= (cairo_image_surface_t
*) surface
;
565 if (! _cairo_surface_is_image (surface
)) {
566 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
570 return image_surface
->data
;
572 slim_hidden_def (cairo_image_surface_get_data
);
575 * cairo_image_surface_get_format:
576 * @surface: a #cairo_image_surface_t
578 * Get the format of the surface.
580 * Return value: the format of the surface
585 cairo_image_surface_get_format (cairo_surface_t
*surface
)
587 cairo_image_surface_t
*image_surface
= (cairo_image_surface_t
*) surface
;
589 if (! _cairo_surface_is_image (surface
)) {
590 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
591 return CAIRO_FORMAT_INVALID
;
594 return image_surface
->format
;
596 slim_hidden_def (cairo_image_surface_get_format
);
599 * cairo_image_surface_get_width:
600 * @surface: a #cairo_image_surface_t
602 * Get the width of the image surface in pixels.
604 * Return value: the width of the surface in pixels.
609 cairo_image_surface_get_width (cairo_surface_t
*surface
)
611 cairo_image_surface_t
*image_surface
= (cairo_image_surface_t
*) surface
;
613 if (! _cairo_surface_is_image (surface
)) {
614 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
618 return image_surface
->width
;
620 slim_hidden_def (cairo_image_surface_get_width
);
623 * cairo_image_surface_get_height:
624 * @surface: a #cairo_image_surface_t
626 * Get the height of the image surface in pixels.
628 * Return value: the height of the surface in pixels.
633 cairo_image_surface_get_height (cairo_surface_t
*surface
)
635 cairo_image_surface_t
*image_surface
= (cairo_image_surface_t
*) surface
;
637 if (! _cairo_surface_is_image (surface
)) {
638 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
642 return image_surface
->height
;
644 slim_hidden_def (cairo_image_surface_get_height
);
647 * cairo_image_surface_get_stride:
648 * @surface: a #cairo_image_surface_t
650 * Get the stride of the image surface in bytes
652 * Return value: the stride of the image surface in bytes (or 0 if
653 * @surface is not an image surface). The stride is the distance in
654 * bytes from the beginning of one row of the image data to the
655 * beginning of the next row.
660 cairo_image_surface_get_stride (cairo_surface_t
*surface
)
663 cairo_image_surface_t
*image_surface
= (cairo_image_surface_t
*) surface
;
665 if (! _cairo_surface_is_image (surface
)) {
666 _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH
);
670 return image_surface
->stride
;
672 slim_hidden_def (cairo_image_surface_get_stride
);
675 _cairo_format_from_content (cairo_content_t content
)
678 case CAIRO_CONTENT_COLOR
:
679 return CAIRO_FORMAT_RGB24
;
680 case CAIRO_CONTENT_ALPHA
:
681 return CAIRO_FORMAT_A8
;
682 case CAIRO_CONTENT_COLOR_ALPHA
:
683 return CAIRO_FORMAT_ARGB32
;
687 return CAIRO_FORMAT_INVALID
;
691 _cairo_content_from_format (cairo_format_t format
)
694 case CAIRO_FORMAT_ARGB32
:
695 return CAIRO_CONTENT_COLOR_ALPHA
;
696 case CAIRO_FORMAT_RGB30
:
697 return CAIRO_CONTENT_COLOR
;
698 case CAIRO_FORMAT_RGB24
:
699 return CAIRO_CONTENT_COLOR
;
700 case CAIRO_FORMAT_RGB16_565
:
701 return CAIRO_CONTENT_COLOR
;
702 case CAIRO_FORMAT_A8
:
703 case CAIRO_FORMAT_A1
:
704 return CAIRO_CONTENT_ALPHA
;
705 case CAIRO_FORMAT_INVALID
:
710 return CAIRO_CONTENT_COLOR_ALPHA
;
714 _cairo_format_bits_per_pixel (cairo_format_t format
)
717 case CAIRO_FORMAT_ARGB32
:
718 case CAIRO_FORMAT_RGB30
:
719 case CAIRO_FORMAT_RGB24
:
721 case CAIRO_FORMAT_RGB16_565
:
723 case CAIRO_FORMAT_A8
:
725 case CAIRO_FORMAT_A1
:
727 case CAIRO_FORMAT_INVALID
:
735 _cairo_image_surface_create_similar (void *abstract_other
,
736 cairo_content_t content
,
740 cairo_image_surface_t
*other
= abstract_other
;
742 TRACE ((stderr
, "%s (other=%u)\n", __FUNCTION__
, other
->base
.unique_id
));
744 if (! _cairo_image_surface_is_size_valid (width
, height
))
745 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE
));
747 if (content
== other
->base
.content
) {
748 return _cairo_image_surface_create_with_pixman_format (NULL
,
749 other
->pixman_format
,
754 return _cairo_image_surface_create_with_content (content
,
759 _cairo_image_surface_snapshot (void *abstract_surface
)
761 cairo_image_surface_t
*image
= abstract_surface
;
762 cairo_image_surface_t
*clone
;
764 /* If we own the image, we can simply steal the memory for the snapshot */
765 if (image
->owns_data
&& image
->base
._finishing
) {
766 clone
= (cairo_image_surface_t
*)
767 _cairo_image_surface_create_for_pixman_image (image
->pixman_image
,
768 image
->pixman_format
);
769 if (unlikely (clone
->base
.status
))
772 image
->pixman_image
= NULL
;
773 image
->owns_data
= FALSE
;
775 clone
->transparency
= image
->transparency
;
776 clone
->color
= image
->color
;
778 clone
->owns_data
= TRUE
;
782 clone
= (cairo_image_surface_t
*)
783 _cairo_image_surface_create_with_pixman_format (NULL
,
784 image
->pixman_format
,
788 if (unlikely (clone
->base
.status
))
791 if (clone
->stride
== image
->stride
) {
792 memcpy (clone
->data
, image
->data
, clone
->stride
* clone
->height
);
794 pixman_image_composite32 (PIXMAN_OP_SRC
,
795 image
->pixman_image
, NULL
, clone
->pixman_image
,
799 image
->width
, image
->height
);
801 clone
->base
.is_clear
= FALSE
;
805 cairo_image_surface_t
*
806 _cairo_image_surface_map_to_image (void *abstract_other
,
807 const cairo_rectangle_int_t
*extents
)
809 cairo_image_surface_t
*other
= abstract_other
;
810 cairo_surface_t
*surface
;
814 data
+= extents
->y
* other
->stride
;
815 data
+= extents
->x
* PIXMAN_FORMAT_BPP (other
->pixman_format
)/ 8;
818 _cairo_image_surface_create_with_pixman_format (data
,
819 other
->pixman_format
,
824 cairo_surface_set_device_offset (surface
, -extents
->x
, -extents
->y
);
825 return (cairo_image_surface_t
*) surface
;
829 _cairo_image_surface_unmap_image (void *abstract_surface
,
830 cairo_image_surface_t
*image
)
832 cairo_surface_finish (&image
->base
);
833 cairo_surface_destroy (&image
->base
);
835 return CAIRO_INT_STATUS_SUCCESS
;
839 _cairo_image_surface_finish (void *abstract_surface
)
841 cairo_image_surface_t
*surface
= abstract_surface
;
843 if (surface
->pixman_image
) {
844 pixman_image_unref (surface
->pixman_image
);
845 surface
->pixman_image
= NULL
;
848 if (surface
->owns_data
) {
849 free (surface
->data
);
850 surface
->data
= NULL
;
853 if (surface
->parent
) {
854 cairo_surface_t
*parent
= surface
->parent
;
855 surface
->parent
= NULL
;
856 cairo_surface_destroy (parent
);
859 return CAIRO_STATUS_SUCCESS
;
863 _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t
*surface
)
865 surface
->owns_data
= TRUE
;
869 _cairo_image_surface_source (void *abstract_surface
,
870 cairo_rectangle_int_t
*extents
)
872 cairo_image_surface_t
*surface
= abstract_surface
;
875 extents
->x
= extents
->y
= 0;
876 extents
->width
= surface
->width
;
877 extents
->height
= surface
->height
;
880 return &surface
->base
;
884 _cairo_image_surface_acquire_source_image (void *abstract_surface
,
885 cairo_image_surface_t
**image_out
,
888 *image_out
= abstract_surface
;
891 return CAIRO_STATUS_SUCCESS
;
895 _cairo_image_surface_release_source_image (void *abstract_surface
,
896 cairo_image_surface_t
*image
,
901 /* high level image interface */
903 _cairo_image_surface_get_extents (void *abstract_surface
,
904 cairo_rectangle_int_t
*rectangle
)
906 cairo_image_surface_t
*surface
= abstract_surface
;
910 rectangle
->width
= surface
->width
;
911 rectangle
->height
= surface
->height
;
917 _cairo_image_surface_paint (void *abstract_surface
,
919 const cairo_pattern_t
*source
,
920 const cairo_clip_t
*clip
)
922 cairo_image_surface_t
*surface
= abstract_surface
;
924 TRACE ((stderr
, "%s (surface=%d)\n",
925 __FUNCTION__
, surface
->base
.unique_id
));
927 return _cairo_compositor_paint (surface
->compositor
,
928 &surface
->base
, op
, source
, clip
);
932 _cairo_image_surface_mask (void *abstract_surface
,
934 const cairo_pattern_t
*source
,
935 const cairo_pattern_t
*mask
,
936 const cairo_clip_t
*clip
)
938 cairo_image_surface_t
*surface
= abstract_surface
;
940 TRACE ((stderr
, "%s (surface=%d)\n",
941 __FUNCTION__
, surface
->base
.unique_id
));
943 return _cairo_compositor_mask (surface
->compositor
,
944 &surface
->base
, op
, source
, mask
, clip
);
948 _cairo_image_surface_stroke (void *abstract_surface
,
950 const cairo_pattern_t
*source
,
951 const cairo_path_fixed_t
*path
,
952 const cairo_stroke_style_t
*style
,
953 const cairo_matrix_t
*ctm
,
954 const cairo_matrix_t
*ctm_inverse
,
956 cairo_antialias_t antialias
,
957 const cairo_clip_t
*clip
)
959 cairo_image_surface_t
*surface
= abstract_surface
;
961 TRACE ((stderr
, "%s (surface=%d)\n",
962 __FUNCTION__
, surface
->base
.unique_id
));
964 return _cairo_compositor_stroke (surface
->compositor
, &surface
->base
,
966 style
, ctm
, ctm_inverse
,
967 tolerance
, antialias
, clip
);
971 _cairo_image_surface_fill (void *abstract_surface
,
973 const cairo_pattern_t
*source
,
974 const cairo_path_fixed_t
*path
,
975 cairo_fill_rule_t fill_rule
,
977 cairo_antialias_t antialias
,
978 const cairo_clip_t
*clip
)
980 cairo_image_surface_t
*surface
= abstract_surface
;
982 TRACE ((stderr
, "%s (surface=%d)\n",
983 __FUNCTION__
, surface
->base
.unique_id
));
985 return _cairo_compositor_fill (surface
->compositor
, &surface
->base
,
987 fill_rule
, tolerance
, antialias
,
992 _cairo_image_surface_glyphs (void *abstract_surface
,
994 const cairo_pattern_t
*source
,
995 cairo_glyph_t
*glyphs
,
997 cairo_scaled_font_t
*scaled_font
,
998 const cairo_clip_t
*clip
)
1000 cairo_image_surface_t
*surface
= abstract_surface
;
1002 TRACE ((stderr
, "%s (surface=%d)\n",
1003 __FUNCTION__
, surface
->base
.unique_id
));
1005 return _cairo_compositor_glyphs (surface
->compositor
, &surface
->base
,
1007 glyphs
, num_glyphs
, scaled_font
,
1012 _cairo_image_surface_get_font_options (void *abstract_surface
,
1013 cairo_font_options_t
*options
)
1015 _cairo_font_options_init_default (options
);
1017 cairo_font_options_set_hint_metrics (options
, CAIRO_HINT_METRICS_ON
);
1018 _cairo_font_options_set_round_glyph_positions (options
, CAIRO_ROUND_GLYPH_POS_ON
);
1021 const cairo_surface_backend_t _cairo_image_surface_backend
= {
1022 CAIRO_SURFACE_TYPE_IMAGE
,
1023 _cairo_image_surface_finish
,
1025 _cairo_default_context_create
,
1027 _cairo_image_surface_create_similar
,
1028 NULL
, /* create similar image */
1029 _cairo_image_surface_map_to_image
,
1030 _cairo_image_surface_unmap_image
,
1032 _cairo_image_surface_source
,
1033 _cairo_image_surface_acquire_source_image
,
1034 _cairo_image_surface_release_source_image
,
1035 _cairo_image_surface_snapshot
,
1037 NULL
, /* copy_page */
1038 NULL
, /* show_page */
1040 _cairo_image_surface_get_extents
,
1041 _cairo_image_surface_get_font_options
,
1046 _cairo_image_surface_paint
,
1047 _cairo_image_surface_mask
,
1048 _cairo_image_surface_stroke
,
1049 _cairo_image_surface_fill
,
1050 NULL
, /* fill-stroke */
1051 _cairo_image_surface_glyphs
,
1054 /* A convenience function for when one needs to coerce an image
1055 * surface to an alternate format. */
1056 cairo_image_surface_t
*
1057 _cairo_image_surface_coerce (cairo_image_surface_t
*surface
)
1059 return _cairo_image_surface_coerce_to_format (surface
,
1060 _cairo_format_from_content (surface
->base
.content
));
1063 /* A convenience function for when one needs to coerce an image
1064 * surface to an alternate format. */
1065 cairo_image_surface_t
*
1066 _cairo_image_surface_coerce_to_format (cairo_image_surface_t
*surface
,
1067 cairo_format_t format
)
1069 cairo_image_surface_t
*clone
;
1070 cairo_status_t status
;
1072 status
= surface
->base
.status
;
1073 if (unlikely (status
))
1074 return (cairo_image_surface_t
*)_cairo_surface_create_in_error (status
);
1076 if (surface
->format
== format
)
1077 return (cairo_image_surface_t
*)cairo_surface_reference(&surface
->base
);
1079 clone
= (cairo_image_surface_t
*)
1080 cairo_image_surface_create (format
, surface
->width
, surface
->height
);
1081 if (unlikely (clone
->base
.status
))
1084 pixman_image_composite32 (PIXMAN_OP_SRC
,
1085 surface
->pixman_image
, NULL
, clone
->pixman_image
,
1089 surface
->width
, surface
->height
);
1090 clone
->base
.is_clear
= FALSE
;
1092 clone
->base
.device_transform
=
1093 surface
->base
.device_transform
;
1094 clone
->base
.device_transform_inverse
=
1095 surface
->base
.device_transform_inverse
;
1100 cairo_image_surface_t
*
1101 _cairo_image_surface_create_from_image (cairo_image_surface_t
*other
,
1102 pixman_format_code_t format
,
1104 int width
, int height
, int stride
)
1106 cairo_image_surface_t
*surface
;
1107 cairo_status_t status
;
1108 pixman_image_t
*image
;
1111 status
= other
->base
.status
;
1112 if (unlikely (status
))
1116 mem
= _cairo_malloc_ab (height
, stride
);
1117 if (unlikely (mem
== NULL
)) {
1118 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1123 image
= pixman_image_create_bits (format
, width
, height
, mem
, stride
);
1124 if (unlikely (image
== NULL
)) {
1125 status
= _cairo_error (CAIRO_STATUS_NO_MEMORY
);
1129 surface
= (cairo_image_surface_t
*)
1130 _cairo_image_surface_create_for_pixman_image (image
, format
);
1131 if (unlikely (surface
->base
.status
)) {
1132 status
= surface
->base
.status
;
1136 pixman_image_composite32 (PIXMAN_OP_SRC
,
1137 other
->pixman_image
, NULL
, image
,
1142 surface
->base
.is_clear
= FALSE
;
1143 surface
->owns_data
= mem
!= NULL
;
1148 pixman_image_unref (image
);
1152 return (cairo_image_surface_t
*) _cairo_surface_create_in_error (status
);
1155 cairo_image_transparency_t
1156 _cairo_image_analyze_transparency (cairo_image_surface_t
*image
)
1160 if (image
->transparency
!= CAIRO_IMAGE_UNKNOWN
)
1161 return image
->transparency
;
1163 if ((image
->base
.content
& CAIRO_CONTENT_ALPHA
) == 0)
1164 return image
->transparency
= CAIRO_IMAGE_IS_OPAQUE
;
1166 if (image
->base
.is_clear
)
1167 return image
->transparency
= CAIRO_IMAGE_HAS_BILEVEL_ALPHA
;
1169 if ((image
->base
.content
& CAIRO_CONTENT_COLOR
) == 0) {
1170 if (image
->format
== CAIRO_FORMAT_A1
) {
1171 return image
->transparency
= CAIRO_IMAGE_HAS_BILEVEL_ALPHA
;
1172 } else if (image
->format
== CAIRO_FORMAT_A8
) {
1173 for (y
= 0; y
< image
->height
; y
++) {
1174 uint8_t *alpha
= (uint8_t *) (image
->data
+ y
* image
->stride
);
1176 for (x
= 0; x
< image
->width
; x
++, alpha
++) {
1177 if (*alpha
> 0 && *alpha
< 255)
1178 return image
->transparency
= CAIRO_IMAGE_HAS_ALPHA
;
1181 return image
->transparency
= CAIRO_IMAGE_HAS_BILEVEL_ALPHA
;
1183 return image
->transparency
= CAIRO_IMAGE_HAS_ALPHA
;
1187 if (image
->format
== CAIRO_FORMAT_RGB16_565
) {
1188 image
->transparency
= CAIRO_IMAGE_IS_OPAQUE
;
1189 return CAIRO_IMAGE_IS_OPAQUE
;
1192 if (image
->format
!= CAIRO_FORMAT_ARGB32
)
1193 return image
->transparency
= CAIRO_IMAGE_HAS_ALPHA
;
1195 image
->transparency
= CAIRO_IMAGE_IS_OPAQUE
;
1196 for (y
= 0; y
< image
->height
; y
++) {
1197 uint32_t *pixel
= (uint32_t *) (image
->data
+ y
* image
->stride
);
1199 for (x
= 0; x
< image
->width
; x
++, pixel
++) {
1200 int a
= (*pixel
& 0xff000000) >> 24;
1201 if (a
> 0 && a
< 255) {
1202 return image
->transparency
= CAIRO_IMAGE_HAS_ALPHA
;
1203 } else if (a
== 0) {
1204 image
->transparency
= CAIRO_IMAGE_HAS_BILEVEL_ALPHA
;
1209 return image
->transparency
;
1213 _cairo_image_analyze_color (cairo_image_surface_t
*image
)
1217 if (image
->color
!= CAIRO_IMAGE_UNKNOWN_COLOR
)
1218 return image
->color
;
1220 if (image
->format
== CAIRO_FORMAT_A1
)
1221 return image
->color
= CAIRO_IMAGE_IS_MONOCHROME
;
1223 if (image
->format
== CAIRO_FORMAT_A8
)
1224 return image
->color
= CAIRO_IMAGE_IS_GRAYSCALE
;
1226 if (image
->format
== CAIRO_FORMAT_ARGB32
) {
1227 image
->color
= CAIRO_IMAGE_IS_MONOCHROME
;
1228 for (y
= 0; y
< image
->height
; y
++) {
1229 uint32_t *pixel
= (uint32_t *) (image
->data
+ y
* image
->stride
);
1231 for (x
= 0; x
< image
->width
; x
++, pixel
++) {
1232 int a
= (*pixel
& 0xff000000) >> 24;
1233 int r
= (*pixel
& 0x00ff0000) >> 16;
1234 int g
= (*pixel
& 0x0000ff00) >> 8;
1235 int b
= (*pixel
& 0x000000ff);
1239 r
= (r
* 255 + a
/ 2) / a
;
1240 g
= (g
* 255 + a
/ 2) / a
;
1241 b
= (b
* 255 + a
/ 2) / a
;
1243 if (!(r
== g
&& g
== b
))
1244 return image
->color
= CAIRO_IMAGE_IS_COLOR
;
1245 else if (r
> 0 && r
< 255)
1246 image
->color
= CAIRO_IMAGE_IS_GRAYSCALE
;
1249 return image
->color
;
1252 if (image
->format
== CAIRO_FORMAT_RGB24
) {
1253 image
->color
= CAIRO_IMAGE_IS_MONOCHROME
;
1254 for (y
= 0; y
< image
->height
; y
++) {
1255 uint32_t *pixel
= (uint32_t *) (image
->data
+ y
* image
->stride
);
1257 for (x
= 0; x
< image
->width
; x
++, pixel
++) {
1258 int r
= (*pixel
& 0x00ff0000) >> 16;
1259 int g
= (*pixel
& 0x0000ff00) >> 8;
1260 int b
= (*pixel
& 0x000000ff);
1261 if (!(r
== g
&& g
== b
))
1262 return image
->color
= CAIRO_IMAGE_IS_COLOR
;
1263 else if (r
> 0 && r
< 255)
1264 image
->color
= CAIRO_IMAGE_IS_GRAYSCALE
;
1267 return image
->color
;
1270 return image
->color
= CAIRO_IMAGE_IS_COLOR
;
1273 cairo_image_surface_t
*
1274 _cairo_image_surface_clone_subimage (cairo_surface_t
*surface
,
1275 const cairo_rectangle_int_t
*extents
)
1277 cairo_surface_t
*image
;
1278 cairo_surface_pattern_t pattern
;
1279 cairo_status_t status
;
1281 image
= cairo_surface_create_similar_image (surface
,
1282 _cairo_format_from_content (surface
->content
),
1286 return to_image_surface (image
);
1288 /* TODO: check me with non-identity device_transform. Should we
1289 * clone the scaling, too? */
1290 cairo_surface_set_device_offset (image
,
1294 _cairo_pattern_init_for_surface (&pattern
, surface
);
1295 pattern
.base
.filter
= CAIRO_FILTER_NEAREST
;
1297 status
= _cairo_surface_paint (image
,
1298 CAIRO_OPERATOR_SOURCE
,
1302 _cairo_pattern_fini (&pattern
.base
);
1304 if (unlikely (status
))
1307 /* We use the parent as a flag during map-to-image/umap-image that the
1308 * resultant image came from a fallback rather than as direct call
1309 * to the backend's map_to_image(). Whilst we use it as a simple flag,
1310 * we need to make sure the parent surface obeys the reference counting
1311 * semantics and is consistent for all callers.
1313 _cairo_image_surface_set_parent (to_image_surface (image
),
1314 cairo_surface_reference (surface
));
1316 return to_image_surface (image
);
1319 cairo_surface_destroy (image
);
1320 return to_image_surface (_cairo_surface_create_in_error (status
));