Move the new chars field to a private struct.
Fixes: #4531
int end_iter_segment_char_offset;
guint end_iter_line_stamp;
guint end_iter_segment_stamp;
-
+
GHashTable *child_anchor_table;
};
tree->end_iter_line = NULL;
tree->end_iter_segment_byte_index = 0;
tree->end_iter_segment_char_offset = 0;
-
+
g_object_ref (tree->table);
tree->tag_changed_handler = g_signal_connect (tree->table,
tree->mark_table = g_hash_table_new (g_str_hash, g_str_equal);
tree->child_anchor_table = NULL;
-
+
/* We don't ref the buffer, since the buffer owns us;
* we'd have some circularity issues. The buffer always
* lasts longer than the BTree
tree->refcount -= 1;
if (tree->refcount == 0)
- {
+ {
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);
tree->mark_table = NULL;
- if (tree->child_anchor_table != NULL)
+ if (tree->child_anchor_table != NULL)
{
g_hash_table_destroy (tree->child_anchor_table);
tree->child_anchor_table = NULL;
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)
{
*/
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 = gdk_find_base_dir (seg->body.chars, seg->byte_count);
-
+
if (pango_dir != PANGO_DIRECTION_NEUTRAL)
{
line->dir_strong = pango_dir;
if (start_line_prev)
dir_above_propagated = start_line_prev->dir_propagated_forward;
- /* Loop forward and propagate the direction of each paragraph
+ /* Loop forward and propagate the direction of each paragraph
* to all neutral lines.
*/
line = start_line;
{
if (line->dir_strong != PANGO_DIRECTION_NEUTRAL)
last_strong = line->dir_strong;
-
+
line->dir_propagated_forward = last_strong;
-
+
line = _gtk_text_line_next (line);
}
*/
{
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)
{
_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
if (end_line_next)
dir_below_propagated = end_line_next->dir_propagated_back;
- /* Loop backward and propagate the direction of each paragraph
+ /* Loop backward and propagate the direction of each paragraph
* to all neutral lines.
*/
line = end_line;
BTreeView *view;
GtkTextBTreeNode *ancestor_node;
GtkTextLine *prevline;
- int chars_moved;
+ int chars_moved;
/* last_seg was appended to start_line up at the top of this function */
chars_moved = 0;
{
node->num_chars += chars_moved;
}
-
+
curnode = end_line->parent;
for (node = curnode; node != NULL;
node = node->parent)
if (deleted_width > 0 || deleted_height > 0)
{
ld = _gtk_text_line_get_data (start_line, view->view_id);
-
+
if (ld == NULL)
{
/* This means that start_line has never been validated.
ld->height = 0;
ld->valid = FALSE;
}
-
+
ld->width = MAX (deleted_width, ld->width);
ld->height += deleted_height;
ld->valid = FALSE;
/* avoid dangling pointer */
deleted_lines = NULL;
-
+
gtk_text_btree_rebalance (tree, curnode);
}
/* extract iterator info */
tree = _gtk_text_iter_get_btree (iter);
line = _gtk_text_iter_get_text_line (iter);
-
+
start_line = line;
start_byte_index = gtk_text_iter_get_line_index (iter);
/* Invalidate all iterators */
chars_changed (tree);
segments_changed (tree);
-
+
/*
* Chop the text up into lines and create a new segment for
* each line, plus a new line for the leftovers from the
while (eol < len)
{
sol = eol;
-
+
pango_find_paragraph_boundary (text + sol,
len - sol,
&delim,
- &eol);
+ &eol);
/* make these relative to the start of the text */
delim += sol;
g_assert (eol >= delim);
g_assert (sol >= 0);
g_assert (eol <= len);
-
+
chunk_len = eol - sol;
g_assert (g_utf8_validate (&text[sol], chunk_len, NULL));
DV (g_print ("invalidating due to inserting paintable/widget (%s)\n", G_STRLOC));
_gtk_text_btree_invalidate_region (tree, &start, iter, FALSE);
}
-
+
void
_gtk_text_btree_insert_paintable (GtkTextIter *iter,
GdkPaintable *paintable)
{
GtkTextLineSegment *seg;
-
+
seg = _gtk_paintable_segment_new (paintable);
seg->body.paintable.tree = _gtk_text_iter_get_btree (iter);
seg->body.paintable.line = _gtk_text_iter_get_text_line (iter);
g_warning (G_STRLOC": Same child anchor can't be inserted twice");
return;
}
-
+
seg = _gtk_widget_segment_new (anchor);
tree = seg->body.child.tree = _gtk_text_iter_get_btree (iter);
seg->body.child.line = _gtk_text_iter_get_text_line (iter);
-
+
insert_paintable_or_widget_segment (iter, seg);
if (tree->child_anchor_table == NULL)
GtkTextLineSegment *seg;
seg = anchor->segment;
-
+
g_hash_table_remove (seg->body.child.tree->child_anchor_table,
anchor);
}
GtkTextLineData *line_data;
g_return_if_fail (tree != NULL);
-
+
view = g_slice_new (BTreeView);
view->view_id = layout;
g_assert (tree->views->prev == NULL);
tree->views->prev = view;
}
-
+
tree->views = view;
/* The last line in the buffer has identity values for the per-view
GtkTextLineData *line_data;
g_return_if_fail (tree != NULL);
-
+
view = tree->views;
while (view != NULL)
}
static void
-iter_stack_push (IterStack *stack,
+iter_stack_push (IterStack *stack,
const GtkTextIter *iter)
{
stack->count += 1;
}
static gboolean
-iter_stack_pop (IterStack *stack,
+iter_stack_pop (IterStack *stack,
GtkTextIter *iter)
{
if (stack->count == 0)
g_return_if_fail (_gtk_text_iter_get_btree (start_orig) ==
_gtk_text_iter_get_btree (end_orig));
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",
add ? "Adding" : "Removing",
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) )
line_count = _gtk_text_btree_line_count (tree);
if (!include_last)
line_count -= 1;
-
+
if (line_number < 0)
{
line_number = line_count;
{
gboolean copy = TRUE;
if (!include_nonchars &&
- g_strcmp0 (_gtk_text_unknown_char_utf8, seg->body.child.obj->chars) == 0)
+ g_strcmp0 (_gtk_text_unknown_char_utf8, gtk_text_child_anchor_get_replacement (seg->body.child.obj)) == 0)
{
copy = FALSE;
}
if (copy)
{
g_string_append_len (string,
- seg->body.child.obj->chars,
+ gtk_text_child_anchor_get_replacement (seg->body.child.obj),
seg->byte_count);
}
}
/* OK if !should_exist and it does already exist, in that case
* we just move it.
*/
-
+
iter = *where;
#ifdef G_ENABLE_DEBUG
segment->body.mark.tree = NULL;
segment->body.mark.line = NULL;
-
+
/* Remove the ref on the mark, which frees segment as a side effect
* if this is the last reference.
*/
/* This calls cleanup_line and segments_changed */
gtk_text_btree_unlink_segment (tree, segment, segment->body.mark.line);
-
+
_gtk_text_btree_release_mark_segment (tree, segment);
}
if (tree->end_iter_line_stamp != tree->chars_changed_stamp)
{
int 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);
-
+
tree->end_iter_line_stamp = tree->chars_changed_stamp;
}
}
ensure_end_iter_line (tree);
last_with_chars = NULL;
-
+
seg = tree->end_iter_line->segments;
while (seg != NULL)
{
/* We know the last char in the last line is '\n' */
tree->end_iter_segment_byte_index = last_with_chars->byte_count - 1;
tree->end_iter_segment_char_offset = last_with_chars->char_count - 1;
-
+
tree->end_iter_segment_stamp = tree->segments_changed_stamp;
g_assert (tree->end_iter_segment->type == >k_text_char_type);
int char_offset)
{
g_return_val_if_fail (byte_index >= 0 || char_offset >= 0, FALSE);
-
+
/* Do this first to avoid walking segments in most cases */
if (!_gtk_text_line_contains_end_iter (line, tree))
return FALSE;
_gtk_text_line_next_excluding_last (GtkTextLine *line)
{
GtkTextLine *next;
-
+
next = _gtk_text_line_next (line);
/* If we were on the end iter line, we can't go to
is less than the max width for the parent node,
and the case where the height is unchanged when we re-wrap.
*/
-
+
g_return_if_fail (ld != NULL);
-
+
ld->valid = FALSE;
gtk_text_btree_node_invalidate_upward (line->parent, ld->view_id);
}
g_return_val_if_fail (line != NULL, FALSE);
g_return_val_if_fail (char_offset >= 0, FALSE);
-
+
*segment = NULL;
*any_segment = NULL;
chars_in_line = 0;
/* 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,
+ 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);
/* Our tag summaries only have node precision, not line
* precision. This means that if any line under a node could contain a
* tag, then any of the others could also contain a tag.
- *
+ *
* In the future we could have some mechanism to keep track of how
* many toggles we've found under a node so far, since we have a
* count of toggles under the node. But for now I'm going with KISS.
NodeData *next)
{
NodeData *nd;
-
+
nd = g_slice_new (NodeData);
nd->view_id = view_id;
}
static inline NodeData*
-node_data_find (NodeData *nd,
+node_data_find (NodeData *nd,
gpointer view_id)
{
while (nd != NULL)
view = gtk_text_btree_get_view (tree, view_id);
g_return_if_fail (view != NULL);
-
+
ld = _gtk_text_line_get_data (line, view_id);
if (!ld || !ld->valid)
{
gtk_text_btree_node_check_valid (node, view->view_id);
view = view->next;
}
-
+
/*
* Scan through the GtkTextBTreeNode’s tag records again and delete any Summary
* records that still have a zero count, or that have all the toggles.
int height;
gboolean valid;
BTreeView *view;
-
+
view = tree->views;
while (view != NULL)
if (view == NULL)
g_error ("Node has data for a view %p no longer attached to the tree",
nd->view_id);
-
+
gtk_text_btree_node_compute_view_aggregates (node, nd->view_id,
&width, &height, &valid);
* invalid - we don’t guarantee that if the node is invalid there
* are invalid lines.
*/
-
+
if (nd->width != width ||
nd->height != height ||
(nd->valid && !valid))
}
else if (seg->type == >k_text_child_type)
{
- char *str = g_strndup (seg->body.child.obj->chars, seg->byte_count);
+ char *str = g_strndup (gtk_text_child_anchor_get_replacement (seg->body.child.obj), seg->byte_count);
printf ("%s child '%s'...\n", spaces, str);
g_free (str);
}
}
else if (seg->type == >k_text_child_type)
{
- char *str = g_strndup (seg->body.child.obj->chars, seg->byte_count);
+ char *str = g_strndup (gtk_text_child_anchor_get_replacement (seg->body.child.obj), seg->byte_count);
printf (" '%s'\n", str);
g_free (str);
}
#include "gtktextlayoutprivate.h"
#include "gtkintl.h"
+typedef struct {
+ char *replacement;
+} GtkTextChildAnchorPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkTextChildAnchor, gtk_text_child_anchor, G_TYPE_OBJECT)
+
#define CHECK_IN_BUFFER(anchor) \
G_STMT_START { \
if ((anchor)->segment == NULL) \
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
GtkTextLineSegment *seg;
+ GtkTextChildAnchorPrivate *priv = gtk_text_child_anchor_get_instance_private (anchor);
seg = g_slice_alloc (WIDGET_SEG_SIZE);
seg->next = NULL;
- seg->byte_count = strlen (anchor->chars);
- seg->char_count = g_utf8_strlen (anchor->chars, seg->byte_count);
+ seg->byte_count = strlen (priv->replacement);
+ seg->char_count = g_utf8_strlen (priv->replacement, seg->byte_count);
seg->body.child.obj = anchor;
seg->body.child.obj->segment = seg;
static void gtk_text_child_anchor_finalize (GObject *obj);
-G_DEFINE_TYPE (GtkTextChildAnchor, gtk_text_child_anchor, G_TYPE_OBJECT)
-
static void
gtk_text_child_anchor_init (GtkTextChildAnchor *child_anchor)
{
GtkTextChildAnchor *
gtk_text_child_anchor_new_with_replacement (const char *replacement_character)
{
+ GtkTextChildAnchor *anchor;
+ GtkTextChildAnchorPrivate *priv;
+
/* only a single character can be set as replacement */
g_return_val_if_fail (g_utf8_strlen (replacement_character, -1) == 1, NULL);
- GtkTextChildAnchor *anchor = g_object_new (GTK_TYPE_TEXT_CHILD_ANCHOR, NULL);
- anchor->chars = g_strdup (replacement_character);
+ anchor = g_object_new (GTK_TYPE_TEXT_CHILD_ANCHOR, NULL);
+
+ priv = gtk_text_child_anchor_get_instance_private (anchor);
+
+ priv->replacement = g_strdup (replacement_character);
+
return anchor;
}
static void
gtk_text_child_anchor_finalize (GObject *obj)
{
- GtkTextChildAnchor *anchor;
- GtkTextLineSegment *seg;
-
- anchor = GTK_TEXT_CHILD_ANCHOR (obj);
-
- seg = anchor->segment;
+ GtkTextChildAnchor *anchor = GTK_TEXT_CHILD_ANCHOR (obj);
+ GtkTextChildAnchorPrivate *priv = gtk_text_child_anchor_get_instance_private (anchor);
+ GtkTextLineSegment *seg = anchor->segment;
if (seg)
{
g_slice_free1 (WIDGET_SEG_SIZE, seg);
}
- anchor->segment = NULL;
+ g_free (priv->replacement);
G_OBJECT_CLASS (gtk_text_child_anchor_parent_class)->finalize (obj);
}
_gtk_anchored_child_set_layout (child, layout);
}
+
+const char *
+gtk_text_child_anchor_get_replacement (GtkTextChildAnchor *anchor)
+{
+ GtkTextChildAnchorPrivate *priv = gtk_text_child_anchor_get_instance_private (anchor);
+
+ return priv->replacement;
+}
/*< private >*/
gpointer segment;
- char *chars; /* replacement character */
};
struct _GtkTextChildAnchorClass
GtkTextLayout* _gtk_anchored_child_get_layout (GtkWidget *child);
+const char * gtk_text_child_anchor_get_replacement (GtkTextChildAnchor *anchor);
+
G_END_DECLS
#endif
"character; this will crash the text buffer. "
"Byte indexes must refer to the start of a character.",
line_byte_offset);
-
+
return real;
}
return 0;
check_invariants (iter);
-
+
if (real->cached_char_index < 0)
{
ensure_char_offsets (real);
-
+
real->cached_char_index =
_gtk_text_line_char_index (real->line);
real->cached_char_index += real->line_char_offset;
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);
int vis_offset;
GtkTextLineSegment *seg;
GtkTextIter pos;
-
+
g_return_val_if_fail (iter != NULL, 0);
real = gtk_text_iter_make_real (iter);
ensure_char_offsets (real);
check_invariants (iter);
-
+
vis_offset = real->line_char_offset;
g_assert (vis_offset >= 0);
-
+
_gtk_text_btree_get_iter_at_line (real->tree,
&pos,
real->line,
if (_gtk_text_btree_char_is_invisible (&pos))
vis_offset -= real->segment_char_offset;
-
+
return vis_offset;
}
int vis_offset;
GtkTextLineSegment *seg;
GtkTextIter pos;
-
+
g_return_val_if_fail (iter != NULL, 0);
real = gtk_text_iter_make_real (iter);
vis_offset = real->line_byte_offset;
g_assert (vis_offset >= 0);
-
+
_gtk_text_btree_get_iter_at_line (real->tree,
&pos,
real->line,
if (_gtk_text_btree_char_is_invisible (&pos))
vis_offset -= real->segment_byte_offset;
-
+
return vis_offset;
}
else if (real->segment->type == >k_text_char_type)
{
ensure_byte_offsets (real);
-
+
return g_utf8_get_char (real->segment->body.chars +
real->segment_byte_offset);
}
else if (real->segment->type == >k_text_child_type)
{
- return g_utf8_get_char (real->segment->body.child.obj->chars);
+ return g_utf8_get_char (gtk_text_child_anchor_get_replacement (real->segment->body.child.obj));
}
else
{
gboolean retval;
g_return_val_if_fail (iter != NULL, FALSE);
-
+
values = gtk_text_attributes_new ();
values->editable = default_setting;
gboolean default_editability)
{
g_return_val_if_fail (iter != NULL, FALSE);
-
+
if (gtk_text_iter_editable (iter, default_editability))
return TRUE;
/* If at start/end of buffer, default editability is used */
{
GtkTextAttributes *values;
PangoLanguage *retval;
-
+
values = gtk_text_attributes_new ();
gtk_text_iter_get_attributes (iter, values);
gtk_text_iter_ends_line (const GtkTextIter *iter)
{
gunichar wc;
-
+
g_return_val_if_fail (iter != NULL, FALSE);
check_invariants (iter);
#define PARAGRAPH_SEPARATOR 0x2029
wc = gtk_text_iter_get_char (iter);
-
+
if (wc == '\r' || wc == PARAGRAPH_SEPARATOR || wc == 0) /* wc == 0 is end iterator */
return TRUE;
else if (wc == '\n')
if (real == NULL)
return FALSE;
-
+
return _gtk_text_btree_is_end (real->tree, real->line,
real->segment,
real->segment_byte_offset,
if (_gtk_text_line_contains_end_iter (real->line, real->tree))
count -= 1; /* Dump the newline that was in the last segment of the end iter line */
-
+
return count;
}
if (_gtk_text_line_contains_end_iter (real->line, real->tree))
count -= 1; /* Dump the newline that was in the last segment of the end iter line */
-
+
return count;
}
if (!_gtk_text_line_contains_end_iter (real->line, real->tree))
{
GtkTextLine *new_line;
-
+
new_line = _gtk_text_line_next (real->line);
g_assert (new_line);
g_assert (new_line != real->line);
g_assert (!_gtk_text_line_is_last (new_line, real->tree));
-
+
real->line = new_line;
real->line_byte_offset = 0;
* the line containing the end iterator.
* However we may not be at the end iterator itself.
*/
-
+
return FALSE;
}
}
return FALSE;
}
}
-#endif
+#endif
/* The return value indicates (MOVEMENT OCCURRED && NEW ITER IS
* DEREFERENCEABLE)
/* End of buffer, but iter is still at start of last segment,
* not at the end iterator. We put it on the end iterator.
*/
-
+
check_invariants (iter);
g_assert (!_gtk_text_line_is_last (real->line, real->tree));
gtk_text_iter_forward_to_line_end (iter);
g_assert (gtk_text_iter_is_end (iter));
-
+
return FALSE;
}
}
g_return_val_if_fail (iter != NULL, FALSE);
FIX_OVERFLOWS (count);
-
+
real = gtk_text_iter_make_real (iter);
if (real == NULL)
g_return_val_if_fail (iter != NULL, FALSE);
FIX_OVERFLOWS (count);
-
+
real = gtk_text_iter_make_real (iter);
if (real == NULL)
/* if in the last fourth of the segment walk backwards */
if (count < real->segment_char_offset / 4)
- p = g_utf8_offset_to_pointer (real->segment->body.chars + real->segment_byte_offset,
+ p = g_utf8_offset_to_pointer (real->segment->body.chars + real->segment_byte_offset,
-count);
else
p = g_utf8_offset_to_pointer (real->segment->body.chars,
GtkTextRealIter *real;
g_return_val_if_fail (iter != NULL, FALSE);
-
+
real = gtk_text_iter_make_real (iter);
if (real == NULL)
else
{
/* On the last line, move to end of it */
-
+
if (!gtk_text_iter_is_end (iter))
gtk_text_iter_forward_to_end (iter);
-
+
check_invariants (iter);
return FALSE;
}
gtk_text_iter_forward_lines (GtkTextIter *iter, int count)
{
FIX_OVERFLOWS (count);
-
+
if (count < 0)
return gtk_text_iter_backward_lines (iter, 0 - count);
else if (count == 0)
if (gtk_text_iter_is_end (iter))
return FALSE;
-
+
old_line = gtk_text_iter_get_line (iter);
gtk_text_iter_set_line (iter, old_line + count);
if (!gtk_text_iter_is_end (iter))
gtk_text_iter_forward_to_end (iter);
}
-
+
return !gtk_text_iter_is_end (iter);
}
}
gtk_text_iter_backward_lines (GtkTextIter *iter, int count)
{
FIX_OVERFLOWS (count);
-
+
if (count < 0)
return gtk_text_iter_forward_lines (iter, 0 - count);
else if (count == 0)
{
if (!gtk_text_iter_forward_char (iter))
return FALSE;
-
+
if (!_gtk_text_btree_char_is_invisible (iter))
return TRUE;
}
while (!gtk_text_iter_ends_line (iter));
}
}
-
+
return FALSE;
}
{
if (!gtk_text_iter_backward_char (iter))
return FALSE;
-
+
if (!_gtk_text_btree_char_is_invisible (iter))
return TRUE;
}
while (!gtk_text_iter_starts_line (iter));
}
}
-
+
return FALSE;
}
int count)
{
FIX_OVERFLOWS (count);
-
+
if (count < 0)
return gtk_text_iter_backward_visible_lines (iter, 0 - count);
else if (count == 0)
while (gtk_text_iter_forward_visible_line (iter) && count > 0)
count--;
return count == 0;
- }
+ }
}
/**
int count)
{
FIX_OVERFLOWS (count);
-
+
if (count < 0)
return gtk_text_iter_forward_visible_lines (iter, 0 - count);
else if (count == 0)
int offset;
g_return_val_if_fail (iter != NULL, FALSE);
-
+
attrs = _gtk_text_buffer_get_line_log_attrs (gtk_text_iter_get_buffer (iter),
- iter, &char_len);
+ iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
typedef gboolean (* OneStepFunc) (GtkTextIter *iter);
typedef gboolean (* MultipleStepFunc) (GtkTextIter *iter, int count);
-
-static gboolean
-move_multiple_steps (GtkTextIter *iter,
+
+static gboolean
+move_multiple_steps (GtkTextIter *iter,
int count,
OneStepFunc step_forward,
MultipleStepFunc n_steps_backward)
g_return_val_if_fail (iter != NULL, FALSE);
FIX_OVERFLOWS (count);
-
+
if (count == 0)
return FALSE;
-
+
if (count < 0)
return n_steps_backward (iter, -count);
-
+
if (!step_forward (iter))
return FALSE;
--count;
break;
--count;
}
-
- return !gtk_text_iter_is_end (iter);
+
+ return !gtk_text_iter_is_end (iter);
}
-
+
/**
* gtk_text_iter_forward_word_end:
gtk_text_iter_forward_word_ends (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_forward_word_end,
gtk_text_iter_backward_word_starts);
}
gtk_text_iter_backward_word_starts (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_backward_word_start,
gtk_text_iter_forward_word_ends);
}
gtk_text_iter_forward_visible_word_ends (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_forward_visible_word_end,
gtk_text_iter_backward_visible_word_starts);
}
gtk_text_iter_backward_visible_word_starts (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_backward_visible_word_start,
gtk_text_iter_forward_visible_word_ends);
}
gtk_text_iter_forward_sentence_ends (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_forward_sentence_end,
gtk_text_iter_backward_sentence_starts);
}
gtk_text_iter_backward_sentence_starts (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_backward_sentence_start,
gtk_text_iter_forward_sentence_ends);
}
gtk_text_iter_forward_cursor_positions (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_forward_cursor_position,
gtk_text_iter_backward_cursor_positions);
}
gtk_text_iter_backward_cursor_positions (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_backward_cursor_position,
gtk_text_iter_forward_cursor_positions);
}
gtk_text_iter_forward_visible_cursor_positions (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_forward_visible_cursor_position,
gtk_text_iter_backward_visible_cursor_positions);
}
gtk_text_iter_backward_visible_cursor_positions (GtkTextIter *iter,
int count)
{
- return move_multiple_steps (iter, count,
+ return move_multiple_steps (iter, count,
gtk_text_iter_backward_visible_cursor_position,
gtk_text_iter_forward_visible_cursor_positions);
}
{
GtkTextRealIter *real;
int chars_in_line;
-
+
g_return_if_fail (iter != NULL);
real = gtk_text_iter_make_surreal (iter);
if (real == NULL)
return;
-
+
check_invariants (iter);
chars_in_line = gtk_text_iter_get_chars_in_line (iter);
iter_set_from_char_offset (real, real->line, char_on_line);
else
gtk_text_iter_forward_line (iter); /* set to start of next line */
-
+
check_invariants (iter);
}
{
GtkTextRealIter *real;
int bytes_in_line;
-
+
g_return_if_fail (iter != NULL);
real = gtk_text_iter_make_surreal (iter);
bytes_in_line = gtk_text_iter_get_bytes_in_line (iter);
g_return_if_fail (byte_on_line <= bytes_in_line);
-
+
if (byte_on_line < bytes_in_line)
iter_set_from_byte_offset (real, real->line, byte_on_line);
else
GtkTextIter pos;
g_return_if_fail (iter != NULL);
-
+
gtk_text_iter_set_line_offset (iter, 0);
pos = *iter;
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
int offset = 0;
GtkTextIter pos;
GtkTextLineSegment *seg;
-
+
g_return_if_fail (iter != NULL);
gtk_text_iter_set_line_offset (iter, 0);
int current_offset;
int new_offset;
-
+
g_return_val_if_fail (iter != NULL, FALSE);
current_offset = gtk_text_iter_get_line_offset (iter);
new_offset = find_paragraph_delimiter_for_line (iter);
-
+
if (current_offset < new_offset)
{
/* Move to end of this line. */
if (limit &&
gtk_text_iter_compare (iter, limit) >= 0)
return FALSE;
-
+
while ((limit == NULL ||
!gtk_text_iter_equal (limit, iter)) &&
gtk_text_iter_forward_char (iter))
- {
+ {
if (matches_pred (iter, pred, user_data))
return TRUE;
}
if (limit &&
gtk_text_iter_compare (iter, limit) <= 0)
return FALSE;
-
+
while ((limit == NULL ||
!gtk_text_iter_equal (limit, iter)) &&
gtk_text_iter_backward_char (iter))
if (limit &&
gtk_text_iter_compare (iter, limit) >= 0)
return FALSE;
-
+
if (*str == '\0')
{
/* If we can move one char, return the empty string there */
match = *iter;
-
+
if (gtk_text_iter_forward_char (&match))
{
if (limit &&
gtk_text_iter_equal (&match, limit))
return FALSE;
-
+
if (match_start)
*match_start = match;
if (match_end)
if (limit &&
gtk_text_iter_compare (&search, limit) >= 0)
break;
-
+
if (lines_match (&search, (const char **)lines,
visible_only, slice, case_insensitive, &match, &end))
{
gtk_text_iter_compare (&end, limit) <= 0))
{
retval = TRUE;
-
+
if (match_start)
*match_start = match;
-
+
if (match_end)
*match_end = end;
}
-
+
break;
}
}
gboolean visible_only;
gboolean slice;
gboolean case_insensitive;
-
+
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
if (limit &&
gtk_text_iter_compare (limit, iter) > 0)
return FALSE;
-
+
if (*str == '\0')
{
/* If we can move one char, return the empty string there */
if (limit && gtk_text_iter_equal (limit, &match))
return FALSE;
-
+
if (gtk_text_iter_backward_char (&match))
{
if (match_start)
/* We're now before the search limit, abort. */
goto out;
}
-
+
/* If there are multiple lines, the first line will
* end in '\n', so this will only match at the
* end of the first line, which is correct.
out:
lines_window_free (&win);
g_strfreev (lines);
-
+
return retval;
}
* gtk_text_iter_equal:
* @lhs: a `GtkTextIter`
* @rhs: another `GtkTextIter`
- *
+ *
* Tests whether two iterators are equal, using the fastest possible
* mechanism.
*
* better than e.g. getting the character offset for each
* iterator and comparing the offsets yourself. Also, it’s a
* bit faster than [method@Gtk.TextIter.compare].
- *
+ *
* Returns: %TRUE if the iterators point to the same place in the buffer
**/
gboolean
check_invariants (lhs);
check_invariants (rhs);
-
+
if (real_lhs->line == real_rhs->line)
{
int left_index, right_index;
g_return_val_if_fail (start != NULL, FALSE);
g_return_val_if_fail (end != NULL, FALSE);
g_return_val_if_fail (gtk_text_iter_compare (start, end) <= 0, FALSE);
-
+
return gtk_text_iter_compare (iter, start) >= 0 &&
gtk_text_iter_compare (iter, end) < 0;
}
g_return_if_fail (tree != NULL);
line = _gtk_text_btree_get_line_no_last (tree, line_number, &real_line);
-
+
iter_init_from_char_offset (iter, tree, line, char_on_line);
/* We might as well cache this, since we know it. */
found = gtk_text_iter_backward_to_tag_toggle (iter, tag);
check_invariants (iter);
-
+
return found;
}
g_return_if_fail (iter != NULL);
g_return_if_fail (tree != NULL);
g_return_if_fail (GTK_IS_TEXT_CHILD_ANCHOR (anchor));
-
- seg = anchor->segment;
+
+ seg = anchor->segment;
g_assert (seg->body.child.line != NULL);
-
+
iter_init_from_segment (iter, tree,
seg->body.child.line, seg);
g_assert (seg->body.child.line == _gtk_text_iter_get_text_line (iter));
{
const char *p;
p = byte_segment->body.chars + seg_byte_offset;
-
+
if (!gtk_text_byte_begins_utf8_char (p))
g_error ("broken iterator byte index pointed into the middle of a character");
}
g_error ("wrong char offset was stored in iterator");
if (segments_updated)
- {
+ {
if (real->segment != char_segment)
g_error ("wrong segment was stored in iterator");
* %GTK_TEXT_DIR_NONE means draw cursors for both
* left-to-right insertion and right-to-left insertion.
* (The two cursors will be visually distinguished.)
- *
+ *
* Sets which text directions (left-to-right and/or right-to-left) for
* which cursors will be drawn for the insertion point. The visual
* point at which new text is inserted depends on whether the new
* @preedit_string: a string to display at the insertion point
* @preedit_attrs: a `PangoAttrList` of attributes that apply to @preedit_string
* @cursor_pos: position of cursor within preedit string in chars
- *
+ *
* Set the preedit string and attributes. The preedit string is a
* string showing text that is currently being edited and not
* yet committed into the buffer.
* we always invalidate the line with "start" even
* if there's an empty range.
*/
-
+
#if 0
gtk_text_view_index_spew (start_index, "invalidate start");
gtk_text_view_index_spew (end_index, "invalidate end");
GtkTextLineData *line_data = _gtk_text_line_get_data (line, layout);
gtk_text_layout_invalidate_cache (layout, line, FALSE);
-
+
if (line_data)
_gtk_text_line_invalidate_wrap (line, line_data);
{
int old_height, new_height;
int top_ink, bottom_ink;
-
+
old_height = line_data ? line_data->height : 0;
top_ink = line_data ? line_data->top_ink : 0;
bottom_ink = line_data ? line_data->bottom_ink : 0;
}
delta_height += new_height - old_height;
-
+
first_line = line;
first_line_y = -seen - new_height - top_ink;
if (!last_line)
{
int old_height, new_height;
int top_ink, bottom_ink;
-
+
old_height = line_data ? line_data->height : 0;
top_ink = line_data ? line_data->top_ink : 0;
bottom_ink = line_data ? line_data->bottom_ink : 0;
}
delta_height += new_height - old_height;
-
+
if (!first_line)
{
first_line = line;
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), NULL);
g_return_val_if_fail (line != NULL, NULL);
-
+
if (line_data == NULL)
{
line_data = _gtk_text_line_data_new (layout, line);
GtkTextLineSegment *seg;
int bytes = 0;
- /* Check if the first char is visible, if so we are partially visible.
- * Note that we have to check this since we don't know the current
- * invisible/noninvisible toggle state; this function can use the whole btree
+ /* Check if the first char is visible, if so we are partially visible.
+ * Note that we have to check this since we don't know the current
+ * invisible/noninvisible toggle state; this function can use the whole btree
* to get it right.
*/
gtk_text_layout_get_iter_at_line (layout, iter, line, 0);
base_dir = PANGO_DIRECTION_RTL;
else
base_dir = PANGO_DIRECTION_LTR;
-
+
break;
case PANGO_DIRECTION_RTL :
display->direction = GTK_TEXT_DIR_RTL;
display->direction = GTK_TEXT_DIR_LTR;
break;
}
-
+
if (display->direction == GTK_TEXT_DIR_RTL)
display->layout = pango_layout_new (layout->rtl_context);
else
display->bottom_margin = style->pixels_below_lines;
display->left_margin = style->left_margin;
display->right_margin = style->right_margin;
-
+
display->x_offset = display->left_margin;
pango_layout_set_indent (display->layout,
g_slice_free (GtkTextAttrAppearance, appearance_attr);
}
-static gboolean
+static gboolean
rgba_equal (const GdkRGBA *rgba1, const GdkRGBA *rgba2)
{
if (rgba1 && rgba2)
return gdk_rgba_equal (rgba1, rgba2);
-
+
if (rgba1 || rgba2)
return FALSE;
if (appearance->underline != PANGO_UNDERLINE_NONE)
{
attr = pango_attr_underline_new (appearance->underline);
-
+
attr->start_index = start;
attr->end_index = start + byte_count;
-
+
pango_attr_list_insert (attrs, attr);
}
if (appearance->strikethrough)
{
attr = pango_attr_strikethrough_new (appearance->strikethrough);
-
+
attr->start_index = start;
attr->end_index = start + byte_count;
-
+
pango_attr_list_insert (attrs, attr);
}
if (appearance->rise != 0)
{
attr = pango_attr_rise_new (appearance->rise);
-
+
attr->start_index = start;
attr->end_index = start + byte_count;
-
+
pango_attr_list_insert (attrs, attr);
}
if (!size_only)
{
attr = gtk_text_attr_appearance_new (appearance);
-
+
attr->start_index = start;
attr->end_index = start + byte_count;
((GtkTextAttrAppearance *)attr)->appearance.is_text = is_text;
-
+
pango_attr_list_insert (attrs, attr);
}
}
width = 1;
height = 1;
-
+
tmp_list = seg->body.child.widgets;
while (tmp_list != NULL)
{
height = req.height;
widget = child;
-
+
break;
}
-
+
tmp_list = tmp_list->next;
}
* @cursor_at_line_end: whether cursor is at the end of line
*
* Checks whether layout should display block cursor at given position.
- * For this layout must be in overwrite mode and text at @insert_iter
+ * For this layout must be in overwrite mode and text at @insert_iter
* must be editable.
*/
static gboolean
is_shape (PangoLayoutRun *run)
{
GSList *tmp_list = run->item->analysis.extra_attrs;
-
+
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
if (end == G_MAXINT)
end = layout->preedit_len;
-
+
if (end == start)
continue;
appearance.overline_rgba = gdk_rgba_copy (appearance.overline_rgba);
if (appearance.strikethrough_rgba)
appearance.strikethrough_rgba = gdk_rgba_copy (appearance.strikethrough_rgba);
-
+
tmp_list = extra_attrs;
while (tmp_list)
{
PangoAttribute *attr = tmp_list->data;
GdkRGBA rgba;
-
+
switch ((guint) attr->klass->type)
{
case PANGO_ATTR_FOREGROUND:
default:
break;
}
-
+
pango_attribute_destroy (attr);
tmp_list = tmp_list->next;
}
-
+
g_slist_free (extra_attrs);
-
+
insert_attr = pango_attr_font_desc_new (font_desc);
insert_attr->start_index = start + offset;
insert_attr->end_index = end + offset;
-
+
pango_attr_list_insert (attrs, insert_attr);
if (language)
insert_attr = pango_attr_language_new (language);
insert_attr->start_index = start + offset;
insert_attr->end_index = end + offset;
-
+
pango_attr_list_insert (attrs, insert_attr);
}
add_generic_attrs (layout, &appearance, end - start,
attrs, start + offset,
size_only, TRUE);
-
+
if (appearance.fg_rgba)
gdk_rgba_free (appearance.fg_rgba);
if (appearance.bg_rgba)
int bytes = 0;
GtkTextLineSegment *prev_seg = NULL;
-
+
while (seg)
{
if (seg->type == >k_text_char_type)
else if (seg->type == >k_text_child_type)
{
saw_widget = TRUE;
-
+
add_generic_attrs (layout, &style->appearance,
seg->byte_count,
attrs, layout_byte_offset,
size_only, FALSE);
add_child_attrs (layout, display, style,
seg, attrs, layout_byte_offset);
- memcpy (text + layout_byte_offset, seg->body.child.obj->chars,
+ memcpy (text + layout_byte_offset, gtk_text_child_anchor_get_replacement (seg->body.child.obj),
seg->byte_count);
layout_byte_offset += seg->byte_count;
buffer_byte_offset += seg->byte_count;
/* We don't know this segment type */
g_assert_not_reached ();
}
-
+
} /* if (segment was visible) */
else
{
seg->type == >k_text_left_mark_type)
{
int cursor_offset = 0;
-
+
/* At the insertion point, add the preedit string, if any */
-
+
if (_gtk_text_btree_mark_is_insert (btree, seg->body.mark.obj))
{
display->insert_index = layout_byte_offset;
-
+
if (layout->preedit_len > 0)
{
text_allocated += layout->preedit_len;
style = get_style (layout, tags);
add_preedit_attrs (layout, style, attrs, layout_byte_offset, size_only);
release_style (layout, style);
-
+
memcpy (text + layout_byte_offset, layout->preedit_string, layout->preedit_len);
layout_byte_offset += layout->preedit_len;
/* DO NOT increment the buffer byte offset for preedit */
-
+
cursor_offset = layout->preedit_cursor - layout->preedit_len;
}
}
-
+
/* Display visible marks */
seg = seg->next;
}
-
+
if (!para_values_set)
{
style = get_style (layout, tags);
set_para_values (layout, base_dir, style, display);
release_style (layout, style);
}
-
+
/* Pango doesn't want the trailing paragraph delimiters */
{
}
}
}
-
+
pango_layout_set_text (display->layout, text, layout_byte_offset);
pango_layout_set_attributes (display->layout, attrs);
break;
}
}
-
+
/* Free this if we aren't in a loop */
if (layout->wrap_loop_count == 0)
invalidate_cached_style (layout);
if (saw_widget)
allocate_child_widgets (layout, display);
-
+
return g_steal_pointer (&display);
}
g_return_val_if_fail (_gtk_text_iter_get_text_line (iter) == display->line, 0);
index = gtk_text_iter_get_visible_line_index (iter);
-
+
if (layout->preedit_len > 0 && display->insert_index >= 0)
{
if (index >= display->insert_index)
{
g_return_if_fail (!_gtk_text_line_is_last (display->line,
_gtk_text_buffer_get_btree (layout->buffer)));
-
+
if (layout->preedit_len > 0 && display->insert_index >= 0)
{
if (index >= display->insert_index + layout->preedit_len)
gtk_text_layout_get_iter_at_line (layout, iter, display->line, 0);
gtk_text_iter_set_visible_line_index (iter, index);
-
+
if (_gtk_text_iter_get_text_line (iter) != display->line)
{
/* Clamp to end of line - really this clamping should have been done
if (!gtk_text_iter_ends_line (iter))
gtk_text_iter_forward_to_line_end (iter);
}
-
+
gtk_text_iter_forward_chars (iter, trailing);
}
line = _gtk_text_iter_get_text_line (iter);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
index = line_display_iter_to_index (layout, display, iter);
-
+
line_top = _gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
-
+
gtk_text_buffer_get_iter_at_mark (layout->buffer, &insert_iter,
gtk_text_buffer_get_insert (layout->buffer));
if (gtk_text_iter_equal (iter, &insert_iter))
index += layout->preedit_cursor - layout->preedit_len;
-
+
pango_layout_get_cursor_pos (display->layout, index,
strong_pos ? &pango_strong_pos : NULL,
weak_pos ? &pango_weak_pos : NULL);
GtkTextLineDisplay *display;
int byte_index;
int x_offset;
-
+
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (_gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer));
g_return_if_fail (rect != NULL);
x_offset = display->x_offset * PANGO_SCALE;
byte_index = gtk_text_iter_get_line_index (iter);
-
+
pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
-
+
rect->x = PANGO_PIXELS (x_offset + pango_rect.x);
rect->y += PANGO_PIXELS (pango_rect.y) + display->top_margin;
rect->width = PANGO_PIXELS (pango_rect.width);
PangoLayoutLine *layout_line = pango_layout_iter_get_line_readonly (layout_iter);
found_byte = layout_line->start_index;
-
+
if (line_top >= y)
{
found_line = line;
while (pango_layout_iter_next_line (layout_iter));
pango_layout_iter_free (layout_iter);
-
+
line_top += display->bottom_margin;
gtk_text_line_display_unref (display);
if (!line)
{
line = _gtk_text_btree_get_end_iter_line (btree);
-
+
line_top = _gtk_text_btree_find_line_top (btree, line, layout);
}
int tmp_top;
layout_iter = pango_layout_get_iter (display->layout);
-
+
line_top -= display->top_margin + display->bottom_margin;
pango_layout_iter_get_layout_extents (layout_iter, NULL, &logical_rect);
line_top -= logical_rect.height / PANGO_SCALE;
found_byte = layout_line->start_index;
pango_layout_iter_get_line_yrange (layout_iter, &first_y, &last_y);
-
+
tmp_top -= (last_y - first_y) / PANGO_SCALE;
if (tmp_top < y)
while (pango_layout_iter_next_line (layout_iter));
pango_layout_iter_free (layout_iter);
-
+
gtk_text_line_display_unref (display);
line = _gtk_text_line_previous (line);
PangoLayoutLine *layout_line;
GtkTextIter orig;
gboolean update_byte = FALSE;
-
+
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
display = gtk_text_layout_get_line_display (layout, prev_line, FALSE);
update_byte = TRUE;
}
-
+
tmp_list = pango_layout_get_lines_readonly (display->layout);
layout_line = tmp_list->data;
}
out:
-
+
gtk_text_line_display_unref (display);
return
g_return_val_if_fail (iter != NULL, FALSE);
orig = *iter;
-
+
line = _gtk_text_iter_get_text_line (iter);
while (line && !found_after)
if (display->height == 0)
goto next;
-
+
if (first)
{
line_byte = line_display_iter_to_index (layout, display, iter);
}
else
line_byte = 0;
-
+
tmp_list = pango_layout_get_lines_readonly (display->layout);
while (tmp_list && !found_after)
{
}
else if (line_byte < layout_line->start_index + layout_line->length || !tmp_list->next)
found = TRUE;
-
+
tmp_list = tmp_list->next;
}
next:
-
+
gtk_text_line_display_unref (display);
line = _gtk_text_line_next_excluding_last (line);
if (!found_after)
gtk_text_buffer_get_end_iter (layout->buffer, iter);
-
+
return
!gtk_text_iter_equal (iter, &orig) &&
!gtk_text_iter_is_end (iter);
int line_byte;
GSList *tmp_list;
GtkTextIter orig;
-
+
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
orig = *iter;
-
+
line = _gtk_text_iter_get_text_line (iter);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
line_byte = line_display_iter_to_index (layout, display, iter);
* are inside a paragraph to avoid going to next line on a
* forced break not at whitespace. Real fix is to keep track
* of whether marks are at leading or trailing edge? */
- if (direction > 0 && layout_line->length > 0 &&
- !gtk_text_iter_ends_line (iter) &&
+ if (direction > 0 && layout_line->length > 0 &&
+ !gtk_text_iter_ends_line (iter) &&
!_gtk_text_btree_char_is_invisible (iter))
gtk_text_iter_backward_char (iter);
break;
}
-
+
tmp_list = tmp_list->next;
}
GtkTextLineDisplay *display;
int line_byte;
GSList *tmp_list;
-
+
g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
* it
*/
gtk_text_line_display_unref (display);
-
+
if (line_byte == layout_line->start_index)
return TRUE;
else
return FALSE;
}
-
+
tmp_list = tmp_list->next;
}
GtkTextLineDisplay *display;
int line_byte;
PangoLayoutIter *layout_iter;
-
+
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (iter != NULL);
while (pango_layout_iter_next_line (layout_iter));
pango_layout_iter_free (layout_iter);
-
+
gtk_text_line_display_unref (display);
}
GtkTextLineDisplay *display = NULL;
GtkTextIter orig;
GtkTextIter lineiter;
-
+
g_return_val_if_fail (layout != NULL, FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
orig = *iter;
-
+
while (count != 0)
{
GtkTextLine *line = _gtk_text_iter_get_text_line (iter);
extra_back = 1;
}
}
-
+
if (new_index < 0 || (new_index == 0 && extra_back))
{
do
goto done;
}
while (totally_invisible_line (layout, line, &lineiter));
-
+
gtk_text_line_display_unref (display);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
gtk_text_iter_forward_to_line_end (&lineiter);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
new_index = 0;
}
-
+
line_display_index_to_iter (layout, display, iter, new_index, new_trailing);
if (extra_back)
gtk_text_iter_backward_char (iter);
g_clear_pointer (&display, gtk_text_line_display_unref);
done:
-
+
return
!gtk_text_iter_equal (iter, &orig) &&
!gtk_text_iter_is_end (iter);