source: libcaca/trunk/ruby/cucul-canvas.c @ 1995

Last change on this file since 1995 was 1995, checked in by Pascal Terjan, 13 years ago
  • Add Cucul::Font
  • Property svn:eol-style set to native
File size: 17.9 KB
Line 
1/*
2 *  libcucul Ruby bindings
3 *  Copyright (c) 2007 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 <cucul.h>
14#include <errno.h>
15#include "cucul-font.h"
16#include "common.h"
17
18VALUE cCanvas;
19
20#define simple_func(x)                                  \
21static VALUE x (VALUE self)                             \
22{                                                       \
23    if( cucul_##x (_SELF) <0)                           \
24        rb_raise(rb_eRuntimeError, strerror(errno));    \
25                                                        \
26    return self;                                        \
27}
28
29#define get_int(x)                                      \
30static VALUE get_##x (VALUE self)                       \
31{                                                       \
32    return INT2NUM(cucul_get_##x (_SELF));              \
33}
34
35static void canvas_free(void * p)
36{
37    cucul_free_canvas((cucul_canvas_t *)p);
38}
39
40static VALUE canvas_alloc(VALUE klass)
41{
42    cucul_canvas_t *canvas;
43    VALUE obj;
44   
45    canvas = cucul_create_canvas(0, 0);
46    obj = Data_Wrap_Struct(klass, 0, canvas_free, canvas);
47   
48    return obj;
49}
50
51static VALUE canvas_initialize(VALUE self, VALUE width, VALUE height)
52{
53    unsigned int w, h;
54
55    w = NUM2INT(width);
56    h = NUM2INT(height);
57   
58    cucul_set_canvas_size(_SELF, w, h);
59   
60    return self;
61}
62
63get_int(canvas_height)
64get_int(canvas_width)
65
66static VALUE set_canvas_width(VALUE self, VALUE width)
67{
68    cucul_set_canvas_size(_SELF, NUM2INT(width), cucul_get_canvas_height(_SELF));
69    return width;
70}
71
72static VALUE set_canvas_width2(VALUE self, VALUE width)
73{
74    set_canvas_width(self, width);
75    return self;
76}
77
78static VALUE set_canvas_height(VALUE self, VALUE height)
79{
80    cucul_set_canvas_size(_SELF, cucul_get_canvas_width(_SELF), NUM2INT(height));
81    return height;
82}
83
84static VALUE set_canvas_height2(VALUE self, VALUE height)
85{
86    set_canvas_height(self, height);
87    return self;
88}
89
90static VALUE set_canvas_size(VALUE self, VALUE height, VALUE width)
91{
92    cucul_set_canvas_size(_SELF, NUM2INT(width), NUM2INT(height));
93    return self;
94}
95
96/****/
97
98static VALUE gotoxy(VALUE self, VALUE x, VALUE y)
99{
100    if( cucul_gotoxy(_SELF, NUM2INT(x), NUM2INT(y)) <0) {
101        rb_raise(rb_eRuntimeError, strerror(errno));
102    }
103    return self;
104}
105
106get_int(cursor_x)
107get_int(cursor_y)
108
109simple_func(clear_canvas)
110
111static VALUE put_char(VALUE self, VALUE x, VALUE y, VALUE ch)
112{
113    cucul_put_char(_SELF, NUM2INT(x), NUM2INT(y), NUM2ULONG(ch));
114    return self;
115}
116
117static VALUE get_char(VALUE self, VALUE x, VALUE y)
118{
119    unsigned long int ch;
120    ch = cucul_get_char(_SELF, NUM2INT(x), NUM2INT(y));
121    return INT2NUM(ch);
122}
123
124static VALUE put_str(VALUE self, VALUE x, VALUE y, VALUE str)
125{
126    cucul_put_str(_SELF, NUM2INT(x), NUM2INT(y), StringValuePtr(str));
127    return self;
128}
129
130static VALUE get_attr(VALUE self, VALUE x, VALUE y)
131{
132    unsigned long int ch;
133    ch = cucul_get_attr(_SELF, NUM2INT(x), NUM2INT(y));
134    return INT2NUM(ch);
135}
136
137static VALUE set_attr(VALUE self, VALUE attr)
138{
139    if(cucul_set_attr(_SELF, NUM2ULONG(attr)) <0)
140        rb_raise(rb_eRuntimeError, strerror(errno));
141
142    return self;
143}
144
145static VALUE set_attr2(VALUE self, VALUE attr)
146{
147    set_attr(self, attr);
148    return self;
149}
150
151static VALUE put_attr(VALUE self, VALUE x, VALUE y, VALUE attr)
152{
153    if(cucul_put_attr(_SELF, NUM2INT(x), NUM2INT(y), NUM2ULONG(attr)) <0)
154        rb_raise(rb_eRuntimeError, strerror(errno));
155
156    return self;
157}
158
159static VALUE set_color_ansi(VALUE self, VALUE fg, VALUE bg)
160{
161    if(cucul_set_color_ansi(_SELF, NUM2INT(fg), NUM2INT(bg)) <0)
162        rb_raise(rb_eRuntimeError, strerror(errno));
163
164    return self;
165}
166
167static VALUE set_color_argb(VALUE self, VALUE fg, VALUE bg)
168{
169    if(cucul_set_color_argb(_SELF, NUM2UINT(fg), NUM2UINT(bg)) <0) {
170        rb_raise(rb_eRuntimeError, strerror(errno));
171    }
172    return self;
173}
174
175static VALUE cprintf(int argc, VALUE* argv, VALUE self)
176{
177    int x, y;
178    VALUE rx, ry, format, rest, string;
179    rb_scan_args(argc, argv, "3*", &rx, &ry, &format, &rest);
180    x = NUM2INT(rx);
181    y = NUM2INT(ry);
182    string = rb_funcall2(rb_mKernel, rb_intern("sprintf"), argc-2, argv+2);
183    cucul_put_str(_SELF, x, y, StringValuePtr(string));
184    return self;
185}
186
187
188get_int(canvas_handle_x)
189get_int(canvas_handle_y)
190
191static VALUE set_canvas_handle(VALUE self, VALUE x, VALUE y)
192{
193    cucul_set_canvas_handle(_SELF, NUM2INT(x), NUM2INT(y));
194    return self;
195}
196
197static VALUE blit(int argc, VALUE* argv, VALUE self) {
198    VALUE x, y, src, mask;
199    cucul_canvas_t *csrc, *cmask;
200
201    rb_scan_args(argc, argv, "31", &x, &y, &src, &mask);
202
203    Check_Type(x, T_FIXNUM);
204    Check_Type(y, T_FIXNUM);
205    //FIXME rather check that class is cCanvas
206    Check_Type(src, TYPE(self));
207    Data_Get_Struct(src, cucul_canvas_t, csrc);
208    if(!NIL_P(mask))
209    {
210        //FIXME rather check that class is cCanvas
211        Check_Type(mask, TYPE(self));
212        Data_Get_Struct(mask, cucul_canvas_t, cmask);
213    }
214    else
215        cmask = NULL;
216   
217    if(cucul_blit(_SELF, NUM2INT(x), NUM2INT(y), csrc, cmask)<0)
218        rb_raise(rb_eRuntimeError, strerror(errno));
219
220    return self;
221}
222
223static VALUE set_canvas_boundaries(VALUE self, VALUE x, VALUE y, VALUE w, VALUE h)
224{
225    if(cucul_set_canvas_boundaries(_SELF, NUM2INT(x), NUM2INT(y), NUM2UINT(w), NUM2UINT(h))<0)
226    {
227        rb_raise(rb_eRuntimeError, strerror(errno));
228    }
229    return self;
230}
231
232/****/
233
234simple_func(invert)
235simple_func(flip)
236simple_func(flop)
237simple_func(rotate_180)
238simple_func(rotate_left)
239simple_func(rotate_right)
240simple_func(stretch_left)
241simple_func(stretch_right)
242
243/****/
244
245static VALUE draw_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE ch)
246{
247    cucul_draw_line(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2),NUM2ULONG(ch));
248    return self;
249}
250
251static VALUE draw_polyline(VALUE self, VALUE points, VALUE ch)
252{
253    int i, n;
254    int *ax, *ay;
255    int error = 0;
256    VALUE v, x, y;
257
258    n = RARRAY(points)->len;
259
260    ax = (int*)malloc(n*sizeof(int));
261    if(!ax)
262        rb_raise(rb_eNoMemError,"Out of memory");
263
264    ay = (int*)malloc(n*sizeof(int));
265    if(!ay)
266    {
267        free(ax);
268        rb_raise(rb_eNoMemError,"Out of memory");
269    }
270
271    for(i=0; i<n; i++)
272    {
273        v = rb_ary_entry(points, i);
274        if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 2))
275        {
276            x = rb_ary_entry(v,0);
277            y = rb_ary_entry(v,1);
278            if(rb_obj_is_kind_of(x, rb_cInteger) &&
279               rb_obj_is_kind_of(y, rb_cInteger))
280            {
281                ax[i] = NUM2INT(x);
282                ay[i] = NUM2INT(y);
283            } else
284                error = 1;
285        }
286        else
287            error = 1;
288    }
289
290    if(error)
291    {
292        free(ax);
293        free(ay);
294        rb_raise(rb_eArgError, "Invalid list of points");
295    }
296
297    n--;
298
299    cucul_draw_polyline(_SELF, ax, ay, n, NUM2ULONG(ch));
300
301    free(ax);
302    free(ay);
303
304    return self;
305}
306
307static VALUE draw_thin_line(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
308{
309    cucul_draw_thin_line(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2));
310    return self;
311}
312
313static VALUE draw_thin_polyline(VALUE self, VALUE points)
314{
315    int i, n;
316    int *ax, *ay;
317    int error = 0;
318    VALUE v, x, y;
319
320    n = RARRAY(points)->len;
321
322    ax = (int*)malloc(n*sizeof(int));
323    if(!ax)
324        rb_raise(rb_eNoMemError,"Out of memory");
325
326    ay = (int*)malloc(n*sizeof(int));
327    if(!ay)
328    {
329        free(ax);
330        rb_raise(rb_eNoMemError,"Out of memory");
331    }
332
333    for(i=0; i<n; i++)
334    {
335        v = rb_ary_entry(points, i);
336        if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 2))
337        {
338            x = rb_ary_entry(v,0);
339            y = rb_ary_entry(v,1);
340            if(rb_obj_is_kind_of(x, rb_cInteger) &&
341               rb_obj_is_kind_of(y, rb_cInteger))
342            {
343                ax[i] = NUM2INT(x);
344                ay[i] = NUM2INT(y);
345            } else
346                error = 1;
347        }
348        else
349            error = 1;
350    }
351
352    if(error)
353    {
354        free(ax);
355        free(ay);
356        rb_raise(rb_eArgError, "Invalid list of points");
357    }
358
359    n--;
360
361    cucul_draw_thin_polyline(_SELF, ax, ay, n);
362
363    free(ax);
364    free(ay);
365
366    return self;
367}
368
369static VALUE draw_circle(VALUE self, VALUE x, VALUE y, VALUE r, VALUE ch)
370{
371    cucul_draw_circle(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(r), NUM2ULONG(ch));
372    return self;
373}
374
375static VALUE draw_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b, VALUE ch)
376{
377    cucul_draw_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b), NUM2ULONG(ch));
378    return self;
379}
380
381static VALUE draw_thin_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b)
382{
383    cucul_draw_thin_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b));
384    return self;
385}
386
387static VALUE fill_ellipse(VALUE self, VALUE x, VALUE y, VALUE a, VALUE b, VALUE ch)
388{
389    cucul_fill_ellipse(_SELF, NUM2INT(x), NUM2INT(y), NUM2INT(a), NUM2INT(b), NUM2ULONG(ch));
390    return self;
391}
392
393static VALUE draw_box(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE ch)
394{
395    cucul_draw_box(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2ULONG(ch));
396    return self;
397}
398
399static VALUE draw_thin_box(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
400{
401    cucul_draw_thin_box(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2));
402    return self;
403}
404
405static VALUE draw_cp437_box(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2)
406{
407    cucul_draw_cp437_box(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2));
408    return self;
409}
410
411static VALUE fill_box(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE ch)
412{
413    cucul_fill_box(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2), NUM2ULONG(ch));
414    return self;
415}
416
417static VALUE draw_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3, VALUE ch)
418{
419    cucul_draw_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2),  NUM2INT(x3), NUM2INT(y3), NUM2ULONG(ch));
420    return self;
421}
422
423static VALUE draw_thin_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3)
424{
425    cucul_draw_thin_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2),  NUM2INT(x3), NUM2INT(y3));
426    return self;
427}
428
429static VALUE fill_triangle(VALUE self, VALUE x1, VALUE y1, VALUE x2, VALUE y2, VALUE x3, VALUE y3, VALUE ch)
430{
431    cucul_fill_triangle(_SELF, NUM2INT(x1), NUM2INT(y1), NUM2INT(x2), NUM2INT(y2),  NUM2INT(x3), NUM2INT(y3), NUM2ULONG(ch));
432    return self;
433}
434
435/****/
436
437get_int(frame_count)
438
439static VALUE set_frame(VALUE self, VALUE id)
440{
441    if(cucul_set_frame(_SELF, NUM2INT(id))<0)
442        rb_raise(rb_eArgError, strerror(errno));
443
444    return self;
445}
446
447static VALUE set_frame2(VALUE self, VALUE id)
448{
449    set_frame(self, id);
450    return self;
451}
452
453static VALUE get_frame_name(VALUE self)
454{
455    return rb_str_new2(cucul_get_frame_name(_SELF));
456}
457
458static VALUE set_frame_name(VALUE self, VALUE name)
459{
460    if(cucul_set_frame_name(_SELF, StringValuePtr(name))<0)
461        rb_raise(rb_eRuntimeError, strerror(errno));
462
463    return self;
464}
465
466static VALUE set_frame_name2(VALUE self, VALUE name)
467{
468    set_frame_name(self, name);
469    return self;
470}
471
472static VALUE create_frame(VALUE self, VALUE id)
473{
474    if(cucul_create_frame(_SELF, NUM2INT(id))<0) {
475        rb_raise(rb_eRuntimeError, strerror(errno));
476    }
477    return self;
478}
479
480static VALUE free_frame(VALUE self, VALUE id)
481{
482    if(cucul_free_frame(_SELF, NUM2INT(id))<0) {
483        rb_raise(rb_eArgError, strerror(errno));
484    }
485    return self;
486}
487
488/****/
489
490static VALUE render_canvas(VALUE self, VALUE font, VALUE width, VALUE height, VALUE pitch)
491{
492    void *buf;
493    cucul_font_t *f;
494    VALUE b;
495
496    //FIXME rather check that class is cFont
497    Check_Type(font, TYPE(self));
498
499    buf = malloc(width*height*4);
500    if(buf == NULL)
501    {
502        rb_raise(rb_eNoMemError, "Out of memory");
503    }
504
505    f = DATA_PTR(font);
506    cucul_render_canvas(_SELF, f, buf, NUM2UINT(width), NUM2UINT(height), NUM2UINT(pitch));
507
508    b = rb_str_new(buf, width*height*4);
509    free(buf);
510    return b;
511}
512
513static VALUE import_memory(VALUE self, VALUE data, VALUE format)
514{
515    long int bytes;
516    bytes = cucul_import_memory (_SELF, StringValuePtr(data), RSTRING(StringValue(data))->len, StringValuePtr(format));
517    if(bytes <= 0)
518        rb_raise(rb_eRuntimeError, strerror(errno));
519
520    return self;
521}
522
523static VALUE import_file(VALUE self, VALUE filename, VALUE format)
524{
525    long int bytes;
526    bytes = cucul_import_file (_SELF, StringValuePtr(filename), StringValuePtr(format));
527    if(bytes <= 0)
528        rb_raise(rb_eRuntimeError, strerror(errno));
529
530    return self;
531}
532
533static VALUE export_memory(VALUE self, VALUE format)
534{
535    unsigned long int bytes;
536    void *result;
537    VALUE ret;
538    result = cucul_export_memory (_SELF, StringValuePtr(format), &bytes);
539    ret = rb_str_new(result, bytes);
540    free(result);
541    return ret;
542}
543
544static VALUE export_list(void)
545{
546    VALUE ary, ary2;
547   
548    char const* const* list;
549   
550    list = cucul_get_export_list();
551   
552    ary = rb_ary_new();
553   
554    while (*list != NULL)
555    {
556        ary2 = rb_ary_new();
557        rb_ary_push(ary2, rb_str_new2(*list));
558        list++;
559        rb_ary_push(ary2, rb_str_new2(*list));
560        list++;
561        rb_ary_push(ary, ary2);
562    }
563
564    return ary;
565}
566
567static VALUE import_list(void)
568{
569    VALUE ary, ary2;
570   
571    char const* const* list;
572   
573    list = cucul_get_import_list();
574   
575    ary = rb_ary_new();
576   
577    while (*list != NULL)
578    {
579        ary2 = rb_ary_new();
580        rb_ary_push(ary2, rb_str_new2(*list));
581        list++;
582        rb_ary_push(ary2, rb_str_new2(*list));
583        list++;
584        rb_ary_push(ary, ary2);
585    }
586
587    return ary;
588}
589
590/****/
591
592void Init_cucul_canvas(VALUE mCucul)
593{
594    cCanvas = rb_define_class_under(mCucul, "Canvas", rb_cObject);
595    rb_define_alloc_func(cCanvas, canvas_alloc);
596
597    rb_define_method(cCanvas, "initialize", canvas_initialize, 2);
598    rb_define_method(cCanvas, "width", get_canvas_width, 0);
599    rb_define_method(cCanvas, "width=", set_canvas_width, 1);
600    rb_define_method(cCanvas, "set_width", set_canvas_width2, 1);
601    rb_define_method(cCanvas, "height", get_canvas_height, 0);
602    rb_define_method(cCanvas, "height=", set_canvas_height, 1);
603    rb_define_method(cCanvas, "set_height", set_canvas_height2, 1);
604    rb_define_method(cCanvas, "set_size", set_canvas_size, 2);
605       
606    rb_define_method(cCanvas, "gotoxy", gotoxy, 2);
607    rb_define_method(cCanvas, "cursor_x", get_cursor_x, 0);
608    rb_define_method(cCanvas, "cursor_y", get_cursor_y, 0);
609    rb_define_method(cCanvas, "handle_x", get_canvas_handle_x, 0);
610    rb_define_method(cCanvas, "handle_y", get_canvas_handle_y, 0);
611    rb_define_method(cCanvas, "set_handle", set_canvas_handle, 2);
612    rb_define_method(cCanvas, "blit", blit, -1);
613    rb_define_method(cCanvas, "set_boundaries", set_canvas_boundaries, 4);
614
615    rb_define_method(cCanvas, "clear", clear_canvas, 0);
616   
617    rb_define_method(cCanvas, "put_char", put_char, 3);
618    rb_define_method(cCanvas, "get_char", get_char, 2);
619    rb_define_method(cCanvas, "put_str", put_str, 3);
620    rb_define_method(cCanvas, "printf", cprintf, -1);
621
622    rb_define_method(cCanvas, "get_attr", get_attr, 3);
623    rb_define_method(cCanvas, "attr=", set_attr, 1);
624    rb_define_method(cCanvas, "set_attr", set_attr2, 1);
625    rb_define_method(cCanvas, "put_attr", put_attr, 3);
626    rb_define_method(cCanvas, "set_color_ansi", set_color_ansi, 2);
627    rb_define_method(cCanvas, "set_color_argb", set_color_argb, 2);
628
629    rb_define_method(cCanvas, "invert", invert, 0);
630    rb_define_method(cCanvas, "flip", flip, 0);
631    rb_define_method(cCanvas, "flop", flop, 0);
632    rb_define_method(cCanvas, "rotate_180", rotate_180, 0);
633    rb_define_method(cCanvas, "rotate_left", rotate_left, 0);
634    rb_define_method(cCanvas, "rotate_right", rotate_right, 0);
635    rb_define_method(cCanvas, "stretch_left", stretch_left, 0);
636    rb_define_method(cCanvas, "stretch_right", stretch_right, 0);
637
638    rb_define_method(cCanvas, "draw_line", draw_line, 5);
639    rb_define_method(cCanvas, "draw_polyline", draw_polyline, 2);
640    rb_define_method(cCanvas, "draw_thin_line", draw_thin_line, 4);
641    rb_define_method(cCanvas, "draw_thin_polyline", draw_thin_polyline, 1);
642    rb_define_method(cCanvas, "draw_circle", draw_circle, 4);
643    rb_define_method(cCanvas, "draw_ellipse", draw_ellipse, 5);
644    rb_define_method(cCanvas, "draw_thin_ellipse", draw_thin_ellipse, 4);
645    rb_define_method(cCanvas, "fill_ellipse", fill_ellipse, 5);
646    rb_define_method(cCanvas, "draw_box", draw_box, 5);
647    rb_define_method(cCanvas, "draw_thin_box", draw_thin_box, 4);
648    rb_define_method(cCanvas, "draw_cp437_box", draw_cp437_box, 4);
649    rb_define_method(cCanvas, "fill_box", fill_box, 5);
650    rb_define_method(cCanvas, "draw_triangle", draw_triangle, 7);
651    rb_define_method(cCanvas, "draw_thin_triangle", draw_thin_triangle, 6);
652    rb_define_method(cCanvas, "fill_triangle", fill_triangle, 7);
653
654    rb_define_method(cCanvas, "frame_count", get_frame_count, 0);
655    rb_define_method(cCanvas, "frame=", set_frame, 1);
656    rb_define_method(cCanvas, "set_frame", set_frame2, 1);
657    rb_define_method(cCanvas, "frame_name", get_frame_name, 0);
658    rb_define_method(cCanvas, "frame_name=", set_frame_name, 1);
659    rb_define_method(cCanvas, "set_frame_name", set_frame_name2, 1);
660    rb_define_method(cCanvas, "create_frame", create_frame, 1);
661    rb_define_method(cCanvas, "free_frame", free_frame, 1);
662
663    rb_define_method(cCanvas, "render", render_canvas, 4);
664    rb_define_method(cCanvas, "import_memory", import_memory, 2);
665    rb_define_method(cCanvas, "import_file", import_file, 2);
666    rb_define_method(cCanvas, "export_memory", export_memory, 1);
667    rb_define_singleton_method(cCanvas, "export_list", export_list, 0);
668    rb_define_singleton_method(cCanvas, "import_list", import_list, 0);
669   
670}
671
Note: See TracBrowser for help on using the repository browser.