From 41b386cd6a84957dd9820083fa594090660c6a5d Mon Sep 17 00:00:00 2001 From: Garrett Regier Date: Fri, 11 Sep 2015 17:49:59 +0200 Subject: [PATCH] cssnode: Optimize listing of classes Avoid creating the GList of strings when the GQuarks will just be determined again. Instead have gtk_style_context_list_classes() do it specifically. --- gtk/gtkcssnode.c | 42 ++++++++++++++---------------- gtk/gtkcssnodedeclaration.c | 22 +++++----------- gtk/gtkcssnodedeclarationprivate.h | 3 ++- gtk/gtkcssnodeprivate.h | 3 ++- gtk/gtkstylecontext.c | 16 +++++++++--- gtk/gtkwidget.c | 11 ++++---- gtk/gtkwidgetpath.c | 19 ++++++++------ gtk/gtkwidgetpath.h | 14 ++++++++++ 8 files changed, 72 insertions(+), 58 deletions(-) diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c index 671613f230..9b5db15ad6 100644 --- a/gtk/gtkcssnode.c +++ b/gtk/gtkcssnode.c @@ -1054,16 +1054,15 @@ gtk_css_node_get_junction_sides (GtkCssNode *cssnode) static void gtk_css_node_clear_classes (GtkCssNode *cssnode) { - GList *list, *l; - - list = gtk_css_node_declaration_list_classes (cssnode->decl); + const GQuark *classes; + guint n_classes, i; - for (l = list; l; l = l->next) + classes = gtk_css_node_declaration_get_classes (cssnode->decl, &n_classes); + + for (i = 0; i < n_classes; ++i) { - gtk_css_node_remove_class (cssnode, GPOINTER_TO_UINT (l->data)); + gtk_css_node_remove_class (cssnode, classes[i]); } - - g_list_free (list); } void @@ -1090,22 +1089,20 @@ gtk_css_node_set_classes (GtkCssNode *cssnode, char ** gtk_css_node_get_classes (GtkCssNode *cssnode) { - GList *list, *l; - GPtrArray *result; - - list = gtk_css_node_declaration_list_classes (cssnode->decl); - result = g_ptr_array_new (); + const GQuark *classes; + char **result; + guint n_classes, i, j; - for (l = list; l; l = l->next) + classes = gtk_css_node_declaration_get_classes (cssnode->decl, &n_classes); + result = g_new (char *, n_classes + 1); + + for (i = n_classes, j = 0; i-- > 0; ++j) { - g_ptr_array_add (result, g_strdup (g_quark_to_string (GPOINTER_TO_UINT (l->data)))); + result[j] = g_strdup (g_quark_to_string (classes[i])); } - g_ptr_array_add (result, NULL); - - g_list_free (list); - - return (char **) g_ptr_array_free (result, FALSE); + result[n_classes] = NULL; + return result; } void @@ -1137,10 +1134,11 @@ gtk_css_node_has_class (GtkCssNode *cssnode, return gtk_css_node_declaration_has_class (cssnode->decl, style_class); } -GList * -gtk_css_node_list_classes (GtkCssNode *cssnode) +const GQuark * +gtk_css_node_list_classes (GtkCssNode *cssnode, + guint *n_classes) { - return gtk_css_node_declaration_list_classes (cssnode->decl); + return gtk_css_node_declaration_get_classes (cssnode->decl, n_classes); } void diff --git a/gtk/gtkcssnodedeclaration.c b/gtk/gtkcssnodedeclaration.c index 221faef7b0..c16189b1fe 100644 --- a/gtk/gtkcssnodedeclaration.c +++ b/gtk/gtkcssnodedeclaration.c @@ -335,22 +335,13 @@ gtk_css_node_declaration_has_class (const GtkCssNodeDeclaration *decl, } } -GList * -gtk_css_node_declaration_list_classes (const GtkCssNodeDeclaration *decl) +const GQuark * +gtk_css_node_declaration_get_classes (const GtkCssNodeDeclaration *decl, + guint *n_classes) { - GQuark *classes; - GList *result; - guint i; + *n_classes = decl->n_classes; - 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; + return get_classes (decl); } static gboolean @@ -589,8 +580,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS 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])); + gtk_widget_path_iter_add_qclass (path, pos, classes[i]); } /* Set widget state */ diff --git a/gtk/gtkcssnodedeclarationprivate.h b/gtk/gtkcssnodedeclarationprivate.h index 9e715fe7d2..51c8c62b1f 100644 --- a/gtk/gtkcssnodedeclarationprivate.h +++ b/gtk/gtkcssnodedeclarationprivate.h @@ -47,7 +47,8 @@ gboolean gtk_css_node_declaration_remove_class (GtkCssN 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); +const GQuark * gtk_css_node_declaration_get_classes (const GtkCssNodeDeclaration *decl, + guint *n_classes); gboolean gtk_css_node_declaration_add_region (GtkCssNodeDeclaration **decl, GQuark region_quark, diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h index cbed7e8585..9f1dc42b4f 100644 --- a/gtk/gtkcssnodeprivate.h +++ b/gtk/gtkcssnodeprivate.h @@ -134,7 +134,8 @@ void gtk_css_node_remove_class (GtkCssNode * GQuark style_class); gboolean gtk_css_node_has_class (GtkCssNode *cssnode, GQuark style_class); -GList * gtk_css_node_list_classes (GtkCssNode *cssnode); +const GQuark * gtk_css_node_list_classes (GtkCssNode *cssnode, + guint *n_classes); void gtk_css_node_add_region (GtkCssNode *cssnode, GQuark region, GtkRegionFlags flags); diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c index b359612903..643a17b896 100644 --- a/gtk/gtkstylecontext.c +++ b/gtk/gtkstylecontext.c @@ -1391,16 +1391,24 @@ GList * gtk_style_context_list_classes (GtkStyleContext *context) { GtkStyleContextPrivate *priv; - GList *classes; + GList *classes_list; + const GQuark *classes; + guint n_classes, i; + const gchar *quark_str; g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL); priv = context->priv; - classes = gtk_css_node_list_classes (priv->cssnode); - quarks_to_strings (classes); + classes = gtk_css_node_list_classes (priv->cssnode, &n_classes); - return classes; + for (i = n_classes; i-- > n_classes;) + { + quark_str = g_quark_to_string (classes[i]); + classes_list = g_list_prepend (classes_list, (gchar *) quark_str); + } + + return classes_list; } /** diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 76207da2ea..26528909ec 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -16333,17 +16333,16 @@ gtk_widget_path_append_for_widget (GtkWidgetPath *path, if (widget->priv->context) { - GList *classes, *l; + const GQuark *classes; + guint n_classes, i; /* Also add any persistent classes in * the style context the widget path */ - classes = gtk_css_node_list_classes (widget->priv->cssnode); + classes = gtk_css_node_list_classes (widget->priv->cssnode, &n_classes); - for (l = classes; l; l = l->next) - gtk_widget_path_iter_add_class (path, pos, g_quark_to_string (GPOINTER_TO_UINT (l->data))); - - g_list_free (classes); + for (i = n_classes; i-- > 0;) + gtk_widget_path_iter_add_qclass (path, pos, classes[i]); } return pos; diff --git a/gtk/gtkwidgetpath.c b/gtk/gtkwidgetpath.c index e8a7ac7919..f83af297a1 100644 --- a/gtk/gtkwidgetpath.c +++ b/gtk/gtkwidgetpath.c @@ -805,20 +805,23 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path, gint pos, const gchar *name) { - GtkPathElement *elem; - gboolean added = FALSE; - GQuark qname; - guint i; - gtk_internal_return_if_fail (path != NULL); gtk_internal_return_if_fail (path->elems->len != 0); gtk_internal_return_if_fail (name != NULL); - if (pos < 0 || pos >= path->elems->len) - pos = path->elems->len - 1; + gtk_widget_path_iter_add_qclass (path, pos, g_quark_from_string (name)); +} + +void +gtk_widget_path_iter_add_qclass (GtkWidgetPath *path, + gint pos, + GQuark qname) +{ + GtkPathElement *elem; + gboolean added = FALSE; + guint i; 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)); diff --git a/gtk/gtkwidgetpath.h b/gtk/gtkwidgetpath.h index f1f7ad7a6a..365c343d79 100644 --- a/gtk/gtkwidgetpath.h +++ b/gtk/gtkwidgetpath.h @@ -107,10 +107,18 @@ GDK_AVAILABLE_IN_ALL void gtk_widget_path_iter_add_class (GtkWidgetPath *path, gint pos, const gchar *name); +GDK_AVAILABLE_IN_3_18 +void gtk_widget_path_iter_add_qclass (GtkWidgetPath *path, + gint pos, + GQuark qname); GDK_AVAILABLE_IN_ALL void gtk_widget_path_iter_remove_class (GtkWidgetPath *path, gint pos, const gchar *name); +GDK_AVAILABLE_IN_3_18 +void gtk_widget_path_iter_remove_qclass (GtkWidgetPath *path, + gint pos, + GQuark qname); GDK_AVAILABLE_IN_ALL void gtk_widget_path_iter_clear_classes (GtkWidgetPath *path, gint pos); @@ -164,6 +172,12 @@ GDK_AVAILABLE_IN_ALL gboolean gtk_widget_path_has_parent (const GtkWidgetPath *path, GType type); +/* private API goes here */ + +void gtk_widget_path_iter_add_qclass (GtkWidgetPath *path, + gint pos, + GQuark qname); + G_END_DECLS #endif /* __GTK_WIDGET_PATH_H__ */