1"""
2Some tests for difficult wrapped graphics functions and methods
3
4NOTE: These require a WindowServer connection on MacOS X
5"""
6from PyObjCTools.TestSupport import *
7from AppKit import *
8from Foundation import *
9import array
10import sys
11
12
13class SimpleImage:
14    """
15    Helper class that makes it easier to access individual pixels in
16    a bitmap image
17    """
18    def __init__(self, image):
19        data = image.TIFFRepresentation()
20        bitmap = NSBitmapImageRep.imageRepWithData_(data)
21        self.bitmap = bitmap
22        self.data = bitmap.bitmapData()
23        self.rowbytes = bitmap.bytesPerRow()
24        self.pixbytes = bitmap.bitsPerPixel() // 8
25        self.rowCount = bitmap.pixelsHigh()
26
27        if bitmap.isPlanar():
28            raise ValueError, "Planar image!"
29        if (bitmap.bitsPerPixel() % 8) != 0:
30            raise ValueError, "bits per pixel isn't multiple of 8"
31
32    def width(self):
33        return self.bitmap.pixelsWide()
34
35    def height(self):
36        return self.bitmap.pixelsHigh()
37
38    def getPixel(self, x, y):
39        x = self.rowCount - 1 - x
40        rowOffset = x * self.rowbytes
41        pixelOffset = y * self.pixbytes
42        offset = rowOffset + pixelOffset
43
44        pixel = self.data[offset:offset + self.pixbytes]
45        return pixel
46
47class RectTest (TestCase):
48    def setUp(self):
49
50        # Force NSApp initialisation, needed for some of the tests
51        NSApplication.sharedApplication().activateIgnoringOtherApps_(0)
52
53
54
55        self.points = (
56            ((10,  0), ( 1,  1)),
57            ((10, 10), ( 1,  1)),
58            (( 0, 10), ( 1,  1)),
59            (( 0,  0), ( 1,  1)),
60            ((70, 70), (10, 10))
61        )
62
63        self.image = NSImage.alloc().initWithSize_((100, 100))
64
65    def makeArray(self, points):
66        if sys.maxint > 2 ** 32:
67            code = 'd'
68        else:
69            code = 'f'
70
71        a = array.array(code, len(points) * [0, 0, 0, 0])
72        for i in range(len(points)):
73            p = points[i]
74            a[(i*4) + 0] = p[0][0]
75            a[(i*4) + 1] = p[0][1]
76            a[(i*4) + 2] = p[1][0]
77            a[(i*4) + 3] = p[1][1]
78
79        return a
80
81    def assertImagePoints(self, image, points):
82        """
83        Check that the image contains white pixels everywhere but at the
84        specified locations points is sequence of NSRect values.
85        """
86
87        img = SimpleImage(image)
88
89        allpoints = [ (x, y)
90                for x in range(img.width())
91                for y in range(img.height())
92        ]
93
94        # Check black points
95        for ((x, y), (h, w)) in points:
96            for ox in range(w):
97                for oy in range(h):
98                    allpoints.remove((x+ox, y+oy))
99                    self.assertEqual(
100                        img.getPixel(x+ox, y+oy),
101                        '\x00\x00\x00\xff',
102                        'Black pixel at %d,%d'%(x+ox, y+oy))
103
104        # And white points
105        for x, y in allpoints:
106            self.assertEqual(
107                img.getPixel(x, y),
108                '\x00\x00\x00\x00',
109                'White pixel at %d,%d'%(x, y))
110
111
112    def tearDown(self):
113        pass
114
115
116    def test_NSRectFillList_tuple(self):
117        """
118        Check NSRectFillList with a tuple of NSRects
119        """
120        self.image.lockFocus()
121        NSRectFillList(self.points, len(self.points))
122        self.image.unlockFocus()
123
124        self.assertImagePoints(self.image, self.points)
125
126    def test_NSRectFillList_array(self):
127        """
128        Check NSRectFillList with a array.array of NSRects
129        """
130        self.image.lockFocus()
131        NSRectFillList(self.makeArray(self.points), len(self.points))
132        self.image.unlockFocus()
133
134
135if __name__ == "__main__":
136    main()
137