gimp r27419 - in trunk: . app app/actions app/menus app/text app/tools app/widgets menus



Author: mitch
Date: Sun Oct 26 17:39:55 2008
New Revision: 27419
URL: http://svn.gnome.org/viewvc/gimp?rev=27419&view=rev

Log:
2008-10-26  Michael Natterer  <mitch gimp org>

	Merge on-canvas GSoC project:

	* configure.in: check for pangocairo.

	* app/Makefile.am
	* app/text/Makefile.am: add its CFLAGS and LIBS.

	* app/text/gimptext-bitmap.[ch]
	* app/text/gimptext-private.h
	* app/text/gimptext-vectors.[ch]
	* app/text/gimptextlayer.c
	* app/text/gimptextlayout-render.c
	* app/text/gimptextlayout.c: port to pangocairo.

	* menus/Makefile.am
	* menus/text-tool-menu.xml
	* app/menus/menus.c
	* app/actions/Makefile.am
	* app/actions/actions.c
	* app/actions/text-tool-actions.[ch]
	* app/actions/text-tool-commands.[ch]: add a context menu for the
	text tool similar to GtkEntry's context menu.

	* app/tools/gimprectangletool.[ch]: add "narrow-mode" property.

	* app/tools/gimptextoptions.[ch]
	* app/widgets/gimptexteditor.[ch]: take a text buffer for the
	standalone text editor window instead of creating one internally.

	* app/tools/gimptexttool.[ch]: all the new wonderful on-canvas
	text editing logic. Wheee!



Added:
   trunk/app/actions/text-tool-actions.c
   trunk/app/actions/text-tool-actions.h
   trunk/app/actions/text-tool-commands.c
   trunk/app/actions/text-tool-commands.h
   trunk/menus/text-tool-menu.xml
Modified:
   trunk/ChangeLog
   trunk/app/Makefile.am
   trunk/app/actions/Makefile.am
   trunk/app/actions/actions.c
   trunk/app/menus/menus.c
   trunk/app/text/Makefile.am
   trunk/app/text/gimptext-bitmap.c
   trunk/app/text/gimptext-bitmap.h
   trunk/app/text/gimptext-private.h
   trunk/app/text/gimptext-vectors.c
   trunk/app/text/gimptext-vectors.h
   trunk/app/text/gimptextlayer.c
   trunk/app/text/gimptextlayout-render.c
   trunk/app/text/gimptextlayout.c
   trunk/app/tools/gimprectangletool.c
   trunk/app/tools/gimprectangletool.h
   trunk/app/tools/gimptextoptions.c
   trunk/app/tools/gimptextoptions.h
   trunk/app/tools/gimptexttool.c
   trunk/app/tools/gimptexttool.h
   trunk/app/widgets/gimptexteditor.c
   trunk/app/widgets/gimptexteditor.h
   trunk/configure.in
   trunk/menus/Makefile.am

Modified: trunk/app/Makefile.am
==============================================================================
--- trunk/app/Makefile.am	(original)
+++ trunk/app/Makefile.am	Sun Oct 26 17:39:55 2008
@@ -90,6 +90,7 @@
 	-I$(top_srcdir)		\
 	$(GTK_CFLAGS)		\
 	$(PANGOFT2_CFLAGS)	\
+	$(PANGOCAIRO_CFLAGS)	\
 	$(DBUS_GLIB_CFLAGS)	\
 	$(GEGL_CFLAGS)		\
 	-I$(includedir)
@@ -137,6 +138,7 @@
 	$(libgimpbase)			\
 	$(GTK_LIBS)			\
 	$(PANGOFT2_LIBS)		\
+	$(PANGOCAIRO_LIBS)		\
 	$(FONTCONFIG_LIBS)		\
 	$(FREETYPE_LIBS)		\
 	$(DBUS_GLIB_LIBS)		\
@@ -181,6 +183,7 @@
 	$(GDK_PIXBUF_LIBS)		\
 	$(CAIRO_LIBS)			\
 	$(PANGOFT2_LIBS)		\
+	$(PANGOCAIRO_LIBS)		\
 	$(FONTCONFIG_LIBS)		\
 	$(FREETYPE_LIBS)		\
 	$(GEGL_LIBS)			\

Modified: trunk/app/actions/Makefile.am
==============================================================================
--- trunk/app/actions/Makefile.am	(original)
+++ trunk/app/actions/Makefile.am	Sun Oct 26 17:39:55 2008
@@ -149,6 +149,10 @@
 	text-editor-actions.h		\
 	text-editor-commands.c		\
 	text-editor-commands.h		\
+	text-tool-actions.c		\
+	text-tool-actions.h		\
+	text-tool-commands.c		\
+	text-tool-commands.h		\
 	tool-options-actions.c		\
 	tool-options-actions.h		\
 	tool-options-commands.c		\

Modified: trunk/app/actions/actions.c
==============================================================================
--- trunk/app/actions/actions.c	(original)
+++ trunk/app/actions/actions.c	Sun Oct 26 17:39:55 2008
@@ -81,6 +81,7 @@
 #include "select-actions.h"
 #include "templates-actions.h"
 #include "text-editor-actions.h"
+#include "text-tool-actions.h"
 #include "tool-options-actions.h"
 #include "tools-actions.h"
 #include "vectors-actions.h"
@@ -195,6 +196,9 @@
   { "templates", N_("Templates"), GIMP_STOCK_TEMPLATE,
     templates_actions_setup,
     templates_actions_update },
+  { "text-tool", N_("Text Tool"), GTK_STOCK_EDIT,
+    text_tool_actions_setup,
+    text_tool_actions_update },
   { "text-editor", N_("Text Editor"), GTK_STOCK_EDIT,
     text_editor_actions_setup,
     text_editor_actions_update },

Added: trunk/app/actions/text-tool-actions.c
==============================================================================
--- (empty file)
+++ trunk/app/actions/text-tool-actions.c	Sun Oct 26 17:39:55 2008
@@ -0,0 +1,172 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "actions-types.h"
+
+#include "core/gimpdrawable.h"
+#include "core/gimpimage.h"
+
+#include "widgets/gimpactiongroup.h"
+#include "widgets/gimptexteditor.h"
+#include "widgets/gimphelp-ids.h"
+
+#include "display/gimpdisplay.h"
+
+#include "tools/gimptool.h"
+#include "tools/gimptexttool.h"
+
+#include "text-tool-actions.h"
+#include "text-tool-commands.h"
+
+#include "gimp-intl.h"
+
+
+static const GimpActionEntry text_tool_actions[] =
+{
+  { "text-tool-popup", NULL,
+    N_("Text Tool Popup"), NULL, NULL, NULL,
+    NULL },
+
+  { "text-tool-cut", GTK_STOCK_CUT,
+    N_("Cut"), NULL, NULL,
+    G_CALLBACK (text_tool_cut_cmd_callback),
+    NULL },
+
+  { "text-tool-copy", GTK_STOCK_COPY,
+    N_("Copy"), NULL, NULL,
+    G_CALLBACK (text_tool_copy_cmd_callback),
+    NULL },
+
+  { "text-tool-paste", GTK_STOCK_PASTE,
+    N_("Paste"), NULL, NULL,
+    G_CALLBACK (text_tool_paste_cmd_callback),
+    NULL },
+
+  { "text-tool-delete", GTK_STOCK_DELETE,
+    N_("Delete selected"), NULL, NULL,
+    G_CALLBACK (text_tool_delete_cmd_callback),
+    NULL },
+
+  { "text-tool-load", GTK_STOCK_OPEN,
+    N_("Open"), NULL,
+    N_("Load text from file"),
+    G_CALLBACK (text_tool_load_cmd_callback),
+    NULL },
+
+  { "text-tool-clear", GTK_STOCK_CLEAR,
+    N_("Clear"), "",
+    N_("Clear all text"),
+    G_CALLBACK (text_tool_clear_cmd_callback),
+    NULL },
+
+  { "text-tool-path-from-text", GIMP_STOCK_PATH,
+    N_("Path from Text"), "",
+    N_("Create a path from the outlines of the current text"),
+    G_CALLBACK (text_tool_path_from_text_callback),
+    NULL },
+
+  { "text-tool-input-methods", NULL,
+    N_("Input Methods"), NULL, NULL, NULL,
+    NULL }
+};
+
+static const GimpRadioActionEntry text_tool_direction_actions[] =
+{
+  { "text-tool-direction-ltr", GIMP_STOCK_TEXT_DIR_LTR,
+    N_("LTR"), "",
+    N_("From left to right"),
+    GIMP_TEXT_DIRECTION_LTR,
+    NULL },
+
+  { "text-tool-direction-rtl", GIMP_STOCK_TEXT_DIR_RTL,
+    N_("RTL"), "",
+    N_("From right to left"),
+    GIMP_TEXT_DIRECTION_RTL,
+    NULL }
+};
+
+
+void
+text_tool_actions_setup (GimpActionGroup *group)
+{
+  gimp_action_group_add_actions (group,
+                                 text_tool_actions,
+                                 G_N_ELEMENTS (text_tool_actions));
+
+  gimp_action_group_add_radio_actions (group,
+                                       text_tool_direction_actions,
+                                       G_N_ELEMENTS (text_tool_direction_actions),
+                                       NULL,
+                                       GIMP_TEXT_DIRECTION_LTR,
+                                       G_CALLBACK (text_tool_direction_cmd_callback));
+}
+
+/*
+ * The following code is written on the assumption that this is for a context
+ * menu, activated by right-clicking in a text layer.  Therefore, the tool
+ * must have a display.  If for any reason the code is adapted to a different
+ * situation, some existence testing will need to be added.
+ */
+void
+text_tool_actions_update (GimpActionGroup *group,
+                          gpointer         data)
+{
+  GimpTextTool  *text_tool  = GIMP_TEXT_TOOL (data);
+  GimpImage     *image      = GIMP_TOOL (text_tool)->display->image;
+  GimpLayer     *layer;
+  GtkClipboard  *clipboard;
+  gboolean       text_layer = FALSE;
+  gboolean       text_sel   = FALSE;   /* some text is selected        */
+  gboolean       clip       = FALSE;   /* clipboard has text available */
+
+  layer = gimp_image_get_active_layer (image);
+
+  if (layer)
+    text_layer = gimp_drawable_is_text_layer (GIMP_DRAWABLE (layer));
+
+  text_sel = gimp_text_tool_get_has_text_selection (text_tool);
+
+  /*
+   * see whether there is text available for pasting
+   */
+  clipboard = gtk_widget_get_clipboard (GIMP_TOOL (text_tool)->display->shell,
+                                        GDK_SELECTION_PRIMARY);
+  clip = gtk_clipboard_wait_is_text_available (clipboard);
+
+#define SET_VISIBLE(action,condition) \
+        gimp_action_group_set_action_visible (group, action, (condition) != 0)
+#define SET_SENSITIVE(action,condition) \
+        gimp_action_group_set_action_sensitive (group, action, (condition) != 0)
+#define SET_ACTIVE(action,condition) \
+        gimp_action_group_set_action_active (group, action, (condition) != 0)
+
+  SET_SENSITIVE ("text-tool-cut",             text_sel);
+  SET_SENSITIVE ("text-tool-copy",            text_sel);
+  SET_SENSITIVE ("text-tool-paste",           clip);
+  SET_SENSITIVE ("text-tool-delete",          text_sel);
+  SET_SENSITIVE ("text-tool-clear",           text_layer);
+  SET_SENSITIVE ("text-tool-load",            image);
+  SET_SENSITIVE ("text-tool-path-from-text",  text_layer);
+}

Added: trunk/app/actions/text-tool-actions.h
==============================================================================
--- (empty file)
+++ trunk/app/actions/text-tool-actions.h	Sun Oct 26 17:39:55 2008
@@ -0,0 +1,28 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 __TEXT_TOOL_ACTIONS_H__
+#define __TEXT_TOOL_ACTIONS_H__
+
+
+void   text_tool_actions_setup  (GimpActionGroup *group);
+void   text_tool_actions_update (GimpActionGroup *group,
+                                 gpointer         data);
+
+
+#endif /* __TEXT_TOOL_ACTIONS_H__ */

