gsl-shell.git - gsl-shell

index : gsl-shell.git
gsl-shell
summary refs log tree commit diff
path: root/agg-plot/plot.h
diff options
context:
space:
mode:
authorFrancesco Abbate <francesco.bbt@gmail.com>2012年07月28日 22:04:58 +0200
committerFrancesco Abbate <francesco.bbt@gmail.com>2012年07月28日 22:04:58 +0200
commit707e54e3350e458530270d9cbd0767771cf6386f (patch)
treeeb3ac932c16c081dbb76d65662b2b5395276e07d /agg-plot/plot.h
parentcf077cb0817f498b8f1bb3a52baf8f89dc919a64 (diff)
parent78702ab307e9d05493cb980a25f19d340d5644a0 (diff)
downloadgsl-shell-707e54e3350e458530270d9cbd0767771cf6386f.tar.gz
Merge branch 'font-freetype-3'
Diffstat (limited to 'agg-plot/plot.h')
-rw-r--r--agg-plot/plot.h 286
1 files changed, 167 insertions, 119 deletions
diff --git a/agg-plot/plot.h b/agg-plot/plot.h
index 016a65c8..174a2829 100644
--- a/agg-plot/plot.h
+++ b/agg-plot/plot.h
@@ -35,6 +35,7 @@
#include "trans.h"
#include "text.h"
#include "categories.h"
+#include "sg_object.h"
#include "agg_array.h"
#include "agg_bounding_rect.h"
@@ -47,13 +48,13 @@
#include "agg_conv_dash.h"
#include "agg_gsv_text.h"
-template <class Canvas, class VertexSource>
-class canvas_adapter : public virtual_canvas<VertexSource> {
+template <class Canvas>
+class canvas_adapter : public virtual_canvas {
public:
canvas_adapter(Canvas* c) : m_canvas(c) {}
- virtual void draw(VertexSource& vs, agg::rgba8 c) { m_canvas->draw(vs, c); }
- virtual void draw_outline(VertexSource& vs, agg::rgba8 c) { m_canvas->draw_outline(vs, c); }
+ virtual void draw(sg_object& vs, agg::rgba8 c) { m_canvas->draw(vs, c); }
+ virtual void draw_outline(sg_object& vs, agg::rgba8 c) { m_canvas->draw_outline(vs, c); }
virtual void clip_box(const agg::rect_base<int>& clip) { m_canvas->clip_box(clip); }
virtual void reset_clipping() { m_canvas->reset_clipping(); }
@@ -62,25 +63,22 @@ private:
Canvas* m_canvas;
};
-template<class VertexSource>
struct plot_item {
- VertexSource* vs;
+ sg_object* vs;
agg::rgba8 color;
bool outline;
plot_item() : vs(0) {};
- plot_item(VertexSource* vs, agg::rgba8& c, bool as_outline):
+ plot_item(sg_object* vs, agg::rgba8& c, bool as_outline):
vs(vs), color(c), outline(as_outline)
{};
- VertexSource& content() { return *vs; };
+ sg_object& content() { return *vs; };
};
-template<class VertexSource, class ResourceManager>
+template<class ResourceManager>
class plot {
- typedef plot_item<VertexSource> item;
- typedef agg::pod_bvector<item> item_list;
static const unsigned max_layers = 8;
@@ -91,9 +89,25 @@ class plot {
canvas_margin_fixed_space = 4,
};
+protected:
+ typedef plot_item item;
+
+ class item_list : public agg::pod_bvector<item>
+ {
+ public:
+ item_list(): agg::pod_bvector<item>() { }
+
+ const opt_rect<double>& bounding_box() const { return m_bbox; }
+ void set_bounding_box(const agg::rect_base<double>& r) { m_bbox.set(r); }
+ void clear_bounding_box() { m_bbox.clear(); }
+
+ private:
+ opt_rect<double> m_bbox;
+ };
+
public:
typedef pod_list<item> iterator;
- typedef virtual_canvas<VertexSource> canvas_type;
+ typedef virtual_canvas canvas_type;
enum axis_e { x_axis, y_axis };
enum placement_e { right = 0, left = 1, bottom = 2, top = 3 };
@@ -146,12 +160,12 @@ public:
};
plot(bool use_units = true) :
- m_root_layer(), m_layers(), m_current_layer(&m_root_layer),
m_drawing_queue(0), m_clip_flag(true),
m_need_redraw(true), m_rect(),
m_use_units(use_units), m_pad_units(false), m_title(),
m_sync_mode(true), m_x_axis(x_axis), m_y_axis(y_axis)
{
+ m_layers.add(&m_root_layer);
compute_user_trans();
for (unsigned k = 0; k < 4; k++)
m_legend[k] = 0;
@@ -159,12 +173,12 @@ public:
virtual ~plot()
{
- layer_dispose_elements(m_root_layer);
for (unsigned k = 0; k < m_layers.size(); k++)
{
item_list *layer = m_layers[k];
- layer_dispose_elements(*layer);
- delete layer;
+ layer_dispose_elements(layer);
+ if (k > 0)
+ delete layer;
}
};
@@ -195,9 +209,11 @@ public:
void set_units(bool use_units);
bool use_units() const { return m_use_units; };
+ void update_units();
void set_limits(const agg::rect_base<double>& r);
+ void unset_limits();
- virtual void add(VertexSource* vs, agg::rgba8& color, bool outline);
+ virtual void add(sg_object* vs, agg::rgba8& color, bool outline);
virtual void before_draw() { }
void get_bounding_rect(agg::rect_base<double>& bb)
@@ -215,11 +231,11 @@ public:
virtual bool push_layer();
virtual bool pop_layer();
+ virtual void clear_current_layer();
/* drawing queue related methods */
void push_drawing_queue();
void clear_drawing_queue();
- void clear_current_layer();
int current_layer_index();
bool clip_is_active() const { return m_clip_flag; };
@@ -294,15 +310,20 @@ protected:
void compute_user_trans();
- bool fit_inside(VertexSource *obj) const;
+ bool fit_inside(sg_object *obj) const;
- void layer_dispose_elements (item_list& layer);
+ void layer_dispose_elements (item_list* layer);
- item_list& current_layer() { return *m_current_layer; };
+ unsigned nb_layers() const { return m_layers.size(); }
+ item_list* get_layer(unsigned j) { return m_layers[j]; }
- item_list m_root_layer;
- agg::pod_auto_vector<item_list*, max_layers> m_layers;
- item_list *m_current_layer;
+ item_list* current_layer() { return m_layers[m_layers.size() - 1]; };
+
+ item_list* parent_layer()
+ {
+ unsigned n = m_layers.size();
+ return (n > 1 ? m_layers[n-2] : 0);
+ }
agg::trans_affine m_trans;
pod_list<item> *m_drawing_queue;
@@ -316,6 +337,9 @@ protected:
units m_ux, m_uy;
private:
+ item_list m_root_layer;
+ agg::pod_auto_vector<item_list*, max_layers> m_layers;
+
bool m_pad_units;
str m_title;
@@ -344,15 +368,15 @@ std_line_width(double scale, double w = 1.0)
#endif
}
-template <class VS, class RM>
-void plot<VS,RM>::commit_pending_draw()
+template <class RM>
+void plot<RM>::commit_pending_draw()
{
push_drawing_queue();
m_need_redraw = false;
}
-template <class VS, class RM>
-void plot<VS,RM>::add(VS* vs, agg::rgba8& color, bool outline)
+template <class RM>
+void plot<RM>::add(sg_object* vs, agg::rgba8& color, bool outline)
{
item d(vs, color, outline);
pod_list<item> *new_node = new pod_list<item>(d);
@@ -360,20 +384,21 @@ void plot<VS,RM>::add(VS* vs, agg::rgba8& color, bool outline)
RM::acquire(vs);
}
-template <class VS, class RM>
-void plot<VS,RM>::push_drawing_queue()
+template <class RM>
+void plot<RM>::push_drawing_queue()
{
+ item_list* layer = current_layer();
for (pod_list<item> *c = m_drawing_queue; c != 0; c = c->next())
{
- m_current_layer->add(c->content());
+ layer->add(c->content());
}
while (m_drawing_queue)
m_drawing_queue = list::pop(m_drawing_queue);
}
-template <class VS, class RM>
-void plot<VS,RM>::clear_drawing_queue()
+template <class RM>
+void plot<RM>::clear_drawing_queue()
{
while (m_drawing_queue)
{
@@ -389,10 +414,10 @@ static bool area_is_valid(const agg::trans_affine& b)
return (b.sx > thresold && b.sy > thresold);
}
-template <class VS, class RM>
-template <class Canvas> void plot<VS,RM>::draw(Canvas& _canvas, agg::trans_affine& canvas_mtx)
+template <class RM>
+template <class Canvas> void plot<RM>::draw(Canvas& _canvas, agg::trans_affine& canvas_mtx)
{
- canvas_adapter<Canvas, VS> canvas(&_canvas);
+ canvas_adapter<Canvas> canvas(&_canvas);
before_draw();
agg::rect_base<int> clip = rect_of_slot_matrix<int>(canvas_mtx);
@@ -406,10 +431,10 @@ template <class Canvas> void plot<VS,RM>::draw(Canvas& _canvas, agg::trans_affin
}
};
-template <class VS, class RM>
-void plot<VS,RM>::draw_element(item& c, canvas_type& canvas, agg::trans_affine& m)
+template <class RM>
+void plot<RM>::draw_element(item& c, canvas_type& canvas, agg::trans_affine& m)
{
- VS& vs = c.content();
+ sg_object& vs = c.content();
vs.apply_transform(m, 1.0);
if (c.outline)
@@ -418,16 +443,16 @@ void plot<VS,RM>::draw_element(item& c, canvas_type& canvas, agg::trans_affine&
canvas.draw(vs, c.color);
}
-template <class VS, class RM>
-agg::trans_affine plot<VS,RM>::get_scaled_matrix(agg::trans_affine& canvas_mtx)
+template <class RM>
+agg::trans_affine plot<RM>::get_scaled_matrix(agg::trans_affine& canvas_mtx)
{
agg::trans_affine m = m_trans;
trans_affine_compose (m, m_area_mtx);
return m;
}
-template<class VS, class RM>
-void plot<VS,RM>::clip_plot_area(canvas_type& canvas, agg::trans_affine& canvas_mtx)
+template<class RM>
+void plot<RM>::clip_plot_area(canvas_type& canvas, agg::trans_affine& canvas_mtx)
{
if (this->clip_is_active())
{
@@ -436,18 +461,13 @@ void plot<VS,RM>::clip_plot_area(canvas_type& canvas, agg::trans_affine& canvas_
}
}
-template <class VS, class RM>
-void plot<VS,RM>::draw_elements(canvas_type& canvas, agg::trans_affine& canvas_mtx)
+template <class RM>
+void plot<RM>::draw_elements(canvas_type& canvas, agg::trans_affine& canvas_mtx)
{
agg::trans_affine m = get_scaled_matrix(canvas_mtx);
this->clip_plot_area(canvas, canvas_mtx);
- for (unsigned j = 0; j < m_root_layer.size(); j++)
- {
- draw_element(m_root_layer[j], canvas, m);
- }
-
for (unsigned k = 0; k < m_layers.size(); k++)
{
item_list& layer = *(m_layers[k]);
@@ -460,12 +480,12 @@ void plot<VS,RM>::draw_elements(canvas_type& canvas, agg::trans_affine& canvas_m
canvas.reset_clipping();
}
-template <class VS, class RM>
-template <class Canvas> void plot<VS,RM>::draw_queue(Canvas& _canvas, agg::trans_affine& canvas_mtx, opt_rect<double>& bb)
+template <class RM>
+template <class Canvas> void plot<RM>::draw_queue(Canvas& _canvas, agg::trans_affine& canvas_mtx, opt_rect<double>& bb)
{
- canvas_adapter<Canvas, VS> canvas(&_canvas);
+ canvas_adapter<Canvas> canvas(&_canvas);
- typedef typename plot<VS,RM>::iterator iter_type;
+ typedef typename plot<RM>::iterator iter_type;
before_draw();
@@ -488,8 +508,8 @@ template <class Canvas> void plot<VS,RM>::draw_queue(Canvas& _canvas, agg::trans
canvas.reset_clipping();
}
-template <class VS, class RM>
-void plot<VS,RM>::compute_user_trans()
+template <class RM>
+void plot<RM>::compute_user_trans()
{
agg::rect_base<double> r;
@@ -515,17 +535,15 @@ void plot<VS,RM>::compute_user_trans()
this->m_trans = agg::trans_affine(fx, 0.0, 0.0, fy, -r.x1 * fx, -r.y1 * fy);
}
-template <class VS, class RM>
-double plot<VS,RM>::draw_axis_m(axis_e dir, units& u,
- agg::trans_affine& user_mtx,
- ptr_list<draw::text>& labels, double scale,
- agg::path_storage& mark, agg::path_storage& ln)
+template <class RM>
+double plot<RM>::draw_axis_m(axis_e dir, units& u,
+ agg::trans_affine& user_mtx,
+ ptr_list<draw::text>& labels, double scale,
+ agg::path_storage& mark, agg::path_storage& ln)
{
const double ppad = double(axis_label_prop_space) / 1000.0;
const double eps = 1.0e-3;
- const double line_width = std_line_width(scale);
-
opt_rect<double> bb;
agg::rect_base<double> r;
@@ -552,7 +570,7 @@ double plot<VS,RM>::draw_axis_m(axis_e dir, units& u,
if (q < -eps || q > 1.0 + eps)
continue;
- draw::text* label = new draw::text(text, 10.0*scale, line_width, hj, vj);
+ draw::text* label = new draw::text(text, 14.0*scale, hj, vj);
label->set_point(isx ? q : -ppad, isx ? -ppad : q);
label->angle(langle);
@@ -600,13 +618,14 @@ static inline double approx_text_height(double text_size)
return text_size * 1.5;
}
-template <class VS, class RM>
-agg::trans_affine plot<VS,RM>::draw_legends(canvas_type& canvas,
- agg::trans_affine& canvas_mtx)
+template <class RM>
+agg::trans_affine plot<RM>::draw_legends(canvas_type& canvas,
+ agg::trans_affine& canvas_mtx)
{
const double sx = canvas_mtx.sx, sy = canvas_mtx.sy;
const double ppad = double(canvas_margin_prop_space) / 1000.0;
const double fpad = double(canvas_margin_fixed_space);
+ const double size_frac_x = 0.125, size_frac_y = 0.05;
double dxl, dxr, dyb, dyt;
@@ -616,16 +635,15 @@ agg::trans_affine plot<VS,RM>::draw_legends(canvas_type& canvas,
if (!str_is_null(&m_title))
{
const double scale = compute_scale(canvas_mtx);
- const double line_width = std_line_width(scale);
const double ptpad = double(axis_title_prop_space) / 1000.0;
- const double title_text_size = 12.0 * scale;
+ const double title_text_size = 18.0 * scale;
const double th = approx_text_height(title_text_size);
double x = 0.5, y = 1.0;
canvas_mtx.transform(&x, &y);
y -= ptpad + dyt + title_text_size;
- draw::text title(m_title.cstr(), title_text_size, line_width, 0.5, 0.0);
+ draw::text title(m_title.cstr(), title_text_size, 0.5, 0.0);
title.set_point(x, y);
title.apply_transform(identity_matrix, 1.0);
@@ -643,26 +661,35 @@ agg::trans_affine plot<VS,RM>::draw_legends(canvas_type& canvas,
agg::rect_base<double> bb;
mp->get_bounding_rect(bb);
- double dx = bb.x2 - bb.x1, dy = bb.y2 - bb.y1;
+ double bb_dx = bb.x2 - bb.x1, bb_dy = bb.y2 - bb.y1;
+ double dx, dy;
double px, py;
switch (k)
{
case right:
+ dx = sx * size_frac_x;
+ dy = dx * bb_dy / bb_dx;
px = sx - dx - ppad * sx - dxr;
py = (sy - dy) / 2;
dxr += dx + 2 * ppad * sx;
break;
case left:
+ dx = sx * size_frac_x;
+ dy = dx * bb_dy / bb_dx;
px = ppad * sx + dxr;
py = (sy - dy) / 2;
dxl += dx + 2 * ppad * sx;
break;
case bottom:
+ dy = sy * size_frac_y;
+ dx = dy * bb_dx / bb_dy;
py = ppad * sy + dyb;
px = (sx - dx) / 2;
dyb += dy + 2 * ppad * sy;
break;
case top:
+ dy = sy * size_frac_y;
+ dx = dy * bb_dx / bb_dy;
py = sy - dy - ppad * sy - dyt;
px = (sx - dx) / 2;
dyt += dy + 2 * ppad * sy;
@@ -687,9 +714,9 @@ agg::trans_affine plot<VS,RM>::draw_legends(canvas_type& canvas,
return agg::trans_affine(ssx, 0.0, 0.0, ssy, cpx + dxl, cpy + dyb);
}
-template <class VS, class RM>
-void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
- agg::rect_base<int>* clip)
+template <class RM>
+void plot<RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
+ agg::rect_base<int>* clip)
{
agg::trans_affine& m = m_area_mtx;
@@ -723,8 +750,7 @@ void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
trans::dash_a lndash(&ln_tr);
trans::stroke_a lns(&lndash);
- const double line_width = std_line_width(scale);
- const double label_text_size = 11.0 * scale;
+ const double label_text_size = 15.0 * scale;
const double plpad = double(axis_label_prop_space) / 1000.0;
const double ptpad = double(axis_title_prop_space) / 1000.0;
@@ -775,13 +801,13 @@ void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
lndash.add_dash(7.0, 3.0);
- lns.width(std_line_width(scale, 0.25));
+ lns.width(std_line_width(scale, 0.15));
canvas.draw(lns, colors::black);
mark_stroke.width(std_line_width(scale, 0.75));
canvas.draw(mark_stroke, colors::black);
- boxvs.width(std_line_width(scale));
+ boxvs.width(std_line_width(scale, 0.75));
canvas.draw(boxvs, colors::black);
if (!str_is_null(&m_x_axis.title))
@@ -790,7 +816,7 @@ void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
double laby = canvas_mtx.ty;
const char* text = m_x_axis.title.cstr();
- draw::text xlabel(text, label_text_size, line_width, 0.5, 0.0);
+ draw::text xlabel(text, label_text_size, 0.5, 0.0);
xlabel.set_point(labx, laby);
xlabel.apply_transform(identity_matrix, 1.0);
@@ -803,7 +829,7 @@ void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
double laby = m.sy * 0.5 + m.ty;
const char* text = m_y_axis.title.cstr();
- draw::text ylabel(text, label_text_size, line_width, 0.5, 1.0);
+ draw::text ylabel(text, label_text_size, 0.5, 1.0);
ylabel.set_point(labx, laby);
ylabel.angle(M_PI/2.0);
ylabel.apply_transform(identity_matrix, 1.0);
@@ -815,16 +841,16 @@ void plot<VS,RM>::draw_axis(canvas_type& canvas, agg::trans_affine& canvas_mtx,
canvas.reset_clipping();
}
-template<class VS, class RM>
-void plot<VS,RM>::set_axis_labels_angle(axis_e axis_dir, double angle)
+template<class RM>
+void plot<RM>::set_axis_labels_angle(axis_e axis_dir, double angle)
{
get_axis(axis_dir).set_labels_angle(angle);
m_need_redraw = true;
compute_user_trans();
}
-template<class VS, class RM>
-void plot<VS,RM>::set_units(bool use_units)
+template<class RM>
+void plot<RM>::set_units(bool use_units)
{
if (m_use_units != use_units)
{
@@ -834,75 +860,97 @@ void plot<VS,RM>::set_units(bool use_units)
}
}
-template<class VS, class RM>
-void plot<VS,RM>::set_limits(const agg::rect_base<double>& r)
+template<class RM>
+void plot<RM>::update_units()
+{
+ if (m_rect.is_defined())
+ {
+ const rect_base<double>& r = m_rect.rect();
+ m_ux = units(r.x1, r.x2);
+ m_uy = units(r.y1, r.y2);
+ }
+ else
+ {
+ m_ux = units();
+ m_uy = units();
+ }
+
+ compute_user_trans();
+}
+
+template<class RM>
+void plot<RM>::set_limits(const agg::rect_base<double>& r)
{
m_rect.set(r);
- m_ux = units(r.x1, r.x2);
- m_uy = units(r.y1, r.y2);
+ update_units();
+ m_need_redraw = true;
+}
+
+template<class RM>
+void plot<RM>::unset_limits()
+{
+ m_rect.clear();
+ update_units();
m_need_redraw = true;
- compute_user_trans();
}
-template<class VS, class RM>
-void plot<VS,RM>::layer_dispose_elements(plot<VS,RM>::item_list& layer)
+template<class RM>
+void plot<RM>::layer_dispose_elements(plot<RM>::item_list* layer)
{
- unsigned n = layer.size();
+ unsigned n = layer->size();
for (unsigned k = 0; k < n; k++)
{
- RM::dispose(layer[k].vs);
+ RM::dispose(layer->at(k).vs);
}
}
-template<class VS, class RM>
-bool plot<VS,RM>::push_layer()
+template<class RM>
+bool plot<RM>::push_layer()
{
if (m_layers.size() >= max_layers)
return false;
item_list *new_layer = new(std::nothrow) item_list();
- if (new_layer == 0)
- return false;
-
- commit_pending_draw();
- m_layers.add(new_layer);
- m_current_layer = new_layer;
+ if (new_layer)
+ {
+ before_draw();
+ push_drawing_queue();
+ m_layers.add(new_layer);
+ return true;
+ }
- return true;
+ return false;
}
-template<class VS, class RM>
-bool plot<VS,RM>::pop_layer()
+template<class RM>
+bool plot<RM>::pop_layer()
{
- unsigned n = m_layers.size();
-
- if (n == 0)
+ if (m_layers.size() <= 1)
return false;
- item_list *layer = m_layers[n-1];
- layer_dispose_elements (*layer);
- delete layer;
-
+ unsigned n = m_layers.size();
+ item_list* layer = m_layers[n-1];
m_layers.inc_size(-1);
- n--;
+ layer_dispose_elements(layer);
+ delete layer;
clear_drawing_queue();
m_need_redraw = true;
- m_current_layer = (n > 0 ? m_layers[n-1] : &m_root_layer);
return true;
}
-template <class VS, class RM>
-void plot<VS,RM>::clear_current_layer()
+template <class RM>
+void plot<RM>::clear_current_layer()
{
+ item_list* current = current_layer();
clear_drawing_queue();
- layer_dispose_elements (current_layer());
- m_current_layer->clear();
+ layer_dispose_elements(current);
+ current->clear();
}
-template <class VS, class RM>
-int plot<VS,RM>::current_layer_index()
+template <class RM>
+int plot<RM>::current_layer_index()
{
return m_layers.size();
}
generated by cgit v1.2.3 (git 2.25.1) at 2025年09月17日 02:23:55 +0000

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