diff options
author | Robert Staudinger <robsta@gnome.org> | 2009-08-06 10:41:56 +0200 |
---|---|---|
committer | Robert Staudinger <robsta@gnome.org> | 2009-08-06 10:41:56 +0200 |
commit | 4c74a2025835dfd6b43dd0a94b01d5006637c883 (patch) | |
tree | c0864300f9e9f2326dd43447cadc302c4e6d4432 | |
parent | 8ed88beda82880a2562f1eb0504faf41890223a7 (diff) |
[style] New method ccss_style_hash().
Calculates a hash value that uniquely identifies a style. If two styles
have the same hash value they are equal.
A hash value of 0 is returned for NULL or empty styles.
Add example-9 for demonstration.
-rw-r--r-- | ccss-doc/ccss-sections.txt | 1 | ||||
-rw-r--r-- | ccss/ccss-style.c | 46 | ||||
-rw-r--r-- | ccss/ccss-style.h | 5 | ||||
-rw-r--r-- | ccss/ccss.sym | 1 | ||||
-rw-r--r-- | examples/Makefile.am | 3 | ||||
-rw-r--r-- | examples/example-1.c | 7 | ||||
-rw-r--r-- | examples/example-9.c | 82 |
7 files changed, 142 insertions, 3 deletions
diff --git a/ccss-doc/ccss-sections.txt b/ccss-doc/ccss-sections.txt index fd3074e..2ed1f1f 100644 --- a/ccss-doc/ccss-sections.txt +++ b/ccss-doc/ccss-sections.txt @@ -53,6 +53,7 @@ ccss_style_get_double ccss_style_get_property ccss_style_set_property ccss_style_get_string +ccss_style_hash ccss_style_iterator_f ccss_style_foreach ccss_style_dump diff --git a/ccss/ccss-style.c b/ccss/ccss-style.c index e01cecb..5068bd2 100644 --- a/ccss/ccss-style.c +++ b/ccss/ccss-style.c @@ -72,6 +72,52 @@ ccss_style_destroy (ccss_style_t *self) } /** + * ccss_style_hash: + * @self: a #ccss_style_t. + * + * Calculates a hash value that uniquely identifies a style. If two styles + * have the same hash value they are equal. + * + * A hash value of 0 is returned for %NULL or empty styles. + * + * Returns: hash value. + **/ +uint32_t +ccss_style_hash (ccss_style_t const *self) +{ + uint32_t hash = 0; + + g_return_val_if_fail (self, 0); + g_return_val_if_fail (self->properties, 0); + g_return_val_if_fail (g_hash_table_size (self->properties), 0); + + { + ccss_property_base_t const *property; + GHashTableIter iter; + int n_properties = g_hash_table_size (self->properties); + void *property_ptrs[n_properties * sizeof (void *) + 1]; + char const *property_str = (char const *) property_ptrs; + int i = 0; + + /* Accumulate string of property pointers. */ + g_hash_table_iter_init (&iter, self->properties); + while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &property)) { + property_ptrs[i] = (void *) property; + i++; + } + property_ptrs[i] = NULL; + + /* sdbm hash */ + while (0 != (i = *property_str++)) { + hash = i + (hash << 6) + (hash << 16) - hash; + } + + } + + return hash; +} + +/** * ccss_style_get_stylesheet: * @self: a #ccss_gramar_t. * diff --git a/ccss/ccss-style.h b/ccss/ccss-style.h index af97a7c..ce2cf97 100644 --- a/ccss/ccss-style.h +++ b/ccss/ccss-style.h @@ -39,7 +39,10 @@ CCSS_BEGIN_DECLS typedef struct ccss_style_ ccss_style_t; void -ccss_style_destroy (ccss_style_t *self); +ccss_style_destroy (ccss_style_t *self); + +uint32_t +ccss_style_hash (ccss_style_t const *self); /* Somewhat hackish */ struct ccss_stylesheet_ * diff --git a/ccss/ccss.sym b/ccss/ccss.sym index b3af4dd..511f6b8 100644 --- a/ccss/ccss.sym +++ b/ccss/ccss.sym @@ -29,6 +29,7 @@ ccss_style_get_double ccss_style_get_property ccss_style_get_string ccss_style_set_property +ccss_style_hash ccss_style_interpret_property ccss_stylesheet_add_from_file ccss_stylesheet_destroy diff --git a/examples/Makefile.am b/examples/Makefile.am index 93f21b1..30f4029 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -24,6 +24,7 @@ noinst_PROGRAMS = \ example-6 \ example-7 \ example-8 \ + example-9 \ $(NULL) noinst_LTLIBRARIES = libexample-8-noinst.la @@ -62,6 +63,8 @@ example_8_LDADD = libexample-8-noinst.la libexample_8_la_LDFLAGS = -avoid-version -export-dynamic -module -no-undefined libexample_8_la_SOURCES = example-8.c +example_9_SOURCES = example-9.c + EXTRA_DIST = \ example-3.png \ example-5.svg \ diff --git a/examples/example-1.c b/examples/example-1.c index 1a29357..4642135 100644 --- a/examples/example-1.c +++ b/examples/example-1.c @@ -42,6 +42,7 @@ main (int argc, ccss_stylesheet_t *stylesheet; ccss_style_t *style; GtkWidget *window; + GtkWidget *area; gtk_init (&argc, &argv); @@ -58,10 +59,12 @@ main (int argc, #endif window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 160, 90); - gtk_widget_set_app_paintable (window, TRUE); g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (gtk_main_quit), NULL); - g_signal_connect (G_OBJECT (window), "expose-event", + + area = gtk_drawing_area_new (); + gtk_container_add (GTK_CONTAINER (window), area); + g_signal_connect (G_OBJECT (area), "expose-event", G_CALLBACK (expose_cb), style); gtk_widget_show_all (window); diff --git a/examples/example-9.c b/examples/example-9.c new file mode 100644 index 0000000..60980ba --- /dev/null +++ b/examples/example-9.c @@ -0,0 +1,82 @@ +/* vim: set ts=8 sw=8 noexpandtab: */ + +#include <stdlib.h> +#include <cairo.h> +#include <ccss-cairo/ccss-cairo.h> +#include <gtk/gtk.h> +#include "config.h" + +static gboolean +expose_cb (GtkWidget *widget, + GdkEventExpose *event, + ccss_stylesheet_t *stylesheet) +{ + ccss_style_t *style; + cairo_t *cr; + uint32_t hash; + + style = ccss_stylesheet_query_type (stylesheet, "box"); + g_return_val_if_fail (style, FALSE); + + hash = ccss_style_hash (style); + g_debug ("%s() style instance='%p' hash='%u'", + __FUNCTION__, + (void *) style, + hash); + + cr = gdk_cairo_create (widget->window); + ccss_cairo_style_draw_rectangle (style, cr, + widget->allocation.x + 10, + widget->allocation.y + 10, + widget->allocation.width - 20, + widget->allocation.height - 20); + + cairo_destroy (cr); + ccss_style_destroy (style); + + return FALSE; +} + +static char const _css[] = " \ + box { \ + border: 3px solid black; \ + border-top: 3px dotted red; \ + border-radius: 3px; \ + } \ +"; + +int +main (int argc, + char **argv) +{ + ccss_grammar_t *grammar; + ccss_stylesheet_t *stylesheet; + GtkWidget *window; + GtkWidget *area; + + gtk_init (&argc, &argv); + + grammar = ccss_cairo_grammar_create (); + stylesheet = ccss_grammar_create_stylesheet_from_buffer (grammar, + _css, sizeof (_css), + NULL); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_default_size (GTK_WINDOW (window), 160, 90); + g_signal_connect (G_OBJECT (window), "delete-event", + G_CALLBACK (gtk_main_quit), NULL); + + area = gtk_drawing_area_new (); + gtk_container_add (GTK_CONTAINER (window), area); + g_signal_connect (G_OBJECT (area), "expose-event", + G_CALLBACK (expose_cb), stylesheet); + + gtk_widget_show_all (window); + gtk_main (); + + ccss_stylesheet_destroy (stylesheet); + ccss_grammar_destroy (grammar); + + return EXIT_SUCCESS; +} + |