Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/wps is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_wps
0005 #define tools_wps
0006 
0007 #include <ctime>
0008 
0009 #include <string>
0010 #include <ostream>
0011 #include <cstring>
0012 #include "sprintf"
0013 
0014 namespace tools {
0015 
0016 class wps {
0017   typedef unsigned char Uchar;
0018   typedef unsigned int  Uint;
0019 
0020 public:
0021   typedef float VCol;
0022   typedef bool(*rgb_func)(void*,unsigned int,unsigned int,VCol&,VCol&,VCol&);
0023 public:
0024   wps(std::ostream& a_out):m_out(a_out){
0025     m_deviceWidth = (8.5f-1.f)*72*METAFILE_SCALE(); // 540 * METAFILE_SCALE
0026     m_deviceHeight = 11*72*METAFILE_SCALE();        // 792 * METAFILE_SCALE
0027     m_pageNumber = 0;
0028   //m_pagePos = 0;
0029   //m_markSize = 2;
0030     m_file = 0;
0031     m_fname.clear();
0032     m_string.clear();
0033     m_gsave = 0;
0034     m_buffer = new Uchar[METAFILE_RECORD_LENGTH()+1];
0035     m_number = 0;
0036 
0037     //m_param.shade = shade_color;
0038   }
0039 
0040   virtual ~wps(){
0041     if(m_file) close_file();
0042     m_string.clear();
0043     if(m_gsave) {
0044       m_out << "tools::wps::~wps :"
0045             << " bad gsave/grestore balance : " << m_gsave
0046             << std::endl;
0047     }
0048     m_gsave = 0;
0049     delete [] m_buffer;
0050   }
0051 //protected:
0052 private:
0053   wps(const wps& a_from):m_out(a_from.m_out){}
0054   wps& operator=(const wps&){return *this;}
0055 public:
0056   //const std::string& file_name() const {return m_fname;}
0057   //FILE* get_FILE() const {return m_file;}
0058 
0059   bool open_file(const std::string& a_name,bool a_anonymous = false){
0060     if(m_file) return false;
0061 
0062     m_file = ::fopen(a_name.c_str(),"wb");
0063     if(!m_file) return false;
0064     m_fname = a_name;
0065 
0066     m_number = 0;
0067     m_buffer[METAFILE_RECORD_LENGTH()]= '\0';
0068     m_pageNumber = 0;
0069     // Header :
0070     PrintFLN("%%!PS-Adobe-2.0");
0071     if(a_anonymous) { //usefull for integration tests.
0072     } else {
0073       PrintFLN("%%%%Creator: tools::wps.");
0074       PrintFLN("%%%%CreationDate: %s",get_date());
0075       PrintFLN("%%%%Title: %s",m_fname.c_str());
0076     }
0077     PrintFLN("%%%%Pages: (atend)");
0078     PrintFLN("%%%%BoundingBox: 0 0 %d %d",(int)m_deviceWidth,(int)m_deviceHeight);
0079     PrintFLN("%%%%DocumentFonts: Courier-Bold");
0080     PrintFLN("%%%%DocumentPaperSizes: a4");
0081     PrintFLN("%%%%EndComments");
0082     // postscript :
0083     PS_SAVE();
0084 /*
0085     // General :
0086     in_buffer("/n {newpath} def ");
0087     in_buffer("/cl {closepath} def ");
0088     in_buffer("/s {stroke} def ");
0089     in_buffer("/f {fill} def ");
0090     // Move :
0091     in_buffer("/m  {moveto} def ");
0092     in_buffer("/rm {rmoveto} def ");
0093     in_buffer("/rl {rlineto} def ");
0094     // Line :
0095     in_buffer("/lc {setlinecap} def ");
0096     in_buffer("/lw {setlinewidth} def ");
0097     in_buffer("/rgb {setrgbcolor} def ");
0098     in_buffer("/ss {[] 0 setdash} def ");     // style solid.
0099     in_buffer("/sd {[12 6] 0 setdash} def "); // style dashed
0100     in_buffer("/so {[6 12] 0 setdash} def "); // style dotted
0101     in_buffer("/sdo {[18 12 6 12] 0 setdash} def "); // dash dotted
0102     // Mark :
0103     m_markSize = 2.;
0104     in_buffer("/ms 2. def /msi .5 def ");        // mark size
0105     in_buffer("/cross {ms ms scale -1. -1. rm  ");
0106     in_buffer ("2. 2. rl 0. -2. rm -2. 2. rl msi msi scale} def ");
0107     in_buffer("/plus  {ms ms scale -1. 0. rm 2. 0. rl ");
0108     in_buffer("-1. 1. rm 0. -2. rl msi msi scale} def ");
0109     in_buffer("/asterisk {ms ms scale -1. 0. rm 2. 0. rl -1. 1. rm ");
0110     in_buffer("0. -2. rl 0. 1. rm -0.707 -0.707 rm 1.414 1.414 rl ");
0111     in_buffer("0. -1.414 rm -1.414 1.414 rl msi msi scale} def ");
0112     in_buffer("/star {ms ms scale 0. 1. rm -0.6 -1.5 rl ");
0113     in_buffer("1.2 0. rl -0.6 1.5 rl msi msi scale} def ");
0114     // Text :
0115     in_buffer("/sh {show} def ");
0116     in_buffer("/df {/Courier-Bold findfont} def ");
0117     in_buffer("/mf {makefont setfont} def ");
0118 */
0119 
0120     PrintFLN("%%%%EndProlog");
0121 
0122     return true;
0123   }
0124 
0125   bool close_file(){
0126     if(!m_file) return false;
0127     PS_RESTORE();
0128     PrintFLN("%%%%Trailer");
0129     PrintFLN("%%%%Pages: %d",m_pageNumber);
0130     PrintFLN("%%%%EOF");
0131     ::fclose(m_file);
0132     m_file = 0;
0133     m_fname.clear();
0134     return true;
0135   }
0136 
0137   void PS_PAGE_SCALE(float a_width,float a_height,bool a_portrait = true){
0138     //NOTE : no check done on [a_width,a_height]<=0
0139 
0140     PS_SCALE(1/METAFILE_SCALE(),1/METAFILE_SCALE());
0141     PS_TRANSLATE(m_deviceWidth/20,m_deviceHeight/30);
0142 
0143     float scale;
0144     if(m_deviceWidth<=m_deviceHeight) {
0145       scale = (a_height<=a_width?m_deviceWidth/a_width:m_deviceWidth/a_height);
0146     } else {
0147       scale = (a_height<=a_width?m_deviceHeight/a_width:m_deviceHeight/a_height);
0148     }
0149 
0150    {float xtra,ytra;
0151     if(a_portrait) {
0152       xtra = (m_deviceWidth  - scale * a_width)/2;
0153       ytra = (m_deviceHeight - scale * a_height)/2;
0154     } else {
0155       PS_TRANSLATE(m_deviceWidth,0);
0156       PS_ROTATE(90);
0157       xtra = (m_deviceHeight - scale * a_width)/2;
0158       ytra = (m_deviceWidth  - scale * a_height)/2;
0159     }
0160     PS_TRANSLATE(xtra,ytra);}
0161 
0162     PS_SCALE(scale,scale);
0163   }
0164 
0165   void PS_SCALE(float a_x,float a_y) {
0166     in_buffer("%.2f %.2f scale ",a_x,a_y);
0167   }
0168 
0169   void PS_TRANSLATE(float a_x,float a_y){
0170     in_buffer("%.2f %.2f translate ",a_x,a_y);
0171   }
0172 
0173   void PS_ROTATE(float a_x){in_buffer("%.2f rotate ",a_x);}
0174 
0175   void PS_SAVE(){in_buffer("gsave ");m_gsave++;}
0176 
0177   void PS_RESTORE(){in_buffer("grestore ");m_gsave--;}
0178 
0179   void PS_BEGIN_PAGE(){
0180     m_pageNumber++;
0181     PrintFLN("%%%%Page: %d %d",m_pageNumber,m_pageNumber);
0182     PS_SAVE();
0183   }
0184 
0185   void PS_END_PAGE(){
0186     in_buffer("showpage ");
0187     PS_RESTORE();
0188   }
0189 
0190   enum rgb_nbit {
0191     rgb_bw = 0,
0192     rgb_2 = 2,
0193     rgb_4 = 4,
0194     rgb_8 = 8
0195   };
0196 
0197   void PS_IMAGE(Uint a_width,Uint a_height,rgb_nbit a_nbit,rgb_func a_proc,void* a_tag){
0198     //NOTE : no check done on [a_width,a_height] being zero.
0199 
0200     Uint   row,col;
0201     VCol   dr,dg,db;
0202     Uchar  red,green,blue,b;
0203 
0204     PS_SAVE();
0205     in_buffer("%d %d scale ", a_width, a_height );
0206     bool status = true;
0207     if(a_nbit==rgb_bw) { //grey or black_white
0208       in_buffer   ("/picstr %d string def ",a_width);
0209       in_buffer   ("%d %d %d ",a_width,a_height,8);
0210       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
0211       in_buffer   ("{ currentfile picstr readhexstring pop } " );
0212       PrintFLN ("image " );
0213       for ( row = 0; row < a_height; row++ ) {
0214         for ( col = 0; col < a_width; col++) {
0215           status = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0216           VCol fgrey = rgb2grey(dr,dg,db);
0217           Uchar grey = (Uchar) ( 255.0F * fgrey);
0218           WriteByte(grey);
0219         }
0220       }
0221       int nbhex = a_width * a_height * 2;
0222       PrintFLN ("%%%% nbhex digit          :%d ",nbhex);
0223       PrintFLN ("%%%% nbhex/record_length  :%d ",
0224                 int(nbhex/METAFILE_RECORD_LENGTH()));
0225       PrintFLN ("%%%% nbhex%%record_length :%d ",
0226                 int(nbhex%METAFILE_RECORD_LENGTH()));
0227 
0228     } else if(a_nbit==rgb_2) {
0229       int nbyte2 = (a_width   *  3)/4;
0230       nbyte2 /=3;
0231       nbyte2 *=3;
0232       Uint col_max = (nbyte2  *  4)/3;
0233       // 2 bit for r and g and b.
0234       // rgbs following each other.
0235       in_buffer   ("/rgbstr %d string def ",nbyte2);
0236       in_buffer   ("%d %d %d ",col_max,a_height,2);
0237       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
0238       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0239       in_buffer   ("false 3 " );
0240       PrintFLN ("colorimage " );
0241       for ( row = 0; row < a_height; row++ ) {
0242         for ( col = 0; col < col_max; col+=4) {
0243           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0244           red     = (Uchar) ( 3.0F * dr);
0245           green   = (Uchar) ( 3.0F * dg);
0246           blue    = (Uchar) ( 3.0F * db);
0247           b       = red;
0248           b       = (b<<2)+green;
0249           b       = (b<<2)+blue;
0250 
0251           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
0252           red     = (Uchar) ( 3.0F * dr);
0253           green   = (Uchar) ( 3.0F * dg);
0254           blue    = (Uchar) ( 3.0F * db);
0255           b       = (b<<2)+red;
0256           WriteByte(b);
0257 
0258           b       = green;
0259           b       = (b<<2)+blue;
0260 
0261           status  = a_proc(a_tag,col+2,row,dr,dg,db)?status:false;
0262           red     = (Uchar) ( 3.0F * dr);
0263           green   = (Uchar) ( 3.0F * dg);
0264           blue    = (Uchar) ( 3.0F * db);
0265           b     = (b<<2)+red;
0266           b     = (b<<2)+green;
0267           WriteByte(b);
0268           b       = blue;
0269 
0270           status  = a_proc(a_tag,col+3,row,dr,dg,db)?status:false;
0271           red     = (Uchar) ( 3.0F * dr);
0272           green   = (Uchar) ( 3.0F * dg);
0273           blue    = (Uchar) ( 3.0F * db);
0274           b     = (b<<2)+red;
0275           b     = (b<<2)+green;
0276           b     = (b<<2)+blue;
0277           WriteByte(b);
0278         }
0279       }
0280 
0281     } else if(a_nbit==rgb_4) {
0282       int nbyte4 = (a_width  * 3)/2;
0283       nbyte4 /=3;
0284       nbyte4 *=3;
0285       Uint col_max = (nbyte4 * 2)/3;
0286       // 4 bit for r and g and b.
0287       // rgbs following each other.
0288       in_buffer   ("/rgbstr %d string def ",nbyte4);
0289       in_buffer   ("%d %d %d ",col_max,a_height,4);
0290       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
0291       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0292       in_buffer   ("false 3 " );
0293       PrintFLN ("colorimage " );
0294       for ( row = 0; row < a_height; row++ ) {
0295         for ( col = 0; col < col_max; col+=2) {
0296           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0297           red     = (Uchar) ( 15.0F * dr);
0298           green   = (Uchar) ( 15.0F * dg);
0299           in_buffer ("%x%x",red,green);
0300           blue    = (Uchar) ( 15.0F * db);
0301 
0302           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
0303           red     = (Uchar) ( 15.0F * dr);
0304           in_buffer ("%x%x",blue,red);
0305           green   = (Uchar) ( 15.0F * dg);
0306           blue    = (Uchar) ( 15.0F * db);
0307           in_buffer ("%x%x",green,blue);
0308         }
0309       }
0310 
0311     } else if(a_nbit==rgb_8) {
0312       int nbyte8 = a_width   * 3;
0313       // 8 bit for r and g and b.
0314       in_buffer   ("/rgbstr %d string def ",nbyte8);
0315       in_buffer   ("%d %d %d ",a_width,a_height,8);
0316       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
0317       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0318       in_buffer   ("false 3 " );
0319       PrintFLN   ("colorimage " );
0320       for ( row = 0; row < a_height; row++ ) {
0321         for ( col = 0; col < a_width; col++) {
0322           status     = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0323           red        = (Uchar) ( 255.0F * dr);
0324           WriteByte (red);
0325           green      = (Uchar) ( 255.0F * dg);
0326           WriteByte (green);
0327           blue       = (Uchar) ( 255.0F * db);
0328           WriteByte (blue);
0329         }
0330       }
0331     } else {
0332       m_out << "PS_IMAGE :"
0333             << " unknown rgb nbit " << a_nbit
0334             << std::endl;
0335     }
0336     if(!status) {
0337       m_out << "PS_IMAGE :"
0338             << " problem to retrieve some pixel rgb."
0339             << std::endl;
0340     }
0341     PS_RESTORE();
0342   }
0343 
0344 protected:
0345   static size_t METAFILE_RECORD_LENGTH() {return 80;}
0346 
0347   static float METAFILE_SCALE() {return 1.0f;}
0348 
0349   static char* get_date(){
0350     char*  string;
0351     time_t d;
0352     ::time(&d);
0353     string = ::ctime(&d);
0354     string[24] = '\0';
0355     return string;
0356   }
0357 
0358   static VCol rgb2grey(VCol a_red,VCol a_green,VCol a_blue){
0359     return (0.30f * a_red + 0.59f * a_green + 0.11f * a_blue);
0360   }
0361 
0362   bool in_buffer(const char* a_format,...){
0363     va_list args;
0364     va_start(args,a_format);
0365     bool status = vsprintf(m_string,2048,a_format,args);
0366     va_end(args);
0367     if(!status) {
0368       m_out << "tools::wps::in_buffer : overflow." << std::endl;
0369       return false;
0370     }
0371 
0372     size_t length = m_string.size();
0373     if(length>METAFILE_RECORD_LENGTH()) {
0374       m_out << "tools::wps::in_buffer : overflow." << std::endl;
0375       return false;
0376     }
0377 
0378     size_t nlength = m_number + length;
0379     if(nlength>METAFILE_RECORD_LENGTH()) {
0380       m_buffer[m_number] = '\0';
0381       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
0382         m_out << "tools::wps::in_buffer : fprintf failed." << std::endl;
0383       }
0384       m_number = 0;
0385       nlength = length;
0386     }
0387     Uchar* pointer = m_buffer + m_number;
0388     ::strcpy((char*)pointer,m_string.c_str());
0389     m_number = nlength;
0390     return true;
0391   }
0392 
0393   bool PrintFLN(const char* a_format,...){
0394     va_list args;
0395     va_start(args,a_format);
0396     bool status = vsprintf(m_string,2048,a_format,args);
0397     va_end(args);
0398     if(!status) {
0399       m_out << "tools::wps::PrintFLN : overflow." << std::endl;
0400       return false;
0401     }
0402 
0403     // put buffer in file :
0404     if(m_number>0) {
0405       m_buffer[m_number] = '\0';
0406       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
0407         m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
0408       }
0409       m_number = 0;
0410     }
0411     if(::fprintf(m_file,"%s\n",m_string.c_str())<0) {
0412       m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
0413     }
0414 
0415     return true;
0416   }
0417 
0418   void WriteByte(Uchar a_byte){
0419     Uchar h = a_byte / 16;
0420     Uchar l = a_byte % 16;
0421     in_buffer("%x%x",h,l);
0422   }
0423 
0424 protected:
0425   std::ostream& m_out;
0426   float         m_deviceWidth;
0427   float         m_deviceHeight;
0428   unsigned int  m_pageNumber;
0429 //double        m_markSize;
0430   FILE*         m_file;
0431   std::string   m_fname;
0432   std::string   m_string;
0433   int           m_gsave;
0434   Uchar*        m_buffer;
0435   size_t        m_number;
0436 //struct {
0437 //  int shade;
0438 //  int nbit;
0439 //} m_param;
0440 };
0441 
0442 }
0443 
0444 #endif
0445 
0446 /*
0447   enum {
0448     shade_color = 0,
0449     shade_grey = 1,
0450     shade_black_white = 2
0451   };
0452 
0453   void PS_BACKGROUND(double a_r,double a_g,double a_b,
0454                      double a_width,double a_height,
0455                      bool a_do_back = true){
0456     PS_NEWPATH();
0457     PS_MOVE       (0.,0.);
0458     PS_RLINETO    (a_width,0.);
0459     PS_RLINETO    (0.,a_height);
0460     PS_RLINETO    (-a_width,0.);
0461     PS_RLINETO    (0.,-a_height);
0462     PS_CLOSEPATH();
0463     if(a_do_back) {
0464       PS_SAVE();
0465       PS_RGB(a_r,a_g,a_b);
0466       PS_FILL();
0467       PS_RESTORE();
0468     }
0469     in_buffer("clip ");
0470   }
0471 
0472   void PS_RGB(double a_r,double a_g,double a_b){
0473     if(m_param.shade==shade_color)
0474       in_buffer("%.2f %.2f %.2f rgb ",a_r,a_g,a_b);
0475     else if(m_param.shade==shade_grey)
0476       in_buffer("%.2f setgray ",rgb2grey(a_r,a_g,a_b));
0477     else if(m_param.shade==shade_black_white)
0478       in_buffer("0. setgray ",rgb2grey(a_r,a_g,a_b));
0479   }
0480 
0481   void PS_LINE_WIDTH(int a_width){in_buffer("%.1f lw ",float(a_width));}
0482 
0483   void PS_NEWPATH() {in_buffer("n ");}
0484   void PS_STROKE() {in_buffer("s ");}
0485   void PS_FILL() {in_buffer("f ");}
0486   void PS_CLOSEPATH() {in_buffer("cl ");}
0487   void PS_CAP(double a_x) {in_buffer ("%1d lc ",a_x);}
0488   void PS_RLINETO(double a_x,double a_y) {
0489     in_buffer ("%.2f %.2f rl ",a_x,a_y);
0490   }
0491   void PS_MOVE(double a_x,double a_y) {
0492     in_buffer ("%.2f %.2f m ",a_x,a_y);
0493   }
0494 
0495   void PS_FRAME(double a_r,double a_g,double a_b,
0496                 double a_width,double a_height){
0497     PS_NEWPATH   ();
0498     PS_MOVE      (0.,0.);
0499     PS_RLINETO   (a_width,0.);
0500     PS_RLINETO   (0.,a_height);
0501     PS_RLINETO   (-a_width,0.);
0502     PS_RLINETO   (0.,-a_height);
0503     PS_CLOSEPATH ();
0504     PS_RGB       (a_r,a_g,a_b);
0505     PS_LINE_WIDTH(1);
0506     PS_CAP       (1);
0507     in_buffer    ("ss ");
0508     PS_STROKE();
0509   }
0510 */