Completed
Push — master ( 64314c...9b9cff )
by Kyle
58s
created

Console.blit()   B

Complexity

Conditions 3

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
cc 3
c 3
b 0
f 1
dl 0
loc 31
rs 8.8571
1
"""
2
libtcod works with a special 'root' console.  You create this console using
3
the :any:`tcod.console_init_root` function.  Usually after setting the font
4
with :any:`console_set_custom_font` first.
5
6
Example::
7
8
    # Make sure 'arial10x10.png' is in the same directory as this script.
9
    import time
10
11
    import tcod
12
13
    # Setup the font.
14
    tcod.console_set_custom_font(
15
        'arial10x10.png',
16
        tcod.FONT_LAYOUT_ASCII_INROW | tcod.FONT_LAYOUT_TCOD,
17
        )
18
    # Initialize the root console in a context.
19
    with tcod.console_init_root(80, 60, 'title') as root_console:
20
        root_console.print_(x=0, y=0, string='Hello World!')
21
        tcod.console_flush() # Show the console.
22
        time.sleep(3) # Wait 3 seconds.
23
    # The window is closed here, after the above context exits.
24
"""
25
26
from __future__ import absolute_import
27
28
import sys
29
30
import numpy as np
0 ignored issues
show
Configuration introduced by
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
31
32
import tcod.libtcod
33
from tcod.libtcod import ffi, lib
34
35
if sys.version_info[0] == 2: # Python 2
36
    def _fmt(string):
0 ignored issues
show
Coding Style introduced by
This function should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
37
        if not isinstance(string, unicode):
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'unicode'
Loading history...
38
            string = string.decode('latin-1')
39
        return string.replace(u'%', u'%%')
40
else:
41
    def _fmt(string):
42
        """Return a string that escapes 'C printf' side effects."""
43
        return string.replace('%', '%%')
44
45
46
class Console(object):
47
    """
48
    Args:
49
        width (int): Width of the new Console.
50
        height (int): Height of the new Console.
51
52
    Attributes:
53
        console_c (CData): A cffi pointer to a TCOD_console_t object.
54
            .. versionadded:: 2.5
55
56
    .. versionadded:: 2.0
57
    """
58
59
    def __init__(self, width, height):
60
        self._key_color = None
61
        self._ch = np.zeros((height, width), dtype=np.intc)
62
        self._fg = np.zeros((height, width, 3), dtype=np.uint8)
63
        self._bg = np.zeros((height, width, 3), dtype=np.uint8)
64
        self._console_data = self.console_c = ffi.new(
65
            'TCOD_console_data_t*',
66
            {
67
            'w': width, 'h': height,
68
            'ch_array': ffi.cast('int*', self._ch.ctypes.data),
69
            'fg_array': ffi.cast('TCOD_color_t*', self._fg.ctypes.data),
70
            'bg_array': ffi.cast('TCOD_color_t*', self._bg.ctypes.data),
71
            'bkgnd_flag': tcod.BKGND_SET,
0 ignored issues
show
Bug introduced by
The Module tcod does not seem to have a member named BKGND_SET.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
72
            'alignment': tcod.LEFT,
0 ignored issues
show
Bug introduced by
The Module tcod does not seem to have a member named LEFT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
73
            'fore': (255, 255, 255),
74
            'back': (0, 0, 0),
75
            },
76
        )
77
78
    @classmethod
79
    def _from_cdata(cls, cdata):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
80
        if isinstance(cdata, cls):
81
            return cdata
82
        self = object.__new__(cls)
83
        self.console_c = cdata
84
        self._init_setup_console_data()
85
        return self
86
87
    def _init_setup_console_data(self):
88
        """Setup numpy arrays over libtcod data buffers."""
89
        self._key_color = None
90
        if self.console_c == ffi.NULL:
91
            self._console_data = lib.TCOD_ctx.root
92
        else:
