Commit fc9c3c36 authored by Matthias Clasen's avatar Matthias Clasen

Merge branch 'fix-nested-attributes' into 'master'

Fix attr iterators with overlapping attributes

See merge request !240
parents 754bd181 54b593ec
Pipeline #214611 passed with stages
in 1 minute and 12 seconds
......@@ -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);
......
......@@ -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 ();
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment