[gtk+/wip/css: 1/153] gtk: Add GtkBitmask
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/css: 1/153] gtk: Add GtkBitmask
- Date: Sat, 7 Jan 2012 01:56:40 +0000 (UTC)
commit 1b92732cfec2ee96d7b02300c4649e793db0e3a4
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 ab46644..01c99b3 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]