static cairo_surface_t * _cairo_win32_display_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height) { cairo_win32_display_surface_t *src = abstract_src; cairo_format_t format = _cairo_format_from_content (content); cairo_surface_t *new_surf = NULL; /* We force a DIB always if: * - we need alpha; or * - the parent is a DIB; or * - the parent is for printing (because we don't care about the * bit depth at that point) * * We also might end up with a DIB even if a DDB is requested if * DDB creation failed due to out of memory. */ if (!(src->is_dib || content & CAIRO_CONTENT_ALPHA)) { /* try to create a ddb */ new_surf = cairo_win32_surface_create_with_ddb (src->win32.dc, CAIRO_FORMAT_RGB24, width, height); if (new_surf->status) new_surf = NULL; } if (new_surf == NULL) { new_surf = _cairo_win32_display_surface_create_for_dc (src->win32.dc, format, width, height); } return new_surf; }
static cairo_surface_t * _cairo_skia_surface_create_similar (void *asurface, cairo_content_t content, int width, int height) { cairo_skia_surface_t *surface = (cairo_skia_surface_t *) asurface; SkBitmap::Config config; bool opaque; if (content == surface->image.base.content) { config = surface->bitmap->getConfig (); opaque = surface->bitmap->isOpaque (); } else if (! format_to_sk_config (_cairo_format_from_content (content), config, opaque)) { return NULL; } return &_cairo_skia_surface_create_internal (config, opaque, NULL, width, height, 0)->image.base; }
cairo_surface_t * _cairo_image_surface_create_with_content (cairo_content_t content, int width, int height) { return cairo_image_surface_create (_cairo_format_from_content (content), width, height); }
static cairo_surface_t * radeon_surface_create_similar (void *abstract_surface, cairo_content_t content, int width, int height) { return cairo_image_surface_create (_cairo_format_from_content (content), width, height); }
cairo_surface_t * _cairo_image_surface_create_with_content (cairo_content_t content, int width, int height) { if (! CAIRO_CONTENT_VALID (content)) return (cairo_surface_t*) &_cairo_surface_nil; return cairo_image_surface_create (_cairo_format_from_content (content), width, height); }
cairo_surface_t * _cairo_image_surface_create_with_content (cairo_content_t content, int width, int height) { if (! CAIRO_CONTENT_VALID (content)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); return cairo_image_surface_create (_cairo_format_from_content (content), width, height); }
static cairo_surface_t * _cairo_win32_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height) { cairo_win32_surface_t *src = abstract_src; cairo_format_t format = _cairo_format_from_content (content); return _cairo_win32_surface_create_for_dc (src->dc, format, width, height); }
cairo_surface_t * cairo_xynth_surface_create_with_content (cairo_content_t content, int width, int height) { cairo_surface_t *surface; ENTER(); if (!CAIRO_CONTENT_VALID(content)) { surface = NULL; } else { surface = cairo_xynth_surface_create( width, height, _cairo_format_from_content(content)); } LEAVE(); return surface; }
cairo_surface_t * _cairo_image_surface_create_for_data_with_content (unsigned char *data, cairo_content_t content, int width, int height, int stride) { if (! CAIRO_CONTENT_VALID (content)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_CONTENT)); return cairo_image_surface_create_for_data (data, _cairo_format_from_content (content), width, height, stride); }
cairo_surface_t * _cairo_image_surface_create_for_data_with_content (unsigned char *data, cairo_content_t content, int width, int height, int stride) { if (! CAIRO_CONTENT_VALID (content)) return (cairo_surface_t*) &_cairo_surface_nil; return cairo_image_surface_create_for_data (data, _cairo_format_from_content (content), width, height, stride); }
cairo_surface_t * _cairo_surface_fallback_snapshot (cairo_surface_t *surface) { cairo_surface_t *snapshot; cairo_status_t status; cairo_format_t format; cairo_surface_pattern_t pattern; cairo_image_surface_t *image; void *image_extra; status = _cairo_surface_acquire_source_image (surface, &image, &image_extra); if (unlikely (status)) return _cairo_surface_create_in_error (status); format = image->format; if (format == CAIRO_FORMAT_INVALID) { /* Non-standard images formats can be generated when retrieving * images from unusual xservers, for example. */ format = _cairo_format_from_content (image->base.content); } snapshot = cairo_image_surface_create (format, image->width, image->height); if (cairo_surface_status (snapshot)) { _cairo_surface_release_source_image (surface, image, image_extra); return snapshot; } _cairo_pattern_init_for_surface (&pattern, &image->base); status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, &pattern.base, NULL, snapshot, 0, 0, 0, 0, 0, 0, image->width, image->height); _cairo_pattern_fini (&pattern.base); _cairo_surface_release_source_image (surface, image, image_extra); if (unlikely (status)) { cairo_surface_destroy (snapshot); return _cairo_surface_create_in_error (status); } return snapshot; }
static cairo_surface_t * _cairo_quartz_image_surface_create_similar (void *asurface, cairo_content_t content, int width, int height) { cairo_surface_t *result; cairo_surface_t *isurf = cairo_image_surface_create (_cairo_format_from_content (content), width, height); if (cairo_surface_status(isurf)) return isurf; result = cairo_quartz_image_surface_create (isurf); cairo_surface_destroy (isurf); return result; }
/** ** Surface backend methods **/ static cairo_surface_t * _cairo_qt_surface_create_similar (void *abstract_surface, cairo_content_t content, int width, int height) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; bool use_pixmap; D(fprintf(stderr, "q[%p] create_similar: %d %d [%d] -> ", abstract_surface, width, height, content)); use_pixmap = qs->image == NULL; if (use_pixmap) { switch (content) { case CAIRO_CONTENT_ALPHA: use_pixmap = FALSE; break; case CAIRO_CONTENT_COLOR: break; case CAIRO_CONTENT_COLOR_ALPHA: use_pixmap = ! _qpixmaps_have_no_alpha; break; } } if (use_pixmap) { cairo_surface_t *result = cairo_qt_surface_create_with_qpixmap (content, width, height); /* XXX result->content is always content. ??? */ if (result->content == content) { D(fprintf(stderr, "qpixmap content: %d\n", content)); return result; } _qpixmaps_have_no_alpha = TRUE; cairo_surface_destroy (result); } D(fprintf (stderr, "qimage\n")); return cairo_qt_surface_create_with_qimage (_cairo_format_from_content (content), width, height); }
static cairo_surface_t * _cairo_skia_surface_create_similar (void *asurface, cairo_content_t content, int width, int height) { SkBitmap::Config config; bool opaque; if (! format_to_sk_config (_cairo_format_from_content (content), config, opaque)) { return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); } return &_cairo_skia_surface_create_internal (config, opaque, NULL, width, height, 0)->base; }
static cairo_surface_t * _cairo_xcb_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height) { cairo_xcb_surface_t *src = abstract_src; XCBConnection *dpy = src->dpy; XCBDRAWABLE d; cairo_xcb_surface_t *surface; cairo_format_t format = _cairo_format_from_content (content); XCBRenderPICTFORMINFO *xrender_format; /* As a good first approximation, if the display doesn't have COMPOSITE, * we're better off using image surfaces for all temporary operations */ if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src)) { return cairo_image_surface_create (format, width, height); } d.pixmap = XCBPIXMAPNew (dpy); XCBCreatePixmap (dpy, _CAIRO_FORMAT_DEPTH (format), d.pixmap, src->drawable, width <= 0 ? 1 : width, height <= 0 ? 1 : height); xrender_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), format); /* XXX: what to do if xrender_format is null? */ surface = (cairo_xcb_surface_t *) cairo_xcb_surface_create_with_xrender_format (dpy, d, src->screen, xrender_format, width, height); if (surface->base.status) { _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t*) &_cairo_surface_nil; } surface->owns_pixmap = TRUE; return &surface->base; }
static cairo_surface_t * _cairo_skia_surface_create_similar (void *asurface, cairo_content_t content, int width, int height) { SkBitmap::Config config; bool opaque; if (! format_to_sk_config (_cairo_format_from_content (content), config, opaque)) { _skia_unsupported (); return NULL; } return &_cairo_skia_surface_create_internal (config, opaque, NULL, width, height, 0)->base; }
static cairo_status_t _cairo_gl_glyph_cache_add_glyph (cairo_gl_glyph_cache_t *cache, cairo_scaled_glyph_t *scaled_glyph) { cairo_image_surface_t *glyph_surface = scaled_glyph->surface; cairo_gl_glyph_private_t *glyph_private; cairo_rtree_node_t *node = NULL; cairo_image_surface_t *clone = NULL; cairo_status_t status; int width, height; GLenum internal_format, format, type; cairo_bool_t has_alpha; if (! _cairo_gl_get_image_format_and_type (glyph_surface->pixman_format, &internal_format, &format, &type, &has_alpha)) { cairo_bool_t is_supported; clone = _cairo_image_surface_coerce (glyph_surface, _cairo_format_from_content (glyph_surface->base.content)); if (unlikely (clone->base.status)) return clone->base.status; is_supported = _cairo_gl_get_image_format_and_type (clone->pixman_format, &internal_format, &format, &type, &has_alpha); assert (is_supported); glyph_surface = clone; } width = glyph_surface->width; if (width < GLYPH_CACHE_MIN_SIZE) width = GLYPH_CACHE_MIN_SIZE; height = glyph_surface->height; if (height < GLYPH_CACHE_MIN_SIZE) height = GLYPH_CACHE_MIN_SIZE; /* search for an available slot */ status = _cairo_rtree_insert (&cache->rtree, width, height, &node); /* search for an unlocked slot */ if (status == CAIRO_INT_STATUS_UNSUPPORTED) { status = _cairo_rtree_evict_random (&cache->rtree, width, height, &node); if (status == CAIRO_STATUS_SUCCESS) { status = _cairo_rtree_node_insert (&cache->rtree, node, width, height, &node); } } if (status) return status; glPixelStorei (GL_UNPACK_ALIGNMENT, 1); glPixelStorei (GL_UNPACK_ROW_LENGTH, glyph_surface->stride / (PIXMAN_FORMAT_BPP (glyph_surface->pixman_format) / 8)); glTexSubImage2D (GL_TEXTURE_2D, 0, node->x, node->y, glyph_surface->width, glyph_surface->height, format, type, glyph_surface->data); glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); scaled_glyph->surface_private = node; node->owner = &scaled_glyph->surface_private; glyph_private = (cairo_gl_glyph_private_t *) node; glyph_private->cache = cache; /* compute tex coords */ glyph_private->p1.x = node->x / (double) cache->width; glyph_private->p1.y = node->y / (double) cache->height; glyph_private->p2.x = (node->x + glyph_surface->width) / (double) cache->width; glyph_private->p2.y = (node->y + glyph_surface->height) / (double) cache->height; cairo_surface_destroy (&clone->base); return CAIRO_STATUS_SUCCESS; }
/* 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)); }
cairo_surface_t * _cairo_xcb_surface_create_similar (void *abstract_other, cairo_content_t content, int width, int height) { cairo_xcb_surface_t *other = abstract_other; cairo_xcb_surface_t *surface; cairo_xcb_connection_t *connection; xcb_pixmap_t pixmap; cairo_status_t status; if (unlikely(width > XLIB_COORD_MAX || height > XLIB_COORD_MAX || width <= 0 || height <= 0)) return cairo_image_surface_create (_cairo_format_from_content (content), width, height); if ((other->connection->flags & CAIRO_XCB_HAS_RENDER) == 0) return _cairo_xcb_surface_create_similar_image (other, _cairo_format_from_content (content), width, height); connection = other->connection; status = _cairo_xcb_connection_acquire (connection); if (unlikely (status)) return _cairo_surface_create_in_error (status); if (content == other->base.content) { pixmap = _cairo_xcb_connection_create_pixmap (connection, other->depth, other->drawable, width, height); surface = (cairo_xcb_surface_t *) _cairo_xcb_surface_create_internal (other->screen, pixmap, TRUE, other->pixman_format, other->xrender_format, width, height); } else { cairo_format_t format; pixman_format_code_t pixman_format; /* XXX find a compatible xrender format */ switch (content) { case CAIRO_CONTENT_ALPHA: pixman_format = PIXMAN_a8; format = CAIRO_FORMAT_A8; break; case CAIRO_CONTENT_COLOR: pixman_format = PIXMAN_x8r8g8b8; format = CAIRO_FORMAT_RGB24; break; default: ASSERT_NOT_REACHED; case CAIRO_CONTENT_COLOR_ALPHA: pixman_format = PIXMAN_a8r8g8b8; format = CAIRO_FORMAT_ARGB32; break; } pixmap = _cairo_xcb_connection_create_pixmap (connection, PIXMAN_FORMAT_DEPTH (pixman_format), other->drawable, width, height); surface = (cairo_xcb_surface_t *) _cairo_xcb_surface_create_internal (other->screen, pixmap, TRUE, pixman_format, connection->standard_formats[format], width, height); } if (unlikely (surface->base.status)) _cairo_xcb_connection_free_pixmap (connection, pixmap); _cairo_xcb_connection_release (connection); return &surface->base; }