X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtktextsegment.c;h=d1493d69a41459207f954e7f84a27acfe2740747;hb=ca2368dba958d6fecf2fce417307bb9cbbe6eb6b;hp=38e905865b69f387725a0a66e9b7d0db2a9de9a1;hpb=ee0895169d57f2d67f7d1b85f941a6fa31b439f0;p=~andy%2Fgtk diff --git a/gtk/gtktextsegment.c b/gtk/gtktextsegment.c index 38e905865..d1493d69a 100644 --- a/gtk/gtktextsegment.c +++ b/gtk/gtktextsegment.c @@ -12,7 +12,7 @@ * California, Sun Microsystems, Inc., and other parties. The * following terms apply to all files associated with the software * unless explicitly disclaimed in individual files. - * + * * The authors hereby grant permission to use, copy, modify, * distribute, and license this software and its documentation for any * purpose, provided that existing copyright notices are retained in @@ -22,13 +22,13 @@ * software may be copyrighted by their authors and need not follow * the licensing terms described here, provided that the new terms are * clearly indicated on the first page of each file where they apply. - * + * * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND @@ -47,12 +47,13 @@ * foregoing, the authors grant the U.S. Government and others acting * in its behalf permission to use and distribute the software in * accordance with the terms specified in this license. - * + * */ +#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API +#include "config.h" #include "gtktextbtree.h" #include -#include #include #include #include "gtktexttag.h" @@ -90,17 +91,20 @@ */ GtkTextLineSegment* -gtk_text_line_segment_split(const GtkTextIter *iter) +gtk_text_line_segment_split (const GtkTextIter *iter) { GtkTextLineSegment *prev, *seg; GtkTextBTree *tree; GtkTextLine *line; int count; - line = gtk_text_iter_get_line(iter); - tree = gtk_text_iter_get_btree(iter); - - count = gtk_text_iter_get_line_byte(iter); + line = _gtk_text_iter_get_text_line (iter); + tree = _gtk_text_iter_get_btree (iter); + + count = gtk_text_iter_get_line_index (iter); + + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) + _gtk_text_iter_check (iter); prev = NULL; seg = line->segments; @@ -115,13 +119,13 @@ gtk_text_line_segment_split(const GtkTextIter *iter) } else { - g_assert(count != seg->byte_count); - g_assert(seg->byte_count > 0); - - gtk_text_btree_segments_changed(tree); - + g_assert (count != seg->byte_count); + g_assert (seg->byte_count > 0); + + _gtk_text_btree_segments_changed (tree); + seg = (*seg->type->splitFunc)(seg, count); - + if (prev == NULL) line->segments = seg; else @@ -140,7 +144,7 @@ gtk_text_line_segment_split(const GtkTextIter *iter) prev = seg; seg = seg->next; } - g_error("split_segment reached end of line!"); + g_error ("split_segment reached end of line!"); return NULL; } @@ -149,86 +153,88 @@ gtk_text_line_segment_split(const GtkTextIter *iter) * Macros that determine how much space to allocate for new segments: */ -#define CSEG_SIZE(chars) ((unsigned) (G_STRUCT_OFFSET(GtkTextLineSegment, body) \ +#define CSEG_SIZE(chars) ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \ + 1 + (chars))) -#define TSEG_SIZE ((unsigned) (G_STRUCT_OFFSET(GtkTextLineSegment, body) \ - + sizeof(GtkTextToggleBody))) +#define TSEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \ + + sizeof (GtkTextToggleBody))) /* * Type functions */ static void -char_segment_self_check(GtkTextLineSegment *seg) +char_segment_self_check (GtkTextLineSegment *seg) { /* This function checks the segment itself, but doesn't assume the segment has been validly inserted into the btree. */ - - g_assert(seg != NULL); - + + g_assert (seg != NULL); + if (seg->byte_count <= 0) { - g_error("char_segment_check_func: segment has size <= 0"); + g_error ("segment has size <= 0"); } - if (strlen(seg->body.chars) != seg->byte_count) + if (strlen (seg->body.chars) != seg->byte_count) { - g_error("char_segment_check_func: segment has wrong size"); + g_error ("segment has wrong size"); } if (g_utf8_strlen (seg->body.chars, seg->byte_count) != seg->char_count) { - g_error("char segment has wrong character count"); + g_error ("char segment has wrong character count"); } } GtkTextLineSegment* -char_segment_new(const gchar *text, guint len) +_gtk_char_segment_new (const gchar *text, guint len) { GtkTextLineSegment *seg; - g_assert(gtk_text_byte_begins_utf8_char(text)); - - seg = g_malloc(CSEG_SIZE(len)); - seg->type = >k_text_char_type; + g_assert (gtk_text_byte_begins_utf8_char (text)); + + seg = g_malloc (CSEG_SIZE (len)); + seg->type = (GtkTextLineSegmentClass *)>k_text_char_type; seg->next = NULL; seg->byte_count = len; - memcpy(seg->body.chars, text, len); + memcpy (seg->body.chars, text, len); seg->body.chars[len] = '\0'; seg->char_count = g_utf8_strlen (seg->body.chars, seg->byte_count); - if (gtk_debug_flags & GTK_DEBUG_TEXT) - char_segment_self_check(seg); - + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) + char_segment_self_check (seg); + return seg; } GtkTextLineSegment* -char_segment_new_from_two_strings(const gchar *text1, guint len1, - const gchar *text2, guint len2) +_gtk_char_segment_new_from_two_strings (const gchar *text1, + guint len1, + guint chars1, + const gchar *text2, + guint len2, + guint chars2) { GtkTextLineSegment *seg; - g_assert(gtk_text_byte_begins_utf8_char(text1)); - g_assert(gtk_text_byte_begins_utf8_char(text2)); - - seg = g_malloc(CSEG_SIZE(len1+len2)); + g_assert (gtk_text_byte_begins_utf8_char (text1)); + g_assert (gtk_text_byte_begins_utf8_char (text2)); + + seg = g_malloc (CSEG_SIZE (len1+len2)); seg->type = >k_text_char_type; seg->next = NULL; seg->byte_count = len1 + len2; - memcpy(seg->body.chars, text1, len1); - memcpy(seg->body.chars + len1, text2, len2); + memcpy (seg->body.chars, text1, len1); + memcpy (seg->body.chars + len1, text2, len2); seg->body.chars[len1+len2] = '\0'; - /* In principle this function could probably take chars1 and chars2 - as args, since it's typically used to merge two char segments */ - seg->char_count = g_utf8_strlen (seg->body.chars, seg->byte_count); + seg->char_count = chars1 + chars2; + + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) + char_segment_self_check (seg); - if (gtk_debug_flags & GTK_DEBUG_TEXT) - char_segment_self_check(seg); - return seg; } @@ -251,35 +257,35 @@ char_segment_new_from_two_strings(const gchar *text1, guint len1, */ static GtkTextLineSegment * -char_segment_split_func(GtkTextLineSegment *seg, int index) +char_segment_split_func (GtkTextLineSegment *seg, int index) { GtkTextLineSegment *new1, *new2; - g_assert(index < seg->byte_count); - - if (gtk_debug_flags & GTK_DEBUG_TEXT) + g_assert (index < seg->byte_count); + + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) { - char_segment_self_check(seg); + char_segment_self_check (seg); } - - new1 = char_segment_new(seg->body.chars, index); - new2 = char_segment_new(seg->body.chars + index, seg->byte_count - index); - g_assert(gtk_text_byte_begins_utf8_char(new1->body.chars)); - g_assert(gtk_text_byte_begins_utf8_char(new2->body.chars)); - g_assert(new1->byte_count + new2->byte_count == seg->byte_count); - g_assert(new1->char_count + new2->char_count == seg->char_count); - + new1 = _gtk_char_segment_new (seg->body.chars, index); + new2 = _gtk_char_segment_new (seg->body.chars + index, seg->byte_count - index); + + g_assert (gtk_text_byte_begins_utf8_char (new1->body.chars)); + g_assert (gtk_text_byte_begins_utf8_char (new2->body.chars)); + g_assert (new1->byte_count + new2->byte_count == seg->byte_count); + g_assert (new1->char_count + new2->char_count == seg->char_count); + new1->next = new2; new2->next = seg->next; - if (gtk_debug_flags & GTK_DEBUG_TEXT) + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) { - char_segment_self_check(new1); - char_segment_self_check(new2); + char_segment_self_check (new1); + char_segment_self_check (new2); } - - g_free(seg); + + g_free (seg); return new1; } @@ -291,6 +297,11 @@ char_segment_split_func(GtkTextLineSegment *seg, int index) * This procedure merges adjacent character segments into * a single character segment, if possible. * + * Arguments: + * segPtr: Pointer to the first of two adjacent segments to + * join. + * line: Line containing segments (not used). + * * Results: * The return value is a pointer to the first segment in * the (new) list of segments that used to start with segPtr. @@ -303,33 +314,34 @@ char_segment_split_func(GtkTextLineSegment *seg, int index) /* ARGSUSED */ static GtkTextLineSegment * -char_segment_cleanup_func(segPtr, line) - GtkTextLineSegment *segPtr; /* Pointer to first of two adjacent - * segments to join. */ - GtkTextLine *line; /* Line containing segments (not - * used). */ +char_segment_cleanup_func (GtkTextLineSegment *segPtr, GtkTextLine *line) { GtkTextLineSegment *segPtr2, *newPtr; - if (gtk_debug_flags & GTK_DEBUG_TEXT) - char_segment_self_check(segPtr); - + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) + char_segment_self_check (segPtr); + segPtr2 = segPtr->next; if ((segPtr2 == NULL) || (segPtr2->type != >k_text_char_type)) { return segPtr; } - newPtr = char_segment_new_from_two_strings(segPtr->body.chars, segPtr->byte_count, - segPtr2->body.chars, segPtr2->byte_count); + newPtr = + _gtk_char_segment_new_from_two_strings (segPtr->body.chars, + segPtr->byte_count, + segPtr->char_count, + segPtr2->body.chars, + segPtr2->byte_count, + segPtr2->char_count); newPtr->next = segPtr2->next; - if (gtk_debug_flags & GTK_DEBUG_TEXT) - char_segment_self_check(newPtr); - - g_free(segPtr); - g_free(segPtr2); + if (gtk_get_debug_flags () & GTK_DEBUG_TEXT) + char_segment_self_check (newPtr); + + g_free (segPtr); + g_free (segPtr2); return newPtr; } @@ -340,6 +352,12 @@ char_segment_cleanup_func(segPtr, line) * * This procedure is invoked to delete a character segment. * + * Arguments: + * segPtr : Segment to delete + * line : Line containing segment + * treeGone : Non-zero means the entire tree is being + * deleted, so everything must get cleaned up. + * * Results: * Always returns 0 to indicate that the segment was deleted. * @@ -351,14 +369,9 @@ char_segment_cleanup_func(segPtr, line) /* ARGSUSED */ static int -char_segment_delete_func(segPtr, line, treeGone) - GtkTextLineSegment *segPtr; /* Segment to delete. */ - GtkTextLine *line; /* Line containing segment. */ - int treeGone; /* Non-zero means the entire tree is - * being deleted, so everything must - * get cleaned up. */ +char_segment_delete_func (GtkTextLineSegment *segPtr, GtkTextLine *line, int treeGone) { - g_free((char*) segPtr); + g_free ((char*) segPtr); return 0; } @@ -370,6 +383,10 @@ char_segment_delete_func(segPtr, line, treeGone) * This procedure is invoked to perform consistency checks * on character segments. * + * Arguments: + * segPtr : Segment to check + * line : Line containing segment + * * Results: * None. * @@ -382,34 +399,25 @@ char_segment_delete_func(segPtr, line, treeGone) /* ARGSUSED */ static void -char_segment_check_func(segPtr, line) - GtkTextLineSegment *segPtr; /* Segment to check. */ - GtkTextLine *line; /* Line containing segment. */ +char_segment_check_func (GtkTextLineSegment *segPtr, GtkTextLine *line) { - char_segment_self_check(segPtr); - - if (segPtr->next == NULL) - { - if (segPtr->body.chars[segPtr->byte_count-1] != '\n') - { - g_error("char_segment_check_func: line doesn't end with newline"); - } - } - else + char_segment_self_check (segPtr); + + if (segPtr->next != NULL) { if (segPtr->next->type == >k_text_char_type) { - g_error("char_segment_check_func: adjacent character segments weren't merged"); + g_error ("adjacent character segments weren't merged"); } } } GtkTextLineSegment* -toggle_segment_new(GtkTextTagInfo *info, gboolean on) +_gtk_toggle_segment_new (GtkTextTagInfo *info, gboolean on) { GtkTextLineSegment *seg; - seg = g_malloc(TSEG_SIZE); + seg = g_malloc (TSEG_SIZE); seg->type = on ? >k_text_toggle_on_type : >k_text_toggle_off_type; @@ -417,7 +425,7 @@ toggle_segment_new(GtkTextTagInfo *info, gboolean on) seg->byte_count = 0; seg->char_count = 0; - + seg->body.toggle.info = info; seg->body.toggle.inNodeCounts = 0; @@ -431,6 +439,12 @@ toggle_segment_new(GtkTextTagInfo *info, gboolean on) * * This procedure is invoked to delete toggle segments. * + * Arguments: + * segPtr : Segment to check + * line : Line containing segment + * treeGone : Non-zero means the entire tree is being + * deleted so everything must get cleaned up + * * Results: * Returns 1 to indicate that the segment may not be deleted, * unless the entire B-tree is going away. @@ -444,16 +458,11 @@ toggle_segment_new(GtkTextTagInfo *info, gboolean on) */ static int -toggle_segment_delete_func(segPtr, line, treeGone) - GtkTextLineSegment *segPtr; /* Segment to check. */ - GtkTextLine *line; /* Line containing segment. */ - int treeGone; /* Non-zero means the entire tree is - * being deleted, so everything must - * get cleaned up. */ +toggle_segment_delete_func (GtkTextLineSegment *segPtr, GtkTextLine *line, int treeGone) { if (treeGone) { - g_free((char *) segPtr); + g_free ((char *) segPtr); return 0; } @@ -467,8 +476,8 @@ toggle_segment_delete_func(segPtr, line, treeGone) if (segPtr->body.toggle.inNodeCounts) { - change_node_toggle_count(line->parent, - segPtr->body.toggle.info, -1); + _gtk_change_node_toggle_count (line->parent, + segPtr->body.toggle.info, -1); segPtr->body.toggle.inNodeCounts = 0; } return 1; @@ -483,6 +492,10 @@ toggle_segment_delete_func(segPtr, line, treeGone) * been modified in some way. It's invoked after the * modifications are complete. * + * Arguments: + * segPtr : Segment to check + * line : Line that now contains segment + * * Results: * The return value is the head segment in a new list * that is to replace the tail of the line that used to @@ -498,9 +511,7 @@ toggle_segment_delete_func(segPtr, line, treeGone) */ static GtkTextLineSegment * -toggle_segment_cleanup_func(segPtr, line) - GtkTextLineSegment *segPtr; /* Segment to check. */ - GtkTextLine *line; /* Line that now contains segment. */ +toggle_segment_cleanup_func (GtkTextLineSegment *segPtr, GtkTextLine *line) { GtkTextLineSegment *segPtr2, *prevPtr; int counts; @@ -530,21 +541,21 @@ toggle_segment_cleanup_func(segPtr, line) + segPtr2->body.toggle.inNodeCounts; if (counts != 0) { - change_node_toggle_count(line->parent, - segPtr->body.toggle.info, -counts); + _gtk_change_node_toggle_count (line->parent, + segPtr->body.toggle.info, -counts); } prevPtr->next = segPtr2->next; - g_free((char *) segPtr2); + g_free ((char *) segPtr2); segPtr2 = segPtr->next; - g_free((char *) segPtr); + g_free ((char *) segPtr); return segPtr2; } } if (!segPtr->body.toggle.inNodeCounts) { - change_node_toggle_count(line->parent, - segPtr->body.toggle.info, 1); + _gtk_change_node_toggle_count (line->parent, + segPtr->body.toggle.info, 1); segPtr->body.toggle.inNodeCounts = 1; } return segPtr; @@ -558,6 +569,10 @@ toggle_segment_cleanup_func(segPtr, line) * This procedure is invoked when a toggle segment is about * to move from one line to another. * + * Arguments: + * segPtr : Segment to check + * line : Line that used to contain segment + * * Results: * None. * @@ -568,14 +583,12 @@ toggle_segment_cleanup_func(segPtr, line) */ static void -toggle_segment_line_change_func(segPtr, line) - GtkTextLineSegment *segPtr; /* Segment to check. */ - GtkTextLine *line; /* Line that used to contain segment. */ +toggle_segment_line_change_func (GtkTextLineSegment *segPtr, GtkTextLine *line) { if (segPtr->body.toggle.inNodeCounts) { - change_node_toggle_count(line->parent, - segPtr->body.toggle.info, -1); + _gtk_change_node_toggle_count (line->parent, + segPtr->body.toggle.info, -1); segPtr->body.toggle.inNodeCounts = 0; } } @@ -585,7 +598,7 @@ toggle_segment_line_change_func(segPtr, line) */ -GtkTextLineSegmentClass gtk_text_char_type = { +const GtkTextLineSegmentClass gtk_text_char_type = { "character", /* name */ 0, /* leftGravity */ char_segment_split_func, /* splitFunc */ @@ -600,14 +613,14 @@ GtkTextLineSegmentClass gtk_text_char_type = { * range: */ -GtkTextLineSegmentClass gtk_text_toggle_on_type = { +const GtkTextLineSegmentClass gtk_text_toggle_on_type = { "toggleOn", /* name */ 0, /* leftGravity */ NULL, /* splitFunc */ toggle_segment_delete_func, /* deleteFunc */ - toggle_segment_cleanup_func, /* cleanupFunc */ - toggle_segment_line_change_func, /* lineChangeFunc */ - toggle_segment_check_func /* checkFunc */ + toggle_segment_cleanup_func, /* cleanupFunc */ + toggle_segment_line_change_func, /* lineChangeFunc */ + _gtk_toggle_segment_check_func /* checkFunc */ }; /* @@ -615,12 +628,12 @@ GtkTextLineSegmentClass gtk_text_toggle_on_type = { * range: */ -GtkTextLineSegmentClass gtk_text_toggle_off_type = { - "toggleOff", /* name */ - 1, /* leftGravity */ - NULL, /* splitFunc */ - toggle_segment_delete_func, /* deleteFunc */ - toggle_segment_cleanup_func, /* cleanupFunc */ - toggle_segment_line_change_func, /* lineChangeFunc */ - toggle_segment_check_func /* checkFunc */ +const GtkTextLineSegmentClass gtk_text_toggle_off_type = { + "toggleOff", /* name */ + 1, /* leftGravity */ + NULL, /* splitFunc */ + toggle_segment_delete_func, /* deleteFunc */ + toggle_segment_cleanup_func, /* cleanupFunc */ + toggle_segment_line_change_func, /* lineChangeFunc */ + _gtk_toggle_segment_check_func /* checkFunc */ };