-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | agg-plot/Makefile | 13 | ||||
-rw-r--r-- | agg-plot/agg-cplot.cpp | 159 | ||||
-rw-r--r-- | agg-plot/agg-cplot.h | 42 | ||||
-rw-r--r-- | agg-plot/c-drawables.cpp | 184 | ||||
-rw-r--r-- | agg-plot/c-drawables.h | 49 | ||||
-rw-r--r-- | agg-plot/drawables.h | 15 | ||||
-rw-r--r-- | agg-plot/lua-cplot-priv.h | 43 | ||||
-rw-r--r-- | agg-plot/lua-plot-priv.h | 62 | ||||
-rw-r--r-- | agg-plot/plot.cpp | 75 | ||||
-rw-r--r-- | agg-plot/plot.h | 124 | ||||
-rw-r--r-- | agg-plot/resource-manager.h | 29 | ||||
-rw-r--r-- | agg-plot/test.cpp | 4 | ||||
-rw-r--r-- | agg-plot/trans.h | 43 | ||||
-rw-r--r-- | agg-plot/units-plot.cpp (renamed from agg-plot/units_cplot.cpp) | 0 | ||||
-rw-r--r-- | agg-plot/units-plot.h (renamed from agg-plot/units_cplot.h) | 0 | ||||
-rw-r--r-- | agg-plot/vertex-source.h | 13 | ||||
-rw-r--r-- | agg-plot/xwin-show.cpp | 45 | ||||
-rw-r--r-- | lua-cplot.c | 318 | ||||
-rw-r--r-- | lua-gsl.c | 4 | ||||
-rw-r--r-- | lua-plot.c | 408 | ||||
-rw-r--r-- | lua-plot.h (renamed from lua-cplot.h) | 2 | ||||
-rw-r--r-- | makeconfig | 2 | ||||
-rw-r--r-- | makeflags | 7 | ||||
-rwxr-xr-x | scripts/saveall.sh | 3 |
@@ -78,7 +78,7 @@ else endif
ifeq ($(strip $(ENABLE_AGG_PLOT)), yes)
- C_SRC_FILES += lua-cplot.c
+ C_SRC_FILES += lua-plot.c
INCLUDES += $(PTHREAD_CFLAGS) -Iagg-plot
SUBDIRS += agg-plot
DEFS += -DAGG_PLOT_ENABLED
diff --git a/agg-plot/Makefile b/agg-plot/Makefile index 531ecf0e..8b3116f9 100644 --- a/agg-plot/Makefile +++ b/agg-plot/Makefile @@ -39,6 +39,7 @@ ifeq ($(strip $(PLATFORM)), mingw) INCLUDES += -I/usr/include -I/usr/pthreads-w32/include
AGG_HOME = /c/fra/src/agg-2.5
AGG_CFLAGS = -I$(AGG_HOME)/include
+ AGG_LIBS = -L$(AGG_HOME)/src -lagg -lgdi32 -lsupc++
PLATSUP_SRC_FILES = agg_platform_support_win32.cpp agg_win32_bmp.cpp
else
AGG_CFLAGS = -I/usr/include/agg2
@@ -47,8 +48,8 @@ endif INCLUDES += -I$(GSH_BASE_DIR) -I$(LUADIR)/src -I$(LUADIR)/etc
-# AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp cplot.cpp units_cplot.cpp xwin-show.cpp agg-cplot.cpp
-AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp plot.cpp test.cpp
+AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp c-drawables.cpp plot.cpp xwin-show.cpp
+# AGGPLOT_SRC_FILES = $(PLATSUP_SRC_FILES) utils.cpp c-drawables.cpp test.cpp
AGGPLOT_OBJ_FILES := $(AGGPLOT_SRC_FILES:%.cpp=%.o)
@@ -58,13 +59,13 @@ DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) CXXCOMPILE = $(CXX) $(CXXFLAGS) $(DEFS) $(INCLUDES) $(AGG_CFLAGS)
-#TARGETS = libaggplot.a
-TARGETS = test
+TARGETS = libaggplot.a
+#TARGETS = test.exe
all: $(TARGETS)
-test: $(AGGPLOT_OBJ_FILES)
- gcc -o test $(AGGPLOT_OBJ_FILES) -lagg -lX11 -lm -lsupc++
+#test.exe: $(AGGPLOT_OBJ_FILES)
+# gcc -o test.exe $(AGGPLOT_OBJ_FILES) $(AGG_LIBS)
libaggplot.a: $(AGGPLOT_OBJ_FILES)
$(AR) $@ $?
diff --git a/agg-plot/agg-cplot.cpp b/agg-plot/agg-cplot.cpp deleted file mode 100644 index 457868de..00000000 --- a/agg-plot/agg-cplot.cpp +++ /dev/null @@ -1,159 +0,0 @@ -
-#include "units_cplot.h"
-#include "lua-cplot-priv.h"
-#include "cplot.h"
-
-#include "agg-cplot.h"
-
-static agg::rgba8
-color_lookup (const char *color_str)
-{
- const char *p = color_str;
- agg::rgba8 c;
- int val = 180;
-
- if (strncmp (p, "light", 5) == 0)
- {
- val = 255;
- p += 5;
- }
- else if (strncmp (p, "dark", 4) == 0)
- {
- val = 120;
- p += 4;
- }
-
- if (strcmp (p, "red") == 0)
- c = agg::rgba8(val, 0, 0);
- else if (strcmp (p, "green") == 0)
- c = agg::rgba8(0, val, 0);
- else if (strcmp (p, "blue") == 0)
- c = agg::rgba8(0, 0, val);
- else if (strcmp (p, "cyan") == 0)
- c = agg::rgba8(0, val, val);
- else if (strcmp (p, "magenta") == 0)
- c = agg::rgba8(val, 0, val);
- else if (strcmp (p, "yellow") == 0)
- c = agg::rgba8(val, val, 0);
- else if (strcmp (p, "gray") == 0)
- c = agg::rgba8(val, val, val);
- else
- c = agg::rgba8(0, 0, 0);
-
- return c;
-}
-
-CCPLOT *
-cplot_new(int with_units)
-{
- cplot *cp;
- if (with_units)
- cp = new units_cplot();
- else
- cp = new cplot();
-
- return (CCPLOT *) cp;
-}
-
-void cplot_free (CCPLOT* _d)
-{
- cplot* cp = (cplot*) _d;
- delete cp;
-}
-
-void cplot_add(CCPLOT *_p, CDRAW *_d)
-{
- cplot *p = (cplot *) _p;
- drawable *d = (drawable *) _d;
- p->add(d);
-}
-
-CPATH* line_new(const char *color_str)
-{
- agg::rgba8 c = color_lookup (color_str);
- line* ln = new line(c);
- return (CPATH *) ln;
-}
-
-CPATH* poly_new(const char *color_str, const char *outline_color_str)
-{
- agg::rgba8 fill_col = color_lookup (color_str);
- line* ln;
-
- if (outline_color_str)
- {
- agg::rgba8 outline_col = color_lookup (outline_color_str);
- ln = new poly_outline(fill_col, outline_col);
- }
- else
- {
- ln = new polygon(fill_col);
- }
-
- return (CPATH *) ln;
-}
-
-
-CPATH* line_copy(CPATH *_src)
-{
- line* src = (line*) _src;
- line* ln = new line(*src);
- return (CPATH *) ln;
-}
-
-void line_free (CPATH* _d)
-{
- line* ln = (line*) _d;
- delete ln;
-}
-
-void
-line_cmd (CPATH *_d, struct cmd_call_stack *s)
-{
- line* ln = (line*) _d;
- agg::path_storage& p = ln->path;
-
- switch (s->cmd)
- {
- case CMD_MOVE_TO:
- p.move_to (s->f[0], s->f[1]);
- break;
- case CMD_LINE_TO:
- p.line_to (s->f[0], s->f[1]);
- break;
- case CMD_CLOSE:
- p.close_polygon ();
- break;
- case CMD_SET_DASH:
- ln->set_dash (s->f[0], s->f[1]);
- break;
- case CMD_ADD_DASH:
- ln->add_dash (s->f[0], s->f[1]);
- break;
- case CMD_ARC_TO:
- p.arc_to (s->f[0], s->f[1], s->f[2], s->b[0], s->b[1], s->f[3], s->f[4]);
- break;
- case CMD_CURVE3:
- p.curve3 (s->f[0], s->f[1], s->f[2], s->f[3]);
- break;
- case CMD_CURVE4:
- p.curve4 (s->f[0], s->f[1], s->f[2], s->f[3], s->f[4], s->f[5]);
- }
-}
-
-CDRAW *
-ellipse_new (double x, double y, double rx, double ry)
-{
- drawable* d =
-}
-
-extern void ellipse_free (CDRAW *e);
-
-
-CDRAW *
-drawable_copy (CDRAW *_d)
-{
- drawable *src = (drawable *) _d;
- drawable *dst = src->copy();
- return (CDRAW *) dst;
-}
diff --git a/agg-plot/agg-cplot.h b/agg-plot/agg-cplot.h deleted file mode 100644 index b3476200..00000000 --- a/agg-plot/agg-cplot.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef CPLOT_CINTFC_H
-#define CPLOT_CINTFC_H
-
-#include "defs.h"
-
-#define CCPLOT struct _cplot
-#define CPATH struct _cpath
-#define CDRAW struct _cdraw
-
-__BEGIN_DECLS
-
-struct cmd_call_stack;
-
-CCPLOT;
-CPATH;
-CDRAW;
-
-extern CCPLOT * cplot_new (int with_units);
-extern void cplot_add (CCPLOT *p, CDRAW *d);
-extern void cplot_free (CCPLOT *p);
-
-extern CPATH * poly_new (const char *color_str, const char *outline_color);
-
-extern CPATH * path_new (const char *color_str);
-extern CPATH * path_copy (CPATH *p);
-extern void path_free (CPATH *p);
-extern void path_cmd (CPATH *p, struct cmd_call_stack *stack);
-
-extern CDRAW * ellipse_new (double x, double y, double rx, double ry);
-extern void ellipse_free (CDRAW *e);
-
-extern CDRAW * drawable_copy (CDRAW *d);
-
-__END_DECLS
-
-#ifndef __cplusplus
-typedef CCPLOT cplot;
-typedef CPATH path;
-typedef CDRAW drawable;
-#endif
-
-#endif
diff --git a/agg-plot/c-drawables.cpp b/agg-plot/c-drawables.cpp new file mode 100644 index 00000000..ff0bf910 --- /dev/null +++ b/agg-plot/c-drawables.cpp @@ -0,0 +1,184 @@ +
+#include "agg_color_rgba.h"
+
+// #include "units-plot.h"
+#include "plot.h"
+#include "trans.h"
+#include "vertex-source.h"
+#include "lua-plot-priv.h"
+
+#include "c-drawables.h"
+
+typedef my::path path_type;
+typedef my::ellipse ellipse_type;
+
+static agg::rgba8
+color_lookup (const char *color_str)
+{
+ const char *p = color_str;
+ agg::rgba8 c;
+ int val = 180;
+
+ if (strcmp (p, "white") == 0)
+ {
+ c = agg::rgba8(255, 255, 255);
+ return c;
+ }
+
+ if (strncmp (p, "light", 5) == 0)
+ {
+ val = 255;
+ p += 5;
+ }
+ else if (strncmp (p, "dark", 4) == 0)
+ {
+ val = 120;
+ p += 4;
+ }
+
+ if (strcmp (p, "red") == 0)
+ c = agg::rgba8(val, 0, 0);
+ else if (strcmp (p, "green") == 0)
+ c = agg::rgba8(0, val, 0);
+ else if (strcmp (p, "blue") == 0)
+ c = agg::rgba8(0, 0, val);
+ else if (strcmp (p, "cyan") == 0)
+ c = agg::rgba8(0, val, val);
+ else if (strcmp (p, "magenta") == 0)
+ c = agg::rgba8(val, 0, val);
+ else if (strcmp (p, "yellow") == 0)
+ c = agg::rgba8(val, val, 0);
+ else if (strcmp (p, "gray") == 0)
+ c = agg::rgba8(val, val, val);
+ else
+ c = agg::rgba8(0, 0, 0);
+
+ return c;
+}
+
+CPLOT *
+plot_new(int with_units)
+{
+ plot_type *p = new plot_type();
+ return (CPLOT *) p;
+}
+
+void plot_free (CPLOT* _d)
+{
+ plot_type* p = (plot_type*) _d;
+ delete p;
+}
+
+static vertex_source*
+build_pipeline (vertex_source* in, struct trans_spec *base)
+{
+ struct trans_spec *spec;
+ vertex_source* curr;
+ size_t n;
+
+ for (spec = base, n = 0; spec->tag != trans_end; spec++, n++) {}
+
+ for (spec = base + (n-1); spec >= base; spec--)
+ {
+ switch (spec->tag)
+ {
+ case trans_stroke:
+ curr = new trans::stroke(in, spec->content.stroke.width);
+ break;
+ case trans_curve:
+ curr = new trans::curve(in);
+ break;
+ case trans_resize:
+ curr = new trans::resize(in);
+ case trans_end:
+ ;
+ }
+
+ in = curr;
+ }
+
+ return in;
+}
+
+void plot_add(CPLOT *_p, CVERTSRC *_vs, const char *color,
+ struct trans_spec *post, struct trans_spec *pre)
+{
+ plot_type* p = (plot_type*) _p;
+ vertex_source* vs = (vertex_source*) _vs;
+ vertex_source* curr;
+
+ curr = build_pipeline (vs, pre);
+
+ if (curr->need_resize())
+ curr = new trans::resize(curr);
+
+ curr = build_pipeline (curr, post);
+
+ p->add(curr, color_lookup(color));
+}
+
+CPATH* path_new()
+{
+ path_type* p = new path_type();
+ return (CPATH *) p;
+}
+
+void vertex_source_ref (CVERTSRC *_p)
+{
+ vertex_source* p = (vertex_source*) _p;
+ p->ref();
+}
+
+void vertex_source_unref (CVERTSRC* _p)
+{
+ vertex_source* p = (vertex_source*) _p;
+ unsigned rc = p->unref();
+ if (rc == 0)
+ delete p;
+}
+
+void
+path_cmd (CPATH *_p, int _cmd, struct cmd_call_stack *s)
+{
+ path_type* p = (path_type*) _p;
+ agg::path_storage& ps = p->get_path();
+ path_cmd_e cmd = (path_cmd_e) _cmd;
+
+ switch (cmd)
+ {
+ case CMD_MOVE_TO:
+ ps.move_to (s->f[0], s->f[1]);
+ break;
+ case CMD_LINE_TO:
+ ps.line_to (s->f[0], s->f[1]);
+ break;
+ case CMD_CLOSE:
+ ps.close_polygon ();
+ break;
+ case CMD_ARC_TO:
+ ps.arc_to (s->f[0], s->f[1], s->f[2], s->b[0], s->b[1], s->f[3], s->f[4]);
+ break;
+ case CMD_CURVE3:
+ ps.curve3 (s->f[0], s->f[1], s->f[2], s->f[3]);
+ break;
+ case CMD_CURVE4:
+ ps.curve4 (s->f[0], s->f[1], s->f[2], s->f[3], s->f[4], s->f[5]);
+ break;
+ case CMD_ERROR:
+ ;
+ }
+}
+
+CVERTSRC *
+ellipse_new (double x, double y, double rx, double ry)
+{
+ ellipse_type* e = new ellipse_type(x, y, rx, ry);
+ return (CVERTSRC *) e;
+}
+
+void
+ellipse_free (CVERTSRC *_e)
+{
+ ellipse_type* e = (ellipse_type*) _e;
+ delete e;
+};
diff --git a/agg-plot/c-drawables.h b/agg-plot/c-drawables.h new file mode 100644 index 00000000..9b799ba9 --- /dev/null +++ b/agg-plot/c-drawables.h @@ -0,0 +1,49 @@ +#ifndef CPLOT_CINTFC_H
+#define CPLOT_CINTFC_H
+
+#include "defs.h"
+
+#define CPLOT struct my_c_plot
+#define CVERTSRC struct my_c_vs
+#define CPATH struct my_c_path
+
+#ifdef __cplusplus
+typedef plot<vertex_source, ref_manager> plot_type;
+#endif
+
+__BEGIN_DECLS
+
+struct cmd_call_stack;
+struct trans_spec;
+
+CPLOT;
+CVERTSRC;
+CPATH;
+
+extern CPLOT * plot_new (int with_units);
+extern void plot_free (CPLOT *p);
+extern void plot_add (CPLOT *p, CVERTSRC *src, const char *color,
+ struct trans_spec *post, struct trans_spec *pre);
+
+extern void vertex_source_ref (CVERTSRC *p);
+extern void vertex_source_unref (CVERTSRC *p);
+
+extern CPATH * path_new ();
+extern void path_cmd (CPATH *p, int cmd, struct cmd_call_stack *stack);
+
+
+
+extern CVERTSRC * ellipse_new (double x, double y, double rx, double ry);
+extern void ellipse_free (CVERTSRC *e);
+
+extern CVERTSRC * text_new (double x, double y, double size);
+
+__END_DECLS
+
+#ifndef __cplusplus
+typedef CPLOT plot;
+typedef CVERTSRC vertex_source;
+typedef CPATH path;
+#endif
+
+#endif
diff --git a/agg-plot/drawables.h b/agg-plot/drawables.h index 9eba5058..a1483b21 100644 --- a/agg-plot/drawables.h +++ b/agg-plot/drawables.h @@ -15,14 +15,17 @@ #include "agg_array.h" #include "agg_bounding_rect.h" +#include "utils.h" + namespace my { template <class T> class vs_proxy : public vertex_source { T* m_source; + unsigned ref_count; public: - vs_proxy(): vertex_source(), m_source(NULL) {}; + vs_proxy(): vertex_source(), m_source(NULL), ref_count(0) {}; void set_source(T* src) { m_source = src; }; @@ -35,6 +38,14 @@ public: #warning should loop through all the pah_ids agg::bounding_rect_single(*m_source, 0, x1, y1, x2, y2); }; + + virtual void ref() { ref_count++; }; + virtual unsigned unref() + { + if (ref_count > 0) + ref_count--; + return ref_count; + }; }; class path : public vs_proxy<agg::path_storage> { @@ -100,6 +111,8 @@ public: m_stroke.approximation_scale(trans_affine_max_norm(m)); }; + virtual bool need_resize() { return false; }; + void set_text(const char *s) { m_text.text(s); }; }; diff --git a/agg-plot/lua-cplot-priv.h b/agg-plot/lua-cplot-priv.h deleted file mode 100644 index 1c95f0ae..00000000 --- a/agg-plot/lua-cplot-priv.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef LUA_CPLOT_PRIV_H -#define LUA_CPLOT_PRIV_H - -#include <pthread.h> - -#include "defs.h" -#include "agg-cplot.h" - -__BEGIN_DECLS - -enum line_cmd_e { - CMD_ERROR = -1, - CMD_MOVE_TO = 0, - CMD_LINE_TO, - CMD_CLOSE, - CMD_SET_DASH, - CMD_ADD_DASH, - CMD_ARC_TO, - CMD_CURVE3, - CMD_CURVE4, -}; - -struct cmd_call_stack { - enum line_cmd_e cmd; - const char *signature; - double f[6]; - int b[2]; -}; - -struct lcplot { - cplot *plot; - pthread_mutex_t mutex[1]; - int lua_is_owner; - int is_shown; - void *window; -}; - -extern void lcplot_destroy (struct lcplot *cp); -extern void update_callback (void *_app); - -__END_DECLS - -#endif diff --git a/agg-plot/lua-plot-priv.h b/agg-plot/lua-plot-priv.h new file mode 100644 index 00000000..7604182c --- /dev/null +++ b/agg-plot/lua-plot-priv.h @@ -0,0 +1,62 @@ +#ifndef LUA_CPLOT_PRIV_H +#define LUA_CPLOT_PRIV_H + +#include <pthread.h> + +#include "defs.h" +#include "c-drawables.h" + +__BEGIN_DECLS + +enum path_cmd_e { + CMD_ERROR = -1, + CMD_MOVE_TO = 0, + CMD_LINE_TO, + CMD_CLOSE, + CMD_ARC_TO, + CMD_CURVE3, + CMD_CURVE4, +}; + +struct cmd_call_stack { + double f[6]; + int b[2]; +}; + +struct agg_plot { + CPLOT *plot; + pthread_mutex_t mutex[1]; + int lua_is_owner; + int is_shown; + void *window; +}; + +enum trans_type { + trans_end = -1, + trans_stroke = 0, + trans_curve, + trans_resize, +}; + +struct stroke_spec { + double width; +}; + +struct curve_spec { + int stub; +}; + +struct trans_spec { + enum trans_type tag; + union { + struct stroke_spec stroke; + struct curve_spec curve; + } content; +}; + +extern void agg_plot_destroy (struct agg_plot *cp); +extern void update_callback (void *_app); + +__END_DECLS + +#endif diff --git a/agg-plot/plot.cpp b/agg-plot/plot.cpp index 6c908c8c..32a37bff 100644 --- a/agg-plot/plot.cpp +++ b/agg-plot/plot.cpp @@ -7,78 +7,3 @@ #include "agg_conv_contour.h" #include "agg_vcgen_markers_term.h" #include "agg_bounding_rect.h" - -void -plot::bounding_box(double *px1, double *py1, double *px2, double *py2) -{ - bool is_set = false; - double& m_x1 = *px1; - double& m_y1 = *py1; - double& m_x2 = *px2; - double& m_y2 = *py2; - - for (unsigned j = 0; j < m_elements.size(); j++) - { - drawable& d = m_elements[j]; - - double x1, y1, x2, y2; - d.vs->bounding_box(&x1, &y1, &x2, &y2); - - if (! is_set) - { - m_x1 = x1; - m_x2 = x2; - m_y1 = y1; - m_y2 = y2; - - is_set = true; - } - else if (x2 > m_x2 || x1 < m_x1 || y2 > m_y2 || y1 < m_y1) - { - m_x1 = min(x1, m_x1); - m_y1 = min(y1, m_y1); - m_x2 = max(x2, m_x2); - m_y2 = max(y2, m_y2); - } - } -} - -void -plot::trans_matrix_update() -{ - if (! m_bbox_updated) - { - double x1, y1, x2, y2; - bounding_box(&x1, &y1, &x2, &y2); - - double fx = x2 - x1, fy = y2 - y1; - m_trans.reset(); - m_trans.scale(1/fx, 1/fy); - m_trans.translate(-x1/fx, -y1/fy); - m_bbox_updated = true; - } -} - -void -plot::draw_elements(canvas &canvas) -{ - agg::trans_affine m = m_trans; - viewport_scale(m); - canvas.scale(m); - - for (unsigned j = 0; j < m_elements.size(); j++) - { - drawable& d = m_elements[j]; - vertex_source& vs = d.get_vertex_source(); - vs.apply_transform(m, 1.0); - canvas.draw(vs, d.color); - } -} - -void -plot::viewport_scale(agg::trans_affine& m) -{ - const double xoffs = 0.09375, yoffs = 0.09375; - static agg::trans_affine rsz(1-2*xoffs, 0.0, 0.0, 1-2*yoffs, xoffs, yoffs); - trans_affine_compose (m, rsz); -} diff --git a/agg-plot/plot.h b/agg-plot/plot.h index 645857f6..3d2f0e58 100644 --- a/agg-plot/plot.h +++ b/agg-plot/plot.h @@ -10,6 +10,7 @@ #include "drawables.h" #include "canvas.h" #include "units.h" +#include "resource-manager.h" #include "agg_conv_transform.h" #include "agg_color_rgba.h" @@ -17,43 +18,45 @@ #include "agg_ellipse.h" #include "agg_array.h" -struct drawable { - vertex_source* vs; - agg::rgba8 color; +template<class VertexSource, class resource_manager = no_management> +class plot { - drawable(): vs(NULL), color() {}; - drawable(vertex_source* vs, agg::rgba8 c): vs(vs), color(c) {}; + class container { + public: + VertexSource* vs; + agg::rgba8 color; - ~drawable() {}; + container(): vs(NULL), color() {}; + container(VertexSource* vs, agg::rgba8 c): vs(vs), color(c) {}; - void bounding_box(double *x1, double *y1, double *x2, double *y2) - { - vertex_source& vsi = get_vertex_source(); - vsi.bounding_box(x1, y1, x2, y2); - }; + ~container() {}; - vertex_source& get_vertex_source() { return *vs; }; + void bounding_box(double *x1, double *y1, double *x2, double *y2) + { + VertexSource& vsi = get_vertex_source(); + vsi.bounding_box(x1, y1, x2, y2); + }; -/* - void draw(canvas& canvas, agg::trans_affine& t) - { - vs_type& vsi = get_vertex_source(); - agg::conv_transform<vs_type> p(vsi, t); - canvas.draw(p, color); + VertexSource& get_vertex_source() { return *vs; }; }; -*/ -}; -class plot { public: plot() : m_elements(), m_trans(), m_bbox_updated(true) { }; - virtual ~plot() {}; + virtual ~plot() + { + for (unsigned j; j < m_elements.size(); j++) + { + container& d = m_elements[j]; + resource_manager::dispose(d.vs); + } + }; - void add(vertex_source* vs, agg::rgba8 color) + void add(VertexSource* vs, agg::rgba8 color) { - drawable d(vs, color); + container d(vs, color); m_elements.add(d); m_bbox_updated = false; + resource_manager::acquire(vs); }; virtual void draw(canvas &canvas) @@ -69,11 +72,82 @@ protected: static void viewport_scale(agg::trans_affine& trans); - agg::pod_bvector<drawable> m_elements; + agg::pod_bvector<container> m_elements; agg::trans_affine m_trans; // bounding box bool m_bbox_updated; }; +template<class VS, class RM> +void plot<VS,RM>::draw_elements(canvas &canvas) +{ + agg::trans_affine m = m_trans; + viewport_scale(m); + canvas.scale(m); + + for (unsigned j = 0; j < m_elements.size(); j++) + { + container& d = m_elements[j]; + VS& vs = d.get_vertex_source(); + vs.apply_transform(m, 1.0); + canvas.draw(vs, d.color); + } +} + +template<class VS, class RM> +void plot<VS,RM>::trans_matrix_update() +{ + if (! m_bbox_updated) + { + double x1, y1, x2, y2; + bounding_box(&x1, &y1, &x2, &y2); + + double fx = x2 - x1, fy = y2 - y1; + m_trans.reset(); + m_trans.scale(1/fx, 1/fy); + m_trans.translate(-x1/fx, -y1/fy); + m_bbox_updated = true; + } +} + +template<class VS, class RM> +void plot<VS,RM>::bounding_box(double *x1, double *y1, double *x2, double *y2) +{ + bool is_set = false; + + for (unsigned j = 0; j < m_elements.size(); j++) + { + container& d = m_elements[j]; + + double sx1, sy1, sx2, sy2; + d.vs->bounding_box(&sx1, &sy1, &sx2, &sy2); + + if (! is_set) + { + *x1 = sx1; + *x2 = sx2; + *y1 = sy1; + *y2 = sy2; + + is_set = true; + } + else if (sx2 > *x2 || sx1 < *x1 || sy2 > *y2 || sy1 < *y1) + { + *x1 = min(sx1, *x1); + *y1 = min(sy1, *y1); + *x2 = max(sx2, *x2); + *y2 = max(sy2, *y2); + } + } +} + +template<class VS, class RM> +void plot<VS,RM>::viewport_scale(agg::trans_affine& m) +{ + const double xoffs = 0.09375, yoffs = 0.09375; + static agg::trans_affine rsz(1-2*xoffs, 0.0, 0.0, 1-2*yoffs, xoffs, yoffs); + trans_affine_compose (m, rsz); +} + #endif diff --git a/agg-plot/resource-manager.h b/agg-plot/resource-manager.h new file mode 100644 index 00000000..c59782a3 --- /dev/null +++ b/agg-plot/resource-manager.h @@ -0,0 +1,29 @@ +#ifndef AGGPLOT_RESOURCE_MANAGER_H
+#define AGGPLOT_RESOURCE_MANAGER_H
+
+
+class no_management {
+ public:
+ template <class T>
+ static void acquire(T* p) {};
+
+ template <class T>
+ static void dispose(T* p) {};
+};
+
+
+class ref_manager {
+public:
+ template <class T>
+ static void acquire(T* p) { p->ref(); };
+
+ template <class T>
+ static void dispose(T* p)
+ {
+ unsigned rc = p->unref();
+ if (rc == 0)
+ delete p;
+ };
+};
+
+#endif
diff --git a/agg-plot/test.cpp b/agg-plot/test.cpp index c1660fc2..60acf26d 100644 --- a/agg-plot/test.cpp +++ b/agg-plot/test.cpp @@ -48,7 +48,7 @@ public: my::text txt(-0.5, 1.5);
txt.set_text("Hello world!");
- plot plot;
+ plot<vertex_source> plot;
plot.add(&ttri, agg::rgba8(0,180,0));
plot.add(&tris, agg::rgba8(0,0,120));
plot.add(&tris2, agg::rgba8(0,0,0));
@@ -69,7 +69,7 @@ int main(int argc, char *argv[]) the_application app(agg::pix_format_bgr24, flip_y);
app.caption("GSL shell plot - TESTING");
- if(app.init(600, 600, agg::window_resize))
+ if(app.init(300, 300, agg::window_resize))
{
app.run();
}
diff --git a/agg-plot/trans.h b/agg-plot/trans.h index 2b5eaf20..522e3877 100644 --- a/agg-plot/trans.h +++ b/agg-plot/trans.h @@ -13,23 +13,32 @@ template<class T>
class vs_trans_proxy : public vertex_source {
T m_output;
- vertex_source& m_source;
+ vertex_source* m_source;
public:
- vs_trans_proxy(vertex_source& src): m_output(src), m_source(src) {};
+ vs_trans_proxy(vertex_source* src): m_output(*src), m_source(src) {};
virtual void rewind(unsigned path_id) { m_output.rewind(path_id); };
virtual unsigned vertex(double* x, double* y) { return m_output.vertex(x, y); };
+ virtual void ref() {};
+ virtual unsigned unref()
+ {
+ unsigned rc = m_source->unref();
+ if (rc == 0)
+ delete m_source;
+ return 0;
+ };
+
virtual void apply_transform(agg::trans_affine& m, double as)
{
m_output.approximation_scale(as);
- m_source.apply_transform(m, as);
+ m_source->apply_transform(m, as);
};
virtual void bounding_box(double *x1, double *y1, double *x2, double *y2)
{
- m_source.bounding_box(x1, y1, x2, y2);
+ m_source->bounding_box(x1, y1, x2, y2);
};
T& self() { return m_output; };
@@ -45,7 +54,7 @@ namespace trans { public:
typedef agg::conv_stroke<vertex_source> base_type;
- stroke(vertex_source& src, double width = 1.0): vs_stroke(src)
+ stroke(vertex_source* src, double width = 1.0): vs_stroke(src)
{
base_type& v = self();
v.width(width);
@@ -54,34 +63,42 @@ namespace trans { class curve : public vs_curve {
public:
- curve(vertex_source& src): vs_curve(src) {};
+ curve(vertex_source* src): vs_curve(src) {};
};
class resize : public vertex_source {
- agg::conv_transform<vertex_source> m_output;
- vertex_source& m_source;
-
agg::trans_affine m_matrix;
+ agg::conv_transform<vertex_source> m_output;
+ vertex_source* m_source;
public:
- resize(vertex_source& src):
- vertex_source(), m_output(src, m_matrix), m_source(src)
+ resize(vertex_source* src):
+ vertex_source(), m_matrix(), m_output(*src, m_matrix), m_source(src)
{};
virtual void rewind(unsigned path_id) { m_output.rewind(path_id); };
virtual unsigned vertex(double* x, double* y) { return m_output.vertex(x, y); };
+ virtual void ref() {};
+ virtual unsigned unref()
+ {
+ unsigned rc = m_source->unref();
+ if (rc == 0)
+ delete m_source;
+ return 0;
+ };
+
virtual void apply_transform(agg::trans_affine& m, double as)
{
m_matrix = m;
as *= trans_affine_max_norm(m);
- m_source.apply_transform(m, as);
+ m_source->apply_transform(m, as);
};
virtual void bounding_box(double *x1, double *y1, double *x2, double *y2)
{
#warning should loop through all the pah_ids
- agg::bounding_rect_single(m_source, 0, x1, y1, x2, y2);
+ agg::bounding_rect_single(*m_source, 0, x1, y1, x2, y2);
};
};
}
diff --git a/agg-plot/units_cplot.cpp b/agg-plot/units-plot.cpp index b9562168..b9562168 100644 --- a/agg-plot/units_cplot.cpp +++ b/agg-plot/units-plot.cpp diff --git a/agg-plot/units_cplot.h b/agg-plot/units-plot.h index 4217ffc4..4217ffc4 100644 --- a/agg-plot/units_cplot.h +++ b/agg-plot/units-plot.h diff --git a/agg-plot/vertex-source.h b/agg-plot/vertex-source.h index e8e721e0..21e561d3 100644 --- a/agg-plot/vertex-source.h +++ b/agg-plot/vertex-source.h @@ -3,14 +3,23 @@ #include "agg_trans_affine.h" -class vertex_source +class vertex_source_base { public: virtual void rewind(unsigned path_id) = 0; virtual unsigned vertex(double* x, double* y) = 0; + virtual ~vertex_source_base() {}; +}; + +class vertex_source : public vertex_source_base { +public: virtual void apply_transform(agg::trans_affine& m, double as) = 0; virtual void bounding_box(double *x1, double *y1, double *x2, double *y2) = 0; - virtual ~vertex_source() {}; + + virtual void ref() = 0; + virtual unsigned unref() = 0; + + virtual bool need_resize() { return true; }; }; #endif diff --git a/agg-plot/xwin-show.cpp b/agg-plot/xwin-show.cpp index 3ec38b92..60fe108d 100644 --- a/agg-plot/xwin-show.cpp +++ b/agg-plot/xwin-show.cpp @@ -6,8 +6,8 @@ #include "xwin-show.h" #include "canvas.h" -#include "cplot.h" -#include "lua-cplot-priv.h" +#include "plot.h" +#include "lua-plot-priv.h" extern void platform_support_prepare(); @@ -17,8 +17,8 @@ enum flip_y_e { flip_y = true }; class the_application : public agg::platform_support { public: - the_application(agg::pix_format_e format, bool flip_y, struct lcplot *cp) : - agg::platform_support(format, flip_y), m_cp(cp) + the_application(agg::pix_format_e format, bool flip_y, struct agg_plot *p) : + agg::platform_support(format, flip_y), m_plot(p) { }; @@ -30,18 +30,19 @@ public: { canvas can(rbuf_window(), width(), height(), agg::rgba(1.0, 1.0, 1.0)); can.clear(); - m_cp->plot->draw(can); + plot_type* plot = (plot_type*) m_plot->plot; + plot->draw(can); } virtual void on_draw() { - pthread_mutex_lock (m_cp->mutex); + pthread_mutex_lock (m_plot->mutex); on_draw_unprotected(); - pthread_mutex_unlock (m_cp->mutex); + pthread_mutex_unlock (m_plot->mutex); } private: - struct lcplot *m_cp; + struct agg_plot *m_plot; }; void update_callback (void *_app) @@ -52,39 +53,39 @@ void update_callback (void *_app) }; void * -xwin_thread_function (void *_cplot) +xwin_thread_function (void *_plot) { - struct lcplot *cp = (struct lcplot *) _cplot; + struct agg_plot *p = (struct agg_plot *) _plot; platform_support_prepare(); - pthread_mutex_lock (cp->mutex); + pthread_mutex_lock (p->mutex); - the_application app(agg::pix_format_bgr24, flip_y, cp); + the_application app(agg::pix_format_bgr24, flip_y, p); app.caption("GSL shell plot"); if(app.init(780, 400, agg::window_resize)) { - cp->window = (void *) &app; - pthread_mutex_unlock (cp->mutex); + p->window = (void *) &app; + pthread_mutex_unlock (p->mutex); app.run(); } else { - pthread_mutex_unlock (cp->mutex); + pthread_mutex_unlock (p->mutex); } - pthread_mutex_lock (cp->mutex); - cp->window = NULL; - if (cp->lua_is_owner) + pthread_mutex_lock (p->mutex); + p->window = NULL; + if (p->lua_is_owner) { - cp->is_shown = 0; - pthread_mutex_unlock (cp->mutex); + p->is_shown = 0; + pthread_mutex_unlock (p->mutex); } else { - pthread_mutex_unlock (cp->mutex); - lcplot_destroy (cp); + pthread_mutex_unlock (p->mutex); + agg_plot_destroy (p); } return NULL; diff --git a/lua-cplot.c b/lua-cplot.c deleted file mode 100644 index c9b28721..00000000 --- a/lua-cplot.c +++ /dev/null @@ -1,318 +0,0 @@ -
-#include <assert.h>
-#include <pthread.h>
-
-#include "lua.h"
-#include "lauxlib.h"
-
-#include "common.h"
-#include "agg-cplot.h"
-#include "lua-cplot-priv.h"
-#include "xwin-show.h"
-
-extern void cplot_register (lua_State *L);
-
-struct lline {
- line *element;
- bool is_owner;
-};
-
-static const char * const cplot_mt_name = "GSL.pl.cplot";
-static const char * const line_mt_name = "GSL.pl.draw";
-
-static int lline_new (lua_State *L);
-static int lpoly_new (lua_State *L);
-static int lline_move_to (lua_State *L);
-static int lline_line_to (lua_State *L);
-static int lline_close (lua_State *L);
-static int lline_free (lua_State *L);
-
-static int lcplot_new (lua_State *L);
-static int lcplot_show (lua_State *L);
-static int lcplot_add (lua_State *L);
-static int lcplot_free (lua_State *L);
-
-struct lline* check_drawable (lua_State *L, int index);
-struct lcplot* check_lcplot (lua_State *L, int index);
-
-static const struct luaL_Reg cplot_functions[] = {
- {"line", lline_new},
- {"poly", lpoly_new},
- {"cplot", lcplot_new},
- {NULL, NULL}
-};
-
-static const struct luaL_Reg lline_methods[] = {
- {"move_to", lline_move_to},
- {"line_to", lline_line_to},
- {"close", lline_close},
- {"__gc", lline_free},
- {NULL, NULL}
-};
-
-static const struct luaL_Reg cplot_methods[] = {
- {"show", lcplot_show},
- {"add", lcplot_add},
- {"__gc", lcplot_free},
- {NULL, NULL}
-};
-
-int
-lline_new (lua_State *L)
-{
- const char *color_str = luaL_optstring (L, 1, "black");
- struct lline *d;
-
- d = (struct lline *) lua_newuserdata (L, sizeof (struct lline));
-
- if (lua_gettop (L) > 1)
- {
- double ll[2] = {10.0, 10.0};
- size_t j, n;
-
- if (! lua_istable (L, 2))
- return luaL_error (L, "second argument of line should be a list of numbers"
- "to define dashed lines.");
-
- n = lua_objlen (L, 2);
- for (j = 1; j <= n && j <= 2; j++)
- {
- lua_rawgeti (L, 2, j);
- if (lua_isnumber (L, -1))
- ll[j-1] = lua_tonumber (L, -1);
- lua_pop (L, 1);
- }
-
- d->element = dashed_line_new (color_str, ll[0], ll[1]);
- }
- else
- {
- d->element = line_new (color_str);
- }
-
- d->is_owner = true;
-
- luaL_getmetatable (L, line_mt_name);
- lua_setmetatable (L, -2);
-
- printf ("created lline: %p\n", d);
-
- return 1;
-}
-
-int
-lpoly_new (lua_State *L)
-{
- const char *color_str = luaL_checkstring (L, 1);
- const char *outline_color_str = luaL_optstring (L, 2, NULL);
- struct lline *d = (struct lline *) lua_newuserdata (L, sizeof (struct lline));
-
- d->element = poly_new (color_str, outline_color_str);
- d->is_owner = true;
-
- luaL_getmetatable (L, line_mt_name);
- lua_setmetatable (L, -2);
-
- return 1;
-}
-
-struct lline *
-check_drawable (lua_State *L, int index)
-{
- return (struct lline*) luaL_checkudata (L, index, line_mt_name);
-}
-
-int
-lline_free (lua_State *L)
-{
- struct lline *d = check_drawable (L, 1);
- printf ("%p, line free... ", d);
- if (d->is_owner)
- {
- printf ("actually\n");
- line_free (d->element);
- }
- else
- {
- printf ("not really\n");
- }
- return 0;
-}
-
-int
-lline_move_to (lua_State *L)
-{
- struct lline *d = check_drawable (L, 1);
- double x = luaL_checknumber (L, 2);
- double y = luaL_checknumber (L, 3);
- line_move_to (d->element, x, y);
- return 0;
-}
-
-int
-lline_line_to (lua_State *L)
-{
- struct lline *d = check_drawable (L, 1);
- double x = luaL_checknumber (L, 2);
- double y = luaL_checknumber (L, 3);
- /* printf ("%la %la\n", x, y); */
- line_line_to (d->element, x, y);
- return 0;
-}
-
-int
-lline_close (lua_State *L)
-{
- struct lline *d = check_drawable (L, 1);
- line_close (d->element);
- return 0;
-}
-
-struct lcplot *
-check_lcplot (lua_State *L, int index)
-{
- struct lcplot **ptr = luaL_checkudata (L, index, cplot_mt_name);
- return *ptr;
-}
-
-int
-lcplot_new (lua_State *L)
-{
- lua_Integer use_units = 1;
- struct lcplot **cpptr = lua_newuserdata (L, sizeof(void *));
- struct lcplot *cp;
-
- if (lua_isboolean (L, 1))
- use_units = lua_toboolean (L, 1);
-
- cp = emalloc (sizeof(struct lcplot));
- *cpptr = cp;
-
- cp->plot = cplot_new (use_units);
- pthread_mutex_init (cp->mutex, NULL);
-
- cp->lua_is_owner = 1;
- cp->is_shown = 0;
- cp->window = NULL;
-
- luaL_getmetatable (L, cplot_mt_name);
- lua_setmetatable (L, -2);
-
- printf ("created lcplot: %p\n", cp);
-
- return 1;
-}
-
-void
-lcplot_destroy (struct lcplot *cp)
-{
- printf ("lcplot destroy %p\n", cp);
- cplot_free (cp->plot);
- pthread_mutex_destroy (cp->mutex);
- free (cp);
-}
-
-int
-lcplot_free (lua_State *L)
-{
- struct lcplot *cp = check_lcplot (L, 1);
-
- printf ("%p, cplot free... ", cp);
- pthread_mutex_lock (cp->mutex);
-
- assert (cp->lua_is_owner);
-
- if (cp->is_shown)
- {
- printf ("thread taking ownership of lcplot %p\n", cp);
- cp->lua_is_owner = 0;
- }
- else
- {
- printf ("really\n");
- pthread_mutex_unlock (cp->mutex);
- lcplot_destroy (cp);
- return 0;
- }
-
- pthread_mutex_unlock (cp->mutex);
- return 0;
-}
-
-int
-lcplot_add (lua_State *L)
-{
- struct lcplot *cp = check_lcplot (L, 1);
- struct lline *d = check_drawable (L, 2);
- cplot *p = cp->plot;
-
- pthread_mutex_lock (cp->mutex);
-
- if (d->is_owner)
- {
- cplot_add (p, d->element);
- d->is_owner = false;
- }
- else
- {
- line *ln_copy = line_copy (d->element);
- cplot_add (p, ln_copy);
- }
-
- if (cp->window)
- update_callback (cp->window);
-
- pthread_mutex_unlock (cp->mutex);
-
- return 0;
-}
-
-int
-lcplot_show (lua_State *L)
-{
- struct lcplot *cp = check_lcplot (L, 1);
- pthread_t xwin_thread[1];
- pthread_attr_t attr[1];
-
- pthread_mutex_lock (cp->mutex);
-
- if (! cp->is_shown)
- {
- pthread_attr_init (attr);
- pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
-
- if (pthread_create(xwin_thread, attr, xwin_thread_function, (void*) cp))
- {
- pthread_attr_destroy (attr);
- return luaL_error(L, "error creating thread.");
- }
-
- cp->is_shown = 1;
- pthread_attr_destroy (attr);
- }
-
- pthread_mutex_unlock (cp->mutex);
-
- return 0;
-}
-
-void
-cplot_register (lua_State *L)
-{
- /* cplot declaration */
- luaL_newmetatable (L, cplot_mt_name);
- lua_pushvalue (L, -1);
- lua_setfield (L, -2, "__index");
- luaL_register (L, NULL, cplot_methods);
- lua_pop (L, 1);
-
- /* drawable declaration */
- luaL_newmetatable (L, line_mt_name);
- lua_pushvalue (L, -1);
- lua_setfield (L, -2, "__index");
- luaL_register (L, NULL, lline_methods);
- lua_pop (L, 1);
-
- /* gsl module registration */
- luaL_register (L, NULL, cplot_functions);
-}
@@ -39,7 +39,7 @@ #include "cdf.h" #ifdef AGG_PLOT_ENABLED -#include "lua-cplot.h" +#include "lua-plot.h" #endif static const struct luaL_Reg gsl_methods_dummy[] = {{NULL, NULL}}; @@ -66,7 +66,7 @@ luaopen_gsl (lua_State *L) pdf_register (L); cdf_register (L); #ifdef AGG_PLOT_ENABLED - cplot_register (L); + plot_register (L); #endif #ifdef LNUM_COMPLEX diff --git a/lua-plot.c b/lua-plot.c new file mode 100644 index 00000000..6896c3d7 --- /dev/null +++ b/lua-plot.c @@ -0,0 +1,408 @@ +
+#include <assert.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "lua.h"
+#include "lauxlib.h"
+
+#include "common.h"
+#include "lua-plot-priv.h"
+#include "xwin-show.h"
+
+extern void plot_register (lua_State *L);
+
+enum agg_type {
+ AGG_PATH = 1,
+ AGG_ELLIPSE,
+ AGG_TEXT,
+};
+
+struct agg_obj {
+ enum agg_type tag;
+ vertex_source *vs;
+};
+
+struct path_cmd_reg {
+ enum path_cmd_e id;
+ const char *cmd;
+ const char *signature;
+};
+
+static const char * const plot_mt_name = "GSL.pl.plot";
+static const char * const vertex_source_mt_name = "GSL.pl.vs";
+
+static int agg_obj_free (lua_State *L);
+static int agg_obj_index (lua_State *L);
+
+static int agg_path_new (lua_State *L);
+static int agg_path_index (lua_State *L);
+
+static int agg_plot_new (lua_State *L);
+static int agg_plot_show (lua_State *L);
+static int agg_plot_add (lua_State *L);
+static int agg_plot_free (lua_State *L);
+
+struct agg_obj* check_agg_obj (lua_State *L, int index);
+path * check_agg_path (lua_State *L, int index);
+struct agg_plot* check_agg_plot (lua_State *L, int index);
+
+static struct path_cmd_reg cmd_table[] = {
+ {CMD_MOVE_TO, "move_to", "ff"},
+ {CMD_LINE_TO, "line_to", "ff"},
+ {CMD_CLOSE, "close", ""},
+ {CMD_ARC_TO, "arc_to", "fffbbff"},
+ {CMD_CURVE3, "curve3", "ffff"},
+ {CMD_CURVE4, "curve4", "ffffff"},
+ {CMD_ERROR, NULL, NULL}
+};
+
+static const struct luaL_Reg plot_functions[] = {
+ {"path", agg_path_new},
+ {"plot", agg_plot_new},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg agg_vertex_source_methods[] = {
+ {"__index", agg_obj_index},
+ {"__gc", agg_obj_free},
+ {NULL, NULL}
+};
+
+static const struct luaL_Reg agg_plot_methods[] = {
+ {"show", agg_plot_show},
+ {"add", agg_plot_add},
+ {"__gc", agg_plot_free},
+ {NULL, NULL}
+};
+
+int
+agg_path_new (lua_State *L)
+{
+ struct agg_obj *d = lua_newuserdata (L, sizeof (struct agg_obj));
+
+ d->vs = (vertex_source *) path_new ();
+ d->tag = AGG_PATH;
+
+ vertex_source_ref (d->vs);
+
+ luaL_getmetatable (L, vertex_source_mt_name);
+ lua_setmetatable (L, -2);
+
+ return 1;
+}
+
+struct agg_obj *
+check_agg_obj (lua_State *L, int index)
+{
+ return (struct agg_obj *) luaL_checkudata (L, index, vertex_source_mt_name);
+}
+
+path *
+check_agg_path (lua_State *L, int index)
+{
+ struct agg_obj *d = luaL_checkudata (L, index, vertex_source_mt_name);
+ if (d->tag == AGG_PATH)
+ return (path *) d->vs;
+ luaL_error (L, "expected object of type 'path' as argument #%i", index);
+ return NULL;
+}
+
+int
+agg_obj_free (lua_State *L)
+{
+ struct agg_obj *d = check_agg_obj (L, 1);
+ vertex_source_unref (d->vs);
+ return 0;
+}
+
+static int
+agg_path_cmd (lua_State *L)
+{
+ path *p = check_agg_path (L, 1);
+ int id = lua_tointeger (L, lua_upvalueindex(1));
+ const char *signature = lua_tostring (L, lua_upvalueindex(2));
+ int argc = 2, f_count = 0, b_count = 0;
+ struct cmd_call_stack s[1];
+ const char *fc;
+
+ for (fc = signature; fc[0]; fc++)
+ {
+ switch (fc[0])
+ {
+ case 'f':
+ s->f[f_count++] = luaL_checknumber (L, argc++);
+ break;
+ case 'b':
+ if (lua_isboolean (L, argc))
+ s->b[b_count++] = lua_toboolean (L, argc++);
+ else
+ return luaL_error (L, "expected boolean for argument #%i", argc);
+ }
+ }
+
+ path_cmd (p, id, s);
+ return 0;
+}
+
+static int
+agg_path_cmd_makeclosure (lua_State *L)
+{
+ lua_pushcclosure (L, agg_path_cmd, 2);
+ return 1;
+}
+
+int
+agg_obj_index (lua_State *L)
+{
+ struct agg_obj *d = check_agg_obj (L, 1);
+ int narg;
+
+ lua_getmetatable (L, 1);
+ lua_rawgeti (L, -1, (int) d->tag);
+ lua_remove (L, -2);
+ lua_insert (L, 1);
+
+ lua_call (L, 2, LUA_MULTRET);
+ narg = lua_gettop (L);
+
+ return narg;
+}
+
+int
+agg_path_index (lua_State *L)
+{
+ struct path_cmd_reg *r;
+ const char *key;
+
+ if (! lua_isstring (L, 2))
+ return 0;
+
+ key = lua_tostring (L, 2);
+ for (r = cmd_table; r->cmd; r++)
+ {
+ if (strcmp (key, r->cmd) == 0)
+ break;
+ }
+
+ if (r->cmd)
+ {
+ lua_pushcfunction (L, agg_path_cmd_makeclosure);
+ lua_pushinteger (L, (int) r->id);
+ lua_pushstring (L, r->signature);
+ lua_call (L, 2, 1);
+ return 1;
+ }
+
+ return 0;
+}
+
+struct agg_plot *
+check_agg_plot (lua_State *L, int index)
+{
+ struct agg_plot **ptr = luaL_checkudata (L, index, plot_mt_name);
+ return *ptr;
+}
+
+int
+agg_plot_new (lua_State *L)
+{
+ lua_Integer use_units = 1;
+ struct agg_plot **pptr = lua_newuserdata (L, sizeof(void *));
+ struct agg_plot *p;
+
+ if (lua_isboolean (L, 1))
+ use_units = lua_toboolean (L, 1);
+
+ p = emalloc (sizeof(struct agg_plot));
+ *pptr = p;
+
+ p->plot = plot_new (use_units);
+ pthread_mutex_init (p->mutex, NULL);
+
+ p->lua_is_owner = 1;
+ p->is_shown = 0;
+ p->window = NULL;
+
+ luaL_getmetatable (L, plot_mt_name);
+ lua_setmetatable (L, -2);
+
+ return 1;
+}
+
+void
+agg_plot_destroy (struct agg_plot *p)
+{
+ plot_free (p->plot);
+ pthread_mutex_destroy (p->mutex);
+ free (p);
+}
+
+int
+agg_plot_free (lua_State *L)
+{
+ struct agg_plot *p = check_agg_plot (L, 1);
+
+ pthread_mutex_lock (p->mutex);
+
+ assert (p->lua_is_owner);
+ p->lua_is_owner = 0;
+
+ if (p->is_shown)
+ {
+ pthread_mutex_unlock (p->mutex);
+ agg_plot_destroy (p);
+ return 0;
+ }
+
+ pthread_mutex_unlock (p->mutex);
+ return 0;
+}
+
+struct trans_spec *
+parse_spec (lua_State *L, int index, struct trans_spec *spec)
+{
+ const char *tag;
+
+ lua_rawgeti (L, index, 1);
+ if (! lua_isstring (L, -1))
+ {
+ lua_pop (L, 1);
+ return NULL;
+ }
+
+ tag = lua_tostring (L, -1);
+ lua_pop (L, 1);
+
+ if (strcmp (tag, "stroke") == 0)
+ {
+ lua_pushstring (L, "width");
+ lua_rawget (L, index);
+ if (lua_isnumber (L, -1))
+ {
+ struct stroke_spec *prop = &spec->content.stroke;
+ spec->tag = trans_stroke;
+ prop->width = lua_tonumber (L, -1);
+ lua_pop (L, 1);
+ return spec;
+ }
+ lua_pop (L, 1);
+ }
+ else if (strcmp (tag, "curve") == 0)
+ {
+ spec->tag = trans_curve;
+ return spec;
+ }
+ else if (strcmp (tag, "resize") == 0)
+ {
+ spec->tag = trans_resize;
+ return spec;
+ }
+
+ return NULL;
+}
+
+struct trans_spec *
+parse_spec_pipeline (lua_State *L, int index)
+{
+ size_t k, nb;
+ struct trans_spec *spec;
+
+ if (lua_type (L, index) != LUA_TTABLE)
+ return NULL;
+ nb = lua_objlen (L, index);
+
+ spec = emalloc ((nb+1) * sizeof(struct trans_spec));
+ for (k = 0; k < nb; k++)
+ {
+ int subindex;
+ lua_rawgeti (L, index, k+1);
+ subindex = lua_gettop (L);
+ if (parse_spec (L, subindex, spec + k) == NULL)
+ {
+ free (spec);
+ return NULL;
+ }
+ lua_pop (L, 1);
+ }
+
+ spec[k].tag = trans_end;
+
+ return spec;
+}
+
+int
+agg_plot_add (lua_State *L)
+{
+ struct agg_plot *p = check_agg_plot (L, 1);
+ struct agg_obj *d = check_agg_obj (L, 2);
+ const char *color = luaL_checkstring (L, 3);
+ struct trans_spec *post, *pre;
+
+ post = parse_spec_pipeline (L, 4);
+ if (post == NULL)
+ luaL_error (L, "error in definition of post transforms");
+
+ pre = parse_spec_pipeline (L, 5);
+ if (pre == NULL)
+ luaL_error (L, "error in definition of pre transforms");
+
+ pthread_mutex_lock (p->mutex);
+ plot_add (p->plot, d->vs, color, post, pre);
+ if (p->window)
+ update_callback (p->window);
+ pthread_mutex_unlock (p->mutex);
+
+ return 0;
+}
+
+int
+agg_plot_show (lua_State *L)
+{
+ struct agg_plot *cp = check_agg_plot (L, 1);
+ pthread_t xwin_thread[1];
+ pthread_attr_t attr[1];
+
+ pthread_mutex_lock (cp->mutex);
+
+ if (! cp->is_shown)
+ {
+ pthread_attr_init (attr);
+ pthread_attr_setdetachstate (attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(xwin_thread, attr, xwin_thread_function, (void*) cp))
+ {
+ pthread_attr_destroy (attr);
+ return luaL_error(L, "error creating thread.");
+ }
+
+ cp->is_shown = 1;
+ pthread_attr_destroy (attr);
+ }
+
+ pthread_mutex_unlock (cp->mutex);
+
+ return 0;
+}
+
+void
+plot_register (lua_State *L)
+{
+ /* plot declaration */
+ luaL_newmetatable (L, plot_mt_name);
+ lua_pushvalue (L, -1);
+ lua_setfield (L, -2, "__index");
+ luaL_register (L, NULL, agg_plot_methods);
+ lua_pop (L, 1);
+
+ /* line declaration */
+ luaL_newmetatable (L, vertex_source_mt_name);
+ lua_pushinteger (L, (int) AGG_PATH);
+ lua_pushcfunction (L, agg_path_index);
+ lua_settable (L, -3);
+ luaL_register (L, NULL, agg_vertex_source_methods);
+ lua_pop (L, 1);
+
+ /* gsl module registration */
+ luaL_register (L, NULL, plot_functions);
+}
diff --git a/lua-cplot.h b/lua-plot.h index e8ef67ef..b9ce1dcb 100644 --- a/lua-cplot.h +++ b/lua-plot.h @@ -7,7 +7,7 @@ __BEGIN_DECLS
-extern void cplot_register (lua_State *L);
+extern void plot_register (lua_State *L);
__END_DECLS
diff --git a/makeconfig b/makeconfig index 37ef83a8..1782e83e 100644 --- a/makeconfig +++ b/makeconfig @@ -4,5 +4,5 @@ ENABLE_AGG_PLOT = yes BUILD_LUA_DLL = no
# PLATFORM should can be linux or mingw
-PLATFORM = none
+PLATFORM = linux
DEBUG = yes
@@ -1,5 +1,10 @@ -ifeq ($(strip $(DEBUG)), yes) +CC = gcc +CXX = g++ + +DEBUG = yes + +ifeq ($(strip $(DEBUG)), no) CFLAGS = -O2 -Wall CXXFLAGS = -O2 -Wall else diff --git a/scripts/saveall.sh b/scripts/saveall.sh new file mode 100755 index 00000000..8f0e6bc1 --- /dev/null +++ b/scripts/saveall.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +tar czvf 1ドル `find . -type f -not -regex '.*\.\(o\|exe\|dll\|a\|so\)' -a -not -regex '.*\.\(svn\|libs\|deps\).*' -not -name '*~'` |