00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "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";
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;
00187
00188
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;
00196 (void)type;
00197 (void)name;
00198
00199
00200
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;
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;
00219
00220 }
00221
00222 void
00223 marosvg::begin_children(int num_children)
00224 {
00225 (void)num_children;
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 }