[gimp] app: fix XOR cursor drawing artifacts



commit f9bee0d42fa1d760bc3738d8b15aaf0b1699000e
Author: Michael Natterer <mitch gimp org>
Date:   Tue Feb 23 23:14:09 2010 +0100

    app: fix XOR cursor drawing artifacts
    
    Switch to a completely new PangoLayout managing stategy: The drawing
    code relies on text_tool->layout being a view on text_tool->text_buffer,
    if they get out of sync, drawing is b0rk.
    
    Therefore, split the update_layout() function into clear_layout()
    (which kill the layout) and ensure_layout() (which creates the layout
    if it doesn't exist).
    
    Whenever the buffer gets modified, pause the draw tool before the
    modification so the old cursor/selection undraw, then clear the
    layout. Resuming the draw tool will automatically re-create the layout
    for the buffer's new contents.
    
    Also switch off any clipping for cursor and selection, so we can at
    least see that our input has some effect, even if we don't actually
    see the edited text because it's out-of-layer.

 app/tools/gimptexttool-editor.c |   12 ++++---
 app/tools/gimptexttool.c        |   70 +++++++++++++++-----------------------
 app/tools/gimptexttool.h        |    3 +-
 3 files changed, 37 insertions(+), 48 deletions(-)
---
diff --git a/app/tools/gimptexttool-editor.c b/app/tools/gimptexttool-editor.c
index 56ba119..b134cf0 100644
--- a/app/tools/gimptexttool-editor.c
+++ b/app/tools/gimptexttool-editor.c
@@ -471,8 +471,7 @@ gimp_text_tool_editor_get_cursor_rect (GimpTextTool   *text_tool,
   g_return_if_fail (GIMP_IS_TEXT_TOOL (text_tool));
   g_return_if_fail (cursor_rect != NULL);
 
-  if (! text_tool->layout)
-    gimp_text_tool_update_layout (text_tool);
+  gimp_text_tool_ensure_layout (text_tool);
 
   layout = gimp_text_layout_get_pango_layout (text_tool->layout);
 
@@ -664,6 +663,8 @@ gimp_text_tool_move_cursor (GimpTextTool    *text_tool,
         cursor_index = strlen (string);
         g_free (string);
 
+        gimp_text_tool_ensure_layout (text_tool);
+
         layout = gimp_text_layout_get_pango_layout (text_tool->layout);
 
         pango_layout_index_to_line_x (layout, cursor_index, FALSE,
@@ -782,8 +783,7 @@ gimp_text_tool_insert_at_cursor (GimpTextTool *text_tool,
 {
   gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
 
-  gtk_text_buffer_insert_interactive_at_cursor (text_tool->text_buffer,
-                                                str, -1, TRUE);
+  gtk_text_buffer_insert_at_cursor (text_tool->text_buffer, str, -1);
 
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
 }
@@ -912,7 +912,7 @@ gimp_text_tool_delete_from_cursor (GimpTextTool  *text_tool,
     {
       gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
 
-      gtk_text_buffer_delete_interactive (buffer, &cursor, &end, TRUE);
+      gtk_text_buffer_delete (buffer, &cursor, &end);
 
       gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
     }
@@ -1097,6 +1097,8 @@ gimp_text_tool_xy_to_offset (GimpTextTool *text_tool,
   gint            offset;
   gint            trailing;
 
+  gimp_text_tool_ensure_layout (text_tool);
+
   gimp_text_layout_untransform_point (text_tool->layout, &x, &y);
 
   /*  adjust to offset of logical rect  */
diff --git a/app/tools/gimptexttool.c b/app/tools/gimptexttool.c
index 9bcc967..e6e9c24 100644
--- a/app/tools/gimptexttool.c
+++ b/app/tools/gimptexttool.c
@@ -444,9 +444,6 @@ gimp_text_tool_button_press (GimpTool            *tool,
 
           if (text_tool->text)
             {
-              if (! text_tool->layout)
-                gimp_text_tool_update_layout (text_tool);
-
               gimp_text_tool_editor_button_press (text_tool, x, y, press_type);
             }
           else
@@ -558,7 +555,7 @@ gimp_text_tool_motion (GimpTool         *tool,
     {
       gimp_rectangle_tool_motion (tool, coords, time, state, display);
     }
-  else if (text_tool->layout)
+  else
     {
       GimpItem *item = GIMP_ITEM (text_tool->layer);
       gdouble   x    = coords->x - gimp_item_get_offset_x (item);
@@ -726,30 +723,9 @@ gimp_text_tool_draw (GimpDrawTool *draw_tool)
     {
       /* If the text buffer has a selection, highlight the selected letters */
 
-      GdkRectangle clip_rect;
-      gint         x1, x2;
-      gint         y1, y2;
-
-      /* Turn on clipping for selections */
-      g_object_get (text_tool,
-                    "x1", &x1,
-                    "y1", &y1,
-                    "x2", &x2,
-                    "y2", &y2,
-                    NULL);
-
-      clip_rect.x      = x1;
-      clip_rect.width  = x2 - x1;
-      clip_rect.y      = y1;
-      clip_rect.height = y2 - y1;
-
-      gimp_draw_tool_set_clip_rect (draw_tool, &clip_rect, FALSE);
-
       gimp_text_tool_draw_selection (draw_tool,
                                      logical_offset_x, logical_offset_y);
 
-      /* Turn off clipping when done */
-      gimp_draw_tool_set_clip_rect (draw_tool, NULL, FALSE);
     }
   else
     {
@@ -922,12 +898,6 @@ gimp_text_tool_halt (GimpTextTool *text_tool)
 
   gimp_text_tool_set_drawable (text_tool, NULL, FALSE);
 
-  if (text_tool->layout)
-    {
-      g_object_unref (text_tool->layout);
-      text_tool->layout = NULL;
-    }
-
   gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
 }
 
@@ -962,6 +932,8 @@ gimp_text_tool_connect (GimpTextTool  *text_tool,
 
           g_object_set (text_tool->proxy, "text", NULL, NULL);
           gtk_text_buffer_set_text (text_tool->text_buffer, "", -1);
+
+          gimp_text_tool_clear_layout (text_tool);
         }
 
       gimp_context_define_property (GIMP_CONTEXT (options),
@@ -973,6 +945,8 @@ gimp_text_tool_connect (GimpTextTool  *text_tool,
           gimp_config_sync (G_OBJECT (text), G_OBJECT (text_tool->proxy), 0);
           gtk_text_buffer_set_text (text_tool->text_buffer, text->text, -1);
 
+          gimp_text_tool_clear_layout (text_tool);
+
           text_tool->text = g_object_ref (text);
 
           g_signal_connect (text, "notify",
@@ -1040,6 +1014,8 @@ gimp_text_tool_text_notify (GimpText     *text,
 {
   g_return_if_fail (text == text_tool->text);
 
+  gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
   if ((pspec->flags & G_PARAM_READWRITE) == G_PARAM_READWRITE)
     {
       GValue value = { 0, };
@@ -1080,10 +1056,11 @@ gimp_text_tool_text_notify (GimpText     *text,
       g_signal_handlers_unblock_by_func (text_tool->text_buffer,
                                          gimp_text_tool_buffer_changed,
                                          text_tool);
-
-      /* force change of cursor and selection display */
-      gimp_text_tool_update_layout (text_tool);
     }
+
+  gimp_text_tool_clear_layout (text_tool);
+
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
 }
 
 static gboolean
@@ -1166,6 +1143,8 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
         }
     }
 
+  gimp_draw_tool_pause (GIMP_DRAW_TOOL (text_tool));
+
   if (push_undo)
     {
       if (layer->modified)
@@ -1232,7 +1211,9 @@ gimp_text_tool_apply (GimpTextTool *text_tool)
 
   gimp_image_flush (image);
 
-  gimp_text_tool_update_layout (text_tool);
+  gimp_text_tool_clear_layout (text_tool);
+
+  gimp_draw_tool_resume (GIMP_DRAW_TOOL (text_tool));
 }
 
 static void
@@ -1553,16 +1534,21 @@ gimp_text_tool_buffer_changed (GtkTextBuffer *text_buffer,
 }
 
 void
-gimp_text_tool_update_layout (GimpTextTool *text_tool)
+gimp_text_tool_clear_layout (GimpTextTool *text_tool)
 {
-  if (text_tool->text)
+  if (text_tool->layout)
     {
-      GimpImage *image;
-
-      if (text_tool->layout)
-        g_object_unref (text_tool->layout);
+      g_object_unref (text_tool->layout);
+      text_tool->layout = NULL;
+    }
+}
 
-      image = gimp_item_get_image (GIMP_ITEM (text_tool->layer));
+void
+gimp_text_tool_ensure_layout (GimpTextTool *text_tool)
+{
+  if (! text_tool->layout && text_tool->text)
+    {
+      GimpImage *image = gimp_item_get_image (GIMP_ITEM (text_tool->layer));
 
       text_tool->layout = gimp_text_layout_new (text_tool->layer->text, image);
     }
diff --git a/app/tools/gimptexttool.h b/app/tools/gimptexttool.h
index 0e484e6..a61d257 100644
--- a/app/tools/gimptexttool.h
+++ b/app/tools/gimptexttool.h
@@ -113,7 +113,8 @@ void       gimp_text_tool_create_vectors         (GimpTextTool *text_tool);
 void       gimp_text_tool_create_vectors_warped  (GimpTextTool *text_tool);
 
 /*  only for the text editor  */
-void       gimp_text_tool_update_layout          (GimpTextTool *text_tool);
+void       gimp_text_tool_clear_layout           (GimpTextTool *text_tool);
+void       gimp_text_tool_ensure_layout          (GimpTextTool *text_tool);
 
 
 #endif /* __GIMP_TEXT_TOOL_H__ */



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