File: clip_to_rect_test_case.py

package info (click to toggle)
python-enable 4.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,280 kB
  • ctags: 13,899
  • sloc: cpp: 48,447; python: 28,502; ansic: 9,004; makefile: 315; sh: 44
file content (326 lines) | stat: -rw-r--r-- 12,045 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
""" Needed Tests

    clip_to_rect() tests
    --------------------
        DONE *. clip_to_rect is inclusive on lower end and exclusive on upper end.
        DONE *. clip_to_rect behaves intelligently under scaled ctm.
        DONE *. clip_to_rect intersects input rect with the existing clipping rect.
        DONE *. current rectangular clipping path is saved/restored to the stack when
                save_state/restore_state are called.
        DONE *. clip_to_rect clears current path.
        DONE *. clip_to_rect raises NotImplementedError under a rotated ctm.

    clip_to_rects() tests
    ---------------------
        DONE *. Test that clip_to_rects raises not implemented, or whatever.

"""

import unittest

from numpy import array, transpose

import nose

from kiva.agg import GraphicsContextArray
import kiva

from test_utils import Utils

class ClipToRectTestCase(unittest.TestCase, Utils):

    #------------------------------------------------------------------------
    # Simple Clipping to a single rectangle.
    #------------------------------------------------------------------------

    def clip_to_rect_helper(self, desired, scale, clip_rects):
        """ desired -- 2D array with a single channels expected byte pattern.
            scale -- used in scale_ctm() to change the ctm.
            clip_args -- passed in as *clip_args to clip_to_rect.
        """
        shp = tuple(transpose(desired.shape))
        gc = GraphicsContextArray(shp, pix_format="rgb24")
        gc.scale_ctm(scale, scale)

        # clear background to white values (255, 255, 255)
        gc.clear((1.0, 1.0, 1.0))

        if isinstance(clip_rects, tuple):
            gc.clip_to_rect(*clip_rects)
        else:
            for rect in clip_rects:
                gc.clip_to_rect(*rect)

        gc.rect(0, 0, 4, 4)

        # These settings allow the fastest path.
        gc.set_fill_color((0.0, 0.0, 0.0)) # black
        gc.fill_path()

        # test a single color channel
        actual = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired, actual)

    def test_clip_to_rect_simple(self):
        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])
        clip_rect = (1, 1, 2, 2)
        self.clip_to_rect_helper(desired, 1, clip_rect)

    def test_clip_to_rect_simple2(self):
        desired = array([[255, 255, 255, 255],
                         [255, 255, 255, 255],
                         [255,   0, 255, 255],
                         [255, 255, 255, 255]])
        clip_rect = (1, 1, 1, 1)
        self.clip_to_rect_helper(desired, 1, clip_rect)

    def test_clip_to_rect_negative(self):
        desired = array([[255, 255, 255, 255],
                         [  0,   0,   0, 255],
                         [  0,   0,   0, 255],
                         [  0,   0,   0, 255]])
        clip_rect = (-1, -1, 4, 4)
        self.clip_to_rect_helper(desired, 1, clip_rect)

    def test_clip_to_rect_simple3(self):
        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])
        clip_rect = (1, 1, 2.49, 2.49)
        self.clip_to_rect_helper(desired, 1, clip_rect)

    def test_clip_to_rect_simple4(self):
        desired = array([[255,   0,   0,   0],
                         [255,   0,   0,   0],
                         [255,   0,   0,   0],
                         [255, 255, 255, 255]])
        clip_rect = (1, 1, 2.5, 2.5)
        self.clip_to_rect_helper(desired, 1, clip_rect)

    def test_clip_to_rect_simple5(self):
        # This tests clipping with a larger rectangle
        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])
        clip_rects = [(1, 1, 2, 2), (0, 0, 4, 4)]
        self.clip_to_rect_helper(desired, 1, clip_rects)

    def test_empty_clip_region(self):
        # This tests when the clipping region is clipped down to nothing.
        desired = array([[255, 255, 255, 255],
                         [255, 255, 255, 255],
                         [255, 255, 255, 255],
                         [255, 255, 255, 255]])
        clip_rects = [(1,1,4,4), (3,3,1,1), (1,1,1,1)]
        self.clip_to_rect_helper(desired, 1, clip_rects)

    def test_clip_to_rect_scaled(self):
        desired = array([[255, 255, 255, 255, 255, 255, 255, 255],
                         [255, 255, 255, 255, 255, 255, 255, 255],
                         [255, 255,   0,   0,   0,   0, 255, 255],
                         [255, 255,   0,   0,   0,   0, 255, 255],
                         [255, 255,   0,   0,   0,   0, 255, 255],
                         [255, 255,   0,   0,   0,   0, 255, 255],
                         [255, 255, 255, 255, 255, 255, 255, 255],
                         [255, 255, 255, 255, 255, 255, 255, 255]])
        clip_rect = (1, 1, 2, 2)
        self.clip_to_rect_helper(desired, 2.0, clip_rect)

    def test_clip_to_rect_scaled2(self):
        desired = array([[255, 255, 255, 255, 255, 255, 255, 255],
                         [255, 255,   0,   0,   0,   0,   0, 255],
                         [255, 255,   0,   0,   0,   0,   0, 255],
                         [255, 255,   0,   0,   0,   0,   0, 255],
                         [255, 255,   0,   0,   0,   0,   0, 255],
                         [255, 255,   0,   0,   0,   0,   0, 255],
                         [255, 255, 255, 255, 255, 255, 255, 255],
                         [255, 255, 255, 255, 255, 255, 255, 255]])
        clip_rect = (1, 1, 2.25, 2.25)
        self.clip_to_rect_helper(desired, 2.0, clip_rect)

    def test_save_restore_clip_state(self):
        desired1 = array([[255, 255, 255, 255],
                          [255,   0,   0, 255],
                          [255,   0,   0, 255],
                          [255, 255, 255, 255]])
        desired2 = array([[255,   0,   0,   0],
                          [255,   0,   0,   0],
                          [255,   0,   0,   0],
                          [255, 255, 255, 255]])
        gc = GraphicsContextArray((4,4), pix_format="rgb24")
        gc.clear((1.0, 1.0, 1.0))
        gc.set_fill_color((0.0, 0.0, 0.0))

        gc.clip_to_rect(1, 1, 3, 3)

        gc.save_state()
        gc.clip_to_rect(1, 1, 2, 2)
        gc.rect(0, 0, 4, 4)
        gc.fill_path()
        actual1 = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired1, actual1)
        gc.restore_state()

        gc.rect(0, 0, 4, 4)
        gc.fill_path()
        actual2 = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired2, actual2)

    def test_clip_to_rect_rotated(self):
        # FIXME: test skipped
        #   This test raises an exception currently because the
        #   underlying library doesn't handle clipping to a rotated
        #   rectangle.  For now, we catch the the case with an
        #   exception, so that people can't screw up.  In the future,
        #   we should actually support this functionality.
        raise nose.SkipTest

        gc = GraphicsContextArray((1,1), pix_format="rgb24")
        gc.rotate_ctm(1.0)

        self.failUnlessRaises(NotImplementedError,
                              gc.clip_to_rect, 0, 0, 1, 1)

    #------------------------------------------------------------------------
    # Successive Clipping of multiple rectangles.
    #------------------------------------------------------------------------

    def successive_clip_helper(self, desired, scale,
                               clip_rect1, clip_rect2):
        """ desired -- 2D array with a single channels expected byte pattern.
            scale -- used in scale_ctm() to change the ctm.
            clip_rect1 -- 1st clipping path.
            clip_rect2 -- 2nd clipping path.
        """
        shp = tuple(transpose(desired.shape))
        gc = GraphicsContextArray(shp, pix_format="rgb24")
        gc.scale_ctm(scale, scale)

        # clear background to white values (255, 255, 255)
        gc.clear((1.0, 1.0, 1.0))

        gc.clip_to_rect(*clip_rect1)
        gc.clip_to_rect(*clip_rect2)

        gc.rect(0, 0, 4, 4)

        # These settings allow the fastest path.
        gc. set_fill_color((0.0, 0.0, 0.0)) # black
        gc.fill_path()

        # test a single color channel
        actual = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired, actual)

    def test_clip_successive_rects(self):
        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])

        clip_rect1 = (1, 1, 20, 20)
        clip_rect2 = (0, 0, 3, 3)

        self.successive_clip_helper(desired, 1.0, clip_rect1, clip_rect2)

    def test_clip_successive_rects2(self):
        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])

        clip_rect1 = (1, 1, 20, 20)
        clip_rect2 = (-1, -1, 4, 4)

        self.successive_clip_helper(desired, 1.0, clip_rect1, clip_rect2)

    #------------------------------------------------------------------------
    # Save/Restore clipping path.
    #------------------------------------------------------------------------

    def test_save_restore_clip_path(self):

        desired = array([[255, 255, 255, 255],
                         [255,   0,   0, 255],
                         [255,   0,   0, 255],
                         [255, 255, 255, 255]])

        # this is the clipping path we hope to see.
        clip_rect1 = (1, 1, 2, 2)

        # this will be a second path that will push/pop that should
        # never be seen.
        clip_rect2 = (1, 1, 1, 1)

        shp = tuple(transpose(desired.shape))
        gc = GraphicsContextArray(shp, pix_format="rgb24")

        # clear background to white values (255, 255, 255)
        gc.clear((1.0, 1.0, 1.0))

        gc.clip_to_rect(*clip_rect1)

        # push and then pop a path that shouldn't affect the drawing
        gc.save_state()
        gc.clip_to_rect(*clip_rect2)
        gc.restore_state()

        gc.rect(0, 0, 4, 4)

        # These settings allow the fastest path.
        gc. set_fill_color((0.0, 0.0, 0.0)) # black
        gc.fill_path()

        # test a single color channel
        actual = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired, actual)

    def test_reset_path(self):
        """ clip_to_rect() should clear the current path.

            This is to maintain compatibility with the version
            of kiva that sits on top of Apple's Quartz engine.
        """
        desired = array([[255, 255,   0,   0],
                         [255, 255,   0,   0],
                         [255, 255,   0,   0],
                         [255, 255,   0,   0]])

        shp = tuple(transpose(desired.shape))
        gc = GraphicsContextArray(shp, pix_format="rgb24")

        # clear background to white values (255, 255, 255)
        gc.clear((1.0, 1.0, 1.0))

        gc.rect(0, 0, 2, 4)

        gc.clip_to_rect(0, 0, 4, 4)
        gc.rect(2, 0, 2, 4)

        # These settings allow the fastest path.
        gc. set_fill_color((0.0, 0.0, 0.0)) # black
        gc.fill_path()

        # test a single color channel
        actual = gc.bmp_array[:,:,0]
        self.assertRavelEqual(desired, actual)


class ClipToRectsTestCase(unittest.TestCase):
    def test_not_implemented(self):
        """ fix me: Currently not implemented, so we just ensure that
            any call to it throws an exception.
        """

        gc = GraphicsContextArray((1,1), pix_format="rgb24")
        gc.rotate_ctm(1.0)

        #self.failUnlessRaises(NotImplementedError, gc.clip_to_rects, [[0, 0, 1, 1]])

if __name__ == "__main__":
    unittest.main()