Added: trunk/app/actions/text-tool-commands.c
==============================================================================
--- (empty file)
+++ trunk/app/actions/text-tool-commands.c	Sun Oct 26 17:39:55 2008
@@ -0,0 +1,206 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpwidgets/gimpwidgets.h"
+
+#include "actions-types.h"
+
+#include "core/gimp.h"
+
+#include "widgets/gimptexteditor.h"
+#include "widgets/gimphelp-ids.h"
+#include "widgets/gimpuimanager.h"
+#include "widgets/gimpwidgets-utils.h"
+
+#include "tools/gimptexttool.h"
+
+#include "text-tool-commands.h"
+
+#include "gimp-intl.h"
+
+
+/*  local function prototypes  */
+
+static void   text_tool_load_response (GtkWidget      *dialog,
+                                       gint            response_id,
+                                       GimpTextEditor *editor);
+
+
+/*  public functions  */
+
+void
+text_tool_cut_cmd_callback (GtkAction *action,
+                            gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+
+  gimp_text_tool_clipboard_cut (text_tool);
+}
+
+void
+text_tool_copy_cmd_callback (GtkAction *action,
+                             gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+
+  gimp_text_tool_clipboard_copy (text_tool, TRUE);
+}
+
+void
+text_tool_paste_cmd_callback (GtkAction *action,
+                              gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+
+  gimp_text_tool_clipboard_paste (text_tool, TRUE);
+}
+
+void
+text_tool_delete_cmd_callback (GtkAction *action,
+                               gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+
+  if (gtk_text_buffer_get_has_selection (text_tool->text_buffer))
+    gimp_text_tool_delete_text (text_tool);
+}
+
+void
+text_tool_load_cmd_callback (GtkAction *action,
+                             gpointer   data)
+{
+  GimpTextEditor *editor = GIMP_TEXT_EDITOR (data);
+  GtkFileChooser *chooser;
+
+  if (editor->file_dialog)
+    {
+      gtk_window_present (GTK_WINDOW (editor->file_dialog));
+      return;
+    }
+
+  editor->file_dialog =
+    gtk_file_chooser_dialog_new (_("Open Text File (UTF-8)"),
+                                 GTK_WINDOW (editor),
+                                 GTK_FILE_CHOOSER_ACTION_OPEN,
+
+                                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                 GTK_STOCK_OPEN,   GTK_RESPONSE_OK,
+
+                                 NULL);
+
+  chooser = GTK_FILE_CHOOSER (editor->file_dialog);
+
+  gtk_dialog_set_alternative_button_order (GTK_DIALOG (editor->file_dialog),
+                                           GTK_RESPONSE_OK,
+                                           GTK_RESPONSE_CANCEL,
+                                           -1);
+
+  g_object_add_weak_pointer (G_OBJECT (chooser),
+                             (gpointer) &editor->file_dialog);
+
+  gtk_window_set_role (GTK_WINDOW (chooser), "gimp-text-load-file");
+  gtk_window_set_position (GTK_WINDOW (chooser), GTK_WIN_POS_MOUSE);
+  gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
+
+  gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_OK);
+
+  g_signal_connect (chooser, "response",
+                    G_CALLBACK (text_tool_load_response),
+                    editor);
+  g_signal_connect (chooser, "delete-event",
+                    G_CALLBACK (gtk_true),
+                    NULL);
+
+  gtk_widget_show (GTK_WIDGET (chooser));
+}
+
+void
+text_tool_clear_cmd_callback (GtkAction *action,
+                              gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+  GtkTextIter   start, end;
+
+  gtk_text_buffer_get_bounds (text_tool->text_buffer, &start, &end);
+  gtk_text_buffer_select_range (text_tool->text_buffer, &start, &end);
+  gimp_text_tool_delete_text (text_tool);
+}
+
+void
+text_tool_path_from_text_callback (GtkAction *action,
+                                   gpointer   data)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (data);
+
+  gimp_text_tool_create_vectors (text_tool);
+}
+
+void
+text_tool_direction_cmd_callback (GtkAction *action,
+                                  GtkAction *current,
+                                  gpointer   data)
+{
+  GimpTextEditor *editor = GIMP_TEXT_EDITOR (data);
+  gint            value;
+
+  value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+
+  /*
+  gimp_text_tool_set_direction (editor, (GimpTextDirection) value);
+  */
+}
+
+
+/*  private functions  */
+
+static void
+text_tool_load_response (GtkWidget      *dialog,
+                           gint            response_id,
+                           GimpTextEditor *editor)
+{
+  if (response_id == GTK_RESPONSE_OK)
+    {
+      GtkTextBuffer *buffer;
+      gchar         *filename;
+      GError        *error = NULL;
+
+      buffer   = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->view));
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+      if (! gimp_text_buffer_load (buffer, filename, &error))
+        {
+          gimp_message (editor->ui_manager->gimp, G_OBJECT (dialog),
+                        GIMP_MESSAGE_ERROR,
+                        _("Could not open '%s' for reading: %s"),
+                        gimp_filename_to_utf8 (filename),
+                        error->message);
+          g_clear_error (&error);
+          g_free (filename);
+          return;
+        }
+
+      g_free (filename);
+    }
+
+  gtk_widget_destroy (dialog);
+}

