[gtk/wip/otte/css: 34/48] css: Get rid of GtkCssMatcher



commit 8b93ea9238bcbb99f6caadca9f6ef1d422926a35
Author: Benjamin Otte <otte redhat com>
Date:   Thu Jan 23 03:34:25 2020 +0100

    css: Get rid of GtkCssMatcher

 gtk/gtkcssmatcher.c         | 190 -----------------------------------------
 gtk/gtkcssmatcherprivate.h  | 131 ----------------------------
 gtk/gtkcssprovider.c        |  15 ++--
 gtk/gtkcssselector.c        | 203 +++++++++++++++++++++++++++-----------------
 gtk/gtkcssselectorprivate.h |   8 +-
 gtk/gtkcsstypesprivate.h    |   1 -
 gtk/meson.build             |   1 -
 7 files changed, 137 insertions(+), 412 deletions(-)
---
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index a98af871bc..d7f64b76ab 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -392,8 +392,8 @@ gtk_css_provider_init (GtkCssProvider *css_provider)
 
 static void
 verify_tree_match_results (GtkCssProvider *provider,
-                          const GtkCssMatcher *matcher,
-                          GPtrArray *tree_rules)
+                          GtkCssNode     *node,
+                          GPtrArray      *tree_rules)
 {
 #ifdef VERIFY_TREE
   GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (provider);
@@ -415,7 +415,7 @@ verify_tree_match_results (GtkCssProvider *provider,
              break;
            }
        }
