summaryrefslogtreecommitdiff
path: root/gtk/gtktextbtree.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2005-10-11 14:39:17 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2005-10-11 14:39:17 +0000
commita07a5ecba7c1a6cc3c726d0529f30f75a32989ed (patch)
tree4420219545054692aceef5b7b97f68071620611c /gtk/gtktextbtree.c
parent8ad0abb867dd326d3436f484588eaf70e0634435 (diff)
downloadgtk+-a07a5ecba7c1a6cc3c726d0529f30f75a32989ed.tar.gz
Try to match an off toggle here with the matching on toggle if it
2005-10-11 Matthias Clasen <mclasen@redhat.com> * gtk/gtktextbtree.c (_gtk_text_btree_delete): Try to match an off toggle here with the matching on toggle if it immediately follows. This is a common case, and handling it here prevents quadratic blowup in cleanup_line() below. (#317125) * gtk/gtktextsegment.h: * gtk/gtktextsegment.c (_gtk_char_segment_new_from_two_strings): Pass the character counts into this function instead of computing them again.
Diffstat (limited to 'gtk/gtktextbtree.c')
-rw-r--r--gtk/gtktextbtree.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index 1e78da9eb5..98fc15d036 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -1,5 +1,5 @@
/*
- * gtktextbtree.c --
+ * Gtktextbtree.c --
*
* This file contains code that manages the B-tree representation
* of text for the text buffer and implements character and
@@ -732,7 +732,7 @@ _gtk_text_btree_delete (GtkTextIter *start,
* of the deletion range. */
GtkTextLineSegment *last_seg; /* The segment just after the end
* of the deletion range. */
- GtkTextLineSegment *seg, *next;
+ GtkTextLineSegment *seg, *next, *next2;
GtkTextLine *curline;
GtkTextBTreeNode *curnode, *node;
GtkTextBTree *tree;
@@ -885,12 +885,29 @@ _gtk_text_btree_delete (GtkTextIter *start,
seg->next = start_line->segments;
start_line->segments = seg;
}
- else
- {
+ else if (prev_seg->next &&
+ seg->type == &gtk_text_toggle_off_type &&
+ prev_seg->next->type == &gtk_text_toggle_on_type &&
+ seg->body.toggle.info == prev_seg->next->body.toggle.info)
+ {
+ /* Try to match an off toggle with the matching on toggle
+ * if it immediately follows. This is a common case, and
+ * handling it here prevents quadratic blowup in
+ * cleanup_line() below. See bug 317125.
+ */
+ next2 = prev_seg->next->next;
+ g_free ((char *)prev_seg->next);
+ prev_seg->next = next2;
+ g_free ((char *)seg);
+ seg = NULL;
+ }
+ else
+ {
seg->next = prev_seg->next;
prev_seg->next = seg;
}
- if (seg->type->leftGravity)
+
+ if (seg && seg->type->leftGravity)
{
prev_seg = seg;
}
@@ -4718,16 +4735,20 @@ cleanup_line (GtkTextLine *line)
while (changed)
{
changed = FALSE;
- for (prev_p = &line->segments, seg = *prev_p;
- seg != NULL;
- prev_p = &(*prev_p)->next, seg = *prev_p)
+ prev_p = &line->segments;
+ for (seg = *prev_p; seg != NULL; seg = *prev_p)
{
if (seg->type->cleanupFunc != NULL)
{
*prev_p = (*seg->type->cleanupFunc)(seg, line);
if (seg != *prev_p)
- changed = TRUE;
+ {
+ changed = TRUE;
+ continue;
+ }
}
+
+ prev_p = &(*prev_p)->next;
}
}
}