Added: trunk/app/actions/text-tool-commands.h
==============================================================================
--- (empty file)
+++ trunk/app/actions/text-tool-commands.h	Sun Oct 26 17:39:55 2008
@@ -0,0 +1,42 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 __TEXT_TOOL_COMMANDS_H__
+#define __TEXT_TOOL_COMMANDS_H__
+
+
+void   text_tool_cut_cmd_callback        (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_copy_cmd_callback       (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_paste_cmd_callback      (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_delete_cmd_callback     (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_load_cmd_callback       (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_clear_cmd_callback      (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_path_from_text_callback (GtkAction *action,
+                                          gpointer   data);
+void   text_tool_direction_cmd_callback  (GtkAction *action,
+                                          GtkAction *current,
+                                          gpointer   data);
+
+
+#endif /* __TEXT_TOOL_COMMANDS_H__ */

Modified: trunk/app/menus/menus.c
==============================================================================
--- trunk/app/menus/menus.c	(original)
+++ trunk/app/menus/menus.c	Sun Oct 26 17:39:55 2008
@@ -340,6 +340,14 @@
                                       NULL,
                                       NULL);
 
+  gimp_menu_factory_manager_register (global_menu_factory, "<TextTool>",
+                                      "text-tool",
+                                      NULL,
+                                      "/text-tool-popup",
+                                      "text-tool-menu.xml",
+                                      NULL,
+                                      NULL);
+  
   gimp_menu_factory_manager_register (global_menu_factory, "<CursorInfo>",
                                       "cursor-info",
                                       NULL,

Modified: trunk/app/text/Makefile.am
==============================================================================
--- trunk/app/text/Makefile.am	(original)
+++ trunk/app/text/Makefile.am	Sun Oct 26 17:39:55 2008
@@ -10,6 +10,7 @@
 	-I$(top_srcdir)/app	\
 	$(GEGL_CFLAGS)		\
 	$(PANGOFT2_CFLAGS)	\
+	$(PANGOCAIRO_CFLAGS)	\
 	$(GDK_PIXBUF_CFLAGS)	\
 	-I$(includedir)
 

Modified: trunk/app/text/gimptext-bitmap.c
==============================================================================
--- trunk/app/text/gimptext-bitmap.c	(original)
+++ trunk/app/text/gimptext-bitmap.c	Sun Oct 26 17:39:55 2008
@@ -24,7 +24,8 @@
 #include <glib-object.h>
 
 #define PANGO_ENABLE_ENGINE
-#include <pango/pangoft2.h>
+#include <cairo.h>
+#include <pango/pangocairo.h>
 
 #include "text-types.h"
 
@@ -38,102 +39,33 @@
 
 
 void
-gimp_text_render_bitmap (PangoFont  *font,
-                         PangoGlyph  glyph,
-                         FT_Int32    flags,
-                         FT_Matrix  *trafo,
-                         gint        x,
-                         gint        y,
-                         FT_Bitmap  *bitmap)
+gimp_text_render_bitmap (PangoFont            *font,
+                         PangoGlyph            glyph,
+                         cairo_font_options_t *options,
+                         cairo_matrix_t       *trafo,
+                         gint                  x,
+                         gint                  y,
+                         cairo_t              *cr)
 {
-  FT_Face       face;
-  gint          y_start, y_limit, x_start, x_limit;
-  gint          ix, iy;
-  const guchar *src;
-  guchar       *dest;
-
-  face = pango_fc_font_lock_face (PANGO_FC_FONT (font));
-
-  FT_Set_Transform (face, trafo, NULL);
-
-  FT_Load_Glyph (face, (FT_UInt) glyph, flags);
-  FT_Render_Glyph (face->glyph,
-                   (flags & FT_LOAD_TARGET_MONO ?
-                    ft_render_mode_mono : ft_render_mode_normal));
+
+  cairo_scaled_font_t *cfont;
+  cairo_glyph_t        cglyph;
+
+  cfont = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font);
 
   x = PANGO_PIXELS (x);
   y = PANGO_PIXELS (y);
 
-  x_start = MAX (0, - (x + face->glyph->bitmap_left));
-  x_limit = MIN (face->glyph->bitmap.width,
-                 bitmap->width - (x + face->glyph->bitmap_left));
-
-  y_start = MAX (0,  - (y - face->glyph->bitmap_top));
-  y_limit = MIN (face->glyph->bitmap.rows,
-                 bitmap->rows - (y - face->glyph->bitmap_top));
-
-  src = face->glyph->bitmap.buffer + y_start * face->glyph->bitmap.pitch;
-
-  dest = bitmap->buffer +
-    (y_start + y - face->glyph->bitmap_top) * bitmap->pitch +
-    x_start + x + face->glyph->bitmap_left;
-
-  switch (face->glyph->bitmap.pixel_mode)
-    {
-    case ft_pixel_mode_grays:
-      src += x_start;
-      for (iy = y_start; iy < y_limit; iy++)
-        {
-          const guchar *s = src;
-          guchar       *d = dest;
-
-          for (ix = x_start; ix < x_limit; ix++)
-            {
-              switch (*s)
-                {
-                case 0:
-                  break;
-                case 0xff:
-                  *d = 0xff;
-                default:
-                  *d = MIN ((gushort) *d + (const gushort) *s, 0xff);
-                  break;
-                }
-
-              s++;
-              d++;
-            }
-
-          dest += bitmap->pitch;
-          src  += face->glyph->bitmap.pitch;
-        }
-      break;
-
-    case ft_pixel_mode_mono:
-      src += x_start / 8;
-      for (iy = y_start; iy < y_limit; iy++)
-        {
-          const guchar *s = src;
-          guchar       *d = dest;
-
-          for (ix = x_start; ix < x_limit; ix++)
-            {
-              if ((*s) & (1 << (7 - (ix % 8))))
-                *d |= 0xff;
-
-              if ((ix % 8) == 7)
-                s++;
-              d++;
-            }
-
-          dest += bitmap->pitch;
-          src  += face->glyph->bitmap.pitch;
-        }
-      break;
-
-    default:
-      break;
-    }
+  cglyph.x     = x;
+  cglyph.y     = y;
+  cglyph.index = glyph;
+
+  cairo_set_scaled_font (cr, cfont);
+  cairo_set_font_options (cr, options);
+
+  cairo_transform (cr, trafo);
+
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
 
-  pango_fc_font_unlock_face (PANGO_FC_FONT (font));
+  cairo_show_glyphs (cr, &cglyph, 1);
 }

Modified: trunk/app/text/gimptext-bitmap.h
==============================================================================
--- trunk/app/text/gimptext-bitmap.h	(original)
+++ trunk/app/text/gimptext-bitmap.h	Sun Oct 26 17:39:55 2008
@@ -23,13 +23,13 @@
 #define __GIMP_TEXT_BITMAP_H__
 
 
-void  gimp_text_render_bitmap (PangoFont  *font,
-                               PangoGlyph  glyph,
-                               FT_Int32    flags,
-                               FT_Matrix  *trafo,
-                               gint        x,
-                               gint        y,
-                               FT_Bitmap  *bitmap);
+void  gimp_text_render_bitmap (PangoFont            *font,
+                               PangoGlyph            glyph,
+                               cairo_font_options_t *options,
+                               cairo_matrix_t       *trafo,
+                               gint                  x,
+                               gint                  y,
+                               cairo_t              *cr);
 
 
 #endif /* __GIMP_TEXT_BITMAP_H__ */

Modified: trunk/app/text/gimptext-private.h
==============================================================================
--- trunk/app/text/gimptext-private.h	(original)
+++ trunk/app/text/gimptext-private.h	Sun Oct 26 17:39:55 2008
@@ -22,8 +22,9 @@
 #ifndef __GIMP_TEXT_LAYOUT_PRIVATE_H__
 #define __GIMP_TEXT_LAYOUT_PRIVATE_H__
 
+
 /*  The purpose of this extra header file is to hide any Pango or
- *  FreeType types from the rest of the gimp core.
+ *  Cairo types from the rest of the gimp core.
  */
 
 
@@ -44,13 +45,13 @@
 };
 
 
-typedef  void (* GimpTextRenderFunc) (PangoFont  *font,
-                                      PangoGlyph  glyph,
-                                      FT_Int32    load_flags,
-                                      FT_Matrix  *tranform,
-                                      gint        x,
-                                      gint        y,
-                                      gpointer    render_data);
+typedef  void (* GimpTextRenderFunc) (PangoFont            *font,
+                                      PangoGlyph            glyph,
+                                      cairo_font_options_t *options,
+                                      cairo_matrix_t       *tranform,
+                                      gint                  x,
+                                      gint                  y,
+                                      gpointer              render_data);
 
 
 #endif /* __GIMP_TEXT_LAYOUT_PRIVATE_H__ */

Modified: trunk/app/text/gimptext-vectors.c
==============================================================================
--- trunk/app/text/gimptext-vectors.c	(original)
+++ trunk/app/text/gimptext-vectors.c	Sun Oct 26 17:39:55 2008
@@ -1,7 +1,7 @@
 /* GIMP - The GNU Image Manipulation Program
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
- * GimpText
+ * GimpText-vectors
  * Copyright (C) 2003  Sven Neumann <sven gimp org>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -24,11 +24,9 @@
 #include <gegl.h>
 
 #define PANGO_ENABLE_ENGINE
-#include <pango/pangoft2.h>
+#include <cairo.h>
+#include <pango/pangocairo.h>
 
-#include <ft2build.h>
-#include FT_GLYPH_H
-#include FT_OUTLINE_H
 
 #include "text-types.h"
 
@@ -62,13 +60,13 @@
 };
 
 
-static void  gimp_text_render_vectors (PangoFont     *font,
-                                       PangoGlyph     glyph,
-                                       FT_Int32       flags,
-                                       FT_Matrix     *matrix,
-                                       gint           x,
-                                       gint           y,
-                                       RenderContext *context);
+static void  gimp_text_render_vectors (PangoFont            *font,
+                                       PangoGlyph            glyph,
+                                       cairo_font_options_t *options,
+                                       cairo_matrix_t       *cmatrix,
+                                       gint                  x,
+                                       gint                  y,
+                                       RenderContext        *context);
 
 
 GimpVectors *
@@ -108,11 +106,12 @@
 
 static inline void
 gimp_text_vector_coords (RenderContext   *context,
-                         const FT_Vector *vector,
+                         const double x,
+                         const double y,
                          GimpCoords      *coords)
 {
-  coords->x        = context->offset_x + (gdouble) vector->x / 64.0;
-  coords->y        = context->offset_y - (gdouble) vector->y / 64.0;
+  coords->x        = context->offset_x + (gdouble) x;
+  coords->y        = context->offset_y + (gdouble) y;
   coords->pressure = GIMP_COORDS_DEFAULT_PRESSURE;
   coords->xtilt    = GIMP_COORDS_DEFAULT_TILT;
   coords->ytilt    = GIMP_COORDS_DEFAULT_TILT;
@@ -120,17 +119,17 @@
 }
 
 static gint
-moveto (const FT_Vector *to,
-        gpointer         data)
+moveto (RenderContext *context,
+        const double   x,
+        const double   y)
 {
-  RenderContext *context = data;
   GimpCoords     start;
 
 #if GIMP_TEXT_DEBUG
-  g_printerr ("moveto  %f, %f\n", to->x / 64.0, to->y / 64.0);
+  g_printerr ("moveto  %f, %f\n", x, y);
 #endif
 
-  gimp_text_vector_coords (context, to, &start);
+  gimp_text_vector_coords (context, x, y, &start);
 
   if (context->stroke)
     gimp_stroke_close (context->stroke);
@@ -144,20 +143,20 @@
 }
 
 static gint
-lineto (const FT_Vector *to,
-        gpointer         data)
+lineto (RenderContext *context,
+        const double   x,
+        const double   y)
 {
-  RenderContext *context = data;
   GimpCoords     end;
 
 #if GIMP_TEXT_DEBUG
-  g_printerr ("lineto  %f, %f\n", to->x / 64.0, to->y / 64.0);
+  g_printerr ("lineto  %f, %f\n", x, y);
 #endif
 
   if (! context->stroke)
     return 0;
 
-  gimp_text_vector_coords (context, to, &end);
+  gimp_text_vector_coords (context, x, y, &end);
 
   gimp_bezier_stroke_lineto (context->stroke, &end);
 
@@ -165,96 +164,131 @@
 }
 
 static gint
-conicto (const FT_Vector *ftcontrol,
-         const FT_Vector *to,
-         gpointer         data)
+cubicto (RenderContext *context,
+         const double   x1,
+         const double   y1,
+         const double   x2,
+         const double   y2,
+         const double   x3,
+         const double   y3)
 {
-  RenderContext *context = data;
-  GimpCoords     control;
+  GimpCoords     control1;
+  GimpCoords     control2;
   GimpCoords     end;
 
 #if GIMP_TEXT_DEBUG
-  g_printerr ("conicto %f, %f\n", to->x / 64.0, to->y / 64.0);
+  g_printerr ("cubicto %f, %f\n", x3, y3);
 #endif
 
   if (! context->stroke)
     return 0;
 
-  gimp_text_vector_coords (context, ftcontrol, &control);
-  gimp_text_vector_coords (context, to, &end);
+  gimp_text_vector_coords (context, x1, y1, &control1);
+  gimp_text_vector_coords (context, x2, y2, &control2);
+  gimp_text_vector_coords (context, x3, y3, &end);
 
-  gimp_bezier_stroke_conicto (context->stroke, &control, &end);
+  gimp_bezier_stroke_cubicto (context->stroke, &control1, &control2, &end);
 
   return 0;
 }
 
 static gint
-cubicto (const FT_Vector *ftcontrol1,
-         const FT_Vector *ftcontrol2,
-         const FT_Vector *to,
-         gpointer         data)
+closepath (RenderContext *context)
 {
-  RenderContext *context = data;
-  GimpCoords     control1;
-  GimpCoords     control2;
-  GimpCoords     end;
-
 #if GIMP_TEXT_DEBUG
-  g_printerr ("cubicto %f, %f\n", to->x / 64.0, to->y / 64.0);
+  g_printerr ("moveto\n");
 #endif
 
-  if (! context->stroke)
+  if (!context->stroke)
     return 0;
 
-  gimp_text_vector_coords (context, ftcontrol1, &control1);
-  gimp_text_vector_coords (context, ftcontrol2, &control2);
-  gimp_text_vector_coords (context, to, &end);
+  gimp_stroke_close (context->stroke);
 
-  gimp_bezier_stroke_cubicto (context->stroke, &control1, &control2, &end);
+  context->stroke = NULL;
 
   return 0;
 }
 
 
 static void
-gimp_text_render_vectors (PangoFont     *font,
-                          PangoGlyph     pango_glyph,
-                          FT_Int32       flags,
-                          FT_Matrix     *trafo,
-                          gint           x,
-                          gint           y,
-                          RenderContext *context)
+gimp_text_render_vectors (PangoFont            *font,
+                          PangoGlyph            pango_glyph,
+                          cairo_font_options_t *options,
+                          cairo_matrix_t       *matrix,
+                          gint                  x,
+                          gint                  y,
+                          RenderContext        *context)
 {
-  const FT_Outline_Funcs  outline_funcs =
-  {
-    moveto,
-    lineto,
-    conicto,
-    cubicto,
-    0,
-    0
-  };
-
-  FT_Face   face;
-  FT_Glyph  glyph;
+  cairo_surface_t     *surface;
+  cairo_t             *cr;
+  cairo_path_t        *cpath;
+  cairo_scaled_font_t *cfont;
+  cairo_glyph_t        cglyph;
+  gint                 i;
 
-  face = pango_fc_font_lock_face (PANGO_FC_FONT (font));
+  context->offset_x = (gdouble) x / PANGO_SCALE;
+  context->offset_y = (gdouble) y / PANGO_SCALE;
 
-  FT_Load_Glyph (face, (FT_UInt) pango_glyph, flags);
+  cglyph.x     = 0;
+  cglyph.y     = 0;
+  cglyph.index = pango_glyph;
 
-  FT_Get_Glyph (face->glyph, &glyph);
+  /* A cairo_t needs an image surface to function, so "surface" is created
+   * temporarily for this purpose. Nothing is drawn to "surface", but it is
+   * still needed to be connected to "cr" for "cr" to execute
+   * cr_glyph_path(). The size of surface is therefore irrelevant.
+   */
+  surface = cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2);
+  cr = cairo_create (surface);
 
-  if (face->glyph->format == FT_GLYPH_FORMAT_OUTLINE)
-    {
-      FT_OutlineGlyph outline_glyph = (FT_OutlineGlyph) glyph;
+  cfont = pango_cairo_font_get_scaled_font ((PangoCairoFont *) font);
+
+  cairo_set_scaled_font (cr, cfont);
+
+  cairo_set_font_options (cr, options);
 
-      context->offset_x = (gdouble) x / PANGO_SCALE;
-      context->offset_y = (gdouble) y / PANGO_SCALE;
+  cairo_transform (cr, matrix);
+
+  cairo_glyph_path (cr, &cglyph, 1);
+
+  cpath = cairo_copy_path (cr);
+
+  for (i = 0; i < cpath->num_data; i += cpath->data[i].header.length)
+    {
+      cairo_path_data_t *data = &cpath->data[i];
 
-      FT_Outline_Decompose (&outline_glyph->outline, &outline_funcs, context);
+      /* if the drawing operation is the final moveto of the glyph,
+       * break to avoid creating an empty point. This is because cairo
+       * always adds a moveto after each closepath.
+       */
+      if (i + data->header.length >= cpath->num_data)
+        break;
+
+      switch (data->header.type)
+        {
+        case CAIRO_PATH_MOVE_TO:
+          moveto (context, data[1].point.x, data[1].point.y);
+          break;
+
+        case CAIRO_PATH_LINE_TO:
+          lineto (context, data[1].point.x, data[1].point.y);
+          break;
+
+        case CAIRO_PATH_CURVE_TO:
+          cubicto (context,
+                   data[1].point.x, data[1].point.y,
+                   data[2].point.x, data[2].point.y,
+                   data[3].point.x, data[3].point.y);
+          break;
+
+        case CAIRO_PATH_CLOSE_PATH:
+          closepath (context);
+          break;
+        }
     }
 
-  FT_Done_Glyph (glyph);
+  cairo_path_destroy (cpath);
 
-  pango_fc_font_unlock_face (PANGO_FC_FONT (font));
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
 }

Modified: trunk/app/text/gimptext-vectors.h
==============================================================================
--- trunk/app/text/gimptext-vectors.h	(original)
+++ trunk/app/text/gimptext-vectors.h	Sun Oct 26 17:39:55 2008
@@ -1,7 +1,7 @@
 /* GIMP - The GNU Image Manipulation Program
  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  *
- * GimpText
+ * GimpText-vectors
  * Copyright (C) 2003  Sven Neumann <sven gimp org>
  *
  * This program is free software; you can redistribute it and/or modify

Modified: trunk/app/text/gimptextlayer.c
==============================================================================
--- trunk/app/text/gimptextlayer.c	(original)
+++ trunk/app/text/gimptextlayer.c	Sun Oct 26 17:39:55 2008
@@ -24,7 +24,7 @@
 #include <string.h>
 
 #include <gegl.h>
-#include <pango/pangoft2.h>
+#include <pango/pangocairo.h>
 
 #include "libgimpconfig/gimpconfig.h"
 
@@ -61,6 +61,7 @@
   PROP_MODIFIED
 };
 
+
 static void       gimp_text_layer_finalize       (GObject         *object);
 static void       gimp_text_layer_get_property   (GObject         *object,
                                                   guint            property_id,
@@ -151,6 +152,7 @@
                                     "auto-rename", NULL,
                                     TRUE,
                                     GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_MODIFIED,
                                     "modified", NULL,
                                     FALSE,
@@ -194,6 +196,7 @@
     case PROP_MODIFIED:
       g_value_set_boolean (value, text_layer->modified);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -216,6 +219,7 @@
     case PROP_MODIFIED:
       text_layer->modified = g_value_get_boolean (value);
       break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -579,6 +583,7 @@
                                layer->text->text : _("Empty Text Layer"));
 
   gimp_text_layer_render_layout (layer, layout);
+
   g_object_unref (layout);
 
   g_object_thaw_notify (G_OBJECT (drawable));
@@ -590,42 +595,47 @@
 gimp_text_layer_render_layout (GimpTextLayer  *layer,
                                GimpTextLayout *layout)
 {
-  GimpDrawable *drawable = GIMP_DRAWABLE (layer);
-  GimpItem     *item     = GIMP_ITEM (layer);
-  TileManager  *mask;
-  FT_Bitmap     bitmap;
-  PixelRegion   textPR;
-  PixelRegion   maskPR;
-  gint          i;
+  GimpDrawable    *drawable = GIMP_DRAWABLE (layer);
+  GimpItem        *item     = GIMP_ITEM (layer);
+  TileManager     *mask;
+  cairo_t         *cr;
+  cairo_surface_t *surface;
+  PixelRegion      textPR;
+  PixelRegion      maskPR;
+  gint             i;
+  gint             width, height;
 
   gimp_drawable_fill (drawable, &layer->text->color, NULL);
 
-  bitmap.width = gimp_item_width  (item);
-  bitmap.rows  = gimp_item_height (item);
-  bitmap.pitch = bitmap.width;
-  if (bitmap.pitch & 3)
-    bitmap.pitch += 4 - (bitmap.pitch & 3);
 
-  bitmap.buffer = g_malloc0 (bitmap.rows * bitmap.pitch);
+  width = gimp_item_width (item);
+  height = gimp_item_height (item);
+
+
+  surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
+                                        width, height);
+
+  cr = cairo_create (surface);
 
   gimp_text_layout_render (layout,
                            (GimpTextRenderFunc) gimp_text_render_bitmap,
-                           &bitmap);
+                           cr);
 
-  mask = tile_manager_new (bitmap.width, bitmap.rows, 1);
-  pixel_region_init (&maskPR, mask, 0, 0, bitmap.width, bitmap.rows, TRUE);
+  mask = tile_manager_new ( width, height, 1);
+  pixel_region_init (&maskPR, mask, 0, 0, width, height, TRUE);
 
-  for (i = 0; i < bitmap.rows; i++)
+  for (i = 0; i < height; i++)
     pixel_region_set_row (&maskPR,
-                          0, i, bitmap.width,
-                          bitmap.buffer + i * bitmap.pitch);
+                          0, i, width,
+                          cairo_image_surface_get_data (surface) + i * cairo_image_surface_get_stride (surface));
 
-  g_free (bitmap.buffer);
+  cairo_destroy (cr);
+  cairo_surface_destroy (surface);
 
   pixel_region_init (&textPR, gimp_drawable_get_tiles (drawable),
-                     0, 0, bitmap.width, bitmap.rows, TRUE);
+                     0, 0, width, height, TRUE);
   pixel_region_init (&maskPR, mask,
-                     0, 0, bitmap.width, bitmap.rows, FALSE);
+                     0, 0, width, height, FALSE);
 
   apply_mask_to_region (&textPR, &maskPR, OPAQUE_OPACITY);
 

Modified: trunk/app/text/gimptextlayout-render.c
==============================================================================
--- trunk/app/text/gimptextlayout-render.c	(original)
+++ trunk/app/text/gimptextlayout-render.c	Sun Oct 26 17:39:55 2008
@@ -24,7 +24,8 @@
 #include "config.h"
 
 #include <glib-object.h>
-#include <pango/pangoft2.h>
+#include <cairo.h>
+#include <pango/pangocairo.h>
 #include <pango/pango-font.h>
 
 #include "text-types.h"
@@ -61,9 +62,10 @@
                                               gint                x,
                                               gint                y,
                                               gpointer            render_data);
-static FT_Int32   gimp_text_layout_render_flags (GimpTextLayout  *layout);
-static void       gimp_text_layout_render_trafo (GimpTextLayout  *layout,
-                                                 FT_Matrix       *trafo);
+static cairo_font_options_t *
+             gimp_text_layout_render_flags   (GimpTextLayout     *layout);
+static void  gimp_text_layout_render_trafo   (GimpTextLayout     *layout,
+                                              cairo_matrix_t     *trafo);
 
 
 
@@ -164,12 +166,13 @@
                                 gint                y,
                                 gpointer            render_data)
 {
-  PangoGlyphInfo *gi;
-  FT_Int32        flags;
-  FT_Matrix       trafo;
-  FT_Vector       pos;
-  gint            i;
-  gint            x_position = 0;
+  PangoGlyphInfo       *gi;
+  cairo_font_options_t *flags;
+  cairo_matrix_t        trafo;
+  double                pos_x;
+  double                pos_y;
+  gint                  i;
+  gint                  x_position = 0;
 
   flags = gimp_text_layout_render_flags (layout);
   gimp_text_layout_render_trafo (layout, &trafo);
@@ -178,13 +181,14 @@
     {
       if (gi->glyph != PANGO_GLYPH_EMPTY)
         {
-          pos.x = x + x_position + gi->geometry.x_offset;
-          pos.y = y + gi->geometry.y_offset;
 
-          FT_Vector_Transform (&pos, &trafo);
+          pos_x = x + x_position + gi->geometry.x_offset;
+          pos_y = y + gi->geometry.y_offset;
+
+          cairo_matrix_transform_point (&trafo, &pos_x, &pos_y);
 
           render_func (font, gi->glyph, flags, &trafo,
-                       pos.x, pos.y,
+                       pos_x, pos_y,
                        render_data);
         }
 
@@ -192,34 +196,39 @@
     }
 }
 
-static FT_Int32
+static cairo_font_options_t *
 gimp_text_layout_render_flags (GimpTextLayout *layout)
 {
-  GimpText *text  = layout->text;
-  gint      flags;
+  GimpText             *text  = layout->text;
+  cairo_font_options_t *flags;
+
+  flags = cairo_font_options_create ();
 
   if (text->antialias)
-    flags = FT_LOAD_NO_BITMAP;
+    cairo_font_options_set_antialias (flags, CAIRO_ANTIALIAS_DEFAULT);
   else
-    flags = FT_LOAD_TARGET_MONO;
-
-  if (!text->hinting)
-   flags |= FT_LOAD_NO_HINTING;
-
+    cairo_font_options_set_antialias (flags, CAIRO_ANTIALIAS_NONE);
+/*
+ * commented because there's no real autohint support in cairo like there is in ft2
   if (text->autohint)
-    flags |= FT_LOAD_FORCE_AUTOHINT;
+    cairo_font_options_set_hint_style (flags, CAIRO_HINT_STYLE_DEFAULT);
+*/
+  if (!text->hinting)
+    cairo_font_options_set_hint_style (flags, CAIRO_HINT_STYLE_NONE);
 
   return flags;
 }
 
 static void
 gimp_text_layout_render_trafo (GimpTextLayout *layout,
-                               FT_Matrix      *trafo)
+                               cairo_matrix_t *trafo)
 {
   GimpText *text = layout->text;
 
-  trafo->xx = text->transformation.coeff[0][0] * 65536.0 / layout->yres * layout->xres;
-  trafo->xy = text->transformation.coeff[0][1] * 65536.0;
-  trafo->yx = text->transformation.coeff[1][0] * 65536.0 / layout->yres * layout->xres;
-  trafo->yy = text->transformation.coeff[1][1] * 65536.0;
+  trafo->xx = text->transformation.coeff[0][0] * 1.0 / layout->yres * layout->xres;
+  trafo->xy = text->transformation.coeff[0][1] * 1.0;
+  trafo->yx = text->transformation.coeff[1][0] * 1.0 / layout->yres * layout->xres;
+  trafo->yy = text->transformation.coeff[1][1] * 1.0;
+  trafo->x0 = 0;
+  trafo->y0 = 0;
 }

Modified: trunk/app/text/gimptextlayout.c
==============================================================================
--- trunk/app/text/gimptextlayout.c	(original)
+++ trunk/app/text/gimptextlayout.c	Sun Oct 26 17:39:55 2008
@@ -22,7 +22,8 @@
 #include "config.h"
 
 #include <gegl.h>
-#include <pango/pangoft2.h>
+#include <cairo.h>
+#include <pango/pangocairo.h>
 
 #include "text-types.h"
 
@@ -36,19 +37,19 @@
 #include "gimptextlayout.h"
 
 
-static void   gimp_text_layout_finalize           (GObject        *object);
+static void           gimp_text_layout_finalize   (GObject        *object);
 
-static void   gimp_text_layout_position           (GimpTextLayout *layout);
+static void           gimp_text_layout_position   (GimpTextLayout *layout);
 
 static PangoContext * gimp_text_get_pango_context (GimpText       *text,
                                                    gdouble         xres,
                                                    gdouble         yres);
 
-static gint   gimp_text_layout_pixel_size         (Gimp           *gimp,
+static gint           gimp_text_layout_pixel_size (Gimp           *gimp,
                                                    gdouble         value,
                                                    GimpUnit        unit,
                                                    gdouble         res);
-static gint   gimp_text_layout_point_size         (Gimp           *gimp,
+static gint           gimp_text_layout_point_size (Gimp           *gimp,
                                                    gdouble         value,
                                                    GimpUnit        unit,
                                                    gdouble         res);
@@ -302,49 +303,21 @@
 #endif
 }
 
-
-static void
-gimp_text_ft2_subst_func (FcPattern *pattern,
-                          gpointer   data)
-{
-  GimpText *text = GIMP_TEXT (data);
-
-  FcPatternAddBool (pattern, FC_HINTING,   text->hinting);
-  FcPatternAddBool (pattern, FC_AUTOHINT,  text->autohint);
-  FcPatternAddBool (pattern, FC_ANTIALIAS, text->antialias);
-}
-
 static PangoContext *
 gimp_text_get_pango_context (GimpText *text,
                              gdouble   xres,
                              gdouble   yres)
 {
-  PangoContext    *context;
-  PangoFT2FontMap *fontmap;
+  PangoContext      *context;
+  PangoCairoFontMap *fontmap;
 
-  fontmap = PANGO_FT2_FONT_MAP (pango_ft2_font_map_new ());
+  fontmap = PANGO_CAIRO_FONT_MAP (pango_cairo_font_map_new ());
 
-  pango_ft2_font_map_set_resolution (fontmap, xres, yres);
+  pango_cairo_font_map_set_resolution (fontmap, xres);
 
-  pango_ft2_font_map_set_default_substitute (fontmap,
-                                             gimp_text_ft2_subst_func,
-                                             g_object_ref (text),
-                                             (GDestroyNotify) g_object_unref);
-
-  context = pango_ft2_font_map_create_context (fontmap);
+  context = pango_cairo_font_map_create_context (fontmap);
   g_object_unref (fontmap);
 
-  /*  Workaround for bug #143542 (PangoFT2Fontmap leak),
-   *  see also bug #148997 (Text layer rendering leaks font file descriptor):
-   *
-   *  Calling pango_ft2_font_map_substitute_changed() causes the
-   *  font_map cache to be flushed, thereby removing the circular
-   *  reference that causes the leak.
-   */
-  g_object_weak_ref (G_OBJECT (context),
-                     (GWeakNotify) pango_ft2_font_map_substitute_changed,
-                     fontmap);
-
   if (text->language)
     pango_context_set_language (context,
                                 pango_language_from_string (text->language));

Modified: trunk/app/tools/gimprectangletool.c
==============================================================================
--- trunk/app/tools/gimprectangletool.c	(original)
+++ trunk/app/tools/gimprectangletool.c	Sun Oct 26 17:39:55 2008
@@ -414,6 +414,11 @@
                                                               GIMP_TYPE_RECTANGLE_PRECISION,
                                                               GIMP_RECTANGLE_PRECISION_INT,
                                                               GIMP_PARAM_READWRITE));
+      g_object_interface_install_property (iface,
+                                           g_param_spec_boolean ("narrow-mode",
+                                                                 NULL, NULL,
+                                                                 FALSE,
+                                                                 GIMP_PARAM_READWRITE));
 
       iface->execute                   = NULL;
       iface->cancel                    = NULL;
@@ -497,6 +502,9 @@
   g_object_class_override_property (klass,
                                     GIMP_RECTANGLE_TOOL_PROP_PRECISION,
                                     "precision");
+  g_object_class_override_property (klass,
+                                    GIMP_RECTANGLE_TOOL_PROP_NARROW_MODE,
+                                    "narrow-mode");
 }
 
 void
