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
67        a = array.array('f', len(points) * [0, 0, 0, 0])
68        for i in range(len(points)):
69            p = points[i]
70            a[(i*4) + 0] = p[0][0]
71            a[(i*4) + 1] = p[0][1]
72            a[(i*4) + 2] = p[1][0]
73            a[(i*4) + 3] = p[1][1]
74
75        return a
76
77    def assertImagePoints(self, image, points):
78        """
79        Check that the image contains white pixels everywhere but at the
80        specified locations points is sequence of NSRect values.
81        """
82
83        img = SimpleImage(image)
84
85        allpoints = [ (x, y)
86                for x in range(img.width())
87                for y in range(img.height())
88        ]
89
90        # Check black points
91        for ((x, y), (h, w)) in points:
92            for ox in range(w):
93                for oy in range(h):
94                    allpoints.remove((x+ox, y+oy))
95                    self.assertEquals(
96                        img.getPixel(x+ox, y+oy),
97                        '\x00\x00\x00\xff',
98                        'Black pixel at %d,%d'%(x+ox, y+oy))
99
100        # And white points
101        for x, y in allpoints:
102            self.assertEquals(
103                img.getPixel(x, y),
104                '\x00\x00\x00\x00',
105                'White pixel at %d,%d'%(x, y))
106
107
108    def tearDown(self):
109        pass
110
111
112    def test_NSRectFillList_tuple(self):
113        """
114        Check NSRectFillList with a tuple of NSRects
115        """
116        self.image.lockFocus()
117        NSRectFillList(self.points, len(self.points))
118        self.image.unlockFocus()
119
120        self.assertImagePoints(self.image, self.points)
121
122    def test_NSRectFillList_array(self):
123        """
124        Check NSRectFillList with a array.array of NSRects
125        """
126        self.image.lockFocus()
127        NSRectFillList(self.makeArray(self.points), len(self.points))
128        self.image.unlockFocus()
129
130
131if __name__ == "__main__":
132    main()
133