OSDN Git Service

first
[psychlops/cpp.git] / psychlops / extension / prototype / graphic / psychlops_g_SVG.cpp
1 /*
2  *  psychlops_g_SVG.h
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2009/05/20 by Kenchi HOSOKAWA
6  *  (C) 2009 Kenchi HOSOKAWA, Kazushi MARUYA, Takao SATO
7  */
8
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"
13 #include <stdio.h>
14 #include <math.h>
15 #include <vector>
16 #include <fstream>
17 #include <iostream>
18
19 namespace Psychlops {
20
21
22         const char* strokeStyleSVG[3] = { "", "5 5", "1 1" };
23         const char* strokeStyleToSVG(const Stroke &strk) {
24                 switch(strk.pattern) {
25                         case Stroke::DASHED:
26                                 return strokeStyleSVG[1];
27                         case Stroke::DOTTED:
28                                 return strokeStyleSVG[2];
29                         case Stroke::SOLID:
30                         default:
31                                 return strokeStyleSVG[0];
32                 }
33         }
34
35         SVGCanvas::SVGCanvas(double width_, double height_) : width(width_), height(height_) {
36                 prime_backup = Drawable::prime;
37                 Drawable::prime = this;
38         }
39         SVGCanvas::~SVGCanvas() {
40                 Drawable::prime = prime_backup;
41         }
42         SVGCanvas& SVGCanvas::save(std::string filename) {
43                 char buf[32];
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 <<
49                 "<svg";
50                 sprintf(buf, " width=\"%gpx\" height=\"%gpx\"", width, height);
51                 outport << buf;
52                 outport << " xmlns=\"http://www.w3.org/2000/svg\"> " << std::endl;
53                 outport << output;
54                 outport << "</svg>";
55                 outport.close();
56                 return *this;
57         }
58         int SVGCanvas::getWidth() const {
59                 return (int)ceil(width);
60         }
61         int SVGCanvas::getHeight() const {
62                 return (int)ceil(height);
63         }
64         const Point SVGCanvas::getCenter() const {
65                 Point po(width/2.0, height/2.0);
66                 return po;
67         }
68
69         SVGCanvas& SVGCanvas::clear(const Color &col) {
70                 output.clear();
71                 return *this;
72         }
73
74         SVGCanvas& SVGCanvas::pix(const double x, const double y, const Color &col) {
75                 double r, g, b, a;
76                 col.get(r,g,b,a);
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);
81                 return *this;
82         }
83
84         SVGCanvas& SVGCanvas::line(const Line &drawee, const Color &col) {
85                 double r, g, b, a;
86                 col.get(r,g,b,a);
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);
91                 return *this;
92         }
93         SVGCanvas& SVGCanvas::line(const Line &drawee, const Stroke &strk) {
94                 double r, g, b, a;
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);
101                 return *this;
102         }
103         SVGCanvas& SVGCanvas::rect(const Rectangle &drawee, const Color &col) {
104                 double r, g, b, a;
105                 col.get(r,g,b,a);
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);
110                 return *this;
111         }
112         SVGCanvas& SVGCanvas::rect(const Rectangle &drawee, const Stroke &strk) {
113                 double r, g, b, a;
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);
120                 return *this;
121         }
122         SVGCanvas& SVGCanvas::ellipse(const Ellipse &drawee, const Color &col) {
123                 double r, g, b, a;
124                 col.get(r,g,b,a);
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);
129                 return *this;
130         }
131         SVGCanvas& SVGCanvas::ellipse(const Ellipse &drawee, const Stroke &strk) {
132                 double r, g, b, a;
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);
139                 return *this;
140         }
141         SVGCanvas& SVGCanvas::polygon(const Polygon &drawee) {
142                 return polygon(drawee, drawee.stroke);
143         }
144         SVGCanvas& SVGCanvas::polygon(const Polygon &drawee, const Color &col) {
145                 double r, g, b, a;
146                 col.get(r,g,b,a);
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);
151                 }
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);
155                 return *this;
156         }
157         SVGCanvas& SVGCanvas::polygon(const Polygon &drawee, const Stroke &strk) {
158                 double r, g, b, a;
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);
164                 }
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);
169                 return *this;
170         }
171         SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee) {
172                 return polyline(drawee, Color::black);
173         }
174         SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee, const Color &col) {
175                 Stroke strk(col, 1, Stroke::SOLID);
176                 return polyline(drawee, strk);
177         }
178         SVGCanvas& SVGCanvas::polyline(const PolyLine &drawee, const Stroke &strk) {
179                 double r, g, b, a;
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);
185                 }
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);
190                 return *this;
191         }
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(")");
199                 }
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(")");
203                 }
204                 output.append("\">");
205                 if(!drawee.contents.empty()) {
206                         for(int i=0; i<drawee.contents.size(); i++) {
207                                 drawee.contents[i]->draw(*this);
208                         }
209                 }
210                 output.append("</g>");
211                 return *this;
212         }
213
214         SVGCanvas& SVGCanvas::image(const Image &img) {
215                 return *this;
216         }
217         SVGCanvas& SVGCanvas::image(const Image &img, const double x, const double y) {
218                 return *this;
219         }
220         SVGCanvas& SVGCanvas::image(const Image &img, const double alpha) {
221                 return *this;
222         }
223
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) {
228                 double r, g, b, a;
229                 col.get(r,g,b,a);
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);
241                 output.append(">");
242                 output.append("</text>");
243                 return *this;
244         }
245
246 }       /*      <- namespace Psycholops         */