Boost logo

Boost-Commit :

From: jakevoytko_at_[hidden]
Date: 2007-06-17 22:48:15


Author: jakevoytko
Date: 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
New Revision: 7088
URL: http://svn.boost.org/trac/boost/changeset/7088

Log:
Legend added, changed interface, more customizable.

Added:
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp
Text files modified:
   sandbox/SOC/2007/visualization/boost/svg_plot/svg.hpp | 137 +++++---------
   sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp | 382 ++++++++++++++++++++++++++++-----------
   2 files changed, 325 insertions(+), 194 deletions(-)

Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_plot_instruction.hpp 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,47 @@
+// svg_plot_instruction.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_PLOT_INSTRUCTION_HPP
+#define _SVG_PLOT_INSTRUCTION_HPP
+
+#include <iterator>
+#include "svg_style.hpp"
+
+namespace boost {
+namespace svg {
+
+// -----------------------------------------------------------------
+// This struct is the smallest amount of information necessary at
+// the moment to display a legend with enough information
+// -----------------------------------------------------------------
+struct legend_point
+{
+ svg_color stroke_color;
+ svg_color fill_color;
+ std::string text;
+
+ legend_point(const svg_color& _stroke, const svg_color& _fill,
+ std::string _text): stroke_color(_stroke), fill_color(_fill),
+ text(_text)
+ {
+
+ }
+
+ legend_point(svg_color_constant _stroke, svg_color_constant _fill,
+ std::string _text): stroke_color(constant_to_rgb(_stroke)),
+ fill_color(constant_to_rgb(_fill)),
+ text(_text)
+ {
+
+ }
+};
+}
+}
+
+#endif

Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_style.hpp 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,337 @@
+// svg_style.hpp
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_STYLE_HPP
+#define _SVG_STYLE_HPP
+
+#include <map>
+
+namespace boost {
+namespace svg {
+
+// -----------------------------------------------------------------
+// Deals with colors that have special names. The reason that the
+// underscoring does not match the normal Boost format
+// is that these are the names that are specifically allowed by the
+// SVG standard
+// -----------------------------------------------------------------
+enum svg_color_constant
+{
+ aliceblue, antiquewhite, aqua, aquamarine, azure, beige,
+ bisque, black, blanchedalmond, blue, blueviolet, brown,
+ burlywood, cadetblue, chartreuse, chocolate, coral,
+ cornflowerblue, cornsilk, crimson, cyan, darkblue, darkcyan,
+ darkgoldenrod, darkgray, darkgreen, darkgrey, darkkhaki,
+ darkmagenta, darkolivegreen, darkorange, darkorchid, darkred,
+ darksalmon, darkseagreen, darkslateblue, darkslategray,
+ darkslategrey, darkturquoise, darkviolet, deeppink,
+ deepskyblue, dimgray, dimgrey, dodgerblue, firebrick,
+ floralwhite, forestgreen, fuchsia, gainsboro, ghostwhite, gold,
+ goldenrod, gray, grey, green, greenyellow, honeydew, hotpink,
+ indianred, indigo, ivory, khaki, lavender, lavenderblush,
+ lawngreen, lemonchiffon, lightblue, lightcoral, lightcyan,
+ lightgoldenrodyellow, lightgray, lightgreen, lightgrey,
+ lightpink, lightsalmon, lightseagreen, lightskyblue,
+ lightslategray, lightslategrey, lightsteelblue, lightyellow,
+ lime, limegreen, linen, magenta, maroon, mediumaquamarine,
+ mediumblue, mediumorchid, mediumpurple, mediumseagreen,
+ mediumslateblue, mediumspringgreen, mediumturquoise,
+ mediumvioletred, midnightblue, mintcream, mistyrose, moccasin,
+ navajowhite, navy, oldlace, olive, olivedrab, orange,
+ orangered, orchid, palegoldenrod, palegreen, paleturquoise,
+ palevioletred, papayawhip, peachpuff, peru, pink, plum,
+ powderblue, purple, red, rosybrown, royalblue, saddlebrown,
+ salmon, sandybrown, seagreen, seashell, sienna, silver,
+ skyblue, slateblue, slategray, slategrey, snow, springgreen,
+ steelblue, tan, teal, thistle, tomato, turquoise, violet,
+ wheat, white, whitesmoke, yellow, yellowgreen
+};
+
+
+void constant_to_rgb(svg_color_constant _c, unsigned char &r, unsigned char &g,
+ unsigned char &b);
+
+// -----------------------------------------------------------------
+// svg_color is the struct that contains information about sRGB
+// colors.
+//
+// For the constructor: the svg standard specifies that numbers
+// outside the normal rgb range are to be accepted, but are rounded
+// to acceptable values.
+// -----------------------------------------------------------------
+struct svg_color
+{
+ unsigned char r, g, b;
+
+ svg_color(int _r, int _g, int _b)
+ {
+ _r = ( _r < 0 ) ? 0 : _r;
+ _g = ( _g < 0 ) ? 0 : _g;
+ _b = ( _b < 0 ) ? 0 : _b;
+
+ r = (unsigned char)(( _r > 255 ) ? 255 : _r);
+ g = (unsigned char)(( _g > 255 ) ? 255 : _g);
+ b = (unsigned char)(( _b > 255 ) ? 255 : _b);
+ }
+
+ svg_color(svg_color_constant _col)
+ {
+ constant_to_rgb(_col, r, g, b);
+ }
+
+ void write(std::ostream& rhs)
+ {
+ rhs << "rgb(" << (unsigned int)r << "," << (unsigned int) g << ","
+ << (unsigned int)b << ")" ;
+ }
+};
+
+// -----------------------------------------------------------------
+// To facilitate quick lookup of the RGB values of constants
+// -----------------------------------------------------------------
+svg_color color_array[] =
+{
+ svg_color(240, 248, 255), // aliceblue
+ svg_color(250, 235, 215), // antiquewhite
+ svg_color(0 , 255, 255), // aqua
+ svg_color(127, 255, 212), // aquamarine
+ svg_color(240, 255, 255), // azure
+ svg_color(245, 245, 220), // beige
+ svg_color(255, 228, 196), // bisque
+ svg_color(0 , 0 , 0 ), // black
+ svg_color(255, 235, 205), // blanchedalmond. Who thinks of these?
+ svg_color(0 , 0 , 255), // blue
+ svg_color(138, 43 , 226), // blueviolet
+ svg_color(165, 42 , 42 ), // brown
+ svg_color(222, 184, 135), // burlywood
+ svg_color(95 , 158, 160), // cadetblue
+ svg_color(127, 255, 0 ), // chartreuse
+ svg_color(210, 105, 30 ), // chocolate
+ svg_color(255, 127, 80 ), // coral
+ svg_color(100, 149, 237), // cornflowerblue
+ svg_color(255, 248, 220), // cornsilk
+ svg_color(220, 20 , 60 ), // crimson
+ svg_color(0 , 255, 255), // cyan
+ svg_color(0 , 0 , 139), // darkblue
+ svg_color(0 , 139, 139), // darkcyan
+ svg_color(184, 134, 11 ), // darkgoldenrod
+ svg_color(169, 169, 169), // darkgray
+ svg_color(0 , 100, 0 ), // darkgreen
+ svg_color(169, 169, 169), // darkgrey
+ svg_color(189, 183, 107), // darkkhaki
+ svg_color(139, 0 , 139), // darkmagenta
+ svg_color(85 , 107, 47 ), // darkolivegreen
+ svg_color(255, 140, 0 ), // darkorange
+ svg_color(153, 50 , 204), // darkorchid
+ svg_color(139, 0 , 0 ), // darkred
+ svg_color(233, 150, 122), // darksalmon
+ svg_color(143, 188, 143), // darkseagreen
+ svg_color(72 , 61 , 139), // darkslateblue
+ svg_color(47 , 79 , 79 ), // darkslategray
+ svg_color(47 , 79 , 79 ), // darkslategrey
+ svg_color(0 , 206, 209), // darkturquoise
+ svg_color(148, 0 , 211), // darkviolet
+ svg_color(255, 20 , 147), // deeppink
+ svg_color(0 , 191, 255), // deepskyblue
+ svg_color(105, 105, 105), // dimgray
+ svg_color(105, 105, 105), // dimgrey
+ svg_color(30 , 144, 255), // dodgerblue
+ svg_color(178, 34 , 34 ), // firebrick
+ svg_color(255, 250, 240), // floralwhite
+ svg_color(34 , 139, 34 ), // forestgreen
+ svg_color(255, 0 , 255), // fuchsia
+ svg_color(220, 220, 220), // gainsboro
+ svg_color(248, 248, 255), // ghostwhite
+ svg_color(255, 215, 0 ), // gold
+ svg_color(218, 165, 32 ), // goldenrod
+ svg_color(128, 128, 128), // gray
+ svg_color(128, 128, 128), // grey
+ svg_color(0 , 128, 0 ), // green
+ svg_color(173, 255, 47 ), // greenyellow
+ svg_color(240, 255, 240), // honeydew
+ svg_color(255, 105, 180), // hotpink
+ svg_color(205, 92 , 92 ), // indianred
+ svg_color(75 , 0 , 130), // indigo
+ svg_color(255, 255, 240), // ivory
+ svg_color(240, 230, 140), // khaki
+ svg_color(230, 230, 250), // lavender
+ svg_color(255, 240, 245), // lavenderblush
+ svg_color(124, 252, 0 ), // lawngreen
+ svg_color(255, 250, 205), // lemonchiffon
+ svg_color(173, 216, 230), // lightblue
+ svg_color(240, 128, 128), // lightcoral
+ svg_color(224, 255, 255), // lightcyan
+ svg_color(250, 250, 210), // lightgoldenrodyellow
+ svg_color(211, 211, 211), // lightgray
+ svg_color(144, 238, 144), // lightgreen
+ svg_color(211, 211, 211), // lightgrey
+ svg_color(255, 182, 193), // lightpink
+ svg_color(255, 160, 122), // lightsalmon
+ svg_color(32 , 178, 170), // lightseagreen
+ svg_color(135, 206, 250), // lightskyblue
+ svg_color(119, 136, 153), // lightslategray
+ svg_color(119, 136, 153), // lightslategrey
+ svg_color(176, 196, 222), // lightsteelblue
+ svg_color(255, 255, 224), // lightyellow
+ svg_color(0 , 255, 0 ), // lime
+ svg_color(50 , 205, 50 ), // limegreen
+ svg_color(250, 240, 230), // linen
+ svg_color(255, 0 , 255), // magenta
+ svg_color(128, 0 , 0 ), // maroon
+ svg_color(102, 205, 170), // mediumaquamarine
+ svg_color(0 , 0 , 205), // mediumblue
+ svg_color(186, 85 , 211), // mediumorchid
+ svg_color(147, 112, 219), // mediumpurple
+ svg_color(60 , 179, 113), // mediumseagreen
+ svg_color(123, 104, 238), // mediumslateblue
+ svg_color(0 , 250, 154), // mediumspringgreen
+ svg_color(72 , 209, 204), // mediumturquoise
+ svg_color(199, 21 , 133), // mediumvioletred
+ svg_color(25 , 25 , 112), // midnightblue
+ svg_color(245, 255, 250), // mintcream
+ svg_color(255, 228, 225), // mistyrose
+ svg_color(255, 228, 181), // moccasin
+ svg_color(255, 222, 173), // navajowhite
+ svg_color(0 , 0 , 128), // navy
+ svg_color(253, 245, 230), // oldlace
+ svg_color(128, 128, 0 ), // olive
+ svg_color(107, 142, 35 ), // olivedrab
+ svg_color(255, 165, 0 ), // orange
+ svg_color(255, 69 , 0 ), // orangered
+ svg_color(218, 122, 214), // orchid
+ svg_color(238, 232, 170), // palegoldenrod
+ svg_color(152, 251, 152), // palegreen
+ svg_color(175, 238, 238), // paleturquose
+ svg_color(219, 112, 147), // palevioletred
+ svg_color(255, 239, 213), // papayawhip
+ svg_color(255, 218, 185), // peachpuff
+ svg_color(205, 133, 63 ), // peru
+ svg_color(255, 192, 203), // pink
+ svg_color(221, 160, 221), // plum
+ svg_color(176, 224, 230), // powderblue
+ svg_color(128, 0 , 128), // purple
+ svg_color(255, 0 , 0 ), // red
+ svg_color(188, 143, 143), // rosybrown
+ svg_color(65 , 105, 225), // royalblue
+ svg_color(139, 69 , 19 ), // saddlebrown
+ svg_color(250, 128, 114), // salmon
+ svg_color(244, 164, 96 ), // sandybrown
+ svg_color(46 , 139, 87 ), // seagreen
+ svg_color(255, 245, 238), // seashell
+ svg_color(160, 82 , 45 ), // sienna
+ svg_color(192, 192, 192), // silver
+ svg_color(135, 206, 235), // skyblue
+ svg_color(106, 90 , 205), // slateblue
+ svg_color(112, 128, 144), // slategray
+ svg_color(112, 128, 144), // slategrey
+ svg_color(255, 250, 250), // snow
+ svg_color(0 , 255, 127), // springgreen
+ svg_color(70 , 130, 180), // steelblue
+ svg_color(210, 180, 140), // tan
+ svg_color(0 , 128, 128), // teal
+ svg_color(216, 191, 216), // thistle
+ svg_color(255, 99 , 71 ), // tomato
+ svg_color(64 , 224, 208), // turquoise
+ svg_color(238, 130, 238), // violet
+ svg_color(245, 222, 179), // wheat
+ svg_color(255, 255, 255), // white
+ svg_color(245, 245, 245), // whitesmoke
+ svg_color(255, 255, 0 ), // yellow
+ svg_color(154, 205, 50 ), // yellowgreen
+};
+
+
+void constant_to_rgb(svg_color_constant _c, unsigned char &r, unsigned char &g,
+ unsigned char &b)
+{
+ r = color_array[(unsigned int)_c].r;
+ g = color_array[(unsigned int)_c].g;
+ b = color_array[(unsigned int)_c].b;
+}
+
+svg_color constant_to_rgb(svg_color_constant _c)
+{
+ return svg_color(color_array[(unsigned int)_c].r
+ ,color_array[(unsigned int)_c].g
+ ,color_array[(unsigned int)_c].b);
+}
+
+// -----------------------------------------------------------------
+// This is the style information for any <g> tag. This will be
+// expanded to include more data from the SVG standard when the
+// time comes.
+// -----------------------------------------------------------------
+class svg_g_style
+{
+private:
+ svg_color fill_color;
+ svg_color stroke_color;
+
+public:
+ svg_g_style();
+ svg_g_style(const svg_color&, const svg_color&);
+ void set_fill_color(const svg_color&);
+ void set_stroke_color(const svg_color&);
+ void write(std::ostream&);
+
+ svg_color get_fill_color()
+ {
+ return svg_color(fill_color);
+ }
+
+ svg_color get_stroke_color()
+ {
+ return svg_color(stroke_color);
+ }
+};
+
+// -----------------------------------------------------------------
+// These are the defaults that I used in the prototype, and they
+// looked decent enough.
+// -----------------------------------------------------------------
+svg_g_style::svg_g_style():fill_color(svg_color(255, 0, 0)),
+ stroke_color(svg_color(0, 0, 0))
+{
+
+}
+
+
+// -----------------------------------------------------------------
+// For changing the defaults for the colors
+// -----------------------------------------------------------------
+svg_g_style::svg_g_style(const svg_color& _fill, const svg_color& _stroke)
+:fill_color(_fill), stroke_color(_stroke)
+{
+
+}
+
+void svg_g_style::write(std::ostream& rhs)
+{
+ rhs << "stroke=\"";
+ stroke_color.write(rhs);
+ rhs << "\" fill=\"";
+ fill_color.write(rhs);
+ rhs<<"\"";
+}
+
+void svg_g_style::set_stroke_color(const svg_color& rhs)
+{
+ stroke_color = rhs;
+}
+
+void svg_g_style::set_fill_color(const svg_color& rhs)
+{
+ fill_color = rhs;
+}
+
+
+}//svg
+}//boost
+
+
+#endif

