/* testrichtext.c * Copyright (C) 2006 Imendio AB * Authors: Michael Natterer, Tim Janik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include static guint32 quick_rand32_accu = 2147483563; static inline guint32 quick_rand32 (void) { quick_rand32_accu = 1664525 * quick_rand32_accu + 1013904223; return quick_rand32_accu; } static gboolean delete_event (GtkWidget *widget, GdkEventAny *event, gpointer user_data) { gtk_main_quit (); return TRUE; } static void text_tag_enqueue (GtkTextTag *tag, gpointer data) { GSList **slist_p = data; *slist_p = g_slist_prepend (*slist_p, tag); } static const gchar *example_text = "vkndsk vfds vkfds vkdsv fdlksnvkfdvnkfdvnkdsnvs\n" "kmvofdmvfdsvkv fdskvnkfdv nnd.mckfdvnknsknvdnvs" "fdlvmfdsvlkfdsmvnskdnvfdsnvf sbskjnvlknfd cvdvnd" "mvlfdsv vfdkjv m, ds vkfdks v df,v j kfds v d\n" "vnfdskv kjvnfv cfdkvndfnvcm fd,vk kdsf vj d\n" "KLJHkjh kjh klhjKLJH Kjh kjl h34kj h34kj3h klj 23 " "kjlkjlhsdjk 34kljh klj hklj 23k4jkjkjh234kjh 52kj " "2h34 sdaf ukklj kjl32l jkkjl 23j jkl ljk23 jkl\n" "hjhjhj2hj23jh jh jk jk2h3 hj kjj jk jh21 jhhj32."; static GdkAtom setup_buffer (GtkTextBuffer *buffer) { const guint tlen = strlen (example_text); const guint tcount = 17; GtkTextTag **tags; GtkTextTagTable *ttable = gtk_text_buffer_get_tag_table (buffer); GSList *node, *slist = NULL; GdkAtom atom; guint i; tags = g_malloc (sizeof (GtkTextTag *) * tcount); /* cleanup */ gtk_text_buffer_set_text (buffer, "", 0); gtk_text_tag_table_foreach (ttable, text_tag_enqueue, &slist); for (node = slist; node; node = node->next) gtk_text_tag_table_remove (ttable, node->data); g_slist_free (slist); /* create new tags */ for (i = 0; i < tcount; i++) { char *s = g_strdup_printf ("tag%u", i); tags[i] = gtk_text_buffer_create_tag (buffer, s, "weight", quick_rand32() >> 31 ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, "style", quick_rand32() >> 31 ? PANGO_STYLE_OBLIQUE : PANGO_STYLE_NORMAL, "underline", quick_rand32() >> 31, NULL); g_free (s); } /* assign text and tags */ gtk_text_buffer_set_text (buffer, example_text, -1); for (i = 0; i < tcount * 5; i++) { gint a = quick_rand32() % tlen, b = quick_rand32() % tlen; GtkTextIter start, end; gtk_text_buffer_get_iter_at_offset (buffer, &start, MIN (a, b)); gtk_text_buffer_get_iter_at_offset (buffer, &end, MAX (a, b)); gtk_text_buffer_apply_tag (buffer, tags[i % tcount], &start, &end); } /* return serialization format */ atom = gtk_text_buffer_register_deserialize_tagset (buffer, NULL); gtk_text_buffer_deserialize_set_can_create_tags (buffer, atom, TRUE); g_free (tags); return atom; } static gboolean test_serialize_deserialize (GtkTextBuffer *buffer, GdkAtom atom, GError **error) { GtkTextIter start, end; guint8 *spew; gsize spew_length; gboolean success; gtk_text_buffer_get_bounds (buffer, &start, &end); spew = gtk_text_buffer_serialize (buffer, buffer, atom, &start, &end, &spew_length); success = gtk_text_buffer_deserialize (buffer, buffer, atom, &end, spew, spew_length, error); g_free (spew); return success; } gint main (gint argc, gchar *argv[]) { GtkWidget *window; GtkWidget *sw; GtkWidget *view; GtkTextBuffer *buffer; GdkAtom atom; guint i, broken = 0; gtk_init (&argc, &argv); /* initialize random numbers, disable this for deterministic testing */ if (1) quick_rand32_accu = g_random_int(); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request (window, 400, 300); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_set_border_width (GTK_CONTAINER (sw), 12); gtk_container_add (GTK_CONTAINER (window), sw); g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL); buffer = gtk_text_buffer_new (NULL); view = gtk_text_view_new_with_buffer (buffer); g_object_unref (buffer); gtk_container_add (GTK_CONTAINER (sw), view); gtk_widget_show_all (window); if (0) gtk_main (); for (i = 0; i < 250; i++) { GError *error = NULL; g_printerr ("creating randomly tagged text buffer with accu=0x%x...\n", quick_rand32_accu); atom = setup_buffer (buffer); if (test_serialize_deserialize (buffer, atom, &error)) g_printerr ("ok.\n"); else { g_printerr ("FAIL: serialization/deserialization failed:\n %s\n", error->message); broken += 1; } g_clear_error (&error); } return broken > 0; }