@@ -718,6 +726,9 @@
     case GIMP_RECTANGLE_TOOL_PROP_PRECISION:
       private->precision = g_value_get_enum (value);
       break;
+    case GIMP_RECTANGLE_TOOL_PROP_NARROW_MODE:
+      private->narrow_mode = g_value_get_boolean (value);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -758,6 +769,9 @@
     case GIMP_RECTANGLE_TOOL_PROP_PRECISION:
       g_value_set_enum (value, private->precision);
       break;
+    case GIMP_RECTANGLE_TOOL_PROP_NARROW_MODE:
+      g_value_set_boolean (value, private->narrow_mode);
+      break;
 
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);

Modified: trunk/app/tools/gimprectangletool.h
==============================================================================
--- trunk/app/tools/gimprectangletool.h	(original)
+++ trunk/app/tools/gimprectangletool.h	Sun Oct 26 17:39:55 2008
@@ -29,7 +29,8 @@
   GIMP_RECTANGLE_TOOL_PROP_Y2,
   GIMP_RECTANGLE_TOOL_PROP_CONSTRAINT,
   GIMP_RECTANGLE_TOOL_PROP_PRECISION,
-  GIMP_RECTANGLE_TOOL_PROP_LAST = GIMP_RECTANGLE_TOOL_PROP_PRECISION
+  GIMP_RECTANGLE_TOOL_PROP_NARROW_MODE,
+  GIMP_RECTANGLE_TOOL_PROP_LAST = GIMP_RECTANGLE_TOOL_PROP_NARROW_MODE
 } GimpRectangleToolProp;
 
 

Modified: trunk/app/tools/gimptextoptions.c
==============================================================================
--- trunk/app/tools/gimptextoptions.c	(original)
+++ trunk/app/tools/gimptextoptions.c	Sun Oct 26 17:39:55 2008
@@ -62,6 +62,7 @@
   PROP_INDENTATION,
   PROP_LINE_SPACING,
   PROP_LETTER_SPACING,
+  PROP_USE_EDITOR,
 
   PROP_FONT_VIEW_TYPE,
   PROP_FONT_VIEW_SIZE
@@ -173,6 +174,14 @@
                                    GIMP_PARAM_STATIC_STRINGS |
                                    GIMP_CONFIG_PARAM_DEFAULTS);
 
+  GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_USE_EDITOR,
+                                    "use-editor",
+                                    N_("Use an external editor window for text "
+                                       "entry, instead of direct-on-canvas "
+                                       "editing"),
+                                    FALSE,
+                                    GIMP_PARAM_STATIC_STRINGS);
+
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_FONT_VIEW_TYPE,
                                  "font-view-type", NULL,
                                  GIMP_TYPE_VIEW_TYPE,
@@ -192,7 +201,6 @@
 gimp_text_options_init (GimpTextOptions *options)
 {
   options->size_entry           = NULL;
-  options->to_vectors_button    = NULL;
   options->along_vectors_button = NULL;
 }
 
@@ -240,6 +248,10 @@
       g_value_set_double (value, options->letter_spacing);
       break;
 
+    case PROP_USE_EDITOR:
+      g_value_set_boolean (value, options->use_editor);
+      break;
+
     case PROP_FONT_VIEW_TYPE:
       g_value_set_enum (value, options->font_view_type);
       break;
@@ -298,6 +310,10 @@
       options->letter_spacing = g_value_get_double (value);
       break;
 
+    case PROP_USE_EDITOR:
+      options->use_editor = g_value_get_boolean (value);
+      break;
+
     case PROP_FONT_VIEW_TYPE:
       options->font_view_type = g_value_get_enum (value);
       break;
@@ -458,6 +474,10 @@
   gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0);
   gtk_widget_show (vbox);
 
+  button = gimp_prop_check_button_new (config, "use-editor", _("Use editor"));
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
+
   button = gimp_prop_check_button_new (config, "hinting", _("Hinting"));
   gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
   gtk_widget_show (button);
@@ -516,14 +536,6 @@
   gimp_table_attach_stock (GTK_TABLE (table), row++,
                            GIMP_STOCK_LETTER_SPACING, spinbutton, 1, TRUE);
 
-  /*  Create a path from the current text  */
-  button = gtk_button_new_with_label (_("Path from Text"));
-  gtk_box_pack_end (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
-  gtk_widget_set_sensitive (button, FALSE);
-  gtk_widget_show (button);
-
-  options->to_vectors_button = button;
-
   button = gtk_button_new_with_label (_("Text along Path"));
   gtk_box_pack_end (GTK_BOX (main_vbox), button, FALSE, FALSE, 0);
   gtk_widget_set_sensitive (button, FALSE);
@@ -573,7 +585,8 @@
 gimp_text_options_editor_new (GtkWindow       *parent,
                               GimpTextOptions *options,
                               GimpMenuFactory *menu_factory,
-                              const gchar     *title)
+                              const gchar     *title,
+                              GtkTextBuffer   *text_buffer)
 {
   GtkWidget   *editor;
   const gchar *font_name;
@@ -582,7 +595,7 @@
   g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL);
   g_return_val_if_fail (title != NULL, NULL);
 
-  editor = gimp_text_editor_new (title, parent, menu_factory);
+  editor = gimp_text_editor_new (title, parent, menu_factory, text_buffer);
 
   font_name = gimp_context_get_font_name (GIMP_CONTEXT (options));
 

Modified: trunk/app/tools/gimptextoptions.h
==============================================================================
--- trunk/app/tools/gimptextoptions.h	(original)
+++ trunk/app/tools/gimptextoptions.h	Sun Oct 26 17:39:55 2008
@@ -53,9 +53,10 @@
   GimpViewType           font_view_type;
   GimpViewSize           font_view_size;
 
+  gboolean               use_editor;
+
   /*  options gui  */
   GtkWidget             *size_entry;
-  GtkWidget             *to_vectors_button;
   GtkWidget             *along_vectors_button;
 };
 
@@ -70,7 +71,8 @@
 GtkWidget * gimp_text_options_editor_new   (GtkWindow       *parent,
                                             GimpTextOptions *options,
                                             GimpMenuFactory *menu_factory,
-                                            const gchar     *title);
+                                            const gchar     *title,
+                                            GtkTextBuffer   *text_buffer);
 
 
 #endif /* __GIMP_TEXT_OPTIONS_H__ */

Modified: trunk/app/tools/gimptexttool.c
==============================================================================
--- trunk/app/tools/gimptexttool.c	(original)
+++ trunk/app/tools/gimptexttool.c	Sun Oct 26 17:39:55 2008
@@ -28,6 +28,7 @@
 
 #include <gegl.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "libgimpconfig/gimpconfig.h"
 #include "libgimpwidgets/gimpwidgets.h"
@@ -47,16 +48,21 @@
 #include "text/gimptext.h"
 #include "text/gimptext-vectors.h"
 #include "text/gimptextlayer.h"
+#include "text/gimptextlayout.h"
 #include "text/gimptextundo.h"
+#include "text/gimptext-private.h"
 
 #include "vectors/gimpvectors-warp.h"
 
 #include "widgets/gimpdialogfactory.h"
 #include "widgets/gimphelp-ids.h"
+#include "widgets/gimpmenufactory.h"
 #include "widgets/gimptexteditor.h"
 #include "widgets/gimpviewabledialog.h"
 
+#include "display/gimpcanvas.h"
 #include "display/gimpdisplay.h"
+#include "display/gimpdisplayshell.h"
 
 #include "gimpeditselectiontool.h"
 #include "gimprectangletool.h"
@@ -95,10 +101,23 @@
                                                 GdkModifierType    state,
                                                 GimpButtonReleaseType release_type,
                                                 GimpDisplay       *display);
+static void      gimp_text_tool_motion         (GimpTool          *tool,
+                                                GimpCoords        *coords,
+                                                guint32            time,
+                                                GdkModifierType    state,
+                                                GimpDisplay       *display);
+static gboolean  gimp_text_tool_key_press      (GimpTool          *tool,
+                                                GdkEventKey       *kevent,
+                                                GimpDisplay       *display);
 static void      gimp_text_tool_cursor_update  (GimpTool          *tool,
                                                 GimpCoords        *coords,
                                                 GdkModifierType    state,
                                                 GimpDisplay       *display);
