1 | /* |
---|
2 | * libcaca Ruby bindings |
---|
3 | * Copyright (c) 2007-2010 Pascal Terjan <pterjan@linuxfr.org> |
---|
4 | * |
---|
5 | * This library is free software. It comes without any warranty, to |
---|
6 | * the extent permitted by applicable law. You can redistribute it |
---|
7 | * and/or modify it under the terms of the Do What The Fuck You Want |
---|
8 | * To Public License, Version 2, as published by Sam Hocevar. See |
---|
9 | * http://sam.zoy.org/wtfpl/COPYING for more details. |
---|
10 | */ |
---|
11 | |
---|
12 | #include <ruby.h> |
---|
13 | #include <caca.h> |
---|
14 | #include <errno.h> |
---|
15 | #include "caca-dither.h" |
---|
16 | #include "caca-font.h" |
---|
17 | #include "common.h" |
---|
18 | |
---|
19 | VALUE cCanvas; |
---|
20 | |
---|
21 | #define simple_func(x) \ |
---|
22 | static VALUE x (VALUE self) \ |
---|
23 | { \ |
---|
24 | if( caca_##x (_SELF) <0) \ |
---|
25 | rb_raise(rb_eRuntimeError, strerror(errno)); \ |
---|
26 | \ |
---|
27 | return self; \ |
---|
28 | } |
---|
29 | |
---|
30 | #define get_int(x) \ |
---|
31 | static VALUE get_##x (VALUE self) \ |
---|
32 | { \ |
---|
33 | return INT2NUM(caca_get_##x (_SELF)); \ |
---|
34 | } |
---|
35 | |
---|
36 | static void canvas_free(void * p) |
---|
37 | { |
---|
38 | caca_free_canvas((caca_canvas_t *)p); |
---|
39 | } |
---|
40 | |
---|
41 | static VALUE canvas_alloc(VALUE klass) |
---|
42 | { |
---|
43 | VALUE obj; |
---|
44 | obj = Data_Wrap_Struct(klass, NULL, canvas_free, NULL); |
---|
45 | return obj; |
---|
46 | } |
---|
47 | |
---|
48 | VALUE canvas_create(caca_canvas_t *canvas) |
---|
49 | { |
---|
50 | return Data_Wrap_Struct(cCanvas, NULL, NULL, canvas); |
---|
51 | } |
---|
52 | |
---|
53 | static VALUE canvas_initialize(VALUE self, VALUE width, VALUE height) |
---|
54 | { |
---|
55 | caca_canvas_t *canvas; |
---|
56 | |
---|
57 | canvas = caca_create_canvas(NUM2INT(width), NUM2INT(height)); |
---|
58 | |
---|
59 | if(canvas == NULL) |
---|
60 | { |
---|
61 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
62 | } |
---|
63 | |
---|
64 | _SELF = canvas; |
---|
65 | |
---|
66 | return self; |
---|
67 | } |
---|
68 | |
---|
69 | get_int(canvas_height) |
---|
70 | get_int(canvas_width) |
---|
71 | |
---|
72 | static VALUE set_canvas_width(VALUE self, VALUE width) |
---|
73 | { |
---|
74 | caca_set_canvas_size(_SELF, NUM2INT(width), caca_get_canvas_height(_SELF)); |
---|
75 | return width; |
---|
76 | } |
---|
77 | |
---|
78 | static VALUE set_canvas_width2(VALUE self, VALUE width) |
---|
79 | { |
---|
80 | set_canvas_width(self, width); |
---|
81 | return self; |
---|
82 | } |
---|
83 | |
---|
84 | static VALUE set_canvas_height(VALUE self, VALUE height) |
---|
85 | { |
---|
86 | caca_set_canvas_size(_SELF, caca_get_canvas_width(_SELF), NUM2INT(height)); |
---|
87 | return height; |
---|
88 | } |
---|
89 | |
---|
90 | static VALUE set_canvas_height2(VALUE self, VALUE height) |
---|
91 | { |
---|
92 | set_canvas_height(self, height); |
---|
93 | return self; |
---|
94 | } |
---|
95 | |
---|
96 | static VALUE set_canvas_size(VALUE self, VALUE height, VALUE width) |
---|
97 | { |
---|
98 | caca_set_canvas_size(_SELF, NUM2INT(width), NUM2INT(height)); |
---|
99 | return self; |
---|
100 | } |
---|
101 | |
---|
102 | /****/ |
---|
103 | |
---|
104 | static VALUE gotoxy(VALUE self, VALUE x, VALUE y) |
---|
105 | { |
---|
106 | if( caca_gotoxy(_SELF, NUM2INT(x), NUM2INT(y)) <0) { |
---|
107 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
108 | } |
---|
109 | return self; |
---|
110 | } |
---|
111 | |
---|
112 | static VALUE wherex(VALUE self) |
---|
113 | { |
---|
114 | return INT2NUM(caca_wherex(_SELF)); |
---|
115 | } |
---|
116 | |
---|
117 | static VALUE wherey(VALUE self) |
---|
118 | { |
---|
119 | return INT2NUM(caca_wherey(_SELF)); |
---|
120 | } |
---|
121 | |
---|
122 | simple_func(clear_canvas) |
---|
123 | |
---|
124 | static VALUE put_char(VALUE self, VALUE x, VALUE y, VALUE ch) |
---|
125 | { |
---|
126 | caca_put_char(_SELF, NUM2INT(x), NUM2INT(y), NUM2ULONG(ch)); |
---|
127 | return self; |
---|
128 | } |
---|
129 | |
---|
130 | static VALUE get_char(VALUE self, VALUE x, VALUE y) |
---|
131 | { |
---|
132 | unsigned long int ch; |
---|
133 | ch = caca_get_char(_SELF, NUM2INT(x), NUM2INT(y)); |
---|
134 | return INT2NUM(ch); |
---|
135 | } |
---|
136 | |
---|
137 | static VALUE put_str(VALUE self, VALUE x, VALUE y, VALUE str) |
---|
138 | { |
---|
139 | caca_put_str(_SELF, NUM2INT(x), NUM2INT(y), StringValuePtr(str)); |
---|
140 | return self; |
---|
141 | } |
---|
142 | |
---|
143 | static VALUE get_attr(VALUE self, VALUE x, VALUE y) |
---|
144 | { |
---|
145 | unsigned long int ch; |
---|
146 | ch = caca_get_attr(_SELF, NUM2INT(x), NUM2INT(y)); |
---|
147 | return INT2NUM(ch); |
---|
148 | } |
---|
149 | |
---|
150 | static VALUE set_attr(VALUE self, VALUE attr) |
---|
151 | { |
---|
152 | if(caca_set_attr(_SELF, NUM2ULONG(attr)) <0) |
---|
153 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
154 | |
---|
155 | return self; |
---|
156 | } |
---|
157 | |
---|
158 | static VALUE set_attr2(VALUE self, VALUE attr) |
---|
159 | { |
---|
160 | set_attr(self, attr); |
---|
161 | return self; |
---|
162 | } |
---|
163 | |
---|
164 | static VALUE put_attr(VALUE self, VALUE x, VALUE y, VALUE attr) |
---|
165 | { |
---|
166 | if(caca_put_attr(_SELF, NUM2INT(x), NUM2INT(y), NUM2ULONG(attr)) <0) |
---|
167 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
168 | |
---|
169 | return self; |
---|
170 | } |
---|
171 | |
---|
172 | static VALUE set_color_ansi(VALUE self, VALUE fg, VALUE bg) |
---|
173 | { |
---|
174 | if(caca_set_color_ansi(_SELF, NUM2INT(fg), NUM2INT(bg)) <0) |
---|
175 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
176 | |
---|
177 | return self; |
---|
178 | } |
---|
179 | |
---|
180 | static VALUE set_color_argb(VALUE self, VALUE fg, VALUE bg) |
---|
181 | { |
---|
182 | if(caca_set_color_argb(_SELF, NUM2UINT(fg), NUM2UINT(bg)) <0) { |
---|
183 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
184 | } |
---|
185 | return self; |
---|
186 | } |
---|
187 | |
---|
188 | static VALUE cprintf(int argc, VALUE* argv, VALUE self) |
---|
189 | { |
---|
190 | int x, y; |
---|
191 | VALUE rx, ry, format, rest, string; |
---|
192 | rb_scan_args(argc, argv, "3*", &rx, &ry, &format, &rest); |
---|
193 | x = NUM2INT(rx); |
---|
194 | y = NUM2INT(ry); |
---|
195 | string = rb_funcall2(rb_mKernel, rb_intern("sprintf"), argc-2, argv+2); |
---|
196 | caca_put_str(_SELF, x, y, StringValuePtr(string)); |
---|
197 | return self; |
---|
198 | } |
---|
199 | |
---|
200 | |
---|
201 | get_int(canvas_handle_x) |
---|
202 | get_int(canvas_handle_y) |
---|
203 | |
---|
204 | static VALUE set_canvas_handle(VALUE self, VALUE x, VALUE y) |
---|
205 | { |
---|
206 | caca_set_canvas_handle(_SELF, NUM2INT(x), NUM2INT(y)); |
---|
207 | return self; |
---|
208 | } |
---|
209 | |
---|
210 | static VALUE blit(int argc, VALUE* argv, VALUE self) { |
---|
211 | VALUE x, y, src, mask; |
---|
212 | caca_canvas_t *csrc, *cmask; |
---|
213 | |
---|
214 | rb_scan_args(argc, argv, "31", &x, &y, &src, &mask); |
---|
215 | |
---|
216 | Check_Type(x, T_FIXNUM); |
---|
217 | Check_Type(y, T_FIXNUM); |
---|
218 | |
---|
219 | if(CLASS_OF(src) != cCanvas) |
---|
220 | { |
---|
221 | rb_raise(rb_eArgError, "src is not a Caca::Canvas"); |
---|
222 | } |
---|
223 | Data_Get_Struct(src, caca_canvas_t, csrc); |
---|
224 | |
---|
225 | if(!NIL_P(mask)) |
---|
226 | { |
---|
227 | if(CLASS_OF(mask) != cCanvas) |
---|
228 | { |
---|
229 | rb_raise(rb_eArgError, "mask is not a Caca::Canvas"); |
---|
230 | } |
---|
231 | Data_Get_Struct(mask, caca_canvas_t, cmask); |
---|
232 | } |
---|
233 | else |
---|
234 | cmask = NULL; |
---|
235 | |
---|
236 | if(caca_blit(_SELF, NUM2INT(x), NUM2INT(y), csrc, cmask)<0) |
---|
237 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
238 | |
---|
239 | return self; |
---|
240 | } |
---|
241 | |
---|
242 | static VALUE set_canvas_boundaries(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) |
---|
243 | { |
---|
244 | if(caca_set_canvas_boundaries(_SELF, NUM2INT(x), NUM2INT(y), NUM2UINT(w), NUM2UINT(h))<0) |
---|
245 | { |
---|
246 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
247 | } |
---|
248 | return self; |
---|
249 | } |
---|
250 | |
---|
251 | /****/ |
---|
252 | |
---|
253 | simple_func(invert) |
---|
254 | simple_func(flip) |
---|
255 | simple_func(flop) |
---|
256 | simple_func(rotate_180) |
---|
257 | simple_func(rotate_left) |
---|
258 | simple_func(rotate_right) |
---|
259 | simple_func(stretch_left) |
---|
260 | simple_func(stretch_right) |
---|
261 | |
---|
262 | /****/ |
---|
263 | |
---|
264 | static VALUE draw_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE ch) |
---|
265 | { |
---|
266 | caca_draw_line(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2),NUM2ULONG(ch)); |
---|
267 | return self; |
---|
268 | } |
---|
269 | |
---|
270 | static VALUE draw_polyline(VALUE self, VALUE points, VALUE ch) |
---|
271 | { |
---|
272 | int i, n; |
---|
273 | int *ax, *ay; |
---|
274 | int error = 0; |
---|
275 | VALUE v, x, y; |
---|
276 | |
---|
277 | n = RARRAY(points)->len; |
---|
278 | |
---|
279 | ax = (int*)malloc(n*sizeof(int)); |
---|
280 | if(!ax) |
---|
281 | rb_raise(rb_eNoMemError,"Out of memory"); |
---|
282 | |
---|
283 | ay = (int*)malloc(n*sizeof(int)); |
---|
284 | if(!ay) |
---|
285 | { |
---|
286 | free(ax); |
---|
287 | rb_raise(rb_eNoMemError,"Out of memory"); |
---|
288 | } |
---|
289 | |
---|
290 | for(i=0; i<n; i++) |
---|
291 | { |
---|
292 | v = rb_ary_entry(points, i); |
---|
293 | if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 2)) |
---|
294 | { |
---|
295 | x = rb_ary_entry(v,0); |
---|
296 | y = rb_ary_entry(v,1); |
---|
297 | if(rb_obj_is_kind_of(x, rb_cInteger) && |
---|
298 | rb_obj_is_kind_of(y, rb_cInteger)) |
---|
299 | { |
---|
300 | ax[i] = NUM2INT(x); |
---|
301 | ay[i] = NUM2INT(y); |
---|
302 | } else |
---|
303 | error = 1; |
---|
304 | } |
---|
305 | else |
---|
306 | error = 1; |
---|
307 | } |
---|
308 | |
---|
309 | if(error) |
---|
310 | { |
---|
311 | free(ax); |
---|
312 | free(ay); |
---|
313 | rb_raise(rb_eArgError, "Invalid list of points"); |
---|
314 | } |
---|
315 | |
---|
316 | n--; |
---|
317 | |
---|
318 | caca_draw_polyline(_SELF, ax, ay, n, NUM2ULONG(ch)); |
---|
319 | |
---|
320 | free(ax); |
---|
321 | free(ay); |
---|
322 | |
---|
323 | return self; |
---|
324 | } |
---|
325 | |
---|
326 | static VALUE draw_thin_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2) |
---|
327 | { |
---|
328 | caca_draw_thin_line(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2)); |
---|
329 | return self; |
---|
330 | } |
---|
331 | |
---|
332 | static VALUE draw_thin_polyline(VALUE self, VALUE points) |
---|
333 | { |
---|
334 | int i, n; |
---|
335 | int *ax, *ay; |
---|
336 | int error = 0; |
---|
337 | VALUE v, x, y; |
---|
338 | |
---|
339 | n = RARRAY(points)->len; |
---|
340 | |
---|
341 | ax = (int*)malloc(n*sizeof(int)); |
---|
342 | if(!ax) |
---|
343 | rb_raise(rb_eNoMemError,"Out of memory"); |
---|
344 | |
---|
345 | ay = (int*)malloc(n*sizeof(int)); |
---|
346 | if(!ay) |
---|
347 | { |
---|
348 | free(ax); |
---|
349 | rb_raise(rb_eNoMemError,"Out of memory"); |
---|
350 | } |
---|
351 | |
---|
352 | for(i=0; i<n; i++) |
---|
353 | { |
---|
354 | v = rb_ary_entry(points, i); |
---|
355 | if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 2)) |
---|
356 | { |
---|
357 | x = rb_ary_entry(v,0); |
---|
358 | y = rb_ary_entry(v,1); |
---|
359 | if(rb_obj_is_kind_of(x, rb_cInteger) && |
---|
360 | rb_obj_is_kind_of(y, rb_cInteger)) |
---|
361 | { |
---|
362 | ax[i] = NUM2INT(x); |
---|
363 | ay[i] = NUM2INT(y); |
---|
364 | } else |
---|
365 | error = 1; |
---|
366 | } |
---|
367 | else |
---|
368 | error = 1; |
---|
369 | } |
---|
370 | |
---|
371 | if(error) |
---|
372 | { |
---|
373 | free(ax); |
---|
374 | free(ay); |
---|
375 | rb_raise(rb_eArgError, "Invalid list of points"); |
---|
376 | } |
---|
377 | |
---|
378 | n--; |
---|
379 | |
---|
380 | caca_draw_thin_polyline(_SELF, ax, ay, n); |
---|
381 | |
---|
382 | free(ax); |
---|
383 | free(ay); |
---|
384 | |
---|
385 | return self; |
---|
386 | } |
---|
387 | |
---|
388 | static VALUE draw_circle(VALUE self, VALUE x, VALUE y, VALUE r, VALUE ch) |
---|
389 | { |
---|
390 | caca_draw_circle(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(r), NUM2ULONG(ch)); |
---|
391 | return self; |
---|
392 | } |
---|
393 | |
---|
394 | static VALUE draw_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b, VALUE ch) |
---|
395 | { |
---|
396 | caca_draw_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b), NUM2ULONG(ch)); |
---|
397 | return self; |
---|
398 | } |
---|
399 | |
---|
400 | static VALUE draw_thin_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b) |
---|
401 | { |
---|
402 | caca_draw_thin_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b)); |
---|
403 | return self; |
---|
404 | } |
---|
405 | |
---|
406 | static VALUE fill_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b, VALUE ch) |
---|
407 | { |
---|
408 | caca_fill_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b), NUM2ULONG(ch)); |
---|
409 | return self; |
---|
410 | } |
---|
411 | |
---|
412 | static VALUE draw_box(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE ch) |
---|
413 | { |
---|
414 | caca_draw_box(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h), NUM2ULONG(ch)); |
---|
415 | return self; |
---|
416 | } |
---|
417 | |
---|
418 | static VALUE draw_thin_box(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) |
---|
419 | { |
---|
420 | caca_draw_thin_box(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h)); |
---|
421 | return self; |
---|
422 | } |
---|
423 | |
---|
424 | static VALUE draw_cp437_box(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) |
---|
425 | { |
---|
426 | caca_draw_cp437_box(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h)); |
---|
427 | return self; |
---|
428 | } |
---|
429 | |
---|
430 | static VALUE fill_box(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE ch) |
---|
431 | { |
---|
432 | caca_fill_box(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h), NUM2ULONG(ch)); |
---|
433 | return self; |
---|
434 | } |
---|
435 | |
---|
436 | static VALUE draw_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3, VALUE ch) |
---|
437 | { |
---|
438 | caca_draw_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), NUM2ULONG(ch)); |
---|
439 | return self; |
---|
440 | } |
---|
441 | |
---|
442 | static VALUE draw_thin_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3) |
---|
443 | { |
---|
444 | caca_draw_thin_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3)); |
---|
445 | return self; |
---|
446 | } |
---|
447 | |
---|
448 | static VALUE fill_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3, VALUE ch) |
---|
449 | { |
---|
450 | caca_fill_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2INT(x3), NUM2INT(y3), NUM2ULONG(ch)); |
---|
451 | return self; |
---|
452 | } |
---|
453 | |
---|
454 | static VALUE fill_triangle_textured(VALUE self, VALUE coords, VALUE texture, VALUE uv) |
---|
455 | { |
---|
456 | caca_canvas_t *ctexture; |
---|
457 | int i, l; |
---|
458 | int ccoords[6]; |
---|
459 | float cuv[6]; |
---|
460 | VALUE v; |
---|
461 | |
---|
462 | l = RARRAY(coords)->len; |
---|
463 | if(l != 6 && l != 3) |
---|
464 | { |
---|
465 | rb_raise(rb_eArgError, "invalid coords list"); |
---|
466 | } |
---|
467 | for(i=0; i<l; i++) |
---|
468 | { |
---|
469 | v = rb_ary_entry(coords, i); |
---|
470 | if(l==6) |
---|
471 | ccoords[i] = NUM2INT(v); |
---|
472 | else |
---|
473 | { |
---|
474 | if((TYPE(v) != T_ARRAY) || (RARRAY(v)->len != 2)) |
---|
475 | rb_raise(rb_eArgError, "invalid coords list"); |
---|
476 | ccoords[2*i] = NUM2INT(rb_ary_entry(v, 0)); |
---|
477 | ccoords[2*i+1] = NUM2INT(rb_ary_entry(v, 1)); |
---|
478 | } |
---|
479 | } |
---|
480 | |
---|
481 | l = RARRAY(uv)->len; |
---|
482 | if(l != 6 && l != 3) |
---|
483 | { |
---|
484 | rb_raise(rb_eArgError, "invalid uv list"); |
---|
485 | } |
---|
486 | for(i=0; i<l; i++) |
---|
487 | { |
---|
488 | v = rb_ary_entry(uv, i); |
---|
489 | if(l==6) |
---|
490 | cuv[i] = NUM2DBL(v); |
---|
491 | else |
---|
492 | { |
---|
493 | if((TYPE(v) != T_ARRAY) || (RARRAY(v)->len != 2)) |
---|
494 | rb_raise(rb_eArgError, "invalid uv list"); |
---|
495 | ccoords[2*i] = NUM2DBL(rb_ary_entry(v, 0)); |
---|
496 | ccoords[2*i+1] = NUM2DBL(rb_ary_entry(v, 1)); |
---|
497 | } |
---|
498 | } |
---|
499 | |
---|
500 | if(CLASS_OF(texture) != cCanvas) |
---|
501 | { |
---|
502 | rb_raise(rb_eArgError, "texture is not a Caca::Canvas"); |
---|
503 | } |
---|
504 | Data_Get_Struct(texture, caca_canvas_t, ctexture); |
---|
505 | |
---|
506 | caca_fill_triangle_textured(_SELF, ccoords, ctexture, cuv); |
---|
507 | return self; |
---|
508 | } |
---|
509 | |
---|
510 | static VALUE dither_bitmap(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE d, VALUE pixels) |
---|
511 | { |
---|
512 | if(CLASS_OF(d) != cDither) |
---|
513 | rb_raise(rb_eArgError, "d is not a Caca::Dither"); |
---|
514 | Check_Type(pixels, T_STRING); |
---|
515 | |
---|
516 | caca_dither_bitmap(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h), DATA_PTR(d), StringValuePtr(pixels)); |
---|
517 | return self; |
---|
518 | } |
---|
519 | |
---|
520 | /****/ |
---|
521 | |
---|
522 | get_int(frame_count) |
---|
523 | |
---|
524 | static VALUE set_frame(VALUE self, VALUE id) |
---|
525 | { |
---|
526 | if(caca_set_frame(_SELF, NUM2INT(id))<0) |
---|
527 | rb_raise(rb_eArgError, strerror(errno)); |
---|
528 | |
---|
529 | return self; |
---|
530 | } |
---|
531 | |
---|
532 | static VALUE set_frame2(VALUE self, VALUE id) |
---|
533 | { |
---|
534 | set_frame(self, id); |
---|
535 | return self; |
---|
536 | } |
---|
537 | |
---|
538 | static VALUE get_frame_name(VALUE self) |
---|
539 | { |
---|
540 | return rb_str_new2(caca_get_frame_name(_SELF)); |
---|
541 | } |
---|
542 | |
---|
543 | static VALUE set_frame_name(VALUE self, VALUE name) |
---|
544 | { |
---|
545 | if(caca_set_frame_name(_SELF, StringValuePtr(name))<0) |
---|
546 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
547 | |
---|
548 | return self; |
---|
549 | } |
---|
550 | |
---|
551 | static VALUE set_frame_name2(VALUE self, VALUE name) |
---|
552 | { |
---|
553 | set_frame_name(self, name); |
---|
554 | return self; |
---|
555 | } |
---|
556 | |
---|
557 | static VALUE create_frame(VALUE self, VALUE id) |
---|
558 | { |
---|
559 | if(caca_create_frame(_SELF, NUM2INT(id))<0) { |
---|
560 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
561 | } |
---|
562 | return self; |
---|
563 | } |
---|
564 | |
---|
565 | static VALUE free_frame(VALUE self, VALUE id) |
---|
566 | { |
---|
567 | if(caca_free_frame(_SELF, NUM2INT(id))<0) { |
---|
568 | rb_raise(rb_eArgError, strerror(errno)); |
---|
569 | } |
---|
570 | return self; |
---|
571 | } |
---|
572 | |
---|
573 | /****/ |
---|
574 | |
---|
575 | static VALUE render_canvas(VALUE self, VALUE font, VALUE width, VALUE height, VALUE pitch) |
---|
576 | { |
---|
577 | void *buf; |
---|
578 | caca_font_t *f; |
---|
579 | VALUE b; |
---|
580 | |
---|
581 | if(CLASS_OF(font) != cFont) |
---|
582 | { |
---|
583 | rb_raise(rb_eArgError, "First argument is not a Caca::Font"); |
---|
584 | } |
---|
585 | |
---|
586 | buf = malloc(width*height*4); |
---|
587 | if(buf == NULL) |
---|
588 | { |
---|
589 | rb_raise(rb_eNoMemError, "Out of memory"); |
---|
590 | } |
---|
591 | |
---|
592 | f = DATA_PTR(font); |
---|
593 | caca_render_canvas(_SELF, f, buf, NUM2UINT(width), NUM2UINT(height), NUM2UINT(pitch)); |
---|
594 | |
---|
595 | b = rb_str_new(buf, width*height*4); |
---|
596 | free(buf); |
---|
597 | return b; |
---|
598 | } |
---|
599 | |
---|
600 | static VALUE import_from_memory(VALUE self, VALUE data, VALUE format) |
---|
601 | { |
---|
602 | long int bytes; |
---|
603 | bytes = caca_import_canvas_from_memory (_SELF, StringValuePtr(data), RSTRING(StringValue(data))->len, StringValuePtr(format)); |
---|
604 | if(bytes <= 0) |
---|
605 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
606 | |
---|
607 | return self; |
---|
608 | } |
---|
609 | |
---|
610 | static VALUE import_area_from_memory(VALUE self, VALUE x, VALUE y, VALUE data, VALUE format) |
---|
611 | { |
---|
612 | long int bytes; |
---|
613 | bytes = caca_import_area_from_memory (_SELF, NUM2INT(x), NUM2INT(y), StringValuePtr(data), RSTRING(StringValue(data))->len, StringValuePtr(format)); |
---|
614 | if(bytes <= 0) |
---|
615 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
616 | |
---|
617 | return self; |
---|
618 | } |
---|
619 | |
---|
620 | static VALUE import_from_file(VALUE self, VALUE filename, VALUE format) |
---|
621 | { |
---|
622 | long int bytes; |
---|
623 | bytes = caca_import_canvas_from_file (_SELF, StringValuePtr(filename), StringValuePtr(format)); |
---|
624 | if(bytes <= 0) |
---|
625 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
626 | |
---|
627 | return self; |
---|
628 | } |
---|
629 | |
---|
630 | static VALUE import_area_from_file(VALUE self, VALUE x, VALUE y, VALUE filename, VALUE format) |
---|
631 | { |
---|
632 | long int bytes; |
---|
633 | bytes = caca_import_area_from_file (_SELF, NUM2INT(x), NUM2INT(y), StringValuePtr(filename), StringValuePtr(format)); |
---|
634 | if(bytes <= 0) |
---|
635 | rb_raise(rb_eRuntimeError, strerror(errno)); |
---|
636 | |
---|
637 | return self; |
---|
638 | } |
---|
639 | |
---|
640 | static VALUE export_area_to_memory(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h, VALUE format) |
---|
641 | { |
---|
642 | size_t bytes; |
---|
643 | void *result; |
---|
644 | VALUE ret; |
---|
645 | result = caca_export_area_to_memory (_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h), StringValuePtr(format), &bytes); |
---|
646 | ret = rb_str_new(result, bytes); |
---|
647 | free(result); |
---|
648 | return ret; |
---|
649 | } |
---|
650 | |
---|
651 | static VALUE export_to_memory(VALUE self, VALUE format) |
---|
652 | { |
---|
653 | size_t bytes; |
---|
654 | void *result; |
---|
655 | VALUE ret; |
---|
656 | result = caca_export_canvas_to_memory (_SELF, StringValuePtr(format), &bytes); |
---|
657 | ret = rb_str_new(result, bytes); |
---|
658 | free(result); |
---|
659 | return ret; |
---|
660 | } |
---|
661 | |
---|
662 | get_singleton_double_list(export) |
---|
663 | get_singleton_double_list(import) |
---|
664 | |
---|
665 | /****/ |
---|
666 | |
---|
667 | simple_func(disable_dirty_rect) |
---|
668 | simple_func(enable_dirty_rect) |
---|
669 | get_int(dirty_rect_count) |
---|
670 | |
---|
671 | static VALUE dirty_rect(VALUE self, VALUE n) |
---|
672 | { |
---|
673 | int x, y, width, height; |
---|
674 | VALUE ary; |
---|
675 | ary = rb_ary_new(); |
---|
676 | caca_get_dirty_rect(_SELF, NUM2INT(n), &x, &y, &width, &height); |
---|
677 | rb_ary_push(ary, INT2NUM(x)); |
---|
678 | rb_ary_push(ary, INT2NUM(y)); |
---|
679 | rb_ary_push(ary, INT2NUM(width)); |
---|
680 | rb_ary_push(ary, INT2NUM(height)); |
---|
681 | return ary; |
---|
682 | } |
---|
683 | |
---|
684 | static VALUE dirty_rects(VALUE self) |
---|
685 | { |
---|
686 | int n = caca_get_dirty_rect_count(_SELF), i; |
---|
687 | VALUE ary; |
---|
688 | ary = rb_ary_new(); |
---|
689 | for(i=0; i<n; i++) |
---|
690 | { |
---|
691 | rb_ary_push(ary, dirty_rect(self, INT2NUM(i))); |
---|
692 | } |
---|
693 | return ary; |
---|
694 | } |
---|
695 | |
---|
696 | /*FIXME Handle an array for the rect */ |
---|
697 | static VALUE add_dirty_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) |
---|
698 | { |
---|
699 | caca_add_dirty_rect(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h)); |
---|
700 | return self; |
---|
701 | } |
---|
702 | |
---|
703 | static VALUE remove_dirty_rect(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h) |
---|
704 | { |
---|
705 | caca_remove_dirty_rect(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(w), NUM2INT(h)); |
---|
706 | return self; |
---|
707 | } |
---|
708 | |
---|
709 | simple_func(clear_dirty_rect_list) |
---|
710 | |
---|
711 | /****/ |
---|
712 | |
---|
713 | void Init_caca_canvas(VALUE mCaca) |
---|
714 | { |
---|
715 | cCanvas = rb_define_class_under(mCaca, "Canvas", rb_cObject); |
---|
716 | rb_define_alloc_func(cCanvas, canvas_alloc); |
---|
717 | |
---|
718 | rb_define_method(cCanvas, "initialize", canvas_initialize, 2); |
---|
719 | rb_define_method(cCanvas, "width", get_canvas_width, 0); |
---|
720 | rb_define_method(cCanvas, "width=", set_canvas_width, 1); |
---|
721 | rb_define_method(cCanvas, "set_width", set_canvas_width2, 1); |
---|
722 | rb_define_method(cCanvas, "height", get_canvas_height, 0); |
---|
723 | rb_define_method(cCanvas, "height=", set_canvas_height, 1); |
---|
724 | rb_define_method(cCanvas, "set_height", set_canvas_height2, 1); |
---|
725 | rb_define_method(cCanvas, "set_size", set_canvas_size, 2); |
---|
726 | |
---|
727 | rb_define_method(cCanvas, "gotoxy", gotoxy, 2); |
---|
728 | rb_define_method(cCanvas, "wherex", wherex, 0); |
---|
729 | rb_define_method(cCanvas, "wherey", wherey, 0); |
---|
730 | rb_define_method(cCanvas, "handle_x", get_canvas_handle_x, 0); |
---|
731 | rb_define_method(cCanvas, "handle_y", get_canvas_handle_y, 0); |
---|
732 | rb_define_method(cCanvas, "set_handle", set_canvas_handle, 2); |
---|
733 | rb_define_method(cCanvas, "blit", blit, -1); |
---|
734 | rb_define_method(cCanvas, "set_boundaries", set_canvas_boundaries, 4); |
---|
735 | |
---|
736 | rb_define_method(cCanvas, "clear", clear_canvas, 0); |
---|
737 | |
---|
738 | rb_define_method(cCanvas, "put_char", put_char, 3); |
---|
739 | rb_define_method(cCanvas, "get_char", get_char, 2); |
---|
740 | rb_define_method(cCanvas, "put_str", put_str, 3); |
---|
741 | rb_define_method(cCanvas, "printf", cprintf, -1); |
---|
742 | |
---|
743 | rb_define_method(cCanvas, "get_attr", get_attr, 3); |
---|
744 | rb_define_method(cCanvas, "attr=", set_attr, 1); |
---|
745 | rb_define_method(cCanvas, "set_attr", set_attr2, 1); |
---|
746 | rb_define_method(cCanvas, "put_attr", put_attr, 3); |
---|
747 | rb_define_method(cCanvas, "set_color_ansi", set_color_ansi, 2); |
---|
748 | rb_define_method(cCanvas, "set_color_argb", set_color_argb, 2); |
---|
749 | |
---|
750 | rb_define_method(cCanvas, "invert", invert, 0); |
---|
751 | rb_define_method(cCanvas, "flip", flip, 0); |
---|
752 | rb_define_method(cCanvas, "flop", flop, 0); |
---|
753 | rb_define_method(cCanvas, "rotate_180", rotate_180, 0); |
---|
754 | rb_define_method(cCanvas, "rotate_left", rotate_left, 0); |
---|
755 | rb_define_method(cCanvas, "rotate_right", rotate_right, 0); |
---|
756 | rb_define_method(cCanvas, "stretch_left", stretch_left, 0); |
---|
757 | rb_define_method(cCanvas, "stretch_right", stretch_right, 0); |
---|
758 | |
---|
759 | rb_define_method(cCanvas, "draw_line", draw_line, 5); |
---|
760 | rb_define_method(cCanvas, "draw_polyline", draw_polyline, 2); |
---|
761 | rb_define_method(cCanvas, "draw_thin_line", draw_thin_line, 4); |
---|
762 | rb_define_method(cCanvas, "draw_thin_polyline", draw_thin_polyline, 1); |
---|
763 | rb_define_method(cCanvas, "draw_circle", draw_circle, 4); |
---|
764 | rb_define_method(cCanvas, "draw_ellipse", draw_ellipse, 5); |
---|
765 | rb_define_method(cCanvas, "draw_thin_ellipse", draw_thin_ellipse, 4); |
---|
766 | rb_define_method(cCanvas, "fill_ellipse", fill_ellipse, 5); |
---|
767 | rb_define_method(cCanvas, "draw_box", draw_box, 5); |
---|
768 | rb_define_method(cCanvas, "draw_thin_box", draw_thin_box, 4); |
---|
769 | rb_define_method(cCanvas, "draw_cp437_box", draw_cp437_box, 4); |
---|
770 | rb_define_method(cCanvas, "fill_box", fill_box, 5); |
---|
771 | rb_define_method(cCanvas, "draw_triangle", draw_triangle, 7); |
---|
772 | rb_define_method(cCanvas, "draw_thin_triangle", draw_thin_triangle, 6); |
---|
773 | rb_define_method(cCanvas, "fill_triangle", fill_triangle, 7); |
---|
774 | rb_define_method(cCanvas, "fill_triangle_textured", fill_triangle_textured, 4); |
---|
775 | rb_define_method(cCanvas, "dither_bitmap", dither_bitmap, 6); |
---|
776 | |
---|
777 | rb_define_method(cCanvas, "frame_count", get_frame_count, 0); |
---|
778 | rb_define_method(cCanvas, "frame=", set_frame, 1); |
---|
779 | rb_define_method(cCanvas, "set_frame", set_frame2, 1); |
---|
780 | rb_define_method(cCanvas, "frame_name", get_frame_name, 0); |
---|
781 | rb_define_method(cCanvas, "frame_name=", set_frame_name, 1); |
---|
782 | rb_define_method(cCanvas, "set_frame_name", set_frame_name2, 1); |
---|
783 | rb_define_method(cCanvas, "create_frame", create_frame, 1); |
---|
784 | rb_define_method(cCanvas, "free_frame", free_frame, 1); |
---|
785 | |
---|
786 | rb_define_method(cCanvas, "render", render_canvas, 4); |
---|
787 | rb_define_method(cCanvas, "import_from_memory", import_from_memory, 2); |
---|
788 | rb_define_method(cCanvas, "import_area_from_memory", import_area_from_memory, 4); |
---|
789 | rb_define_method(cCanvas, "import_from_file", import_from_file, 2); |
---|
790 | rb_define_method(cCanvas, "import_area_from_file", import_area_from_file, 4); |
---|
791 | rb_define_method(cCanvas, "export_to_memory", export_to_memory, 1); |
---|
792 | rb_define_method(cCanvas, "export_area_to_memory", export_area_to_memory, 5); |
---|
793 | rb_define_singleton_method(cCanvas, "export_list", export_list, 0); |
---|
794 | rb_define_singleton_method(cCanvas, "import_list", import_list, 0); |
---|
795 | |
---|
796 | rb_define_method(cCanvas, "disable_dirty_rect", disable_dirty_rect, 0); |
---|
797 | rb_define_method(cCanvas, "enable_dirty_rect", enable_dirty_rect, 0); |
---|
798 | rb_define_method(cCanvas, "dirty_rect_count", get_dirty_rect_count, 0); |
---|
799 | rb_define_method(cCanvas, "dirty_rect", dirty_rect, 1); |
---|
800 | rb_define_method(cCanvas, "dirty_rects", dirty_rects, 0); |
---|
801 | rb_define_method(cCanvas, "add_dirty_rect", add_dirty_rect, 4); |
---|
802 | rb_define_method(cCanvas, "remove_dirty_rect", remove_dirty_rect, 4); |
---|
803 | rb_define_method(cCanvas, "clear_dirty_rect_list", clear_dirty_rect_list, 0); |
---|
804 | |
---|
805 | } |
---|
806 | |
---|