beta-0.89.2
[luatex.git] / source / libs / cairo / cairo-src / src / cairo-image-surface.c
blob1fd563d1c3499c029463af852ba5e39c9c04f1cc
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
33 * California.
35 * Contributor(s):
36 * Carl D. Worth <cworth@cworth.org>
37 * Chris Wilson <chris@chris-wilson.co.uk>
40 #include "cairoint.h"
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
63 /**
64 * SECTION:cairo-image
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.
72 **/
74 /**
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.
81 * Since: 1.8
82 **/
84 static cairo_bool_t
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;
91 cairo_format_t
92 _cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
94 switch (pixman_format) {
95 case PIXMAN_a8r8g8b8:
96 return CAIRO_FORMAT_ARGB32;
97 case PIXMAN_x2r10g10b10:
98 return CAIRO_FORMAT_RGB30;
99 case PIXMAN_x8r8g8b8:
100 return CAIRO_FORMAT_RGB24;
101 case PIXMAN_a8:
102 return CAIRO_FORMAT_A8;
103 case PIXMAN_a1:
104 return CAIRO_FORMAT_A1;
105 case PIXMAN_r5g6b5:
106 return CAIRO_FORMAT_RGB16_565;
107 #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,22,0)
108 case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8:
109 #endif
110 #if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0,27,2)
111 case PIXMAN_a8r8g8b8_sRGB:
112 #endif
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:
131 #endif
132 default:
133 return CAIRO_FORMAT_INVALID;
136 return CAIRO_FORMAT_INVALID;
139 cairo_content_t
140 _cairo_content_from_pixman_format (pixman_format_code_t pixman_format)
142 cairo_content_t content;
144 content = 0;
145 if (PIXMAN_FORMAT_RGB (pixman_format))
146 content |= CAIRO_CONTENT_COLOR;
147 if (PIXMAN_FORMAT_A (pixman_format))
148 content |= CAIRO_CONTENT_ALPHA;
150 return content;
153 void
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 ();
178 cairo_surface_t *
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,
190 NULL, /* device */
191 _cairo_content_from_pixman_format (pixman_format));
193 _cairo_image_surface_init (surface, pixman_image, pixman_format);
195 return &surface->base;
198 cairo_bool_t
199 _pixman_format_from_masks (cairo_format_masks_t *masks,
200 pixman_format_code_t *format_ret)
202 pixman_format_code_t format;
203 int format_type;
204 int a, r, g, b;
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;
215 else
216 format_type = PIXMAN_TYPE_ABGR;
217 } else if (masks->alpha_mask) {
218 format_type = PIXMAN_TYPE_A;
219 } else {
220 return FALSE;
223 format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
225 if (! pixman_format_supported_destination (format))
226 return FALSE;
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,
231 * or whatever. */
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)
238 return FALSE;
241 *format_ret = format;
242 return TRUE;
245 /* A mask consisting of N bits set to 1. */
246 #define MASK(N) ((1UL << (N))-1)
248 cairo_bool_t
249 _pixman_format_to_masks (pixman_format_code_t format,
250 cairo_format_masks_t *masks)
252 int a, r, g, b;
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);
268 return TRUE;
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);
274 return TRUE;
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);
281 return TRUE;
282 #endif
283 case PIXMAN_TYPE_A:
284 masks->alpha_mask = MASK (a);
285 masks->red_mask = 0;
286 masks->green_mask = 0;
287 masks->blue_mask = 0;
288 return TRUE;
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:
294 default:
295 masks->alpha_mask = 0;
296 masks->red_mask = 0;
297 masks->green_mask = 0;
298 masks->blue_mask = 0;
299 return FALSE;
303 pixman_format_code_t
304 _cairo_format_to_pixman_format_code (cairo_format_t format)
306 pixman_format_code_t ret;
307 switch (format) {
308 case CAIRO_FORMAT_A1:
309 ret = PIXMAN_a1;
310 break;
311 case CAIRO_FORMAT_A8:
312 ret = PIXMAN_a8;
313 break;
314 case CAIRO_FORMAT_RGB24:
315 ret = PIXMAN_x8r8g8b8;
316 break;
317 case CAIRO_FORMAT_RGB30:
318 ret = PIXMAN_x2r10g10b10;
319 break;
320 case CAIRO_FORMAT_RGB16_565:
321 ret = PIXMAN_r5g6b5;
322 break;
323 case CAIRO_FORMAT_ARGB32:
324 case CAIRO_FORMAT_INVALID:
325 default:
326 ret = PIXMAN_a8r8g8b8;
327 break;
329 return ret;
332 cairo_surface_t *
333 _cairo_image_surface_create_with_pixman_format (unsigned char *data,
334 pixman_format_code_t pixman_format,
335 int width,
336 int height,
337 int stride)
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,
354 pixman_format);
355 if (unlikely (surface->status)) {
356 pixman_image_unref (pixman_image);
357 return surface;
360 /* we can not make any assumptions about the initial state of user data */
361 surface->is_clear = data == NULL;
362 return surface;
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
379 * with it.
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.
385 * Since: 1.0
387 cairo_surface_t *
388 cairo_image_surface_create (cairo_format_t format,
389 int width,
390 int height)
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,
400 width, height, -1);
402 slim_hidden_def (cairo_image_surface_create);
404 cairo_surface_t *
405 _cairo_image_surface_create_with_content (cairo_content_t content,
406 int width,
407 int height)
409 return cairo_image_surface_create (_cairo_format_from_content (content),
410 width, height);
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>
423 * int stride;
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,
430 * width, height,
431 * stride);
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
436 * too large.
438 * Since: 1.6
441 cairo_format_stride_for_width (cairo_format_t format,
442 int width)
444 int bpp;
446 if (! CAIRO_FORMAT_VALID (format)) {
447 _cairo_error_throw (CAIRO_STATUS_INVALID_FORMAT);
448 return -1;
451 bpp = _cairo_format_bits_per_pixel (format);
452 if ((unsigned) (width) >= (INT32_MAX - 7) / (unsigned) (bpp))
453 return -1;
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
470 * buffer.
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
490 * with it.
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.
502 * Since: 1.0
504 cairo_surface_t *
505 cairo_image_surface_create_for_data (unsigned char *data,
506 cairo_format_t format,
507 int width,
508 int height,
509 int stride)
511 pixman_format_code_t pixman_format;
512 int minstride;
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);
524 if (stride < 0) {
525 if (stride > -minstride) {
526 return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));
528 } else {
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,
536 pixman_format,
537 width, height,
538 stride);
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()
556 * has been called.
558 * Since: 1.2
560 unsigned char *
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);
567 return NULL;
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
582 * Since: 1.2
584 cairo_format_t
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.
606 * Since: 1.0
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);
615 return 0;
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.
630 * Since: 1.0
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);
639 return 0;
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.
657 * Since: 1.2
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);
667 return 0;
670 return image_surface->stride;
672 slim_hidden_def (cairo_image_surface_get_stride);
674 cairo_format_t
675 _cairo_format_from_content (cairo_content_t content)
677 switch (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;
686 ASSERT_NOT_REACHED;
687 return CAIRO_FORMAT_INVALID;
690 cairo_content_t
691 _cairo_content_from_format (cairo_format_t format)
693 switch (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:
706 break;
709 ASSERT_NOT_REACHED;
710 return CAIRO_CONTENT_COLOR_ALPHA;
714 _cairo_format_bits_per_pixel (cairo_format_t format)
716 switch (format) {
717 case CAIRO_FORMAT_ARGB32:
718 case CAIRO_FORMAT_RGB30:
719 case CAIRO_FORMAT_RGB24:
720 return 32;
721 case CAIRO_FORMAT_RGB16_565:
722 return 16;
723 case CAIRO_FORMAT_A8:
724 return 8;
725 case CAIRO_FORMAT_A1:
726 return 1;
727 case CAIRO_FORMAT_INVALID:
728 default:
729 ASSERT_NOT_REACHED;
730 return 0;
734 cairo_surface_t *
735 _cairo_image_surface_create_similar (void *abstract_other,
736 cairo_content_t content,
737 int width,
738 int height)
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,
750 width, height,
754 return _cairo_image_surface_create_with_content (content,
755 width, height);
758 cairo_surface_t *
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))
770 return &clone->base;
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;
779 return &clone->base;
782 clone = (cairo_image_surface_t *)
783 _cairo_image_surface_create_with_pixman_format (NULL,
784 image->pixman_format,
785 image->width,
786 image->height,
788 if (unlikely (clone->base.status))
789 return &clone->base;
791 if (clone->stride == image->stride) {
792 memcpy (clone->data, image->data, clone->stride * clone->height);
793 } else {
794 pixman_image_composite32 (PIXMAN_OP_SRC,
795 image->pixman_image, NULL, clone->pixman_image,
796 0, 0,
797 0, 0,
798 0, 0,
799 image->width, image->height);
801 clone->base.is_clear = FALSE;
802 return &clone->base;
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;
811 uint8_t *data;
813 data = other->data;
814 data += extents->y * other->stride;
815 data += extents->x * PIXMAN_FORMAT_BPP (other->pixman_format)/ 8;
817 surface =
818 _cairo_image_surface_create_with_pixman_format (data,
819 other->pixman_format,
820 extents->width,
821 extents->height,
822 other->stride);
824 cairo_surface_set_device_offset (surface, -extents->x, -extents->y);
825 return (cairo_image_surface_t *) surface;
828 cairo_int_status_t
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;
838 cairo_status_t
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;
862 void
863 _cairo_image_surface_assume_ownership_of_data (cairo_image_surface_t *surface)
865 surface->owns_data = TRUE;
868 cairo_surface_t *
869 _cairo_image_surface_source (void *abstract_surface,
870 cairo_rectangle_int_t *extents)
872 cairo_image_surface_t *surface = abstract_surface;
874 if (extents) {
875 extents->x = extents->y = 0;
876 extents->width = surface->width;
877 extents->height = surface->height;
880 return &surface->base;
883 cairo_status_t
884 _cairo_image_surface_acquire_source_image (void *abstract_surface,
885 cairo_image_surface_t **image_out,
886 void **image_extra)
888 *image_out = abstract_surface;
889 *image_extra = NULL;
891 return CAIRO_STATUS_SUCCESS;
894 void
895 _cairo_image_surface_release_source_image (void *abstract_surface,
896 cairo_image_surface_t *image,
897 void *image_extra)
901 /* high level image interface */
902 cairo_bool_t
903 _cairo_image_surface_get_extents (void *abstract_surface,
904 cairo_rectangle_int_t *rectangle)
906 cairo_image_surface_t *surface = abstract_surface;
908 rectangle->x = 0;
909 rectangle->y = 0;
910 rectangle->width = surface->width;
911 rectangle->height = surface->height;
913 return TRUE;
916 cairo_int_status_t
917 _cairo_image_surface_paint (void *abstract_surface,
918 cairo_operator_t op,
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);
931 cairo_int_status_t
932 _cairo_image_surface_mask (void *abstract_surface,
933 cairo_operator_t op,
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);
947 cairo_int_status_t
948 _cairo_image_surface_stroke (void *abstract_surface,
949 cairo_operator_t op,
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,
955 double tolerance,
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,
965 op, source, path,
966 style, ctm, ctm_inverse,
967 tolerance, antialias, clip);
970 cairo_int_status_t
971 _cairo_image_surface_fill (void *abstract_surface,
972 cairo_operator_t op,
973 const cairo_pattern_t *source,
974 const cairo_path_fixed_t *path,
975 cairo_fill_rule_t fill_rule,
976 double tolerance,
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,
986 op, source, path,
987 fill_rule, tolerance, antialias,
988 clip);
991 cairo_int_status_t
992 _cairo_image_surface_glyphs (void *abstract_surface,
993 cairo_operator_t op,
994 const cairo_pattern_t *source,
995 cairo_glyph_t *glyphs,
996 int num_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,
1006 op, source,
1007 glyphs, num_glyphs, scaled_font,
1008 clip);
1011 void
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,
1043 NULL, /* flush */
1044 NULL,
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))
1082 return clone;
1084 pixman_image_composite32 (PIXMAN_OP_SRC,
1085 surface->pixman_image, NULL, clone->pixman_image,
1086 0, 0,
1087 0, 0,
1088 0, 0,
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;
1097 return clone;
1100 cairo_image_surface_t *
1101 _cairo_image_surface_create_from_image (cairo_image_surface_t *other,
1102 pixman_format_code_t format,
1103 int x, int y,
1104 int width, int height, int stride)
1106 cairo_image_surface_t *surface;
1107 cairo_status_t status;
1108 pixman_image_t *image;
1109 void *mem = NULL;
1111 status = other->base.status;
1112 if (unlikely (status))
1113 goto cleanup;
1115 if (stride) {
1116 mem = _cairo_malloc_ab (height, stride);
1117 if (unlikely (mem == NULL)) {
1118 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1119 goto cleanup;
1123 image = pixman_image_create_bits (format, width, height, mem, stride);
1124 if (unlikely (image == NULL)) {
1125 status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
1126 goto cleanup_mem;
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;
1133 goto cleanup_image;
1136 pixman_image_composite32 (PIXMAN_OP_SRC,
1137 other->pixman_image, NULL, image,
1138 x, y,
1139 0, 0,
1140 0, 0,
1141 width, height);
1142 surface->base.is_clear = FALSE;
1143 surface->owns_data = mem != NULL;
1145 return surface;
1147 cleanup_image:
1148 pixman_image_unref (image);
1149 cleanup_mem:
1150 free (mem);
1151 cleanup:
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)
1158 int x, y;
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;
1182 } else {
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;
1212 cairo_image_color_t
1213 _cairo_image_analyze_color (cairo_image_surface_t *image)
1215 int x, y;
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);
1236 if (a == 0) {
1237 r = g = b = 0;
1238 } else {
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),
1283 extents->width,
1284 extents->height);
1285 if (image->status)
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,
1291 -extents->x,
1292 -extents->y);
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,
1299 &pattern.base,
1300 NULL);
1302 _cairo_pattern_fini (&pattern.base);
1304 if (unlikely (status))
1305 goto error;
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);
1318 error:
1319 cairo_surface_destroy (image);
1320 return to_image_surface (_cairo_surface_create_in_error (status));