Added: sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/detail/svg_tag.hpp 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,257 @@
+// svg_tag.hpp
+
+// Copyright (C) Jacob Voytko 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// For more information, see http://www.boost.org
+
+// -----------------------------------------------------------------
+
+#ifndef _SVG_TAG_HPP
+#define _SVG_TAG_HPP
+
+#include <sstream>
+#include <string>
+#include <boost/ptr_container/ptr_container.hpp>
+#include <boost/noncopyable.hpp>
+
+#include "svg_style.hpp"
+
+namespace boost {
+namespace svg {
+
+
+// -----------------------------------------------------------------
+// This file defines all classes that can occur in the SVG parse
+// tree
+// -----------------------------------------------------------------
+
+
+// -----------------------------------------------------------------
+// The base class for all leaf elements
+// -----------------------------------------------------------------
+
+class svg_element
+{
+public:
+ virtual void write(std::ostream&) = 0;
+};
+
+// -----------------------------------------------------------------
+// The node element of our document tree
+// -----------------------------------------------------------------
+
+class g_element: public svg_element
+{
+private:
+ svg_g_style style_info;
+
+public:
+ boost::ptr_vector<svg_element> children;
+
+ svg_element& operator[](unsigned int);
+ size_t size();
+
+ void set_stroke_color(const svg_color&);
+ void set_fill_color(const svg_color&);
+
+ svg_color get_stroke_color()
+ {
+ return style_info.get_stroke_color();
+ }
+ void write(std::ostream&);
+
+ g_element& g_tag(int);
+};
+
+svg_element& g_element::operator[](unsigned int i)
+{
+ return children[i];
+}
+
+size_t g_element::size()
+{
+ return children.size();
+}
+
+void g_element::write(std::ostream& rhs)
+{
+ rhs << "<g ";
+ style_info.write(rhs);
+ rhs<< " >" << std::endl;
+
+ for(unsigned int i=0; i<children.size(); ++i)
+ {
+ children[i].write(rhs);
+ }
+
+ rhs << "</g>" << std::endl;
+
+}
+
+g_element& g_element::g_tag(int i)
+{
+ return *(static_cast<g_element*>(&children[i]));
+}
+
+void g_element::set_stroke_color(const svg_color& _col)
+{
+ style_info.set_stroke_color(_col);
+}
+
+void g_element::set_fill_color(const svg_color& _col)
+{
+ style_info.set_fill_color(_col);
+}
+
+
+// -----------------------------------------------------------------
+// Represents a single point
+// -----------------------------------------------------------------
+class point_element: public svg_element
+{
+private:
+ double x, y;
+
+public:
+ point_element(double, double);
+ void write(std::ostream&);
+};
+
+point_element::point_element(double _x, double _y):x(_x), y(_y)
+{
+
+}
+
+void point_element::write(std::ostream& rhs)
+{
+ rhs<<"<circle cx=\""<<x<<"\" cy=\""<<y<<"\" r=\"5\"/>";
+
+}
+
+// -----------------------------------------------------------------
+// Represents a line
+// -----------------------------------------------------------------
+class line_element: public svg_element
+{
+private:
+ double x1, x2, y1, y2, y;
+
+public:
+ line_element(double, double, double, double);
+ void write(std::ostream&);
+};
+
+line_element::line_element(double _x1, double _y1, double _x2,
+ double _y2):x1(_x1), y1(_y1),
+ x2(_x2), y2(_y2)
+{
+
+}
+
+void line_element::write(std::ostream& rhs)
+{
+ rhs<<"<line x1=\""<<x1<<"\" y1=\""<<y1<<"\" x2=\""<<x2<<"\" y2=\""
+ <<y2<<"\"/>";
+}
+
+// -----------------------------------------------------------------
+// Represents a single block of text
+// -----------------------------------------------------------------
+enum text_style{left_align, right_align, center_align};
+
+class text_element: public svg_element
+{
+private:
+ double x, y;
+ std::string text;
+ text_style alignment;
+
+public:
+ text_element(double, double, std::string);
+ void write(std::ostream&);
+ void set_alignment(text_style _a)
+ {
+ alignment = _a;
+ }
+};
+
+text_element::text_element(double _x, double _y, std::string _text)
+ :x(_x), y(_y), text(_text), alignment(left_align)
+{
+
+}
+
+void text_element::write(std::ostream& rhs)
+{
+ std::string align;
+
+ switch(alignment)
+ {
+ case left_align:
+ align = "start";
+ break;
+
+ case right_align:
+ align = "end";
+ break;
+
+ case center_align:
+ align = "middle";
+ break;
+
+ default:
+ align = "";
+ break;
+ }
+
+ rhs << "<text x=\"" << x << "\""
+ <<" y=\""<<y<<"\" ";
+
+ if(align != "")
+ {
+ rhs << "text-anchor=\""<<align<<"\" ";
+ }
+
+ rhs <<" fill=\"black\" stroke=\"black\" font-family=\"verdana\""
+ <<" font-size=\"12\">"
+ << text
+ <<" </text>";
+}
+
+
+
+// -----------------------------------------------------------------
+// Represents a single block of text
+// -----------------------------------------------------------------
+class rect_element: public svg_element
+{
+private:
+ double x, y, height, width;
+
+public:
+ rect_element(double, double, double, double);
+ void write(std::ostream&);
+};
+
+rect_element::rect_element(double _x, double _y, double _w, double _h)
+ :x(_x), y(_y), width(_w), height(_h)
+{
+
+}
+
+void rect_element::write(std::ostream& rhs)
+{
+ rhs<<"<rect x=\""<<x<<"\""
+ <<" y=\""<<y<<"\" "
+ <<" width=\""<<width<<"\" "
+ <<" height=\""<<height<<"\"/>"
+ ;
+}
+
+
+
+}
+}
+
+#endif
\ No newline at end of file

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 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -16,7 +16,6 @@
 #include <iostream>
 #include <fstream>
 
