michael@0: diff -r c1195334f839 gfx/cairo/cairo/src/cairo-xlib-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-xlib-surface.c Fri May 21 17:42:55 2010 +0300 michael@0: +++ b/gfx/cairo/cairo/src/cairo-xlib-surface.c Fri May 21 19:12:29 2010 +0300 michael@0: @@ -189,16 +189,57 @@ static const XTransform identity = { { michael@0: michael@0: #define CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 11) michael@0: michael@0: #define CAIRO_SURFACE_RENDER_SUPPORTS_OPERATOR(surface, op) \ michael@0: ((op) <= CAIRO_OPERATOR_SATURATE || \ michael@0: (CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS(surface) && \ michael@0: (op) <= CAIRO_OPERATOR_HSL_LUMINOSITY)) michael@0: michael@0: +static Visual * michael@0: +_visual_for_xrender_format(Screen *screen, michael@0: + XRenderPictFormat *xrender_format) michael@0: +{ michael@0: + int d, v; michael@0: + for (d = 0; d < screen->ndepths; d++) { michael@0: + Depth *d_info = &screen->depths[d]; michael@0: + if (d_info->depth != xrender_format->depth) michael@0: + continue; michael@0: + michael@0: + for (v = 0; v < d_info->nvisuals; v++) { michael@0: + Visual *visual = &d_info->visuals[v]; michael@0: + michael@0: + switch (visual->class) { michael@0: + case TrueColor: michael@0: + if (xrender_format->type != PictTypeDirect) michael@0: + continue; michael@0: + break; michael@0: + case DirectColor: michael@0: + /* Prefer TrueColor to DirectColor. michael@0: + (XRenderFindVisualFormat considers both TrueColor and michael@0: + DirectColor Visuals to match the same PictFormat.) */ michael@0: + continue; michael@0: + case StaticGray: michael@0: + case GrayScale: michael@0: + case StaticColor: michael@0: + case PseudoColor: michael@0: + if (xrender_format->type != PictTypeIndexed) michael@0: + continue; michael@0: + break; michael@0: + } michael@0: + michael@0: + if (xrender_format == michael@0: + XRenderFindVisualFormat (DisplayOfScreen(screen), visual)) michael@0: + return visual; michael@0: + } michael@0: + } michael@0: + michael@0: + return NULL; michael@0: +} michael@0: + michael@0: static cairo_status_t michael@0: _cairo_xlib_surface_set_clip_region (cairo_xlib_surface_t *surface, michael@0: cairo_region_t *region) michael@0: { michael@0: cairo_bool_t had_clip_rects = surface->clip_region != NULL; michael@0: michael@0: if (had_clip_rects == FALSE && region == NULL) michael@0: return CAIRO_STATUS_SUCCESS; michael@0: @@ -313,16 +354,19 @@ _cairo_xlib_surface_create_similar (void michael@0: * visual/depth etc. as possible. */ michael@0: pix = XCreatePixmap (src->dpy, src->drawable, michael@0: width <= 0 ? 1 : width, height <= 0 ? 1 : height, michael@0: xrender_format->depth); michael@0: michael@0: visual = NULL; michael@0: if (xrender_format == src->xrender_format) michael@0: visual = src->visual; michael@0: + else michael@0: + visual = _visual_for_xrender_format(src->screen->screen, michael@0: + xrender_format); michael@0: michael@0: surface = (cairo_xlib_surface_t *) michael@0: _cairo_xlib_surface_create_internal (src->screen, pix, michael@0: visual, michael@0: xrender_format, michael@0: width, height, michael@0: xrender_format->depth); michael@0: } michael@0: @@ -3178,28 +3222,32 @@ cairo_xlib_surface_create_with_xrender_f michael@0: Screen *scr, michael@0: XRenderPictFormat *format, michael@0: int width, michael@0: int height) michael@0: { michael@0: cairo_xlib_screen_t *screen; michael@0: cairo_surface_t *surface; michael@0: cairo_status_t status; michael@0: + Visual *visual; michael@0: michael@0: if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) michael@0: return _cairo_surface_create_in_error (CAIRO_STATUS_INVALID_SIZE); michael@0: michael@0: status = _cairo_xlib_screen_get (dpy, scr, &screen); michael@0: if (unlikely (status)) michael@0: return _cairo_surface_create_in_error (status); michael@0: michael@0: X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable)); michael@0: michael@0: + if (format) michael@0: + visual = _visual_for_xrender_format (scr, format); michael@0: + michael@0: surface = _cairo_xlib_surface_create_internal (screen, drawable, michael@0: - NULL, format, michael@0: + visual, format, michael@0: width, height, 0); michael@0: _cairo_xlib_screen_destroy (screen); michael@0: michael@0: return surface; michael@0: } michael@0: slim_hidden_def (cairo_xlib_surface_create_with_xrender_format); michael@0: michael@0: /** michael@0: @@ -3413,33 +3461,37 @@ cairo_xlib_surface_get_screen (cairo_sur michael@0: michael@0: return surface->screen->screen; michael@0: } michael@0: michael@0: /** michael@0: * cairo_xlib_surface_get_visual: michael@0: * @surface: a #cairo_xlib_surface_t michael@0: * michael@0: - * Get the X Visual used for underlying X Drawable. michael@0: + * Gets the X Visual associated with @surface, suitable for use with the michael@0: + * underlying X Drawable. If @surface was created by michael@0: + * cairo_xlib_surface_create(), the return value is the Visual passed to that michael@0: + * constructor. michael@0: * michael@0: - * Return value: the visual. michael@0: + * Return value: the Visual or %NULL if there is no appropriate Visual for michael@0: + * @surface. michael@0: * michael@0: * Since: 1.2 michael@0: **/ michael@0: Visual * michael@0: -cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface) michael@0: +cairo_xlib_surface_get_visual (cairo_surface_t *surface) michael@0: { michael@0: - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface; michael@0: - michael@0: - if (! _cairo_surface_is_xlib (abstract_surface)) { michael@0: + cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface; michael@0: + michael@0: + if (! _cairo_surface_is_xlib (surface)) { michael@0: _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); michael@0: return NULL; michael@0: } michael@0: michael@0: - return surface->visual; michael@0: + return xlib_surface->visual; michael@0: } michael@0: michael@0: /** michael@0: * cairo_xlib_surface_get_depth: michael@0: * @surface: a #cairo_xlib_surface_t michael@0: * michael@0: * Get the number of bits used to represent each pixel value. michael@0: *