[gimp] app: make manual kerning / character spacing work



commit f8ac0c61ab568949c56380c1ec30ce518216b538
Author: Michael Natterer <mitch gimp org>
Date:   Mon Mar 1 16:27:34 2010 +0100

    app: make manual kerning / character spacing work
    
    Add gimp_text_buffer_get_iter_at_index() which does the reverse thing
    than the already existing function gimp_text_buffer_get_iter_index().
    Use the new function when cursor-navigation lines. Add "gboolean
    layout_index" to both functions, which if TRUE indicates that the
    passed in/out index is an index into the PangoLayout's content rather
    than the text buffer's. When dealing with layout indices, take into
    account the additional characters we insert into the serialized markup
    (and thus the layout) for each character that is tagged with spacing.

 app/tools/gimptexttool-editor.c |   16 ++----
 app/tools/gimptexttool.c        |    4 +-
 app/widgets/gimptextbuffer.c    |  108 +++++++++++++++++++++++++++++++++++++-
 app/widgets/gimptextbuffer.h    |    7 ++-
 4 files changed, 118 insertions(+), 17 deletions(-)
---
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
index ab7676c..21319e7 100644
--- a/app/tools/gimptexttool-editor.c
+++ b/app/tools/gimptexttool-editor.c
@@ -560,7 +560,8 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool   *text_tool,
 
   gtk_text_buffer_get_iter_at_mark (buffer, &cursor,
                                     gtk_text_buffer_get_insert (buffer));
-  cursor_index = gimp_text_buffer_get_iter_index (text_tool->buffer, &cursor);
+  cursor_index = gimp_text_buffer_get_iter_index (text_tool->buffer, &cursor,
+                                                  TRUE);
 
   pango_layout_index_to_pos (layout, cursor_index, cursor_rect);
   gimp_text_layout_transform_rect (text_tool->layout, cursor_rect);
@@ -719,7 +720,6 @@ gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
       {
         GtkTextIter      start;
         GtkTextIter      end;
-        gchar           *string;
         gint             cursor_index;
         PangoLayout     *layout;
         PangoLayoutLine *layout_line;
@@ -732,7 +732,7 @@ gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
         gtk_text_buffer_get_bounds (buffer, &start, &end);
 
         cursor_index = gimp_text_buffer_get_iter_index (text_tool->buffer,
-                                                        &cursor);
+                                                        &cursor, TRUE);
 
         gimp_text_tool_ensure_layout (text_tool);
 
@@ -783,14 +783,8 @@ gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
         pango_layout_line_x_to_index (layout_line, x_pos - logical.x,
                                       &cursor_index, &trailing);
 
-        string = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
-
-        string[cursor_index] = '\0';
-
-        gtk_text_buffer_get_iter_at_offset (buffer, &cursor,
-                                            g_utf8_strlen (string, -1));
-
-        g_free (string);
+        gimp_text_buffer_get_iter_at_index (text_tool->buffer, &cursor,
+                                            cursor_index, TRUE);
 
         while (trailing--)
           gtk_text_iter_forward_char (&cursor);
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 20ac045..ce11b51 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -759,8 +759,8 @@ gimp_text_tool_draw_selection (GimpDrawTool *draw_tool,
 
   gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end);
 
-  min = gimp_text_buffer_get_iter_index (text_tool->buffer, &sel_start);
-  max = gimp_text_buffer_get_iter_index (text_tool->buffer, &sel_end);
+  min = gimp_text_buffer_get_iter_index (text_tool->buffer, &sel_start, TRUE);
+  max = gimp_text_buffer_get_iter_index (text_tool->buffer, &sel_end, TRUE);
 
   layout = gimp_text_layout_get_pango_layout (text_tool->layout);
 
diff --git a/app/widgets/gimptextbuffer.c b/app/widgets/gimptextbuffer.c
index cab2399..b4f27c5 100644
--- a/app/widgets/gimptextbuffer.c
+++ b/app/widgets/gimptextbuffer.c
@@ -51,6 +51,9 @@
 #include "gimp-intl.h"
 
 
