-rw-r--r-- | agg-plot/lua-draw.cpp | 41 | ||||
-rw-r--r-- | agg-plot/markers.cpp | 57 | ||||
-rw-r--r-- | agg-plot/markers.h | 1 | ||||
-rw-r--r-- | agg-plot/sg_marker.h | 54 |
diff --git a/agg-plot/lua-draw.cpp b/agg-plot/lua-draw.cpp index 4148c3c8..ff559d51 100644 --- a/agg-plot/lua-draw.cpp +++ b/agg-plot/lua-draw.cpp @@ -32,6 +32,7 @@ extern "C" { #include "gs-types.h" #include "trans.h" #include "colors.h" +#include "sg_marker.h" pthread_mutex_t agg_mutex[1]; @@ -66,6 +67,9 @@ static int agg_ellipse_free (lua_State *L); static int textshape_new (lua_State *L); static int textshape_free (lua_State *L); +static int marker_new (lua_State *L); +static int marker_free (lua_State *L); + static void path_cmd (draw::path *p, int cmd, struct cmd_call_stack *stack); static struct path_cmd_reg cmd_table[] = { @@ -83,6 +87,7 @@ static const struct luaL_Reg draw_functions[] = { {"ellipse", agg_ellipse_new}, {"circle", agg_circle_new}, {"textshape", textshape_new}, + {"marker", marker_new}, {NULL, NULL} }; @@ -103,6 +108,12 @@ static const struct luaL_Reg agg_ellipse_methods[] = { {NULL, NULL} }; + +static const struct luaL_Reg marker_methods[] = { + {"__gc", marker_free}, + {NULL, NULL} +}; + int agg_path_new (lua_State *L) { @@ -273,6 +284,32 @@ textshape_free (lua_State *L) return object_free<draw::text_shape>(L, 1, GS_DRAW_TEXTSHAPE); } +int +marker_new (lua_State *L) +{ + const double x = luaL_checknumber(L, 1); + const double y = luaL_checknumber(L, 2); + const char *sym_name = luaL_optstring(L, 3, ""); + const double size = luaL_optnumber(L, 4, 5.0); + + bool stroke; + sg_object* sym = new_marker_symbol_raw(sym_name, stroke); + draw::marker* marker = new draw::marker(x, y, sym, size); + + if (stroke) + new(L, GS_DRAW_MARKER) trans::stroke(marker); + else + new(L, GS_DRAW_MARKER) sg_object_ref<manage_owner>(marker); + + return 1; +} + +int +marker_free (lua_State *L) +{ + return object_free<sg_object>(L, 1, GS_DRAW_MARKER); +} + void draw_register (lua_State *L) { @@ -290,6 +327,10 @@ draw_register (lua_State *L) luaL_register (L, NULL, textshape_methods); lua_pop (L, 1); + luaL_newmetatable (L, GS_METATABLE(GS_DRAW_MARKER)); + luaL_register (L, NULL, marker_methods); + lua_pop (L, 1); + /* gsl module registration */ luaL_register (L, NULL, draw_functions); } diff --git a/agg-plot/markers.cpp b/agg-plot/markers.cpp index 1aca7586..8cf7adea 100644 --- a/agg-plot/markers.cpp +++ b/agg-plot/markers.cpp @@ -10,15 +10,15 @@ struct symbol_reg { const char *name; - sg_object *(*builder)(); + sg_object *(*builder)(bool&); }; -static sg_object *build_circle(); -static sg_object *build_square(); -static sg_object *build_triangle(); -static sg_object *build_diamond(); -static sg_object *build_plus(); -static sg_object *build_cross(); +static sg_object *build_circle(bool& stroke); +static sg_object *build_square(bool& stroke); +static sg_object *build_triangle(bool& stroke); +static sg_object *build_diamond(bool& stroke); +static sg_object *build_plus(bool& stroke); +static sg_object *build_cross(bool& stroke); const unsigned NB_SYMBOLS = 6; static struct symbol_reg builder_table[NB_SYMBOLS+1] = { @@ -32,16 +32,17 @@ static struct symbol_reg builder_table[NB_SYMBOLS+1] = { }; sg_object * -build_circle() +build_circle(bool& stroke) { draw::ellipse* c = new draw::ellipse(); trans::scaling* s = new trans::scaling(c); c->self().init(0.0, 0.0, 0.5, 0.5); + stroke = false; return s; } sg_object * -build_square() +build_square(bool& stroke) { draw::path* p = new draw::path(); trans::scaling* s = new trans::scaling(p); @@ -53,11 +54,12 @@ build_square() square.line_to(-0.5, 0.5); square.close_polygon(); + stroke = false; return s; } sg_object * -build_triangle() +build_triangle(bool& stroke) { draw::path* p = new draw::path(); trans::scaling* s = new trans::scaling(p); @@ -70,11 +72,12 @@ build_triangle() triangle.line_to( 0.0, 2*ht/3); triangle.close_polygon(); + stroke = false; return s; } sg_object * -build_diamond() +build_diamond(bool& stroke) { draw::path* p = new draw::path(); trans::scaling* s = new trans::scaling(p); @@ -86,11 +89,12 @@ build_diamond() square.line_to( 0.0, -0.5); square.close_polygon(); + stroke = false; return s; } sg_object * -build_plus() +build_plus(bool& stroke) { draw::path* p = new draw::path(); trans::scaling* s = new trans::scaling(p); @@ -101,11 +105,12 @@ build_plus() plus.move_to( 0.0, -0.5); plus.line_to( 0.0, 0.5); - return new trans::stroke(s); + stroke = true; + return s; } sg_object * -build_cross() +build_cross(bool& stroke) { draw::path* p = new draw::path(); trans::scaling* s = new trans::scaling(p); @@ -116,25 +121,39 @@ build_cross() plus.move_to(-0.5, 0.5); plus.line_to( 0.5, -0.5); - return new trans::stroke(s); + stroke = true; + return s; } sg_object* -new_marker_symbol (const char *req_name) +new_marker_symbol_raw(const char *req_name, bool& stroke) { struct symbol_reg *reg; for (reg = builder_table; reg->name != NULL; reg++) { if (strcmp (reg->name, req_name) == 0) - return reg->builder(); + return reg->builder(stroke); } - return builder_table[0].builder(); + return builder_table[0].builder(stroke); +} + +sg_object* +new_marker_symbol (const char *req_name) +{ + bool stroke; + sg_object* s = new_marker_symbol_raw(req_name, stroke); + + trans::scaling *ss = new trans::scaling(s); + sg_object* sf = ss; + if (stroke) + sf = new trans::stroke(sf); + return sf; } sg_object* new_marker_symbol (int n) { n = (n-1) % NB_SYMBOLS; - return builder_table[n].builder(); + return new_marker_symbol(builder_table[n].name); } diff --git a/agg-plot/markers.h b/agg-plot/markers.h index d7672bb7..b54b1415 100644 --- a/agg-plot/markers.h +++ b/agg-plot/markers.h @@ -5,5 +5,6 @@ extern sg_object* new_marker_symbol(const char *name); extern sg_object* new_marker_symbol(int n); +extern sg_object* new_marker_symbol_raw(const char *req_name, bool& stroke); #endif diff --git a/agg-plot/sg_marker.h b/agg-plot/sg_marker.h new file mode 100644 index 00000000..076054ed --- /dev/null +++ b/agg-plot/sg_marker.h @@ -0,0 +1,54 @@ +#ifndef AGGPLOT_SG_MARKER_H +#define AGGPLOT_SG_MARKER_H + +#include "agg_conv_transform.h" +#include "agg_trans_affine.h" + +#include "sg_object.h" +#include "markers.h" +#include "utils.h" + +typedef agg::conv_transform<sg_object> conv_type; + +namespace draw { + + class marker_a : public sg_adapter<conv_type, no_approx_scale> { + + public: + marker_a(double x, double y, sg_object* sym, double size): + sg_adapter<conv_type, no_approx_scale>(sym, m_trans), + m_trans(size), m_symbol(sym), m_x(x), m_y(y) + { + // the following is needed to adjust the approximation_scale of the + // symbol + m_symbol->apply_transform(identity_matrix, size); + } + + virtual void apply_transform(const agg::trans_affine& m, double as) + { + double *tx = &m_trans.tx, *ty = &m_trans.ty; + *tx = m_x; + *ty = m_y; + m.transform(tx, ty); + } + + virtual void bounding_box(double *x1, double *y1, double *x2, double *y2) + { + *x1 = *x2 = m_x; + *y1 = *y2 = m_y; + } + + protected: + agg::trans_affine_scaling m_trans; + sg_object* m_symbol; + double m_x, m_y; + }; + + class marker : public marker_a { + public: + marker(double x, double y, sg_object* s, double sz) : marker_a(x, y, s, sz) {} + ~marker() { delete m_symbol; } + }; +} + +#endif |