gcompris r3403 - in branches/gcomprixogoo: . src/boards src/goocanvas/src src/goocanvas/src/CVS



Author: bcoudoin
Date: Sat May  3 22:35:09 2008
New Revision: 3403
URL: http://svn.gnome.org/viewvc/gcompris?rev=3403&view=rev

Log:
	Syncing goocanvas and pygoocanvas with upstream goocanvas 0.10



Removed:
   branches/gcomprixogoo/src/goocanvas/src/CVS/
Modified:
   branches/gcomprixogoo/ChangeLog
   branches/gcomprixogoo/src/boards/goocanvas.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvas.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvas.h
   branches/gcomprixogoo/src/goocanvas/src/goocanvasimage.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.h
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.h
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.h
   branches/gcomprixogoo/src/goocanvas/src/goocanvasmarshal.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvastable.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvastext.c
   branches/gcomprixogoo/src/goocanvas/src/goocanvastext.h

Modified: branches/gcomprixogoo/src/boards/goocanvas.c
==============================================================================
--- branches/gcomprixogoo/src/boards/goocanvas.c	(original)
+++ branches/gcomprixogoo/src/boards/goocanvas.c	Sat May  3 22:35:09 2008
@@ -207,6 +207,8 @@
 #define PyGtkContainer_Type (*_PyGtkContainer_Type)
 static PyTypeObject *_PyGtkAdjustment_Type;
 #define PyGtkAdjustment_Type (*_PyGtkAdjustment_Type)
+static PyTypeObject *_PyGdkCairoContext_Type;
+#define PyGdkCairoContext_Type (*_PyGdkCairoContext_Type)
 
 
 /* ---------- forward type declarations ---------- */
@@ -237,7 +239,7 @@
 PyTypeObject G_GNUC_INTERNAL PyGooCanvasItemModel_Type;
 
 
-#line 663 "goocanvas.override"
+#line 664 "goocanvas.override"
 
 static PyObject *
 _py_canvas_style_get_property(GooCanvasStyle *style,
@@ -288,13 +290,13 @@
 }
 
 
-#line 292 "goocanvas.c"
+#line 294 "goocanvas.c"
 
 
 
 /* ----------- GooCanvasPoints ----------- */
 
-#line 279 "goocanvas.override"
+#line 280 "goocanvas.override"
 static int
 _wrap_goo_canvas_points_new(PyGBoxed *self, PyObject *args, PyObject *kwargs)
 {
@@ -321,7 +323,7 @@
     self->gtype = GOO_TYPE_CANVAS_POINTS;
     return 0;
 }
-#line 325 "goocanvas.c"
+#line 327 "goocanvas.c"
 
 
 PyTypeObject G_GNUC_INTERNAL PyGooCanvasPoints_Type = {
@@ -373,7 +375,7 @@
 
 /* ----------- GooCanvasLineDash ----------- */
 
-#line 444 "goocanvas.override"
+#line 445 "goocanvas.override"
 static int
 _wrap_goo_canvas_line_dash_newv(PyGBoxed *self, PyObject *args, PyObject *kwargs)
 {
@@ -410,7 +412,7 @@
     self->free_on_dealloc = TRUE;
     return 0;
 }
-#line 414 "goocanvas.c"
+#line 416 "goocanvas.c"
 
 
 PyTypeObject G_GNUC_INTERNAL PyGooCanvasLineDash_Type = {
@@ -569,7 +571,7 @@
     return pygobject_new((GObject *)ret);
 }
 
-#line 1436 "goocanvas.override"
+#line 1437 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_get_items_at(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -600,10 +602,10 @@
     return ret;
 }
 
-#line 604 "goocanvas.c"
+#line 606 "goocanvas.c"
 
 
-#line 1468 "goocanvas.override"
+#line 1469 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_get_items_in_area(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -641,7 +643,7 @@
     return ret;
 }
 
-#line 645 "goocanvas.c"
+#line 647 "goocanvas.c"
 
 
 static PyObject *
@@ -670,7 +672,7 @@
     return Py_None;
 }
 
-#line 512 "goocanvas.override"
+#line 513 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_get_bounds(PyGObject *self)
 {
@@ -681,7 +683,7 @@
     return Py_BuildValue("dddd", left, right, top, bottom);
 }
 
-#line 685 "goocanvas.c"
+#line 687 "goocanvas.c"
 
 
 static PyObject *
@@ -751,7 +753,7 @@
     return Py_None;
 }
 
-#line 539 "goocanvas.override"
+#line 540 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_convert_to_pixels(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -766,10 +768,10 @@
     return Py_BuildValue("dd", x, y);
 }
 
-#line 770 "goocanvas.c"
+#line 772 "goocanvas.c"
 
 
-#line 555 "goocanvas.override"
+#line 556 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_convert_from_pixels(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -784,10 +786,10 @@
     return Py_BuildValue("dd", x, y);
 }
 
-#line 788 "goocanvas.c"
+#line 790 "goocanvas.c"
 
 
-#line 571 "goocanvas.override"
+#line 572 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_convert_to_item_space(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -803,10 +805,10 @@
     
     return Py_BuildValue("dd", x, y);
 }
-#line 807 "goocanvas.c"
+#line 809 "goocanvas.c"
 
 
-#line 588 "goocanvas.override"
+#line 589 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_convert_from_item_space(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -822,7 +824,7 @@
 
     return Py_BuildValue("dd", x, y);
 }
-#line 826 "goocanvas.c"
+#line 828 "goocanvas.c"
 
 
 static PyObject *
@@ -1674,7 +1676,7 @@
 
 /* ----------- GooCanvasItemSimple ----------- */
 
-#line 256 "goocanvas.override"
+#line 257 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_simple_get_path_bounds(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -1696,7 +1698,7 @@
     return py_bounds;    
 }
 
-#line 1700 "goocanvas.c"
+#line 1702 "goocanvas.c"
 
 
 static PyObject *
@@ -1943,7 +1945,7 @@
     { NULL, NULL, 0, NULL }
 };
 
-#line 782 "goocanvas.override"
+#line 783 "goocanvas.override"
 
 static int
 _wrap_goo_canvas_item_simple__set_bounds_x1(PyGObject *self, PyObject *py_value, void *closure)
@@ -1956,7 +1958,7 @@
     return 0;
 }
 
-#line 1960 "goocanvas.c"
+#line 1962 "goocanvas.c"
 
 
 static PyObject *
@@ -1968,7 +1970,7 @@
     return PyFloat_FromDouble(ret);
 }
 
-#line 796 "goocanvas.override"
+#line 797 "goocanvas.override"
 
 static int
 _wrap_goo_canvas_item_simple__set_bounds_x2(PyGObject *self, PyObject *py_value, void *closure)
@@ -1981,7 +1983,7 @@
     return 0;
 }
 
-#line 1985 "goocanvas.c"
+#line 1987 "goocanvas.c"
 
 
 static PyObject *
@@ -1993,7 +1995,7 @@
     return PyFloat_FromDouble(ret);
 }
 
-#line 810 "goocanvas.override"
+#line 811 "goocanvas.override"
 
 static int
 _wrap_goo_canvas_item_simple__set_bounds_y1(PyGObject *self, PyObject *py_value, void *closure)
@@ -2006,7 +2008,7 @@
     return 0;
 }
 
-#line 2010 "goocanvas.c"
+#line 2012 "goocanvas.c"
 
 
 static PyObject *
@@ -2018,7 +2020,7 @@
     return PyFloat_FromDouble(ret);
 }
 
-#line 824 "goocanvas.override"
+#line 825 "goocanvas.override"
 
 static int
 _wrap_goo_canvas_item_simple__set_bounds_y2(PyGObject *self, PyObject *py_value, void *closure)
@@ -2031,7 +2033,7 @@
     return 0;
 }
 
-#line 2035 "goocanvas.c"
+#line 2037 "goocanvas.c"
 
 
 static PyObject *
@@ -2043,7 +2045,7 @@
     return PyFloat_FromDouble(ret);
 }
 
-#line 1586 "goocanvas.override"
+#line 1587 "goocanvas.override"
 
 static int
 _wrap_goo_canvas_item_simple__set_bounds(PyGObject *self, PyObject *py_value, void *closure)
@@ -2061,7 +2063,8 @@
 {
     return pygoo_canvas_bounds_new(&GOO_CANVAS_ITEM_SIMPLE(pygobject_get(self))->bounds);
 }
-#line 2065 "goocanvas.c"
+
+#line 2068 "goocanvas.c"
 
 
 static const PyGetSetDef goo_canvas_item_simple_getsets[] = {
@@ -2136,7 +2139,7 @@
         pyg_gil_state_release(__py_state);
         return;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     
     py_args = PyTuple_New(1);
     PyTuple_SET_ITEM(py_args, 0, py_cr);
@@ -2197,7 +2200,7 @@
         pyg_gil_state_release(__py_state);
         return;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     
     py_args = PyTuple_New(1);
     PyTuple_SET_ITEM(py_args, 0, py_cr);
@@ -2259,7 +2262,7 @@
         pyg_gil_state_release(__py_state);
         return;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_bounds = pygoo_canvas_bounds_new(bounds);
     
     py_args = PyTuple_New(2);
@@ -2329,7 +2332,7 @@
     }
     py_x = PyFloat_FromDouble(x);
     py_y = PyFloat_FromDouble(y);
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_is_pointer_event = is_pointer_event? Py_True : Py_False;
     
     py_args = PyTuple_New(4);
@@ -2914,7 +2917,7 @@
     return Py_None;
 }
 
-#line 715 "goocanvas.override"
+#line 716 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_style_get_property(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -2927,10 +2930,10 @@
     return _py_canvas_style_get_property(GOO_CANVAS_STYLE(self->obj), name);
 }
 
-#line 2931 "goocanvas.c"
+#line 2934 "goocanvas.c"
 
 
-#line 729 "goocanvas.override"
+#line 730 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_style_set_property(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -2947,7 +2950,7 @@
     return Py_None;
 }
 
-#line 2951 "goocanvas.c"
+#line 2954 "goocanvas.c"
 
 
 static PyObject *
@@ -3000,7 +3003,7 @@
     { NULL, NULL, 0, NULL }
 };
 
-#line 747 "goocanvas.override"
+#line 748 "goocanvas.override"
 
 static PyObject *
 goo_canvas_style_subscript(PyGObject *self, PyObject *arg)
@@ -3034,7 +3037,7 @@
     (objobjargproc) _wrap_goo_canvas_style_ass_subscript, /* objobjargproc mp_ass_subscript; */
 };
 
-#line 3038 "goocanvas.c"
+#line 3041 "goocanvas.c"
 
 
 PyTypeObject G_GNUC_INTERNAL PyGooCanvasStyle_Type = {
@@ -3184,6 +3187,31 @@
 
 /* ----------- GooCanvasText ----------- */
 
+#line 1607 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_text_get_natural_extents(PyGObject *self)
+{
+    PangoRectangle ink_rect, logical_rect;
+
+    goo_canvas_text_get_natural_extents(GOO_CANVAS_TEXT(self->obj), &ink_rect,
+                                        &logical_rect);
+    
+    return Py_BuildValue("((iiii)(iiii))",
+			 ink_rect.x, ink_rect.y,
+			 ink_rect.width, ink_rect.height,
+			 logical_rect.x, logical_rect.y,
+			 logical_rect.width, logical_rect.height);
+}
+
+#line 3207 "goocanvas.c"
+
+
+static const PyMethodDef _PyGooCanvasText_methods[] = {
+    { "get_natural_extents", (PyCFunction)_wrap_goo_canvas_text_get_natural_extents, METH_NOARGS,
+      NULL },
+    { NULL, NULL, 0, NULL }
+};
+
 PyTypeObject G_GNUC_INTERNAL PyGooCanvasText_Type = {
     PyObject_HEAD_INIT(NULL)
     0,                                 /* ob_size */
@@ -3214,7 +3242,7 @@
     offsetof(PyGObject, weakreflist),             /* tp_weaklistoffset */
     (getiterfunc)0,          /* tp_iter */
     (iternextfunc)0,     /* tp_iternext */
-    (struct PyMethodDef*)NULL, /* tp_methods */
+    (struct PyMethodDef*)_PyGooCanvasText_methods, /* tp_methods */
     (struct PyMemberDef*)0,              /* tp_members */
     (struct PyGetSetDef*)0,  /* tp_getset */
     NULL,                              /* tp_base */
@@ -3404,7 +3432,7 @@
     return Py_None;
 }
 
-#line 482 "goocanvas.override"
+#line 483 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_remove_child(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -3433,10 +3461,129 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
-#line 3437 "goocanvas.c"
+#line 3465 "goocanvas.c"
+
+
+#line 1708 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_get_child_property(PyGObject *self,
+                                         PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char    *kwlist[] = { "child", "property", NULL };
+    PyGObject *pychild;
+    gchar *property_name;
+    GooCanvasItem *item, *child;
+    GObjectClass *class;
+    GParamSpec *pspec;
+    GValue value = { 0, } ;
+    PyObject *ret;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "O!s:GooCanvasItem.get_child_property",
+                                     kwlist, &PyGooCanvasItem_Type, &pychild,
+                                     &property_name)) {
+        return NULL;
+    }
+
+    item = GOO_CANVAS_ITEM(self->obj);
+    child = GOO_CANVAS_ITEM(pychild->obj);
+
+    if (goo_canvas_item_find_child(item, child) == -1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "first argument must be a child");
+        return NULL;
+    }
+
+    class = G_OBJECT_GET_CLASS(item);
+    pspec = goo_canvas_item_class_find_child_property(class, property_name);
+    if (!pspec) {
+        gchar buf[512];
+        g_snprintf(buf, sizeof(buf),
+                   "item does not support property `%s'",
+                   property_name);
+
+        PyErr_SetString(PyExc_TypeError, buf);
+        return NULL;
+    }
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+    goo_canvas_item_get_child_property(item,
+                                       child,
+                                       property_name,
+                                       &value);
+
+    ret = pyg_value_as_pyobject(&value, TRUE);
+    g_value_unset(&value);
+
+    return ret;
+}
+
+#line 3524 "goocanvas.c"
+
+
+#line 1650 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_set_child_property(PyGObject *self,
+                                         PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char    *kwlist[] = { "child", "property", "value", NULL };
+    gchar *property_name;
+    PyGObject *pychild;
+    GooCanvasItem *item, *child;
+    PyGObject *pyvalue;
+    GObjectClass *class;
+    GParamSpec *pspec;
+    GValue value = { 0, } ;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                     "O!sO:GooCanvasItem.set_child_property",
+                                     kwlist,
+                                    &PyGooCanvasItem_Type, &pychild,
+                                    &property_name, &pyvalue)) {
+        return NULL;
+    }
+    
+    item = GOO_CANVAS_ITEM(self->obj);
+    child = GOO_CANVAS_ITEM(pychild->obj);
+
+    if (goo_canvas_item_find_child(item, child) == -1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "first argument must be a child");
+        return NULL;
+    }
+
+    class = G_OBJECT_GET_CLASS(self->obj);
+    pspec = goo_canvas_item_class_find_child_property(class, property_name);
+    if (!pspec) {
+        gchar buf[512];
+        g_snprintf(buf, sizeof(buf),
+                   "item does not support property `%s'",
+                   property_name);
+        PyErr_SetString(PyExc_TypeError, buf);
+
+        return NULL;
+    }
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+    pyg_value_from_pyobject(&value, (PyObject*)pyvalue);
+
+    goo_canvas_item_set_child_property(item,
+                                       child,
+                                       property_name,
+                                       &value);
+    g_value_unset(&value);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+#line 3584 "goocanvas.c"
 
 
-#line 920 "goocanvas.override"
+#line 921 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_get_child_properties(PyGObject *self, PyObject *args)
 {
@@ -3517,10 +3664,10 @@
     return tuple;
 }
 
