/** bezier curve algorithm **/ static void bezier_point(VALUE points, float u, float * x, float * y, int n, int format, int draw_offset_x, int draw_offset_y) { int xy_index; double sumx = 0, sumy = 0; for(int k = 0; k < n; k++) { switch(format) { case POINT_FORMAT: sumx += NUM2DBL(point_x(get_from_array(points, k))) * bernstein(n - 1, k, u); sumy += NUM2DBL(point_y(get_from_array(points, k))) * bernstein(n - 1, k, u); break; case SIMPLE_FORMAT: xy_index = k * 2; sumx += NUM2DBL(get_from_array(points, xy_index)) * bernstein(n - 1, k, u); sumy += NUM2DBL(get_from_array(points, xy_index + 1)) * bernstein(n - 1, k, u); break; default: rb_raise(rb_eArgError, "pixel format must be either POINT_FORMAT or SIMPLE_FORMAT"); } } *x = sumx + draw_offset_x; *y = sumy + draw_offset_y; }
err_t gui_widget_begin_paint(gui_widget_t* widget, painter_t* painter, const rect_t* rect) { if(painter == NULL) return E_NULL_POINTER; RETURN_ERR_IF_FAIL(painter_init(painter, gui_graphics(gui_object_gui(GUI_OBJECT(widget))))); point_t widget_point; rect_t widget_rect; gui_widget_screen_visible_position(widget, &widget_point, &widget_rect); rect_t paint_rect; if(rect != NULL){ rect_copy(&paint_rect, rect); rect_clip(&paint_rect, &widget_rect); }else{ rect_copy(&paint_rect, &widget_rect); } painter_set_scissor_rect(painter, &paint_rect); painter_set_scissor_enabled(painter, true); painter_set_offset(painter, point_x(&widget_point), point_y(&widget_point)); painter_set_offset_enabled(painter, true); return E_NO_ERROR; }
void link_nodes(t_hex *self) { int i, p, d, nx, ny, ncode; t_node *node; for (i = 0; i < self->count; ++i) { node = &self->nodes_by_id[i]; p = node->pos; for (d = 0; d < NB_DIRS; ++d) { nx = point_x(p) + DIRS[d][0]; ny = point_y(p) + DIRS[d][1]; ncode = make_point(nx, ny); if (contains_pos(self, ncode)) { append_link(node, self->nodes_by_pos[ncode]->id); } } } }
trace_match line_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) { int x, y, W, H, F; int xinc, yinc; action_struct cur; int thickness = 1; bool has_trace = false; rgba trace_color; trace_mode_type trace_mode = no_mode; if(has_optional_hash_arg(hash_arg, "thickness")) thickness = NUM2INT(get_from_hash(hash_arg, "thickness")); if(has_optional_hash_arg(hash_arg, "trace") && primary) { VALUE trace_hash = get_from_hash(hash_arg, "trace"); /* we're tracing (not drawing) */ has_trace = true; /* since we're not drawing, no need to sync */ sync_mode = no_sync; if(has_optional_hash_arg(trace_hash, "until_color")) { VALUE c = get_from_hash(trace_hash, "until_color"); trace_color = convert_rb_color_to_rgba(c); trace_mode = until_color; } else if(has_optional_hash_arg(trace_hash, "while_color")) { VALUE c = get_from_hash(trace_hash, "while_color"); trace_color = convert_rb_color_to_rgba(c); trace_mode = while_color; } } draw_prologue(&cur, tex, x1, y1, x2, y2, &hash_arg, sync_mode, primary, &payload); /* clip the line */ cohen_sutherland_clip(&x1, &y1, &x2, &y2, 0, 0, tex->width - 1, tex->height - 1); W = ABS(x2 - x1); H = ABS(y2 - y1); if(x1 < x2) xinc = 1; else xinc = -1; if(y1 < y2) yinc = 1; else yinc = -1; x = x1; y = y1; if(W >= H) { F = 2 * H - W; while(x != x2) { if(thickness <= 1) { if(!has_trace) set_pixel_color_with_style(payload, tex, x, y); else { rgba c = get_pixel_color(tex, x, y); if (is_trace_match(payload, c, trace_color, trace_mode)) return (trace_match) { x, y, c }; } } else { set_hash_value(hash_arg, "fill", Qtrue); circle_do_action(x, y, thickness / 2, tex, hash_arg, no_sync, false, payload); } if(F < 0) F += 2 * H; else { F += 2 * (H - W); y += yinc; } x += xinc; } } else { F = 2 * W - H; while(y != y2 ) { if(thickness <= 1) { if(!has_trace) set_pixel_color_with_style(payload, tex, x, y); else { rgba c = get_pixel_color(tex, x, y); if (is_trace_match(payload, c, trace_color, trace_mode)) return (trace_match) { x, y, c }; } } else { set_hash_value(hash_arg, "fill", Qtrue); circle_do_action(x, y, thickness / 2, tex, hash_arg, no_sync, false, payload); } if(F < 0) F += 2 * W; else { F += 2 * (W - H); x += xinc; } y += yinc; } } if(thickness <= 1) { if(!has_trace) set_pixel_color_with_style(payload, tex, x2, y2); else { rgba c = get_pixel_color(tex, x, y); if (is_trace_match(payload, c, trace_color, trace_mode)) return (trace_match) { x, y, c }; } } else { set_hash_value(hash_arg, "fill", Qtrue); circle_do_action(x2, y2, thickness / 2, tex, hash_arg, no_sync, false, payload); } draw_epilogue(&cur, tex, primary); return (trace_match) { .x = -9999, .y = -9999, .color = not_a_color_v }; } /** end line **/ /** polyline algorithm **/ /* used by both polyline and bezier */ #define SIMPLE_FORMAT 0 #define POINT_FORMAT 1 /* calculate a single point */ static void polyline_point(VALUE points, int k, int * x, int * y, int format, int draw_offset_x, int draw_offset_y) { int xy_index; switch(format) { case POINT_FORMAT: *x = NUM2INT(point_x(get_from_array(points, k))) + draw_offset_x; *y = NUM2INT(point_y(get_from_array(points, k))) + draw_offset_y; break; case SIMPLE_FORMAT: xy_index = k * 2; *x = NUM2INT(get_from_array(points, xy_index)) + draw_offset_x; *y = NUM2INT(get_from_array(points, xy_index + 1)) + draw_offset_y; break; default: rb_raise(rb_eArgError, "pixel format must be either POINT_FORMAT or SIMPLE_FORMAT"); } }