+static GimpUIManager * gimp_text_tool_get_popup(GimpTool          *tool,
+                                                GimpCoords        *coords,
+                                                GdkModifierType    state,
+                                                GimpDisplay       *display,
+                                                const gchar      **ui_path);
 
 static void      gimp_text_tool_connect        (GimpTextTool      *text_tool,
                                                 GimpTextLayer     *layer,
@@ -115,16 +134,15 @@
 static gboolean  gimp_text_tool_idle_apply     (GimpTextTool      *text_tool);
 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);
 
+static void    gimp_text_tool_canvas_editor          (GimpTextTool *text_tool);
+static gchar  *gimp_text_tool_canvas_editor_get_text (GimpTextTool *text_tool);
+
 static void      gimp_text_tool_editor         (GimpTextTool      *text_tool);
-static void      gimp_text_tool_editor_update  (GimpTextTool      *text_tool);
-static void      gimp_text_tool_text_changed   (GimpTextEditor    *editor,
-                                                GimpTextTool      *text_tool);
 
 static void      gimp_text_tool_layer_changed  (GimpImage         *image,
                                                 GimpTextTool      *text_tool);
@@ -139,6 +157,36 @@
 void             gimp_rectangle_tool_frame_item(GimpRectangleTool *rect_tool,
                                                 GimpItem          *item);
 
+static void gimp_text_tool_draw                (GimpDrawTool      *draw_tool);
+static void gimp_text_tool_draw_preedit_lines  (GimpDrawTool      *draw_tool);
+static void gimp_text_tool_draw_text_selection (GimpDrawTool      *draw_tool);
+
+static void gimp_text_tool_update_layout       (GimpTextTool      *text_tool);
+static void gimp_text_tool_update_proxy        (GimpTextTool      *text_tool);
+
+static void gimp_text_tool_reset_im_context    (GimpTextTool      *text_tool);
+static void gimp_text_tool_enter_text          (GimpTextTool      *text_tool,
+                                                const gchar       *str);
+static void gimp_text_tool_text_buffer_changed (GtkTextBuffer     *text_buffer,
+                                                GimpTextTool      *text_tool);
+static void gimp_text_tool_text_buffer_mark_set (GtkTextBuffer    *text_buffer,
+                                                 GtkTextIter      *location,
+                                                 GtkTextMark      *mark,
+                                                 GimpTextTool     *text_tool);
+static void gimp_text_tool_use_editor_notify   (GimpTextOptions   *options,
+                                                GParamSpec        *pspec,
+                                                GimpTextTool      *text_tool);
+
+/* IM Context Callbacks
+ */
+static void gimp_text_tool_commit_cb           (GtkIMContext      *context,
+                                                const gchar       *str,
+                                                GimpTextTool      *text_tool);
+
+static void gimp_text_tool_preedit_changed_cb (GtkIMContext       *context,
+                                               GimpTextTool       *text_tool);
+
+
 G_DEFINE_TYPE_WITH_CODE (GimpTextTool, gimp_text_tool,
                          GIMP_TYPE_DRAW_TOOL,
                          G_IMPLEMENT_INTERFACE (GIMP_TYPE_RECTANGLE_TOOL,
@@ -183,20 +231,21 @@
 
   tool_class->control        = gimp_text_tool_control;
   tool_class->button_press   = gimp_text_tool_button_press;
-  tool_class->motion         = gimp_rectangle_tool_motion;
+  tool_class->motion         = gimp_text_tool_motion;
   tool_class->button_release = gimp_text_tool_button_release;
-  tool_class->key_press      = gimp_edit_selection_tool_key_press;
+  tool_class->key_press      = gimp_text_tool_key_press;
   tool_class->oper_update    = gimp_rectangle_tool_oper_update;
   tool_class->cursor_update  = gimp_text_tool_cursor_update;
+  tool_class->get_popup      = gimp_text_tool_get_popup;
 
-  draw_tool_class->draw      = gimp_rectangle_tool_draw;
+  draw_tool_class->draw      = gimp_text_tool_draw;
 }
 
 static void
 gimp_text_tool_rectangle_tool_iface_init (GimpRectangleToolInterface *iface)
 {
-  iface->execute           = NULL;
-  iface->cancel            = NULL;
+  iface->execute                   = NULL;
+  iface->cancel                    = NULL;
   iface->rectangle_change_complete = gimp_text_tool_rectangle_change_complete;
 }
 
@@ -212,12 +261,35 @@
   text_tool->text    = NULL;
   text_tool->layer   = NULL;
   text_tool->image   = NULL;
+  text_tool->layout  = NULL;
+
+  text_tool->text_buffer = gtk_text_buffer_new (NULL);
+  gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
+
+  g_signal_connect (text_tool->text_buffer, "changed",
+                    G_CALLBACK (gimp_text_tool_text_buffer_changed),
+                    text_tool);
+  g_signal_connect (text_tool->text_buffer, "mark-set",
+                    G_CALLBACK (gimp_text_tool_text_buffer_mark_set),
+                    text_tool);
+
+  text_tool->im_context = gtk_im_multicontext_new ();
 
-  gimp_tool_control_set_scroll_lock (tool->control, TRUE);
-  gimp_tool_control_set_tool_cursor (tool->control,
-                                     GIMP_TOOL_CURSOR_TEXT);
-  gimp_tool_control_set_action_object_1 (tool->control,
-                                         "context/context-font-select-set");
+  text_tool->preedit_string = NULL;
+
+  g_signal_connect (text_tool->im_context, "commit",
+                    G_CALLBACK (gimp_text_tool_commit_cb),
+                    text_tool);
+  g_signal_connect (text_tool->im_context, "preedit_changed",
+                    G_CALLBACK (gimp_text_tool_preedit_changed_cb),
+                    text_tool);
+
+  gimp_tool_control_set_scroll_lock          (tool->control, TRUE);
+  gimp_tool_control_set_wants_all_key_events (tool->control, TRUE);
+  gimp_tool_control_set_tool_cursor          (tool->control,
+                                              GIMP_TOOL_CURSOR_TEXT);
+  gimp_tool_control_set_action_object_1      (tool->control,
+                                              "context/context-font-select-set");
 
   text_tool->handle_rectangle_change_complete = TRUE;
 }
@@ -246,6 +318,14 @@
                            G_CALLBACK (gimp_text_tool_proxy_notify),
                            text_tool, 0);
 
+  g_signal_connect_object (options, "notify::use-editor",
+                           G_CALLBACK (gimp_text_tool_use_editor_notify),
+                           text_tool, 0);
+
+  g_object_set (options,
+                "highlight", FALSE,
+                NULL);
+
   return object;
 }
 
@@ -253,9 +333,16 @@
 gimp_text_tool_dispose (GObject *object)
 {
   GimpTextTool *text_tool = GIMP_TEXT_TOOL (object);
+  GimpTool     *tool      = GIMP_TOOL (object);
 
   gimp_text_tool_set_drawable (text_tool, NULL, FALSE);
 
+  if (text_tool->editor)
+    {
+      gtk_widget_destroy (text_tool->editor);
+      text_tool->editor = NULL;
+    }
+
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
@@ -270,6 +357,24 @@
       text_tool->proxy = NULL;
     }
 
+  if (text_tool->layout)
+    {
+      g_object_unref (text_tool->layout);
+      text_tool->layout = NULL;
+    }
+
+  if (text_tool->text_buffer)
+    {
+      g_object_unref (text_tool->text_buffer);
+      text_tool->text_buffer = NULL;
+    }
+
+  if (text_tool->im_context)
+    {
+      g_object_unref (text_tool->im_context);
+      text_tool->im_context = NULL;
+    }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -308,35 +413,64 @@
   GimpDrawable      *drawable;
   GimpTextOptions   *options     = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
   GimpRectangleTool *rect_tool   = GIMP_RECTANGLE_TOOL (tool);
+  gint               cx, cy;
+  gint               x1, y1;
+  gint               x2, y2;
 
   gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
 
-
-  /* FIXME: this should certainly be done elsewhere */
-  g_object_set (options,
-                "highlight", FALSE,
-                NULL);
+  g_signal_handlers_block_by_func (text_tool->text_buffer,
+                                   G_CALLBACK (gimp_text_tool_text_buffer_mark_set),
+                                   text_tool);
 
   text_tool->x1 = coords->x;
   text_tool->y1 = coords->y;
 
-  gimp_rectangle_tool_button_press (tool, coords, time, state, display);
+  g_object_get (rect_tool,
+                "x1", &x1,
+                "y1", &y1,
+                "x2", &x2,
+                "y2", &y2,
+                NULL);
+
+  cx = coords->x;
+  cy = coords->y;
+
+  if (x1 <= cx && x2 >= cx && y1 <= cy && y2 >= cy)
+    {
+      text_tool->text_cursor_changing = TRUE;
+
+      gimp_rectangle_tool_set_function (rect_tool, GIMP_RECTANGLE_TOOL_DEAD);
+      gimp_tool_control_activate (tool->control);
+    }
+  else
+    {
+      text_tool->text_cursor_changing = FALSE;
+
+      gimp_rectangle_tool_button_press (tool, coords, time, state, display);
+    }
 
-  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
 
-  /* bail out now if the rectangle is narrow and the button
-     press is outside the layer */
+  /* bail out now if the rectangle is narrow and the button press is
+   * outside the layer
+   */
   if (text_tool->layer &&
-      gimp_rectangle_tool_get_function (rect_tool) != GIMP_RECTANGLE_TOOL_CREATING)
+      gimp_rectangle_tool_get_function (rect_tool) !=
+      GIMP_RECTANGLE_TOOL_CREATING)
     {
       GimpItem *item = GIMP_ITEM (text_tool->layer);
       gdouble   x    = coords->x - item->offset_x;
       gdouble   y    = coords->y - item->offset_y;
 
       if (x < 0 || x > item->width || y < 0 || y > item->height)
-        return;
+        {
+          gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+          return;
+        }
     }
 
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+
   drawable = gimp_image_get_active_drawable (display->image);
 
   gimp_text_tool_set_drawable (text_tool, drawable, FALSE);
@@ -356,10 +490,46 @@
           /*  did the user click on a text layer?  */
           if (gimp_text_tool_set_drawable (text_tool, drawable, TRUE))
             {
-              /*  on second click, open the text editor  */
+              /*enable keyboard-handling for the text*/
+
+              gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+
               if (text && text_tool->text == text)
-                gimp_text_tool_editor (text_tool);
+                {
+                  gimp_text_tool_canvas_editor (text_tool);
+                  gtk_text_buffer_set_text (text_tool->text_buffer,
+                                            text_tool->text->text, -1);
 
+                  gimp_text_tool_update_layout (text_tool);
+                }
+
+              if (text_tool->layout)
+                {
+                  GtkTextIter cursor, start, end;
+                  gint        offset;
+                  gint        trailing;
+                  gchar      *string;
+
+                  gtk_text_buffer_get_bounds (text_tool->text_buffer,
+                                             &start, &end);
+                  string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                                     &start, &end, TRUE);
+                  pango_layout_xy_to_index (text_tool->layout->layout,
+                                            x * PANGO_SCALE, y * PANGO_SCALE,
+                                            &offset, &trailing);
+                  offset = g_utf8_pointer_to_offset (string,
+                                                    (string + offset));
+                  offset += trailing;
+
+                  g_free (string);
+
+                  gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+                                                     &cursor, offset);
+                  gtk_text_buffer_place_cursor (text_tool->text_buffer,
+                                               &cursor);
+                }
+
+              gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
               return;
             }
         }
@@ -367,8 +537,22 @@
 
   /*  create a new text layer  */
   text_tool->text_box_fixed = FALSE;
+
+  if (text_tool->text)
+    {
+      g_object_unref (text_tool->text);
+      text_tool->text = NULL;
+    }
+
+  gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
   gimp_text_tool_connect (text_tool, NULL, NULL);
-  gimp_text_tool_editor (text_tool);
+  gimp_text_tool_canvas_editor (text_tool);
+
+/*   if (text_tool->text) */
+/*     gtk_text_buffer_set_text (text_tool->text_buffer, */
+/*                               text_tool->text->text, -1); */
+/*   else */
+/*     gtk_text_buffer_set_text (text_tool->text_buffer, "", -1); */
 }
 
 #define MIN_LAYER_WIDTH 20
@@ -400,13 +584,17 @@
   GimpText          *text           = text_tool->text;
   gint               x1, y1, x2, y2;
 
-  g_object_get (rect_tool,
+  g_object_get (text_tool,
                 "x1", &x1,
                 "y1", &y1,
                 "x2", &x2,
                 "y2", &y2,
                 NULL);
 
+  if (gtk_text_buffer_get_has_selection (text_tool->text_buffer))
+    gimp_text_tool_clipboard_copy (text_tool, FALSE);
+  text_tool->text_cursor_changing = FALSE;
+
   if (text && text_tool->text == text)
     {
       if (gimp_rectangle_tool_rectangle_is_new (rect_tool))
@@ -418,11 +606,45 @@
           gimp_rectangle_tool_frame_item (rect_tool,
                                           GIMP_ITEM (text_tool->layer));
           text_tool->handle_rectangle_change_complete = TRUE;
+
+          g_signal_handlers_unblock_by_func (text_tool->text_buffer,
+                                           G_CALLBACK (gimp_text_tool_text_buffer_mark_set),
+                                           text_tool);
+
           return;
         }
       else
         {
           /* user has modified shape of an existing text layer */
+          gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+          if (text_tool->layout && text_tool->text_cursor_changing)
+            {
+              GimpItem   *item = GIMP_ITEM (text_tool->layer);
+              gdouble     x    = coords->x - item->offset_x;
+              gdouble     y    = coords->y - item->offset_y;
+              GtkTextIter cursor, start, end;
+              gint        offset, trailing;
+              gchar      *string;
+
+              gtk_text_buffer_get_bounds (text_tool->text_buffer, &start, &end);
+
+              string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                                &start, &end, TRUE);
+
+              pango_layout_xy_to_index (text_tool->layout->layout,
+                                        x * PANGO_SCALE, y * PANGO_SCALE,
+                                        &offset, &trailing);
+
+              offset = g_utf8_pointer_to_offset (string, (string + offset));
+              offset += trailing;
+
+              g_free (string);
+
+              gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer, &cursor, offset);
+              gtk_text_buffer_move_mark_by_name (text_tool->text_buffer,
+                                                 "selection_bound",  &cursor);
+            }
+          gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
         }
     }
   else if (y2 - y1 < MIN_LAYER_WIDTH)
