diff options
author | Havoc Pennington <hp@pobox.com> | 2001-04-24 12:24:35 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2001-04-24 12:24:35 +0000 |
commit | b84d2f1234b6a6c1fd42cab2541b563f2ad66615 (patch) | |
tree | 44407326be6f5dc11512800930a0164b7f09f411 /gtk/gtktextiter.c | |
parent | 60051ff6700171c384257134952110a3db0643e9 (diff) | |
download | gdk-pixbuf-b84d2f1234b6a6c1fd42cab2541b563f2ad66615.tar.gz |
handle 0-height empty/invisible lines.
2001-04-21 Havoc Pennington <hp@pobox.com>
* gtk/gtktextdisplay.c (gtk_text_layout_draw): handle 0-height
empty/invisible lines.
* gtk/gtktextiter.c (gtk_text_iter_set_visible_line_offset)
(gtk_text_iter_set_visible_line_index): new functions to set
indexes excluding invisible text
* gtk/gtktextlayout.c (line_display_iter_to_index): get visible
index
* gtk/gtktextiter.c (gtk_text_iter_get_visible_line_index)
(gtk_text_iter_get_visible_line_offset): new functions to
get indexes excluding invisible text
* gtk/gtkmessagedialog.c (gtk_message_dialog_init): strip out a
bunch of extra padding that served no purpose
* gtk/gtkdialog.c: Make all the spacings configurable via style
properties, for chubbiness configuration in themes
* tests/testtext.c: fix path to the immodules.
Diffstat (limited to 'gtk/gtktextiter.c')
-rw-r--r-- | gtk/gtktextiter.c | 196 |
1 files changed, 194 insertions, 2 deletions
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c index 73a51ed36..241529d38 100644 --- a/gtk/gtktextiter.c +++ b/gtk/gtktextiter.c @@ -650,7 +650,6 @@ gtk_text_iter_get_line (const GtkTextIter *iter) gint gtk_text_iter_get_line_offset (const GtkTextIter *iter) { - GtkTextRealIter *real; g_return_val_if_fail (iter != NULL, 0); @@ -683,7 +682,7 @@ gint gtk_text_iter_get_line_index (const GtkTextIter *iter) { GtkTextRealIter *real; - + g_return_val_if_fail (iter != NULL, 0); real = gtk_text_iter_make_surreal (iter); @@ -698,6 +697,108 @@ gtk_text_iter_get_line_index (const GtkTextIter *iter) return real->line_byte_offset; } +gint +gtk_text_iter_get_visible_line_offset (const GtkTextIter *iter) +{ + GtkTextRealIter *real; + gint vis_offset; + GtkTextLineSegment *seg; + GtkTextIter pos; + + g_return_val_if_fail (iter != NULL, 0); + + real = gtk_text_iter_make_real (iter); + + if (real == NULL) + return 0; + + ensure_char_offsets (real); + + check_invariants (iter); + + vis_offset = real->line_char_offset; + + _gtk_text_btree_get_iter_at_line (real->tree, + &pos, + real->line, + 0); + + seg = _gtk_text_iter_get_indexable_segment (&pos); + + while (seg != real->segment) + { + /* This is a pretty expensive call, making the + * whole function pretty lame; we could keep track + * of current invisibility state by looking at toggle + * segments as we loop, and then call this function + * only once per line, in order to speed up the loop + * quite a lot. + */ + if (_gtk_text_btree_char_is_invisible (&pos)) + vis_offset -= seg->char_count; + + _gtk_text_iter_forward_indexable_segment (&pos); + + seg = _gtk_text_iter_get_indexable_segment (&pos); + } + + if (_gtk_text_btree_char_is_invisible (&pos)) + vis_offset -= real->segment_char_offset; + + return vis_offset; +} + +gint +gtk_text_iter_get_visible_line_index (const GtkTextIter *iter) +{ + GtkTextRealIter *real; + gint vis_offset; + GtkTextLineSegment *seg; + GtkTextIter pos; + + g_return_val_if_fail (iter != NULL, 0); + + real = gtk_text_iter_make_real (iter); + + if (real == NULL) + return 0; + + ensure_char_offsets (real); + + check_invariants (iter); + + vis_offset = real->line_byte_offset; + + _gtk_text_btree_get_iter_at_line (real->tree, + &pos, + real->line, + 0); + + seg = _gtk_text_iter_get_indexable_segment (&pos); + + while (seg != real->segment) + { + /* This is a pretty expensive call, making the + * whole function pretty lame; we could keep track + * of current invisibility state by looking at toggle + * segments as we loop, and then call this function + * only once per line, in order to speed up the loop + * quite a lot. + */ + if (_gtk_text_btree_char_is_invisible (&pos)) + vis_offset -= seg->byte_count; + + _gtk_text_iter_forward_indexable_segment (&pos); + + seg = _gtk_text_iter_get_indexable_segment (&pos); + } + + if (_gtk_text_btree_char_is_invisible (&pos)) + vis_offset -= real->segment_byte_offset; + + return vis_offset; +} + /* * Dereferencing */ @@ -3276,6 +3377,97 @@ gtk_text_iter_set_line_index (GtkTextIter *iter, check_invariants (iter); } + +/** + * gtk_text_iter_set_visible_line_offset: + * @iter: a #GtkTextIter + * @char_on_line: a character offset + * + * Like gtk_text_iter_set_line_offset(), but the offset is in visible + * characters, i.e. text with a tag making it invisible is not + * counted in the offset. + **/ +void +gtk_text_iter_set_visible_line_offset (GtkTextIter *iter, + gint char_on_line) +{ + gint chars_seen = 0; + GtkTextIter pos; + + g_return_if_fail (iter != NULL); + + pos = *iter; + + /* For now we use a ludicrously slow implementation */ + while (chars_seen < char_on_line) + { + if (!_gtk_text_btree_char_is_invisible (&pos)) + ++chars_seen; + + if (!gtk_text_iter_forward_char (&pos)) + break; + + if (chars_seen == char_on_line) + break; + } + + if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter)) + *iter = pos; + else + gtk_text_iter_forward_line (iter); +} + +static gint +bytes_in_char (GtkTextIter *iter) +{ + return g_unichar_to_utf8 (gtk_text_iter_get_char (iter), NULL); +} + +/** + * gtk_text_iter_set_visible_line_index: + * @iter: a #GtkTextIter + * @byte_on_line: a byte index + * + * Like gtk_text_iter_set_line_index(), but the index is in visible + * bytes, i.e. text with a tag making it invisible is not counted + * in the index. + **/ +void +gtk_text_iter_set_visible_line_index (GtkTextIter *iter, + gint byte_on_line) +{ + gint bytes_seen = 0; + GtkTextIter pos; + + g_return_if_fail (iter != NULL); + + pos = *iter; + + /* For now we use a ludicrously slow implementation */ + while (bytes_seen < byte_on_line) + { + if (!_gtk_text_btree_char_is_invisible (&pos)) + bytes_seen += bytes_in_char (&pos); + + if (!gtk_text_iter_forward_char (&pos)) + break; + + if (bytes_seen >= byte_on_line) + break; + } + + if (bytes_seen > byte_on_line) + g_warning ("%s: Incorrect visible byte index %d falls in the middle of a UTF-8 " + "character; this will crash the text buffer. " + "Byte indexes must refer to the start of a character.", + G_STRLOC, byte_on_line); + + if (_gtk_text_iter_get_text_line (&pos) == _gtk_text_iter_get_text_line (iter)) + *iter = pos; + else + gtk_text_iter_forward_line (iter); +} + /** * gtk_text_iter_set_line: * @iter: a #GtkTextIter |