00001
00002
00003 #include <assert.h>
00004
00005 #include "Bounding_Box.hpp"
00006 #include "String.hpp"
00007 #include "SVG.hpp"
00008
00009 #include <algorithm>
00010
00022
00023 void SVG::cartesian_scale(double x_width, double y_height,
00024 BoundingBox *bounding_box) {
00025
00026 double maximum_x = bounding_box->max_x();
00027 double minimum_x = bounding_box->min_x();
00028 double maximum_y = bounding_box->max_y();
00029 double minimum_y = bounding_box->min_y();
00030
00031
00032 double x_span = maximum_x - minimum_x;
00033 double y_span = maximum_y - minimum_y;
00034
00035
00036
00037 double x_scale = x_width / x_span;
00038 double y_scale = y_height / y_span;
00039
00040
00041
00042 x_scale = std::min(x_scale, y_scale);
00043 y_scale = x_scale;
00044
00045
00046
00047 double scaled_x_span = x_span;
00048 double scaled_y_span = y_span;
00049
00050
00051
00052
00053 double x_offset = (minimum_x + maximum_x) / 2.0 - scaled_x_span / 2.0;
00054
00055 double y_offset = (minimum_y + maximum_y) / 2.0 + scaled_y_span / 2.0;
00056
00057
00058
00059 width = x_width * x_scale;
00060 height = y_height * y_scale;
00061 this->x_scale = x_scale;
00062
00063 this->y_scale = -y_scale;
00064 this->x_offset = -x_offset;
00065 this->y_offset = -y_offset;
00066 }
00067
00068
00073
00074 SVG::~SVG() {
00075
00076 File__format(stream, "</svg>\n");
00077 File__close(stream);
00078 }
00079
00090
00091 void SVG::line(double x1, double y1, double x2, double y2,
00092 String_Const stroke) {
00093
00094
00095 File__format(stream,
00096 "<line x1=\"%f%s\" y1=\"%f%s\"",
00097 (x1 + x_offset) * x_scale, units, (y1 + y_offset) * y_scale, units);
00098 File__format(stream,
00099 " x2=\"%f%s\" y2=\"%f%s\"",
00100 (x2 + x_offset) * x_scale, units, (y2 + y_offset) * y_scale, units);
00101 File__format(stream,
00102 " style=\"stroke:%s\"/>\n", stroke);
00103 }
00104
00116
00117 SVG::SVG(String_Const base_name,
00118 double width, double height, double x_scale, double y_scale,
00119 String_Const units) {
00120
00121 assert (String__equal(units, "cm") ||
00122 String__equal(units, "mm") ||
00123 String__equal(units, "in"));
00124
00125
00126 char file_name[100];
00127 (void)sprintf(file_name, "%s.svg", base_name);
00128 stream = File__open(file_name, "w");
00129 if (stream == (File)0) {
00130 File__format(stderr, "Unable to open %s.svg\n", base_name);
00131 } else {
00132
00133 this->height = height;
00134 this->width = width;
00135 this->units = units;
00136 this->x_scale = x_scale;
00137 this->y_scale = y_scale;
00138 this->x_offset = 0.0;
00139 this->y_offset = 0.0;
00140
00141
00142 File__format(stream,
00143 "<?xml version=\"1.0\" standalone=\"no\"?>\n\n");
00144 File__format(stream,
00145 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
00146 File__format(stream,
00147 " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n\n");
00148 File__format(stream,
00149 "<svg width=\"%f%s\" height=\"%f%s\"\n",
00150 width * x_scale, units, height * y_scale, units);
00151 File__format(stream,
00152 " version=\"1.1\"\n");
00153 File__format(stream,
00154 " xmlns=\"http://www.w3.org/2000/svg\">\n\n");
00155 }
00156 }
00157
00170
00171 void SVG::rectangle(double x, double y, double width, double height,
00172 String_Const stroke_color, String_Const fill_color) {
00173
00174 double x_final = (x + x_offset) * x_scale;
00175 double y_final = (y + y_offset) * y_scale;
00176 File__format(stream,
00177 "<rect x=\"%f%s\" y=\"%f%s\"", x_final, units, y_final, units);
00178 File__format(stream,
00179 " width=\"%f%s\" height=\"%f%s\"",
00180 width * x_scale, units, height * y_scale, units);
00181 File__format(stream,
00182 " style=\"stroke:%s; fill:%s\"/>\n", stroke_color, fill_color);
00183 }
00184
00195
00196 void SVG::text(String_Const message, double x, double y,
00197 String_Const font_family, unsigned int font_size) {
00198
00199 File__format(stream,
00200 "<text x=\"%f%s\" y=\"%f%s\"",
00201 (x + x_offset) * x_scale, units, (y + y_offset) * y_scale, units);
00202 File__format(stream,
00203 " style=\"font-family:%s; font-size:%d\">", font_family, font_size);
00204 File__format(stream, "%s</text>\n", message);
00205 }
00206
00207 void SVG::setOffsets(double x, double y) {
00208 x_offset = x;
00209 y_offset = y;
00210 }