/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */ /********************************************************************** rbart_bpath.c - $Author: ktou $ $Date: 2005/06/07 14:07:46 $ Copyright (C) 2004 Ruby-GNOME2 Project Team Copyright (C) 2003 Tom Payne **********************************************************************/ #include "rbart.h" VALUE artBpath; #define Bpath_Ptr(r_obj) ((ArtBpath *)(RDATA(r_obj)->data)) /*************************************************/ ArtBpath * get_art_bpath(r_obj) VALUE r_obj; { if (!rb_obj_is_instance_of(r_obj, artBpath)) rb_raise(rb_eTypeError, "not an Art::Bpath"); return Bpath_Ptr(r_obj); } VALUE make_art_bpath(bpath) ArtBpath *bpath; { return Data_Wrap_Struct(artBpath, 0, art_free, bpath); } /*************************************************/ /* * Art::Bpath.new([[pathcode1, x, y,..], [pathcode1, x, y,..]]) * Or Art::Bpath.new([pathcode1, x, y,..], [pathcode1, x, y,..]) * [pathcode1, x, y,..] are: * [Art::MOVETO, x, y] * [Art::MOVETO_OPEN, x, y] * [Art::CURVETO, x1, y1, x2, y2, x3, y3] * [Art::LINETO, x, y] * [Art::END] - Always required at the end of parameters. */ static VALUE bpath_initialize(argc, argv, self) int argc; VALUE *argv; VALUE self; { ArtBpath *bpath; int i; VALUE r_array; if (argc == 1){ VALUE ary; rb_scan_args(argc, argv, "1", &ary); if (TYPE(RARRAY(ary)->ptr) == T_ARRAY){ r_array = (VALUE)(RARRAY(ary)->ptr[0]); } else { r_array = ary; } } else { rb_scan_args(argc, argv, "*", &r_array); } Check_Type(r_array, T_ARRAY); bpath = art_new(ArtBpath, RARRAY(r_array)->len); for (i = 0; i < RARRAY(r_array)->len; i++) { VALUE r_point = RARRAY(r_array)->ptr[i]; Check_Type(r_point, T_ARRAY); if (RARRAY(r_point)->len < 1) rb_raise(rb_eTypeError, "wrong size of Array (expect 1, 3 or 7)"); bpath[i].code = NUM2INT(RARRAY(r_point)->ptr[0]); switch (bpath[i].code) { case ART_MOVETO: case ART_MOVETO_OPEN: case ART_LINETO: if (RARRAY(r_point)->len != 3) rb_raise(rb_eTypeError, "wrong size of Array (expect 3)"); bpath[i].x3 = NUM2DBL(RARRAY(r_point)->ptr[1]); bpath[i].y3 = NUM2DBL(RARRAY(r_point)->ptr[2]); break; case ART_CURVETO: if (RARRAY(r_point)->len != 7) rb_raise(rb_eTypeError, "wrong size of Array (expect 7)"); bpath[i].x1 = NUM2DBL(RARRAY(r_point)->ptr[1]); bpath[i].y1 = NUM2DBL(RARRAY(r_point)->ptr[2]); bpath[i].x2 = NUM2DBL(RARRAY(r_point)->ptr[3]); bpath[i].y2 = NUM2DBL(RARRAY(r_point)->ptr[4]); bpath[i].x3 = NUM2DBL(RARRAY(r_point)->ptr[5]); bpath[i].y3 = NUM2DBL(RARRAY(r_point)->ptr[6]); break; case ART_END: if (RARRAY(r_point)->len != 1) rb_raise(rb_eTypeError, "wrong size of Array (expect 1)"); break; default: rb_raise(rb_eTypeError, "invalid code"); break; } } DATA_PTR(self) = bpath; return Qnil; } static VALUE bpath_affine_transform(r_self, r_affine) VALUE r_self; VALUE r_affine; { return make_art_bpath(art_bpath_affine_transform(get_art_bpath(r_self), get_art_affine(r_affine))); } static VALUE bpath_to_a(r_self) VALUE r_self; { VALUE r_result; ArtBpath *bpath; r_result = rb_ary_new(); for (bpath = get_art_bpath(r_self); bpath->code != ART_END; ++bpath) switch (bpath->code) { case ART_MOVETO: case ART_MOVETO_OPEN: case ART_LINETO: rb_ary_push(r_result, rb_ary_new3(3, INT2NUM(bpath->code), rb_float_new(bpath->x3), rb_float_new(bpath->y3))); break; case ART_CURVETO: rb_ary_push(r_result, rb_ary_new3(7, INT2NUM(bpath->code), rb_float_new(bpath->x1), rb_float_new(bpath->y1), rb_float_new(bpath->x2), rb_float_new(bpath->y2), rb_float_new(bpath->x3), rb_float_new(bpath->y3))); break; default: rb_raise(rb_eTypeError, "invalid code"); break; } rb_ary_push(r_result, rb_ary_new3(1, INT2NUM(ART_END))); return r_result; } static VALUE bpath_to_vpath(r_self, r_flatness) VALUE r_self; VALUE r_flatness; { return make_art_vpath(art_bez_path_to_vec(get_art_bpath(r_self), NUM2DBL(r_flatness))); } void Init_art_bpath(mArt) VALUE mArt; { artBpath = rb_define_class_under(mArt, "Bpath", rb_cData); RBART_INIT_FUNC(artBpath); rb_define_method(artBpath, "initialize", bpath_initialize, -1); rb_define_method(artBpath, "affine_transform", bpath_affine_transform, 1); rb_define_method(artBpath, "to_a", bpath_to_a, 0); rb_define_method(artBpath, "to_vpath", bpath_to_vpath, 1); }