Skip to content

Commit

Permalink
Add tests, update docs and add unique check
Browse files Browse the repository at this point in the history
  • Loading branch information
Temmie3754 committed Oct 25, 2024
1 parent 69bc9ce commit 0eae228
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
4 changes: 2 additions & 2 deletions docs/reST/ref/transform.rst
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ Instead, always begin with the original image and scale to the desired size.)
This maps an image to a new surface warping the image so that its corners
match the provided points in a clockwise order: top left, top right, bottom
right, bottom left. Provided points represent the pixel coordinates of the
new corners of the image and can be positive or negative provided they fit
in the new surface.
new corners of the image, they must be unique and can be positive or negative
provided they fit in the new surface.

When no 'dest_surface' is provided, the 'adjust_size' option will set the
size of the resulting surface to be the smallest surface the points are
Expand Down
14 changes: 10 additions & 4 deletions src_c/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,13 @@ surf_skew(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL;
surf = pgSurface_AsSurface(surfobj);
SURF_INIT_CHECK(surf)

if ((x1 == x2 && y1 == y2) || (x1 == x3 && y1 == y3) ||
(x1 == x4 && y1 == y4) || (x2 == x3 && y2 == y3) ||
(x2 == x4 && y2 == y4) || (x3 == x4 && y3 == y4)) {
return RAISE(PyExc_ValueError, "all four points must be unique");
}

if (!dest_surface) {
if (adjust_size) {
start = MIN(MIN(x1, x2), MIN(x3, x4));
Expand Down Expand Up @@ -1096,7 +1103,7 @@ surf_skew(PyObject *self, PyObject *args, PyObject *kwargs)

if (PG_SURF_BytesPerPixel(surf) == 0 || PG_SURF_BytesPerPixel(surf) > 4)
return RAISE(PyExc_ValueError,
"unsupported surface bit depth for transform");
"unsupported Surface bit depth for transform");

SDL_Point points[4] = {{x1 - start, y1 - top},
{x2 - start, y2 - top},
Expand All @@ -1107,7 +1114,7 @@ surf_skew(PyObject *self, PyObject *args, PyObject *kwargs)
_check_inside(newsurf, points[2]) &&
_check_inside(newsurf, points[3]))) {
return RAISE(PyExc_ValueError,
"points are not within specified surface");
"points are not within specified Surface");
}

SDL_LockSurface(newsurf);
Expand Down Expand Up @@ -1141,8 +1148,7 @@ surf_skew(PyObject *self, PyObject *args, PyObject *kwargs)
}
}
else {
if (!pg_MappedColorFromObj(colorobj, surf->format, &bgcolor,
PG_COLOR_HANDLE_ALL))
if (_color_from_obj(colorobj, surf, NULL, &bgcolor))
return RAISE(PyExc_TypeError, "invalid bg_color argument");
}

Expand Down
44 changes: 44 additions & 0 deletions test/transform_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,50 @@ def test_rotate__lossless_at_90_degrees(self):
for pt, color in gradient:
self.assertTrue(s.get_at(pt) == color)

def test_skew(self):
blue = (0, 0, 255, 255)
red = (255, 0, 0, 255)
black = (0, 0, 0)
w, h = 32, 32
s = pygame.Surface((w, h), pygame.SRCALPHA, 32)
s.fill(red)
s.fill(black, pygame.rect.Rect(0, 0, 16, 16))
corner_points = [
[(1, 1), (19, 1), (19, 19), (1, 19)],
[(0, 10), (31, 0), (3, 31), (0, 13)],
[(5, 16), (17, 2), (19, 13), (2, 18)],
[(5, 4), (28, 2), (8, 25), (27, 20)],
[(20, 20), (15, 5), (30, 30), (5, 15)],
]
test_points = [
[((0, 31), blue), ((5, 16), red), ((4, 4), black)],
[((7, 7), black), ((6, 7), blue), ((16, 16), red)],
[((19, 13), red), ((10, 9), black), ((11, 9), red)],
[((10, 8), black), ((18, 14), red), ((20, 14), blue)],
[((17, 14), black), ((17, 13), red), ((16, 14), blue)],
]

# check specified test points are correct
for i in range(len(corner_points)):
s2 = pygame.transform.skew(s, corner_points[i], blue, False)
for test in test_points[i]:
self.assertEqual(
s2.get_at(test[0]),
test[1],
"Failed for {0} at {1}".format(corner_points[i], test[0]),
)

def test_skew_adjust_size(self):
w, h = 32, 32
s = pygame.Surface((w, h), pygame.SRCALPHA, 32)
size_values = [-100, -72, -23, -1, 1, 15, 104, 1009]
for x in size_values:
for y in size_values:
s2 = pygame.transform.skew(
s, [(x, 0), (0, 0), (x, y), (0, y)], adjust_size=True
)
self.assertEqual(s2.size, (abs(x) + 1, abs(y) + 1))

def test_scale2x(self):
# __doc__ (as of 2008-06-25) for pygame.transform.scale2x:

Expand Down

0 comments on commit 0eae228

Please sign in to comment.