Compare commits
6 Commits
wip/matthi
...
wip/css-bi
Author | SHA1 | Date | |
---|---|---|---|
|
46982d1234 | ||
|
f9d9b26d98 | ||
|
493b7f2719 | ||
|
0fa10388dd | ||
|
1ffc8ebb8a | ||
|
c18d21f312 |
565
gtk/gtkbitmask.c
565
gtk/gtkbitmask.c
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#define GTK_INSIDE_BITMASK_C
|
||||
#include "gtk/gtkbitmaskprivate.h"
|
||||
|
||||
#define VALUE_TYPE gsize
|
||||
@@ -28,10 +27,163 @@
|
||||
#define VALUE_SIZE_BITS (sizeof (VALUE_TYPE) * 8)
|
||||
#define VALUE_BIT(idx) (((VALUE_TYPE) 1) << (idx))
|
||||
|
||||
struct _GtkBitmask {
|
||||
guint len;
|
||||
guint alloc;
|
||||
VALUE_TYPE data[1];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
GtkBitmask bitmask;
|
||||
VALUE_TYPE more_data[3];
|
||||
const GtkBitmask *orig;
|
||||
} GtkBitmaskPrealloc;
|
||||
|
||||
static GtkBitmask *
|
||||
_gtk_bitmask_allocate (guint size)
|
||||
{
|
||||
GtkBitmask *mask;
|
||||
|
||||
mask = g_malloc (sizeof (GtkBitmask) + sizeof(VALUE_TYPE) * (size - 1));
|
||||
mask->len = 0;
|
||||
mask->alloc = size;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static void
|
||||
_gtk_bitmask_resize (GtkBitmask **mask, guint len)
|
||||
{
|
||||
GtkBitmask *new, *old;
|
||||
int i;
|
||||
|
||||
old = *mask;
|
||||
|
||||
if (old->alloc < len)
|
||||
{
|
||||
new = _gtk_bitmask_allocate (len);
|
||||
for (i = 0; i < old->len; i++)
|
||||
new->data[i] = old->data[i];
|
||||
new->len = old->len;
|
||||
g_free (old);
|
||||
*mask = new;
|
||||
}
|
||||
|
||||
/* If expanding, clear the new data */
|
||||
if (len > (*mask)->len)
|
||||
{
|
||||
for (i = (*mask)->len; i < len; i++)
|
||||
(*mask)->data[i] = 0;
|
||||
}
|
||||
|
||||
(*mask)->len = len;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_bitmask_is_bit (const GtkBitmask *mask)
|
||||
{
|
||||
return (((gsize)mask) & 1);
|
||||
}
|
||||
|
||||
static GtkBitmask *
|
||||
gtk_bitmask_for_bit (guint bit)
|
||||
{
|
||||
gsize mask;
|
||||
|
||||
mask = bit;
|
||||
mask <<= 1;
|
||||
mask |= 1;
|
||||
return (GtkBitmask *)mask;
|
||||
}
|
||||
|
||||
static guint
|
||||
gtk_bitmask_get_bit (const GtkBitmask *mask)
|
||||
{
|
||||
return ((gsize)mask) >> 1;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_bitmask_is_inline (const GtkBitmask *mask)
|
||||
{
|
||||
return mask == NULL || gtk_bitmask_is_bit (mask);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bitmask_realize_for_write (GtkBitmask **mask, guint size_hint)
|
||||
{
|
||||
GtkBitmask *realized;
|
||||
|
||||
if (*mask == NULL)
|
||||
{
|
||||
realized = _gtk_bitmask_allocate (MAX (size_hint, 1));
|
||||
realized->len = 0;
|
||||
*mask = realized;
|
||||
}
|
||||
else if (gtk_bitmask_is_bit (*mask))
|
||||
{
|
||||
guint bit = gtk_bitmask_get_bit (*mask);
|
||||
guint len = (bit / VALUE_SIZE_BITS) + 1;
|
||||
int i;
|
||||
|
||||
realized = _gtk_bitmask_allocate (MAX (len, size_hint));
|
||||
realized->len = len;
|
||||
for (i = 0; i < len; i++)
|
||||
realized->data[i] = 0;
|
||||
|
||||
_gtk_bitmask_set (&realized, bit, TRUE);
|
||||
|
||||
*mask = realized;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_bitmask_realize (const GtkBitmask **mask, GtkBitmaskPrealloc *prealloc)
|
||||
{
|
||||
prealloc->orig = *mask;
|
||||
if (*mask == NULL)
|
||||
{
|
||||
prealloc->bitmask.len = 0;
|
||||
prealloc->bitmask.alloc = 4;
|
||||
*mask = &prealloc->bitmask;
|
||||
}
|
||||
else if (gtk_bitmask_is_bit (*mask))
|
||||
{
|
||||
GtkBitmask *realized;
|
||||
int i;
|
||||
guint bit = gtk_bitmask_get_bit (*mask);
|
||||
guint len = (bit / VALUE_SIZE_BITS) + 1;
|
||||
|
||||
if (len <= 4)
|
||||
{
|
||||
prealloc->bitmask.alloc = 4;
|
||||
realized = &prealloc->bitmask;
|
||||
}
|
||||
else
|
||||
realized = _gtk_bitmask_allocate (len);
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
realized->data[i] = 0;
|
||||
realized->len = len;
|
||||
|
||||
_gtk_bitmask_set (&realized, bit, TRUE);
|
||||
|
||||
*mask = realized;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bitmask_unrealize (const GtkBitmask *mask, GtkBitmaskPrealloc *prealloc)
|
||||
{
|
||||
if (mask != prealloc->orig &&
|
||||
mask != &prealloc->bitmask)
|
||||
g_free ((GtkBitmask *)mask);
|
||||
}
|
||||
|
||||
GtkBitmask *
|
||||
_gtk_bitmask_new (void)
|
||||
{
|
||||
return g_array_new (FALSE, TRUE, sizeof (VALUE_TYPE));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkBitmask *
|
||||
@@ -39,10 +191,11 @@ _gtk_bitmask_copy (const GtkBitmask *mask)
|
||||
{
|
||||
GtkBitmask *copy;
|
||||
|
||||
g_return_val_if_fail (mask != NULL, NULL);
|
||||
if (gtk_bitmask_is_inline (mask))
|
||||
return (GtkBitmask *)mask;
|
||||
|
||||
copy = _gtk_bitmask_new ();
|
||||
_gtk_bitmask_union (copy, mask);
|
||||
_gtk_bitmask_union (©, mask);
|
||||
|
||||
return copy;
|
||||
}
|
||||
@@ -50,29 +203,31 @@ _gtk_bitmask_copy (const GtkBitmask *mask)
|
||||
void
|
||||
_gtk_bitmask_free (GtkBitmask *mask)
|
||||
{
|
||||
g_return_if_fail (mask != NULL);
|
||||
|
||||
g_array_free (mask, TRUE);
|
||||
if (!gtk_bitmask_is_inline (mask))
|
||||
g_free (mask);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_print (const GtkBitmask *mask,
|
||||
GString *string)
|
||||
GString *string)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
int i;
|
||||
|
||||
g_return_if_fail (mask != NULL);
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
|
||||
g_return_if_fail (string != NULL);
|
||||
|
||||
for (i = mask->len * VALUE_SIZE_BITS - 1; i >= 0; i--)
|
||||
{
|
||||
if (_gtk_bitmask_get (mask, i))
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 0)
|
||||
{
|
||||
g_string_append_c (string, '0');
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -80,13 +235,15 @@ _gtk_bitmask_print (const GtkBitmask *mask,
|
||||
{
|
||||
g_string_append_c (string, _gtk_bitmask_get (mask, i) ? '1' : '0');
|
||||
}
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -97,74 +254,139 @@ _gtk_bitmask_to_string (const GtkBitmask *mask)
|
||||
* _gtk_bitmask_is_empty() depends on this.
|
||||
*/
|
||||
static void
|
||||
gtk_bitmask_shrink (GtkBitmask *mask)
|
||||
gtk_bitmask_shrink (GtkBitmask **mask)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = mask->len; i; i--)
|
||||
if (gtk_bitmask_is_inline (*mask))
|
||||
return;
|
||||
|
||||
for (i = (*mask)->len; i; i--)
|
||||
{
|
||||
if (g_array_index (mask, VALUE_TYPE, i - 1))
|
||||
break;
|
||||
if ((*mask)->data[i - 1])
|
||||
break;
|
||||
}
|
||||
|
||||
g_array_set_size (mask, i);
|
||||
if (i == 0)
|
||||
{
|
||||
g_free (*mask);
|
||||
*mask = NULL;
|
||||
}
|
||||
else
|
||||
(*mask)->len = i;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_intersect (GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
_gtk_bitmask_intersect (GtkBitmask **mask,
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
GtkBitmaskPrealloc other_prealloc;
|
||||
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++)
|
||||
if (gtk_bitmask_is_inline (*mask) &&
|
||||
gtk_bitmask_is_inline (other))
|
||||
{
|
||||
g_array_index (mask, VALUE_TYPE, i) &= g_array_index (other, VALUE_TYPE, i);
|
||||
if (mask == NULL || other == NULL)
|
||||
*mask = NULL;
|
||||
else
|
||||
{
|
||||
/* Different bits, the intersection is empty */
|
||||
if (*mask != other)
|
||||
*mask = NULL;
|
||||
/* If same bit, the value is already right */
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_bitmask_realize (&other, &other_prealloc);
|
||||
gtk_bitmask_realize_for_write (mask, 0);
|
||||
|
||||
_gtk_bitmask_resize (mask, MIN ((*mask)->len, other->len));
|
||||
for (i = 0; i < (*mask)->len; i++)
|
||||
(*mask)->data[i] &= other->data[i];
|
||||
|
||||
gtk_bitmask_shrink (mask);
|
||||
|
||||
gtk_bitmask_unrealize (other, &other_prealloc);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_union (GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
_gtk_bitmask_union (GtkBitmask **mask,
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
GtkBitmaskPrealloc other_prealloc;
|
||||
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++)
|
||||
if (gtk_bitmask_is_inline (*mask) &&
|
||||
gtk_bitmask_is_inline (other))
|
||||
{
|
||||
g_array_index (mask, VALUE_TYPE, i) |= g_array_index (other, VALUE_TYPE, i);
|
||||
/* Union nothing with something is something */
|
||||
if (*mask == NULL)
|
||||
{
|
||||
*mask = (GtkBitmask *)other;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Union with nothing or same is same */
|
||||
if (other == NULL ||
|
||||
*mask == other)
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_bitmask_realize (&other, &other_prealloc);
|
||||
gtk_bitmask_realize_for_write (mask, other->len);
|
||||
|
||||
_gtk_bitmask_resize (mask, MAX ((*mask)->len, other->len));
|
||||
for (i = 0; i < other->len; i++)
|
||||
(*mask)->data[i] |= other->data[i];
|
||||
|
||||
gtk_bitmask_unrealize (other, &other_prealloc);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_subtract (GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
_gtk_bitmask_subtract (GtkBitmask **mask,
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
GtkBitmaskPrealloc other_prealloc;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (mask != NULL);
|
||||
g_return_if_fail (other != NULL);
|
||||
|
||||
if (gtk_bitmask_is_inline (*mask) &&
|
||||
gtk_bitmask_is_inline (other))
|
||||
{
|
||||
/* Subtract from nothing, or subtract nothing => no change */
|
||||
if (*mask == NULL ||
|
||||
other == NULL)
|
||||
return;
|
||||
|
||||
/* Subtract the same bit => nothing */
|
||||
if (*mask == other)
|
||||
*mask = NULL;
|
||||
/* Subtract other bit => no change */
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_bitmask_realize (&other, &other_prealloc);
|
||||
gtk_bitmask_realize_for_write (mask, 0);
|
||||
|
||||
for (i = 0; i < other->len; i++)
|
||||
{
|
||||
g_array_index (mask, VALUE_TYPE, i) &= ~g_array_index (other, VALUE_TYPE, i);
|
||||
}
|
||||
(*mask)->data[i] &= ~(other->data[i]);
|
||||
|
||||
gtk_bitmask_shrink (mask);
|
||||
|
||||
gtk_bitmask_unrealize (other, &other_prealloc);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_bitmask_indexes (guint index_,
|
||||
guint *array_index,
|
||||
guint *bit_index)
|
||||
guint *array_index,
|
||||
guint *bit_index)
|
||||
{
|
||||
*array_index = index_ / VALUE_SIZE_BITS;
|
||||
*bit_index = index_ % VALUE_SIZE_BITS;
|
||||
@@ -172,52 +394,79 @@ gtk_bitmask_indexes (guint index_,
|
||||
|
||||
gboolean
|
||||
_gtk_bitmask_get (const GtkBitmask *mask,
|
||||
guint index_)
|
||||
guint index_)
|
||||
{
|
||||
guint array_index, bit_index;
|
||||
|
||||
g_return_val_if_fail (mask != NULL, FALSE);
|
||||
if (mask == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (gtk_bitmask_is_bit (mask))
|
||||
{
|
||||
guint bit = gtk_bitmask_get_bit (mask);
|
||||
if (bit == index_)
|
||||
return TRUE;
|
||||
else
|
||||
return 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;
|
||||
return (mask->data[array_index] & VALUE_BIT (bit_index)) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_set (GtkBitmask *mask,
|
||||
guint index_,
|
||||
gboolean value)
|
||||
_gtk_bitmask_set (GtkBitmask **mask,
|
||||
guint index_,
|
||||
gboolean value)
|
||||
{
|
||||
guint array_index, bit_index;
|
||||
|
||||
g_return_if_fail (mask != NULL);
|
||||
|
||||
if (*mask == NULL)
|
||||
{
|
||||
if (value)
|
||||
*mask = gtk_bitmask_for_bit (index_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gtk_bitmask_is_bit (*mask) &&
|
||||
gtk_bitmask_get_bit (*mask) == index_)
|
||||
{
|
||||
if (!value)
|
||||
*mask = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_bitmask_realize_for_write (mask, 0);
|
||||
|
||||
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);
|
||||
if (array_index >= (*mask)->len)
|
||||
_gtk_bitmask_resize (mask, array_index + 1);
|
||||
|
||||
(*mask)->data[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);
|
||||
}
|
||||
if (array_index < (*mask)->len)
|
||||
{
|
||||
(*mask)->data[array_index] &= ~ VALUE_BIT (bit_index);
|
||||
gtk_bitmask_shrink (mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_invert_range (GtkBitmask *mask,
|
||||
guint start,
|
||||
guint end)
|
||||
_gtk_bitmask_invert_range (GtkBitmask **mask,
|
||||
guint start,
|
||||
guint end)
|
||||
{
|
||||
guint i;
|
||||
|
||||
@@ -227,53 +476,231 @@ _gtk_bitmask_invert_range (GtkBitmask *mask,
|
||||
/* I CAN HAS SPEEDUP? */
|
||||
|
||||
for (i = start; i < end; i++)
|
||||
_gtk_bitmask_set (mask, i, !_gtk_bitmask_get (mask, 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;
|
||||
return mask == NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_bitmask_equals (const GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
GtkBitmaskPrealloc other_prealloc;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (mask != NULL, FALSE);
|
||||
g_return_val_if_fail (other != NULL, FALSE);
|
||||
if (gtk_bitmask_is_inline (mask) &&
|
||||
gtk_bitmask_is_inline (other))
|
||||
return mask == other;
|
||||
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
gtk_bitmask_realize (&other, &other_prealloc);
|
||||
|
||||
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;
|
||||
if (mask->data[i] != other->data[i])
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
gtk_bitmask_unrealize (other, &other_prealloc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_bitmask_intersects (const GtkBitmask *mask,
|
||||
const GtkBitmask *other)
|
||||
const GtkBitmask *other)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
GtkBitmaskPrealloc other_prealloc;
|
||||
int i;
|
||||
gboolean res;
|
||||
|
||||
g_return_val_if_fail (mask != NULL, FALSE);
|
||||
g_return_val_if_fail (other != NULL, FALSE);
|
||||
if (gtk_bitmask_is_inline (mask) &&
|
||||
gtk_bitmask_is_inline (other))
|
||||
{
|
||||
if (mask == NULL || other == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (mask == other)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
gtk_bitmask_realize (&other, &other_prealloc);
|
||||
|
||||
res = 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;
|
||||
if (mask->data[i] & other->data[i])
|
||||
{
|
||||
res = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
gtk_bitmask_unrealize (other, &other_prealloc);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_clear (GtkBitmask **mask)
|
||||
{
|
||||
_gtk_bitmask_free (*mask);
|
||||
*mask = NULL;
|
||||
}
|
||||
|
||||
guint
|
||||
_gtk_bitmask_get_uint (const GtkBitmask *mask,
|
||||
guint index_)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
guint array_index, bit_index;
|
||||
VALUE_TYPE value1, value2;
|
||||
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
|
||||
gtk_bitmask_indexes (index_, &array_index, &bit_index);
|
||||
|
||||
value1 = value2 = 0;
|
||||
if (array_index < mask->len)
|
||||
value1 = mask->data[array_index];
|
||||
if (array_index + 1 < mask->len)
|
||||
value2 = mask->data[array_index + 1];
|
||||
|
||||
value1 >>= bit_index;
|
||||
if (bit_index != 0)
|
||||
value2 <<= VALUE_SIZE_BITS - bit_index;
|
||||
else
|
||||
value2 = 0;
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
|
||||
return (guint)(value1 | value2);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_bitmask_set_uint (GtkBitmask **mask,
|
||||
guint index_,
|
||||
guint bits)
|
||||
{
|
||||
guint array_index, bit_index;
|
||||
VALUE_TYPE value1, value2;
|
||||
VALUE_TYPE new_value1, new_value2;
|
||||
|
||||
g_return_if_fail (mask != NULL);
|
||||
|
||||
gtk_bitmask_realize_for_write (mask, 0);
|
||||
|
||||
gtk_bitmask_indexes (index_, &array_index, &bit_index);
|
||||
|
||||
value1 = value2 = 0;
|
||||
if (array_index < (*mask)->len)
|
||||
value1 = (*mask)->data[array_index];
|
||||
if (array_index + 1 < (*mask)->len)
|
||||
value2 = (*mask)->data[array_index + 1];
|
||||
|
||||
/* Mask out old uint value */
|
||||
new_value1 = ((VALUE_TYPE)G_MAXUINT) << bit_index;
|
||||
if (bit_index != 0)
|
||||
new_value2 = ((VALUE_TYPE)G_MAXUINT) >> (VALUE_SIZE_BITS - bit_index);
|
||||
else
|
||||
new_value2 = 0;
|
||||
value1 &= ~new_value1;
|
||||
value2 &= ~new_value2;
|
||||
|
||||
/* merge in new uint value */
|
||||
new_value1 = ((VALUE_TYPE)bits) << bit_index;
|
||||
if (bit_index != 0)
|
||||
new_value2 = ((VALUE_TYPE)bits) >> (VALUE_SIZE_BITS - bit_index);
|
||||
else
|
||||
new_value2 = 0;
|
||||
value1 |= new_value1;
|
||||
value2 |= new_value2;
|
||||
|
||||
/* Ensure there is space to write back */
|
||||
_gtk_bitmask_resize (mask, MAX ((*mask)->len, array_index + 2));
|
||||
|
||||
(*mask)->data[array_index] = value1;
|
||||
(*mask)->data[array_index + 1] = value2;
|
||||
|
||||
gtk_bitmask_shrink (mask);
|
||||
}
|
||||
|
||||
guint
|
||||
_gtk_bitmask_hash (const GtkBitmask *mask)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
int i;
|
||||
VALUE_TYPE value, hash;
|
||||
|
||||
if (mask == NULL)
|
||||
return 0;
|
||||
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
|
||||
hash = 0;
|
||||
|
||||
for (i = mask->len - 1; i >= 0; i--)
|
||||
{
|
||||
value = mask->data[i];
|
||||
hash = hash ^ value;
|
||||
}
|
||||
|
||||
if (sizeof (hash) > sizeof (guint))
|
||||
hash = hash ^ (hash >> 32);
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_bitmask_find_next_set (const GtkBitmask *mask,
|
||||
guint *pos)
|
||||
{
|
||||
GtkBitmaskPrealloc mask_prealloc;
|
||||
guint array_index, bit_index;
|
||||
VALUE_TYPE value;
|
||||
|
||||
if (mask == NULL)
|
||||
return FALSE;
|
||||
|
||||
gtk_bitmask_realize (&mask, &mask_prealloc);
|
||||
|
||||
gtk_bitmask_indexes (*pos, &array_index, &bit_index);
|
||||
|
||||
while (array_index < mask->len)
|
||||
{
|
||||
value = mask->data[array_index];
|
||||
|
||||
/* TODO: This could use ffsl if bit_index == 0 */
|
||||
while (bit_index < VALUE_SIZE_BITS)
|
||||
{
|
||||
if (value & VALUE_BIT (bit_index))
|
||||
{
|
||||
*pos = array_index * VALUE_SIZE_BITS + bit_index;
|
||||
return TRUE;
|
||||
}
|
||||
bit_index++;
|
||||
}
|
||||
array_index++;
|
||||
bit_index = 0;
|
||||
}
|
||||
|
||||
gtk_bitmask_unrealize (mask, &mask_prealloc);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@@ -25,11 +25,7 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef GTK_INSIDE_BITMASK_C
|
||||
typedef GArray GtkBitmask;
|
||||
#else
|
||||
typedef struct _GtkBitmask GtkBitmask;
|
||||
#endif
|
||||
|
||||
|
||||
GtkBitmask * _gtk_bitmask_new (void);
|
||||
@@ -40,20 +36,26 @@ char * _gtk_bitmask_to_string (const GtkBitmask *mask);
|
||||
void _gtk_bitmask_print (const GtkBitmask *mask,
|
||||
GString *string);
|
||||
|
||||
void _gtk_bitmask_intersect (GtkBitmask *mask,
|
||||
void _gtk_bitmask_intersect (GtkBitmask **mask,
|
||||
const GtkBitmask *other);
|
||||
void _gtk_bitmask_union (GtkBitmask *mask,
|
||||
void _gtk_bitmask_union (GtkBitmask **mask,
|
||||
const GtkBitmask *other);
|
||||
void _gtk_bitmask_subtract (GtkBitmask *mask,
|
||||
void _gtk_bitmask_subtract (GtkBitmask **mask,
|
||||
const GtkBitmask *other);
|
||||
|
||||
gboolean _gtk_bitmask_get (const GtkBitmask *mask,
|
||||
guint index_);
|
||||
void _gtk_bitmask_set (GtkBitmask *mask,
|
||||
void _gtk_bitmask_set (GtkBitmask **mask,
|
||||
guint index_,
|
||||
gboolean value);
|
||||
void _gtk_bitmask_clear (GtkBitmask **mask);
|
||||
guint _gtk_bitmask_get_uint (const GtkBitmask *mask,
|
||||
guint index_);
|
||||
void _gtk_bitmask_set_uint (GtkBitmask **mask,
|
||||
guint index_,
|
||||
guint bits);
|
||||
|
||||
void _gtk_bitmask_invert_range (GtkBitmask *mask,
|
||||
void _gtk_bitmask_invert_range (GtkBitmask **mask,
|
||||
guint start,
|
||||
guint end);
|
||||
|
||||
@@ -62,6 +64,9 @@ gboolean _gtk_bitmask_equals (const GtkBitmask *mask,
|
||||
const GtkBitmask *other);
|
||||
gboolean _gtk_bitmask_intersects (const GtkBitmask *mask,
|
||||
const GtkBitmask *other);
|
||||
guint _gtk_bitmask_hash (const GtkBitmask *mask);
|
||||
gboolean _gtk_bitmask_find_next_set (const GtkBitmask *mask,
|
||||
guint *pos);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -45,7 +45,7 @@ _gtk_css_lookup_new (void)
|
||||
|
||||
lookup = g_malloc0 (sizeof (GtkCssLookup) + sizeof (GtkCssLookupValue) * n);
|
||||
lookup->missing = _gtk_bitmask_new ();
|
||||
_gtk_bitmask_invert_range (lookup->missing, 0, n);
|
||||
_gtk_bitmask_invert_range (&lookup->missing, 0, n);
|
||||
|
||||
return lookup;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ _gtk_css_lookup_set (GtkCssLookup *lookup,
|
||||
g_return_if_fail (_gtk_bitmask_get (lookup->missing, id));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
_gtk_bitmask_set (lookup->missing, id, FALSE);
|
||||
_gtk_bitmask_set (&lookup->missing, id, FALSE);
|
||||
lookup->values[id].value = value;
|
||||
lookup->values[id].section = section;
|
||||
}
|
||||
@@ -133,7 +133,7 @@ _gtk_css_lookup_set_computed (GtkCssLookup *lookup,
|
||||
g_return_if_fail (_gtk_bitmask_get (lookup->missing, id));
|
||||
g_return_if_fail (value != NULL);
|
||||
|
||||
_gtk_bitmask_set (lookup->missing, id, FALSE);
|
||||
_gtk_bitmask_set (&lookup->missing, id, FALSE);
|
||||
lookup->values[id].computed = value;
|
||||
lookup->values[id].section = section;
|
||||
}
|
||||
|
@@ -1216,7 +1216,7 @@ gtk_css_ruleset_add (GtkCssRuleset *ruleset,
|
||||
g_return_if_fail (_gtk_css_style_property_is_specified_type (GTK_CSS_STYLE_PROPERTY (prop),
|
||||
G_VALUE_TYPE (&value->value)));
|
||||
|
||||
_gtk_bitmask_set (ruleset->set_styles,
|
||||
_gtk_bitmask_set (&ruleset->set_styles,
|
||||
_gtk_css_style_property_get_id (GTK_CSS_STYLE_PROPERTY (prop)),
|
||||
TRUE);
|
||||
g_hash_table_insert (ruleset->style, prop, value);
|
||||
|
@@ -307,12 +307,6 @@ typedef struct PropertyValue PropertyValue;
|
||||
typedef struct AnimationInfo AnimationInfo;
|
||||
typedef struct StyleData StyleData;
|
||||
|
||||
struct GtkRegion
|
||||
{
|
||||
GQuark class_quark;
|
||||
GtkRegionFlags flags;
|
||||
};
|
||||
|
||||
struct GtkStyleProviderData
|
||||
{
|
||||
GtkStyleProvider *provider;
|
||||
@@ -329,8 +323,8 @@ struct PropertyValue
|
||||
|
||||
struct GtkStyleInfo
|
||||
{
|
||||
GArray *style_classes;
|
||||
GArray *regions;
|
||||
GtkBitmask *style_classes;
|
||||
GtkBitmask *regions;
|
||||
GtkJunctionSides junction_sides;
|
||||
GtkStateFlags state_flags;
|
||||
};
|
||||
@@ -477,8 +471,8 @@ style_info_new (void)
|
||||
GtkStyleInfo *info;
|
||||
|
||||
info = g_slice_new0 (GtkStyleInfo);
|
||||
info->style_classes = g_array_new (FALSE, FALSE, sizeof (GQuark));
|
||||
info->regions = g_array_new (FALSE, FALSE, sizeof (GtkRegion));
|
||||
info->style_classes = _gtk_bitmask_new ();
|
||||
info->regions = _gtk_bitmask_new ();
|
||||
|
||||
return info;
|
||||
}
|
||||
@@ -486,8 +480,8 @@ style_info_new (void)
|
||||
static void
|
||||
style_info_free (GtkStyleInfo *info)
|
||||
{
|
||||
g_array_free (info->style_classes, TRUE);
|
||||
g_array_free (info->regions, TRUE);
|
||||
_gtk_bitmask_free (info->style_classes);
|
||||
_gtk_bitmask_free (info->regions);
|
||||
g_slice_free (GtkStyleInfo, info);
|
||||
}
|
||||
|
||||
@@ -497,13 +491,10 @@ style_info_copy (const GtkStyleInfo *info)
|
||||
GtkStyleInfo *copy;
|
||||
|
||||
copy = style_info_new ();
|
||||
g_array_insert_vals (copy->style_classes, 0,
|
||||
info->style_classes->data,
|
||||
info->style_classes->len);
|
||||
|
||||
g_array_insert_vals (copy->regions, 0,
|
||||
info->regions->data,
|
||||
info->regions->len);
|
||||
_gtk_bitmask_union (©->style_classes,
|
||||
info->style_classes);
|
||||
_gtk_bitmask_union (©->regions,
|
||||
info->regions);
|
||||
|
||||
copy->junction_sides = info->junction_sides;
|
||||
copy->state_flags = info->state_flags;
|
||||
@@ -515,25 +506,12 @@ static guint
|
||||
style_info_hash (gconstpointer elem)
|
||||
{
|
||||
const GtkStyleInfo *info;
|
||||
guint i, hash = 0;
|
||||
guint hash = 0;
|
||||
|
||||
info = elem;
|
||||
|
||||
for (i = 0; i < info->style_classes->len; i++)
|
||||
{
|
||||
hash += g_array_index (info->style_classes, GQuark, i);
|
||||
hash <<= 5;
|
||||
}
|
||||
|
||||
for (i = 0; i < info->regions->len; i++)
|
||||
{
|
||||
GtkRegion *region;
|
||||
|
||||
region = &g_array_index (info->regions, GtkRegion, i);
|
||||
hash += region->class_quark;
|
||||
hash += region->flags;
|
||||
hash <<= 5;
|
||||
}
|
||||
hash = _gtk_bitmask_hash (info->style_classes);
|
||||
hash ^= _gtk_bitmask_hash (info->regions);
|
||||
|
||||
return hash ^ info->state_flags;
|
||||
}
|
||||
@@ -553,20 +531,12 @@ style_info_equal (gconstpointer elem1,
|
||||
if (info1->junction_sides != info2->junction_sides)
|
||||
return FALSE;
|
||||
|
||||
if (info1->style_classes->len != info2->style_classes->len)
|
||||
if (!_gtk_bitmask_equals (info1->style_classes,
|
||||
info2->style_classes))
|
||||
return FALSE;
|
||||
|
||||
if (memcmp (info1->style_classes->data,
|
||||
info2->style_classes->data,
|
||||
info1->style_classes->len * sizeof (GQuark)) != 0)
|
||||
return FALSE;
|
||||
|
||||
if (info1->regions->len != info2->regions->len)
|
||||
return FALSE;
|
||||
|
||||
if (memcmp (info1->regions->data,
|
||||
info2->regions->data,
|
||||
info1->regions->len * sizeof (GtkRegion)) != 0)
|
||||
if (!_gtk_bitmask_equals (info1->regions,
|
||||
info2->regions))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@@ -1034,7 +1004,7 @@ create_query_path (GtkStyleContext *context)
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkWidgetPath *path;
|
||||
GtkStyleInfo *info;
|
||||
guint i, pos;
|
||||
guint pos;
|
||||
|
||||
priv = context->priv;
|
||||
path = gtk_widget_path_copy (priv->widget_path);
|
||||
@@ -1042,26 +1012,11 @@ create_query_path (GtkStyleContext *context)
|
||||
|
||||
info = priv->info_stack->data;
|
||||
|
||||
/* Set widget regions */
|
||||
for (i = 0; i < info->regions->len; i++)
|
||||
{
|
||||
GtkRegion *region;
|
||||
|
||||
region = &g_array_index (info->regions, GtkRegion, i);
|
||||
gtk_widget_path_iter_add_region (path, pos,
|
||||
g_quark_to_string (region->class_quark),
|
||||
region->flags);
|
||||
}
|
||||
_gtk_widget_path_iter_add_regions (path, pos,
|
||||
info->regions);
|
||||
|
||||
/* Set widget classes */
|
||||
for (i = 0; i < info->style_classes->len; i++)
|
||||
{
|
||||
GQuark quark;
|
||||
|
||||
quark = g_array_index (info->style_classes, GQuark, i);
|
||||
gtk_widget_path_iter_add_class (path, pos,
|
||||
g_quark_to_string (quark));
|
||||
}
|
||||
_gtk_widget_path_iter_add_classes (path, pos, info->style_classes);
|
||||
|
||||
return path;
|
||||
}
|
||||
@@ -1861,96 +1816,79 @@ gtk_style_context_restore (GtkStyleContext *context)
|
||||
priv->current_data = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
style_class_find (GArray *array,
|
||||
GQuark class_quark,
|
||||
guint *position)
|
||||
static GHashTable *style_class_masks;
|
||||
static GPtrArray *style_class_masks_reverse;
|
||||
static guint style_class_masks_next;
|
||||
static GHashTable *style_region_masks;
|
||||
static GPtrArray *style_region_masks_reverse;
|
||||
static guint style_region_masks_next;
|
||||
|
||||
guint
|
||||
_gtk_style_class_get_mask (const gchar *class_name)
|
||||
{
|
||||
gint min, max, mid;
|
||||
gboolean found = FALSE;
|
||||
guint pos;
|
||||
guint value;
|
||||
gpointer ptr_value;
|
||||
|
||||
if (position)
|
||||
*position = 0;
|
||||
|
||||
if (!array || array->len == 0)
|
||||
return FALSE;
|
||||
|
||||
min = 0;
|
||||
max = array->len - 1;
|
||||
|
||||
do
|
||||
if (style_class_masks == NULL)
|
||||
{
|
||||
GQuark item;
|
||||
|
||||
mid = (min + max) / 2;
|
||||
item = g_array_index (array, GQuark, mid);
|
||||
|
||||
if (class_quark == item)
|
||||
{
|
||||
found = TRUE;
|
||||
pos = mid;
|
||||
}
|
||||
else if (class_quark > item)
|
||||
min = pos = mid + 1;
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
pos = mid;
|
||||
}
|
||||
style_class_masks = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
style_class_masks_reverse = g_ptr_array_new ();
|
||||
}
|
||||
while (!found && min <= max);
|
||||
|
||||
if (position)
|
||||
*position = pos;
|
||||
|
||||
return found;
|
||||
if (g_hash_table_lookup_extended (style_class_masks, class_name,
|
||||
NULL, &ptr_value))
|
||||
value = GPOINTER_TO_INT (ptr_value);
|
||||
else
|
||||
{
|
||||
char *str = (char *)g_intern_string (class_name);
|
||||
value = style_class_masks_next++;
|
||||
ptr_value = GINT_TO_POINTER (value);
|
||||
g_hash_table_insert (style_class_masks, str, ptr_value);
|
||||
g_ptr_array_add (style_class_masks_reverse, str);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
region_find (GArray *array,
|
||||
GQuark class_quark,
|
||||
guint *position)
|
||||
const gchar *
|
||||
_gtk_style_class_get_name_from_mask (guint mask)
|
||||
{
|
||||
gint min, max, mid;
|
||||
gboolean found = FALSE;
|
||||
guint pos;
|
||||
if (mask < style_class_masks_next)
|
||||
return g_ptr_array_index (style_class_masks_reverse, mask);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (position)
|
||||
*position = 0;
|
||||
guint
|
||||
_gtk_style_region_get_mask (const gchar *region_name)
|
||||
{
|
||||
guint value;
|
||||
gpointer ptr_value;
|
||||
|
||||
if (!array || array->len == 0)
|
||||
return FALSE;
|
||||
|
||||
min = 0;
|
||||
max = array->len - 1;
|
||||
|
||||
do
|
||||
if (style_region_masks == NULL)
|
||||
{
|
||||
GtkRegion *region;
|
||||
|
||||
mid = (min + max) / 2;
|
||||
region = &g_array_index (array, GtkRegion, mid);
|
||||
|
||||
if (region->class_quark == class_quark)
|
||||
{
|
||||
found = TRUE;
|
||||
pos = mid;
|
||||
}
|
||||
else if (region->class_quark > class_quark)
|
||||
min = pos = mid + 1;
|
||||
else
|
||||
{
|
||||
max = mid - 1;
|
||||
pos = mid;
|
||||
}
|
||||
style_region_masks = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
style_region_masks_reverse = g_ptr_array_new ();
|
||||
}
|
||||
while (!found && min <= max);
|
||||
|
||||
if (position)
|
||||
*position = pos;
|
||||
if (g_hash_table_lookup_extended (style_region_masks, region_name,
|
||||
NULL, &ptr_value))
|
||||
value = GPOINTER_TO_INT (ptr_value);
|
||||
else
|
||||
{
|
||||
char *str = (char *)g_intern_string (region_name);
|
||||
value = style_region_masks_next++;
|
||||
ptr_value = GINT_TO_POINTER (value);
|
||||
g_hash_table_insert (style_region_masks, str, ptr_value);
|
||||
g_ptr_array_add (style_region_masks_reverse, str);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
return found;
|
||||
const gchar *
|
||||
_gtk_style_region_get_name_from_mask (guint mask)
|
||||
{
|
||||
if (mask < style_region_masks_next)
|
||||
return g_ptr_array_index (style_region_masks_reverse, mask);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1983,21 +1921,20 @@ gtk_style_context_add_class (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark class_quark;
|
||||
guint position;
|
||||
guint class_mask;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (class_name != NULL);
|
||||
|
||||
priv = context->priv;
|
||||
class_quark = g_quark_from_string (class_name);
|
||||
class_mask = _gtk_style_class_get_mask (class_name);
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (!style_class_find (info->style_classes, class_quark, &position))
|
||||
if (!_gtk_bitmask_get (info->style_classes, class_mask))
|
||||
{
|
||||
g_array_insert_val (info->style_classes, position, class_quark);
|
||||
_gtk_bitmask_set (&info->style_classes, class_mask, TRUE);
|
||||
|
||||
/* Unset current data, as it likely changed due to the class change */
|
||||
priv->current_data = NULL;
|
||||
@@ -2019,25 +1956,21 @@ gtk_style_context_remove_class (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark class_quark;
|
||||
guint position;
|
||||
guint class_mask;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (class_name != NULL);
|
||||
|
||||
class_quark = g_quark_try_string (class_name);
|
||||
|
||||
if (!class_quark)
|
||||
return;
|
||||
class_mask = _gtk_style_class_get_mask (class_name);
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (style_class_find (info->style_classes, class_quark, &position))
|
||||
if (_gtk_bitmask_get (info->style_classes, class_mask))
|
||||
{
|
||||
g_array_remove_index (info->style_classes, position);
|
||||
_gtk_bitmask_set (&info->style_classes, class_mask, FALSE);
|
||||
|
||||
/* Unset current data, as it likely changed due to the class change */
|
||||
priv->current_data = NULL;
|
||||
@@ -2062,25 +1995,19 @@ gtk_style_context_has_class (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark class_quark;
|
||||
guint class_mask;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (class_name != NULL, FALSE);
|
||||
|
||||
class_quark = g_quark_try_string (class_name);
|
||||
|
||||
if (!class_quark)
|
||||
return FALSE;
|
||||
class_mask = _gtk_style_class_get_mask (class_name);
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (style_class_find (info->style_classes, class_quark, NULL))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
return _gtk_bitmask_get (info->style_classes, class_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2111,12 +2038,12 @@ gtk_style_context_list_classes (GtkStyleContext *context)
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
for (i = 0; i < info->style_classes->len; i++)
|
||||
i = 0;
|
||||
while (_gtk_bitmask_find_next_set (info->style_classes, &i))
|
||||
{
|
||||
GQuark quark;
|
||||
|
||||
quark = g_array_index (info->style_classes, GQuark, i);
|
||||
classes = g_list_prepend (classes, (gchar *) g_quark_to_string (quark));
|
||||
classes = g_list_prepend (classes,
|
||||
(gchar *) _gtk_style_class_get_name_from_mask (i));
|
||||
i++;
|
||||
}
|
||||
|
||||
return classes;
|
||||
@@ -2150,15 +2077,16 @@ gtk_style_context_list_regions (GtkStyleContext *context)
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
for (i = 0; i < info->regions->len; i++)
|
||||
i = 0;
|
||||
while (_gtk_bitmask_find_next_set (info->regions, &i))
|
||||
{
|
||||
GtkRegion *region;
|
||||
const gchar *class_name;
|
||||
guint region = i / GTK_REGION_FLAGS_NUM_BITS;
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
region = &g_array_index (info->regions, GtkRegion, i);
|
||||
classes = g_list_prepend (classes,
|
||||
(gchar *)_gtk_style_region_get_name_from_mask (region));
|
||||
|
||||
class_name = g_quark_to_string (region->class_quark);
|
||||
classes = g_list_prepend (classes, (gchar *) class_name);
|
||||
i += GTK_REGION_FLAGS_NUM_BITS;
|
||||
}
|
||||
|
||||
return classes;
|
||||
@@ -2222,27 +2150,29 @@ gtk_style_context_add_region (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark region_quark;
|
||||
guint position;
|
||||
guint region;
|
||||
guint i;
|
||||
guint old_flags;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (region_name != NULL);
|
||||
g_return_if_fail (_gtk_style_context_check_region_name (region_name));
|
||||
|
||||
priv = context->priv;
|
||||
region_quark = g_quark_from_string (region_name);
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (!region_find (info->regions, region_quark, &position))
|
||||
region = _gtk_style_region_get_mask (region_name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
old_flags = _gtk_bitmask_get_uint (info->regions, i);
|
||||
if ((old_flags & GTK_REGION_ADDED) == 0)
|
||||
{
|
||||
GtkRegion region;
|
||||
/* Ensure *some* flag is always set so we know this is added */
|
||||
old_flags |= flags | GTK_REGION_ADDED;
|
||||
|
||||
region.class_quark = region_quark;
|
||||
region.flags = flags;
|
||||
|
||||
g_array_insert_val (info->regions, position, region);
|
||||
_gtk_bitmask_set_uint (&info->regions, i, old_flags);
|
||||
|
||||
/* Unset current data, as it likely changed due to the region change */
|
||||
priv->current_data = NULL;
|
||||
@@ -2264,25 +2194,28 @@ gtk_style_context_remove_region (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark region_quark;
|
||||
guint position;
|
||||
guint region;
|
||||
guint i, old_flags;
|
||||
|
||||
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
|
||||
g_return_if_fail (region_name != NULL);
|
||||
|
||||
region_quark = g_quark_try_string (region_name);
|
||||
|
||||
if (!region_quark)
|
||||
return;
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (region_find (info->regions, region_quark, &position))
|
||||
region = _gtk_style_region_get_mask (region_name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
if (info->regions == NULL)
|
||||
return;
|
||||
|
||||
old_flags = _gtk_bitmask_get_uint (info->regions, i);
|
||||
if ((old_flags & GTK_REGION_ADDED) != 0)
|
||||
{
|
||||
g_array_remove_index (info->regions, position);
|
||||
old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED);
|
||||
_gtk_bitmask_set_uint (&info->regions, i, old_flags);
|
||||
|
||||
/* Unset current data, as it likely changed due to the region change */
|
||||
priv->current_data = NULL;
|
||||
@@ -2310,8 +2243,8 @@ gtk_style_context_has_region (GtkStyleContext *context,
|
||||
{
|
||||
GtkStyleContextPrivate *priv;
|
||||
GtkStyleInfo *info;
|
||||
GQuark region_quark;
|
||||
guint position;
|
||||
guint region;
|
||||
guint i, flags;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), FALSE);
|
||||
g_return_val_if_fail (region_name != NULL, FALSE);
|
||||
@@ -2319,25 +2252,19 @@ gtk_style_context_has_region (GtkStyleContext *context,
|
||||
if (flags_return)
|
||||
*flags_return = 0;
|
||||
|
||||
region_quark = g_quark_try_string (region_name);
|
||||
|
||||
if (!region_quark)
|
||||
return FALSE;
|
||||
|
||||
priv = context->priv;
|
||||
|
||||
g_assert (priv->info_stack != NULL);
|
||||
info = priv->info_stack->data;
|
||||
|
||||
if (region_find (info->regions, region_quark, &position))
|
||||
region = _gtk_style_region_get_mask (region_name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
flags = _gtk_bitmask_get_uint (info->regions, i);
|
||||
if ((flags & GTK_REGION_ADDED) != 0)
|
||||
{
|
||||
if (flags_return)
|
||||
{
|
||||
GtkRegion *region;
|
||||
|
||||
region = &g_array_index (info->regions, GtkRegion, position);
|
||||
*flags_return = region->flags;
|
||||
}
|
||||
*flags_return = flags & GTK_REGION_FLAGS_MASK;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@
|
||||
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtksymboliccolor.h"
|
||||
#include "gtkbitmaskprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -46,6 +47,22 @@ void _gtk_style_context_get_cursor_color (GtkStyleContext *c
|
||||
GdkRGBA *primary_color,
|
||||
GdkRGBA *secondary_color);
|
||||
|
||||
guint _gtk_style_class_get_mask (const gchar *class_name);
|
||||
const gchar * _gtk_style_class_get_name_from_mask (guint mask);
|
||||
guint _gtk_style_region_get_mask (const gchar *region_name);
|
||||
const gchar * _gtk_style_region_get_name_from_mask (guint mask);
|
||||
|
||||
void _gtk_widget_path_iter_add_classes (GtkWidgetPath *path,
|
||||
gint pos,
|
||||
GtkBitmask *classes);
|
||||
void _gtk_widget_path_iter_add_regions (GtkWidgetPath *path,
|
||||
gint pos,
|
||||
GtkBitmask *regions);
|
||||
|
||||
#define GTK_REGION_FLAGS_MASK ((1 << 6) - 1)
|
||||
#define GTK_REGION_FLAGS_NUM_BITS 7
|
||||
#define GTK_REGION_ADDED (1 << 6)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STYLE_CONTEXT_PRIVATE_H__ */
|
||||
|
@@ -91,8 +91,8 @@ struct GtkPathElement
|
||||
{
|
||||
GType type;
|
||||
GQuark name;
|
||||
GHashTable *regions;
|
||||
GArray *classes;
|
||||
GtkBitmask *regions;
|
||||
GtkBitmask *classes;
|
||||
GtkWidgetPath *siblings;
|
||||
guint sibling_index;
|
||||
};
|
||||
@@ -137,23 +137,8 @@ gtk_path_element_copy (GtkPathElement *dest,
|
||||
dest->siblings = gtk_widget_path_ref (src->siblings);
|
||||
dest->sibling_index = src->sibling_index;
|
||||
|
||||
if (src->regions)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, src->regions);
|
||||
dest->regions = g_hash_table_new (NULL, NULL);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
g_hash_table_insert (dest->regions, key, value);
|
||||
}
|
||||
|
||||
if (src->classes)
|
||||
{
|
||||
dest->classes = g_array_new (FALSE, FALSE, sizeof (GQuark));
|
||||
g_array_append_vals (dest->classes, src->classes->data, src->classes->len);
|
||||
}
|
||||
dest->regions = _gtk_bitmask_copy (src->regions);
|
||||
dest->classes = _gtk_bitmask_copy (src->classes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,11 +220,8 @@ gtk_widget_path_unref (GtkWidgetPath *path)
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, i);
|
||||
|
||||
if (elem->regions)
|
||||
g_hash_table_destroy (elem->regions);
|
||||
|
||||
if (elem->classes)
|
||||
g_array_free (elem->classes, TRUE);
|
||||
_gtk_bitmask_free (elem->regions);
|
||||
_gtk_bitmask_free (elem->classes);
|
||||
|
||||
if (elem->siblings)
|
||||
gtk_widget_path_unref (elem->siblings);
|
||||
@@ -304,7 +286,8 @@ char *
|
||||
gtk_widget_path_to_string (const GtkWidgetPath *path)
|
||||
{
|
||||
GString *string;
|
||||
guint i, j;
|
||||
guint i, j, k;
|
||||
guint pos;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
@@ -336,22 +319,23 @@ gtk_widget_path_to_string (const GtkWidgetPath *path)
|
||||
|
||||
if (elem->classes)
|
||||
{
|
||||
for (j = 0; j < elem->classes->len; j++)
|
||||
{
|
||||
pos = 0;
|
||||
while (_gtk_bitmask_find_next_set (elem->classes, &pos))
|
||||
{
|
||||
g_string_append_c (string, '.');
|
||||
g_string_append (string, g_quark_to_string (g_array_index (elem->classes, GQuark, j)));
|
||||
}
|
||||
g_string_append (string,
|
||||
_gtk_style_class_get_name_from_mask (pos));
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->regions)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_hash_table_iter_init (&iter, elem->regions);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
GtkRegionFlags flags = GPOINTER_TO_UINT (value);
|
||||
k = 0;
|
||||
while (_gtk_bitmask_find_next_set (elem->regions, &k))
|
||||
{
|
||||
guint region = k / GTK_REGION_FLAGS_NUM_BITS;
|
||||
guint flags;
|
||||
static const char *flag_names[] = {
|
||||
"even",
|
||||
"odd",
|
||||
@@ -361,8 +345,12 @@ gtk_widget_path_to_string (const GtkWidgetPath *path)
|
||||
"sorted"
|
||||
};
|
||||
|
||||
k = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
flags = _gtk_bitmask_get_uint (elem->regions, k);
|
||||
|
||||
g_string_append_c (string, ' ');
|
||||
g_string_append (string, g_quark_to_string (GPOINTER_TO_UINT (key)));
|
||||
g_string_append (string, _gtk_style_region_get_name_from_mask (region));
|
||||
for (j = 0; j < G_N_ELEMENTS(flag_names); j++)
|
||||
{
|
||||
if (flags & (1 << j))
|
||||
@@ -371,7 +359,9 @@ gtk_widget_path_to_string (const GtkWidgetPath *path)
|
||||
g_string_append (string, flag_names[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
k += GTK_REGION_FLAGS_NUM_BITS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,9 +705,6 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path,
|
||||
const gchar *name)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
gboolean added = FALSE;
|
||||
GQuark qname;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
@@ -727,33 +714,26 @@ gtk_widget_path_iter_add_class (GtkWidgetPath *path,
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
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));
|
||||
_gtk_bitmask_set (&elem->classes, _gtk_style_class_get_mask (name), TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < elem->classes->len; i++)
|
||||
{
|
||||
GQuark quark;
|
||||
void
|
||||
_gtk_widget_path_iter_add_classes (GtkWidgetPath *path,
|
||||
gint pos,
|
||||
GtkBitmask *classes)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
|
||||
quark = g_array_index (elem->classes, GQuark, i);
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
|
||||
if (qname == quark)
|
||||
{
|
||||
/* Already there */
|
||||
added = TRUE;
|
||||
break;
|
||||
}
|
||||
if (qname < quark)
|
||||
{
|
||||
g_array_insert_val (elem->classes, i, qname);
|
||||
added = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
if (!added)
|
||||
g_array_append_val (elem->classes, qname);
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
_gtk_bitmask_union (&elem->classes, classes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -773,8 +753,6 @@ gtk_widget_path_iter_remove_class (GtkWidgetPath *path,
|
||||
const gchar *name)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
GQuark qname;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
@@ -783,30 +761,9 @@ gtk_widget_path_iter_remove_class (GtkWidgetPath *path,
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
qname = g_quark_try_string (name);
|
||||
|
||||
if (qname == 0)
|
||||
return;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (!elem->classes)
|
||||
return;
|
||||
|
||||
for (i = 0; i < elem->classes->len; i++)
|
||||
{
|
||||
GQuark quark;
|
||||
|
||||
quark = g_array_index (elem->classes, GQuark, i);
|
||||
|
||||
if (quark > qname)
|
||||
break;
|
||||
else if (quark == qname)
|
||||
{
|
||||
g_array_remove_index (elem->classes, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
_gtk_bitmask_set (&elem->classes, _gtk_style_class_get_mask (name), FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -836,8 +793,7 @@ gtk_widget_path_iter_clear_classes (GtkWidgetPath *path,
|
||||
if (!elem->classes)
|
||||
return;
|
||||
|
||||
if (elem->classes->len > 0)
|
||||
g_array_remove_range (elem->classes, 0, elem->classes->len);
|
||||
_gtk_bitmask_clear (&elem->classes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -874,12 +830,11 @@ gtk_widget_path_iter_list_classes (const GtkWidgetPath *path,
|
||||
if (!elem->classes)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < elem->classes->len; i++)
|
||||
i = 0;
|
||||
while (_gtk_bitmask_find_next_set (elem->classes, &i))
|
||||
{
|
||||
GQuark quark;
|
||||
|
||||
quark = g_array_index (elem->classes, GQuark, i);
|
||||
list = g_slist_prepend (list, (gchar *) g_quark_to_string (quark));
|
||||
list = g_slist_prepend (list, (gchar *) _gtk_style_class_get_name_from_mask (i));
|
||||
i++;
|
||||
}
|
||||
|
||||
return g_slist_reverse (list);
|
||||
@@ -903,34 +858,8 @@ gtk_widget_path_iter_has_qclass (const GtkWidgetPath *path,
|
||||
gint pos,
|
||||
GQuark qname)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (path->elems->len != 0, FALSE);
|
||||
g_return_val_if_fail (qname != 0, FALSE);
|
||||
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (!elem->classes)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < elem->classes->len; i++)
|
||||
{
|
||||
GQuark quark;
|
||||
|
||||
quark = g_array_index (elem->classes, GQuark, i);
|
||||
|
||||
if (quark == qname)
|
||||
return TRUE;
|
||||
else if (quark > qname)
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return gtk_widget_path_iter_has_class (path, pos,
|
||||
g_quark_to_string (qname));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -951,7 +880,8 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path,
|
||||
gint pos,
|
||||
const gchar *name)
|
||||
{
|
||||
GQuark qname;
|
||||
GtkPathElement *elem;
|
||||
guint mask;
|
||||
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (path->elems->len != 0, FALSE);
|
||||
@@ -960,12 +890,14 @@ gtk_widget_path_iter_has_class (const GtkWidgetPath *path,
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
qname = g_quark_try_string (name);
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (qname == 0)
|
||||
if (!elem->classes)
|
||||
return FALSE;
|
||||
|
||||
return gtk_widget_path_iter_has_qclass (path, pos, qname);
|
||||
mask = _gtk_style_class_get_mask (name);
|
||||
|
||||
return _gtk_bitmask_get (elem->classes, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -991,7 +923,9 @@ gtk_widget_path_iter_add_region (GtkWidgetPath *path,
|
||||
GtkRegionFlags flags)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
GQuark qname;
|
||||
guint region;
|
||||
guint i;
|
||||
guint old_flags;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
@@ -1002,14 +936,33 @@ gtk_widget_path_iter_add_region (GtkWidgetPath *path,
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
qname = g_quark_from_string (name);
|
||||
|
||||
if (!elem->regions)
|
||||
elem->regions = g_hash_table_new (NULL, NULL);
|
||||
region = _gtk_style_region_get_mask (name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
g_hash_table_insert (elem->regions,
|
||||
GUINT_TO_POINTER (qname),
|
||||
GUINT_TO_POINTER (flags));
|
||||
old_flags = _gtk_bitmask_get_uint (elem->regions, i);
|
||||
old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED);
|
||||
/* Ensure *some* flag is always set so we know this is added */
|
||||
old_flags |= flags | GTK_REGION_ADDED;
|
||||
_gtk_bitmask_set_uint (&elem->regions, i, old_flags);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_widget_path_iter_add_regions (GtkWidgetPath *path,
|
||||
gint pos,
|
||||
GtkBitmask *regions)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
_gtk_bitmask_union (&elem->regions, regions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1029,7 +982,9 @@ gtk_widget_path_iter_remove_region (GtkWidgetPath *path,
|
||||
const gchar *name)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
GQuark qname;
|
||||
guint region;
|
||||
guint i;
|
||||
guint old_flags;
|
||||
|
||||
g_return_if_fail (path != NULL);
|
||||
g_return_if_fail (path->elems->len != 0);
|
||||
@@ -1038,15 +993,17 @@ gtk_widget_path_iter_remove_region (GtkWidgetPath *path,
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
qname = g_quark_try_string (name);
|
||||
|
||||
if (qname == 0)
|
||||
return;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (elem->regions)
|
||||
g_hash_table_remove (elem->regions, GUINT_TO_POINTER (qname));
|
||||
if (elem->regions == NULL)
|
||||
return;
|
||||
|
||||
region = _gtk_style_region_get_mask (name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
old_flags = _gtk_bitmask_get_uint (elem->regions, i);
|
||||
old_flags &= ~(GTK_REGION_FLAGS_MASK | GTK_REGION_ADDED);
|
||||
_gtk_bitmask_set_uint (&elem->regions, i, old_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1074,7 +1031,7 @@ gtk_widget_path_iter_clear_regions (GtkWidgetPath *path,
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (elem->regions)
|
||||
g_hash_table_remove_all (elem->regions);
|
||||
_gtk_bitmask_clear (&elem->regions);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1097,9 +1054,8 @@ gtk_widget_path_iter_list_regions (const GtkWidgetPath *path,
|
||||
gint pos)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
GHashTableIter iter;
|
||||
GSList *list = NULL;
|
||||
gpointer key;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
g_return_val_if_fail (path->elems->len != 0, NULL);
|
||||
@@ -1112,14 +1068,16 @@ gtk_widget_path_iter_list_regions (const GtkWidgetPath *path,
|
||||
if (!elem->regions)
|
||||
return NULL;
|
||||
|
||||
g_hash_table_iter_init (&iter, elem->regions);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
i = 0;
|
||||
while (_gtk_bitmask_find_next_set (elem->regions, &i))
|
||||
{
|
||||
GQuark qname;
|
||||
guint region = i / GTK_REGION_FLAGS_NUM_BITS;
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
qname = GPOINTER_TO_UINT (key);
|
||||
list = g_slist_prepend (list, (gchar *) g_quark_to_string (qname));
|
||||
list = g_slist_prepend (list,
|
||||
(gchar *) _gtk_style_region_get_name_from_mask (region));
|
||||
|
||||
i += GTK_REGION_FLAGS_NUM_BITS;
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -1145,30 +1103,8 @@ gtk_widget_path_iter_has_qregion (const GtkWidgetPath *path,
|
||||
GQuark qname,
|
||||
GtkRegionFlags *flags)
|
||||
{
|
||||
GtkPathElement *elem;
|
||||
gpointer value;
|
||||
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (path->elems->len != 0, FALSE);
|
||||
g_return_val_if_fail (qname != 0, FALSE);
|
||||
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (!elem->regions)
|
||||
return FALSE;
|
||||
|
||||
if (!g_hash_table_lookup_extended (elem->regions,
|
||||
GUINT_TO_POINTER (qname),
|
||||
NULL, &value))
|
||||
return FALSE;
|
||||
|
||||
if (flags)
|
||||
*flags = GPOINTER_TO_UINT (value);
|
||||
|
||||
return TRUE;
|
||||
return gtk_widget_path_iter_has_region (path, pos,
|
||||
g_quark_to_string (qname), flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1189,9 +1125,11 @@ gboolean
|
||||
gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
|
||||
gint pos,
|
||||
const gchar *name,
|
||||
GtkRegionFlags *flags)
|
||||
GtkRegionFlags *flags_return)
|
||||
{
|
||||
GQuark qname;
|
||||
GtkPathElement *elem;
|
||||
guint region;
|
||||
guint i, flags;
|
||||
|
||||
g_return_val_if_fail (path != NULL, FALSE);
|
||||
g_return_val_if_fail (path->elems->len != 0, FALSE);
|
||||
@@ -1200,12 +1138,23 @@ gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
|
||||
if (pos < 0 || pos >= path->elems->len)
|
||||
pos = path->elems->len - 1;
|
||||
|
||||
qname = g_quark_try_string (name);
|
||||
elem = &g_array_index (path->elems, GtkPathElement, pos);
|
||||
|
||||
if (qname == 0)
|
||||
if (!elem->regions)
|
||||
return FALSE;
|
||||
|
||||
return gtk_widget_path_iter_has_qregion (path, pos, qname, flags);
|
||||
region = _gtk_style_region_get_mask (name);
|
||||
i = region * GTK_REGION_FLAGS_NUM_BITS;
|
||||
|
||||
flags = _gtk_bitmask_get_uint (elem->regions, i);
|
||||
if ((flags & GTK_REGION_ADDED) != 0)
|
||||
{
|
||||
if (flags_return)
|
||||
*flags_return = flags & GTK_REGION_FLAGS_MASK;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -48,9 +48,9 @@ gtk_bitmask_new_parse (const char *string)
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (string[i] == '0')
|
||||
_gtk_bitmask_set (mask, length - i - 1, FALSE);
|
||||
_gtk_bitmask_set (&mask, length - i - 1, FALSE);
|
||||
else if (string[i] == '1')
|
||||
_gtk_bitmask_set (mask, length - i - 1, TRUE);
|
||||
_gtk_bitmask_set (&mask, length - i - 1, TRUE);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -142,12 +142,12 @@ test_set (void)
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
indexes[j] = g_test_rand_int_range (0, MAX_INDEX);
|
||||
_gtk_bitmask_set (copy, indexes[j], g_test_rand_bit ());
|
||||
_gtk_bitmask_set (©, indexes[j], g_test_rand_bit ());
|
||||
}
|
||||
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
_gtk_bitmask_set (copy, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
|
||||
_gtk_bitmask_set (©, indexes[j], _gtk_bitmask_get (mask, indexes[j]));
|
||||
}
|
||||
|
||||
assert_cmpmasks (copy, mask);
|
||||
@@ -155,6 +155,61 @@ test_set (void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_set_uint (void)
|
||||
{
|
||||
guint i, j, k;
|
||||
guint index;
|
||||
GtkBitmask *copy;
|
||||
GtkBitmask *mask;
|
||||
guint val;
|
||||
|
||||
for (i = 0; i < N_RUNS; i++)
|
||||
{
|
||||
mask = _gtk_bitmask_copy (masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))]);
|
||||
val = g_test_rand_int ();
|
||||
copy = _gtk_bitmask_copy (mask);
|
||||
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
index = g_test_rand_int_range (0, MAX_INDEX);
|
||||
|
||||
_gtk_bitmask_set_uint (©, index, val);
|
||||
|
||||
for (k = 0; k < sizeof (guint) * 8; k++)
|
||||
_gtk_bitmask_set (&mask, index + k, val & (1<<k));
|
||||
|
||||
assert_cmpmasks (copy, mask);
|
||||
}
|
||||
|
||||
_gtk_bitmask_free (copy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_get_uint (void)
|
||||
{
|
||||
guint i, j, k;
|
||||
guint index;
|
||||
GtkBitmask *mask;
|
||||
guint val;
|
||||
|
||||
for (i = 0; i < N_RUNS; i++)
|
||||
{
|
||||
mask = masks[g_test_rand_int_range (0, G_N_ELEMENTS (tests))];
|
||||
|
||||
for (j = 0; j < N_TRIES; j++)
|
||||
{
|
||||
index = g_test_rand_int_range (0, 100);
|
||||
|
||||
val = _gtk_bitmask_get_uint (mask, index);
|
||||
|
||||
for (k = 0; k < sizeof (guint) * 8; k++)
|
||||
g_assert_cmpint (!!_gtk_bitmask_get (mask, index + k), ==, !!(val & (1<<k)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_union (void)
|
||||
{
|
||||
@@ -173,15 +228,15 @@ test_union (void)
|
||||
guint id = g_test_rand_int_range (0, MAX_INDEX);
|
||||
|
||||
if (g_test_rand_bit ())
|
||||
_gtk_bitmask_set (left, id, TRUE);
|
||||
_gtk_bitmask_set (&left, id, TRUE);
|
||||
else
|
||||
_gtk_bitmask_set (right, id, TRUE);
|
||||
_gtk_bitmask_set (&right, id, TRUE);
|
||||
|
||||
_gtk_bitmask_set (expected, id, TRUE);
|
||||
_gtk_bitmask_set (&expected, id, TRUE);
|
||||
}
|
||||
|
||||
_gtk_bitmask_union (left, right);
|
||||
_gtk_bitmask_union (right, left);
|
||||
_gtk_bitmask_union (&left, right);
|
||||
_gtk_bitmask_union (&right, left);
|
||||
|
||||
assert_cmpmasks (left, expected);
|
||||
assert_cmpmasks (right, expected);
|
||||
@@ -211,13 +266,13 @@ test_intersect (void)
|
||||
|
||||
if (g_test_rand_bit ())
|
||||
{
|
||||
_gtk_bitmask_set (left, id, set);
|
||||
_gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (right, id) : 0);
|
||||
_gtk_bitmask_set (&left, id, set);
|
||||
_gtk_bitmask_set (&expected, id, set ? _gtk_bitmask_get (right, id) : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_gtk_bitmask_set (right, id, set);
|
||||
_gtk_bitmask_set (expected, id, set ? _gtk_bitmask_get (left, id) : 0);
|
||||
_gtk_bitmask_set (&right, id, set);
|
||||
_gtk_bitmask_set (&expected, id, set ? _gtk_bitmask_get (left, id) : 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,8 +280,8 @@ test_intersect (void)
|
||||
g_assert_cmpint (intersects, ==, _gtk_bitmask_intersects (right, left));
|
||||
g_assert_cmpint (intersects, !=, _gtk_bitmask_is_empty (expected));
|
||||
|
||||
_gtk_bitmask_intersect (left, right);
|
||||
_gtk_bitmask_intersect (right, left);
|
||||
_gtk_bitmask_intersect (&left, right);
|
||||
_gtk_bitmask_intersect (&right, left);
|
||||
|
||||
assert_cmpmasks (left, expected);
|
||||
assert_cmpmasks (right, expected);
|
||||
@@ -267,19 +322,19 @@ test_invert_range (void)
|
||||
end = MIN (left_end, right_end);
|
||||
|
||||
if (left_start != left_end)
|
||||
_gtk_bitmask_invert_range (left, left_start, left_end);
|
||||
_gtk_bitmask_invert_range (&left, left_start, left_end);
|
||||
if (right_start != right_end)
|
||||
_gtk_bitmask_invert_range (right, right_start, right_end);
|
||||
_gtk_bitmask_invert_range (&right, right_start, right_end);
|
||||
if (start < end)
|
||||
_gtk_bitmask_invert_range (expected, start, end);
|
||||
_gtk_bitmask_invert_range (&expected, start, end);
|
||||
|
||||
intersection = _gtk_bitmask_copy (left);
|
||||
_gtk_bitmask_intersect (intersection, right);
|
||||
_gtk_bitmask_intersect (&intersection, right);
|
||||
|
||||
assert_cmpmasks (intersection, expected);
|
||||
|
||||
if (start < end)
|
||||
_gtk_bitmask_invert_range (expected, start, end);
|
||||
_gtk_bitmask_invert_range (&expected, start, end);
|
||||
|
||||
g_assert_cmpint (_gtk_bitmask_is_empty (expected), ==, TRUE);
|
||||
|
||||
@@ -328,6 +383,8 @@ main (int argc, char *argv[])
|
||||
g_test_add_func ("/bitmask/is_empty", test_is_empty);
|
||||
g_test_add_func ("/bitmask/equals", test_equals);
|
||||
g_test_add_func ("/bitmask/set", test_set);
|
||||
g_test_add_func ("/bitmask/set_uint", test_set_uint);
|
||||
g_test_add_func ("/bitmask/get_uint", test_get_uint);
|
||||
g_test_add_func ("/bitmask/union", test_union);
|
||||
g_test_add_func ("/bitmask/intersect", test_intersect);
|
||||
g_test_add_func ("/bitmask/invert_range", test_invert_range);
|
||||
|
Reference in New Issue
Block a user