summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Staudinger <robsta@gnome.org>2009-08-06 10:41:56 +0200
committerRobert Staudinger <robsta@gnome.org>2009-08-06 10:41:56 +0200
commit4c74a2025835dfd6b43dd0a94b01d5006637c883 (patch)
treec0864300f9e9f2326dd43447cadc302c4e6d4432
parent8ed88beda82880a2562f1eb0504faf41890223a7 (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.txt1
-rw-r--r--ccss/ccss-style.c46
-rw-r--r--ccss/ccss-style.h5
-rw-r--r--ccss/ccss.sym1
-rw-r--r--examples/Makefile.am3
-rw-r--r--examples/example-1.c7
-rw-r--r--examples/example-9.c82
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;
+}
+