gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat
-rw-r--r--agg-plot/plot.h 15
-rw-r--r--agg-plot/rect.h 16
-rw-r--r--fox-gui/Makefile 2
-rw-r--r--fox-gui/fx_plot_canvas.cpp 248
-rw-r--r--fox-gui/fx_plot_canvas.h 77
-rw-r--r--fox-gui/image_buf.h 16
-rw-r--r--fox-gui/lua_plot_window.cpp 58
-rw-r--r--fox-gui/window_part.cpp 5
-rw-r--r--fox-gui/window_part.h 2
-rw-r--r--fox-gui/window_surface.cpp 142
-rw-r--r--fox-gui/window_surface.h 91
11 files changed, 367 insertions, 305 deletions
diff --git a/agg-plot/plot.h b/agg-plot/plot.h
index 0ab76a89..06d0d35a 100644
--- a/agg-plot/plot.h
+++ b/agg-plot/plot.h
@@ -466,6 +466,11 @@ protected:
bool m_need_redraw;
opt_rect<double> m_rect;
+ // keep trace of the region where changes happened since
+ // the last pushlayer or clear
+ opt_rect<double> m_changes_accu;
+ opt_rect<double> m_changes_pending;
+
bool m_use_units;
units m_ux, m_uy;
@@ -505,6 +510,7 @@ void plot<RM>::commit_pending_draw()
{
push_drawing_queue();
m_need_redraw = false;
+ m_changes_pending.clear();
}
template <class RM>
@@ -642,6 +648,13 @@ template <class Canvas> void plot<RM>::draw_queue(Canvas& _canvas, const agg::tr
bb.add<rect_union>(ebb);
}
+ m_changes_accu.add<rect_union>(bb);
+
+ if (m_changes_pending.is_defined())
+ {
+ bb.add<rect_union>(m_changes_pending);
+ }
+
canvas.reset_clipping();
}
@@ -1114,6 +1127,8 @@ void plot<RM>::clear_current_layer()
clear_drawing_queue();
layer_dispose_elements(current);
current->clear();
+ m_changes_pending = m_changes_accu;
+ m_changes_accu.clear();
}
template <class RM>
diff --git a/agg-plot/rect.h b/agg-plot/rect.h
index 3205da6c..d768d0dd 100644
--- a/agg-plot/rect.h
+++ b/agg-plot/rect.h
@@ -20,10 +20,20 @@ public:
void clear() {
m_defined = false;
};
+
void set(const rect_type& r) {
m_defined = true;
m_rect = r;
};
+
+ void set(T x1, T y1, T x2, T y2) {
+ m_defined = true;
+ m_rect.x1 = x1;
+ m_rect.y1 = y1;
+ m_rect.x2 = x2;
+ m_rect.y2 = y2;
+ };
+
bool is_defined() const {
return m_defined;
};
@@ -41,6 +51,12 @@ public:
m_rect = src.m_rect;
}
+ void operator = (const rect_type& src)
+ {
+ m_defined = true;
+ m_rect = src;
+ }
+
template <set_oper_e op>
void add(const rect_type& r)
{
diff --git a/fox-gui/Makefile b/fox-gui/Makefile
index c3d99526..0d793220 100644
--- a/fox-gui/Makefile
+++ b/fox-gui/Makefile
@@ -36,7 +36,7 @@ INCLUDES += -I$(GSH_BASE_DIR) -I$(GSH_BASE_DIR)/lua-gsl -I$(GSH_BASE_DIR)/agg-pl
INCLUDES += $(AGG_INCLUDES) $(FOX_INCLUDES) $(FREETYPE_INCLUDES) $(PTHREADS_CFLAGS)
LIBS += $(GSL_SHELL_LIBS) $(FOX_LIBS) $(AGG_LIBS) $(FREETYPE_LIBS) $(PTHREADS_LIBS) $(GSL_LIBS) -lsupc++ -lm
-FOXGUI_SRC_FILES = io_thread.cpp fx_console.cpp redirect.cpp gsl_shell_interp.cpp gsl_shell_thread.cpp fox_gsl_shell.cpp gsl_shell_window.cpp window_part.cpp fx_plot_canvas.cpp fx_plot_window.cpp lua_plot_window.cpp gsl_shell_app.cpp gsl-shell-fox.cpp
+FOXGUI_SRC_FILES = io_thread.cpp window_surface.cpp fx_console.cpp redirect.cpp gsl_shell_interp.cpp gsl_shell_thread.cpp fox_gsl_shell.cpp gsl_shell_window.cpp window_part.cpp fx_plot_canvas.cpp fx_plot_window.cpp lua_plot_window.cpp gsl_shell_app.cpp gsl-shell-fox.cpp
FOXGUI_OBJ_FILES := $(FOXGUI_SRC_FILES:%.cpp=%.o)
DEP_FILES := $(FOXGUI_SRC_FILES:%.cpp=.deps/%.P)
diff --git a/fox-gui/fx_plot_canvas.cpp b/fox-gui/fx_plot_canvas.cpp
index d96a0943..879a2135 100644
--- a/fox-gui/fx_plot_canvas.cpp
+++ b/fox-gui/fx_plot_canvas.cpp
@@ -8,91 +8,22 @@
FXDEFMAP(fx_plot_canvas) fx_plot_canvas_map[]=
{
FXMAPFUNC(SEL_PAINT, 0, fx_plot_canvas::on_cmd_paint),
- FXMAPFUNC(SEL_UPDATE, 0, fx_plot_canvas::on_update),
};
FXIMPLEMENT(fx_plot_canvas,FXCanvas,fx_plot_canvas_map,ARRAYNUMBER(fx_plot_canvas_map));
fx_plot_canvas::fx_plot_canvas(FXComposite* p, const char* split_str, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h):
- FXCanvas(p, tgt, sel, opts, x, y, w, h),
- m_img(), m_save_img(), m_canvas(0)
+ FXCanvas(p, tgt, sel, opts, x, y, w, h), m_surface(split_str)
{
- split(split_str ? split_str : ".");
-}
-
-fx_plot_canvas::~fx_plot_canvas()
-{
- delete m_canvas;
-}
-
-void fx_plot_canvas::split(const char* split_str)
-{
- m_part.parse(split_str);
- m_part.split();
-
- m_plots.clear();
- plot_ref empty;
- for (unsigned k = 0; k < m_part.get_slot_number(); k++)
- m_plots.add(empty);
-}
-
-bool fx_plot_canvas::prepare_image_buffer(unsigned ww, unsigned hh)
-{
- if (likely(m_img.resize(ww, hh)))
- {
- m_canvas = new(std::nothrow) canvas(m_img, ww, hh, colors::white);
- plots_set_to_dirty();
- return (m_canvas != NULL);
- }
- return false;
-}
-
-bool fx_plot_canvas::ensure_canvas_size(unsigned ww, unsigned hh)
-{
- if (unlikely(m_img.width() != ww || m_img.height() != hh))
- {
- return prepare_image_buffer(ww, hh);
- }
- return true;
-}
-
-void fx_plot_canvas::plot_render(plot_ref& ref, const agg::rect_i& r)
-{
- m_canvas->clear_box(r);
- if (ref.plot)
- {
- AGG_LOCK();
- ref.plot->draw(*m_canvas, r, &ref.inf);
- AGG_UNLOCK();
- }
- ref.is_image_dirty = false;
-}
-
-void fx_plot_canvas::plot_render(unsigned index)
-{
- plot_ref& ref = m_plots[index];
- int ww = getWidth(), hh = getHeight();
- agg::rect_i r = m_part.rect(index, ww, hh);
- plot_render(ref, r);
-}
-
-opt_rect<double>
-fx_plot_canvas::plot_render_queue(plot_ref& ref, const agg::rect_i& box)
-{
- const agg::trans_affine m = affine_matrix(box);
- opt_rect<double> r, draw_rect;
- AGG_LOCK();
- ref.plot->draw_queue(*m_canvas, m, ref.inf, draw_rect);
- AGG_UNLOCK();
- r.add<rect_union>(draw_rect);
- r.add<rect_union>(ref.dirty_rect);
- ref.dirty_rect = draw_rect;
- return r;
}
void fx_plot_canvas::update_region(const agg::rect_i& r)
{
FXshort ww = r.x2 - r.x1, hh= r.y2 - r.y1;
+ if (ww <= 0 || hh <= 0) return;
+
+ const image& src_img = m_surface.get_image();
+
FXImage img(getApp(), NULL, IMAGE_OWNED|IMAGE_SHMI|IMAGE_SHMP, ww, hh);
const unsigned fox_pixel_size = 4;
@@ -101,7 +32,7 @@ void fx_plot_canvas::update_region(const agg::rect_i& r)
dest.attach((agg::int8u*) img.getData(), ww, hh, -ww * fox_pixel_size);
rendering_buffer_ro src;
- rendering_buffer_get_const_view(src, m_img, r, image_pixel_width);
+ rendering_buffer_get_const_view(src, src_img, r, window_surface::image_pixel_width);
my_color_conv(&dest, &src, color_conv_rgb24_to_rgba32());
@@ -111,151 +42,82 @@ void fx_plot_canvas::update_region(const agg::rect_i& r)
dc.drawImage(&img, r.x1, getHeight() - r.y2);
}
-void fx_plot_canvas::plot_draw(unsigned index, int canvas_width, int canvas_height)
-{
- plot_ref& ref = m_plots[index];
- agg::rect_i r = m_part.rect(index, canvas_width, canvas_height);
- if (ref.is_image_dirty)
- plot_render(ref, r);
- update_region(r);
- ref.is_dirty = false;
-}
-
-sg_plot* fx_plot_canvas::get_plot(unsigned index, int canvas_width, int canvas_height, agg::rect_i& area)
+void fx_plot_canvas::update_plot_region(unsigned index)
{
- plot_ref& ref = m_plots[index];
- if (ref.plot)
- area = m_part.rect(index, canvas_width, canvas_height);
- return ref.plot;
+ agg::rect_i area = m_surface.get_plot_area(index);
+ update_region(area);
}
-void fx_plot_canvas::plot_draw(unsigned index)
+int fx_plot_canvas::attach(sg_plot* p, const char* slot_str)
{
- int ww = getWidth(), hh = getHeight();
- plot_draw(index, ww, hh);
+ return m_surface.attach(p, slot_str);
}
-void
-fx_plot_canvas::plot_draw_queue(unsigned index, int canvas_width, int canvas_height, bool draw_all)
+void fx_plot_canvas::slot_refresh(unsigned index)
{
- plot_ref& ref = m_plots[index];
-
- if (!ref.plot) return;
-
- agg::rect_i r = m_part.rect(index, canvas_width, canvas_height);
- opt_rect<double> rect = plot_render_queue(ref, r);
+ bool redraw = m_surface.plot(index)->need_redraw();
+ if (redraw)
+ {
+ m_surface.render(index);
+ }
- if (draw_all)
+ opt_rect<int> r = m_surface.render_drawing_queue(index);
+ agg::rect_i area = m_surface.get_plot_area(index);
+ if (redraw)
{
- update_region(r);
+ update_region(area);
}
- else if (rect.is_defined())
+ else
{
- const int pd = 4;
- const agg::rect_d& ur = rect.rect();
- const agg::rect_i box(0, 0, canvas_width, canvas_height);
- agg::rect_i ri(ur.x1 - pd, ur.y1 - pd, ur.x2 + pd, ur.y2 + pd);
- ri.clip(box);
- update_region(ri);
+ if (r.is_defined())
+ {
+ const int pad = 4;
+ const agg::rect_i& ri = r.rect();
+ agg::rect_i r_pad(ri.x1 - pad, ri.y1 - pad, ri.x2 + pad, ri.y2 + pad);
+ r_pad.clip(area);
+ update_region(r_pad);
+ }
}
}
-
-void fx_plot_canvas::plot_draw_queue(unsigned index, bool draw_all)
-{
- int ww = getWidth(), hh = getHeight();
- plot_draw_queue(index, ww, hh, draw_all);
-}
-
-void plot_ref::attach(sg_plot* p)
+void
+fx_plot_canvas::slot_update(unsigned index)
{
- plot = p;
- is_dirty = true;
- is_image_dirty = true;
- dirty_rect.clear();
+ m_surface.render(index);
+ m_surface.render_drawing_queue(index);
+ update_plot_region(index);
}
-int fx_plot_canvas::attach(sg_plot* p, const char* slot_str)
+void
+fx_plot_canvas::save_slot_image(unsigned index)
{
- int index = m_part.get_slot_index(slot_str);
- if (index >= 0)
- m_plots[index].attach(p);
- return index;
+ m_surface.save_plot_image(index);
}
-bool fx_plot_canvas::save_plot_image(unsigned index)
-{
- int ww = getWidth(), hh = getHeight();
-
- if (!m_save_img.ensure_size(ww, hh)) return false;
-
- plot_ref& ref = m_plots[index];
- agg::rect_i r = m_part.rect(index, ww, hh);
-
- if (ref.is_image_dirty)
- plot_render(ref, r);
-
- rendering_buffer_ro src;
- rendering_buffer_get_const_view(src, m_img, r, image_pixel_width);
-
- agg::rendering_buffer dest;
- rendering_buffer_get_view(dest, m_save_img, r, image_pixel_width);
-
- dest.copy_from(src);
- return true;
-}
-
-bool fx_plot_canvas::restore_plot_image(unsigned index)
-{
- int ww = getWidth(), hh = getHeight();
-
- if (!image::match(m_img, m_save_img))
- return false;
-
- agg::rect_i r = m_part.rect(index, ww, hh);
-
- rendering_buffer_ro src;
- rendering_buffer_get_const_view(src, m_save_img, r, image_pixel_width);
-
- agg::rendering_buffer dest;
- rendering_buffer_get_view(dest, m_img, r, image_pixel_width);
-
- dest.copy_from(src);
- return true;
-}
-
-long fx_plot_canvas::on_cmd_paint(FXObject *, FXSelector, void *ptr)
+void
+fx_plot_canvas::restore_slot_image(unsigned index)
{
- int ww = getWidth(), hh = getHeight();
- if (unlikely(!ensure_canvas_size(ww, hh)))
- return 1;
- for (unsigned k = 0; k < m_plots.size(); k++)
+ if (m_surface.have_saved_image(index))
{
- plot_draw(k, ww, hh);
+ m_surface.restore_plot_image(index);
+ }
+ else
+ {
+ m_surface.render(index);
+ m_surface.save_plot_image(index);
}
- return 1;
}
-long fx_plot_canvas::on_update(FXObject *, FXSelector, void *)
+long fx_plot_canvas::on_cmd_paint(FXObject *, FXSelector, void *ptr)
{
int ww = getWidth(), hh = getHeight();
- if (unlikely(!ensure_canvas_size(ww, hh)))
- return 1;
- for (unsigned k = 0; k < m_plots.size(); k++)
+
+ if (!m_surface.canvas_size_match(ww, hh))
{
- plot_ref& ref = m_plots[k];
- if (ref.is_dirty)
- {
- plot_draw(k, ww, hh);
- }
+ m_surface.resize(ww, hh);
+ m_surface.draw_image_buffer();
}
- return 1;
-}
-void fx_plot_canvas::plots_set_to_dirty()
-{
- for (unsigned k = 0; k < m_plots.size(); k++)
- {
- plot_ref& ref = m_plots[k];
- ref.is_image_dirty = true;
- }
+ agg::rect_i r(0, 0, ww, hh);
+ update_region(r);
+ return 1;
}
diff --git a/fox-gui/fx_plot_canvas.h b/fox-gui/fx_plot_canvas.h
index de54e63d..3609c968 100644
--- a/fox-gui/fx_plot_canvas.h
+++ b/fox-gui/fx_plot_canvas.h
@@ -1,95 +1,50 @@
#ifndef FOXGUI_FX_PLOT_CANVAS_H
#define FOXGUI_FX_PLOT_CANVAS_H
-#include <new>
#include <fx.h>
#include <agg_basics.h>
#include <agg_rendering_buffer.h>
#include <agg_trans_affine.h>
-#include "image_buf.h"
-#include "window_part.h"
-#include "sg_object.h"
-#include "lua-plot-cpp.h"
-#include "canvas.h"
-#include "rect.h"
-
-struct plot_ref {
- plot_ref(): plot(NULL) {}
-
- void attach(sg_plot* p);
-
- sg_plot* plot;
- plot_render_info inf;
- bool is_dirty;
- bool is_image_dirty;
- opt_rect<double> dirty_rect;
-};
+#include "window_surface.h"
class fx_plot_canvas : public FXCanvas
{
FXDECLARE(fx_plot_canvas)
- enum { image_pixel_width = 3 };
-
- typedef image_gen<image_pixel_width, true> image;
+ typedef window_surface::image image;
public:
fx_plot_canvas(FXComposite* p, const char* split, FXObject* tgt=NULL, FXSelector sel=0,
FXuint opts=FRAME_NORMAL,
FXint x=0, FXint y=0, FXint w=0, FXint h=0);
- ~fx_plot_canvas();
-
int attach(sg_plot* p, const char* slot_str);
- void split(const char* split_str);
-
- void update_region(const agg::rect_base<int>& r);
- void plot_draw(unsigned index);
- void plot_draw_queue(unsigned index, bool draw_all);
- void plot_render(unsigned index);
+ bool is_ready() const { return m_surface.is_ready(); }
- sg_plot* get_plot(unsigned index, int canvas_width, int canvas_height, agg::rect_i& area);
- unsigned get_plot_number() const { return m_plots.size(); }
+ sg_plot* get_plot(unsigned index) const { return m_surface.plot(index); }
+ unsigned get_plot_number() const { return m_surface.plot_number(); }
+ agg::rect_i get_plot_area(unsigned index, int w, int h) const { return m_surface.get_plot_area(index, w, h); }
- bool need_redraw(unsigned index)
- {
- return m_plots[index].plot->need_redraw();
- }
+ void draw(unsigned index);
- bool is_ready() const { return (m_canvas != 0); }
-
- bool save_plot_image(unsigned index);
- bool restore_plot_image(unsigned index);
+ void slot_refresh(unsigned index);
+ void slot_update(unsigned index);
+ void save_slot_image(unsigned index);
+ void restore_slot_image(unsigned index);
long on_cmd_paint(FXObject *, FXSelector, void *);
- long on_update(FXObject *, FXSelector, void *);
protected:
- fx_plot_canvas() {}
+ fx_plot_canvas(): m_surface(NULL) {}
private:
- bool prepare_image_buffer(unsigned ww, unsigned hh);
- bool ensure_canvas_size(unsigned ww, unsigned hh);
- void plots_set_to_dirty();
-
- void plot_render(plot_ref& ref, const agg::rect_i& r);
- void plot_draw(unsigned index, int canvas_width, int canvas_height);
- opt_rect<double> plot_render_queue(plot_ref& ref, const agg::rect_i& r);
- void plot_draw_queue(unsigned index, int canvas_width, int canvas_height, bool draw_all);
-
- bool plot_is_defined(unsigned index)
- {
- return (m_plots[index].plot != NULL);
- }
-
- image m_img;
- image m_save_img;
- window_part m_part;
- agg::pod_bvector<plot_ref> m_plots;
- canvas* m_canvas;
+ void update_region(const agg::rect_i& r);
+ void update_plot_region(unsigned index);
+
+ window_surface m_surface;
};
#endif
diff --git a/fox-gui/image_buf.h b/fox-gui/image_buf.h
index 9136d8f7..2d36153c 100644
--- a/fox-gui/image_buf.h
+++ b/fox-gui/image_buf.h
@@ -1,9 +1,12 @@
#ifndef FOXGUI_IMAGE_BUF_H
#define FOXGUI_IMAGE_BUF_H
+#include <new>
+
#include "defs.h"
-#include <agg_rendering_buffer.h>
+#include "agg_rendering_buffer.h"
+#include "rendering_buffer_utils.h"
template <unsigned PixelSize, bool FlipY>
struct image_gen : agg::rendering_buffer
@@ -50,6 +53,17 @@ struct image_gen : agg::rendering_buffer
return (a.width() == b.width() && a.height() == b.height());
}
+ static void copy_region(image_gen& dest_img, const image_gen& src_img, const agg::rect_i r)
+ {
+ rendering_buffer_ro src;
+ rendering_buffer_get_const_view(src, src_img, r, PixelSize);
+
+ agg::rendering_buffer dest;
+ rendering_buffer_get_view(dest, dest_img, r, PixelSize);
+
+ dest.copy_from(src);
+ }
+
private:
bool init(unsigned w, unsigned h)
{
diff --git a/fox-gui/lua_plot_window.cpp b/fox-gui/lua_plot_window.cpp
index 945ac09f..02acc1a9 100644
--- a/fox-gui/lua_plot_window.cpp
+++ b/fox-gui/lua_plot_window.cpp
@@ -147,7 +147,8 @@ fox_window_attach_try(lua_State *L)
if (index < 0) return error_return(L, "invalid slot specification");
- canvas->plot_draw(index);
+ if (canvas->is_ready())
+ canvas->slot_update(index);
window_refs_add (L, index + 1, 1, 2);
return 0;
@@ -189,8 +190,8 @@ fox_window_close(lua_State* L)
return nret;
}
-static int
-fox_window_slot_generic_try(lua_State *L, void (*slot_func)(fx_plot_canvas*, unsigned))
+int
+fx_canvas_slot_operation(lua_State *L, void (fx_plot_canvas::*method_ptr)(unsigned))
{
window_mutex wm(L, 1);
@@ -207,72 +208,40 @@ fox_window_slot_generic_try(lua_State *L, void (*slot_func)(fx_plot_canvas*, uns
if (canvas->is_ready())
{
- slot_func(canvas, slot_id - 1);
+ (canvas->*method_ptr)(slot_id - 1);
}
return 0;
}
-static void
-slot_refresh(fx_plot_canvas* canvas, unsigned index)
-{
- bool redraw = canvas->need_redraw(index);
- if (redraw)
- canvas->plot_render(index);
- canvas->plot_draw_queue(index, redraw);
-}
-
int
fox_window_slot_refresh(lua_State* L)
{
- int nret = fox_window_slot_generic_try(L, slot_refresh);
+ int nret = fx_canvas_slot_operation(L, &fx_plot_canvas::slot_refresh);
if (nret < 0) lua_error(L);
return nret;
}
-static void
-slot_update(fx_plot_canvas* canvas, unsigned index)
-{
- canvas->plot_render(index);
- canvas->plot_draw_queue(index, true);
-}
-
int
fox_window_slot_update(lua_State* L)
{
- int nret = fox_window_slot_generic_try(L, slot_update);
+ int nret = fx_canvas_slot_operation(L, &fx_plot_canvas::slot_update);
if (nret < 0) lua_error(L);
return nret;
}
-static void
-save_slot_image(fx_plot_canvas* canvas, unsigned index)
-{
- canvas->save_plot_image(index);
-}
-
int
fox_window_save_slot_image (lua_State *L)
{
- int nret = fox_window_slot_generic_try(L, save_slot_image);
+ int nret = fx_canvas_slot_operation(L, &fx_plot_canvas::save_slot_image);
if (nret < 0) lua_error(L);
return nret;
}
-static void
-restore_slot_image(fx_plot_canvas* canvas, unsigned index)
-{
- if (!canvas->restore_plot_image(index))
- {
- canvas->plot_render(index);
- canvas->save_plot_image(index);
- }
-}
-
int
fox_window_restore_slot_image (lua_State *L)
{
- int nret = fox_window_slot_generic_try(L, restore_slot_image);
+ int nret = fx_canvas_slot_operation(L, &fx_plot_canvas::restore_slot_image);
if (nret < 0) lua_error(L);
return nret;
}
@@ -315,14 +284,14 @@ fox_window_export_svg_try(lua_State *L)
unsigned n = fxcanvas->get_plot_number();
for (unsigned k = 0; k < n; k++)
{
- agg::rect_i box;
char plot_name[64];
- sg_plot* p = fxcanvas->get_plot(k, int(w), int(h), box);
+ sg_plot* p = fxcanvas->get_plot(k);
if (p)
{
+ agg::rect_i area = fxcanvas->get_plot_area(k, int(w), int(h));
sprintf(plot_name, "plot%u", k + 1);
canvas.write_group_header(plot_name);
- p->draw(canvas, box, NULL);
+ p->draw(canvas, area, NULL);
canvas.write_group_end(plot_name);
}
}
@@ -337,8 +306,7 @@ int
fox_window_export_svg(lua_State *L)
{
int nret = fox_window_export_svg_try(L);
- if (unlikely(nret < 0))
- return lua_error(L);
+ if (nret < 0) return lua_error(L);
return nret;
}
diff --git a/fox-gui/window_part.cpp b/fox-gui/window_part.cpp
index 1f487c21..89d9b84c 100644
--- a/fox-gui/window_part.cpp
+++ b/fox-gui/window_part.cpp
@@ -175,10 +175,9 @@ window_part::get_slot_index(const char* str)
}
agg::rect_i
-window_part::rect(unsigned index, int w, int h)
+window_part::rect(unsigned index, int w, int h) const
{
-#warning TODO: enforce that rect is never bigger than canvas
- rect_type& r = m_rect[index];
+ const rect_type& r = m_rect[index];
return agg::rect_i(w * r.x1, h * r.y1, w * r.x2, h * r.y2);
}
diff --git a/fox-gui/window_part.h b/fox-gui/window_part.h
index 99039cf0..d01b724d 100644
--- a/fox-gui/window_part.h
+++ b/fox-gui/window_part.h
@@ -23,7 +23,7 @@ public:
int get_slot_index(const char* str);
unsigned get_slot_number() const;
- agg::rect_i rect(unsigned index, int canvas_width, int canvas_height);
+ agg::rect_i rect(unsigned index, int canvas_width, int canvas_height) const;
private:
int skip_node(int index, int& leaf_count);
diff --git a/fox-gui/window_surface.cpp b/fox-gui/window_surface.cpp
new file mode 100644
index 00000000..b44bb01d
--- /dev/null
+++ b/fox-gui/window_surface.cpp
@@ -0,0 +1,142 @@
+#include "window_surface.h"
+
+#include "util/agg_color_conv_rgb8.h"
+
+#include "fatal.h"
+#include "lua-graph.h"
+
+window_surface::window_surface(const char* split_str):
+m_img(), m_save_img(), m_canvas(0)
+{
+ split(split_str ? split_str : ".");
+}
+
+window_surface::~window_surface()
+{
+ delete m_canvas;
+}
+
+void window_surface::split(const char* split_str)
+{
+ m_part.parse(split_str);
+ m_part.split();
+
+ m_plots.clear();
+ plot_ref empty;
+ for (unsigned k = 0; k < m_part.get_slot_number(); k++)
+ m_plots.add(empty);
+}
+
+bool window_surface::resize(unsigned ww, unsigned hh)
+{
+ m_save_img.clear();
+
+ for (unsigned k = 0; k < plot_number(); k++)
+ m_plots[k].have_save_img = false;
+
+ if (likely(m_img.resize(ww, hh)))
+ {
+ m_canvas = new(std::nothrow) canvas(m_img, ww, hh, colors::white);
+ return (m_canvas != NULL);
+ }
+ return false;
+}
+
+void window_surface::draw_image_buffer()
+{
+ for (unsigned k = 0; k < plot_number(); k++)
+ render(k);
+}
+
+void window_surface::render(plot_ref& ref, const agg::rect_i& r)
+{
+ m_canvas->clear_box(r);
+ if (ref.plot)
+ {
+ graph_mutex::lock();
+ ref.plot->draw(*m_canvas, r, &ref.inf);
+ graph_mutex::unlock();
+ }
+}
+
+void window_surface::render(unsigned index)
+{
+ int canvas_width = get_width(), canvas_height = get_height();
+ plot_ref& ref = m_plots[index];
+ agg::rect_i area = m_part.rect(index, canvas_width, canvas_height);
+ render(ref, area);
+}
+
+opt_rect<int>
+window_surface::render_drawing_queue(plot_ref& ref, const agg::rect_i& box)
+{
+ const agg::trans_affine m = affine_matrix(box);
+ opt_rect<double> r;
+
+ graph_mutex::lock();
+ ref.plot->draw_queue(*m_canvas, m, ref.inf, r);
+ graph_mutex::unlock();
+
+ opt_rect<int> ri;
+ if (r.is_defined())
+ {
+ const agg::rect_d& rx = r.rect();
+ ri.set(rx.x1, rx.y1, rx.x2, rx.y2);
+ }
+
+ return ri;
+}
+
+opt_rect<int>
+window_surface::render_drawing_queue(unsigned index)
+{
+ int canvas_width = get_width(), canvas_height = get_height();
+ plot_ref& ref = m_plots[index];
+
+ if (unlikely(!ref.plot))
+ fatal_exception("call to plot_draw_queue for undefined plot");
+
+ agg::rect_i area = m_part.rect(index, canvas_width, canvas_height);
+ return render_drawing_queue(ref, area);
+}
+
+int window_surface::attach(sg_plot* p, const char* slot_str)
+{
+ int index = m_part.get_slot_index(slot_str);
+ if (index >= 0)
+ m_plots[index].plot = p;
+ return index;
+}
+
+bool window_surface::save_plot_image(unsigned index)
+{
+ int ww = get_width(), hh = get_height();
+ if (unlikely(!m_save_img.ensure_size(ww, hh))) return false;
+
+ agg::rect_i r = m_part.rect(index, ww, hh);
+ image::copy_region(m_save_img, m_img, r);
+ m_plots[index].have_save_img = true;
+ return true;
+}
+
+bool window_surface::restore_plot_image(unsigned index)
+{
+ if (unlikely(!m_plots[index].have_save_img))
+ fatal_exception("window_surface::restore_slot_image invalid restore image");
+
+ int ww = get_width(), hh = get_height();
+ agg::rect_i r = m_part.rect(index, ww, hh);
+ image::copy_region(m_img, m_save_img, r);
+ return true;
+}
+
+agg::rect_i window_surface::get_plot_area(unsigned index) const
+{
+ int canvas_width = get_width(), canvas_height = get_height();
+ return m_part.rect(index, canvas_width, canvas_height);
+}
+
+agg::rect_i window_surface::get_plot_area(unsigned index, int width, int height) const
+{
+ return m_part.rect(index, width, height);
+}
diff --git a/fox-gui/window_surface.h b/fox-gui/window_surface.h
new file mode 100644
index 00000000..c92cbde0
--- /dev/null
+++ b/fox-gui/window_surface.h
@@ -0,0 +1,91 @@
+#ifndef FOXGUI_WINDOW_SURFACE_H
+#define FOXGUI_WINDOW_SURFACE_H
+
+#include <fx.h>
+
+#include <agg_basics.h>
+#include <agg_rendering_buffer.h>
+#include <agg_trans_affine.h>
+
+#include "lua-graph.h"
+#include "image_buf.h"
+#include "window_part.h"
+#include "sg_object.h"
+#include "lua-plot-cpp.h"
+#include "canvas.h"
+#include "rect.h"
+
+struct plot_ref {
+ plot_ref(): plot(NULL), have_save_img(false) {}
+
+ sg_plot* plot;
+ plot_render_info inf;
+ bool have_save_img;
+};
+
+struct graph_mutex {
+ static void lock() { AGG_LOCK(); }
+ static void unlock() { AGG_UNLOCK(); }
+};
+
+class window_surface
+{
+public:
+ enum { image_pixel_width = 3 };
+ typedef image_gen<image_pixel_width, true> image;
+
+ window_surface(const char* split);
+ ~window_surface();
+
+ int attach(sg_plot* p, const char* slot_str);
+ void split(const char* split_str);
+
+ bool canvas_size_match(unsigned ww, unsigned hh)
+ {
+ return (m_img.width() == ww && m_img.height() == hh);
+ }
+
+ bool resize(unsigned ww, unsigned hh);
+
+ // redraw all the image buffer for the current plots
+ void draw_image_buffer();
+
+ int get_width() const { return m_img.width(); }
+ int get_height() const { return m_img.height(); }
+
+ void render(unsigned index);
+ opt_rect<int> render_drawing_queue(unsigned index);
+
+ sg_plot* plot(unsigned index) const { return m_plots[index].plot; }
+
+ agg::rect_i get_plot_area(unsigned index) const;
+ agg::rect_i get_plot_area(unsigned index, int width, int height) const;
+ unsigned plot_number() const { return m_plots.size(); }
+
+ bool is_ready() const { return (m_canvas != 0); }
+
+ bool save_plot_image(unsigned index);
+ bool restore_plot_image(unsigned index);
+
+ const image& get_image() { return m_img; }
+
+ bool have_saved_image(unsigned k) const { return m_plots[k].have_save_img; }
+
+private:
+ void render(plot_ref& ref, const agg::rect_i& r);
+
+ opt_rect<int> render_drawing_queue(plot_ref& ref, const agg::rect_i& r);
+
+ bool plot_is_defined(unsigned index) const
+ {
+ return (m_plots[index].plot != NULL);
+ }
+
+ image m_img;
+ image m_save_img;
+ window_part m_part;
+ agg::pod_bvector<plot_ref> m_plots;
+ canvas* m_canvas;
+};
+
+#endif
generated by cgit v1.2.3 (git 2.25.1) at 2025年09月17日 21:29:34 +0000

AltStyle によって変換されたページ (->オリジナル) /