summaryrefslogtreecommitdiff
path: root/gtk/gtktextiter.c
diff options
context:
space:
mode:
authorHavoc Pennington <hp@pobox.com>2001-04-24 12:24:35 +0000
committerHavoc Pennington <hp@src.gnome.org>2001-04-24 12:24:35 +0000
commitb84d2f1234b6a6c1fd42cab2541b563f2ad66615 (patch)
tree44407326be6f5dc11512800930a0164b7f09f411 /gtk/gtktextiter.c
parent60051ff6700171c384257134952110a3db0643e9 (diff)
downloadgdk-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.c196
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