[gtk+] stylecontext: Split out functionality into custom object
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] stylecontext: Split out functionality into custom object
- Date: Tue, 21 Oct 2014 01:03:49 +0000 (UTC)
commit 5c2c65912200789c3edd9c574d619b65e398ccb2
Author: Benjamin Otte <otte redhat com>
Date: Sat Oct 18 05:45:21 2014 +0200
stylecontext: Split out functionality into custom object
GtkCssNodeDeclaration is a new struct with copy-on-write semantics.
It encapsulated the properties used to define a node in the CSS tree.
The idea is to use it in various places for caching, in particular as
key in hash tables.
gtk/Makefile.am | 2 +
gtk/gtkcssnodedeclaration.c | 528 ++++++++++++++++++++++++++++++++++++
gtk/gtkcssnodedeclarationprivate.h | 67 +++++
gtk/gtkstylecontext.c | 357 ++++---------------------
4 files changed, 648 insertions(+), 306 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index ee32932..41943da 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -558,6 +558,7 @@ gtk_private_h_sources = \
gtkcsskeyframesprivate.h \
gtkcsslookupprivate.h \
gtkcssmatcherprivate.h \
+ gtkcssnodedeclarationprivate.h \
gtkcssnumbervalueprivate.h \
gtkcssparserprivate.h \
gtkcsspositionvalueprivate.h \
@@ -881,6 +882,7 @@ gtk_base_c_sources = \
gtkcsskeyframes.c \
gtkcsslookup.c \
gtkcssmatcher.c \
+ gtkcssnodedeclaration.c \
gtkcssnumbervalue.c \
gtkcssparser.c \
gtkcsspositionvalue.c \
diff --git a/gtk/gtkcssnodedeclaration.c b/gtk/gtkcssnodedeclaration.c
new file mode 100644
index 0000000..b5874ff
--- /dev/null
+++ b/gtk/gtkcssnodedeclaration.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright © 2014 Benjamin Otte <otte gnome org>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkcssnodedeclarationprivate.h"
+
+#include <string.h>
+
+typedef struct _GtkRegion GtkRegion;
+
+struct _GtkRegion
+{
+ GQuark class_quark;
+ GtkRegionFlags flags;
+};
+
+struct _GtkCssNodeDeclaration {
+ guint refcount;
+ GtkJunctionSides junction_sides;
+ GtkStateFlags state;
+ guint n_classes;
+ guint n_regions;
+ /* GQuark classes[n_classes]; */
+ /* GtkRegion region[n_regions]; */
+};
+
+static inline GQuark *
+get_classes (const GtkCssNodeDeclaration *decl)
+{
+ return (GQuark *) (decl + 1);
+}
+
+static inline GtkRegion *
+get_regions (const GtkCssNodeDeclaration *decl)
+{
+ return (GtkRegion *) (get_classes (decl) + decl->n_classes);
+}
+
+static inline gsize
+sizeof_node (guint n_classes,
+ guint n_regions)
+{
+ return sizeof (GtkCssNodeDeclaration)
+ + sizeof (GQuark) * n_classes
+ + sizeof (GtkRegion) * n_regions;
+}
+
+static inline gsize
+sizeof_this_node (GtkCssNodeDeclaration *decl)
+{
+ return sizeof_node (decl->n_classes, decl->n_regions);
+}
+
+static void
+gtk_css_node_declaration_make_writable (GtkCssNodeDeclaration **decl)
+{
+ if ((*decl)->refcount == 1)
+ return;
+
+ (*decl)->refcount--;
+
+ *decl = g_memdup (*decl, sizeof_this_node (*decl));
+ (*decl)->refcount = 1;
+}
+
+static void
+gtk_css_node_declaration_make_writable_resize (GtkCssNodeDeclaration **decl,
+ gsize offset,
+ gsize bytes_added,
+ gsize bytes_removed)
+{
+ gsize old_size = sizeof_this_node (*decl);
+ gsize new_size = old_size + bytes_added - bytes_removed;
+
+ if ((*decl)->refcount == 1)
+ {
+ if (bytes_removed > 0 && old_size - offset - bytes_removed > 0)
+ memmove (((char *) *decl) + offset + bytes_removed, ((char *) *decl) + offset, old_size - offset -
bytes_removed);
+ *decl = g_realloc (*decl, new_size);
+ if (bytes_added > 0 && old_size - offset > 0)
+ memmove (((char *) *decl) + offset + bytes_added, ((char *) *decl) + offset, old_size - offset);
+ }
+ else
+ {
+ GtkCssNodeDeclaration *old = *decl;
+
+ old->refcount--;
+
+ *decl = g_malloc (new_size);
+ memcpy (*decl, old, offset);
+ if (old_size - offset - bytes_removed > 0)
+ memcpy (((char *) *decl) + offset + bytes_added, ((char *) old) + offset + bytes_removed, old_size -
offset - bytes_removed);
+ (*decl)->refcount = 1;
+ }
+}
+
+GtkCssNodeDeclaration *
+gtk_css_node_declaration_new (void)
+{
+ static GtkCssNodeDeclaration empty = {
+ 1, /* need to own a ref ourselves so the copy-on-write path kicks in when people change things */
+ 0,
+ 0,
+ 0,
+ 0
+ };
+
+ return gtk_css_node_declaration_ref (&empty);
+}
+
+GtkCssNodeDeclaration *
+gtk_css_node_declaration_ref (GtkCssNodeDeclaration *decl)
+{
+ decl->refcount++;
+
+ return decl;
+}
+
+void
+gtk_css_node_declaration_unref (GtkCssNodeDeclaration *decl)
+{
+ decl->refcount--;
+ if (decl->refcount > 0)
+ return;
+
+ g_free (decl);
+}
+
+gboolean
+gtk_css_node_declaration_set_junction_sides (GtkCssNodeDeclaration **decl,
+ GtkJunctionSides junction_sides)
+{
+ if ((*decl)->junction_sides == junction_sides)
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable (decl);
+ (*decl)->junction_sides = junction_sides;
+
+ return TRUE;
+}
+
+GtkJunctionSides
+gtk_css_node_declaration_get_junction_sides (const GtkCssNodeDeclaration *decl)
+{
+ return decl->junction_sides;
+}
+
+gboolean
+gtk_css_node_declaration_set_state (GtkCssNodeDeclaration **decl,
+ GtkStateFlags state)
+{
+ if ((*decl)->state == state)
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable (decl);
+ (*decl)->state = state;
+
+ return TRUE;
+}
+
+GtkStateFlags
+gtk_css_node_declaration_get_state (const GtkCssNodeDeclaration *decl)
+{
+ return decl->state;
+}
+
+static gboolean
+find_class (const GtkCssNodeDeclaration *decl,
+ GQuark class_quark,
+ guint *position)
+{
+ gint min, max, mid;
+ gboolean found = FALSE;
+ GQuark *classes;
+ guint pos;
+
+ if (position)
+ *position = 0;
+
+ if (decl->n_classes == 0)
+ return FALSE;
+
+ min = 0;
+ max = decl->n_classes - 1;
+ classes = get_classes (decl);
+
+ do
+ {
+ GQuark item;
+
+ mid = (min + max) / 2;
+ item = classes[mid];
+
+ if (class_quark == item)
+ {
+ found = TRUE;
+ pos = mid;
+ break;
+ }
+ else if (class_quark > item)
+ min = pos = mid + 1;
+ else
+ {
+ max = mid - 1;
+ pos = mid;
+ }
+ }
+ while (min <= max);
+
+ if (position)
+ *position = pos;
+
+ return found;
+}
+
+gboolean
+gtk_css_node_declaration_add_class (GtkCssNodeDeclaration **decl,
+ GQuark class_quark)
+{
+ guint pos;
+
+ if (find_class (*decl, class_quark, &pos))
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable_resize (decl,
+ (char *) &get_classes (*decl)[pos] - (char *) *decl,
+ sizeof (GQuark),
+ 0);
+ (*decl)->n_classes++;
+ get_classes(*decl)[pos] = class_quark;
+
+ return TRUE;
+}
+
+gboolean
+gtk_css_node_declaration_remove_class (GtkCssNodeDeclaration **decl,
+ GQuark class_quark)
+{
+ guint pos;
+
+ if (!find_class (*decl, class_quark, &pos))
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable_resize (decl,
+ (char *) &get_classes (*decl)[pos] - (char *) *decl,
+ 0,
+ sizeof (GQuark));
+ (*decl)->n_classes--;
+
+ return TRUE;
+}
+
+gboolean
+gtk_css_node_declaration_has_class (const GtkCssNodeDeclaration *decl,
+ GQuark class_quark)
+{
+ return find_class (decl, class_quark, NULL);
+}
+
+GList *
+gtk_css_node_declaration_list_classes (const GtkCssNodeDeclaration *decl)
+{
+ GQuark *classes;
+ GList *result;
+ guint i;
+
+ classes = get_classes (decl);
+ result = NULL;
+
+ for (i = 0; i < decl->n_classes; i++)
+ {
+ result = g_list_prepend (result, GUINT_TO_POINTER (classes[i]));
+ }
+
+ return result;
+}
+
+static gboolean
+find_region (const GtkCssNodeDeclaration *decl,
+ GQuark region_quark,
+ guint *position)
+{
+ gint min, max, mid;
+ gboolean found = FALSE;
+ GtkRegion *regions;
+ guint pos;
+
+ if (position)
+ *position = 0;
+
+ if (decl->n_regions == 0)
+ return FALSE;
+
+ min = 0;
+ max = decl->n_regions - 1;
+ regions = get_regions (decl);
+
+ do
+ {
+ GQuark item;
+
+ mid = (min + max) / 2;
+ item = regions[mid].class_quark;
+
+ if (region_quark == item)
+ {
+ found = TRUE;
+ pos = mid;
+ break;
+ }
+ else if (region_quark > item)
+ min = pos = mid + 1;
+ else
+ {
+ max = mid - 1;
+ pos = mid;
+ }
+ }
+ while (min <= max);
+
+ if (position)
+ *position = pos;
+
+ return found;
+}
+
+gboolean
+gtk_css_node_declaration_add_region (GtkCssNodeDeclaration **decl,
+ GQuark region_quark,
+ GtkRegionFlags flags)
+{
+ GtkRegion *regions;
+ guint pos;
+
+ if (find_region (*decl, region_quark, &pos))
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable_resize (decl,
+ (char *) &get_regions (*decl)[pos] - (char *) *decl,
+ sizeof (GtkRegion),
+ 0);
+ (*decl)->n_regions++;
+ regions = get_regions(*decl);
+ regions[pos].class_quark = region_quark;
+ regions[pos].flags = flags;
+
+ return TRUE;
+}
+
+gboolean
+gtk_css_node_declaration_remove_region (GtkCssNodeDeclaration **decl,
+ GQuark region_quark)
+{
+ guint pos;
+
+ if (!find_region (*decl, region_quark, &pos))
+ return FALSE;
+
+ gtk_css_node_declaration_make_writable_resize (decl,
+ (char *) &get_regions (*decl)[pos] - (char *) *decl,
+ 0,
+ sizeof (GtkRegion));
+ (*decl)->n_regions--;
+
+ return TRUE;
+}
+
+gboolean
+gtk_css_node_declaration_has_region (const GtkCssNodeDeclaration *decl,
+ GQuark region_quark,
+ GtkRegionFlags *flags_return)
+{
+ guint pos;
+
+ if (!find_region (decl, region_quark, &pos))
+ {
+ if (flags_return)
+ *flags_return = 0;
+ return FALSE;
+ }
+
+ if (flags_return)
+ *flags_return = get_regions (decl)[pos].flags;
+
+ return TRUE;
+}
+
+GList *
+gtk_css_node_declaration_list_regions (const GtkCssNodeDeclaration *decl)
+{
+ GtkRegion *regions;
+ GList *result;
+ guint i;
+
+ regions = get_regions (decl);
+ result = NULL;
+
+ for (i = 0; i < decl->n_regions; i++)
+ {
+ result = g_list_prepend (result, GUINT_TO_POINTER (regions[i].class_quark));
+ }
+
+ return result;
+}
+
+guint
+gtk_css_node_declaration_hash (gconstpointer elem)
+{
+ const GtkCssNodeDeclaration *decl = elem;
+ GQuark *classes;
+ GtkRegion *regions;
+ guint hash, i;
+
+ hash = 0;
+
+ classes = get_classes (decl);
+ for (i = 0; i < decl->n_classes; i++)
+ {
+ hash <<= 5;
+ hash += classes[i];
+ }
+
+ regions = get_regions (decl);
+ for (i = 0; i < decl->n_regions; i++)
+ {
+ hash <<= 5;
+ hash += regions[i].class_quark;
+ hash += regions[i].flags;
+ }
+
+ hash ^= ((guint) decl->junction_sides) << (sizeof (guint) * 8 - 5);
+ hash ^= decl->state;
+
+ return hash;
+}
+
+gboolean
+gtk_css_node_declaration_equal (gconstpointer elem1,
+ gconstpointer elem2)
+{
+ const GtkCssNodeDeclaration *decl1 = elem1;
+ const GtkCssNodeDeclaration *decl2 = elem2;
+ GQuark *classes1, *classes2;
+ GtkRegion *regions1, *regions2;
+ guint i;
+
+ if (decl1 == decl2)
+ return TRUE;
+
+ if (decl1->state != decl2->state)
+ return FALSE;
+
+ if (decl1->n_classes != decl2->n_classes)
+ return FALSE;
+
+ classes1 = get_classes (decl1);
+ classes2 = get_classes (decl2);
+ for (i = 0; i < decl1->n_classes; i++)
+ {
+ if (classes1[i] != classes2[i])
+ return FALSE;
+ }
+
+ if (decl1->n_regions != decl2->n_regions)
+ return FALSE;
+
+ regions1 = get_regions (decl1);
+ regions2 = get_regions (decl2);
+ for (i = 0; i < decl1->n_regions; i++)
+ {
+ if (regions1[i].class_quark != regions2[i].class_quark ||
+ regions1[i].flags != regions2[i].flags)
+ return FALSE;
+ }
+
+ if (decl1->junction_sides != decl2->junction_sides)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+gtk_css_node_declaration_add_to_widget_path (const GtkCssNodeDeclaration *decl,
+ GtkWidgetPath *path,
+ guint pos)
+{
+ GQuark *classes;
+ GtkRegion *regions;
+ guint i;
+
+ /* Set widget regions */
+ regions = get_regions (decl);
+ for (i = 0; i < decl->n_regions; i++)
+ {
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ gtk_widget_path_iter_add_region (path, pos,
+ g_quark_to_string (regions[i].class_quark),
+ regions[i].flags);
+G_GNUC_END_IGNORE_DEPRECATIONS
+ }
+
+ /* Set widget classes */
+ classes = get_classes (decl);
+ for (i = 0; i < decl->n_classes; i++)
+ {
+ gtk_widget_path_iter_add_class (path, pos,
+ g_quark_to_string (classes[i]));
+ }
+
+ /* Set widget state */
+ gtk_widget_path_iter_set_state (path, pos, decl->state);
+}
+
diff --git a/gtk/gtkcssnodedeclarationprivate.h b/gtk/gtkcssnodedeclarationprivate.h
new file mode 100644
index 0000000..767b6ec
--- /dev/null
+++ b/gtk/gtkcssnodedeclarationprivate.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright © 2014 Benjamin Otte <otte gnome org>
+ *
+ * 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.1 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_CSS_NODE_DECLARATION_PRIVATE_H__
+#define __GTK_CSS_NODE_DECLARATION_PRIVATE_H__
+
+#include "gtkenums.h"
+#include "gtkwidgetpath.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GtkCssNodeDeclaration GtkCssNodeDeclaration;
+
+
+GtkCssNodeDeclaration * gtk_css_node_declaration_new (void);
+GtkCssNodeDeclaration * gtk_css_node_declaration_ref (GtkCssNodeDeclaration
*decl);
+void gtk_css_node_declaration_unref (GtkCssNodeDeclaration
*decl);
+
+gboolean gtk_css_node_declaration_set_junction_sides (GtkCssNodeDeclaration **decl,
+ GtkJunctionSides
junction_sides);
+GtkJunctionSides gtk_css_node_declaration_get_junction_sides (const GtkCssNodeDeclaration
*decl);
+gboolean gtk_css_node_declaration_set_state (GtkCssNodeDeclaration **decl,
+ GtkStateFlags
flags);
+GtkStateFlags gtk_css_node_declaration_get_state (const GtkCssNodeDeclaration
*decl);
+
+gboolean gtk_css_node_declaration_add_class (GtkCssNodeDeclaration **decl,
+ GQuark
class_quark);
+gboolean gtk_css_node_declaration_remove_class (GtkCssNodeDeclaration **decl,
+ GQuark
class_quark);
+gboolean gtk_css_node_declaration_has_class (const GtkCssNodeDeclaration *decl,
+ GQuark
class_quark);
+GList * gtk_css_node_declaration_list_classes (const GtkCssNodeDeclaration
*decl);
+
+gboolean gtk_css_node_declaration_add_region (GtkCssNodeDeclaration **decl,
+ GQuark
region_quark,
+ GtkRegionFlags
flags);
+gboolean gtk_css_node_declaration_remove_region (GtkCssNodeDeclaration **decl,
+ GQuark
region_quark);
+gboolean gtk_css_node_declaration_has_region (const GtkCssNodeDeclaration *decl,
+ GQuark
region_quark,
+ GtkRegionFlags
*flags_return);
+GList * gtk_css_node_declaration_list_regions (const GtkCssNodeDeclaration
*decl);
+
+guint gtk_css_node_declaration_hash (gconstpointer
elem);
+gboolean gtk_css_node_declaration_equal (gconstpointer
elem1,
+ gconstpointer
elem2);
+
+void gtk_css_node_declaration_add_to_widget_path (const GtkCssNodeDeclaration *decl,
+ GtkWidgetPath *path,
+ guint pos);
+G_END_DECLS
+
+#endif /* __GTK_CSS_NODE_DECLARATION_PRIVATE_H__ */
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 97785f3..8ef33af 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -28,6 +28,7 @@
#include "gtkcsscornervalueprivate.h"
#include "gtkcssenumvalueprivate.h"
#include "gtkcssimagevalueprivate.h"
+#include "gtkcssnodedeclarationprivate.h"
#include "gtkcssnumbervalueprivate.h"
#include "gtkcssrgbavalueprivate.h"
#include "gtkcssshadowsvalueprivate.h"
@@ -129,15 +130,8 @@
#define GTK_STYLE_CONTEXT_CACHED_CHANGE (GTK_CSS_CHANGE_STATE)
typedef struct GtkStyleInfo GtkStyleInfo;
-typedef struct GtkRegion GtkRegion;
typedef struct PropertyValue PropertyValue;
-struct GtkRegion
-{
- GQuark class_quark;
- GtkRegionFlags flags;
-};
-
struct PropertyValue
{
GType widget_type;
@@ -147,10 +141,7 @@ struct PropertyValue
struct GtkStyleInfo
{
- GArray *style_classes;
- GArray *regions;
- GtkJunctionSides junction_sides;
- GtkStateFlags state_flags;
+ GtkCssNodeDeclaration *decl;
GtkCssComputedValues *values;
};
@@ -306,8 +297,7 @@ 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->decl = gtk_css_node_declaration_new ();
return info;
}
@@ -333,8 +323,7 @@ style_info_free (GtkStyleInfo *info)
{
if (info->values)
g_object_unref (info->values);
- g_array_free (info->style_classes, TRUE);
- g_array_free (info->regions, TRUE);
+ gtk_css_node_declaration_unref (info->decl);
g_slice_free (GtkStyleInfo, info);
}
@@ -356,16 +345,7 @@ style_info_copy (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);
-
- copy->junction_sides = info->junction_sides;
- copy->state_flags = info->state_flags;
+ copy->decl = gtk_css_node_declaration_ref (info->decl);
style_info_set_values (copy, info->values);
return copy;
@@ -374,28 +354,9 @@ style_info_copy (GtkStyleInfo *info)
static guint
style_info_hash (gconstpointer elem)
{
- const GtkStyleInfo *info;
- guint i, hash = 0;
-
- info = elem;
-
- for (i = 0; i < info->style_classes->len; i++)
- {
- hash += g_array_index (info->style_classes, GQuark, i);
- hash <<= 5;
- }
+ const GtkStyleInfo *info = elem;
- 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;
- }
-
- return hash ^ info->state_flags;
+ return gtk_css_node_declaration_hash (info->decl);
}
static gboolean
@@ -407,29 +368,7 @@ style_info_equal (gconstpointer elem1,
info1 = elem1;
info2 = elem2;
- if (info1->state_flags != info2->state_flags)
- return FALSE;
-
- 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)
- return FALSE;
-
- if (memcmp (info1->regions->data,
- info2->regions->data,
- info1->regions->len * sizeof (GtkRegion)) != 0)
- return FALSE;
-
- return TRUE;
+ return gtk_css_node_declaration_equal (info1->decl, info2->decl);
}
static void
@@ -490,7 +429,7 @@ gtk_style_context_init (GtkStyleContext *style_context)
/* Create default info store */
priv->info = style_info_new ();
- priv->info->state_flags = GTK_STATE_FLAG_DIR_LTR;
+ gtk_css_node_declaration_set_state (&priv->info->decl, GTK_STATE_FLAG_DIR_LTR);
priv->property_cache = g_array_new (FALSE, FALSE, sizeof (PropertyValue));
@@ -717,40 +656,6 @@ gtk_style_context_is_saved (GtkStyleContext *context)
return context->priv->saved_nodes != NULL;
}
-static void
-style_info_add_to_widget_path (GtkStyleInfo *info,
- GtkWidgetPath *path,
- guint pos)
-{
- guint i;
-
- /* Set widget regions */
- for (i = 0; i < info->regions->len; i++)
- {
- GtkRegion *region;
-
- region = &g_array_index (info->regions, GtkRegion, i);
-G_GNUC_BEGIN_IGNORE_DEPRECATIONS
- gtk_widget_path_iter_add_region (path, pos,
- g_quark_to_string (region->class_quark),
- region->flags);
-G_GNUC_END_IGNORE_DEPRECATIONS
- }
-
- /* 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));
- }
-
- /* Set widget state */
- gtk_widget_path_iter_set_state (path, pos, info->state_flags);
-}
-
static GtkWidgetPath *
create_query_path (GtkStyleContext *context,
GtkStyleInfo *info)
@@ -767,15 +672,15 @@ create_query_path (GtkStyleContext *context,
GtkStyleInfo *root = g_slist_last (context->priv->saved_nodes)->data;
if (length > 0)
- style_info_add_to_widget_path (root, path, length - 1);
+ gtk_css_node_declaration_add_to_widget_path (root->decl, path, length - 1);
- gtk_widget_path_append_type (path, length > 0 ?gtk_widget_path_iter_get_object_type (path, length - 1)
: G_TYPE_NONE);
- style_info_add_to_widget_path (info, path, length);
+ gtk_widget_path_append_type (path, length > 0 ? gtk_widget_path_iter_get_object_type (path, length -
1) : G_TYPE_NONE);
+ gtk_css_node_declaration_add_to_widget_path (info->decl, path, length);
}
else
{
if (length > 0)
- style_info_add_to_widget_path (info, path, length - 1);
+ gtk_css_node_declaration_add_to_widget_path (info->decl, path, length - 1);
}
return path;
@@ -856,7 +761,7 @@ style_values_lookup_for_state (GtkStyleContext *context,
{
GtkCssComputedValues *values;
- if (context->priv->info->state_flags == state)
+ if (gtk_css_node_declaration_get_state (context->priv->info->decl) == state)
return style_values_lookup (context);
gtk_style_context_save (context);
@@ -1296,11 +1201,10 @@ gtk_style_context_set_state (GtkStyleContext *context,
GtkStateFlags old_flags;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- old_flags = context->priv->info->state_flags;
- if (old_flags == flags)
- return;
+ old_flags = gtk_css_node_declaration_get_state (context->priv->info->decl);
- context->priv->info->state_flags = flags;
+ if (!gtk_css_node_declaration_set_state (&context->priv->info->decl, flags))
+ return;
if (((old_flags ^ flags) & (GTK_STATE_FLAG_DIR_LTR | GTK_STATE_FLAG_DIR_RTL)) &&
!gtk_style_context_is_saved (context))
@@ -1324,7 +1228,7 @@ gtk_style_context_get_state (GtkStyleContext *context)
{
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
- return context->priv->info->state_flags;
+ return gtk_css_node_declaration_get_state (context->priv->info->decl);
}
/**
@@ -1583,98 +1487,6 @@ gtk_style_context_restore (GtkStyleContext *context)
gtk_style_context_pop_style_info (context);
}
-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;
-
- if (!array || array->len == 0)
- return FALSE;
-
- min = 0;
- max = array->len - 1;
-
- do
- {
- 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;
- }
- }
- while (!found && min <= max);
-
- if (position)
- *position = pos;
-
- return found;
-}
-
-static gboolean
-region_find (GArray *array,
- GQuark class_quark,
- guint *position)
-{
- gint min, max, mid;
- gboolean found = FALSE;
- guint pos;
-
- if (position)
- *position = 0;
-
- if (!array || array->len == 0)
- return FALSE;
-
- min = 0;
- max = array->len - 1;
-
- do
- {
- 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;
- }
- }
- while (!found && min <= max);
-
- if (position)
- *position = pos;
-
- return found;
-}
-
/**
* gtk_style_context_add_class:
* @context: a #GtkStyleContext
@@ -1704,9 +1516,7 @@ gtk_style_context_add_class (GtkStyleContext *context,
const gchar *class_name)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark class_quark;
- guint position;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (class_name != NULL);
@@ -1714,14 +1524,8 @@ gtk_style_context_add_class (GtkStyleContext *context,
priv = context->priv;
class_quark = g_quark_from_string (class_name);
- info = priv->info;
-
- if (!style_class_find (info->style_classes, class_quark, &position))
- {
- g_array_insert_val (info->style_classes, position, class_quark);
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
- }
+ if (gtk_css_node_declaration_add_class (&priv->info->decl, class_quark))
+ gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
}
/**
@@ -1738,9 +1542,7 @@ gtk_style_context_remove_class (GtkStyleContext *context,
const gchar *class_name)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark class_quark;
- guint position;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (class_name != NULL);
@@ -1752,14 +1554,8 @@ gtk_style_context_remove_class (GtkStyleContext *context,
priv = context->priv;
- info = priv->info;
-
- if (style_class_find (info->style_classes, class_quark, &position))
- {
- g_array_remove_index (info->style_classes, position);
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
- }
+ if (gtk_css_node_declaration_remove_class (&priv->info->decl, class_quark))
+ gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_CLASS);
}
/**
@@ -1779,7 +1575,6 @@ gtk_style_context_has_class (GtkStyleContext *context,
const gchar *class_name)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark class_quark;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
@@ -1792,12 +1587,18 @@ gtk_style_context_has_class (GtkStyleContext *context,
priv = context->priv;
- info = priv->info;
+ return gtk_css_node_declaration_has_class (priv->info->decl, class_quark);
+}
- if (style_class_find (info->style_classes, class_quark, NULL))
- return TRUE;
+static void
+quarks_to_strings (GList *list)
+{
+ GList *l;
- return FALSE;
+ for (l = list; l; l = l->next)
+ {
+ l->data = (char *) g_quark_to_string (GPOINTER_TO_UINT (l->data));
+ }
}
/**
@@ -1817,23 +1618,14 @@ GList *
gtk_style_context_list_classes (GtkStyleContext *context)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
- GList *classes = NULL;
- guint i;
+ GList *classes;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
priv = context->priv;
-
- info = priv->info;
-
- for (i = 0; i < info->style_classes->len; i++)
- {
- GQuark quark;
-
- quark = g_array_index (info->style_classes, GQuark, i);
- classes = g_list_prepend (classes, (gchar *) g_quark_to_string (quark));
- }
+
+ classes = gtk_css_node_declaration_list_classes (priv->info->decl);
+ quarks_to_strings (classes);
return classes;
}
@@ -1857,28 +1649,16 @@ GList *
gtk_style_context_list_regions (GtkStyleContext *context)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
- GList *classes = NULL;
- guint i;
+ GList *regions;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
priv = context->priv;
- info = priv->info;
-
- for (i = 0; i < info->regions->len; i++)
- {
- GtkRegion *region;
- const gchar *class_name;
-
- region = &g_array_index (info->regions, GtkRegion, i);
+ regions = gtk_css_node_declaration_list_regions (priv->info->decl);
+ quarks_to_strings (regions);
- class_name = g_quark_to_string (region->class_quark);
- classes = g_list_prepend (classes, (gchar *) class_name);
- }
-
- return classes;
+ return regions;
}
gboolean
@@ -1940,9 +1720,7 @@ gtk_style_context_add_region (GtkStyleContext *context,
GtkRegionFlags flags)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark region_quark;
- guint position;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (region_name != NULL);
@@ -1951,19 +1729,8 @@ gtk_style_context_add_region (GtkStyleContext *context,
priv = context->priv;
region_quark = g_quark_from_string (region_name);
- info = priv->info;
-
- if (!region_find (info->regions, region_quark, &position))
- {
- GtkRegion region;
-
- region.class_quark = region_quark;
- region.flags = flags;
-
- g_array_insert_val (info->regions, position, region);
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
- }
+ if (gtk_css_node_declaration_add_region (&priv->info->decl, region_quark, flags))
+ gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
}
/**
@@ -1982,9 +1749,7 @@ gtk_style_context_remove_region (GtkStyleContext *context,
const gchar *region_name)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark region_quark;
- guint position;
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (region_name != NULL);
@@ -1996,14 +1761,8 @@ gtk_style_context_remove_region (GtkStyleContext *context,
priv = context->priv;
- info = priv->info;
-
- if (region_find (info->regions, region_quark, &position))
- {
- g_array_remove_index (info->regions, position);
-
- gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
- }
+ if (gtk_css_node_declaration_remove_region (&priv->info->decl, region_quark))
+ gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_REGION);
}
/**
@@ -2028,9 +1787,7 @@ gtk_style_context_has_region (GtkStyleContext *context,
GtkRegionFlags *flags_return)
{
GtkStyleContextPrivate *priv;
- GtkStyleInfo *info;
GQuark region_quark;
- guint position;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
g_return_val_if_fail (region_name != NULL, FALSE);
@@ -2045,21 +1802,7 @@ gtk_style_context_has_region (GtkStyleContext *context,
priv = context->priv;
- info = priv->info;
-
- if (region_find (info->regions, region_quark, &position))
- {
- if (flags_return)
- {
- GtkRegion *region;
-
- region = &g_array_index (info->regions, GtkRegion, position);
- *flags_return = region->flags;
- }
- return TRUE;
- }
-
- return FALSE;
+ return gtk_css_node_declaration_has_region (priv->info->decl, region_quark, flags_return);
}
static gint
@@ -2629,7 +2372,7 @@ gtk_style_context_set_junction_sides (GtkStyleContext *context,
{
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
- context->priv->info->junction_sides = sides;
+ gtk_css_node_declaration_set_junction_sides (&context->priv->info->decl, sides);
}
/**
@@ -2647,7 +2390,7 @@ gtk_style_context_get_junction_sides (GtkStyleContext *context)
{
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
- return context->priv->info->junction_sides;
+ return gtk_css_node_declaration_get_junction_sides (context->priv->info->decl);
}
gboolean
@@ -3854,6 +3597,7 @@ _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context)
{
GtkCssIconStyle icon_style;
GtkIconLookupFlags flags;
+ GtkStateFlags state;
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), 0);
@@ -3875,9 +3619,10 @@ _gtk_style_context_get_icon_lookup_flags (GtkStyleContext *context)
return 0;
}
- if (context->priv->info->state_flags & GTK_STATE_FLAG_DIR_LTR)
+ state = gtk_style_context_get_state (context);
+ if (state & GTK_STATE_FLAG_DIR_LTR)
flags |= GTK_ICON_LOOKUP_DIR_LTR;
- else if (context->priv->info->state_flags & GTK_STATE_FLAG_DIR_RTL)
+ else if (state & GTK_STATE_FLAG_DIR_RTL)
flags |= GTK_ICON_LOOKUP_DIR_RTL;
return flags;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]