mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 20:28:02 +02:00
xlib: Find matching Visual for XRenderFormat
Not only is this useful for users to know which Visual matches any
particular Cairo surface, it should also close a few obscure bugs of not
converting images correctly on upload.
Fixes:
Bug 28492 - cairo_xlib_surface_create_with_xrender_format does not
create visual for resulting surface
https://bugs.freedesktop.org/show_bug.cgi?id=28492
Mozilla Bug 567065 - Try to create offscreen Xlib surface from existing
visual if possible
https://bugzilla.mozilla.org/show_bug.cgi?id=567065
Mozilla Bug 445250 - cairo_draw_with_xlib should provide a non-NULL visual
to callback
https://bugzilla.mozilla.org/show_bug.cgi?id=445250
Reported-by: Oleg Romashin <romaxa@gmail.com>
This commit is contained in:
parent
cf426bce8e
commit
55037bfb24
1 changed files with 65 additions and 9 deletions
|
|
@ -183,6 +183,56 @@ static const XTransform identity = { {
|
|||
(CAIRO_SURFACE_RENDER_HAS_PDF_OPERATORS(surface) && \
|
||||
(op) <= CAIRO_OPERATOR_HSL_LUMINOSITY))
|
||||
|
||||
static Visual *
|
||||
_visual_for_xrender_format(Screen *screen,
|
||||
XRenderPictFormat *xrender_format)
|
||||
{
|
||||
int d, v;
|
||||
|
||||
/* XXX Consider searching through the list of known cairo_visual_t for
|
||||
* the reverse mapping.
|
||||
*/
|
||||
|
||||
for (d = 0; d < screen->ndepths; d++) {
|
||||
Depth *d_info = &screen->depths[d];
|
||||
|
||||
if (d_info->depth != xrender_format->depth)
|
||||
continue;
|
||||
|
||||
for (v = 0; v < d_info->nvisuals; v++) {
|
||||
Visual *visual = &d_info->visuals[v];
|
||||
|
||||
switch (visual->class) {
|
||||
case TrueColor:
|
||||
if (xrender_format->type != PictTypeDirect)
|
||||
continue;
|
||||
break;
|
||||
|
||||
case DirectColor:
|
||||
/* Prefer TrueColor to DirectColor.
|
||||
* (XRenderFindVisualFormat considers both TrueColor and DirectColor
|
||||
* Visuals to match the same PictFormat.)
|
||||
*/
|
||||
continue;
|
||||
|
||||
case StaticGray:
|
||||
case GrayScale:
|
||||
case StaticColor:
|
||||
case PseudoColor:
|
||||
if (xrender_format->type != PictTypeIndexed)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
if (xrender_format ==
|
||||
XRenderFindVisualFormat (DisplayOfScreen(screen), visual))
|
||||
return visual;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_set_clip_region (cairo_xlib_surface_t *surface,
|
||||
cairo_region_t *region)
|
||||
|
|
@ -306,9 +356,11 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
|
|||
width <= 0 ? 1 : width, height <= 0 ? 1 : height,
|
||||
xrender_format->depth);
|
||||
|
||||
visual = NULL;
|
||||
if (xrender_format == src->xrender_format)
|
||||
visual = src->visual;
|
||||
else
|
||||
visual = _visual_for_xrender_format(src->screen->screen,
|
||||
xrender_format);
|
||||
|
||||
surface = (cairo_xlib_surface_t *)
|
||||
_cairo_xlib_surface_create_internal (src->screen, pix,
|
||||
|
|
@ -3235,8 +3287,8 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
|
|||
X_DEBUG ((dpy, "create_with_xrender_format (drawable=%x)", (unsigned int) drawable));
|
||||
|
||||
return _cairo_xlib_surface_create_internal (screen, drawable,
|
||||
NULL, format,
|
||||
width, height, 0);
|
||||
_visual_for_xrender_format (scr, format),
|
||||
format, width, height, 0);
|
||||
}
|
||||
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
|
||||
|
||||
|
|
@ -3468,23 +3520,27 @@ cairo_xlib_surface_get_screen (cairo_surface_t *abstract_surface)
|
|||
* cairo_xlib_surface_get_visual:
|
||||
* @surface: a #cairo_xlib_surface_t
|
||||
*
|
||||
* Get the X Visual used for underlying X Drawable.
|
||||
* Gets the X Visual associated with @surface, suitable for use with the
|
||||
* underlying X Drawable. If @surface was created by
|
||||
* cairo_xlib_surface_create(), the return value is the Visual passed to that
|
||||
* constructor.
|
||||
*
|
||||
* Return value: the visual.
|
||||
* Return value: the Visual or %NULL if there is no appropriate Visual for
|
||||
* @surface.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
Visual *
|
||||
cairo_xlib_surface_get_visual (cairo_surface_t *abstract_surface)
|
||||
cairo_xlib_surface_get_visual (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = (cairo_xlib_surface_t *) abstract_surface;
|
||||
cairo_xlib_surface_t *xlib_surface = (cairo_xlib_surface_t *) surface;
|
||||
|
||||
if (! _cairo_surface_is_xlib (abstract_surface)) {
|
||||
if (! _cairo_surface_is_xlib (surface)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return surface->visual;
|
||||
return xlib_surface->visual;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue