Commit 565074f9 authored by Havoc Pennington's avatar Havoc Pennington Committed by Havoc Pennington

fix breakage here that cause a segfault on text insertion

2000-12-08  Havoc Pennington  <hp@redhat.com>

	* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
	that cause a segfault on text insertion

	* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
	warning

	* gtk/gtktextiter.c (test_log_attrs): use
	_gtk_text_buffer_get_line_log_attrs to speed things up a bit

	* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
	Get log attrs for a line, using a cache stored on the buffer

	* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
	reported by Jeff Franks
parent 544bfc3d
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
2000-12-08 Havoc Pennington <hp@redhat.com>
* gtk/gtktextbtree.c (gtk_text_btree_insert): fix breakage here
that cause a segfault on text insertion
* gtk/gtktextchild.c (gtk_text_child_anchor_queue_resize): fix
warning
* gtk/gtktextiter.c (test_log_attrs): use
_gtk_text_buffer_get_line_log_attrs to speed things up a bit
* gtk/gtktextbuffer.c (_gtk_text_buffer_get_line_log_attrs):
Get log attrs for a line, using a cache stored on the buffer
* gtk/gtkcolorsel.h (GTK_COLOR_SELECTION_GET_CLASS): fix typo,
reported by Jeff Franks
2000-12-08 Alexander Larsson <alla@lysator.liu.se>
* gdk/linux-fb/gdkmouse-fb.c (gdk_fb_mouse_ms_open):
......@@ -145,6 +162,7 @@
(return bytes not chars)
2000-12-05 Elliot Lee <sopwith@redhat.com>
* gdk/gdkcolor.h: Make GdkColor specify element sizes
to avoid waste on 64-bit platforms.
......
......@@ -40,7 +40,7 @@ extern "C" {
#define GTK_COLOR_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
#define GTK_IS_COLOR_SELECTION(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_COLOR_SELECTION))
#define GTK_IS_COLOR_SELECTION_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_COLOR_SELECTION))
#define GTK_COLOR_SELECTION_GET_CLASS(obj) (GTK_CHECK_GET_CLAS ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
#define GTK_COLOR_SELECTION_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_COLOR_SELECTION, GtkColorSelectionClass))
typedef struct _GtkColorSelection GtkColorSelection;
......
......@@ -976,6 +976,10 @@ gtk_text_btree_insert (GtkTextIter *iter,
&delim,
&eol);
/* make these relative to the start of the text */
delim += sol;
eol += sol;
chunk_len = eol - sol;
seg = _gtk_char_segment_new (&text[sol], chunk_len);
......
......@@ -97,6 +97,7 @@ static void gtk_text_buffer_real_remove_tag (GtkTextBuffer *buffe
static void gtk_text_buffer_real_changed (GtkTextBuffer *buffer);
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
static void free_log_attr_cache (GtkTextLogAttrCache *cache);
static GtkObjectClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };
......@@ -292,6 +293,11 @@ gtk_text_buffer_finalize (GObject *object)
gtk_text_btree_unref (buffer->btree);
buffer->btree = NULL;
}
if (buffer->log_attr_cache)
free_log_attr_cache (buffer->log_attr_cache);
buffer->log_attr_cache = NULL;
G_OBJECT_CLASS (parent_class)->finalize (object);
}
......@@ -2612,6 +2618,155 @@ gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
}
/*
* Logical attribute cache
*/
#define ATTR_CACHE_SIZE 2
typedef struct _CacheEntry CacheEntry;
struct _CacheEntry
{
gint line;
gint char_len;
PangoLogAttr *attrs;
};
struct _GtkTextLogAttrCache
{
gint chars_changed_stamp;
CacheEntry entries[ATTR_CACHE_SIZE];
};
static void
free_log_attr_cache (GtkTextLogAttrCache *cache)
{
gint i = 0;
while (i < ATTR_CACHE_SIZE)
{
g_free (cache->entries[i].attrs);
++i;
}
g_free (cache);
}
static void
clear_log_attr_cache (GtkTextLogAttrCache *cache)
{
gint i = 0;
while (i < ATTR_CACHE_SIZE)
{
g_free (cache->entries[i].attrs);
cache->entries[i].attrs = NULL;
++i;
}
}
static PangoLogAttr*
compute_log_attrs (const GtkTextIter *iter,
gint *char_lenp)
{
GtkTextIter start;
GtkTextIter end;
gchar *paragraph;
gint char_len, byte_len;
PangoLogAttr *attrs = NULL;
gchar *lang;
start = *iter;
end = *iter;
gtk_text_iter_set_line_offset (&start, 0);
gtk_text_iter_forward_line (&end);
paragraph = gtk_text_iter_get_slice (&start, &end);
char_len = g_utf8_strlen (paragraph, -1);
byte_len = strlen (paragraph);
g_assert (char_len > 0);
if (char_lenp)
*char_lenp = char_len;
attrs = g_new (PangoLogAttr, char_len);
lang = gtk_text_iter_get_language (&start);
pango_get_log_attrs (paragraph, byte_len, -1,
lang,
attrs);
g_free (lang);
g_free (paragraph);
return attrs;
}
/* The return value from this is valid until you call this a second time.
*/
const PangoLogAttr*
_gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
const GtkTextIter *anywhere_in_line,
gint *char_len)
{
gint line;
GtkTextLogAttrCache *cache;
gint i;
g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
g_return_val_if_fail (anywhere_in_line != NULL, NULL);
g_return_val_if_fail (!gtk_text_iter_is_last (anywhere_in_line), NULL);
/* FIXME we also need to recompute log attrs if the language tag at
* the start of a paragraph changes
*/
if (buffer->log_attr_cache == NULL)
{
buffer->log_attr_cache = g_new0 (GtkTextLogAttrCache, 1);
buffer->log_attr_cache->chars_changed_stamp =
gtk_text_btree_get_chars_changed_stamp (get_btree (buffer));
}
else if (buffer->log_attr_cache->chars_changed_stamp !=
gtk_text_btree_get_chars_changed_stamp (get_btree (buffer)))
{
clear_log_attr_cache (buffer->log_attr_cache);
}
cache = buffer->log_attr_cache;
line = gtk_text_iter_get_line (anywhere_in_line);
i = 0;
while (i < ATTR_CACHE_SIZE)
{
if (cache->entries[i].attrs &&
cache->entries[i].line == line)
{
if (char_len)
*char_len = cache->entries[i].char_len;
return cache->entries[i].attrs;
}
++i;
}
/* Not in cache; open up the first cache entry */
if (cache->entries[ATTR_CACHE_SIZE-1].attrs)
g_free (cache->entries[ATTR_CACHE_SIZE-1].attrs);
g_memmove (cache->entries + 1, cache->entries,
sizeof (CacheEntry) * (ATTR_CACHE_SIZE - 1));
cache->entries[0].line = line;
cache->entries[0].attrs = compute_log_attrs (anywhere_in_line,
&cache->entries[0].char_len);
if (char_len)
*char_len = cache->entries[0].char_len;
return cache->entries[0].attrs;
}
/*
* Debug spew
......
......@@ -44,6 +44,8 @@ extern "C" {
typedef struct _GtkTextBTree GtkTextBTree;
typedef struct _GtkTextLogAttrCache GtkTextLogAttrCache;
#define GTK_TYPE_TEXT_BUFFER (gtk_text_buffer_get_type ())
#define GTK_TEXT_BUFFER(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_TEXT_BUFFER, GtkTextBuffer))
#define GTK_TEXT_BUFFER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TEXT_BUFFER, GtkTextBufferClass))
......@@ -61,6 +63,8 @@ struct _GtkTextBuffer
GtkTextBTree *btree;
GtkTextBuffer *clipboard_contents;
GtkTextLogAttrCache *log_attr_cache;
/* Whether the buffer has been modified since last save */
guint modified : 1;
......@@ -312,13 +316,17 @@ gboolean gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
GtkTextIter *end);
gboolean gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
gboolean interactive,
gboolean default_editable);
gboolean default_editable);
/* INTERNAL private stuff */
void _gtk_text_buffer_spew (GtkTextBuffer *buffer);
GtkTextBTree* _gtk_text_buffer_get_btree (GtkTextBuffer *buffer);
const PangoLogAttr* _gtk_text_buffer_get_line_log_attrs (GtkTextBuffer *buffer,
const GtkTextIter *anywhere_in_line,
gint *char_len);
#ifdef __cplusplus
}
#endif /* __cplusplus */
......
......@@ -445,7 +445,7 @@ gtk_text_child_anchor_queue_resize (GtkTextChildAnchor *anchor,
seg = anchor->segment;
if (seg->body.child.tree == NULL)
return NULL;
return;
gtk_text_buffer_get_iter_at_child_anchor (layout->buffer,
&start, anchor);
......
......@@ -1268,7 +1268,7 @@ gtk_text_iter_editable (const GtkTextIter *iter,
*
* Return value: language in effect at @iter
**/
static gchar*
gchar*
gtk_text_iter_get_language (const GtkTextIter *iter)
{
GtkTextAttributes *values;
......@@ -2384,14 +2384,14 @@ gtk_text_iter_backward_lines (GtkTextIter *iter, gint count)
}
}
typedef gboolean (* FindLogAttrFunc) (PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset);
typedef gboolean (* FindLogAttrFunc) (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
gint *found_offset);
static gboolean
find_word_end_func (PangoLogAttr *attrs,
find_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
......@@ -2410,7 +2410,7 @@ find_word_end_func (PangoLogAttr *attrs,
}
static gboolean
is_word_end_func (PangoLogAttr *attrs,
is_word_end_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
......@@ -2420,7 +2420,7 @@ is_word_end_func (PangoLogAttr *attrs,
}
static gboolean
find_word_start_func (PangoLogAttr *attrs,
find_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
......@@ -2439,7 +2439,7 @@ find_word_start_func (PangoLogAttr *attrs,
}
static gboolean
is_word_start_func (PangoLogAttr *attrs,
is_word_start_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
......@@ -2449,7 +2449,7 @@ is_word_start_func (PangoLogAttr *attrs,
}
static gboolean
inside_word_func (PangoLogAttr *attrs,
inside_word_func (const PangoLogAttr *attrs,
gint offset,
gint min_offset,
gint len,
......@@ -2464,52 +2464,27 @@ inside_word_func (PangoLogAttr *attrs,
}
static gboolean
test_log_attrs (GtkTextIter *iter,
test_log_attrs (const GtkTextIter *iter,
FindLogAttrFunc func,
gint *found_offset)
{
GtkTextIter start;
GtkTextIter end;
gchar *paragraph;
gint char_len, byte_len;
PangoLogAttr *attrs;
gint char_len;
const PangoLogAttr *attrs;
int offset;
gboolean result = FALSE;
g_return_val_if_fail (iter != NULL, FALSE);
start = *iter;
end = *iter;
gtk_text_iter_set_line_offset (&start, 0);
gtk_text_iter_forward_line (&end);
paragraph = gtk_text_iter_get_slice (&start, &end);
char_len = g_utf8_strlen (paragraph, -1);
byte_len = strlen (paragraph);
attrs = _gtk_text_buffer_get_line_log_attrs (gtk_text_iter_get_buffer (iter),
iter, &char_len);
offset = gtk_text_iter_get_line_offset (iter);
if (char_len > 0 && offset < char_len)
{
gchar *lang;
attrs = g_new (PangoLogAttr, char_len);
lang = gtk_text_iter_get_language (iter);
pango_get_log_attrs (paragraph, byte_len, -1,
lang,
attrs);
g_free (lang);
result = (* func) (attrs, offset, 0, char_len, found_offset);
g_free (attrs);
}
g_free (paragraph);
g_assert (char_len > 0);
if (offset < char_len)
result = (* func) (attrs, offset, 0, char_len, found_offset);
return result;
}
......
......@@ -134,8 +134,8 @@ gboolean gtk_text_iter_ends_line (const GtkTextIter *iter);
gint gtk_text_iter_get_chars_in_line (const GtkTextIter *iter);
gboolean gtk_text_iter_get_attributes (const GtkTextIter *iter,
GtkTextAttributes *values);
GtkTextAttributes *values);
gchar* gtk_text_iter_get_language (const GtkTextIter *iter);
gboolean gtk_text_iter_is_last (const GtkTextIter *iter);
gboolean gtk_text_iter_is_first (const GtkTextIter *iter);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment