[gtk/avoid-redundant-attributes] text layout: Avoid redundant text attributes



commit 552fe0406cb68244b086a5119cd2ea4e5e071f78
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jul 24 19:03:07 2019 -0400

    text layout: Avoid redundant text attributes
    
    Don't insert text attributes if the font, or scale
    or fallback did not actually change. This helps
    Pango avoid excessive item breaks, which in turn
    helps shaping to work across things like color
    changes.
    
    Related: https://gitlab.gnome.org/GNOME/pango/issues/28

 gtk/gtktextlayout.c | 56 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 46 insertions(+), 10 deletions(-)
---
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index f5dc11722b..3196db22f8 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1641,32 +1641,62 @@ add_text_attrs (GtkTextLayout      *layout,
                 gint                byte_count,
                 PangoAttrList      *attrs,
                 gint                start,
-                gboolean            size_only)
+                gboolean            size_only,
+                PangoAttribute    **last_font_attr,
+                PangoAttribute    **last_scale_attr,
+                PangoAttribute    **last_fallback_attr)
 {
   PangoAttribute *attr;
 
-  attr = pango_attr_font_desc_new (style->font);
-  attr->start_index = start;
-  attr->end_index = start + byte_count;
+  if (*last_font_attr &&
+      pango_font_description_equal (style->font, ((PangoAttrFontDesc*)*last_font_attr)->desc) &&
+      (*last_font_attr)->end_index >= start)
+    {
+      (*last_font_attr)->start_index = MIN ((*last_font_attr)->start_index, start);
+      (*last_font_attr)->end_index = MAX ((*last_font_attr)->end_index, start + byte_count);
+    }
+  else
+    {
+      attr = pango_attr_font_desc_new (style->font);
+      attr->start_index = start;
+      attr->end_index = start + byte_count;
 
-  pango_attr_list_insert (attrs, attr);
+      pango_attr_list_insert (attrs, attr);
+      *last_font_attr = attr;
+    }
 
-  if (style->font_scale != 1.0)
+  if (*last_scale_attr &&
+      style->font_scale == ((PangoAttrFloat*)*last_scale_attr)->value &&
+      (*last_scale_attr)->end_index >= start)
+    {
+      (*last_scale_attr)->start_index = MIN ((*last_scale_attr)->start_index, start);
+      (*last_scale_attr)->end_index = MAX ((*last_scale_attr)->end_index, start + byte_count);
+    }
+  else if (style->font_scale != 1.0)
     {
       attr = pango_attr_scale_new (style->font_scale);
       attr->start_index = start;
       attr->end_index = start + byte_count;
 
       pango_attr_list_insert (attrs, attr);
+      *last_scale_attr = attr;
     }
 
-  if (style->no_fallback)
+  if (*last_fallback_attr &&
+      (!style->no_fallback) == ((PangoAttrInt*)*last_fallback_attr)->value &&
+      (*last_fallback_attr)->end_index >= start)
+    {
+      (*last_fallback_attr)->start_index = MIN ((*last_fallback_attr)->start_index, start);
+      (*last_fallback_attr)->end_index = MAX ((*last_fallback_attr)->end_index, start + byte_count);
+    }
+  else if (style->no_fallback)
     {
       attr = pango_attr_fallback_new (!style->no_fallback);
       attr->start_index = start;
       attr->end_index = start + byte_count;
 
       pango_attr_list_insert (attrs, attr);
+      *last_fallback_attr = attr;
     }
 
   if (style->letter_spacing != 0)
@@ -2269,7 +2299,10 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
   gboolean initial_toggle_segments;
   gint h_margin;
   gint h_padding;
-  
+  PangoAttribute *last_font_attr = NULL;
+  PangoAttribute *last_scale_attr = NULL;
+  PangoAttribute *last_fallback_attr = NULL;
+
   g_return_val_if_fail (line != NULL, NULL);
 
   if (layout->one_display_cache)
@@ -2316,7 +2349,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
       base_dir = (layout->keyboard_direction == GTK_TEXT_DIR_LTR) ?
         PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;
     }
-  
+
   /* Allocate space for flat text for buffer
    */
   text_allocated = _gtk_text_line_byte_count (line);
@@ -2413,7 +2446,10 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                                      attrs, layout_byte_offset - bytes,
                                      size_only, TRUE);
                   add_text_attrs (layout, style, bytes, attrs,
-                                  layout_byte_offset - bytes, size_only);
+                                  layout_byte_offset - bytes, size_only,
+                                  &last_font_attr,
+                                  &last_scale_attr,
+                                  &last_fallback_attr);
                 }
               else if (seg->type == &gtk_text_texture_type)
                 {


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