summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-24 23:48:14 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-07-24 23:48:14 +0000
commit16f5871fa28ee107d192ba4885b4f66e52118427 (patch)
treeab6f94dc682eabc707e5328092202368f5bb4a07
parentdd3fc1b1976890bde122c87813f03da6c26129b9 (diff)
parent637a18c17f6c25e9285476f1585f210c77506780 (diff)
downloadpango-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.c2
-rw-r--r--pango/pango-layout.c178
-rw-r--r--tests/itemize/two.expected12
-rw-r--r--tests/layouts/valid-1.expected4
-rw-r--r--tests/test-itemize.c60
-rw-r--r--tests/test-shape.c85
-rw-r--r--utils/test-color-run.markup2
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>