Index: vectors/gimpvectors-warp.c
===================================================================
RCS file: vectors/gimpvectors-warp.c
diff -N vectors/gimpvectors-warp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ vectors/gimpvectors-warp.c	8 Mar 2005 15:50:21 -0000
@@ -0,0 +1,162 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpvectors-warp.c
+ * Copyright (C) 2005 Bill Skaggs  <weskaggs@primate.ucdavis.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib-object.h>
+
+#include "vectors-types.h"
+
+#include "core/gimp-utils.h"
+#include "core/gimpcoords.h"
+
+#include "gimpanchor.h"
+#include "gimpstroke.h"
+#include "gimpvectors.h"
+
+#define EPSILON 0.2
+#define DX      2.0
+
+static void gimp_stroke_warp_point   (const GimpStroke  *stroke,
+                                      gdouble            x,
+                                      gdouble            y,
+                                      GimpCoords        *point_warped,
+                                      gdouble            y_offset);
+
+static void gimp_vectors_warp_stroke (const GimpVectors *vectors,
+                                      GimpStroke        *stroke,
+                                      gdouble            y_offset);
+
+void
+gimp_vectors_warp_point (const GimpVectors *vectors,
+                         GimpCoords        *point,
+                         GimpCoords        *point_warped,
+                         gdouble            y_offset)
+{
+  gdouble     x      = point->x;
+  gdouble     y      = point->y;
+  gdouble     len;
+  GList      *list;
+  GimpStroke *stroke;
+
+  for (list = vectors->strokes; list; list = g_list_next (list))
+    {
+      stroke = list->data;
+
+      len = gimp_vectors_stroke_get_length (vectors, stroke);
+
+      if (x < len)
+        break;
+
+      x -= len;
+    }
+
+  if (! list)
+    {
+      point_warped->x = 0;
+      point_warped->y = 0;
+      return;
+    }
+
+  gimp_stroke_warp_point (stroke, x, y, point_warped, y_offset);
+}
+
+
+static void
+gimp_stroke_warp_point (const GimpStroke *stroke,
+                        gdouble           x,
+                        gdouble           y,
+                        GimpCoords       *point_warped,
+                        gdouble           y_offset)
+{
+  GimpCoords *point_zero;
+  GimpCoords *point_minus;
+  GimpCoords *point_plus;
+  gdouble     slope;
+  gdouble     dx, dy, nx, ny, len;
+
+  point_zero  = (GimpCoords*) g_new0 (GimpCoords, 1);
+  point_minus = (GimpCoords*) g_new0 (GimpCoords, 1);
+  point_plus  = (GimpCoords*) g_new0 (GimpCoords, 1);
+
+  if (! gimp_stroke_get_point_at_dist (stroke, x, EPSILON, point_zero,  &slope))
+    {
+      point_warped->x = 0;
+      point_warped->y = 0;
+      return;
+    }
+
+  point_warped->x = point_zero->x;
+  point_warped->y = point_zero->y;
+
+  if (!  gimp_stroke_get_point_at_dist (stroke, x - DX, EPSILON, point_minus, &slope))
+    return;
+
+  if (! gimp_stroke_get_point_at_dist (stroke, x + DX, EPSILON, point_plus,  &slope))
+    return;
+
+  dx = point_plus->x - point_minus->x;
+  dy = point_plus->y - point_minus->y;
+
+  len = hypot (dx, dy);
+
+  if (len < 0.01)
+    return;
+
+  nx = - dy / len;
+  ny =   dx / len;
+
+  point_warped->x = point_zero->x + nx * (y - y_offset);
+  point_warped->y = point_zero->y + ny * (y - y_offset);
+}
+
+static void
+gimp_vectors_warp_stroke (const GimpVectors *vectors,
+                          GimpStroke        *stroke,
+                          gdouble            y_offset)
+{
+  GList *list;
+
+  for (list = stroke->anchors; list; list = g_list_next (list))
+    {
+      GimpAnchor *anchor = list->data;
+
+      gimp_vectors_warp_point (vectors,
+                               &anchor->position, &anchor->position,
+                               y_offset);
+    }
+}
+
+void
+gimp_vectors_warp_vectors (const GimpVectors *vectors,
+                           GimpVectors       *vectors_in,
+                           gdouble            y_offset)
+{
+  GList *list;
+
+  for (list = vectors_in->strokes; list; list = g_list_next (list))
+    {
+      GimpStroke *stroke = list->data;
+
+      gimp_vectors_warp_stroke (vectors, stroke, y_offset);
+    }
+}
+
Index: vectors/gimpvectors-warp.h
===================================================================
RCS file: vectors/gimpvectors-warp.h
diff -N vectors/gimpvectors-warp.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ vectors/gimpvectors-warp.h	8 Mar 2005 15:50:21 -0000
@@ -0,0 +1,36 @@
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * gimpvectors-warp.h
+ * Copyright (C) 2005 Bill Skaggs  <weskaggs@primate.ucdavis.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GIMP_VECTORS_WARP_H__
+#define __GIMP_VECTORS_WARP_H__
+
+void gimp_vectors_warp_point   (const GimpVectors *vectors,
+                                GimpCoords        *point,
+                                GimpCoords        *point_warped,
+                                gdouble            y_offset);
+
+
+void gimp_vectors_warp_vectors (const GimpVectors *vectors,
+                                GimpVectors       *vectors_in,
+                                gdouble            yoffset);
+
+#endif /* __GIMP_VECTORS_WARP_H__ */
+
Index: tools/gimptextoptions.c
===================================================================
RCS file: /cvs/gnome/gimp/app/tools/gimptextoptions.c,v
retrieving revision 1.56
diff -u -p -r1.56 gimptextoptions.c
--- tools/gimptextoptions.c	2 Mar 2005 12:54:54 -0000	1.56
+++ tools/gimptextoptions.c	8 Mar 2005 15:50:21 -0000
@@ -501,6 +501,14 @@ gimp_text_options_gui (GimpToolOptions *
   g_object_set_data (G_OBJECT (tool_options),
                      "gimp-text-to-vectors", button);
 
+  button = gtk_button_new_with_label (_("Text along path"));
+  gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  gtk_widget_set_sensitive (button, FALSE);
+  gtk_widget_show (button);
+
+  g_object_set_data (G_OBJECT (tool_options),
+                     "gimp-text-to-vectors-warped", button);
+
   return vbox;
 }
 
