[gtk+] textview: Track differences between ink and logical rects



commit 45dfdbce3f51bf00b16703717522778cb0a35bf8
Author: Benjamin Otte <otte redhat com>
Date:   Wed Mar 16 00:35:45 2016 +0100

    textview: Track differences between ink and logical rects
    
    This way, we can ensure that we queue redraws on the full ink rect. This
    is particularly visible for squiggly underlines in spell checking.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763741

 gtk/gtktextbtree.c  |   10 ++++++++--
 gtk/gtktextbtree.h  |    2 ++
 gtk/gtktextlayout.c |   28 ++++++++++++++++++++++++----
 3 files changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index 9e8d838..2c995aa 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -2650,14 +2650,18 @@ redisplay_region (GtkTextBTree      *tree,
       else
         end_y = _gtk_text_btree_find_line_top (tree, end_line, view->view_id);
 
+      ld = _gtk_text_line_get_data (start_line, view->view_id);
+      if (ld)
+        start_y -= ld->top_ink;
+
       ld = _gtk_text_line_get_data (end_line, view->view_id);
       if (ld)
-        end_y += ld->height;
+        end_y += ld->height + ld->bottom_ink;
 
       if (cursors_only)
        gtk_text_layout_cursors_changed (view->layout, start_y,
                                         end_y - start_y,
-                                         end_y - start_y);
+                                        end_y - start_y);
       else
        gtk_text_layout_changed (view->layout, start_y,
                                 end_y - start_y,
@@ -3616,6 +3620,8 @@ _gtk_text_line_data_new (GtkTextLayout *layout,
   line_data->next = NULL;
   line_data->width = 0;
   line_data->height = 0;
+  line_data->top_ink = 0;
+  line_data->bottom_ink = 0;
   line_data->valid = FALSE;
 
   return line_data;
diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h
index 0866218..bea4841 100644
--- a/gtk/gtktextbtree.h
+++ b/gtk/gtktextbtree.h
@@ -220,6 +220,8 @@ struct _GtkTextLineData {
   gpointer view_id;
   GtkTextLineData *next;
   gint height;
+  gint top_ink : 16;
+  gint bottom_ink : 16;
   signed int width : 24;
   guint valid : 8;             /* Actually a boolean */
 };
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 6adcdc5..6829d45 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1041,23 +1041,31 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
       if (!line_data || !line_data->valid)
         {
           gint old_height, new_height;
+          gint top_ink, bottom_ink;
          
          old_height = line_data ? line_data->height : 0;
+          top_ink = line_data ? line_data->top_ink : 0;
+          bottom_ink = line_data ? line_data->bottom_ink : 0;
 
           _gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
                                          line, layout);
           line_data = _gtk_text_line_get_data (line, layout);
 
          new_height = line_data ? line_data->height : 0;
+          if (line_data)
+            {
+              top_ink = MAX (top_ink, line_data->top_ink);
+              bottom_ink = MAX (bottom_ink, line_data->bottom_ink);
+            }
 
           delta_height += new_height - old_height;
           
           first_line = line;
-          first_line_y = -seen - new_height;
+          first_line_y = -seen - new_height - top_ink;
           if (!last_line)
             {
               last_line = line;
-              last_line_y = -seen;
+              last_line_y = -seen + bottom_ink;
             }
         }
 
@@ -1074,23 +1082,31 @@ gtk_text_layout_validate_yrange (GtkTextLayout *layout,
       if (!line_data || !line_data->valid)
         {
           gint old_height, new_height;
+          gint top_ink, bottom_ink;
          
          old_height = line_data ? line_data->height : 0;
+          top_ink = line_data ? line_data->top_ink : 0;
+          bottom_ink = line_data ? line_data->bottom_ink : 0;
 
           _gtk_text_btree_validate_line (_gtk_text_buffer_get_btree (layout->buffer),
                                          line, layout);
           line_data = _gtk_text_line_get_data (line, layout);
          new_height = line_data ? line_data->height : 0;
+          if (line_data)
+            {
+              top_ink = MAX (top_ink, line_data->top_ink);
+              bottom_ink = MAX (bottom_ink, line_data->bottom_ink);
+            }
 
           delta_height += new_height - old_height;
           
           if (!first_line)
             {
               first_line = line;
-              first_line_y = seen;
+              first_line_y = seen - top_ink;
             }
           last_line = line;
-          last_line_y = seen + new_height;
+          last_line_y = seen + new_height + bottom_ink;
         }
 
       seen += line_data ? line_data->height : 0;
@@ -1152,6 +1168,7 @@ gtk_text_layout_real_wrap (GtkTextLayout   *layout,
                            GtkTextLineData *line_data)
 {
   GtkTextLineDisplay *display;
+  PangoRectangle ink_rect, logical_rect;
 
   g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
   g_return_val_if_fail (line != NULL, NULL);
@@ -1166,6 +1183,9 @@ gtk_text_layout_real_wrap (GtkTextLayout   *layout,
   line_data->width = display->width;
   line_data->height = display->height;
   line_data->valid = TRUE;
+  pango_layout_get_pixel_extents (display->layout, &ink_rect, &logical_rect);
+  line_data->top_ink = MAX (0, logical_rect.x - ink_rect.x);
+  line_data->bottom_ink = MAX (0, logical_rect.x + logical_rect.width - ink_rect.x - ink_rect.width);
   gtk_text_layout_free_line_display (layout, display);
 
   return line_data;


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