471 lines
13 KiB
Python
471 lines
13 KiB
Python
if __name__ == '__main__':
|
|
import sys
|
|
import os
|
|
pkg_dir = os.path.split(os.path.abspath(__file__))[0]
|
|
parent_dir, pkg_name = os.path.split(pkg_dir)
|
|
is_pygame_pkg = (pkg_name == 'tests' and
|
|
os.path.split(parent_dir)[1] == 'pygame')
|
|
if not is_pygame_pkg:
|
|
sys.path.insert(0, parent_dir)
|
|
else:
|
|
is_pygame_pkg = __name__.startswith('pygame.tests.')
|
|
|
|
import unittest
|
|
import pygame
|
|
import pygame.mask
|
|
from pygame.locals import *
|
|
|
|
import random
|
|
|
|
def random_mask(size = (100,100)):
|
|
"""random_mask(size=(100,100)): return Mask
|
|
Create a mask of the given size, with roughly half the bits set at random."""
|
|
m = pygame.Mask(size)
|
|
for i in range(size[0] * size[1] // 2):
|
|
x, y = random.randint(0,size[0] - 1), random.randint(0, size[1] - 1)
|
|
m.set_at((x,y))
|
|
return m
|
|
|
|
def maskFromSurface(surface, threshold = 127):
|
|
mask = pygame.Mask(surface.get_size())
|
|
key = surface.get_colorkey()
|
|
if key:
|
|
for y in range(surface.get_height()):
|
|
for x in range(surface.get_width()):
|
|
if surface.get_at((x+0.1,y+0.1)) != key:
|
|
mask.set_at((x,y),1)
|
|
else:
|
|
for y in range(surface.get_height()):
|
|
for x in range (surface.get_width()):
|
|
if surface.get_at((x,y))[3] > threshold:
|
|
mask.set_at((x,y),1)
|
|
return mask
|
|
|
|
#pygame.init()
|
|
#pygame.display.set_mode((10,10))
|
|
|
|
class MaskTypeTest( unittest.TestCase ):
|
|
def assertMaskEquals(self, m1, m2):
|
|
self.assertEquals(m1.get_size(), m2.get_size())
|
|
for i in range(m1.get_size()[0]):
|
|
for j in range(m1.get_size()[1]):
|
|
self.assertEquals(m1.get_at((i,j)), m2.get_at((i,j)))
|
|
|
|
def todo_test_get_at(self):
|
|
|
|
# __doc__ (as of 2008-08-02) for pygame.mask.Mask.get_at:
|
|
|
|
# Mask.get_at((x,y)) -> int
|
|
# Returns nonzero if the bit at (x,y) is set.
|
|
#
|
|
# Coordinates start at (0,0) is top left - just like Surfaces.
|
|
|
|
self.fail()
|
|
|
|
def todo_test_get_size(self):
|
|
|
|
# __doc__ (as of 2008-08-02) for pygame.mask.Mask.get_size:
|
|
|
|
# Mask.get_size() -> width,height
|
|
# Returns the size of the mask.
|
|
|
|
self.fail()
|
|
|
|
def todo_test_overlap(self):
|
|
|
|
# __doc__ (as of 2008-08-02) for pygame.mask.Mask.overlap:
|
|
|
|
# Mask.overlap(othermask, offset) -> x,y
|
|
# Returns the point of intersection if the masks overlap with the
|
|
# given offset - or None if it does not overlap.
|
|
|
|
# The overlap tests uses the following offsets (which may be negative):
|
|
# +----+----------..
|
|
# |A | yoffset
|
|
# | +-+----------..
|
|
# +--|B
|
|
# |xoffset
|
|
# | |
|
|
# : :
|
|
|
|
self.fail()
|
|
|
|
def todo_test_overlap_area(self):
|
|
|
|
# __doc__ (as of 2008-08-02) for pygame.mask.Mask.overlap_area:
|
|
|
|
# Mask.overlap_area(othermask, offset) -> numpixels
|
|
# Returns the number of overlapping 'pixels'.
|
|
#
|
|
# You can see how many pixels overlap with the other mask given. This
|
|
# can be used to see in which direction things collide, or to see how
|
|
# much the two masks collide.
|
|
|
|
self.fail()
|
|
|
|
def todo_test_set_at(self):
|
|
|
|
# __doc__ (as of 2008-08-02) for pygame.mask.Mask.set_at:
|
|
|
|
# Mask.set_at((x,y),value)
|
|
# Sets the position in the mask given by x and y.
|
|
|
|
self.fail()
|
|
|
|
def test_mask_access( self ):
|
|
""" do the set_at, and get_at parts work correctly?
|
|
"""
|
|
m = pygame.Mask((10,10))
|
|
m.set_at((0,0), 1)
|
|
self.assertEqual(m.get_at((0,0)), 1)
|
|
m.set_at((9,0), 1)
|
|
self.assertEqual(m.get_at((9,0)), 1)
|
|
|
|
#s = pygame.Surface((10,10))
|
|
#s.set_at((1,0), (0, 0, 1, 255))
|
|
#self.assertEqual(s.get_at((1,0)), (0, 0, 1, 255))
|
|
#s.set_at((-1,0), (0, 0, 1, 255))
|
|
|
|
# out of bounds, should get IndexError
|
|
self.assertRaises(IndexError, lambda : m.get_at((-1,0)) )
|
|
self.assertRaises(IndexError, lambda : m.set_at((-1,0), 1) )
|
|
self.assertRaises(IndexError, lambda : m.set_at((10,0), 1) )
|
|
self.assertRaises(IndexError, lambda : m.set_at((0,10), 1) )
|
|
|
|
def test_drawing(self):
|
|
""" Test fill, clear, invert, draw, erase
|
|
"""
|
|
|
|
m = pygame.Mask((100,100))
|
|
self.assertEqual(m.count(), 0)
|
|
|
|
m.fill()
|
|
self.assertEqual(m.count(), 10000)
|
|
|
|
m2 = pygame.Mask((10,10))
|
|
m2.fill()
|
|
m.erase(m2, (50,50))
|
|
self.assertEqual(m.count(), 9900)
|
|
|
|
m.invert()
|
|
self.assertEqual(m.count(), 100)
|
|
|
|
m.draw(m2, (0,0))
|
|
self.assertEqual(m.count(), 200)
|
|
|
|
m.clear()
|
|
self.assertEqual(m.count(), 0)
|
|
|
|
def test_outline(self):
|
|
"""
|
|
"""
|
|
|
|
m = pygame.Mask((20,20))
|
|
self.assertEqual(m.outline(), [])
|
|
|
|
m.set_at((10,10), 1)
|
|
self.assertEqual(m.outline(), [(10,10)])
|
|
|
|
m.set_at((10,12), 1)
|
|
self.assertEqual(m.outline(10), [(10,10)])
|
|
|
|
m.set_at((11,11), 1)
|
|
self.assertEqual(m.outline(), [(10,10), (11,11), (10,12), (11,11), (10,10)])
|
|
self.assertEqual(m.outline(2), [(10,10), (10,12), (10,10)])
|
|
|
|
#TODO: Test more corner case outlines.
|
|
|
|
def test_convolve__size(self):
|
|
sizes = [(1,1), (31,31), (32,32), (100,100)]
|
|
for s1 in sizes:
|
|
m1 = pygame.Mask(s1)
|
|
for s2 in sizes:
|
|
m2 = pygame.Mask(s2)
|
|
o = m1.convolve(m2)
|
|
for i in (0,1):
|
|
self.assertEquals(o.get_size()[i], m1.get_size()[i] + m2.get_size()[i] - 1)
|
|
|
|
def test_convolve__point_identities(self):
|
|
"""Convolving with a single point is the identity, while convolving a point with something flips it."""
|
|
m = random_mask((100,100))
|
|
k = pygame.Mask((1,1))
|
|
k.set_at((0,0))
|
|
|
|
self.assertMaskEquals(m,m.convolve(k))
|
|
self.assertMaskEquals(m,k.convolve(k.convolve(m)))
|
|
|
|
def test_convolve__with_output(self):
|
|
"""checks that convolution modifies only the correct portion of the output"""
|
|
|
|
m = random_mask((10,10))
|
|
k = pygame.Mask((2,2))
|
|
k.set_at((0,0))
|
|
|
|
o = pygame.Mask((50,50))
|
|
test = pygame.Mask((50,50))
|
|
|
|
m.convolve(k,o)
|
|
test.draw(m,(1,1))
|
|
self.assertMaskEquals(o, test)
|
|
|
|
o.clear()
|
|
test.clear()
|
|
|
|
m.convolve(k,o, (10,10))
|
|
test.draw(m,(11,11))
|
|
self.assertMaskEquals(o, test)
|
|
|
|
def test_convolve__out_of_range(self):
|
|
full = pygame.Mask((2,2))
|
|
full.fill()
|
|
|
|
self.assertEquals(full.convolve(full, None, ( 0, 3)).count(), 0)
|
|
self.assertEquals(full.convolve(full, None, ( 0, 2)).count(), 3)
|
|
self.assertEquals(full.convolve(full, None, (-2, -2)).count(), 1)
|
|
self.assertEquals(full.convolve(full, None, (-3, -3)).count(), 0)
|
|
|
|
def test_convolve(self):
|
|
"""Tests the definition of convolution"""
|
|
m1 = random_mask((100,100))
|
|
m2 = random_mask((100,100))
|
|
conv = m1.convolve(m2)
|
|
|
|
for i in range(conv.get_size()[0]):
|
|
for j in range(conv.get_size()[1]):
|
|
self.assertEquals(conv.get_at((i,j)) == 0, m1.overlap(m2, (i - 99, j - 99)) is None)
|
|
|
|
|
|
def test_connected_components(self):
|
|
"""
|
|
"""
|
|
|
|
m = pygame.Mask((10,10))
|
|
self.assertEquals(repr(m.connected_components()), "[]")
|
|
|
|
comp = m.connected_component()
|
|
self.assertEquals(m.count(), comp.count())
|
|
|
|
m.set_at((0,0), 1)
|
|
m.set_at((1,1), 1)
|
|
comp = m.connected_component()
|
|
comps = m.connected_components()
|
|
comps1 = m.connected_components(1)
|
|
comps2 = m.connected_components(2)
|
|
comps3 = m.connected_components(3)
|
|
self.assertEquals(comp.count(), comps[0].count())
|
|
self.assertEquals(comps1[0].count(), 2)
|
|
self.assertEquals(comps2[0].count(), 2)
|
|
self.assertEquals(repr(comps3), "[]")
|
|
|
|
m.set_at((9, 9), 1)
|
|
comp = m.connected_component()
|
|
comp1 = m.connected_component((1, 1))
|
|
comp2 = m.connected_component((2, 2))
|
|
comps = m.connected_components()
|
|
comps1 = m.connected_components(1)
|
|
comps2 = m.connected_components(2)
|
|
comps3 = m.connected_components(3)
|
|
self.assertEquals(comp.count(), 2)
|
|
self.assertEquals(comp1.count(), 2)
|
|
self.assertEquals(comp2.count(), 0)
|
|
self.assertEquals(len(comps), 2)
|
|
self.assertEquals(len(comps1), 2)
|
|
self.assertEquals(len(comps2), 1)
|
|
self.assertEquals(len(comps3), 0)
|
|
|
|
|
|
def test_get_bounding_rects(self):
|
|
"""
|
|
"""
|
|
|
|
m = pygame.Mask((10,10))
|
|
m.set_at((0,0), 1)
|
|
m.set_at((1,0), 1)
|
|
|
|
m.set_at((0,1), 1)
|
|
|
|
m.set_at((0,3), 1)
|
|
m.set_at((3,3), 1)
|
|
|
|
r = m.get_bounding_rects()
|
|
|
|
self.assertEquals(repr(r), "[<rect(0, 0, 2, 2)>, <rect(0, 3, 1, 1)>, <rect(3, 3, 1, 1)>]")
|
|
|
|
|
|
|
|
|
|
|
|
#1100
|
|
#1111
|
|
m = pygame.Mask((4,2))
|
|
m.set_at((0,0), 1)
|
|
m.set_at((1,0), 1)
|
|
m.set_at((2,0), 0)
|
|
m.set_at((3,0), 0)
|
|
|
|
m.set_at((0,1), 1)
|
|
m.set_at((1,1), 1)
|
|
m.set_at((2,1), 1)
|
|
m.set_at((3,1), 1)
|
|
|
|
r = m.get_bounding_rects()
|
|
self.assertEquals(repr(r), "[<rect(0, 0, 4, 2)>]")
|
|
|
|
|
|
#00100
|
|
#01110
|
|
#00100
|
|
m = pygame.Mask((5,3))
|
|
m.set_at((0,0), 0)
|
|
m.set_at((1,0), 0)
|
|
m.set_at((2,0), 1)
|
|
m.set_at((3,0), 0)
|
|
m.set_at((4,0), 0)
|
|
|
|
m.set_at((0,1), 0)
|
|
m.set_at((1,1), 1)
|
|
m.set_at((2,1), 1)
|
|
m.set_at((3,1), 1)
|
|
m.set_at((4,1), 0)
|
|
|
|
m.set_at((0,2), 0)
|
|
m.set_at((1,2), 0)
|
|
m.set_at((2,2), 1)
|
|
m.set_at((3,2), 0)
|
|
m.set_at((4,2), 0)
|
|
|
|
r = m.get_bounding_rects()
|
|
self.assertEquals(repr(r), "[<rect(1, 0, 3, 3)>]")
|
|
|
|
|
|
|
|
#00010
|
|
#00100
|
|
#01000
|
|
m = pygame.Mask((5,3))
|
|
m.set_at((0,0), 0)
|
|
m.set_at((1,0), 0)
|
|
m.set_at((2,0), 0)
|
|
m.set_at((3,0), 1)
|
|
m.set_at((4,0), 0)
|
|
|
|
m.set_at((0,1), 0)
|
|
m.set_at((1,1), 0)
|
|
m.set_at((2,1), 1)
|
|
m.set_at((3,1), 0)
|
|
m.set_at((4,1), 0)
|
|
|
|
m.set_at((0,2), 0)
|
|
m.set_at((1,2), 1)
|
|
m.set_at((2,2), 0)
|
|
m.set_at((3,2), 0)
|
|
m.set_at((4,2), 0)
|
|
|
|
r = m.get_bounding_rects()
|
|
self.assertEquals(repr(r), "[<rect(1, 0, 3, 3)>]")
|
|
|
|
|
|
|
|
|
|
#00011
|
|
#11111
|
|
m = pygame.Mask((5,2))
|
|
m.set_at((0,0), 0)
|
|
m.set_at((1,0), 0)
|
|
m.set_at((2,0), 0)
|
|
m.set_at((3,0), 1)
|
|
m.set_at((4,0), 1)
|
|
|
|
m.set_at((0,1), 1)
|
|
m.set_at((1,1), 1)
|
|
m.set_at((2,1), 1)
|
|
m.set_at((3,1), 1)
|
|
m.set_at((3,1), 1)
|
|
|
|
r = m.get_bounding_rects()
|
|
#TODO: this should really make one bounding rect.
|
|
#self.assertEquals(repr(r), "[<rect(0, 0, 5, 2)>]")
|
|
|
|
class MaskModuleTest(unittest.TestCase):
|
|
def test_from_surface(self):
|
|
""" Does the mask.from_surface() work correctly?
|
|
"""
|
|
|
|
mask_from_surface = pygame.mask.from_surface
|
|
|
|
surf = pygame.Surface((70,70), SRCALPHA, 32)
|
|
|
|
surf.fill((255,255,255,255))
|
|
|
|
amask = pygame.mask.from_surface(surf)
|
|
#amask = mask_from_surface(surf)
|
|
|
|
self.assertEqual(amask.get_at((0,0)), 1)
|
|
self.assertEqual(amask.get_at((66,1)), 1)
|
|
self.assertEqual(amask.get_at((69,1)), 1)
|
|
|
|
surf.set_at((0,0), (255,255,255,127))
|
|
surf.set_at((1,0), (255,255,255,128))
|
|
surf.set_at((2,0), (255,255,255,0))
|
|
surf.set_at((3,0), (255,255,255,255))
|
|
|
|
amask = mask_from_surface(surf)
|
|
self.assertEqual(amask.get_at((0,0)), 0)
|
|
self.assertEqual(amask.get_at((1,0)), 1)
|
|
self.assertEqual(amask.get_at((2,0)), 0)
|
|
self.assertEqual(amask.get_at((3,0)), 1)
|
|
|
|
surf.fill((255,255,255,0))
|
|
amask = mask_from_surface(surf)
|
|
self.assertEqual(amask.get_at((0,0)), 0)
|
|
|
|
#TODO: test a color key surface.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_from_threshold(self):
|
|
""" Does mask.from_threshold() work correctly?
|
|
"""
|
|
|
|
a = [16, 24, 32]
|
|
|
|
for i in a:
|
|
surf = pygame.surface.Surface((70,70), 0, i)
|
|
surf.fill((100,50,200),(20,20,20,20))
|
|
mask = pygame.mask.from_threshold(surf,(100,50,200,255),(10,10,10,255))
|
|
|
|
self.assertEqual(mask.count(), 400)
|
|
self.assertEqual(mask.get_bounding_rects(), [pygame.Rect((20,20,20,20))])
|
|
|
|
for i in a:
|
|
surf = pygame.surface.Surface((70,70), 0, i)
|
|
surf2 = pygame.surface.Surface((70,70), 0, i)
|
|
surf.fill((100,100,100))
|
|
surf2.fill((150,150,150))
|
|
surf2.fill((100,100,100), (40,40,10,10))
|
|
mask = pygame.mask.from_threshold(surf, (0,0,0,0), (10,10,10,255), surf2)
|
|
|
|
self.assertEqual(mask.count(), 100)
|
|
self.assertEqual(mask.get_bounding_rects(), [pygame.Rect((40,40,10,10))])
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if 1:
|
|
unittest.main()
|
|
else:
|
|
mask_from_surface = maskFromSurface
|
|
|
|
surf = pygame.Surface((70,70), SRCALPHA, 32)
|
|
#surf = surf.convert_alpha()
|
|
surf.set_at((0,0), (255,255,255,0))
|
|
print (surf.get_at((0,0)))
|
|
|
|
print ("asdf")
|
|
print (surf)
|