diff options
author | Jonathan Blandford <jrb@redhat.com> | 2000-09-08 18:42:06 +0000 |
---|---|---|
committer | Jonathan Blandford <jrb@src.gnome.org> | 2000-09-08 18:42:06 +0000 |
commit | 2ea04c9040af34b36ed4b1536fd08c5843467446 (patch) | |
tree | ecef9fde712af4c50b58cf6c1b6219bc1bcbc346 /pango/pango-attributes.c | |
parent | 5c177160d308355826450ca00217ee400a8a8c7b (diff) | |
download | pango-2ea04c9040af34b36ed4b1536fd08c5843467446.tar.gz |
Minor fixes to Owen's patch below to make it work.
2000-09-08 Jonathan Blandford <jrb@redhat.com>
* pango/pango-attributes.c (pango_attr_list_change): Minor fixes
to Owen's patch below to make it work.
* pango/pango-attributes.c (pango_attribute_copy): Copy the
start_index/end_index explicitly rather then rely on the copy
function doing it for you, as none did so.
Diffstat (limited to 'pango/pango-attributes.c')
-rw-r--r-- | pango/pango-attributes.c | 155 |
1 files changed, 127 insertions, 28 deletions
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index d2349eac..b87f6542 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -74,9 +74,15 @@ pango_attr_type_register (const gchar *name) PangoAttribute * pango_attribute_copy (const PangoAttribute *attr) { + PangoAttribute *result; + g_return_val_if_fail (attr != NULL, NULL); - return attr->klass->copy (attr); + result = attr->klass->copy (attr); + result->start_index = attr->start_index; + result->end_index = attr->end_index; + + return result; } /** @@ -836,7 +842,7 @@ pango_attr_list_change (PangoAttrList *list, tmp_list = list->attributes; prev = NULL; - while (tmp_list) + while (1) { PangoAttribute *tmp_attr; @@ -858,30 +864,71 @@ pango_attr_list_change (PangoAttrList *list, list->attributes_tail = link; prev = link; + tmp_list = prev->next; + break; } tmp_attr = tmp_list->data; - if (tmp_attr->end_index >= start_index && - pango_attribute_compare (tmp_attr, attr)) + if (tmp_attr->klass->type == attr->klass->type && + tmp_attr->end_index >= start_index) { - /* We can merge the new attribute with this attribute - */ - end_index = MAX (end_index, tmp_attr->end_index); - tmp_attr->end_index = end_index; - pango_attribute_destroy (attr); + /* We overlap with an existing attribute */ + if (pango_attribute_compare (tmp_attr, attr)) + { + /* We can merge the new attribute with this attribute + */ + if (tmp_attr->end_index >= end_index) + { + /* We are totally overlapping the previous attribute. + * No action is needed. + */ + pango_attribute_destroy (attr); + return; + } + tmp_attr->end_index = end_index; + pango_attribute_destroy (attr); + + attr = tmp_attr; + + prev = tmp_list; + tmp_list = tmp_list->next; + + break; + } + else + { + /* Truncate and/or remove the old attribute + */ + if (tmp_attr->end_index > attr->end_index) + { + PangoAttribute *end_attr = pango_attribute_copy (tmp_attr); - attr = tmp_attr; + end_attr->start_index = attr->end_index; + pango_attr_list_insert (list, end_attr); + } - prev = tmp_list; - tmp_list = tmp_list->next; + if (tmp_attr->start_index == attr->start_index) + { + pango_attribute_destroy (tmp_attr); + tmp_list->data = attr; - break; + prev = tmp_list; + tmp_list = tmp_list->next; + break; + } + else + { + tmp_attr->end_index = attr->start_index; + } + } } - prev = tmp_list; tmp_list = tmp_list->next; } + /* At this point, prev points to the list node with attr in it, + * tmp_list points to prev->next. + */ /* We now have the range inserted into the list one way or the * other. Fix up the remainder @@ -892,23 +939,75 @@ pango_attr_list_change (PangoAttrList *list, if (tmp_attr->start_index > end_index) break; - else if (pango_attribute_compare (tmp_attr, attr)) + else if (tmp_attr->klass->type == attr->klass->type) { - /* We can merge the new attribute with this attribute - */ - attr->end_index = MAX (end_index, tmp_attr->end_index); - - pango_attribute_destroy (tmp_attr); - prev->next = tmp_list->next; + if (tmp_attr->end_index <= attr->end_index || + pango_attribute_compare (tmp_attr, attr)) + { + /* We can merge the new attribute with this attribute. + */ + attr->end_index = MAX (end_index, tmp_attr->end_index); + + pango_attribute_destroy (tmp_attr); + prev->next = tmp_list->next; + + if (!prev->next) + list->attributes_tail = prev; + + g_slist_free_1 (tmp_list); + tmp_list = prev->next; + + continue; + } + else + { + /* Trim the start of this attribute that it begins at the end + * of the new attribute. This may involve moving + * it in the list to maintain the required non-decreasing + * order of start indices + */ + GSList *tmp_list2; + GSList *prev2; + + tmp_attr->start_index = attr->end_index; + + tmp_list2 = tmp_list->next; + prev2 = tmp_list; - g_slist_free_1 (tmp_list); - tmp_list = prev->next; - } - else - { - prev = tmp_list; - tmp_list = tmp_list->next; + while (tmp_list2) + { + PangoAttribute *tmp_attr2 = tmp_list2->data; + + if (tmp_attr2->start_index >= tmp_attr->start_index) + break; + + tmp_list2 = tmp_list2->next; + prev2 = tmp_list2; + } + + /* Now remove and insert before tmp_list2. We'll + * hit this attribute again later, but that's harmless. + */ + if (prev2 != tmp_list) + { + GSList *old_next = tmp_list->next; + + prev->next = old_next; + prev2->next = tmp_list; + tmp_list->next = tmp_list2; + + if (!tmp_list->next) + list->attributes_tail = tmp_list; + + tmp_list = old_next; + + continue; + } + } } + + prev = tmp_list; + tmp_list = tmp_list->next; } } |