93
            self._console_data = ffi.cast('TCOD_console_data_t *', self.console_c)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (82/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
94
95
        def unpack_color(color_data):
96
            """return a (height, width, 3) shaped array from an image struct"""
97
            color_buffer = ffi.buffer(color_data[0:self.width * self.height])
98
            array = np.frombuffer(color_buffer, np.uint8)
99
            return array.reshape((self.height, self.width, 3))
100
101
        self._fg = unpack_color(self._console_data.fg_array)
102
        self._bg = unpack_color(self._console_data.bg_array)
103
104
        buf = self._console_data.ch_array
105
        buf = ffi.buffer(buf[0:self.width * self.height])
106
        self._ch = np.frombuffer(buf, np.intc).reshape((self.height,
107
                                                        self.width))
108
109
    @property
110
    def width(self):
111
        """int: The width of this Console. (read-only)"""
112
        return lib.TCOD_console_get_width(self.console_c)
113
114
    @property
115
    def height(self):
116
        """int: The height of this Console. (read-only)"""
117
        return lib.TCOD_console_get_height(self.console_c)
118
119
    @property
120
    def bg(self):
121
        """A uint8 array with the shape (height, width, 3).
122
123
        You can change the consoles background colors by using this array.
124
125
        Index this array with ``console.bg[y, x, channel]``
126
        """
127
        return self._bg
128
129
    @property
130
    def fg(self):
131
        """A uint8 array with the shape (height, width, 3).
132
133
        You can change the consoles foreground colors by using this array.
134
135
        Index this array with ``console.fg[y, x, channel]``
136
        """
137
        return self._fg
138
139
    @property
140
    def ch(self):
141
        """An integer array with the shape (height, width).
142
143
        You can change the consoles character codes by using this array.
144
145
        Index this array with ``console.ch[y, x]``
146
        """
147
        return self._ch
148
149
    @property
150
    def default_bg(self):
151
        """Tuple[int, int, int]: The default background color."""
152
        color = self._console_data.back
153
        return color.r, color.g, color.b
154
    @default_bg.setter
155
    def default_bg(self, color):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
156
        self._console_data.back = color
157
158
    @property
159
    def default_fg(self):
160
        """Tuple[int, int, int]: The default foreground color."""
161
        color = self._console_data.fore
162
        return color.r, color.g, color.b
163
    @default_fg.setter
164
    def default_fg(self, color):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
165
        self._console_data.fore = color
166
167
    @property
168
    def default_bg_blend(self):
169
        """int: The default blending mode."""
170
        return self._console_data.bkgnd_flag
171
    @default_bg_blend.setter
172
    def default_bg_blend(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
173
        self._console_data.bkgnd_flag = value
174
175
    @property
176
    def default_alignment(self):
177
        """int: The default text alignment."""
178
        return self._console_data.alignment
179
    @default_alignment.setter
180
    def default_alignment(self, value):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
181
        self._console_data.alignment = value
182
183
    def clear(self):
184
        """Reset this console to its default colors and the space character.
185
        """
186
        lib.TCOD_console_clear(self.console_c)
187
188
    def put_char(self, x, y, ch, bg_blend=tcod.libtcod.BKGND_DEFAULT):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
189
        """Draw the character c at x,y using the default colors and a blend mode.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (81/79).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
190
191
        Args:
192
            x (int): The x coordinate from the left.
193
            y (int): The y coordinate from the top.
194
            ch (int): Character code to draw.  Must be in integer form.
195
            bg_blend (int): Blending mode to use, defaults to BKGND_DEFAULT.
196
        """
197
        lib.TCOD_console_put_char(self.console_c, x, y, ch, bg_blend)
198
199
    def print_(self, x, y, string, bg_blend=tcod.libtcod.BKGND_DEFAULT,
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
200
               alignment=None):
201
        """Print a color formatted string on a console.
202
203
        Args:
204
            x (int): The x coordinate from the left.
205
            y (int): The y coordinate from the top.
206
            string (Text): A Unicode string optionaly using color codes.
207
        """
208
        alignment = self.default_alignment if alignment is None else alignment
209
210
        lib.TCOD_console_print_ex_utf(self.console_c, x, y,
211
                                      bg_blend, alignment, _fmt(string))
212
213
    def print_rect(self, x, y, width, height, string,
214
                   bg_blend=tcod.libtcod.BKGND_DEFAULT, alignment=None):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
215
        """Print a string constrained to a rectangle.
216
217
        If h > 0 and the bottom of the rectangle is reached,
218
        the string is truncated. If h = 0,
219
        the string is only truncated if it reaches the bottom of the console.
220
221
        Args:
222
            x (int): The x coordinate from the left.
223
            y (int): The y coordinate from the top.
224
            width (int): Maximum width to render the text.
225
            height (int): Maximum lines to render the text.
226
            string (Text): A Unicode string.
227
            bg_blend (int): Background blending flag.
228
            alignment (Optional[int]): Alignment flag.
229
230
        Returns:
231
            int: The number of lines of text once word-wrapped.
232
        """
233
        alignment = self.default_alignment if alignment is None else alignment
234
        return lib.TCOD_console_print_rect_ex_utf(self.console_c,
235
            x, y, width, height, bg_blend, alignment, _fmt(string))
236
237
    def get_height_rect(self, x, y, width, height, string):
238
        """Return the height of this text word-wrapped into this rectangle.
239
240
        Args:
241
            x (int): The x coordinate from the left.
242
            y (int): The y coordinate from the top.
243
            width (int): Maximum width to render the text.
244
            height (int): Maximum lines to render the text.
245
            string (Text): A Unicode string.
246
247
        Returns:
248
            int: The number of lines of text once word-wrapped.
249
        """
250
        return lib.TCOD_console_get_height_rect_utf(
251
            self.console_c, x, y, width, height, _fmt(string))
252
253
    def rect(self, x, y, width, height, clear,
254
             bg_blend=tcod.libtcod.BKGND_DEFAULT):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
255
        """Draw a the background color on a rect optionally clearing the text.
256
257
        If clr is True the affected tiles are changed to space character.
258
259
        Args:
260
            x (int): The x coordinate from the left.
261
            y (int): The y coordinate from the top.
262
            width (int): Maximum width to render the text.
263
            height (int): Maximum lines to render the text.
264
            clear (bool): If True all text in the affected area will be
265
                          removed.
266
            bg_blend (int): Background blending flag.
267
        """
268
        lib.TCOD_console_rect(self.console_c, x, y, width, height, clear,
269
                              bg_blend)
270
271
    def hline(self, x, y, width, bg_blend=tcod.libtcod.BKGND_DEFAULT):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
272
        """Draw a horizontal line on the console.
273
274
        This always uses the character 196, the horizontal line character.
275
276
        Args:
277
            x (int): The x coordinate from the left.
278
            y (int): The y coordinate from the top.
279
            width (int): The horozontal length of this line.
280
            bg_blend (int): The background blending flag.
281
        """
282
        lib.TCOD_console_hline(self.console_c, x, y, width, bg_blend)
283
284
    def vline(self, x, y, height, bg_blend=tcod.libtcod.BKGND_DEFAULT):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
285
        """Draw a vertical line on the console.
286
287
        This always uses the character 179, the vertical line character.
288
289
        Args:
290
            x (int): The x coordinate from the left.
291
            y (int): The y coordinate from the top.
292
            height (int): The horozontal length of this line.
293
            bg_blend (int): The background blending flag.
294
        """
295
        lib.TCOD_console_vline(self.console_c, x, y, height, bg_blend)
296
297
    def print_frame(self, x, y, width, height, string='',
298
                    clear=True, bg_blend=tcod.libtcod.BKGND_DEFAULT):
0 ignored issues
show
Bug introduced by
The Module tcod.libtcod does not seem to have a member named BKGND_DEFAULT.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
299
        """Draw a framed rectangle with optinal text.
300
301
        This uses the default background color and blend mode to fill the
302
        rectangle and the default foreground to draw the outline.
303
304
        string will be printed on the inside of the rectangle, word-wrapped.
305
306
        Args:
307
            x (int): The x coordinate from the left.
308
            y (int): The y coordinate from the top.
309
            width (int): The width if the frame.
310
            height (int): The height of the frame.
311
            string (Text): A Unicode string to print.
312
            clear (bool): If True all text in the affected area will be
313
                          removed.
314
            bg_blend (int): The background blending flag.
315
316
        Note:
317
            This method does not support Unicode outside of the 0-255 range.
318
        """
319
        lib.TCOD_console_print_frame(self.console_c, x, y, width, height,
320
                                     clear, bg_blend, string.encode('latin-1'))
321
322
    def blit(self, x, y, width, height,
323
             dest, dest_x, dest_y, fg_alpha=1.0, bg_alpha=1.0, key_color=None):
324
        """Blit from this console onto the ``dest`` console.
325
326
        Args:
327
            x (int): X coordinate of this console to blit, from the left.
328
            y (int): Y coordinate of this console to blit, from the top.
329
            width (int): The width of the region to blit.
330
331
                If this is 0 the maximum possible width will be used.
332
            height (int): The height of the region to blit.
333
334
                If this is 0 the maximum possible height will be used.
335
            dest (Console): The destintaion console to blit onto.
336
            dest_x (int): Leftmost coordinate of the destintaion console.
337
            dest_y (int): Topmost coordinate of the destintaion console.
338
            fg_alpha (float): Foreground color alpha vaule.
339
            bg_alpha (float): Background color alpha vaule.
340
            key_color (Optional[Tuple[int, int, int]]):
341
                None, or a (red, green, blue) tuple with values of 0-255.
342
        """
343
        if key_color or self._key_color:
344
            key_color = ffi.new('TCOD_color_t*', key_color)
345
            lib.TCOD_console_blit_key_color(
346
            self.console_c, x, y, width, height,
347
            dest.console_c, dest_x, dest_y, fg_alpha, bg_alpha, key_color
348
            )
349
        else:
350
            lib.TCOD_console_blit(
351
                self.console_c, x, y, width, height,
352
                dest.console_c, dest_x, dest_y, fg_alpha, bg_alpha
353
            )
354
355
    def set_key_color(self, color):
356
        """Set a consoles blit transparent color.
357
358
        Args:
359
            color (Tuple[int, int, int]):
360
        """
361
        self._key_color = color
362
363
    def __enter__(self):
364
        """Returns this console in a managed context.
365
366
        When the root console is used as a context, the graphical window will
367
        close once the context is left as if :any:`tcod.console_delete` was
368
        called on it.
369
370
        This is useful for some Python IDE's like IDLE, where the window would
371
        not be closed on its own otherwise.
372
        """
373
        if self.console_c != ffi.NULL:
374
            raise NotImplementedError('Only the root console has a context.')
375
        return self
376
377
    def __exit__(self, *args):
378
        """Closes the graphical window on exit.
379
380
        Some tcod functions may have undefined behavior after this point.
381
        """
382
        lib.TCOD_console_delete(self.console_c)
383
384
    def __bool__(self):
385
        """Returns False if this is the root console.
386
387
        This mimics libtcodpy behavior.
388
        """
389
        return self.console_c != ffi.NULL
390
391
    __nonzero__ = __bool__
392
393
    def __getstate__(self):
394
        state = self.__dict__.copy()
395
        del state['console_c']
396
        state['_console_data'] = {
397
            'w': self.width, 'h': self.height,
398
            'bkgnd_flag': self.default_bg_blend,
399
            'alignment': self.default_alignment,
400
            'fore': self.default_fg,
401
            'back': self.default_bg,
402
        }
403
        if self.console_c == ffi.NULL:
404
            state['_ch'] = np.copy(self._ch)
405
            state['_fg'] = np.copy(self._fg)
406
            state['_bg'] = np.copy(self._bg)
407
        return state
408
409
    def __setstate__(self, state):
410
        self._key_color = None
411
        self.__dict__.update(state)
412
        self._console_data.update(
413
            {
414
            'ch_array': ffi.cast('int*', self._ch.ctypes.data),
415
            'fg_array': ffi.cast('TCOD_color_t*', self._fg.ctypes.data),
416
            'bg_array': ffi.cast('TCOD_color_t*', self._bg.ctypes.data),
417
            }
418
        )
419
        self._console_data = self.console_c = ffi.new(
420
            'TCOD_console_data_t*', self._console_data)
421