static void draw_line (GtkWidget *widget, GdkEventButton *event, gamine_t *cb) { cairo_t *drawingline; //for the first draw if (! xold) { xold=event->x+1; yold=event->y; } else { float red = ((rand() % 128) + 127) /255.0; float green = ((rand() % 128) + 127) /255.0; float blue = ((rand() % 128) + 127) /255.0; drawingline = get_cairo_context(cb); cairo_new_path (drawingline); cairo_set_source_rgba (drawingline, red, green, blue, 0.5); cairo_set_line_width (drawingline, linewidth); //move the cursor cairo_move_to (drawingline, xold, yold); //line for old cursor to new one's cairo_line_to (drawingline, event->x+1, event->y); //draw cairo_stroke (drawingline); xold=event->x+1; yold=event->y; } }
ETERM * rel_curve_to(ETERM* arg, int c_node) { ETERM *c1x, *c1y, *c2x, *c2y, *x, *y; cairo_context *ctx = get_cairo_context(arg); if (ctx) { c1x = erl_element(2, arg); c1y = erl_element(3, arg); c2x = erl_element(4, arg); c2y = erl_element(5, arg); x = erl_element(6, arg); y = erl_element(7, arg); cairo_rel_curve_to(ctx->cr, val(c1x), val(c1y), val(c2x), val(c2y), val(x), val(y)); erl_free_term(c1x); erl_free_term(c1y); erl_free_term(c2x); erl_free_term(c2y); erl_free_term(x); erl_free_term(y); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
static void draw_star (GtkWidget *widget, GdkEventButton *event, gamine_t *cb) { const gint spike_count = random() % 6 + 2; const gint inner_radius = objectweight; const gint outer_radius = 20; gfloat red = random() % 10 * 0.1; gfloat green = random() % 10 * 0.1; gfloat blue = random() % 10 * 0.1; cairo_t *cr; gdouble x, y; int i; cr = get_cairo_context(cb); play_random_sound(cb->bus); cairo_set_source_rgb (cr, red, green, blue); cairo_new_path (cr); for (i = 0; i < spike_count + 1; i++) { x = event->x + cos ((i * 2) * M_PI / spike_count) * inner_radius; y = event->y + sin ((i * 2) * M_PI / spike_count) * inner_radius; if (i == 0) cairo_move_to (cr, x, y); else cairo_line_to (cr, x, y); x = event->x + cos ((i * 2 + 1) * M_PI / spike_count) * outer_radius; y = event->y + sin ((i * 2 + 1) * M_PI / spike_count) * outer_radius; cairo_line_to (cr, x, y); } cairo_fill (cr); }
ETERM * stroke_preserve(ETERM* arg, int c_node) { cairo_context *ctx = get_cairo_context(arg); if (ctx) { cairo_stroke_preserve(ctx->cr); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * close_image(ETERM* arg, int c_node) { cairo_context *ctx = get_cairo_context(arg); if (ctx) { cairo_destroy(ctx->cr); cairo_surface_destroy(ctx->sf); free(ctx->cbuf); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * rotate(ETERM* arg, int c_node) { ETERM *angle; cairo_context *ctx = get_cairo_context(arg); if (ctx) { angle = erl_element(2, arg); cairo_rotate(ctx->cr, val(angle)); erl_free_term(angle); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * set_font_size(ETERM* arg, int c_node) { ETERM *size; cairo_context *ctx = get_cairo_context(arg); if (ctx) { size = erl_element(2, arg); cairo_set_font_size(ctx->cr, val(size)); erl_free_term(size); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * show_text(ETERM* arg, int c_node) { ETERM *text; cairo_context *ctx = get_cairo_context(arg); if (ctx) { text = erl_element(2, arg); cairo_show_text(ctx->cr, (char *)ERL_ATOM_PTR(text)); erl_free_term(text); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * set_operator(ETERM* arg, int c_node) { ETERM *operator; cairo_context *ctx = get_cairo_context(arg); if (ctx) { operator = erl_element(2, arg); cairo_set_operator(ctx->cr, ERL_INT_VALUE(operator)); erl_free_term(operator); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * set_line_width(ETERM* arg, int c_node) { ETERM *width; cairo_context *ctx = get_cairo_context(arg); if (ctx) { width = erl_element(2, arg); cairo_set_line_width(ctx->cr, ERL_INT_VALUE(width)); erl_free_term(width); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * write_to_png(ETERM* arg, int c_node) { int status; ETERM *file; cairo_context *ctx = get_cairo_context(arg); if (ctx) { file = erl_element(2, arg); status = cairo_surface_write_to_png(ctx->sf, (char *)ERL_ATOM_PTR(file)); erl_free_term(file); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * text_extents(ETERM* arg, int c_node) { ETERM *text; cairo_text_extents_t extents; cairo_context *ctx = get_cairo_context(arg); if (ctx) { text = erl_element(2, arg); cairo_text_extents (ctx->cr, (char *)ERL_ATOM_PTR(text), &extents); erl_free_term(text); return erl_format("{c_node, ~i, {~f, ~f}}", c_node, extents.width, extents.height); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * scale(ETERM* arg, int c_node) { ETERM *sx, *sy; cairo_context *ctx = get_cairo_context(arg); if (ctx) { sx = erl_element(2, arg); sy = erl_element(3, arg); cairo_scale(ctx->cr, val(sx), val(sy)); erl_free_term(sx); erl_free_term(sy); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * rel_line_to(ETERM* arg, int c_node) { ETERM *x, *y; cairo_context *ctx = get_cairo_context(arg); if (ctx) { x = erl_element(2, arg); y = erl_element(3, arg); cairo_rel_line_to(ctx->cr, val(x), val(y)); erl_free_term(x); erl_free_term(y); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * translate(ETERM* arg, int c_node) { ETERM *tx, *ty; cairo_context *ctx = get_cairo_context(arg); if (ctx) { tx = erl_element(2, arg); ty = erl_element(3, arg); cairo_translate(ctx->cr, val(tx), val(ty)); erl_free_term(tx); erl_free_term(ty); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * set_source_surface(ETERM* arg, int c_node) { ETERM *surface, *x, *y; cairo_context *ctx = get_cairo_context(arg); if (ctx) { surface = erl_element(2, arg); x = erl_element(3, arg); y = erl_element(4, arg); cairo_set_source_surface(ctx->cr, ptr(surface), val(x), val(y)); erl_free_term(surface); erl_free_term(x); erl_free_term(y); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * select_font_face(ETERM* arg, int c_node) { ETERM *family, *slant, *weight; cairo_context *ctx = get_cairo_context(arg); if (ctx) { family = erl_element(2, arg); slant = erl_element(3, arg); weight = erl_element(4, arg); cairo_select_font_face(ctx->cr, (char *)ERL_ATOM_PTR(family), ERL_INT_VALUE(slant), val(weight)); erl_free_term(family); erl_free_term(slant); erl_free_term(weight); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * set_source_rgba(ETERM* arg, int c_node) { ETERM *r, *g, *b, *a; cairo_context *ctx = get_cairo_context(arg); if (ctx) { r = erl_element(2, arg); g = erl_element(3, arg); b = erl_element(4, arg); a = erl_element(5, arg); cairo_set_source_rgba(ctx->cr, ERL_FLOAT_VALUE(r), val(g), val(b), val(a)); erl_free_term(r); erl_free_term(g); erl_free_term(b); erl_free_term(a); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
static void draw_string ( gamine_t *cb, gint cx, gint cy, gchar *str) { cairo_t *cr; gfloat red = random() % 10 * 0.1; gfloat green = random() % 10 * 0.1; gfloat blue = random() % 10 * 0.1; play_random_sound(cb->bus); cr = get_cairo_context(cb); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, fontweight); cairo_move_to (cr, cx - 15, cy + 15); cairo_set_source_rgb (cr, red, green, blue); cairo_show_text (cr, str); cairo_stroke (cr); }
ETERM * rectangle(ETERM* arg, int c_node) { ETERM *x1, *y1, *x2, *y2; cairo_context *ctx = get_cairo_context(arg); if (ctx) { x1 = erl_element(2, arg); y1 = erl_element(3, arg); x2 = erl_element(4, arg); y2 = erl_element(5, arg); cairo_rectangle(ctx->cr, val(x1), val(y1), val(x2), val(y2)); erl_free_term(x1); erl_free_term(y1); erl_free_term(x2); erl_free_term(y2); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }
ETERM * write_to_png_stream(ETERM* arg, int c_node) { cairo_context * const ctx = get_cairo_context(arg); if(!ctx) return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); struct png_data out = {}; const int status = cairo_surface_write_to_png_stream(ctx->sf, write_cb, &out); ETERM *term = NULL; ei_x_buff req; ei_x_new_with_version(&req); ei_x_encode_tuple_header(&req, 3); ei_x_encode_atom(&req, "c_node"); ei_x_encode_long(&req, c_node); ei_x_encode_tuple_header(&req, 2); ei_x_encode_atom(&req, "ok"); ei_x_encode_binary(&req, out.buf, out.written); int index = 0; ei_decode_term(req.buff, &index, &term); ei_x_free(&req); free(out.buf); return term; }
ETERM * arc_negative(ETERM* arg, int c_node) { ETERM *x, *y, *r, *a1, *a2; cairo_context *ctx = get_cairo_context(arg); if (ctx) { x = erl_element(2, arg); y = erl_element(3, arg); r = erl_element(4, arg); a1 = erl_element(5, arg); a2 = erl_element(6, arg); cairo_arc_negative(ctx->cr, val(x), val(y), val(r), val(a1), val(a2)); erl_free_term(x); erl_free_term(y); erl_free_term(r); erl_free_term(a1); erl_free_term(a2); return erl_format("{c_node, ~i, ok}", c_node); } else { return erl_format("{c_node, ~i, {error, '~s'}}", c_node, ERR_CONTEXT); } }