view nodejs/paints.cc @ 734:5ac257be7bc0

Testcase for linear and radial paint for JS
author Thinker K.F. Li <thinker@branda.to>
date Fri, 20 Aug 2010 09:34:49 +0800
parents 163f0d9e6382
children d0ee92a96c47
line wrap: on
line source

#include <v8.h>

extern "C" {
#include "mb.h"
}

#include "mbfly_njs.h"

using namespace v8;

#ifndef ASSERT
#define ASSERT(x)
#endif

/*! \defgroup xnjsmb_paints JS binding for paints
 * \ingroup xnjsmb
 *
 * @{
 */

static void
xnjsmb_paint_fill(paint_t *paint, Handle<Object> self, shape_t *sh) {
    Handle<Value> rt_v;
    Handle<Object> rt_o;
    redraw_man_t *rdman;

    rt_v = GET(self, "mbrt");
    rt_o = rt_v->ToObject();
    rdman = xnjsmb_rt_rdman(rt_o);
    
    rdman_paint_fill(rdman, paint, sh);
    
    if(sh_get_coord(sh))
	rdman_shape_changed(rdman, sh);
}

static void
xnjsmb_paint_stroke(paint_t *paint, Handle<Object> self, shape_t *sh) {
    Handle<Value> rt_v;
    Handle<Object> rt_o;
    redraw_man_t *rdman;

    rt_v = GET(self, "mbrt");
    rt_o = rt_v->ToObject();
    rdman = xnjsmb_rt_rdman(rt_o);
    
    rdman_paint_stroke(rdman, paint, sh);
    
    if(sh_get_coord(sh))
	rdman_shape_changed(rdman, sh);
}

static void
xnjsmb_paint_color_set_color(paint_t *paint, Handle<Object> self,
			     float r, float g, float b, float a) {
    Handle<Value> rt_v;
    Handle<Object> rt_o;
    redraw_man_t *rdman;

    rt_v = GET(self, "mbrt");
    rt_o = rt_v->ToObject();
    rdman = xnjsmb_rt_rdman(rt_o);

    paint_color_set(paint, r, g, b, a);

    rdman_paint_changed(rdman, paint);
}

/*! \brief Set stops for linear paint for Javascript code.
 */
static void
xnjsmb_paint_linear_set_stops(paint_t *paint, Handle<Value> stops) {
    Array *stops_o;
    Array *stop_o;
    int nstops;
    grad_stop_t *grad_stops, *old_grad_stops;
    int i;

    stops_o = Array::Cast(*stops);
    nstops = stops_o->Length();
    grad_stops = (grad_stop_t *)malloc(sizeof(grad_stop_t) * nstops);
    ASSERT(grad_stops != NULL);

    for(i = 0; i < nstops; i++) {
	stop_o = Array::Cast(*stops_o->Get(i));
	ASSERT(stop_o->Length() == 5);
	grad_stop_init(grad_stops + i,
		       stop_o->Get(0)->ToNumber()->Value(),  /* off */
		       stop_o->Get(1)->ToNumber()->Value(),  /* r */
		       stop_o->Get(2)->ToNumber()->Value(),  /* g */
		       stop_o->Get(3)->ToNumber()->Value(),  /* b */
		       stop_o->Get(4)->ToNumber()->Value()); /* a */
    }
    
    old_grad_stops = paint_linear_stops(paint, nstops, grad_stops);
    if(old_grad_stops)
	free(old_grad_stops);	/* The stops, here, were allocated for
				 * previous calling of this
				 * function. */
}

/*! \brief Set stops for radial paint for Javascript code.
 */
static void
xnjsmb_paint_radial_set_stops(paint_t *paint, Handle<Value> stops) {
    Array *stops_o;
    Array *stop_o;
    int nstops;
    grad_stop_t *grad_stops, *old_grad_stops;
    int i;

    stops_o = Array::Cast(*stops);
    nstops = stops_o->Length();
    grad_stops = (grad_stop_t *)malloc(sizeof(grad_stop_t) * nstops);
    ASSERT(grad_stops != NULL);

    for(i = 0; i < nstops; i++) {
	stop_o = Array::Cast(*stops_o->Get(i));
	ASSERT(stop_o->Length() == 5);
	grad_stop_init(grad_stops + i,
		       stop_o->Get(0)->ToNumber()->Value(),  /* off */
		       stop_o->Get(1)->ToNumber()->Value(),  /* r */
		       stop_o->Get(2)->ToNumber()->Value(),  /* g */
		       stop_o->Get(3)->ToNumber()->Value(),  /* b */
		       stop_o->Get(4)->ToNumber()->Value()); /* a */
    }
    
    old_grad_stops = paint_linear_stops(paint, nstops, grad_stops);
    if(old_grad_stops)
	free(old_grad_stops);	/* The stops, here, were allocated for
				 * previous calling of this
				 * function. */
}

