mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-30 15:31:34 +00:00
Merge branch 'matthiasc/for-master' into 'master'
Speed up gtk_text_buffer_insert_markup See merge request GNOME/gtk!2432
This commit is contained in:
commit
ebaf533a31
@ -1837,7 +1837,7 @@ gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
|
||||
g_return_if_fail (iter != NULL);
|
||||
g_return_if_fail (text != NULL);
|
||||
g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
|
||||
|
||||
|
||||
start_offset = gtk_text_iter_get_offset (iter);
|
||||
|
||||
gtk_text_buffer_insert (buffer, iter, text, len);
|
||||
@ -1859,6 +1859,28 @@ gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_buffer_insert_with_tagsv (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
const char *text,
|
||||
int len,
|
||||
GtkTextTag **tags,
|
||||
int n_tags)
|
||||
{
|
||||
int start_offset;
|
||||
GtkTextIter start;
|
||||
int i;
|
||||
|
||||
start_offset = gtk_text_iter_get_offset (iter);
|
||||
|
||||
gtk_text_buffer_insert (buffer, iter, text, len);
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
|
||||
|
||||
for (i = 0; i < n_tags; i++)
|
||||
gtk_text_buffer_apply_tag (buffer, tags[i], &start, iter);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_insert_with_tags_by_name:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
@ -4379,161 +4401,150 @@ _gtk_text_buffer_spew (GtkTextBuffer *buffer)
|
||||
_gtk_text_btree_spew (get_btree (buffer));
|
||||
}
|
||||
|
||||
static GtkTextTag *
|
||||
get_tag_for_attributes (PangoAttrIterator *iter)
|
||||
static void
|
||||
get_tags_for_attributes (PangoAttrIterator *iter,
|
||||
GtkTextTagTable *table,
|
||||
GPtrArray *tags)
|
||||
{
|
||||
PangoAttribute *attr;
|
||||
GtkTextTag *tag;
|
||||
char name[256];
|
||||
|
||||
tag = gtk_text_tag_new (NULL);
|
||||
|
||||
#define STRING_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
const char *string = ((PangoAttrString*)attr)->value; \
|
||||
g_snprintf (name, 256, "%s=%s", #attr_name, string); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, string, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
g_ptr_array_add (tags, tag); \
|
||||
}
|
||||
|
||||
#define INT_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
int value = ((PangoAttrInt*)attr)->value; \
|
||||
g_snprintf (name, 256, "%s=%d", #attr_name, value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, value, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
g_ptr_array_add (tags, tag); \
|
||||
}
|
||||
|
||||
#define FLOAT_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
float value = ((PangoAttrFloat*)attr)->value; \
|
||||
g_snprintf (name, 256, "%s=%g", #attr_name, value); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, value, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
g_ptr_array_add (tags, tag); \
|
||||
}
|
||||
|
||||
#define RGBA_ATTR(pango_attr_name, attr_name) \
|
||||
attr = pango_attr_iterator_get (iter, pango_attr_name); \
|
||||
if (attr) \
|
||||
{ \
|
||||
PangoColor *color; \
|
||||
GdkRGBA rgba; \
|
||||
color = &((PangoAttrColor*)attr)->color; \
|
||||
rgba.red = color->red / 65535.; \
|
||||
rgba.green = color->green / 65535.; \
|
||||
rgba.blue = color->blue / 65535.; \
|
||||
rgba.alpha = 1.; \
|
||||
char *str = gdk_rgba_to_string (&rgba); \
|
||||
g_snprintf (name, 256, "%s=%s", #attr_name, str); \
|
||||
g_free (str); \
|
||||
tag = gtk_text_tag_table_lookup (table, name); \
|
||||
if (!tag) \
|
||||
{ \
|
||||
tag = gtk_text_tag_new (name); \
|
||||
g_object_set (tag, #attr_name, &rgba, NULL); \
|
||||
gtk_text_tag_table_add (table, tag); \
|
||||
g_object_unref (tag); \
|
||||
} \
|
||||
g_ptr_array_add (tags, tag); \
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_BACKGROUND);
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_LANGUAGE);
|
||||
if (attr)
|
||||
g_object_set (tag, "language", pango_language_to_string (((PangoAttrLanguage*)attr)->value), NULL);
|
||||
{
|
||||
const char *language = pango_language_to_string (((PangoAttrLanguage*)attr)->value);
|
||||
g_snprintf (name, 256, "language=%s", language);
|
||||
tag = gtk_text_tag_table_lookup (table, name);
|
||||
if (!tag)
|
||||
{
|
||||
tag = gtk_text_tag_new (name);
|
||||
g_object_set (tag, "language", language, NULL);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
g_object_unref (tag);
|
||||
}
|
||||
g_ptr_array_add (tags, tag);
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FAMILY);
|
||||
if (attr)
|
||||
g_object_set (tag, "family", ((PangoAttrString*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_STYLE);
|
||||
if (attr)
|
||||
g_object_set (tag, "style", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_WEIGHT);
|
||||
if (attr)
|
||||
g_object_set (tag, "weight", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_VARIANT);
|
||||
if (attr)
|
||||
g_object_set (tag, "variant", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_STRETCH);
|
||||
if (attr)
|
||||
g_object_set (tag, "stretch", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_SIZE);
|
||||
if (attr)
|
||||
g_object_set (tag, "size", ((PangoAttrInt*)attr)->value, NULL);
|
||||
STRING_ATTR(PANGO_ATTR_FAMILY, family)
|
||||
INT_ATTR(PANGO_ATTR_STYLE, style)
|
||||
INT_ATTR(PANGO_ATTR_WEIGHT, weight)
|
||||
INT_ATTR(PANGO_ATTR_VARIANT, variant)
|
||||
INT_ATTR(PANGO_ATTR_STRETCH, stretch)
|
||||
INT_ATTR(PANGO_ATTR_SIZE, size)
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_DESC);
|
||||
if (attr)
|
||||
g_object_set (tag, "font-desc", ((PangoAttrFontDesc*)attr)->desc, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FOREGROUND);
|
||||
if (attr)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
|
||||
color = &((PangoAttrColor*)attr)->color;
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = 1.;
|
||||
g_object_set (tag, "foreground-rgba", &rgba, NULL);
|
||||
};
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_BACKGROUND);
|
||||
if (attr)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
|
||||
color = &((PangoAttrColor*)attr)->color;
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = 1.;
|
||||
g_object_set (tag, "background-rgba", &rgba, NULL);
|
||||
};
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE);
|
||||
if (attr)
|
||||
g_object_set (tag, "underline", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_UNDERLINE_COLOR);
|
||||
if (attr)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
|
||||
color = &((PangoAttrColor*)attr)->color;
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = 1.;
|
||||
g_object_set (tag, "underline-rgba", &rgba, NULL);
|
||||
PangoFontDescription *desc = ((PangoAttrFontDesc*)attr)->desc;
|
||||
char *str = pango_font_description_to_string (desc);
|
||||
g_snprintf (name, 256, "font-desc=%s", str);
|
||||
g_free (str);
|
||||
tag = gtk_text_tag_table_lookup (table, name);
|
||||
if (!tag)
|
||||
{
|
||||
tag = gtk_text_tag_new (name);
|
||||
g_object_set (tag, "font-desc", desc, NULL);
|
||||
gtk_text_tag_table_add (table, tag);
|
||||
g_object_unref (tag);
|
||||
}
|
||||
g_ptr_array_add (tags, tag);
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_OVERLINE);
|
||||
if (attr)
|
||||
g_object_set (tag, "overline", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_OVERLINE_COLOR);
|
||||
if (attr)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
|
||||
color = &((PangoAttrColor*)attr)->color;
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = 1.;
|
||||
g_object_set (tag, "overline-rgba", &rgba, NULL);
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_STRIKETHROUGH);
|
||||
if (attr)
|
||||
g_object_set (tag, "strikethrough", (gboolean) (((PangoAttrInt*)attr)->value != 0), NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_STRIKETHROUGH_COLOR);
|
||||
if (attr)
|
||||
{
|
||||
PangoColor *color;
|
||||
GdkRGBA rgba;
|
||||
|
||||
color = &((PangoAttrColor*)attr)->color;
|
||||
rgba.red = color->red / 65535.;
|
||||
rgba.green = color->green / 65535.;
|
||||
rgba.blue = color->blue / 65535.;
|
||||
rgba.alpha = 1.;
|
||||
g_object_set (tag, "strikethrough-rgba", &rgba, NULL);
|
||||
}
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_RISE);
|
||||
if (attr)
|
||||
g_object_set (tag, "rise", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_SCALE);
|
||||
if (attr)
|
||||
g_object_set (tag, "scale", ((PangoAttrFloat*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FALLBACK);
|
||||
if (attr)
|
||||
g_object_set (tag, "fallback", (gboolean) (((PangoAttrInt*)attr)->value != 0), NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_LETTER_SPACING);
|
||||
if (attr)
|
||||
g_object_set (tag, "letter-spacing", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_FONT_FEATURES);
|
||||
if (attr)
|
||||
g_object_set (tag, "font-features", ((PangoAttrString*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_ALLOW_BREAKS);
|
||||
if (attr)
|
||||
g_object_set (tag, "allow-breaks", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_SHOW);
|
||||
if (attr)
|
||||
g_object_set (tag, "show-spaces", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
attr = pango_attr_iterator_get (iter, PANGO_ATTR_INSERT_HYPHENS);
|
||||
if (attr)
|
||||
g_object_set (tag, "insert-hyphens", ((PangoAttrInt*)attr)->value, NULL);
|
||||
|
||||
return tag;
|
||||
RGBA_ATTR(PANGO_ATTR_FOREGROUND, foreground_rgba)
|
||||
RGBA_ATTR(PANGO_ATTR_BACKGROUND, background_rgba)
|
||||
INT_ATTR(PANGO_ATTR_UNDERLINE, underline)
|
||||
RGBA_ATTR(PANGO_ATTR_UNDERLINE_COLOR, underline_rgba)
|
||||
INT_ATTR(PANGO_ATTR_OVERLINE, overline)
|
||||
RGBA_ATTR(PANGO_ATTR_OVERLINE_COLOR, overline_rgba)
|
||||
INT_ATTR(PANGO_ATTR_STRIKETHROUGH, strikethrough)
|
||||
RGBA_ATTR(PANGO_ATTR_STRIKETHROUGH_COLOR, strikethrough_rgba)
|
||||
INT_ATTR(PANGO_ATTR_RISE, rise)
|
||||
FLOAT_ATTR(PANGO_ATTR_SCALE, scale)
|
||||
INT_ATTR(PANGO_ATTR_FALLBACK, fallback)
|
||||
INT_ATTR(PANGO_ATTR_LETTER_SPACING, letter_spacing)
|
||||
STRING_ATTR(PANGO_ATTR_FONT_FEATURES, font_features)
|
||||
INT_ATTR(PANGO_ATTR_ALLOW_BREAKS, allow_breaks)
|
||||
INT_ATTR(PANGO_ATTR_SHOW, show_spaces)
|
||||
INT_ATTR(PANGO_ATTR_INSERT_HYPHENS, insert_hyphens)
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4544,7 +4555,8 @@ gtk_text_buffer_insert_with_attributes (GtkTextBuffer *buffer,
|
||||
{
|
||||
GtkTextMark *mark;
|
||||
PangoAttrIterator *attr;
|
||||
GtkTextTagTable *tags;
|
||||
GtkTextTagTable *table;
|
||||
GPtrArray *tags;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
|
||||
@ -4557,11 +4569,11 @@ gtk_text_buffer_insert_with_attributes (GtkTextBuffer *buffer,
|
||||
/* create mark with right gravity */
|
||||
mark = gtk_text_buffer_create_mark (buffer, NULL, iter, FALSE);
|
||||
attr = pango_attr_list_get_iterator (attributes);
|
||||
tags = gtk_text_buffer_get_tag_table (buffer);
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
tags = g_ptr_array_new ();
|
||||
|
||||
do
|
||||
{
|
||||
GtkTextTag *tag;
|
||||
int start, end;
|
||||
|
||||
pango_attr_iterator_range (attr, &start, &end);
|
||||
@ -4569,20 +4581,24 @@ gtk_text_buffer_insert_with_attributes (GtkTextBuffer *buffer,
|
||||
if (end == G_MAXINT) /* last chunk */
|
||||
end = start - 1; /* resulting in -1 to be passed to _insert */
|
||||
|
||||
tag = get_tag_for_attributes (attr);
|
||||
gtk_text_tag_table_add (tags, tag);
|
||||
get_tags_for_attributes (attr, table, tags);
|
||||
|
||||
gtk_text_buffer_insert_with_tags (buffer, iter, text + start, end - start, tag, NULL);
|
||||
gtk_text_buffer_insert_with_tagsv (buffer,
|
||||
iter,
|
||||
text + start, end - start,
|
||||
(GtkTextTag **)tags->pdata, tags->len);
|
||||
|
||||
g_ptr_array_set_size (tags, 0);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, iter, mark);
|
||||
|
||||
g_object_unref (tag);
|
||||
}
|
||||
while (pango_attr_iterator_next (attr));
|
||||
|
||||
|
||||
g_ptr_array_unref (tags);
|
||||
|
||||
gtk_text_buffer_delete_mark (buffer, mark);
|
||||
pango_attr_iterator_destroy (attr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_insert_markup:
|
||||
@ -4616,8 +4632,9 @@ gtk_text_buffer_insert_markup (GtkTextBuffer *buffer,
|
||||
|
||||
gtk_text_buffer_insert_with_attributes (buffer, iter, text, attributes);
|
||||
|
||||
g_print ("created %d tags\n", gtk_text_tag_table_get_size (gtk_text_buffer_get_tag_table (buffer)));
|
||||
pango_attr_list_unref (attributes);
|
||||
g_free (text);
|
||||
g_free (text);
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user