@@ -444,6 +666,171 @@
   gimp_rectangle_tool_button_release (tool, coords, time, state,
                                       release_type, display);
   text_tool->handle_rectangle_change_complete = TRUE;
+
+  g_signal_handlers_unblock_by_func (text_tool->text_buffer,
+                                     G_CALLBACK (gimp_text_tool_text_buffer_mark_set),
+                                     text_tool);
+}
+
+void
+gimp_text_tool_motion (GimpTool        *tool,
+                       GimpCoords      *coords,
+                       guint32          time,
+                       GdkModifierType  state,
+                       GimpDisplay     *display)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+  gdouble       snapped_x;
+  gdouble       snapped_y;
+  gint          snap_x, snap_y;
+
+  if (text_tool->text_cursor_changing)
+    {
+      if (text_tool->layout)
+        {
+          GimpItem    *item        = GIMP_ITEM (text_tool->layer);
+          gdouble      x           = coords->x - item->offset_x;
+          gdouble      y           = coords->y - item->offset_y;
+          GtkTextIter  cursor;
+          GtkTextIter  start, end;
+          GtkTextIter  old_selection_bound;
+          GtkTextMark *selection_mark;
+          gint         offset, trailing;
+          gint         old_cursor_offset;
+          gchar       *string;
+
+          gtk_text_buffer_get_bounds (text_tool->text_buffer, &start, &end);
+          string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                            &start, &end, TRUE);
+
+          pango_layout_xy_to_index (text_tool->layout->layout, x * PANGO_SCALE,
+                                    y * PANGO_SCALE, &offset, &trailing);
+
+          offset = g_utf8_pointer_to_offset (string, (string + offset));
+          offset += trailing;
+
+          g_free (string);
+
+          selection_mark = gtk_text_buffer_get_selection_bound (text_tool->text_buffer);
+
+          gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
+                                           &old_selection_bound,
+                                            selection_mark);
+
+          old_cursor_offset = gtk_text_iter_get_offset (&old_selection_bound);
+
+          if (offset == old_cursor_offset)
+              return;
+
+          gimp_draw_tool_pause (GIMP_DRAW_TOOL (tool));
+          gtk_text_buffer_get_iter_at_offset (text_tool->text_buffer,
+                                             &cursor, offset);
+          gtk_text_buffer_move_mark_by_name (text_tool->text_buffer,
+                                             "selection_bound",  &cursor);
+          gimp_draw_tool_resume (GIMP_DRAW_TOOL (tool));
+        }
+    }
+  else
+    {
+      gimp_rectangle_tool_motion (tool, coords, time, state, display);
+    }
+}
+
+static gboolean
+gimp_text_tool_key_press (GimpTool    *tool,
+                          GdkEventKey *kevent,
+                          GimpDisplay *display)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+  GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
+  GtkTextMark  *insert;
+  GtkTextMark  *selection_bound;
+  GtkTextIter   cursor, selection;
+  GtkTextIter  *sel_start;
+  gboolean      retval = TRUE;
+
+  if (gtk_im_context_filter_keypress (text_tool->im_context, kevent))
+    {
+      text_tool->needs_im_reset = TRUE;
+
+      return TRUE;
+    }
+
+  insert = gtk_text_buffer_get_insert (text_tool->text_buffer);
+  selection_bound = gtk_text_buffer_get_selection_bound (text_tool->text_buffer);
+
+  gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
+                                   &cursor, insert);
+  gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
+                                   &selection, selection_bound);
+
+  if (kevent->state & GDK_SHIFT_MASK)
+    sel_start = &cursor;
+  else
+    sel_start = &selection;
+
+  switch (kevent->keyval)
+    {
+    case GDK_Return:
+    case GDK_KP_Enter:
+    case GDK_ISO_Enter:
+      gimp_draw_tool_pause (draw_tool);
+      gtk_text_buffer_delete_selection (text_tool->text_buffer, TRUE, TRUE);
+      gimp_text_tool_enter_text (text_tool, "\n");
+      gimp_text_tool_reset_im_context (text_tool);
+      gimp_text_tool_update_layout (text_tool);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    case GDK_BackSpace:
+      gimp_draw_tool_pause (draw_tool);
+      gimp_text_tool_delete_text (text_tool);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    case GDK_Right:
+    case GDK_KP_Right:
+      gimp_draw_tool_pause (draw_tool);
+      gtk_text_iter_forward_cursor_position (&selection);
+      gtk_text_buffer_select_range (text_tool->text_buffer, sel_start,
+                                    &selection);
+      gimp_text_tool_reset_im_context (text_tool);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    case GDK_Left:
+    case GDK_KP_Left:
+      gimp_draw_tool_pause (draw_tool);
+      gtk_text_iter_backward_cursor_position (&selection);
+      gtk_text_buffer_select_range (text_tool->text_buffer, sel_start,
+                                    &selection);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    case GDK_Home:
+    case GDK_KP_Home:
+      gimp_draw_tool_pause (draw_tool);
+      gtk_text_iter_set_line (&selection, gtk_text_iter_get_line (&selection));
+      gtk_text_buffer_select_range (text_tool->text_buffer, sel_start,
+                                    &selection);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    case GDK_End:
+    case GDK_KP_End:
+      gimp_draw_tool_pause (draw_tool);
+      gtk_text_iter_set_line (&selection, gtk_text_iter_get_line (&selection));
+      gtk_text_iter_forward_to_line_end (&selection);
+      gtk_text_buffer_select_range (text_tool->text_buffer, sel_start,
+                                    &selection);
+      gimp_draw_tool_resume (draw_tool);
+      break;
+
+    default:
+      retval = FALSE;
+    }
+
+  return retval;
 }
 
 static void
@@ -452,13 +839,96 @@
                               GdkModifierType  state,
                               GimpDisplay     *display)
 {
-  /* FIXME: should do something fancy here... */
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+
+  if (tool->display == display)
+    {
+      gint x, y;
+      gint x1, y1;
+      gint x2, y2;
+
+      x = coords->x;
+      y = coords->y;
 
-  gimp_rectangle_tool_cursor_update (tool, coords, state, display);
+      g_object_get (G_OBJECT (tool),
+                    "x1", &x1,
+                    "y1", &y1,
+                    "x2", &x2,
+                    "y2", &y2,
+                    NULL);
+
+      if (x1 <= x && x2 >= x && y1 <= y && y2 >= y)
+        {
+          GimpCursorType cursor = GDK_XTERM;
+
+          gimp_tool_control_set_cursor (tool->control, cursor);
+        }
+      else
+        {
+          gimp_rectangle_tool_cursor_update (tool, coords, state, display);
+        }
+    }
 
   GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
 }
 
+static GimpUIManager *
+gimp_text_tool_get_popup (GimpTool         *tool,
+                          GimpCoords       *coords,
+                          GdkModifierType   state,
+                          GimpDisplay      *display,
+                          const gchar     **ui_path)
+{
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (tool);
+  gint          cx, cy;
+  gint          x1, y1, x2, y2;
+
+  if (! text_tool->ui_manager)
+    {
+      GimpDialogFactory *dialog_factory;
+      GtkWidget         *im_menu;
+      GtkWidget         *im_menuitem;
+
+      dialog_factory = gimp_dialog_factory_from_name ("toplevel");
+
+      text_tool->ui_manager =
+        gimp_menu_factory_manager_new (dialog_factory->menu_factory,
+                                       "<TextTool>",
+                                       text_tool, FALSE);
+
+      im_menuitem = gtk_ui_manager_get_widget (GTK_UI_MANAGER (text_tool->ui_manager),
+                                               "/text-tool-popup/text-tool-input-methods");
+
+      im_menu = gtk_menu_new ();
+
+      gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (text_tool->im_context),
+                                            GTK_MENU_SHELL (im_menu));
+      gtk_menu_item_set_submenu (GTK_MENU_ITEM (im_menuitem), im_menu);
+      gtk_widget_show (im_menuitem);
+    }
+
+  g_object_get (text_tool,
+                "x1", &x1,
+                "y1", &y1,
+                "x2", &x2,
+                "y2", &y2,
+                NULL);
+
+  cx = coords->x;
+  cy = coords->y;
+
+  if (x1 > cx || x2 < cx || y1 > cy || y2 < cy)
+    {
+      return NULL;
+    }
+
+  gimp_ui_manager_update (text_tool->ui_manager, text_tool);
+
+  *ui_path = "/text-tool-popup";
+
+  return text_tool->ui_manager;
+}
+
 static void
 gimp_text_tool_connect (GimpTextTool  *text_tool,
                         GimpTextLayer *layer,
@@ -468,9 +938,6 @@
 
   g_return_if_fail (text == NULL || (layer != NULL && layer->text == text));
 
-  if (! text && text_tool->editor)
-    gtk_widget_destroy (text_tool->editor);
-
   if (text_tool->text != text)
     {
       GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (tool);
@@ -484,14 +951,6 @@
           if (text_tool->pending)
             gimp_text_tool_apply (text_tool);
 
-          if (options->to_vectors_button)
-            {
-              gtk_widget_set_sensitive (options->to_vectors_button, FALSE);
-              g_signal_handlers_disconnect_by_func (options->to_vectors_button,
-                                                    gimp_text_tool_create_vectors,
-                                                    text_tool);
-            }
-
           if (options->along_vectors_button)
             {
               gtk_widget_set_sensitive (options->along_vectors_button,
@@ -521,14 +980,6 @@
                             G_CALLBACK (gimp_text_tool_text_notify),
                             text_tool);
 
-          if (options->to_vectors_button)
-            {
-              g_signal_connect_swapped (options->to_vectors_button, "clicked",
-                                        G_CALLBACK (gimp_text_tool_create_vectors),
-                                        text_tool);
-              gtk_widget_set_sensitive (options->to_vectors_button, TRUE);
-            }
-
           if (options->along_vectors_button)
             {
               g_signal_connect_swapped (options->along_vectors_button, "clicked",
@@ -536,9 +987,6 @@
                                         text_tool);
               gtk_widget_set_sensitive (options->along_vectors_button, TRUE);
             }
-
-          if (text_tool->editor)
-            gimp_text_tool_editor_update (text_tool);
         }
     }
 
@@ -562,6 +1010,23 @@
 }
 
 static void
+gimp_text_tool_use_editor_notify (GimpTextOptions *options,
+                                  GParamSpec      *pspec,
+                                  GimpTextTool    *text_tool)
+{
+  if (options->use_editor)
+    {
+      if (text_tool->text && text_tool->text_buffer)
+        gimp_text_tool_editor (text_tool);
+    }
+  else
+    {
+      if (text_tool->editor)
+        gtk_widget_destroy (text_tool->editor);
+    }
+}
+
+static void
 gimp_text_tool_layer_notify (GimpTextLayer *layer,
                              GParamSpec    *pspec,
                              GimpTextTool  *text_tool)
@@ -620,9 +1085,6 @@
       g_value_unset (&value);
     }
 
-  if (text_tool->editor && strcmp (pspec->name, "text") == 0)
-    gimp_text_tool_editor_update (text_tool);
-
   /* we need to redraw the rectangle if it is visible and the shape of
      the layer has changed, because of an undo for example. */
   if (strcmp (pspec->name, "box-width") == 0  ||
@@ -636,6 +1098,27 @@
                                       GIMP_ITEM (text_tool->layer));
       text_tool->handle_rectangle_change_complete = TRUE;
     }
+
+  /* if the text has changed, (probably because of an undo), we put
+   * the new text into the text buffer
+   */
+  if (strcmp (pspec->name, "text") == 0)
+    {
+      g_signal_handlers_block_by_func (text_tool->proxy,
+                                       gimp_text_tool_text_buffer_changed,
+                                       text_tool);
+
+      gtk_text_buffer_set_text (text_tool->text_buffer, text->text, -1);
+
+      g_signal_handlers_unblock_by_func (text_tool->proxy,
+                                         gimp_text_tool_text_buffer_changed,
+                                         text_tool);
+
+      /* force change of cursor and selection display */
+      gimp_text_tool_update_layout (text_tool);
+/*       gimp_text_tool_update_proxy (text_tool); */
+      return;
+    }
 }
 
 static gboolean
@@ -784,9 +1267,10 @@
     }
 
   gimp_image_flush (image);
+  gimp_text_tool_update_layout (text_tool);
 }
 
-static void
+void
 gimp_text_tool_create_vectors (GimpTextTool *text_tool)
 {
   GimpVectors *vectors;
@@ -853,10 +1337,11 @@
     {
       gchar *str;
 
-      str = gimp_text_editor_get_text (GIMP_TEXT_EDITOR (text_tool->editor));
+      str = gimp_text_tool_canvas_editor_get_text (text_tool);
 
       g_object_set (text_tool->proxy,
                     "text", str,
+                    "box-mode", GIMP_TEXT_BOX_DYNAMIC,
                     NULL);
 
       g_free (str);
@@ -933,6 +1418,23 @@
 }
 
 static void
+gimp_text_tool_canvas_editor (GimpTextTool *text_tool)
+{
+  GimpTool        *tool    = GIMP_TOOL (text_tool);
+  GimpTextOptions *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
+
+  gtk_im_context_set_client_window (text_tool->im_context,
+                                    GIMP_DISPLAY_SHELL (tool->display->shell)->canvas->window);
+
+  gtk_im_context_focus_in (text_tool->im_context);
+
+  gimp_text_tool_update_layout (text_tool);
+
+  if (options->use_editor)
+    gimp_text_tool_editor (text_tool);
+}
+
+static void
 gimp_text_tool_editor (GimpTextTool *text_tool)
 {
   GimpTextOptions   *options = GIMP_TEXT_TOOL_GET_OPTIONS (text_tool);
@@ -952,7 +1454,8 @@
 
   text_tool->editor = gimp_text_options_editor_new (parent, options,
                                                     dialog_factory->menu_factory,
-                                                    _("GIMP Text Editor"));
+                                                    _("GIMP Text Editor"),
+                                                    text_tool->text_buffer);
 
   g_object_add_weak_pointer (G_OBJECT (text_tool->editor),
                              (gpointer) &text_tool->editor);
@@ -961,60 +1464,55 @@
                                    "gimp-text-tool-dialog",
                                    text_tool->editor);
 