-      should_match = _gtk_css_selector_matches (ruleset->selector, matcher);
+      should_match = _gtk_css_selector_matches (ruleset->selector, node);
       if (found != !!should_match)
        {
          g_error ("expected rule '%s' to %s, but it %s",
@@ -456,7 +456,6 @@ gtk_css_style_provider_lookup (GtkStyleProvider    *provider,
   GtkCssProvider *css_provider = GTK_CSS_PROVIDER (provider);
   GtkCssProviderPrivate *priv = gtk_css_provider_get_instance_private (css_provider);
   GtkCssRuleset *ruleset;
-  GtkCssMatcher matcher;
   guint j;
   int i;
   GPtrArray *tree_rules;
@@ -464,12 +463,10 @@ gtk_css_style_provider_lookup (GtkStyleProvider    *provider,
   if (_gtk_css_selector_tree_is_empty (priv->tree))
     return;
 
-  _gtk_css_matcher_node_init (&matcher, node);
-
-  tree_rules = _gtk_css_selector_tree_match_all (priv->tree, &matcher);
+  tree_rules = _gtk_css_selector_tree_match_all (priv->tree, node);
   if (tree_rules)
     {
-      verify_tree_match_results (css_provider, &matcher, tree_rules);
+      verify_tree_match_results (css_provider, node, tree_rules);
 
       for (i = tree_rules->len - 1; i >= 0; i--)
         {
@@ -500,7 +497,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider    *provider,
     }
 
   if (change)
-    *change = _gtk_css_selector_tree_get_change_all (priv->tree, &matcher);
+    *change = _gtk_css_selector_tree_get_change_all (priv->tree, node);
 }
 
 static void
diff --git a/gtk/gtkcssselector.c b/gtk/gtkcssselector.c
index a27c111e93..1e7da07305 100644
--- a/gtk/gtkcssselector.c
+++ b/gtk/gtkcssselector.c
@@ -49,7 +49,7 @@ typedef enum {
 
 typedef struct _GtkCssSelectorClass GtkCssSelectorClass;
 typedef gboolean (* GtkCssSelectorForeachFunc) (const GtkCssSelector *selector,
-                                                const GtkCssMatcher  *matcher,
+                                                GtkCssNode           *node,
                                                 gpointer              data);
 
 struct _GtkCssSelectorClass {
@@ -58,18 +58,18 @@ struct _GtkCssSelectorClass {
 
   void              (* print)       (const GtkCssSelector       *selector,
                                      GString                    *string);
-  /* NULL or an iterator that calls func with each submatcher of @matcher.
-   * Potentially no submatcher exists.
+  /* NULL or an iterator that calls func with each subnode of @node.
+   * Potentially no subnode exists.
    * If any @invocation of @func returns %TRUE, the function will immediately
    * return %TRUE itself. If @func never returns %TRUE (or isn't called at all),
    * %FALSE will be returned.
    */
   gboolean          (* foreach_matcher)  (const GtkCssSelector       *selector,
-                                          const GtkCssMatcher        *matcher,
+                                          GtkCssNode                 *node,
                                           GtkCssSelectorForeachFunc   func,
                                           gpointer                    data);
   gboolean          (* match_one)   (const GtkCssSelector       *selector,
-                                     const GtkCssMatcher        *matcher);
+                                     GtkCssNode                 *node);
   GtkCssChange      (* get_change)  (const GtkCssSelector       *selector,
                                     GtkCssChange                previous_change);
   void              (* add_specificity)  (const GtkCssSelector  *selector,
@@ -188,18 +188,18 @@ gtk_css_selector_tree_found_match (const GtkCssSelectorTree  *tree,
 
 static inline gboolean
 gtk_css_selector_match (const GtkCssSelector *selector,
-                        const GtkCssMatcher  *matcher)
+                        GtkCssNode           *node)
 {
-  return selector->class->match_one (selector, matcher);
+  return selector->class->match_one (selector, node);
 }
 
 static inline gboolean
 gtk_css_selector_foreach (const GtkCssSelector      *selector,
-                          const GtkCssMatcher       *matcher,
+                          GtkCssNode                *node,
                           GtkCssSelectorForeachFunc  func,
                           gpointer                   data)
 {
-  return selector->class->foreach_matcher (selector, matcher, func, data);
+  return selector->class->foreach_matcher (selector, node, func, data);
 }
 
 static int
@@ -260,16 +260,16 @@ gtk_css_selector_default_add_specificity (const GtkCssSelector *selector,
  
 static gboolean
 gtk_css_selector_default_foreach_matcher (const GtkCssSelector       *selector,
-                                          const GtkCssMatcher        *matcher,
+                                          GtkCssNode                 *node,
                                           GtkCssSelectorForeachFunc   func,
                                           gpointer                    data)
 {
-  return func (selector, matcher, data);
+  return func (selector, node, data);
 }
 
 static gboolean
 gtk_css_selector_default_match_one (const GtkCssSelector *selector,
-                                    const GtkCssMatcher  *matcher)
+                                    GtkCssNode           *node)
 {
   return TRUE;
 }
@@ -298,17 +298,17 @@ gtk_css_selector_descendant_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_descendant_foreach_matcher (const GtkCssSelector      *selector,
-                                             const GtkCssMatcher       *matcher,
+                                             GtkCssNode                *node,
                                              GtkCssSelectorForeachFunc  func,
                                              gpointer                   data)
 {
-  GtkCssMatcher ancestor;
+  GtkCssNode *parent;
 
-  while (_gtk_css_matcher_get_parent (&ancestor, matcher))
+  for (parent = gtk_css_node_get_parent (node);
+       parent;
+       parent = gtk_css_node_get_parent (parent))
     {
-      matcher = &ancestor;
-
-      if (func (selector, &ancestor, data))
+      if (func (selector, parent, data))
         return TRUE;
     }
 
@@ -344,16 +344,17 @@ gtk_css_selector_child_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_child_foreach_matcher (const GtkCssSelector      *selector,
-                                        const GtkCssMatcher       *matcher,
+                                        GtkCssNode                *node,
                                         GtkCssSelectorForeachFunc  func,
                                         gpointer                   data)
 {
-  GtkCssMatcher parent;
+  GtkCssNode *parent;
 
-  if (!_gtk_css_matcher_get_parent (&parent, matcher))
+  parent = gtk_css_node_get_parent (node);
+  if (parent == NULL)
     return FALSE;
 
-  return func (selector, &parent, data);
+  return func (selector, parent, data);
 }
 
 static GtkCssChange
@@ -383,19 +384,39 @@ gtk_css_selector_sibling_print (const GtkCssSelector *selector,
   g_string_append (string, " ~ ");
 }
 
+static GtkCssNode *
+get_previous_visible_sibling (GtkCssNode *node)
+{
+  do {
+    node = gtk_css_node_get_previous_sibling (node);
+  } while (node && !gtk_css_node_get_visible (node));
+
+  return node;
+}
+
+static GtkCssNode *
+get_next_visible_sibling (GtkCssNode *node)
+{
+  do {
+    node = gtk_css_node_get_next_sibling (node);
+  } while (node && !gtk_css_node_get_visible (node));
+
+  return node;
+}
+
 static gboolean
 gtk_css_selector_sibling_foreach_matcher (const GtkCssSelector      *selector,
-                                          const GtkCssMatcher       *matcher,
+                                          GtkCssNode                *node,
                                           GtkCssSelectorForeachFunc  func,
                                           gpointer                   data)
 {
-  GtkCssMatcher previous;
+  GtkCssNode *prev;
 
-  while (_gtk_css_matcher_get_previous (&previous, matcher))
+  for (prev = get_previous_visible_sibling (node);
+       prev;
+       prev = get_previous_visible_sibling (prev))
     {
-      matcher = &previous;
-
-      if (func (selector, matcher, data))
+      if (func (selector, prev, data))
         return TRUE;
     }
 
@@ -431,16 +452,17 @@ gtk_css_selector_adjacent_print (const GtkCssSelector *selector,
 
 static gboolean
 gtk_css_selector_adjacent_foreach_matcher (const GtkCssSelector      *selector,
-                                           const GtkCssMatcher       *matcher,
+                                           GtkCssNode                *node,
                                            GtkCssSelectorForeachFunc  func,
                                            gpointer                   data)
 {
-  GtkCssMatcher previous;
+  GtkCssNode *prev;
 
-  if (!_gtk_css_matcher_get_previous (&previous, matcher))
+  prev = get_previous_visible_sibling (node);
+  if (prev == NULL)
     return FALSE;
-  
-  return func (selector, &previous, data);
+
+  return func (selector, prev, data);
 }
 
 static GtkCssChange
@@ -491,9 +513,9 @@ gtk_css_selector_not_ ## n ## _print (const GtkCssSelector *selector, \
 \
 static gboolean \
 gtk_css_selector_not_ ## n ## _match_one (const GtkCssSelector *selector, \
-                                          const GtkCssMatcher  *matcher) \
+                                          GtkCssNode           *node) \
 { \
-  return !match_func (selector, matcher); \
+  return !match_func (selector, node); \
 } \
 \
 static GtkCssChange \
@@ -557,7 +579,7 @@ print_any (const GtkCssSelector *selector,
 
 static gboolean
 match_any (const GtkCssSelector *selector,
-           const GtkCssMatcher  *matcher)
+           GtkCssNode           *node)
 {
   return TRUE;
 }
@@ -580,9 +602,9 @@ print_name (const GtkCssSelector *selector,
 
 static gboolean
 match_name (const GtkCssSelector *selector,
-            const GtkCssMatcher  *matcher)
+            GtkCssNode           *node)
 {
-  return _gtk_css_matcher_has_name (matcher, selector->name.name);
+  return gtk_css_node_get_name (node) == selector->name.name;
 }
 
 static guint
@@ -613,9 +635,9 @@ print_class (const GtkCssSelector *selector,
 
 static gboolean
 match_class (const GtkCssSelector *selector,
-             const GtkCssMatcher  *matcher)
+             GtkCssNode           *node)
 {
-  return _gtk_css_matcher_has_class (matcher, selector->style_class.style_class);
+  return gtk_css_node_has_class (node, selector->style_class.style_class);
 }
 
 static guint
@@ -650,9 +672,9 @@ print_id (const GtkCssSelector *selector,
 
 static gboolean
 match_id (const GtkCssSelector *selector,
-          const GtkCssMatcher  *matcher)
+          GtkCssNode           *node)
 {
-  return _gtk_css_matcher_has_id (matcher, selector->id.name);
+  return gtk_css_node_get_id (node) == selector->id.name;
 }
 
 static guint
@@ -686,9 +708,9 @@ print_pseudoclass_state (const GtkCssSelector *selector,
 
 static gboolean
 match_pseudoclass_state (const GtkCssSelector *selector,
-                         const GtkCssMatcher  *matcher)
+                         GtkCssNode           *node)
 {
-  return _gtk_css_matcher_has_state (matcher, selector->state.state);
+  return (gtk_css_node_get_state (node) & selector->state.state) == selector->state.state;
 }
 
 static guint
@@ -809,23 +831,57 @@ print_pseudoclass_position (const GtkCssSelector *selector,
     }
 }
 
+static gboolean
+match_position (GtkCssNode *node,
+                GtkCssNode *(* prev_node_func) (GtkCssNode *),
+                int         a,
+                int         b)
+{
+  int pos, x;
+
+  /* special-case the common "first-child" and "last-child" */
+  if (a == 0)
+    {
+      while (b > 0 && node != NULL)
+        {
+          b--;
+          node = prev_node_func (node);
+        }
+
+      return b == 0 && node == NULL;
+    }
+
+  /* count nodes */
+  for (pos = 0; node != NULL; pos++)
+    node = prev_node_func (node);
+
+  /* solve pos = a * X + b
+   * and return TRUE if X is integer >= 0 */
+  x = pos - b;
+
+  if (x % a)
+    return FALSE;
+
+  return x / a >= 0;
+}
+
 static gboolean
 match_pseudoclass_position (const GtkCssSelector *selector,
-                           const GtkCssMatcher  *matcher)
+                           GtkCssNode           *node)
 {
   switch (selector->position.type)
     {
     case POSITION_FORWARD:
-      if (!_gtk_css_matcher_has_position (matcher, TRUE, selector->position.a, selector->position.b))
+      if (!match_position (node, get_previous_visible_sibling, selector->position.a, selector->position.b))
         return FALSE;
       break;
     case POSITION_BACKWARD:
-      if (!_gtk_css_matcher_has_position (matcher, FALSE, selector->position.a, selector->position.b))
+      if (!match_position (node, get_next_visible_sibling, selector->position.a, selector->position.b))
         return FALSE;
       break;
     case POSITION_ONLY:
-      if (!_gtk_css_matcher_has_position (matcher, TRUE, 0, 1) ||
-          !_gtk_css_matcher_has_position (matcher, FALSE, 0, 1))
+      if (get_previous_visible_sibling (node) ||
+          get_next_visible_sibling (node))
         return FALSE;
       break;
     default:
@@ -1645,7 +1701,7 @@ _gtk_css_selector_to_string (const GtkCssSelector *selector)
 
 static gboolean
 gtk_css_selector_foreach_match (const GtkCssSelector *selector,
-                                const GtkCssMatcher  *matcher,
+                                GtkCssNode           *node,
                                 gpointer              unused)
 {
   selector = gtk_css_selector_previous (selector);
@@ -1653,38 +1709,33 @@ gtk_css_selector_foreach_match (const GtkCssSelector *selector,
   if (selector == NULL)
     return TRUE;
 
-  if (!gtk_css_selector_match (selector, matcher))
+  if (!gtk_css_selector_match (selector, node))
     return FALSE;
 
-  return gtk_css_selector_foreach (selector, matcher, gtk_css_selector_foreach_match, NULL);
+  return gtk_css_selector_foreach (selector, node, gtk_css_selector_foreach_match, NULL);
 }
 
 /**
  * _gtk_css_selector_matches:
  * @selector: the selector
- * @path: the path to check
- * @state: The state to match
+ * @node: The node to match
  *
- * Checks if the @selector matches the given @path. If @length is
- * smaller than the number of elements in @path, it is assumed that
- * only the first @length element of @path are valid and the rest
- * does not exist. This is useful for doing parent matches for the
- * 'inherit' keyword.
+ * Checks if the @selector matches the given @node.
  *
- * Returns: %TRUE if the selector matches @path
+ * Returns: %TRUE if the selector matches @node
  **/
 gboolean
 _gtk_css_selector_matches (const GtkCssSelector *selector,
-                           const GtkCssMatcher  *matcher)
+                           GtkCssNode           *node)
 {
 
   g_return_val_if_fail (selector != NULL, FALSE);
-  g_return_val_if_fail (matcher != NULL, FALSE);
+  g_return_val_if_fail (node != NULL, FALSE);
 
-  if (!gtk_css_selector_match (selector, matcher))
+  if (!gtk_css_selector_match (selector, node))
     return FALSE;
 
-  return gtk_css_selector_foreach (selector, matcher, gtk_css_selector_foreach_match, NULL);
+  return gtk_css_selector_foreach (selector, node, gtk_css_selector_foreach_match, NULL);
 }
 
 /* Computes specificity according to CSS 2.1.
@@ -1821,13 +1872,13 @@ gtk_css_selectors_skip_initial_selector (GtkCssSelector *selector, const GtkCssS
 
 static gboolean
 gtk_css_selector_tree_match_foreach (const GtkCssSelector *selector,
-                                     const GtkCssMatcher  *matcher,
+                                     GtkCssNode           *node,
                                      gpointer              res)
 {
   const GtkCssSelectorTree *tree = (const GtkCssSelectorTree *) selector;
   const GtkCssSelectorTree *prev;
 
-  if (!gtk_css_selector_match (selector, matcher))
+  if (!gtk_css_selector_match (selector, node))
     return FALSE;
 
   gtk_css_selector_tree_found_match (tree, res);
@@ -1835,20 +1886,20 @@ gtk_css_selector_tree_match_foreach (const GtkCssSelector *selector,
   for (prev = gtk_css_selector_tree_get_previous (tree);
        prev != NULL;
        prev = gtk_css_selector_tree_get_sibling (prev))
-    gtk_css_selector_foreach (&prev->selector, matcher, gtk_css_selector_tree_match_foreach, res);
+    gtk_css_selector_foreach (&prev->selector, node, gtk_css_selector_tree_match_foreach, res);
 
   return FALSE;
 }
 
 GPtrArray *
 _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
-                                 const GtkCssMatcher *matcher)
+                                  GtkCssNode               *node)
 {
   GPtrArray *array = NULL;
 
   for (; tree != NULL;
        tree = gtk_css_selector_tree_get_sibling (tree))
-    gtk_css_selector_foreach (&tree->selector, matcher, gtk_css_selector_tree_match_foreach, &array);
+    gtk_css_selector_foreach (&tree->selector, node, gtk_css_selector_tree_match_foreach, &array);
 
   return array;
 }
@@ -1860,12 +1911,12 @@ _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
 
 static gboolean
 gtk_css_selector_match_for_change (const GtkCssSelector *selector,
-                                   const GtkCssMatcher  *matcher)
+                                   GtkCssNode           *node)
 {
   if (selector->class->category != GTK_CSS_SELECTOR_CATEGORY_SIMPLE_RADICAL)
     return TRUE;
 
-  return selector->class->match_one (selector, matcher);
+  return selector->class->match_one (selector, node);
 }
 
 /* When checking for changes via the tree we need to know if a rule further
@@ -1897,12 +1948,12 @@ gtk_css_selector_tree_collect_change (const GtkCssSelectorTree *tree)
 
 static GtkCssChange
 gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
-                                 const GtkCssMatcher      *matcher)
+                                 GtkCssNode               *node)
 {
   GtkCssChange change = 0;
   const GtkCssSelectorTree *prev;
 
-  if (!gtk_css_selector_match_for_change (&tree->selector, matcher))
+  if (!gtk_css_selector_match_for_change (&tree->selector, node))
     return 0;
 
   if (!gtk_css_selector_is_simple (&tree->selector))
@@ -1911,7 +1962,7 @@ gtk_css_selector_tree_get_change (const GtkCssSelectorTree *tree,
   for (prev = gtk_css_selector_tree_get_previous (tree);
        prev != NULL;
        prev = gtk_css_selector_tree_get_sibling (prev))
-    change |= gtk_css_selector_tree_get_change (prev, matcher);
+    change |= gtk_css_selector_tree_get_change (prev, node);
 
   if (change || gtk_css_selector_tree_get_matches (tree))
     change = tree->selector.class->get_change (&tree->selector, change & ~GTK_CSS_CHANGE_GOT_MATCH) | 
GTK_CSS_CHANGE_GOT_MATCH;
@@ -1927,7 +1978,7 @@ _gtk_css_selector_tree_is_empty (const GtkCssSelectorTree *tree)
 
 GtkCssChange
 _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
-                                      const GtkCssMatcher *matcher)
+                                      GtkCssNode               *node)
 {
   GtkCssChange change;
 
@@ -1936,7 +1987,7 @@ _gtk_css_selector_tree_get_change_all (const GtkCssSelectorTree *tree,
   /* no need to foreach here because we abort for non-simple selectors */
   for (; tree != NULL;
        tree = gtk_css_selector_tree_get_sibling (tree))
-    change |= gtk_css_selector_tree_get_change (tree, matcher);
+    change |= gtk_css_selector_tree_get_change (tree, node);
 
   /* Never return reserved bit set */
   return change & ~GTK_CSS_CHANGE_RESERVED_BIT;
diff --git a/gtk/gtkcssselectorprivate.h b/gtk/gtkcssselectorprivate.h
index b8673edda5..64a05b63f7 100644
--- a/gtk/gtkcssselectorprivate.h
+++ b/gtk/gtkcssselectorprivate.h
@@ -18,7 +18,7 @@
 #ifndef __GTK_CSS_SELECTOR_PRIVATE_H__
 #define __GTK_CSS_SELECTOR_PRIVATE_H__
 
-#include "gtk/gtkcssmatcherprivate.h"
+#include "gtk/gtkcsstypesprivate.h"
 #include "gtk/gtkcssparserprivate.h"
 
 G_BEGIN_DECLS
@@ -35,16 +35,16 @@ void              _gtk_css_selector_print           (const GtkCssSelector   *sel
                                                      GString                *str);
 
 gboolean          _gtk_css_selector_matches         (const GtkCssSelector   *selector,
-                                                     const GtkCssMatcher    *matcher);
+                                                    GtkCssNode             *node);
 GtkCssChange      _gtk_css_selector_get_change      (const GtkCssSelector   *selector);
 int               _gtk_css_selector_compare         (const GtkCssSelector   *a,
                                                      const GtkCssSelector   *b);
 
 void         _gtk_css_selector_tree_free             (GtkCssSelectorTree       *tree);
 GPtrArray *  _gtk_css_selector_tree_match_all        (const GtkCssSelectorTree *tree,
-                                                     const GtkCssMatcher      *matcher);
+                                                     GtkCssNode               *node);
 GtkCssChange _gtk_css_selector_tree_get_change_all   (const GtkCssSelectorTree *tree,
-                                                     const GtkCssMatcher *matcher);
+                                                     GtkCssNode               *node);
 void         _gtk_css_selector_tree_match_print      (const GtkCssSelectorTree *tree,
                                                      GString                  *str);
 gboolean     _gtk_css_selector_tree_is_empty         (const GtkCssSelectorTree *tree) G_GNUC_CONST;
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index 156e3763a8..af552e13fd 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -25,7 +25,6 @@
 
 G_BEGIN_DECLS
 
-typedef union _GtkCssMatcher GtkCssMatcher;
 typedef struct _GtkCssNode GtkCssNode;
 typedef struct _GtkCssNodeDeclaration GtkCssNodeDeclaration;
 typedef struct _GtkCssStyle GtkCssStyle;
diff --git a/gtk/meson.build b/gtk/meson.build
index 99b8b5cda3..4c42b008a0 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -72,7 +72,6 @@ gtk_private_sources = files([
   'gtkcssinitialvalue.c',
   'gtkcsskeyframes.c',
   'gtkcsslookup.c',
-  'gtkcssmatcher.c',
   'gtkcssnode.c',
   'gtkcssnodedeclaration.c',
   'gtkcssnodestylecache.c',


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