3 * Psychlops Standard Library (Universal)
5 * Last Modified 2009/05/20 by Kenchi HOSOKAWA
6 * (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
9 #include "psychlops_g_SVG.h"
10 #include "../../../core/graphic/psychlops_g_shape.h"
11 #include "../../../core/graphic/psychlops_g_font.h"
12 #include "../../../core/devices/psychlops_io_file.h"
22 const char* strokeStyleSVG[3] = { "", "5 5", "1 1" };
23 const char* strokeStyleToSVG(const Stroke &strk) {
24 switch(strk.pattern) {
26 return strokeStyleSVG[1];
28 return strokeStyleSVG[2];
31 return strokeStyleSVG[0];
35 SVGCanvas::SVGCanvas(double width_, double height_) : width(width_), height(height_) {
36 prime_backup = Drawable::prime;
37 Drawable::prime = this;
39 SVGCanvas::~SVGCanvas() {
40 Drawable::prime = prime_backup;
42 SVGCanvas& SVGCanvas::save(std::string filename) {
44 std::string filenamechacker = File::decodePath(filename);
45 std::ofstream outport;
46 outport.open(filenamechacker.c_str());
47 outport << "<?xml version=\"1.0\" standalone=\"no\"?>" << std::endl <<
48 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" << std::endl <<
50 sprintf(buf, " width=\"%gpx\" height=\"%gpx\"", width, height);
52 outport << " xmlns=\"http://www.w3.org/2000/svg\"> " << std::endl;
58 int SVGCanvas::getWidth() const {
59 return (int)ceil(width);
61 int SVGCanvas::getHeight() const {
62 return (int)ceil(height);
64 const Point SVGCanvas::getCenter() const {
65 Point po(width/2.0, height/2.0);
69 SVGCanvas& SVGCanvas::clear(const Color &col) {
74 SVGCanvas& SVGCanvas::pix(const double x, const double y, const Color &col) {
77 sprintf(buffer, "<rect x1=\"%gpx\" y1=\"%gpx\" x2=\"%gpx\" y2=\"%gpx\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" />"
78 , x-.5, y-.5, x+.5, y+.5
79 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
80 output.append(buffer);
84 SVGCanvas& SVGCanvas::line(const Line &drawee, const Color &col) {
87 sprintf(buffer, "<line x1=\"%gpx\" y1=\"%gpx\" x2=\"%gpx\" y2=\"%gpx\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" />"
88 , drawee.datum.x, drawee.datum.y, drawee.getEnd().x, drawee.getEnd().y
89 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
90 output.append(buffer);
93 SVGCanvas& SVGCanvas::line(const Line &drawee, const Stroke &strk) {
95 strk.color.get(r,g,b,a);
96 sprintf(buffer, "line x1=\"%gpx\" y1=\"%gpx\" x2=\"%gpx\" y2=\"%gpx\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-width=\"%g\" stroke-dasharray=\"%s\" />"
97 , drawee.datum.x, drawee.datum.y, drawee.getEnd().x, drawee.getEnd().y
98 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a
99 , strk.width, strokeStyleToSVG(strk));
100 output.append(buffer);
103 SVGCanvas& SVGCanvas::rect(const Rectangle &drawee, const Color &col) {
106 sprintf(buffer, "<rect x=\"%gpx\" y=\"%gpx\" width=\"%gpx\" height=\"%gpx\" fill=\"#%02x%02x%02x\" opacity=\"%g\" />"
107 , drawee.getLeft(), drawee.getTop(), drawee.getWidth(), drawee.getHeight()
108 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
109 output.append(buffer);
112 SVGCanvas& SVGCanvas::rect(const Rectangle &drawee, const Stroke &strk) {
114 strk.color.get(r,g,b,a);
115 sprintf(buffer, "<rect x=\"%gpx\" y=\"%gpx\" width=\"%gpx\" height=\"%gpx\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-width=\"%g\" stroke-dasharray=\"%s\" />"
116 , drawee.getLeft(), drawee.getTop(), drawee.getWidth(), drawee.getHeight()
117 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a
118 , strk.width, strokeStyleToSVG(strk));
119 output.append(buffer);
122 SVGCanvas& SVGCanvas::ellipse(const Ellipse &drawee, const Color &col) {
125 sprintf(buffer, "<ellipse cx=\"%gpx\" cy=\"%gpx\" rx=\"%gpx\" ry=\"%gpx\" fill=\"#%02x%02x%02x\" opacity=\"%g\" />"
126 , drawee.datum.x, drawee.datum.y, drawee.radius, drawee.v_radius
127 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
128 output.append(buffer);
131 SVGCanvas& SVGCanvas::ellipse(const Ellipse &drawee, const Stroke &strk) {
133 strk.color.get(r,g,b,a);
134 sprintf(buffer, "<ellipse cx=\"%gpx\" cy=\"%gpx\" rx=\"%gpx\" ry=\"%gpx\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-width=\"%g\" stroke-dasharray=\"%s\" />"
135 , drawee.datum.x, drawee.datum.y, drawee.radius, drawee.v_radius
136 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a
137 , strk.width, strokeStyleToSVG(strk));
138 output.append(buffer);
141 SVGCanvas& SVGCanvas::polygon(const Polygon &drawee) {
142 return polygon(drawee, drawee.stroke);
144 SVGCanvas& SVGCanvas::polygon(const Polygon &drawee, const Color &col) {
147 output.append("<polygon points=\"");
148 for(std::deque<Point>::const_iterator v=drawee.vertices.begin(); v!=drawee.vertices.end(); v++) {
149 sprintf(buffer, "%gpx,%gpx ", (*v).x, (*v).y);
150 output.append(buffer);
152 sprintf(buffer, "\" fill=\"#%02x%02x%02x\" opacity=\"%g\" />"
153 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
154 output.append(buffer);
157 SVGCanvas& SVGCanvas::polygon(const Polygon &drawee, const Stroke &strk) {
159 strk.color.get(r,g,b,a);
160 output.append("<polygon points=\"");
161 for(std::deque<Point>::const_iterator v=drawee.vertices.begin(); v!=drawee.vertices.end(); v++) {
162 sprintf(buffer, "%gpx,%gpx ", (*v).x, (*v).y);
163 output.append(buffer);
165 sprintf(buffer, "\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-width=\"%g\" stroke-dasharray=\"%s\" />"
166 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a
167 , strk.width, strokeStyleToSVG(strk));
168 output.append(buffer);
171 SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee) {
172 return polyline(drawee, Color::black);
174 SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee, const Color &col) {
175 Stroke strk(col, 1, Stroke::SOLID);
176 return polyline(drawee, strk);
178 SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee, const Stroke &strk) {
180 strk.color.get(r,g,b,a);
181 output.append("<polyline points=\"");
182 for(std::deque<Point>::const_iterator v=drawee.vertices.begin(); v!=drawee.vertices.end(); v++) {
183 sprintf(buffer, "%gpx,%gpx ", (*v).x, (*v).y);
184 output.append(buffer);
186 sprintf(buffer, "\" stroke=\"#%02x%02x%02x\" stroke-opacity=\"%g\" stroke-width=\"%g\" stroke-dasharray=\"%s\" />"
187 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a
188 , strk.width, strokeStyleToSVG(strk));
189 output.append(buffer);
192 SVGCanvas& SVGCanvas::figures(const Group &drawee) {
193 output.append("<g transform=\"");
194 sprintf(buffer, "%g, %g", drawee.datum.x, drawee.datum.y);
195 output.append(" translate(").append(buffer).append(")");
196 if(drawee.scaling.x!=0.0 || drawee.scaling.y!=0.0 || drawee.scaling.z!=0.0) {
197 sprintf(buffer, "%g, %g", drawee.scaling.x, drawee.scaling.y);
198 output.append(" scale(").append(buffer).append(")");
200 if(drawee.rotation!=0.0) {
201 sprintf(buffer, "%g, %g, %g", drawee.rotation, drawee.datum.x, drawee.datum.y);
202 output.append(" rotate(").append(buffer).append(")");
204 output.append("\">");
205 if(!drawee.contents.empty()) {
206 for(int i=0; i<drawee.contents.size(); i++) {
207 drawee.contents[i]->draw(*this);
210 output.append("</g>");
214 SVGCanvas& SVGCanvas::image(const Image &img) {
217 SVGCanvas& SVGCanvas::image(const Image &img, const double x, const double y) {
220 SVGCanvas& SVGCanvas::image(const Image &img, const double alpha) {
224 const char* SVG_TEXT_ANCHOR[4] = { "start", "start", "middle", "end" };
225 const char* SVG_FONT_STYLE[3] = { "normal", "italic", "oblique" };
226 const char* SVG_TEXT_DECORATION[4] = { "none", "underline", "overline", "line-through" };
227 SVGCanvas& SVGCanvas::letters(Letters &let, const Color &col) {
230 Font font = let.getFont();
231 output.append("<text x=\"");
232 sprintf(buffer, "%gpx\", y=\"%g\" text-anchor=\"%s\" "
233 , let.getDatum().x, let.getDatum().y, SVG_TEXT_ANCHOR[let.align+1]);
234 output.append(buffer);
235 sprintf(buffer, "font-size=\"%gpx\" font-weight=\"%d\" font-style=\"%s\" font-family=\"%s\" />"
236 , font.size, font.weight, SVG_FONT_STYLE[font.style], font.family[0].c_str());
237 output.append(buffer);
238 sprintf(buffer, "fill=\"#%02x%02x%02x\" opacity=\"%g\" />"
239 , (unsigned char)(r*255), (unsigned char)(g*255), (unsigned char)(b*255), a);
240 output.append(buffer);
242 output.append("</text>");
246 } /* <- namespace Psycholops */