summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2012-02-07 23:36:43 +0100
committerAlexander Larsson <alexl@redhat.com>2012-02-08 00:27:13 +0100
commit1ffc8ebb8ae55018e62ff00e78f3524166a6d0ed (patch)
tree867c96cc99f29b50d9348ccb4199692199191f44
parentc18d21f312a6e46a2c77188a96e5e8e8635c88e3 (diff)
downloadgtk+-1ffc8ebb8ae55018e62ff00e78f3524166a6d0ed.tar.gz
Initial version of using bitmaps for regions and styles
-rw-r--r--gtk/gtkstylecontext.c341
-rw-r--r--gtk/gtkstylecontextprivate.h17
-rw-r--r--gtk/gtkwidgetpath.c304
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;
}
/**