#include "rays/ruby/painter.h" #include #include "rays/ruby/point.h" #include "rays/ruby/bounds.h" #include "rays/ruby/color.h" #include "rays/ruby/matrix.h" #include "rays/ruby/image.h" #include "rays/ruby/font.h" #include "rays/ruby/shader.h" #include "defs.h" RUCY_DEFINE_VALUE_FROM_TO(Rays::Painter) #define THIS to(self) #define CHECK RUCY_CHECK_OBJECT(Rays::Painter, self) static VALUE alloc(VALUE klass) { return new_type(klass); } static VALUE canvas(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#canvas", argc, 4, 5, 6, 7); switch (argc) { case 4: THIS->canvas( to(argv[0]), to(argv[1]), to(argv[2]), to(argv[3])); break; case 5: THIS->canvas( to(argv[0]), to(argv[1]), to(argv[2]), to(argv[3]), to(argv[4])); break; case 6: THIS->canvas( to(argv[0]), to(argv[1]), to(argv[2]), to(argv[3]), to(argv[4]), to(argv[5])); break; case 7: THIS->canvas( to(argv[0]), to(argv[1]), to(argv[2]), to(argv[3]), to(argv[4]), to(argv[5]), to(argv[6])); break; } return self; } static VALUE bounds(VALUE self) { CHECK; return value(THIS->bounds()); } static VALUE pixel_density(VALUE self) { CHECK; return value(THIS->pixel_density()); } static VALUE begin_paint(VALUE self) { CHECK; THIS->begin(); return self; } static VALUE end_paint(VALUE self) { CHECK; THIS->end(); return self; } static VALUE is_painting(VALUE self) { CHECK; return value(THIS->painting()); } static VALUE clear(VALUE self) { CHECK; THIS->clear(); } static VALUE polygon(VALUE self, VALUE poly) { CHECK; THIS->polygon(to(poly)); return self; } static VALUE line(VALUE self, VALUE args, VALUE loop) { CHECK; std::vector points; get_line_args(&points, args.size(), args.as_array()); THIS->line(&points[0], points.size(), loop); return self; } static VALUE polyline(VALUE self, VALUE poly) { CHECK; THIS->line(to(poly)); return self; } static VALUE rect(VALUE self, VALUE args, VALUE round, VALUE lefttop, VALUE righttop, VALUE leftbottom, VALUE rightbottom) { CHECK; coord x, y, w, h, lt, rt, lb, rb; uint _; get_rect_args( &x, &y, &w, &h, <, &rt, &lb, &rb, &_, args.size(), args.as_array(), round, lefttop, righttop, leftbottom, rightbottom, nil()); THIS->rect(x, y, w, h, lt, rt, lb, rb); return self; } static VALUE ellipse(VALUE self, VALUE args, VALUE center, VALUE radius, VALUE hole, VALUE angle_from, VALUE angle_to) { CHECK; coord x, y, w, h; Rays::Point hole_size; float from, to_; uint _; get_ellipse_args( &x, &y, &w, &h, &hole_size, &from, &to_, &_, args.size(), args.as_array(), center, radius, hole, angle_from, angle_to, nil()); THIS->ellipse(x, y, w, h, hole_size, from, to_); return self; } static VALUE curve(VALUE self, VALUE args, VALUE loop) { CHECK; if (args.empty()) argument_error(__FILE__, __LINE__); std::vector points; get_line_args(&points, args.size(), args.as_array()); THIS->curve(&points[0], points.size(), loop); return self; } static VALUE bezier(VALUE self, VALUE args, VALUE loop) { CHECK; if (args.empty()) argument_error(__FILE__, __LINE__); std::vector points; get_line_args(&points, args.size(), args.as_array()); THIS->bezier(&points[0], points.size(), loop); return self; } static VALUE image(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#image", argc, 1, 3, 5, 7, 9); const Rays::Image* image = to(argv[0]); if (!image) argument_error(__FILE__, __LINE__, "%s is not an image.", argv[0].inspect().c_str()); if (argc == 1) THIS->image(*image); else if (argc == 3) { coord x = to(argv[1]), y = to(argv[2]); THIS->image(*image, x, y); } else if (argc == 5) { coord x = to(argv[1]), w = to(argv[3]); coord y = to(argv[2]), h = to(argv[4]); THIS->image(*image, x, y, w, h); } else if (argc == 7) { coord sx = to(argv[1]), dx = to(argv[5]); coord sy = to(argv[2]), dy = to(argv[6]); coord sw = to(argv[3]); coord sh = to(argv[4]); THIS->image(*image, sx, sy, sw, sh, dx, dy); } else if (argc == 9) { coord sx = to(argv[1]), dx = to(argv[5]); coord sy = to(argv[2]), dy = to(argv[6]); coord sw = to(argv[3]), dw = to(argv[7]); coord sh = to(argv[4]), dh = to(argv[8]); THIS->image(*image, sx, sy, sw, sh, dx, dy, dw, dh); } return self; } static VALUE text(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#text", argc, 1, 3, 5); if (argc == 1) THIS->text(argv[0].c_str()); else if (argc == 3) { coord x = to(argv[1]), y = to(argv[2]); THIS->text(argv[0].c_str(), x, y); } else if (argc == 5) { coord x = to(argv[1]), w = to(argv[3]); coord y = to(argv[2]), h = to(argv[4]); THIS->text(argv[0].c_str(), x, y, w, h); } return self; } static VALUE set_background(VALUE self) { CHECK; THIS->set_background(to(argc, argv)); return self; } static VALUE get_background(VALUE self) { CHECK; return value(THIS->background()); } static VALUE no_background(VALUE self) { CHECK; THIS->no_background(); return self; } static VALUE set_fill(VALUE self) { CHECK; THIS->set_fill(to(argc, argv)); return self; } static VALUE get_fill(VALUE self) { CHECK; return value(THIS->fill()); } static VALUE no_fill(VALUE self) { CHECK; THIS->no_fill(); return self; } static VALUE set_stroke(VALUE self) { CHECK; THIS->set_stroke(to(argc, argv)); return self; } static VALUE get_stroke(VALUE self) { CHECK; return value(THIS->stroke()); } static VALUE no_stroke(VALUE self) { CHECK; THIS->no_stroke(); return self; } static VALUE set_stroke_width(VALUE self, VALUE width) { CHECK; THIS->set_stroke_width(to(width)); return self; } static VALUE get_stroke_width(VALUE self) { CHECK; return value(THIS->stroke_width()); } static VALUE set_stroke_cap(VALUE self, VALUE cap) { CHECK; THIS->set_stroke_cap(to(cap)); return self; } static VALUE get_stroke_cap(VALUE self) { CHECK; return value(THIS->stroke_cap()); } static VALUE set_stroke_join(VALUE self, VALUE join) { CHECK; THIS->set_stroke_join(to(join)); return self; } static VALUE get_stroke_join(VALUE self) { CHECK; return value(THIS->stroke_join()); } static VALUE set_miter_limit(VALUE self, VALUE limit) { CHECK; THIS->set_miter_limit(to(limit)); return self; } static VALUE get_miter_limit(VALUE self) { CHECK; return value(THIS->miter_limit()); } static VALUE set_nsegment(VALUE self, VALUE nsegment) { CHECK; THIS->set_nsegment(nsegment ? to(nsegment) : 0); return self; } static VALUE get_nsegment(VALUE self) { CHECK; return value(THIS->nsegment()); } static VALUE set_blend_mode(VALUE self, VALUE mode) { CHECK; THIS->set_blend_mode(to(mode)); return self; } static VALUE get_blend_mode(VALUE self) { CHECK; return value(THIS->blend_mode()); } static VALUE set_clip(VALUE self) { CHECK; THIS->set_clip(to(argc, argv)); return self; } static VALUE get_clip(VALUE self) { CHECK; return value(THIS->clip()); } static VALUE no_clip(VALUE self) { CHECK; THIS->no_clip(); return self; } static VALUE set_font(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#set_font", argc, 0, 1, 2); THIS->set_font(to(argc, argv)); return self; } static VALUE get_font(VALUE self) { CHECK; return value(THIS->font()); } static VALUE set_shader(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#set_shader", argc, 1); if (argc >= 1 && !argv[0]) THIS->no_shader(); else THIS->set_shader(to(argc, argv)); return self; } static VALUE get_shader(VALUE self) { CHECK; const Rays::Shader& shader = THIS->shader(); return shader ? value(shader) : nil(); } static VALUE no_shader(VALUE self) { CHECK; THIS->no_shader(); return self; } static VALUE push_state(VALUE self) { CHECK; THIS->push_state(); return self; } static VALUE pop_state(VALUE self) { CHECK; THIS->pop_state(); return self; } static VALUE translate(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#translate", argc, 2, 3); coord xx = to(argv[0]); coord yy = to(argv[1]); coord zz = (argc >= 3) ? to(argv[2]) : 0; THIS->translate(xx, yy, zz); return self; } static VALUE scale(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#scale", argc, 2, 3); coord xx = to(argv[0]); coord yy = to(argv[1]); coord zz = (argc >= 3) ? to(argv[2]) : 1; THIS->scale(xx, yy, zz); return self; } static VALUE rotate(VALUE self) { CHECK; check_arg_count(__FILE__, __LINE__, "Painter#rotate", argc, 1, 3, 4); coord aa = to(argv[0]), xx = 0, yy = 0, zz = 1; if (argc >= 3) { xx = to(argv[1]); yy = to(argv[2]); zz = argc >= 4 ? to(argv[3]) : 0; } THIS->rotate(aa, xx, yy, zz); return self; } static VALUE set_matrix(VALUE self) { CHECK; THIS->set_matrix(to(argc, argv)); return value(THIS->matrix()); } static VALUE get_matrix(VALUE self) { CHECK; return value(THIS->matrix()); } static VALUE push_matrix(VALUE self) { CHECK; THIS->push_matrix(); return self; } static VALUE pop_matrix(VALUE self) { CHECK; THIS->pop_matrix(); return self; } static Class cPainter; void Init_rays_painter () { Module mRays = rb_define_module("Rays"); cPainter = rb_define_class_under(mRays, "Painter", rb_cObject); rb_define_alloc_func(cPainter, alloc); rb_define_method(cPainter, "canvas", RUBY_METHOD_FUNC(canvas), -1); rb_define_method(cPainter, "bounds", RUBY_METHOD_FUNC(bounds), 0); rb_define_method(cPainter, "pixel_density", RUBY_METHOD_FUNC(pixel_density), 0); rb_define_private_method(cPainter, "begin_paint", RUBY_METHOD_FUNC(begin_paint), 0); rb_define_private_method(cPainter, "end_paint", RUBY_METHOD_FUNC(end_paint), 0); cPainter.define_method( "painting?", is_painting); rb_define_method(cPainter, "clear", RUBY_METHOD_FUNC(clear), 0); rb_define_method(cPainter, "polygon", RUBY_METHOD_FUNC(polygon), 1); rb_define_private_method(cPainter, "draw_line", RUBY_METHOD_FUNC(line), 2); rb_define_private_method(cPainter, "draw_polyline", RUBY_METHOD_FUNC(polyline), 1); rb_define_private_method(cPainter, "draw_rect", RUBY_METHOD_FUNC(rect), 6); rb_define_private_method(cPainter, "draw_ellipse", RUBY_METHOD_FUNC(ellipse), 6); rb_define_private_method(cPainter, "draw_curve", RUBY_METHOD_FUNC(curve), 2); rb_define_private_method(cPainter, "draw_bezier", RUBY_METHOD_FUNC(bezier), 2); rb_define_method(cPainter, "image", RUBY_METHOD_FUNC(image), -1); rb_define_method(cPainter, "text", RUBY_METHOD_FUNC(text), -1); rb_define_method(cPainter, "background=", RUBY_METHOD_FUNC(set_background), -1); rb_define_method(cPainter, "background", RUBY_METHOD_FUNC(get_background), 0); rb_define_method(cPainter, "no_background", RUBY_METHOD_FUNC(no_background), 0); rb_define_method(cPainter, "fill=", RUBY_METHOD_FUNC(set_fill), -1); rb_define_method(cPainter, "fill", RUBY_METHOD_FUNC(get_fill), 0); rb_define_method(cPainter, "no_fill", RUBY_METHOD_FUNC(no_fill), 0); rb_define_method(cPainter, "stroke=", RUBY_METHOD_FUNC(set_stroke), -1); rb_define_method(cPainter, "stroke", RUBY_METHOD_FUNC(get_stroke), 0); rb_define_method(cPainter, "no_stroke", RUBY_METHOD_FUNC(no_stroke), 0); rb_define_method(cPainter, "stroke_width=", RUBY_METHOD_FUNC(set_stroke_width), 1); rb_define_method(cPainter, "stroke_width", RUBY_METHOD_FUNC(get_stroke_width), 0); rb_define_method(cPainter, "stroke_cap=", RUBY_METHOD_FUNC(set_stroke_cap), 1); rb_define_method(cPainter, "stroke_cap", RUBY_METHOD_FUNC(get_stroke_cap), 0); rb_define_method(cPainter, "stroke_join=", RUBY_METHOD_FUNC(set_stroke_join), 1); rb_define_method(cPainter, "stroke_join", RUBY_METHOD_FUNC(get_stroke_join), 0); rb_define_method(cPainter, "miter_limit=", RUBY_METHOD_FUNC(set_miter_limit), 1); rb_define_method(cPainter, "miter_limit", RUBY_METHOD_FUNC(get_miter_limit), 0); rb_define_method(cPainter, "nsegment=", RUBY_METHOD_FUNC(set_nsegment), 1); rb_define_method(cPainter, "nsegment", RUBY_METHOD_FUNC(get_nsegment), 0); rb_define_method(cPainter, "blend_mode=", RUBY_METHOD_FUNC(set_blend_mode), 1); rb_define_method(cPainter, "blend_mode", RUBY_METHOD_FUNC(get_blend_mode), 0); rb_define_method(cPainter, "clip=", RUBY_METHOD_FUNC(set_clip), -1); rb_define_method(cPainter, "clip", RUBY_METHOD_FUNC(get_clip), 0); rb_define_method(cPainter, "no_clip", RUBY_METHOD_FUNC(no_clip), 0); rb_define_method(cPainter, "font=", RUBY_METHOD_FUNC(set_font), -1); rb_define_method(cPainter, "font", RUBY_METHOD_FUNC(get_font), 0); rb_define_private_method(cPainter, "set_shader", RUBY_METHOD_FUNC(set_shader), -1); rb_define_method(cPainter, "shader", RUBY_METHOD_FUNC(get_shader), 0); rb_define_method(cPainter, "no_shader", RUBY_METHOD_FUNC(no_shader), 0); rb_define_method(cPainter, "push_state", RUBY_METHOD_FUNC(push_state), 0); rb_define_method(cPainter, "pop_state", RUBY_METHOD_FUNC(pop_state), 0); rb_define_method(cPainter, "translate", RUBY_METHOD_FUNC(translate), -1); rb_define_method(cPainter, "scale", RUBY_METHOD_FUNC(scale), -1); rb_define_method(cPainter, "rotate", RUBY_METHOD_FUNC(rotate), -1); rb_define_method(cPainter, "matrix=", RUBY_METHOD_FUNC(set_matrix), -1); rb_define_method(cPainter, "matrix", RUBY_METHOD_FUNC(get_matrix), 0); rb_define_method(cPainter, "push_matrix", RUBY_METHOD_FUNC(push_matrix), 0); rb_define_method(cPainter, "pop_matrix", RUBY_METHOD_FUNC(pop_matrix), 0); } namespace Rays { Class painter_class () { return cPainter; } }// Rays