[gtk+/wip/css: 1/167] gtk: Add GtkBitmask



commit b760c284ca433ac04c06a493b51fa292e6527cdb
Author: Benjamin Otte <otte redhat com>
Date:   Fri Dec 23 12:16:18 2011 +0100

    gtk: Add GtkBitmask
    
    The CSS code likes to have that very much.

 gtk/Makefile.am         |    2 +
 gtk/gtkbitmask.c        |  279 +++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkbitmaskprivate.h |   68 ++++++++++++
 3 files changed, 349 insertions(+), 0 deletions(-)
---
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index bcac2cf..673a5f9 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -402,6 +402,7 @@ gtk_private_h_sources =		\
 	gtkappchoosermodule.h	\
 	gtkappchooseronline.h	\
 	gtkbindingsprivate.h	\
+	gtkbitmaskprivate.h	\
 	gtkborderimageprivate.h \
 	gtkboxprivate.h         \
 	gtkbuilderprivate.h	\
@@ -543,6 +544,7 @@ gtk_base_c_sources = 		\
 	gtkbbox.c		\
 	gtkbin.c		\
 	gtkbindings.c		\
+	gtkbitmask.c		\
 	gtkborder.c		\
 	gtkborderimage.c	\
 	gtkbox.c		\
diff --git a/gtk/gtkbitmask.c b/gtk/gtkbitmask.c
new file mode 100644
index 0000000..a47d755
--- /dev/null
+++ b/gtk/gtkbitmask.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright  2011 Red Hat Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#include <config.h>
+
+#define GTK_INSIDE_BITMASK_C
+#include "gtk/gtkbitmaskprivate.h"
+
+#define VALUE_TYPE gsize
+
+#define VALUE_SIZE_BITS (sizeof (VALUE_TYPE) * 8)
+#define VALUE_BIT(idx) (((VALUE_TYPE) 1) << (idx))
+
+GtkBitmask *
+_gtk_bitmask_new (void)
+{
+  return g_array_new (FALSE, TRUE, sizeof (VALUE_TYPE));
+}
+
+GtkBitmask *
+_gtk_bitmask_copy (const GtkBitmask *mask)
+{
+  GtkBitmask *copy;
+
+  g_return_val_if_fail (mask != NULL, NULL);
+
+  copy = _gtk_bitmask_new ();
+  _gtk_bitmask_union (copy, mask);
+
+  return copy;
+}
+
+void
+_gtk_bitmask_free (GtkBitmask *mask)
+{
+  g_return_if_fail (mask != NULL);
+
+  g_array_free (mask, TRUE);
+}
+
+void
+_gtk_bitmask_print (const GtkBitmask *mask,
+                    GString          *string)
+{
+  int i;
+
+  g_return_if_fail (mask != NULL);
+  g_return_if_fail (string != NULL);
+
+  for (i = mask->len * VALUE_SIZE_BITS - 1; i >= 0; i--)
+    {
+      if (_gtk_bitmask_get (mask, i))
+        break;
+    }
+
+  if (i < 0)
+    {
+      g_string_append_c (string, '0');
+      return;
+    }
+
+  for (; i >= 0; i--)
+    {
+      g_string_append_c (string, _gtk_bitmask_get (mask, i) ? '1' : '0');
+    }
+}
+
+char *
+_gtk_bitmask_to_string (const GtkBitmask *mask)
+{
+  GString *string;
+  
+  string = g_string_new (NULL);
+  _gtk_bitmask_print (mask, string);
+  return g_string_free (string, FALSE);
+}
+
+/* NB: Call this function whenever the
+ * array might have become too large.
+ * _gtk_bitmask_is_empty() depends on this.
+ */
+static void
+gtk_bitmask_shrink (GtkBitmask *mask)
+{
+  guint i;
+
+  for (i = mask->len; i; i--)
+    {
+      if (g_array_index (mask, VALUE_TYPE, i - 1))
+        break;
+    }
+
+  g_array_set_size (mask, i);
+}
+
+void
+_gtk_bitmask_intersect (GtkBitmask       *mask,
+                        const GtkBitmask *other)
+{
+  guint i;
+
+  g_return_if_fail (mask != NULL);
+  g_return_if_fail (other != NULL);
+
+  g_array_set_size (mask, MIN (mask->len, other->len));
+  for (i = 0; i < mask->len; i++)
+    {
+      g_array_index (mask, VALUE_TYPE, i) &= g_array_index (other, VALUE_TYPE, i);
+    }
+
+  gtk_bitmask_shrink (mask);
+}
+
+void
+_gtk_bitmask_union (GtkBitmask       *mask,
+                    const GtkBitmask *other)
+{
+  guint i;
+
+  g_return_if_fail (mask != NULL);
+  g_return_if_fail (other != NULL);
+
+  g_array_set_size (mask, MAX (mask->len, other->len));
+  for (i = 0; i < other->len; i++)
+    {
+      g_array_index (mask, VALUE_TYPE, i) |= g_array_index (other, VALUE_TYPE, i);
+    }
+}
+
+void
+_gtk_bitmask_subtract (GtkBitmask       *mask,
+                       const GtkBitmask *other)
+{
+  guint i;
+
+  g_return_if_fail (mask != NULL);
+  g_return_if_fail (other != NULL);
+
+  for (i = 0; i < other->len; i++)
+    {
+      g_array_index (mask, VALUE_TYPE, i) &= ~g_array_index (other, VALUE_TYPE, i);
+    }
+
+  gtk_bitmask_shrink (mask);
+}
+
+static void
+gtk_bitmask_indexes (guint index_,
+                     guint *array_index,
+                     guint *bit_index)
+{
+  *array_index = index_ / VALUE_SIZE_BITS;
+  *bit_index = index_ % VALUE_SIZE_BITS;
+}
+
+gboolean
+_gtk_bitmask_get (const GtkBitmask *mask,
+                  guint             index_)
+{
+  guint array_index, bit_index;
+
+  g_return_val_if_fail (mask != NULL, FALSE);
+
+  gtk_bitmask_indexes (index_, &array_index, &bit_index);
+
+  if (array_index >= mask->len)
+    return FALSE;
+
+  return (g_array_index (mask, VALUE_TYPE, array_index) & VALUE_BIT (bit_index)) ? TRUE : FALSE;
+}
+
+void
+_gtk_bitmask_set (GtkBitmask *mask,
+                  guint       index_,
+                  gboolean    value)
+{
+  guint array_index, bit_index;
+
+  g_return_if_fail (mask != NULL);
+
+  gtk_bitmask_indexes (index_, &array_index, &bit_index);
+
+  if (value)
+    {
+      if (array_index >= mask->len)
+        g_array_set_size (mask, array_index + 1);
+      
+      g_array_index (mask, VALUE_TYPE, array_index) |= VALUE_BIT (bit_index);
+    }
+  else
+    {
+      if (array_index < mask->len)
+        {
+          g_array_index (mask, VALUE_TYPE, array_index) &= ~ VALUE_BIT (bit_index);
+          gtk_bitmask_shrink (mask);
+        }
+    }
+}
+
+void
+_gtk_bitmask_invert_range (GtkBitmask *mask,
+                           guint       start,
+                           guint       end)
+{
+  guint i;
+
+  g_return_if_fail (mask != NULL);
+  g_return_if_fail (start < end);
+
+  /* I CAN HAS SPEEDUP? */
+
+  for (i = start; i < end; i++)
+    _gtk_bitmask_set (mask, i, !_gtk_bitmask_get (mask, i));
+}
+
+gboolean
+_gtk_bitmask_is_empty (const GtkBitmask *mask)
+{
+  g_return_val_if_fail (mask != NULL, FALSE);
+
+  return mask->len == 0;
+}
+
+gboolean
+_gtk_bitmask_equals (const GtkBitmask  *mask,
+                     const GtkBitmask  *other)
+{
+  guint i;
+
+  g_return_val_if_fail (mask != NULL, FALSE);
+  g_return_val_if_fail (other != NULL, FALSE);
+
+  if (mask->len != other->len)
+    return FALSE;
+
+  for (i = 0; i < mask->len; i++)
+    {
+      if (g_array_index (mask, VALUE_TYPE, i) != g_array_index (other, VALUE_TYPE, i))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+_gtk_bitmask_intersects (const GtkBitmask *mask,
+                         const GtkBitmask *other)
+{
+  int i;
+
+  g_return_val_if_fail (mask != NULL, FALSE);
+  g_return_val_if_fail (other != NULL, FALSE);
+
+  for (i = MIN (mask->len, other->len) - 1; i >= 0; i--)
+    {
+      if (g_array_index (mask, VALUE_TYPE, i) & g_array_index (other, VALUE_TYPE, i))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
diff --git a/gtk/gtkbitmaskprivate.h b/gtk/gtkbitmaskprivate.h
new file mode 100644
index 0000000..adb65cf
--- /dev/null
+++ b/gtk/gtkbitmaskprivate.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright  2011 Red Hat Inc.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Authors: Benjamin Otte <otte gnome org>
+ */
+
+#ifndef __GTK_BITMASK_PRIVATE_H__
+#define __GTK_BITMASK_PRIVATE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#ifdef GTK_INSIDE_BITMASK_C
+typedef GArray GtkBitmask;
+#else
+typedef struct _GtkBitmask           GtkBitmask;
+#endif
+
+
+GtkBitmask *   _gtk_bitmask_new                  (void);
+GtkBitmask *   _gtk_bitmask_copy                 (const GtkBitmask  *mask);
+void           _gtk_bitmask_free                 (GtkBitmask        *mask);
+
+char *         _gtk_bitmask_to_string            (const GtkBitmask  *mask);
+void           _gtk_bitmask_print                (const GtkBitmask  *mask,
+                                                  GString           *string);
+
+void           _gtk_bitmask_intersect            (GtkBitmask        *mask,
+                                                  const GtkBitmask  *other);
+void           _gtk_bitmask_union                (GtkBitmask        *mask,
+                                                  const GtkBitmask  *other);
+void           _gtk_bitmask_subtract             (GtkBitmask        *mask,
+                                                  const GtkBitmask  *other);
+
+gboolean       _gtk_bitmask_get                  (const GtkBitmask  *mask,
+                                                  guint              index_);
+void           _gtk_bitmask_set                  (GtkBitmask        *mask,
+                                                  guint              index_,
+                                                  gboolean           value);
+
+void           _gtk_bitmask_invert_range         (GtkBitmask        *mask,
+                                                  guint              start,
+                                                  guint              end);
+
+gboolean       _gtk_bitmask_is_empty             (const GtkBitmask  *mask);
+gboolean       _gtk_bitmask_equals               (const GtkBitmask  *mask,
+                                                  const GtkBitmask  *other);
+gboolean       _gtk_bitmask_intersects           (const GtkBitmask  *mask,
+                                                  const GtkBitmask  *other);
+
+G_END_DECLS
+
+#endif /* __GTK_BITMASK_PRIVATE_H__ */



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