summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-11 19:28:36 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-07-11 19:28:36 +0000
commitcdeb8308ff13f7c6c4bc583b803bb13e5224277c (patch)
treec3107b142a421d660c0a83f47ef338a091b55652
parente445b8978ea73ab60f5462af4403987d73300a1f (diff)
parent9307a8c38a55056147b931c429d60409cb4bd779 (diff)
downloadpango-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.c45
-rw-r--r--pango/pango-item.h4
-rw-r--r--pango/pango-layout.c84
-rw-r--r--pango/pangofc-shape.c46
-rw-r--r--tests/itemize/two.expected8
-rw-r--r--tests/itemize/two.items3
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>