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_file = 0;
0029     m_fname.clear();
0030     m_string.clear();
0031     m_gsave = 0;
0032     m_buffer = new Uchar[METAFILE_RECORD_LENGTH()+1];
0033     m_number = 0;
0034   }
0035 
0036   virtual ~wps(){
0037     if(m_file) close_file();
0038     m_string.clear();
0039     if(m_gsave) {
0040       m_out << "tools::wps::~wps :"
0041             << " bad gsave/grestore balance : " << m_gsave
0042             << std::endl;
0043     }
0044     m_gsave = 0;
0045     delete [] m_buffer;
0046   }
0047 private:
0048   wps(const wps& a_from):m_out(a_from.m_out){}
0049   wps& operator=(const wps&){return *this;}
0050 public:
0051   bool open_file(const std::string& a_name,bool a_anonymous = false){
0052     if(m_file) return false;
0053 
0054     m_file = ::fopen(a_name.c_str(),"wb");
0055     if(!m_file) return false;
0056     m_fname = a_name;
0057 
0058     m_number = 0;
0059     m_buffer[METAFILE_RECORD_LENGTH()]= '\0';
0060     m_pageNumber = 0;
0061     // Header :
0062     PrintFLN("%%!PS-Adobe-2.0");
0063     if(a_anonymous) { //usefull for integration tests.
0064     } else {
0065       PrintFLN("%%%%Creator: tools::wps.");
0066       PrintFLN("%%%%CreationDate: %s",get_date());
0067       PrintFLN("%%%%Title: %s",m_fname.c_str());
0068     }
0069     PrintFLN("%%%%Pages: (atend)");
0070     PrintFLN("%%%%BoundingBox: 0 0 %d %d",(int)m_deviceWidth,(int)m_deviceHeight);
0071     PrintFLN("%%%%DocumentFonts: Courier-Bold");
0072     PrintFLN("%%%%DocumentPaperSizes: a4");
0073     PrintFLN("%%%%EndComments");
0074     // postscript :
0075     PS_SAVE();
0076     PrintFLN("%%%%EndProlog");
0077 
0078     return true;
0079   }
0080 
0081   bool close_file(){
0082     if(!m_file) return false;
0083     PS_RESTORE();
0084     PrintFLN("%%%%Trailer");
0085     PrintFLN("%%%%Pages: %d",m_pageNumber);
0086     PrintFLN("%%%%EOF");
0087     ::fclose(m_file);
0088     m_file = 0;
0089     m_fname.clear();
0090     return true;
0091   }
0092 
0093   void PS_PAGE_SCALE(float a_width,float a_height,bool a_portrait = true){
0094     //NOTE : no check done on [a_width,a_height]<=0
0095 
0096     PS_SCALE(1/METAFILE_SCALE(),1/METAFILE_SCALE());
0097     PS_TRANSLATE(m_deviceWidth/20,m_deviceHeight/30);
0098 
0099     float scale;
0100     if(m_deviceWidth<=m_deviceHeight) {
0101       scale = (a_height<=a_width?m_deviceWidth/a_width:m_deviceWidth/a_height);
0102     } else {
0103       scale = (a_height<=a_width?m_deviceHeight/a_width:m_deviceHeight/a_height);
0104     }
0105 
0106    {float xtra,ytra;
0107     if(a_portrait) {
0108       xtra = (m_deviceWidth  - scale * a_width)/2;
0109       ytra = (m_deviceHeight - scale * a_height)/2;
0110     } else {
0111       PS_TRANSLATE(m_deviceWidth,0);
0112       PS_ROTATE(90);
0113       xtra = (m_deviceHeight - scale * a_width)/2;
0114       ytra = (m_deviceWidth  - scale * a_height)/2;
0115     }
0116     PS_TRANSLATE(xtra,ytra);}
0117 
0118     PS_SCALE(scale,scale);
0119   }
0120 
0121   void PS_SCALE(float a_x,float a_y) {
0122     in_buffer("%.2f %.2f scale ",a_x,a_y);
0123   }
0124 
0125   void PS_TRANSLATE(float a_x,float a_y){
0126     in_buffer("%.2f %.2f translate ",a_x,a_y);
0127   }
0128 
0129   void PS_ROTATE(float a_x){in_buffer("%.2f rotate ",a_x);}
0130 
0131   void PS_SAVE(){in_buffer("gsave ");m_gsave++;}
0132 
0133   void PS_RESTORE(){in_buffer("grestore ");m_gsave--;}
0134 
0135   void PS_BEGIN_PAGE(){
0136     m_pageNumber++;
0137     PrintFLN("%%%%Page: %d %d",m_pageNumber,m_pageNumber);
0138     PS_SAVE();
0139   }
0140 
0141   void PS_END_PAGE(){
0142     in_buffer("showpage ");
0143     PS_RESTORE();
0144   }
0145 
0146   enum rgb_nbit {
0147     rgb_bw = 0,
0148     rgb_2 = 2,
0149     rgb_4 = 4,
0150     rgb_8 = 8
0151   };
0152 
0153   void PS_IMAGE(Uint a_width,Uint a_height,rgb_nbit a_nbit,rgb_func a_proc,void* a_tag){
0154     //NOTE : no check done on [a_width,a_height] being zero.
0155 
0156     Uint   row,col;
0157     VCol   dr,dg,db;
0158     Uchar  red,green,blue,b;
0159 
0160     PS_SAVE();
0161     in_buffer("%d %d scale ", a_width, a_height );
0162     bool status = true;
0163     if(a_nbit==rgb_bw) { //grey or black_white
0164       in_buffer   ("/picstr %d string def ",a_width);
0165       in_buffer   ("%d %d %d ",a_width,a_height,8);
0166       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
0167       in_buffer   ("{ currentfile picstr readhexstring pop } " );
0168       PrintFLN ("image " );
0169       for ( row = 0; row < a_height; row++ ) {
0170         for ( col = 0; col < a_width; col++) {
0171           status = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0172           VCol fgrey = rgb2grey(dr,dg,db);
0173           Uchar grey = (Uchar) ( 255.0F * fgrey);
0174           WriteByte(grey);
0175         }
0176       }
0177       int nbhex = a_width * a_height * 2;
0178       PrintFLN ("%%%% nbhex digit          :%d ",nbhex);
0179       PrintFLN ("%%%% nbhex/record_length  :%d ",
0180                 int(nbhex/METAFILE_RECORD_LENGTH()));
0181       PrintFLN ("%%%% nbhex%%record_length :%d ",
0182                 int(nbhex%METAFILE_RECORD_LENGTH()));
0183 
0184     } else if(a_nbit==rgb_2) {
0185       int nbyte2 = (a_width   *  3)/4;
0186       nbyte2 /=3;
0187       nbyte2 *=3;
0188       Uint col_max = (nbyte2  *  4)/3;
0189       // 2 bit for r and g and b.
0190       // rgbs following each other.
0191       in_buffer   ("/rgbstr %d string def ",nbyte2);
0192       in_buffer   ("%d %d %d ",col_max,a_height,2);
0193       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
0194       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0195       in_buffer   ("false 3 " );
0196       PrintFLN ("colorimage " );
0197       for ( row = 0; row < a_height; row++ ) {
0198         for ( col = 0; col < col_max; col+=4) {
0199           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0200           red     = (Uchar) ( 3.0F * dr);
0201           green   = (Uchar) ( 3.0F * dg);
0202           blue    = (Uchar) ( 3.0F * db);
0203           b       = red;
0204           b       = (b<<2)+green;
0205           b       = (b<<2)+blue;
0206 
0207           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
0208           red     = (Uchar) ( 3.0F * dr);
0209           green   = (Uchar) ( 3.0F * dg);
0210           blue    = (Uchar) ( 3.0F * db);
0211           b       = (b<<2)+red;
0212           WriteByte(b);
0213 
0214           b       = green;
0215           b       = (b<<2)+blue;
0216 
0217           status  = a_proc(a_tag,col+2,row,dr,dg,db)?status:false;
0218           red     = (Uchar) ( 3.0F * dr);
0219           green   = (Uchar) ( 3.0F * dg);
0220           blue    = (Uchar) ( 3.0F * db);
0221           b     = (b<<2)+red;
0222           b     = (b<<2)+green;
0223           WriteByte(b);
0224           b       = blue;
0225 
0226           status  = a_proc(a_tag,col+3,row,dr,dg,db)?status:false;
0227           red     = (Uchar) ( 3.0F * dr);
0228           green   = (Uchar) ( 3.0F * dg);
0229           blue    = (Uchar) ( 3.0F * db);
0230           b     = (b<<2)+red;
0231           b     = (b<<2)+green;
0232           b     = (b<<2)+blue;
0233           WriteByte(b);
0234         }
0235       }
0236 
0237     } else if(a_nbit==rgb_4) {
0238       int nbyte4 = (a_width  * 3)/2;
0239       nbyte4 /=3;
0240       nbyte4 *=3;
0241       Uint col_max = (nbyte4 * 2)/3;
0242       // 4 bit for r and g and b.
0243       // rgbs following each other.
0244       in_buffer   ("/rgbstr %d string def ",nbyte4);
0245       in_buffer   ("%d %d %d ",col_max,a_height,4);
0246       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
0247       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0248       in_buffer   ("false 3 " );
0249       PrintFLN ("colorimage " );
0250       for ( row = 0; row < a_height; row++ ) {
0251         for ( col = 0; col < col_max; col+=2) {
0252           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0253           red     = (Uchar) ( 15.0F * dr);
0254           green   = (Uchar) ( 15.0F * dg);
0255           in_buffer ("%x%x",red,green);
0256           blue    = (Uchar) ( 15.0F * db);
0257 
0258           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
0259           red     = (Uchar) ( 15.0F * dr);
0260           in_buffer ("%x%x",blue,red);
0261           green   = (Uchar) ( 15.0F * dg);
0262           blue    = (Uchar) ( 15.0F * db);
0263           in_buffer ("%x%x",green,blue);
0264         }
0265       }
0266 
0267     } else if(a_nbit==rgb_8) {
0268       int nbyte8 = a_width   * 3;
0269       // 8 bit for r and g and b.
0270       in_buffer   ("/rgbstr %d string def ",nbyte8);
0271       in_buffer   ("%d %d %d ",a_width,a_height,8);
0272       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
0273       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
0274       in_buffer   ("false 3 " );
0275       PrintFLN   ("colorimage " );
0276       for ( row = 0; row < a_height; row++ ) {
0277         for ( col = 0; col < a_width; col++) {
0278           status     = a_proc(a_tag,col,row,dr,dg,db)?status:false;
0279           red        = (Uchar) ( 255.0F * dr);
0280           WriteByte (red);
0281           green      = (Uchar) ( 255.0F * dg);
0282           WriteByte (green);
0283           blue       = (Uchar) ( 255.0F * db);
0284           WriteByte (blue);
0285         }
0286       }
0287     } else {
0288       m_out << "PS_IMAGE :"
0289             << " unknown rgb nbit " << a_nbit
0290             << std::endl;
0291     }
0292     if(!status) {
0293       m_out << "PS_IMAGE :"
0294             << " problem to retrieve some pixel rgb."
0295             << std::endl;
0296     }
0297     PS_RESTORE();
0298   }
0299 
0300 protected:
0301   static size_t METAFILE_RECORD_LENGTH() {return 80;}
0302 
0303   static float METAFILE_SCALE() {return 1.0f;}
0304 
0305   static char* get_date(){
0306     char*  string;
0307     time_t d;
0308     ::time(&d);
0309     string = ::ctime(&d);
0310     string[24] = '\0';
0311     return string;
0312   }
0313 
0314   static VCol rgb2grey(VCol a_red,VCol a_green,VCol a_blue){
0315     return (0.30f * a_red + 0.59f * a_green + 0.11f * a_blue);
0316   }
0317 
0318   bool in_buffer(const char* a_format,...){
0319     va_list args;
0320     va_start(args,a_format);
0321     bool status = vsprintf(m_string,2048,a_format,args);
0322     va_end(args);
0323     if(!status) {
0324       m_out << "tools::wps::in_buffer : overflow." << std::endl;
0325       return false;
0326     }
0327 
0328     size_t length = m_string.size();
0329     if(length>METAFILE_RECORD_LENGTH()) {
0330       m_out << "tools::wps::in_buffer : overflow." << std::endl;
0331       return false;
0332     }
0333 
0334     size_t nlength = m_number + length;
0335     if(nlength>METAFILE_RECORD_LENGTH()) {
0336       m_buffer[m_number] = '\0';
0337       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
0338         m_out << "tools::wps::in_buffer : fprintf failed." << std::endl;
0339       }
0340       m_number = 0;
0341       nlength = length;
0342     }
0343     Uchar* pointer = m_buffer + m_number;
0344     ::strcpy((char*)pointer,m_string.c_str());
0345     m_number = nlength;
0346     return true;
0347   }
0348 
0349   bool PrintFLN(const char* a_format,...){
0350     va_list args;
0351     va_start(args,a_format);
0352     bool status = vsprintf(m_string,2048,a_format,args);
0353     va_end(args);
0354     if(!status) {
0355       m_out << "tools::wps::PrintFLN : overflow." << std::endl;
0356       return false;
0357     }
0358 
0359     // put buffer in file :
0360     if(m_number>0) {
0361       m_buffer[m_number] = '\0';
0362       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
0363         m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
0364       }
0365       m_number = 0;
0366     }
0367     if(::fprintf(m_file,"%s\n",m_string.c_str())<0) {
0368       m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
0369     }
0370 
0371     return true;
0372   }
0373 
0374   void WriteByte(Uchar a_byte){
0375     Uchar h = a_byte / 16;
0376     Uchar l = a_byte % 16;
0377     in_buffer("%x%x",h,l);
0378   }
0379 
0380 protected:
0381   std::ostream& m_out;
0382   float         m_deviceWidth;
0383   float         m_deviceHeight;
0384   unsigned int  m_pageNumber;
0385   FILE*         m_file;
0386   std::string   m_fname;
0387   std::string   m_string;
0388   int           m_gsave;
0389   Uchar*        m_buffer;
0390   size_t        m_number;
0391 };
0392 
0393 }
0394 
0395 #endif