/* * call-seq: * typemap.fit_to_result( result ) * * Check that the type map fits to the result. * * This method is called, when a type map is assigned to a result. * It must return a PG::TypeMap object or raise an Exception. * This can be +self+ or some other type map that fits to the result. * */ static VALUE pg_tmir_fit_to_result( VALUE self, VALUE result ) { t_tmir *this = DATA_PTR( self ); t_typemap *default_tm; t_typemap *p_new_typemap; VALUE sub_typemap; VALUE new_typemap; if( rb_respond_to(self, s_id_fit_to_result) ){ new_typemap = rb_funcall( self, s_id_fit_to_result, 1, result ); if ( !rb_obj_is_kind_of(new_typemap, rb_cTypeMap) ) { rb_raise( rb_eTypeError, "wrong return type from fit_to_result: %s expected kind of PG::TypeMap", rb_obj_classname( new_typemap ) ); } Check_Type( new_typemap, T_DATA ); } else { new_typemap = self; } /* Ensure that the default type map fits equaly. */ default_tm = DATA_PTR( this->typemap.default_typemap ); sub_typemap = default_tm->funcs.fit_to_result( this->typemap.default_typemap, result ); if( sub_typemap != this->typemap.default_typemap ){ new_typemap = rb_obj_dup( new_typemap ); } p_new_typemap = DATA_PTR(new_typemap); p_new_typemap->default_typemap = sub_typemap; return new_typemap; }
/** * @call * Font.new -> font 对象。 * Font.new(font_name) -> font 对象。 * Font.new(font_name, font_size) -> font 对象。 * * @desc * 创建一个字体对象。 */ VALUE CRbFont::initialize(int argc, VALUE * argv, VALUE obj) { // 检查参数个数 if(argc > 2) rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc); // 检查参数有效性 if(argc > 0) SafeStringValue(argv[0]); if(argc > 1) SafeFontSetSize(argv[1]); // 初始化默认属性 m_name = rb_obj_dup(argc > 0 ? argv[0] : dm_get_default_name(rb_cFont)); m_size = argc > 1 ? argv[1] : dm_get_default_size(rb_cFont); m_bold = dm_get_default_bold(rb_cFont); m_italic = dm_get_default_italic(rb_cFont); m_shadow = dm_get_default_shadow(rb_cFont); VALUE __argv[1] = { ULONG2NUM(GetObjectPtr<CRbColor>(__default_color__)->GetColor()) }; VALUE color = rb_class_new_instance(1, __argv, rb_cColor);//CRbColor::dm_clone(dm_get_default_color(rb_cFont)); m_color_ptr = GetObjectPtr<CRbColor>(color); // 创建逻辑字体 m_lfw.lfHeight = FIX2INT(m_size); m_lfw.lfItalic = (BYTE)RTEST(m_italic); m_lfw.lfWeight = RTEST(m_bold) ? FW_BOLD : FW_NORMAL; wcscpy_s(m_lfw.lfFaceName, Kconv::UTF8ToUnicode(RSTRING_PTR(m_name))); m_hFont = CreateFontIndirectW(&m_lfw); return obj; }
static void * rb_obj_imp_copyWithZone(void *rcv, SEL sel, void *zone) { // XXX honor zone? // for now let rb_obj_dup allocate an instance, since we don't honor the // zone yet anyways return (void *)rb_obj_dup((VALUE)rcv); }
/** rectangle algorithm **/ void rect_do_action(int x1, int y1, int x2, int y2, texture_info * tex, VALUE hash_arg, texplay_sync sync_mode, bool primary, action_struct * payload) { action_struct cur; bool fill = false; int thickness = 1; draw_prologue(&cur, tex, x1, y1, x2, y2, &hash_arg, sync_mode, primary, &payload); if(is_a_hash(hash_arg)) { /* make our private copy of the hash so we can mess with it */ hash_arg = rb_obj_dup(hash_arg); if(RTEST(get_from_hash(hash_arg, "fill")) || RTEST(get_from_hash(hash_arg, "filled"))) { fill = true; /* since we're filling the rect, line thickness is irrelevant */ delete_from_hash(hash_arg, "thickness"); } else if(RTEST(get_from_hash(hash_arg, "thickness"))) { thickness = NUM2INT(get_from_hash(hash_arg, "thickness")); /* TO DO: find a better way of doing this */ if(thickness > 1) { cur.xmin = x1 - thickness / 2; cur.ymin = y1 - thickness / 2; cur.xmax = x2 + thickness / 2 + 1; cur.ymax = y2 + thickness / 2 + 1; } } } if(!fill) { line_do_action(x1, y1, x2, y1, tex, hash_arg, no_sync, false, payload); line_do_action(x1, y1, x1, y2, tex, hash_arg, no_sync, false, payload); line_do_action(x1, y2, x2, y2, tex, hash_arg, no_sync, false, payload); line_do_action(x2, y1, x2, y2, tex, hash_arg, no_sync, false, payload); } else { if(y1 > y2) SWAP(y1, y2); for(int y = y1; y <= y2; y++) line_do_action(x1, y, x2, y, tex, hash_arg, no_sync, false, payload); } draw_epilogue(&cur, tex, primary); }
/* * (see Pointer#order) */ static VALUE struct_order(int argc, VALUE* argv, VALUE self) { Struct* s; Data_Get_Struct(self, Struct, s); if (argc == 0) { return rb_funcall(s->rbPointer, rb_intern("order"), 0); } else { VALUE retval = rb_obj_dup(self); VALUE rbPointer = rb_funcall2(s->rbPointer, rb_intern("order"), argc, argv); struct_set_pointer(retval, rbPointer); return retval; } }
/* * call-seq: * enum.each {...} * * Iterates over the block according to how this Enumerable was constructed. * If no block is given, returns self. * */ static VALUE enumerator_each(int argc, VALUE *argv, VALUE obj) { if (argc > 0) { struct enumerator *e = enumerator_ptr(obj = rb_obj_dup(obj)); VALUE args = e->args; if (args) { args = rb_ary_dup(args); rb_ary_cat(args, argv, argc); } else { args = rb_ary_new4(argc, argv); } e->args = args; } if (!rb_block_given_p()) return obj; return enumerator_block_call(obj, 0, obj); }
/* * Create a Pathname object from the given String (or String-like object). * If +path+ contains a NULL character (<tt>\0</tt>), an ArgumentError is raised. */ static VALUE path_initialize(VALUE self, VALUE arg) { VALUE str; if (RB_TYPE_P(arg, T_STRING)) { str = arg; } else { str = rb_check_funcall(arg, id_to_path, 0, NULL); if (str == Qundef) str = arg; StringValue(str); } if (memchr(RSTRING_PTR(str), '\0', RSTRING_LEN(str))) rb_raise(rb_eArgError, "pathname contains null byte"); str = rb_obj_dup(str); set_strpath(self, str); OBJ_INFECT(self, str); return self; }
VALUE shoes_canvas_style(int argc, VALUE *argv, VALUE self) { rb_arg_list args; SETUP_CANVAS(); switch (rb_parse_args(argc, argv, "kh,h,", &args)) { case 1: shoes_app_style(canvas->app, args.a[0], args.a[1]); break; case 2: if (NIL_P(canvas->attr)) canvas->attr = rb_hash_new(); rb_funcall(canvas->attr, s_update, 1, args.a[0]); shoes_canvas_repaint_all(canvas->parent); break; case 3: return rb_obj_freeze(rb_obj_dup(canvas->attr)); } return self; }
static VALUE aspirin_response_create_env(VALUE obj, VALUE default_env) { VALUE env = rb_obj_dup(default_env); Aspirin_Response *response; Data_Get_Struct(obj, Aspirin_Response, response); struct evhttp_request *request = response->request; set_rack_input(env, request->input_buffer); set_rack_errors(env); set_request_method(env, request->type); set_remote_host(env, request->remote_host); set_http_version(env, request->major, request->minor); set_async_callback(env, obj); set_request_uri(env, evhttp_request_uri(request)); set_request_path(env, evhttp_request_uri(request)); set_http_header(env, request->input_headers); return env; }
/* * call-seq: * pathname.to_s -> string * pathname.to_path -> string * * Return the path as a String. * * to_path is implemented so Pathname objects are usable with File.open, etc. */ static VALUE path_to_s(VALUE self) { return rb_obj_dup(get_strpath(self)); }
void ray_drawable_copy_attr(VALUE self, VALUE orig) { VALUE attr = rb_iv_get(orig, "@shader_attributes"); if (!NIL_P(attr)) rb_iv_set(self, "@shader_attributes", rb_obj_dup(attr)); }
void bezier_do_action(VALUE points, texture_info * tex, VALUE hash_arg, texplay_sync sync_mode, bool primary, action_struct * payload) { float u = 0.0; action_struct cur; float x1, y1, x2, y2; int first_x, first_y; int format; int num_point_pairs; bool closed = false; VALUE offset_val; int draw_offset_x, draw_offset_y; /* defaults to 200 (1 / 0.005) samples per curve */ float step_size = 0.005; draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload); /* calculate offset */ offset_val = get_image_local(tex->image, DRAW_OFFSET); draw_offset_x = NUM2INT(get_from_array(offset_val, 0)); draw_offset_y = NUM2INT(get_from_array(offset_val, 1)); if(is_a_hash(hash_arg)) { /* if the polyline is 'closed' make the last point the first */ if(RTEST(get_from_hash(hash_arg, "closed")) || RTEST(get_from_hash(hash_arg, "close"))) { /* so that our additional point is not persistent */ points = rb_obj_dup(points); closed = true; } /* number of points to sample */ if(RTEST(get_from_hash(hash_arg, "sample_size"))) { VALUE c = get_from_hash(hash_arg, "sample_size"); Check_Type(c, T_FIXNUM); step_size = 1.0 / (float)FIX2INT(c); } } if(is_a_point(get_from_array(points, 0))) { format = POINT_FORMAT; if(closed) rb_ary_push(points, get_from_array(points, 0)); num_point_pairs = RARRAY_LEN(points); } else { format = SIMPLE_FORMAT; /* ensure points are given in pairs */ if(RARRAY_LEN(points) % 2) rb_raise(rb_eArgError, "bezier needs an even number of points. got %d\n", (int)RARRAY_LEN(points)); if(closed) { rb_ary_push(points, get_from_array(points, 0)); rb_ary_push(points, get_from_array(points, 1)); } num_point_pairs = RARRAY_LEN(points) / 2; } if(num_point_pairs > 17) rb_raise(rb_eArgError, "too many points for bezier curve. 17 points is current maximum. got %d\n", num_point_pairs); /* get the first point */ bezier_point(points, 0, &x1, &y1, num_point_pairs, format, draw_offset_x, draw_offset_y); /* save it so we can link up with last point properly if the curve is 'closed' */ first_x = x1; first_y = y1; while(u <= 1) { bezier_point(points, u, &x2, &y2, num_point_pairs, format, draw_offset_x, draw_offset_y); line_do_action(x1, y1, x2, y2, tex, hash_arg, no_sync, false, payload); /* update drawing rectangle */ update_bounds(payload, x1, y1, x2, y2); x1 = x2; y1 = y2; u += step_size; } /* sometimes beziers dont close properly, so we'll ensure it's closed */ if(closed) line_do_action(x2, y2, first_x, first_y, tex, hash_arg, no_sync, false, payload); draw_epilogue(&cur, tex, primary); }
/** midpoint circle algorithm **/ void circle_do_action(int x1, int y1, int r, texture_info * tex, VALUE hash_arg, texplay_sync sync_mode, bool primary, action_struct * payload) { int x, y; float p; action_struct cur; bool fill = false; draw_prologue(&cur, tex, x1 - r, y1 - r, x1 + r, y1 + r, &hash_arg, sync_mode, primary, &payload); if(is_a_hash(hash_arg)) { /* make our private copy of the hash so we can mess with it */ hash_arg = rb_obj_dup(hash_arg); if(RTEST(get_from_hash(hash_arg, "fill")) || RTEST(get_from_hash(hash_arg, "filled"))) { fill = true; /* to prevent infinite recursion set line thickness to 1 :D NB: a filled circle uses lines and a thick line uses filled circles :D */ delete_from_hash(hash_arg, "thickness"); } } x = 0 ; y = r; p = 5 / 4 - r; if(!fill) { while (x <= y) { set_pixel_color_with_style(payload, tex, x1 + x, y1 + y); set_pixel_color_with_style(payload, tex, x1 + x, y1 - y); set_pixel_color_with_style(payload, tex, x1 - x, y1 + y); set_pixel_color_with_style(payload, tex, x1 - x, y1 - y); set_pixel_color_with_style(payload, tex, x1 + y, y1 + x); set_pixel_color_with_style(payload, tex, x1 + y, y1 - x); set_pixel_color_with_style(payload, tex, x1 - y, y1 + x); set_pixel_color_with_style(payload, tex, x1 - y, y1 - x); if (p < 0) { p += 2 * x + 3; } else { y--; p += 2 * (x - y) + 5; } x++; } } else { while (x <= y) { line_do_action(x1 - x, y1 + y, x1 + x, y1 + y, tex, hash_arg, no_sync, false, payload); line_do_action(x1 - x, y1 - y, x1 + x, y1 - y, tex, hash_arg, no_sync, false, payload); line_do_action(x1 - y, y1 + x, x1 + y, y1 + x, tex, hash_arg, no_sync, false, payload); line_do_action(x1 - y, y1 - x, x1 + y, y1 - x, tex, hash_arg, no_sync, false, payload); if (p < 0) { p += 2 * x + 3; } else { y--; p += 2 * (x - y) + 5; } x++; } } draw_epilogue(&cur, tex, primary); }
void polyline_do_action(VALUE points, texture_info * tex, VALUE hash_arg, texplay_sync sync_mode, bool primary, action_struct * payload) { int x1, y1, x2, y2; int format; int num_point_pairs; int k; int draw_offset_y, draw_offset_x; action_struct cur; VALUE offset_val; bool closed = false; draw_prologue(&cur, tex, XMAX_OOB, YMAX_OOB, XMIN_OOB, YMIN_OOB, &hash_arg, sync_mode, primary, &payload); /* calculate offset */ offset_val = get_image_local(tex->image, DRAW_OFFSET); draw_offset_x = NUM2INT(get_from_array(offset_val, 0)); draw_offset_y = NUM2INT(get_from_array(offset_val, 1)); /* if the polyline is 'closed' make the last point the first */ if(is_a_hash(hash_arg)) if(RTEST(get_from_hash(hash_arg, "closed")) || RTEST(get_from_hash(hash_arg, "close"))) { /* so that our additional point is not persistent */ points = rb_obj_dup(points); closed = true; } /* determine format of points */ if(is_a_point(get_from_array(points, 0))) { format = POINT_FORMAT; /* if the polyline is closed to form a polygon then make the last point and first point identical */ if(closed) rb_ary_push(points, get_from_array(points, 0)); num_point_pairs = RARRAY_LEN(points); } else { format = SIMPLE_FORMAT; /* ensure there is an 'x' for every 'y' */ if(RARRAY_LEN(points) % 2) rb_raise(rb_eArgError, "polyline needs an even number of points. got %d\n", (int)RARRAY_LEN(points)); if(closed) { rb_ary_push(points, get_from_array(points, 0)); rb_ary_push(points, get_from_array(points, 1)); } num_point_pairs = RARRAY_LEN(points) / 2; } /* calculate first point */ polyline_point(points, 0, &x1, &y1, format, draw_offset_x, draw_offset_y); /* calc the points and draw the polyline */ for(k = 1; k < num_point_pairs; k++) { polyline_point(points, k, &x2, &y2, format, draw_offset_x, draw_offset_y); line_do_action(x1, y1, x2, y2, tex, hash_arg, no_sync, false, payload); /* update drawing rectangle */ update_bounds(payload, x1, y1, x2, y2); x1 = x2; y1 = y2; } draw_epilogue(&cur, tex, primary); }