bpp-core3  3.0.0
SvgGraphicDevice.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "SvgGraphicDevice.h"
6 
7 using namespace bpp;
8 using namespace std;
9 
11 {
12  layers_.clear();
13  minx_ = maxx_ = miny_ = maxy_ = 0;
14 }
15 
17 {
18  // Header:
19  out_ << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" << endl;
20  out_ << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD Svg 1.1//EN\"" << endl;
21  out_ << "\"http://www.w3.org/Graphics/Svg/1.1/DTD/svg11.dtd\">" << endl;
22  out_ << "<svg width=\"" << (maxx_ - minx_) << "\" height=\"" << (maxy_ - miny_) << "\" version=\"1.1\"" << endl;
23  out_ << " xmlns=\"http://www.w3.org/2000/svg\"" << endl;
24  if (inkscapeEnabled_)
25  out_ << " xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"";
26  out_ << " >" << endl;
27 
28  out_ << "<g transform=\"translate(" << (-minx_) << "," << (-miny_) << ")\">" << endl;
29 
30  for (map<int, vector<string>>::iterator it = layers_.begin(); it != layers_.end(); it++)
31  {
32  out_ << "<g id=\"layer" << it->first << "\"";
33  if (inkscapeEnabled_)
34  {
35  out_ << " inkscape:groupmode=\"layer\"";
36  }
37  out_ << " >" << endl;
38  vector<string>* v = &it->second;
39  for (unsigned int i = 0; i < v->size(); i++)
40  {
41  out_ << (*v)[i] << endl;
42  }
43  out_ << "</g>" << endl;
44  }
45  out_ << "</g>" << endl;
46 
47  out_ << "</svg>" << endl;
48 }
49 
50 void SvgGraphicDevice::drawLine(double x1, double y1, double x2, double y2)
51 {
52  x1 = x_(x1);
53  x2 = x_(x2);
54  y1 = y_(y1);
55  y2 = y_(y2);
56  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
57  if (getCurrentLineType() == LINE_DASHED)
58  style += ";stroke-dasharray:4,4";
59  else if (getCurrentLineType() == LINE_DOTTED)
60  style += ";stroke-dasharray:1,2";
61  ostringstream oss;
62  oss << "<line x1=\"" << x1 << "\" y1=\"" << y1 << "\" x2=\"" << x2 << "\" y2=\"" << y2 << "\" style=\"" << style << "\" />";
63  layers_[getCurrentLayer()].push_back(oss.str());
64  if (x1 < minx_)
65  minx_ = x1;
66  if (x2 < minx_)
67  minx_ = x2;
68  if (y1 < miny_)
69  miny_ = y1;
70  if (y2 < miny_)
71  miny_ = y2;
72  if (x1 > maxx_)
73  maxx_ = x1;
74  if (x2 > maxx_)
75  maxx_ = x2;
76  if (y1 > maxy_)
77  maxy_ = y1;
78  if (y2 > maxy_)
79  maxy_ = y2;
80 }
81 
82 void SvgGraphicDevice::drawRect(double x, double y, double width, double height, short fill)
83 {
84  x = x_(x);
85  y = y_(y);
86  width = x_(width);
87  height = y_(height);
88  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
89  if (fill == FILL_FILLED)
90  {
91  style += ";fill:" + colorToText(getCurrentBackgroundColor());
92  }
93  ostringstream oss;
94  oss << "<rect x=\"" << x << "\" y=\"" << y << "\" width=\"" << width << "\" height=\"" << height << "\" style=\"" << style << "\" />";
95  layers_[getCurrentLayer()].push_back(oss.str());
96  if (x < minx_)
97  minx_ = x;
98  if (y < miny_)
99  miny_ = y;
100  if (x + width > maxx_)
101  maxx_ = x + width;
102  if (y + height > maxy_)
103  maxx_ = y + height;
104 }
105 
106 void SvgGraphicDevice::drawCircle(double x, double y, double radius, short fill)
107 {
108  x = x_(x);
109  y = y_(y);
110  radius = x_(radius);
111  string style = "stroke:" + colorToText(getCurrentForegroundColor()) + ";stroke-width:" + TextTools::toString(getCurrentPointSize());
112  if (fill == FILL_FILLED)
113  {
114  style += ";fill:" + colorToText(getCurrentBackgroundColor());
115  }
116  ostringstream oss;
117  oss << "<rect cx=\"" << x << "\" cy=\"" << y << "\" cr=\"" << radius << "\" style=\"" << style << "\" />";
118  layers_[getCurrentLayer()].push_back(oss.str());
119 }
120 
121 void SvgGraphicDevice::drawText(double x, double y, const std::string& text, short hpos, short vpos, double angle)
122 {
123  x = x_(x);
124  y = y_(y);
125  string style = "font-family:" + getCurrentFont().getFamily() + ";font-style:" + fontStyles_[getCurrentFont().getStyle()] + ";font-weight:" + fontWeights_[getCurrentFont().getWeight()] + ";font-size:" + TextTools::toString(getCurrentFont().getSize()) + "px";
126  style += ";dominant-baseline:";
127  if (vpos == TEXT_VERTICAL_BOTTOM)
128  style += "before-edge";
129  else if (vpos == TEXT_VERTICAL_TOP)
130  style += "after-edge";
131  else if (vpos == TEXT_VERTICAL_CENTER)
132  style += "middle";
133  else
134  throw UnvalidFlagException("SvgGraphicDevice::drawText. Invalid vertical alignment option.");
135  style += ";text-anchor:";
136  if (hpos == TEXT_HORIZONTAL_LEFT)
137  style += "start";
138  else if (hpos == TEXT_HORIZONTAL_RIGHT)
139  style += "end";
140  else if (hpos == TEXT_HORIZONTAL_CENTER)
141  style += "middle";
142  else
143  throw UnvalidFlagException("SvgGraphicDevice::drawText. Invalid horizontal alignment option.");
144  style += ";fill:" + colorToText(getCurrentForegroundColor());
145 
146  ostringstream oss;
147  oss << "<text x=\"" << x << "\" y=\"" << y << "\" rotate=\"" << angle << "\" style=\"" << style << "\" >" << text << "</text>";
148  layers_[getCurrentLayer()].push_back(oss.str());
149 }
void drawCircle(double x, double y, double radius, short fill=FILL_EMPTY)
Draw a circle.
void begin()
Start the painting.
void drawRect(double x, double y, double width, double height, short fill=FILL_EMPTY)
Draw a rectangle.
void drawLine(double x1, double y1, double x2, double y2)
Draw a line between two points.
STL namespace.
void end()
End the painting.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
void drawText(double x, double y, const std::string &text, short hpos=TEXT_HORIZONTAL_LEFT, short vpos=TEXT_VERTICAL_BOTTOM, double angle=0)
Draw some characters.