X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktextbtree.c;h=2757c8ca40a51094186ef7a6b129a86c6affd0c1;hb=ea043cab5718304d9b6170afa2d3f959fc99c718;hp=155ed8692105218e3690b03ef4ccbfb6052d0f90;hpb=290e4efdfeff91b7abad43bb9644e4c8e0ff9887;p=~andy%2Fgtk diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c index 155ed8692..2757c8ca4 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 @@ -53,13 +53,13 @@ */ #define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API +#include "config.h" #include "gtktextbtree.h" #include -#include #include #include -#include "gtksignal.h" #include "gtktexttag.h" +#include "gtktexttagprivate.h" #include "gtktexttagtable.h" #include "gtktextlayout.h" #include "gtktextiterprivate.h" @@ -101,7 +101,7 @@ struct _NodeData { /* Height and width of this node */ gint height; - gint width : 24; + signed int width : 24; /* boolean indicating whether the lines below this node are in need of validation. * However, width/height should always represent the current total width and @@ -109,7 +109,7 @@ struct _NodeData { * width/height on the lines needs recomputing, not whether the totals * need recomputing. */ - gint valid : 8; + guint valid : 8; /* Actually a boolean */ }; @@ -143,14 +143,14 @@ struct _GtkTextBTreeNode { int level; /* Level of this node in the B-tree. * 0 refers to the bottom of the tree * (children are lines, not nodes). */ + int num_lines; /* Total number of lines (leaves) in + * the subtree rooted here. */ + int num_chars; /* Number of chars below here */ + int num_children; /* Number of children of this node. */ union { /* First in linked list of children. */ struct _GtkTextBTreeNode *node; /* Used if level > 0. */ GtkTextLine *line; /* Used if level == 0. */ } children; - int num_children; /* Number of children of this node. */ - int num_lines; /* Total number of lines (leaves) in - * the subtree rooted here. */ - int num_chars; /* Number of chars below here */ NodeData *node_data; }; @@ -183,7 +183,7 @@ struct _GtkTextBTree { GtkTextBuffer *buffer; BTreeView *views; GSList *tag_infos; - guint tag_changed_handler; + gulong tag_changed_handler; /* Incremented when a segment with a byte size > 0 * is added to or removed from the tree (i.e. the @@ -281,7 +281,9 @@ static NodeData *node_data_find (NodeData *nd, gpointer view_id); static GtkTextBTreeNode *gtk_text_btree_node_new (void); +#if 0 static void gtk_text_btree_node_invalidate_downward (GtkTextBTreeNode *node); +#endif static void gtk_text_btree_node_invalidate_upward (GtkTextBTreeNode *node, gpointer view_id); static NodeData * gtk_text_btree_node_check_valid (GtkTextBTreeNode *node, @@ -340,7 +342,8 @@ static void gtk_text_btree_remove_tag_info (GtkTextBTree *tre static void redisplay_region (GtkTextBTree *tree, const GtkTextIter *start, - const GtkTextIter *end); + const GtkTextIter *end, + gboolean cursors_only); /* Inline thingies */ @@ -426,10 +429,10 @@ _gtk_text_btree_new (GtkTextTagTable *table, tree->end_iter_segment_byte_index = 0; tree->end_iter_segment_char_offset = 0; - g_object_ref (G_OBJECT (tree->table)); + g_object_ref (tree->table); - tree->tag_changed_handler = g_signal_connect (G_OBJECT (tree->table), - "tag_changed", + tree->tag_changed_handler = g_signal_connect (tree->table, + "tag-changed", G_CALLBACK (tag_changed_cb), tree); @@ -472,8 +475,8 @@ _gtk_text_btree_new (GtkTextTagTable *table, seg->body.mark.not_deleteable = TRUE; - g_object_ref (G_OBJECT (tree->insert_mark)); - g_object_ref (G_OBJECT (tree->selection_bound_mark)); + g_object_ref (tree->insert_mark); + g_object_ref (tree->selection_bound_mark); } tree->refcount = 1; @@ -499,19 +502,29 @@ _gtk_text_btree_unref (GtkTextBTree *tree) tree->refcount -= 1; if (tree->refcount == 0) - { - gtk_text_btree_node_destroy (tree, tree->root_node); + { + g_signal_handler_disconnect (tree->table, + tree->tag_changed_handler); + g_object_unref (tree->table); + tree->table = NULL; + + gtk_text_btree_node_destroy (tree, tree->root_node); + tree->root_node = NULL; + g_assert (g_hash_table_size (tree->mark_table) == 0); g_hash_table_destroy (tree->mark_table); - - g_object_unref (G_OBJECT (tree->insert_mark)); - g_object_unref (G_OBJECT (tree->selection_bound_mark)); - - g_signal_handler_disconnect (G_OBJECT (tree->table), - tree->tag_changed_handler); - - g_object_unref (G_OBJECT (tree->table)); + tree->mark_table = NULL; + if (tree->child_anchor_table != NULL) + { + g_hash_table_destroy (tree->child_anchor_table); + tree->child_anchor_table = NULL; + } + + g_object_unref (tree->insert_mark); + tree->insert_mark = NULL; + g_object_unref (tree->selection_bound_mark); + tree->selection_bound_mark = NULL; g_free (tree); } @@ -546,20 +559,189 @@ _gtk_text_btree_segments_changed (GtkTextBTree *tree) * Indexable segment mutation */ +/* + * The following function is responsible for resolving the bidi direction + * for the lines between start and end. But it also calculates any + * dependent bidi direction for surrounding lines that change as a result + * of the bidi direction decisions within the range. The function is + * trying to do as little propagation as is needed. + */ +static void +gtk_text_btree_resolve_bidi (GtkTextIter *start, + GtkTextIter *end) +{ + GtkTextBTree *tree = _gtk_text_iter_get_btree (start); + GtkTextLine *start_line, *end_line, *start_line_prev, *end_line_next, *line; + PangoDirection last_strong, dir_above_propagated, dir_below_propagated; + + /* Resolve the strong bidi direction for all lines between + * start and end. + */ + start_line = _gtk_text_iter_get_text_line (start); + start_line_prev = _gtk_text_line_previous (start_line); + end_line = _gtk_text_iter_get_text_line (end); + end_line_next = _gtk_text_line_next (end_line); + + line = start_line; + while (line && line != end_line_next) + { + /* Loop through the segments and search for a strong character + */ + GtkTextLineSegment *seg = line->segments; + line->dir_strong = PANGO_DIRECTION_NEUTRAL; + + while (seg) + { + if (seg->type == >k_text_char_type && seg->byte_count > 0) + { + PangoDirection pango_dir; + + pango_dir = pango_find_base_dir (seg->body.chars, + seg->byte_count); + + if (pango_dir != PANGO_DIRECTION_NEUTRAL) + { + line->dir_strong = pango_dir; + break; + } + } + seg = seg->next; + } + + line = _gtk_text_line_next (line); + } + + /* Sweep forward */ + + /* The variable dir_above_propagated contains the forward propagated + * direction before start. It is neutral if start is in the beginning + * of the buffer. + */ + dir_above_propagated = PANGO_DIRECTION_NEUTRAL; + if (start_line_prev) + dir_above_propagated = start_line_prev->dir_propagated_forward; + + /* Loop forward and propagate the direction of each paragraph + * to all neutral lines. + */ + line = start_line; + last_strong = dir_above_propagated; + while (line != end_line_next) + { + if (line->dir_strong != PANGO_DIRECTION_NEUTRAL) + last_strong = line->dir_strong; + + line->dir_propagated_forward = last_strong; + + line = _gtk_text_line_next (line); + } + + /* Continue propagating as long as the previous resolved forward + * is different from last_strong. + */ + { + GtkTextIter end_propagate; + + while (line && + line->dir_strong == PANGO_DIRECTION_NEUTRAL && + line->dir_propagated_forward != last_strong) + { + GtkTextLine *prev = line; + line->dir_propagated_forward = last_strong; + + line = _gtk_text_line_next(line); + if (!line) + { + line = prev; + break; + } + } + + /* The last line to invalidate is the last line before the + * line with the strong character. Or in case of the end of the + * buffer, the last line of the buffer. (There seems to be an + * extra "virtual" last line in the buffer that must not be used + * calling _gtk_text_btree_get_iter_at_line (causes crash). Thus the + * _gtk_text_line_previous is ok in that case as well.) + */ + line = _gtk_text_line_previous (line); + _gtk_text_btree_get_iter_at_line (tree, &end_propagate, line, 0); + _gtk_text_btree_invalidate_region (tree, end, &end_propagate, FALSE); + } + + /* Sweep backward */ + + /* The variable dir_below_propagated contains the backward propagated + * direction after end. It is neutral if end is at the end of + * the buffer. + */ + dir_below_propagated = PANGO_DIRECTION_NEUTRAL; + if (end_line_next) + dir_below_propagated = end_line_next->dir_propagated_back; + + /* Loop backward and propagate the direction of each paragraph + * to all neutral lines. + */ + line = end_line; + last_strong = dir_below_propagated; + while (line != start_line_prev) + { + if (line->dir_strong != PANGO_DIRECTION_NEUTRAL) + last_strong = line->dir_strong; + + line->dir_propagated_back = last_strong; + + line = _gtk_text_line_previous (line); + } + + /* Continue propagating as long as the resolved backward dir + * is different from last_strong. + */ + { + GtkTextIter start_propagate; + + while (line && + line->dir_strong == PANGO_DIRECTION_NEUTRAL && + line->dir_propagated_back != last_strong) + { + GtkTextLine *prev = line; + line->dir_propagated_back = last_strong; + + line = _gtk_text_line_previous (line); + if (!line) + { + line = prev; + break; + } + } + + /* We only need to invalidate for backwards propagation if the + * line we ended up on didn't get a direction from forwards + * propagation. + */ + if (line && line->dir_propagated_forward == PANGO_DIRECTION_NEUTRAL) + { + _gtk_text_btree_get_iter_at_line (tree, &start_propagate, line, 0); + _gtk_text_btree_invalidate_region (tree, &start_propagate, start, FALSE); + } + } +} + void _gtk_text_btree_delete (GtkTextIter *start, - GtkTextIter *end) + GtkTextIter *end) { GtkTextLineSegment *prev_seg; /* The segment just before the 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; GtkTextLine *start_line; GtkTextLine *end_line; + GtkTextLine *line; GtkTextLine *deleted_lines = NULL; /* List of lines we've deleted */ gint start_byte_offset; @@ -572,69 +754,12 @@ _gtk_text_btree_delete (GtkTextIter *start, tree = _gtk_text_iter_get_btree (start); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); - { - /* FIXME this code should no longer be required */ - /* - * The code below is ugly, but it's needed to make sure there - * is always a dummy empty line at the end of the text. If the - * final newline of the file (just before the dummy line) is being - * deleted, then back up index to just before the newline. If - * there is a newline just before the first character being deleted, - * then back up the first index too, so that an even number of lines - * gets deleted. Furthermore, remove any tags that are present on - * the newline that isn't going to be deleted after all (this simulates - * deleting the newline and then adding a "clean" one back again). - */ - - gint line1; - gint line2; - - line1 = gtk_text_iter_get_line (start); - line2 = gtk_text_iter_get_line (end); - - if (line2 == _gtk_text_btree_line_count (tree)) - { - GtkTextTag** tags; - int array_size; - GtkTextIter orig_end; - - orig_end = *end; - gtk_text_iter_backward_char (end); - - --line2; - - if (gtk_text_iter_get_line_offset (start) == 0 && - line1 != 0) - { - gtk_text_iter_backward_char (start); - --line1; - } - - tags = _gtk_text_btree_get_tags (end, - &array_size); - - if (tags != NULL) - { - int i; - - i = 0; - while (i < array_size) - { - _gtk_text_btree_tag (end, &orig_end, tags[i], FALSE); - - ++i; - } - - g_free (tags); - } - } - } - /* Broadcast the need for redisplay before we break the iterators */ - _gtk_text_btree_invalidate_region (tree, start, end); + DV (g_print ("invalidating due to deleting some text (%s)\n", G_STRLOC)); + _gtk_text_btree_invalidate_region (tree, start, end, FALSE); /* Save the byte offset so we can reset the iterators */ start_byte_offset = gtk_text_iter_get_line_index (start); @@ -764,12 +889,30 @@ _gtk_text_btree_delete (GtkTextIter *start, seg->next = start_line->segments; start_line->segments = seg; } - else - { + else if (prev_seg->next && + prev_seg->next != last_seg && + seg->type == >k_text_toggle_off_type && + prev_seg->next->type == >k_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; } @@ -850,7 +993,6 @@ _gtk_text_btree_delete (GtkTextIter *start, view = tree->views; while (view) { - GtkTextLine *line; GtkTextLineData *ld; gint deleted_width = 0; @@ -868,24 +1010,27 @@ _gtk_text_btree_delete (GtkTextIter *start, deleted_height += ld->height; } - if (!view->next) - gtk_text_line_destroy (tree, line); - line = next_line; } if (deleted_width > 0 || deleted_height > 0) { ld = _gtk_text_line_get_data (start_line, view->view_id); - - /* FIXME: ld is _NOT_ necessarily non-null here, but there is currently - * no way to add ld without also validating the node, which would - * be improper at this point. - */ - /* This assertion does actually fail sometimes, must - fix before stable release -hp */ - g_assert (ld); - + + if (ld == NULL) + { + /* This means that start_line has never been validated. + * We don't really want to do the validation here but + * we do need to store our temporary sizes. So we + * create the line data and assume a line w/h of 0. + */ + ld = _gtk_text_line_data_new (view->layout, start_line); + _gtk_text_line_add_data (start_line, ld); + ld->width = 0; + ld->height = 0; + ld->valid = FALSE; + } + ld->width = MAX (deleted_width, ld->width); ld->height += deleted_height; ld->valid = FALSE; @@ -898,6 +1043,16 @@ _gtk_text_btree_delete (GtkTextIter *start, view = view->next; } + line = deleted_lines; + while (line) + { + GtkTextLine *next_line = line->next; + + gtk_text_line_destroy (tree, line); + + line = next_line; + } + /* avoid dangling pointer */ deleted_lines = NULL; @@ -921,12 +1076,14 @@ _gtk_text_btree_delete (GtkTextIter *start, chars_changed (tree); segments_changed (tree); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); /* Re-initialize our iterators */ _gtk_text_btree_get_iter_at_line (tree, start, start_line, start_byte_offset); *end = *start; + + gtk_text_btree_resolve_bidi (start, end); } void @@ -1086,12 +1243,14 @@ _gtk_text_btree_insert (GtkTextIter *iter, above. FIXME */ gtk_text_iter_forward_chars (&end, char_count_delta); - _gtk_text_btree_invalidate_region (tree, - &start, &end); + DV (g_print ("invalidating due to inserting some text (%s)\n", G_STRLOC)); + _gtk_text_btree_invalidate_region (tree, &start, &end, FALSE); /* Convenience for the user */ *iter = end; + + gtk_text_btree_resolve_bidi (&start, &end); } } @@ -1134,7 +1293,8 @@ insert_pixbuf_or_widget_segment (GtkTextIter *iter, *iter = start; gtk_text_iter_forward_char (iter); /* skip forward past the segment */ - _gtk_text_btree_invalidate_region (tree, &start, iter); + DV (g_print ("invalidating due to inserting pixbuf/widget (%s)\n", G_STRLOC)); + _gtk_text_btree_invalidate_region (tree, &start, iter, FALSE); } void @@ -1198,7 +1358,7 @@ find_line_by_y (GtkTextBTree *tree, BTreeView *view, { gint current_y = 0; - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); if (node->level == 0) @@ -1467,9 +1627,10 @@ _gtk_text_btree_remove_view (GtkTextBTree *tree, } void -_gtk_text_btree_invalidate_region (GtkTextBTree *tree, - const GtkTextIter *start, - const GtkTextIter *end) +_gtk_text_btree_invalidate_region (GtkTextBTree *tree, + const GtkTextIter *start, + const GtkTextIter *end, + gboolean cursors_only) { BTreeView *view; @@ -1477,7 +1638,10 @@ _gtk_text_btree_invalidate_region (GtkTextBTree *tree, while (view != NULL) { - gtk_text_layout_invalidate (view->layout, start, end); + if (cursors_only) + gtk_text_layout_invalidate_cursors (view->layout, start, end); + else + gtk_text_layout_invalidate (view->layout, start, end); view = view->next; } @@ -1510,7 +1674,7 @@ static IterStack* iter_stack_new (void) { IterStack *stack; - stack = g_new (IterStack, 1); + stack = g_slice_new (IterStack); stack->iters = NULL; stack->count = 0; stack->alloced = 0; @@ -1518,20 +1682,22 @@ iter_stack_new (void) } static void -iter_stack_push (IterStack *stack, const GtkTextIter *iter) +iter_stack_push (IterStack *stack, + const GtkTextIter *iter) { stack->count += 1; if (stack->count > stack->alloced) { stack->alloced = stack->count*2; stack->iters = g_realloc (stack->iters, - stack->alloced*sizeof (GtkTextIter)); + stack->alloced * sizeof (GtkTextIter)); } stack->iters[stack->count-1] = *iter; } static gboolean -iter_stack_pop (IterStack *stack, GtkTextIter *iter) +iter_stack_pop (IterStack *stack, + GtkTextIter *iter) { if (stack->count == 0) return FALSE; @@ -1547,7 +1713,7 @@ static void iter_stack_free (IterStack *stack) { g_free (stack->iters); - g_free (stack); + g_slice_free (IterStack, stack); } static void @@ -1579,12 +1745,13 @@ queue_tag_redisplay (GtkTextBTree *tree, { if (_gtk_text_tag_affects_size (tag)) { - _gtk_text_btree_invalidate_region (tree, start, end); + DV (g_print ("invalidating due to size-affecting tag (%s)\n", G_STRLOC)); + _gtk_text_btree_invalidate_region (tree, start, end, FALSE); } else if (_gtk_text_tag_affects_nonsize_appearance (tag)) { /* We only need to queue a redraw, not a relayout */ - redisplay_region (tree, start, end); + redisplay_region (tree, start, end, FALSE); } /* We don't need to do anything if the tag doesn't affect display */ @@ -1612,7 +1779,7 @@ _gtk_text_btree_tag (const GtkTextIter *start_orig, g_return_if_fail (GTK_IS_TEXT_TAG (tag)); g_return_if_fail (_gtk_text_iter_get_btree (start_orig) == _gtk_text_iter_get_btree (end_orig)); - g_return_if_fail (tag->table == _gtk_text_iter_get_btree (start_orig)->table); + g_return_if_fail (tag->priv->table == _gtk_text_iter_get_btree (start_orig)->table); #if 0 printf ("%s tag %s from %d to %d\n", @@ -1727,7 +1894,7 @@ _gtk_text_btree_tag (const GtkTextIter *start_orig, g_assert (seg != NULL); g_assert (indexable_seg != NULL); g_assert (seg != indexable_seg); - + if ( (seg->type == >k_text_toggle_on_type || seg->type == >k_text_toggle_off_type) && (seg->body.toggle.info == info) ) @@ -1841,7 +2008,9 @@ _gtk_text_btree_tag (const GtkTextIter *start_orig, segments_changed (tree); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + queue_tag_redisplay (tree, tag, &start, &end); + + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); } @@ -1955,7 +2124,6 @@ _gtk_text_btree_get_line_at_char (GtkTextBTree *tree, GtkTextLineSegment *seg; int chars_left; int chars_in_line; - int bytes_in_line; node = tree->root_node; @@ -2001,7 +2169,6 @@ _gtk_text_btree_get_line_at_char (GtkTextBTree *tree, */ chars_in_line = 0; - bytes_in_line = 0; seg = NULL; for (line = node->children.line; line != NULL; line = line->next) { @@ -2031,6 +2198,8 @@ _gtk_text_btree_get_line_at_char (GtkTextBTree *tree, return line; } +/* It returns an array sorted by tags priority, ready to pass to + * _gtk_text_attributes_fill_from_tags() */ GtkTextTag** _gtk_text_btree_get_tags (const GtkTextIter *iter, gint *num_tags) @@ -2041,13 +2210,11 @@ _gtk_text_btree_get_tags (const GtkTextIter *iter, int src, dst, index; TagInfo tagInfo; GtkTextLine *line; - GtkTextBTree *tree; gint byte_index; #define NUM_TAG_INFOS 10 line = _gtk_text_iter_get_text_line (iter); - tree = _gtk_text_iter_get_btree (iter); byte_index = gtk_text_iter_get_line_index (iter); tagInfo.numTags = 0; @@ -2141,6 +2308,10 @@ _gtk_text_btree_get_tags (const GtkTextIter *iter, g_free (tagInfo.tags); return NULL; } + + /* Sort tags in ascending order of priority */ + _gtk_text_tag_array_sort (tagInfo.tags, dst); + return tagInfo.tags; } @@ -2219,8 +2390,8 @@ copy_segment (GString *string, if (copy) { g_string_append_len (string, - gtk_text_unknown_char_utf8, - 3); + _gtk_text_unknown_char_utf8, + GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN); } } @@ -2235,7 +2406,6 @@ _gtk_text_btree_get_text (const GtkTextIter *start_orig, GtkTextLineSegment *seg; GtkTextLineSegment *end_seg; GString *retval; - GtkTextBTree *tree; gchar *str; GtkTextIter iter; GtkTextIter start; @@ -2251,9 +2421,7 @@ _gtk_text_btree_get_text (const GtkTextIter *start_orig, gtk_text_iter_order (&start, &end); - retval = g_string_new (""); - - tree = _gtk_text_iter_get_btree (&start); + retval = g_string_new (NULL); end_seg = _gtk_text_iter_get_indexable_segment (&end); iter = start; @@ -2298,7 +2466,7 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) { gboolean invisible = FALSE; /* if nobody says otherwise, it's visible */ - int deftagCnts[LOTSA_TAGS]; + int deftagCnts[LOTSA_TAGS] = { 0, }; int *tagCnts = deftagCnts; GtkTextTag *deftags[LOTSA_TAGS]; GtkTextTag **tags = deftags; @@ -2321,15 +2489,10 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) /* almost always avoid malloc, so stay out of system calls */ if (LOTSA_TAGS < numTags) { - tagCnts = g_new (int, numTags); + tagCnts = g_new0 (int, numTags); tags = g_new (GtkTextTag*, numTags); } - for (i=0; itype == >k_text_toggle_off_type)) { tag = seg->body.toggle.info->tag; - if (tag->invisible_set && tag->values->invisible) + if (tag->priv->invisible_set) { - tags[tag->priority] = tag; - tagCnts[tag->priority]++; + tags[tag->priv->priority] = tag; + tagCnts[tag->priv->priority]++; } } } @@ -2367,10 +2530,10 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) || (seg->type == >k_text_toggle_off_type)) { tag = seg->body.toggle.info->tag; - if (tag->invisible_set && tag->values->invisible) + if (tag->priv->invisible_set) { - tags[tag->priority] = tag; - tagCnts[tag->priority]++; + tags[tag->priv->priority] = tag; + tagCnts[tag->priv->priority]++; } } } @@ -2396,10 +2559,10 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) if (summary->toggle_count & 1) { tag = summary->info->tag; - if (tag->invisible_set && tag->values->invisible) + if (tag->priv->invisible_set) { - tags[tag->priority] = tag; - tagCnts[tag->priority] += summary->toggle_count; + tags[tag->priv->priority] = tag; + tagCnts[tag->priv->priority] += summary->toggle_count; } } } @@ -2426,7 +2589,7 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) } #endif #endif - invisible = tags[i]->values->invisible; + invisible = tags[i]->priv->values->invisible; break; } } @@ -2448,7 +2611,8 @@ _gtk_text_btree_char_is_invisible (const GtkTextIter *iter) static void redisplay_region (GtkTextBTree *tree, const GtkTextIter *start, - const GtkTextIter *end) + const GtkTextIter *end, + gboolean cursors_only) { BTreeView *view; GtkTextLine *start_line, *end_line; @@ -2480,9 +2644,14 @@ redisplay_region (GtkTextBTree *tree, if (ld) end_y += ld->height; - gtk_text_layout_changed (view->layout, start_y, - end_y - start_y, - end_y - start_y); + if (cursors_only) + gtk_text_layout_cursors_changed (view->layout, start_y, + end_y - start_y, + end_y - start_y); + else + gtk_text_layout_changed (view->layout, start_y, + end_y - start_y, + end_y - start_y); view = view->next; } @@ -2493,6 +2662,7 @@ redisplay_mark (GtkTextLineSegment *mark) { GtkTextIter iter; GtkTextIter end; + gboolean cursor_only; _gtk_text_btree_get_iter_at_mark (mark->body.mark.tree, &iter, @@ -2501,8 +2671,9 @@ redisplay_mark (GtkTextLineSegment *mark) end = iter; gtk_text_iter_forward_char (&end); - _gtk_text_btree_invalidate_region (mark->body.mark.tree, - &iter, &end); + DV (g_print ("invalidating due to moving visible mark (%s)\n", G_STRLOC)); + cursor_only = mark == mark->body.mark.tree->insert_mark->segment; + _gtk_text_btree_invalidate_region (mark->body.mark.tree, &iter, &end, cursor_only); } static void @@ -2519,8 +2690,7 @@ ensure_not_off_end (GtkTextBTree *tree, GtkTextLineSegment *mark, GtkTextIter *iter) { - if (gtk_text_iter_get_line (iter) == - _gtk_text_btree_line_count (tree)) + if (gtk_text_iter_get_line (iter) == _gtk_text_btree_line_count (tree)) gtk_text_iter_backward_char (iter); } @@ -2541,7 +2711,12 @@ real_set_mark (GtkTextBTree *tree, g_return_val_if_fail (_gtk_text_iter_get_btree (where) == tree, NULL); if (existing_mark) - mark = existing_mark->segment; + { + if (gtk_text_mark_get_buffer (existing_mark) != NULL) + mark = existing_mark->segment; + else + mark = NULL; + } else if (name != NULL) mark = g_hash_table_lookup (tree->mark_table, name); @@ -2560,7 +2735,7 @@ real_set_mark (GtkTextBTree *tree, iter = *where; - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_iter_check (&iter); if (mark != NULL) @@ -2573,7 +2748,7 @@ real_set_mark (GtkTextBTree *tree, _gtk_text_btree_get_iter_at_mark (tree, &old_pos, mark->body.mark.obj); - redisplay_region (tree, &old_pos, where); + redisplay_region (tree, &old_pos, where, TRUE); } /* @@ -2601,9 +2776,13 @@ real_set_mark (GtkTextBTree *tree, } else { - mark = _gtk_mark_segment_new (tree, - left_gravity, - name); + if (existing_mark) + g_object_ref (existing_mark); + else + existing_mark = gtk_text_mark_new (name, left_gravity); + + mark = existing_mark->segment; + _gtk_mark_segment_set_tree (mark, tree); mark->body.mark.line = _gtk_text_iter_get_text_line (&iter); @@ -2613,7 +2792,7 @@ real_set_mark (GtkTextBTree *tree, mark); } - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_iter_check (&iter); /* Link mark into new location */ @@ -2628,10 +2807,10 @@ real_set_mark (GtkTextBTree *tree, redisplay_mark_if_visible (mark); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_iter_check (&iter); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); return mark; @@ -2695,18 +2874,39 @@ void _gtk_text_btree_place_cursor (GtkTextBTree *tree, const GtkTextIter *iter) { - GtkTextIter start, end; + _gtk_text_btree_select_range (tree, iter, iter); +} + +void +_gtk_text_btree_select_range (GtkTextBTree *tree, + const GtkTextIter *ins, + const GtkTextIter *bound) +{ + GtkTextIter old_ins, old_bound; + + _gtk_text_btree_get_iter_at_mark (tree, &old_ins, + tree->insert_mark); + _gtk_text_btree_get_iter_at_mark (tree, &old_bound, + tree->selection_bound_mark); + + /* Check if it's no-op since gtk_text_buffer_place_cursor() + * also calls this, and this will redraw the cursor line. */ + if (!gtk_text_iter_equal (&old_ins, ins) || + !gtk_text_iter_equal (&old_bound, bound)) + { + redisplay_region (tree, &old_ins, &old_bound, TRUE); - if (_gtk_text_btree_get_selection_bounds (tree, &start, &end)) - redisplay_region (tree, &start, &end); + /* Move insert AND selection_bound before we redisplay */ + real_set_mark (tree, tree->insert_mark, + "insert", FALSE, ins, TRUE, FALSE); + real_set_mark (tree, tree->selection_bound_mark, + "selection_bound", FALSE, bound, TRUE, FALSE); - /* Move insert AND selection_bound before we redisplay */ - real_set_mark (tree, tree->insert_mark, - "insert", FALSE, iter, TRUE, FALSE); - real_set_mark (tree, tree->selection_bound_mark, - "selection_bound", FALSE, iter, TRUE, FALSE); + redisplay_region (tree, ins, bound, TRUE); + } } + void _gtk_text_btree_remove_mark_by_name (GtkTextBTree *tree, const gchar *name) @@ -2736,7 +2936,7 @@ _gtk_text_btree_release_mark_segment (GtkTextBTree *tree, /* Remove the ref on the mark, which frees segment as a side effect * if this is the last reference. */ - g_object_unref (G_OBJECT (segment->body.mark.obj)); + g_object_unref (segment->body.mark.obj); } void @@ -2776,6 +2976,18 @@ _gtk_text_btree_mark_is_selection_bound (GtkTextBTree *tree, return segment == tree->selection_bound_mark; } +GtkTextMark * +_gtk_text_btree_get_insert (GtkTextBTree *tree) +{ + return tree->insert_mark; +} + +GtkTextMark * +_gtk_text_btree_get_selection_bound (GtkTextBTree *tree) +{ + return tree->selection_bound_mark; +} + GtkTextMark* _gtk_text_btree_get_mark_by_name (GtkTextBTree *tree, const gchar *name) @@ -2818,7 +3030,8 @@ gtk_text_mark_set_visible (GtkTextMark *mark, { seg->body.mark.visible = setting; - redisplay_mark (seg); + if (seg->body.mark.tree) + redisplay_mark (seg); } } @@ -3188,13 +3401,10 @@ ensure_end_iter_line (GtkTextBTree *tree) { if (tree->end_iter_line_stamp != tree->chars_changed_stamp) { - int n_lines; - int real_line; - - /* n_lines is without the magic line at the end */ - n_lines = _gtk_text_btree_line_count (tree); - - g_assert (n_lines >= 1); + gint real_line; + + /* n_lines is without the magic line at the end */ + g_assert (_gtk_text_btree_line_count (tree) >= 1); tree->end_iter_line = _gtk_text_btree_get_line_no_last (tree, -1, &real_line); @@ -3377,9 +3587,27 @@ _gtk_text_line_previous (GtkTextLine *line) return NULL; } + +GtkTextLineData* +_gtk_text_line_data_new (GtkTextLayout *layout, + GtkTextLine *line) +{ + GtkTextLineData *line_data; + + line_data = g_new (GtkTextLineData, 1); + + line_data->view_id = layout; + line_data->next = NULL; + line_data->width = 0; + line_data->height = 0; + line_data->valid = FALSE; + + return line_data; +} + void _gtk_text_line_add_data (GtkTextLine *line, - GtkTextLineData *data) + GtkTextLineData *data) { g_return_if_fail (line != NULL); g_return_if_fail (data != NULL); @@ -3599,9 +3827,9 @@ _gtk_text_line_byte_to_segment (GtkTextLine *line, while (offset >= seg->byte_count) { - g_assert (seg != NULL); /* means an invalid byte index */ offset -= seg->byte_count; seg = seg->next; + g_assert (seg != NULL); /* means an invalid byte index */ } if (seg_offset) @@ -3625,9 +3853,9 @@ _gtk_text_line_char_to_segment (GtkTextLine *line, while (offset >= seg->char_count) { - g_assert (seg != NULL); /* means an invalid char index */ offset -= seg->char_count; seg = seg->next; + g_assert (seg != NULL); /* means an invalid char index */ } if (seg_offset) @@ -3651,9 +3879,9 @@ _gtk_text_line_byte_to_any_segment (GtkTextLine *line, while (offset > 0 && offset >= seg->byte_count) { - g_assert (seg != NULL); /* means an invalid byte index */ offset -= seg->byte_count; seg = seg->next; + g_assert (seg != NULL); /* means an invalid byte index */ } if (seg_offset) @@ -3677,9 +3905,9 @@ _gtk_text_line_char_to_any_segment (GtkTextLine *line, while (offset > 0 && offset >= seg->char_count) { - g_assert (seg != NULL); /* means an invalid byte index */ offset -= seg->char_count; seg = seg->next; + g_assert (seg != NULL); /* means an invalid byte index */ } if (seg_offset) @@ -3703,12 +3931,10 @@ _gtk_text_line_byte_to_char (GtkTextLine *line, while (byte_offset >= seg->byte_count) /* while (we need to go farther than the next segment) */ { - g_assert (seg != NULL); /* our byte_index was bogus if this happens */ - byte_offset -= seg->byte_count; char_offset += seg->char_count; - seg = seg->next; + g_assert (seg != NULL); /* our byte_index was bogus if this happens */ } g_assert (seg != NULL); @@ -3752,7 +3978,6 @@ _gtk_text_line_byte_locate (GtkTextLine *line, gint *line_byte_offset) { GtkTextLineSegment *seg; - GtkTextLineSegment *after_prev_indexable; GtkTextLineSegment *after_last_indexable; GtkTextLineSegment *last_indexable; gint offset; @@ -3769,7 +3994,6 @@ _gtk_text_line_byte_locate (GtkTextLine *line, last_indexable = NULL; after_last_indexable = line->segments; - after_prev_indexable = line->segments; seg = line->segments; /* The loop ends when we're inside a segment; @@ -3782,7 +4006,6 @@ _gtk_text_line_byte_locate (GtkTextLine *line, offset -= seg->byte_count; bytes_in_line += seg->byte_count; last_indexable = seg; - after_prev_indexable = after_last_indexable; after_last_indexable = last_indexable->next; } @@ -3832,7 +4055,6 @@ _gtk_text_line_char_locate (GtkTextLine *line, gint *line_char_offset) { GtkTextLineSegment *seg; - GtkTextLineSegment *after_prev_indexable; GtkTextLineSegment *after_last_indexable; GtkTextLineSegment *last_indexable; gint offset; @@ -3849,7 +4071,6 @@ _gtk_text_line_char_locate (GtkTextLine *line, last_indexable = NULL; after_last_indexable = line->segments; - after_prev_indexable = line->segments; seg = line->segments; /* The loop ends when we're inside a segment; @@ -3862,7 +4083,6 @@ _gtk_text_line_char_locate (GtkTextLine *line, offset -= seg->char_count; chars_in_line += seg->char_count; last_indexable = seg; - after_prev_indexable = after_last_indexable; after_last_indexable = last_indexable->next; } @@ -3979,16 +4199,16 @@ _gtk_text_line_char_to_byte_offsets (GtkTextLine *line, if (seg->type == >k_text_char_type) { - *seg_byte_offset = 0; - while (offset > 0) - { - gint bytes; - const char * start = seg->body.chars + *seg_byte_offset; + const char *p; - bytes = g_utf8_next_char (start) - start; - *seg_byte_offset += bytes; - offset -= 1; - } + /* if in the last fourth of the segment walk backwards */ + if (seg->char_count - offset < seg->char_count / 4) + p = g_utf8_offset_to_pointer (seg->body.chars + seg->byte_count, + offset - seg->char_count); + else + p = g_utf8_offset_to_pointer (seg->body.chars, offset); + + *seg_byte_offset = p - seg->body.chars; g_assert (*seg_byte_offset < seg->byte_count); @@ -4108,7 +4328,7 @@ _gtk_text_line_next_could_contain_tag (GtkTextLine *line, g_return_val_if_fail (line != NULL, NULL); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); if (tag == NULL) @@ -4271,7 +4491,7 @@ _gtk_text_line_previous_could_contain_tag (GtkTextLine *line, g_return_val_if_fail (line != NULL, NULL); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); if (tag == NULL) @@ -4326,9 +4546,7 @@ _gtk_text_line_previous_could_contain_tag (GtkTextLine *line, line_ancestor = line->parent; line_ancestor_parent = line->parent->parent; - node = line_ancestor_parent->children.node; - while (node != line_ancestor && - line_ancestor != info->tag_root) + while (line_ancestor != info->tag_root) { GSList *child_nodes = NULL; GSList *tmp; @@ -4336,8 +4554,12 @@ _gtk_text_line_previous_could_contain_tag (GtkTextLine *line, /* Create reverse-order list of nodes before * line_ancestor */ - while (node != line_ancestor - && node != NULL) + if (line_ancestor_parent != NULL) + node = line_ancestor_parent->children.node; + else + node = line_ancestor; + + while (node != line_ancestor && node != NULL) { child_nodes = g_slist_prepend (child_nodes, node); @@ -4367,8 +4589,6 @@ _gtk_text_line_previous_could_contain_tag (GtkTextLine *line, /* Didn't find anything on this level; go up one level. */ line_ancestor = line_ancestor_parent; line_ancestor_parent = line_ancestor->parent; - - node = line_ancestor_parent->children.node; } /* No dice. */ @@ -4466,13 +4686,7 @@ _gtk_text_line_previous_could_contain_tag (GtkTextLine *line, static void summary_list_destroy (Summary *summary) { - Summary *next; - while (summary != NULL) - { - next = summary->next; - summary_destroy (summary); - summary = next; - } + g_slice_free_chain (Summary, summary, next); } static GtkTextLine* @@ -4506,7 +4720,10 @@ gtk_text_line_new (void) { GtkTextLine *line; - line = g_new0(GtkTextLine, 1); + line = g_slice_new0 (GtkTextLine); + line->dir_strong = PANGO_DIRECTION_NEUTRAL; + line->dir_propagated_forward = PANGO_DIRECTION_NEUTRAL; + line->dir_propagated_back = PANGO_DIRECTION_NEUTRAL; return line; } @@ -4534,7 +4751,7 @@ gtk_text_line_destroy (GtkTextBTree *tree, GtkTextLine *line) ld = next; } - g_free (line); + g_slice_free (GtkTextLine, line); } static void @@ -4567,16 +4784,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; } } } @@ -4590,7 +4811,7 @@ node_data_new (gpointer view_id) { NodeData *nd; - nd = g_new (NodeData, 1); + nd = g_slice_new (NodeData); nd->view_id = view_id; nd->next = NULL; @@ -4604,26 +4825,18 @@ node_data_new (gpointer view_id) static void node_data_destroy (NodeData *nd) { - g_free (nd); + g_slice_free (NodeData, nd); } static void node_data_list_destroy (NodeData *nd) { - NodeData *iter; - NodeData *next; - - iter = nd; - while (iter != NULL) - { - next = iter->next; - node_data_destroy (iter); - iter = next; - } + g_slice_free_chain (NodeData, nd, next); } static NodeData* -node_data_find (NodeData *nd, gpointer view_id) +node_data_find (NodeData *nd, + gpointer view_id) { while (nd != NULL) { @@ -4641,7 +4854,7 @@ summary_destroy (Summary *summary) summary->info = (void*)0x1; summary->toggle_count = 567; summary->next = (void*)0x1; - g_free (summary); + g_slice_free (Summary, summary); } static GtkTextBTreeNode* @@ -4649,7 +4862,7 @@ gtk_text_btree_node_new (void) { GtkTextBTreeNode *node; - node = g_new (GtkTextBTreeNode, 1); + node = g_slice_new (GtkTextBTreeNode); node->node_data = NULL; @@ -4679,7 +4892,7 @@ gtk_text_btree_node_adjust_toggle_count (GtkTextBTreeNode *node, { /* didn't find a summary for our tag. */ g_return_if_fail (adjust > 0); - summary = g_new (Summary, 1); + summary = g_slice_new (Summary); summary->info = info; summary->toggle_count = adjust; summary->next = node->summary; @@ -4709,6 +4922,7 @@ gtk_text_btree_node_has_tag (GtkTextBTreeNode *node, GtkTextTag *tag) } /* Add node and all children to the damage region. */ +#if 0 static void gtk_text_btree_node_invalidate_downward (GtkTextBTreeNode *node) { @@ -4754,6 +4968,7 @@ gtk_text_btree_node_invalidate_downward (GtkTextBTreeNode *node) } } } +#endif static void gtk_text_btree_node_invalidate_upward (GtkTextBTreeNode *node, gpointer view_id) @@ -5048,7 +5263,7 @@ _gtk_text_btree_validate (GtkTextBTree *tree, if (new_height) *new_height = state.new_height; - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); return TRUE; @@ -5298,7 +5513,7 @@ gtk_text_btree_node_free_empty (GtkTextBTree *tree, summary_list_destroy (node->summary); node_data_list_destroy (node->node_data); - g_free (node); + g_slice_free (GtkTextBTreeNode, node); } static NodeData* @@ -5446,8 +5661,8 @@ tag_changed_cb (GtkTextTagTable *table, { /* Must be a last toggle if there was a first one. */ _gtk_text_btree_get_iter_at_last_toggle (tree, &end, tag); - _gtk_text_btree_invalidate_region (tree, - &start, &end); + DV (g_print ("invalidating due to tag change (%s)\n", G_STRLOC)); + _gtk_text_btree_invalidate_region (tree, &start, &end, FALSE); } } @@ -5757,7 +5972,7 @@ post_insert_fixup (GtkTextBTree *tree, gtk_text_btree_rebalance (tree, node); } - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); } @@ -5794,14 +6009,20 @@ gtk_text_btree_get_tag_info (GtkTextBTree *tree, { /* didn't find it, create. */ - info = g_new (GtkTextTagInfo, 1); + info = g_slice_new (GtkTextTagInfo); info->tag = tag; - g_object_ref (G_OBJECT (tag)); + g_object_ref (tag); info->tag_root = NULL; info->toggle_count = 0; tree->tag_infos = g_slist_prepend (tree->tag_infos, info); + +#if 0 + g_print ("Created tag info %p for tag %s(%p)\n", + info, info->tag->name ? info->tag->name : "anon", + info->tag); +#endif } return info; @@ -5822,6 +6043,12 @@ gtk_text_btree_remove_tag_info (GtkTextBTree *tree, info = list->data; if (info->tag == tag) { +#if 0 + g_print ("Removing tag info %p for tag %s(%p)\n", + info, info->tag->name ? info->tag->name : "anon", + info->tag); +#endif + if (prev != NULL) { prev->next = list->next; @@ -5833,12 +6060,13 @@ gtk_text_btree_remove_tag_info (GtkTextBTree *tree, list->next = NULL; g_slist_free (list); - g_object_unref (G_OBJECT (info->tag)); + g_object_unref (info->tag); - g_free (info); + g_slice_free (GtkTextTagInfo, info); return; } + prev = list; list = g_slist_next (list); } } @@ -6134,7 +6362,7 @@ _gtk_change_node_toggle_count (GtkTextBTreeNode *node, */ GtkTextBTreeNode *rootnode = info->tag_root; - summary = (Summary *) g_malloc (sizeof (Summary)); + summary = g_slice_new (Summary); summary->info = info; summary->toggle_count = info->toggle_count - delta; summary->next = rootnode->summary; @@ -6143,7 +6371,7 @@ _gtk_change_node_toggle_count (GtkTextBTreeNode *node, rootLevel = rootnode->level; info->tag_root = rootnode; } - summary = (Summary *) g_malloc (sizeof (Summary)); + summary = g_slice_new (Summary); summary->info = info; summary->toggle_count = delta; summary->next = node->summary; @@ -6310,7 +6538,7 @@ gtk_text_btree_link_segment (GtkTextLineSegment *seg, cleanup_line (line); segments_changed (tree); - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) _gtk_text_btree_check (tree); } @@ -6571,7 +6799,7 @@ gtk_text_btree_node_check_consistency (GtkTextBTree *tree, break; } g_error ("gtk_text_btree_node_check_consistency: GtkTextBTreeNode tag \"%s\" not %s", - summary->info->tag->name, + summary->info->tag->priv->name, "present in parent summaries"); } if (summary->info == summary2->info) @@ -6607,7 +6835,7 @@ gtk_text_btree_node_check_consistency (GtkTextBTree *tree, if (summary->info->toggle_count == summary->toggle_count) { g_error ("gtk_text_btree_node_check_consistency: found unpruned root for \"%s\"", - summary->info->tag->name); + summary->info->tag->priv->name); } toggle_count = 0; if (node->level == 0) @@ -6661,7 +6889,7 @@ gtk_text_btree_node_check_consistency (GtkTextBTree *tree, if (summary2->info == summary->info) { g_error ("gtk_text_btree_node_check_consistency: duplicated GtkTextBTreeNode tag: %s", - summary->info->tag->name); + summary->info->tag->priv->name); } } } @@ -6693,15 +6921,15 @@ _gtk_text_btree_check (GtkTextBTree *tree) GtkTextLine *line; GtkTextLineSegment *seg; GtkTextTag *tag; - GSList *taglist = NULL; + GSList *all_tags, *taglist = NULL; int count; GtkTextTagInfo *info; /* * Make sure that the tag toggle counts and the tag root pointers are OK. */ - for (taglist = list_of_tags (tree->table); - taglist != NULL ; taglist = taglist->next) + all_tags = list_of_tags (tree->table); + for (taglist = all_tags; taglist != NULL ; taglist = taglist->next) { tag = taglist->data; info = gtk_text_btree_get_existing_tag_info (tree, tag); @@ -6713,19 +6941,19 @@ _gtk_text_btree_check (GtkTextBTree *tree) if (info->toggle_count != 0) { g_error ("_gtk_text_btree_check found \"%s\" with toggles (%d) but no root", - tag->name, info->toggle_count); + tag->priv->name, info->toggle_count); } continue; /* no ranges for the tag */ } else if (info->toggle_count == 0) { g_error ("_gtk_text_btree_check found root for \"%s\" with no toggles", - tag->name); + tag->priv->name); } else if (info->toggle_count & 1) { g_error ("_gtk_text_btree_check found odd toggle count for \"%s\" (%d)", - tag->name, info->toggle_count); + tag->priv->name, info->toggle_count); } for (summary = node->summary; summary != NULL; summary = summary->next) @@ -6753,7 +6981,7 @@ _gtk_text_btree_check (GtkTextBTree *tree) } else { - GtkTextLineSegmentClass * last = NULL; + const GtkTextLineSegmentClass *last = NULL; for (line = node->children.line ; line != NULL ; line = line->next) @@ -6780,13 +7008,12 @@ _gtk_text_btree_check (GtkTextBTree *tree) if (count != info->toggle_count) { g_error ("_gtk_text_btree_check toggle_count (%d) wrong for \"%s\" should be (%d)", - info->toggle_count, tag->name, count); + info->toggle_count, tag->priv->name, count); } } } - g_slist_free (taglist); - taglist = NULL; + g_slist_free (all_tags); /* * Call a recursive procedure to do the main body of checks. @@ -6890,7 +7117,7 @@ _gtk_text_btree_spew (GtkTextBTree *tree) info = list->data; printf (" tag `%s': root at %p, toggle count %d\n", - info->tag->name, info->tag_root, info->toggle_count); + info->tag->priv->name, info->tag_root, info->toggle_count); list = g_slist_next (list); } @@ -6956,7 +7183,7 @@ _gtk_text_btree_spew_line_short (GtkTextLine *line, int indent) seg->type == >k_text_toggle_off_type) { printf ("%s tag `%s' %s\n", - spaces, seg->body.toggle.info->tag->name, + spaces, seg->body.toggle.info->tag->priv->name, seg->type == >k_text_toggle_off_type ? "off" : "on"); } @@ -6983,7 +7210,7 @@ _gtk_text_btree_spew_node (GtkTextBTreeNode *node, int indent) while (s) { printf ("%s %d toggles of `%s' below this node\n", - spaces, s->toggle_count, s->info->tag->name); + spaces, s->toggle_count, s->info->tag->priv->name); s = s->next; } @@ -7058,9 +7285,7 @@ _gtk_text_btree_spew_segment (GtkTextBTree* tree, GtkTextLineSegment * seg) seg->type == >k_text_toggle_off_type) { printf (" tag `%s' priority %d\n", - seg->body.toggle.info->tag->name, - seg->body.toggle.info->tag->priority); + seg->body.toggle.info->tag->priv->name, + seg->body.toggle.info->tag->priv->priority); } } - -