Object
Are we using the buggy imlib_image_draw_pixel() work-around?
Versions of Imlib2 up to and including 1.0.5 had a broken imlib_image_draw_pixel() call. Imlib2-Ruby has a work-around, which simulates drawing a pixel with a 1x1 rectangle. This method allows you to check whether the work-around behavior is enabled.
Examples:
puts 'work-around is enabled' if Imlib2::Image::draw_pixel_workaround? puts 'work-around is enabled' if Imlib2::Image::bypass_draw_pixel?
VALUE image_dp_workaround(VALUE klass) {
UNUSED(klass);
return draw_pixel_workaround ? Qtrue : Qfalse;
}
Are we using the buggy imlib_image_draw_pixel() work-around?
Versions of Imlib2 up to and including 1.0.5 had a broken imlib_image_draw_pixel() call. Imlib2-Ruby has a work-around, which simulates drawing a pixel with a 1x1 rectangle. This method allows you to check whether the work-around behavior is enabled.
Examples:
puts 'work-around is enabled' if Imlib2::Image::draw_pixel_workaround? puts 'work-around is enabled' if Imlib2::Image::bypass_draw_pixel?
VALUE image_dp_workaround(VALUE klass) {
UNUSED(klass);
return draw_pixel_workaround ? Qtrue : Qfalse;
}
Returns a new Imlib2::Image with the specified width and height.
Examples:
width, height = 640, 480 image = Imlib2::Image.new width, height width, height = 320, 240 image = Imlib2::Image.create width, height
VALUE image_new(VALUE klass, VALUE w, VALUE h) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_create_image(NUM2INT(w), NUM2INT(h));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
rb_obj_call_init(im_o, 0, NULL);
return im_o;
}
Returns a new Imlib2::Image initialized with the specified data.
Examples:
other_image = Imlib2::Image.load 'sample_file.png' width, height = other_image.width, other_image.height data = other_image.data image = Imlib2::Image.create_using_copied_data width, height, data
VALUE image_create_using_copied_data(VALUE klass, VALUE w, VALUE h, VALUE data) {
ImStruct *im;
VALUE im_o;
im = malloc(sizeof(ImStruct));
im->im = imlib_create_image_using_copied_data(NUM2INT(w), NUM2INT(h), (DATA32 *) StringValuePtr (data));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
rb_obj_call_init(im_o, 0, NULL);
return im_o;
}
Returns a new Imlib2::Image initialized with the specified data.
Examples:
other_image = Imlib2::Image.load 'sample_file.png' width, height = other_image.width, other_image.height data = other_image.data_for_reading_only image = Imlib2::Image.create_using_data width, height, data
VALUE image_create_using_data(VALUE klass, VALUE w, VALUE h, VALUE data) {
ImStruct *im;
VALUE im_o;
im = malloc(sizeof(ImStruct));
im->im = imlib_create_image_using_data(NUM2INT(w), NUM2INT(h), (DATA32 *) StringValuePtr (data));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
rb_obj_call_init(im_o, 0, NULL);
return im_o;
}
Are we using the buggy imlib_image_draw_pixel() work-around?
Versions of Imlib2 up to and including 1.0.5 had a broken imlib_image_draw_pixel() call. Imlib2-Ruby has a work-around, which simulates drawing a pixel with a 1x1 rectangle. This method allows you to check whether the work-around behavior is enabled.
Examples:
puts 'work-around is enabled' if Imlib2::Image::draw_pixel_workaround? puts 'work-around is enabled' if Imlib2::Image::bypass_draw_pixel?
VALUE image_dp_workaround(VALUE klass) {
UNUSED(klass);
return draw_pixel_workaround ? Qtrue : Qfalse;
}
Are we using the buggy imlib_image_draw_pixel() work-around?
Versions of Imlib2 up to and including 1.0.5 had a broken imlib_image_draw_pixel() call. Imlib2-Ruby has a work-around, which simulates drawing a pixel with a 1x1 rectangle. This method allows you to check whether the work-around behavior is enabled.
Examples:
puts 'work-around is enabled' if Imlib2::Image::draw_pixel_workaround? puts 'work-around is enabled' if Imlib2::Image::bypass_draw_pixel?
VALUE image_dp_workaround(VALUE klass) {
UNUSED(klass);
return draw_pixel_workaround ? Qtrue : Qfalse;
}
Load an Imlib2::Image from a file (throws exceptions).
Examples:
image = Imlib2::Image.load 'sample_file.png' begin image = Imlib2::Image.load 'sample_file.png' rescue Imlib2::FileError $stderr.puts 'Couldn't load file: ' + $! end
static VALUE image_load(VALUE klass, VALUE filename) {
ImStruct *im;
Imlib_Image iim;
Imlib_Load_Error err;
VALUE im_o = Qnil;
char *path;
/* grab filename */
path = StringValuePtr(filename);
iim = imlib_load_image_with_error_return(path, &err);
if (err == IMLIB_LOAD_ERROR_NONE) {
im = malloc(sizeof(ImStruct));
im->im = iim;
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
if (rb_block_given_p())
rb_yield(im_o);
} else {
/* there was an error loading -- throw an exception if we weren't
* passed a block */
if (!rb_block_given_p())
raise_imlib_error(path, err);
}
return im_o;
}
Load an Imlib2::Image from a file (no exceptions or error).
Imlib2::Image::load_image() provides access to the low-level imlib_load_image() function. You probably want to use Imlib2::Image::load() instead of Imlib2::Image::load_image().
Examples:
image = Imlib2::Image.load_image 'sample_file.png'
static VALUE image_load_image(VALUE klass, VALUE filename) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_load_image(StringValuePtr(filename));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
return im_o;
}
Load an Imlib2::Image from a file (no exceptions or error).
Imlib2::Image::load_immediately() provides access to the low-level imlib_load_image_immediately() function. You probably want to use Imlib2::Image::load() instead of this function.
Examples:
image = Imlib2::Image.load_immediately 'sample_file.png'
static VALUE image_load_immediately(VALUE klass, VALUE filename) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_load_image_immediately(StringValuePtr(filename));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
return im_o;
}
Load an Imlib2::Image from a file (no caching, deferred loading, exceptions, or errors).
Imlib2::Image::load_immediately_without_cache() provides access to the low-level imlib_load_image_immediately_without_cache() function. You probably want to use Imlib2::Image::load() instead of this function.
Examples:
image = Imlib2::Image.load_immediately_without_cache 'sample_file.png'
static VALUE image_load_immediately_without_cache(VALUE klass, VALUE filename) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_load_image_immediately_without_cache(StringValuePtr(filename));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
return im_o;
}
Load an Imlib2::Image from a file with a hash of the error value and the image.
Imlib2::Image::load_with_error_return() provides access to the low-level imlib_load_image_with_error_return() function. You probably want to use Imlib2::Image::load() instead of this function.
Examples:
hash = Imlib2::Image.load_with_error_return 'sample_file.png' if hash['error'] == 0 # 0 is no error image = hash['image'] end
static VALUE image_load_with_error_return(VALUE klass, VALUE filename) {
ImStruct *im = malloc(sizeof(ImStruct));
Imlib_Load_Error er;
VALUE hash, im_o;
im->im = imlib_load_image_with_error_return(StringValuePtr(filename), &er);
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("image"), im_o);
rb_hash_aset(hash, rb_str_new2("error"), INT2FIX(er));
return hash;
}
Load an Imlib2::Image from a file (no caching, exception, or error).
Imlib2::Image::load_without_cache() provides access to the low-level imlib_load_image_without_cache() function. You probably want to use Imlib2::Image::load() instead of this function.
Examples:
image = Imlib2::Image.load_without_cache 'sample_file.png'
static VALUE image_load_without_cache(VALUE klass, VALUE filename) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_load_image_without_cache(StringValuePtr(filename));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
return im_o;
}
Returns a new Imlib2::Image with the specified width and height.
Examples:
width, height = 640, 480 image = Imlib2::Image.new width, height width, height = 320, 240 image = Imlib2::Image.create width, height
VALUE image_new(VALUE klass, VALUE w, VALUE h) {
ImStruct *im = malloc(sizeof(ImStruct));
VALUE im_o;
im->im = imlib_create_image(NUM2INT(w), NUM2INT(h));
im_o = Data_Wrap_Struct(klass, 0, im_struct_free, im);
rb_obj_call_init(im_o, 0, NULL);
return im_o;
}
Get an integer value attached to an Imlib2::Image.
Examples:
qual = image.get_attached_value('quality')
qual = image['quality']
static VALUE image_get_attach_val(VALUE self, VALUE key_o) {
ImStruct *im;
VALUE ret;
char *key;
/* char *data; */
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
key = StringValuePtr(key_o);
/* if it's got data, retrn that, otherwise return the value */
/*
* if ((data = (char*) imlib_image_get_attached_value(key)) != NULL) {
* fprintf(stderr, "it's a string \"%s\": %x\n", key, data);
* ret = rb_str_new2(data);
* } else {
* fprintf(stderr, "it's an integer \"%s\"\n", key);
*/
ret = INT2FIX(imlib_image_get_attached_value(key));
/*
* }
*/
/* return result */
return ret;
}
Attach an integer value to an Imlib2::Image.
Examples:
image.attach_value('quality', 90)
image['quality'] = 90
static VALUE image_attach_val(VALUE self, VALUE key_o, VALUE val_o) {
ImStruct *im;
char *key;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
key = StringValuePtr(key_o);
/* if (rb_obj_is_kind_of(val_o, rb_cString)) {
void *val = (void*) StringValuePtr(val_o);
fprintf(stderr, "attaching string\n");
imlib_image_attach_data_value(key, val, 0, NULL);
} else */ if (rb_obj_is_kind_of(val_o, rb_cNumeric)) {
int val = NUM2INT(val_o);
imlib_image_attach_data_value(key, NULL, val, NULL);
} else {
rb_raise(rb_eTypeError, "Invalid argument (not string or integer)");
}
/* return value */
return val_o;
}
Apply an Imlib2::ColorModifier to the image
Examples:
# modify the contrast of the entire image cmod = Imlib2::ColorModifier.new cmod.contrast = 1.5 image.apply_cmod color_mod # adjust the gamma of the given rect cmod = Imlib2::ColorModifier.new cmod.gamma = 0.5 rect = [10, 10, 20, 40] image.apply_color_modifier cmod, rect
static VALUE image_apply_cmod(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Modifier *cmod;
char whole_image = 0;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
whole_image = 1;
break;
case 2:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 5:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Modifier, cmod);
imlib_context_set_color_modifier(*cmod);
if (whole_image)
imlib_apply_color_modifier();
else
imlib_apply_color_modifier_to_rectangle(x, y, w, h);
return self;
}
Apply an Imlib2::ColorModifier to the image
Examples:
# modify the contrast of the entire image cmod = Imlib2::ColorModifier.new cmod.contrast = 1.5 image.apply_cmod color_mod # adjust the gamma of the given rect cmod = Imlib2::ColorModifier.new cmod.gamma = 0.5 rect = [10, 10, 20, 40] image.apply_color_modifier cmod, rect
static VALUE image_apply_cmod(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Modifier *cmod;
char whole_image = 0;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
whole_image = 1;
break;
case 2:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 5:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Modifier, cmod);
imlib_context_set_color_modifier(*cmod);
if (whole_image)
imlib_apply_color_modifier();
else
imlib_apply_color_modifier_to_rectangle(x, y, w, h);
return self;
}
Apply an Imlib2::ColorModifier to the image
Examples:
# modify the contrast of the entire image cmod = Imlib2::ColorModifier.new cmod.contrast = 1.5 image.apply_cmod color_mod # adjust the gamma of the given rect cmod = Imlib2::ColorModifier.new cmod.gamma = 0.5 rect = [10, 10, 20, 40] image.apply_color_modifier cmod, rect
static VALUE image_apply_cmod(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Modifier *cmod;
char whole_image = 0;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
whole_image = 1;
break;
case 2:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 5:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Modifier, cmod);
imlib_context_set_color_modifier(*cmod);
if (whole_image)
imlib_apply_color_modifier();
else
imlib_apply_color_modifier_to_rectangle(x, y, w, h);
return self;
}
Apply a scripted filter or a static (eg Imlib2::Filter) filter
Example:
# apply a static filter
filter = Imlib2::Filter.new 20
filter.set 2, 2, Imlib2::Color::GREEN
image.filter filter
# apply a scripted filter
x, y = 20, 10
filter_string = "tint( x=#{x}, y=#{y}, red=255, alpha=55 );"
image.filter filter_string
static VALUE image_filter(VALUE self, VALUE filter) {
if (rb_obj_is_kind_of(self, rb_cString) == Qtrue) {
return image_static_filter(self, filter);
} else if (rb_obj_is_kind_of(self, cFilter) == Qtrue) {
return image_script_filter(self, filter);
} else {
rb_raise(rb_eTypeError, "Invalid argument type "
"(not String or Imlib2::Filter)");
}
return self;
}
Attach an integer value to an Imlib2::Image.
Examples:
image.attach_value('quality', 90)
image['quality'] = 90
static VALUE image_attach_val(VALUE self, VALUE key_o, VALUE val_o) {
ImStruct *im;
char *key;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
key = StringValuePtr(key_o);
/* if (rb_obj_is_kind_of(val_o, rb_cString)) {
void *val = (void*) StringValuePtr(val_o);
fprintf(stderr, "attaching string\n");
imlib_image_attach_data_value(key, val, 0, NULL);
} else */ if (rb_obj_is_kind_of(val_o, rb_cNumeric)) {
int val = NUM2INT(val_o);
imlib_image_attach_data_value(key, NULL, val, NULL);
} else {
rb_raise(rb_eTypeError, "Invalid argument (not string or integer)");
}
/* return value */
return val_o;
}
Return a copy of the image with the a portion of the source image blended at the specified rectangle.
Examples:
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend source_image, src_rect, dst_rect, merge_alpha
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend_image source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend_image source_image, src_rect, dst_rect, merge_alpha
static VALUE image_blend_image(int argc, VALUE *argv, VALUE self) {
ImStruct *im, *new_im;
VALUE i_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
i_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return image_blend_image_inline(argc, argv, i_o);
}
Blend a source image onto the image
Examples:
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend! source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend! source_image, src_rect, dst_rect, merge_alpha
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend_image! source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend_image! source_image, src_rect, dst_rect, merge_alpha
static VALUE image_blend_image_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im, *src_im;
int i, s[4], d[4];
char merge_alpha = 1;
switch (argc) {
case 4:
/* four arguments is source image, an array or hash of
* [sx, sy, sw, sh], an array or hash of [sx, sy, sw, sh], and
* merge_alpha */
merge_alpha = (argv[3] == Qtrue) ? 1 : 0;
case 3:
/* three arguments is source image, an array or hash of
* [sx, sy, sw, sh], and an array or hash of [sx, sy, sw, sh],
* with merge_alpha defaulting to true */
switch (TYPE(argv[1])) {
case T_HASH:
s[0] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
s[1] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
s[2] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
s[3] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 4; i++)
s[i] = NUM2INT(rb_ary_entry(argv[1], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
d[0] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("x")));
d[1] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("y")));
d[2] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
d[3] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 4; i++)
d[i] = NUM2INT(rb_ary_entry(argv[2], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
/* six arguments is source image, an array or hash of [sx, sy], an
* array or hash of [sw, sh], an array or hash of [dx, dy], an
* array or hash of [dw, dh], and merge_alpha */
merge_alpha = (argv[5] == Qtrue) ? 1 : 0;
case 5:
/* five arguments is source image, an array or hash of [sx, sy], an
* array or hash of [sw, sh], an array or hash of [dx, dy], and an
* array or hash of [dw, dh], with merge_alpha defaulting to true */
switch (TYPE(argv[1])) {
case T_HASH:
s[0] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
s[1] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
s[i] = NUM2INT(rb_ary_entry(argv[1], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
s[2] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("s")));
s[3] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
s[i + 2] = NUM2INT(rb_ary_entry(argv[2], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[3])) {
case T_HASH:
d[0] = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("x")));
d[1] = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("y")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
d[i] = NUM2INT(rb_ary_entry(argv[3], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[4])) {
case T_HASH:
d[2] = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("s")));
d[3] = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
d[i + 2] = NUM2INT(rb_ary_entry(argv[4], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 10:
/* ten arguments is source image, sx, sy, sw, sh, dx, dy, dw, dh,
* and merge_alpha */
merge_alpha = (argv[9] == Qtrue) ? 1 : 0;
case 9:
/* ten arguments is source image, sx, sy, sw, sh, dx, dy, dw, and
* dh, with merge_alpha defaulting to true */
for (i = 0; i < 4; i++)
s[i] = NUM2INT(argv[i + 1]);
for (i = 0; i < 4; i++)
d[i] = NUM2INT(argv[i + 5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count "
"(not 3, 4, 5, 6, 9, or 10)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
GET_AND_CHECK_IMAGE(argv[0], src_im);
imlib_blend_image_onto_image(src_im->im, merge_alpha,
s[0], s[1], s[2], s[3],
d[0], d[1], d[2], d[3]);
return self;
}
Return a copy of the image with the a portion of the source image blended at the specified rectangle.
Examples:
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend source_image, src_rect, dst_rect, merge_alpha
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend_image source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend_image source_image, src_rect, dst_rect, merge_alpha
static VALUE image_blend_image(int argc, VALUE *argv, VALUE self) {
ImStruct *im, *new_im;
VALUE i_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
i_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return image_blend_image_inline(argc, argv, i_o);
}
Blend a source image onto the image
Examples:
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend! source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend! source_image, src_rect, dst_rect, merge_alpha
src_x, src_y, src_w, src_h = 10, 10, 100, 100
dst_x, dst_y, dst_w, dst_h = 10, 10, 50, 50
image.blend_image! source_image,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h
src_rect = [50, 50, 5, 5]
dst_rect = [0, 0, image.width, image.height]
merge_alpha = false
image.blend_image! source_image, src_rect, dst_rect, merge_alpha
static VALUE image_blend_image_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im, *src_im;
int i, s[4], d[4];
char merge_alpha = 1;
switch (argc) {
case 4:
/* four arguments is source image, an array or hash of
* [sx, sy, sw, sh], an array or hash of [sx, sy, sw, sh], and
* merge_alpha */
merge_alpha = (argv[3] == Qtrue) ? 1 : 0;
case 3:
/* three arguments is source image, an array or hash of
* [sx, sy, sw, sh], and an array or hash of [sx, sy, sw, sh],
* with merge_alpha defaulting to true */
switch (TYPE(argv[1])) {
case T_HASH:
s[0] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
s[1] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
s[2] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
s[3] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 4; i++)
s[i] = NUM2INT(rb_ary_entry(argv[1], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
d[0] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("x")));
d[1] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("y")));
d[2] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
d[3] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 4; i++)
d[i] = NUM2INT(rb_ary_entry(argv[2], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
/* six arguments is source image, an array or hash of [sx, sy], an
* array or hash of [sw, sh], an array or hash of [dx, dy], an
* array or hash of [dw, dh], and merge_alpha */
merge_alpha = (argv[5] == Qtrue) ? 1 : 0;
case 5:
/* five arguments is source image, an array or hash of [sx, sy], an
* array or hash of [sw, sh], an array or hash of [dx, dy], and an
* array or hash of [dw, dh], with merge_alpha defaulting to true */
switch (TYPE(argv[1])) {
case T_HASH:
s[0] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
s[1] = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
s[i] = NUM2INT(rb_ary_entry(argv[1], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
s[2] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("s")));
s[3] = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
s[i + 2] = NUM2INT(rb_ary_entry(argv[2], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[3])) {
case T_HASH:
d[0] = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("x")));
d[1] = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("y")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
d[i] = NUM2INT(rb_ary_entry(argv[3], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[4])) {
case T_HASH:
d[2] = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("s")));
d[3] = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("h")));
break;
case T_ARRAY:
for (i = 0; i < 2; i++)
d[i + 2] = NUM2INT(rb_ary_entry(argv[4], i));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 10:
/* ten arguments is source image, sx, sy, sw, sh, dx, dy, dw, dh,
* and merge_alpha */
merge_alpha = (argv[9] == Qtrue) ? 1 : 0;
case 9:
/* ten arguments is source image, sx, sy, sw, sh, dx, dy, dw, and
* dh, with merge_alpha defaulting to true */
for (i = 0; i < 4; i++)
s[i] = NUM2INT(argv[i + 1]);
for (i = 0; i < 4; i++)
d[i] = NUM2INT(argv[i + 5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count "
"(not 3, 4, 5, 6, 9, or 10)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
GET_AND_CHECK_IMAGE(argv[0], src_im);
imlib_blend_image_onto_image(src_im->im, merge_alpha,
s[0], s[1], s[2], s[3],
d[0], d[1], d[2], d[3]);
return self;
}
Return a blurred copy of an image
Examples:
radius = 20 # radius of blur, in pixels new_image = old_image.blur radius
static VALUE image_blur(VALUE self, VALUE val) {
ImStruct *im, *new_im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
imlib_context_set_image(new_im->im);
imlib_image_blur(NUM2INT(val));
return Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
}
Blur an image
Examples:
radius = 20 # radius of blur, in pixels image.blur! radius
static VALUE image_blur_inline(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_blur(NUM2INT(val));
return self;
}
Get the Imlib2::Border of an Imlib2::Image
Examples:
border = image.get_border border = image.border
static VALUE image_get_border(VALUE self) {
ImStruct *im;
Imlib_Border *border;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
border = malloc(sizeof(Imlib_Border));
imlib_image_get_border(border);
argv[0] = INT2NUM(border->left);
argv[1] = INT2NUM(border->top);
argv[2] = INT2NUM(border->right);
argv[3] = INT2NUM(border->bottom);
free(border);
return border_new(4, argv, cBorder);
}
Set the Imlib2::Border of an Imlib2::Image
Examples:
image.set_border border image.border = border
static VALUE image_set_border(VALUE self, VALUE border) {
ImStruct *im;
Imlib_Border *b;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(border, Imlib_Border, b);
imlib_image_set_border(b);
return border;
}
Flag this image as changing on disk
Examples:
image.changes_on_disk
static VALUE image_changes_on_disk(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_changes_on_disk();
return Qtrue;
}
Clear the contents of an image
Examples:
image.clear
static VALUE image_clear(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_clear();
return self;
}
I'm honestly not quite sure what this function does, but I wrapped it anyway.
static VALUE image_clear_color(VALUE self, VALUE rgba_color) {
ImStruct *im, *new_im;
Imlib_Color *color;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
imlib_context_set_image(new_im->im);
Data_Get_Struct(rgba_color, Imlib_Color, color);
imlib_image_clear_color(color->red, color->blue, color->green, color->alpha);
return Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
}
I'm honestly not quite sure what this function does, but I wrapped it anyway.
static VALUE image_clear_color_inline(VALUE self, VALUE rgba_color) {
ImStruct *im;
Imlib_Color *color;
GET_AND_CHECK_IMAGE(self, im);
Data_Get_Struct(rgba_color, Imlib_Color, color);
imlib_context_set_image(im->im);
imlib_image_clear_color(color->red, color->blue, color->green, color->alpha);
return self;
}
Copy an Imlib2::Image
Examples:
new_image = old_image.clone new_image = old_image.dup
static VALUE image_clone(VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
new_im = malloc(sizeof(ImStruct));
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Fill a rectangle with the given Imlib2::Gradient at a given angle
Examples:
x, y, w, h = 10, 10, image.width - 20, image.height - 20 angle = 45.2 image.fill_gradient gradient, x, y, w, h, angle rect = [5, 5, 500, 20] image.gradient gradient, rect, 36.8
static VALUE image_fill_gradient(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Range *grad;
int x, y, w, h;
double angle;
switch (argc) {
case 3:
/* three arguments is a gradient, an array or hash of [x,y,w,h],
* and an angle */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[2]);
break;
case 4:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[3]);
break;
case 6:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
angle = NUM2DBL(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Range, grad);
imlib_context_set_color_range(*grad);
imlib_image_fill_color_range_rectangle(x, y, w, h, angle);
return self;
}
Copy the alpha channel from the source image to the specified coordinates
Examples:
image.copy_alpha source_image, 10, 10 image.copy_alpha source_image, [10, 10]
static VALUE image_copy_alpha(int argc, VALUE *argv, VALUE self) {
ImStruct *src_im, *im;
VALUE src;
int x, y;
src = argv[0];
switch (argc) {
case 2:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 2 or 3)");
}
GET_AND_CHECK_IMAGE(src, src_im);
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_copy_alpha_to_image(src_im->im, x, y);
return self;
}
Copy the alpha channel from a rectangle of the source image to the specified coordinates
Examples:
x, y, w, h = 10, 20, 100, 200 dest_x, dest_y = 5, 10 image.copy_alpha_rect source_image, x, y, w, h, dest_x, dest_y source_rect = [10, 20, 100, 200] dest_coords = [5, 10] image.copy_alpha_rect source_image, source_rect, dest_coords values = [10, 20, 100, 200, 5, 10] image.copy_alpha_rect source_image, values
static VALUE image_copy_alpha_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *src_im, *im;
VALUE src;
int x, y, w, h, dx, dy;
x = y = w = h = dx = dy = 0;
src = argv[0];
switch (argc) {
case 2:
/* 2 arguments is a source image and an array or hash of
* x, y, w, h, dx, dy */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
dx = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dy")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
dx = NUM2INT(rb_ary_entry(argv[1], 4));
dy = NUM2INT(rb_ary_entry(argv[1], 5));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is a source image, an array or hash of x,y,w,h,
* and an array or hash of dx, dy */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[1], 0));
dy = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 4:
/* four arguments is a source image, an array or hash of [x, y],
* an array or hash of [w, h], and an array or hash of [dx, dy],
* or a source image, an array or hash of [x, y, w, h], dx, dy */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
switch (TYPE(argv[3])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[3], 0));
dy = NUM2INT(rb_ary_entry(argv[3], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
switch (TYPE(argv[3])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[3], 0));
dy = NUM2INT(rb_ary_entry(argv[3], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
dx = NUM2INT(argv[2]);
dy = NUM2INT(argv[3]);
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
switch (TYPE(argv[3])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[3], 0));
dy = NUM2INT(rb_ary_entry(argv[3], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
switch (TYPE(argv[3])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[3], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[3], 0));
dy = NUM2INT(rb_ary_entry(argv[3], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
dx = NUM2INT(argv[2]);
dy = NUM2INT(argv[3]);
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 5:
/* five arguments is a source image, an array or hash of [x, y],
* an array or hash of [w, h], dx, dy */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
dx = NUM2INT(argv[3]);
dy = NUM2INT(argv[4]);
case 6:
/* six arguments is a source image, x, y, w, h, and an array or
* hash of [dx, dy], or source image, an array or hash of [x, y],
* an array or hash of [w, h], dx, dy */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
}
break;
case 7:
/* seven arguments is a source image, x, y, w, y, dx, dy */
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
dx = NUM2INT(argv[5]);
dy = NUM2INT(argv[6]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count "
"(not 2, 3, 4, 5, 6, or 7)");
}
GET_AND_CHECK_IMAGE(src, src_im);
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_copy_alpha_rectangle_to_image(src_im->im, x, y, w, h, dx, dy);
return self;
}
Copy a rectangle to the specified coordinates
Examples:
x, y, w, h = 10, 20, 100, 200 dest_x, dest_y = 5, 10 image.copy_rect x, y, w, h, dest_x, dest_y source_rect = [10, 20, 100, 200] dest_coords = [5, 10] image.copy_rect source_rect, dest_coords values = [10, 20, 100, 200, 5, 10] image.copy_rect values
static VALUE image_copy_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
int x, y, w, h, dx, dy;
switch (argc) {
case 1:
/* one argument is an array or hash of [x, y, w, h, dx, dy] */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dx = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dy")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dx = NUM2INT(rb_ary_entry(argv[0], 4));
dy = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of [x, y, w, h] and an array
* or hash of [dx, dy] */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[1], 0));
dy = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of [x, y], an array or hash
* of [w, h] and an array or hash of [dx, dy], or an array or hash
* of [x, y, w, h], dx, dy */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dx = NUM2INT(argv[1]);
dy = NUM2INT(argv[2]);
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dx = NUM2INT(argv[1]);
dy = NUM2INT(argv[2]);
}
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 4:
/* four arguments is an array or hash of [x, y], an array or hash
* of [w, h], dx, dy */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
dx = NUM2INT(argv[2]);
dy = NUM2INT(argv[3]);
break;
case 5:
/* five arguments is x, y, w, h, and an array or hash of
* [dx, dy] */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
switch (TYPE(argv[4])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[4], 0));
dy = NUM2INT(rb_ary_entry(argv[4], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 6:
/* six arguments is x, y, w, h, dx, dy */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dx = NUM2INT(argv[4]);
dy = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count "
"(not 2, 3, 4, 5, 6, or 7)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_copy_rect(x, y, w, h, dx, dy);
return self;
}
Return a cropped copy of the image
Examples:
x, y, w, h = 10, 10, old_image.width - 10, old_image.height - 10 new_image = old_image.crop x, y, w, h rect = [10, 10, old_image.width - 10, old_image.height - 10] new_image = old_image.crop rect x, y, w, h = 10, 10, old_image.width - 10, old_image.height - 10 new_image = old_image.create_cropped x, y, w, h rect = [10, 10, old_image.width - 10, old_image.height - 10] new_image = old_image.create_cropped rect
static VALUE image_crop(int argc, VALUE *argv, VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
int x = 0, y = 0, w = 0, h = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 4:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 4)");
}
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_create_cropped_image(x, y, w, h);
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Crop an image
Examples:
x, y, w, h = 10, 10, image.width - 10, image.height - 10 image.crop! x, y, w, h rect = [10, 10, image.width - 10, image.height - 10] image.crop! rect x, y, w, h = 10, 10, image.width - 10, image.height - 10 image.create_cropped! x, y, w, h rect = [10, 10, image.width - 10, image.height - 10] image.create_cropped! rect
static VALUE image_crop_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Image old_im;
int x = 0, y = 0, w = 0, h = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 4:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 4)");
}
GET_AND_CHECK_IMAGE(self, im);
old_im = im->im;
imlib_context_set_image(old_im);
im->im = imlib_create_cropped_image(x, y, w, h);
imlib_context_set_image(old_im);
imlib_free_image();
return self;
}
Create a cropped and scaled copy of an image
Examples:
iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 new_image = old_image.crop_scaled x, y, w, h, new_w, new_h iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] new_image = old_image.crop_scaled values iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 new_image = old_image.create_crop_scaled x, y, w, h, new_w, new_h iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] new_image = old_image.create_crop_scaled values
static VALUE image_crop_scaled(int argc, VALUE *argv, VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dw = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dw")));
dh = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dh")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dw = NUM2INT(rb_ary_entry(argv[0], 4));
dh = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dw = NUM2INT(argv[4]);
dh = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 6)");
}
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_create_cropped_scaled_image(x, y, w, h, dw, dh);
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Crop and scale an image
Examples:
iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 image.crop_scaled! x, y, w, h, new_w, new_h iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] image.crop_scaled! values iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 image.create_crop_scaled! x, y, w, h, new_w, new_h iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] image.create_crop_scaled! values
static VALUE image_crop_scaled_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Image old_im;
int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dw = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dw")));
dh = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dh")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dw = NUM2INT(rb_ary_entry(argv[0], 4));
dh = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dw = NUM2INT(argv[4]);
dh = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
old_im = im->im;
imlib_context_set_image(old_im);
im->im = imlib_create_cropped_scaled_image(x, y, w, h, dw, dh);
imlib_context_set_image(old_im);
imlib_free_image();
return self;
}
Return a cropped copy of the image
Examples:
x, y, w, h = 10, 10, old_image.width - 10, old_image.height - 10 new_image = old_image.crop x, y, w, h rect = [10, 10, old_image.width - 10, old_image.height - 10] new_image = old_image.crop rect x, y, w, h = 10, 10, old_image.width - 10, old_image.height - 10 new_image = old_image.create_cropped x, y, w, h rect = [10, 10, old_image.width - 10, old_image.height - 10] new_image = old_image.create_cropped rect
static VALUE image_crop(int argc, VALUE *argv, VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
int x = 0, y = 0, w = 0, h = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 4:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 4)");
}
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_create_cropped_image(x, y, w, h);
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Crop an image
Examples:
x, y, w, h = 10, 10, image.width - 10, image.height - 10 image.crop! x, y, w, h rect = [10, 10, image.width - 10, image.height - 10] image.crop! rect x, y, w, h = 10, 10, image.width - 10, image.height - 10 image.create_cropped! x, y, w, h rect = [10, 10, image.width - 10, image.height - 10] image.create_cropped! rect
static VALUE image_crop_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Image old_im;
int x = 0, y = 0, w = 0, h = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 4:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 4)");
}
GET_AND_CHECK_IMAGE(self, im);
old_im = im->im;
imlib_context_set_image(old_im);
im->im = imlib_create_cropped_image(x, y, w, h);
imlib_context_set_image(old_im);
imlib_free_image();
return self;
}
Create a cropped and scaled copy of an image
Examples:
iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 new_image = old_image.crop_scaled x, y, w, h, new_w, new_h iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] new_image = old_image.crop_scaled values iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 new_image = old_image.create_crop_scaled x, y, w, h, new_w, new_h iw, ih = old_image.width, old_image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] new_image = old_image.create_crop_scaled values
static VALUE image_crop_scaled(int argc, VALUE *argv, VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dw = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dw")));
dh = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dh")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dw = NUM2INT(rb_ary_entry(argv[0], 4));
dh = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dw = NUM2INT(argv[4]);
dh = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 6)");
}
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_create_cropped_scaled_image(x, y, w, h, dw, dh);
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Crop and scale an image
Examples:
iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 image.crop_scaled! x, y, w, h, new_w, new_h iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] image.crop_scaled! values iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 x, y, w, h = 10, 10, iw - 10, ih - 10 image.create_crop_scaled! x, y, w, h, new_w, new_h iw, ih = image.width, image.height new_w, new_h = iw - 20, ih - 20 values = [10, 10, iw - 10, iw - 10, new_w, new_h] image.create_crop_scaled! values
static VALUE image_crop_scaled_inline(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Image old_im;
int x = 0, y = 0, w = 0, h = 0, dw = 0, dh = 0;
switch (argc) {
case 1:
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dw = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dw")));
dh = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dh")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dw = NUM2INT(rb_ary_entry(argv[0], 4));
dh = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 6:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dw = NUM2INT(argv[4]);
dh = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1 or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
old_im = im->im;
imlib_context_set_image(old_im);
im->im = imlib_create_cropped_scaled_image(x, y, w, h, dw, dh);
imlib_context_set_image(old_im);
imlib_free_image();
return self;
}
Return a copy of an image's raw 32-bit data.
Examples:
raw = image.data
static VALUE image_data(VALUE self) {
ImStruct *im;
int w, h;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
w = imlib_image_get_width();
h = imlib_image_get_height();
return rb_str_new((char*) imlib_image_get_data(), h * w * 4);
}
Return a read-only reference to an image's raw 32-bit data.
Examples:
RAW_DATA = image.data_for_reading_only RAW_DATA = image.data!
static VALUE image_data_ro(VALUE self) {
ImStruct *im;
int w, h;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
w = imlib_image_get_width();
h = imlib_image_get_height();
return rb_str_new((char*) imlib_image_get_data_for_reading_only(), h * w * 4);
}
Fill an image using raw 32-bit data.
Note: The new data buffer must be the same size (in bytes) as the original data buffer.
Examples:
RAW_DATA = other_image.data! image.put_data RAW_DATA RAW_DATA = other_image.data! image.data = RAW_DATA
static VALUE image_put_data(VALUE self, VALUE str) {
ImStruct *im;
DATA32 *old_data, *new_data;
int w, h, old_size;
/* get image, check it, then set the context */
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
/* get old data, calculate buffer size from width and height */
old_data = imlib_image_get_data();
w = imlib_image_get_width();
h = imlib_image_get_height();
old_size = w * h * 4;
/* get new data, check size of buffer */
new_data = (DATA32*) StringValuePtr(str);
/* check size of new buffer */
if (RSTRING_LEN(str) != old_size)
rb_raise(rb_eArgError, "invalid buffer size");
/* copy new data to old address */
if (old_data != new_data)
memcpy(old_data, new_data, old_size);
/* actual put_back_data() call */
imlib_image_put_back_data(old_data);
/* return success */
return Qtrue;
}
Return a read-only reference to an image's raw 32-bit data.
Examples:
RAW_DATA = image.data_for_reading_only RAW_DATA = image.data!
static VALUE image_data_ro(VALUE self) {
ImStruct *im;
int w, h;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
w = imlib_image_get_width();
h = imlib_image_get_height();
return rb_str_new((char*) imlib_image_get_data_for_reading_only(), h * w * 4);
}
Free an Imlib2::Image object, and (optionally) de-cache it as well.
Note: Any future operations on this image will raise an exception.
Examples:
# free image im.delete! # free image, and de-cache it too im.delete!(true)
static VALUE image_delete(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
/* get image */
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
/* free image, and possibly de-cache it as well */
if (argc > 0 && argv[0] != Qnil && argv[0] != Qfalse)
imlib_free_image_and_decache();
else
imlib_free_image();
/* set struct ptr to NULL */
im->im = NULL;
return Qnil;
}
Draw an ellipse at the specified coordinates with the given color
Examples:
# draw an ellipse in the center of the image using the context color xc, yc, w, h = image.w / 2, image.h / 2, image.w / 2, image.h / 2 image.draw_oval xc, yc, w, h # draw a violet circle in the center of the image rect = [image.w / 2, image.h / 2, image.w / 2, image.w / 2] color = Imlib2::Color::VIOLET image.draw_ellipse rect, color
static VALUE image_draw_ellipse(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_draw_ellipse(x, y, w, h);
return self;
}
Draw a line at the specified coordinates.
Examples:
# draw line from 10, 10 to 20, 20 using context color im.draw_line 10, 10, 20, 20 # draw magenta line from 5, 10 to 15, 20 im.draw_line 5, 10, 15, 20, Imlib2::Color::MAGENTA # draw line from 10, 15 to 20, 25 using context color im.draw_pixel [10, 15], [20, 25] # draw line from 1000, 2000 to 2100, 4200 with funky color my_color = Imlib2::Color::CmykColor.new 100, 255, 0, 128 im.draw_line [1000, 2000], [2100, 4200], my_color
static VALUE image_draw_line(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int i = 0, x[2] = {0, 0}, y[2] = {0, 0};
switch (argc) {
case 2:
/* two arguments is an array or hash of points, with color
* defaulting to Qnil (ie, the context color) */
for (i = 0; i < 2; i++) {
switch (TYPE(argv[i])) {
case T_HASH:
x[i] = NUM2INT(rb_hash_aref(argv[i], rb_str_new2("x")));
y[i] = NUM2INT(rb_hash_aref(argv[i], rb_str_new2("y")));
break;
case T_ARRAY:
x[i] = NUM2INT(rb_ary_entry(argv[i], 0));
y[i] = NUM2INT(rb_ary_entry(argv[i], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
}
break;
case 3:
/* three arguments is two arrays or hashes of points and a color
* */
for (i = 0; i < 2; i++) {
switch (TYPE(argv[i])) {
case T_HASH:
x[i] = NUM2INT(rb_hash_aref(argv[i], rb_str_new2("x")));
y[i] = NUM2INT(rb_hash_aref(argv[i], rb_str_new2("y")));
break;
case T_ARRAY:
x[i] = NUM2INT(rb_ary_entry(argv[i], 0));
y[i] = NUM2INT(rb_ary_entry(argv[i], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
}
color = argv[2];
break;
case 5:
/* 5 arguments is 4 fixnum points and a color value */
color = argv[4];
/* pass-through */
case 4:
x[0] = NUM2INT(argv[0]);
y[0] = NUM2INT(argv[1]);
x[1] = NUM2INT(argv[2]);
y[1] = NUM2INT(argv[3]);
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
(void) imlib_image_draw_line(x[0], y[0], x[1], y[1], 0);
return self;
}
Draw an ellipse at the specified coordinates with the given color
Examples:
# draw an ellipse in the center of the image using the context color xc, yc, w, h = image.w / 2, image.h / 2, image.w / 2, image.h / 2 image.draw_oval xc, yc, w, h # draw a violet circle in the center of the image rect = [image.w / 2, image.h / 2, image.w / 2, image.w / 2] color = Imlib2::Color::VIOLET image.draw_ellipse rect, color
static VALUE image_draw_ellipse(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_draw_ellipse(x, y, w, h);
return self;
}
Draw a pixel at the specified coordinates.
Note: Versions of Imlib2 up to and including 1.0.5 had a broken imlib_image_draw_pixel() call. Imlib2-Ruby has a work-around, which simulates drawing a pixel with a 1x1 rectangle. To disable this behavior, see the Imlib2::Image::draw_pixel_workaround= method.
Examples:
im.draw_pixel 10, 10 # draw using context color im.draw_pixel 10, 10, Imlib2::Color::BLUE # draw blue pixel im.draw_pixel [10, 10], Imlib2::Color::RED # draw red pixel
static VALUE image_draw_pixel(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x = 0, y = 0;
int blend, aa;
switch (argc) {
case 1:
/* one argument is an array or hash of points, with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is either two fixnum points (with color
* defaulting to Qnil), or an array or hash of points and a color
* */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
color = argv[1];
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
color = argv[1];
break;
case T_FIXNUM:
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is two fixnum points and a color value */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
color = argv[2];
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1, 2, or 3)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
if (draw_pixel_workaround) {
/* use draw_pixel workaround */
/*********************************************************************/
/* WORKAROUND: workaround for borked Imlib2 imlib_image_draw_pixel() */
/*********************************************************************/
/* save context, then disable blending and aa */
blend = imlib_context_get_blend();
aa = imlib_context_get_anti_alias();
/* draw 1x1 rectangle */
imlib_image_draw_rectangle(x, y, 1, 1);
/* restore blend and aa context */
imlib_context_set_blend(blend);
imlib_context_set_anti_alias(aa);
} else {
/* use imlib_image_draw_pixel() (buggy for Imlib2 <= 1.0.5) */
(void) imlib_image_draw_pixel(x, y, 0);
}
return self;
}
Draw an Imlib2::Polygon with the specified color
Examples:
# create a simple blue right triangle triangle = Imlib2::Polygon.new [10, 10], [20, 20], [10, 20] image.draw_polygon triangle, Imlib2::Color::BLUE # create an open red square polygon square = Imlib2.Polygon.new [10, 10], [20, 10], [20, 20], [10, 20] image.draw_poly square, false, Imlib2::Color::RED
static VALUE image_draw_poly(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
ImlibPolygon *poly;
VALUE color = Qnil;
unsigned char closed = Qtrue;
switch (argc) {
case 1:
/* one argument is poly.. closed is default (Qtrue) */
break;
case 2:
/* two arguments is poly and closed, or poly and color */
if ((rb_obj_is_kind_of(argv[1], cRgbaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cHsvaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cHlsaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cCmyaColor) == Qtrue)) {
color = argv[1];
} else /* FIXME: do type check here */ {
closed = (argv[1] == Qtrue) ? 1 : 0;
}
break;
case 3:
/* two arguments is poly, closed, and color */
closed = (argv[1] == Qtrue) ? 1 : 0;
color = argv[2];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
Data_Get_Struct(argv[0], ImlibPolygon, poly);
imlib_image_draw_polygon(*poly, closed);
return self;
}
Draw an Imlib2::Polygon with the specified color
Examples:
# create a simple blue right triangle triangle = Imlib2::Polygon.new [10, 10], [20, 20], [10, 20] image.draw_polygon triangle, Imlib2::Color::BLUE # create an open red square polygon square = Imlib2.Polygon.new [10, 10], [20, 10], [20, 20], [10, 20] image.draw_poly square, false, Imlib2::Color::RED
static VALUE image_draw_poly(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
ImlibPolygon *poly;
VALUE color = Qnil;
unsigned char closed = Qtrue;
switch (argc) {
case 1:
/* one argument is poly.. closed is default (Qtrue) */
break;
case 2:
/* two arguments is poly and closed, or poly and color */
if ((rb_obj_is_kind_of(argv[1], cRgbaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cHsvaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cHlsaColor) == Qtrue) ||
(rb_obj_is_kind_of(argv[1], cCmyaColor) == Qtrue)) {
color = argv[1];
} else /* FIXME: do type check here */ {
closed = (argv[1] == Qtrue) ? 1 : 0;
}
break;
case 3:
/* two arguments is poly, closed, and color */
closed = (argv[1] == Qtrue) ? 1 : 0;
color = argv[2];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
Data_Get_Struct(argv[0], ImlibPolygon, poly);
imlib_image_draw_polygon(*poly, closed);
return self;
}
Draw a rectangle outline at the specified coordinates.
Examples:
# draw rectangle around edge of image using context color rect = [1, 1, im.width - 2, im.height - 2] im.draw_rect rect # draw magenta rectangle outline in top-left corner of image color = Imlib2::Color::MAGENTA im.draw_rect [0, 0], [im.width / 2, im.height / 2], color # draw square from 10, 10 to 30, 30 using context color im.draw_rect [10, 10, 20, 20]
static VALUE image_draw_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_draw_rectangle(x, y, w, h);
return self;
}
Draw a rectangle outline at the specified coordinates.
Examples:
# draw rectangle around edge of image using context color rect = [1, 1, im.width - 2, im.height - 2] im.draw_rect rect # draw magenta rectangle outline in top-left corner of image color = Imlib2::Color::MAGENTA im.draw_rect [0, 0], [im.width / 2, im.height / 2], color # draw square from 10, 10 to 30, 30 using context color im.draw_rect [10, 10, 20, 20]
static VALUE image_draw_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError,"Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_draw_rectangle(x, y, w, h);
return self;
}
Draw a string with the given Imlib2::Font at the specified coordinates
Examples:
font = Imlib2::Font.new 'helvetica/12'
string = 'the blue crow flies at midnight'
image.draw_text font, string, 10, 10
# draw text in a specified color
font = Imlib2::Font.new 'helvetica/12'
string = 'the blue crow flies at midnight'
color = Imlib2::Color::AQUA
image.draw_text font, string, 10, 10, color
# draw text in a specified direction
font = Imlib2::Font.new 'verdana/24'
string = 'the blue crow flies at midnight'
color = Imlib2::Color::YELLOW
direction = Imlib2::Direction::DOWN
image.draw_text font, string, 10, 10, color, direction
# draw text with return metrics
font = Imlib2::Font.new 'arial/36'
string = 'the blue crow flies at midnight'
color = Imlib2::Color::PURPLE
direction = Imlib2::Direction::LEFT
metrics = image.draw_text font, string, 10, 10, color, direction
['width', 'height', 'horiz_advance', 'vert_advance'].each_index { |i, v|
puts v << ' = ' << metrics[i]
}
static VALUE image_draw_text(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Font *font;
VALUE text, ary, color = Qnil, dir = Qnil;
int x, y, i, r[] = { 0, 0, 0, 0 }, old_dir = -1;
switch (argc) {
case 3:
/* three arguments is a font, a string, and an array or hash of
* x, y, with both color and direction defaulting to Qnil (the
* context values) */
switch (TYPE(argv[2])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[2], 0));
y = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 2 or 3)");
}
break;
case 4:
/* four arguments is a font, a string, x, y, with color and
* direction defaulting to Qnil, OR a font, a string, an array
* or hash of [x, y] and either a color or a direction */
switch (TYPE(argv[2])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("y")));
if (FIXNUM_P(argv[3]))
dir = argv[3];
else
color = argv[3];
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[2], 0));
y = NUM2INT(rb_ary_entry(argv[2], 1));
break;
if (FIXNUM_P(argv[3]))
dir = argv[3];
else
color = argv[3];
default:
x = NUM2INT(argv[2]);
y = NUM2INT(argv[3]);
}
break;
case 5:
/* five arguments is a font, a string, x, y, a color, OR a font, a
* string, an array or hash of [x, y], a color and a direction */
if (FIXNUM_P(argv[2])) {
x = NUM2INT(argv[2]);
y = NUM2INT(argv[3]);
color = argv[4];
} else {
switch (TYPE(argv[2])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[2], 0));
y = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not Array or Hash)");
}
color = argv[3];
dir = argv[4];
}
break;
case 6:
x = NUM2INT(argv[2]);
y = NUM2INT(argv[3]);
color = argv[4];
dir = argv[5];
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 5)");
}
Data_Get_Struct(argv[0], Imlib_Font, font);
GET_AND_CHECK_IMAGE(self, im);
text = argv[1];
imlib_context_set_font(*font);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
if (dir != Qnil) {
old_dir = imlib_context_get_direction();
imlib_context_set_direction(NUM2INT(dir));
}
imlib_text_draw_with_return_metrics(x, y, StringValuePtr(text),
&r[0], &r[1], &r[2], &r[3]);
if (dir != Qnil)
imlib_context_set_direction(old_dir);
ary = rb_ary_new();
for (i = 0; i < 4; i++)
rb_ary_push(ary, INT2FIX(r[i]));
return ary;
}
Copy an Imlib2::Image
Examples:
new_image = old_image.clone new_image = old_image.dup
static VALUE image_clone(VALUE self) {
ImStruct *old_im, *new_im;
VALUE im_o;
new_im = malloc(sizeof(ImStruct));
GET_AND_CHECK_IMAGE(self, old_im);
imlib_context_set_image(old_im->im);
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
return im_o;
}
Return the filename of an Imlib2::Image.
Examples:
path = image.filename
static VALUE image_filename(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return rb_str_new2(imlib_image_get_filename());
}
Fill a rectangle with the given Imlib2::Gradient at a given angle
Examples:
x, y, w, h = 10, 10, image.width - 20, image.height - 20 angle = 45.2 image.fill_gradient gradient, x, y, w, h, angle rect = [5, 5, 500, 20] image.gradient gradient, rect, 36.8
static VALUE image_fill_gradient(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Range *grad;
int x, y, w, h;
double angle;
switch (argc) {
case 3:
/* three arguments is a gradient, an array or hash of [x,y,w,h],
* and an angle */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[2]);
break;
case 4:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[3]);
break;
case 6:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
angle = NUM2DBL(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Range, grad);
imlib_context_set_color_range(*grad);
imlib_image_fill_color_range_rectangle(x, y, w, h, angle);
return self;
}
Fill an ellipse at the specified coordinates with the given color
Examples:
# fill an ellipse in the center of the image using the context color xc, yc, w, h = image.w / 2, image.h / 2, image.w / 2, image.h / 2 image.draw_oval xc, yc, w, h # fill a violet circle in the center of the image rect = [image.w / 2, image.h / 2, image.w / 2, image.w / 2] color = Imlib2::Color::VIOLET image.draw_ellipse rect, color
static VALUE image_fill_ellipse(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_fill_ellipse(x, y, w, h);
return self;
}
Fill a rectangle with the given Imlib2::Gradient at a given angle
Examples:
x, y, w, h = 10, 10, image.width - 20, image.height - 20 angle = 45.2 image.fill_gradient gradient, x, y, w, h, angle rect = [5, 5, 500, 20] image.gradient gradient, rect, 36.8
static VALUE image_fill_gradient(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Range *grad;
int x, y, w, h;
double angle;
switch (argc) {
case 3:
/* three arguments is a gradient, an array or hash of [x,y,w,h],
* and an angle */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[2]);
break;
case 4:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[3]);
break;
case 6:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
angle = NUM2DBL(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Range, grad);
imlib_context_set_color_range(*grad);
imlib_image_fill_color_range_rectangle(x, y, w, h, angle);
return self;
}
Fill an ellipse at the specified coordinates with the given color
Examples:
# fill an ellipse in the center of the image using the context color xc, yc, w, h = image.w / 2, image.h / 2, image.w / 2, image.h / 2 image.draw_oval xc, yc, w, h # fill a violet circle in the center of the image rect = [image.w / 2, image.h / 2, image.w / 2, image.w / 2] color = Imlib2::Color::VIOLET image.draw_ellipse rect, color
static VALUE image_fill_ellipse(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_fill_ellipse(x, y, w, h);
return self;
}
Fill an Imlib2::Polygon with the specified color
Examples:
# create an filled green diamond polygon square = Imlib2.Polygon.new [50, 10], [70, 30], [50, 50], [30, 30] image.fill_poly square, false, Imlib2::Color::GREEN
static VALUE image_fill_poly(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
ImlibPolygon *poly;
VALUE color = Qnil;
switch (argc) {
case 1:
/* one argument is poly.. closed is default (Qtrue) */
break;
case 2:
color = argv[1];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
Data_Get_Struct(argv[0], ImlibPolygon, poly);
imlib_image_fill_polygon(*poly);
return self;
}
Fill an Imlib2::Polygon with the specified color
Examples:
# create an filled green diamond polygon square = Imlib2.Polygon.new [50, 10], [70, 30], [50, 50], [30, 30] image.fill_poly square, false, Imlib2::Color::GREEN
static VALUE image_fill_poly(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
ImlibPolygon *poly;
VALUE color = Qnil;
switch (argc) {
case 1:
/* one argument is poly.. closed is default (Qtrue) */
break;
case 2:
color = argv[1];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
Data_Get_Struct(argv[0], ImlibPolygon, poly);
imlib_image_fill_polygon(*poly);
return self;
}
Fill a rectangle at the specified coordinates.
Examples:
# fill image using context color rect = [0, 0, im.width, im.height] im.fill_rect rect # fill top-left quarter of image with green color = Imlib2::Color::GREEN im.fill_rect [0, 0], [im.width / 2, im.height / 2], color # fill square from 10, 10 to 30, 30 using context color im.fill_rect [10, 10, 20, 20]
static VALUE image_fill_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_fill_rectangle(x, y, w, h);
return self;
}
Fill a rectangle at the specified coordinates.
Examples:
# fill image using context color rect = [0, 0, im.width, im.height] im.fill_rect rect # fill top-left quarter of image with green color = Imlib2::Color::GREEN im.fill_rect [0, 0], [im.width / 2, im.height / 2], color # fill square from 10, 10 to 30, 30 using context color im.fill_rect [10, 10, 20, 20]
static VALUE image_fill_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
VALUE color = Qnil;
int x, y, w, h;
x = y = w = h = 0;
switch (argc) {
case 1:
/* 1 argument is an array or hash of x, y, w, h with color
* defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of x, y, w, h with a color,
* or an array or hash of x, y, and an array or hash of w, h (with
* color defaulting to Qnil (ie, the context color) */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
/* we could do a type check here, but if it's invalid
* it'll get caught in the set_context_color() call */
color = argv[1];
}
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of x, y and a color */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
color = argv[2];
break;
case 4:
/* 4 arguments is x, y, w, y (color to Qnil) */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
break;
case 5:
/* 4 arguments is x, y, w, y, color */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
color = argv[4];
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 1, 2, 3, 4, or 5)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
if (color != Qnil)
set_context_color(color);
imlib_image_fill_rectangle(x, y, w, h);
return self;
}
Apply a scripted filter or a static (eg Imlib2::Filter) filter
Example:
# apply a static filter
filter = Imlib2::Filter.new 20
filter.set 2, 2, Imlib2::Color::GREEN
image.filter filter
# apply a scripted filter
x, y = 20, 10
filter_string = "tint( x=#{x}, y=#{y}, red=255, alpha=55 );"
image.filter filter_string
static VALUE image_filter(VALUE self, VALUE filter) {
if (rb_obj_is_kind_of(self, rb_cString) == Qtrue) {
return image_static_filter(self, filter);
} else if (rb_obj_is_kind_of(self, cFilter) == Qtrue) {
return image_script_filter(self, filter);
} else {
rb_raise(rb_eTypeError, "Invalid argument type "
"(not String or Imlib2::Filter)");
}
return self;
}
Create a copy of an image flipped along it's diagonal axis
Examples:
new_image = old_image.flip_diagonal
static VALUE image_flip_diagonal(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_flip_diagonal();
return im_o;
}
Flip an image along it's diagonal axis
Examples:
image.flip_diagonal!
static VALUE image_flip_diagonal_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_flip_diagonal();
return self;
}
Create a horizontally-flipped copy of an image
Examples:
backwards_image = old_image.flip_horizontal
static VALUE image_flip_horizontal(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_flip_horizontal();
return im_o;
}
Flip an image horizontally
Examples:
image.flip_horizontal!
static VALUE image_flip_horizontal_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_flip_horizontal();
return self;
}
Create a vertically-flipped copy of an image
Examples:
upside_down_image = old_image.flip_vertical
static VALUE image_flip_vertical(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_flip_vertical();
return im_o;
}
Flip an image vertically
Examples:
image.flip_vertical!
static VALUE image_flip_vertical_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_flip_vertical();
return self;
}
Get the on-disk format of an Imlib2::Image
Examples:
format = image.get_format format = image.format
static VALUE image_get_format(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return rb_str_new2(imlib_image_format());
}
Set the on-disk format of an Imlib2::Image
Examples:
image.get_format 'png' image.format = 'png'
static VALUE image_set_format(VALUE self, VALUE format) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_format(StringValuePtr(format));
return format;
}
Get an integer value attached to an Imlib2::Image.
Examples:
qual = image.get_attached_value('quality')
qual = image['quality']
static VALUE image_get_attach_val(VALUE self, VALUE key_o) {
ImStruct *im;
VALUE ret;
char *key;
/* char *data; */
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
key = StringValuePtr(key_o);
/* if it's got data, retrn that, otherwise return the value */
/*
* if ((data = (char*) imlib_image_get_attached_value(key)) != NULL) {
* fprintf(stderr, "it's a string \"%s\": %x\n", key, data);
* ret = rb_str_new2(data);
* } else {
* fprintf(stderr, "it's an integer \"%s\"\n", key);
*/
ret = INT2FIX(imlib_image_get_attached_value(key));
/*
* }
*/
/* return result */
return ret;
}
Get the Imlib2::Border of an Imlib2::Image
Examples:
border = image.get_border border = image.border
static VALUE image_get_border(VALUE self) {
ImStruct *im;
Imlib_Border *border;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
border = malloc(sizeof(Imlib_Border));
imlib_image_get_border(border);
argv[0] = INT2NUM(border->left);
argv[1] = INT2NUM(border->top);
argv[2] = INT2NUM(border->right);
argv[3] = INT2NUM(border->bottom);
free(border);
return border_new(4, argv, cBorder);
}
Get the on-disk format of an Imlib2::Image
Examples:
format = image.get_format format = image.format
static VALUE image_get_format(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return rb_str_new2(imlib_image_format());
}
Fill a rectangle with the given Imlib2::Gradient at a given angle
Examples:
x, y, w, h = 10, 10, image.width - 20, image.height - 20 angle = 45.2 image.fill_gradient gradient, x, y, w, h, angle rect = [5, 5, 500, 20] image.gradient gradient, rect, 36.8
static VALUE image_fill_gradient(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
Imlib_Color_Range *grad;
int x, y, w, h;
double angle;
switch (argc) {
case 3:
/* three arguments is a gradient, an array or hash of [x,y,w,h],
* and an angle */
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
w = NUM2INT(rb_ary_entry(argv[1], 2));
h = NUM2INT(rb_ary_entry(argv[1], 3));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[2]);
break;
case 4:
switch (TYPE(argv[1])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[1], 0));
y = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
switch (TYPE(argv[2])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[2], 0));
h = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError,"Invalid argument type (not array or hash)");
}
angle = NUM2DBL(argv[3]);
break;
case 6:
x = NUM2INT(argv[1]);
y = NUM2INT(argv[2]);
w = NUM2INT(argv[3]);
h = NUM2INT(argv[4]);
angle = NUM2DBL(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count (not 3, 4, or 6)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(argv[0], Imlib_Color_Range, grad);
imlib_context_set_color_range(*grad);
imlib_image_fill_color_range_rectangle(x, y, w, h, angle);
return self;
}
Return the height of an Imlib2::Image.
Examples:
h = image.height h = image.h
static VALUE image_height(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return INT2FIX(imlib_image_get_height());
}
Does this image have transparent or translucent regions?
Examples:
if image.has_alpha? puts 'this image has alpha' end
static VALUE image_has_alpha(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return imlib_image_has_alpha() ? Qtrue : Qfalse;
}
Set image alpha transparency.
Examples:
image.set_has_alpha true image.has_alpha = true
static VALUE image_set_has_alpha(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_has_alpha(val == Qtrue);
return val;
}
Does this image have transparent or translucent regions?
Examples:
if image.has_alpha? puts 'this image has alpha' end
static VALUE image_has_alpha(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return imlib_image_has_alpha() ? Qtrue : Qfalse;
}
Return the height of an Imlib2::Image.
Examples:
h = image.height h = image.h
static VALUE image_height(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return INT2FIX(imlib_image_get_height());
}
Set the irrelevant_alpha flag of an Imlib2::Image
Examples:
image.set_irrelevant_alpha true image.irrelevant_alpha = true
static VALUE image_irrelevant_alpha(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_alpha(val != Qfalse);
return val;
}
Set the irrelevant_border flag of an Imlib2::Image
Examples:
image.set_irrelevant_border true image.irrelevant_border = true
static VALUE image_irrelevant_border(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_border(val != Qfalse);
return val;
}
Set the irrelevant_format flag of an Imlib2::Image
Examples:
image.set_irrelevant_format true image.irrelevant_format = true
static VALUE image_irrelevant_format(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_format(val != Qfalse);
return val;
}
Return a copy of an image rotated in 90 degree increments
Examples:
increments = 3 # 90 * 3 degrees (eg 270 degrees) new_image = old_image.orientate increments
static VALUE image_orientate(VALUE self, VALUE val) {
ImStruct *im, *new_im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
imlib_context_set_image(new_im->im);
imlib_image_orientate(NUM2INT(val));
return Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
}
Rotate an image in 90 degree increments
Examples:
increments = 3 # 90 * 3 degrees (eg 270 degrees) image.orientate! increments
static VALUE image_orientate_inline(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_orientate(NUM2INT(val));
return self;
}
Get the Imlib2::Color::RgbaColor value of the pixel at x, y
Examples:
color = image.query_pixel 320, 240 color = image.pixel 320, 240
static VALUE image_query_pixel(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
Imlib_Color color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel(NUM2INT(x), NUM2INT(y), &color);
argv[0] = INT2NUM(color.red);
argv[1] = INT2NUM(color.green);
argv[2] = INT2NUM(color.blue);
argv[3] = INT2NUM(color.alpha);
return rgba_color_new(4, argv, cRgbaColor);
}
Get the Imlib2::Color::CmyaColor value of the pixel at x, y
Examples:
color = image.query_pixel_cmya 320, 240 color = image.pixel_cmya 320, 240
static VALUE image_query_pixel_cmya(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
CmyaColor color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_cmya(NUM2INT(x), NUM2INT(y), &color.cyan, &color.magenta, &color.yellow, &color.alpha);
argv[0] = INT2NUM(color.cyan);
argv[1] = INT2NUM(color.magenta);
argv[2] = INT2NUM(color.yellow);
argv[3] = INT2NUM(color.alpha);
return cmya_color_new(4, argv, cCmyaColor);
}
Get the Imlib2::Color::HlsaColor value of the pixel at x, y
Examples:
color = image.query_pixel_hlsa 320, 240 color = image.pixel_hlsa 320, 240
static VALUE image_query_pixel_hlsa(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
float hue, lightness, saturation;
int alpha;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_hsva(NUM2INT(x), NUM2INT(y), &hue, &lightness, &saturation, &alpha);
argv[0] = rb_float_new(hue);
argv[1] = rb_float_new(lightness);
argv[2] = rb_float_new(saturation);
argv[3] = INT2NUM(alpha);
return hlsa_color_new(4, argv, cHlsaColor);
}
Get the Imlib2::Color::HsvaColor value of the pixel at x, y
Examples:
color = image.query_pixel_hsva 320, 240 color = image.pixel_hsva 320, 240
static VALUE image_query_pixel_hsva(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
float hue, saturation, value;
int alpha;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_hsva(NUM2INT(x), NUM2INT(y), &hue, &saturation, &value, &alpha);
argv[0] = rb_float_new(hue);
argv[1] = rb_float_new(saturation);
argv[2] = rb_float_new(value);
argv[3] = INT2NUM(alpha);
return hsva_color_new(4, argv, cHsvaColor);
}
Get the Imlib2::Color::RgbaColor value of the pixel at x, y
Examples:
color = image.query_pixel 320, 240 color = image.pixel 320, 240
static VALUE image_query_pixel(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
Imlib_Color color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel(NUM2INT(x), NUM2INT(y), &color);
argv[0] = INT2NUM(color.red);
argv[1] = INT2NUM(color.green);
argv[2] = INT2NUM(color.blue);
argv[3] = INT2NUM(color.alpha);
return rgba_color_new(4, argv, cRgbaColor);
}
Fill an image using raw 32-bit data.
Note: The new data buffer must be the same size (in bytes) as the original data buffer.
Examples:
RAW_DATA = other_image.data! image.put_data RAW_DATA RAW_DATA = other_image.data! image.data = RAW_DATA
static VALUE image_put_data(VALUE self, VALUE str) {
ImStruct *im;
DATA32 *old_data, *new_data;
int w, h, old_size;
/* get image, check it, then set the context */
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
/* get old data, calculate buffer size from width and height */
old_data = imlib_image_get_data();
w = imlib_image_get_width();
h = imlib_image_get_height();
old_size = w * h * 4;
/* get new data, check size of buffer */
new_data = (DATA32*) StringValuePtr(str);
/* check size of new buffer */
if (RSTRING_LEN(str) != old_size)
rb_raise(rb_eArgError, "invalid buffer size");
/* copy new data to old address */
if (old_data != new_data)
memcpy(old_data, new_data, old_size);
/* actual put_back_data() call */
imlib_image_put_back_data(old_data);
/* return success */
return Qtrue;
}
Get the Imlib2::Color::RgbaColor value of the pixel at x, y
Examples:
color = image.query_pixel 320, 240 color = image.pixel 320, 240
static VALUE image_query_pixel(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
Imlib_Color color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel(NUM2INT(x), NUM2INT(y), &color);
argv[0] = INT2NUM(color.red);
argv[1] = INT2NUM(color.green);
argv[2] = INT2NUM(color.blue);
argv[3] = INT2NUM(color.alpha);
return rgba_color_new(4, argv, cRgbaColor);
}
Get the Imlib2::Color::CmyaColor value of the pixel at x, y
Examples:
color = image.query_pixel_cmya 320, 240 color = image.pixel_cmya 320, 240
static VALUE image_query_pixel_cmya(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
CmyaColor color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_cmya(NUM2INT(x), NUM2INT(y), &color.cyan, &color.magenta, &color.yellow, &color.alpha);
argv[0] = INT2NUM(color.cyan);
argv[1] = INT2NUM(color.magenta);
argv[2] = INT2NUM(color.yellow);
argv[3] = INT2NUM(color.alpha);
return cmya_color_new(4, argv, cCmyaColor);
}
Get the Imlib2::Color::HlsaColor value of the pixel at x, y
Examples:
color = image.query_pixel_hlsa 320, 240 color = image.pixel_hlsa 320, 240
static VALUE image_query_pixel_hlsa(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
float hue, lightness, saturation;
int alpha;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_hsva(NUM2INT(x), NUM2INT(y), &hue, &lightness, &saturation, &alpha);
argv[0] = rb_float_new(hue);
argv[1] = rb_float_new(lightness);
argv[2] = rb_float_new(saturation);
argv[3] = INT2NUM(alpha);
return hlsa_color_new(4, argv, cHlsaColor);
}
Get the Imlib2::Color::HsvaColor value of the pixel at x, y
Examples:
color = image.query_pixel_hsva 320, 240 color = image.pixel_hsva 320, 240
static VALUE image_query_pixel_hsva(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
float hue, saturation, value;
int alpha;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel_hsva(NUM2INT(x), NUM2INT(y), &hue, &saturation, &value, &alpha);
argv[0] = rb_float_new(hue);
argv[1] = rb_float_new(saturation);
argv[2] = rb_float_new(value);
argv[3] = INT2NUM(alpha);
return hsva_color_new(4, argv, cHsvaColor);
}
Get the Imlib2::Color::RgbaColor value of the pixel at x, y
Examples:
color = image.query_pixel 320, 240 color = image.pixel 320, 240
static VALUE image_query_pixel(VALUE self, VALUE x, VALUE y) {
ImStruct *im;
Imlib_Color color;
VALUE argv[4];
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_query_pixel(NUM2INT(x), NUM2INT(y), &color);
argv[0] = INT2NUM(color.red);
argv[1] = INT2NUM(color.green);
argv[2] = INT2NUM(color.blue);
argv[3] = INT2NUM(color.alpha);
return rgba_color_new(4, argv, cRgbaColor);
}
Remove an integer value attached to an Imlib2::Image.
Examples:
image.remove_attached_value('quality')
static VALUE image_rm_attach_val(VALUE self, VALUE key_o) {
ImStruct *im;
char *key;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
key = StringValuePtr(key_o);
imlib_image_remove_attached_data_value(key);
return Qnil;
}
Return a rotated copy of the image
Examples:
new_image = old_image.rotate 37.2
static VALUE image_rotate(VALUE self, VALUE angle) {
ImStruct *new_im, *im;
double a;
new_im = malloc(sizeof(ImStruct));
GET_AND_CHECK_IMAGE(self, im);
a = rb_float_new(angle);
imlib_context_set_image(im->im);
new_im->im = imlib_create_rotated_image(a);
return Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
}
Rotates the image
Examples:
image.rotate! 37.2
static VALUE image_rotate_inline(VALUE self, VALUE angle) {
ImStruct *im;
Imlib_Image new_im;
double a;
GET_AND_CHECK_IMAGE(self, im);
a = rb_float_new(angle);
imlib_context_set_image(im->im);
new_im = imlib_create_rotated_image(a);
imlib_context_set_image(im->im);
imlib_free_image();
im->im = new_im;
return self;
}
Save an Imlib2::Image to a file (throws an exception on error).
Examples:
image.save 'output_file.png'
filename = 'output_file.jpg'
begin
image.save filename
rescue Imlib2::FileError
$stderr.puts "Couldn't save file \"#{filename}\": " + $!
end
static VALUE image_save(VALUE self, VALUE val) {
ImStruct *im;
Imlib_Load_Error er;
char *path;
path = StringValuePtr(val);
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_save_image_with_error_return(path, &er);
if (er == IMLIB_LOAD_ERROR_NONE)
return self;
if (er > IMLIB_LOAD_ERROR_UNKNOWN)
er = IMLIB_LOAD_ERROR_UNKNOWN;
raise_imlib_error(path, er);
return Qnil;
}
Save an Imlib2::Image to a file (no exception or error).
Provides access to the low-level imlib_save_image() call. You probably want to use Imlib2::Image::save() instead.
Examples:
image.save_image 'output_file.png'
static VALUE image_save_image(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_save_image(StringValuePtr(val));
return self;
}
Save an Imlib2::Image to a file (error returned as number).
Provides access to the low-level imlib_save_image_with_error_return() call. You probably want to use Imlib2::Image::save() instead.
Examples:
error = image.save_with_error_return 'output_file.png' puts 'an error occurred' unless error == 0
static VALUE image_save_with_error_return(VALUE self, VALUE val) {
ImStruct *im;
Imlib_Load_Error er;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_save_image_with_error_return(StringValuePtr(val), &er);
if (er > IMLIB_LOAD_ERROR_UNKNOWN)
er = IMLIB_LOAD_ERROR_UNKNOWN;
return INT2FIX(er);
}
Apply a scripted filter
You should probably using Imlib2::Image#filter() instead, since it is polymorphic (eg, it can handle both static and scripted filters).
Example:
x, y = 20, 10
filter_string = "tint( x=#{x}, y=#{y}, red=255, alpha=55 );"
image.script_filter filter_string
static VALUE image_script_filter(VALUE self, VALUE filter) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_apply_filter(StringValuePtr(filter));
return self;
}
Scroll a rectangle to the specified coordinates
Examples:
x, y, w, h = 10, 20, 100, 200 dest_x, dest_y = 5, 10 image.scroll_rect x, y, w, h, dest_x, dest_y source_rect = [10, 20, 100, 200] dest_coords = [5, 10] image.scroll_rect source_rect, dest_coords values = [10, 20, 100, 200, 5, 10] image.scroll_rect values
static VALUE image_scroll_rect(int argc, VALUE *argv, VALUE self) {
ImStruct *im;
int x, y, w, h, dx, dy;
switch (argc) {
case 1:
/* one argument is an array or hash of [x, y, w, h, dx, dy] */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dx = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("dy")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dx = NUM2INT(rb_ary_entry(argv[0], 4));
dy = NUM2INT(rb_ary_entry(argv[0], 5));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 2:
/* two arguments is an array or hash of [x, y, w, h] and an array
* or hash of [dx, dy] */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[1], 0));
dy = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 3:
/* three arguments is an array or hash of [x, y], an array or hash
* of [w, h] and an array or hash of [dx, dy], or an array or hash
* of [x, y, w, h], dx, dy */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("h")));
dx = NUM2INT(argv[1]);
dy = NUM2INT(argv[2]);
}
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
switch (TYPE(argv[2])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[2], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[2], 0));
dy = NUM2INT(rb_ary_entry(argv[2], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type "
"(not array or hash)");
}
break;
default:
w = NUM2INT(rb_ary_entry(argv[0], 2));
h = NUM2INT(rb_ary_entry(argv[0], 3));
dx = NUM2INT(argv[1]);
dy = NUM2INT(argv[2]);
}
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 4:
/* four arguments is an array or hash of [x, y], an array or hash
* of [w, h], dx, dy */
switch (TYPE(argv[0])) {
case T_HASH:
x = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("x")));
y = NUM2INT(rb_hash_aref(argv[0], rb_str_new2("y")));
break;
case T_ARRAY:
x = NUM2INT(rb_ary_entry(argv[0], 0));
y = NUM2INT(rb_ary_entry(argv[0], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
switch (TYPE(argv[1])) {
case T_HASH:
w = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("w")));
h = NUM2INT(rb_hash_aref(argv[1], rb_str_new2("h")));
break;
case T_ARRAY:
w = NUM2INT(rb_ary_entry(argv[1], 0));
h = NUM2INT(rb_ary_entry(argv[1], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
dx = NUM2INT(argv[2]);
dy = NUM2INT(argv[3]);
break;
case 5:
/* five arguments is x, y, w, h, and an array or hash of
* [dx, dy] */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
switch (TYPE(argv[4])) {
case T_HASH:
dx = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("dx")));
dy = NUM2INT(rb_hash_aref(argv[4], rb_str_new2("dy")));
break;
case T_ARRAY:
dx = NUM2INT(rb_ary_entry(argv[4], 0));
dy = NUM2INT(rb_ary_entry(argv[4], 1));
break;
default:
rb_raise(rb_eTypeError, "Invalid argument type (not array or hash)");
}
break;
case 6:
/* six arguments is x, y, w, h, dx, dy */
x = NUM2INT(argv[0]);
y = NUM2INT(argv[1]);
w = NUM2INT(argv[2]);
h = NUM2INT(argv[3]);
dx = NUM2INT(argv[4]);
dy = NUM2INT(argv[5]);
break;
default:
rb_raise(rb_eTypeError, "Invalid argument count "
"(not 2, 3, 4, 5, 6, or 7)");
}
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_scroll_rect(x, y, w, h, dx, dy);
return self;
}
Set the Imlib2::Border of an Imlib2::Image
Examples:
image.set_border border image.border = border
static VALUE image_set_border(VALUE self, VALUE border) {
ImStruct *im;
Imlib_Border *b;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(border, Imlib_Border, b);
imlib_image_set_border(b);
return border;
}
Flag this image as changing on disk
Examples:
image.changes_on_disk
static VALUE image_changes_on_disk(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_changes_on_disk();
return Qtrue;
}
Set the on-disk format of an Imlib2::Image
Examples:
image.get_format 'png' image.format = 'png'
static VALUE image_set_format(VALUE self, VALUE format) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_format(StringValuePtr(format));
return format;
}
Set image alpha transparency.
Examples:
image.set_has_alpha true image.has_alpha = true
static VALUE image_set_has_alpha(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_has_alpha(val == Qtrue);
return val;
}
Set the irrelevant_alpha flag of an Imlib2::Image
Examples:
image.set_irrelevant_alpha true image.irrelevant_alpha = true
static VALUE image_irrelevant_alpha(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_alpha(val != Qfalse);
return val;
}
Set the irrelevant_border flag of an Imlib2::Image
Examples:
image.set_irrelevant_border true image.irrelevant_border = true
static VALUE image_irrelevant_border(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_border(val != Qfalse);
return val;
}
Set the irrelevant_format flag of an Imlib2::Image
Examples:
image.set_irrelevant_format true image.irrelevant_format = true
static VALUE image_irrelevant_format(VALUE self, VALUE val) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_set_irrelevant_format(val != Qfalse);
return val;
}
Apply an Imlib2::Filter (eg a static filter)
You should probably using Imlib2::Image#filter() instead, since it is polymorphic (eg, it can handle both static and scripted filters).
Example:
filter = Imlib2::Filter.new 20 filter.set 2, 2, Imlib2::Color::GREEN image.static_filter filter
static VALUE image_static_filter(VALUE self, VALUE filter) {
ImStruct *im;
Imlib_Filter *f;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
Data_Get_Struct(filter, Imlib_Filter, f);
imlib_context_set_filter(*f);
imlib_image_filter();
return self;
}
Return a copy of an image suitable for seamless tiling
Examples:
horiz_tile = old_image.tile
static VALUE image_tile(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_tile();
return im_o;
}
Modify an image so it is suitable for seamless tiling
Examples:
image.tile!
static VALUE image_tile_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_tile();
return self;
}
Return a copy of an image suitable for seamless horizontal tiling
Examples:
horiz_tile = old_image.tile_horizontal
static VALUE image_tile_horizontal(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_tile_horizontal();
return im_o;
}
Modify an image so it is suitable for seamless horizontal tiling
Examples:
image.tile_horizontal!
static VALUE image_tile_horizontal_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_tile_horizontal();
return self;
}
Return a copy of an image suitable for seamless vertical tiling
Examples:
vert_tile = old_image.tile_vertical
static VALUE image_tile_vertical(VALUE self) {
ImStruct *im, *new_im;
VALUE im_o;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
new_im = malloc(sizeof(ImStruct));
new_im->im = imlib_clone_image();
im_o = Data_Wrap_Struct(cImage, 0, im_struct_free, new_im);
imlib_context_set_image(new_im->im);
imlib_image_tile_vertical();
return im_o;
}
Modify an image so it is suitable for seamless vertical tiling
Examples:
image.tile_vertical!
static VALUE image_tile_vertical_inline(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
imlib_image_tile_vertical();
return self;
}
Return the width of an Imlib2::Image.
Examples:
w = image.width w = image.w
static VALUE image_width(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return INT2FIX(imlib_image_get_width());
}
Return the width of an Imlib2::Image.
Examples:
w = image.width w = image.w
static VALUE image_width(VALUE self) {
ImStruct *im;
GET_AND_CHECK_IMAGE(self, im);
imlib_context_set_image(im->im);
return INT2FIX(imlib_image_get_width());
}
Generated with the Darkfish Rdoc Generator 2.