"Fossies" - the Fresh Open Source Software Archive 
Member "libcaca-0.99.beta20/python/caca/canvas.py" (21 Apr 2017, 58986 Bytes) of package /linux/privat/libcaca-0.99.beta20.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
1 # -*- coding: utf-8 -*-
2 #
3 # libcaca Colour ASCII-Art library
4 # Python language bindings
5 # Copyright (c) 2010 Alex Foulon <alxf@lavabit.com>
6 # All Rights Reserved
7 #
8 # This library is free software. It comes without any warranty, to
9 # the extent permitted by applicable law. You can redistribute it
10 # and/or modify it under the terms of the Do What the Fuck You Want
11 # to Public License, Version 2, as published by Sam Hocevar. See
12 # http://www.wtfpl.net/ for more details.
13 #
14
15 """ Libcaca Python bindings """
16
17 import ctypes
18 import errno
19
20 from caca import _lib, utf8_to_utf32, utf32_to_utf8
21 from caca import _PYTHON3, _str_to_bytes, _bytes_to_str
22 from caca.font import _Font
23
24
25 class _CanvasStruct(ctypes.Structure):
26 pass
27
28 class _Canvas(object):
29 """ Model for Canvas objects.
30 """
31
32 def __init__(self):
33 self._cv = None
34
35 def from_param(self):
36 """ Required by ctypes module to call object as parameter of
37 a C function.
38 """
39 return self._cv
40
41 def __str__(self):
42 return "<CacaCanvas %dx%d>" % (self.get_width(), self.get_height())
43
44 def __del__(self):
45 if self._cv and _lib is not None:
46 self._free()
47
48 def _free(self):
49 """ Free a libcaca canvas.
50 """
51 _lib.caca_free_canvas.argtypes = [_Canvas]
52 _lib.caca_free_canvas.restype = ctypes.c_int
53
54 return _lib.caca_free_canvas(self)
55
56 class Canvas(_Canvas):
57 """ Canvas object, methods are libcaca functions with canvas_t as
58 first parameter.
59 """
60 def __init__(self, width=0, height=0, pointer=None):
61 """ Canvas constructor.
62
63 width -- the desired canvas width
64 height -- the desired canvas height
65 pointer -- pointer to libcaca canvas
66 """
67 _lib.caca_create_canvas.argtypes = [ctypes.c_int, ctypes.c_int]
68 _lib.caca_create_canvas.restype = ctypes.POINTER(_CanvasStruct)
69
70 if pointer is None:
71 try:
72 self._cv = _lib.caca_create_canvas(width, height)
73 except ctypes.ArgumentError:
74 self._cv = 0
75 raise CanvasError("Specified width or height is invalid")
76 else:
77 if self._cv == 0:
78 err = ctypes.c_int.in_dll(_lib, "errno")
79 if err.value == errno.EINVAL:
80 raise CanvasError("Specified width or height is"
81 " invalid")
82 elif err.value == errno.ENOMEM:
83 raise CanvasError("Not enough memory for the requested"
84 " canvas size")
85 else:
86 raise CanvasError("Unknown error: failed to create"
87 " canvas")
88 else:
89 self._cv = pointer
90
91 def manage(self, *args, **kw):
92 """ Not implemented.
93 """
94 raise CanvasError("Not implemented")
95
96 def unmanage(self, *args, **kw):
97 """ Not implemented.
98 """
99 raise CanvasError("Not implemented")
100
101 def set_size(self, width, height):
102 """ Resize a canvas.
103
104 width -- the desired canvas width
105 height -- the desired canvas height
106 """
107 _lib.caca_set_canvas_size.argtypes = [
108 _Canvas, ctypes.c_int, ctypes.c_int
109 ]
110 _lib.caca_set_canvas_size.restype = ctypes.c_int
111
112 try:
113 ret = _lib.caca_set_canvas_size(self, width, height)
114 except ctypes.ArgumentError:
115 raise CanvasError("Specified width or height is invalid")
116 else:
117 if ret == -1:
118 err = ctypes.c_int.in_dll(_lib, "errno")
119 if err.value == errno.EINVAL:
120 raise CanvasError("Specified width or height is invalid")
121 elif err.value == errno.EBUSY:
122 raise CanvasError("The canvas is in use by a display driver"
123 " and cannot be resized")
124 elif err.value == errno.ENOMEM:
125 raise CanvasError("Not enough memory for the requested"
126 " canvas size")
127 else:
128 return ret
129
130 def get_width(self):
131 """ Get the canvas width.
132 """
133 _lib.caca_get_canvas_width.argtypes = [_Canvas]
134 _lib.caca_get_canvas_width.restype = ctypes.c_int
135
136 return _lib.caca_get_canvas_width(self)
137
138 def get_height(self):
139 """ Get the canvas height.
140 """
141 _lib.caca_get_canvas_height.argtypes = [_Canvas]
142 _lib.caca_get_canvas_height.restype = ctypes.c_int
143
144 return _lib.caca_get_canvas_height(self)
145
146 def get_chars(self, *args, **kw):
147 """ Not implemented.
148 """
149 raise CanvasError("Not implemented")
150
151 def get_attrs(self, *args, **kw):
152 """ Not implemented.
153 """
154 raise CanvasError("Not implemented")
155
156 def gotoxy(self, x, y):
157 """ Set cursor position. Setting the cursor position outside the canvas
158 is legal but the cursor will not be shown.
159
160 x -- X cursor coordinate
161 y -- Y cursor coordinate
162 """
163 _lib.caca_gotoxy.argtypes = [_Canvas, ctypes.c_int, ctypes.c_int]
164 _lib.caca_gotoxy.restyoe = ctypes.c_int
165
166 try:
167 ret = _lib.caca_gotoxy(self, x, y)
168 except ctypes.ArgumentError:
169 raise CanvasError("specified coordinate X or Y is invalid")
170 else:
171 return ret
172
173 def wherex(self):
174 """ Get X cursor position.
175 """
176 _lib.caca_wherex.argtypes = [_Canvas]
177 _lib.caca_wherex.restype = ctypes.c_int
178
179 return _lib.caca_wherex(self)
180
181 def wherey(self):
182 """ Get Y cursor position.
183 """
184 _lib.caca_wherey.argtypes = [_Canvas]
185 _lib.caca_wherey.restype = ctypes.c_int
186
187 return _lib.caca_wherey(self)
188
189 def put_char(self, x, y, ch):
190 """ Print an ASCII or Unicode character. Return the width of the
191 printed character: 2 for a fullwidth character, 1 otherwise.
192
193 x -- X coordinate
194 y -- Y coordinate
195 ch -- the character to print
196 """
197 _lib.caca_put_char.argtypes = [
198 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_uint32
199 ]
200 _lib.caca_put_char.restype = ctypes.c_int
201
202 if not isinstance(ch, str):
203 raise CanvasError("Specified character is invalid")
204 else:
205 try:
206 ch = ord(ch)
207 except TypeError:
208 ch = utf8_to_utf32(ch)
209
210 try:
211 ret = _lib.caca_put_char(self, x, y, ch)
212 except ctypes.ArgumentError:
213 raise CanvasError("specified coordinate X or Y is invalid")
214 else:
215 return ret
216
217 def get_char(self, x, y):
218 """ Get the Unicode character at the given coordinates.
219
220 x -- X coordinate
221 y -- Y coordinate
222 """
223 _lib.caca_get_char.argtypes = [
224 _Canvas, ctypes.c_int, ctypes.c_int
225 ]
226 _lib.caca_get_char.restype = ctypes.c_uint32
227
228 try:
229 ch = _lib.caca_get_char(self, x, y)
230 except ctypes.ArgumentError:
231 raise CanvasError("specified coordinate X or Y is invalid")
232 else:
233 try:
234 ch = ord(ch)
235 except TypeError:
236 ch = utf32_to_utf8(ch)
237
238 return ch
239
240 def put_str(self, x, y, s):
241 """ Print a string.
242
243 x -- X coordinate
244 y -- Y coordinate
245 s -- the string to print
246 """
247 _lib.caca_put_str.argtypes = [
248 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_char_p
249 ]
250 _lib.caca_put_str.restype = ctypes.c_int
251
252 if _PYTHON3 and isinstance(s, str):
253 s = _str_to_bytes(s)
254
255 try:
256 ret = _lib.caca_put_str(self, x, y, s)
257 except ctypes.ArgumentError:
258 raise CanvasError("Invalid argument")
259 else:
260 return ret
261
262 def printf(self, x, y, fmt, *args):
263 """ Print a formated string.
264
265 x -- X coordinate
266 y -- Y coordinate
267 fmt -- the format string to print
268 args -- Arguments to the format string
269 """
270 _lib.caca_printf.argtypes = [
271 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_char_p
272 ]
273 _lib.caca_printf.restype = ctypes.c_int
274
275 if _PYTHON3 and isinstance(fmt, str):
276 fmt = _str_to_bytes(fmt)
277
278 if _PYTHON3:
279 nargs = []
280 for arg in args[:]:
281 if isinstance(arg, str):
282 nargs.append(_str_to_bytes(arg))
283 else:
284 nargs.append(arg)
285 else:
286 nargs = args
287
288 try:
289 ret = _lib.caca_printf(self, x, y, fmt, *nargs)
290 except ctypes.ArgumentError:
291 raise CanvasError("Specified coordinate X or Y is invalid")
292 else:
293 return ret
294
295 def vprintf(self, *args, **kw):
296 """ Not implemented.
297 """
298 raise CanvasError("Not implemented")
299
300 def clear(self):
301 """ Clear the canvas.
302 """
303 _lib.caca_clear_canvas.argtypes = [_Canvas]
304 _lib.caca_clear_canvas.restype = ctypes.c_int
305
306 return _lib.caca_clear_canvas(self)
307
308 def set_handle(self, x, y):
309 """ Set cursor handle. Blitting method will use the handle value to
310 put the canvas at the proper coordinates.
311
312 x -- X handle coordinate
313 y -- Y handle coordinate
314 """
315 _lib.caca_set_canvas_handle.argtypes = [
316 _Canvas, ctypes.c_int, ctypes.c_int
317 ]
318 _lib.caca_set_canvas_handle.restype = ctypes.c_int
319
320 try:
321 ret = _lib.caca_set_canvas_handle(self, x, y)
322 except ctypes.ArgumentError:
323 raise CanvasError("Specified coordinate X or Y is invalid")
324 else:
325 return ret
326
327 def get_handle_x(self):
328 """ Get X handle position.
329 """
330 _lib.caca_get_canvas_handle_x.argtypes = [_Canvas]
331 _lib.caca_get_canvas_handle_x.restype = ctypes.c_int
332
333 return _lib.caca_get_canvas_handle_x(self)
334
335 def get_handle_y(self):
336 """ Get Y handle position.
337 """
338 _lib.caca_get_canvas_handle_y.argtypes = [_Canvas]
339 _lib.caca_get_canvas_handle_y.restype = ctypes.c_int
340
341 return _lib.caca_get_canvas_handle_y(self)
342
343 def blit(self, x, y, cv, mask=None):
344 """ Blit canvas onto another one.
345
346 x -- X coordinate
347 y -- Y coordinate
348 cv -- the source canvas
349 mask -- the mask canvas
350 """
351 _lib.caca_blit.argtypes = [
352 _Canvas, ctypes.c_int, ctypes.c_int, _Canvas, _Canvas
353 ]
354 _lib.caca_blit.restype = ctypes.c_int
355
356 if not isinstance(cv, Canvas):
357 raise CanvasError("Specified mask canvas is invalid")
358 else:
359 if mask is None:
360 mask = NullCanvas()
361 else:
362 if not isinstance(mask, _Canvas):
363 raise CanvasError("Specified mask canvas is invalid")
364
365 try:
366 ret = _lib.caca_blit(self, x, y, cv, mask)
367 except ctypes.ArgumentError:
368 raise CanvasError("Specified coordinate X or Y is invalid")
369 else:
370 if ret == -1:
371 err = ctypes.c_int.in_dll(_lib, "errno")
372 if err.value == errno.EINVAL:
373 raise CanvasError("A mask was specified but the mask size"
374 " and source canvas size do not match")
375 else:
376 return ret
377
378 def set_boundaries(self, x, y, width, height):
379 """ Set a canvas' new boundaries.
380
381 x -- X coordinate of the top-left corner
382 y -- Y coordinate of the top-left corner
383 width -- width of the box
384 height -- height of the box
385 """
386 _lib.caca_set_canvas_boundaries.argtypes = [
387 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int
388 ]
389 _lib.caca_set_canvas_boundaries.restype = ctypes.c_int
390
391 try:
392 ret = _lib.caca_set_canvas_boundaries(self, x, y, width, height)
393 except ctypes.ArgumentError:
394 raise CanvasError("Specified coordinate or size is invalid")
395 else:
396 if ret == -1:
397 err = ctypes.c_int.in_dll(_lib, "errno")
398 if err.value == errno.EINVAL:
399 raise CanvasError("Specified width or height is invalid")
400 elif err.value == errno.EBUSY:
401 raise CanvasError("The canvas is in use by a display driver"
402 " and cannot be resized")
403 elif err.value == errno.ENOMEM:
404 raise CanvasError("Not enough memory for the requested"
405 " canvas size")
406 else:
407 return ret
408
409 def disable_dirty_rect(self):
410 """ Disable dirty rectangles.
411 """
412 _lib.caca_disable_dirty_rect.argtypes = [_Canvas]
413 _lib.caca_disable_dirty_rect.restype = ctypes.c_int
414
415 return _lib.caca_disable_dirty_rect(self)
416
417 def enable_dirty_rect(self):
418 """ Enable dirty rectangles.
419 """
420 _lib.caca_enable_dirty_rect.argtypes = [_Canvas]
421 _lib.caca_enable_dirty_rect.restype = ctypes.c_int
422
423 ret = _lib.caca_enable_dirty_rect(self)
424 if ret == -1:
425 err = ctypes.c_int.in_dll(_lib, "errno")
426 if err.value == errno.EINVAL:
427 raise CanvasError("Dirty rectangles were not disabled")
428 else:
429 return ret
430
431 def get_dirty_rect_count(self):
432 """ Get the number of dirty rectangles in the canvas.
433 """
434 _lib.caca_get_dirty_rect_count.argtypes = [_Canvas]
435 _lib.caca_get_dirty_rect_count.restype = ctypes.c_int
436
437 return _lib.caca_get_dirty_rect_count(self)
438
439 def get_dirty_rect(self, idx):
440 """ Get a canvas's dirty rectangle. Return python dictionnary with
441 coords as keys: x, y, width, height.
442
443 idx -- the requested rectangle index
444 """
445 dct = None
446 x = ctypes.c_int()
447 y = ctypes.c_int()
448 width = ctypes.c_int()
449 height = ctypes.c_int()
450
451 _lib.caca_get_dirty_rect.argtypes = [
452 _Canvas, ctypes.c_int,
453 ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int),
454 ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int)
455 ]
456 _lib.caca_get_dirty_rect.restype = ctypes.c_int
457
458 try:
459 ret = _lib.caca_get_dirty_rect(self, idx, x, y, width, height)
460 except ctypes.ArgumentError:
461 raise CanvasError("Specified rectangle index is invalid")
462 else:
463 if ret == -1:
464 err = ctypes.c_int.in_dll(_lib, "errno")
465 if err.value == errno.EINVAL:
466 raise CanvasError("Specified rectangle index is out of"
467 " bounds")
468 else:
469 dct = {
470 'x': x.value, 'y': y.value,
471 'width': width.value, 'height': height.value,
472 }
473 return dct
474
475 def add_dirty_rect(self, x, y, width, height):
476 """ Add an area to the canvas's dirty rectangle list.
477
478 x -- the leftmost edge of the additional dirty rectangle
479 y -- the topmost edge of the additional dirty rectangle
480 width -- the width of the additional dirty rectangle
481 height -- the height of the additional dirty rectangle
482 """
483 _lib.caca_add_dirty_rect.argtypes = [
484 _Canvas, ctypes.c_int, ctypes.c_int,
485 ctypes.c_int, ctypes.c_int
486 ]
487 _lib.caca_add_dirty_rect.restype = ctypes.c_int
488
489 try:
490 ret =_lib.caca_add_dirty_rect(self, x, y, width, height)
491 except ctypes.ArgumentError:
492 raise CanvasError("Specified coordinate or size is invalid")
493 else:
494 if ret == -1:
495 err = ctypes.c_int.in_dll(_lib, "errno")
496 if err.value == errno.EINVAL:
497 raise CanvasError("Specified rectangle coordinates are out"
498 " of bounds")
499 else:
500 return ret
501
502 def remove_dirty_rect(self, x, y, width, height):
503 """ Remove an area from the dirty rectangle list.
504
505 x -- the leftmost edge of the additional dirty rectangle
506 y -- the topmost edge of the additional dirty rectangle
507 width -- the width of the additional rectangle
508 height -- the height of the additional dirty rectangle
509 """
510 _lib.caca_remove_dirty_rect.argtypes = [
511 _Canvas, ctypes.c_int, ctypes.c_int,
512 ctypes.c_int, ctypes.c_int
513 ]
514 _lib.caca_remove_dirty_rect.restype = ctypes.c_int
515
516 try:
517 ret = _lib.caca_remove_dirty_rect(self, x, y, width, height)
518 except ctypes.ArgumentError:
519 raise CanvasError("Specified coordinate or size is invalid")
520 else:
521 if ret == -1:
522 err = ctypes.c_int.in_dll(_lib, "errno")
523 if err.value == errno.EINVAL:
524 raise CanvasError("Specified rectangle coordinates are out"
525 " of bounds")
526 else:
527 return ret
528
529 def clear_dirty_rect_list(self):
530 """ Clear a canvas's dirty rectangle list.
531 """
532 _lib.caca_clear_dirty_rect_list.argtypes = [_Canvas]
533 _lib.caca_clear_dirty_rect_list.restype = ctypes.c_int
534
535 return _lib.caca_clear_dirty_rect_list(self)
536
537 def invert(self):
538 """ Invert a canvas' colours.
539 """
540 _lib.caca_invert.argtypes = [_Canvas]
541 _lib.caca_invert.restype = ctypes.c_int
542
543 return _lib.caca_invert(self)
544
545 def flip(self):
546 """ Flip a canvas horizontally.
547 """
548 _lib.caca_flip.argtypes = [_Canvas]
549 _lib.caca_flip.restype = ctypes.c_int
550
551 return _lib.caca_flip(self)
552
553 def flop(self):
554 """ Flip a canvas vertically.
555 """
556 _lib.caca_flop.argtypes = [_Canvas]
557 _lib.caca_flop.restype = ctypes.c_int
558
559 return _lib.caca_flop(self)
560
561 def rotate_180(self):
562 """ Rotate a canvas.
563 """
564 _lib.caca_rotate_180.argtypes = [_Canvas]
565 _lib.caca_rotate_180.restype = ctypes.c_int
566
567 return _lib.caca_rotate_180(self)
568
569 def rotate_left(self):
570 """ Rotate a canvas, 90 degrees counterclockwise.
571 """
572 _lib.caca_rotate_left.argtypes = [_Canvas]
573 _lib.caca_rotate_left.restype = ctypes.c_int
574
575 ret = _lib.caca_rotate_left(self)
576 if ret == -1:
577 err = ctypes.c_int.in_dll(_lib, "errno")
578 if err.value == errno.EBUSY:
579 raise CanvasError("The canvas is in use by a display driver"
580 " and cannot be rotated")
581 elif err.value == errno.ENOMEM:
582 raise CanvasError("Not enough memory to allocate the new"
583 " canvas size")
584 else:
585 return ret
586
587 def rotate_right(self):
588 """ Rotate a canvas, 90 degrees clockwise.
589 """
590 _lib.caca_rotate_right.argtypes = [_Canvas]
591 _lib.caca_rotate_right.restype = ctypes.c_int
592
593 ret = _lib.caca_rotate_right(self)
594 if ret == -1:
595 err = ctypes.c_int.in_dll(_lib, "errno")
596 if err.value == errno.EBUSY:
597 raise CanvasError("The canvas is in use by a display driver"
598 " and cannot be rotated")
599 elif err.value == errno.ENOMEM:
600 raise CanvasError("Not enough memory to allocate the new"
601 " canvas size")
602 else:
603 return ret
604
605 def stretch_left(self):
606 """ Rotate and stretch a canvas, 90 degrees counterclockwise.
607 """
608 _lib.caca_stretch_left.argtypes = [_Canvas]
609 _lib.caca_stretch_left.restype = ctypes.c_int
610
611 ret = _lib.caca_stretch_left(self)
612 if ret == -1:
613 err = ctypes.c_int.in_dll(_lib, "errno")
614 if err.value == errno.EBUSY:
615 raise CanvasError("The canvas is in use by a display driver"
616 " and cannot be rotated")
617 elif err.value == errno.ENOMEM:
618 raise CanvasError("Not enough memory to allocate the new"
619 " canvas size")
620 else:
621 return ret
622
623 def stretch_right(self):
624 """ Rotate and stretch a canvas, 90 degrees clockwise.
625 """
626 _lib.caca_stretch_right.argtypes = [_Canvas]
627 _lib.caca_stretch_right.restype = ctypes.c_int
628
629 ret = _lib.caca_stretch_right(self)
630 if ret == -1:
631 err = ctypes.c_int.in_dll(_lib, "errno")
632 if err.value == errno.EBUSY:
633 raise CanvasError("The canvas is in use by a display driver"
634 " and cannot be rotated")
635 elif err.value == errno.ENOMEM:
636 raise CanvasError("Not enough memory to allocate the new"
637 " canvas size")
638 else:
639 return ret
640
641 def get_attr(self, x, y):
642 """ Get the text attribute at the given coordinates.
643
644 x -- X coordinate
645 y -- Y coordinate
646 """
647 _lib.caca_get_attr.argtypes = [_Canvas, ctypes.c_int, ctypes.c_int]
648 _lib.caca_get_attr.restype = ctypes.c_uint32
649
650 try:
651 ret = _lib.caca_get_attr(self, x, y)
652 except ctypes.ArgumentError:
653 raise CanvasError("Specified coordinate X or Y is invalid")
654 else:
655 return ret
656
657 def set_attr(self, attr):
658 """ Set the default character attribute.
659
660 attr -- the requested attribute value
661 """
662 _lib.caca_set_attr.argtypes = [_Canvas, ctypes.c_uint32]
663 _lib.caca_set_attr.restype = ctypes.c_int
664
665 try:
666 ret = _lib.caca_set_attr(self, attr)
667 except ctypes.ArgumentError:
668 raise CanvasError("Specified attribute is invalid")
669 else:
670 return ret
671
672 def unset_attr(self, attr):
673 """ Unset the default character attribute.
674
675 attr -- the requested attribute value
676 """
677 _lib.caca_unset_attr.argtypes = [_Canvas, ctypes.c_uint32]
678 _lib.caca_unset_attr.restype = ctypes.c_int
679
680 try:
681 ret = _lib.caca_unset_attr(self, attr)
682 except ctypes.ArgumentError:
683 raise CanvasError("Specified attribute is invalid")
684 else:
685 return ret
686
687 def toggle_attr(self, attr):
688 """ Toggle the default character attribute.
689
690 attr -- the requested attribute value
691 """
692 _lib.caca_toggle_attr.argtypes = [_Canvas, ctypes.c_uint32]
693 _lib.caca_toggle_attr.restype = ctypes.c_int
694
695 try:
696 ret = _lib.caca_toggle_attr(self, attr)
697 except ctypes.ArgumentError:
698 raise CanvasError("Specified attribute is invalid")
699 else:
700 return ret
701
702 def put_attr(self, x, y, attr):
703 """ Set the character attribute at the given coordinates.
704
705 x -- X coordinate
706 y -- Y coordinate
707 attr -- the requested attribute value
708 """
709 _lib.caca_put_attr.argtypes = [
710 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_uint32
711 ]
712 _lib.caca_put_attr.restype = ctypes.c_int
713
714 try:
715 ret = _lib.caca_put_attr(self, x, y, attr)
716 except ctypes.ArgumentError:
717 raise CanvasError("Specified coordinate or attribute is invalid")
718 else:
719 return ret
720
721 def set_color_ansi(self, fg, bg):
722 """ Set the default colour pair for text (ANSI version).
723
724 fg -- the requested ANSI foreground colour.
725 bg -- the requested ANSI background colour.
726 """
727 _lib.caca_set_color_ansi.argtypes = [
728 _Canvas, ctypes.c_uint8, ctypes.c_uint8
729 ]
730 _lib.caca_set_color_ansi.restype = ctypes.c_int
731
732 try:
733 ret = _lib.caca_set_color_ansi(self, fg, bg)
734 except ctypes.ArgumentError:
735 raise CanvasError("At least one of the colour values is invalid")
736 else:
737 if ret == -1:
738 err = ctypes.c_int.in_dll(_lib, "errno")
739 if err.value == errno.EINVAL:
740 raise CanvasError("At least one of the colour values"
741 " is invalid")
742 else:
743 return ret
744
745 def set_color_argb(self, fg, bg):
746 """ Set the default colour pair for text (truecolor version).
747
748 fg -- the requested ARGB foreground colour.
749 bg -- the requested ARGB background colour.
750 """
751 _lib.caca_set_color_argb.argtypes = [
752 _Canvas, ctypes.c_uint16, ctypes.c_uint16
753 ]
754 _lib.caca_set_color_argb.restype = ctypes.c_int
755
756 try:
757 ret = _lib.caca_set_color_argb(self, fg, bg)
758 except ctypes.ArgumentError:
759 raise CanvasError("At least one of the colour values is invalid")
760 else:
761 return ret
762
763 def draw_line(self, x1, y1, x2, y2, ch):
764 """ Draw a line on the canvas using the given character.
765
766 x1 -- X coordinate of the first point
767 y1 -- Y coordinate of the first point
768 x2 -- X coordinate of the second point
769 y2 -- Y coordinate of the second point
770 ch -- character to be used to draw the line
771 """
772 _lib.caca_draw_line.argtypes = [
773 _Canvas, ctypes.c_int, ctypes.c_int,
774 ctypes.c_int, ctypes.c_int, ctypes.c_uint32
775 ]
776 _lib.caca_draw_line.restype = ctypes.c_int
777
778 if not isinstance(ch, str):
779 raise CanvasError("Specified character is invalid")
780 else:
781 try:
782 ch = ord(ch)
783 except TypeError:
784 ch = utf8_to_utf32(ch)
785
786 try:
787 ret = _lib.caca_draw_line(self, x1, y1, x2, y2, ch)
788 except ctypes.ArgumentError:
789 raise CanvasError("specified coordinate is invalid")
790 else:
791 return ret
792
793 def draw_polyline(self, array_xy, ch):
794 """ Draw a polyline.
795
796 array_xy -- List of (X, Y) coordinates
797 ch -- character to be used to draw the line
798 """
799 if not isinstance(array_xy, list) or len(array_xy) < 2:
800 raise CanvasError("Specified array of coordinates is invalid")
801 else:
802 for item in array_xy:
803 if not isinstance(item, list) and \
804 not isinstance(item, tuple):
805 raise CanvasError("Specified array of coordinates"
806 " is invalid")
807
808 ax = ctypes.c_int * len(array_xy)
809 ay = ctypes.c_int * len(array_xy)
810
811 _lib.caca_draw_polyline.argtypes = [
812 _Canvas, ax, ay, ctypes.c_int, ctypes.c_uint32
813 ]
814 _lib.caca_draw_polyline.restype = ctypes.c_int
815
816 if not isinstance(ch, str):
817 raise CanvasError("Specified character is invalid")
818 else:
819 try:
820 ch = ord(ch)
821 except TypeError:
822 ch = utf8_to_utf32(ch)
823
824 try:
825 ax = ax(*[x[0] for x in array_xy])
826 ay = ay(*[y[1] for y in array_xy])
827 except IndexError:
828 raise CanvasError("Specified array coordinates is invalid")
829
830 try:
831 ret = _lib.caca_draw_polyline(self, ax, ay,
832 len(array_xy) - 1, ch)
833 except ctypes.ArgumentError:
834 raise CanvasError("specified array of coordinates is invalid")
835 else:
836 return ret
837
838 def draw_thin_line(self, x1, y1, x2, y2):
839 """ Draw a thin line on the canvas, using ASCII art.
840
841 x1 -- X coordinate of the first point
842 y1 -- Y coordinate of the first point
843 x2 -- X coordinate of the second point
844 y2 -- Y coordinate of the second point
845 """
846 _lib.caca_draw_thin_line.argtypes = [
847 _Canvas, ctypes.c_int, ctypes.c_int,
848 ctypes.c_int, ctypes.c_int
849 ]
850 _lib.caca_draw_thin_line.restype = ctypes.c_int
851
852 try:
853 ret = _lib.caca_draw_thin_line(self, x1, y1, x2, y2)
854 except ctypes.ArgumentError:
855 raise CanvasError("specified coordinate is invalid")
856 else:
857 return ret
858
859 def draw_thin_polyline(self, array_xy):
860 """ Draw an ASCII art thin polyline.
861
862 array_xy -- Array of (X, Y) coordinates
863 """
864 if not isinstance(array_xy, list) or len(array_xy) < 2:
865 raise CanvasError("Specified array of coordinates is invalid")
866 else:
867 for item in array_xy:
868 if not isinstance(item, list) and \
869 not isinstance(item, tuple):
870 raise CanvasError("Specified array of coordinates"
871 " is invalid")
872
873 ax = ctypes.c_int * len(array_xy)
874 ay = ctypes.c_int * len(array_xy)
875
876 _lib.caca_draw_thin_polyline.argtypes = [
877 Canvas, ax, ay, ctypes.c_int
878 ]
879 _lib.caca_draw_thin_polyline.restype = ctypes.c_int
880
881 try:
882 ax = ax(*[x[0] for x in array_xy])
883 ay = ay(*[y[1] for y in array_xy])
884 except IndexError:
885 raise CanvasError("Specified array coordinates is invalid")
886
887 try:
888 ret = _lib.caca_draw_thin_polyline(self, ax, ay, len(array_xy) - 1)
889 except ctypes.ArgumentError:
890 raise CanvasError("specified array of coordinates is invalid")
891 else:
892 return ret
893
894 def draw_circle(self, x, y, r, ch):
895 """ Draw a circle on the canvas using the given character.
896
897 x -- center X coordinate
898 y -- center Y coordinate
899 r -- circle radius
900 ch -- the UTF-32 character to be used to draw the circle outline
901 """
902 _lib.caca_draw_circle.argtypes = [
903 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint32
904 ]
905 _lib.caca_draw_circle.restype = ctypes.c_int
906
907 if not isinstance(ch, str):
908 raise CanvasError("Specified character is invalid")
909 else:
910 try:
911 ch = ord(ch)
912 except TypeError:
913 ch = utf8_to_utf32(ch)
914
915 try:
916 ret = _lib.caca_draw_circle(self, x, y, r, ch)
917 except ctypes.ArgumentError:
918 raise CanvasError("Specified circle coordinate or radius is"
919 " invalid")
920 else:
921 return ret
922
923 def draw_ellipse(self, xo, yo, a, b, ch):
924 """ Draw an ellipse on the canvas using the given character.
925
926 xo -- center X coordinate
927 yo -- center Y coordinate
928 a -- ellipse x radius
929 b -- ellipse y radius
930 ch -- UTF-32 character to be used to draw the ellipse outline
931 """
932 _lib.caca_draw_ellipse.argtypes = [
933 _Canvas, ctypes.c_int, ctypes.c_int,
934 ctypes.c_int, ctypes.c_int, ctypes.c_uint32
935 ]
936 _lib.caca_draw_ellipse.restype = ctypes.c_int
937
938 if not isinstance(ch, str):
939 raise CanvasError("Specified character is invalid")
940 else:
941 try:
942 ch = ord(ch)
943 except TypeError:
944 ch = utf8_to_utf32(ch)
945
946 try:
947 ret = _lib.caca_draw_ellipse(self, xo, yo, a, b, ch)
948 except ctypes.ArgumentError:
949 raise CanvasError("Specified ellipse coordinate or radius is"
950 " invalid")
951 else:
952 return ret
953
954 def draw_thin_ellipse(self, xo, yo, a, b):
955 """ Draw a thin ellipse on the canvas.
956
957 xo -- center X coordinate
958 yo -- center Y coordinate
959 a -- ellipse X radius
960 b -- ellipse Y radius
961 """
962 _lib.caca_draw_thin_ellipse.argtypes = [
963 _Canvas, ctypes.c_int, ctypes.c_int,
964 ctypes.c_int, ctypes.c_int
965 ]
966 _lib.caca_draw_thin_ellipse.restype = ctypes.c_int
967
968 try:
969 ret = _lib.caca_draw_thin_ellipse(self, xo, yo, a, b)
970 except ctypes.ArgumentError:
971 raise CanvasError("Specified ellipse coordinate or radius is"
972 " invalid")
973 else:
974 return ret
975
976 def fill_ellipse(self, xo, yo, a, b, ch):
977 """ Fill an ellipse on the canvas using the given character.
978
979 xo -- center X coordinate
980 yo -- center Y coordinate
981 a -- ellipse X radius
982 b -- ellipse Y radius
983 ch -- UTF-32 character to be used to fill the ellipse
984 """
985 _lib.caca_fill_ellipse.argtypes = [
986 _Canvas, ctypes.c_int, ctypes.c_int,
987 ctypes.c_int, ctypes.c_int, ctypes.c_uint32
988 ]
989 _lib.caca_fill_ellipse.restype = ctypes.c_int
990
991 if not isinstance(ch, str):
992 raise CanvasError("Specified character is invalid")
993 else:
994 try:
995 ch = ord(ch)
996 except TypeError:
997 ch = utf8_to_utf32(ch)
998
999 try:
1000 ret = _lib.caca_fill_ellipse(self, xo, yo, a, b, ch)
1001 except ctypes.ArgumentError:
1002 raise CanvasError("Specified ellipse coordinate or radius is"
1003 " invalid")
1004 else:
1005 return ret
1006
1007 def draw_box(self, x, y, width, height, ch):
1008 """ Draw a box on the canvas using the given character.
1009
1010 x -- X coordinate of the upper-left corner of the box
1011 y -- Y coordinate of the upper-left corner of the box
1012 width -- width of the box
1013 height -- height of the box
1014 ch -- character to be used to draw the box
1015 """
1016 _lib.caca_draw_box.argtypes = [
1017 Canvas, ctypes.c_int, ctypes.c_int,
1018 ctypes.c_int, ctypes.c_int, ctypes.c_uint32
1019 ]
1020 _lib.caca_draw_box.restype = ctypes.c_int
1021
1022 if not isinstance(ch, str):
1023 raise CanvasError("Specified character is invalid")
1024 else:
1025 try:
1026 ch = ord(ch)
1027 except TypeError:
1028 ch = utf8_to_utf32(ch)
1029
1030 try:
1031 ret = _lib.caca_draw_box(self, x, y, width, height, ch)
1032 except ctypes.ArgumentError:
1033 raise CanvasError("specified box coordinate is invalid")
1034 else:
1035 return ret
1036
1037 def draw_thin_box(self, x, y, width, height):
1038 """ Draw a thin box on the canvas.
1039
1040 x -- X coordinate of the upper-left corner of the box
1041 y -- Y coordinate of the upper-left corner of the box
1042 width -- width of the box
1043 height -- height of the box
1044 """
1045 _lib.caca_draw_thin_box.argtypes = [
1046 _Canvas, ctypes.c_int, ctypes.c_int,
1047 ctypes.c_int, ctypes.c_int
1048 ]
1049 _lib.caca_draw_thin_box.restype = ctypes.c_int
1050
1051 try:
1052 ret = _lib.caca_draw_thin_box(self, x, y, width, height)
1053 except ctypes.ArgumentError:
1054 raise CanvasError("specified box coordinate is invalid")
1055 else:
1056 return ret
1057
1058 def draw_cp437_box(self, x, y, width, height):
1059 """ Draw a box on the canvas using CP437 characters.
1060
1061 x -- X coordinate of the upper-left corner box
1062 y -- Y coordinate of the upper-left corner box
1063 width -- width of the box
1064 height -- height of the box
1065 """
1066 _lib.caca_draw_cp437_box.argtypes = [
1067 _Canvas, ctypes.c_int, ctypes.c_int,
1068 ctypes.c_int, ctypes.c_int
1069 ]
1070 _lib.caca_draw_cp437_box.restype = ctypes.c_int
1071
1072 try:
1073 ret = _lib.caca_draw_cp437_box(self, x, y, width, height)
1074 except ctypes.ArgumentError:
1075 raise CanvasError("specified box coordinate is invalid")
1076 else:
1077 return ret
1078
1079 def fill_box(self, x, y, width, height, ch):
1080 """ Fill a box on the canvas using the given character.
1081
1082 x -- X coordinate of the upper-left corner of the box
1083 y -- Y coordinate of the upper-left corner of the box
1084 width -- width of the box
1085 height -- height of the box
1086 ch -- UFT-32 character to be used to fill the box
1087 """
1088 _lib.caca_fill_box.argtypes = [
1089 _Canvas, ctypes.c_int, ctypes.c_int,
1090 ctypes.c_int, ctypes.c_int, ctypes.c_uint32
1091 ]
1092 _lib.caca_fill_box.restype = ctypes.c_int
1093
1094 if not isinstance(ch, str):
1095 raise CanvasError("Specified character is invalid")
1096 else:
1097 try:
1098 ch = ord(ch)
1099 except TypeError:
1100 ch = utf8_to_utf32(ch)
1101
1102 try:
1103 ret = _lib.caca_fill_box(self, x, y, width, height, ch)
1104 except ctypes.ArgumentError:
1105 raise CanvasError("specified box coordinate is invalid")
1106 else:
1107 return ret
1108
1109 def draw_triangle(self, x1, y1, x2, y2, x3, y3, ch):
1110 """ Draw a triangle on the canvas using the given character.
1111
1112 x1 -- X coordinate of the first point
1113 y1 -- Y coordinate of the first point
1114 x2 -- X coordinate of the second point
1115 y2 -- Y coordinate of the second point
1116 x3 -- X coordinate of the third point
1117 y3 -- Y coordinate of the third point
1118 ch -- UTF-32 character to be used to draw the triangle outline
1119 """
1120 _lib.caca_draw_triangle.argtypes = [
1121 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int,
1122 ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_uint32
1123 ]
1124 _lib.caca_draw_triangle.restype = ctypes.c_int
1125
1126 if not isinstance(ch, str):
1127 raise CanvasError("Specified character is invalid")
1128 else:
1129 try:
1130 ch = ord(ch)
1131 except TypeError:
1132 ch = utf8_to_utf32(ch)
1133
1134 try:
1135 ret = _lib.caca_draw_triangle(self, x1, y1, x2, y2, x3, y3, ch)
1136 except ctypes.ArgumentError:
1137 raise CanvasError("specified triangle coordinate is invalid")
1138 else:
1139 return ret
1140
1141 def draw_thin_triangle(self, x1, y1, x2, y2, x3, y3):
1142 """ Draw a thin triangle on the canvas.
1143
1144 x1 -- X coordinate of the first point
1145 y1 -- Y coordinate of the first point
1146 x2 -- X coordinate of the second point
1147 y2 -- Y coordinate of the second point
1148 x3 -- X coordinate of the third point
1149 y3 -- Y coordinate of the third point
1150 """
1151 _lib.caca_draw_thin_triangle.argtypes = [
1152 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int,
1153 ctypes.c_int, ctypes.c_int, ctypes.c_int
1154 ]
1155 _lib.caca_draw_thin_triangle.restype = ctypes.c_int
1156
1157 try:
1158 ret = _lib.caca_draw_thin_triangle(self, x1, y1, x2, y2, x3, y3)
1159 except ctypes.ArgumentError:
1160 raise CanvasError("specified triangle coordinate is invalid")
1161 else:
1162 return ret
1163
1164 def fill_triangle(self, x1, y1, x2, y2, x3, y3, ch):
1165 """ Fill a triangle on the canvas using the given character.
1166
1167 x1 -- X coordinate of the first point
1168 y1 -- Y coordinate of the first point
1169 x2 -- X coordinate of the second point
1170 y2 -- Y coordinate of the second point
1171 x3 -- X coordinate of the second point
1172 y3 -- Y coordinate of the second point
1173 ch -- UTF-32 character to be used to fill the triangle
1174 """
1175 _lib.caca_fill_triangle.argtypes = [
1176 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int,
1177 ctypes.c_int, ctypes.c_int, ctypes.c_int
1178 ]
1179 _lib.caca_fill_triangle.restype = ctypes.c_int
1180
1181 if not isinstance(ch, str):
1182 raise CanvasError("Specified character is invalid")
1183 else:
1184 try:
1185 ch = ord(ch)
1186 except TypeError:
1187 ch = utf8_to_utf32(ch)
1188
1189 try:
1190 ret = _lib.caca_fill_triangle(self, x1, y1, x2, y2, x3, y3, ch)
1191 except ctypes.ArgumentError:
1192 raise CanvasError("specified triangle coordinate is invalid")
1193 else:
1194 return ret
1195
1196 def fill_triangle_textured(self, coords, tex, uv):
1197 """ Fill a triangle on the canvas using an arbitrary-sized texture.
1198
1199 coords -- coordinates of the triangle (3{x,y})
1200 tex -- the handle of the canvas texture
1201 uv -- coordinates of the texture (3{u,v})
1202 """
1203 _lib.caca_fill_triangle_textured.argtypes = [
1204 _Canvas, ctypes.c_int * 6, _Canvas, ctypes.c_int * 6
1205 ]
1206 _lib.caca_fill_triangle_textured.restype = ctypes.c_int
1207
1208 return _lib.caca_fill_triangle_textured(self, coords, tex, uv)
1209
1210 def get_frame_count(self):
1211 """ Get the number of frames in a canvas.
1212 """
1213 _lib.caca_get_frame_count.argtypes = [_Canvas]
1214 _lib.caca_get_frame_count.restype = ctypes.c_int
1215
1216 return _lib.caca_get_frame_count(self)
1217
1218 def set_frame(self, idx):
1219 """ Activate a given canvas frame.
1220
1221 idx -- the canvas frame to activate
1222 """
1223 _lib.caca_set_frame.argtypes = [_Canvas, ctypes.c_int]
1224 _lib.caca_set_frame.restype = ctypes.c_int
1225
1226 try:
1227 ret = _lib.caca_set_frame(self, idx)
1228 except ctypes.ArgumentError:
1229 raise CanvasError("specified index is invalid")
1230 else:
1231 err = ctypes.c_int.in_dll(_lib, "errno")
1232 if err.value == errno.EINVAL:
1233 raise CanvasError("Requested frame is out of range")
1234 else:
1235 return ret
1236
1237 def get_frame_name(self):
1238 """ Get the current frame's name.
1239 """
1240 _lib.caca_get_frame_name.argtypes = [_Canvas]
1241 _lib.caca_get_frame_name.restype = ctypes.c_char_p
1242
1243 if _PYTHON3:
1244 return _bytes_to_str(_lib.caca_get_frame_name(self))
1245 else:
1246 return _lib.caca_get_frame_name(self)
1247
1248 def set_frame_name(self, name):
1249 """ Set the current frame's name.
1250
1251 name -- the name to give to the current frame
1252 """
1253 _lib.caca_set_frame_name.argtypes = [_Canvas, ctypes.c_char_p]
1254 _lib.caca_set_frame_name.restype = ctypes.c_int
1255
1256 if _PYTHON3 and isinstance(name, str):
1257 name = _str_to_bytes(name)
1258
1259 try:
1260 ret = _lib.caca_set_frame_name(self, name)
1261 except ctypes.ArgumentError:
1262 raise CanvasError("Specified name is invalid")
1263 else:
1264 err = ctypes.c_int.in_dll(_lib, "errno")
1265 if err.value == errno.ENOMEM:
1266 raise CanvasError("Not enough memory to allocate new frame")
1267 else:
1268 return ret
1269
1270 def create_frame(self, idx):
1271 """ Add a frame to a canvas.
1272
1273 idx -- the index where to insert the new frame
1274 """
1275 _lib.caca_create_frame.argtypes = [_Canvas, ctypes.c_int]
1276 _lib.caca_create_frame.restype = ctypes.c_int
1277
1278 try:
1279 ret = _lib.caca_create_frame(self, idx)
1280 except ctypes.ArgumentError:
1281 raise CanvasError("specified index is invalid")
1282 else:
1283 err = ctypes.c_int.in_dll(_lib, "errno")
1284 if err.value == errno.ENOMEM:
1285 raise CanvasError("Not enough memory to allocate new frame")
1286 else:
1287 return ret
1288
1289 def free_frame(self, idx):
1290 """ Remove a frame from a canvas.
1291
1292 idx -- the index of the frame to delete
1293 """
1294 _lib.caca_free_frame.argtypes = [_Canvas, ctypes.c_int]
1295 _lib.caca_free_frame.restype = ctypes.c_int
1296
1297 try:
1298 ret = _lib.caca_free_frame(self, idx)
1299 except ctypes.ArgumentError:
1300 raise CanvasError("specified index is invalid")
1301 else:
1302 err = ctypes.c_int.in_dll(_lib, "errno")
1303 if err.value == errno.EINVAL:
1304 raise CanvasError("Requested frame is out of range, or attempt"
1305 " to delete the last frame of the canvas")
1306 else:
1307 return ret
1308
1309 def import_from_memory(self, data, fmt):
1310 """ Import a memory buffer into a canvas.
1311
1312 data -- a memory area containing the data to be loaded into
1313 the canvas
1314 fmt -- a string describing the input format
1315
1316 Valid values for format are:
1317 - "": attempt to autodetect the file format.
1318 - caca: import native libcaca files.
1319 - text: import ASCII text files.
1320 - ansi: import ANSI files.
1321 - utf8: import UTF-8 files with ANSI colour codes.
1322 """
1323
1324 _lib.caca_import_canvas_from_memory.argtypes = [
1325 Canvas, ctypes.c_char_p,
1326 ctypes.c_size_t, ctypes.c_char_p
1327 ]
1328 _lib.caca_import_canvas_from_memory.restype = ctypes.c_int
1329
1330 if _PYTHON3 and isinstance(data, str):
1331 data = _str_to_bytes(data)
1332 if _PYTHON3 and isinstance(fmt, str):
1333 fmt = _str_to_bytes(fmt)
1334
1335 length = ctypes.c_size_t(len(data))
1336
1337 try:
1338 ret = _lib.caca_import_canvas_from_memory(self, data, length, fmt)
1339 except ctypes.ArgumentError:
1340 raise CanvasError("Given data are invalid")
1341 else:
1342 err = ctypes.c_int.in_dll(_lib, "errno")
1343 if ret == -1:
1344 if err.value == errno.ENOMEM:
1345 raise CanvasError("Not enough memory to allocate canvas")
1346 elif err.value == errno.EINVAL:
1347 raise CanvasError("Invalid format requested")
1348 else:
1349 return ret
1350
1351 def import_from_file(self, filename, fmt):
1352 """ Import a file into a canvas.
1353
1354 filename -- the name of the file to load
1355 fmt -- a string describing the input format
1356
1357 Valid values for format are:
1358 - "": attempt to autodetect the file format.
1359 - caca: import native libcaca files.
1360 - text: import ASCII text files.
1361 - ansi: import ANSI files.
1362 - utf8: import UTF-8 files with ANSI colour codes.
1363 """
1364 _lib.caca_import_canvas_from_file.argtypes = [
1365 _Canvas, ctypes.c_char_p, ctypes.c_char_p
1366 ]
1367 _lib.caca_import_canvas_from_file.restype = ctypes.c_int
1368
1369 if _PYTHON3 and isinstance(filename, str):
1370 filename = _str_to_bytes(filename)
1371 if _PYTHON3 and isinstance(fmt, str):
1372 fmt = _str_to_bytes(fmt)
1373
1374 try:
1375 ret = _lib.caca_import_canvas_from_file(self, filename, fmt)
1376 except ctypes.ArgumentError:
1377 raise CanvasError("Specified filename is invalid")
1378 else:
1379 err = ctypes.c_int.in_dll(_lib, "errno")
1380 if ret == -1:
1381 if err.value == errno.ENOSYS:
1382 raise CanvasError("File access is not implemented on this"
1383 " system")
1384 elif err.value == errno.ENOMEM:
1385 raise CanvasError("Not enough memory to allocate canvas")
1386 elif err.value == errno.EINVAL:
1387 raise CanvasError("Invalid format requested")
1388 else:
1389 return ret
1390
1391 def import_area_from_memory(self, x, y, data, fmt):
1392 """ Import a memory buffer into a canvas area.
1393
1394 x -- the leftmost coordinate of the area to import to
1395 y -- the topmost coordinate of the area to import to
1396 data -- a memory area containing the data to be loaded into
1397 the canvas
1398 fmt -- a string describing the input format
1399
1400 Valid values for format are:
1401 - "": attempt to autodetect the file format.
1402 - caca: import native libcaca files.
1403 - text: import ASCII text files.
1404 - ansi: import ANSI files.
1405 - utf8: import UTF-8 files with ANSI colour codes.
1406 """
1407 length = ctypes.c_size_t(len(data))
1408
1409 _lib.caca_import_area_from_memory.argtypes = [
1410 _Canvas, ctypes.c_int, ctypes.c_int,
1411 ctypes.c_char_p, ctypes.c_size_t, ctypes.c_char_p
1412 ]
1413 _lib.caca_import_area_from_memory.restype = ctypes.c_int
1414
1415 if _PYTHON3 and isinstance(data, str):
1416 data = _str_to_bytes(data)
1417 if _PYTHON3 and isinstance(fmt, str):
1418 fmt = _str_to_bytes(fmt)
1419
1420 try:
1421 ret = _lib.caca_import_area_from_memory(self, x, y,
1422 data, length, fmt)
1423 except ctypes.ArgumentError:
1424 raise CanvasError("Specified coordinate X or Y is invalid")
1425 else:
1426 if ret == -1:
1427 err = ctypes.c_int.in_dll(_lib, "errno")
1428 if err.value == errno.EINVAL:
1429 raise CanvasError("Unsupported format requested or"
1430 " invalid coordinates")
1431 elif err.value == errno.ENOMEM:
1432 raise CanvasError("Not enough memory to allocate canvas")
1433 else:
1434 return ret
1435
1436 def import_area_from_file(self, x, y, filename, fmt):
1437 """ Import a file into a canvas area.
1438
1439 x -- the leftmost coordinate of the area to import to
1440 y -- the topmost coordinate of the area to import to
1441 filename -- the name of the file to be load
1442 fmt -- a string describing the input format
1443
1444 Valid values for format are:
1445 - "": attempt to autodetect the file format.
1446 - caca: import native libcaca files.
1447 - text: import ASCII text files.
1448 - ansi: import ANSI files.
1449 - utf8: import UTF-8 files with ANSI colour codes.
1450 """
1451 _lib.caca_import_area_from_file.argtypes = [
1452 _Canvas, ctypes.c_int, ctypes.c_int,
1453 ctypes.c_char_p, ctypes.c_char_p
1454 ]
1455 _lib.caca_import_area_from_file.restype = ctypes.c_int
1456
1457 if _PYTHON3 and isinstance(filename, str):
1458 filename = _str_to_bytes(filename)
1459 if _PYTHON3 and isinstance(fmt, str):
1460 fmt = _str_to_bytes(fmt)
1461
1462 try:
1463 ret = _lib.caca_import_area_from_file(self, x, y, filename, fmt)
1464 except ctypes.ArgumentError:
1465 raise CanvasError("Specified coordinate X or Y is invalid")
1466 else:
1467 if ret == -1:
1468 err = ctypes.c_int.in_dll(_lib, "errno")
1469 if err.value == errno.ENOSYS:
1470 raise CanvasError("File access is not implemented on this"
1471 " system")
1472 elif err.value == errno.ENOMEM:
1473 raise CanvasError("Not enough memory to allocate canvas")
1474 elif err.value == errno.EINVAL:
1475 raise CanvasError("Unsupported format requested or"
1476 " invalid coordinates")
1477 else:
1478 return ret
1479
1480 def export_to_memory(self, fmt):
1481 """ Export a canvas into a foreign format.
1482
1483 fmt -- a string describing the output format
1484
1485 Valid values for format are:
1486 - caca: export native libcaca files.
1487 - ansi: export ANSI art (CP437 charset with ANSI colour codes).
1488 - html: export an HTML page with CSS information.
1489 - html3: export an HTML table that should be compatible with
1490 most navigators, including textmode ones.
1491 - irc: export UTF-8 text with mIRC colour codes.
1492 - ps: export a PostScript document.
1493 - svg: export an SVG vector image.
1494 - tga: export a TGA image.
1495 """
1496 p_size_t = ctypes.POINTER(ctypes.c_size_t)
1497 _lib.caca_export_canvas_to_memory.argtypes = [
1498 _Canvas, ctypes.c_char_p, p_size_t
1499 ]
1500 _lib.caca_export_canvas_to_memory.restype = ctypes.POINTER(
1501 ctypes.c_char_p)
1502
1503 p = ctypes.c_size_t()
1504
1505 if _PYTHON3 and isinstance(fmt, str):
1506 fmt = _str_to_bytes(fmt)
1507
1508 try:
1509 ret = _lib.caca_export_canvas_to_memory(self, fmt, p)
1510 except ctypes.ArgumentError:
1511 raise CanvasError("Invalid format requested")
1512 else:
1513 if not ret:
1514 err = ctypes.c_int.in_dll(_lib, "errno")
1515 if err.value == errno.EINVAL:
1516 raise CanvasError("Invalid format requested")
1517 elif err.value == errno.ENOMEM:
1518 raise CanvasError("Not enough memory to allocate output"
1519 " buffer")
1520 else:
1521 if _PYTHON3:
1522 return _bytes_to_str(ctypes.string_at(ret, p.value))
1523 else:
1524 return ctypes.string_at(ret, p.value)
1525
1526 def export_area_to_memory(self, x, y, width, height, fmt):
1527 """ Export a canvas portion into a foreign format.
1528
1529 x -- the leftmost coordinate of the area to export
1530 y -- the topmost coordinate of the area to export
1531 width -- the width of the area to export
1532 height -- the height of the area to export
1533 fmt -- a string describing the output format
1534
1535 Valid values for format are:
1536 - caca: export native libcaca files.
1537 - ansi: export ANSI art (CP437 charset with ANSI colour codes).
1538 - html: export an HTML page with CSS information.
1539 - html3: export an HTML table that should be compatible with
1540 most navigators, including textmode ones.
1541 - irc: export UTF-8 text with mIRC colour codes.
1542 - ps: export a PostScript document.
1543 - svg: export an SVG vector image.
1544 - tga: export a TGA image.
1545 """
1546 p_size_t = ctypes.POINTER(ctypes.c_size_t)
1547
1548 _lib.caca_export_area_to_memory.argtypes = [
1549 _Canvas, ctypes.c_int, ctypes.c_int, ctypes.c_int,
1550 ctypes.c_int, ctypes.c_char_p, p_size_t
1551 ]
1552 _lib.caca_export_area_to_memory.restype = ctypes.POINTER(ctypes.c_char_p)
1553
1554 p = ctypes.c_size_t()
1555
1556 if _PYTHON3 and isinstance(fmt, str):
1557 fmt = _str_to_bytes(fmt)
1558
1559 try:
1560 ret = _lib.caca_export_area_to_memory(self, x, y, width, height,
1561 fmt, p)
1562 except ctypes.ArgumentError:
1563 raise CanvasError("Requested area coordinate is invalid")
1564 else:
1565 if not ret:
1566 err = ctypes.c_int.in_dll(_lib, "errno")
1567 if err.value == errno.EINVAL:
1568 raise CanvasError("Invalid format requested")
1569 elif err.value == errno.ENOMEM:
1570 raise CanvasError("Not enough memory to allocate output"
1571 " buffer")
1572 else:
1573 if _PYTHON3:
1574 return _bytes_to_str(ctypes.string_at(ret, p.value))
1575 else:
1576 return ctypes.string_at(ret, p.value)
1577
1578 def set_figfont(self, filename):
1579 """ Load a figfont and attach it to a canvas.
1580
1581 filename -- the figfont file to load.
1582 """
1583 _lib.caca_canvas_set_figfont.argtypes = [_Canvas, ctypes.c_char_p]
1584 _lib.caca_canvas_set_figfont.restype = ctypes.c_int
1585
1586 if _PYTHON3 and isinstance(filename, str):
1587 filename = _str_to_bytes(filename)
1588
1589 return _lib.caca_canvas_set_figfont(self, filename)
1590
1591 def put_figchar(self, ch):
1592 """ Paste a character using the current figfont.
1593
1594 ch -- the character to paste
1595 """
1596 _lib.caca_put_figchar.argtypes = [_Canvas, ctypes.c_uint32]
1597 _lib.caca_put_figchar.restype = ctypes.c_int
1598
1599 if _PYTHON3 and isinstance(ch, str):
1600 ch = _str_to_bytes(ch)
1601
1602 try:
1603 ch = ord(ch)
1604 except TypeError:
1605 ch = utf8_to_utf32(ch)
1606
1607 return _lib.caca_put_figchar(self, ch)
1608
1609 def flush_figlet(self):
1610 """ Flush the figlet context
1611 """
1612 _lib.caca_flush_figlet.argtypes = [_Canvas]
1613 _lib.caca_flush_figlet.restype = ctypes.c_int
1614
1615 return _lib.caca_flush_figlet(self)
1616
1617 def render(self, font, buf, width, height, pitch):
1618 """ Render the canvas onto an image buffer.
1619
1620 font -- a Font() object
1621 buf -- the image buffer
1622 width -- the width (in pixels) of the image
1623 heigth -- the height (in pixels) of the image
1624 pitch -- the pitch (in bytes) of the image
1625 """
1626 _lib.caca_render_canvas.argtypes = [
1627 _Canvas, _Font, ctypes.c_char_p,
1628 ctypes.c_int, ctypes.c_int, ctypes.c_int
1629 ]
1630 _lib.caca_render_canvas.restype = ctypes.c_int
1631
1632 return _lib.caca_render_canvas(self, font, buf, width, height, pitch)
1633
1634 class NullCanvas(_Canvas):
1635 """ Represent a NULL canvas_t, eg to use as canvas mask for blit operations.
1636 """
1637 def __str__(self):
1638 return "<NullCanvas>"
1639
1640 class CanvasError(Exception):
1641 pass
1642