-#line 3521 "goocanvas.c"
+#line 3668 "goocanvas.c"
 
 
-#line 838 "goocanvas.override"
+#line 839 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_set_child_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -3601,7 +3748,7 @@
     return Py_None;
 }
 
-#line 3605 "goocanvas.c"
+#line 3752 "goocanvas.c"
 
 
 static PyObject *
@@ -3743,7 +3890,7 @@
     return Py_None;
 }
 
-#line 1545 "goocanvas.override"
+#line 1546 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_get_transform(PyGObject *self)
 {
@@ -3762,7 +3909,7 @@
     return matrix;
 }
 
-#line 3766 "goocanvas.c"
+#line 3913 "goocanvas.c"
 
 
 static PyObject *
@@ -3782,6 +3929,21 @@
     return Py_None;
 }
 
+#line 1624 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_get_simple_transform(PyGObject *self)
+{
+    gdouble x, y, scale, rotation;
+    
+    goo_canvas_item_get_simple_transform(GOO_CANVAS_ITEM(self->obj), &x, &y,
+                                         &scale, &rotation);
+    
+    return Py_BuildValue("dddd", x, y, scale, rotation);
+}
+
+#line 3945 "goocanvas.c"
+
+
 static PyObject *
 _wrap_goo_canvas_item_set_simple_transform(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -3929,7 +4091,7 @@
     return Py_None;
 }
 
-#line 524 "goocanvas.override"
+#line 525 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_get_bounds(PyGObject *self)
 {
@@ -3943,10 +4105,10 @@
     return py_bounds;
 }
 
-#line 3947 "goocanvas.c"
+#line 4109 "goocanvas.c"
 
 
-#line 1507 "goocanvas.override"
+#line 1508 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_get_items_at(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -3983,7 +4145,7 @@
     return ret;
 }
 
-#line 3987 "goocanvas.c"
+#line 4149 "goocanvas.c"
 
 
 static PyObject *
@@ -4133,7 +4295,7 @@
     return Py_None;
 }
 
-#line 1207 "goocanvas.override"
+#line 1208 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_find_child_property (PyObject *cls,
                                            PyObject *args,
@@ -4173,10 +4335,10 @@
     return pyg_param_spec_new(pspec);
 }
 
-#line 4177 "goocanvas.c"
+#line 4339 "goocanvas.c"
 
 
-#line 1290 "goocanvas.override"
+#line 1291 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_list_child_properties (PyObject *cls,
                                              PyObject *args,
@@ -4217,10 +4379,10 @@
     return list;
 }
 
-#line 4221 "goocanvas.c"
+#line 4383 "goocanvas.c"
 
 
-#line 1384 "goocanvas.override"
+#line 1385 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_install_child_property (PyObject *cls,
                                               PyObject *args,
@@ -4271,7 +4433,7 @@
     return Py_None;
 }
 
-#line 4275 "goocanvas.c"
+#line 4437 "goocanvas.c"
 
 
 static PyObject *
@@ -5092,6 +5254,10 @@
       NULL },
     { "remove_child", (PyCFunction)_wrap_goo_canvas_item_remove_child, METH_VARARGS|METH_KEYWORDS,
       NULL },
+    { "get_child_property", (PyCFunction)_wrap_goo_canvas_item_get_child_property, METH_VARARGS,
+      NULL },
+    { "set_child_property", (PyCFunction)_wrap_goo_canvas_item_set_child_property, METH_VARARGS|METH_KEYWORDS,
+      NULL },
     { "get_child_properties", (PyCFunction)_wrap_goo_canvas_item_get_child_properties, METH_VARARGS,
       NULL },
     { "set_child_properties", (PyCFunction)_wrap_goo_canvas_item_set_child_properties, METH_VARARGS|METH_KEYWORDS,
@@ -5118,6 +5284,8 @@
       NULL },
     { "set_transform", (PyCFunction)_wrap_goo_canvas_item_set_transform, METH_VARARGS|METH_KEYWORDS,
       NULL },
+    { "get_simple_transform", (PyCFunction)_wrap_goo_canvas_item_get_simple_transform, METH_NOARGS,
+      NULL },
     { "set_simple_transform", (PyCFunction)_wrap_goo_canvas_item_set_simple_transform, METH_VARARGS|METH_KEYWORDS,
       NULL },
     { "translate", (PyCFunction)_wrap_goo_canvas_item_translate, METH_VARARGS|METH_KEYWORDS,
@@ -5926,7 +6094,7 @@
     Py_DECREF(py_self);
     pyg_gil_state_release(__py_state);
 }
-#line 605 "goocanvas.override"
+#line 606 "goocanvas.override"
 static void
 _wrap_GooCanvasItem__proxy_do_get_bounds(GooCanvasItem *self, GooCanvasBounds *bounds)
 {
@@ -5952,10 +6120,10 @@
     Py_XDECREF(py_bounds);
     pyg_gil_state_release(__py_state);
 }
-#line 5956 "goocanvas.c"
+#line 6124 "goocanvas.c"
 
 
-#line 632 "goocanvas.override"
+#line 633 "goocanvas.override"
 static void
 _wrap_GooCanvasItem__proxy_do_update(GooCanvasItem *self, gboolean entire_tree,
                                      cairo_t *cr, GooCanvasBounds *bounds)
@@ -5975,7 +6143,7 @@
 
     py_bounds = PyObject_CallMethod(py_self, "do_update", "iN",
                                     entire_tree,
-                                    PycairoContext_FromContext(cairo_reference(cr), NULL, NULL));
+                                    PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL));
     if (py_bounds)
         *bounds = ((PyGooCanvasBounds *) py_bounds)->bounds;
     else
@@ -5985,7 +6153,7 @@
     pyg_gil_state_release(__py_state);
 }
 
-#line 5989 "goocanvas.c"
+#line 6157 "goocanvas.c"
 
 
 static void
@@ -6008,7 +6176,7 @@
         pyg_gil_state_release(__py_state);
         return;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_bounds = pygoo_canvas_bounds_new(bounds);
     py_scale = PyFloat_FromDouble(scale);
     
@@ -6076,7 +6244,7 @@
         pyg_gil_state_release(__py_state);
         return FALSE;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_requested_area = pygoo_canvas_bounds_new(requested_area);
     
     py_args = PyTuple_New(2);
@@ -6147,7 +6315,7 @@
         pyg_gil_state_release(__py_state);
         return;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_requested_area = pygoo_canvas_bounds_new(requested_area);
     py_allocated_area = pygoo_canvas_bounds_new(allocated_area);
     py_x_offset = PyFloat_FromDouble(x_offset);
@@ -6408,7 +6576,7 @@
         pyg_gil_state_release(__py_state);
         return -G_MAXFLOAT;
     }
-    py_cr = PycairoContext_FromContext(cairo_reference(cr), NULL, NULL);
+    py_cr = PycairoContext_FromContext(cairo_reference(cr), &PyGdkCairoContext_Type, NULL);
     py_width = PyFloat_FromDouble(width);
     
     py_args = PyTuple_New(2);
@@ -7755,7 +7923,125 @@
     return PyInt_FromLong(ret);
 }
 
-#line 1083 "goocanvas.override"
+#line 1823 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_model_get_child_property(PyGObject *self,
+                                         PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char    *kwlist[] = { "child", "property", NULL };
+    PyGObject *pychild;
+    gchar *property_name;
+    GooCanvasItemModel *item, *child;
+    GObjectClass *class;
+    GParamSpec *pspec;
+    GValue value = { 0, } ;
+    PyObject *ret;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                "O!s:GooCanvasItemModel.get_child_property",
+                                kwlist, &PyGooCanvasItemModel_Type, &pychild,
+                                &property_name)) {
+        return NULL;
+    }
+
+    item = GOO_CANVAS_ITEM_MODEL(self->obj);
+    child = GOO_CANVAS_ITEM_MODEL(pychild->obj);
+
+    if (goo_canvas_item_model_find_child(item, child) == -1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "first argument must be a child");
+        return NULL;
+    }
+
+    class = G_OBJECT_GET_CLASS(item);
+    pspec = goo_canvas_item_model_class_find_child_property(class, property_name);
+    if (!pspec) {
+        gchar buf[512];
+        g_snprintf(buf, sizeof(buf),
+                   "item model does not support property `%s'",
+                   property_name);
+
+        PyErr_SetString(PyExc_TypeError, buf);
+        return NULL;
+    }
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+    goo_canvas_item_model_get_child_property(item,
+                                             child,
+                                             property_name,
+                                             &value);
+
+    ret = pyg_value_as_pyobject(&value, TRUE);
+    g_value_unset(&value);
+
+    return ret;
+}
+#line 7982 "goocanvas.c"
+
+
+#line 1765 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_model_set_child_property(PyGObject *self,
+                                         PyObject *args,
+                                         PyObject *kwargs)
+{
+    static char    *kwlist[] = { "child", "property", "value", NULL };
+    gchar *property_name;
+    PyGObject *pychild;
+    GooCanvasItemModel *item, *child;
+    PyGObject *pyvalue;
+    GObjectClass *class;
+    GParamSpec *pspec;
+    GValue value = { 0, } ;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                "O!sO:GooCanvasItemModel.set_child_property",
+                                kwlist,
+                                &PyGooCanvasItemModel_Type, &pychild,
+                                &property_name, &pyvalue)) {
+        return NULL;
+    }
+    
+    item = GOO_CANVAS_ITEM_MODEL(self->obj);
+    child = GOO_CANVAS_ITEM_MODEL(pychild->obj);
+
+    if (goo_canvas_item_model_find_child(item, child) == -1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "first argument must be a child");
+        return NULL;
+    }
+
+    class = G_OBJECT_GET_CLASS(self->obj);
+    pspec = goo_canvas_item_model_class_find_child_property(class, property_name);
+    if (!pspec) {
+        gchar buf[512];
+        g_snprintf(buf, sizeof(buf),
+                   "item model does not support property `%s'",
+                   property_name);
+        PyErr_SetString(PyExc_TypeError, buf);
+
+        return NULL;
+    }
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+    pyg_value_from_pyobject(&value, (PyObject*)pyvalue);
+
+    goo_canvas_item_model_set_child_property(item,
+                                             child,
+                                             property_name,
+                                             &value);
+    g_value_unset(&value);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+#line 8042 "goocanvas.c"
+
+
+#line 1084 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_get_child_properties(PyGObject *self, PyObject *args)
 {
@@ -7837,10 +8123,10 @@
     return tuple;
 }
 
-#line 7841 "goocanvas.c"
+#line 8127 "goocanvas.c"
 
 
-#line 1002 "goocanvas.override"
+#line 1003 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_set_child_properties(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -7920,7 +8206,7 @@
     return Py_None;
 }
 
-#line 7924 "goocanvas.c"
+#line 8210 "goocanvas.c"
 
 
 static PyObject *
@@ -8002,7 +8288,7 @@
     return Py_None;
 }
 
-#line 1565 "goocanvas.override"
+#line 1566 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_get_transform(PyGObject *self)
 {
@@ -8022,7 +8308,7 @@
     return matrix;
 }
 
-#line 8026 "goocanvas.c"
+#line 8312 "goocanvas.c"
 
 
 static PyObject *
