[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:
Emmanuele Bassi 2008-12-17 15:40:33 +00:00
parent ca310d49ca
commit e130e0c9b3

View File

@ -243,6 +243,9 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
priv->cr_surface_data = NULL; priv->cr_surface_data = NULL;
} }
if (priv->width == 0 || priv->height == 0)
return;
#if CAIRO_VERSION > 106000 #if CAIRO_VERSION > 106000
priv->rowstride = cairo_format_stride_for_width (priv->format, priv->width); priv->rowstride = cairo_format_stride_for_width (priv->format, priv->width);
#else #else
@ -287,34 +290,15 @@ clutter_cairo_texture_surface_resize_internal (ClutterCairoTexture *cairo)
4, 0, NULL); 4, 0, NULL);
} }
static GObject * static void
clutter_cairo_texture_constructor (GType gtype, clutter_cairo_texture_constructed (GObject *gobject)
guint n_properties,
GObjectConstructParam *properties)
{ {
GObjectClass *parent_class; ClutterCairoTexture *cairo = CLUTTER_CAIRO_TEXTURE (gobject);
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;
}
clutter_cairo_texture_surface_resize_internal (cairo); 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 static void
@ -356,7 +340,7 @@ clutter_cairo_texture_class_init (ClutterCairoTextureClass *klass)
gobject_class->finalize = clutter_cairo_texture_finalize; gobject_class->finalize = clutter_cairo_texture_finalize;
gobject_class->set_property = clutter_cairo_texture_set_property; gobject_class->set_property = clutter_cairo_texture_set_property;
gobject_class->get_property = clutter_cairo_texture_get_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 = actor_class->get_preferred_width =
clutter_cairo_texture_get_preferred_width; clutter_cairo_texture_get_preferred_width;
@ -594,6 +578,18 @@ clutter_cairo_texture_create_region (ClutterCairoTexture *self,
if (height < 0) if (height < 0)
height = priv->height; 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 = g_new0 (ClutterCairoTextureContext, 1);
ctxt->cairo = self; ctxt->cairo = self;