-rw-r--r-- | agg-plot/canvas-window.cpp | 2 | ||||
-rw-r--r-- | agg-plot/drawable.cpp | 4 | ||||
-rw-r--r-- | agg-plot/drawable.h | 8 | ||||
-rw-r--r-- | agg-plot/lua-draw.cpp | 3 | ||||
-rw-r--r-- | agg-plot/markers.cpp | 103 | ||||
-rw-r--r-- | agg-plot/markers.h | 7 | ||||
-rw-r--r-- | agg-plot/plot-window.cpp | 1 | ||||
-rw-r--r-- | agg-plot/plot.h | 2 | ||||
-rw-r--r-- | agg-plot/scalable.h | 30 | ||||
-rw-r--r-- | agg-plot/text.cpp | 4 | ||||
-rw-r--r-- | agg-plot/text.h | 2 | ||||
-rw-r--r-- | agg-plot/trans.h | 24 | ||||
-rw-r--r-- | examples/nlinfit.lua | 6 | ||||
-rw-r--r-- | gsl-shell.c | 52 |
diff --git a/agg-plot/canvas-window.cpp b/agg-plot/canvas-window.cpp index d2e9e066..98d9f7e6 100644 --- a/agg-plot/canvas-window.cpp +++ b/agg-plot/canvas-window.cpp @@ -197,7 +197,7 @@ canvas_window_draw_gener (lua_State *L, bool as_line) agg::rgba8 *color = check_color_rgba8 (L, 3); const agg::trans_affine& mtx = win->transform(); - obj->apply_transform(mtx); + obj->apply_transform(mtx, 1.0); bool success = win->draw(obj, color, as_line); diff --git a/agg-plot/drawable.cpp b/agg-plot/drawable.cpp index d2d18354..4258d7a8 100644 --- a/agg-plot/drawable.cpp +++ b/agg-plot/drawable.cpp @@ -7,10 +7,10 @@ agg::trans_affine window_scalable::dummy_matrix; void -window_scalable::apply_transform(const agg::trans_affine& m) +window_scalable::apply_transform(const agg::trans_affine& m, double as) { m_trans.transformer(m); - m_source->approximation_scale (m.scale()); + m_source->apply_transform (m, as * m.scale()); } void diff --git a/agg-plot/drawable.h b/agg-plot/drawable.h index d786b3a7..37f4c980 100644 --- a/agg-plot/drawable.h +++ b/agg-plot/drawable.h @@ -9,7 +9,7 @@ // Interface struct window_object { public: - virtual void apply_transform(const agg::trans_affine& m) = 0; + virtual void apply_transform(const agg::trans_affine& m, double as) = 0; virtual void bounding_box(double *x1, double *y1, double *x2, double *y2) = 0; virtual bool dispose() = 0; @@ -39,7 +39,7 @@ public: virtual void rewind(unsigned path_id); virtual unsigned vertex(double* x, double* y); - virtual void apply_transform(const agg::trans_affine& m); + virtual void apply_transform(const agg::trans_affine& m, double as); virtual void bounding_box(double *x1, double *y1, double *x2, double *y2); virtual bool dispose(); @@ -55,9 +55,9 @@ public: template <class init_type> drawable_adapter(drawable* src, init_type& val): root_type(src, val) {}; - virtual void apply_transform(const agg::trans_affine& m) + virtual void apply_transform(const agg::trans_affine& m, double as) { - this->m_source->apply_transform(m); + this->m_source->apply_transform(m, as); }; virtual void bounding_box(double *x1, double *y1, double *x2, double *y2) diff --git a/agg-plot/lua-draw.cpp b/agg-plot/lua-draw.cpp index 812cb43e..f70a181f 100644 --- a/agg-plot/lua-draw.cpp +++ b/agg-plot/lua-draw.cpp @@ -141,6 +141,7 @@ agg_path_free (lua_State *L) { typedef draw::path path_type; path_type *path = check_agg_path (L, 1); + printf("Deallocating path: %p\n", (void *) path); path->~path_type(); return 0; } @@ -406,8 +407,6 @@ draw_register (lua_State *L) { pthread_mutex_init (agg_mutex, NULL); - markers::init(); - luaL_newmetatable (L, GS_METATABLE(GS_DRAW_PATH)); luaL_register (L, NULL, agg_path_methods); lua_pop (L, 1); diff --git a/agg-plot/markers.cpp b/agg-plot/markers.cpp index 72289e6b..04354683 100644 --- a/agg-plot/markers.cpp +++ b/agg-plot/markers.cpp @@ -9,54 +9,71 @@ struct symbol_reg { const char *name; - scalable *path; + scalable *(*builder)(); }; -static vs_proxy<agg::ellipse, false> s_circle; -static vs_proxy<agg::path_storage, false> s_square, s_triangle; +static scalable *build_circle(); +static scalable *build_square(); +static scalable *build_triangle(); -static struct symbol_reg symbol_table[] = { - {"circle", &s_circle}, - {"square", &s_square}, - {"triangle", &s_triangle}, +static struct symbol_reg builder_table[] = { + {"circle", build_circle}, + {"square", build_square}, + {"triangle", build_triangle}, {NULL, NULL} }; -static scalable& s_default = s_circle; - -namespace markers { - - void init() - { - agg::ellipse& ellipse = s_circle.self(); - ellipse.init(0.0, 0.0, 0.5, 0.5); - - agg::path_storage& square = s_square.self(); - - square.move_to(-0.5, -0.5); - square.line_to( 0.5, -0.5); - square.line_to( 0.5, 0.5); - square.line_to(-0.5, 0.5); - square.close_polygon(); - - agg::path_storage& triangle = s_triangle.self(); - - double ht = 0.86602540378444; - triangle.move_to(-0.5, -ht/3); - triangle.line_to( 0.5, -ht/3); - triangle.line_to( 0.0, 2*ht/3); - triangle.close_polygon(); - } - - scalable& get (const char *req_name) - { - struct symbol_reg *reg; - for (reg = symbol_table; reg->name != NULL; reg++) - { - if (strcmp (reg->name, req_name) == 0) - return *reg->path; - } - return s_default; - } +scalable * +build_circle() +{ + typedef vs_proxy_approx<agg::ellipse> circle_type; + circle_type *circle = new circle_type(); + circle->self().init(0.0, 0.0, 0.5, 0.5); + return (scalable *) circle; +} + +scalable * +build_square() +{ + typedef vs_proxy<agg::path_storage> path_type; + path_type *p = new path_type(); + + agg::path_storage& square = p->self(); + square.move_to(-0.5, -0.5); + square.line_to( 0.5, -0.5); + square.line_to( 0.5, 0.5); + square.line_to(-0.5, 0.5); + square.close_polygon(); + + return (scalable *) p; +} + +scalable * +build_triangle() +{ + typedef vs_proxy<agg::path_storage> path_type; + path_type *p = new path_type(); + + agg::path_storage& triangle = p->self(); + + double ht = 0.86602540378444; + triangle.move_to(-0.5, -ht/3); + triangle.line_to( 0.5, -ht/3); + triangle.line_to( 0.0, 2*ht/3); + triangle.close_polygon(); + + return (scalable *) p; +} + +scalable* +new_marker_symbol (const char *req_name) +{ + struct symbol_reg *reg; + for (reg = builder_table; reg->name != NULL; reg++) + { + if (strcmp (reg->name, req_name) == 0) + return reg->builder(); + } + return builder_table[0].builder(); } diff --git a/agg-plot/markers.h b/agg-plot/markers.h index f7ffd2a1..41fd94c5 100644 --- a/agg-plot/markers.h +++ b/agg-plot/markers.h @@ -3,11 +3,6 @@ #include "scalable.h" -namespace markers { - - extern void init(); - - extern scalable& get(const char *name); -} +extern scalable* new_marker_symbol(const char *name); #endif diff --git a/agg-plot/plot-window.cpp b/agg-plot/plot-window.cpp index 929975a4..8f55fbd2 100644 --- a/agg-plot/plot-window.cpp +++ b/agg-plot/plot-window.cpp @@ -163,6 +163,7 @@ int plot_window_free (lua_State *L) { plot_window *p = plot_window::check(L, 1); + printf("Deallocating plot-window: %p\n", (void *) p); p->~plot_window(); return 0; } diff --git a/agg-plot/plot.h b/agg-plot/plot.h index 446bfbf5..e6884d85 100644 --- a/agg-plot/plot.h +++ b/agg-plot/plot.h @@ -202,7 +202,7 @@ void plot<VS,RM>::draw_elements(canvas &canvas) { container& d = m_elements[j]; VS& vs = d.get_vertex_source(); - vs.apply_transform(m); + vs.apply_transform(m, 1.0); if (d.outline) canvas.draw_outline(vs, d.color); diff --git a/agg-plot/scalable.h b/agg-plot/scalable.h index eb75450d..2521426d 100644 --- a/agg-plot/scalable.h +++ b/agg-plot/scalable.h @@ -21,6 +21,8 @@ #ifndef AGGPLOT_SCALABLE_H #define AGGPLOT_SCALABLE_H +#include "agg_trans_affine.h" + struct vertex_source { virtual void rewind(unsigned path_id) = 0; virtual unsigned vertex(double* x, double* y) = 0; @@ -29,7 +31,7 @@ struct vertex_source { }; struct scalable_object { - virtual void approximation_scale(double as) = 0; + virtual void apply_transform(const agg::trans_affine& m, double as) = 0; virtual bool dispose() = 0; virtual ~scalable_object() { }; @@ -41,8 +43,9 @@ struct scalable : public vertex_source, public scalable_object { /* This class is basically a wrapper around a native AGG vertex_source object. The wrapper implements the "scalable" interface. */ -template <class T, bool system_managed> +template <class T, bool system_managed = false> class vs_proxy : public scalable { +protected: T m_base; public: @@ -51,12 +54,25 @@ public: virtual void rewind(unsigned path_id) { m_base.rewind(path_id); }; virtual unsigned vertex(double* x, double* y) { return m_base.vertex(x, y); }; - virtual void approximation_scale(double as) { }; + virtual void apply_transform(const agg::trans_affine& m, double as) { }; virtual bool dispose() { return (system_managed ? false : true); }; T& self() { return m_base; }; }; +/* The same as vs_proxy but with approximation_scale. */ +template <class T, bool system_managed = false> +class vs_proxy_approx : public vs_proxy<T, system_managed> { + typedef vs_proxy<T, system_managed> root_type; +public: + vs_proxy_approx(): root_type() {}; + + virtual void apply_transform(const agg::trans_affine& m, double as) + { + this->m_base.approximation_scale(as); + }; +}; + /* this class does work does permit to perform an AGG transformation like conv_stroke, conv_dash or any other transform. This adapter is meant to preserve the scalable or the window_drawable interface. */ @@ -108,9 +124,9 @@ public: template <class init_type> scalable_adapter(scalable* src, init_type& val): root_type(src, val) {}; - virtual void approximation_scale(double as) + virtual void apply_transform(const agg::trans_affine& m, double as) { - this->m_source->approximation_scale(as); + this->m_source->apply_transform(m, as); }; }; @@ -124,10 +140,10 @@ public: template <class init_type> scalable_adapter_approx(scalable* src, init_type& val): root_type(src, val) {}; - virtual void approximation_scale(double as) + virtual void apply_transform(const agg::trans_affine& m, double as) { this->m_output.approximation_scale(as); - this->m_source->approximation_scale(as); + this->m_source->apply_transform(m, as); }; }; diff --git a/agg-plot/text.cpp b/agg-plot/text.cpp index 70c8ab6b..b020409f 100644 --- a/agg-plot/text.cpp +++ b/agg-plot/text.cpp @@ -16,7 +16,7 @@ namespace draw { } void - text::apply_transform(const agg::trans_affine& m) + text::apply_transform(const agg::trans_affine& m, double as) { double& x = m_matrix.tx; double& y = m_matrix.ty; @@ -25,6 +25,8 @@ namespace draw { y = m_y; m.transform(&x, &y); + + m_stroke.approximation_scale(as); } void diff --git a/agg-plot/text.h b/agg-plot/text.h index 5e3949ee..3c30436b 100644 --- a/agg-plot/text.h +++ b/agg-plot/text.h @@ -43,7 +43,7 @@ namespace draw { virtual void rewind(unsigned path_id); virtual unsigned vertex(double* x, double* y); - virtual void apply_transform(const agg::trans_affine& m); + virtual void apply_transform(const agg::trans_affine& m, double as); virtual void bounding_box(double *x1, double *y1, double *x2, double *y2); virtual bool dispose(); diff --git a/agg-plot/trans.h b/agg-plot/trans.h index e92bc0e8..4fb0d5b1 100644 --- a/agg-plot/trans.h +++ b/agg-plot/trans.h @@ -93,6 +93,11 @@ struct trans { { m_norm = m_matrix.scale(); }; + + virtual void apply_transform(const agg::trans_affine& m, double as) + { + this->m_source->apply_transform(m, as * m_norm); + }; }; typedef agg::conv_transform<scalable> symbol_type; @@ -100,16 +105,29 @@ struct trans { typedef typename context::template simple<marker_base> vs_marker; class marker : public vs_marker { - scalable& m_symbol; + double m_size; + scalable* m_symbol; agg::trans_affine m_matrix; agg::conv_transform<scalable> m_trans; public: marker(base_type* src, double size, const char *sym): vs_marker(src, m_trans), - m_symbol(markers::get(sym)), m_matrix(), m_trans(m_symbol, m_matrix) + m_size(size), m_symbol(new_marker_symbol(sym)), m_matrix(), + m_trans(*m_symbol, m_matrix) + { + m_matrix.scale(m_size); + }; + + ~marker() + { + delete m_symbol; + }; + + virtual void apply_transform(const agg::trans_affine& m, double as) { - m_matrix.scale(size); + this->m_symbol->apply_transform(m, as * m_size); + this->m_source->apply_transform(m, as); }; }; }; diff --git a/examples/nlinfit.lua b/examples/nlinfit.lua index cb2410ec..e9944f2a 100644 --- a/examples/nlinfit.lua +++ b/examples/nlinfit.lua @@ -80,8 +80,8 @@ function demo2() end end - pl = plot('Non-linear fit / A * exp(a t) sin(w t)') - pl:addline(xyline(x, y), 'blue', {{'marker', size= 5}}) + local pl = plot('Non-linear fit / A * exp(a t) sin(w t)') + pl:add(xyline(x, y), 'blue', {{'stroke'}, {'marker', size= 5, mark="triangle"}}) local function print_state(s) print ("x: ", tr(s.p)) @@ -90,7 +90,7 @@ function demo2() s = nlfsolver {fdf= expf, n= n, p0= p0} - pl:addline(fxline(|x| fmodel(s.p, x), 0, xs(n)), 'red', {{'dash', a=7, b=3}}) + pl:addline(fxline(|x| fmodel(s.p, x), 0, xs(n)), 'red', {{'dash', 7, 3, 3, 3}}) repeat print_state (s) diff --git a/gsl-shell.c b/gsl-shell.c index a4647d19..97b6893d 100644 --- a/gsl-shell.c +++ b/gsl-shell.c @@ -300,6 +300,10 @@ static int loadline (lua_State *L) { if (!pushline(L, 1)) return -1; /* no input */ +#warning DEBUG CODE + if (strcmp (lua_tostring(L, 1), "EXIT") == 0) + return -1; + lua_pushfstring(L, "return %s", lua_tostring(L, 1)); status = luaL_loadbuffer(L, lua_tostring(L, 2), lua_strlen(L, 2), "=stdin"); if (status == 0) @@ -325,15 +329,36 @@ static int loadline (lua_State *L) { return status; } +static void do_windows_unref (lua_State *L) +{ + struct window_unref_cell *wu; + size_t j; + + GSL_SHELL_LOCK(); + + for (j = 0; j < unref_fixed_count; j++) + mlua_window_unref (L, unref_fixed_list[j]); + + unref_fixed_count = 0; + + for (wu = window_unref_list; wu != NULL; /* */) + { + struct window_unref_cell *nxt = wu->next; + mlua_window_unref (L, wu->id); + free (wu); + wu = nxt; + } + window_unref_list = NULL; + + GSL_SHELL_UNLOCK(); +} static void dotty (lua_State *L) { const char *oldprogname = progname; progname = NULL; for (;;) { - struct window_unref_cell *wu; int status = loadline(L); - size_t j; if (status == -1) break; @@ -351,25 +376,13 @@ static void dotty (lua_State *L) { l_message(progname, emsg); } } - GSL_SHELL_LOCK(); - - for (j = 0; j < unref_fixed_count; j++) - mlua_window_unref (L, unref_fixed_list[j]); - - unref_fixed_count = 0; - - for (wu = window_unref_list; wu != NULL; /* */) - { - struct window_unref_cell *nxt = wu->next; - mlua_window_unref (L, wu->id); - free (wu); - wu = nxt; - } - window_unref_list = NULL; - GSL_SHELL_UNLOCK(); + do_windows_unref (L); } + + do_windows_unref (L); lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); fflush(stdout); progname = oldprogname; @@ -544,6 +557,9 @@ int main (int argc, char **argv) { status = lua_cpcall(L, &pmain, &s); report(L, status); lua_close(L); + + pthread_mutex_destroy (gsl_shell_mutex); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; } |