-  if (text_tool->text)
-    gimp_text_editor_set_text (GIMP_TEXT_EDITOR (text_tool->editor),
-                               text_tool->text->text, -1);
-
-  g_signal_connect_object (text_tool->editor, "text-changed",
-                           G_CALLBACK (gimp_text_tool_text_changed),
-                           text_tool, 0);
-
   gtk_widget_show (text_tool->editor);
 }
 
-static void
-gimp_text_tool_editor_update (GimpTextTool *text_tool)
-{
-  gchar *str = NULL;
-
-  if (! text_tool->editor)
-    return;
-
-  if (text_tool->text)
-    g_object_get (text_tool->text, "text", &str, NULL);
-
-  g_signal_handlers_block_by_func (text_tool->editor,
-                                   gimp_text_tool_text_changed, text_tool);
-
-  gimp_text_editor_set_text (GIMP_TEXT_EDITOR (text_tool->editor),
-                             str, str ? -1 : 0);
-
-  g_signal_handlers_unblock_by_func (text_tool->editor,
-                                     gimp_text_tool_text_changed, text_tool);
-
-  g_free (str);
-}
-
-static void
-gimp_text_tool_text_changed (GimpTextEditor *editor,
-                             GimpTextTool   *text_tool)
+static gchar *
+gimp_text_tool_canvas_editor_get_text (GimpTextTool *text_tool)
 {
-  if (text_tool->text)
+  if (text_tool->text_buffer)
     {
-      gchar *text;
+      GtkTextIter  start, end;
+      GtkTextIter  selstart, selend;
+      gchar       *string;
+      gchar       *fb;
+      gchar       *lb;
+
+      gtk_text_buffer_get_bounds (text_tool->text_buffer, &start, &end);
+      gtk_text_buffer_get_selection_bounds (text_tool->text_buffer,
+                                            &selstart, &selend);
+
+      fb = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                     &start, &selstart, TRUE);
+      lb = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                     &selstart, &end, TRUE);
 
-      text = gimp_text_editor_get_text (GIMP_TEXT_EDITOR (text_tool->editor));
+      if (text_tool->preedit_string)
+        {
+          if (fb == NULL)
+            {
+              string = g_strconcat (text_tool->preedit_string, lb, NULL);
+            }
+          else
+            {
+              string = g_strconcat (fb, text_tool->preedit_string, lb, NULL);
+            }
+        }
+      else
+        {
+          string = g_strconcat (fb, lb, NULL);
+        }
 
-      g_object_set (text_tool->proxy, "text", text, NULL);
+      g_free (fb);
+      g_free (lb);
 
-      g_free (text);
-    }
-  else
-    {
-      gimp_text_tool_create_layer (text_tool, NULL);
+      return string;
     }
+
+  return NULL;
 }
 
+
 #define  RESPONSE_NEW 1
 
 static void
@@ -1041,7 +1539,7 @@
           if (text_tool->proxy)
             g_object_notify (G_OBJECT (text_tool->proxy), "text");
 
-          gimp_text_tool_editor (text_tool);
+          gimp_text_tool_canvas_editor (text_tool);
           break;
 
         default:
@@ -1268,7 +1766,7 @@
         {
           tool->drawable = GIMP_DRAWABLE (layer);
 
-          gimp_text_tool_editor (text_tool);
+          gimp_text_tool_canvas_editor (text_tool);
         }
     }
 }
@@ -1276,14 +1774,14 @@
 static gboolean
 gimp_text_tool_rectangle_change_complete (GimpRectangleTool *rect_tool)
 {
-  GimpTextTool   *text_tool     = GIMP_TEXT_TOOL (rect_tool);
-  GimpText       *text          = text_tool->text;
-  GimpImage      *image         = text_tool->image;
-  GimpItem       *item ;
-  gint            x1, y1, x2, y2;
+  GimpTextTool *text_tool = GIMP_TEXT_TOOL (rect_tool);
 
   if (text_tool->handle_rectangle_change_complete)
     {
+      GimpText *text = text_tool->text;
+      GimpItem *item;
+      gint      x1, y1, x2, y2;
+
       g_object_get (rect_tool,
                     "x1", &x1,
                     "y1", &y1,
@@ -1293,7 +1791,7 @@
 
       text_tool->text_box_fixed = TRUE;
 
-      if (! text)
+      if (! text || ! text->text || (text->text[0] == 0))
         {
           /*
            * we can't set properties for the text layer, because
@@ -1310,15 +1808,17 @@
                     "box-height", (gdouble) (y2 - y1),
                     NULL);
 
-      gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_TEXT,
-                               _("Reshape Text Layer"));
+      gimp_image_undo_group_start (text_tool->image, GIMP_UNDO_GROUP_TEXT,
+                                   _("Reshape Text Layer"));
+
       item = GIMP_ITEM (text_tool->layer);
       gimp_item_translate (item,
                            x1 - item->offset_x,
                            y1 - item->offset_y,
                            TRUE);
       gimp_text_tool_apply (text_tool);
-      gimp_image_undo_group_end (image);
+
+      gimp_image_undo_group_end (text_tool->image);
     }
 
   return TRUE;
@@ -1343,7 +1843,7 @@
 gimp_rectangle_tool_frame_item (GimpRectangleTool *rect_tool,
                                 GimpItem          *item)
 {
-  GimpDisplay *display  = GIMP_TOOL (rect_tool)->display;
+  GimpDisplay *display = GIMP_TOOL (rect_tool)->display;
   gint         offset_x;
   gint         offset_y;
   gint         width;
@@ -1371,8 +1871,7 @@
                 "y2", offset_y + height,
                 NULL);
 
-  /*
-   * kludge to force handle sizes to update.  This call may be
+  /* kludge to force handle sizes to update.  This call may be
    * harmful if this function is ever moved out of the text tool code.
    */
   gimp_rectangle_tool_set_constraint (rect_tool,
@@ -1381,3 +1880,443 @@
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (rect_tool));
 }
 
+static void
+gimp_text_tool_draw_preedit_lines (GimpDrawTool *draw_tool)
+{
+  GimpTextTool    *text_tool = GIMP_TEXT_TOOL (draw_tool);
+  PangoLayout     *layout;
+  PangoLayoutIter *line_iter;
+  GtkTextIter      cursor, start;
+  gint             i;
+  gint             min, max;
+  gchar           *string;
+
+  gtk_text_buffer_get_selection_bounds (text_tool->text_buffer, &cursor, NULL);
+  gtk_text_buffer_get_start_iter (text_tool->text_buffer, &start);
+
+  string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                     &start, &cursor, FALSE);
+  min = strlen (string);
+  g_free (string);
+
+  max = min + text_tool->preedit_len;
+
+  layout = text_tool->layout->layout;
+  line_iter = pango_layout_get_iter (layout);
+  i = 0;
+
+  do
+    {
+      gint firstline, lastline;
+      gint first_x,   last_x;
+
+      pango_layout_index_to_line_x (layout, min, 0, &firstline, &first_x);
+      pango_layout_index_to_line_x (layout, max, 0, &lastline, &last_x);
+
+      if (i >= firstline && i <= lastline)
+        {
+          PangoRectangle crect;
+
+          pango_layout_iter_get_line_extents (line_iter, NULL, &crect);
+          pango_extents_to_pixels (&crect, NULL);
+
+          gimp_draw_tool_draw_line (draw_tool,
+                                    crect.x, crect.y + crect.height,
+                                    crect.x + crect.width,
+                                    crect.y + crect.height,
+                                    TRUE);
+          if (i == firstline)
+            {
+              PangoRectangle crect2 = crect;
+
+              crect2.width = PANGO_PIXELS (first_x) - crect.x;
+              crect2.x     = crect.x;
+
+              gimp_draw_tool_draw_line (draw_tool,
+                                        crect2.x, crect2.y + crect2.height,
+                                        crect2.width,
+                                        crect2.y + crect2.height,
+                                        TRUE);
+            }
+          if (i == lastline)
+            {
+              PangoRectangle crect2 = crect;
+
+              crect2.width = crect.x + crect.width - PANGO_PIXELS (last_x);
+              crect2.x     = PANGO_PIXELS (last_x);
+
+              gimp_draw_tool_draw_line (draw_tool,
+                                        crect2.x, crect2.y + crect2.height,
+                                        crect2.x + crect2.width,
+                                        crect2.y + crect2.height,
+                                        TRUE);
+            }
+        }
+
+      i++;
+    }
+  while (pango_layout_iter_next_line (line_iter));
+
+  pango_layout_iter_free (line_iter);
+}
+
+static void
+gimp_text_tool_draw_text_selection (GimpDrawTool *draw_tool)
+{
+  GimpTextTool    *text_tool = GIMP_TEXT_TOOL (draw_tool);
+  PangoLayout     *layout;
+  PangoLayoutIter *line_iter;
+  GtkTextIter      start;
+  GtkTextIter      sel_start, sel_end;
+  gint             i;
+  gint             min, max;
+  gchar           *string;
+
+  gtk_text_buffer_get_selection_bounds (text_tool->text_buffer,
+                                        &sel_start, &sel_end);
+  gtk_text_buffer_get_start_iter (text_tool->text_buffer, &start);
+
+  string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                     &start, &sel_start, FALSE);
+  min = strlen (string);
+  g_free (string);
+
+  string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                     &start, &sel_end, FALSE);
+  max = strlen (string);
+  g_free (string);
+
+  layout = text_tool->layout->layout;
+  line_iter = pango_layout_get_iter (layout);
+  i = 0;
+
+  /* Invert the selected letters by inverting all
+   * lines containing selected letters, then
+   * invert the unselected letters on these lines
+   * a second time to make them look normal*/
+  do
+    {
+      gint firstline, lastline;
+      gint first_x,   last_x;
+
+      pango_layout_index_to_line_x (layout, min, 0, &firstline, &first_x);
+      pango_layout_index_to_line_x (layout, max, 0, &lastline, &last_x);
+
+      if (i >= firstline && i <= lastline)
+        {
+          PangoRectangle crect;
+
+          pango_layout_iter_get_line_extents (line_iter, NULL, &crect);
+          pango_extents_to_pixels (&crect, NULL);
+
+          gimp_draw_tool_draw_rectangle (draw_tool, TRUE,
+                                         crect.x, crect.y,
+                                         crect.width, crect.height,
+                                         TRUE);
+          if (i == firstline)
+            {
+              /* Twice invert all letters before the selection,
+               * making them look normal
+               */
+              PangoRectangle crect2 = crect;
+
+              crect2.width = PANGO_PIXELS (first_x) - crect.x;
+              crect2.x     = crect.x;
+
+              gimp_draw_tool_draw_rectangle (draw_tool, TRUE,
+                                             crect2.x, crect2.y,
+                                             crect2.width, crect2.height,
+                                             TRUE);
+            }
+          if (i == lastline)
+            {
+              /* Twice invert all letters after the selection,
+               * making them look normal
+               */
+              PangoRectangle crect2 = crect;
+
+              crect2.width = crect.x + crect.width - PANGO_PIXELS (last_x);
+              crect2.x     = PANGO_PIXELS (last_x);
+
+              gimp_draw_tool_draw_rectangle (draw_tool, TRUE,
+                                             crect2.x, crect2.y,
+                                             crect2.width, crect2.height,
+                                             TRUE);
+            }
+        }
+      i++;
+    }
+  while (pango_layout_iter_next_line (line_iter));
+  pango_layout_iter_free (line_iter);
+}
+
+static void
+gimp_text_tool_draw (GimpDrawTool *draw_tool)
+{
+  GimpTextTool     *text_tool   = GIMP_TEXT_TOOL (draw_tool);
+  GimpTool         *tool        = GIMP_TOOL (draw_tool);
+  GimpDisplayShell *shell;
+  GdkRectangle      cliprect;
+  gint              width, height;
+  gint              x1, x2, y1, y2;
+  GtkTextIter       start;
+
+  g_object_set (text_tool,
+                "narrow-mode", TRUE,
+                NULL);
+
+  gimp_rectangle_tool_draw (draw_tool);
+
+  if (!text_tool->layer) return;
+  if (!text_tool->layer->text) return;
+
+  /* There will be no layout if the function is called from the wrong place */
+  if (! text_tool->layout)
+    gimp_text_tool_update_layout (text_tool);
+
+  g_object_get (text_tool,
+                "x1", &x1,
+                "y1", &y1,
+                "x2", &x2,
+                "y2", &y2,
+                NULL);
+
+  /* Turn on clipping for text-cursor and selections */
+  cliprect.x = x1;
+  cliprect.width = x2 - x1;
+  cliprect.y = y1;
+  cliprect.height = y2 - y1;
+  gimp_canvas_set_clip_rect (GIMP_CANVAS (GIMP_DISPLAY_SHELL (tool->display->shell)->canvas),
+                             GIMP_CANVAS_STYLE_XOR, &cliprect);
+
+  gtk_text_buffer_get_start_iter (text_tool->text_buffer, &start);
+
+  if (! gtk_text_buffer_get_has_selection (text_tool->text_buffer))
+    {
+      /* If the text buffer has no selection, draw the text cursor */
+
+      gint           cursorx;
+      GtkTextIter    cursor;
+      PangoRectangle crect;
+      gchar          *string;
+
+      gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer, &cursor,
+                                        gtk_text_buffer_get_insert (text_tool->text_buffer));
+
+      string = gtk_text_buffer_get_text (text_tool->text_buffer,
+                                         &start, &cursor, FALSE);
+
+      /* Using strlen to get the byte index, not the character offset*/
+      cursorx = strlen (string);
+
+      /* TODO: make cursor position itself
+       * even inside preedits!*/
+      if (text_tool->preedit_len > 0)
+        cursorx += text_tool->preedit_len;
+
+      g_free (string);
+
+      pango_layout_index_to_pos (text_tool->layout->layout, cursorx, &crect);
+
+      crect.x = PANGO_PIXELS (crect.x);
+      crect.y = PANGO_PIXELS (crect.y);
+      crect.height = PANGO_PIXELS (crect.height);
+
+      gimp_draw_tool_draw_rectangle (draw_tool, TRUE,
+                                     crect.x, crect.y,
+                                     4, crect.height,
+                                     TRUE);
+
+      if (text_tool->preedit_string && text_tool->preedit_len > 0)
+          gimp_text_tool_draw_preedit_lines (draw_tool);
+    }
+  else
+    {
+      /* If the text buffer has a selection, highlight the
+       * selected letters*/
+
+      gimp_text_tool_draw_text_selection (draw_tool);
+    }
+
+  /* Turn off clipping when done */
+  shell = GIMP_DISPLAY_SHELL (tool->display->shell);
+  gimp_canvas_set_clip_rect (GIMP_CANVAS (shell->canvas),
+                             GIMP_CANVAS_STYLE_XOR, NULL);
+}
+
+static void
+gimp_text_tool_commit_cb (GtkIMContext *context,
+                          const gchar *str,
+                          GimpTextTool *text_tool)
+{
+  gimp_text_tool_enter_text (text_tool, str);
+}
+
+static void
+gimp_text_tool_reset_im_context (GimpTextTool *text_tool)
+{
+  if (text_tool->needs_im_reset)
+    {
+      text_tool->needs_im_reset = FALSE;
+      gtk_im_context_reset (text_tool->im_context);
+    }
+}
+
+static void
+gimp_text_tool_preedit_changed_cb (GtkIMContext *context,
+                                   GimpTextTool *text_tool)
+{
+  if (text_tool->preedit_string)
+    g_free (text_tool->preedit_string);
+
+  gtk_im_context_get_preedit_string (context,
+                                     &text_tool->preedit_string, NULL,
+                                     &text_tool->preedit_cursor);
+
+  text_tool->preedit_len = strlen (text_tool->preedit_string);
+
+  gimp_text_tool_update_proxy (text_tool);
+}
+
+static void
+gimp_text_tool_update_proxy (GimpTextTool *text_tool)
+{
+  if (text_tool->text)
+    {
+      gchar *string;
+
+      string = gimp_text_tool_canvas_editor_get_text (text_tool);
+
+      g_object_set (text_tool->proxy, "text",
+                    string, NULL);
+
+      g_free (string);
+    }
+  else
+    {
+      gimp_text_tool_create_layer (text_tool, NULL);
+    }
+}
+
+void
+gimp_text_tool_delete_text (GimpTextTool *text_tool)
+{
+  GtkTextIter cursor, start, end;
+
+  gtk_text_buffer_get_iter_at_mark (text_tool->text_buffer,
+                                    &cursor,
+                                    gtk_text_buffer_get_insert (text_tool->text_buffer));
+
+  if (gtk_text_buffer_get_has_selection (text_tool->text_buffer))
+    {
+      gtk_text_buffer_delete_selection (text_tool->text_buffer, TRUE, TRUE);
+    }
+  else
+    {
+      gtk_text_buffer_backspace (text_tool->text_buffer, &cursor, TRUE, TRUE);
+    }
+}
+
+static void
+gimp_text_tool_enter_text (GimpTextTool *text_tool,
+                           const gchar  *str)
+{
+  if (gtk_text_buffer_get_has_selection (text_tool->text_buffer))
+    {
+      gtk_text_buffer_delete_selection (text_tool->text_buffer, TRUE, TRUE);
+    }
+
+  gtk_text_buffer_insert_at_cursor (text_tool->text_buffer, str, -1);
+}
+
+static void
+gimp_text_tool_text_buffer_changed (GtkTextBuffer *text_buffer,
+                                    GimpTextTool  *text_tool)
+{
+  gimp_text_tool_update_proxy (text_tool);
+}
+
+static void
+gimp_text_tool_text_buffer_mark_set (GtkTextBuffer *text_buffer,
+                                     GtkTextIter   *iter,
+                                     GtkTextMark   *mark,
+                                     GimpTextTool  *text_tool)
+{
+  gimp_text_tool_update_layout (text_tool);
+/*   gimp_text_tool_update_proxy (text_tool); */
+}
+
+static void
+gimp_text_tool_update_layout (GimpTextTool *text_tool)
+{
+  GimpItem  *item;
+  GimpImage *image;
+
+  if (! text_tool->text)
+    {
+      gimp_text_tool_update_proxy (text_tool);
+      return;
+    }
+
+  if (text_tool->layout)
+    g_object_unref (text_tool->layout);
+
+  item = GIMP_ITEM (text_tool->layer);
+  image = gimp_item_get_image (item);
+
+  text_tool->layout = gimp_text_layout_new (text_tool->layer->text, image);
+}
+
+gboolean
+gimp_text_tool_get_has_text_selection (GimpTextTool *text_tool)
+{
+  if (text_tool->text_buffer)
+    return gtk_text_buffer_get_has_selection (text_tool->text_buffer);
+  else
+    return FALSE;
+}
+
+void
+gimp_text_tool_clipboard_cut (GimpTextTool *text_tool)
+{
+  GimpTool     *tool = GIMP_TOOL (text_tool);
+  GtkClipboard *clipboard;
+
+  clipboard = gtk_widget_get_clipboard (tool->display->shell,
+                                        GDK_SELECTION_CLIPBOARD);
+  gtk_text_buffer_cut_clipboard (text_tool->text_buffer, clipboard, TRUE);
+}
+
+void
+gimp_text_tool_clipboard_copy (GimpTextTool *text_tool,
+                               gboolean      use_clipboard)
+{
+  GimpTool     *tool = GIMP_TOOL (text_tool);
+  GtkClipboard *clipboard;
+
+  if (use_clipboard)
+    clipboard = gtk_widget_get_clipboard (tool->display->shell,
+                                          GDK_SELECTION_CLIPBOARD);
+  else
+    clipboard = gtk_widget_get_clipboard (tool->display->shell,
+                                          GDK_SELECTION_PRIMARY);
+
+  gtk_text_buffer_copy_clipboard (text_tool->text_buffer, clipboard);
+}
+
+void
+gimp_text_tool_clipboard_paste (GimpTextTool *text_tool,
+                                gboolean      use_clipboard)
+{
+  GimpTool     *tool = GIMP_TOOL (text_tool);
+  GtkClipboard *clipboard;
+
+  if (use_clipboard)
+    clipboard = gtk_widget_get_clipboard (tool->display->shell,
+                                          GDK_SELECTION_CLIPBOARD);
+  else
+    clipboard = gtk_widget_get_clipboard (tool->display->shell,
+                                          GDK_SELECTION_PRIMARY);
+
+  gtk_text_buffer_paste_clipboard (text_tool->text_buffer, clipboard, NULL, TRUE);
+}