@@ -8042,6 +8328,21 @@
     return Py_None;
 }
 
+#line 1637 "goocanvas.override"
+static PyObject *
+_wrap_goo_canvas_item_model_get_simple_transform(PyGObject *self)
+{
+    gdouble x, y, scale, rotation;
+    
+    goo_canvas_item_model_get_simple_transform(GOO_CANVAS_ITEM_MODEL(self->obj),
+                                               &x, &y, &scale, &rotation);
+    
+    return Py_BuildValue("dddd", x, y, scale, rotation);
+}
+
+#line 8344 "goocanvas.c"
+
+
 static PyObject *
 _wrap_goo_canvas_item_model_set_simple_transform(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -8189,7 +8490,7 @@
     return Py_None;
 }
 
-#line 1207 "goocanvas.override"
+#line 1208 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_find_child_property (PyObject *cls,
                                                  PyObject *args,
@@ -8229,10 +8530,10 @@
     return pyg_param_spec_new(pspec);
 }
 
-#line 8233 "goocanvas.c"
+#line 8534 "goocanvas.c"
 
 
-#line 1290 "goocanvas.override"
+#line 1291 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_list_child_properties (PyObject *cls,
                                                    PyObject *args,
@@ -8273,10 +8574,10 @@
     return list;
 }
 
-#line 8277 "goocanvas.c"
+#line 8578 "goocanvas.c"
 
 
-#line 1384 "goocanvas.override"
+#line 1385 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_item_model_install_child_property (PyObject *cls,
                                                     PyObject *args,
@@ -8327,7 +8628,7 @@
     return Py_None;
 }
 
-#line 8331 "goocanvas.c"
+#line 8632 "goocanvas.c"
 
 
 static PyObject *
@@ -8682,6 +8983,10 @@
       NULL },
     { "find_child", (PyCFunction)_wrap_goo_canvas_item_model_find_child, METH_VARARGS|METH_KEYWORDS,
       NULL },
+    { "get_child_property", (PyCFunction)_wrap_goo_canvas_item_model_get_child_property, METH_VARARGS,
+      NULL },
+    { "set_child_property", (PyCFunction)_wrap_goo_canvas_item_model_set_child_property, METH_VARARGS|METH_KEYWORDS,
+      NULL },
     { "get_child_properties", (PyCFunction)_wrap_goo_canvas_item_model_get_child_properties, METH_VARARGS,
       NULL },
     { "set_child_properties", (PyCFunction)_wrap_goo_canvas_item_model_set_child_properties, METH_VARARGS|METH_KEYWORDS,
@@ -8702,6 +9007,8 @@
       NULL },
     { "set_transform", (PyCFunction)_wrap_goo_canvas_item_model_set_transform, METH_VARARGS|METH_KEYWORDS,
       NULL },
+    { "get_simple_transform", (PyCFunction)_wrap_goo_canvas_item_model_get_simple_transform, METH_NOARGS,
+      NULL },
     { "set_simple_transform", (PyCFunction)_wrap_goo_canvas_item_model_set_simple_transform, METH_VARARGS|METH_KEYWORDS,
       NULL },
     { "translate", (PyCFunction)_wrap_goo_canvas_item_model_translate, METH_VARARGS|METH_KEYWORDS,
@@ -9886,7 +10193,7 @@
 
 /* ----------- functions ----------- */
 
-#line 307 "goocanvas.override"
+#line 308 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_polyline_new_line(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -9953,10 +10260,10 @@
     
     return pygobject_new((GObject *)ret);
 }
-#line 9957 "goocanvas.c"
+#line 10264 "goocanvas.c"
 
 
-#line 375 "goocanvas.override"
+#line 376 "goocanvas.override"
 static PyObject *
 _wrap_goo_canvas_polyline_model_new_line(PyGObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -10024,7 +10331,7 @@
     return pygobject_new((GObject *)ret);
 }
 
-#line 10028 "goocanvas.c"
+#line 10335 "goocanvas.c"
 
 
 static PyObject *
@@ -10140,6 +10447,18 @@
             "could not import gtk");
         return ;
     }
+    if ((module = PyImport_ImportModule("gtk.gdk")) != NULL) {
+        _PyGdkCairoContext_Type = (PyTypeObject *)PyObject_GetAttrString(module, "CairoContext");
+        if (_PyGdkCairoContext_Type == NULL) {
+            PyErr_SetString(PyExc_ImportError,
+                "cannot import name CairoContext from gtk.gdk");
+            return ;
+        }
+    } else {
+        PyErr_SetString(PyExc_ImportError,
+            "could not import gtk.gdk");
+        return ;
+    }
 
 
 #line 198 "goocanvas.override"
@@ -10152,7 +10471,7 @@
 
 
 
-#line 10156 "goocanvas.c"
+#line 10475 "goocanvas.c"
     pyg_register_boxed(d, "Points", GOO_TYPE_CANVAS_POINTS, &PyGooCanvasPoints_Type);
     pyg_register_boxed(d, "LineDash", GOO_TYPE_CANVAS_LINE_DASH, &PyGooCanvasLineDash_Type);
     pyg_register_interface(d, "Item", GOO_TYPE_CANVAS_ITEM, &PyGooCanvasItem_Type);

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvas.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvas.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvas.c	Sat May  3 22:35:09 2008
@@ -124,7 +124,8 @@
   PROP_RESOLUTION_Y,
   PROP_BACKGROUND_COLOR,
   PROP_BACKGROUND_COLOR_RGB,
-  PROP_INTEGER_LAYOUT
+  PROP_INTEGER_LAYOUT, 
+  PROP_CLEAR_BACKGROUND
 };
 
 enum {
@@ -385,6 +386,13 @@
 							 FALSE,
 							 G_PARAM_READWRITE));
 
+  g_object_class_install_property (gobject_class, PROP_CLEAR_BACKGROUND, 
+                                   g_param_spec_boolean ("clear-background",
+							 _("Clear Background"),
+							 _("If the background is cleared before the canvas is painted"),
+							 TRUE,
+							 G_PARAM_READWRITE));
+
   /**
    * GooCanvas::set-scroll-adjustments
    * @canvas: the canvas.
@@ -446,6 +454,7 @@
   canvas->need_entire_subtree_update = TRUE;
   canvas->crossing_event.type = GDK_LEAVE_NOTIFY;
   canvas->anchor = GTK_ANCHOR_NORTH_WEST;
+  canvas->clear_background = TRUE;
 
   /* Set the default bounds to a reasonable size. */
   canvas->bounds.x1 = 0.0;
@@ -570,6 +579,9 @@
 {
   gdouble line_width = 2.0;
 
+  if (!canvas)
+    return 2.0;
+
   /* We use the same default as cairo when using pixels, i.e. 2 pixels.
      For other units we use 2 points, or thereabouts. */
   switch (canvas->units)
@@ -609,7 +621,7 @@
   /* If the canvas is realized we can use the GDK function to create a cairo
      context for the canvas window. Otherwise we create a small temporary
      image surface. */
-  if (canvas->canvas_window)
+  if (canvas && canvas->canvas_window)
     {
       cr = gdk_cairo_create (canvas->canvas_window);
     }
@@ -688,6 +700,9 @@
     case PROP_INTEGER_LAYOUT:
       g_value_set_boolean (value, canvas->integer_layout);
       break;
+    case PROP_CLEAR_BACKGROUND:
+      g_value_set_boolean (value, canvas->clear_background);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -788,6 +803,9 @@
       canvas->need_entire_subtree_update = TRUE;
       goo_canvas_request_update (canvas);
       break;
+    case PROP_CLEAR_BACKGROUND:
+      canvas->clear_background = g_value_get_boolean (value);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2221,10 +2239,13 @@
     return FALSE;
 
   /* Clear the background. */
-  gdk_draw_rectangle (canvas->canvas_window,
-		      widget->style->base_gc[widget->state], TRUE,
-		      event->area.x, event->area.y,
-		      event->area.width, event->area.height);
+  if (canvas->clear_background)
+    {
+      gdk_draw_rectangle (canvas->canvas_window,
+			  widget->style->base_gc[widget->state], TRUE,
+			  event->area.x, event->area.y,
+			  event->area.width, event->area.height);
+    }
 
   cr = goo_canvas_create_cairo_context (canvas);
 
@@ -2297,6 +2318,9 @@
 		   const GooCanvasBounds *bounds,
 		   gdouble                scale)
 {
+  if (canvas->need_update)
+    goo_canvas_update (canvas);
+
   /* Set the default line width based on the current units setting. */
   cairo_set_line_width (cr, goo_canvas_get_default_line_width (canvas));
 

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvas.h
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvas.h	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvas.h	Sat May  3 22:35:09 2008
@@ -81,6 +81,9 @@
   /* This is TRUE if the automatic bounds are calculated from the origin. */
   guint bounds_from_origin : 1;
 
+  /* This is TRUE if the background is cleared before painting the canvas. */
+  guint clear_background : 1;
+
   /* This is the padding around the automatic bounds. */
   gdouble bounds_padding;
 

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasimage.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasimage.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasimage.c	Sat May  3 22:35:09 2008
@@ -295,9 +295,9 @@
     case PROP_PIXBUF:
       cairo_pattern_destroy (image_data->pattern);
       pixbuf = g_value_get_object (value);
-      image_data->pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-      image_data->width = gdk_pixbuf_get_width (pixbuf);
-      image_data->height = gdk_pixbuf_get_height (pixbuf);
+      image_data->pattern = pixbuf ? goo_canvas_cairo_pattern_from_pixbuf (pixbuf) : NULL;
+      image_data->width = pixbuf ? gdk_pixbuf_get_width (pixbuf) : 0;
+      image_data->height = pixbuf ? gdk_pixbuf_get_height (pixbuf) : 0;
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.c	Sat May  3 22:35:09 2008
@@ -507,6 +507,7 @@
   GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
 
   g_return_if_fail (iface->add_child != NULL);
+  g_return_if_fail (item != child);
 
   iface->add_child (item, child, position);
 }
@@ -656,9 +657,14 @@
  * @parent: the new parent item.
  * 
  * This function is only intended to be used when implementing new canvas
