ext/wxPalette.cpp
/*
* wxPalette.cpp
*
* Created on: 20.11.2013
* Author: hanmac
*/
#include "wxPalette.hpp"
#include "wxColor.hpp"
#if wxUSE_PALETTE
#define _self unwrap<wxPalette*>(self)
VALUE rb_cWXPalette;
template <>
wxPalette* unwrap< wxPalette* >(const VALUE &vimage)
{
return unwrapTypedPtr<wxPalette>(vimage, rb_cWXPalette);
}
template <>
wxPalette unwrap< wxPalette >(const VALUE &vimage)
{
return *unwrap<wxPalette*>(vimage);
}
namespace RubyWX {
namespace Palette {
singlereturn(GetColoursCount)
DLL_LOCAL VALUE _alloc(VALUE self) {
return wrap(new wxPalette);
}
DLL_LOCAL VALUE _initialize(int argc, VALUE *argv, VALUE self) {
if(argc > 0)
{
unsigned char red[argc];
unsigned char green[argc];
unsigned char blue[argc];
for(std::size_t i = 0; i < (std::size_t)argc; ++i)
{
wxColor temp = unwrap<wxColor>(argv[i]);
red[i] = temp.Red();
green[i] = temp.Green();
blue[i] = temp.Blue();
}
_self->Create(argc,red,green,blue);
}
return self;
}
DLL_LOCAL VALUE _initialize_copy(VALUE self,VALUE other) {
wxPalette *cother = unwrap<wxPalette*>(other);
std::size_t count(cother->GetColoursCount());
unsigned char red[count];
unsigned char green[count];
unsigned char blue[count];
for(std::size_t i = 0; i < count; ++i)
{
cother->GetRGB(i,&red[i],&green[i],&blue[i]);
}
_self->Create(count,red,green,blue);
return self;
}
/*
* call-seq:
* image[idx] -> WX::Color or nil
*
* Returns the color at the given position or nil if out of range
* ===Arguments
* * idx is Integer
* ===Return value
* WX::Color or nil
*/
DLL_LOCAL VALUE _get(VALUE self,VALUE idx)
{
unsigned char red,green,blue;
if(_self->GetRGB(RB_NUM2UINT(idx),&red,&green,&blue))
return wrap(new wxColor(red,green,blue));
return Qnil;
}
/*
* call-seq:
* each -> Enumerator
* each { |color| } -> self
*
* iterates the colors in this Palette.
* ===Return value
* self
*
*/
DLL_LOCAL VALUE _each(VALUE self)
{
RETURN_SIZED_ENUMERATOR(self,0,NULL,RUBY_METHOD_FUNC(_GetColoursCount));
unsigned char red,green,blue;
std::size_t count = _self->GetColoursCount();
for(std::size_t i = 0; i < count; ++i)
{
_self->GetRGB(i,&red,&green,&blue);
rb_yield(wrap(new wxColor(red,green,blue)));
}
return self;
}
/*
* call-seq:
* hash -> Fixnum
*
* Generates a Fixnum hash value for this object.
*
*
*/
DLL_LOCAL VALUE _getHash(VALUE self)
{
std::size_t count = _self->GetColoursCount();
st_index_t h = rb_hash_start(count);
for(std::size_t i = 0; i < count; ++i)
{
unsigned char red,green,blue;
_self->GetRGB(i,&red,&green,&blue);
h = rb_hash_uint32(h, red | (green << 8) | (blue << 16));
}
h = rb_hash_end(h);
return RB_LONG2FIX(h);
}
bool check_equal(const wxPalette &self, const wxPalette &cother)
{
if(self.GetColoursCount() != cother.GetColoursCount()){
return false;
}
std::size_t count = self.GetColoursCount();
for(std::size_t i = 0; i < count; ++i)
{
unsigned char red, green, blue;
unsigned char cred, cgreen, cblue;
self.GetRGB(i,&red,&green,&blue);
cother.GetRGB(i,&cred,&cgreen,&cblue);
if(red != cred || green != cgreen || blue != cblue)
return false;
}
return true;
}
struct equal_obj {
wxPalette* self;
VALUE other;
};
VALUE _equal_block(equal_obj *obj)
{
return wrap(check_equal(*obj->self, unwrap<wxPalette>(obj->other)));
}
/*
* call-seq:
* == palette -> bool
*
* compares two palettes.
*
*
*/
DLL_LOCAL VALUE _equal(VALUE self, VALUE other)
{
equal_obj obj;
obj.self = _self;
obj.other = other;
return rb_rescue(
RUBY_METHOD_FUNC(_equal_block),(VALUE)&obj,
RUBY_METHOD_FUNC(_equal_rescue),Qnil
);
}
/*
* call-seq:
* marshal_dump -> Array
*
* Provides marshalling support for use by the Marshal library.
* ===Return value
* Array
*/
DLL_LOCAL VALUE _marshal_dump(VALUE self)
{
VALUE ary = rb_ary_new(); //2(_self->GetColoursCount()*3);
std::size_t count = _self->GetColoursCount();
for(std::size_t i = 0; i < count; ++i)
{
unsigned char red,green,blue;
_self->GetRGB(i,&red,&green,&blue);
rb_ary_push(ary, RB_UINT2NUM(red | (green << 8) | (blue << 16)));
}
return ary;
}
/*
* call-seq:
* marshal_load(array) -> nil
*
* Provides marshalling support for use by the Marshal library.
*
*
*/
DLL_LOCAL VALUE _marshal_load(VALUE self,VALUE data)
{
data = rb_Array(data);
std::size_t count = RARRAY_LEN(data);
unsigned char red[count];
unsigned char green[count];
unsigned char blue[count];
for(std::size_t i = 0; i < count; ++i)
{
unsigned int colRGB = RB_NUM2UINT(RARRAY_AREF(data,i));
red[i] = 0xFF & colRGB;
green[i] = 0xFF & (colRGB >> 8);
blue[i] = 0xFF & (colRGB >> 16);
}
_self->Create(count,red,green,blue);
return self;
}
}
}
#endif
/* Document-method: size
* call-seq:
* size -> Integer
*
* returns the count of colors in this Palette list.
* ===Return value
* Integer
*/
DLL_LOCAL void Init_WXPalette(VALUE rb_mWX)
{
#if wxUSE_PALETTE
using namespace RubyWX::Palette;
rb_cWXPalette = rb_define_class_under(rb_mWX,"Palette",rb_cObject);
rb_define_alloc_func(rb_cWXPalette,_alloc);
rb_include_module(rb_cWXPalette,rb_mEnumerable);
rb_define_method(rb_cWXPalette,"initialize",RUBY_METHOD_FUNC(_initialize),-1);
rb_define_private_method(rb_cWXPalette,"initialize_copy",RUBY_METHOD_FUNC(_initialize_copy),1);
rb_define_method(rb_cWXPalette,"[]",RUBY_METHOD_FUNC(_get),1);
rb_define_method(rb_cWXPalette,"hash",RUBY_METHOD_FUNC(_getHash),0);
rb_define_method(rb_cWXPalette,"==",RUBY_METHOD_FUNC(_equal),1);
rb_define_alias(rb_cWXPalette,"eql?","==");
rb_define_method(rb_cWXPalette,"size",RUBY_METHOD_FUNC(_GetColoursCount),0);
rb_define_method(rb_cWXPalette,"each",RUBY_METHOD_FUNC(_each),0);
rb_define_method(rb_cWXPalette,"marshal_dump",RUBY_METHOD_FUNC(_marshal_dump),0);
rb_define_method(rb_cWXPalette,"marshal_load",RUBY_METHOD_FUNC(_marshal_load),1);
registerInfo<wxPalette>(rb_cWXPalette);
#endif
}