a84eacdfb2f349f4a8990374421eff61ed6062ad
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index 513c579..53ea15a 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -3548,6 +3548,7 @@ gtk_table_get_col_spacing
 gtk_table_get_default_col_spacing
 gtk_table_get_default_row_spacing
 gtk_table_get_homogeneous
+gtk_table_get_orientation
 gtk_table_get_row_spacing
 gtk_table_get_type G_GNUC_CONST
 gtk_table_new
@@ -3555,6 +3556,7 @@ gtk_table_resize
 gtk_table_set_col_spacing
 gtk_table_set_col_spacings
 gtk_table_set_homogeneous
+gtk_table_set_orientation
 gtk_table_set_row_spacing
 gtk_table_set_row_spacings
 #endif
diff --git a/gtk/gtktable.c b/gtk/gtktable.c
index 9002ad3..b922ce5 100644
--- a/gtk/gtktable.c
+++ b/gtk/gtktable.c
@@ -26,10 +26,16 @@
 
 #include <config.h>
 #include "gtktable.h"
+#include "gtkextendedlayout.h"
+#include "gtksizegroup.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkalias.h"
 
+#define GTK_TABLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TABLE, GtkTablePrivate))
+
+typedef struct _GtkTablePrivate GtkTablePrivate;
+
 enum
 {
   PROP_0,
@@ -37,7 +43,8 @@ enum
   PROP_N_COLUMNS,
   PROP_COLUMN_SPACING,
   PROP_ROW_SPACING,
-  PROP_HOMOGENEOUS
+  PROP_HOMOGENEOUS,
+  PROP_ORIENTATION
 };
 
 enum
@@ -53,6 +60,10 @@ enum
   CHILD_PROP_Y_PADDING
 };
   
