[gtk+/wip/css-tree: 4/4] css: Create and use a tree for css selector matching



commit fa2f5eee64fc81f5414a4f4885deed03337ad7aa
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Nov 28 11:21:06 2012 +0100

    css: Create and use a tree for css selector matching

 gtk/gtkcssprovider.c |   73 +++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 60 insertions(+), 13 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index 68bd3e5..d1dbe0b 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -1011,6 +1011,7 @@ struct _GtkCssProviderPrivate
   GHashTable *keyframes;
 
   GArray *rulesets;
+  GtkCssSelectorTree *tree;
   GResource *resource;
 };
 
@@ -1506,17 +1507,41 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
   GtkCssProviderPrivate *priv;
   GtkCssRuleset *ruleset;
   guint j;
+  int i;
+  GPtrArray *tree_rules;
 
   css_provider = GTK_CSS_PROVIDER (provider);
   priv = css_provider->priv;
 
-  if (priv->rulesets->len == 0)
-    return;
+  tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
 
-  for (ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, priv->rulesets->len - 1);
-       ruleset >= &g_array_index (priv->rulesets, GtkCssRuleset, 0);
-       ruleset--)
+#ifdef VERIFY_TREE
+  for (i = 0; i < priv->rulesets->len; i++)
     {
+      gboolean found = FALSE;
+
+      ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
+
+      for (j = 0; j < tree_rules->len; j++)
+	{
+	  if (ruleset == tree_rules->pdata[j])
+	    {
+	      found = TRUE;
+	      break;
+	    }
+	}
+
+      if (found)
+	g_assert (gtk_css_ruleset_matches (ruleset, matcher));
+      else
+	g_assert (!gtk_css_ruleset_matches (ruleset, matcher));
+    }
+#endif
+
+  for (i = tree_rules->len - 1; i >= 0; i--)
+    {
+      ruleset = tree_rules->pdata[i];
+
       if (ruleset->styles == NULL)
         continue;
 
@@ -1524,9 +1549,6 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
                                     ruleset->set_styles))
         continue;
 
-      if (!gtk_css_ruleset_matches (ruleset, matcher))
-        continue;
-
       for (j = 0; j < ruleset->n_styles; j++)
         {
           GtkCssStyleProperty *prop = ruleset->styles[j].property;
@@ -1544,6 +1566,8 @@ gtk_css_style_provider_lookup (GtkStyleProviderPrivate *provider,
       if (_gtk_bitmask_is_empty (_gtk_css_lookup_get_missing (lookup)))
         break;
     }
+
+  g_ptr_array_free (tree_rules, TRUE);
 }
 
 static GtkCssChange
@@ -1553,26 +1577,28 @@ gtk_css_style_provider_get_change (GtkStyleProviderPrivate *provider,
   GtkCssProvider *css_provider;
   GtkCssProviderPrivate *priv;
   GtkCssChange change = 0;
+  GPtrArray *tree_rules;
   int i;
 
   css_provider = GTK_CSS_PROVIDER (provider);
   priv = css_provider->priv;
 
-  for (i = priv->rulesets->len - 1; i >= 0; i--)
+  tree_rules = _gtk_css_selector_tree_match_all (priv->tree, matcher);
+
+  for (i = tree_rules->len - 1; i >= 0; i--)
     {
       GtkCssRuleset *ruleset;
 
-      ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
+      ruleset = tree_rules->pdata[i];
 
       if (ruleset->styles == NULL)
         continue;
 
-      if (!gtk_css_ruleset_matches (ruleset, matcher))
-        continue;
-
       change |= gtk_css_ruleset_get_change (ruleset);
     }
 
+  g_ptr_array_free (tree_rules, TRUE);
+
   return change;
 }
 
@@ -1599,6 +1625,7 @@ gtk_css_provider_finalize (GObject *object)
     gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
 
   g_array_free (priv->rulesets, TRUE);
+  _gtk_css_selector_tree_free (priv->tree);
 
   g_hash_table_destroy (priv->symbolic_colors);
   g_hash_table_destroy (priv->keyframes);
@@ -1736,6 +1763,9 @@ gtk_css_provider_reset (GtkCssProvider *css_provider)
   for (i = 0; i < priv->rulesets->len; i++)
     gtk_css_ruleset_clear (&g_array_index (priv->rulesets, GtkCssRuleset, i));
   g_array_set_size (priv->rulesets, 0);
+  _gtk_css_selector_tree_free (priv->tree);
+  priv->tree = NULL;
+
 }
 
 static void
@@ -2370,8 +2400,25 @@ static void
 gtk_css_provider_postprocess (GtkCssProvider *css_provider)
 {
   GtkCssProviderPrivate *priv = css_provider->priv;
+  GtkCssSelectorTreeBuilder *builder;
+  guint i;
 
   g_array_sort (priv->rulesets, gtk_css_provider_compare_rule);
+
+  builder = _gtk_css_selector_tree_builder_new ();
+  for (i = 0; i < priv->rulesets->len; i++)
+    {
+      GtkCssRuleset *ruleset;
+
+      ruleset = &g_array_index (priv->rulesets, GtkCssRuleset, i);
+
+      _gtk_css_selector_tree_builder_add (builder,
+					  ruleset->selector,
+					  ruleset);
+    }
+
+  priv->tree = _gtk_css_selector_tree_builder_build (builder);
+  _gtk_css_selector_tree_builder_free (builder);
 }
 
 static gboolean



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]