- * items, specifically container items such as #GooCanvasGroup.
- *
- * It sets the parent of the item.
+ * items (specifically container items such as #GooCanvasGroup).
+ * It sets the parent of the child item.
+ * <!--PARAMETERS-->
+ * <note><para>
+ * This function cannot be used to add an item to a group
+ * or to change the parent of an item.
+ * To do that use the #GooCanvasItem:parent property.
+ * </para></note>
  **/
 void
 goo_canvas_item_set_parent (GooCanvasItem *item,
@@ -847,6 +853,61 @@
 
 
 /**
+ * goo_canvas_item_get_simple_transform:
+ * @item: an item.
+ * @x: returns the x coordinate of the origin of the item's coordinate space.
+ * @y: returns the y coordinate of the origin of the item's coordinate space.
+ * @scale: returns the scale of the item.
+ * @rotation: returns the clockwise rotation of the item, in degrees (0-360).
+ * 
+ * This function can be used to get the position, scale and rotation of an
+ * item, providing that the item has a simple transformation matrix
+ * (e.g. set with goo_canvas_item_set_simple_transform(), or using a
+ * combination of simple translate, scale and rotate operations). If the item
+ * has a complex transformation matrix the results will be incorrect.
+ * 
+ * Returns: %TRUE if a transform is set.
+ **/
+gboolean
+goo_canvas_item_get_simple_transform (GooCanvasItem   *item,
+				      gdouble         *x,
+				      gdouble         *y,
+				      gdouble         *scale,
+				      gdouble         *rotation)
+{
+  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  cairo_matrix_t matrix = { 1, 0, 0, 1, 0, 0 };
+  double x1 = 1.0, y1 = 0.0, radians;
+  gboolean has_transform = FALSE;
+
+  if (iface->get_transform)
+    has_transform = iface->get_transform (item, &matrix);
+
+  if (!has_transform)
+    {
+      *x = *y = *rotation = 0.0;
+      *scale = 1.0;
+      return FALSE;
+    }
+
+  *x = matrix.x0;
+  *y = matrix.y0;
+
+  matrix.x0 = 0.0;
+  matrix.y0 = 0.0;
+
+  cairo_matrix_transform_point (&matrix, &x1, &y1);
+  *scale = sqrt (x1 * x1 + y1 * y1);
+  radians = atan2 (y1, x1);
+  *rotation = radians * (180 / M_PI);
+  if (*rotation < 0)
+    *rotation += 360;
+
+  return TRUE;
+}
+
+
+/**
  * goo_canvas_item_set_simple_transform:
  * @item: an item.
  * @x: the x coordinate of the origin of the item's coordinate space.
@@ -1393,9 +1454,18 @@
 goo_canvas_item_is_visible  (GooCanvasItem   *item)
 {
   GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+  GooCanvasItem *parent;
+
+  if (iface->is_visible)
+    return iface->is_visible (item);
+
+  /* If the item doesn't implement the is_visible method we assume it is
+     visible and check its ancestors. */
+  parent = goo_canvas_item_get_parent (item);
+  if (parent)
+    return goo_canvas_item_is_visible (parent);
 
-  /* If the item doesn't implement this method assume it is visible. */
-  return iface->is_visible ? iface->is_visible (item) : TRUE;
+  return TRUE;
 }
 
 
@@ -1607,6 +1677,100 @@
 /*
  * Child Properties.
  */
+static inline void
+item_get_child_property (GObject      *object,
+			 GObject      *child,
+			 GParamSpec   *pspec,
+			 GValue       *value,
+			 gboolean      is_model)
+{
+  GObjectClass *class;
+
+  class = g_type_class_peek (pspec->owner_type);
+
+  if (is_model)
+    {
+      GooCanvasItemModelIface *iface;
+
+      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM_MODEL);
+      iface->get_child_property ((GooCanvasItemModel*) object,
+				 (GooCanvasItemModel*) child,
+				 pspec->param_id, value, pspec);
+    }
+  else
+    {
+      GooCanvasItemIface *iface;
+
+      iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
+      iface->get_child_property ((GooCanvasItem*) object,
+				 (GooCanvasItem*) child,
+				 pspec->param_id, value, pspec);
+    }
+}
+
+
+void
+_goo_canvas_item_get_child_property_internal (GObject              *object,
+					      GObject              *child,
+					      const gchar          *property_name,
+					      GValue               *value,
+					      GParamSpecPool       *property_pool,
+					      gboolean              is_model)
+{
+  GParamSpec *pspec;
+
+  g_object_ref (object);
+  g_object_ref (child);
+  pspec = g_param_spec_pool_lookup (property_pool, property_name,
+				    G_OBJECT_TYPE (object), TRUE);
+  if (!pspec)
+    g_warning ("%s: class `%s' has no child property named `%s'",
+	       G_STRLOC,
+	       G_OBJECT_TYPE_NAME (object),
+	       property_name);
+  else if (!(pspec->flags & G_PARAM_READABLE))
+    g_warning ("%s: child property `%s' of class `%s' is not readable",
+	       G_STRLOC,
+	       pspec->name,
+	       G_OBJECT_TYPE_NAME (object));
+  else
+    {
+      GValue *prop_value, tmp_value = { 0, };
+
+      /* auto-conversion of the callers value type
+       */
+      if (G_VALUE_TYPE (value) == G_PARAM_SPEC_VALUE_TYPE (pspec))
+	{
+	  g_value_reset (value);
+	  prop_value = value;
+	}
+      else if (!g_value_type_transformable (G_PARAM_SPEC_VALUE_TYPE (pspec), G_VALUE_TYPE (value)))
+	{
+	  g_warning ("can't retrieve child property `%s' of type `%s' as value of type `%s'",
+		     pspec->name,
+		     g_type_name (G_PARAM_SPEC_VALUE_TYPE (pspec)),
+		     G_VALUE_TYPE_NAME (value));
+	  g_object_unref (child);
+	  g_object_unref (object);
+	  return;
+	}
+      else
+	{
+	  g_value_init (&tmp_value, G_PARAM_SPEC_VALUE_TYPE (pspec));
+	  prop_value = &tmp_value;
+	}
+      item_get_child_property (object, child, pspec, prop_value, is_model);
+      if (prop_value != value)
+	{
+	  g_value_transform (prop_value, value);
+	  g_value_unset (&tmp_value);
+	}
+    }
+  g_object_unref (child);
+  g_object_unref (object);
+}
+
+
 void
 _goo_canvas_item_get_child_properties_internal (GObject              *object,
 						GObject              *child,
@@ -1620,7 +1784,6 @@
 
   for (;;)
     {
-      GObjectClass *class;
       GValue value = { 0, };
       GParamSpec *pspec;
       gchar *name, *error = NULL;
@@ -1644,28 +1807,7 @@
 	  break;
 	}
       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-
-      class = g_type_class_peek (pspec->owner_type);
-
-      if (is_model)
-	{
-	  GooCanvasItemModelIface *iface;
-
-	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM_MODEL);
-	  iface->get_child_property ((GooCanvasItemModel*) object,
-				     (GooCanvasItemModel*) child,
-				     pspec->param_id, &value, pspec);
-	}
-      else
-	{
-	  GooCanvasItemIface *iface;
-
-	  iface = g_type_interface_peek (class, GOO_TYPE_CANVAS_ITEM);
-	  iface->get_child_property ((GooCanvasItem*) object,
-				     (GooCanvasItem*) child,
-				     pspec->param_id, &value, pspec);
-	}
-
+      item_get_child_property (object, child, pspec, &value, is_model);
       G_VALUE_LCOPY (&value, var_args, 0, &error);
       if (error)
 	{
@@ -1740,6 +1882,45 @@
 
 
 void
+_goo_canvas_item_set_child_property_internal (GObject              *object,
+					      GObject              *child,
+					      const gchar          *property_name,
+					      const GValue         *value,
+					      GParamSpecPool       *property_pool,
+					      GObjectNotifyContext *notify_context,
+					      gboolean              is_model)
+{
+  GObjectNotifyQueue *nqueue;
+  GParamSpec *pspec;
+
+  g_object_ref (object);
+  g_object_ref (child);
+
+  nqueue = g_object_notify_queue_freeze (child, notify_context);
+  pspec = g_param_spec_pool_lookup (property_pool, property_name,
+				    G_OBJECT_TYPE (object), TRUE);
+  if (!pspec)
+    g_warning ("%s: class `%s' has no child property named `%s'",
+	       G_STRLOC,
+	       G_OBJECT_TYPE_NAME (object),
+	       property_name);
+  else if (!(pspec->flags & G_PARAM_WRITABLE))
+    g_warning ("%s: child property `%s' of class `%s' is not writable",
+	       G_STRLOC,
+	       pspec->name,
+	       G_OBJECT_TYPE_NAME (object));
+  else
+    {
+      canvas_item_set_child_property (object, child, pspec,
+				      value, nqueue, is_model);
+    }
+  g_object_notify_queue_thaw (child, nqueue);
+  g_object_unref (object);
+  g_object_unref (child);
+}
+
+
+void
 _goo_canvas_item_set_child_properties_internal (GObject              *object,
 						GObject              *child,
 						va_list	              var_args,
@@ -1802,16 +1983,61 @@
 
 
 /**
+ * goo_canvas_item_get_child_property:
+ * @item: a #GooCanvasItem.
+ * @child: a child #GooCanvasItem.
+ * @property_name: the name of the child property to get.
+ * @value: a location to return the value.
+ * 
+ * Gets a child property of @child.
+ **/
+void
+goo_canvas_item_get_child_property (GooCanvasItem *item,
+				    GooCanvasItem *child,
+				    const gchar   *property_name,
+				    GValue        *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_item_get_child_property_internal ((GObject*) item, (GObject*) child, property_name, value, _goo_canvas_item_child_property_pool, FALSE);
+}
+
+
+/**
+ * goo_canvas_item_set_child_property:
+ * @item: a #GooCanvasItem.
+ * @child: a child #GooCanvasItem.
+ * @property_name: the name of the child property to set.
+ * @value: the value to set the property to.
+ * 
+ * Sets a child property of @child.
+ **/
+void
+goo_canvas_item_set_child_property (GooCanvasItem   *item,
+				    GooCanvasItem   *child,
+				    const gchar     *property_name,
+				    const GValue    *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (item));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_item_set_child_property_internal ((GObject*) item, (GObject*) child, property_name, value, _goo_canvas_item_child_property_pool, _goo_canvas_item_child_property_notify_context, FALSE);
+}
+
+
+/**
  * goo_canvas_item_get_child_properties_valist:
  * @item: a #GooCanvasItem.
  * @child: a child #GooCanvasItem.
  * @var_args: pairs of property names and value pointers, and a terminating
  *  %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It gets the values of one or more child properties of @child.
+ * Gets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_get_child_properties_valist (GooCanvasItem   *item,
@@ -1831,10 +2057,7 @@
  * @child: a child #GooCanvasItem.
  * @var_args: pairs of property names and values, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It sets the values of one or more child properties of @child.
+ * Sets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_set_child_properties_valist (GooCanvasItem   *item,
@@ -1854,10 +2077,7 @@
  * @child: a child #GooCanvasItem.
  * @...: pairs of property names and value pointers, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It gets the values of one or more child properties of @child.
+ * Gets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_get_child_properties        (GooCanvasItem   *item,
@@ -1878,10 +2098,7 @@
  * @child: a child #GooCanvasItem.
  * @...: pairs of property names and values, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * items, specifically layout container items such as #GooCanvasTable.
- *
- * It sets the values of one or more child properties of @child.
+ * Sets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_set_child_properties        (GooCanvasItem   *item,

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.h
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.h	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitem.h	Sat May  3 22:35:09 2008
@@ -313,6 +313,14 @@
 void               goo_canvas_item_remove_child   (GooCanvasItem   *item,
 						   gint             child_num);
 
+void  goo_canvas_item_get_child_property	  (GooCanvasItem   *item,
+						   GooCanvasItem   *child,
+						   const gchar     *property_name,
+						   GValue          *value);
+void  goo_canvas_item_set_child_property	  (GooCanvasItem   *item,
+						   GooCanvasItem   *child,
+						   const gchar     *property_name,
+						   const GValue    *value);
 void  goo_canvas_item_get_child_properties        (GooCanvasItem   *item,
 						   GooCanvasItem   *child,
 						   ...) G_GNUC_NULL_TERMINATED;
@@ -352,6 +360,11 @@
 						   cairo_matrix_t  *transform);
 void               goo_canvas_item_set_transform  (GooCanvasItem         *item,
 						   const cairo_matrix_t  *transform);
+gboolean	   goo_canvas_item_get_simple_transform (GooCanvasItem   *item,
+							 gdouble         *x,
+							 gdouble         *y,
+							 gdouble         *scale,
+							 gdouble         *rotation);
 void               goo_canvas_item_set_simple_transform (GooCanvasItem   *item,
 							 gdouble          x,
 							 gdouble          y,

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.c	Sat May  3 22:35:09 2008
@@ -45,6 +45,12 @@
 
 static void goo_canvas_item_model_base_init (gpointer g_class);
 extern void _goo_canvas_style_init (void);
+extern void _goo_canvas_item_get_child_property_internal (GObject              *object,
+							  GObject              *child,
+							  const gchar          *property_name,
+							  GValue               *value,
+							  GParamSpecPool       *property_pool,
+							  gboolean              is_model);
 
 
 GType
@@ -274,6 +280,7 @@
   GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
 
   g_return_if_fail (iface->add_child != NULL);
+  g_return_if_fail (model != child);
 
   iface->add_child (model, child, position);
 }
@@ -420,7 +427,15 @@
  * @model: an item model.
  * @parent: the new parent item model.
  * 
- * Sets the parent of the model.
+ * This function is only intended to be used when implementing new canvas
+ * item models (specifically container models such as #GooCanvasGroupModel).
+ * It sets the parent of the child model.
+ * <!--PARAMETERS-->
+ * <note><para>
+ * This function cannot be used to add a model to a group
+ * or to change the parent of a model.
+ * To do that use the #GooCanvasItemModel:parent property.
+ * </para></note>
  **/
 void
 goo_canvas_item_model_set_parent (GooCanvasItemModel *model,
@@ -579,6 +594,61 @@
 
 
 /**
+ * goo_canvas_item_model_get_simple_transform:
+ * @model: an item model.
+ * @x: returns the x coordinate of the origin of the model's coordinate space.
+ * @y: returns the y coordinate of the origin of the model's coordinate space.
+ * @scale: returns the scale of the model.
+ * @rotation: returns the clockwise rotation of the model, in degrees (0-360).
+ * 
+ * This function can be used to get the position, scale and rotation of an
+ * item model, providing that the model has a simple transformation matrix
+ * (e.g. set with goo_canvas_item_model_set_simple_transform(), or using a
+ * combination of simple translate, scale and rotate operations). If the model
+ * has a complex transformation matrix the results will be incorrect.
+ * 
+ * Returns: %TRUE if a transform is set.
+ **/
+gboolean
+goo_canvas_item_model_get_simple_transform (GooCanvasItemModel *model,
+					    gdouble            *x,
+					    gdouble            *y,
+					    gdouble            *scale,
+					    gdouble            *rotation)
+{
+  GooCanvasItemModelIface *iface = GOO_CANVAS_ITEM_MODEL_GET_IFACE (model);
+  cairo_matrix_t matrix = { 1, 0, 0, 1, 0, 0 };
+  double x1 = 1.0, y1 = 0.0, radians;
+  gboolean has_transform = FALSE;
+
+  if (iface->get_transform)
+    has_transform = iface->get_transform (model, &matrix);
+
+  if (!has_transform)
+    {
+      *x = *y = *rotation = 0.0;
+      *scale = 1.0;
+      return FALSE;
+    }
+
+  *x = matrix.x0;
+  *y = matrix.y0;
+
+  matrix.x0 = 0.0;
+  matrix.y0 = 0.0;
+
+  cairo_matrix_transform_point (&matrix, &x1, &y1);
+  *scale = sqrt (x1 * x1 + y1 * y1);
+  radians = atan2 (y1, x1);
+  *rotation = radians * (180 / M_PI);
+  if (*rotation < 0)
+    *rotation += 360;
+
+  return TRUE;
+}
+
+
+/**
  * goo_canvas_item_model_set_simple_transform:
  * @model: an item model.
  * @x: the x coordinate of the origin of the model's coordinate space.
@@ -837,23 +907,69 @@
 /*
  * Child Properties.
  */
+extern void _goo_canvas_item_set_child_property_internal (GObject *object, GObject *child, const gchar *property_name, const GValue *value, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
+
 extern void _goo_canvas_item_get_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
 
 extern void _goo_canvas_item_set_child_properties_internal (GObject *object, GObject *child, va_list var_args, GParamSpecPool *property_pool, GObjectNotifyContext *notify_context, gboolean is_model);
 
 
 /**
+ * goo_canvas_item_model_get_child_property:
+ * @model: a #GooCanvasItemModel.
+ * @child: a child #GooCanvasItemModel.
+ * @property_name: the name of the child property to get.
+ * @value: a location to return the value.
+ * 
+ * Gets a child property of @child.
+ **/
+void
+goo_canvas_item_model_get_child_property (GooCanvasItemModel *model,
+					  GooCanvasItemModel *child,
+					  const gchar        *property_name,
+					  GValue             *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_item_get_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_item_model_child_property_pool, TRUE);
+}
+
+
+/**
+ * goo_canvas_item_model_set_child_property:
+ * @model: a #GooCanvasItemModel.
+ * @child: a child #GooCanvasItemModel.
+ * @property_name: the name of the child property to set.
+ * @value: the value to set the property to.
+ * 
+ * Sets a child property of @child.
+ **/
+void
+goo_canvas_item_model_set_child_property (GooCanvasItemModel *model,
+					  GooCanvasItemModel *child,
+					  const gchar        *property_name,
+					  const GValue       *value)
+{
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (model));
+  g_return_if_fail (GOO_IS_CANVAS_ITEM_MODEL (child));
+  g_return_if_fail (property_name != NULL);
+  g_return_if_fail (G_IS_VALUE (value));
+
+  _goo_canvas_item_set_child_property_internal ((GObject*) model, (GObject*) child, property_name, value, _goo_canvas_item_model_child_property_pool, _goo_canvas_item_model_child_property_notify_context, TRUE);
+}
+
+
+/**
  * goo_canvas_item_model_get_child_properties_valist:
  * @model: a #GooCanvasItemModel.
  * @child: a child #GooCanvasItemModel.
  * @var_args: pairs of property names and value pointers, and a terminating
  *  %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It gets the values of one or more child properties of @child.
+ * Gets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_model_get_child_properties_valist (GooCanvasItemModel *model,
@@ -873,11 +989,7 @@
  * @child: a child #GooCanvasItemModel.
  * @var_args: pairs of property names and values, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It sets the values of one or more child properties of @child.
+ * Sets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_model_set_child_properties_valist (GooCanvasItemModel *model,
@@ -897,11 +1009,7 @@
  * @child: a child #GooCanvasItemModel.
  * @...: pairs of property names and value pointers, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It gets the values of one or more child properties of @child.
+ * Gets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_model_get_child_properties  (GooCanvasItemModel   *model,
@@ -922,11 +1030,7 @@
  * @child: a child #GooCanvasItemModel.
  * @...: pairs of property names and values, and a terminating %NULL.
  * 
- * This function is only intended to be used when implementing new canvas
- * item models, specifically layout container item models such as
- * #GooCanvasTableModel.
- *
- * It sets the values of one or more child properties of @child.
+ * Sets the values of one or more child properties of @child.
  **/
 void
 goo_canvas_item_model_set_child_properties  (GooCanvasItemModel   *model,

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.h
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.h	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitemmodel.h	Sat May  3 22:35:09 2008
@@ -169,6 +169,14 @@
 gint                goo_canvas_item_model_find_child     (GooCanvasItemModel *model,
 							  GooCanvasItemModel *child);
 
+void     goo_canvas_item_model_get_child_property	 (GooCanvasItemModel   *model,
+							  GooCanvasItemModel   *child,
+							  const gchar          *property_name,
+							  GValue               *value);
+void     goo_canvas_item_model_set_child_property	 (GooCanvasItemModel   *model,
+							  GooCanvasItemModel   *child,
+							  const gchar          *property_name,
+							  const GValue         *value);
 void     goo_canvas_item_model_get_child_properties	 (GooCanvasItemModel   *model,
 							  GooCanvasItemModel   *child,
 							  ...) G_GNUC_NULL_TERMINATED;
@@ -201,6 +209,11 @@
 							  cairo_matrix_t     *transform);
 void                goo_canvas_item_model_set_transform  (GooCanvasItemModel   *model,
 							  const cairo_matrix_t *transform);
+gboolean	    goo_canvas_item_model_get_simple_transform (GooCanvasItemModel *model,
+								gdouble            *x,
+								gdouble            *y,
+								gdouble            *scale,
+								gdouble            *rotation);
 void                goo_canvas_item_model_set_simple_transform (GooCanvasItemModel *model,
 								gdouble             x,
 								gdouble             y,

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.c	Sat May  3 22:35:09 2008
@@ -9,8 +9,8 @@
  * SECTION:goocanvasitemsimple
  * @Title: GooCanvasItemSimple
  * @Short_Description: the base class for the standard canvas items.
- * @Stability_Level:
- * @See_Also:
+ * @Stability_Level: 
+ * @See_Also: 
  *
  * #GooCanvasItemSimple is used as a base class for all of the standard canvas
  * items. It can also be used as the base class for new custom canvas items.
@@ -22,7 +22,7 @@
  * method. (#GooCanvasEllipse, #GooCanvasRect and #GooCanvasPath do this.)
  *
  * More complicated items need to implement the update(), paint() and
- * is_item_at() methods. (#GooCanvasImage, #GooCanvasPolyline,
+ * is_item_at() methods instead. (#GooCanvasImage, #GooCanvasPolyline,
  * #GooCanvasText and #GooCanvasWidget do this.) They may also need to
  * override some of the other GooCanvasItem methods such as set_canvas(),
  * set_parent() or allocate_area() if special code is needed. (#GooCanvasWidget
@@ -96,6 +96,20 @@
 						 const GValue         *value,
 						 GParamSpec           *pspec);
 
+static void     goo_canvas_item_simple_default_create_path (GooCanvasItemSimple   *simple,
+							    cairo_t               *cr);
+static void     goo_canvas_item_simple_default_update      (GooCanvasItemSimple   *simple,
+							    cairo_t               *cr);
+static void     goo_canvas_item_simple_default_paint       (GooCanvasItemSimple   *simple,
+							    cairo_t               *cr,
+							    const GooCanvasBounds *bounds);
+static gboolean goo_canvas_item_simple_default_is_item_at  (GooCanvasItemSimple   *simple,
+							    double                 x,
+							    double                 y,
+							    cairo_t               *cr,
+							    gboolean               is_pointer_event);
+
+
 G_DEFINE_TYPE_WITH_CODE (GooCanvasItemSimple, goo_canvas_item_simple,
 			 G_TYPE_OBJECT,
 			 G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
@@ -328,6 +342,11 @@
     }
 
   goo_canvas_item_simple_install_common_properties (gobject_class);
+
+  klass->simple_create_path = goo_canvas_item_simple_default_create_path;
+  klass->simple_update      = goo_canvas_item_simple_default_update;
+  klass->simple_paint       = goo_canvas_item_simple_default_paint;
+  klass->simple_is_item_at  = goo_canvas_item_simple_default_is_item_at;
 }
 
 
@@ -413,6 +432,27 @@
 }
 
 
+static guint
+convert_color (double red, double green, double blue, double alpha)
+{
+  guint red_byte, green_byte, blue_byte, alpha_byte;
+
+  red_byte = red * 256;
+  red_byte -= red_byte >> 8;
+
+  green_byte = green * 256;
+  green_byte -= green_byte >> 8;
+
+  blue_byte = blue * 256;
+  blue_byte -= blue_byte >> 8;
+
+  alpha_byte = alpha * 256;
+  alpha_byte -= alpha_byte >> 8;
+
+  return (red_byte << 24) + (green_byte << 16) + (blue_byte << 8) + alpha_byte;
+}
+
+
 static void
 goo_canvas_item_simple_get_common_property (GObject                 *object,
 					    GooCanvasItemSimpleData *simple_data,
@@ -425,6 +465,9 @@
   GValue *svalue;
   gdouble line_width = 2.0;
   gchar *font = NULL;
+  cairo_pattern_t *pattern;
+  double red, green, blue, alpha;
+  guint rgba = 0;
 
   switch (prop_id)
     {
@@ -493,6 +536,34 @@
       g_value_set_enum (value, svalue ? svalue->data[0].v_long : CAIRO_HINT_METRICS_OFF);
       break;
 
+      /* Convenience properties. */
+    case PROP_STROKE_COLOR_RGBA:
+      svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
+      if (svalue && svalue->data[0].v_pointer)
+	{
+	  pattern = svalue->data[0].v_pointer;
+	  if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
+	    {
+	      cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
+	      rgba = convert_color (red, green, blue, alpha);
+	    }
+	}
+      g_value_set_uint (value, rgba);
+      break;
+    case PROP_FILL_COLOR_RGBA:
+      svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
+      if (svalue && svalue->data[0].v_pointer)
+	{
+	  pattern = svalue->data[0].v_pointer;
+	  if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
+	    {
+	      cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
+	      rgba = convert_color (red, green, blue, alpha);
+	    }
+	}
+      g_value_set_uint (value, rgba);
+      break;
+
       /* Other properties. */
     case PROP_TRANSFORM:
       g_value_set_boxed (value, simple_data->transform);
@@ -771,7 +842,6 @@
   GooCanvasItem *parent;
   AtkObject *accessible;
   gboolean recompute_bounds;
-  gint child_num;
 
   if (simple->model)
     {
@@ -783,11 +853,7 @@
     {
     case PROP_PARENT:
       parent = g_value_get_object (value);
-      if (simple->parent)
-	{
-	  child_num = goo_canvas_item_find_child (simple->parent, item);
-	  goo_canvas_item_remove_child (simple->parent, child_num);
-	}
+      goo_canvas_item_remove (item);
       goo_canvas_item_add_child (parent, item, -1);
       break;
     case PROP_TITLE:
@@ -854,7 +920,7 @@
  * goo_canvas_item_simple_changed:
  * @item: a #GooCanvasItemSimple.
  * @recompute_bounds: if the item's bounds need to be recomputed.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple.
  *
  * It is used as a callback for the "changed" signal of the item models.
@@ -965,7 +1031,7 @@
 
   if (simple->need_update)
     goo_canvas_item_ensure_updated (item);
-
+    
   *bounds = simple->bounds;
 }
 
@@ -983,7 +1049,6 @@
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
   GooCanvasItemSimpleData *simple_data = simple->simple_data;
   double user_x = x, user_y = y;
-  GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL;
   cairo_matrix_t matrix;
   gboolean add_item = FALSE;
 
@@ -1006,8 +1071,6 @@
 	      || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
 		  && simple->canvas->scale < simple_data->visibility_threshold)))
 	return found_items;
-
-      pointer_events = simple_data->pointer_events;
     }
 
   cairo_save (cr);
@@ -1033,20 +1096,8 @@
 	}
     }
 
