"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.
For more information about "canvas.py" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
0.99.beta19_vs_0.99.beta20.
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