Mercurial > MadButterfly
view nodejs/shapes.cc @ 1223:ec964cf4c993
merge
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Thu, 06 Jan 2011 09:39:47 +0800 |
parents | df6ee4568ca2 |
children |
line wrap: on
line source
// -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 4; -*- // vim: sw=4:ts=8:sts=4 #include <v8.h> #include "mbfly_njs.h" #include <string.h> extern "C" { #include <mb.h> } #ifndef ASSERT #define ASSERT(x) #endif #define OK 0 using namespace v8; /*! \defgroup xnjsmb_shapes JS binding for shapes. * \ingroup xnjsmb * * @{ */ /*! \brief This function is called when GC collecting a shape. * * It was installed by Persistent<Object>::MakeWeak(). */ static void xnjsmb_shape_recycled(Persistent<Value> obj, void *parameter) { Persistent<Object> *self_hdl = (Persistent<Object> *)parameter; Handle<Object> js_rt; redraw_man_t *rdman; shape_t *shape; shape = (shape_t *)UNWRAP(*self_hdl); if(shape == NULL) return; WRAP(*self_hdl, NULL); js_rt = GET(*self_hdl, "mbrt")->ToObject(); rdman = xnjsmb_rt_rdman(js_rt); rdman_shape_changed(rdman, shape); rdman_shape_free(rdman, shape); self_hdl->Dispose(); delete self_hdl; } static void xnjsmb_shape_mod(Handle<Object> self, shape_t *sh) { Persistent<Object> *self_hdl; static int count = 0; /* Keep associated js object in property store for retrieving, * later, without create new js object. */ self_hdl = new Persistent<Object>(); *self_hdl = Persistent<Object>::New(self); mb_prop_set(&sh->obj.props, PROP_JSOBJ, self_hdl); self_hdl->MakeWeak(self_hdl, xnjsmb_shape_recycled); /* XXX: should be remove. It is for trace recycle of shape */ count++; if(count > 10000) { V8::LowMemoryNotification(); count = 0; } } static void xnjsmb_sh_stext_set_text(shape_t *sh, Handle<Object> self, const char *txt) { Handle<Object> rt; redraw_man_t *rdman; sh_stext_set_text(sh, txt); /* * Mark changed. */ rt = GET(self, "mbrt")->ToObject(); ASSERT(rt != NULL); rdman = xnjsmb_rt_rdman(rt); if(sh_get_coord(sh)) rdman_shape_changed(rdman, sh); } /*! \brief Set style blocks for a stext object from JS. * * A style block is style setting of a chip of text. It is a 3-tuple, * includes number of charaters, a font face, and font size. This * function need a list of 3-tuples to set style of text chips of the * stext. */ static void xnjsmb_sh_stext_set_style(shape_t *sh, Handle<Object> self, Handle<Value> blks, const char **err) { Array *blksobj; Array *blkobj; mb_style_blk_t *mb_blks; int nblks; Handle<Object> rt; redraw_man_t *rdman; int r; int i; blksobj = Array::Cast(*blks); nblks = blksobj->Length(); mb_blks = new mb_style_blk_t[nblks]; for(i = 0; i < nblks; i++) { blkobj = Array::Cast(*blksobj->Get(i)); mb_blks[i].n_chars = blkobj->Get(0)->ToInt32()->Value(); mb_blks[i].face = (mb_font_face_t *)UNWRAP(blkobj->Get(1)->ToObject()); mb_blks[i].font_sz = blkobj->Get(2)->ToNumber()->Value(); } r = sh_stext_set_style(sh, mb_blks, nblks); if(r != 0) { *err = "Unknown error"; return; } /* * Mark changed. */ rt = GET(self, "mbrt")->ToObject(); ASSERT(rt != NULL); rdman = xnjsmb_rt_rdman(rt); if(sh_get_coord(sh)) rdman_shape_changed(rdman, sh); delete mb_blks; } static Handle<Value> xnjsmb_shape_stroke_width_get(Handle<Object> self, shape_t *sh, const char **err) { float stroke_width; stroke_width = sh_get_stroke_width(sh); return Number::New(stroke_width); } static void xnjsmb_shape_stroke_width_set(Handle<Object> self, shape_t *sh, Handle<Value> value, const char **err) { float stroke_width; Handle<Object> rt; redraw_man_t *rdman; stroke_width = value->Int32Value(); sh_set_stroke_width(sh, stroke_width); /* * Mark changed. */ rt = GET(self, "mbrt")->ToObject(); ASSERT(rt != NULL); rdman = xnjsmb_rt_rdman(rt); if(sh_get_coord(sh)) rdman_shape_changed(rdman, sh); } static void xnjsmb_shape_show(shape_t *sh, Handle<Object> self) { Handle<Object> js_rt; redraw_man_t *rdman; js_rt = GET(self, "mbrt")->ToObject(); ASSERT(js_rt != NULL); rdman = xnjsmb_rt_rdman(js_rt); sh_show(sh); rdman_shape_changed(rdman, sh); } static void xnjsmb_shape_hide(shape_t *sh, Handle<Object> self) { Handle<Object> js_rt; redraw_man_t *rdman; js_rt = GET(self, "mbrt")->ToObject(); ASSERT(js_rt != NULL); rdman = xnjsmb_rt_rdman(js_rt); sh_hide(sh); rdman_shape_changed(rdman, sh); } static void xnjsmb_shape_remove(shape_t *sh, Handle<Object> self) { Handle<Object> js_rt; redraw_man_t *rdman; Persistent<Object> *self_hdl; int r; self_hdl = (Persistent<Object> *)mb_prop_get(&sh->obj.props, PROP_JSOBJ); SET(*self_hdl, "valid", Boolean::New(0)); WRAP(*self_hdl, NULL); js_rt = GET(*self_hdl, "mbrt")->ToObject(); ASSERT(js_rt != NULL); rdman = xnjsmb_rt_rdman(js_rt); rdman_shape_changed(rdman, sh); r = rdman_shape_free(rdman, sh); if(r != OK) THROW_noret("Can not free a shape for unknown reason"); self_hdl->Dispose(); delete self_hdl; } static void xnjsmb_sh_rect_set(shape_t *sh, Handle<Object> self, float x, float y, float w, float h, float rx, float ry) { Handle<Object> rt; redraw_man_t *rdman; sh_rect_set(sh, x, y, w, h, rx, ry); /* * Mark changed. */ rt = GET(self, "mbrt")->ToObject(); ASSERT(rt != NULL); rdman = xnjsmb_rt_rdman(rt); if(sh_get_coord(sh)) rdman_shape_changed(rdman, sh); } /* @} */ #include "shapes-inc.h" /*! \defgroup xnjsmb_shapes_wraps Exported wrapper makers for shapes * \ingroup xnjsmb_shapes * * These functions are used by methods of mb_rt to wrap shape objects * as Javascript objects. * * @{ */ Handle<Value> export_xnjsmb_auto_path_new(shape_t *sh) { return xnjsmb_auto_path_new(sh); } Handle<Value> export_xnjsmb_auto_stext_new(shape_t *sh) { return xnjsmb_auto_stext_new(sh); } Handle<Value> export_xnjsmb_auto_image_new(shape_t *sh) { return xnjsmb_auto_image_new(sh); } Handle<Value> export_xnjsmb_auto_rect_new(shape_t *sh) { return xnjsmb_auto_rect_new(sh); } /* @} */ /*! \defgroup xnjsmb_shapes_cons Constructor of shapes * \ingroup xnjsmb_shapes * * @{ */ shape_t * xnjsmb_path_new(njs_runtime_t *rt, const char *d) { redraw_man_t *rdman; shape_t *sh; rdman = njs_mb_rdman(rt); sh = rdman_shape_path_new(rdman, d); /* Code generator supposes that callee should free the memory */ free((void *)d); return sh; } shape_t * xnjsmb_stext_new(njs_runtime_t *rt, const char *txt, float x, float y) { redraw_man_t *rdman; shape_t *sh; rdman = njs_mb_rdman(rt); sh = rdman_shape_stext_new(rdman, txt, x, y); /* Code generator supposes that callee should free the memory */ free((void *)txt); return sh; } shape_t * xnjsmb_image_new(njs_runtime_t *rt, float x, float y, float w, float h) { redraw_man_t *rdman; shape_t *sh; rdman = njs_mb_rdman(rt); sh = rdman_shape_image_new(rdman, x, y, w, h); return sh; } shape_t * xnjsmb_rect_new(njs_runtime_t *rt, float x, float y, float w, float h, float rx, float ry, const char **err) { redraw_man_t *rdman; shape_t *sh; rdman = njs_mb_rdman(rt); sh = rdman_shape_rect_new(rdman, x, y, w, h, rx, ry); if(sh == NULL) { *err = "Can not create a sh_rect_t"; return NULL; } return sh; } /* @} */ /*! \brief Set properties of template of mb_rt. * \ingroup xnjsmb_shapes */ void xnjsmb_shapes_init_mb_rt_temp(Handle<FunctionTemplate> rt_temp) { HandleScope scope; Handle<FunctionTemplate> path_new_temp, stext_new_temp; Handle<FunctionTemplate> image_new_temp; Handle<ObjectTemplate> rt_proto_temp; static int temp_init_flag = 0; if(temp_init_flag == 0) { xnjsmb_auto_shape_init(); xnjsmb_auto_path_init(); xnjsmb_auto_stext_init(); xnjsmb_auto_image_init(); xnjsmb_auto_rect_init(); temp_init_flag = 1; } return; }