diff --git a/gtk/gtkallocatedbitmask.c b/gtk/gtkallocatedbitmask.c index dff1189edf..2ebe0e14e2 100644 --- a/gtk/gtkallocatedbitmask.c +++ b/gtk/gtkallocatedbitmask.c @@ -207,7 +207,7 @@ _gtk_allocated_bitmask_subtract (GtkBitmask *mask, const GtkBitmask *other) { GtkBitmask other_allocated; - guint i; + guint i, len; g_return_val_if_fail (mask != NULL, NULL); g_return_val_if_fail (other != NULL, NULL); @@ -215,9 +215,10 @@ _gtk_allocated_bitmask_subtract (GtkBitmask *mask, mask = gtk_bitmask_ensure_allocated (mask); ENSURE_ALLOCATED (other, other_allocated); - for (i = 0; i < other->len; i++) + len = MIN (mask->len, other->len); + for (i = 0; i < len; i++) { - mask->data[i] |= ~other->data[i]; + mask->data[i] &= ~other->data[i]; } return gtk_allocated_bitmask_shrink (mask); diff --git a/testsuite/gtk/bitmask.c b/testsuite/gtk/bitmask.c index 7d186a986a..b457c08fd8 100644 --- a/testsuite/gtk/bitmask.c +++ b/testsuite/gtk/bitmask.c @@ -280,6 +280,53 @@ test_intersect_hardcoded (void) } } +static void +test_subtract_hardcoded (void) +{ + GtkBitmask *left, *right, *subtracted, *expected; + const char *left_str, *right_str; + guint left_len, right_len; + guint i, l, r; + + for (l = 0; l < G_N_ELEMENTS (tests); l++) + { + for (r = 0; r < G_N_ELEMENTS (tests); r++) + { + left = masks[l]; + right = masks[r]; + left_str = tests[l]; + right_str = tests[r]; + left_len = strlen (tests[l]); + right_len = strlen (tests[r]); + + expected = _gtk_bitmask_new (); + for (i = MIN (right_len, left_len); i < left_len; i++) + { + expected = _gtk_bitmask_set (expected, i, left_str[left_len - i - 1] == '1'); + } + if (left_len > right_len) + left_str += left_len - right_len; + if (right_len > left_len) + right_str += right_len - left_len; + i = MIN (right_len, left_len); + while (i--) + { + expected = _gtk_bitmask_set (expected, i, left_str[0] == '1' && right_str[0] == '0'); + right_str++; + left_str++; + } + + g_print ("%s - %s\n", _gtk_bitmask_to_string (left), _gtk_bitmask_to_string (right)); + subtracted = _gtk_bitmask_subtract (_gtk_bitmask_copy (left), right); + + assert_cmpmasks (subtracted, expected); + + _gtk_bitmask_free (subtracted); + _gtk_bitmask_free (expected); + } + } +} + #define SWAP(_a, _b) G_STMT_START{ \ guint _tmp = _a; \ _a = _b; \ @@ -375,6 +422,7 @@ main (int argc, char *argv[]) g_test_add_func ("/bitmask/union", test_union); g_test_add_func ("/bitmask/intersect", test_intersect); g_test_add_func ("/bitmask/intersect_hardcoded", test_intersect_hardcoded); + g_test_add_func ("/bitmask/subtract_hardcoded", test_subtract_hardcoded); g_test_add_func ("/bitmask/invert_range", test_invert_range); result = g_test_run ();