-  if (class->simple_is_item_at)
-    {
-      add_item = class->simple_is_item_at (simple, user_x, user_y, cr,
-					   is_pointer_event);
-    }
-  else
-    {
-      /* Use the virtual method subclasses define to create the path. */
-      class->simple_create_path (simple, cr);
-
-      if (goo_canvas_item_simple_check_in_path (simple, user_x, user_y, cr,
-						pointer_events))
-	add_item = TRUE;
-    }
+  add_item = class->simple_is_item_at (simple, user_x, user_y, cr,
+                                       is_pointer_event);
 
   cairo_restore (cr);
 
@@ -1058,6 +1109,31 @@
 
 
 static gboolean
+goo_canvas_item_simple_default_is_item_at (GooCanvasItemSimple *simple,
+					   double               x,
+					   double               y,
+					   cairo_t             *cr,
+					   gboolean             is_pointer_event)
+{
+  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
+
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasPointerEvents pointer_events = GOO_CANVAS_EVENTS_ALL;
+
+  if (is_pointer_event)
+    pointer_events = simple_data->pointer_events;
+
+  /* Use the virtual method subclasses define to create the path. */
+  class->simple_create_path (simple, cr);
+
+  if (goo_canvas_item_simple_check_in_path (simple, x, y, cr, pointer_events))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+static gboolean
 goo_canvas_item_simple_is_visible  (GooCanvasItem   *item)
 {
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
@@ -1078,7 +1154,7 @@
 /**
  * goo_canvas_item_simple_check_style:
  * @item: a #GooCanvasItemSimple.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple,
  * typically in their update() or get_requested_area() methods.
  *
@@ -1129,17 +1205,7 @@
 
   cairo_get_matrix (cr, &transform);
 
-  if (class->simple_update)
-    {
-      class->simple_update (simple, cr);
-    }
-  else
-    {
-      /* Use the identity matrix to get the bounds completely in user space. */
-      cairo_identity_matrix (cr);
-      class->simple_create_path (simple, cr);
-      goo_canvas_item_simple_get_path_bounds (simple, cr, &simple->bounds);
-    }
+  class->simple_update (simple, cr);
 
   /* Modify the extents by the item's clip path. */
   if (simple_data->clip_path_commands)
@@ -1165,6 +1231,20 @@
 
 
 static void
+goo_canvas_item_simple_default_update (GooCanvasItemSimple   *simple,
+				       cairo_t               *cr)
+{
+  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
+
+  /* Use the identity matrix to get the bounds completely in user space. */
+  cairo_identity_matrix (cr);
+
+  class->simple_create_path (simple, cr);
+  goo_canvas_item_simple_get_path_bounds (simple, cr, &simple->bounds);
+}
+
+
+static void
 goo_canvas_item_simple_update  (GooCanvasItem   *item,
 				gboolean         entire_tree,
 				cairo_t         *cr,
@@ -1333,21 +1413,31 @@
       cairo_clip (cr);
     }
 
-  if (class->simple_paint)
-    {
-      class->simple_paint (simple, cr, bounds);
-    }
-  else
-    {
-      class->simple_create_path (simple, cr);
-
-      goo_canvas_item_simple_paint_path (simple, cr);
-    }
+  class->simple_paint (simple, cr, bounds);
 
   cairo_restore (cr);
 }
 
 