-#include "svg_instruction.hpp"
 #include "svg_tag.hpp"
 #include "svg_style.hpp"
 
@@ -42,35 +41,28 @@
     
     g_element document;
 
- void _size(unsigned int, unsigned int);
-
- void _write();
-
- void _point(double, double);
- void _point(double, double, g_element&);
-
- void _line(double, double, double, double);
- void _line(double, double, double, double, g_element&);
-
- void _text(double, double, std::string);
- void _line_color(svg_color);
-
-
 public:
     svg(const std::string&);
     
     virtual ~svg();
+
     svg(const svg&);
     svg& operator=(const svg&);
 
- svg& operator<<(const svg_instruction&);
+ svg& image_size(unsigned int, unsigned int);
+ svg& write();
 
- svg& operator<<(const svg_point&);
-
- svg& operator<<(const svg_line&);
- svg& operator<<(const svg_text&);
+ svg& point(double, double);
+ svg& point(double, double, g_element&);
+
+ svg& line(double, double, double, double);
+ svg& line(double, double, double, double, g_element&);
+
+ svg& text(double, double, std::string);
+ svg& line_color(svg_color);
 
- svg& operator<<(const svg_stroke_color&);
+ svg& rect(double, double, double, double);
+ svg& rect(double, double, double, double, g_element&);
 
     friend std::ostream& operator<<(std::ostream&, const svg&);
 };
