Skip to content

Commit 6f03c0a

Browse files
committed
well, at least the tests pass
1 parent 9c5e0b2 commit 6f03c0a

File tree

2 files changed

+47
-83
lines changed

2 files changed

+47
-83
lines changed

src_c/mask.c

Lines changed: 21 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,8 @@ extract_color(SDL_Surface *surf, PyObject *color_obj, Uint8 rgba_color[],
19851985
*/
19861986
static void
19871987
draw_to_surface(SDL_Surface *surf, bitmask_t *bitmask, int x_dest, int y_dest,
1988-
int draw_setbits, int draw_unsetbits, SDL_Surface *setsurf,
1988+
int x_area_offset, int y_area_offset, int draw_setbits,
1989+
int draw_unsetbits, SDL_Surface *setsurf,
19891990
SDL_Surface *unsetsurf, Uint32 *setcolor, Uint32 *unsetcolor)
19901991
{
19911992
Uint8 *pixel = NULL;
@@ -2050,10 +2051,12 @@ draw_to_surface(SDL_Surface *surf, bitmask_t *bitmask, int x_dest, int y_dest,
20502051

20512052
for (y = y_start, ym = ym_start; y < y_end; ++y, ++ym) {
20522053
pixel = (Uint8 *)surf->pixels + y * surf->pitch + x_start * bpp;
2053-
setpixel = (Uint8 *)setsurf->pixels + ym * setsurf->pitch +
2054-
xm_start * bpp;
2055-
unsetpixel = (Uint8 *)unsetsurf->pixels + ym * unsetsurf->pitch +
2056-
xm_start * bpp;
2054+
setpixel = (Uint8 *)setsurf->pixels +
2055+
(y_area_offset + ym) * setsurf->pitch +
2056+
(x_area_offset + xm_start) * bpp;
2057+
unsetpixel = (Uint8 *)unsetsurf->pixels +
2058+
(y_area_offset + ym) * unsetsurf->pitch +
2059+
(x_area_offset + xm_start) * bpp;
20572060

20582061
for (x = x_start, xm = xm_start; x < x_end;
20592062
++x, ++xm, pixel += bpp, setpixel += bpp, unsetpixel += bpp) {
@@ -2084,13 +2087,15 @@ draw_to_surface(SDL_Surface *surf, bitmask_t *bitmask, int x_dest, int y_dest,
20842087
draw_unsetbits && NULL != unsetsurf && unsetsurf->h > ym;
20852088

20862089
if (use_setsurf) {
2087-
setpixel = (Uint8 *)setsurf->pixels + ym * setsurf->pitch +
2088-
xm_start * bpp;
2090+
setpixel = (Uint8 *)setsurf->pixels +
2091+
(y_area_offset + ym) * setsurf->pitch +
2092+
(x_area_offset + xm_start) * bpp;
20892093
}
20902094

20912095
if (use_unsetsurf) {
20922096
unsetpixel = (Uint8 *)unsetsurf->pixels +
2093-
ym * unsetsurf->pitch + xm_start * bpp;
2097+
(y_area_offset + ym) * unsetsurf->pitch +
2098+
(x_area_offset + xm_start) * bpp;
20942099
}
20952100

20962101
for (x = x_start, xm = xm_start; x < x_end;
@@ -2227,12 +2232,12 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
22272232
area_rect->h += area_rect->y;
22282233
area_rect->y = 0;
22292234
}
2230-
2235+
22312236
// clamp rect width and height to not stick out of the mask
22322237
area_rect->w = MAX(MIN(area_rect->w, bitmask->w - area_rect->x), 0);
22332238
area_rect->h = MAX(MIN(area_rect->h, bitmask->h - area_rect->y), 0);
22342239

2235-
create_area_bitmask = area_rect->w > 0 && area_rect->h > 0;
2240+
create_area_bitmask = 1;
22362241
}
22372242
else {
22382243
temp_rect.x = temp_rect.y = 0;
@@ -2351,60 +2356,22 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
23512356
if (create_area_bitmask) {
23522357
area_bitmask = bitmask_create(area_rect->w, area_rect->h);
23532358
if (NULL == area_bitmask) {
2354-
PyErr_Format(PyExc_MemoryError, "failed to allocate memory for a mask");
2355-
return NULL;
2356-
}
2357-
2358-
bitmask_t *overlap_bitmask = bitmask_copy(area_bitmask);
2359-
if (NULL == overlap_bitmask) {
2360-
PyErr_SetString(PyExc_MemoryError, "failed to allocate memory for a mask");
2359+
PyErr_Format(PyExc_MemoryError,
2360+
"failed to allocate memory for a mask");
23612361
return NULL;
23622362
}
23632363

2364-
bitmask_fill(overlap_bitmask);
2365-
2366-
bitmask_overlap_mask(bitmask, overlap_bitmask, area_bitmask,
2367-
area_rect->x, area_rect->y);
2368-
2369-
printf("%i,%i\n", area_rect->x, area_rect->y);
2370-
printf("%ix%i\n", bitmask->w, bitmask->h);
2371-
for (int y = 0; y < bitmask->h; ++y) {
2372-
for (int x = 0; x < bitmask->w; ++x) {
2373-
int bit_value = (bitmask->bits[y] >> x) & 1;
2374-
printf("%d ", bit_value);
2375-
}
2376-
printf("\n");
2377-
}
2378-
printf("\n");
2379-
printf("overlap\n");
2380-
for (int y = 0; y < overlap_bitmask->h; ++y) {
2381-
for (int x = 0; x < overlap_bitmask->w; ++x) {
2382-
int bit_value = (overlap_bitmask->bits[y] >> x) & 1;
2383-
printf("%d ", bit_value);
2384-
}
2385-
printf("\n");
2386-
}
2387-
printf("\n%ix%i\n", area_rect->w, area_rect->h);
2388-
for (int y = 0; y < area_bitmask->h; ++y) {
2389-
for (int x = 0; x < area_bitmask->w; ++x) {
2390-
int bit_value = (area_bitmask->bits[y] >> x) & 1;
2391-
printf("%d ", bit_value);
2392-
}
2393-
printf("\n");
2394-
}
2395-
printf("\n");
2396-
2397-
bitmask_free(overlap_bitmask);
2364+
bitmask_draw(area_bitmask, bitmask, -area_rect->x, -area_rect->y);
23982365
}
23992366
else {
24002367
area_bitmask = bitmask;
24012368
}
24022369

24032370
Py_BEGIN_ALLOW_THREADS; /* Release the GIL. */
24042371

2405-
draw_to_surface(surf, area_bitmask, x_dest, y_dest, draw_setbits,
2406-
draw_unsetbits, setsurf, unsetsurf, setcolor_ptr,
2407-
unsetcolor_ptr);
2372+
draw_to_surface(surf, area_bitmask, x_dest, y_dest, area_rect->x,
2373+
area_rect->y, draw_setbits, draw_unsetbits, setsurf,
2374+
unsetsurf, setcolor_ptr, unsetcolor_ptr);
24082375

24092376
Py_END_ALLOW_THREADS; /* Obtain the GIL. */
24102377

test/mask_test.py

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,7 +2870,7 @@ def test_to_surface__area_output(self):
28702870
[{"dest": (1, 0), "area": (0, 0, 1, 2)}, [[black, white], [black, white]]],
28712871
[{"dest": (0, 0), "area": (0, 0, 0, 0)}, [[black, black], [black, black]]],
28722872
[{"dest": (1, 0), "area": (-1, 0, 1, 1)}, [[black, black], [black, black]]],
2873-
[{"dest": (0, 0), "area": (-1, 0, 2, 1)}, [[black, white], [black, black]]],
2873+
[{"dest": (0, 0), "area": (-1, 0, 2, 1)}, [[white, black], [black, black]]],
28742874
[
28752875
{"dest": (1, 1), "area": (-2, -2, 1, 1)},
28762876
[[black, black], [black, black]],
@@ -2881,16 +2881,16 @@ def test_to_surface__area_output(self):
28812881
],
28822882
[
28832883
{"dest": (-1, 0), "area": (-1, 0, 2, 2)},
2884-
[[white, black], [white, black]],
2884+
[[black, black], [black, black]],
28852885
],
28862886
[
28872887
{"dest": (0, -1), "area": (-1, 0, 3, 2)},
2888-
[[black, white], [black, black]],
2888+
[[white, white], [black, black]],
28892889
],
28902890
[{"dest": (0, 0), "area": (2, 2, 2, 2)}, [[black, black], [black, black]]],
28912891
[
28922892
{"dest": (-5, -5), "area": (-5, -5, 6, 6)},
2893-
[[white, black], [black, black]],
2893+
[[black, black], [black, black]],
28942894
],
28952895
[
28962896
{"dest": (-5, -5), "area": (-5, -5, 1, 1)},
@@ -4550,12 +4550,12 @@ def test_to_surface__dest_locations(self):
45504550
default_setcolor = pygame.Color("white")
45514551
default_unsetcolor = pygame.Color("black")
45524552

4553-
directions = (
4554-
((s, 0) for s in range(-SIDE, SIDE + 1)), # left to right
4555-
((0, s) for s in range(-SIDE, SIDE + 1)), # top to bottom
4556-
((s, s) for s in range(-SIDE, SIDE + 1)), # topleft to bottomright diag
4557-
((-s, s) for s in range(-SIDE, SIDE + 1)), # topright to bottomleft diag
4558-
)
4553+
directions = [
4554+
[(s, 0) for s in range(-SIDE, SIDE + 1)], # left to right
4555+
[(0, s) for s in range(-SIDE, SIDE + 1)], # top to bottom
4556+
[(s, s) for s in range(-SIDE, SIDE + 1)], # topleft to bottomright diag
4557+
[(-s, s) for s in range(-SIDE, SIDE + 1)], # topright to bottomleft diag
4558+
]
45594559

45604560
for fill in (True, False):
45614561
mask = pygame.mask.Mask((SIDE, SIDE), fill=fill)
@@ -4583,12 +4583,12 @@ def test_to_surface__area_locations(self):
45834583
default_setcolor = pygame.Color("white")
45844584
default_unsetcolor = pygame.Color("black")
45854585

4586-
directions = (
4586+
directions = [
45874587
[(s, 0) for s in range(-SIDE, SIDE + 1)], # left to right
45884588
[(0, s) for s in range(-SIDE, SIDE + 1)], # top to bottom
45894589
[(s, s) for s in range(-SIDE, SIDE + 1)], # topleft to bottomright diag
45904590
[(-s, s) for s in range(-SIDE, SIDE + 1)], # topright to bottomleft diag
4591-
)
4591+
]
45924592

45934593
for fill in (True, False):
45944594
mask = pygame.mask.Mask((SIDE, SIDE), fill=fill)
@@ -4623,16 +4623,16 @@ def test_to_surface__dest_and_area_locations(self):
46234623
default_setcolor = pygame.Color("white")
46244624
default_unsetcolor = pygame.Color("black")
46254625

4626-
dest_directions = (
4627-
((s, 0) for s in range(-SIDE, SIDE + 1)), # left to right
4628-
((0, s) for s in range(-SIDE, SIDE + 1)), # top to bottom
4629-
((s, s) for s in range(-SIDE, SIDE + 1)), # topleft to bottomright diag
4630-
((-s, s) for s in range(-SIDE, SIDE + 1)), # topright to bottomleft diag
4631-
)
4626+
dest_directions = [
4627+
[(s, 0) for s in range(-SIDE, SIDE + 1)], # left to right
4628+
[(0, s) for s in range(-SIDE, SIDE + 1)], # top to bottom
4629+
[(s, s) for s in range(-SIDE, SIDE + 1)], # topleft to bottomright diag
4630+
[(-s, s) for s in range(-SIDE, SIDE + 1)], # topright to bottomleft diag
4631+
]
46324632

46334633
# Using only the topleft to bottomright diagonal to test the area (to
46344634
# reduce the number of loop iterations).
4635-
area_positions = list(dest_directions[2])
4635+
area_positions = dest_directions[2]
46364636

46374637
for fill in (True, False):
46384638
mask = pygame.mask.Mask((SIDE, SIDE), fill=fill)
@@ -5145,17 +5145,14 @@ def test_to_surface__area_on_mask(self):
51455145
overlap_rect = mask_rect.clip(area_rect)
51465146
overlap_rect.topleft = (0, 0)
51475147

5148-
with self.subTest(
5149-
pos=pos, area_rect=area_rect.copy(), overlap_rect=overlap_rect
5150-
):
5151-
to_surface = mask.to_surface(surface, area=area_rect)
5148+
to_surface = mask.to_surface(surface, area=area_rect)
51525149

5153-
self.assertIs(to_surface, surface)
5154-
self.assertEqual(to_surface.get_size(), size)
5155-
assertSurfaceFilled(self, to_surface, expected_color, overlap_rect)
5156-
assertSurfaceFilledIgnoreArea(
5157-
self, to_surface, surface_color, overlap_rect
5158-
)
5150+
self.assertIs(to_surface, surface)
5151+
self.assertEqual(to_surface.get_size(), size)
5152+
assertSurfaceFilled(self, to_surface, expected_color, overlap_rect)
5153+
assertSurfaceFilledIgnoreArea(
5154+
self, to_surface, surface_color, overlap_rect
5155+
)
51595156

51605157
def test_to_surface__area_on_mask_with_setsurface_unsetsurface(self):
51615158
"""Ensures area values on the mask work correctly

0 commit comments

Comments
 (0)