+static void
+goo_canvas_item_simple_default_paint (GooCanvasItemSimple   *simple,
+				      cairo_t               *cr,
+				      const GooCanvasBounds *bounds)
+{
+  GooCanvasItemSimpleClass *class = GOO_CANVAS_ITEM_SIMPLE_GET_CLASS (simple);
+
+  class->simple_create_path (simple, cr);
+  goo_canvas_item_simple_paint_path (simple, cr);
+}
+
+
+static void
+goo_canvas_item_simple_default_create_path (GooCanvasItemSimple   *simple,
+					    cairo_t               *cr)
+{
+  /* Do nothing. */
+}
+
 
 static void
 goo_canvas_item_simple_title_changed (GooCanvasItemModelSimple *smodel,
@@ -1418,7 +1508,7 @@
  * goo_canvas_item_simple_set_model:
  * @item: a #GooCanvasItemSimple.
  * @model: the model that @item will view.
- *
+ * 
  * This function should be called by subclasses of #GooCanvasItemSimple
  * in their set_model() method.
  **/
@@ -1482,7 +1572,7 @@
  * goo_canvas_item_simple_paint_path:
  * @item: a #GooCanvasItemSimple.
  * @cr: a cairo context.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple.
  *
  * It paints the current path, using the item's style settings.
@@ -1512,7 +1602,7 @@
  * @item: a #GooCanvasItemSimple.
  * @cr: a cairo context.
  * @bounds: the #GooCanvasBounds struct to store the resulting bounding box.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple,
  * typically in their update() or get_requested_area() methods.
  *
@@ -1598,7 +1688,7 @@
  * @item: a #GooCanvasItemSimple.
  * @cr: a cairo context.
  * @bounds: the bounds of the item, in the item's coordinate space.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple,
  * typically in their update() or get_requested_area() methods.
  *
@@ -1646,7 +1736,7 @@
  * @item: a #GooCanvasItemSimple.
  * @cr: a cairo context.
  * @bounds: the bounds of the item, in the item's coordinate space.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple,
  * typically in their get_requested_area() method.
  *
@@ -1705,12 +1795,12 @@
  * @y: the y coordinate of the point.
  * @cr: a cairo context.
  * @pointer_events: specifies which parts of the path to check.
- *
+ * 
  * This function is intended to be used by subclasses of #GooCanvasItemSimple.
  *
  * It checks if the given point is in the current path, using the item's
  * style settings.
- *
+ * 
  * Returns: %TRUE if the given point is in the current path.
  **/
 gboolean
@@ -1752,9 +1842,9 @@
 /**
  * goo_canvas_item_simple_get_line_width:
  * @item: a #GooCanvasItemSimple.
- *
+ * 
  * Gets the item's line width.
- *
+ * 
  * Returns: the item's line width.
  **/
 gdouble
@@ -1777,8 +1867,8 @@
  * SECTION:goocanvasitemmodelsimple
  * @Title: GooCanvasItemModelSimple
  * @Short_Description: the base class for the standard canvas item models.
- * @Stability_Level:
- * @See_Also:
+ * @Stability_Level: 
+ * @See_Also: 
  *
  * #GooCanvasItemModelSimple is used as a base class for the standard canvas
  * item models. It can also be used as the base class for new custom canvas
@@ -1897,17 +1987,12 @@
   GooCanvasItemSimpleData *simple_data = &smodel->simple_data;
   GooCanvasItemModel *parent;
   gboolean recompute_bounds;
-  gint child_num;
 
   switch (prop_id)
     {
     case PROP_PARENT:
       parent = g_value_get_object (value);
-      if (smodel->parent)
-	{
-	  child_num = goo_canvas_item_model_find_child (smodel->parent, model);
-	  goo_canvas_item_model_remove_child (smodel->parent, child_num);
-	}
+      goo_canvas_item_model_remove (model);
       goo_canvas_item_model_add_child (parent, model, -1);
       break;
     case PROP_TITLE:

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.h
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.h	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasitemsimple.h	Sat May  3 22:35:09 2008
@@ -117,6 +117,8 @@
  *  All updating, painting and hit-testing is provided automatically by the
  *  #GooCanvasItemSimple class. (This method is used by the builtin
  *  #GooCanvasEllipse, #GooCanvasRect and #GooCanvasPath items.)
+ *  More complicated subclasses must override @simple_update, @simple_paint and
+ *  @simple_is_item_at instead.
  * @simple_update: subclasses should override this to calculate their new
  *  bounds, in user space.
  * @simple_paint: subclasses should override this to paint their item.
@@ -126,7 +128,7 @@
  * subclasses can override.
  *
  * Simple items need only implement the create_path() method. More complex
- * items must override the update(), paint() and is_item_at() methods.
+ * items must override the update(), paint() and is_item_at() methods instead.
  */
 struct _GooCanvasItemSimpleClass
 {

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvasmarshal.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvasmarshal.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvasmarshal.c	Sat May  3 22:35:09 2008
@@ -55,10 +55,10 @@
 /* VOID:INT,INT (./goocanvasmarshal.list:3) */
 void
 goo_canvas_marshal_VOID__INT_INT (GClosure     *closure,
-                                  GValue       *return_value,
+                                  GValue       *return_value G_GNUC_UNUSED,
                                   guint         n_param_values,
                                   const GValue *param_values,
-                                  gpointer      invocation_hint,
+                                  gpointer      invocation_hint G_GNUC_UNUSED,
                                   gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer     data1,
@@ -94,10 +94,10 @@
 /* VOID:OBJECT,OBJECT (./goocanvasmarshal.list:5) */
 void
 goo_canvas_marshal_VOID__OBJECT_OBJECT (GClosure     *closure,
-                                        GValue       *return_value,
+                                        GValue       *return_value G_GNUC_UNUSED,
                                         guint         n_param_values,
                                         const GValue *param_values,
-                                        gpointer      invocation_hint,
+                                        gpointer      invocation_hint G_GNUC_UNUSED,
                                         gpointer      marshal_data)
 {
   typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer     data1,
@@ -131,10 +131,10 @@
 /* BOOLEAN:BOXED (./goocanvasmarshal.list:6) */
 void
 goo_canvas_marshal_BOOLEAN__BOXED (GClosure     *closure,
-                                   GValue       *return_value,
+                                   GValue       *return_value G_GNUC_UNUSED,
                                    guint         n_param_values,
                                    const GValue *param_values,
-                                   gpointer      invocation_hint,
+                                   gpointer      invocation_hint G_GNUC_UNUSED,
                                    gpointer      marshal_data)
 {
   typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer     data1,
@@ -170,10 +170,10 @@
 /* BOOLEAN:OBJECT,BOXED (./goocanvasmarshal.list:7) */
 void
 goo_canvas_marshal_BOOLEAN__OBJECT_BOXED (GClosure     *closure,
-                                          GValue       *return_value,
+                                          GValue       *return_value G_GNUC_UNUSED,
                                           guint         n_param_values,
                                           const GValue *param_values,
-                                          gpointer      invocation_hint,
+                                          gpointer      invocation_hint G_GNUC_UNUSED,
                                           gpointer      marshal_data)
 {
   typedef gboolean (*GMarshalFunc_BOOLEAN__OBJECT_BOXED) (gpointer     data1,

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvastable.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvastable.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvastable.c	Sat May  3 22:35:09 2008
@@ -56,7 +56,11 @@
   PROP_ROW_SPACING,
   PROP_COLUMN_SPACING,
   PROP_HOMOGENEOUS_ROWS,
-  PROP_HOMOGENEOUS_COLUMNS
+  PROP_HOMOGENEOUS_COLUMNS,
+  PROP_X_BORDER_SPACING,
+  PROP_Y_BORDER_SPACING,
+  PROP_VERT_GRID_LINE_WIDTH,
+  PROP_HORZ_GRID_LINE_WIDTH
 };
 
 enum
@@ -106,10 +110,14 @@
 typedef struct _GooCanvasTableDimensionLayoutData GooCanvasTableDimensionLayoutData;
 struct _GooCanvasTableDimensionLayoutData
 {
-  /* This is the actual spacing for after the row or column. It is set in
-     goo_canvas_table_init_layout_data(). */
+  /* This is the actual spacing for after the row or column, including
+     the grid line width. It is set in goo_canvas_table_init_layout_data(). */
   gdouble spacing;
 
+  /* Stores the grid line visibilty for the grid lines to the right or bottom
+     of this row/column, respectivel, for each cell in the other dimension. */
+  guint32 *grid_line_visibility;
+
   /* The requisition is calculated in goo_canvas_table_size_request_pass[123]*/
   gdouble requisition;
 
@@ -139,6 +147,16 @@
   gdouble start_pad[2], end_pad[2];
 };
 
+/* Convenience macros to set/unset/check bit-flags. */
+#define GOO_CANVAS_TABLE_SET_GRID_LINE_VISIBILITY(dim, x, y) \
+  ((dim)[(x)].grid_line_visibility[(y)/32] |= (1 << ((y) % 32)))
+
+#define GOO_CANVAS_TABLE_UNSET_GRID_LINE_VISIBILITY(dim, x, y) \
+  ((dim)[(x)].grid_line_visibility[(y)/32] &= ~(1 << ((y) % 32)))
+
+#define GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(dim, x, y) \
+  ((dim)[(x)].grid_line_visibility[(y)/32] & (1 << ((y) % 32)))
+
 /* The children array is only kept around while doing the layout.
    It gets freed in goo_canvas_table_allocate_area(). */
 struct _GooCanvasTableLayoutData
@@ -152,6 +170,17 @@
   /* This is the border width used, possibly rounded to an integer. */
   gdouble border_width;
 
+  /* The actual property value */
+  gdouble prop_grid_line_width[2];
+
+  /* The grid line width in both directions (rounded for integer layout). */
+  gdouble grid_line_width[2];
+
+  /* This is the actual spacing between the uppermost, bottommost, leftmost
+     and rightmost cells from the widget border. This is the border spacing
+     for that dimension. */
+  gdouble border_spacing[2];
+
   /* These are in the table's coordinate space. */
   gdouble natural_size[2];
   gdouble requested_size[2];
@@ -176,6 +205,7 @@
 					   const GValue       *value,
 					   GParamSpec         *pspec);
 
+static void goo_canvas_table_init_layout_data (GooCanvasTable *table);
 static void goo_canvas_table_free_layout_data (GooCanvasTableData *table_data);
 
 G_DEFINE_TYPE_WITH_CODE (GooCanvasTable, goo_canvas_table,
@@ -207,14 +237,14 @@
   /* FIXME: Support setting individual row/col spacing. */
   g_object_class_install_property (gobject_class, PROP_ROW_SPACING,
                                    g_param_spec_double ("row-spacing",
-							_("Row spacing"),
+							_("Row Spacing"),
 							_("The default space between rows"),
 							0.0, G_MAXDOUBLE, 0.0,
 							G_PARAM_READWRITE));
 
   g_object_class_install_property (gobject_class, PROP_COLUMN_SPACING,
                                    g_param_spec_double ("column-spacing",
-							_("Column spacing"),
+							_("Column Spacing"),
 							_("The default space between columns"),
 							0.0, G_MAXDOUBLE, 0.0,
 							G_PARAM_READWRITE));
@@ -232,6 +262,31 @@
 							 _("If all columns are the same width"),
 							 FALSE,
 							 G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_X_BORDER_SPACING,
+                                   g_param_spec_double("x-border-spacing",
+                                                       _("X Border Spacing"),
+                                                       _("The amount of spacing between the lefmost and rightmost cells and the border grid line"),
+                                                       0.0, G_MAXDOUBLE, 0.0,
+                                                       G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_Y_BORDER_SPACING,
+                                   g_param_spec_double("y-border-spacing",
+                                                       _("Y Border Spacing"),
+                                                       _("The amount of spacing between the topmost and bottommost cells and the border grid line"),
+                                                       0.0, G_MAXDOUBLE, 0.0,
+                                                       G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_WIDTH,
+                                   g_param_spec_double("horz-grid-line-width",
+                                                        _("Horizontal Grid Line Width"),
+                                                        _("The width of the grid line to draw between rows"),
+                                                        0.0, G_MAXDOUBLE, 0.0,
+                                                        G_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_WIDTH,
+                                   g_param_spec_double("vert-grid-line-width",
+                                                       _("Vertical Grid Line Width"),
+                                                       _("The width of the grid line to draw between columns"),
+                                                       0.0, G_MAXDOUBLE, 0.0,
+                                                       G_PARAM_READWRITE));
 
   /*
    * Child properties.
@@ -373,6 +428,16 @@
   table_data->border_width = 0.0;
 
   table_data->children = g_array_new (0, 0, sizeof (GooCanvasTableChild));
+
+  table_data->layout_data = g_slice_new (GooCanvasTableLayoutData);
+  table_data->layout_data->children = NULL;
+  for (d = 0; d < 2; d++)
+    {
+      table_data->layout_data->dldata[d] = NULL;
+      table_data->layout_data->prop_grid_line_width[d] = 0.0;
+      table_data->layout_data->grid_line_width[d] = 0.0;
+      table_data->layout_data->border_spacing[d] = 0.0;
+    }
 }
 
 
@@ -525,6 +590,18 @@
     case PROP_HOMOGENEOUS_COLUMNS:
       g_value_set_boolean (value, table_data->dimensions[HORZ].homogeneous);
       break;
+    case PROP_X_BORDER_SPACING:
+      g_value_set_double (value, table_data->layout_data->border_spacing[HORZ]);
+      break;
+    case PROP_Y_BORDER_SPACING:
+      g_value_set_double (value, table_data->layout_data->border_spacing[VERT]);
+      break;
+    case PROP_HORZ_GRID_LINE_WIDTH:
+      g_value_set_double (value, table_data->layout_data->prop_grid_line_width[HORZ]);
+      break;
+    case PROP_VERT_GRID_LINE_WIDTH:
+      g_value_set_double (value, table_data->layout_data->prop_grid_line_width[VERT]);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -574,6 +651,18 @@
     case PROP_HOMOGENEOUS_COLUMNS:
       table_data->dimensions[HORZ].homogeneous = g_value_get_boolean (value);
       break;
+    case PROP_X_BORDER_SPACING:
+      table_data->layout_data->border_spacing[HORZ] = g_value_get_double (value);
+      break;
+    case PROP_Y_BORDER_SPACING:
+      table_data->layout_data->border_spacing[VERT] = g_value_get_double (value);
+      break;
+    case PROP_HORZ_GRID_LINE_WIDTH:
+      table_data->layout_data->prop_grid_line_width[HORZ] = g_value_get_double (value);
+      break;
+    case PROP_VERT_GRID_LINE_WIDTH:
+      table_data->layout_data->prop_grid_line_width[VERT] = g_value_get_double (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -611,26 +700,90 @@
 goo_canvas_table_update_dimensions (GooCanvasTableData    *table_data,
 				    GooCanvasTableChild   *table_child)
 {
-  gint d, size, i;
+  GooCanvasTableLayoutData *layout_data;
+  gint d, size[2], i;
+  layout_data = table_data->layout_data;
+  size[0] = table_child->start[0] + table_child->size[0];
+  size[1] = table_child->start[1] + table_child->size[1];
 
   for (d = 0; d < 2; d++)
     {
-      size = table_child->start[d] + table_child->size[d];
+      if (size[d] > table_data->dimensions[d].size)
+        {
+	  /* Resize the spacings array and the layout data array. */
+          table_data->dimensions[d].spacings = g_realloc (table_data->dimensions[d].spacings, size[d] * sizeof (gdouble));
+          layout_data->dldata[d] = g_renew (GooCanvasTableDimensionLayoutData, layout_data->dldata[d], size[d]);
+
+          /* Initialize new spacings to -1.0 so the default is used, and
+	     set the new grid_line_visibility arrays to NULL. */
+          for (i = table_data->dimensions[d].size; i < size[d]; i++)
+	    {
+	      table_data->dimensions[d].spacings[i] = -1.0;
+	      layout_data->dldata[d][i].grid_line_visibility = NULL;
+	    }
+        }
+    }
 
-      if (size > table_data->dimensions[d].size)
-	{
-	  table_data->dimensions[d].spacings = g_realloc (table_data->dimensions[d].spacings, size * sizeof (gdouble));
+  table_data->dimensions[0].size = MAX (size[0], table_data->dimensions[0].size);
+  table_data->dimensions[1].size = MAX (size[1], table_data->dimensions[1].size);
+}
+
+/* Sets or unsets grid line visibility for a given child */
+static void
+goo_canvas_update_grid_line_visibility (GooCanvasTableData *table_data)
+{
+  GooCanvasTableLayoutData *layout_data;
+  GooCanvasTableChild *table_child;
+  guint32 grid_line_size;
+  gint d, d2, child_num, i, j;
 
-	  /* Initialize new spacings to -1.0 so the default is used. */
-	  for (i = table_data->dimensions[d].size; i < size; i++)
-	    table_data->dimensions[d].spacings[i] = -1.0;
+  layout_data = table_data->layout_data;
+  for (d = 0; d < 2; d++)
+    {
+      /* This is the opposite dimension. */
+      d2 = 1 - d;
 
-	  table_data->dimensions[d].size = size;
-	}
+      /* The amount of guint32s we need to store grid line visibility
+         for a particular row or column. In case of vertical grid lines
+         we store the grid lines (right to) a particular column for each row.
+         Therefore we need one bit for each row. This is also why this depends
+         on dimensions[1-d] instead of dimensions[d]. */
+      grid_line_size = ((table_data->dimensions[d2].size + 31) / 32);
+
+      /* Allocate or reallocate the grid_line_visibility arrays and initialize
+	 all grid lines to visible (by setting to the arrays to all 0xFF). */
+      for (i = 0; i + 1 < table_data->dimensions[d].size; i++)
+	{
+	  layout_data->dldata[d][i].grid_line_visibility
+	    = g_realloc (layout_data->dldata[d][i].grid_line_visibility,
+			 grid_line_size * sizeof (guint32));
+	  memset (layout_data->dldata[d][i].grid_line_visibility, 0xff,
+		  grid_line_size * sizeof (guint32));
+	}
+
+      /* Remove lines for each child spanning multiple rows/colmuns */
+      for (child_num = 0; child_num < table_data->children->len; child_num++)
+        {
+          table_child = &g_array_index (table_data->children,
+					GooCanvasTableChild, child_num);
+
+          /* Foreach cell the child is spanning */
+          for (i = table_child->start[d];
+	       i < table_child->start[d] + table_child->size[d] - 1;
+	       i++)
+            {
+              /* Iterate through occupied cells in the other dimension */
+              for (j = table_child->start[d2];
+		   j < table_child->start[d2] + table_child->size[d2];
+		   j++)
+                {
+                  GOO_CANVAS_TABLE_UNSET_GRID_LINE_VISIBILITY (layout_data->dldata[d], i, j);
+                }
+            }
+        }
     }
 }
 
-
 static void
 goo_canvas_table_add_child_internal (GooCanvasTableData *table_data,
 				     gint                position)
@@ -993,8 +1146,14 @@
 static void
 goo_canvas_table_free_layout_data (GooCanvasTableData *table_data)
 {
+  gint i;
+
   if (table_data->layout_data)
     {
+      for (i = 0; i < table_data->dimensions[VERT].size; i++)
+        g_free (table_data->layout_data->dldata[VERT][i].grid_line_visibility);
+      for (i = 0; i < table_data->dimensions[HORZ].size; i++)
+        g_free (table_data->layout_data->dldata[HORZ][i].grid_line_visibility);
       g_free (table_data->layout_data->dldata[HORZ]);
       g_free (table_data->layout_data->dldata[VERT]);
       g_free (table_data->layout_data->children);
@@ -1011,30 +1170,41 @@
   GooCanvasItemSimple *simple = (GooCanvasItemSimple*) table;
   GooCanvasTableData *table_data = table->table_data;
   GooCanvasTableDimension *dimension;
-  GooCanvasTableLayoutData *layout_data;
+  GooCanvasTableLayoutData *layout_data = table_data->layout_data;
   GooCanvasTableDimensionLayoutData *dldata;
   gint d, i;
 
-  /* Free any previous data. */
-  goo_canvas_table_free_layout_data (table->table_data);
-
-  layout_data = g_slice_new (GooCanvasTableLayoutData);
-
-  table_data->layout_data = layout_data;
   layout_data->children = g_new (GooCanvasTableChildLayoutData,
 				 table_data->children->len);
   layout_data->last_width = -1;
-  layout_data->integer_layout = simple->canvas->integer_layout;
+
+  /* If we are not yet added to a canvas, integer layout is irrelevant anyway.
+     We still need the layout_data for private fields, such as border spacing
+     and grid line visibility. */
+  if (simple->canvas)
+    layout_data->integer_layout = simple->canvas->integer_layout;
+  else
+    layout_data->integer_layout = FALSE;
   layout_data->border_width = table_data->border_width;
   if (layout_data->integer_layout)
     layout_data->border_width = floor (layout_data->border_width + 0.5);
 
+  layout_data->grid_line_width[0] = layout_data->prop_grid_line_width[0];
+  layout_data->grid_line_width[1] = layout_data->prop_grid_line_width[1];
+  if (layout_data->integer_layout)
+    {
+      layout_data->grid_line_width[0] = floor (layout_data->grid_line_width[0] + 0.5);
+      layout_data->grid_line_width[1] = floor (layout_data->grid_line_width[1] + 0.5);
+    }
+
   for (d = 0; d < 2; d++)
     {
       dimension = &table_data->dimensions[d];
 
-      layout_data->dldata[d] = g_new (GooCanvasTableDimensionLayoutData,
-				      dimension->size);
+      /* Already allocated in goo_canvas_table_update_dimensions() */
+      /*layout_data->dldata[d] = g_renew (GooCanvasTableDimensionLayoutData,
+                                        layout_data->dldata[d],
+				        dimension->size);*/
       dldata = layout_data->dldata[d];
 
       for (i = 0; i < dimension->size; i++)
@@ -1045,6 +1215,9 @@
 	  else
 	    dldata[i].spacing = dimension->default_spacing;
 
+          /* Add grid line widths to spacing */
+          dldata[i].spacing += layout_data->prop_grid_line_width[1-d];
+
 	  /* In integer layout mode, round spacings to the nearest integer. */
 	  if (layout_data->integer_layout)
 	    dldata[i].spacing = floor (dldata[i].spacing + 0.5);
@@ -1056,6 +1229,9 @@
 	  dldata[i].empty = TRUE;
 	}
     }
+
+  /* Update grid line visibility */
+  goo_canvas_update_grid_line_visibility (table_data);
 }
 
 
@@ -1392,7 +1568,7 @@
   GooCanvasTableLayoutData *layout_data = table_data->layout_data;
   GooCanvasTableDimension *dimension;
   GooCanvasTableDimensionLayoutData *dldata;
-  gdouble total_size, size_to_allocate, natural_size, extra;
+  gdouble total_size, size_to_allocate, natural_size, extra, old_extra;
   gint i, nexpand, nshrink;
   
   /* If we were allocated more space than we requested
@@ -1402,8 +1578,6 @@
   dimension = &table_data->dimensions[d];
   dldata = layout_data->dldata[d];
 
-  total_size = layout_data->allocated_size[d] - layout_data->border_width * 2.0;
-
   natural_size = 0;
   nexpand = 0;
   nshrink = 0;
@@ -1418,7 +1592,22 @@
     }
   for (i = 0; i + 1 < dimension->size; i++)
     natural_size += dldata[i].spacing;
-      
+
+  /* Note: natural_size does not contain without border width and
+     border spacing here. */
+
+  /* total_size is the size available for allocating widgets. We always
+     allocate space for border_width, but for right/bottom border_spacing only
+     if all children can be allocated without being shrunk. */
+  if (layout_data->allocated_size[d] < layout_data->border_width * 2.0 + layout_data->border_spacing[d] + layout_data->grid_line_width[1-d])
+    total_size = 0;
+  else if (layout_data->allocated_size[d] < layout_data->border_width * 2.0 + layout_data->border_spacing[d] + layout_data->grid_line_width[1-d] + natural_size)
+    total_size = layout_data->allocated_size[d] - layout_data->border_width * 2.0 - layout_data->border_spacing[d] - layout_data->grid_line_width[1-d];
+  else if (layout_data->allocated_size[d] < layout_data->border_width * 2.0 + (layout_data->border_spacing[d] + layout_data->grid_line_width[1-d]) * 2.0 + natural_size)
+    total_size = natural_size;
+  else
+    total_size = layout_data->allocated_size[d] - layout_data->border_width * 2.0 - (layout_data->border_spacing[d] + layout_data->grid_line_width[1-d])* 2.0;
+
   if (dimension->homogeneous)
     {
       /* If the table is homogeneous in this dimension we check if any of
@@ -1492,6 +1681,7 @@
 	  while (total_nshrink > 0 && extra > 0)
 	    {
 	      nshrink = total_nshrink;
+	      old_extra = extra;
 	      for (i = 0; i < dimension->size; i++)
 		{
 		  if (dldata[i].shrink && dldata[i].allocation > 0.0)
@@ -1511,6 +1701,8 @@
 			total_nshrink -= 1;
 		    }
 		}
+	      if (extra >= old_extra)
+		break;
 	    }
 	}
     }
@@ -1532,7 +1724,7 @@
   dimension = &table_data->dimensions[d];
   dldata = layout_data->dldata[d];
 
-  pos = layout_data->border_width;
+  pos = layout_data->border_width + layout_data->border_spacing[d] + layout_data->grid_line_width[1-d];
   for (i = 0; i < dimension->size; i++)
     {
       dldata[i].start = pos;
@@ -1721,7 +1913,7 @@
       if (row < end)
 	height += rows[row].spacing;
     }
-  height += layout_data->border_width * 2.0;
+  height += (layout_data->border_width + layout_data->border_spacing[VERT] + layout_data->grid_line_width[HORZ]) * 2.0;
 
   layout_data->natural_size[VERT] = height;
 }
@@ -1780,7 +1972,7 @@
       if (column < end)
 	width += columns[column].spacing;
     }
-  width += layout_data->border_width * 2.0;
+  width += (layout_data->border_width + layout_data->border_spacing[HORZ] + layout_data->grid_line_width[VERT]) * 2.0;
   
   /* Save the natural size, so we know if we have to clip children. */
   layout_data->natural_size[HORZ] = width;
@@ -1807,7 +1999,7 @@
       if (row < end)
 	height += rows[row].spacing;
     }
-  height += layout_data->border_width * 2.0;
+  height += (layout_data->border_width + layout_data->border_spacing[VERT] + layout_data->grid_line_width[HORZ]) * 2.0;
 
   /* Save the natural size, so we know if we have to clip children. */
   layout_data->natural_size[VERT] = height;
@@ -2007,12 +2199,18 @@
   GooCanvasTableLayoutData *layout_data = table_data->layout_data;
   GooCanvasTableDimensionLayoutData *rows = layout_data->dldata[VERT];
   GooCanvasTableDimensionLayoutData *columns = layout_data->dldata[HORZ];
+  gdouble vert_grid_line_width = layout_data->grid_line_width[VERT];
+  gdouble horz_grid_line_width = layout_data->grid_line_width[HORZ];
   GArray *children = table_data->children;
   GooCanvasTableChild *table_child;
   GooCanvasItem *child;
   gboolean check_clip = FALSE, clip;
   gint start_column, end_column, start_row, end_row, i, j;
   gdouble x, y, end_x, end_y;
+  gdouble frame_width, frame_height;
+  gdouble line_start, line_end;
+  gdouble spacing, half_spacing_before, half_spacing_after;
+  gboolean old_grid_line_visibility = FALSE, cur_grid_line_visibility;
 
   /* Skip the item if the bounds don't intersect the expose rectangle. */
   if (simple->bounds.x1 > bounds->x2 || simple->bounds.x2 < bounds->x1
@@ -2044,6 +2242,163 @@
       || layout_data->allocated_size[VERT] < layout_data->natural_size[VERT])
     check_clip = TRUE;
 
+  /* frame_width/frame_height is the size of the table we draw the grid lines
+     around. This normally is the allocated size, except when we are shrunk
+     in which case we use the natural size. The grid will be clipped in that
+     case. */
+  frame_width = MAX (layout_data->allocated_size[HORZ], layout_data->natural_size[HORZ]);
+  frame_height = MAX (layout_data->allocated_size[VERT], layout_data->natural_size[VERT]);
+
+  /* Save current line width, line cap etc. for drawing items after having
+     drawn grid lines */
+  cairo_save (cr);
+
+  /* Draw border and grid lines */
+  if (check_clip)
+    {
+      cairo_rectangle (cr,
+                       layout_data->border_width,
+                       layout_data->border_width,
+                       layout_data->allocated_size[HORZ] - 2*layout_data->border_width,
+                       layout_data->allocated_size[VERT] - 2*layout_data->border_width);
+      cairo_clip (cr);
+    }
+
+  cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT);
+
+  /* Horizontal grid lines */
+  if (horz_grid_line_width > 0.0)
+    {
+      cairo_set_line_width (cr, horz_grid_line_width);
+
+      /* Outer lines */
+      line_start = layout_data->border_width;
+      line_end = frame_width - layout_data->border_width;
+
+      cairo_move_to (cr, line_start, layout_data->border_width + horz_grid_line_width/2);
+      cairo_rel_line_to (cr, line_end - line_start, 0);
+
+      cairo_move_to (cr, line_start, frame_height - layout_data->border_width - horz_grid_line_width/2);
+      cairo_rel_line_to (cr, line_end - line_start, 0);
+
+      /* Inner lines. Make sure we don't do overlapping drawing operations,
+         so we could easily draw alpha transparent borders */
+      for (i = 0; i + 1 < table_data->dimensions[VERT].size; i++)
+        {
+          for (j = 0; j < table_data->dimensions[HORZ].size; j++)
+            {
+              cur_grid_line_visibility = GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[VERT], i, j);
+              if (cur_grid_line_visibility)
+                {
+                  spacing = (columns[j].spacing - vert_grid_line_width);
+		  half_spacing_before = spacing / 2.0;
+                  if (simple->canvas->integer_layout)
+		    half_spacing_before = floor (half_spacing_before);
+		  half_spacing_after = spacing - half_spacing_before;
+
+                  if (j == 0)
+                    line_start = layout_data->border_width + vert_grid_line_width;
+                  else
+                    if (old_grid_line_visibility)
+                      line_start = columns[j].start - half_spacing_after;
+                    else
+                      line_start = columns[j-1].end + half_spacing_before;
+
+                  half_spacing_after = (columns[j].spacing - vert_grid_line_width)/2.0;
+                  if (simple->canvas->integer_layout)
+                    half_spacing_after = ceil (half_spacing_after);
+
+                  if (j == table_data->dimensions[HORZ].size - 1)
+                    line_end = frame_width - layout_data->border_width - vert_grid_line_width;
+                  else
+                    line_end = columns[j + 1].start - half_spacing_after;
+
+                  cairo_move_to (cr, line_start, rows[i].end + rows[i].spacing/2.0);
+                  cairo_rel_line_to (cr, line_end - line_start, 0);
+                }
+
+              old_grid_line_visibility = cur_grid_line_visibility;
+            }
+        }
+      
+      cairo_stroke (cr);
+    }
+
+  /* Vertical grid lines */
+  if (vert_grid_line_width > 0.0)
+    {
+      cairo_set_line_width (cr, vert_grid_line_width);
+
+      /* Outer lines */
+      line_start = layout_data->border_width + horz_grid_line_width;
+      line_end = frame_height - layout_data->border_width - horz_grid_line_width;
+
+      cairo_move_to (cr, layout_data->border_width + vert_grid_line_width/2, line_start);
+      cairo_rel_line_to (cr, 0, line_end - line_start);
+
+      cairo_move_to (cr, frame_width - layout_data->border_width - vert_grid_line_width/2, line_start);
+      cairo_rel_line_to (cr, 0, line_end - line_start);
+
+      /* Inner lines. Make sure we don't do overlapping drawing operations,
+         so we could easily draw alpha transparent borders. We need to
+         take additionally care that we don't cross already drawn
+         horizontal lines. */
+      for (i = 0; i + 1 < table_data->dimensions[HORZ].size; i++)
+        {
+          for (j = 0; j < table_data->dimensions[VERT].size; j++)
+            {
+              cur_grid_line_visibility = GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[HORZ], i, j);
+              if (cur_grid_line_visibility)
+                {
+                  spacing = (rows[j].spacing - horz_grid_line_width);
+		  half_spacing_before = spacing / 2.0;
+                  if (simple->canvas->integer_layout)
+		    half_spacing_before = floor (half_spacing_before);
+		  half_spacing_after = spacing - half_spacing_before;
+
+                  if (j == 0)
+                    line_start = layout_data->border_width + horz_grid_line_width;
+                  else
+                    if (old_grid_line_visibility)
+                      line_start = rows[j].start - half_spacing_after;
+                    else
+                      /* Don't draw top part if already drawn by horizontal grid line */
+                      if (GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[VERT], j-1, i)
+                          || GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[VERT], j-1, i+1))
+                        line_start = rows[j].start - half_spacing_after;
+                      else
+                        line_start = rows[j-1].end + half_spacing_before;
+
+                  half_spacing_before = half_spacing_after = (rows[j].spacing - horz_grid_line_width)/2.0;
+                  if (simple->canvas->integer_layout)
+                    {
+                      half_spacing_before = floor (half_spacing_before);
+                      half_spacing_after = ceil (half_spacing_after);
+                    }
+
+                  if (j == table_data->dimensions[VERT].size - 1)
+                    line_end = frame_height - layout_data->border_width - horz_grid_line_width;
+                  else
+                    /* Don't draw bottom part if already drawn by horizontal grid line */
+                    if (GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[VERT], j, i)
+                        || GOO_CANVAS_TABLE_IS_GRID_LINE_VISIBLE(layout_data->dldata[VERT], j, i+1))
+                      line_end = rows[j].end + half_spacing_before;
+                    else
+                      line_end = rows[j + 1].start - half_spacing_after;
+
+                  cairo_move_to (cr, columns[i].end + columns[i].spacing/2.0, line_start);
+                  cairo_rel_line_to (cr, 0, line_end - line_start);
+                }
+
+              old_grid_line_visibility = cur_grid_line_visibility;
+            }
+        }
+
+      cairo_stroke (cr);
+    }
+
+  cairo_restore (cr);
+
   for (i = 0; i < group->items->len; i++)
     {
       child = group->items->pdata[i];

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvastext.c
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvastext.c	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvastext.c	Sat May  3 22:35:09 2008
@@ -365,15 +365,14 @@
 
 
 static PangoLayout*
-goo_canvas_text_create_layout (GooCanvasText     *text,
-			       cairo_t           *cr,
-			       GooCanvasBounds   *bounds,
-			       gdouble	         *origin_x_return,
-			       gdouble	         *origin_y_return)
+goo_canvas_text_create_layout (GooCanvasItemSimpleData *simple_data,
+			       GooCanvasTextData       *text_data,
+			       gdouble                  layout_width,
+			       cairo_t                 *cr,
+			       GooCanvasBounds         *bounds,
+			       gdouble	               *origin_x_return,
+			       gdouble	               *origin_y_return)
 {
-  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text;
-  GooCanvasItemSimpleData *simple_data = simple->simple_data;
-  GooCanvasTextData *text_data = text->text_data;
   GooCanvasStyle *style = simple_data->style;
   GValue *svalue;
   PangoLayout *layout;
@@ -390,8 +389,8 @@
   layout = pango_cairo_create_layout (cr);
   context = pango_layout_get_context (layout);
 
-  if (text->layout_width > 0)
-    pango_layout_set_width (layout, (double) text->layout_width * PANGO_SCALE);
+  if (layout_width > 0)
+    pango_layout_set_width (layout, (double) layout_width * PANGO_SCALE);
 
   if (text_data->use_markup)
     pango_layout_set_markup (layout, string, -1);
@@ -544,8 +543,9 @@
   text->layout_width = text->text_data->width;
 
   /* Compute the new bounds. */
-  layout = goo_canvas_text_create_layout (text, cr, &simple->bounds,
-					  NULL, NULL);
+  layout = goo_canvas_text_create_layout (simple->simple_data, text->text_data,
+					  text->layout_width, cr,
+					  &simple->bounds, NULL, NULL);
   g_object_unref (layout);
 }
 
@@ -592,7 +592,8 @@
       && goo_canvas_text_is_unpainted (simple_data->style))
     return FALSE;
 
