[gtk+] Rework GtkTextView cursor code.



commit 0bff1af7a20948a7275a4e9e1fa3fac903a422f8
Author: Paolo Borelli <pborelli gnome org>
Date:   Sat Nov 26 23:48:10 2011 +0100

    Rework GtkTextView cursor code.
    
    Move the handling of primary/secondary cursors to gtktextdisplay, which
    makes code simpler and more consistent to how GtkLabel and GtkEntry
    draw cursors, which is useful in preparation to further refactoring.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=640317

 gtk/gtktextdisplay.c |   86 +++++++++++++++++++++++++------------------------
 gtk/gtktextlayout.c  |   56 +++-----------------------------
 gtk/gtktextlayout.h  |   11 +------
 3 files changed, 51 insertions(+), 102 deletions(-)
---
diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c
index 360f515..6911dae 100644
--- a/gtk/gtktextdisplay.c
+++ b/gtk/gtktextdisplay.c
@@ -822,7 +822,6 @@ gtk_text_layout_draw (GtkTextLayout *layout,
                       GList **widgets)
 {
   gint offset_y;
-  GSList *cursor_list;
   GtkTextRenderer *text_renderer;
   GtkTextIter selection_start, selection_end;
   gboolean have_selection;
@@ -862,8 +861,6 @@ gtk_text_layout_draw (GtkTextLayout *layout,
       GtkTextLineDisplay *line_display;
       gint selection_start_index = -1;
       gint selection_end_index = -1;
-      gboolean have_strong;
-      gboolean have_weak;
 
       GtkTextLine *line = tmp_list->data;
 
@@ -905,47 +902,52 @@ gtk_text_layout_draw (GtkTextLayout *layout,
                        selection_start_index, selection_end_index);
 
           /* We paint the cursors last, because they overlap another chunk
-         and need to appear on top. */
-
- 	  have_strong = FALSE;
- 	  have_weak = FALSE;
-	  
-	  cursor_list = line_display->cursors;
-	  while (cursor_list)
-	    {
-	      GtkTextCursorDisplay *cursor = cursor_list->data;
- 	      if (cursor->is_strong)
- 		have_strong = TRUE;
- 	      else
- 		have_weak = TRUE;
-	      
-	      cursor_list = cursor_list->next;
- 	    }
-	  
-          cursor_list = line_display->cursors;
-          while (cursor_list)
+           * and need to appear on top.
+           */
+          if (line_display->cursors != NULL)
             {
-              GtkTextCursorDisplay *cursor = cursor_list->data;
-	      GtkTextDirection dir;
- 	      GdkRectangle cursor_location;
-
-              dir = line_display->direction;
- 	      if (have_strong && have_weak)
- 		{
- 		  if (!cursor->is_strong)
- 		    dir = (dir == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
- 		}
- 
- 	      cursor_location.x = line_display->x_offset + cursor->x;
- 	      cursor_location.y = line_display->top_margin + cursor->y;
- 	      cursor_location.width = 0;
- 	      cursor_location.height = cursor->height;
+              int i;
 
-	      gtk_draw_insertion_cursor (widget, cr, &cursor_location,
-                                         cursor->is_strong,
-                                         dir, have_strong && have_weak);
-
-              cursor_list = cursor_list->next;
+              for (i = 0; i < line_display->cursors->len; i++)
+                {
+                  int index;
+                  PangoRectangle strong_pos, weak_pos;
+                  GdkRectangle cursor_location;
+
+                  index = g_array_index(line_display->cursors, int, i);
+                  pango_layout_get_cursor_pos (line_display->layout, index, &strong_pos, &weak_pos);
+
+                  cursor_location.x = line_display->x_offset + PANGO_PIXELS (strong_pos.x);
+                  cursor_location.y = line_display->top_margin + PANGO_PIXELS (strong_pos.y);
+                  cursor_location.width = 0;
+                  cursor_location.height = PANGO_PIXELS (strong_pos.height);
+
+                  if (layout->cursor_direction == GTK_TEXT_DIR_NONE ||
+                      line_display->direction == layout->cursor_direction)
+                    {
+                      gtk_draw_insertion_cursor (widget, cr,
+                                                 &cursor_location, TRUE, line_display->direction,
+                                                 layout->cursor_direction != GTK_TEXT_DIR_NONE);
+                    }
+
+                  if ((strong_pos.x != weak_pos.x || strong_pos.y != weak_pos.y) &&
+                      (layout->cursor_direction == GTK_TEXT_DIR_NONE ||
+                       line_display->direction != layout->cursor_direction))
+                    {
+                      GtkTextDirection dir;
+
+                      dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
+
+                      cursor_location.x = line_display->x_offset + PANGO_PIXELS (weak_pos.x);
+                      cursor_location.y = line_display->top_margin + PANGO_PIXELS (weak_pos.y);
+                      cursor_location.width = 0;
+                      cursor_location.height = PANGO_PIXELS (weak_pos.height);
+
+                      gtk_draw_insertion_cursor (widget, cr,
+                                                 &cursor_location, FALSE, dir,
+                                                 TRUE);
+                    }
+                }
             }
         } /* line_display->height > 0 */
           
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 7d48a3d..a78886a 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -827,8 +827,8 @@ gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
 
       if (cursors_only)
 	{
-	  g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
-	  g_slist_free (display->cursors);
+          if (display->cursors)
+            g_array_free (display->cursors, TRUE);
 	  display->cursors = NULL;
 	  display->cursors_invalid = TRUE;
 	  display->has_block_cursor = FALSE;
@@ -1733,11 +1733,6 @@ add_cursor (GtkTextLayout      *layout,
             GtkTextLineSegment *seg,
             gint                start)
 {
-  PangoRectangle strong_pos, weak_pos;
-  GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */
-  gboolean add_weak = FALSE;
-  gboolean add_strong = FALSE;
-  
   /* Hide insertion cursor when we have a selection or the layout
    * user has hidden the cursor.
    */
@@ -1767,46 +1762,10 @@ add_cursor (GtkTextLayout      *layout,
 	}
     }
 
-  pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos);
-
-  if (layout->cursor_direction == GTK_TEXT_DIR_NONE)
-    {
-      add_strong = TRUE;
-      add_weak = TRUE;
-    }
-  else if (display->direction == layout->cursor_direction)
-    add_strong = TRUE;
-  else
-    add_weak = TRUE;
+  if (!display->cursors)
+    display->cursors = g_array_new (FALSE, FALSE, sizeof(int));
 
-  if (add_strong)
-    {
-      cursor = g_new (GtkTextCursorDisplay, 1);
-
-      cursor->x = PANGO_PIXELS (strong_pos.x);
-      cursor->y = PANGO_PIXELS (strong_pos.y);
-      cursor->height = PANGO_PIXELS (strong_pos.height);
-      cursor->is_strong = TRUE;
-      cursor->is_weak = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
-      display->cursors = g_slist_prepend (display->cursors, cursor);
-    }
-  
-  if (add_weak)
-    {
-      if (weak_pos.x == strong_pos.x && add_strong)
-	cursor->is_weak = TRUE;
-      else
-	{
-	  cursor = g_new (GtkTextCursorDisplay, 1);
-	  
-	  cursor->x = PANGO_PIXELS (weak_pos.x);
-	  cursor->y = PANGO_PIXELS (weak_pos.y);
-	  cursor->height = PANGO_PIXELS (weak_pos.height);
-	  cursor->is_strong = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
-	  cursor->is_weak = TRUE;
-	  display->cursors = g_slist_prepend (display->cursors, cursor);
-	}
-    }
+  display->cursors = g_array_append_val (display->cursors, start);
 }
 
 static gboolean
@@ -2530,10 +2489,7 @@ gtk_text_layout_free_line_display (GtkTextLayout      *layout,
         g_object_unref (display->layout);
 
       if (display->cursors)
-        {
-          g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
-          g_slist_free (display->cursors);
-        }
+        g_array_free (display->cursors, TRUE);
 
       if (display->pg_bg_color)
         gdk_color_free (display->pg_bg_color);
diff --git a/gtk/gtktextlayout.h b/gtk/gtktextlayout.h
index 78ec750..ed2556a 100644
--- a/gtk/gtktextlayout.h
+++ b/gtk/gtktextlayout.h
@@ -109,7 +109,6 @@ typedef struct _GtkTextLineData GtkTextLineData;
 typedef struct _GtkTextLayout         GtkTextLayout;
 typedef struct _GtkTextLayoutClass    GtkTextLayoutClass;
 typedef struct _GtkTextLineDisplay    GtkTextLineDisplay;
-typedef struct _GtkTextCursorDisplay  GtkTextCursorDisplay;
 typedef struct _GtkTextAttrAppearance GtkTextAttrAppearance;
 
 struct _GtkTextLayout
@@ -225,19 +224,11 @@ struct _GtkTextAttrAppearance
   PangoAttribute attr;
   GtkTextAppearance appearance;
 };
-struct _GtkTextCursorDisplay
-{
-  gint x;
-  gint y;
-  gint height;
-  guint is_strong : 1;
-  guint is_weak : 1;
-};
 
 struct _GtkTextLineDisplay
 {
   PangoLayout *layout;
-  GSList *cursors;
+  GArray *cursors;      /* indexes of cursors in the PangoLayout */
 
   GtkTextDirection direction;
 



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