Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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