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.

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