Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

GXFileVisitor.cxx

Go to the documentation of this file.
00001 // This is oxl/oxp/GXFileVisitor.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 //  \file
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 //: Open ".gx" file specified by filename, parse, and call the various virtuals.
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 // fsm. added 'return false;' in all these to suppress compiler warnings.
00040 // apologies if 'true' was the better choice.
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     {        // Set point radius
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     { // "p" x y, or just x y
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     { // + sign
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     { // Polyline
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; //fsm
00099         }
00100       }
00101       if (npoints > 1023) {
00102         vcl_cerr << "movie: Polyline longer than 1024 points!!\n";
00103         return false; //fsm
00104         //npoints = 1023;
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") { // Text
00116       if (do_text) {
00117         char const* text = awk.line();
00118         // text is of form "t +number +number + ...thetext"
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         // Assume 0-1 rgb spec
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             //was : color = colors[i].c;
00156             // fsm. some compilers (SGI native) don't
00157             // like assignment from float [3] to float [3].
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; //fsm
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; //fsm
00175     }
00176   }
00177   return true; // fsm. see above
00178 }

Generated on Thu Jan 10 14:46:06 2008 for contrib/oxl/oxp by  doxygen 1.4.4