You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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