@@ -102,66 +94,8 @@
 }
 
 // -----------------------------------------------------------------
-// Processes the svg_instructions
-// This allows the user to easily enter information than ordinary
-// method calls, and is more clear that the method supports chaining
-// -----------------------------------------------------------------
-svg& svg::operator<<(const svg_instruction& rhs)
-{
- switch(rhs.i_type)
- {
- case SVG_WRITE:
- _write();
- break;
- }
- return *this;
-}
-
-// -----------------------------------------------------------------
-// Chained stream operators. Each operator overload below will
-// represent a different instruction type, after I rewrite svg's
-// instructions to be more generic.
 // -----------------------------------------------------------------
-svg& svg::operator<<(const svg_point &rhs)
-{
- switch(rhs.i_type)
- {
- case SVG_SIZE:
- _size((unsigned int)rhs.x, (unsigned int)rhs.y);
- break;
- case SVG_POINT:
- _point(rhs.x, rhs.y, document);
- }
-
- return *this;
-}
-
-svg& svg::operator<<(const svg_line &rhs)
-{
- _line(rhs.x1, rhs.y1, rhs.x2, rhs.y2);
-
- return *this;
-}
-
-svg& svg::operator<<(const svg_text &rhs)
-{
- _text(rhs.x, rhs.y, rhs.text);
-
- return *this;
-}
-
-svg& svg::operator<<(const svg_stroke_color &rhs)
-{
- _line_color(rhs.col);
-
- return *this;
-}
-
-// -----------------------------------------------------------------
-// Internal function to write the data to a specified stream
-// TODO: allow other streams than a file stream
-// -----------------------------------------------------------------
-void svg::_write()
+svg& svg::write()
 {
     _write_header();
 
@@ -174,6 +108,8 @@
 
     //close off svg tag
     *s_out<<"</svg>";
+
+ return *this;
 }
 
 // -----------------------------------------------------------------
