diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-24 23:48:14 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-24 23:48:14 +0000 |
commit | 16f5871fa28ee107d192ba4885b4f66e52118427 (patch) | |
tree | ab6f94dc682eabc707e5328092202368f5bb4a07 | |
parent | dd3fc1b1976890bde122c87813f03da6c26129b9 (diff) | |
parent | 637a18c17f6c25e9285476f1585f210c77506780 (diff) | |
download | pango-16f5871fa28ee107d192ba4885b4f66e52118427.tar.gz |
Merge branch 'run-attributes' into 'master'
Flip the logic for attribute filtering
See merge request GNOME/pango!100
-rw-r--r-- | pango/pango-item.c | 2 | ||||
-rw-r--r-- | pango/pango-layout.c | 178 | ||||
-rw-r--r-- | tests/itemize/two.expected | 12 | ||||
-rw-r--r-- | tests/layouts/valid-1.expected | 4 | ||||
-rw-r--r-- | tests/test-itemize.c | 60 | ||||
-rw-r--r-- | tests/test-shape.c | 85 | ||||
-rw-r--r-- | utils/test-color-run.markup | 2 |
7 files changed, 244 insertions, 99 deletions
diff --git a/pango/pango-item.c b/pango/pango-item.c index b43ed3a5..dae65645 100644 --- a/pango/pango-item.c +++ b/pango/pango-item.c @@ -208,7 +208,7 @@ pango_item_apply_attrs (PangoItem *item, { if (!g_slist_find_custom (attrs, l->data, compare_attr)) - attrs = g_slist_prepend (attrs, pango_attribute_copy (l->data)); + attrs = g_slist_prepend (attrs, pango_attribute_copy (l->data)); } g_slist_free_full (list, (GDestroyNotify)pango_attribute_destroy); } diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 4d55558e..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; + default: + return FALSE; + } +} - return FALSE; +static gboolean +affects_break_or_shape (PangoAttribute *attr, + gpointer data) +{ + switch (attr->klass->type) + { + /* Affects breaks */ + case PANGO_ATTR_ALLOW_BREAKS: + /* Affects shaping */ + case PANGO_ATTR_FONT_FEATURES: + return TRUE; + default: + return FALSE; + } } -static PangoAttrList * -filter_no_shape_attributes (PangoAttrList *attrs) +static void +apply_attributes_to_items (GList *items, + PangoAttrList *attrs) { - return pango_attr_list_filter (attrs, - no_shape_filter_func, - NULL); + 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_no_shape_attributes (PangoLayout *layout, - PangoAttrList *no_shape_attrs) +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; @@ -4030,8 +4071,8 @@ apply_no_shape_attributes (PangoLayout *layout, GSList *new_runs; new_runs = pango_glyph_item_apply_attrs (glyph_item, - layout->text, - no_shape_attrs); + layout->text, + attrs); line->runs = g_slist_concat (new_runs, line->runs); } @@ -4040,49 +4081,6 @@ apply_no_shape_attributes (PangoLayout *layout, } } -static gboolean -no_break_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_break_attributes (PangoAttrList *attrs) -{ - return pango_attr_list_filter (attrs, - no_break_filter_func, - NULL); -} - -static void -apply_no_break_attributes (GList *items, - PangoAttrList *no_break_attrs) -{ - GList *l; - PangoAttrIterator *iter; - - iter = pango_attr_list_get_iterator (no_break_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_break_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_break_attrs = filter_no_break_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_break_attrs) - apply_no_break_attributes (state.items, no_break_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_break_attrs) - pango_attr_list_unref (no_break_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/itemize/two.expected b/tests/itemize/two.expected index 57446958..ebe9757c 100644 --- a/tests/itemize/two.expected +++ b/tests/itemize/two.expected @@ -1,8 +1,8 @@ <span font="Cantarell 11">one <span font_features="tnum=0">tw<u>o</u> <span font_features="dlig=1">two</span> </span>th<b>r</b>ee</span> -Items: one |tw |o | |two | |th |r |ee -Font: Cantarell 11|Cantarell 11 |Cantarell 11 |Cantarell 11 |Cantarell 11 |Cantarell 11 |Cantarell 11|Cantarell Bold 11|Cantarell 11 -Script: latin |latin |latin |latin |latin |latin |latin |latin |latin -Lang: en-us |en-us |en-us |en-us |en-us |en-us |en-us |en-us |en-us -Bidi: 0 |0 |0 |0 |0 |0 |0 |0 |0 -Attrs: |[4,12]font-features=tnum=0|[4,12]font-features=tnum=0,[6,7]underline=1|[4,12]font-features=tnum=0|[4,12]font-features=tnum=0,[8,11]font-features=dlig=1|[4,12]font-features=tnum=0| | | +Items: one tw |o | two th |r |ee +Font: Cantarell 11 |Cantarell 11 |Cantarell 11 |Cantarell Bold 11|Cantarell 11 +Script: latin |latin |latin |latin |latin +Lang: en-us |en-us |en-us |en-us |en-us +Bidi: 0 |0 |0 |0 |0 +Attrs: [4,12]font-features=tnum=0|[6,7]underline=1,[4,12]font-features=tnum=0|[8,11]font-features=dlig=1,[4,12]font-features=tnum=0| | 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 diff --git a/tests/test-itemize.c b/tests/test-itemize.c index 8ddf2ec9..d66c40d1 100644 --- a/tests/test-itemize.c +++ b/tests/test-itemize.c @@ -51,6 +51,59 @@ append_text (GString *s, } } +static gboolean +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; + default: + return FALSE; + } +} + +static void +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 test_file (const gchar *filename, GString *string) { @@ -61,6 +114,7 @@ test_file (const gchar *filename, GString *string) char *test; char *text; PangoAttrList *attrs; + PangoAttrList *itemize_attrs; GList *items, *l; const char *sep = ""; @@ -96,7 +150,11 @@ test_file (const gchar *filename, GString *string) if (text[length - 1] == '\n') length--; - items = pango_itemize (context, text, 0, length, attrs, NULL); + itemize_attrs = pango_attr_list_filter (attrs, affects_itemization, NULL); + items = pango_itemize (context, text, 0, length, itemize_attrs, NULL); + + apply_attributes_to_items (items, attrs); + pango_attr_list_unref (itemize_attrs); for (l = items; l; l = l->next) { diff --git a/tests/test-shape.c b/tests/test-shape.c index 1cf52044..898c4a84 100644 --- a/tests/test-shape.c +++ b/tests/test-shape.c @@ -71,6 +71,75 @@ parse_params (const char *str, g_strfreev (strings); } +static gboolean +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; + default: + return FALSE; + } +} + +static gboolean +affects_break_or_shape (PangoAttribute *attr, + gpointer data) +{ + 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_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 test_file (const gchar *filename, GString *string) { @@ -80,6 +149,8 @@ test_file (const gchar *filename, GString *string) char *test; char *text; PangoAttrList *attrs; + PangoAttrList *itemize_attrs; + PangoAttrList *shape_attrs; GList *items, *l; GString *s1, *s2, *s3, *s4, *s5, *s6, *s7; gboolean insert_hyphen = FALSE; @@ -124,7 +195,14 @@ test_file (const gchar *filename, GString *string) if (text[length - 1] == '\n') length--; - items = pango_itemize (context, text, 0, length, attrs, NULL); + itemize_attrs = pango_attr_list_filter (attrs, affects_itemization, NULL); + shape_attrs = pango_attr_list_filter (attrs, affects_break_or_shape, NULL); + + items = pango_itemize (context, text, 0, length, itemize_attrs, NULL); + apply_attributes_to_items (items, shape_attrs); + + pango_attr_list_unref (itemize_attrs); + pango_attr_list_unref (shape_attrs); pango_attr_list_unref (attrs); @@ -133,11 +211,16 @@ test_file (const gchar *filename, GString *string) PangoItem *item = l->data; PangoGlyphString *glyphs; gboolean rtl = item->analysis.level % 2; + PangoGlyphItem glyph_item; int i; glyphs = pango_glyph_string_new (); pango_shape_full (text + item->offset, item->length, text, length, &item->analysis, glyphs); + glyph_item.item = item; + glyph_item.glyphs = glyphs; + pango_glyph_item_apply_attrs (&glyph_item, text, attrs); + g_string_append (s1, sep); g_string_append (s2, sep); g_string_append (s3, sep); diff --git a/utils/test-color-run.markup b/utils/test-color-run.markup new file mode 100644 index 00000000..4b3d679f --- /dev/null +++ b/utils/test-color-run.markup @@ -0,0 +1,2 @@ + +<span size="x-large" font="noto sans arabic"><span foreground="red">ب</span><span foreground="blue">هداد</span></span> |