From 17c5fc733570caa94b75970d8490d7a2a0d19005 Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Sat, 17 Nov 2007 12:21:21 +0000 Subject: [PATCH] * Add Cucul::Dither (incomplete) --- ruby/Makefile.am | 6 +- ruby/README | 16 +++- ruby/cucul-dither.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ ruby/cucul-dither.h | 9 +++ ruby/cucul.c | 2 + ruby/t/tc_dither.rb | 51 +++++++++++++ 6 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 ruby/cucul-dither.c create mode 100644 ruby/cucul-dither.h create mode 100644 ruby/t/tc_dither.rb diff --git a/ruby/Makefile.am b/ruby/Makefile.am index 3c237d9..0754492 100644 --- a/ruby/Makefile.am +++ b/ruby/Makefile.am @@ -7,15 +7,17 @@ TESTS = test endif cucul_la_CPPFLAGS = -I$(top_srcdir)/cucul -I$(RUBY_ARCHDIR) -cucul_la_SOURCES = cucul.c cucul-canvas.c cucul-font.c +cucul_la_SOURCES = cucul.c cucul-canvas.c cucul-dither.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 \ + cucul-dither.h \ + cucul-font.h \ common.h \ test.rb \ t/tc_canvas.rb \ + t/tc_dither.rb \ t/tc_font.rb \ t/tc_frame.rb \ README diff --git a/ruby/README b/ruby/README index 79f416c..aa60afd 100644 --- a/ruby/README +++ b/ruby/README @@ -7,7 +7,8 @@ There is no real documentation but "methods" on any object should help you :) The objects available for now are : - Cucul::Canvas (functions that have a cucul_canvas_t* as first argument) - * dither_bitmap is missing as Cucul::Dither is not yet implemented + +- Cucul::Dither (functions that have a cucul_dither_t* as first argument) - Cucul::Font (functions that have a cucul_font_t* as first argument) * The constructor can currently only accept the name of a builtin font @@ -26,7 +27,7 @@ irb(main):001:0> Cucul.constants => ["BROWN", "BOLD", "GREEN", "LIGHTMAGENTA", "LIGHTBLUE", "BLINK", "MAGENTA", "DEFAULT", "TRANSPARENT", "BLUE", "LIGHTRED", "DARKGRAY", "UNDERLINE", "RED", "WHITE", "BLACK", "LIGHTCYAN", "LIGHTGRAY", -"ITALICS", "CYAN", "YELLOW", "LIGHTGREEN", "Canvas", "Font"] +"ITALICS", "CYAN", "YELLOW", "LIGHTGREEN", "Canvas", "Dither", "Font"] \endcode \code @@ -53,13 +54,24 @@ Cucul::Canvas.ancestors[1].instance_methods "stretch_left", "stretch_right", "width", "width="] \endcode +\code irb(main):004:0> Cucul::Font.methods.sort - Cucul::Font.ancestors[1].methods => ["list"] +\endcode +\code irb(main):005:0> Cucul::Font.instance_methods.sort - Cucul::Font.ancestors[1].instance_methods => ["blocks", "height", "width"] +\endcode + +\code +irb(main):006:0> Cucul::Dither.instance_methods.sort - +Cucul::Dither.ancestors[1].instance_methods => ["brightness=", +"contrast=", "gamma=", "palette=", "set_brightness", "set_contrast", +"set_gamma", "set_palette"] +\endcode And here are sample uses : diff --git a/ruby/cucul-dither.c b/ruby/cucul-dither.c new file mode 100644 index 0000000..bba27dc --- /dev/null +++ b/ruby/cucul-dither.c @@ -0,0 +1,180 @@ +/* + * 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 dither_free(void *dither) +{ + cucul_free_dither((cucul_dither_t *)dither); +} + +static VALUE dither_alloc(VALUE klass) +{ + VALUE obj; + obj = Data_Wrap_Struct(klass, 0, dither_free, NULL); + return obj; +} + +static VALUE dither_initialize(VALUE self, VALUE bpp, VALUE w, VALUE h, VALUE pitch, VALUE rmask, VALUE gmask, VALUE bmask, VALUE amask) +{ + cucul_dither_t *dither; + + dither = cucul_create_dither(NUM2UINT(bpp), NUM2UINT(w), NUM2UINT(h), NUM2UINT(pitch), NUM2ULONG(rmask), NUM2ULONG(gmask), NUM2ULONG(bmask), NUM2ULONG(amask)); + if(dither == NULL) + { + rb_raise(rb_eRuntimeError, strerror(errno)); + } + _SELF = dither; + return self; +} + +static VALUE set_dither_palette(VALUE self, VALUE palette) +{ + int i; + unsigned int *red, *blue, *green, *alpha; + VALUE v, r, g, b, a; + int error = 0; + + if(RARRAY(palette)->len != 256) + { + rb_raise(rb_eArgError, "Palette must contain 256 elements"); + } + + red = ALLOC_N(unsigned int, 256); + if(!red) + rb_raise(rb_eNoMemError,"Out of memory"); + + green = ALLOC_N(unsigned int, 256); + if(!green) + { + free(red); + rb_raise(rb_eNoMemError,"Out of memory"); + } + + blue = ALLOC_N(unsigned int, 256); + if(!blue) + { + free(red); + free(green); + rb_raise(rb_eNoMemError,"Out of memory"); + } + + alpha = ALLOC_N(unsigned int, 256); + if(!alpha) + { + free(red); + free(green); + free(blue); + rb_raise(rb_eNoMemError,"Out of memory"); + } + + for(i=0; i<256; i++) + { + v = rb_ary_entry(palette, i); + if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 4)) + { + r = rb_ary_entry(v,0); + g = rb_ary_entry(v,1); + b = rb_ary_entry(v,2); + a = rb_ary_entry(v,3); + if(rb_obj_is_kind_of(r, rb_cInteger) && + rb_obj_is_kind_of(g, rb_cInteger) && + rb_obj_is_kind_of(b, rb_cInteger) && + rb_obj_is_kind_of(a, rb_cInteger)) + { + red[i] = NUM2INT(r); + green[i] = NUM2INT(g); + blue[i] = NUM2INT(b); + alpha[i] = NUM2INT(a); + } else + error = 1; + } + else + error = 1; + } + + if(error) + { + free(red); + free(green); + free(blue); + free(alpha); + rb_raise(rb_eArgError, "Invalid palette"); + } + + if(cucul_set_dither_palette(_SELF, red, green, blue, alpha)<0) + { + free(red); + free(green); + free(blue); + free(alpha); + rb_raise(rb_eRuntimeError, strerror(errno)); + } + + free(red); + free(green); + free(blue); + free(alpha); + + return palette; +} + +static VALUE set_dither_palette2(VALUE self, VALUE palette) +{ + set_dither_palette(self, palette); + return self; +} + +#define set_float(x) \ +static VALUE set_##x (VALUE self, VALUE x) \ +{ \ + if(cucul_set_dither_##x(_SELF, (float)NUM2DBL(x))<0)\ + rb_raise(rb_eRuntimeError, strerror(errno)); \ + \ + return x; \ +} \ + \ +static VALUE set_##x##2 (VALUE self, VALUE x) \ +{ \ + set_##x(self, x); \ + return self; \ +} + +set_float(brightness) +set_float(gamma) +set_float(contrast) + +/* + int cucul_set_dither_invert (cucul_dither_t *, int) + Invert colors of dither. +*/ + +void Init_cucul_dither(VALUE mCucul) +{ + cFont = rb_define_class_under(mCucul, "Dither", rb_cObject); + rb_define_alloc_func(cFont, dither_alloc); + + rb_define_method(cFont, "initialize", dither_initialize, 8); + rb_define_method(cFont, "palette=", set_dither_palette, 1); + rb_define_method(cFont, "set_palette", set_dither_palette2, 1); + rb_define_method(cFont, "brightness=", set_brightness, 1); + rb_define_method(cFont, "set_brightness", set_brightness2, 1); + rb_define_method(cFont, "gamma=", set_gamma, 1); + rb_define_method(cFont, "set_gamma", set_gamma2, 1); + rb_define_method(cFont, "contrast=", set_contrast, 1); + rb_define_method(cFont, "set_contrast", set_contrast2, 1); +} + diff --git a/ruby/cucul-dither.h b/ruby/cucul-dither.h new file mode 100644 index 0000000..701f5b1 --- /dev/null +++ b/ruby/cucul-dither.h @@ -0,0 +1,9 @@ +#ifndef __CUCUL_DITHER_H__ +#define __CUCUL_DITHER_H__ + +#include + +extern VALUE cDither; +extern void Init_cucul_dither(VALUE); + +#endif diff --git a/ruby/cucul.c b/ruby/cucul.c index c8e4cc1..7db48c2 100644 --- a/ruby/cucul.c +++ b/ruby/cucul.c @@ -13,6 +13,7 @@ #include #include "cucul-canvas.h" +#include "cucul-dither.h" #include "cucul-font.h" void Init_cucul() @@ -44,5 +45,6 @@ void Init_cucul() rb_define_const(mCucul, "BLINK", INT2FIX(CUCUL_BLINK)); Init_cucul_canvas(mCucul); + Init_cucul_dither(mCucul); Init_cucul_font(mCucul); } diff --git a/ruby/t/tc_dither.rb b/ruby/t/tc_dither.rb new file mode 100644 index 0000000..e69ce46 --- /dev/null +++ b/ruby/t/tc_dither.rb @@ -0,0 +1,51 @@ +require 'test/unit' +require 'cucul' + +class TC_Canvas < Test::Unit::TestCase + def test_create + assert_nothing_raised { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + } + end + def test_fail_create + assert_raise(RuntimeError) { + d = Cucul::Dither.new(-1, 32, 32, 32, 0, 0, 0, 0) + } + end + def test_set_palette + assert_nothing_raised { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.palette=[[0xfff, 0xfff, 0xfff, 0xfff]]*256 + } + end + def test_fail_set_palette + assert_raise(ArgumentError) { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.palette=[] + } + end + def test_fail_set_palette2 + assert_raise(RuntimeError) { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.palette=[[0xffff, 0, 0, 0]]*256 + } + end + def test_set_brightness + assert_nothing_raised { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.brightness=0.5 + } + end + def test_set_gamma + assert_nothing_raised { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.gamma=0.5 + } + end + def test_set_contrast + assert_nothing_raised { + d = Cucul::Dither.new(8, 32, 32, 32, 0, 0, 0, 0) + d.contrast=0.5 + } + end +end