90409630716c7c4f25256fd7da95508297d01f38
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index a31cb1e..e80ee70 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -25,6 +25,7 @@
 
 #include <config.h>
 #include <math.h>
+#include <stdlib.h>
 #include <string.h>
 #include "gtklabel.h"
 #include "gtkaccellabel.h"
@@ -43,6 +44,7 @@
 #include "gtknotebook.h"
 #include "gtkstock.h"
 #include "gtkbindings.h"
+#include "gtkextendedlayout.h"
 #include "gtkprivate.h"
 #include "gtkalias.h"
 
@@ -58,6 +60,7 @@ typedef struct
   gint width_chars;
   gint max_width_chars;
   gboolean full_size;
+  gint baseline_offset;
 }
 GtkLabelPrivate;
 
@@ -201,9 +204,14 @@ static gint gtk_label_move_forward_word  (GtkLabel        *label,
 static gint gtk_label_move_backward_word (GtkLabel        *label,
 					  gint             start);
 
+static void gtk_label_extended_layout_interface_init (GtkExtendedLayoutIface *iface);
+
+
 static GQuark quark_angle = 0;
 
-G_DEFINE_TYPE (GtkLabel, gtk_label, GTK_TYPE_MISC)
+G_DEFINE_TYPE_WITH_CODE (GtkLabel, gtk_label, GTK_TYPE_MISC,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+						gtk_label_extended_layout_interface_init))
 
 static void
 add_move_binding (GtkBindingSet  *binding_set,
@@ -2455,7 +2463,8 @@ get_layout_location (GtkLabel  *label,
     x = MIN (x, widget->allocation.x + widget->allocation.width - misc->xpad);
 
   y = floor (widget->allocation.y + (gint)misc->ypad +
-  	     misc->yalign * (widget->allocation.height - req_height));
+  	     misc->yalign * (widget->allocation.height - req_height) +
+	     priv->baseline_offset);
 
   if (xp)
     *xp = x;
@@ -4354,5 +4363,126 @@ gtk_label_do_popup (GtkLabel       *label,
                     0, gtk_get_current_event_time ());
 }
 
+static GtkExtendedLayoutFeatures
+gtk_label_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  GtkLabel *label = GTK_LABEL (layout);
+  GtkLabelPrivate *priv = GTK_LABEL_GET_PRIVATE (label);
+  GtkExtendedLayoutFeatures features;
+
+  features =
+    GTK_EXTENDED_LAYOUT_NATURAL_SIZE |
+    GTK_EXTENDED_LAYOUT_BASELINES;
+
+  if (label->ellipsize || (label->wrap && priv->full_size))
+    {
+      gdouble angle = gtk_label_get_angle (label);
+
+      if (0 == angle || 180 == angle)
+        features |= GTK_EXTENDED_LAYOUT_HEIGHT_FOR_WIDTH;
+      else if (90 == angle || 270 == angle)
+        features |= GTK_EXTENDED_LAYOUT_WIDTH_FOR_HEIGHT;
+    }
+
+  return features;
+}
+
+static gint
+gtk_label_extended_layout_get_size_for_allocation (GtkExtendedLayout *layout,
+                                                   gint               size)
+{
+  GtkLabel *label = GTK_LABEL (layout);
+  gdouble angle = gtk_label_get_angle (label);
+  PangoLayout *tmp;
+
+  /* this test is slightly more tolerant than the get_features test */
+  g_assert (0 == (((gint)angle) % 90));
+
+  gtk_label_ensure_layout (label);
+  tmp = pango_layout_copy (label->layout);
+  pango_layout_set_width (tmp, PANGO_SCALE * size);
+  pango_layout_get_pixel_size (tmp, NULL, &size);
+  g_object_unref (tmp);
+
+  return size;
+}
+
+static void
+gtk_label_extended_layout_get_natural_size (GtkExtendedLayout *layout,
+                                            GtkRequisition    *requisition)
+{
+  GtkLabel *label;
+  gboolean ellipsize;
+  PangoLayout *tmp;
+
+  label = GTK_LABEL (layout);
+  gtk_label_ensure_layout (label);
+
+  ellipsize = label->ellipsize;
+  label->ellipsize = PANGO_ELLIPSIZE_NONE;
+
+  tmp = label->layout;
+  label->layout = pango_layout_copy (tmp);
+
+  pango_layout_set_width (label->layout, -1);
+  gtk_label_size_request (GTK_WIDGET (label), requisition);
+
+  g_object_unref (label->layout);
+  label->ellipsize = ellipsize;
+  label->layout = tmp;
+}
+
+static gint
+gtk_label_extended_layout_get_baselines (GtkExtendedLayout  *layout,
+                                         gint              **baselines)
+{
+  GtkLabel *label;
+  gint num_lines;
+  GSList *lines;
+
+  label = GTK_LABEL (layout);
+  gtk_label_ensure_layout (label);
+  lines = pango_layout_get_lines_readonly (label->layout);
+  num_lines = g_slist_length (lines);
+
+  if (baselines)
+    {
+      PangoRectangle log;
+      gint *baseptr;
+      gint offset;
+
+      get_layout_location (label, NULL, &offset);
+      offset -= GTK_WIDGET (label)->allocation.y;
+
+      *baselines = baseptr = g_new (gint, num_lines);
+
+      for (; lines; lines = lines->next, ++baseptr, offset += log.height)
+        {
+          pango_layout_line_get_pixel_extents (lines->data, NULL, &log);
+          *baseptr = offset + PANGO_ASCENT (log);
+        }
+    }
+
+  return num_lines;
+}
+
+static void
+gtk_label_extended_layout_set_baseline_offset (GtkExtendedLayout *layout,
+                                               gint               offset)
+{
+  GTK_LABEL_GET_PRIVATE (layout)->baseline_offset = offset;
+}
+
+static void
+gtk_label_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_label_extended_layout_get_features;
+  iface->get_height_for_width = gtk_label_extended_layout_get_size_for_allocation;
+  iface->get_width_for_height = gtk_label_extended_layout_get_size_for_allocation;
+  iface->get_natural_size = gtk_label_extended_layout_get_natural_size;
+  iface->get_baselines = gtk_label_extended_layout_get_baselines;
+  iface->set_baseline_offset = gtk_label_extended_layout_set_baseline_offset;
+}
+
 #define __GTK_LABEL_C__
 #include "gtkaliasdef.c"
