summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-09-17 13:04:36 +0000
committerMatthias Clasen <mclasen@redhat.com>2020-09-17 13:04:36 +0000
commitfc9c3c3628aef1ee0b646b9bd10f47cee1549ec4 (patch)
tree5d4c3be03991407ffbfd126bd2f38bd502db3d32
parent754bd1814d33ff374a4a265bd399549269f2ce06 (diff)
parent54b593ec3e7829583ce2fec3fe22dff512db07fb (diff)
downloadpango-fc9c3c3628aef1ee0b646b9bd10f47cee1549ec4.tar.gz
Merge branch 'fix-nested-attributes' into 'master'
Fix attr iterators with overlapping attributes See merge request GNOME/pango!240
-rw-r--r--pango/pango-attributes.c17
-rw-r--r--tests/testattributes.c89
2 files changed, 95 insertions, 11 deletions
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 12942043..4f96135b 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -2003,7 +2003,7 @@ pango_attr_iterator_range (PangoAttrIterator *iterator,
gboolean
pango_attr_iterator_next (PangoAttrIterator *iterator)
{
- guint i;
+ int i;
g_return_val_if_fail (iterator != NULL, FALSE);
@@ -2016,19 +2016,14 @@ pango_attr_iterator_next (PangoAttrIterator *iterator)
if (iterator->attribute_stack)
{
- for (i = 0; i < iterator->attribute_stack->len; i++)
+ for (i = iterator->attribute_stack->len - 1; i>= 0; i--)
{
const PangoAttribute *attr = g_ptr_array_index (iterator->attribute_stack, i);
if (attr->end_index == iterator->start_index)
- {
- g_ptr_array_remove_index (iterator->attribute_stack, i); /* Can't use index_fast :( */;
- i--;
- }
+ g_ptr_array_remove_index (iterator->attribute_stack, i); /* Can't use index_fast :( */
else
- {
- iterator->end_index = MIN (iterator->end_index, attr->end_index);
- }
+ iterator->end_index = MIN (iterator->end_index, attr->end_index);
}
}
@@ -2136,14 +2131,14 @@ PangoAttribute *
pango_attr_iterator_get (PangoAttrIterator *iterator,
PangoAttrType type)
{
- guint i;
+ int i;
g_return_val_if_fail (iterator != NULL, NULL);
if (!iterator->attribute_stack)
return NULL;
- for (i = 0; i < iterator->attribute_stack->len; i++)
+ for (i = iterator->attribute_stack->len - 1; i>= 0; i--)
{
PangoAttribute *attr = g_ptr_array_index (iterator->attribute_stack, i);
diff --git a/tests/testattributes.c b/tests/testattributes.c
index 8db42b4a..6131f38c 100644
--- a/tests/testattributes.c
+++ b/tests/testattributes.c
@@ -944,6 +944,94 @@ test_merge2 (void)
pango_attr_list_unref (list);
}
+/* This only prints rise, size and scale, which are the
+ * only relevant attributes in the test that uses this
+ * function.
+ */
+static void
+print_tags_for_attributes (PangoAttrIterator *iter,
+ GString *s)
+{
+ PangoAttribute *attr;
+
+ attr = pango_attr_iterator_get (iter, PANGO_ATTR_RISE);
+ if (attr)
+ g_string_append_printf (s, "[%d, %d]rise=%d\n",
+ attr->start_index, attr->end_index,
+ ((PangoAttrInt*)attr)->value);
+
+ attr = pango_attr_iterator_get (iter, PANGO_ATTR_SIZE);
+ if (attr)
+ g_string_append_printf (s, "[%d, %d]size=%d\n",
+ attr->start_index, attr->end_index,
+ ((PangoAttrInt*)attr)->value);
+
+ attr = pango_attr_iterator_get (iter, PANGO_ATTR_SCALE);
+ if (attr)
+ g_string_append_printf (s, "[%d, %d]scale=%f\n",
+ attr->start_index, attr->end_index,
+ ((PangoAttrFloat*)attr)->value);
+}
+
+static void
+test_iter_epsilon_zero (void)
+{
+ const char *markup = "𝜀<span rise=\"-6000\" size=\"x-small\" font_desc=\"italic\">0</span> = 𝜔<span rise=\"8000\" size=\"smaller\">𝜔<span rise=\"14000\" size=\"smaller\">𝜔<span rise=\"20000\">.<span rise=\"23000\">.<span rise=\"26000\">.</span></span></span></span></span>";
+ PangoAttrList *attributes;
+ PangoAttrIterator *attr;
+ char *text;
+ GError *error = NULL;
+ GString *s;
+
+ s = g_string_new ("");
+
+ pango_parse_markup (markup, -1, 0, &attributes, &text, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (text, ==, "𝜀0 = 𝜔𝜔𝜔...");
+
+ attr = pango_attr_list_get_iterator (attributes);
+ do
+ {
+ int start, end;
+
+ pango_attr_iterator_range (attr, &start, &end);
+
+ g_string_append_printf (s, "range: [%d, %d]\n", start, end);
+
+ print_tags_for_attributes (attr, s);
+ }
+ while (pango_attr_iterator_next (attr));
+
+ g_assert_cmpstr (s->str, ==,
+ "range: [0, 4]\n"
+ "range: [4, 5]\n"
+ "[4, 5]rise=-6000\n"
+ "[4, 5]scale=0.694444\n"
+ "range: [5, 12]\n"
+ "range: [12, 16]\n"
+ "[12, 23]rise=8000\n"
+ "[12, 23]scale=0.833333\n"
+ "range: [16, 20]\n"
+ "[16, 23]rise=14000\n"
+ "[16, 23]scale=0.694444\n"
+ "range: [20, 21]\n"
+ "[20, 23]rise=20000\n"
+ "[16, 23]scale=0.694444\n"
+ "range: [21, 22]\n"
+ "[21, 23]rise=23000\n"
+ "[16, 23]scale=0.694444\n"
+ "range: [22, 23]\n"
+ "[22, 23]rise=26000\n"
+ "[16, 23]scale=0.694444\n"
+ "range: [23, 2147483647]\n");
+
+ g_free (text);
+ pango_attr_list_unref (attributes);
+ pango_attr_iterator_destroy (attr);
+
+ g_string_free (s, TRUE);
+}
+
int
main (int argc, char *argv[])
{
@@ -966,6 +1054,7 @@ main (int argc, char *argv[])
g_test_add_func ("/attributes/iter/get", test_iter_get);
g_test_add_func ("/attributes/iter/get_font", test_iter_get_font);
g_test_add_func ("/attributes/iter/get_attrs", test_iter_get_attrs);
+ g_test_add_func ("/attributes/iter/epsilon_zero", test_iter_epsilon_zero);
return g_test_run ();
}