-rw-r--r-- | agg-plot/agg_platform_support_x11.cpp | 6 | ||||
-rw-r--r-- | agg-plot/lua-plot.cpp | 6 | ||||
-rw-r--r-- | agg-plot/platform_support_ext.h | 28 | ||||
-rw-r--r-- | agg-plot/plot.h | 33 | ||||
-rw-r--r-- | agg-plot/window-cpp.h | 14 | ||||
-rw-r--r-- | agg-plot/window.cpp | 94 | ||||
-rw-r--r-- | agg-plot/window.h | 2 |
diff --git a/agg-plot/agg_platform_support_x11.cpp b/agg-plot/agg_platform_support_x11.cpp index ddc0d04b..77e7026c 100644 --- a/agg-plot/agg_platform_support_x11.cpp +++ b/agg-plot/agg_platform_support_x11.cpp @@ -37,12 +37,6 @@ #include "util/agg_color_conv_rgb8.h" #include "platform_support_ext.h" -/* -extern "C" { - static int thread_error_handler (Display *d, XErrorEvent *ev); -} -*/ - namespace agg { //------------------------------------------------------------------------ diff --git a/agg-plot/lua-plot.cpp b/agg-plot/lua-plot.cpp index 1a07330f..72f00ba0 100644 --- a/agg-plot/lua-plot.cpp +++ b/agg-plot/lua-plot.cpp @@ -312,9 +312,13 @@ int plot_push_layer (lua_State *L) { lua_plot *p = object_check<lua_plot>(L, 1, GS_PLOT); + AGG_LOCK(); p->push_layer(); AGG_UNLOCK(); + + window_plot_rev_lookup_apply (L, 1, window_save_slot_image); + return 0; } @@ -337,6 +341,8 @@ plot_clear (lua_State *L) p->clear_current_layer(); AGG_UNLOCK(); + window_plot_rev_lookup_apply (L, 1, window_restore_slot_image); + if (p->sync_mode()) plot_update_raw (L, p, 1); diff --git a/agg-plot/platform_support_ext.h b/agg-plot/platform_support_ext.h index e9007b9b..2cbcccd9 100644 --- a/agg-plot/platform_support_ext.h +++ b/agg-plot/platform_support_ext.h @@ -24,6 +24,34 @@ void my_color_conv(RenBufDst* dst, const RenBufSrc* src, CopyRow copy_row_functo } } +template<class RenBufDst, class RenBufSrc> +void rendering_buffer_get_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r, + unsigned pixel_width) +{ + int w = r.x2 - r.x1, h = r.y2 - r.y1; + for (int y = 0; y < h; y++) + { + unsigned char *drow = dst.row_ptr(y); + unsigned char *srow = src.row_ptr(r.y1 + y); + srow += r.x1 * pixel_width; + memcpy (drow, srow, pixel_width * w); + } +} + +template<class RenBufDst, class RenBufSrc> +void rendering_buffer_put_region (RenBufDst& dst, RenBufSrc& src, agg::rect_base<int>& r, + unsigned pixel_width) +{ + int w = r.x2 - r.x1, h = r.y2 - r.y1; + for (int y = 0; y < h; y++) + { + unsigned char *drow = dst.row_ptr(r.y1 + y); + unsigned char *srow = src.row_ptr(y); + drow += r.x1 * pixel_width; + memcpy (drow, srow, pixel_width * w); + } +} + template<class T> class row_accessor_ro { public: diff --git a/agg-plot/plot.h b/agg-plot/plot.h index c44fec94..61984d3c 100644 --- a/agg-plot/plot.h +++ b/agg-plot/plot.h @@ -115,12 +115,8 @@ public: bool need_redraw() const { return m_need_redraw; }; void commit_pending_draw(); - bool draw_queue(canvas &canvas, - agg::trans_affine& m, - agg::rect_base<double>& bbox, - iterator*& current); - - iterator* drawing_start() { return m_drawing_queue; }; + bool draw_queue(canvas &canvas, agg::trans_affine& m, + agg::rect_base<double>& bbox); void sync_mode(bool req_mode) { m_sync_mode = req_mode; }; bool sync_mode() const { return m_sync_mode; }; @@ -300,21 +296,23 @@ void plot<VS,RM>::draw_elements(canvas &canvas, agg::trans_affine& canvas_mtx) template<class VS, class RM> bool plot<VS,RM>::draw_queue(canvas &canvas, agg::trans_affine& canvas_mtx, - agg::rect_base<double>& bb, - plot<VS,RM>::iterator*& current) + agg::rect_base<double>& bb) { - if (current == 0) - return false; + plot<VS,RM>::iterator *c0 = m_drawing_queue; + for (plot<VS,RM>::iterator *c = c0; c != 0; c = c->next()) + { + item& d = c->content(); + agg::trans_affine m = get_scaled_matrix(canvas_mtx); + draw_element(d, canvas, m); - item& d = current->content(); - agg::trans_affine m = get_scaled_matrix(canvas_mtx); - draw_element(d, canvas, m); + agg::rect_base<double> ebb; + agg::bounding_rect_single(d.vertex_source(), 0, + &ebb.x1, &ebb.y1, &ebb.x2, &ebb.y2); - agg::bounding_rect_single(d.vertex_source(), 0, - &bb.x1, &bb.y1, &bb.x2, &bb.y2); + bb = (c == c0 ? ebb : agg::unite_rectangles(ebb, bb)); + } - current = current->next(); - return true; + return (c0 != 0); } template<class VS, class RM> @@ -536,7 +534,6 @@ void plot<VS,RM>::clear_current_layer() clear_drawing_queue(); layer_dispose_elements (current_layer()); m_current_layer->clear(); - m_need_redraw = true; } #endif diff --git a/agg-plot/window-cpp.h b/agg-plot/window-cpp.h index 99db9163..42abcfc3 100644 --- a/agg-plot/window-cpp.h +++ b/agg-plot/window-cpp.h @@ -30,8 +30,13 @@ public: bmatrix matrix; - ref() : plot(0), matrix() {}; - ref(plot_type *p) : plot(p), matrix() {}; + unsigned char *layer_buf; + agg::rendering_buffer layer_img; + + ref() : plot(0), matrix(), layer_buf(0) {}; + ref(plot_type *p) : plot(p), matrix(), layer_buf(0) {}; + + ~ref() { if (layer_buf) delete layer_buf; }; static void compose(bmatrix& a, const bmatrix& b); static int calculate(node *t, const bmatrix& m, int id); @@ -46,7 +51,7 @@ private: static ref *ref_lookup (ref::node *p, int slot_id); ref::node* m_tree; - + public: window(agg::rgba& bgcol) : canvas_window(bgcol), m_tree(0) { @@ -60,6 +65,9 @@ public: void draw_slot(int slot_id, bool update_req); void refresh_slot(int slot_id); + void save_slot_image(int slot_id); + void restore_slot_image(int slot_id); + void cleanup_refs(lua_State *L, int window_index) { cleanup_tree_rec (L, window_index, m_tree); diff --git a/agg-plot/window.cpp b/agg-plot/window.cpp index fb4c86a5..78b81a68 100644 --- a/agg-plot/window.cpp +++ b/agg-plot/window.cpp @@ -14,11 +14,12 @@ extern "C" { #include "colors.h" #include "lua-plot-cpp.h" #include "split-parser.h" +#include "platform_support_ext.h" __BEGIN_DECLS -static int window_free (lua_State *L); -static int window_split (lua_State *L); +static int window_free (lua_State *L); +static int window_split (lua_State *L); static const struct luaL_Reg window_functions[] = { {"window", window_new}, @@ -158,16 +159,67 @@ window::draw_slot(int slot_id, bool clean_req) } void +window::save_slot_image(int slot_id) +{ + ref *ref = window::ref_lookup (this->m_tree, slot_id); + if (ref != 0) + { + agg::trans_affine mtx(ref->matrix); + this->scale(mtx); + + agg::rect_base<int> r = rect_of_slot_matrix(mtx); + int w = r.x2 - r.x1, h = r.y2 - r.y1; + + unsigned img_bpp = this->bpp(); + int row_len = w * (img_bpp / 8); + + if (ref->layer_buf == 0) + { + unsigned int bufsize = row_len * h; + ref->layer_buf = new(std::nothrow) unsigned char[bufsize]; + ref->layer_img.attach(ref->layer_buf, w, h, this->flip_y() ? -row_len : row_len); + } + + if (ref->layer_buf != 0) + { + agg::rendering_buffer& img = ref->layer_img; + agg::rendering_buffer& win = this->rbuf_window(); + rendering_buffer_get_region (img, win, r, img_bpp / 8); + } + } +} + +void +window::restore_slot_image(int slot_id) +{ + ref *ref = window::ref_lookup (this->m_tree, slot_id); + if (ref != 0) + { + agg::trans_affine mtx(ref->matrix); + this->scale(mtx); + + agg::rect_base<int> r = rect_of_slot_matrix(mtx); + unsigned img_bpp = this->bpp(); + + if (ref->layer_buf != 0) + { + agg::rendering_buffer& img = ref->layer_img; + agg::rendering_buffer& win = this->rbuf_window(); + rendering_buffer_put_region (win, img, r, img_bpp / 8); + } + } +} + +void window::refresh_slot_by_ref(ref& ref) { agg::trans_affine mtx(ref.matrix); this->scale(mtx); - agg::rect_base<double> bb; AGG_LOCK(); try { - plot_type::iterator *current = ref.plot->drawing_start(); - while (ref.plot->draw_queue(*m_canvas, mtx, bb, current)) + agg::rect_base<double> bb; + if (ref.plot->draw_queue(*m_canvas, mtx, bb)) { agg::rect_base<int> bbw(bb.x1 - 4, bb.y1 - 4, bb.x2 + 4, bb.y2 + 4); platform_support_update_region (this, bbw); @@ -367,6 +419,38 @@ window_update (lua_State *L) return 0; } +int +window_save_slot_image (lua_State *L) +{ + window *win = object_check<window>(L, 1, GS_WINDOW); + int slot_id = luaL_checkinteger (L, 2); + + win->lock(); + if (win->status == canvas_window::running) + { + win->save_slot_image(slot_id); + } + win->unlock(); + + return 0; +} + +int +window_restore_slot_image (lua_State *L) +{ + window *win = object_check<window>(L, 1, GS_WINDOW); + int slot_id = luaL_checkinteger (L, 2); + + win->lock(); + if (win->status == canvas_window::running) + { + win->restore_slot_image(slot_id); + } + win->unlock(); + + return 0; +} + void window_register (lua_State *L) { diff --git a/agg-plot/window.h b/agg-plot/window.h index 1eb42705..99b59fa2 100644 --- a/agg-plot/window.h +++ b/agg-plot/window.h @@ -11,6 +11,8 @@ extern void window_register (lua_State *L); extern int window_slot_update (lua_State *L); extern int window_slot_refresh (lua_State *L); +extern int window_save_slot_image (lua_State *L); +extern int window_restore_slot_image (lua_State *L); extern int window_update (lua_State *L); extern int window_new (lua_State *L); extern int window_attach (lua_State *L); |