Marsyas  0.6.0-alpha
/usr/src/RPM/BUILD/marsyas-0.6.0/src/marsyas/marosvg.cpp
Go to the documentation of this file.
00001 /*
00002 ** Copyright (C) 1998-2011 George Tzanetakis <gtzan@cs.uvic.ca>
00003 **
00004 ** This program is free software; you can redistribute it and/or modify
00005 ** it under the terms of the GNU General Public License as published by
00006 ** the Free Software Foundation; either version 2 of the License, or
00007 ** (at your option) any later version.
00008 **
00009 ** This program is distributed in the hope that it will be useful,
00010 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 ** GNU General Public License for more details.
00013 **
00014 ** You should have received a copy of the GNU General Public License
00015 ** along with this program; if not, write to the Free Software
00016 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 
00020 #include <marsyas/marosvg.h>
00021 #include <sstream>
00022 #include <iostream>
00023 
00024 using namespace std;
00025 using namespace Marsyas;
00026 
00027 marosvg::SVGObj_::SVGObj_(SVGObj_* p, std::string t, std::string n)
00028 {
00029   parent_=p; t=t; n_=n;
00030   if(parent_!=NULL) {
00031     parent_->addChild(this);
00032   }
00033 }
00034 marosvg::SVGObj_::~SVGObj_()
00035 {
00036   while(children_.size()>0) {
00037     SVGObj_* c = children_.back();
00038     children_.pop_back();
00039     delete c;
00040   }
00041 }
00042 void
00043 marosvg::SVGObj_::addChild(SVGObj_* c)
00044 {
00045   if(c!=NULL)
00046     children_.push_back(c);
00047 }
00048 
00049 void
00050 marosvg::SVGObj_::sizeAdj()
00051 {
00052   if (children_.size()>0) {
00053     if(t=="Series") {
00054       int max_height=0;
00055       int w=0;
00056 
00057       for(int i=0; i < (int)children_.size(); ++i) {
00058         SVGObj_* s=children_[i];
00059         s->sizeAdj();
00060 
00061         if (s->h_>max_height)
00062           max_height = s->h_;
00063         w = w + 20 + s->w_;
00064       }
00065       h_ = max_height + 20 + 20;
00066       w_ = w + 20;
00067     }
00068     else if (t=="Fanout" || t=="Parallel") {
00069       int max_width=0;
00070       int h=0;
00071 
00072       for(int i=0; i < (int)children_.size(); ++i) {
00073         SVGObj_* s=children_[i];
00074         s->sizeAdj();
00075 
00076         h = h + 20 + s->h_;
00077         if (s->w_ > max_width)
00078           max_width = s->w_;
00079       }
00080       h_ = h + 20;
00081       w_ = max_width + 20 + 20;
00082     }
00083   }
00084   else {
00085     h_=40;
00086     w_=100;
00087   }
00088 }
00089 
00090 void
00091 marosvg::SVGObj_::posAdj(int x, int y)
00092 {
00093   x_=x; y_=y;
00094   int midY = (h_ >> 1) + y;
00095   x+=20;
00096   if (children_.size()>0) {
00097     if (t=="Series") {
00098       for(int i=0; i < (int)children_.size(); ++i) {
00099         SVGObj_* s=children_[i];
00100         int sy = midY - (s->h_ >> 1);
00101         s->posAdj(x,sy);
00102         x = x + s->w_ + 20;
00103       }
00104     }
00105     else if (t=="Fanout" || t=="Parallel") {
00106       y += 20;
00107       for(int i=0; i < (int)children_.size(); ++i) {
00108         SVGObj_* s=children_[i];
00109         s->posAdj(x,y);
00110         y = y + s->h_ + 20;
00111       }
00112     }
00113   }
00114 }
00115 
00116 std::string
00117 marosvg::SVGObj_::str()
00118 {
00119   bool fanout=(t=="Fanout");
00120   bool parallel=(t=="Parallel");
00121   bool series=(t=="Series");
00122   std::ostringstream op;
00123   op << "<rect ";
00124   if (fanout) { op << "class=\"fanout\" "; }
00125   else if (parallel) { op << "class=\"parallel\" "; }
00126   else if (series) { op << "class=\"series\" "; }
00127   op << "x=\"" << x_
00128      << "\" y=\"" << y_
00129      << "\" width=\"" << w_
00130      << "\" height=\"" << h_
00131      << "\" />\n";//style=\"fill:rgb(230,230,255);stroke-width:1; stroke:rgb(0,0,0)\"/>\n";
00132 
00133   op << "<text class=\"marsysid\" x=\"" << (x_+5) << "\" y=\"" << (y_+15) << "\">" << t << "/" << n_ << "</text>\n";
00134 
00135   int my = y_ + (h_ >> 1);
00136   if (series) {
00137     op << "<line class=\"wire\" x1=\"" << x_
00138        << "\" y1=\"" << my
00139        << "\" x2=\"" << (x_+w_)
00140        << "\" y2=\"" << my
00141        << "\" />\n";
00142   }
00143 
00144   for(int i=0; i < (int)children_.size(); ++i) {
00145     SVGObj_* c = children_[i];
00146     int cmy = c->y_ + (c->h_ >> 1);
00147     if(fanout) {
00148       op << "<line class=\"wire\" x1=\"" << x_
00149          << "\" y1=\"" << my
00150          << "\" x2=\"" << c->x_
00151          << "\" y2=\"" << cmy
00152          << "\" />";
00153 
00154       op << "<line class=\"wire\" x1=\"" << c->x_
00155          << "\" y1=\"" << cmy
00156          << "\" x2=\"" << (x_+w_)
00157          << "\" y2=\"" << cmy
00158          << "\" />\n";
00159     }
00160     else if (parallel) {
00161       op << "<line class=\"wire\" x1=\"" << x_
00162          << "\" y1=\"" << cmy
00163          << "\" x2=\"" << (x_+w_)
00164          << "\" y2=\"" << cmy
00165          << "\" />\n";
00166     }
00167     op << c->str();
00168   }
00169   return op.str();
00170 }
00171 
00172 marosvg::marosvg() : marostring()
00173 {
00174   curr_=NULL;
00175   load_properties();
00176 }
00177 
00178 marosvg::~marosvg()
00179 {
00180   clear();
00181 }
00182 
00183 void
00184 marosvg::begin_marsystem(bool isComposite, std::string type, std::string name)
00185 {
00186   (void)isComposite;  // avoid unused parameter warning
00187 
00188   // make this node the root of the tree for recursive marsystem creation
00189   curr_ = new SVGObj_(curr_,type,name);
00190 }
00191 
00192 void
00193 marosvg::end_marsystem(bool isComposite, std::string type, std::string name)
00194 {
00195   (void)isComposite;  // avoid warnings about unused parameters
00196   (void)type;
00197   (void)name;
00198 
00199   //"<rect x=\"50\" y=\"50\" width=\"300\" height=\"100\" style=\"fill:rgb(0,0,255);stroke-width:1; stroke:rgb(0,0,0)\"/>"
00200   // return parent to the root of the tree
00201   if(curr_!=NULL && curr_->parent_!=NULL)
00202     curr_=curr_->parent_;
00203 }
00204 
00205 void
00206 marosvg::begin_control(std::string type, std::string name, std::string value, bool has_state)
00207 {
00208   (void)type; // avoid unused parameter warning
00209   (void)name;
00210   (void)value;
00211   (void)has_state;
00212 
00213 }
00214 
00215 void
00216 marosvg::begin_controls(int num_controls)
00217 {
00218   (void)num_controls;  // avoid unused parameter warning
00219 
00220 }
00221 
00222 void
00223 marosvg::begin_children(int num_children)
00224 {
00225   (void)num_children;  // avoid unused parameter warning
00226 }
00227 
00228 void
00229 marosvg::load_properties()
00230 {
00231   style_["marsystem"]["fill"] = "rgb(196,196,196)";
00232   style_["marsystem"]["stroke"] = "black";
00233   style_["marsystem"]["stroke-width"] = "1";
00234 
00235   style_["series"]["fill"] = "rgb(255,196,196)";
00236 
00237   style_["parallel"]["fill"] = "rgb(196,255,196)";
00238 
00239   style_["fanout"]["fill"] = "rgb(196,196,255)";
00240 
00241   style_["wire"]["stroke-width"] = "1";
00242   style_["wire"]["stroke"] = "black";
00243 
00244   style_["marsysid"]["stroke"] = "black";
00245 }
00246 
00247 void
00248 marosvg::style(std::string obj, std::string property, std::string value)
00249 {
00250   style_[obj][property] = value;
00251 }
00252 
00253 void
00254 marosvg::output_properties(std::string property)
00255 {
00256   std::map<std::string,std::string> prop = style_[property];
00257   std::map<std::string,std::string>::iterator iter;
00258 
00259   for (iter = prop.begin(); iter != prop.end(); ++iter ) {
00260     result_ << iter->first << ':' << iter->second << ';';
00261   }
00262 }
00263 std::string
00264 marosvg::str()
00265 {
00266   if (curr_!=NULL) {
00267     curr_->sizeAdj();
00268     curr_->posAdj(0,0);
00269 
00270     int ww = curr_->w_;
00271     int hh = curr_->h_;
00272     std::map<std::string,std::string>::iterator iter;
00273 
00274     result_ << "<?xml version=\"1.0\"?>\n"
00275             << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"
00276             << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\"  width=\""<<ww<<"\" height=\""<<hh<<"\">\n"
00277 
00278             << "<style>\n";
00279 
00280     result_ << "  line.wire{"; output_properties("wire"); result_ << "}\n";
00281 
00282     result_ << "  rect{"; output_properties("marsystem"); result_ << "}\n";
00283 
00284     result_ << "  rect.series{"; output_properties("series"); result_ << "}\n";
00285 
00286     result_ << "  rect.parallel{"; output_properties("parallel"); result_ << "}\n";
00287 
00288     result_ << "  rect.fanout{"; output_properties("fanout"); result_ << "}\n";
00289 
00290     result_ << "  text.marsysid{"; output_properties("marsysid"); result_ << "}\n";
00291     result_ << "</style>\n";
00292 
00293     result_ << curr_->str();
00294     result_ << "\n</svg>\n";
00295     return result_.str();
00296   }
00297   return "";
00298 }
00299 
00300 void
00301 marosvg::clear()
00302 {
00303   marostring::clear();
00304   if (curr_!=NULL) {
00305     delete curr_;
00306     curr_=NULL;
00307   }
00308 }