[cairo-texture] Silently discard 0x0 surfaces
authorEmmanuele Bassi <ebassi@linux.intel.com>
Wed, 17 Dec 2008 15:40:33 +0000 (15:40 +0000)
committerEmmanuele Bassi <ebassi@linux.intel.com>
Wed, 17 Dec 2008 15:58:11 +0000 (15:58 +0000)
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.

clutter/clutter-cairo-texture.c

index 2343a9a..cb170ea 100644 (file)
@@ -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;