@@ -206,10 +142,12 @@
 // Writes the information about the size of the file to the document
 // TODO: allow other unit identifiers
 // -----------------------------------------------------------------
-void svg::_size(unsigned int x, unsigned int y)
+svg& svg::image_size(unsigned int x, unsigned int y)
 {
     x_size = x;
     y_size = y;
+
+ return *this;
 }
 
 // -----------------------------------------------------------------
@@ -220,14 +158,18 @@
 // -----------------------------------------------------------------
 
 // this overload has a pointer to a node in the document tree
-void svg::_point(double x, double y, g_element& location)
+svg& svg::point(double x, double y, g_element& location)
 {
     location.children.push_back(new point_element(x, y));
+
+ return *this;
 }
 
-void svg::_point(double x, double y)
+svg& svg::point(double x, double y)
 {
     document.children.push_back(new point_element(x, y));
+
+ return *this;
 }
 
 // -----------------------------------------------------------------
@@ -235,32 +177,53 @@
 // TODO: Allow other line thicknesses
 // TODO: Allow other line colors
 // -----------------------------------------------------------------
-void svg::_line(double x1, double y1, double x2, double y2)
+svg& svg::line(double x1, double y1, double x2, double y2)
 {
     document.children.push_back(new line_element(x1, y1, x2, y2));
+
+ return *this;
 }
 
