[cairo-texture] Silently discard 0x0 surfaces
The current CairoTexture can be created with a surface size of 0 by 0 pixels, but a warning will be printed. Worse, the surface can be resized to be 0 by 0 pixels without a warning. The :surface-width and :surface-height properties accept a minimum value of 0, and not check is performed on either the constructor or set_surface_size() parameters to enforce the "greater than zero" rule. The correct and consistent behaviour is to allow a 0 by 0 pixels surface size everywhere; inside surface_resize_internal(), the current surface will be destroyed and if either :surface-width or :surface-height are set to 0, the resizing terminates. Attempting to create a Cairo context from a CairoTexture with either :surface-width or :surface-height set to 0 will result in a warning. This allows: - creating a CairoTexture with :surface-width or :surface-height set to zero and delaying the surface resize at a later point; - resizing the surface to 0 by 0 pixels to destroy the image surface used internally; - increase the consistency in the usage of CairoTexture.
This commit is contained in:
parent
ca310d49ca
commit
e130e0c9b3
@ -243,6 +243,9 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
|
||||
priv->cr_surface_data = NULL;
|
||||
}
|
||||
|
||||
if (priv->width == 0 || priv->height == 0)
|
||||
return;
|
||||
|
||||
#if CAIRO_VERSION > 106000
|
||||
priv->rowstride = cairo_format_stride_for_width (priv->format, priv->width);
|
||||
#else
|
||||
@ -287,34 +290,15 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
|
||||
4, 0, NULL);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
clutter_cairo_texture_constructor (GType gtype,
|
||||
guint n_properties,
|
||||
GObjectConstructParam *properties)
|
||||
static void
|
||||
clutter_cairo_texture_constructed (GObject *gobject)
|
||||
{
|
||||
GObjectClass *parent_class;
|
||||
GObject *obj;
|
||||
ClutterCairoTexture *cairo;
|
||||
ClutterCairoTexturePrivate *priv;
|
||||
|
||||
parent_class = G_OBJECT_CLASS (clutter_cairo_texture_parent_class);
|
||||
obj = parent_class->constructor (gtype, n_properties, properties);
|
||||
|
||||
/* Now all of the object properties are set */
|
||||
cairo = CLUTTER_CAIRO_TEXTURE (obj);
|
||||
priv = cairo->priv;
|
||||
|
||||
if (!priv->width || !priv->height)
|
||||
{
|
||||
g_warning ("Unable to create the Cairo surface: invalid size (%dx%d)",
|
||||
priv->width,
|
||||
priv->height);
|
||||
return obj;
|
||||
}
|
||||
ClutterCairoTexture *cairo = CLUTTER_CAIRO_TEXTURE (gobject);
|
||||
|
||||
clutter_cairo_texture_surface_resize_internal (cairo);
|
||||
|
||||
return obj;
|
||||
if (G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_cairo_texture_parent_class)->constructed (gobject);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -356,7 +340,7 @@ clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
|
||||
gobject_class->finalize = clutter_cairo_texture_finalize;
|
||||
gobject_class->set_property = clutter_cairo_texture_set_property;
|
||||
gobject_class->get_property = clutter_cairo_texture_get_property;
|
||||
gobject_class->constructor = clutter_cairo_texture_constructor;
|
||||
gobject_class->constructed = clutter_cairo_texture_constructed;
|
||||
|
||||
actor_class->get_preferred_width =
|
||||
clutter_cairo_texture_get_preferred_width;
|
||||
@ -594,6 +578,18 @@ clutter_cairo_texture_create_region (ClutterCairoTexture *self,
|
||||
if (height < 0)
|
||||
height = priv->height;
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
g_warning ("Unable to create a context for an image surface of "
|
||||
"width %d and height %d. Set the surface size to be "
|
||||
"at least 1 pixel by 1 pixel.",
|
||||
width, height);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!priv->cr_surface)
|
||||
return NULL;
|
||||
|
||||
ctxt = g_new0 (ClutterCairoTextureContext, 1);
|
||||
ctxt->cairo = self;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user