Index: /libcaca/trunk/ruby/t/tc_dither.rb
===================================================================
--- /libcaca/trunk/ruby/t/tc_dither.rb	(revision 2008)
+++ /libcaca/trunk/ruby/t/tc_dither.rb	(revision 2008)
@@ -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
Index: /libcaca/trunk/ruby/Makefile.am
===================================================================
--- /libcaca/trunk/ruby/Makefile.am	(revision 2007)
+++ /libcaca/trunk/ruby/Makefile.am	(revision 2008)
@@ -8,13 +8,15 @@
 
 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 \
Index: /libcaca/trunk/ruby/cucul-dither.c
===================================================================
--- /libcaca/trunk/ruby/cucul-dither.c	(revision 2008)
+++ /libcaca/trunk/ruby/cucul-dither.c	(revision 2008)
@@ -0,0 +1,180 @@
+/*
+ *  libcucul Ruby bindings
+ *  Copyright (c) 2007 Pascal Terjan <pterjan@linuxfr.org>
+ *
+ *  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 <ruby.h>
+#include <cucul.h>
+#include <errno.h>
+#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);
+}
+
Index: /libcaca/trunk/ruby/cucul.c
===================================================================
--- /libcaca/trunk/ruby/cucul.c	(revision 2007)
+++ /libcaca/trunk/ruby/cucul.c	(revision 2008)
@@ -14,4 +14,5 @@
 
 #include "cucul-canvas.h"
+#include "cucul-dither.h"
 #include "cucul-font.h"
 
@@ -45,4 +46,5 @@
 
     Init_cucul_canvas(mCucul);
+    Init_cucul_dither(mCucul);
     Init_cucul_font(mCucul);
 }
Index: /libcaca/trunk/ruby/README
===================================================================
--- /libcaca/trunk/ruby/README	(revision 2007)
+++ /libcaca/trunk/ruby/README	(revision 2008)
@@ -8,5 +8,6 @@
 
 - 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)
@@ -27,5 +28,5 @@
 "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
 
@@ -54,11 +55,22 @@
 \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 :
Index: /libcaca/trunk/ruby/cucul-dither.h
===================================================================
--- /libcaca/trunk/ruby/cucul-dither.h	(revision 2008)
+++ /libcaca/trunk/ruby/cucul-dither.h	(revision 2008)
@@ -0,0 +1,9 @@
+#ifndef __CUCUL_DITHER_H__
+#define __CUCUL_DITHER_H__
+
+#include <ruby.h>
+
+extern VALUE cDither;
+extern void Init_cucul_dither(VALUE);
+
+#endif
