/* Limit on the width / height of an image surface in pixels. This is *mainlydeterminedbycoordinatesofthingssenttopixmanatthe
* moment being in 16.16 format. */ #define MAX_IMAGE_SIZE 32767
cairo_format_t
_cairo_format_from_pixman_format (pixman_format_code_t pixman_format)
{ switch (pixman_format) { case PIXMAN_rgba_float: return CAIRO_FORMAT_RGBA128F; case PIXMAN_rgb_float: return CAIRO_FORMAT_RGB96F; case PIXMAN_a8r8g8b8: return CAIRO_FORMAT_ARGB32; case PIXMAN_x2r10g10b10: return CAIRO_FORMAT_RGB30; case PIXMAN_x8r8g8b8: return CAIRO_FORMAT_RGB24; case PIXMAN_a8: return CAIRO_FORMAT_A8; case PIXMAN_a1: return CAIRO_FORMAT_A1; case PIXMAN_r5g6b5: return CAIRO_FORMAT_RGB16_565; case PIXMAN_r8g8b8a8: case PIXMAN_r8g8b8x8: case PIXMAN_a8r8g8b8_sRGB: #if HAS_PIXMAN_r8g8b8_sRGB case PIXMAN_r8g8b8_sRGB: #endif case PIXMAN_a8b8g8r8: case PIXMAN_x8b8g8r8: case PIXMAN_r8g8b8: case PIXMAN_b8g8r8: case PIXMAN_b5g6r5: case PIXMAN_a1r5g5b5: case PIXMAN_x1r5g5b5: case PIXMAN_a1b5g5r5: case PIXMAN_x1b5g5r5: case PIXMAN_a4r4g4b4: case PIXMAN_x4r4g4b4: case PIXMAN_a4b4g4r4: case PIXMAN_x4b4g4r4: case PIXMAN_r3g3b2: case PIXMAN_b2g3r3: case PIXMAN_a2r2g2b2: case PIXMAN_a2b2g2r2: case PIXMAN_c8: case PIXMAN_g8: case PIXMAN_x4a4: case PIXMAN_a4: case PIXMAN_r1g2b1: case PIXMAN_b1g2r1: case PIXMAN_a1r1g1b1: case PIXMAN_a1b1g1r1: case PIXMAN_c4: case PIXMAN_g4: case PIXMAN_g1: case PIXMAN_yuy2: case PIXMAN_yv12: case PIXMAN_b8g8r8x8: case PIXMAN_b8g8r8a8: case PIXMAN_a2b10g10r10: case PIXMAN_x2b10g10r10: case PIXMAN_a2r10g10b10: case PIXMAN_x14r6g6b6: default: return CAIRO_FORMAT_INVALID;
}
cairo_bool_t
_pixman_format_from_masks (cairo_format_masks_t *masks,
pixman_format_code_t *format_ret)
{
pixman_format_code_t format; int format_type; int a, r, g, b;
cairo_format_masks_t format_masks;
a = _cairo_popcount (masks->alpha_mask);
r = _cairo_popcount (masks->red_mask);
g = _cairo_popcount (masks->green_mask);
b = _cairo_popcount (masks->blue_mask);
format = PIXMAN_FORMAT (masks->bpp, format_type, a, r, g, b);
if (! pixman_format_supported_destination (format)) returnFALSE;
/* Sanity check that we got out of PIXMAN_FORMAT exactly what we *expected.Thisavoidanyproblemsfromsomethingbizarrelike *alphaintheleast-significantbits,orinsanechannelorder,
* or whatever. */ if (!_pixman_format_to_masks (format, &format_masks) ||
masks->bpp != format_masks.bpp ||
masks->red_mask != format_masks.red_mask ||
masks->green_mask != format_masks.green_mask ||
masks->blue_mask != format_masks.blue_mask)
{ returnFALSE;
}
*format_ret = format; return TRUE;
}
/* Convenience function to convert #cairo_dither_t into #pixman_dither_t */ static pixman_dither_t
_cairo_dither_to_pixman_dither (cairo_dither_t dither)
{ switch (dither) { case CAIRO_DITHER_FAST: return PIXMAN_DITHER_FAST; case CAIRO_DITHER_GOOD: return PIXMAN_DITHER_GOOD; case CAIRO_DITHER_BEST: return PIXMAN_DITHER_BEST; case CAIRO_DITHER_NONE: case CAIRO_DITHER_DEFAULT: default: return PIXMAN_DITHER_NONE;
}
}
/* A mask consisting of N bits set to 1. */ #define MASK(N) ((1UL << (N))-1)
cairo_bool_t
_pixman_format_to_masks (pixman_format_code_t format,
cairo_format_masks_t *masks)
{ int a, r, g, b;
masks->bpp = PIXMAN_FORMAT_BPP (format);
/* Number of bits in each channel */
a = PIXMAN_FORMAT_A (format);
r = PIXMAN_FORMAT_R (format);
g = PIXMAN_FORMAT_G (format);
b = PIXMAN_FORMAT_B (format);
pixman_format_code_t
_cairo_format_to_pixman_format_code (cairo_format_t format)
{
pixman_format_code_t ret; switch (format) { case CAIRO_FORMAT_A1:
ret = PIXMAN_a1; break; case CAIRO_FORMAT_A8:
ret = PIXMAN_a8; break; case CAIRO_FORMAT_RGB24:
ret = PIXMAN_x8r8g8b8; break; case CAIRO_FORMAT_RGB30:
ret = PIXMAN_x2r10g10b10; break; case CAIRO_FORMAT_RGB16_565:
ret = PIXMAN_r5g6b5; break; case CAIRO_FORMAT_RGB96F:
ret = PIXMAN_rgb_float; break; case CAIRO_FORMAT_RGBA128F:
ret = PIXMAN_rgba_float; break; case CAIRO_FORMAT_ARGB32: case CAIRO_FORMAT_INVALID: default:
ret = PIXMAN_a8r8g8b8; break;
} return ret;
}
cairo_surface_t *
_cairo_image_surface_create_with_pixman_format (unsignedchar *data,
pixman_format_code_t pixman_format, int width, int height, int stride)
{
cairo_surface_t *surface;
pixman_image_t *pixman_image;
cairo_content_t
_cairo_content_from_format (cairo_format_t format)
{ switch (format) { case CAIRO_FORMAT_RGBA128F: case CAIRO_FORMAT_ARGB32: return CAIRO_CONTENT_COLOR_ALPHA; case CAIRO_FORMAT_RGB96F: case CAIRO_FORMAT_RGB30: return CAIRO_CONTENT_COLOR; case CAIRO_FORMAT_RGB24: return CAIRO_CONTENT_COLOR; case CAIRO_FORMAT_RGB16_565: return CAIRO_CONTENT_COLOR; case CAIRO_FORMAT_A8: case CAIRO_FORMAT_A1: return CAIRO_CONTENT_ALPHA; case CAIRO_FORMAT_INVALID: break;
}
int
_cairo_format_bits_per_pixel (cairo_format_t format)
{ switch (format) { case CAIRO_FORMAT_RGBA128F: return128; case CAIRO_FORMAT_RGB96F: return96; case CAIRO_FORMAT_ARGB32: case CAIRO_FORMAT_RGB30: case CAIRO_FORMAT_RGB24: return32; case CAIRO_FORMAT_RGB16_565: return16; case CAIRO_FORMAT_A8: return8; case CAIRO_FORMAT_A1: return1; case CAIRO_FORMAT_INVALID: default:
ASSERT_NOT_REACHED; return0;
}
}
cairo_surface_t *
_cairo_image_surface_create_similar (void *abstract_other,
cairo_content_t content, int width, int height)
{
cairo_image_surface_t *other = abstract_other;
/* If we own the image, we can simply steal the memory for the snapshot */ if (image->owns_data && image->base._finishing) {
clone = (cairo_image_surface_t *)
_cairo_image_surface_create_for_pixman_image (image->pixman_image,
image->pixman_format); if (unlikely (clone->base.status)) return &clone->base;
/* A convenience function for when one needs to coerce an image
* surface to an alternate format. */
cairo_image_surface_t *
_cairo_image_surface_coerce (cairo_image_surface_t *surface)
{ return _cairo_image_surface_coerce_to_format (surface,
_cairo_format_from_content (surface->base.content));
}
/* A convenience function for when one needs to coerce an image
* surface to an alternate format. */
cairo_image_surface_t *
_cairo_image_surface_coerce_to_format (cairo_image_surface_t *surface,
cairo_format_t format)
{
cairo_image_surface_t *clone;
cairo_status_t status;
status = surface->base.status; if (unlikely (status)) return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
if (surface->format == format) return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);
cairo_image_surface_t *
_cairo_image_surface_create_from_image (cairo_image_surface_t *other,
pixman_format_code_t format, int x, int y, int width, int height, int stride)
{
cairo_image_surface_t *surface;
cairo_status_t status;
pixman_image_t *image; void *mem = NULL;
status = other->base.status; if (unlikely (status)) goto cleanup;
if (stride) {
mem = _cairo_malloc_ab (height, stride); if (unlikely (mem == NULL)) {
status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto cleanup;
}
}
if (image->width == 0 || image->height == 0) return CAIRO_IMAGE_IS_MONOCHROME;
if (image->format == CAIRO_FORMAT_A1) return CAIRO_IMAGE_IS_MONOCHROME;
if (image->format == CAIRO_FORMAT_A8) return CAIRO_IMAGE_IS_GRAYSCALE;
if (image->format == CAIRO_FORMAT_ARGB32) {
color = CAIRO_IMAGE_IS_MONOCHROME; for (y = 0; y < image->height; y++) {
uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
for (x = 0; x < image->width; x++, pixel++) { int a = (*pixel & 0xff000000) >> 24; int r = (*pixel & 0x00ff0000) >> 16; int g = (*pixel & 0x0000ff00) >> 8; int b = (*pixel & 0x000000ff); if (a == 0) {
r = g = b = 0;
} else {
r = (r * 255 + a / 2) / a;
g = (g * 255 + a / 2) / a;
b = (b * 255 + a / 2) / a;
} if (!(r == g && g == b)) return CAIRO_IMAGE_IS_COLOR; elseif (r > 0 && r < 255)
color = CAIRO_IMAGE_IS_GRAYSCALE;
}
} return color;
}
if (image->format == CAIRO_FORMAT_RGB24) {
color = CAIRO_IMAGE_IS_MONOCHROME; for (y = 0; y < image->height; y++) {
uint32_t *pixel = (uint32_t *) (image->data + y * image->stride);
for (x = 0; x < image->width; x++, pixel++) { int r = (*pixel & 0x00ff0000) >> 16; int g = (*pixel & 0x0000ff00) >> 8; int b = (*pixel & 0x000000ff); if (!(r == g && g == b)) return CAIRO_IMAGE_IS_COLOR; elseif (r > 0 && r < 255)
color = CAIRO_IMAGE_IS_GRAYSCALE;
}
} return color;
}
return CAIRO_IMAGE_IS_COLOR;
}
cairo_image_color_t
_cairo_image_analyze_color (cairo_image_surface_t *image)
{ if (_cairo_surface_is_snapshot (&image->base)) { if (image->color == CAIRO_IMAGE_UNKNOWN_COLOR)
image->color = _cairo_image_compute_color (image);
/* TODO: check me with non-identity device_transform. Should we
* clone the scaling, too? */
cairo_surface_set_device_offset (image,
-extents->x,
-extents->y);
status = _cairo_surface_paint (image,
CAIRO_OPERATOR_SOURCE,
&pattern.base,
NULL);
_cairo_pattern_fini (&pattern.base);
if (unlikely (status)) goto error;
/* We use the parent as a flag during map-to-image/umap-image that the *resultantimagecamefromafallbackratherthanasdirectcall *tothebackend'smap_to_image().Whilstweuseitasasimpleflag, *weneedtomakesuretheparentsurfaceobeysthereferencecounting *semanticsandisconsistentforallcallers.
*/
_cairo_image_surface_set_parent (to_image_surface (image),
cairo_surface_reference (surface));
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.