[pango/run-attributes: 3/6] layout: Flip the logic for attribute filtering



commit 7fead4c8931b83c54e3c075a9c67320f583f4c95
Author: Matthias Clasen <mclasen redhat com>
Date:   Wed Jul 24 15:50:27 2019 -0400

    layout: Flip the logic for attribute filtering
    
    Instead of filtering out the attributes we don't
    want to influence itemization, explicitly filter
    only those attributes that we want to affect itemization.
    This makes us no longer break items for custom
    attributes, such as GtkTextAppearance attributes
    that are created by GtkTextLayout.
    
    Update expected output for layout testcases.

 pango/pango-layout.c           | 174 +++++++++++++++++++++--------------------
 tests/layouts/valid-1.expected |   4 +-
 2 files changed, 90 insertions(+), 88 deletions(-)
---
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 62ca3217..e7db7563 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3981,42 +3981,83 @@ pango_layout_get_effective_attributes (PangoLayout *layout)
 }
 
 static gboolean
-no_shape_filter_func (PangoAttribute *attribute,
-                     gpointer        data G_GNUC_UNUSED)
-{
-  static const PangoAttrType no_shape_types[] = {
-    PANGO_ATTR_FOREGROUND,
-    PANGO_ATTR_BACKGROUND,
-    PANGO_ATTR_FOREGROUND_ALPHA,
-    PANGO_ATTR_BACKGROUND_ALPHA,
-    PANGO_ATTR_UNDERLINE,
-    PANGO_ATTR_STRIKETHROUGH,
-    PANGO_ATTR_RISE
-  };
-
-  int i;
-
-  for (i = 0; i < (int)G_N_ELEMENTS (no_shape_types); i++)
-    if (attribute->klass->type == no_shape_types[i])
+affects_itemization (PangoAttribute *attr,
+                     gpointer        data)
+{
+  switch (attr->klass->type)
+    {
+    /* These affect font selection */
+    case PANGO_ATTR_LANGUAGE:
+    case PANGO_ATTR_FAMILY:
+    case PANGO_ATTR_STYLE:
+    case PANGO_ATTR_WEIGHT:
+    case PANGO_ATTR_VARIANT:
+    case PANGO_ATTR_STRETCH:
+    case PANGO_ATTR_SIZE:
+    case PANGO_ATTR_FONT_DESC:
+    case PANGO_ATTR_SCALE:
+    case PANGO_ATTR_FALLBACK:
+    case PANGO_ATTR_ABSOLUTE_SIZE:
+    case PANGO_ATTR_GRAVITY:
+    case PANGO_ATTR_GRAVITY_HINT:
+    /* These are part of ItemProperties, so need to break runs */
+    case PANGO_ATTR_SHAPE:
+    case PANGO_ATTR_RISE:
+    case PANGO_ATTR_UNDERLINE:
+    case PANGO_ATTR_STRIKETHROUGH:
+    case PANGO_ATTR_LETTER_SPACING:
       return TRUE;
-
-  return FALSE;
+    default:
+      return FALSE;
+    }
 }
 
-static PangoAttrList *
-filter_no_shape_attributes (PangoAttrList *attrs)
+static gboolean
+affects_break_or_shape (PangoAttribute *attr,
+                        gpointer        data)
 {
-  return pango_attr_list_filter (attrs,
-                                no_shape_filter_func,
-                                NULL);
+  switch (attr->klass->type)
+    {
+    /* Affects breaks */
+    case PANGO_ATTR_ALLOW_BREAKS:
+    /* Affects shaping */
+    case PANGO_ATTR_FONT_FEATURES:
+      return TRUE;
+    default:
+      return FALSE;
+    }
 }
 
 static void
-apply_no_shape_attributes (PangoLayout   *layout,
+apply_attributes_to_items (GList         *items,
                            PangoAttrList *attrs)
+{
+  GList *l;
+  PangoAttrIterator *iter;
+
+  if (!attrs)
+    return;
+
+  iter = pango_attr_list_get_iterator (attrs);
+
+  for (l = items; l; l = l->next)
+    {
+      PangoItem *item = l->data;
+      pango_item_apply_attrs (item, iter);
+    }
+
+  pango_attr_iterator_destroy (iter);
+}
+
+static void
+apply_attributes_to_runs (PangoLayout   *layout,
+                          PangoAttrList *attrs)
 {
   GSList *ll;
 
+  if (!attrs)
+    return;
+
   for (ll = layout->lines; ll; ll = ll->next)
     {
       PangoLayoutLine *line = ll->data;
@@ -4040,49 +4081,6 @@ apply_no_shape_attributes (PangoLayout   *layout,
     }
 }
 
-static gboolean
-no_itemize_filter_func (PangoAttribute *attribute,
-                        gpointer        data G_GNUC_UNUSED)
-{
-  static const PangoAttrType no_break_types[] = {
-    PANGO_ATTR_FONT_FEATURES,
-    PANGO_ATTR_ALLOW_BREAKS
-  };
-  int i;
-
-  for (i = 0; i < (int)G_N_ELEMENTS (no_break_types); i++)
-    if (attribute->klass->type == no_break_types[i])
-      return TRUE;
-
-  return FALSE;
-}
-
-static PangoAttrList *
-filter_no_itemize_attributes (PangoAttrList *attrs)
-{
-  return pango_attr_list_filter (attrs,
-                                 no_itemize_filter_func,
-                                 NULL);
-}
-
-static void
-apply_no_itemize_attributes (GList         *items,
-                             PangoAttrList *attrs)
-{
-  GList *l;
-  PangoAttrIterator *iter;
-
-  iter = pango_attr_list_get_iterator (attrs);
-
-  for (l = items; l; l = l->next)
-    {
-      PangoItem *item = l->data;
-      pango_item_apply_attrs (item, iter);
-    }
-
-  pango_attr_iterator_destroy (iter);
-}
-
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
 
@@ -4093,8 +4091,8 @@ pango_layout_check_lines (PangoLayout *layout)
   gboolean done = FALSE;
   int start_offset;
   PangoAttrList *attrs;
-  PangoAttrList *no_shape_attrs;
-  PangoAttrList *no_itemize_attrs;
+  PangoAttrList *itemize_attrs;
+  PangoAttrList *shape_attrs;
   PangoAttrIterator *iter;
   PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL;
   ParaBreakState state;
@@ -4113,9 +4111,13 @@ pango_layout_check_lines (PangoLayout *layout)
     pango_layout_set_text (layout, NULL, 0);
 
   attrs = pango_layout_get_effective_attributes (layout);
-  no_shape_attrs = filter_no_shape_attributes (attrs);
-  no_itemize_attrs = filter_no_itemize_attributes (attrs);
-  iter = pango_attr_list_get_iterator (attrs);
+
+  shape_attrs = pango_attr_list_filter (attrs, affects_break_or_shape, NULL);
+  itemize_attrs = pango_attr_list_filter (attrs, affects_itemization, NULL);
+  if (itemize_attrs)
+    iter = pango_attr_list_get_iterator (itemize_attrs);
+  else
+    iter = NULL;
 
   layout->log_attrs = g_new (PangoLogAttr, layout->n_chars + 1);
 
@@ -4192,11 +4194,10 @@ pango_layout_check_lines (PangoLayout *layout)
                                                 layout->text,
                                                 start - layout->text,
                                                 end - start,
-                                                attrs,
+                                                itemize_attrs,
                                                 iter);
 
-      if (no_itemize_attrs)
-        apply_no_itemize_attributes (state.items, no_itemize_attrs);
+      apply_attributes_to_items (state.items, shape_attrs);
 
       get_items_log_attrs (start,
                            delimiter_index + delim_len,
@@ -4248,19 +4249,20 @@ pango_layout_check_lines (PangoLayout *layout)
     }
   while (!done);
 
-  pango_attr_iterator_destroy (iter);
-  pango_attr_list_unref (attrs);
+  apply_attributes_to_runs (layout, attrs);
+  layout->lines = g_slist_reverse (layout->lines);
 
-  if (no_itemize_attrs)
-    pango_attr_list_unref (no_itemize_attrs);
+  if (iter)
+    pango_attr_iterator_destroy (iter);
 
-  if (no_shape_attrs)
-    {
-      apply_no_shape_attributes (layout, no_shape_attrs);
-      pango_attr_list_unref (no_shape_attrs);
-    }
+  if (itemize_attrs)
+    pango_attr_list_unref (itemize_attrs);
 
-  layout->lines = g_slist_reverse (layout->lines);
+  if (shape_attrs)
+    pango_attr_list_unref (shape_attrs);
+
+  if (attrs)
+    pango_attr_list_unref (attrs);
 }
 
 #pragma GCC diagnostic pop
diff --git a/tests/layouts/valid-1.expected b/tests/layouts/valid-1.expected
index 292d6f43..6fb890b5 100644
--- a/tests/layouts/valid-1.expected
+++ b/tests/layouts/valid-1.expected
@@ -25,11 +25,11 @@ i=2, index=49, paragraph-start=1, dir=ltr ''
 
 i=1, index=0, chars=22, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 'This 
is a test of the '
 i=2, index=22, chars=11, level=0, gravity=south, flags=0, font=OMITTED, script=latin, language=en-us, 
'automatic e'
-[22,41]foreground=#00000000ffff
 [22,41]underline=1
+[22,41]foreground=#00000000ffff
 i=3, index=33, chars=15, level=0, gravity=south, flags=2, font=OMITTED, script=common, language=en-us, 
'mergency brake!'
+[0,2147483647]foreground=#00000000ffff
 [0,2147483647]fallback=0
 [22,41]foreground=#00000000ffff
-[22,41]underline=1
 i=4, index=48, no run, line end
 i=5, index=49, no run, line end


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