-void svg::_line(double x1, double y1, double x2, double y2,
+svg& svg::line(double x1, double y1, double x2, double y2,
                 g_element& location)
 {
     location.children.push_back(new line_element(x1, y1, x2, y2));
+
+ return *this;
 }
 
 // -----------------------------------------------------------------
 // Writes the information about text to the document
 // TODO: allow different fonts and font sizes
 // -----------------------------------------------------------------
-void svg::_text(double x, double y, std::string text)
+svg& svg::text(double x, double y, std::string text)
 {
     document.children.push_back(new text_element(x, y, text));
+
+ return *this;
 }
 
 // -----------------------------------------------------------------
 // Hopefully this one will be filld out next week
 // -----------------------------------------------------------------
-void svg::_line_color(svg_color col)
+svg& svg::line_color(svg_color col)
+{
+ return *this;
+}
+
+svg& svg::rect(double x1, double y1, double x2, double y2)
+{
+ document.children.push_back(new rect_element(x1, y1, x2, y2));
+
+ return *this;
+}
+
+svg& svg::rect(double x1, double y1, double x2, double y2,
+ g_element& location)
 {
+ location.children.push_back(new rect_element(x1, y1, x2, y2));
 
+ return *this;
 }
 
 

Modified: sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp
==============================================================================
--- sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp (original)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_plot.hpp 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -16,8 +16,9 @@
 #include <iterator>
 #include <limits>
 
-#include "svg_plot_instruction.hpp"
 #include "svg.hpp"
+#include "svg_plot_instruction.hpp"
+
 
 #include <boost/array.hpp>
 
@@ -30,12 +31,15 @@
 // when I'm building data. It's easier to refer to:
 // document[SVG_PLOT_BACKGROUND].color()
 //
-// than it is to do it any other way I can think of.
+// than other possibilities I can think of!
+//
+// "legend" is on top because either it'll be laid on top of the graph,
+// or it'll be off to the side.
 // -----------------------------------------------------------------
 #define SVG_PLOT_DOC_CHILDREN 3
 
-enum svg_plot_doc_structure{SVG_PLOT_BACKGROUND, SVG_PLOT_LEGEND,
- SVG_PLOT_PLOT};
+enum svg_plot_doc_structure{SVG_PLOT_BACKGROUND, SVG_PLOT_PLOT,
+ SVG_PLOT_LEGEND};
 
 // -----------------------------------------------------------------
 // The following enums define the children for the legend. This will be
@@ -62,42 +66,53 @@
 {
 private:
     double transform_matrix[3][3];
-
     double x_min, x_max;
 
     //Still keep track of this for when we have a view window
     //for the graph
- double y_window_min, y_window_max;
+
+ double y_window_min, y_window_max;
+
+ double y_axis;
     
+ bool legend_on;
+ std::vector<legend_point> legend;
+
     //Don't let the user use this without specifying a stream.
     //I can't think of a reasonable default, and I don't think
     //they'd want the svg formatted output spit to the console
     svg_plot();
 
- void _x_scale(double, double);
- void _plot_image_size(unsigned int, unsigned int);
+ void _transform_point(double &x);
+ void _clear_legend();
+ void _draw_legend_header(int, int, int, int);
+ void _draw_legend();
 
- void _plot_range(std::vector<double>::const_iterator,
- std::vector<double>::const_iterator);
- void _plot_range(std::vector<double>::const_iterator,
- std::vector<double>::const_iterator,
- svg_color);
+public:
+ svg_plot(const std::string& file);
+
+ svg_plot& x_scale(double, double);
 
+ svg_plot& draw_axis();
+ svg_plot& show_legend();
+
+ svg_plot& line_color(const svg_color&);
 
- void _transform_point(double &x);
- void _draw_axis();
- void _line_color(const svg_color&);
+ svg_plot& write();
 
-public:
- using svg::operator<<;
+ svg_plot& image_size(unsigned int, unsigned int);
 
- svg_plot(const std::string& file);
- svg_plot& operator<<(const plot_single_val&);
- svg_plot& operator<<(const plot_two_vals&);
- svg_plot& operator<<(const plot_draw_range&);
- svg_plot& operator<<(const plot_draw_col_range&);
- svg_plot& operator<<(const plot_command&);
- svg_plot& operator<<(const plot_color&);
+ svg_plot& set_background_color(svg_color_constant);
+ svg_plot& set_background_color(const svg_color&);
+
+ svg_plot& set_legend_background_color(svg_color_constant);
+ svg_plot& set_legend_background_color(const svg_color&);
+
+ void plot_range(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator, std::string);
+
+ void plot_range(std::vector<double>::const_iterator,
+ std::vector<double>::const_iterator, std::string, svg_color_constant);
 };
 
 // -----------------------------------------------------------------
@@ -121,24 +136,29 @@
     }
     
     //to determine: reasonable default values
- _size(100, 100);
+ image_size(100, 100);
     
     y_window_min = 0;
     y_window_max = 100;
 
+ y_axis = (y_window_min + y_window_max) / 2.;
+
     x_min = -10;
     x_max = 10;
 
+ legend_on = false;
+
     transform_matrix[0][0] = transform_matrix[2][2] = transform_matrix[1][1] = 1;
 
     transform_matrix[0][2] = x_size * (-x_min / (x_min - x_max));
 
- //build the document tree
+ //build the document tree.. add children of the root node
     for(int i=0; i<SVG_PLOT_DOC_CHILDREN; ++i)
     {
         document.children.push_back(new g_element());
     }
 