Modified: trunk/app/tools/gimptexttool.h
==============================================================================
--- trunk/app/tools/gimptexttool.h	(original)
+++ trunk/app/tools/gimptexttool.h	Sun Oct 26 17:39:55 2008
@@ -37,24 +37,37 @@
 
 struct _GimpTextTool
 {
-  GimpDrawTool   parent_instance;
+  GimpDrawTool    parent_instance;
 
-  GimpText      *proxy;
-  GList         *pending;
-  guint          idle_id;
+  GimpText       *proxy;
+  GList          *pending;
+  guint           idle_id;
 
-  gint           x1, y1;
-  gint           x2, y2;
+  gint            x1, y1;
+  gint            x2, y2;
 
-  GimpText      *text;
-  GimpTextLayer *layer;
-  GimpImage     *image;
+  GtkTextBuffer  *text_buffer;
 
-  GtkWidget     *editor;
-  GtkWidget     *confirm_dialog;
+  GimpText       *text;
+  GimpTextLayer  *layer;
+  GimpImage      *image;
 
-  gboolean       handle_rectangle_change_complete;
-  gboolean       text_box_fixed;
+  GtkWidget      *editor;
+  GtkWidget      *confirm_dialog;
+  GimpUIManager  *ui_manager;
+  GtkIMContext   *im_context;
+
+  gboolean        needs_im_reset;
+
+  gchar          *preedit_string;
+  gint            preedit_len;
+  gint            preedit_cursor;
+
+  gboolean        handle_rectangle_change_complete;
+  gboolean        text_box_fixed;
+  gboolean        text_cursor_changing;
+
+  GimpTextLayout *layout;
 };
 
 struct _GimpTextToolClass
@@ -63,13 +76,23 @@
 };
 
 
-void    gimp_text_tool_register  (GimpToolRegisterCallback  callback,
-                                  gpointer                  data);
+void       gimp_text_tool_register               (GimpToolRegisterCallback  callback,
+                                                  gpointer                  data);
+
+GType      gimp_text_tool_get_type               (void) G_GNUC_CONST;
+
+void       gimp_text_tool_set_layer              (GimpTextTool *text_tool,
+                                                  GimpLayer    *layer);
 
-GType   gimp_text_tool_get_type  (void) G_GNUC_CONST;
+void       gimp_text_tool_delete_text            (GimpTextTool *text_tool);
+void       gimp_text_tool_clipboard_cut          (GimpTextTool *text_tool);
+void       gimp_text_tool_clipboard_copy         (GimpTextTool *text_tool,
+                                                  gboolean      use_clipboard);
+void       gimp_text_tool_clipboard_paste        (GimpTextTool *text_tool,
+                                                  gboolean      use_clipboard);
 
-void    gimp_text_tool_set_layer (GimpTextTool *text_tool,
-                                  GimpLayer    *layer);
+gboolean   gimp_text_tool_get_has_text_selection (GimpTextTool *text_tool);
+void       gimp_text_tool_create_vectors         (GimpTextTool *text_tool);
 
 
 #endif /* __GIMP_TEXT_TOOL_H__ */

Modified: trunk/app/widgets/gimptexteditor.c
==============================================================================
--- trunk/app/widgets/gimptexteditor.c	(original)
+++ trunk/app/widgets/gimptexteditor.c	Sun Oct 26 17:39:55 2008
@@ -129,10 +129,10 @@
 GtkWidget *
 gimp_text_editor_new (const gchar     *title,
                       GtkWindow       *parent,
-                      GimpMenuFactory *menu_factory)
+                      GimpMenuFactory *menu_factory,
+                      GtkTextBuffer   *text_buffer)
 {
   GimpTextEditor *editor;
-  GtkTextBuffer  *buffer;
   GtkWidget      *toolbar;
   GtkWidget      *scrolled_window;
 
@@ -155,6 +155,10 @@
                     G_CALLBACK (gtk_widget_destroy),
                     NULL);
 
+  g_signal_connect_object (text_buffer, "changed",
+                           G_CALLBACK (gimp_text_editor_text_changed),
+                           editor, 0);
+
   editor->ui_manager = gimp_menu_factory_manager_new (menu_factory,
                                                       "<TextEditor>",
                                                       editor, FALSE);
@@ -206,18 +210,12 @@
                       scrolled_window, TRUE, TRUE, 0);
   gtk_widget_show (scrolled_window);
 
-  editor->view = gtk_text_view_new ();
+  editor->view = gtk_text_view_new_with_buffer (text_buffer);
   gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (editor->view),
                                GTK_WRAP_WORD_CHAR);
   gtk_container_add (GTK_CONTAINER (scrolled_window), editor->view);
   gtk_widget_show (editor->view);
 
-  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->view));
-
-  g_signal_connect (buffer, "changed",
-                    G_CALLBACK (gimp_text_editor_text_changed),
-                    editor);
-
   switch (editor->base_dir)
     {
     case GIMP_TEXT_DIRECTION_LTR:

Modified: trunk/app/widgets/gimptexteditor.h
==============================================================================
--- trunk/app/widgets/gimptexteditor.h	(original)
+++ trunk/app/widgets/gimptexteditor.h	Sun Oct 26 17:39:55 2008
@@ -56,7 +56,8 @@
 GType               gimp_text_editor_get_type      (void) G_GNUC_CONST;
 GtkWidget         * gimp_text_editor_new           (const gchar       *title,
                                                     GtkWindow         *parent,
-                                                    GimpMenuFactory   *menu_factory);
+                                                    GimpMenuFactory   *menu_factory,
+                                                    GtkTextBuffer     *text_buffer);
 
 void                gimp_text_editor_set_text      (GimpTextEditor    *editor,
                                                     const gchar       *text,

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sun Oct 26 17:39:55 2008
@@ -45,6 +45,7 @@
 m4_define([glib_required_version], [2.16.1])
 m4_define([gtk_required_version], [2.12.5])
 m4_define([gdk_pixbuf_required_version], [gtk_required_version])
+m4_define([pangocairo_required_version], [1.20.1])
 m4_define([pangoft2_required_version], [1.18.0])
 m4_define([fontconfig_required_version], [2.2.0])
 m4_define([cairo_required_version], [1.4.10])
@@ -496,6 +497,14 @@
 
 PKG_CHECK_MODULES(CAIRO, cairo >= cairo_required_version)
 
+PKG_CHECK_MODULES(PANGOCAIRO, pangocairo >= pangocairo_required_version, :,
+  AC_MSG_ERROR([Test for PangoCairo failed.
+*** We require Pango with the optional support for Cairo compiled in.
+*** See the file 'INSTALL' for more help.]))
+
+CFLAGS=$gimp_save_CFLAGS
+CFLAGS="$PANGOCAIRO_CFLAGS $CFLAGS"
+
 PKG_CHECK_MODULES(FONTCONFIG, fontconfig >= fontconfig_required_version)
 
 PKG_CHECK_MODULES(PANGOFT2, pangoft2 >= pangoft2_required_version, :,
@@ -536,6 +545,7 @@
 *** the same as the result here.])
 fi
 
+
 AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no)
 if test "x$FREETYPE_CONFIG" != "xno" ; then
   AC_MSG_CHECKING([for freetype libraries])

Modified: trunk/menus/Makefile.am
==============================================================================
--- trunk/menus/Makefile.am	(original)
+++ trunk/menus/Makefile.am	Sun Oct 26 17:39:55 2008
@@ -31,6 +31,7 @@
 	selection-menu.xml		\
 	templates-menu.xml		\
 	text-editor-toolbar.xml		\
+	text-tool-menu.xml		\
 	tool-options-menu.xml		\
 	tools-menu.xml			\
 	undo-menu.xml			\

Added: trunk/menus/text-tool-menu.xml
==============================================================================
--- (empty file)
+++ trunk/menus/text-tool-menu.xml	Sun Oct 26 17:39:55 2008
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE ui SYSTEM "gtkuimanager.dtd">
+
+<ui>
+  <popup action="text-tool-popup">
+    <menuitem action="text-tool-cut" />
+    <menuitem action="text-tool-copy" />
+    <menuitem action="text-tool-paste" />
+    <menuitem action="text-tool-delete" />
+    <separator />
+    <menuitem action="text-tool-load" />
+    <menuitem action="text-tool-clear" />
+    <separator />
+    <menuitem action="text-tool-path-from-text" />
+    <separator />
+    <menuitem action="text-tool-direction-ltr" />
+    <menuitem action="text-tool-direction-rtl" />
+    <separator />
+    <menu action="text-tool-input-methods">
+    </menu>
+  </popup>
+</ui>



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