Marsyas
0.6.0-alpha
|
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 }