+/* #define ENABLE_SPACING */
+
+
 /*  local function prototypes  */
 
 static GObject * gimp_text_buffer_constructor (GType                  type,
@@ -242,7 +245,7 @@ gimp_text_buffer_set_markup (GimpTextBuffer *buffer,
         {
           GtkTextIter start, end;
 
-#if 0
+#ifdef ENABLE_SPACING
           gimp_text_buffer_post_deserialize (buffer, content);
 #endif
 
@@ -277,7 +280,7 @@ gimp_text_buffer_get_markup (GimpTextBuffer *buffer)
 
   gtk_text_buffer_insert_range (content, &insert, &start, &end);
 
-#if 0
+#ifdef ENABLE_SPACING
   gimp_text_buffer_pre_serialize (buffer, content);
 #endif
 
@@ -755,7 +758,8 @@ gimp_text_buffer_insert (GimpTextBuffer *buffer,
 
 gint
 gimp_text_buffer_get_iter_index (GimpTextBuffer *buffer,
-                                 GtkTextIter    *iter)
+                                 GtkTextIter    *iter,
+                                 gboolean        layout_index)
 {
   GtkTextIter  start;
   gchar       *string;
@@ -770,9 +774,107 @@ gimp_text_buffer_get_iter_index (GimpTextBuffer *buffer,
   index = strlen (string);
   g_free (string);
 
+#ifdef ENABLE_SPACING
+  if (layout_index)
+    {
+      do
+        {
+          GSList *tags = gtk_text_iter_get_tags (&start);
+          GSList *list;
+
+          for (list = tags; list; list = g_slist_next (list))
+            {
+              GtkTextTag *tag = list->data;
+
+              if (g_list_find (buffer->spacing_tags, tag))
+                {
+                  index += strlen ("\342\200\215");
+
+                  break;
+                }
+            }
+
+          g_slist_free (tags);
+
+          gtk_text_iter_forward_char (&start);
+
+          /* We might have moved too far */
+          if (gtk_text_iter_compare (&start, iter) > 0)
+            start = *iter;
+        }
+      while (! gtk_text_iter_equal (&start, iter));
+    }
+#endif
+
   return index;
 }
 
+void
+gimp_text_buffer_get_iter_at_index (GimpTextBuffer *buffer,
+                                    GtkTextIter    *iter,
+                                    gint            index,
+                                    gboolean        layout_index)
+{
+  GtkTextIter  start;
+  GtkTextIter  end;
+  gchar       *string;
+
+  g_return_if_fail (GIMP_IS_TEXT_BUFFER (buffer));
+
+  gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (buffer), &start, &end);
+
+  string = gtk_text_buffer_get_text (GTK_TEXT_BUFFER (buffer),
+                                     &start, &end, TRUE);
+
+#ifdef ENABLE_SPACING
+  if (layout_index)
+    {
+      gchar *my_string = string;
+      gint   my_index  = 0;
+      gchar *tmp;
+
+      do
+        {
+          GSList *tags = gtk_text_iter_get_tags (&start);
+          GSList *list;
+
+          tmp = g_utf8_next_char (my_string);
+          my_index += (tmp - my_string);
+          my_string = tmp;
+
+          for (list = tags; list; list = g_slist_next (list))
+            {
+              GtkTextTag *tag = list->data;
+
+              if (g_list_find (buffer->spacing_tags, tag))
+                {
+                  index -= strlen ("\342\200\215");
+
+                  break;
+                }
+            }
+
+          g_slist_free (tags);
+
+          gtk_text_iter_forward_char (&start);
+
+          /* We might have moved too far */
+          if (gtk_text_iter_compare (&start, &end) > 0)
+            start = end;
+        }
+      while (my_index < index &&
+             ! gtk_text_iter_equal (&start, &end));
+    }
+#endif
+
+  string[index] = '\0';
+
+  gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (buffer), iter,
+                                      g_utf8_strlen (string, -1));
+
+  g_free (string);
+}
+
 gboolean
 gimp_text_buffer_load (GimpTextBuffer *buffer,
                        const gchar    *filename,
diff --git a/app/widgets/gimptextbuffer.h b/app/widgets/gimptextbuffer.h
index a21838f..02055b4 100644
--- a/app/widgets/gimptextbuffer.h
+++ b/app/widgets/gimptextbuffer.h
@@ -92,7 +92,12 @@ void             gimp_text_buffer_insert            (GimpTextBuffer    *buffer,
                                                      const gchar       *text);
 
 gint             gimp_text_buffer_get_iter_index    (GimpTextBuffer    *buffer,
-                                                     GtkTextIter       *iter);
+                                                     GtkTextIter       *iter,
+                                                     gboolean           layout_index);
+void             gimp_text_buffer_get_iter_at_index (GimpTextBuffer    *buffer,
+                                                     GtkTextIter       *iter,
+                                                     gint               index,
+                                                     gboolean           layout_index);
 
 gboolean         gimp_text_buffer_load              (GimpTextBuffer    *buffer,
                                                      const gchar       *filename,



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