#include "paints-inc.h"

/*! \defgroup xnjsmb_paints_cons Constructor of paints
 *
 * @{
 */
paint_t *
xnjsmb_paint_color_new(njs_runtime_t *rt,
		       float r, float g, float b, float a,
		       const char **err) {
    paint_t *paint;
    redraw_man_t *rdman;

    rdman = X_njs_MB_rdman(rt);
    paint = rdman_paint_color_new(rdman, r, g, b, a);
    if(paint == NULL) {
	*err = "can not allocate a paint_color_t";
	return NULL;
    }

    return paint;
}

paint_t *
xnjsmb_paint_image_new(njs_runtime_t *rt, mb_img_data_t *img,
		       const char **err) {
    paint_t *paint;
    redraw_man_t *rdman;

    rdman = X_njs_MB_rdman(rt);
    paint = rdman_paint_image_new(rdman, img);
    if(paint == NULL) {
	*err = "can not allocate a paint_image_t";
	return NULL;
    }

    return paint;
}

paint_t *
xnjsmb_paint_linear_new(njs_runtime_t *rt,
			float x1, float y1, float x2, float y2,
			const char **err) {
    paint_t *paint;
    redraw_man_t *rdman;

    rdman = X_njs_MB_rdman(rt);
    paint = rdman_paint_linear_new(rdman, x1, y1, x2, y2);
    if(paint == NULL) {
	*err = "can not allocate a paint_linear_t";
	return NULL;
    }

    return paint;
}

paint_t *
xnjsmb_paint_radial_new(njs_runtime_t *rt,
			float cx, float cy, float r,
			const char **err) {
    paint_t *paint;
    redraw_man_t *rdman;

    rdman = X_njs_MB_rdman(rt);
    paint = rdman_paint_radial_new(rdman, cx, cy, r);
    if(paint == NULL) {
	*err = "can not allocate a paint_radial_t";
	return NULL;
    }

    return paint;
}

/* @} */

/*! \defgroup xnjsmb_paints_export Exported wrapper maker for paints
 *
 * These functions are used by MB runtime to wrap C paints to JS
 * objects.
 *
 * @{
 */
Handle<Value>
export_xnjsmb_auto_paint_color_new(paint_t *paint) {
    Handle<Value> ret;
    
    ret = xnjsmb_auto_paint_color_new(paint);
    
    return ret;
}

Handle<Value>
export_xnjsmb_auto_paint_image_new(paint_t *paint) {
    Handle<Value> ret;
    
    ret = xnjsmb_auto_paint_image_new(paint);
    
    return ret;
}

Handle<Value>
export_xnjsmb_auto_paint_linear_new(paint_t *paint) {
    Handle<Value> ret;
    
    ret = xnjsmb_auto_paint_linear_new(paint);
    
    return ret;
}

Handle<Value>
export_xnjsmb_auto_paint_radial_new(paint_t *paint) {
    Handle<Value> ret;
    
    ret = xnjsmb_auto_paint_radial_new(paint);
    
    return ret;
}
/* @} */

/*! \brief Initialize paints for mbfly.
 *
 * This function is called by init() in mbfly_njs.cc when the module
 * being loaded.
 */
void xnjsmb_paints_init_mb_rt_temp(Handle<FunctionTemplate> rt_temp) {
    static int init_flag = 0;
    Handle<ObjectTemplate> rt_proto_temp;

    if(!init_flag) {
	xnjsmb_auto_paint_init();
	xnjsmb_auto_paint_color_init();
	xnjsmb_auto_paint_image_init();
	
	init_flag = 1;
    }
}

/* @} */