Index: tools/gimptexttool.c
===================================================================
RCS file: /cvs/gnome/gimp/app/tools/gimptexttool.c,v
retrieving revision 1.248
diff -u -p -r1.248 gimptexttool.c
--- tools/gimptexttool.c	4 Mar 2005 19:05:40 -0000	1.248
+++ tools/gimptexttool.c	8 Mar 2005 15:50:21 -0000
@@ -54,6 +54,8 @@
 #include "widgets/gimptexteditor.h"
 #include "widgets/gimpviewabledialog.h"
 
+#include "vectors/gimpvectors-warp.h"
+
 #include "display/gimpdisplay.h"
 
 #include "gimpeditselectiontool.h"
@@ -106,6 +108,8 @@ static gboolean  gimp_text_tool_idle_app
 static void      gimp_text_tool_apply          (GimpTextTool      *text_tool);
 
 static void      gimp_text_tool_create_vectors (GimpTextTool      *text_tool);
+static void      gimp_text_tool_create_vectors_warped
+                                               (GimpTextTool      *text_tool);
 static void      gimp_text_tool_create_layer   (GimpTextTool      *text_tool,
                                                 GimpText          *text);
 
@@ -361,9 +365,11 @@ gimp_text_tool_connect (GimpTextTool  *t
     {
       GimpTextOptions *options;
       GtkWidget       *button;
+      GtkWidget       *button2;
 
       options = GIMP_TEXT_OPTIONS (tool->tool_info->tool_options);
-      button = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors");
+      button  = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors");
+      button2 = g_object_get_data (G_OBJECT (options), "gimp-text-to-vectors-warped");
 
       if (text_tool->text)
         {
@@ -382,6 +388,14 @@ gimp_text_tool_connect (GimpTextTool  *t
                                                     text_tool);
             }
 
+          if (button2)
+            {
+              gtk_widget_set_sensitive (button2, FALSE);
+              g_signal_handlers_disconnect_by_func (button2,
+                                                    gimp_text_tool_create_vectors_warped,
+                                                    text_tool);
+            }
+
           g_object_unref (text_tool->text);
           text_tool->text = NULL;
 
@@ -411,6 +425,14 @@ gimp_text_tool_connect (GimpTextTool  *t
               gtk_widget_set_sensitive (button, TRUE);
             }
 
+          if (button2)
+            {
+              g_signal_connect_swapped (button2, "clicked",
+                                        G_CALLBACK (gimp_text_tool_create_vectors_warped),
+                                        text_tool);
+              gtk_widget_set_sensitive (button2, TRUE);
+            }
+
           if (text_tool->editor)
             gimp_text_tool_editor_update (text_tool);
         }
@@ -653,6 +675,32 @@ gimp_text_tool_create_vectors (GimpTextT
       gimp_item_offsets (GIMP_ITEM (text_tool->layer), &x, &y);
       gimp_item_translate (GIMP_ITEM (vectors), x, y, FALSE);
     }
+
+  gimp_image_add_vectors (text_tool->image, vectors, -1);
+
+  gimp_image_flush (text_tool->image);
+}
+
+static void
+gimp_text_tool_create_vectors_warped (GimpTextTool *text_tool)
+{
+  GimpVectors   *vectors0;
+  GimpVectors   *vectors;
+  GimpText      *text      = text_tool->text;
+  gdouble        box_height;
+
+  if (! text || ! text_tool->image || ! text_tool->layer)
+    return;
+
+  box_height = gimp_item_height (GIMP_ITEM (text_tool->layer));
+
+  vectors0 = gimp_image_get_active_vectors (text_tool->image);
+  if (! vectors0)
+    return;
+
+  vectors = gimp_text_vectors_new (text_tool->image, text_tool->text);
+
+  gimp_vectors_warp_vectors (vectors0, vectors, 0.5 * box_height);
 
   gimp_image_add_vectors (text_tool->image, vectors, -1);
 
