diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-07-11 19:28:36 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-07-11 19:28:36 +0000 |
commit | cdeb8308ff13f7c6c4bc583b803bb13e5224277c (patch) | |
tree | c3107b142a421d660c0a83f47ef338a091b55652 | |
parent | e445b8978ea73ab60f5462af4403987d73300a1f (diff) | |
parent | 9307a8c38a55056147b931c429d60409cb4bd779 (diff) | |
download | pango-cdeb8308ff13f7c6c4bc583b803bb13e5224277c.tar.gz |
Merge branch 'non-breaking-attrs' into 'master'
itemize: Don't break runs for font_features
Closes #242
See merge request GNOME/pango!79
-rw-r--r-- | pango/pango-item.c | 45 | ||||
-rw-r--r-- | pango/pango-item.h | 4 | ||||
-rw-r--r-- | pango/pango-layout.c | 84 | ||||
-rw-r--r-- | pango/pangofc-shape.c | 46 | ||||
-rw-r--r-- | tests/itemize/two.expected | 8 | ||||
-rw-r--r-- | tests/itemize/two.items | 3 |
6 files changed, 150 insertions, 40 deletions
diff --git a/pango/pango-item.c b/pango/pango-item.c index 8c368874..787fb65e 100644 --- a/pango/pango-item.c +++ b/pango/pango-item.c @@ -153,3 +153,48 @@ pango_item_split (PangoItem *orig, return new_item; } + +static int +compare_attr (gconstpointer p1, gconstpointer p2) +{ + if (pango_attribute_equal ((PangoAttribute *)p1, (PangoAttribute *)p2)) + return 0; + + return 1; +} + +void +pango_item_apply_attrs (PangoItem *item, + PangoAttrIterator *iter) +{ + int start, end; + GSList *attrs = NULL; + + do + { + pango_attr_iterator_range (iter, &start, &end); + + if (start >= item->offset + item->length) + break; + + if (end >= item->offset) + { + GSList *list, *l; + + list = pango_attr_iterator_get_attrs (iter); + for (l = list; l; l = l->next) + { + if (!g_slist_find_custom (attrs, l->data, compare_attr)) + + attrs = g_slist_prepend (attrs, pango_attribute_copy (l->data)); + } + g_slist_free_full (list, (GDestroyNotify)pango_attribute_destroy); + } + + if (end >= item->offset + item->length) + break; + } + while (pango_attr_iterator_next (iter)); + + item->analysis.extra_attrs = g_slist_concat (item->analysis.extra_attrs, attrs); +} diff --git a/pango/pango-item.h b/pango/pango-item.h index cb6a7ed3..2d7e58a1 100644 --- a/pango/pango-item.h +++ b/pango/pango-item.h @@ -23,6 +23,7 @@ #define __PANGO_ITEM_H__ #include <pango/pango-types.h> +#include <pango/pango-attributes.h> G_BEGIN_DECLS @@ -112,6 +113,9 @@ PANGO_AVAILABLE_IN_ALL PangoItem *pango_item_split (PangoItem *orig, int split_index, int split_offset); +PANGO_AVAILABLE_IN_1_44 +void pango_item_apply_attrs (PangoItem *item, + PangoAttrIterator *iter); G_END_DECLS diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 2384d6b0..97beccc8 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -4006,11 +4006,6 @@ no_shape_filter_func (PangoAttribute *attribute, PANGO_ATTR_UNDERLINE, PANGO_ATTR_STRIKETHROUGH, PANGO_ATTR_RISE - /* Ideally we want font-features here, because we don't - * want it to break shaping runs. But if we put it here, - * it won't show up in the shaper anymore :(. To be - * fixed later. */ - /* PANGO_ATTR_FONT_FEATURES */ }; int i; @@ -4032,33 +4027,76 @@ filter_no_shape_attributes (PangoAttrList *attrs) static void apply_no_shape_attributes (PangoLayout *layout, - PangoAttrList *no_shape_attrs) + PangoAttrList *no_shape_attrs) { - GSList *line_list; + GSList *ll; - for (line_list = layout->lines; line_list; line_list = line_list->next) + for (ll = layout->lines; ll; ll = ll->next) { - PangoLayoutLine *line = line_list->data; + PangoLayoutLine *line = ll->data; GSList *old_runs = g_slist_reverse (line->runs); - GSList *run_list; + GSList *rl; line->runs = NULL; - for (run_list = old_runs; run_list; run_list = run_list->next) - { - PangoGlyphItem *glyph_item = run_list->data; - GSList *new_runs; + for (rl = old_runs; rl; rl = rl->next) + { + PangoGlyphItem *glyph_item = rl->data; + GSList *new_runs; - new_runs = pango_glyph_item_apply_attrs (glyph_item, - layout->text, - no_shape_attrs); + new_runs = pango_glyph_item_apply_attrs (glyph_item, + layout->text, + no_shape_attrs); - line->runs = g_slist_concat (new_runs, line->runs); - } + line->runs = g_slist_concat (new_runs, line->runs); + } g_slist_free (old_runs); } } +static gboolean +no_break_filter_func (PangoAttribute *attribute, + gpointer data G_GNUC_UNUSED) +{ + static const PangoAttrType no_break_types[] = { + PANGO_ATTR_FONT_FEATURES + }; + + 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" @@ -4070,6 +4108,7 @@ pango_layout_check_lines (PangoLayout *layout) int start_offset; PangoAttrList *attrs; PangoAttrList *no_shape_attrs; + PangoAttrList *no_break_attrs; PangoAttrIterator *iter; PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL; ParaBreakState state; @@ -4089,6 +4128,7 @@ pango_layout_check_lines (PangoLayout *layout) 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); layout->log_attrs = g_new (PangoLogAttr, layout->n_chars + 1); @@ -4169,6 +4209,12 @@ pango_layout_check_lines (PangoLayout *layout) attrs, iter); + if (no_break_attrs) + { + apply_no_break_attributes (state.items, no_break_attrs); + pango_attr_list_unref (no_break_attrs); + } + get_items_log_attrs (start, state.items, layout->log_attrs + start_offset, delim_len); diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c index b062bd26..2846449e 100644 --- a/pango/pangofc-shape.c +++ b/pango/pangofc-shape.c @@ -440,10 +440,11 @@ _pango_fc_shape (PangoFont *font, GSList *tmp_attrs; for (tmp_attrs = analysis->extra_attrs; tmp_attrs && num_features < G_N_ELEMENTS (features); tmp_attrs = tmp_attrs->next) - { - if (((PangoAttribute *) tmp_attrs->data)->klass->type == PANGO_ATTR_FONT_FEATURES) - { - const PangoAttrFontFeatures *fattr = (const PangoAttrFontFeatures *) tmp_attrs->data; + { + PangoAttribute *attr = tmp_attrs->data; + if (attr->klass->type == PANGO_ATTR_FONT_FEATURES) + { + PangoAttrFontFeatures *fattr = (PangoAttrFontFeatures *) attr; const gchar *feat; const gchar *end; int len; @@ -451,23 +452,26 @@ _pango_fc_shape (PangoFont *font, feat = fattr->features; while (feat != NULL && num_features < G_N_ELEMENTS (features)) - { - end = strchr (feat, ','); - if (end) - len = end - feat; - else - len = -1; - - if (hb_feature_from_string (feat, len, &features[num_features])) - num_features++; - - if (end == NULL) - break; - - feat = end + 1; - } - } - } + { + end = strchr (feat, ','); + if (end) + len = end - feat; + else + len = -1; + if (hb_feature_from_string (feat, len, &features[num_features])) + { + features[num_features].start = attr->start_index; + features[num_features].end = attr->end_index; + num_features++; + } + + if (end == NULL) + break; + + feat = end + 1; + } + } + } } hb_shape (hb_font, hb_buffer, features, num_features); diff --git a/tests/itemize/two.expected b/tests/itemize/two.expected new file mode 100644 index 00000000..f0adbad0 --- /dev/null +++ b/tests/itemize/two.expected @@ -0,0 +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: Latn |Latn |Latn |Latn |Latn |Latn |Latn |Latn |Latn +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]features=tnum=0|[4,12]features=tnum=0,[6,7]underline=1|[4,12]features=tnum=0|[4,12]features=tnum=0,[8,11]features=dlig=1|[4,12]features=tnum=0| | | diff --git a/tests/itemize/two.items b/tests/itemize/two.items new file mode 100644 index 00000000..4ba41454 --- /dev/null +++ b/tests/itemize/two.items @@ -0,0 +1,3 @@ +# test that font_features attributes don't break the +# runs anymore (but other attributes do) +<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> |