diff options
author | Alexander Larsson <alexl@redhat.com> | 2012-02-07 23:36:43 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2012-02-08 00:27:13 +0100 |
commit | 1ffc8ebb8ae55018e62ff00e78f3524166a6d0ed (patch) | |
tree | 867c96cc99f29b50d9348ccb4199692199191f44 | |
parent | c18d21f312a6e46a2c77188a96e5e8e8635c88e3 (diff) | |
download | gtk+-1ffc8ebb8ae55018e62ff00e78f3524166a6d0ed.tar.gz |
Initial version of using bitmaps for regions and styles
-rw-r--r-- | gtk/gtkstylecontext.c | 341 | ||||
-rw-r--r-- | gtk/gtkstylecontextprivate.h | 17 | ||||
-rw-r--r-- | gtk/gtkwidgetpath.c | 304 |
3 files changed, 292 insertions, 370 deletions
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index e497d1f249..b117d719bb 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -307,12 +307,6 @@ typedef struct PropertyValue PropertyValue; typedef struct AnimationInfo AnimationInfo; typedef struct StyleData StyleData; -struct GtkRegion -{ - GQuark class_quark; - GtkRegionFlags flags; -}; - struct GtkStyleProviderData { GtkStyleProvider *provider; @@ -329,8 +323,8 @@ struct PropertyValue struct GtkStyleInfo { - GArray *style_classes; - GArray *regions; + GtkBitmask *style_classes; + GtkBitmask *regions; GtkJunctionSides junction_sides; GtkStateFlags state_flags; }; @@ -477,8 +471,8 @@ style_info_new (void) GtkStyleInfo *info; info = g_slice_new0 (GtkStyleInfo); - info->style_classes = g_array_new (FALSE, FALSE, sizeof (GQuark)); - info->regions = g_array_new (FALSE, FALSE, sizeof (GtkRegion)); + info->style_classes = _gtk_bitmask_new (); + info->regions = _gtk_bitmask_new (); return info; } @@ -486,8 +480,8 @@ style_info_new (void) static void style_info_free (GtkStyleInfo *info) { - g_array_free (info->style_classes, TRUE); - g_array_free (info->regions, TRUE); + _gtk_bitmask_free (info->style_classes); + _gtk_bitmask_free (info->regions); g_slice_free (GtkStyleInfo, info); } @@ -497,13 +491,10 @@ style_info_copy (const GtkStyleInfo *info) GtkStyleInfo *copy; copy = style_info_new (); - g_array_insert_vals (copy->style_classes, 0, - info->style_classes->data, - info->style_classes->len); - - g_array_insert_vals (copy->regions, 0, - info->regions->data, - info->regions->len); + _gtk_bitmask_union (copy->style_classes, + info->style_classes); + _gtk_bitmask_union (copy->regions, + info->regions); copy->junction_sides = info->junction_sides; copy->state_flags = info->state_flags; @@ -515,25 +506,12 @@ static guint style_info_hash (gconstpointer elem) { const GtkStyleInfo *info; - guint i, hash = 0; + guint hash = 0; info = elem; - for (i = 0; i < info->style_classes->len; i++) - { - hash += g_array_index (info->style_classes, GQuark, i); - hash <<= 5; - } - - for (i = 0; i < info->regions->len; i++) - { - GtkRegion *region; - - region = &g_array_index (info->regions, GtkRegion, i); - hash += region->class_quark; - hash += region->flags; - hash <<= 5; - } + hash = _gtk_bitmask_hash (info->style_classes); + hash ^= _gtk_bitmask_hash (info->regions); return hash ^ info->state_flags; } @@ -553,20 +531,12 @@ style_info_equal (gconstpointer elem1, if (info1->junction_sides != info2->junction_sides) return FALSE; - if (info1->style_classes->len != info2->style_classes->len) - return FALSE; - - if (memcmp (info1->style_classes->data, - info2->style_classes->data, - info1->style_classes->len * sizeof (GQuark)) != 0) - return FALSE; - - if (info1->regions->len != info2->regions->len) + if (!_gtk_bitmask_equals (info1->style_classes, + info2->style_classes)) return FALSE; - if (memcmp (info1->regions->data, - info2->regions->data, - info1->regions->len * sizeof (GtkRegion)) != 0) + if (!_gtk_bitmask_equals (info1->regions, + info2->regions)) return FALSE; return TRUE; @@ -1034,7 +1004,7 @@ create_query_path (GtkStyleContext *context) GtkStyleContextPrivate *priv; GtkWidgetPath *path; GtkStyleInfo *info; - guint i, pos; + guint pos; priv = context->priv; path = gtk_widget_path_copy (priv->widget_path); @@ -1042,26 +1012,11 @@ create_query_path (GtkStyleContext *context) info = priv->info_stack->data; - /* Set widget regions */ - for (i = 0; i < info->regions->len; i++) - { - GtkRegion *region; - - region = &g_array_index (info->regions, GtkRegion, i); - gtk_widget_path_iter_add_region (path, pos, - g_quark_to_string (region->class_quark), - region->flags); - } + _gtk_widget_path_iter_add_regions (path, pos, + info->regions); /* Set widget classes */ - for (i = 0; i < info->style_classes->len; i++) - { - GQuark quark; - - quark = g_array_index (info->style_classes, GQuark, i); - gtk_widget_path_iter_add_class (path, pos, - g_quark_to_string (quark)); - } + _gtk_widget_path_iter_add_classes (path, pos, info->style_classes); return path; } @@ -1861,96 +1816,79 @@ gtk_style_context_restore (GtkStyleContext *context) priv->current_data = NULL; } -static gboolean -style_class_find (GArray *array, - GQuark class_quark, - guint *position) -{ - gint min, max, mid; - gboolean found = FALSE; - guint pos; - - if (position) - *position = 0; +static GHashTable *style_class_masks; +static GPtrArray *style_class_masks_reverse; +static guint style_class_masks_next; +static GHashTable *style_region_masks; +static GPtrArray *style_region_masks_reverse; +static guint style_region_masks_next; - if (!array || array->len == 0) - return FALSE; - - min = 0; - max = array->len - 1; +guint +_gtk_style_class_get_mask (const gchar *class_name) +{ + guint value; + gpointer ptr_value; - do + if (style_class_masks == NULL) { - GQuark item; - - mid = (min + max) / 2; - item = g_array_index (array, GQuark, mid); - - if (class_quark == item) - { - found = TRUE; - pos = mid; - } - else if (class_quark > item) - min = pos = mid + 1; - else - { - max = mid - 1; - pos = mid; - } + style_class_masks = g_hash_table_new (g_str_hash, g_str_equal); + style_class_masks_reverse = g_ptr_array_new (); } - while (!found && min <= max); - - if (position) - *position = pos; - return found; + if (g_hash_table_lookup_extended (style_class_masks, class_name, + NULL, &ptr_value)) + value = GPOINTER_TO_INT (ptr_value); + else + { + const char *str = g_intern_string (class_name); + value = style_class_masks_next++; + ptr_value = GINT_TO_POINTER (value); + g_hash_table_insert (style_class_masks, str, ptr_value); + g_ptr_array_add (style_class_masks_reverse, str); + } + return value; } -static gboolean -region_find (GArray *array, - GQuark class_quark, - guint *position) +const gchar * +_gtk_style_class_get_name_from_mask (guint mask) { - gint min, max, mid; - gboolean found = FALSE; - guint pos; - - if (position) - *position = 0; - - if (!array || array->len == 0) - return FALSE; + if (mask < style_class_masks_next) + return g_ptr_array_index (style_class_masks_reverse, mask); + return NULL; +} - min = 0; - max = array->len - 1; +guint +_gtk_style_region_get_mask (const gchar *region_name) +{ + guint value; + gpointer ptr_value; - do + if (style_region_masks == NULL) { - GtkRegion *region; - - mid = (min + max) / 2; - region = &g_array_index (array, GtkRegion, mid); - - if (region->class_quark == class_quark) - { - found = TRUE; - pos = mid; - } - else if (region->class_quark > class_quark) - min = pos = mid + 1; - else - { - max = mid - 1; - pos = mid; - } + style_region_masks = g_hash_table_new (g_str_hash, g_str_equal); + style_region_masks_reverse = g_ptr_array_new (); } - while (!found && min <= max); - if (position) - *position = pos; + if (g_hash_table_lookup_extended (style_region_masks, region_name, + NULL, &ptr_value)) + value = GPOINTER_TO_INT (ptr_value); + else + { + const char *str = g_intern_string (region_name); + value = style_region_masks_next++; + ptr_value = GINT_TO_POINTER (value); + g_hash_table_insert (style_region_masks, str, ptr_value); + g_ptr_array_add (style_region_masks_reverse, str); + } + return value; +} - return found; +const gchar * +_gtk_style_region_get_name_from_mask (guint mask) +{ + if (mask < style_region_masks_next) + return g_ptr_array_index (style_region_masks_reverse, mask); + return NULL; } /** @@ -1983,21 +1921,20 @@ gtk_style_context_add_class (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark class_quark; - guint position; + guint class_mask; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (class_name != NULL); priv = context->priv; - class_quark = g_quark_from_string (class_name); + class_mask = _gtk_style_class_get_mask (class_name); g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (!style_class_find (info->style_classes, class_quark, &position)) + if (!_gtk_bitmask_get (info->style_classes, class_mask)) { - g_array_insert_val (info->style_classes, position, class_quark); + _gtk_bitmask_set (info->style_classes, class_mask, TRUE); /* Unset current data, as it likely changed due to the class change */ priv->current_data = NULL; @@ -2019,25 +1956,21 @@ gtk_style_context_remove_class (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark class_quark; - guint position; + guint class_mask; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (class_name != NULL); - class_quark = g_quark_try_string (class_name); - - if (!class_quark) - return; + class_mask = _gtk_style_class_get_mask (class_name); priv = context->priv; g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (style_class_find (info->style_classes, class_quark, &position)) + if (_gtk_bitmask_get (info->style_classes, class_mask)) { - g_array_remove_index (info->style_classes, position); + _gtk_bitmask_set (info->style_classes, class_mask, FALSE); /* Unset current data, as it likely changed due to the class change */ priv->current_data = NULL; @@ -2062,25 +1995,19 @@ gtk_style_context_has_class (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark class_quark; + guint class_mask; g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE); g_return_val_if_fail (class_name != NULL, FALSE); - class_quark = g_quark_try_string (class_name); - - if (!class_quark) - return FALSE; + class_mask = _gtk_style_class_get_mask (class_name); priv = context->priv; g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (style_class_find (info->style_classes, class_quark, NULL)) - return TRUE; - - return FALSE; + return _gtk_bitmask_get (info->style_classes, class_mask); } /** @@ -2111,12 +2038,12 @@ gtk_style_context_list_classes (GtkStyleContext *context) g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - for (i = 0; i < info->style_classes->len; i++) + i = 0; + while (_gtk_bitmask_find_next_set (info->style_classes, &i)) { - GQuark quark; - - quark = g_array_index (info->style_classes, GQuark, i); - classes = g_list_prepend (classes, (gchar *) g_quark_to_string (quark)); + classes = g_list_prepend (classes, + (gchar *) _gtk_style_class_get_name_from_mask (i)); + i++; } return classes; @@ -2150,15 +2077,16 @@ gtk_style_context_list_regions (GtkStyleContext *context) g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - for (i = 0; i < info->regions->len; i++) + i = 0; + while (_gtk_bitmask_find_next_set (info->regions, &i)) { - GtkRegion *region; - const gchar *class_name; + guint region = i / GTK_REGION_FLAGS_NUM_BITS; + i = region * GTK_REGION_FLAGS_NUM_BITS; - region = &g_array_index (info->regions, GtkRegion, i); + classes = g_list_prepend (classes, + (gchar *)_gtk_style_region_get_name_from_mask (region)); - class_name = g_quark_to_string (region->class_quark); - classes = g_list_prepend (classes, (gchar *) class_name); + i += GTK_REGION_FLAGS_NUM_BITS; } return classes; @@ -2222,27 +2150,29 @@ gtk_style_context_add_region (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark region_quark; - guint position; + guint region; + guint i; + guint old_flags; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (region_name != NULL); g_return_if_fail (_gtk_style_context_check_region_name (region_name)); priv = context->priv; - region_quark = g_quark_from_string (region_name); g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (!region_find (info->regions, region_quark, &position)) - { - GtkRegion region; + region = _gtk_style_region_get_mask (region_name); + i = region * GTK_REGION_FLAGS_NUM_BITS; - region.class_quark = region_quark; - region.flags = flags; + old_flags = _gtk_bitmask_get_uint (info->regions, i); + if ((old_flags & GTK_REGION_ADDED) == 0) + { + /* Ensure *some* flag is always set so we know this is added */ + old_flags |= flags | GTK_REGION_ADDED; - g_array_insert_val (info->regions, position, region); + _gtk_bitmask_set_uint (info->regions, i, old_flags); /* Unset current data, as it likely changed due to the region change */ priv->current_data = NULL; @@ -2264,25 +2194,28 @@ gtk_style_context_remove_region (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark region_quark; - guint position; + guint region; + guint i, old_flags; g_return_if_fail (GTK_IS_STYLE_CONTEXT (context)); g_return_if_fail (region_name != NULL); - region_quark = g_quark_try_string (region_name); - - if (!region_quark) - return; - priv = context->priv; g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (region_find (info->regions, region_quark, &position)) + region = _gtk_style_region_get_mask (region_name); + i = region * GTK_REGION_FLAGS_NUM_BITS; + + if (info->regions == NULL) + return; + + old_flags = _gtk_bitmask_get_uint (info->regions, i); + if ((old_flags & GTK_REGION_ADDED) != 0) { - g_array_remove_index (info->regions, position); + old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED); + _gtk_bitmask_set_uint (info->regions, i, old_flags); /* Unset current data, as it likely changed due to the region change */ priv->current_data = NULL; @@ -2310,8 +2243,8 @@ gtk_style_context_has_region (GtkStyleContext *context, { GtkStyleContextPrivate *priv; GtkStyleInfo *info; - GQuark region_quark; - guint position; + guint region; + guint i, flags; g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE); g_return_val_if_fail (region_name != NULL, FALSE); @@ -2319,25 +2252,19 @@ gtk_style_context_has_region (GtkStyleContext *context, if (flags_return) *flags_return = 0; - region_quark = g_quark_try_string (region_name); - - if (!region_quark) - return FALSE; - priv = context->priv; g_assert (priv->info_stack != NULL); info = priv->info_stack->data; - if (region_find (info->regions, region_quark, &position)) + region = _gtk_style_region_get_mask (region_name); + i = region * GTK_REGION_FLAGS_NUM_BITS; + + flags = _gtk_bitmask_get_uint (info->regions, i); + if ((flags & GTK_REGION_ADDED) != 0) { if (flags_return) - { - GtkRegion *region; - - region = &g_array_index (info->regions, GtkRegion, position); - *flags_return = region->flags; - } + *flags_return = flags & GTK_REGION_FLAGS_MASK; return TRUE; } diff --git a/gtk/gtkstylecontextprivate.h b/gtk/gtkstylecontextprivate.h index 59a8a698ca..90fb62c4fa 100644 --- a/gtk/gtkstylecontextprivate.h +++ b/gtk/gtkstylecontextprivate.h @@ -22,6 +22,7 @@ #include "gtkstylecontext.h" #include "gtksymboliccolor.h" +#include "gtkbitmaskprivate.h" G_BEGIN_DECLS @@ -46,6 +47,22 @@ void _gtk_style_context_get_cursor_color (GtkStyleContext *c GdkRGBA *primary_color, GdkRGBA *secondary_color); +guint _gtk_style_class_get_mask (const gchar *class_name); +const gchar * _gtk_style_class_get_name_from_mask (guint mask); +guint _gtk_style_region_get_mask (const gchar *region_name); +const gchar * _gtk_style_region_get_name_from_mask (guint mask); + +void _gtk_widget_path_iter_add_classes (GtkWidgetPath *path, + gint pos, + GtkBitmask *classes); +void _gtk_widget_path_iter_add_regions (GtkWidgetPath *path, + gint pos, + GtkBitmask *regions); + +#define GTK_REGION_FLAGS_MASK ((1 << 6) - 1) +#define GTK_REGION_FLAGS_NUM_BITS 7 +#define GTK_REGION_ADDED (1 << 6) + G_END_DECLS #endif /* __GTK_STYLE_CONTEXT_PRIVATE_H__ */ diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c index 5720b38444..0d90a0c549 100644 --- a/gtk/gtkwidgetpath.c +++ b/gtk/gtkwidgetpath.c @@ -91,8 +91,8 @@ struct GtkPathElement { GType type; GQuark name; - GHashTable *regions; - GArray *classes; + GtkBitmask *regions; + GtkBitmask *classes; GtkWidgetPath *siblings; guint sibling_index; }; @@ -139,20 +139,14 @@ gtk_path_element_copy (GtkPathElement *dest, if (src->regions) { - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, src->regions); - dest->regions = g_hash_table_new (NULL, NULL); - - while (g_hash_table_iter_next (&iter, &key, &value)) - g_hash_table_insert (dest->regions, key, value); + dest->regions = _gtk_bitmask_new (); + _gtk_bitmask_union (dest->regions, src->regions); } if (src->classes) { - dest->classes = g_array_new (FALSE, FALSE, sizeof (GQuark)); - g_array_append_vals (dest->classes, src->classes->data, src->classes->len); + dest->classes = _gtk_bitmask_new (); + _gtk_bitmask_union (dest->classes, src->classes); } } @@ -236,10 +230,10 @@ gtk_widget_path_unref (GtkWidgetPath *path) elem = &g_array_index (path->elems, GtkPathElement, i); if (elem->regions) - g_hash_table_destroy (elem->regions); + _gtk_bitmask_free (elem->regions); if (elem->classes) - g_array_free (elem->classes, TRUE); + _gtk_bitmask_free (elem->classes); if (elem->siblings) gtk_widget_path_unref (elem->siblings); @@ -304,7 +298,8 @@ char * gtk_widget_path_to_string (const GtkWidgetPath *path) { GString *string; - guint i, j; + guint i, j, k; + guint pos; g_return_val_if_fail (path != NULL, NULL); @@ -336,22 +331,23 @@ gtk_widget_path_to_string (const GtkWidgetPath *path) if (elem->classes) { - for (j = 0; j < elem->classes->len; j++) - { + pos = 0; + while (_gtk_bitmask_find_next_set (elem->classes, &pos)) + { g_string_append_c (string, '.'); - g_string_append (string, g_quark_to_string (g_array_index (elem->classes, GQuark, j))); - } + g_string_append (string, + _gtk_style_class_get_name_from_mask (pos)); + pos++; + } } if (elem->regions) { - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, elem->regions); - while (g_hash_table_iter_next (&iter, &key, &value)) - { - GtkRegionFlags flags = GPOINTER_TO_UINT (value); + k = 0; + while (_gtk_bitmask_find_next_set (elem->regions, &k)) + { + guint region = k / GTK_REGION_FLAGS_NUM_BITS; + guint flags; static const char *flag_names[] = { "even", "odd", @@ -361,8 +357,12 @@ gtk_widget_path_to_string (const GtkWidgetPath *path) "sorted" }; + k = region * GTK_REGION_FLAGS_NUM_BITS; + + flags = _gtk_bitmask_get_uint (elem->regions, k); + g_string_append_c (string, ' '); - g_string_append (string, g_quark_to_string (GPOINTER_TO_UINT (key))); + g_string_append (string, _gtk_style_region_get_name_from_mask (region)); for (j = 0; j < G_N_ELEMENTS(flag_names); j++) { if (flags & (1 << j)) @@ -371,7 +371,9 @@ gtk_widget_path_to_string (const GtkWidgetPath *path) g_string_append (string, flag_names[j]); } } - } + + k += GTK_REGION_FLAGS_NUM_BITS; + } } } @@ -715,9 +717,6 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path, const gchar *name) { GtkPathElement *elem; - gboolean added = FALSE; - GQuark qname; - guint i; g_return_if_fail (path != NULL); g_return_if_fail (path->elems->len != 0); @@ -727,33 +726,33 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path, pos = path->elems->len - 1; elem = &g_array_index (path->elems, GtkPathElement, pos); - qname = g_quark_from_string (name); if (!elem->classes) - elem->classes = g_array_new (FALSE, FALSE, sizeof (GQuark)); + elem->classes = _gtk_bitmask_new (); - for (i = 0; i < elem->classes->len; i++) - { - GQuark quark; + _gtk_bitmask_set (elem->classes, _gtk_style_class_get_mask (name), TRUE); +} - quark = g_array_index (elem->classes, GQuark, i); +void +_gtk_widget_path_iter_add_classes (GtkWidgetPath *path, + gint pos, + GtkBitmask *classes) +{ + GtkPathElement *elem; - if (qname == quark) - { - /* Already there */ - added = TRUE; - break; - } - if (qname < quark) - { - g_array_insert_val (elem->classes, i, qname); - added = TRUE; - break; - } - } + g_return_if_fail (path != NULL); + g_return_if_fail (path->elems->len != 0); + g_return_if_fail (classes != NULL); + + if (pos < 0 || pos >= path->elems->len) + pos = path->elems->len - 1; + + elem = &g_array_index (path->elems, GtkPathElement, pos); - if (!added) - g_array_append_val (elem->classes, qname); + if (!elem->classes) + elem->classes = _gtk_bitmask_new (); + + _gtk_bitmask_union (elem->classes, classes); } /** @@ -773,8 +772,6 @@ gtk_widget_path_iter_remove_class (GtkWidgetPath *path, const gchar *name) { GtkPathElement *elem; - GQuark qname; - guint i; g_return_if_fail (path != NULL); g_return_if_fail (path->elems->len != 0); @@ -783,30 +780,12 @@ gtk_widget_path_iter_remove_class (GtkWidgetPath *path, if (pos < 0 || pos >= path->elems->len) pos = path->elems->len - 1; - qname = g_quark_try_string (name); - - if (qname == 0) - return; - elem = &g_array_index (path->elems, GtkPathElement, pos); if (!elem->classes) - return; - - for (i = 0; i < elem->classes->len; i++) - { - GQuark quark; + elem->classes = _gtk_bitmask_new (); - quark = g_array_index (elem->classes, GQuark, i); - - if (quark > qname) - break; - else if (quark == qname) - { - g_array_remove_index (elem->classes, i); - break; - } - } + _gtk_bitmask_set (elem->classes, _gtk_style_class_get_mask (name), FALSE); } /** @@ -836,8 +815,7 @@ gtk_widget_path_iter_clear_classes (GtkWidgetPath *path, if (!elem->classes) return; - if (elem->classes->len > 0) - g_array_remove_range (elem->classes, 0, elem->classes->len); + _gtk_bitmask_clear (elem->classes); } /** @@ -874,12 +852,11 @@ gtk_widget_path_iter_list_classes (const GtkWidgetPath *path, if (!elem->classes) return NULL; - for (i = 0; i < elem->classes->len; i++) + i = 0; + while (_gtk_bitmask_find_next_set (elem->classes, &i)) { - GQuark quark; - - quark = g_array_index (elem->classes, GQuark, i); - list = g_slist_prepend (list, (gchar *) g_quark_to_string (quark)); + list = g_slist_prepend (list, (gchar *) _gtk_style_class_get_name_from_mask (i)); + i++; } return g_slist_reverse (list); @@ -903,34 +880,8 @@ gtk_widget_path_iter_has_qclass (const GtkWidgetPath *path, gint pos, GQuark qname) { - GtkPathElement *elem; - guint i; - - g_return_val_if_fail (path != NULL, FALSE); - g_return_val_if_fail (path->elems->len != 0, FALSE); - g_return_val_if_fail (qname != 0, FALSE); - - if (pos < 0 || pos >= path->elems->len) - pos = path->elems->len - 1; - - elem = &g_array_index (path->elems, GtkPathElement, pos); - - if (!elem->classes) - return FALSE; - - for (i = 0; i < elem->classes->len; i++) - { - GQuark quark; - - quark = g_array_index (elem->classes, GQuark, i); - - if (quark == qname) - return TRUE; - else if (quark > qname) - break; - } - - return FALSE; + return gtk_widget_path_iter_has_class (path, pos, + g_quark_to_string (qname)); } /** @@ -951,7 +902,8 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path, gint pos, const gchar *name) { - GQuark qname; + GtkPathElement *elem; + guint mask; g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (path->elems->len != 0, FALSE); @@ -960,12 +912,14 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path, if (pos < 0 || pos >= path->elems->len) pos = path->elems->len - 1; - qname = g_quark_try_string (name); + elem = &g_array_index (path->elems, GtkPathElement, pos); - if (qname == 0) + if (!elem->classes) return FALSE; - return gtk_widget_path_iter_has_qclass (path, pos, qname); + mask = _gtk_style_class_get_mask (name); + + return _gtk_bitmask_get (elem->classes, mask); } /** @@ -991,7 +945,9 @@ gtk_widget_path_iter_add_region (GtkWidgetPath *path, GtkRegionFlags flags) { GtkPathElement *elem; - GQuark qname; + guint region; + guint i; + guint old_flags; g_return_if_fail (path != NULL); g_return_if_fail (path->elems->len != 0); @@ -1002,14 +958,40 @@ gtk_widget_path_iter_add_region (GtkWidgetPath *path, pos = path->elems->len - 1; elem = &g_array_index (path->elems, GtkPathElement, pos); - qname = g_quark_from_string (name); if (!elem->regions) - elem->regions = g_hash_table_new (NULL, NULL); + elem->regions = _gtk_bitmask_new (); + + region = _gtk_style_region_get_mask (name); + i = region * GTK_REGION_FLAGS_NUM_BITS; + + old_flags = _gtk_bitmask_get_uint (elem->regions, i); + old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED); + /* Ensure *some* flag is always set so we know this is added */ + old_flags |= flags | GTK_REGION_ADDED; + _gtk_bitmask_set_uint (elem->regions, i, old_flags); +} + +void +_gtk_widget_path_iter_add_regions (GtkWidgetPath *path, + gint pos, + GtkBitmask *regions) +{ + GtkPathElement *elem; + + g_return_if_fail (path != NULL); + g_return_if_fail (path->elems->len != 0); + g_return_if_fail (regions != NULL); + + if (pos < 0 || pos >= path->elems->len) + pos = path->elems->len - 1; + + elem = &g_array_index (path->elems, GtkPathElement, pos); + + if (!elem->regions) + elem->regions = _gtk_bitmask_new (); - g_hash_table_insert (elem->regions, - GUINT_TO_POINTER (qname), - GUINT_TO_POINTER (flags)); + _gtk_bitmask_union (elem->regions, regions); } /** @@ -1029,7 +1011,9 @@ gtk_widget_path_iter_remove_region (GtkWidgetPath *path, const gchar *name) { GtkPathElement *elem; - GQuark qname; + guint region; + guint i; + guint old_flags; g_return_if_fail (path != NULL); g_return_if_fail (path->elems->len != 0); @@ -1038,15 +1022,17 @@ gtk_widget_path_iter_remove_region (GtkWidgetPath *path, if (pos < 0 || pos >= path->elems->len) pos = path->elems->len - 1; - qname = g_quark_try_string (name); + elem = &g_array_index (path->elems, GtkPathElement, pos); - if (qname == 0) + if (elem->regions == NULL) return; - elem = &g_array_index (path->elems, GtkPathElement, pos); + region = _gtk_style_region_get_mask (name); + i = region * GTK_REGION_FLAGS_NUM_BITS; - if (elem->regions) - g_hash_table_remove (elem->regions, GUINT_TO_POINTER (qname)); + old_flags = _gtk_bitmask_get_uint (elem->regions, i); + old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED); + _gtk_bitmask_set_uint (elem->regions, i, old_flags); } /** @@ -1074,7 +1060,7 @@ gtk_widget_path_iter_clear_regions (GtkWidgetPath *path, elem = &g_array_index (path->elems, GtkPathElement, pos); if (elem->regions) - g_hash_table_remove_all (elem->regions); + _gtk_bitmask_clear (elem->regions); } /** @@ -1097,9 +1083,8 @@ gtk_widget_path_iter_list_regions (const GtkWidgetPath *path, gint pos) { GtkPathElement *elem; - GHashTableIter iter; GSList *list = NULL; - gpointer key; + guint i; g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (path->elems->len != 0, NULL); @@ -1112,14 +1097,16 @@ gtk_widget_path_iter_list_regions (const GtkWidgetPath *path, if (!elem->regions) return NULL; - g_hash_table_iter_init (&iter, elem->regions); - - while (g_hash_table_iter_next (&iter, &key, NULL)) + i = 0; + while (_gtk_bitmask_find_next_set (elem->regions, &i)) { - GQuark qname; + guint region = i / GTK_REGION_FLAGS_NUM_BITS; + i = region * GTK_REGION_FLAGS_NUM_BITS; - qname = GPOINTER_TO_UINT (key); - list = g_slist_prepend (list, (gchar *) g_quark_to_string (qname)); + list = g_slist_prepend (list, + (gchar *) _gtk_style_region_get_name_from_mask (region)); + + i += GTK_REGION_FLAGS_NUM_BITS; } return list; @@ -1145,30 +1132,8 @@ gtk_widget_path_iter_has_qregion (const GtkWidgetPath *path, GQuark qname, GtkRegionFlags *flags) { - GtkPathElement *elem; - gpointer value; - - g_return_val_if_fail (path != NULL, FALSE); - g_return_val_if_fail (path->elems->len != 0, FALSE); - g_return_val_if_fail (qname != 0, FALSE); - - if (pos < 0 || pos >= path->elems->len) - pos = path->elems->len - 1; - - elem = &g_array_index (path->elems, GtkPathElement, pos); - - if (!elem->regions) - return FALSE; - - if (!g_hash_table_lookup_extended (elem->regions, - GUINT_TO_POINTER (qname), - NULL, &value)) - return FALSE; - - if (flags) - *flags = GPOINTER_TO_UINT (value); - - return TRUE; + return gtk_widget_path_iter_has_region (path, pos, + g_quark_to_string (qname), flags); } /** @@ -1189,9 +1154,11 @@ gboolean gtk_widget_path_iter_has_region (const GtkWidgetPath *path, gint pos, const gchar *name, - GtkRegionFlags *flags) + GtkRegionFlags *flags_return) { - GQuark qname; + GtkPathElement *elem; + guint region; + guint i, flags; g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (path->elems->len != 0, FALSE); @@ -1200,12 +1167,23 @@ gtk_widget_path_iter_has_region (const GtkWidgetPath *path, if (pos < 0 || pos >= path->elems->len) pos = path->elems->len - 1; - qname = g_quark_try_string (name); + elem = &g_array_index (path->elems, GtkPathElement, pos); - if (qname == 0) + if (!elem->regions) return FALSE; - return gtk_widget_path_iter_has_qregion (path, pos, qname, flags); + region = _gtk_style_region_get_mask (name); + i = region * GTK_REGION_FLAGS_NUM_BITS; + + flags = _gtk_bitmask_get_uint (elem->regions, i); + if ((flags & GTK_REGION_ADDED) != 0) + { + if (flags_return) + *flags_return = flags & GTK_REGION_FLAGS_MASK; + return TRUE; + } + + return FALSE; } /** |