+ //add children of the plot node
     for(int i=0; i<SVG_PLOT_DOC_PLOT_CHILDREN; ++i)
     {
         (static_cast<g_element*>
@@ -146,74 +166,19 @@
                 ->children.push_back(new g_element());
     }
     
-}
-
-// -----------------------------------------------------------------
-// The chained stream operators. Each overload below deals with a
-// different instruction type by cases.
-// -----------------------------------------------------------------
-
-svg_plot& svg_plot::operator<<(const plot_two_vals& rhs)
-{
- switch(rhs.i_type)
- {
- case PLOT_SCALE_X:
- _x_scale(rhs.x1, rhs.x2);
- break;
-
- case PLOT_SIZE:
- _plot_image_size((unsigned int)rhs.x1, (unsigned int)rhs.x2);
- break;
- }
-
- return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator <<(const plot_single_val& rhs)
-{
-/* switch(rhs.i_type)
- {
- default:
- break;
- }
-*/
- return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_command& rhs)
-{
- _draw_axis();
- return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_draw_range& rhs)
-{
- _plot_range(rhs.data.begin(), rhs.data.end());
- return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_draw_col_range& rhs)
-{
- _plot_range(rhs.data.begin(), rhs.data.end(), rhs.fill_color);
- return (svg_plot&)*this;
-}
-
-svg_plot& svg_plot::operator<<(const plot_color& rhs)
-{
- switch(rhs.i_type)
+ //add children of the legend node
+ for(int i=0; i<SVG_PLOT_DOC_LEGEND_CHILDREN; ++i)
     {
- case PLOT_LINE_COLOR:
- _line_color(rhs.col);
- break;
+ (static_cast<g_element*>
+ (&(document.children[SVG_PLOT_LEGEND])))
+ ->children.push_back(new g_element());
     }
-
- return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // Set the scale for x values
 // -----------------------------------------------------------------
-void svg_plot::_x_scale(double x1, double x2)
+svg_plot& svg_plot::x_scale(double x1, double x2)
 {
     x_min = x1;
     x_max = x2;
@@ -225,54 +190,74 @@
 
     transform_matrix[0][0] = x_size/(x2-x1);
     transform_matrix[0][2] = x_size*(-x1 / (x2 - x1));
+
+ return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // set the size of the svg image produced
 // -----------------------------------------------------------------
-void svg_plot::_plot_image_size(unsigned int x, unsigned int y)
+svg_plot& svg_plot::image_size(unsigned int x, unsigned int y)
 {
- _size(x, y);
+ svg::image_size(x, y);
     
     y_window_max = y;
 
+ y_axis = (y + y_window_min)/2.;
+
     transform_matrix[0][2] = x_size * (-x_min / (x_min - x_max) );
+
+ return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
 // Actually draw data to the plot. Default color information
 // -----------------------------------------------------------------
-void svg_plot::_plot_range(std::vector<double>::const_iterator begin,
- std::vector<double>::const_iterator end)
+void svg_plot::plot_range(std::vector<double>::const_iterator begin,
+ std::vector<double>::const_iterator end,
+ std::string _str)
 {
     double x;
 
     double i=0;
 
- double y_point = (y_window_min + y_window_max) / 2.;
-
+ g_element* g_ptr = &(document.g_tag(SVG_PLOT_PLOT).
+ g_tag(SVG_PLOT_PLOT_POINTS));
+
+ g_ptr->children.push_back(new g_element);
+
+ // this sets the current <g> element to the one that will contain
+ // the data that is being pushed back.
+ g_ptr = &(g_ptr->g_tag((int)(g_ptr->size())-1));
+
+ g_ptr->set_fill_color(black);
+
     for(std::vector<double>::const_iterator b = begin; b!=end; ++b)
     {
         x = *b;
         _transform_point(x);
- _point(x, y_point,
- document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_POINTS));
+ point(x, y_axis,
+ *g_ptr);
     }
+
+ // no matter what, we need to store information for the legend
+ // so that it's easier to deal with when when turn it on after
+ // we call this function =)
+ legend.push_back(legend_point(g_ptr->get_stroke_color(), black, _str));
 }
 
 // -----------------------------------------------------------------
 // Actually draw data to the plot. Fill color information provided
 // -----------------------------------------------------------------
-void svg_plot::_plot_range(std::vector<double>::const_iterator begin,
+void svg_plot::plot_range(std::vector<double>::const_iterator begin,
                             std::vector<double>::const_iterator end,
- svg_color _col)
+ std::string _str,
+ svg_color_constant _col)
 {
     double x;
 
     double i=0;
 
- double y_point = (y_window_min + y_window_max) / 2.;
-
     g_element* g_ptr = &(document.g_tag(SVG_PLOT_PLOT).
         g_tag(SVG_PLOT_PLOT_POINTS));
 
@@ -288,10 +273,56 @@
     {
         x = *b;
         _transform_point(x);
- _point(x, y_point,
+ point(x, y_axis,
             *g_ptr);
     }
+
+ // no matter what, we need to store information for the legend
+ // so that it's easier to deal with when when turn it on after
+ // we call this function =)
+ legend.push_back(legend_point(g_ptr->get_stroke_color(), _col, _str));
 }
+
+// -----------------------------------------------------------------
+// Sets the background color in the area of the document. Specifically,
+// done by adding a rectangle to the background that hits the edges
+// of the image
+// -----------------------------------------------------------------
+svg_plot& svg_plot::set_background_color(svg_color_constant _col)
+{
+ set_background_color(constant_to_rgb(_col));
+
+ return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::set_background_color(const svg_color& _col)
+{
+ document.g_tag(SVG_PLOT_BACKGROUND).set_fill_color(_col);
+
+ document.g_tag(SVG_PLOT_BACKGROUND)
+ .children.push_back(new rect_element(0, 0, x_size, y_size));
+
+ return (svg_plot&)*this;
+}
+
+// -----------------------------------------------------------------
+// Sets the background color in the area of the legend
+// -----------------------------------------------------------------
+svg_plot& svg_plot::set_legend_background_color(svg_color_constant _col)
+{
+ set_legend_background_color(constant_to_rgb(_col));
+
+ return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::set_legend_background_color(const svg_color& _col)
+{
+ document.g_tag(SVG_PLOT_LEGEND).g_tag(SVG_PLOT_LEGEND_BACKGROUND)
+ .set_fill_color(_col);
+
+ return (svg_plot&)*this;
+}
+
 // -----------------------------------------------------------------
 // This transforms a 1-D Cartesian point into a svg point. We don't
 // use the svg-defined coordinate transform because sizing is a harder
@@ -307,7 +338,7 @@
 // -----------------------------------------------------------------
 // TODO: Refactor
 // -----------------------------------------------------------------
-void svg_plot::_draw_axis()
+svg_plot& svg_plot::draw_axis()
 {
     // one major axis. We just need to draw a verticle line through
     // the origin for now. We will make that an option later.
@@ -323,11 +354,11 @@
     double y_mean = (y_window_min + y_window_max)/2.;
     double x_mean = (x1 + x2)/2.;
 
- _line(x1, y_mean, x2, y_mean,
+ line(x1, y_mean, x2, y_mean,
         document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
 
     //origin
- _line(x_mean, y_window_min, x_mean, y_window_max,
+ line(x_mean, y_window_min, x_mean, y_window_max,
         document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
 
     y1 = y2 = 0;
@@ -344,7 +375,7 @@
         _transform_point(x1);
         _transform_point(x2);
 
- _line(x1, y1, x1, y2,
+ line(x1, y1, x1, y2,
             document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
     }
 
@@ -357,9 +388,18 @@
 
         _transform_point(x1);
 
- _line(x1, y1, x1, y2,
+ line(x1, y1, x1, y2,
             document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS));
     }
+
+ return (svg_plot&)*this;
+}
+
+svg_plot& svg_plot::show_legend()
+{
+ legend_on = true;
+
+ return (svg_plot&)*this;
 }
 
 // -----------------------------------------------------------------
@@ -368,10 +408,138 @@
 // by removing the default for <g> in the constructor (ran out of
 // time this week)
 // -----------------------------------------------------------------
-void svg_plot::_line_color(const svg_color& _col)
+svg_plot& svg_plot::line_color(const svg_color& _col)
 {
     document.g_tag(SVG_PLOT_PLOT).g_tag(SVG_PLOT_PLOT_AXIS)
         .set_stroke_color(_col);
+
+ return (svg_plot&)*this;
+}
+
+// -----------------------------------------------------------------
+// When writing to multiple documents, the contents of the plot
+// may change significantly between. Rather than figuring out what
+// has and has not changed, just erase the contents of the legend
+// in the document and start over.
+// -----------------------------------------------------------------
+void svg_plot::_clear_legend()
+{
+ g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+ .g_tag(SVG_PLOT_LEGEND_POINTS));
+
+ g_ptr->children.erase(g_ptr->children.begin(), g_ptr->children.end());
+
+ g_ptr = &(document.g_tag(SVG_PLOT_LEGEND).g_tag(SVG_PLOT_LEGEND_TEXT));
+ g_ptr->children.erase(g_ptr->children.begin(), g_ptr->children.end());
+}
+
+// -----------------------------------------------------------------
+// Factored out to make _draw_legend() cleaner
+// -----------------------------------------------------------------
+void svg_plot::_draw_legend_header(int _x, int _y, int _width, int _height)
+{
+ g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+ .g_tag(SVG_PLOT_LEGEND_TEXT));
+
+ text_element legend_header(_x+(_width/2), _y + 20, "Legend");
+
+ legend_header.set_alignment(center_align);
+
+ g_ptr->children.push_back(new text_element(legend_header));
+}
+
+// -----------------------------------------------------------------
+// Important note: there are a lot of magic numbers that are temporary
+// fill-ins for the time when the legend system is more configurable.
+// This will happen bit-by-bit, as I give the user options to change
+// these values
+// -----------------------------------------------------------------
+void svg_plot::_draw_legend()
+{
+ _clear_legend();
+
+ int num_points = (int)(legend.size());
+
+ int legend_width(200);
+ int legend_height(25);
+
+ // Figure out how wide the legend should be
+ if(x_size < 200)
+ {
+ legend_width = x_size;
+ }
+
+ int legend_x_start(x_size-legend_width-20);
+ int legend_y_start(40);
+
+ // legend_height = title_spacing + (space per element)(num_elements)
+ // + (end spacing)
+ legend_height = 25 + (25 * num_points) + 10;
+
+ // TODO: Figure out how tall the legend should be
+
+ g_element* g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+ .g_tag(SVG_PLOT_LEGEND_BACKGROUND));
+
+ g_ptr->children.push_back(new rect_element(legend_x_start, legend_y_start,
+ legend_width, legend_height));
+
+ _draw_legend_header(legend_x_start, legend_y_start, legend_width, legend_height);
+
+ g_ptr = &(document.g_tag(SVG_PLOT_LEGEND)
+ .g_tag(SVG_PLOT_LEGEND_POINTS));
+
+ g_element* g_inner_ptr;
+ int i=0;
+
+ for(std::vector<legend_point>::iterator iter = legend.begin();
+ iter!=legend.end(); ++iter, ++i)
+ {
+ g_ptr -> children.push_back( new g_element() );
+ g_inner_ptr = &(g_ptr->g_tag((int)(g_ptr->children.size())-1));
+
+ g_inner_ptr->set_fill_color((*iter).fill_color);
+ g_inner_ptr->set_stroke_color((*iter).stroke_color);
+
+ g_inner_ptr->children.push_back(new point_element(legend_x_start + 25,
+ legend_y_start + 36 + i*25));
+
+ g_inner_ptr->children.push_back(new text_element(legend_x_start + 40,
+ legend_y_start + 42 + i*25, (*iter).text));
+ }
+}
+
+svg_plot& svg_plot::write()
+{
+ // Hold off drawing the legend until the very end.. it's
+ // easier to draw the size that it needs at the end than
+ // it is to
+ // Don't bother with re-adding things if we don't need to
+ if(legend_on)
+ {
+ _draw_legend();
+ }
+
+ svg::write();
+
+ return (svg_plot&)*this;
+}
+
+template <class iter>
+void plot_range(svg_plot& _cont, iter _begin, iter _end, std::string _str)
+{
+ vector<double> vect(_begin, _end);
+
+ _cont.plot_range(vect.begin(), vect.end(), _str);
+}
+
+template <class iter>
+void plot_range(svg_plot& _cont, iter _begin, iter _end, std::string _str,
+ svg_color_constant _col)
+{
+ vector<double> vect(_begin, _end);
+
+ _cont.plot_range(vect.begin(), vect.end(), _str, _col);
 }
 
 }

Added: sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/SOC/2007/visualization/boost/svg_plot/svg_test.cpp 2007-06-17 22:48:14 EDT (Sun, 17 Jun 2007)
@@ -0,0 +1,53 @@
+#include <vector>
+#include <deque>
+#include <cmath>
+
+#include "svg_plot.hpp"
+
+using namespace boost::svg;
+using namespace std;
+
+double f(double x)
+{
+ return (x*x)/2.;
+}
+
+double g(double x)
+{
+ return -2 + x;
+}
+
+int main()
+{
+ double start = 0, finish = 10;
+
+ vector<double> data1;
+ deque<double> data2;
+
+
+ double inter = 3.1415926535 / 4.;
+
+ for(double i = start; i <= finish; i += inter)
+ data1.push_back(f(i));
+
+ for(double i=start; i <= finish; i += inter)
+ data2.push_back(g(i));
+
+ svg_plot my_plot("D:\\1D_legend_demo.svg");
+
+ my_plot.image_size(500, 350).x_scale(-2, 10);
+
+ my_plot.draw_axis().show_legend();
+
+ my_plot.set_background_color(lightgray)
+ .set_legend_background_color(whitesmoke);
+
+
+ plot_range(my_plot, data2.begin(), data2.end(), "Lions", blue);
+ plot_range(my_plot, data1.begin(), data1.end(), "Tigers", limegreen);
+
+ my_plot.write();
+
+ return 0;
+}
+


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