/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /********************************************************************** rbrsvg.c - $Author: ggc $ $Date: 2007/07/13 16:07:34 $ Copyright (C) 2005-2006 Ruby-GNOME2 Project Team Copyright (C) 2004 Kouhei Sutou **********************************************************************/ #include #include #include #ifdef HAVE_LIBRSVG_RSVG_GZ_H # include #else # include #endif #ifdef HAVE_LIBRSVG_RSVG_CAIRO_H # include # include #endif #ifdef HAVE_LIBRSVG_LIBRSVG_ENUM_TYPES_H # include #else # include "librsvg-enum-types.h" #endif #include #define RBRSVG_MAJOR_VERSION RBGLIB_MAJOR_VERSION #define RBRSVG_MINOR_VERSION RBGLIB_MINOR_VERSION #define RBRSVG_MICRO_VERSION RBGLIB_MICRO_VERSION #define LIBRSVG_CHECK_VERSION(major, minor, micro) \ (LIBRSVG_MAJOR_VERSION > (major) || \ (LIBRSVG_MAJOR_VERSION == (major) && LIBRSVG_MINOR_VERSION > (minor)) || \ (LIBRSVG_MAJOR_VERSION == (major) && LIBRSVG_MINOR_VERSION == (minor) && \ LIBRSVG_MICRO_VERSION >= (micro))) #ifdef RSVG_TYPE_HANDLE # define _SELF(self) (RSVG_HANDLE(RVAL2GOBJ(self))) #else # define _SELF(self) ((RsvgHandle *)DATA_PTR(self)) #endif #define RVAL2DIM(obj) ((RsvgDimensionData *)DATA_PTR(obj)) static VALUE cHandle; static ID id_call; static ID id_callback; static ID id_closed; static ID id_to_s; static void exec_callback(gint *width, gint *height, gpointer self) { VALUE result; result = rb_funcall(rb_ivar_get((VALUE)self, id_callback), id_call, 2, INT2NUM(*width), INT2NUM(*height)); if (T_ARRAY == TYPE(result)) { VALUE w, h; w = rb_ary_entry(result, 0); h = rb_ary_entry(result, 1); if (!NIL_P(w)) { *width = NUM2INT(w); } if (!NIL_P(h)) { *height = NUM2INT(h); } } } #ifdef HAVE_TYPE_RSVGDIMENSIONDATA static VALUE to_s(VALUE obj) { return rb_funcall(obj, id_to_s, 0); } static VALUE cDim; static void rb_rsvg_dim_free(RsvgDimensionData *dimp) { if (dimp) { free(dimp); } } static VALUE rb_rsvg_dim_alloc(VALUE klass) { RsvgDimensionData *dimp; return Data_Make_Struct(klass, RsvgDimensionData, 0, rb_rsvg_dim_free, dimp); } static VALUE rb_rsvg_dim_initialize(int argc, VALUE *argv, VALUE self) { VALUE width, height, em, ex; RsvgDimensionData *dimp; dimp = RVAL2DIM(self); rb_scan_args(argc, argv, "04", &width, &height, &em, &ex); if (!NIL_P(width)) dimp->width = NUM2INT(width); if (!NIL_P(height)) dimp->height = NUM2INT(height); if (!NIL_P(em)) dimp->em = NUM2DBL(em); if (!NIL_P(ex)) dimp->ex = NUM2DBL(ex); return Qnil; } static VALUE rb_rsvg_dim_get_width(VALUE self) { return INT2NUM(RVAL2DIM(self)->width); } static VALUE rb_rsvg_dim_set_width(VALUE self, VALUE width) { RVAL2DIM(self)->width = NUM2INT(width); return Qnil; } static VALUE rb_rsvg_dim_get_height(VALUE self) { return INT2NUM(RVAL2DIM(self)->height); } static VALUE rb_rsvg_dim_set_height(VALUE self, VALUE height) { RVAL2DIM(self)->height = NUM2INT(height); return Qnil; } static VALUE rb_rsvg_dim_get_em(VALUE self) { return rb_float_new(RVAL2DIM(self)->em); } static VALUE rb_rsvg_dim_set_em(VALUE self, VALUE em) { RVAL2DIM(self)->em = NUM2DBL(em); return Qnil; } static VALUE rb_rsvg_dim_get_ex(VALUE self) { return rb_float_new(RVAL2DIM(self)->ex); } static VALUE rb_rsvg_dim_set_ex(VALUE self, VALUE ex) { RVAL2DIM(self)->ex = NUM2DBL(ex); return Qnil; } static VALUE rb_rsvg_dim_to_a(VALUE self) { return rb_ary_new3(4, rb_rsvg_dim_get_width(self), rb_rsvg_dim_get_height(self), rb_rsvg_dim_get_em(self), rb_rsvg_dim_get_ex(self)); } static VALUE rb_rsvg_dim_to_s(VALUE self) { VALUE ret; ret = rb_str_new2("#<"); rb_str_cat2(ret, rb_obj_classname(self)); rb_str_cat2(ret, ":"); rb_str_concat(ret, rb_funcall(INT2NUM(self), id_to_s, 0)); rb_str_cat2(ret, " "); rb_str_cat2(ret, "width="); rb_str_concat(ret, to_s(rb_rsvg_dim_get_width(self))); rb_str_cat2(ret, ", "); rb_str_cat2(ret, "height="); rb_str_concat(ret, to_s(rb_rsvg_dim_get_height(self))); rb_str_cat2(ret, ", "); rb_str_cat2(ret, "em="); rb_str_concat(ret, to_s(rb_rsvg_dim_get_em(self))); rb_str_cat2(ret, ", "); rb_str_cat2(ret, "ex="); rb_str_concat(ret, to_s(rb_rsvg_dim_get_ex(self))); rb_str_cat2(ret, ">"); return ret; } #endif static VALUE rb_rsvg_set_default_dpi(VALUE self, VALUE dpi) { #ifdef HAVE_RSVG_SET_DEFAULT_DPI rsvg_set_default_dpi(NUM2DBL(dpi)); #else rb_warning("rsvg_set_default_dpi isn't supported in your librsvg"); #endif return self; } static VALUE rb_rsvg_set_default_dpi_x_y(VALUE self, VALUE dpi_x, VALUE dpi_y) { #ifdef HAVE_RSVG_SET_DEFAULT_DPI_X_Y rsvg_set_default_dpi_x_y(NUM2DBL(dpi_x), NUM2DBL(dpi_y)); #else rb_warning("rsvg_set_default_dpi_x_y isn't supported in your librsvg"); #endif return self; } static VALUE rb_rsvg_handle_set_dpi(VALUE self, VALUE dpi) { #ifdef HAVE_RSVG_HANDLE_SET_DPI rsvg_handle_set_dpi(_SELF(self), NUM2DBL(dpi)); #else rb_warning("rsvg_handle_set_dpi isn't supported in your librsvg"); #endif return self; } static VALUE rb_rsvg_handle_set_dpi_x_y(VALUE self, VALUE dpi_x, VALUE dpi_y) { #ifdef HAVE_RSVG_HANDLE_SET_DPI_X_Y rsvg_handle_set_dpi_x_y(_SELF(self), NUM2DBL(dpi_x), NUM2DBL(dpi_y)); #else rb_warning("rsvg_handle_set_dpi_x_y isn't supported in your librsvg"); #endif return self; } #ifndef RSVG_TYPE_HANDLE static void rb_rsvg_handle_free(RsvgHandle *handle) { if (handle) { rsvg_handle_free(handle); } } static VALUE rb_rsvg_handle_alloc(VALUE klass) { return Data_Wrap_Struct(klass, 0, rb_rsvg_handle_free, 0); } #endif #if LIBRSVG_CHECK_VERSION(2, 14, 0) static VALUE rb_rsvg_handle_new_from_data(VALUE self, VALUE data) { GError *error = NULL; RsvgHandle *handle; handle = rsvg_handle_new_from_data((const guint8 *)RVAL2CSTR(data), RSTRING_LEN(data), &error); if (error) RAISE_GERROR(error); return GOBJ2RVAL(handle); } static VALUE rb_rsvg_handle_new_from_file(VALUE self, VALUE file) { GError *error = NULL; RsvgHandle *handle; handle = rsvg_handle_new_from_file((const gchar *)RVAL2CSTR(file), &error); if (error) RAISE_GERROR(error); return GOBJ2RVAL(handle); } #endif static VALUE rb_rsvg_handle_initialize(int argc, VALUE *argv, VALUE self) { RsvgHandle *handle; VALUE gz; rb_scan_args(argc, argv, "01", &gz); #if LIBRSVG_CHECK_VERSION(2, 11, 0) handle = rsvg_handle_new(); #else if (RVAL2CBOOL(gz)) { # ifdef HAVE_LIBRSVG_RSVG_GZ_H handle = rsvg_handle_new_gz(); # else rb_warning("gz handling is not supported in your librsvg"); handle = rsvg_handle_new(); # endif } else { handle = rsvg_handle_new(); } #endif #ifdef RSVG_TYPE_HANDLE G_INITIALIZE(self, handle); #else DATA_PTR(self) = handle; #endif rb_ivar_set(self, id_closed, Qfalse); return Qnil; } static VALUE rb_rsvg_handle_set_size_callback(VALUE self) { rb_ivar_set(self, id_callback, rb_block_proc()); rsvg_handle_set_size_callback(_SELF(self), exec_callback, (gpointer)self, NULL); return self; } static VALUE rb_rsvg_handle_write(VALUE self, VALUE buf) { gboolean result; GError *error = NULL; result = rsvg_handle_write(_SELF(self), (const guchar*)RVAL2CSTR(buf), RSTRING_LEN(buf), &error); if (!result) RAISE_GERROR(error); return CBOOL2RVAL(result); } static VALUE rb_rsvg_handle_close(VALUE self) { gboolean result; GError *error = NULL; if (RVAL2CBOOL(rb_ivar_get(self, id_closed))) { return Qnil; } result = rsvg_handle_close(_SELF(self), &error); if (result) { rb_ivar_set(self, id_closed, Qtrue); } else { RAISE_GERROR(error); } return CBOOL2RVAL(result); } static VALUE rb_rsvg_handle_closed(VALUE self) { return rb_ivar_get(self, id_closed); } static VALUE rb_rsvg_handle_get_pixbuf(int argc, VALUE *argv, VALUE self) { VALUE id; VALUE rb_pixbuf; GdkPixbuf *pixbuf = NULL; rb_scan_args(argc, argv, "01", &id); if (NIL_P(id)) { pixbuf = rsvg_handle_get_pixbuf(_SELF(self)); } else { #ifdef HAVE_RSVG_HANDLE_GET_PIXBUF_SUB pixbuf = rsvg_handle_get_pixbuf_sub(_SELF(self), (const char *)RVAL2CSTR(id)); #else rb_warning("rsvg_handle_get_pixbuf_sub isn't " "supported in your librsvg"); #endif } rb_pixbuf = GOBJ2RVAL(pixbuf); if (pixbuf) g_object_unref(pixbuf); return rb_pixbuf; } #if LIBRSVG_CHECK_VERSION(2, 9, 0) static VALUE rb_rsvg_handle_get_base_uri(VALUE self) { return CSTR2RVAL(rsvg_handle_get_base_uri(_SELF(self))); } static VALUE rb_rsvg_handle_set_base_uri(VALUE self, VALUE base_uri) { rsvg_handle_set_base_uri(_SELF(self), RVAL2CSTR(base_uri)); return self; } #endif /* Convenience API */ static VALUE rb_rsvg_pixbuf_from_file(VALUE self, VALUE file_name) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file(RVAL2CSTR(file_name), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_zoom(VALUE self, VALUE file_name, VALUE x_zoom, VALUE y_zoom) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_zoom(RVAL2CSTR(file_name), NUM2DBL(x_zoom), NUM2DBL(y_zoom), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_size(VALUE self, VALUE file_name, VALUE width, VALUE height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_size(RVAL2CSTR(file_name), NUM2INT(width), NUM2INT(height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_max_size(VALUE self, VALUE file_name, VALUE max_width, VALUE max_height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_max_size(RVAL2CSTR(file_name), NUM2INT(max_width), NUM2INT(max_height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_zoom_with_max(VALUE self, VALUE file_name, VALUE x_zoom, VALUE y_zoom, VALUE max_width, VALUE max_height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_zoom_with_max(RVAL2CSTR(file_name), NUM2DBL(x_zoom), NUM2DBL(y_zoom), NUM2INT(max_width), NUM2INT(max_height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } #ifdef HAVE_TYPE_RSVGDIMENSIONDATA static VALUE rb_rsvg_handle_get_dim(VALUE self) { RsvgDimensionData dim; VALUE args[4]; rsvg_handle_get_dimensions(_SELF(self), &dim); args[0] = INT2NUM(dim.width); args[1] = INT2NUM(dim.height); args[2] = rb_float_new(dim.em); args[3] = rb_float_new(dim.ex); return rb_class_new_instance(sizeof(args) / sizeof(VALUE), args, cDim); } #endif /* Accessibility API */ static VALUE rb_rsvg_handle_get_title(VALUE self) { return CSTR2RVAL(rsvg_handle_get_title(_SELF(self))); } static VALUE rb_rsvg_handle_get_desc(VALUE self) { return CSTR2RVAL(rsvg_handle_get_desc(_SELF(self))); } #ifdef HAVE_RSVG_HANDLE_GET_METADATA static VALUE rb_rsvg_handle_get_metadata(VALUE self) { return CSTR2RVAL(rsvg_handle_get_metadata(_SELF(self))); } #endif #if !LIBRSVG_CHECK_VERSION(2, 11, 0) /* Extended Convenience API */ static VALUE rb_rsvg_pixbuf_from_file_at_size_ex(VALUE self, VALUE file_name, VALUE width, VALUE height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_size_ex(_SELF(self), RVAL2CSTR(file_name), NUM2INT(width), NUM2INT(height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_ex(VALUE self, VALUE file_name) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_ex(_SELF(self), RVAL2CSTR(file_name), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_zoom_ex(VALUE self, VALUE file_name, VALUE x_zoom, VALUE y_zoom) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_zoom_ex(_SELF(self), RVAL2CSTR(file_name), NUM2DBL(x_zoom), NUM2DBL(y_zoom), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_max_size_ex(VALUE self, VALUE file_name, VALUE max_width, VALUE max_height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_max_size_ex(_SELF(self), RVAL2CSTR(file_name), NUM2INT(max_width), NUM2INT(max_height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } static VALUE rb_rsvg_pixbuf_from_file_at_zoom_with_max_ex(VALUE self, VALUE file_name, VALUE x_zoom, VALUE y_zoom, VALUE max_width, VALUE max_height) { VALUE rb_pixbuf; GdkPixbuf *pixbuf; GError *error = NULL; pixbuf = rsvg_pixbuf_from_file_at_zoom_with_max_ex(_SELF(self), RVAL2CSTR(file_name), NUM2DBL(x_zoom), NUM2DBL(y_zoom), NUM2INT(max_width), NUM2INT(max_height), &error); if (error) RAISE_GERROR(error); rb_pixbuf = GOBJ2RVAL(pixbuf); g_object_unref(pixbuf); return rb_pixbuf; } #endif static VALUE rb_rsvg_cairo_available(VALUE self) { #ifdef HAVE_LIBRSVG_RSVG_CAIRO_H return Qtrue; #else return Qfalse; #endif } #ifdef HAVE_LIBRSVG_RSVG_CAIRO_H static VALUE rb_rsvg_handle_render_cairo(int argc, VALUE *argv, VALUE self) { VALUE cr, id; rb_scan_args(argc, argv, "11", &cr, &id); if (NIL_P(id)) { rsvg_handle_render_cairo( _SELF(self), RVAL2CRCONTEXT(cr)); } else { rsvg_handle_render_cairo_sub( _SELF(self), RVAL2CRCONTEXT(cr), (const char *)RVAL2CSTR(id)); } return Qnil; } #endif void Init_rsvg2(void) { VALUE mRSVG = rb_define_module("RSVG"); #if LIBRSVG_CHECK_VERSION(2, 9, 0) rsvg_init(); atexit(rsvg_term); #endif #ifdef RSVG_TYPE_HANDLE cHandle = G_DEF_CLASS(RSVG_TYPE_HANDLE, "Handle", mRSVG); #else cHandle = rb_define_class_under(mRSVG, "Handle", rb_cObject); rb_define_alloc_func(cHandle, rb_rsvg_handle_alloc); #endif G_DEF_ERROR(RSVG_ERROR, "Error", mRSVG, rb_eRuntimeError, RSVG_TYPE_ERROR); id_call = rb_intern("call"); id_callback = rb_intern("callback"); id_closed = rb_intern("closed"); id_to_s = rb_intern("to_s"); rb_define_const(mRSVG, "BINDING_VERSION", rb_ary_new3(3, INT2FIX(RBRSVG_MAJOR_VERSION), INT2FIX(RBRSVG_MINOR_VERSION), INT2FIX(RBRSVG_MICRO_VERSION))); rb_define_const(mRSVG, "BUILD_VERSION", rb_ary_new3(3, INT2FIX(LIBRSVG_MAJOR_VERSION), INT2FIX(LIBRSVG_MINOR_VERSION), INT2FIX(LIBRSVG_MICRO_VERSION))); rb_define_module_function(mRSVG, "set_default_dpi", rb_rsvg_set_default_dpi, 1); rb_define_module_function(mRSVG, "set_default_dpi_x_y", rb_rsvg_set_default_dpi_x_y, 2); #ifdef HAVE_TYPE_RSVGDIMENSIONDATA cDim = rb_define_class_under(mRSVG, "DimensionData", rb_cObject); rb_define_alloc_func(cDim, rb_rsvg_dim_alloc); rb_define_method(cDim, "initialize", rb_rsvg_dim_initialize, -1); rb_define_method(cDim, "width", rb_rsvg_dim_get_width, 0); rb_define_method(cDim, "set_width", rb_rsvg_dim_set_width, 1); rb_define_method(cDim, "height", rb_rsvg_dim_get_height, 0); rb_define_method(cDim, "set_height", rb_rsvg_dim_set_height, 1); rb_define_method(cDim, "em", rb_rsvg_dim_get_em, 0); rb_define_method(cDim, "set_em", rb_rsvg_dim_set_em, 1); rb_define_method(cDim, "ex", rb_rsvg_dim_get_ex, 0); rb_define_method(cDim, "set_ex", rb_rsvg_dim_set_ex, 1); rb_define_method(cDim, "to_s", rb_rsvg_dim_to_s, 0); rb_define_method(cDim, "to_a", rb_rsvg_dim_to_a, 0); rb_define_alias(cDim, "to_ary", "to_a"); G_DEF_SETTERS(cDim); #endif #if LIBRSVG_CHECK_VERSION(2, 14, 0) rb_define_module_function(cHandle, "new_from_data", rb_rsvg_handle_new_from_data, 1); rb_define_module_function(cHandle, "new_from_file", rb_rsvg_handle_new_from_file, 1); #endif rb_define_method(cHandle, "initialize", rb_rsvg_handle_initialize, -1); rb_define_method(cHandle, "set_size_callback", rb_rsvg_handle_set_size_callback, 0); rb_define_method(cHandle, "set_dpi", rb_rsvg_handle_set_dpi, 1); rb_define_method(cHandle, "set_dpi_x_y", rb_rsvg_handle_set_dpi_x_y, 2); rb_define_method(cHandle, "write", rb_rsvg_handle_write, 1); rb_define_method(cHandle, "close", rb_rsvg_handle_close, 0); rb_define_method(cHandle, "closed?", rb_rsvg_handle_closed, 0); rb_define_method(cHandle, "pixbuf", rb_rsvg_handle_get_pixbuf, -1); #if LIBRSVG_CHECK_VERSION(2, 9, 0) rb_define_method(cHandle, "base_uri", rb_rsvg_handle_get_base_uri, 0); rb_define_method(cHandle, "set_base_uri", rb_rsvg_handle_set_base_uri, 1); #endif /* Convenience API */ rb_define_module_function(mRSVG, "pixbuf_from_file", rb_rsvg_pixbuf_from_file, 1); rb_define_module_function(mRSVG, "pixbuf_from_file_at_zoom", rb_rsvg_pixbuf_from_file_at_zoom, 3); rb_define_module_function(mRSVG, "pixbuf_from_file_at_size", rb_rsvg_pixbuf_from_file_at_size, 3); rb_define_module_function(mRSVG, "pixbuf_from_file_at_max_size", rb_rsvg_pixbuf_from_file_at_max_size, 3); rb_define_module_function(mRSVG, "pixbuf_from_file_at_zoom_with_max", rb_rsvg_pixbuf_from_file_at_zoom_with_max, 5); #ifdef HAVE_TYPE_RSVGDIMENSIONDATA rb_define_method(cHandle, "dimensions", rb_rsvg_handle_get_dim, 0); #endif /* Accessibility API */ rb_define_method(cHandle, "title", rb_rsvg_handle_get_title, 0); rb_define_method(cHandle, "desc", rb_rsvg_handle_get_desc, 0); #ifdef HAVE_RSVG_HANDLE_GET_METADATA rb_define_method(cHandle, "metadata", rb_rsvg_handle_get_metadata, 0); #endif #if !LIBRSVG_CHECK_VERSION(2, 11, 0) /* Extended Convenience API */ rb_define_method(cHandle, "pixbuf_from_file_at_size", rb_rsvg_pixbuf_from_file_at_size_ex, 3); rb_define_method(cHandle, "pixbuf_from_file", rb_rsvg_pixbuf_from_file_ex, 1); rb_define_method(cHandle, "pixbuf_from_file_at_zoom", rb_rsvg_pixbuf_from_file_at_zoom_ex, 3); rb_define_method(cHandle, "pixbuf_from_file_at_max_size", rb_rsvg_pixbuf_from_file_at_max_size_ex, 3); rb_define_method(cHandle, "pixbuf_from_file_at_zoom_with_max", rb_rsvg_pixbuf_from_file_at_zoom_with_max_ex, 5); #endif rb_define_singleton_method(mRSVG, "cairo_available?", rb_rsvg_cairo_available, 0); #ifdef HAVE_LIBRSVG_RSVG_CAIRO_H rb_define_method(cHandle, "render_cairo", rb_rsvg_handle_render_cairo, -1); #endif G_DEF_SETTERS(cHandle); }