commit 9755c4912ce21fcd47192e2b34283f3371fd6075
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.

diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index 9e8d838..6d2972f 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -2644,6 +2644,9 @@ redisplay_region (GtkTextBTree      *tree,
       GtkTextLineData *ld;
 
       start_y = _gtk_text_btree_find_line_top (tree, start_line, view->view_id);
+      ld = _gtk_text_line_get_data (end_line, view->view_id);
+      if (ld)
+        start_y += ld->top_ink;
 
       if (end_line == start_line)
         end_y = start_y;
@@ -2652,12 +2655,12 @@ redisplay_region (GtkTextBTree      *tree,
 
       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 +3619,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..bea48419 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..5d685ac 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1152,6 +1152,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 +1167,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;

