SVG.cpp
Go to the documentation of this file.
00001 // Copyright (c) 2013-2014 by Wayne C. Gramlich.  All rights reserved.
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     // Grab the minimum/maximum values from *bounding_box*.
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     // Compute the span in x and y:
00032     double x_span = maximum_x - minimum_x;
00033     double y_span = maximum_y - minimum_y;
00034     //File__format(stderr, "X/Y span=(%.2f, %.2f)\n", x_span, y_span);
00035 
00036     // COmpute the axis independent scale in X and Y:
00037     double x_scale = x_width / x_span;
00038     double y_scale = y_height / y_span;
00039     //File__format(stderr, "X/Y scale=(%.6f, %.6f)\n", x_scale, y_scale);
00040 
00041     // Take the smaller of the two so that the X and Y scales are equal:
00042     x_scale = std::min(x_scale, y_scale);
00043     y_scale = x_scale;
00044     //File__format(stderr, "X/Y scale=(%.6f, %.6f)\n", x_scale, y_scale);
00045 
00046     // Compute X/Y spans adjusted by the aspect ratio:
00047     double scaled_x_span = x_span;
00048     double scaled_y_span = y_span;
00049     //File__format(stderr,
00050     //  "Scaled X/Y span=(%.2f, %.2f)\n", scaled_x_span, scaled_y_span);
00051     
00052     // Now compute the X and Y offsets:
00053     double x_offset = (minimum_x + maximum_x) / 2.0 - scaled_x_span / 2.0;
00054     // Swap Y axis direction by adding *scaled_y_span* instead of subtracting:
00055     double y_offset = (minimum_y + maximum_y) / 2.0 + scaled_y_span / 2.0;
00056     //File__format(stderr, "X/Y offset=(%.2f, %.2f)\n", x_offset, y_offset);
00057     
00058     // Load up *svg*:
00059     width = x_width * x_scale;
00060     height = y_height * y_scale;
00061     this->x_scale = x_scale;
00062     // Swap Y axis direction by negating *y_scale*:
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     // Close *svg*:
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     // Output "<line ... />" to *svg_stream*:
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     // Verify that units are OK:
00121     assert (String__equal(units, "cm") ||
00122       String__equal(units, "mm") ||
00123       String__equal(units, "in"));
00124 
00125     // Get *svg_stream* opened:
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         // Allocate and load up *svg*:
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         // Ouput the header for *svg*:
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     // Output "<rect ... />" to *svg_stream*:
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 }


fiducial_lib
Author(s): Wayne Gramlich
autogenerated on Thu Jun 6 2019 18:08:04