00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008 #include "GXFileVisitor.h"
00009
00010 #include <vcl_cstdlib.h>
00011 #include <vcl_cstring.h>
00012 #include <vcl_fstream.h>
00013
00014 #include <vul/vul_reg_exp.h>
00015 #include <vcl_iostream.h>
00016 #include <vul/vul_awk.h>
00017
00018 bool GXFileVisitor::do_text = true;
00019 bool GXFileVisitor::do_antialias = false;
00020
00021 GXFileVisitor::GXFileVisitor()
00022 {
00023 color[0] = color[1] = color[2] = 1.0;
00024 point_radius = 1;
00025 line_width = 0;
00026 }
00027
00028
00029 bool GXFileVisitor::visit(char const* filename)
00030 {
00031 vcl_ifstream f(filename);
00032 if (!f.good()) {
00033 vcl_cerr << "GXFileVisitor: Could not open [" << filename << "]\n";
00034 return false;
00035 }
00036 return visit(f);
00037 }
00038
00039
00040
00041 bool GXFileVisitor::point(char const*, float, float) {return false;}
00042 bool GXFileVisitor::polyline(float const*, float const*, int) {return false;}
00043 bool GXFileVisitor::text(float, float, char const*) {return false;}
00044 bool GXFileVisitor::set_color(float, float, float) {return false;}
00045 bool GXFileVisitor::set_point_radius(float) {return false;}
00046 bool GXFileVisitor::set_line_width(float) {return false;}
00047
00048 struct StringToFloat {
00049 double value;
00050 bool ok_;
00051
00052 StringToFloat(const char* s) {
00053 char * ep;
00054 value = strtod(s, &ep);
00055 ok_ = (ep != s);
00056 }
00057
00058 double operator() () { return value; }
00059 bool ok() { return ok_; }
00060 };
00061
00062 bool GXFileVisitor::visit(vcl_istream& s)
00063 {
00064 vul_reg_exp re("^t +[-+.0-9e]+ +[-+.0-9e]+ +(.+)$");
00065 for (vul_awk awk(s); awk; ++awk) {
00066 int NF = awk.NF();
00067 if (NF == 0)
00068 continue;
00069 vcl_string instruction = awk[0];
00070 StringToFloat instruction_value(instruction.c_str());
00071 if (instruction == "r")
00072 {
00073 this->point_radius = (float)vcl_atof(awk[1]);
00074 this->set_point_radius(this->point_radius);
00075 }
00076 else if (instruction == "p" || (instruction_value.ok() && NF == 2))
00077 {
00078 int base = (instruction == "p") ? 1 : 0;
00079 this->point("p", (float)vcl_atof(awk[base+0]), (float)vcl_atof(awk[base+1]));
00080 }
00081 else if (instruction == "+")
00082 {
00083 this->point("+", (float)vcl_atof(awk[1]), (float)vcl_atof(awk[2]));
00084 }
00085 else if (instruction == "l" || (instruction_value.ok() && NF == 4))
00086 {
00087 bool numbers_only = instruction_value.ok();
00088 int npoints, base;
00089 if (numbers_only) {
00090 base = 0;
00091 npoints = NF/2;
00092 }
00093 else {
00094 base = 1;
00095 npoints = (NF - 1)/2;
00096 if (npoints * 2 + 1 != NF) {
00097 vcl_cerr << "movie: Polyline with odd # of vertices!!!\n";
00098 return false;
00099 }
00100 }
00101 if (npoints > 1023) {
00102 vcl_cerr << "movie: Polyline longer than 1024 points!!\n";
00103 return false;
00104
00105 }
00106
00107 float x[1024];
00108 float y[1024];
00109 for (int i = 0; i < npoints; ++i) {
00110 x[i] = (float)vcl_atof(awk[i*2 + 0 + base]);
00111 y[i] = (float)vcl_atof(awk[i*2 + 1 + base]);
00112 }
00113 this->polyline(x, y, npoints);
00114
00115 } else if (instruction == "t") {
00116 if (do_text) {
00117 char const* text = awk.line();
00118
00119 if (!*text || !re.find(text))
00120 vcl_cerr << "GXFileVisitor: Bad \"t\" line: [" << text << "]\n";
00121 else
00122 this->text((float)vcl_atof(awk[1]), (float)vcl_atof(awk[2]), re.match(1).c_str());
00123 }
00124 } else if (instruction == "c") {
00125 if (awk.NF() == 4) {
00126
00127 color[0] = (float)vcl_atof(awk[1]);
00128 color[1] = (float)vcl_atof(awk[2]);
00129 color[2] = (float)vcl_atof(awk[3]);
00130 }
00131 else
00132 {
00133 static struct { char const* s; float c[3]; } colors [] = {
00134 {"r", {1, 0, 0}},
00135 {"g", {0, 1, 0}},
00136 {"b", {0, 0, 1}},
00137 {"y", {1, 1, 0}},
00138 {"m", {1, 0, 1}},
00139 {"c", {0, 1, 1}},
00140 {"k", {0, 0, 0}},
00141 {"w", {1, 1, 1}},
00142 {"red", {1, 0, 0}},
00143 {"green", {0, 1, 0}},
00144 {"blue", {0, 0, 1}},
00145 {"yellow", {1, 1, 0}},
00146 {"black", {0, 0, 0}},
00147 {"white", {1, 1, 1}},
00148 {0,{0,0,0}}
00149 };
00150 vcl_string colour = awk[1];
00151 char const* cs = colour.c_str();
00152 bool ok = false;
00153 for (unsigned i = 0; i < sizeof colors / sizeof colors[0]; ++i)
00154 if (vcl_strcmp(colors[i].s, cs) == 0) {
00155
00156
00157
00158 color[0] = colors[i].c[0];
00159 color[1] = colors[i].c[1];
00160 color[2] = colors[i].c[2];
00161 ok = true;
00162 break;
00163 }
00164 if (!ok) {
00165 vcl_cerr << "GXFileVisitor: Colour [" << cs << "] not recognised\n";
00166 return false;
00167 }
00168 }
00169
00170 this->set_color(color[0], color[1], color[2]);
00171 }
00172 else {
00173 vcl_cerr << "movie: bad gx line " << awk.line() << vcl_endl;
00174 return false;
00175 }
00176 }
00177 return true;
00178 }