diff --git a/ruby/Makefile.am b/ruby/Makefile.am index 11ee0fb..80f1948 100644 --- a/ruby/Makefile.am +++ b/ruby/Makefile.am @@ -7,11 +7,13 @@ TESTS = test endif cucul_la_CPPFLAGS = -I$(top_srcdir)/cucul -I$(RUBY_ARCHDIR) -cucul_la_SOURCES = cucul.c cucul-canvas.c +cucul_la_SOURCES = cucul.c cucul-canvas.c cucul-font.c cucul_la_LDFLAGS = -module -avoid-version -shared -L$(RUBY_LIBDIR) -l$(RUBY_SO_NAME) cucul_la_LIBADD = ../cucul/libcucul.la EXTRA_DIST = cucul-canvas.h \ + cucul-canvas.h \ + common.h \ test.rb \ t/tc_frame.rb \ README diff --git a/ruby/common.h b/ruby/common.h new file mode 100644 index 0000000..e9668d0 --- /dev/null +++ b/ruby/common.h @@ -0,0 +1,6 @@ +#ifndef __COMMON_H__ +#define __COMMON_H__ + +#define _SELF (DATA_PTR(self)) + +#endif diff --git a/ruby/cucul-canvas.c b/ruby/cucul-canvas.c index ea53689..41ac2ff 100644 --- a/ruby/cucul-canvas.c +++ b/ruby/cucul-canvas.c @@ -12,9 +12,10 @@ #include #include #include -#include "cucul-canvas.h" +#include "cucul-font.h" +#include "common.h" -#define _SELF (DATA_PTR(self)) +VALUE cCanvas; #define simple_func(x) \ static VALUE x (VALUE self) \ @@ -201,10 +202,12 @@ static VALUE blit(int argc, VALUE* argv, VALUE self) { Check_Type(x, T_FIXNUM); Check_Type(y, T_FIXNUM); + //FIXME rather check that class is cCanvas Check_Type(src, TYPE(self)); Data_Get_Struct(src, cucul_canvas_t, csrc); if(!NIL_P(mask)) { + //FIXME rather check that class is cCanvas Check_Type(mask, TYPE(self)); Data_Get_Struct(mask, cucul_canvas_t, cmask); } @@ -484,6 +487,29 @@ static VALUE free_frame(VALUE self, VALUE id) /****/ +static VALUE render_canvas(VALUE self, VALUE font, VALUE width, VALUE height, VALUE pitch) +{ + void *buf; + cucul_font_t *f; + VALUE b; + + //FIXME rather check that class is cFont + Check_Type(font, TYPE(self)); + + buf = malloc(width*height*4); + if(buf == NULL) + { + rb_raise(rb_eNoMemError, "Out of memory"); + } + + f = DATA_PTR(font); + cucul_render_canvas(_SELF, f, buf, NUM2UINT(width), NUM2UINT(height), NUM2UINT(pitch)); + + b = rb_str_new(buf, width*height*4); + free(buf); + return b; +} + static VALUE import_memory(VALUE self, VALUE data, VALUE format) { long int bytes; @@ -565,7 +591,7 @@ static VALUE import_list(void) void Init_cucul_canvas(VALUE mCucul) { - VALUE cCanvas = rb_define_class_under(mCucul, "Canvas", rb_cObject); + cCanvas = rb_define_class_under(mCucul, "Canvas", rb_cObject); rb_define_alloc_func(cCanvas, canvas_alloc); rb_define_method(cCanvas, "initialize", canvas_initialize, 2); @@ -634,6 +660,7 @@ void Init_cucul_canvas(VALUE mCucul) rb_define_method(cCanvas, "create_frame", create_frame, 1); rb_define_method(cCanvas, "free_frame", free_frame, 1); + rb_define_method(cCanvas, "render", render_canvas, 4); rb_define_method(cCanvas, "import_memory", import_memory, 2); rb_define_method(cCanvas, "import_file", import_file, 2); rb_define_method(cCanvas, "export_memory", export_memory, 1); diff --git a/ruby/cucul-canvas.h b/ruby/cucul-canvas.h index 587ced3..4748e08 100644 --- a/ruby/cucul-canvas.h +++ b/ruby/cucul-canvas.h @@ -1,6 +1,9 @@ #ifndef __CUCUL_CANVAS_H__ #define __CUCUL_CANVAS_H__ +#include + +extern VALUE cCanvas; extern void Init_cucul_canvas(VALUE); #endif diff --git a/ruby/cucul-font.c b/ruby/cucul-font.c new file mode 100644 index 0000000..ff138e2 --- /dev/null +++ b/ruby/cucul-font.c @@ -0,0 +1,99 @@ +/* + * libcucul Ruby bindings + * Copyright (c) 2007 Pascal Terjan + * + * This library is free software. It comes without any warranty, to + * the extent permitted by applicable law. You can redistribute it + * and/or modify it under the terms of the Do What The Fuck You Want + * To Public License, Version 2, as published by Sam Hocevar. See + * http://sam.zoy.org/wtfpl/COPYING for more details. + */ + +#include +#include +#include +#include "common.h" + +VALUE cFont; + +void font_free(void *font) +{ + cucul_free_font((cucul_font_t *)font); +} + +static VALUE font_alloc(VALUE klass) +{ + VALUE obj; + obj = Data_Wrap_Struct(klass, 0, font_free, NULL); + return obj; +} + +static VALUE font_initialize(VALUE self, VALUE name) +{ + cucul_font_t *font; + + font = cucul_load_font(StringValuePtr(name), 0); + if(font == NULL) + { + rb_raise(rb_eRuntimeError, strerror(errno)); + } + _SELF = font; + return self; +} + +static VALUE font_list(void) +{ + VALUE ary; + char const* const* list; + + list = cucul_get_font_list(); + + ary = rb_ary_new(); + while (*list != NULL) + { + rb_ary_push(ary, rb_str_new2(*list)); + list++; + } + + return ary; +} + +static VALUE get_font_width(VALUE self) +{ + return UINT2NUM(cucul_get_font_width(_SELF)); +} + +static VALUE get_font_height(VALUE self) +{ + return UINT2NUM(cucul_get_font_height(_SELF)); +} + +static VALUE get_font_blocks(VALUE self) +{ + VALUE ary; + unsigned long int const *list; + + list = cucul_get_font_blocks(_SELF); + + ary = rb_ary_new(); + while (*list != 0L) + { + rb_ary_push(ary, ULONG2NUM(*list)); + list++; + } + + return ary; +} + +void Init_cucul_font(VALUE mCucul) +{ + cFont = rb_define_class_under(mCucul, "Font", rb_cObject); + rb_define_alloc_func(cFont, font_alloc); + + rb_define_method(cFont, "initialize", font_initialize, 1); + rb_define_method(cFont, "width", get_font_width, 0); + rb_define_method(cFont, "height", get_font_height, 0); + rb_define_method(cFont, "blocks", get_font_blocks, 0); + rb_define_singleton_method(cFont, "list", font_list, 0); +} + diff --git a/ruby/cucul-font.h b/ruby/cucul-font.h new file mode 100644 index 0000000..57141a5 --- /dev/null +++ b/ruby/cucul-font.h @@ -0,0 +1,9 @@ +#ifndef __CUCUL_FONT_H__ +#define __CUCUL_FONT_H__ + +#include + +extern VALUE cFont; +extern void Init_cucul_font(VALUE); + +#endif diff --git a/ruby/cucul.c b/ruby/cucul.c index b0222a6..c8e4cc1 100644 --- a/ruby/cucul.c +++ b/ruby/cucul.c @@ -13,12 +13,11 @@ #include #include "cucul-canvas.h" - -static VALUE mCucul; +#include "cucul-font.h" void Init_cucul() { - mCucul = rb_define_module("Cucul"); + VALUE mCucul = rb_define_module("Cucul"); rb_define_const(mCucul, "BLACK", INT2FIX(CUCUL_BLACK)); rb_define_const(mCucul, "BLUE", INT2FIX(CUCUL_BLUE)); @@ -45,4 +44,5 @@ void Init_cucul() rb_define_const(mCucul, "BLINK", INT2FIX(CUCUL_BLINK)); Init_cucul_canvas(mCucul); + Init_cucul_font(mCucul); } diff --git a/ruby/t/tc_canvas.rb b/ruby/t/tc_canvas.rb index d3d466a..860076d 100644 --- a/ruby/t/tc_canvas.rb +++ b/ruby/t/tc_canvas.rb @@ -44,4 +44,10 @@ class TC_Canvas < Test::Unit::TestCase @c.put_char(1, 1, 42) assert_equal(42, @c.get_char(1,1)) end + def test_render + c = Cucul::Canvas.new(4,4) + c.put_str(0,0,"plop") + f = Cucul::Font.new(Cucul::Font.list[0]) + assert_not_nil(c.render(f, c.width*f.width, c.height*f.height, c.width*f.width*4)) + end end diff --git a/ruby/t/tc_font.rb b/ruby/t/tc_font.rb new file mode 100644 index 0000000..ca06e2d --- /dev/null +++ b/ruby/t/tc_font.rb @@ -0,0 +1,22 @@ +require 'test/unit' +require 'cucul' + +class TC_Canvas < Test::Unit::TestCase + def test_list + assert_not_nil(Cucul::Font.list) + end + def test_load + Cucul::Font.list.each{|f| + font = Cucul::Font.new(f) + assert_not_nil(font) + assert_not_nil(font.width) + assert_not_nil(font.height) + assert_not_nil(font.blocks) + } + end + def test_fail_load + assert_raise(RuntimeError) { + Cucul::Font.new("This font should not exist") + } + end +end