-  layout = goo_canvas_text_create_layout (text, cr, &bounds,
+  layout = goo_canvas_text_create_layout (simple_data, text->text_data,
+					  text->layout_width, cr, &bounds,
 					  &origin_x, &origin_y);
 
   /* Convert the coordinates into Pango units. */
@@ -654,7 +655,9 @@
   goo_canvas_style_set_fill_options (simple->simple_data->style, cr);
 
   cairo_new_path (cr);
-  layout = goo_canvas_text_create_layout (text, cr, &layout_bounds,
+  layout = goo_canvas_text_create_layout (simple->simple_data, text->text_data,
+					  text->layout_width, cr,
+					  &layout_bounds,
 					  &origin_x, &origin_y);
   cairo_move_to (cr, origin_x, origin_y);
   pango_cairo_show_layout (cr, layout);
@@ -691,8 +694,9 @@
     text->layout_width /= simple_data->transform->xx;
 
   /* Create layout with given width. */
-  layout = goo_canvas_text_create_layout (text, cr, &simple->bounds,
-					  NULL, NULL);
+  layout = goo_canvas_text_create_layout (simple_data, text->text_data,
+					  text->layout_width, cr,
+					  &simple->bounds, NULL, NULL);
   g_object_unref (layout);
 
   /* Convert to the parent's coordinate space. As above,  we only need to
@@ -711,6 +715,40 @@
 }
 
 
+/**
+ * goo_canvas_text_get_natural_extents:
+ * @text: a #GooCanvasText.
+ * @ink_rect: the location to return the ink rect, or %NULL.
+ * @logical_rect: the location to return the logical rect, or %NULL.
+ * 
+ * Gets the natural extents of the text, in the text item's coordinate space.
+ *
+ * The final extents of the text may be different, if the text item is placed
+ * in a layout container such as #GooCanvasTable.
+ **/
+void
+goo_canvas_text_get_natural_extents (GooCanvasText  *text,
+				     PangoRectangle *ink_rect,
+				     PangoRectangle *logical_rect)
+{
+  GooCanvasItem *item = (GooCanvasItem*) text;
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) text;
+  PangoLayout *layout;
+  cairo_t *cr;
+
+  if (simple->need_update)
+    goo_canvas_item_ensure_updated (item);
+
+  cr = goo_canvas_create_cairo_context (simple->canvas);
+  layout = goo_canvas_text_create_layout (simple->simple_data, text->text_data,
+					  text->text_data->width, cr, NULL,
+					  NULL, NULL);
+  pango_layout_get_extents (layout, ink_rect, logical_rect);
+  g_object_unref (layout);
+  cairo_destroy (cr);
+}
+
+
 static void
 goo_canvas_text_set_model    (GooCanvasItem      *item,
 			      GooCanvasItemModel *model)

Modified: branches/gcomprixogoo/src/goocanvas/src/goocanvastext.h
==============================================================================
--- branches/gcomprixogoo/src/goocanvas/src/goocanvastext.h	(original)
+++ branches/gcomprixogoo/src/goocanvas/src/goocanvastext.h	Sat May  3 22:35:09 2008
@@ -75,6 +75,9 @@
 					       GtkAnchorType       anchor,
 					       ...);
 
+void	goo_canvas_text_get_natural_extents   (GooCanvasText  *text,
+					       PangoRectangle *ink_rect,
+					       PangoRectangle *logical_rect);
 
 
 #define GOO_TYPE_CANVAS_TEXT_MODEL            (goo_canvas_text_model_get_type ())



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]