+struct _GtkTablePrivate
+{
+  GtkOrientation orientation;
+};
 
 static void gtk_table_finalize	    (GObject	    *object);
 static void gtk_table_size_request  (GtkWidget	    *widget,
@@ -97,8 +108,11 @@ static void gtk_table_size_allocate_init  (GtkTable *table);
 static void gtk_table_size_allocate_pass1 (GtkTable *table);
 static void gtk_table_size_allocate_pass2 (GtkTable *table);
 
+static void gtk_table_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
 
-G_DEFINE_TYPE (GtkTable, gtk_table, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_CODE (GtkTable, gtk_table, GTK_TYPE_CONTAINER,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+                                                gtk_table_extended_layout_interface_init))
 
 static void
 gtk_table_class_init (GtkTableClass *class)
@@ -121,7 +135,8 @@ gtk_table_class_init (GtkTableClass *class)
   container_class->child_type = gtk_table_child_type;
   container_class->set_child_property = gtk_table_set_child_property;
   container_class->get_child_property = gtk_table_get_child_property;
-  
+
+  g_type_class_add_private (class, sizeof (GtkTablePrivate));
 
   g_object_class_install_property (gobject_class,
                                    PROP_N_ROWS,
@@ -166,6 +181,14 @@ gtk_table_class_init (GtkTableClass *class)
 							 P_("If TRUE, the table cells are all the same width/height"),
 							 FALSE,
 							 GTK_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                   PROP_ORIENTATION,
+                                   g_param_spec_enum ("orientation",
+						      P_("Orientation"),
+						      P_("The orientation used for child allocation"),
+						      GTK_TYPE_ORIENTATION,
+						      GTK_ORIENTATION_VERTICAL,
+						      GTK_PARAM_READWRITE));
 
   gtk_container_class_install_child_property (container_class,
 					      CHILD_PROP_LEFT_ATTACH,
@@ -258,6 +281,9 @@ gtk_table_get_property (GObject      *object,
     case PROP_HOMOGENEOUS:
       g_value_set_boolean (value, table->homogeneous);
       break;
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, GTK_TABLE_GET_PRIVATE (table)->orientation);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -291,6 +317,9 @@ gtk_table_set_property (GObject      *object,
     case PROP_HOMOGENEOUS:
       gtk_table_set_homogeneous (table, g_value_get_boolean (value));
       break;
+    case PROP_ORIENTATION:
+      gtk_table_set_orientation (table, g_value_get_enum (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -440,6 +469,8 @@ gtk_table_get_child_property (GtkContainer    *container,
 static void
 gtk_table_init (GtkTable *table)
 {
+  GtkTablePrivate *priv;
+
   GTK_WIDGET_SET_FLAGS (table, GTK_NO_WINDOW);
   gtk_widget_set_redraw_on_allocate (GTK_WIDGET (table), FALSE);
   
@@ -452,6 +483,9 @@ gtk_table_init (GtkTable *table)
   table->row_spacing = 0;
   table->homogeneous = FALSE;
 
+  priv = GTK_TABLE_GET_PRIVATE (table);
+  priv->orientation = GTK_ORIENTATION_VERTICAL;
+
   gtk_table_resize (table, 1, 1);
 }
 
@@ -795,6 +829,52 @@ gtk_table_get_homogeneous (GtkTable *table)
   return table->homogeneous;
 }
 
+/**
+ * gtk_table_set_orientation:
+ * @table: a #GtkTable
+ * @orientation: the orientation to use
+ *
+ * Changes the orientation of the table. The orientation specifies if
+ * height-for-width or width-for-height is used for child allocation.
+ * With an orientation of #GTK_ORIENTATION_VERTICAL heigth-for-width
+ * and for #GTK_ORIENTATION_HORIZONTAL width-for-heigth is used.
+ **/
+void
+gtk_table_set_orientation (GtkTable       *table,
+			   GtkOrientation  orientation)
+{
+  GtkTablePrivate *priv;
+
+  g_return_if_fail (GTK_IS_TABLE (table));
+  priv = GTK_TABLE_GET_PRIVATE (table);
+
+  if (orientation != priv->orientation)
+    {
+      priv->orientation = orientation;
+
+      if (GTK_WIDGET_VISIBLE (table))
+	gtk_widget_queue_resize (GTK_WIDGET (table));
+
+      g_object_notify (G_OBJECT (table), "orientation");
+    }
+}
+
+/**
+ * gtk_table_get_orientation:
+ * @table: a #GtkTable
+ *
+ * Returns whether the table prefers height-for-width or width-for-height
+ * for child allocation. (See gtk_table_set_orientation ())
+ *
+ * Return value: the orientation used
+ **/
+GtkOrientation
+gtk_table_get_orientation (GtkTable *table)
+{
+  g_return_val_if_fail (GTK_IS_TABLE (table), GTK_ORIENTATION_VERTICAL);
+  return GTK_TABLE_GET_PRIVATE (table)->orientation;
+}
+
 static void
 gtk_table_finalize (GObject *object)
 {
@@ -811,8 +891,9 @@ gtk_table_finalize (GObject *object)
 }
 
 static void
-gtk_table_size_request (GtkWidget      *widget,
-			GtkRequisition *requisition)
+gtk_table_real_size_request (GtkWidget      *widget,
+			     GtkRequisition *requisition,
+                             gboolean        consider_natural_size)
 {
   GtkTable *table;
   gint row, col;
@@ -830,14 +911,24 @@ gtk_table_size_request (GtkWidget      *widget,
   gtk_table_size_request_pass2 (table);
   gtk_table_size_request_pass3 (table);
   gtk_table_size_request_pass2 (table);
+
+  if (consider_natural_size)
+    {
+      for (col = 0; col < table->ncols; col++)
+        requisition->width += table->cols[col].natural_size;
+      for (row = 0; row < table->nrows; row++)
+        requisition->height += table->rows[row].natural_size;
+    }
+  else
+    {
+      for (col = 0; col < table->ncols; col++)
+        requisition->width += table->cols[col].requisition;
+      for (row = 0; row < table->nrows; row++)
+        requisition->height += table->rows[row].requisition;
+    }
   
-  for (col = 0; col < table->ncols; col++)
-    requisition->width += table->cols[col].requisition;
   for (col = 0; col + 1 < table->ncols; col++)
     requisition->width += table->cols[col].spacing;
-  
-  for (row = 0; row < table->nrows; row++)
-    requisition->height += table->rows[row].requisition;
   for (row = 0; row + 1 < table->nrows; row++)
     requisition->height += table->rows[row].spacing;
   
@@ -846,6 +937,13 @@ gtk_table_size_request (GtkWidget      *widget,
 }
 
 static void
+gtk_table_size_request (GtkWidget      *widget,
+			GtkRequisition *requisition)
+{
+  gtk_table_real_size_request (widget, requisition, FALSE);
+}
+
+static void
 gtk_table_size_allocate (GtkWidget     *widget,
 			 GtkAllocation *allocation)
 {
@@ -942,11 +1040,13 @@ gtk_table_size_request_init (GtkTable *table)
   for (row = 0; row < table->nrows; row++)
     {
       table->rows[row].requisition = 0;
+      table->rows[row].natural_size = 0;
       table->rows[row].expand = FALSE;
     }
   for (col = 0; col < table->ncols; col++)
     {
       table->cols[col].requisition = 0;
+      table->cols[col].natural_size = 0;
       table->cols[col].expand = FALSE;
     }
   
@@ -966,7 +1066,7 @@ gtk_table_size_request_init (GtkTable *table)
 	table->rows[child->top_attach].expand = TRUE;
     }
 }
-
+#include "gtklabel.h"
 static void
 gtk_table_size_request_pass1 (GtkTable *table)
 {
@@ -983,15 +1083,24 @@ gtk_table_size_request_pass1 (GtkTable *table)
       
       if (GTK_WIDGET_VISIBLE (child->widget))
 	{
-	  GtkRequisition child_requisition;
+	  GtkRequisition child_requisition, child_natural_size;
 	  gtk_widget_get_child_requisition (child->widget, &child_requisition);
 
+          if (GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
+            gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (child->widget),
+                                                  &child_natural_size);
+          else
+            child_natural_size = child_requisition;
+
 	  /* Child spans a single column.
 	   */
 	  if (child->left_attach == (child->right_attach - 1))
 	    {
 	      width = child_requisition.width + child->xpadding * 2;
 	      table->cols[child->left_attach].requisition = MAX (table->cols[child->left_attach].requisition, width);
+
+	      width = child_natural_size.width + child->xpadding * 2;
+              table->cols[child->left_attach].natural_size = MAX (table->cols[child->left_attach].natural_size, width);
 	    }
 	  
 	  /* Child spans a single row.
@@ -1000,6 +1109,9 @@ gtk_table_size_request_pass1 (GtkTable *table)
 	    {
 	      height = child_requisition.height + child->ypadding * 2;
 	      table->rows[child->top_attach].requisition = MAX (table->rows[child->top_attach].requisition, height);
+
+	      height = child_natural_size.height + child->ypadding * 2;
+              table->rows[child->top_attach].natural_size = MAX (table->rows[child->top_attach].natural_size, height);
 	    }
 	}
     }
@@ -1046,14 +1158,25 @@ gtk_table_size_request_pass3 (GtkTable *table)
       
       if (GTK_WIDGET_VISIBLE (child->widget))
 	{
+          GtkRequisition child_natural_size;
+          GtkRequisition child_requisition;
+
+	  if (child->left_attach != (child->right_attach - 1) ||
+	      child->top_attach != (child->bottom_attach - 1))
+            {
+	      gtk_widget_get_child_requisition (child->widget, &child_requisition);
+
+              if (GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (child->widget))
+                gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (child->widget),
+                                                      &child_natural_size);
+              else
+                child_natural_size = child_requisition;
+            }
+
 	  /* Child spans multiple columns.
 	   */
 	  if (child->left_attach != (child->right_attach - 1))
 	    {
-	      GtkRequisition child_requisition;
-
-	      gtk_widget_get_child_requisition (child->widget, &child_requisition);
-	      
 	      /* Check and see if there is already enough space
 	       *  for the child.
 	       */
@@ -1101,10 +1224,6 @@ gtk_table_size_request_pass3 (GtkTable *table)
 	   */
 	  if (child->top_attach != (child->bottom_attach - 1))
 	    {
-	      GtkRequisition child_requisition;
-
-	      gtk_widget_get_child_requisition (child->widget, &child_requisition);
-
 	      /* Check and see if there is already enough space
 	       *  for the child.
 	       */
@@ -1353,10 +1472,13 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
   gint real_width;
   gint real_height;
   gint width, height;
+  gint natural_delta;
+  gint natural_size;
   gint row, col;
   gint nexpand;
   gint nshrink;
   gint extra;
+  gint delta;
   
   /* If we were allocated more space than we requested
    *  then we have to expand any expandable rows and columns
@@ -1365,6 +1487,7 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
   
   real_width = GTK_WIDGET (table)->allocation.width - GTK_CONTAINER (table)->border_width * 2;
   real_height = GTK_WIDGET (table)->allocation.height - GTK_CONTAINER (table)->border_width * 2;
+  natural_delta = 0;
   
   if (table->homogeneous)
     {
@@ -1403,29 +1526,45 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
       for (col = 0; col < table->ncols; col++)
 	{
 	  width += table->cols[col].requisition;
+          delta = table->cols[col].natural_size - table->cols[col].requisition;
+
 	  if (table->cols[col].expand)
 	    nexpand += 1;
 	  if (table->cols[col].shrink)
 	    nshrink += 1;
+
+	  if (delta > 0)
+            natural_delta += delta;
 	}
       for (col = 0; col + 1 < table->ncols; col++)
 	width += table->cols[col].spacing;
       
       /* Check to see if we were allocated more width than we requested.
        */
-      if ((width < real_width) && (nexpand >= 1))
+      if ((width < real_width) && (nexpand >= 1 || natural_delta > 0))
 	{
 	  width = real_width - width;
-	  
+          natural_size = MAX (0, MIN (width, natural_delta));
+          width = width - natural_size;
+
 	  for (col = 0; col < table->ncols; col++)
-	    if (table->cols[col].expand)
-	      {
-		extra = width / nexpand;
-		table->cols[col].allocation += extra;
-		
-		width -= extra;
-		nexpand -= 1;
-	      }
+            {
+              if (natural_size)
+                {
+                  delta = table->cols[col].natural_size - table->cols[col].requisition;
+                  delta = natural_size * delta / natural_delta;
+                  table->cols[col].allocation += delta;
+                }
+
+              if (table->cols[col].expand)
+                {
+                  extra = width / nexpand;
+                  table->cols[col].allocation += extra;
+
+                  width -= extra;
+                  nexpand -= 1;
+                }
+            }
 	}
       
       /* Check to see if we were allocated less width than we requested,
@@ -1496,29 +1635,44 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
       for (row = 0; row < table->nrows; row++)
 	{
 	  height += table->rows[row].requisition;
+          delta = table->rows[row].natural_size - table->rows[row].requisition;
+
 	  if (table->rows[row].expand)
 	    nexpand += 1;
 	  if (table->rows[row].shrink)
 	    nshrink += 1;
+	  if (table->rows[row].natural_size > table->rows[row].requisition)
+            natural_delta += delta;
 	}
       for (row = 0; row + 1 < table->nrows; row++)
 	height += table->rows[row].spacing;
       
       /* Check to see if we were allocated more height than we requested.
        */
-      if ((height < real_height) && (nexpand >= 1))
+      if ((height < real_height) && (nexpand >= 1 || natural_delta > 0))
 	{
 	  height = real_height - height;
-	  
+          natural_size = MAX (0, MIN (height, natural_delta));
+          height = height - natural_size;
+
 	  for (row = 0; row < table->nrows; row++)
-	    if (table->rows[row].expand)
-	      {
-		extra = height / nexpand;
-		table->rows[row].allocation += extra;
-		
-		height -= extra;
-		nexpand -= 1;
-	      }
+            {
+              if (natural_size)
+                {
+                  delta = table->rows[row].natural_size - table->rows[row].requisition;
+                  delta = natural_size * delta / natural_delta;
+                  table->rows[row].allocation += delta;
+                }
+
+              if (table->rows[row].expand)
+                {
+                  extra = height / nexpand;
+                  table->rows[row].allocation += extra;
+
+                  height -= extra;
+                  nexpand -= 1;
+                }
+            }
 	}
       
       /* Check to see if we were allocated less height than we requested.
@@ -1636,5 +1790,25 @@ gtk_table_size_allocate_pass2 (GtkTable *table)
     }
 }
 
+static GtkExtendedLayoutFeatures
+gtk_table_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  return GTK_EXTENDED_LAYOUT_NATURAL_SIZE;
+}
+
+static void
+gtk_table_extended_layout_get_natural_size (GtkExtendedLayout *layout,
+                                            GtkRequisition    *requisition)
+{
+  gtk_table_real_size_request (GTK_WIDGET (layout), requisition, TRUE);
+}
+
+static void
+gtk_table_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_table_extended_layout_get_features;
+  iface->get_natural_size = gtk_table_extended_layout_get_natural_size;
+}
+
 #define __GTK_TABLE_C__
 #include "gtkaliasdef.c"
diff --git a/gtk/gtktable.h b/gtk/gtktable.h
index f925d33..85ca9b0 100644
--- a/gtk/gtktable.h
+++ b/gtk/gtktable.h
@@ -93,6 +93,7 @@ struct _GtkTableRowCol
   guint expand : 1;
   guint shrink : 1;
   guint empty : 1;
+  guint16 natural_size;
 };
 
 
@@ -139,6 +140,9 @@ void	   gtk_table_set_homogeneous  (GtkTable	       *table,
 				       gboolean		homogeneous);
 gboolean   gtk_table_get_homogeneous  (GtkTable        *table);
 
+void           gtk_table_set_orientation  (GtkTable       *table,
+					   GtkOrientation  orientation);
+GtkOrientation gtk_table_get_orientation  (GtkTable       *table);
 
 G_END_DECLS
 
