|
Boost-Commit : |
From: JakeVoytko_at_[hidden]
Date: 2008-01-20 23:40:07
Author: jakevoytko
Date: 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
New Revision: 42888
URL: http://svn.boost.org/trac/boost/changeset/42888
Log:
Changes to svg that makes the interface more consistent. For example,
add_g_element() and get_g_element(int) are now g() and g(int). The
element placers in svg now return references to the base classes instead
of to the svg instance. For example my_svg.circle(,,,) returns a
reference to circle_element. Docs will be updated thusly.
Text files modified:
sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp | 234 ++++++++------
sandbox/SOC/2007/visualization/boost/svg_plot/detail/numeric_limits_handling.hpp | 2
sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp | 619 ++++++++++++++++++++++-----------------
sandbox/SOC/2007/visualization/boost/svg_plot/stylesheet.hpp | 2
sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp | 206 +++++-------
sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp | 156 ++++-----
sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp | 2
7 files changed, 641 insertions(+), 580 deletions(-)
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/axis_plot_frame.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -25,6 +25,26 @@
{
namespace svg
{
+ //JV: G++ can't resolve names in these enums in axis_plot_frame
+ // when they are in svg_2d_plot.hpp
+
+ static const double wh = 0.7; // font text width/height ratio.
+ // Even after reading http://www.w3.org/TR/SVG/fonts.html, unclear how to
+ // determine the exact width of digits, so an
+ // arbitrary average width height ratio wh = 0.7 is used as a good approximation.
+
+ static const double sin45 = 0.707; // Use if axis value labels are sloping.
+
+ // x_axis_position_ and y_axis_position_ use these.
+ enum x_axis_intersect {bottom = -1, x_intersects_y = 0, top = +1};
+ // bottom = X-axis free below bottom of end of Y-axis (case of all Y definitely < 0).
+ // top = X-axis free above top of X-axis (case of all Y definitely > 0).
+ // x_intersects_y when Y values include zero, so X intersects the Y axis.
+
+ enum y_axis_intersect {left = -1, y_intersects_x = 0, right = +1};
+ // left = Y-axis free to left of end of X-axis (case of all X definitely < 0).
+ // right = Y-axis free to left of end of X-axis (case of all X definitely > 0).
+ // y_intersects_x when X values include zero, so intersects the X axis.
enum legend_places
{ // Placing of legend box, if requested by legend_on(true).
@@ -322,7 +342,7 @@
{ // ! use_x_ticks_on_plot_window_ = Internal - value labels just below horizontal X-axis.
if ((derived().x_ticks_.ticks_on_plot_window_on_ != 0) || ((value != 0) && derived().x_axis_.axis_line_on_))
{ // Avoid a "0" below the X-axis if it would be cut through by any internal vertical Y-axis line.
- derived().image.get_g_element(detail::PLOT_VALUE_LABELS).text(
+ derived().image.g(detail::PLOT_VALUE_LABELS).text(
x, // to centre on tick
y,
label.str(),
@@ -354,23 +374,23 @@
xleft -= (std::max)(derived().y_ticks_.minor_tick_length_, derived().y_ticks_.major_tick_length_);
}
double y = derived().x_axis_.axis_; // y = 0, (provided y range includes zero).
- derived().image.get_g_element(PLOT_X_AXIS).line(xleft, y, xright, y);
+ derived().image.g(PLOT_X_AXIS).line(xleft, y, xright, y);
if (derived().x_ticks_.ticks_on_plot_window_on_ < 0)
{ // Draw a vertical line holding the ticks on the top of plot window.
- derived().image.get_g_element(PLOT_X_AXIS).line(xleft, derived().plot_bottom_, xright, derived().plot_bottom_);
+ derived().image.g(PLOT_X_AXIS).line(xleft, derived().plot_bottom_, xright, derived().plot_bottom_);
}
else if (derived().x_ticks_.ticks_on_plot_window_on_ > 0)
{// Draw a vertical line holding the ticks on the bottom of plot window.
- derived().image.get_g_element(PLOT_X_AXIS).line(xleft, derived().plot_top_, xright, derived().plot_top_);
+ derived().image.g(PLOT_X_AXIS).line(xleft, derived().plot_top_, xright, derived().plot_top_);
}
}
else if (derived().x_axis_position_ == top)
{
- derived().image.get_g_element(PLOT_X_AXIS).line(xleft, derived().plot_top_, xright, derived().plot_top_);
+ derived().image.g(PLOT_X_AXIS).line(xleft, derived().plot_top_, xright, derived().plot_top_);
}
else if (derived().x_axis_position_ == bottom)
{
- derived().image.get_g_element(PLOT_X_AXIS).line(xleft, derived().plot_bottom_, xright, derived().plot_bottom_);
+ derived().image.g(PLOT_X_AXIS).line(xleft, derived().plot_bottom_, xright, derived().plot_bottom_);
}
else
{ // warn that things have gone wrong?
@@ -378,10 +398,10 @@
} // x_axis_.axis_line_on_
// Access the paths for the ticks & grids, ready for additions.
- path_element& minor_tick_path = derived().image.get_g_element(PLOT_X_MINOR_TICKS).path();
- path_element& major_tick_path = derived().image.get_g_element(PLOT_X_MAJOR_TICKS).path();
- path_element& minor_grid_path = derived().image.get_g_element(PLOT_X_MINOR_GRID).path();
- path_element& major_grid_path = derived().image.get_g_element(PLOT_X_MAJOR_GRID).path();
+ path_element& minor_tick_path = derived().image.g(PLOT_X_MINOR_TICKS).path();
+ path_element& major_tick_path = derived().image.g(PLOT_X_MAJOR_TICKS).path();
+ path_element& minor_grid_path = derived().image.g(PLOT_X_MINOR_GRID).path();
+ path_element& major_grid_path = derived().image.g(PLOT_X_MAJOR_GRID).path();
// x_minor_jump is the interval between minor ticks.
double x_minor_jump = derived().x_ticks_.major_interval_ /
@@ -449,7 +469,7 @@
double y;
y = derived().title_info_.style().font_size() * derived().text_margin_; // Leave a linespace above.
derived().title_info_.y(y);
- derived().image.get_g_element(PLOT_TITLE).push_back(new text_element(derived().title_info_));
+ derived().image.g(PLOT_TITLE).push_back(new text_element(derived().title_info_));
} // void draw_title()
void size_legend_box()
@@ -490,7 +510,10 @@
} // for
std::cout.flags(std::ios_base::dec);
// std::cout << "\nLongest legend header or data descriptor " << longest << " chars" << std::endl;
- derived().legend_width_ = (1 + longest) * wh * font_size;
+ derived().legend_width_ = (1 + longest)
+ * ::boost::svg::wh
+ * font_size;
+
// Allow for a leading space, longest text
// & trailing space before box margin.
if (derived().legend_lines_)
@@ -618,7 +641,7 @@
}
// Draw border box round legend.
- g_element* g_ptr = &(derived().image.get_g_element(PLOT_LEGEND_BACKGROUND));
+ g_element* g_ptr = &(derived().image.g(PLOT_LEGEND_BACKGROUND));
g_ptr->push_back(new
rect_element(derived().legend_left_, derived().legend_top_, derived().legend_width_, derived().legend_height_));
} // if legend_on_
@@ -642,7 +665,7 @@
double legend_height = derived().legend_height_;
// Draw border box round legend.
- g_element* g_ptr = &(derived().image.get_g_element(PLOT_LEGEND_BACKGROUND));
+ g_element* g_ptr = &(derived().image.g(PLOT_LEGEND_BACKGROUND));
g_ptr->push_back(new
rect_element(legend_x_start, legend_y_start, legend_width, legend_height));
@@ -651,20 +674,20 @@
{ // Draw the legend header text for example: "My Plot Legend".
derived().legend_header_.x(legend_x_start + legend_width / 2.); // / 2. to center in legend box.
derived().legend_header_.y(legend_y_pos);
- derived().image.get_g_element(PLOT_LEGEND_TEXT).push_back(new
+ derived().image.g(PLOT_LEGEND_TEXT).push_back(new
text_element(derived().legend_header_));
legend_y_pos += 2 * spacing;
}
- g_ptr = &(derived().image.get_g_element(PLOT_LEGEND_POINTS));
+ g_ptr = &(derived().image.g(PLOT_LEGEND_POINTS));
g_element* g_inner_ptr = g_ptr;
- g_inner_ptr = &(derived().image.get_g_element(PLOT_LEGEND_TEXT));
+ g_inner_ptr = &(derived().image.g(PLOT_LEGEND_TEXT));
for(unsigned int i = 0; i < derived().series.size(); ++i)
{ // Show point marker, text info and perhaps line for all the data series.
double legend_x_pos = legend_x_start;
legend_x_pos += spacing; // space before point marker.
- g_inner_ptr = &(g_ptr->add_g_element());
+ g_inner_ptr = &(g_ptr->g());
// Use both stroke & fill colors from the point's style.
g_inner_ptr->style().stroke_color(derived().series[i].point_style_.stroke_color_);
g_inner_ptr->style().fill_color(derived().series[i].point_style_.fill_color_);
@@ -686,7 +709,7 @@
g_inner_ptr->style() // Use stroke colors from line style.
.stroke_color(derived().series[i].line_style_.color_);
// g_inner_ptr->style().width(4); // Use stroke colors from line style.
- // == image.get_g_element(PLOT_DATA_LINES).style().stroke_width(width);
+ // == image.g(PLOT_DATA_LINES).style().stroke_width(width);
// but this sets width for BOTH point and line :-(
g_inner_ptr->push_back(new line_element(
legend_x_pos + spacing /2., // half space leading space
@@ -697,7 +720,7 @@
} // legend_lines_
// Legend text for each Data Series added to the plot.
- g_inner_ptr = &(derived().image.get_g_element(PLOT_LEGEND_TEXT));
+ g_inner_ptr = &(derived().image.g(PLOT_LEGEND_TEXT));
g_inner_ptr->push_back(new text_element(
legend_x_pos, // allow space for the marker.
legend_y_pos,
@@ -711,7 +734,7 @@
void draw_x_label()
{
// color is set in constructor.
- //image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(black);
+ //image.g(detail::PLOT_X_LABEL).style().stroke_color(black);
// and using x_label_color(color)
std::string label = derived().x_label_info_.text(); // x_axis_ label, and optional units.
@@ -729,7 +752,7 @@
y -= derived().image_border_.margin_; // Allow a margin.
y -= derived().x_axis_label_style_.font_size() / 2; // Allow a half font too.
}
- derived().image.get_g_element(PLOT_X_LABEL).push_back(new text_element(
+ derived().image.g(PLOT_X_LABEL).push_back(new text_element(
( // x position relative to the x-axis which is middle of plot window.
derived().plot_right_ + derived().plot_left_) / 2, // x coordinate - middle.
y, // Up from image bottom edge.
@@ -795,7 +818,7 @@
switch(sty.shape_) // from enum point_shape none, round, square, point, egg
{
case round:
- g_ptr.circle(x, y, half_size);
+ g_ptr.circle(x, y, (int)half_size);
break;
case square:
g_ptr.rect(x - half_size, y - half_size, size, size);
@@ -905,51 +928,51 @@
void clear_background()
{
- derived().image.get_g_element(PLOT_BACKGROUND).clear();
+ derived().image.g(PLOT_BACKGROUND).clear();
}
void clear_title()
{
- derived().image.get_g_element(PLOT_TITLE).clear();
+ derived().image.g(PLOT_TITLE).clear();
}
void clear_points()
{
- derived().image.get_g_element(PLOT_DATA_POINTS).clear();
+ derived().image.g(PLOT_DATA_POINTS).clear();
}
void clear_plot_background()
{
- derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).clear();
+ derived().image.g(PLOT_WINDOW_BACKGROUND).clear();
}
void clear_legend()
{
- derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).clear();
- derived().image.get_g_element(PLOT_LEGEND_POINTS).clear();
- derived().image.get_g_element(PLOT_LEGEND_TEXT).clear();
+ derived().image.g(PLOT_LEGEND_BACKGROUND).clear();
+ derived().image.g(PLOT_LEGEND_POINTS).clear();
+ derived().image.g(PLOT_LEGEND_TEXT).clear();
}
void clear_x_axis()
{
- derived().image.get_g_element(PLOT_X_AXIS).clear();
- derived().image.get_g_element(PLOT_X_MINOR_TICKS).clear();
- derived().image.get_g_element(PLOT_X_MAJOR_TICKS).clear();
- derived().image.get_g_element(PLOT_X_LABEL).clear();
- derived().image.get_g_element(PLOT_VALUE_LABELS).clear();
+ derived().image.g(PLOT_X_AXIS).clear();
+ derived().image.g(PLOT_X_MINOR_TICKS).clear();
+ derived().image.g(PLOT_X_MAJOR_TICKS).clear();
+ derived().image.g(PLOT_X_LABEL).clear();
+ derived().image.g(PLOT_VALUE_LABELS).clear();
}
void clear_y_axis()
{
- derived().image.get_g_element(PLOT_Y_AXIS).clear();
+ derived().image.g(PLOT_Y_AXIS).clear();
}
void clear_grids()
{
- derived().image.get_g_element(PLOT_X_MAJOR_GRID).clear();
- derived().image.get_g_element(PLOT_X_MINOR_GRID).clear();
- derived().image.get_g_element(PLOT_Y_MAJOR_GRID).clear();
- derived().image.get_g_element(PLOT_Y_MINOR_GRID).clear();
+ derived().image.g(PLOT_X_MAJOR_GRID).clear();
+ derived().image.g(PLOT_X_MINOR_GRID).clear();
+ derived().image.g(PLOT_Y_MAJOR_GRID).clear();
+ derived().image.g(PLOT_Y_MINOR_GRID).clear();
}
private:
@@ -1137,29 +1160,29 @@
svg_color background_color()
{
- return derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color();
+ return derived().image.g(PLOT_BACKGROUND).style().fill_color();
}
Derived& background_border_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color(col);
+ derived().image.g(PLOT_BACKGROUND).style().stroke_color(col);
return derived();
}
svg_color background_border_color()
{
- return derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_color();
+ return derived().image.g(PLOT_BACKGROUND).style().stroke_color();
}
Derived& background_border_width(double w)
{
- derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_width(w);
+ derived().image.g(PLOT_BACKGROUND).style().stroke_width(w);
return derived();
}
double background_border_width()
{
- return derived().image.get_g_element(PLOT_BACKGROUND).style().stroke_width();
+ return derived().image.g(PLOT_BACKGROUND).style().stroke_width();
}
Derived& description(const std::string d)
@@ -1494,7 +1517,7 @@
derived().legend_on_ = cmd;
if(cmd)
{
- derived().image.get_g_element(detail::PLOT_LEGEND_BACKGROUND)
+ derived().image.g(detail::PLOT_LEGEND_BACKGROUND)
.style().fill_color(white)
.stroke_color(black);
}
@@ -1527,7 +1550,7 @@
if(cmd)
{ // Set plot window
- derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style()
+ derived().image.g(detail::PLOT_WINDOW_BACKGROUND).style()
.fill_color(derived().plot_window_border_.fill_) // background color and
.stroke_color(derived().plot_window_border_.stroke_); // border color.
}
@@ -1543,24 +1566,24 @@
Derived& plot_border_color(const svg_color& col)
{
derived().plot_window_border_.stroke_ = col;
- derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color(col);
+ derived().image.g(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color(col);
return derived();
}
svg_color plot_border_color()
{
- return derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color();
+ return derived().image.g(detail::PLOT_WINDOW_BACKGROUND).style().stroke_color();
}
double plot_border_width()
{
- return derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width();
+ return derived().image.g(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width();
}
Derived& plot_border_width(double w)
{
derived().plot_window_border_.width_ = w;
- derived().image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width(w);
+ derived().image.g(detail::PLOT_WINDOW_BACKGROUND).style().stroke_width(w);
return derived();
}
@@ -1736,26 +1759,26 @@
Derived& x_axis_label_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
- derived().image.get_g_element(detail::PLOT_X_LABEL).style().fill_color(col);
- derived().image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color(col);
+ derived().image.g(detail::PLOT_X_LABEL).style().fill_color(col);
+ derived().image.g(detail::PLOT_X_LABEL).style().stroke_color(col);
return *this;
}
svg_color x_axis_label_color()
{ // But only return the stroke color.
- return derived().image.get_g_element(detail::PLOT_X_LABEL).style().stroke_color();
+ return derived().image.g(detail::PLOT_X_LABEL).style().stroke_color();
}
Derived& x_axis_value_color(const svg_color& col)
{ // Set BOTH stroke and fill to the same color.
- derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().fill_color(col);
- derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
+ derived().image.g(detail::PLOT_VALUE_LABELS).style().fill_color(col);
+ derived().image.g(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
return *this;
}
svg_color x_axis_value_color()
{ // But only return the stroke color.
- return derived().image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
+ return derived().image.g(detail::PLOT_VALUE_LABELS).style().stroke_color();
}
Derived& x_ticks_on_plot_window_on(int cmd)
@@ -1874,90 +1897,90 @@
Derived& title_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_TITLE).style().stroke_color(col);
- derived().image.get_g_element(PLOT_TITLE).style().fill_color(col);
+ derived().image.g(PLOT_TITLE).style().stroke_color(col);
+ derived().image.g(PLOT_TITLE).style().fill_color(col);
return derived();
}
svg_color title_color()
{ // Function title_color sets both fill and stroke,
// but stroke (outside) is considered 'more important'.
- return derived().image.get_g_element(PLOT_TITLE).style().stroke_color();
+ return derived().image.g(PLOT_TITLE).style().stroke_color();
}
Derived& title_font_width(double width)
{ // width of text is effectively the boldness.
// Not useful with current browsers, setting this may cause lower quality graphic fonts
// perhaps because the font is created using graphics rather than a built-in font.
- derived().image.get_g_element(PLOT_TITLE).style().stroke_width(width);
+ derived().image.g(PLOT_TITLE).style().stroke_width(width);
return derived();
}
double title_font_width()
{
- return derived().image.get_g_element(PLOT_TITLE).style().stroke_width();
+ return derived().image.g(PLOT_TITLE).style().stroke_width();
}
Derived& legend_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_color(col);
+ derived().image.g(PLOT_LEGEND_TEXT).style().stroke_color(col);
return derived();
}
svg_color legend_color()
{ // Function legend_color sets only stroke, assuming that 'filled' text is not being used.
// (It produces much lower quality fonts on some browsers).
- return derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_color();
+ return derived().image.g(PLOT_LEGEND_TEXT).style().stroke_color();
}
Derived& legend_font_width(double width)
{ // width of text is effectively the boldness.
- derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_width(width);
+ derived().image.g(PLOT_LEGEND_TEXT).style().stroke_width(width);
return derived();
}
double legend_font_width()
{ // Probably not useful at present (se above).
- return derived().image.get_g_element(PLOT_LEGEND_TEXT).style().stroke_width();
+ return derived().image.g(PLOT_LEGEND_TEXT).style().stroke_width();
}
Derived& background_color(const svg_color& col)
{ //
- derived().image.get_g_element(PLOT_BACKGROUND).style().fill_color(col);
+ derived().image.g(PLOT_BACKGROUND).style().fill_color(col);
return derived();
}
Derived& legend_background_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).style().fill_color(col);
+ derived().image.g(PLOT_LEGEND_BACKGROUND).style().fill_color(col);
return derived();
}
svg_color legend_background_color()
{
- return derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).style().fill_color();
+ return derived().image.g(PLOT_LEGEND_BACKGROUND).style().fill_color();
}
Derived& legend_border_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).style().stroke_color(col);
+ derived().image.g(PLOT_LEGEND_BACKGROUND).style().stroke_color(col);
return derived();
}
svg_color legend_border_color()
{
- return derived().image.get_g_element(PLOT_LEGEND_BACKGROUND).style().stroke_color();
+ return derived().image.g(PLOT_LEGEND_BACKGROUND).style().stroke_color();
}
Derived& plot_background_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color(col);
+ derived().image.g(PLOT_WINDOW_BACKGROUND).style().fill_color(col);
return derived();
}
svg_color plot_background_color()
{
- return derived().image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color();
+ return derived().image.g(PLOT_WINDOW_BACKGROUND).style().fill_color();
}
const std::string x_axis_position()
@@ -1977,149 +2000,148 @@
Derived& x_axis_color(const svg_color& col)
{ // Note only stroke color is set.
- derived().image.get_g_element(PLOT_X_AXIS).style().stroke_color(col);
+ derived().image.g(PLOT_X_AXIS).style().stroke_color(col);
return derived();
}
svg_color x_axis_color()
{
- return derived().image.get_g_element(PLOT_X_AXIS).style().stroke_color();
+ return derived().image.g(PLOT_X_AXIS).style().stroke_color();
}
Derived& y_axis_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_Y_AXIS).style().stroke_color(col);
+ derived().image.g(PLOT_Y_AXIS).style().stroke_color(col);
return derived();
}
svg_color y_axis_color()
{
- return derived().image.get_g_element(PLOT_Y_AXIS).style().stroke_color();
+ return derived().image.g(PLOT_Y_AXIS).style().stroke_color();
}
Derived& x_label_color(const svg_color& col)
{ // add fill as well PAB Oct 07
- derived().image.get_g_element(PLOT_X_LABEL).style().fill_color(col);
- derived().image.get_g_element(PLOT_X_LABEL).style().stroke_color(col);
+ derived().image.g(PLOT_X_LABEL).style().fill_color(col);
+ derived().image.g(PLOT_X_LABEL).style().stroke_color(col);
return derived();
}
Derived& x_label_width(double width)
{ // width of text is effectively the boldness.
- x_label_width_ = width;
- derived().image.get_g_element(PLOT_X_LABEL).style().stroke_width(width);
+ derived().image.g(PLOT_X_LABEL).style().stroke_width(width);
return derived();
}
double x_label_width()
{
//return x_label_width_;
- return derived().image.get_g_element(PLOT_X_LABEL).style().stroke_width();
+ return derived().image.g(PLOT_X_LABEL).style().stroke_width();
}
svg_color x_label_color()
{
- return derived().image.get_g_element(PLOT_X_LABEL).style().fill_color();
+ return derived().image.g(PLOT_X_LABEL).style().fill_color();
}
Derived& y_label_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_Y_LABEL).style().fill_color(col);
- derived().image.get_g_element(PLOT_Y_LABEL).style().stroke_color(col);
+ derived().image.g(PLOT_Y_LABEL).style().fill_color(col);
+ derived().image.g(PLOT_Y_LABEL).style().stroke_color(col);
return derived();
}
svg_color y_label_color()
{
- return derived().image.get_g_element(PLOT_Y_LABEL).style().fill_color();
+ return derived().image.g(PLOT_Y_LABEL).style().fill_color();
}
Derived& x_major_tick_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_color(col);
+ derived().image.g(PLOT_X_MAJOR_TICKS).style().stroke_color(col);
return derived();
}
svg_color x_major_tick_color()
{
- return derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_color();
+ return derived().image.g(PLOT_X_MAJOR_TICKS).style().stroke_color();
}
Derived& x_minor_tick_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_color(col);
+ derived().image.g(PLOT_X_MINOR_TICKS).style().stroke_color(col);
return derived();
}
svg_color x_minor_tick_color()
{
- return derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_color();
+ return derived().image.g(PLOT_X_MINOR_TICKS).style().stroke_color();
}
Derived& x_major_grid_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_color(col);
+ derived().image.g(PLOT_X_MAJOR_GRID).style().stroke_color(col);
return derived();
}
svg_color x_major_grid_color()
{
- return derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_color();
+ return derived().image.g(PLOT_X_MAJOR_GRID).style().stroke_color();
}
Derived& x_major_grid_width(double w)
{
- derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width(w);
+ derived().image.g(PLOT_X_MAJOR_GRID).style().stroke_width(w);
return derived();
}
double x_major_grid_width()
{
- return derived().image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width();
+ return derived().image.g(PLOT_X_MAJOR_GRID).style().stroke_width();
}
Derived& x_minor_grid_color(const svg_color& col)
{
- derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_color(col);
+ derived().image.g(PLOT_X_MINOR_GRID).style().stroke_color(col);
return derived();
}
svg_color x_minor_grid_color()
{
- return derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_color();
+ return derived().image.g(PLOT_X_MINOR_GRID).style().stroke_color();
}
Derived& x_minor_grid_width(double w)
{
- derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width(w);
+ derived().image.g(PLOT_X_MINOR_GRID).style().stroke_width(w);
return derived();
}
double x_minor_grid_width()
{
- return derived().image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width();
+ return derived().image.g(PLOT_X_MINOR_GRID).style().stroke_width();
}
Derived& x_axis_width(double width)
{
- derived().image.get_g_element(PLOT_X_AXIS).style().stroke_width(width);
+ derived().image.g(PLOT_X_AXIS).style().stroke_width(width);
return derived();
}
double x_axis_width()
{
- return derived().image.get_g_element(PLOT_X_AXIS).style().stroke_width();
+ return derived().image.g(PLOT_X_AXIS).style().stroke_width();
}
Derived& data_lines_width(double width)
{
- derived().image.get_g_element(PLOT_DATA_LINES).style().stroke_width(width);
+ derived().image.g(PLOT_DATA_LINES).style().stroke_width(width);
return derived();
}
double data_lines_width()
{
- return derived().image.get_g_element(PLOT_DATA_LINES).style().stroke_width();
+ return derived().image.g(PLOT_DATA_LINES).style().stroke_width();
}
Derived& x_label(const std::string& str)
@@ -2192,13 +2214,13 @@
Derived& x_major_tick_width(double width)
{
derived().x_ticks_.major_tick_width_ = width; // Redundant?
- derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width(width);
+ derived().image.g(PLOT_X_MAJOR_TICKS).style().stroke_width(width);
return derived();
}
double x_major_tick_width()
{
- return derived().image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width();
+ return derived().image.g(PLOT_X_MAJOR_TICKS).style().stroke_width();
}
Derived& x_minor_tick_length(double length)
@@ -2215,14 +2237,14 @@
Derived& x_minor_tick_width(double width)
{
derived().x_ticks_.minor_tick_width_ = width;
- derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width(width);
+ derived().image.g(PLOT_X_MINOR_TICKS).style().stroke_width(width);
return derived();
}
double x_minor_tick_width()
{
// return derived().x_minor_tick_width_; // should be the same but store in stroke_width is definitive.
- return derived().image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width();
+ return derived().image.g(PLOT_X_MINOR_TICKS).style().stroke_width();
}
Derived& x_major_tick(double d)
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/numeric_limits_handling.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/numeric_limits_handling.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/numeric_limits_handling.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -12,7 +12,7 @@
#ifndef BOOST_SVG_NUMERIC_LIMITS_HANDLING_DETAIL_HPP
#define BOOST_SVG_NUMERIC_LIMITS_HANDLING_DETAIL_HPP
-#include <boost\math\special_functions\fpclassify.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
// TODO use the boost version instead to be more portable?
// Since only double is used, template versions are not needed,
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -12,9 +12,10 @@
#ifndef BOOST_SVG_TAG_HPP
#define BOOST_SVG_TAG_HPP
-// -------------------------------------------------------------------------------
-// This file svg_tag.hpp defines all classes that can occur in the SVG parse tree.
-// -------------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// This file svg_tag.hpp defines all classes that can occur in the
+// SVG parse tree.
+// -----------------------------------------------------------------------------
#include <boost/ptr_container/ptr_container.hpp>
// using boost::vec_ptr;
@@ -22,6 +23,7 @@
// using boost::array;
#include "../svg_style.hpp"
+#include "svg_style_detail.hpp"
#include <ostream>
// using std::ostream;
@@ -67,38 +69,62 @@
// for grouping together related graphics elements, for example:
// <g stroke="rgb(255,0,0)" <rect x="0" y="0" width="500" height="600"/> </g>
- // -----------------------------------------------------------------------------
+ // --------------------------------------------------------------------------
// svg_element is base class for all the leaf elements:
// rect_element, circle_element, line_element, text_element,
- // polygon_element, polyline_element, path_element, clip_path_element, g_element
+ // polygon_element, polyline_element, path_element, clip_path_element,
+ // g_element
+ //
// g_element ('g' element is a container element
// for grouping together related graphics elements).
// http://www.w3.org/TR/SVG/struct.html#NewDocument 5.2.1 Overview
- // -----------------------------------------------------------------------------
+ // --------------------------------------------------------------------------
class svg_element
{ // Base class
protected:
- svg_style style_info; // fill, stroke, width, get by function style().
- std::string id_name; // set & get by function id.
- std::string clip_name; // set & get by function clip_id.
+ svg_style style_info_; // fill, stroke, width, get by function style.
+ std::string id_name_; // set & get by function id.
+ std::string class_name_; // set & get by class id.
+ std::string clip_name_; // set & get by function clip_id.
void write_attributes(std::ostream& s_out)
{ // group_element id and clip-path.
- if(id_name.size() != 0)
+ if(id_name_.size() != 0)
{ // Example: id="imageBackground"
- s_out << " id=\"" << id_name << "\""; // Prefix with space.
+ s_out << " id=\"" << id_name_ << "\""; // Prefix with space.
}
- if(clip_name.size() != 0)
+ if(class_name_.size() != 0)
+ {
+ s_out << " class=\"" << class_name_ << "\"";
+ }
+ if(clip_name_.size() != 0)
{ // Example: clip-path="url(#plot_window)"
- s_out << " clip-path=\"url(#" << clip_name << ")\""; // Prefix with space.
+ s_out << " clip-path=\"url(#" << clip_name_ << ")\""; // Prefix with space.
}
// Inherited classes add other references, 5.3.1, like color, fill, stroke, gradients...
// Example id: <g id="yMinorGrid" ></g>
+ // Example class: <g class="grid_style"></g>
// Example URI: fill="url(#Gradient01) // local URL
} // void write_attributes(std::ostream& s_out)
public:
+
+ svg_element(const svg_style& style_info,
+ const std::string& id_name = "",
+ const std::string& class_name = "",
+ const std::string& clip_name = "")
+ :style_info_(style_info),
+ id_name_(id_name),
+ class_name_(class_name),
+ clip_name_(clip_name)
+ {
+ }
+
+ svg_element()
+ {
+ }
+
virtual void write(std::ostream& rhs) = 0;
virtual ~svg_element()
{
@@ -106,18 +132,18 @@
bool operator==(const svg_element& lhs)
{ // might be useful for Boost.Test.
- return lhs.id_name == id_name;
+ return lhs.id_name_ == id_name_;
}
// Set and get member functions.
svg_style& style()
{
- return style_info;
+ return style_info_;
}
const svg_style& style() const
{ // const version.
- return style_info;
+ return style_info_;
}
void id(const std::string& id)
@@ -135,23 +161,36 @@
// A group of elements, as well as individual objects,
// can be given a name using the id attribute.
// Named groups are needed for several purposes such as animation and re-usable objects.
- id_name = id;
+ id_name_ = id;
// Example: id="plotBackground"
}
std::string id()
{ // Unique name for an element.
- return id_name;
+ return id_name_;
+ }
+
+ void class_id(const std::string& class_id)
+ { // Non-unique identifier for an element.
+ // http://www.w3.org/TR/2001/REC-SVG-20010904/styling.html#ClassAttribute
+ // 6.12 Attributes common to all elements: id and xml:base
+ // Example: class="info"
+ class_name_ = class_id;
+ }
+
+ std::string class_id()
+ { // Unique name for an element.
+ return class_name_;
}
void clip_id(const std::string& id)
{ // Named clip, for example: g_ptr.clip_id(plot_window_clip_);
- clip_name = id;
+ clip_name_ = id;
}
std::string clip_id()
{
- return clip_name;
+ return clip_name_;
}
}; // class svg_element
@@ -165,21 +204,32 @@
class line_element: public svg_element
{
private:
- double x1; // Line from (x1, x2) to (y1, y2)
- double x2;
- double y1;
- double y2;
+ double x1_; // Line from (x1_, x2_) to (y1_, y2_)
+ double x2_;
+ double y1_;
+ double y2_;
public:
line_element(double x1, double y1, double x2, double y2)
- : x1(x1), y1(y1), x2(x2), y2(y2)
+ : x1_(x1), y1_(y1), x2_(x2), y2_(y2)
+ {
+ }
+
+ line_element(double x1, double y1,
+ double x2, double y2,
+ const svg_style& style_info,
+ const std::string& id_name="",
+ const std::string& class_name="",
+ const std::string& clip_name = "")
+ : x1_(x1), y1_(y1), x2_(x2), y2_(y2),
+ svg_element(style_info, id_name, class_name, clip_name)
{
}
void write(std::ostream& rhs)
{
- rhs << "<line x1=\"" << x1 << "\" y1=\"" << y1
- << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\"/>";
+ rhs << "<line x1=\"" << x1_ << "\" y1=\"" << y1_
+ << "\" x2=\"" << x2_ << "\" y2=\"" << y2_ << "\"/>";
// Example: <line x1="5" y1="185" x2="340" y2="185"/>
}
}; // class line_element
@@ -206,6 +256,16 @@
{ // Constructor defines all private data (no defaults).
}
+ rect_element(double x, double y, double w, double h,
+ const svg_style& style_info,
+ const std::string& id_name,
+ const std::string& class_name,
+ const std::string& clip_name)
+ : x_(x), y_(y), width_(w), height_(h),
+ svg_element(style_info, id_name, class_name, clip_name)
+ { // Constructor defines all private data (no defaults).
+ }
+
double x() const
{
return x_;
@@ -281,6 +341,17 @@
{ // Define all private data.
}
+ circle_element(double x, double y, double radius,
+ const svg_style& style_info,
+ const std::string& id_name="",
+ const std::string& class_name="",
+ const std::string& clip_name=""
+ )
+ : x(x), y(y), radius(radius),
+ svg_element(style_info, id_name, class_name, clip_name)
+ { // Define all private data.
+ }
+
void write(std::ostream& rhs)
{
rhs << "<circle";
@@ -308,6 +379,26 @@
{ // Define all private data.
}
+ ellipse_element(double cx, double cy, double rx, double ry,
+ const svg_style& style_info,
+ const std::string& id_name="",
+ const std::string& class_name="",
+ const std::string& clip_name="")
+ : cx(cx), cy(cy), rx(rx), ry(ry),
+ svg_element(style_info, id_name, class_name, clip_name)
+ { // Define all private data.
+ }
+
+ ellipse_element(double cx, double cy,
+ const svg_style& style_info,
+ const std::string& id_name="",
+ const std::string& class_name="",
+ const std::string& clip_name="")
+ : cx(cx), cy(cy), rx(4), ry(8), // 4 and 8 are the same defaults used above
+ svg_element(style_info, id_name, class_name, clip_name)
+ { // Define all private data.
+ }
+
void write(std::ostream& rhs)
{
rhs << "<ellipse";
@@ -326,196 +417,182 @@
left_align, right_align, center_align
};
- //enum rotate_style defined in svg_style.
- //{ // Rotation in degrees from horizontal.
- // horizontal = 0, // normal left to right.
- // uphill = -45, // slope up.
- // upward = -90, // vertical writing up.
- // backup = -135, // slope up backwards.
- // downhill = 45, // slope down.
- // downward = 90, // vertical writing down.
- // backdown = 135, // slope down backwards.
- // upsidedown = 180 // == -180
- //};
-
- class text_element: public svg_element
- { // Holds text with position, size, font, (& styles) & orientation.
- // Not necessarily shown correctly by all browsers, alas.
- private: // Access only via member functions below.
- // SVG Coordinates of 1st character EM box, see
- // http://www.w3.org/TR/SVG/text.html#TextElement 10.2
- // So any text with y coordinate = 0 shows only any roman lower case descenders!
- double x_; // Left edge.
- double y_; // Bottom of roman capital character.
- std::string text_; // Actual text to display.
- text_style style_; // font variants.
- align_style align_; // left_align, right_align, center_align
- rotate_style rotate_; // horizontal, upward, downward, upsidedown
-
- // (Text may contain embedded xml Unicode characters
- // for Greek, math etc, for example: Ω).
- //int size; // " font-size = 12"
- //// http://www.w3.org/TR/SVG/text.html#CharactersAndGlyphs
- //std::string font; // font-family: "Arial" | "Times New Roman" | "Verdana" | "Lucida Sans Unicode"
- //// "sans", "serif", "times"
- //// http://www.w3.org/TR/SVG/text.html#FontFamilyProperty
- //// 10.10 Font selection properties
- //std::string style_; // font-style: normal | bold | italic | oblique
- //std::string weight; // font-weight: normal | bold | bolder | lighter | 100 | 200 .. 900
- //std::string stretch; // font-stretch: normal | wider | narrower ...
- //std::string decoration; // // "underline" | "overline" | "line-through"
- //// Example:
- //// <text x="250" y="219.5" text-anchor="middle" font-family="verdana" font-size="12">0 </text>
- public:
- // Set and get member functions.
+class text_element: public svg_element
+{ // Holds text with position, size, font, (& styles) & orientation.
+ // Not necessarily shown correctly by all browsers, alas.
+ private: // Access only via member functions below.
+ // SVG Coordinates of 1st character EM box, see
+ // http://www.w3.org/TR/SVG/text.html#TextElement 10.2
+ // So any text with y coordinate = 0 shows only any roman lower case descenders!
+ double x_; // Left edge.
+ double y_; // Bottom of roman capital character.
+ std::string text_; // Actual text to display.
+ text_style style_; // font variants.
+ align_style align_; // left_align, right_align, center_align
+ rotate_style rotate_; // horizontal, upward, downward, upsidedown
+
+ // (Text may contain embedded xml Unicode characters
+ // for Greek, math etc, for example: Ω).
+ //int size; // " font-size = 12"
+ // http://www.w3.org/TR/SVG/text.html#CharactersAndGlyphs
+ //std::string font; // font-family: "Arial" | "Times New Roman" | "Verdana" | "Lucida Sans Unicode"
+ // "sans", "serif", "times"
+ // http://www.w3.org/TR/SVG/text.html#FontFamilyProperty
+ // 10.10 Font selection properties
+ //std::string style_; // font-style: normal | bold | italic | oblique
+ //std::string weight; // font-weight: normal | bold | bolder | lighter | 100 | 200 .. 900
+ //std::string stretch; // font-stretch: normal | wider | narrower ...
+ //std::string decoration; // // "underline" | "overline" | "line-through"
+ // Example:
+ // <text x="250" y="219.5" text-anchor="middle" font-family="verdana" font-size="12">0 </text>
+
+public:
+
+ text_style& style()
+ { // Access to font family, size ...
+ return style_;
+ }
- text_style& style()
- { // Access to font family, size ...
- return style_;
- }
+ const text_style& style() const
+ {
+ return style_;
+ }
- const text_style& style() const
- {
- return style_;
- }
+ void alignment(align_style a)
+ { // left_align, right_align, center_align
+ align_ = a;
+ }
- void alignment(align_style a)
- { // left_align, right_align, center_align
- align_ = a;
- }
+ align_style alignment()
+ { // left_align, right_align, center_align
+ return align_;
+ }
- align_style alignment()
- { // left_align, right_align, center_align
- return align_;
- }
+ void rotation(rotate_style rot)
+ { // Degrees: horizontal = 0, upward = -90, downward, upsidedown
+ rotate_ = rot;
+ }
- void rotation(rotate_style rot)
- { // Degrees: horizontal = 0, upward = -90, downward, upsidedown
- rotate_ = rot;
- }
+ rotate_style rotation() const
+ {
+ return rotate_;
+ }
- rotate_style rotation() const
- {
- return rotate_;
- }
+ void x(double x)
+ { // x coordinate of text to write.
+ x_ = x;
+ }
- void x(double x)
- { // x coordinate of text to write.
- x_ = x;
- }
+ double x() const
+ { // x coordinate of text to write.
+ return x_;
+ }
- double x() const
- { // x coordinate of text to write.
- return x_;
- }
+ void y(double y)
+ { // y coordinate of text to write.
+ y_ = y;
+ }
- void y(double y)
- { // y coordinate of text to write.
- y_ = y;
- }
+ double y() const
+ { // y coordinate of text to write.
+ return y_;
+ }
- double y() const
- { // y coordinate of text to write.
- return y_;
- }
+ void text(const std::string& t)
+ { // text to write.
+ text_ = t;
+ }
- void text(const std::string& t)
- { // text to write.
- text_ = t;
- }
-
- const std::string& text()
- {
- return text_;
- }
-
- text_element(
- // Coordinates of 1st character EM box, see
- // http://www.w3.org/TR/SVG/text.html#TextElement 10.2
- double x = 0., // Left edge.
- double y = 0., // Bottom of character (roman capital).
- // So any text with y coordinate = 0 shows only the roman lower case descenders!
- const std::string text = "",
- text_style ts = no_style, // Left to SVG defaults.
- align_style align = left_align,
- rotate_style rotate = horizontal)
- : // Constructor.
- x_(x), y_(y), // location.
- text_(text),
- //size(size), font(font), style_(style), weight(weight), stretch(stretch), decoration(decoration),
- style_(ts),
- align_(align),
- rotate_(rotate)
- { // text_element default constructor, defines defaults for all private members.
- }
+ const std::string& text()
+ {
+ return text_;
+ }
- void write(std::ostream& os)
- { // text_element, style & attributes to stream.
- // Changed to new convention on spaces:
- // NO trailing space, but *start* each item with a space.
- // For debug, may be convenient to start with newline.
- // os << " <text x=\"" << x_ << "\" y=\"" << y_ << "\"";
- os << "\n<text x=\"" << x_ << "\" y=\"" << y_ << "\"";
- std::string anchor;
- switch(align_)
- {
- case left_align:
- // anchor = "start"; // This is the initial == default.
- // so should be possible to reduce file size this by:
- anchor = "";
- break;
- case right_align:
- anchor = "end";
- break;
- case center_align:
- anchor = "middle";
- break;
- default:
- anchor = "";
- break;
- }
- if(anchor != "")
- {
- os << " text-anchor=\"" << anchor << "\"";
- }
- if(rotate_ != 0)
- {
- os << " transform = \"rotate("
- << rotate_ << " "
- << x_ << " "
- << y_ << " )\"";
- }
- if (style_.font_size() != 0)
- {
- os << " font-size=\"" << style_.font_size() << "\"";
- }
- if (style_.font_family() != "")
- { // Example: Arial.
- os << " font-family=\"" << style_.font_family() << "\"";
- }
- if (style_.font_style().size() != 0)
- { // Example: italic.
- os << " font-style=\"" << style_.font_style() << "\"";
- }
- if (style_.font_weight().size() != 0)
- { // Example: bold.
- os << " font-weight=\"" << style_.font_weight() << "\"";
- }
- if (style_.font_stretch().size() != 0)
- {
- os << " font-stretch=\"" << style_.font_stretch() << "\"";
- }
- if (style_.font_decoration().size() != 0)
- {
- os << " font-decoration=\"" << style_.font_decoration() << "\"";
- }
- os << '>' << text_ << "</text>";
- // Example:
- } // void write(std::ostream& os)
+ text_element(
+ // Coordinates of 1st character EM box, see
+ // http://www.w3.org/TR/SVG/text.html#TextElement 10.2
+ double x = 0., // Left edge.
+ double y = 0., // Bottom of character (roman capital).
+ // So any text with y coordinate = 0 shows only the roman lower case descenders!
+ const std::string text = "",
+ text_style ts = no_style, // Left to SVG defaults.
+ align_style align = left_align,
+ rotate_style rotate = horizontal)
+ : // Constructor.
+ x_(x), y_(y), // location.
+ text_(text),
+ //size(size), font(font), style_(style), weight(weight), stretch(stretch), decoration(decoration),
+ style_(ts),
+ align_(align),
+ rotate_(rotate)
+ { // text_element default constructor, defines defaults for all private members.
+ }
-
- }; // class text_element
+ void write(std::ostream& os)
+ { // text_element, style & attributes to stream.
+ // Changed to new convention on spaces:
+ // NO trailing space, but *start* each item with a space.
+ // For debug, may be convenient to start with newline.
+ // os << " <text x=\"" << x_ << "\" y=\"" << y_ << "\"";
+ os << "\n<text x=\"" << x_ << "\" y=\"" << y_ << "\"";
+ std::string anchor;
+ switch(align_)
+ {
+ case left_align:
+ // anchor = "start"; // This is the initial == default.
+ // so should be possible to reduce file size this by:
+ anchor = "";
+ break;
+ case right_align:
+ anchor = "end";
+ break;
+ case center_align:
+ anchor = "middle";
+ break;
+ default:
+ anchor = "";
+ break;
+ }
+ if(anchor != "")
+ {
+ os << " text-anchor=\"" << anchor << "\"";
+ }
+ if(rotate_ != 0)
+ {
+ os << " transform = \"rotate("
+ << rotate_ << " "
+ << x_ << " "
+ << y_ << " )\"";
+ }
+ if (style_.font_size() != 0)
+ {
+ os << " font-size=\"" << style_.font_size() << "\"";
+ }
+ if (style_.font_family() != "")
+ { // Example: Arial.
+ os << " font-family=\"" << style_.font_family() << "\"";
+ }
+ if (style_.font_style().size() != 0)
+ { // Example: italic.
+ os << " font-style=\"" << style_.font_style() << "\"";
+ }
+ if (style_.font_weight().size() != 0)
+ { // Example: bold.
+ os << " font-weight=\"" << style_.font_weight() << "\"";
+ }
+ if (style_.font_stretch().size() != 0)
+ {
+ os << " font-stretch=\"" << style_.font_stretch() << "\"";
+ }
+ if (style_.font_decoration().size() != 0)
+ {
+ os << " font-decoration=\"" << style_.font_decoration() << "\"";
+ }
+ os << '>' << text_ << "</text>";
+ // Example:
+ } // void write(std::ostream& os)
+}; // class text_element_
std::ostream& operator<< (std::ostream& os, text_element& t)
{ //
@@ -528,7 +605,6 @@
return os;
} // std::ostream& operator<<
-
class clip_path_element: public svg_element
{ // The clipping path restricts the region to which paint can be applied.
// 14.3 Clipping paths http://www.w3.org/TR/SVG/masking.html#ClipPathProperty
@@ -842,6 +918,14 @@
path = (const_cast<path_element&>(rhs)).path.release();
}
+ path_element(const svg_style& style_info,
+ const std::string& id_name="",
+ const std::string& class_name="",
+ const std::string& clip_name="")
+ : svg_element(style_info, id_name, class_name, clip_name)
+ {
+ }
+
path_element() : fill(true)
{ // TODO why is the default fill(true)?
}
@@ -966,8 +1050,11 @@
(*i).write(o_str); // M1,2
}
o_str << "\"";
+
write_attributes(o_str); // id & clip_path
- style_info.write(o_str); // fill, stroke, width...
+
+ style_info_.write(o_str); // fill, stroke, width...
+
if(!fill)
{
o_str << " fill=\"none\"";
@@ -1102,7 +1189,7 @@
poly_points.push_back(new poly_path_point(p.x, p.y));
}
}
-
+/*
template<int n>
polygon_element (boost::array<const poly_path_point, n>& points, bool f = true)
:
@@ -1131,7 +1218,7 @@
poly_points.push_back(new poly_path_point(p.x, p.y));
}
}
-
+*/
// Member function to add more points to polygon.
polygon_element& P(double x, double y)
{ // Add another (x, y) - absolute only.
@@ -1148,7 +1235,7 @@
}
o_str << "\"";
write_attributes(o_str);
- style_info.write(o_str);
+ style_info_.write(o_str);
if(!fill)
{
o_str << " fill = \"none\"";
@@ -1256,7 +1343,7 @@
}
o_str << "\"";
write_attributes(o_str);
- style_info.write(o_str);
+ style_info_.write(o_str);
o_str<<"/>";
// Example: <polyline points=" 100,100 200,100 300,200 400,400"/>
} // void write(std::ostream& o_str)
@@ -1314,7 +1401,7 @@
os << "<g"; // Do NOT need space if convention is to start following item with space.
write_attributes(os); // id="background" (or clip_path)
- style_info.write(os); // stroke="rgb(0,0,0)"
+ style_info_.write(os); // stroke="rgb(0,0,0)"
os << ">" ;
for(unsigned int i = 0; i < children.size(); ++i)
{
@@ -1325,117 +1412,111 @@
// <g fill="rgb(255,255,255)" id="background"><rect x="0" y="0" width="500" height="350"/></g>
} // void write(std::ostream& rhs)
- g_element& g_tag(int i)
+ g_element& g(int i)
{ // i is index of children nodes.
return *(static_cast<g_element*>(&children[i]));
}
// Returns a reference to the new child node just created.
- g_element& add_g_element()
+ g_element& g()
{
- children.push_back(new g_element);
+ children.push_back(new g_element());
return *(static_cast<g_element*>(&children[children.size()-1]));
}
- // get ith g_element or child node.
- g_element& get_g_element(int i)
+ line_element& line(double x1, double y1, double x2, double y2)
{
- return *(static_cast<g_element*>(&children[i]));
+ children.push_back(new line_element(x1, y1, x2, y2));
+ return *(static_cast<line_element*>(&children[children.size()-1]));
}
- void push_back(svg_element* g)
+ rect_element& rect(double x1, double y1, double x2, double y2)
{
- children.push_back(g);
- }
-
- void clear()
- {
- children.clear();
+ children.push_back(new rect_element(x1, y1, x2, y2));
+ return *(static_cast<rect_element*>(&children[children.size()-1]));
}
- // Push_back the several elements:
- // circle, ellipse, rect, line, path, text, polyline, polygon.
- g_element& circle(double x, double y, double radius = 5.)
+ circle_element& circle(double x, double y, unsigned int radius = 5)
{
children.push_back(new circle_element(x, y, radius));
- return *this;
+ return *(static_cast<circle_element*>(&children[children.size()-1]));
}
- g_element& ellipse(double x, double y, double radius_x = 3., double radius_y = 6.)
+ ellipse_element& ellipse(double rx, double ry, double cx, double cy)
{
- children.push_back(new ellipse_element(x, y, radius_x, radius_y));
- return *this;
+ children.push_back(new ellipse_element(rx, ry, cx, cy));
+ return *(static_cast<ellipse_element*>(&children[children.size()-1]));
}
- g_element& text(double x = 0., double y = 0.,
- const std::string& text = "",
- text_style& style = no_style, // Use svg implementation's defaults.
- align_style align = left_align,
- rotate_style rotate = horizontal)
+ text_element& text(double x = 0., double y = 0.,
+ const std::string& text = "",
+ const text_style& style = no_style, // Use svg implementation's defaults.
+ const align_style& align = left_align,
+ const rotate_style& rotate = horizontal)
{
children.push_back(new text_element(x, y, text, style, align, rotate));
- // font, style, weight, stretch, decoration, now in text_style.
- return *this;
+ return *(static_cast<text_element*>(&children[children.size()-1]));
}
- g_element& rect(double x1, double y1, double x2, double y2)
+ // push_back info about polygon shapes:
+ // Polygon for shapes with many vertices.
+ polygon_element& polygon(double x, double y, bool f = true)
{
- children.push_back(new rect_element(x1, y1, x2, y2));
- return *this;
+ children.push_back(new polygon_element(x, y, f));
+ return *(static_cast<polygon_element*>(&children[children.size()-1]));
}
- g_element& line(double x1, double y1, double x2, double y2)
- {
- children.push_back(new line_element(x1, y1, x2, y2));
- return *this;
+ //JVTODO: Replace with template version
+ polygon_element& polygon(std::vector<poly_path_point>& v, bool f = true)
+ { // push_back a complete many-sided polygon to the document.
+ children.push_back(new polygon_element(v, f));
+ return *(static_cast<polygon_element*>(&children[children.size()-1]));
+ }
+
+ //JVTODO: Replace with template version
+ polyline_element& polyline(std::vector<poly_path_point>& v)
+ { // push_back a complete many-sided polygon to the document.
+ children.push_back(new polyline_element(v));
+ return *(static_cast<polyline_element*>(&children[children.size()-1]));
}
- // TODO should the default be fill or not?
- g_element& polygon(double x1, double y1, bool f = true)
+ polyline_element& polyline(double x, double y) // 1st point only, add others later with .P(x, y).
{
- children.push_back(new polygon_element(x1, y1, f));
- return *this;
+ children.push_back(new polyline_element(x, y));
+ return *(static_cast<polyline_element*>(&children[children.size()-1]));
}
- g_element& polygon(std::vector<poly_path_point>& points, bool f = true)
+ void push_back(svg_element* g)
{
- children.push_back(new polygon_element(points, f));
- return *this;
+ children.push_back(g);
}
- g_element& triangle(double x1, double y1, double x2, double y2, double x3, double y3, bool f = true)
+ polygon_element& triangle(double x1, double y1, double x2, double y2, double x3, double y3, bool f)
{
children.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, f));
- return *this;
+ return *(static_cast<polygon_element*>(&(children[(unsigned int)(children.size()-1)])));
}
- g_element& rhombus(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool f = true)
+ polygon_element& rhombus(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool f)
{
children.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, f = true));
- return *this;
+ return *(static_cast<polygon_element*>(&(children[(unsigned int)(children.size()-1)])));
}
- g_element& pentagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, bool f = true)
+ polygon_element& pentagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, bool f = true)
{ // push_back a complete pentagon to the document.
children.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, f));
- return *this; // svg&
+ return *(static_cast<polygon_element*>(&(children[(unsigned int)(children.size()-1)])));
}
- g_element& hexagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6, bool f = true)
+ polygon_element& hexagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6, bool f = true)
{ // push_back a complete 6-sided star to the document.
children.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, f));
- return *this; // svg&
- }
-
- g_element& polyline(double x1, double y1, bool f = true)
- {
- children.push_back(new polygon_element(x1, y1, f));
- return *this;
+ return *(static_cast<polygon_element*>(&(children[(unsigned int)(children.size()-1)])));
}
// These return a reference to the last child node just pushed.
// (Unlike the above functions that return a g_element&).
- // TODO why?
polygon_element& polygon()
{
children.push_back(new polygon_element()); // Empty polygon,
@@ -1455,6 +1536,12 @@
return *(static_cast<path_element*>(&(children[(unsigned int)(children.size()-1)])));
}
+ void clear()
+ {
+ children.clear();
+ }
+
+
}; // class g_element
} // namespace svg
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/stylesheet.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/stylesheet.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/stylesheet.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -14,8 +14,8 @@
#include <boost/spirit/core.hpp>
#include <boost/spirit/utility/distinct.hpp>
+#include <stdexcept>
// TODO get some inscrutable errors from this and so commented out of other modules.
-
#include <exception>
#include <string>
#include <fstream>
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -17,7 +17,7 @@
#include <exception>
#include <vector>
-//#include "stylesheet.hpp" // TODO better to be called svg_stylesheet.hpp?
+#include "stylesheet.hpp" // TODO better to be called svg_stylesheet.hpp?
#include "detail/svg_tag.hpp" // element class definitions.
#include "svg_style.hpp"
//#include "svg_fwd.hpp"
@@ -233,26 +233,23 @@
}
// Set & get functions for x_size_ and y_size_
- svg& x_size(unsigned int x)
+ void x_size(unsigned int x)
{
x_size_ = x;
- return *this;
}
- unsigned int x_size()
- { // x_size_ name is now used in class to permit function called x_size.
- // TODO Better called image_x_size()?
- return x_size_;
- }
-
- svg& y_size(unsigned int y)
+ void y_size(unsigned int y)
{
y_size_ = y;
- return *this;
+ }
+
+ unsigned int x_size()
+ {
+ return x_size_;
}
unsigned int y_size()
- { // y_size_ name is now used in class to permit function called y_size.
+ {
return y_size_;
}
@@ -261,7 +258,7 @@
return static_cast<unsigned int>(document.size());
}
- svg& coord_precision(int digits)
+ void coord_precision(int digits)
{ // Set decimal digits to be output for output of coordinates.
// Default stream precision 6 decimal digits is probably excessive.
// 4.1 Basic data types, integer or float in decimal or scientific (using e format).
@@ -273,7 +270,6 @@
// but can be changed using this function.
// Used in svg.write below and so applies to all the svg document.
coord_precision_ = digits;
- return *this;
}
int coord_precision()
@@ -292,7 +288,7 @@
// recommends MUST have correct Content-Encoding headers.
// --------------------------------------------------------------------------------
- svg& write(const std::string& file)
+ void write(const std::string& file)
{// Write whole .svg 'file' contents to file.
std::ofstream f_out(file.c_str());
if(f_out.fail())
@@ -303,10 +299,9 @@
}
filename_ = file; // Note so that can embed into file as comment.
write(f_out);
- return *this;
}
- svg& write(std::ostream& s_out)
+ void write(std::ostream& s_out)
{ // Write whole .svg 'file' contents to stream (perhaps a file).
write_header(s_out); // "<?xml version=...
// write svg document, begin <svg tag.
@@ -404,10 +399,9 @@
write_css(s_out);// stylesheet, if any.
write_document(s_out); // write clip paths and all document elements.
s_out << "</svg>" << std::endl; // close off svg tag.
- return *this;
}
- svg& license( // Set license requirements for the svg document.
+ void license( // Set license requirements for the svg document.
const std::string repro = "permits",
const std::string distrib = "permits",
const std::string attrib = "requires",
@@ -418,14 +412,12 @@
attribution_ = attrib;
commercialuse_ = commercial;
is_license_ = true; // Assume want this if set these?
- return *this;
}
- svg& license_on(bool l)
+ void license(bool l)
{ // Set (or not) license using all requirement (default permits).
// Implicitly set by setting a license requirement using license above.
is_license_ = l;
- return *this;
}
bool license_on()
@@ -433,10 +425,9 @@
return is_license_;
}
- svg& boost_license_on(bool l)
+ void boost_license_on(bool l)
{ // Set (or not) Boost license.
is_boost_license_ = l;
- return *this;
}
bool boost_license_on()
@@ -466,17 +457,15 @@
// Writes the information about the image to the document.
// TODO: allow other unit identifiers.
// -------------------------------------------------------
- svg& image_size(unsigned int x, unsigned int y)
+ void image_size(unsigned int x, unsigned int y)
{
x_size_ = x;
y_size_ = y;
- return *this;
}
- svg& description(const std::string d)
+ void description(const std::string d)
{ // Writes description to the document(for header as <desc>).
image_desc_ = d;
- return *this;
}
const std::string& description()
@@ -484,10 +473,9 @@
return image_desc_;
}
- svg& author(const std::string a)
+ void author(const std::string a)
{ // Writes author to the document (default is copyright_holder).
author_ = a;
- return *this;
}
const std::string& author()
@@ -495,10 +483,9 @@
return author_;
}
- svg& document_title(const std::string d)
+ void document_title(const std::string d)
{ // Writes document title for the document(for header as <title>)..
title_document_ = d;
- return *this;
}
const std::string document_title()
@@ -506,10 +493,9 @@
return title_document_;
}
- svg& copyright_holder(const std::string d)
+ void copyright_holder(const std::string d)
{ // Writes document title for the document(for header as <title>)..
holder_copyright_ = d;
- return *this;
}
const std::string copyright_holder()
@@ -517,10 +503,9 @@
return holder_copyright_;
}
- svg& copyright_date(const std::string d)
+ void copyright_date(const std::string d)
{ // Writes document title for the document(for header as <title>)..
date_copyright_ = d;
- return *this;
}
const std::string copyright_date()
@@ -528,10 +513,9 @@
return date_copyright_;
}
- svg& image_filename(const std::string filename)
+ void image_filename(const std::string filename)
{ // Writes image filename for the document(for header as <title>)..
filename_ = filename;
- return *this;
}
const std::string image_filename()
@@ -542,105 +526,89 @@
// ------------------------------------------------------------------------
// push_back information about line, rec, circle & ellipse to the document.
// ------------------------------------------------------------------------
- svg& line(double x1, double y1, double x2, double y2)
+ line_element& line(double x1, double y1, double x2, double y2)
{ // 'line' element defines a line segment
// that starts at one point and ends at another.
- document.push_back(new line_element(x1, y1, x2, y2));
- return *this;
+ return document.line(x1, y1, x2, y2);
}
- svg& rect(double x1, double y1, double x2, double y2)
+ rect_element& rect(double x1, double y1, double x2, double y2)
{
- document.push_back(new rect_element(x1, y1, x2, y2));
-
- return *this;
+ return document.rect(x1, y1, x2, y2);
}
- svg& circle(double x, double y, unsigned int radius = 5)
+ circle_element& circle(double x, double y, unsigned int radius = 5)
{
- document.push_back(new circle_element(x, y, radius));
- return *this;
+ return document.circle(x, y, radius);
}
- svg& ellipse(double rx, double ry, double cx, double cy)
- { //
- document.push_back(new ellipse_element(rx, ry, cx, cy));
- return *this;
+ ellipse_element& ellipse(double rx, double ry, double cx, double cy)
+ {
+ return document.ellipse(rx, ry, cx, cy);
}
// -------------------------------------------------
// push_back information about text to the document.
// -------------------------------------------------
- svg& text(double x, double y, const std::string& text,
- const text_style& style, // size, font etc.
- align_style align = center_align, rotate_style rotate = horizontal
- )
+ text_element& text(double x, double y, const std::string& text,
+ const text_style& style, // size, font etc.
+ align_style align, rotate_style rotate)
{
- document.push_back(new text_element(x, y, text, style, align, rotate) );
- return *this;
- }
+ return document.text(x, y, text, style, align, rotate);
+ }
// push_back info about polygon shapes:
// Polygon for shapes with many vertices.
-
- svg& polygon(double x, double y, bool f = true) // 1st point only, add others later with .P(x, y).
+ polygon_element& polygon(double x, double y, bool f = true) // 1st point only, add others later with .P(x, y).
{
- document.push_back(new polygon_element(x, y, f));
- return *this;
+ return document.polygon(x, y, f);
}
- svg& polygon(std::vector<poly_path_point>& v, bool f = true)
+ //JVTODO: Replace with template version
+ polygon_element& polygon(std::vector<poly_path_point>& v, bool f = true)
{ // push_back a complete many-sided polygon to the document.
- document.push_back(new polygon_element(v, f));
- return *this; // svg&
+ return document.polygon(v, f);
}
+ // JVTODO: These are not in the standard. Remove, or keep as convenience?
// Specific polygon shapes: triangle, rhombus, pentagon & hexagon.
- svg& triangle(double x1, double y1, double x2, double y2, double x3, double y3, bool f = true)
+ polygon_element& triangle(double x1, double y1, double x2, double y2, double x3, double y3, bool f = true)
{ // push_back a complete triangle to the document.
- document.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, f));
- return *this; // svg&
+ return document.polygon(x1, y1, f).P(x2, y2).P(x3, y3);
}
- svg& rhombus(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool f = true)
+ polygon_element& rhombus(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool f = true)
{ // push_back a complete rhombus to the document.
- document.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, f));
- return *this; // svg&
+ return document.polygon(x1, y1, f).P(x2, y2).P(x3, y3).P(x4, y4);
}
- svg& pentagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, bool f = true)
+ polygon_element& pentagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, bool f = true)
{ // push_back a complete pentagon to the document.
- document.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, f));
- return *this; // svg&
+ return document.polygon(x1, y1, f).P(x2, y2).P(x3, y3).P(x4, y4).P(x5, y5);
}
- svg& hexagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6, bool f = true)
+ polygon_element& hexagon(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double x5, double y5, double x6, double y6, bool f = true)
{ // push_back a complete 6-sided star to the document.
- document.push_back(new polygon_element(x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6, f));
- return *this; // svg&
+ return document.polygon(x1, y1, f).P(x2, y2).P(x3, y3).P(x4, y4).P(x5, y5).P(x6, y6);
}
// push_back info about polylines.
- svg& polyline(double x, double y) // 1st point only, add others later with .P(x, y).
+ polyline_element& polyline(double x, double y) // 1st point only, add others later with .P(x, y).
{
- document.push_back(new polyline_element(x, y));
- return *this;
+ return document.polyline(x, y);
}
- svg& polyline(double x1, double y1, double x2, double y2)
+ polyline_element& polyline(double x1, double y1, double x2, double y2)
{ // Two points only, add others later with .P(x, y).
- document.push_back(new polyline_element(x1, y1));
- document.push_back(new polyline_element(x2, y2));
- return *this;
+ return document.polyline(x1, y1).P(x2, y2);
}
- svg& polyline(std::vector<poly_path_point>& v, bool f = true)
+ polyline_element& polyline(std::vector<poly_path_point>& v)
{ // push_back a complete many-sided polygon to the document,
// from a vector of points.
- document.push_back(new polygon_element(v, f));
- return *this; // svg&
+ return document.polyline(v);
}
// --------------------------------------------------------------------------------
@@ -649,58 +617,58 @@
path_element& path()
{
- document.push_back(new path_element()); // empty path, ready for additions with M., L. ...
- return *(static_cast<path_element*>(&(document[(unsigned int)(document.size()-1)])));
- // reference to the path_element just pushed.
+ return document.path(); // empty path, ready for additions with M., L. ...
}
- svg& clip_path(const rect_element& rect, const std::string& id)
+ clip_path_element& clip_path(const rect_element& rect, const std::string& id)
{ // Rectangle outside which 'painting' is 'clipped' so doesn't show.
clip_paths.push_back(clip_path_element(id, rect));
- return *this;
+ return clip_paths[clip_paths.size()-1];
}
// -------------------------------------------------------------
// Writes information about a group element to the document.
// -------------------------------------------------------------
- g_element& add_g_element()
+ g_element& g()
{
- return document.add_g_element();
+ return document.g();
}
- g_element& get_g_element(int i)
+ g_element& g(int i)
{ // Array of g_elements document,
// indexed by group type, PLOT_BACKGROUND, PLOT_WINDOW_BACKGROUND, ... SVG_PLOT_DOC_CHILDREN
- return document.g_tag(i);
+ return document.g(i);
}
//// -------------------------------------------------------------
//// Load stylesheet
//// -------------------------------------------------------------
- //svg& load_stylesheet(const std::string& input)
- //{ // Load a stylesheet into string css from an input file.
- // std::ifstream if_str(input.c_str());
-
- // if(if_str.fail())
- // {
- // throw std::runtime_error("Error opening file " + input);
- // }
- // if(!validate_stylesheet(if_str))
- // {
- // throw std::runtime_error("Error loading stylesheet!");
- // }
- // if_str.clear();
- // if_str.seekg(0);
- // std::string tmp;
- // css = "";
- // while(std::getline(if_str, tmp))
- // {
- // css += tmp;
- // }
- // return *this;
- //} // svg& load_stylesheet
+ void load_stylesheet(const std::string& input)
+ { // Load a stylesheet into string css from an input file.
+ std::ifstream if_str(input.c_str());
+
+ if(if_str.fail())
+ {
+ throw std::runtime_error("Error opening file " + input);
+ }
+ if(!validate_stylesheet(if_str))
+ {
+ throw std::runtime_error("Error loading stylesheet!");
+ }
+
+ if_str.clear();
+ if_str.seekg(0);
+
+ std::string tmp;
+ css = "";
+
+ while(std::getline(if_str, tmp))
+ {
+ css += tmp;
+ }
+ } // svg& load_stylesheet
}; // class svg
} // namespace svg
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_2d_plot.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -42,24 +42,6 @@
class svg_2d_plot; // Plot.
class svg_2d_plot_series; // plot data series.
- static const double wh = 0.7; // font text width/height ratio.
- // Even after reading http://www.w3.org/TR/SVG/fonts.html, unclear how to
- // determine the exact width of digits, so an
- // arbitrary average width height ratio wh = 0.7 is used as a good approximation.
-
- static const double sin45 = 0.707; // Use if axis value labels are sloping.
-
- // x_axis_position_ and y_axis_position_ use these.
- enum x_axis_intersect {bottom = -1, x_intersects_y = 0, top = +1};
- // bottom = X-axis free below bottom of end of Y-axis (case of all Y definitely < 0).
- // top = X-axis free above top of X-axis (case of all Y definitely > 0).
- // x_intersects_y when Y values include zero, so X intersects the Y axis.
-
- enum y_axis_intersect {left = -1, y_intersects_x = 0, right = +1};
- // left = Y-axis free to left of end of X-axis (case of all X definitely < 0).
- // right = Y-axis free to left of end of X-axis (case of all X definitely > 0).
- // y_intersects_x when X values include zero, so intersects the X axis.
-
// -----------------------------------------------------------------
// This allows us to store plot state locally in svg_plot. We don't
// store it in "svg" because transforming the points after they are
@@ -200,6 +182,8 @@
text_style y_value_label_style_;
text_style point_symbols_style_; // Used for data point marking.
+ double x_label_width_;
+
text_element title_info_; // Plot title.
text_element legend_header_; // legend box header or title (if any).
text_element x_label_info_; // For example: "length"
@@ -274,7 +258,7 @@
y_axis_label_style_(14, "Verdana", "", ""),
y_value_label_style_(12, "Verdana", "", ""),
point_symbols_style_(12, "Lucida Sans Unicode"), // Used for data point marking.
-
+ x_label_width_(5),
title_info_(0, 0, "Plot of data", title_style_, center_align, horizontal),
x_label_info_(0, 0, "X Axis", x_axis_label_style_, center_align, horizontal),
x_units_info_(0, 0, " (units)", x_value_label_style_, center_align, horizontal),
@@ -315,25 +299,25 @@
// Build the document tree by adding all children of the root node.
for(int i = 0; i < SVG_PLOT_DOC_CHILDREN; ++i)
{
- image.add_g_element();
+ image.g();
}
set_ids();
// Set other SVG color, stroke & width defaults for various child PLOT nodes.
- image.get_g_element(PLOT_BACKGROUND).style().fill_color(image_border_.fill_);
- image.get_g_element(PLOT_BACKGROUND).style().stroke_color(image_border_.stroke_);
- image.get_g_element(PLOT_BACKGROUND).style().stroke_width(image_border_.width_); //
- image.get_g_element(PLOT_WINDOW_BACKGROUND).style().fill_color(plot_window_border_.fill_);
- image.get_g_element(PLOT_WINDOW_BACKGROUND).style().stroke_width(plot_window_border_.width_).stroke_color(plot_window_border_.stroke_);
- image.get_g_element(PLOT_LIMIT_POINTS).style().stroke_color(lightslategray).fill_color(antiquewhite);
- image.get_g_element(PLOT_X_AXIS).style().stroke_color(black).stroke_width(x_axis_.width());
- image.get_g_element(PLOT_Y_AXIS).style().stroke_color(black).stroke_width(y_axis_.width());
- image.get_g_element(PLOT_X_LABEL).style().fill_color(black);
- image.get_g_element(PLOT_Y_LABEL).style().fill_color(black);
- image.get_g_element(PLOT_VALUE_LABELS).style().fill_color(black);
- image.get_g_element(PLOT_LEGEND_TEXT).style().fill_color(black);
- image.get_g_element(PLOT_TITLE).style().fill_color(black).stroke_on(false);
+ image.g(PLOT_BACKGROUND).style().fill_color(image_border_.fill_);
+ image.g(PLOT_BACKGROUND).style().stroke_color(image_border_.stroke_);
+ image.g(PLOT_BACKGROUND).style().stroke_width(image_border_.width_); //
+ image.g(PLOT_WINDOW_BACKGROUND).style().fill_color(plot_window_border_.fill_);
+ image.g(PLOT_WINDOW_BACKGROUND).style().stroke_width(plot_window_border_.width_).stroke_color(plot_window_border_.stroke_);
+ image.g(PLOT_LIMIT_POINTS).style().stroke_color(lightslategray).fill_color(antiquewhite);
+ image.g(PLOT_X_AXIS).style().stroke_color(black).stroke_width(x_axis_.width());
+ image.g(PLOT_Y_AXIS).style().stroke_color(black).stroke_width(y_axis_.width());
+ image.g(PLOT_X_LABEL).style().fill_color(black);
+ image.g(PLOT_Y_LABEL).style().fill_color(black);
+ image.g(PLOT_VALUE_LABELS).style().fill_color(black);
+ image.g(PLOT_LEGEND_TEXT).style().fill_color(black);
+ image.g(PLOT_TITLE).style().fill_color(black).stroke_on(false);
// Note that widths are stored in member data *and* copied here.
// Not sure if this is wise but ...
@@ -341,22 +325,22 @@
// Ticks
if(x_ticks_.use_up_ticks() || x_ticks_.use_down_ticks())
{
- image.get_g_element(PLOT_X_MAJOR_TICKS).style().stroke_width(x_ticks_.major_tick_width_).stroke_color(black);
- image.get_g_element(PLOT_X_MINOR_TICKS).style().stroke_width(x_ticks_.minor_tick_width_).stroke_color(black);
+ image.g(PLOT_X_MAJOR_TICKS).style().stroke_width(x_ticks_.major_tick_width_).stroke_color(black);
+ image.g(PLOT_X_MINOR_TICKS).style().stroke_width(x_ticks_.minor_tick_width_).stroke_color(black);
}
if(y_ticks_.left_ticks_on_ || y_ticks_.right_ticks_on_)
{
- image.get_g_element(PLOT_Y_MAJOR_TICKS).style().stroke_width(y_ticks_.major_tick_width_).stroke_color(black);
- image.get_g_element(PLOT_Y_MINOR_TICKS).style().stroke_width(y_ticks_.minor_tick_width_).stroke_color(black);
+ image.g(PLOT_Y_MAJOR_TICKS).style().stroke_width(y_ticks_.major_tick_width_).stroke_color(black);
+ image.g(PLOT_Y_MINOR_TICKS).style().stroke_width(y_ticks_.minor_tick_width_).stroke_color(black);
}
// Grids.
// Default color & width for grid, used or not.
- image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_width(x_ticks_.major_grid_width_).stroke_color(svg_color(200, 220, 255));
- BOOST_ASSERT(image.get_g_element(PLOT_X_MAJOR_GRID).style().stroke_color() == svg_color(200, 220, 255));
- image.get_g_element(PLOT_X_MINOR_GRID).style().stroke_width(x_ticks_.minor_grid_width_).stroke_color(svg_color(200, 220, 255));
- image.get_g_element(PLOT_Y_MAJOR_GRID).style().stroke_width(y_ticks_.major_grid_width_).stroke_color(svg_color(200, 220, 255));
- image.get_g_element(PLOT_Y_MINOR_GRID).style().stroke_width(y_ticks_.minor_grid_width_).stroke_color(svg_color(200, 220, 255));
- image.get_g_element(PLOT_DATA_LINES).style().stroke_width(2); // default width.
+ image.g(PLOT_X_MAJOR_GRID).style().stroke_width(x_ticks_.major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ BOOST_ASSERT(image.g(PLOT_X_MAJOR_GRID).style().stroke_color() == svg_color(200, 220, 255));
+ image.g(PLOT_X_MINOR_GRID).style().stroke_width(x_ticks_.minor_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.g(PLOT_Y_MAJOR_GRID).style().stroke_width(y_ticks_.major_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.g(PLOT_Y_MINOR_GRID).style().stroke_width(y_ticks_.minor_grid_width_).stroke_color(svg_color(200, 220, 255));
+ image.g(PLOT_DATA_LINES).style().stroke_width(2); // default width.
// Alter with plot.data_lines_width(4);
legend_place_ = (plot_window_on_) ? outside_right : inside; // Defaults.
@@ -376,7 +360,7 @@
{ // document ids for use in <g id = "PLOT_TITLE".../>
for(int i = 0; i < detail::SVG_PLOT_DOC_CHILDREN; ++i)
{ // Order determines the painting order.
- image.get_g_element(i).id(detail::document_ids[i]);
+ image.g(i).id(detail::document_ids[i]);
}
} // void set_ids()
@@ -612,7 +596,7 @@
}
if (plot_window_on_)
{ // Draw plot window rectangle with border and/or background.
- image.get_g_element(detail::PLOT_WINDOW_BACKGROUND).push_back(
+ image.g(detail::PLOT_WINDOW_BACKGROUND).push_back(
new rect_element(plot_left_, plot_top_, (plot_right_ - plot_left_), plot_bottom_ - plot_top_));
}
@@ -633,24 +617,24 @@
{ // Extend the vertical line down in lieu of longest tick.
ybottom += (std::max)(x_ticks_.minor_tick_length_, x_ticks_.major_tick_length_);// Avoid macro max trap!
}
- image.get_g_element(detail::PLOT_Y_AXIS).line(x, plot_top_, x, ybottom);
+ image.g(detail::PLOT_Y_AXIS).line(x, plot_top_, x, ybottom);
// <g id="yAxis" stroke="rgb(0,0,0)"><line x1="70.5" y1="53" x2="70.5" y2="357"/>
if (y_ticks_.ticks_on_plot_window_on_ < 0) //(y_axis_position_ == left)
{ // Draw vertical line holding the ticks on the left of plot window.
- image.get_g_element(detail::PLOT_Y_AXIS).line(plot_left_, plot_top_, plot_left_, plot_bottom_);
+ image.g(detail::PLOT_Y_AXIS).line(plot_left_, plot_top_, plot_left_, plot_bottom_);
}
else
{// Draw vertical line holding the ticks on the right of plot window.
- image.get_g_element(detail::PLOT_Y_AXIS).line(plot_right_, plot_top_, plot_right_, plot_bottom_);
+ image.g(detail::PLOT_Y_AXIS).line(plot_right_, plot_top_, plot_right_, plot_bottom_);
}
}
else if (y_axis_position_ == left)
{ // Draw on the left of plot window.
- image.get_g_element(detail::PLOT_Y_AXIS).line(plot_left_, plot_top_, plot_left_, plot_bottom_);
+ image.g(detail::PLOT_Y_AXIS).line(plot_left_, plot_top_, plot_left_, plot_bottom_);
}
else if (y_axis_position_ == right)
{// Draw on the lright of plot window.
- image.get_g_element(detail::PLOT_Y_AXIS).line(plot_right_, plot_top_, plot_right_, plot_bottom_);
+ image.g(detail::PLOT_Y_AXIS).line(plot_right_, plot_top_, plot_right_, plot_bottom_);
}
else
{ // ??? Warn that things have gone wrong?
@@ -658,10 +642,10 @@
}
// Access the paths for the ticks & grids, ready for additions.
- path_element& minor_tick_path = image.get_g_element(detail::PLOT_Y_MINOR_TICKS).path();
- path_element& major_tick_path = image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).path();
- path_element& minor_grid_path = image.get_g_element(detail::PLOT_Y_MINOR_GRID).path();
- path_element& major_grid_path = image.get_g_element(detail::PLOT_Y_MAJOR_GRID).path();
+ path_element& minor_tick_path = image.g(detail::PLOT_Y_MINOR_TICKS).path();
+ path_element& major_tick_path = image.g(detail::PLOT_Y_MAJOR_TICKS).path();
+ path_element& minor_grid_path = image.g(detail::PLOT_Y_MINOR_GRID).path();
+ path_element& major_grid_path = image.g(detail::PLOT_Y_MAJOR_GRID).path();
// y_minor_jump is the interval between minor ticks.
double y_minor_jump = y_ticks_.major_interval_ / ((double)(y_ticks_.num_minor_ticks_ + 1.) );
@@ -723,7 +707,7 @@
}
double y = image_border_.width_ + image_border_.margin_ + y_axis_label_style_.font_size();
- image.get_g_element(detail::PLOT_Y_LABEL).push_back(new
+ image.g(detail::PLOT_Y_LABEL).push_back(new
text_element(y,
// shift over one char height to right from left edge of image.
(plot_bottom_ + plot_top_) / 2., // center on the plot window.
@@ -833,7 +817,7 @@
}
// Always want all values including "0", if labeling external to plot window.
// y_ticks_.ticks_on_plot_window_on_ == true != 0
- image.get_g_element(detail::PLOT_VALUE_LABELS).text(
+ image.g(detail::PLOT_VALUE_LABELS).text(
x_left,
y,
label.str(), y_value_label_style_, alignment, y_ticks_.label_rotation_);
@@ -843,7 +827,7 @@
if ((value != 0) && y_axis_.axis_line_on_)
{ // Avoid a zero ON the Y-axis if it would be cut through by any horizontal X-axis line.
y += y_value_label_style_.font_size() / 2;
- image.get_g_element(detail::PLOT_VALUE_LABELS).text(
+ image.g(detail::PLOT_VALUE_LABELS).text(
x_left ,
y, // Just shift down half a digit to center value digits on tick.
label.str(),
@@ -927,7 +911,7 @@
double temp_x(0.);
double temp_y;
- g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_LINES).add_g_element();
+ g_element& g_ptr = image.g(detail::PLOT_DATA_LINES).g();
g_ptr.clip_id(plot_window_clip_);
g_ptr.style().stroke_color(series.line_style_.color_);
g_ptr.style().fill_color(series.line_style_.area_fill_);
@@ -989,7 +973,7 @@
void draw_bezier_lines(const svg_2d_plot_series& series)
{
- g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_LINES).add_g_element();
+ g_element& g_ptr = image.g(detail::PLOT_DATA_LINES).g();
g_ptr.clip_id(plot_window_clip_);
g_ptr.style().stroke_color(series.line_style_.color_);
path_element& path = g_ptr.path();
@@ -1085,7 +1069,7 @@
// painting, so the order of drawing is important.
// Draw image background (perhaps with border and/or fill color).
- image.get_g_element(detail::PLOT_BACKGROUND).push_back(
+ image.g(detail::PLOT_BACKGROUND).push_back(
new rect_element(0, 0, image.x_size(), image.y_size()));
calculate_plot_window();
@@ -1101,7 +1085,7 @@
plot_window_clip_);
// <clipPath id="plot_window"><rect x="35" y="38" width="309" height="322"/></clipPath>
- image.get_g_element(detail::PLOT_DATA_POINTS).clip_id(plot_window_clip_);
+ image.g(detail::PLOT_DATA_POINTS).clip_id(plot_window_clip_);
// Draw axes, labels & legend, as required.
draw_x_axis(); // Must do X-axis first.
@@ -1126,7 +1110,7 @@
double y(0.);
for(unsigned int i = 0; i < series.size(); ++i)
{
- g_element& g_ptr = image.get_g_element(detail::PLOT_DATA_POINTS).add_g_element();
+ g_element& g_ptr = image.g(detail::PLOT_DATA_POINTS).g();
g_ptr.style()
.fill_color(series[i].point_style_.fill_color_)
@@ -1148,7 +1132,7 @@
// Draw all the 'bad' at_limit points.
for(unsigned int i = 0; i < series.size(); ++i)
{
- g_element& g_ptr = image.get_g_element(detail::PLOT_LIMIT_POINTS);
+ g_element& g_ptr = image.g(detail::PLOT_LIMIT_POINTS);
for(std::multimap<double,double>::const_iterator j = series[i].series_limits.begin();
j!=series[i].series_limits.end(); ++j)
@@ -1266,13 +1250,13 @@
svg_2d_plot& y_axis_width(double width)
{
- image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width(width);
+ image.g(detail::PLOT_Y_AXIS).style().stroke_width(width);
return *this;
}
double y_axis_width()
{
- return image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_width();
+ return image.g(detail::PLOT_Y_AXIS).style().stroke_width();
}
svg_2d_plot& y_value_precision(int digits)
@@ -1286,7 +1270,7 @@
return y_ticks_.value_precision_;
}
- svg_2d_plot& y_value_ioflags(int flags)
+ svg_2d_plot& y_value_ioflags(std::_Ios_Fmtflags flags)
{ // IO flags of Y tick label values (default 0X201).
y_ticks_.value_ioflags_ = flags;
return *this;
@@ -1310,24 +1294,24 @@
svg_2d_plot& y_axis_color(const svg_color& col)
{ // Set only stroke color.
- image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_color(col);
+ image.g(detail::PLOT_Y_AXIS).style().stroke_color(col);
return *this;
}
svg_color y_axis_color()
{ // return the stroke color.
- return image.get_g_element(detail::PLOT_Y_AXIS).style().stroke_color();
+ return image.g(detail::PLOT_Y_AXIS).style().stroke_color();
}
svg_2d_plot& y_axis_label_color(const svg_color& col)
{ // Set stroke color.
- image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
+ image.g(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
return *this;
}
svg_color y_axis_label_color()
{ // But only return the stroke color.
- return image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
+ return image.g(detail::PLOT_VALUE_LABELS).style().stroke_color();
}
svg_2d_plot& y_label_units_on(bool b)
@@ -1343,68 +1327,68 @@
svg_2d_plot& y_axis_value_color(const svg_color& col)
{
- image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
+ image.g(detail::PLOT_VALUE_LABELS).style().stroke_color(col);
return *this;
}
svg_color y_axis_value_color()
{ // Only return the stroke color.
- return image.get_g_element(detail::PLOT_VALUE_LABELS).style().stroke_color();
+ return image.g(detail::PLOT_VALUE_LABELS).style().stroke_color();
}
svg_2d_plot& y_label_width(double width)
{
- image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_width(width);
+ image.g(detail::PLOT_Y_LABEL).style().stroke_width(width);
return *this;
}
double y_label_width()
{
- return image.get_g_element(detail::PLOT_Y_LABEL).style().stroke_width();
+ return image.g(detail::PLOT_Y_LABEL).style().stroke_width();
}
svg_2d_plot& y_major_grid_color(const svg_color& col)
{
- image.get_g_element(detail::PLOT_Y_MAJOR_GRID).style().stroke_color(col);
+ image.g(detail::PLOT_Y_MAJOR_GRID).style().stroke_color(col);
return *this;
}
const svg_color y_major_grid_color()
{
- return image.get_g_element(detail::PLOT_Y_MAJOR_GRID).style().stroke_color();
+ return image.g(detail::PLOT_Y_MAJOR_GRID).style().stroke_color();
}
svg_2d_plot& y_minor_grid_color(const svg_color& col)
{
- image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_color(col);
+ image.g(detail::PLOT_Y_MINOR_GRID).style().stroke_color(col);
return *this;
}
const svg_color y_minor_grid_color()
{
- return image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_color();
+ return image.g(detail::PLOT_Y_MINOR_GRID).style().stroke_color();
}
svg_2d_plot& y_major_tick_color(const svg_color& col)
{
- image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color(col);
+ image.g(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color(col);
return *this;
}
const svg_color y_major_tick_color()
{
- return image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color();
+ return image.g(detail::PLOT_Y_MAJOR_TICKS).style().stroke_color();
}
svg_2d_plot& y_minor_tick_color(const svg_color& col)
{
- image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_color(col);
+ image.g(detail::PLOT_Y_MINOR_TICKS).style().stroke_color(col);
return *this;
}
const svg_color y_minor_tick_color()
{
- return image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_color();
+ return image.g(detail::PLOT_Y_MINOR_TICKS).style().stroke_color();
}
const std::string y_axis_position()
@@ -1514,7 +1498,7 @@
svg_2d_plot& y_major_tick_width(double width)
{
y_ticks_.major_tick_width_ = width;
- image.get_g_element(detail::PLOT_Y_MAJOR_TICKS).style().stroke_width(width);
+ image.g(detail::PLOT_Y_MAJOR_TICKS).style().stroke_width(width);
return *this;
}
@@ -1526,7 +1510,7 @@
svg_2d_plot& y_minor_tick_width(double width)
{
y_ticks_.minor_tick_width_ = width;
- image.get_g_element(detail::PLOT_Y_MINOR_TICKS).style().stroke_width(width);
+ image.g(detail::PLOT_Y_MINOR_TICKS).style().stroke_width(width);
return *this;
}
@@ -1606,7 +1590,7 @@
svg_2d_plot& y_minor_grid_width(double width)
{
y_ticks_.minor_grid_width_ = width;
- image.get_g_element(detail::PLOT_Y_MINOR_GRID).style().stroke_width(width);
+ image.g(detail::PLOT_Y_MINOR_GRID).style().stroke_width(width);
return *this;
}
@@ -1618,7 +1602,7 @@
svg_2d_plot& y_major_grid_width(double width)
{
y_ticks_.major_grid_width_ = width;
- image.get_g_element(detail::PLOT_Y_MAJOR_GRID).style().stroke_width(width);
+ image.g(detail::PLOT_Y_MAJOR_GRID).style().stroke_width(width);
return *this;
}
Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_style.hpp 2008-01-20 23:40:06 EST (Sun, 20 Jan 2008)
@@ -738,7 +738,7 @@
bool major_grid_on_; // Draw X grid at major ticks.
bool minor_grid_on_;// Draw X grid at minor ticks.
int value_precision_; // precision for tick value labels, usually 3 will suffice.
- int value_ioflags_; // IO formatting flags for the axis default std::ios::dec.
+ std::_Ios_Fmtflags value_ioflags_; // IO formatting flags for the axis default std::ios::dec.
bool strip_e0s_; // If redundant zero, + and e are to be stripped.
size_t label_max_chars_; // width (in SVG units) of longest label on axis.
int ticks_on_plot_window_on_; // Value labels & ticks on the plot window border
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk