Index: gtk+/gtk/gtkhscale.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkhscale.c,v
retrieving revision 1.43
diff -u -p -r1.43 gtkhscale.c
--- gtk+/gtk/gtkhscale.c	4 Oct 2002 22:49:28 -0000	1.43
+++ gtk+/gtk/gtkhscale.c	5 Mar 2003 16:04:16 -0000
@@ -36,6 +36,13 @@ static void     gtk_hscale_class_init   
 static void     gtk_hscale_init             (GtkHScale      *hscale);
 static gboolean gtk_hscale_expose           (GtkWidget      *widget,
                                              GdkEventExpose *event);
+static void     gtk_hscale_get_text_offsets (GtkScale       *scale,
+                                             gint           *x,
+                                             gint           *y);
+static gboolean gtk_hscale_do_get_offsets   (GtkWidget      *widget,
+                                             PangoLayout    *layout,
+                                             gint           *x,
+                                             gint           *y);
 
 GType
 gtk_hscale_get_type (void)
@@ -69,13 +76,17 @@ gtk_hscale_class_init (GtkHScaleClass *c
 {
   GtkWidgetClass *widget_class;
   GtkRangeClass *range_class;
+  GtkScaleClass *scale_class;
   
   widget_class = GTK_WIDGET_CLASS (class);
   range_class = GTK_RANGE_CLASS (class);
+  scale_class = GTK_SCALE_CLASS (class);
 
   parent_class = g_type_class_peek_parent (class);
 
   range_class->slider_detail = "hscale";
+
+  scale_class->get_text_offsets = gtk_hscale_get_text_offsets;
   
   widget_class->expose_event = gtk_hscale_expose;
 }
@@ -145,13 +156,9 @@ static gboolean
 gtk_hscale_expose (GtkWidget      *widget,
                    GdkEventExpose *event)
 {
-  GtkRange *range;
-  GtkHScale *hscale;
   GtkScale *scale;
   
-  range = GTK_RANGE (widget);
   scale = GTK_SCALE (widget);
-  hscale = GTK_HSCALE (widget);
 
   /* We need to chain up _first_ so the various geometry members of
    * GtkRange struct are updated.
@@ -162,58 +169,19 @@ gtk_hscale_expose (GtkWidget      *widge
   if (scale->draw_value)
     {
       PangoLayout *layout;
-      PangoRectangle logical_rect;
       gchar *txt;
       gint x, y;
       GtkStateType state_type;
-      gint value_spacing;
 
-      gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
-      
       txt = _gtk_scale_format_value (scale,
                                      GTK_RANGE (scale)->adjustment->value);
       
       layout = gtk_widget_create_pango_layout (widget, txt);
       g_free (txt);
       
-      pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-      
-      switch (scale->value_pos)
-        {
-        case GTK_POS_LEFT:
-          x = range->range_rect.x - value_spacing - logical_rect.width;
-          y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
-          break;
-          
-        case GTK_POS_RIGHT:
-          x = range->range_rect.x + range->range_rect.width + value_spacing;
-          y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
-          break;
-          
-        case GTK_POS_TOP:
-          x = range->slider_start +
-            (range->slider_end - range->slider_start - logical_rect.width) / 2;
-          x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
-          y = range->range_rect.y - logical_rect.height - value_spacing;
-          break;
-          
-        case GTK_POS_BOTTOM:
-          x = range->slider_start +
-            (range->slider_end - range->slider_start - logical_rect.width) / 2;
-          x = CLAMP (x, 0, widget->allocation.width - logical_rect.width);
-          y = range->range_rect.y + range->range_rect.height + value_spacing;
-          break;
-
-        default:
-          g_return_val_if_reached (FALSE);
-          x = 0;
-          y = 0;
-          break;
-        }
+      if (!gtk_hscale_do_get_offsets (widget, layout, &x, &y))
+        return FALSE;
 
-      x += widget->allocation.x;
-      y += widget->allocation.y;
-      
       state_type = GTK_STATE_NORMAL;
       if (!GTK_WIDGET_IS_SENSITIVE (scale))
         state_type = GTK_STATE_INSENSITIVE;
@@ -232,4 +200,91 @@ gtk_hscale_expose (GtkWidget      *widge
     }
   
   return FALSE;
+}
+
+static void     
+gtk_hscale_get_text_offsets (GtkScale *scale,
+                             gint     *x,
+                             gint     *y)
+{
+  if (scale->draw_value)
+    {
+      GtkWidget *widget;
+      GtkRange *range;
+      PangoLayout *layout;
+      gchar *txt;
+
+      widget = GTK_WIDGET (scale);
+      
+      txt = _gtk_scale_format_value (scale,
+                                     GTK_RANGE (scale)->adjustment->value);
+      
+      layout = gtk_widget_create_pango_layout (widget, txt);
+      g_free (txt);
+      
+      gtk_hscale_do_get_offsets (widget, layout, x, y);
+      g_object_unref (layout);
+    }
+  else
+    {
+      *x = 0;
+      *y = 0;
+    }
+}
+
+static gboolean
+gtk_hscale_do_get_offsets (GtkWidget   *widget,
+                           PangoLayout *layout,
+                           gint           *x,
+                           gint           *y)
+{
+  GtkRange *range;
+  GtkScale *scale;
+  PangoRectangle logical_rect;
+  gint value_spacing;
+
+  gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
+
+  range = GTK_RANGE (widget);
+  scale = GTK_SCALE (widget);
+
+  pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+      
+  switch (scale->value_pos)
+    {
+     case GTK_POS_LEFT:
+       *x = range->range_rect.x - value_spacing - logical_rect.width;
+       *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
+       break;
+          
+    case GTK_POS_RIGHT:
+      *x = range->range_rect.x + range->range_rect.width + value_spacing;
+      *y = range->range_rect.y + (range->range_rect.height - logical_rect.height) / 2;
+      break;
+          
+    case GTK_POS_TOP:
+      *x = range->slider_start +
+        (range->slider_end - range->slider_start - logical_rect.width) / 2;
+      *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width);
+      *y = range->range_rect.y - logical_rect.height - value_spacing;
+      break;
+          
+    case GTK_POS_BOTTOM:
+      *x = range->slider_start +
+        (range->slider_end - range->slider_start - logical_rect.width) / 2;
+      *x = CLAMP (*x, 0, widget->allocation.width - logical_rect.width);
+      *y = range->range_rect.y + range->range_rect.height + value_spacing;
+      break;
+
+    default:
+      g_return_val_if_reached (FALSE);
+      *x = 0;
+      *y = 0;
+      break;
+    }
+
+  *x += widget->allocation.x;
+  *y += widget->allocation.y;
+      
+  return TRUE;
 }
Index: gtk+/gtk/gtkscale.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkscale.c,v
retrieving revision 1.38
diff -u -p -r1.38 gtkscale.c
--- gtk+/gtk/gtkscale.c	4 Oct 2002 22:49:28 -0000	1.38
+++ gtk+/gtk/gtkscale.c	5 Mar 2003 16:04:16 -0000
@@ -618,3 +618,76 @@ _gtk_scale_format_value (GtkScale *scale
     return g_strdup_printf ("%0.*f", scale->digits,
                             value);
 }
+
+/**
+ * gtk_scale_get_text:
+ * @scale: a #GtkScale
+ *
+ * Fetches the text from a scale widget as displayed on the screen.
+ *
+ * Return value: the text of the scale widget. This string is
+ *   not owned by the widget and must be freed after use.
+ **/
+gchar*
+gtk_scale_get_text (GtkScale *scale)
+{
+  if (scale->draw_value)
+    return _gtk_scale_format_value (scale,
+                                    GTK_RANGE (scale)->adjustment->value);
+  else
+    return NULL;
+}
+
+/**
+ * gtk_scale_get_layout:
+ * @label: a #GtkScale
+ *
+ * Gets the #PangoLayout used to display the scale.
+ * The returned layout is not owned by the scale so needs to be
+ * freed by the caller.
+ *
+ * Return value: the #PangoLayout for this scale
+ **/
+PangoLayout*
+gtk_scale_get_text_layout (GtkScale *scale)
+{
+  if (scale->draw_value)
+    {
+      PangoLayout *layout;
+      gchar *txt;
+
+      layout = gtk_widget_create_pango_layout (GTK_WIDGET (scale), NULL);
+      txt = _gtk_scale_format_value (scale,
+                                     GTK_RANGE (scale)->adjustment->value);
+      pango_layout_set_text (layout, txt, -1);
+      g_free (txt);
+
+      return layout;
+    }
+  else
+    return NULL;
+}
+
+void
+gtk_scale_get_text_offsets (GtkScale *scale,
+                            gint     *x,
+                            gint     *y)
+{
+  gint *real_x, *real_y;
+  gint local_x, local_y;
+
+  if (x)
+    real_x = x;
+  else
+    real_x = &local_x;
+
+  if (y)
+    real_y = y;
+  else
+    real_y = &local_y;
+  
+  if (GTK_SCALE_GET_CLASS (scale)->get_text_offsets)
+    (GTK_SCALE_GET_CLASS (scale)->get_text_offsets) (scale, real_x, real_y);
+}
+
+
Index: gtk+/gtk/gtkscale.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkscale.h,v
retrieving revision 1.20
diff -u -p -r1.20 gtkscale.h
--- gtk+/gtk/gtkscale.h	4 Oct 2002 22:49:28 -0000	1.20
+++ gtk+/gtk/gtkscale.h	5 Mar 2003 16:04:16 -0000
@@ -66,8 +66,10 @@ struct _GtkScaleClass
   
   void (* draw_value) (GtkScale *scale);
 
+  void (* get_text_offsets) (GtkScale *scale,
+                             gint     *x,
+                             gint     *y);
   /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
@@ -85,6 +87,11 @@ void            gtk_scale_set_value_pos 
                                           GtkPositionType  pos);
 GtkPositionType gtk_scale_get_value_pos  (GtkScale        *scale);
 
+gchar           *gtk_scale_get_text        (GtkScale        *scale);
+void            gtk_scale_get_text_offsets (GtkScale        *scale,
+                                            gint            *x,
+                                            gint            *y);
+PangoLayout     *gtk_scale_get_text_layout (GtkScale       *scale);
 
 void    _gtk_scale_get_value_size  (GtkScale        *scale,
                                     gint            *width,
Index: gtk+/gtk/gtkvscale.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkvscale.c,v
retrieving revision 1.42
diff -u -p -r1.42 gtkvscale.c
--- gtk+/gtk/gtkvscale.c	4 Oct 2002 22:49:28 -0000	1.42
+++ gtk+/gtk/gtkvscale.c	5 Mar 2003 16:04:16 -0000
@@ -38,6 +38,13 @@ static void     gtk_vscale_class_init   
 static void     gtk_vscale_init             (GtkVScale      *vscale);
 static gboolean gtk_vscale_expose           (GtkWidget      *widget,
                                              GdkEventExpose *event);
+static void	gtk_vscale_get_text_offsets (GtkScale	    *scale,
+                                             gint	    *x,
+                                             gint	    *y);
+static gboolean	gtk_vscale_do_get_offsets   (GtkWidget	    *widget,
+                                             PangoLayout    *layout,
+                                             gint	    *x,
+                                             gint	    *y);
 
 GType
 gtk_vscale_get_type (void)
@@ -71,14 +78,18 @@ gtk_vscale_class_init (GtkVScaleClass *c
 {
   GtkWidgetClass *widget_class;
   GtkRangeClass *range_class;
+  GtkScaleClass *scale_class;
   
   widget_class = GTK_WIDGET_CLASS (class);
   range_class = GTK_RANGE_CLASS (class); 
+  scale_class = GTK_SCALE_CLASS (class); 
 
   parent_class = g_type_class_peek_parent (class);
 
   range_class->slider_detail = "vscale";
   
+  scale_class->get_text_offsets = gtk_vscale_get_text_offsets;
+
   widget_class->expose_event = gtk_vscale_expose;
 }
 
@@ -147,13 +158,9 @@ static gboolean
 gtk_vscale_expose (GtkWidget      *widget,
                    GdkEventExpose *event)
 {
-  GtkRange *range;
-  GtkVScale *vscale;
   GtkScale *scale;
   
-  range = GTK_RANGE (widget);
   scale = GTK_SCALE (widget);
-  vscale = GTK_VSCALE (widget);
   
   /* We need to chain up _first_ so the various geometry members of
    * GtkRange struct are updated.
@@ -164,13 +171,10 @@ gtk_vscale_expose (GtkWidget      *widge
   if (scale->draw_value)
     {
       PangoLayout *layout;
-      PangoRectangle logical_rect;
       gchar *txt;
       gint x, y;
       GtkStateType state_type;
-      gint value_spacing;
 
-      gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
       
       txt = _gtk_scale_format_value (scale,
                                      GTK_RANGE (scale)->adjustment->value);
@@ -178,42 +182,9 @@ gtk_vscale_expose (GtkWidget      *widge
       layout = gtk_widget_create_pango_layout (widget, txt);
       g_free (txt);
       
-      pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
-      
-      switch (scale->value_pos)
-        {
-        case GTK_POS_LEFT:
-          x = range->range_rect.x - logical_rect.width - value_spacing;
-          y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
-          y = CLAMP (y, 0, widget->allocation.height - logical_rect.height);
-          break;
-          
-        case GTK_POS_RIGHT:
-          x = range->range_rect.x + range->range_rect.width + value_spacing;
-          y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
-          y = CLAMP (y, 0, widget->allocation.height - logical_rect.height);
-          break;
-          
-        case GTK_POS_TOP:
-          x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
-          y = range->range_rect.y - logical_rect.height - value_spacing;
-          break;
-          
-        case GTK_POS_BOTTOM:
-          x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
-          y = range->range_rect.y + range->range_rect.height + value_spacing;
-          break;
-
-        default:
-          g_return_val_if_reached (FALSE);
-          x = 0;
-          y = 0;
-          break;
-        }
-      
-      x += widget->allocation.x;
-      y += widget->allocation.y;
-      
+      if (!gtk_vscale_do_get_offsets (widget, layout, &x, &y))
+         return FALSE;
+
       state_type = GTK_STATE_NORMAL;
       if (!GTK_WIDGET_IS_SENSITIVE (scale))
         state_type = GTK_STATE_INSENSITIVE;
@@ -232,4 +203,92 @@ gtk_vscale_expose (GtkWidget      *widge
     }
   
   return FALSE;
+
 }
+
+static void
+gtk_vscale_get_text_offsets (GtkScale *scale,
+                             gint     *x,
+                             gint     *y)
+{
+  if (scale->draw_value)
+    {
+      GtkWidget *widget;
+      PangoLayout *layout;
+      gchar *txt;
+      GtkStateType state_type;
+
+      widget = GTK_WIDGET (scale);
+
+      txt = _gtk_scale_format_value (scale,
+                                     GTK_RANGE (scale)->adjustment->value);
+      
+      layout = gtk_widget_create_pango_layout (widget, txt);
+      g_free (txt);
+      
+      gtk_vscale_do_get_offsets (widget, layout, x, y);
+      
+      g_object_unref (layout);
+    }
+  else
+    {
+      *x = 0;
+      *y = 0;
+    }
+}
+
+static gboolean
+gtk_vscale_do_get_offsets (GtkWidget   *widget,
+                           PangoLayout *layout,
+                           gint        *x,
+                           gint	       *y)
+{
+  GtkRange *range;
+  GtkScale *scale;
+  PangoRectangle logical_rect;
+  gint value_spacing;
+
+  range = GTK_RANGE (widget);
+  scale = GTK_SCALE (widget);
+
+  gtk_widget_style_get (widget, "value_spacing", &value_spacing, NULL);
+      
+  pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+    
+  switch (scale->value_pos)
+    {
+    case GTK_POS_LEFT:
+      *x = range->range_rect.x - logical_rect.width - value_spacing;
+      *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
+      *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height);
+      break;
+      
+    case GTK_POS_RIGHT:
+      *x = range->range_rect.x + range->range_rect.width + value_spacing;
+      *y = range->slider_start + (range->slider_end - range->slider_start - logical_rect.height) / 2;
+      *y = CLAMP (*y, 0, widget->allocation.height - logical_rect.height);
+      break;
+          
+    case GTK_POS_TOP:
+      *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
+      *y = range->range_rect.y - logical_rect.height - value_spacing;
+      break;
+          
+    case GTK_POS_BOTTOM:
+      *x = range->range_rect.x + (range->range_rect.width - logical_rect.width) / 2;
+      *y = range->range_rect.y + range->range_rect.height + value_spacing;
+      break;
+
+    default:
+      g_return_val_if_reached (FALSE);
+      *x = 0;
+      *y = 0;
+      break;
+    }
+
+  *x += widget->allocation.x;
+  *y += widget->allocation.y;
+      
+  return TRUE;
+}
+
