Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/wps

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_wps
  5 #define tools_wps
  6 
  7 #include <ctime>
  8 
  9 #include <string>
 10 #include <ostream>
 11 #include <cstring>
 12 #include "sprintf"
 13 
 14 namespace tools {
 15 
 16 class wps {
 17   typedef unsigned char Uchar;
 18   typedef unsigned int  Uint;
 19 
 20 public:
 21   typedef float VCol;
 22   typedef bool(*rgb_func)(void*,unsigned int,unsigned int,VCol&,VCol&,VCol&);
 23 public:
 24   wps(std::ostream& a_out):m_out(a_out){
 25     m_deviceWidth = (8.5f-1.f)*72*METAFILE_SCALE(); // 540 * METAFILE_SCALE
 26     m_deviceHeight = 11*72*METAFILE_SCALE();        // 792 * METAFILE_SCALE
 27     m_pageNumber = 0;
 28   //m_pagePos = 0;
 29   //m_markSize = 2;
 30     m_file = 0;
 31     m_fname.clear();
 32     m_string.clear();
 33     m_gsave = 0;
 34     m_buffer = new Uchar[METAFILE_RECORD_LENGTH()+1];
 35     m_number = 0;
 36 
 37     //m_param.shade = shade_color;
 38   }
 39 
 40   virtual ~wps(){
 41     if(m_file) close_file();
 42     m_string.clear();
 43     if(m_gsave) {
 44       m_out << "tools::wps::~wps :"
 45             << " bad gsave/grestore balance : " << m_gsave
 46             << std::endl;
 47     }
 48     m_gsave = 0;
 49     delete [] m_buffer;
 50   }
 51 //protected:
 52 private:
 53   wps(const wps& a_from):m_out(a_from.m_out){}
 54   wps& operator=(const wps&){return *this;}
 55 public:
 56   //const std::string& file_name() const {return m_fname;}
 57   //FILE* get_FILE() const {return m_file;}
 58 
 59   bool open_file(const std::string& a_name,bool a_anonymous = false){
 60     if(m_file) return false;
 61 
 62     m_file = ::fopen(a_name.c_str(),"wb");
 63     if(!m_file) return false;
 64     m_fname = a_name;
 65 
 66     m_number = 0;
 67     m_buffer[METAFILE_RECORD_LENGTH()]= '\0';
 68     m_pageNumber = 0;
 69     // Header :
 70     PrintFLN("%%!PS-Adobe-2.0");
 71     if(a_anonymous) { //usefull for integration tests.
 72     } else {
 73       PrintFLN("%%%%Creator: tools::wps.");
 74       PrintFLN("%%%%CreationDate: %s",get_date());
 75       PrintFLN("%%%%Title: %s",m_fname.c_str());
 76     }
 77     PrintFLN("%%%%Pages: (atend)");
 78     PrintFLN("%%%%BoundingBox: 0 0 %d %d",(int)m_deviceWidth,(int)m_deviceHeight);
 79     PrintFLN("%%%%DocumentFonts: Courier-Bold");
 80     PrintFLN("%%%%DocumentPaperSizes: a4");
 81     PrintFLN("%%%%EndComments");
 82     // postscript :
 83     PS_SAVE();
 84 /*
 85     // General :
 86     in_buffer("/n {newpath} def ");
 87     in_buffer("/cl {closepath} def ");
 88     in_buffer("/s {stroke} def ");
 89     in_buffer("/f {fill} def ");
 90     // Move :
 91     in_buffer("/m  {moveto} def ");
 92     in_buffer("/rm {rmoveto} def ");
 93     in_buffer("/rl {rlineto} def ");
 94     // Line :
 95     in_buffer("/lc {setlinecap} def ");
 96     in_buffer("/lw {setlinewidth} def ");
 97     in_buffer("/rgb {setrgbcolor} def ");
 98     in_buffer("/ss {[] 0 setdash} def ");     // style solid.
 99     in_buffer("/sd {[12 6] 0 setdash} def "); // style dashed
100     in_buffer("/so {[6 12] 0 setdash} def "); // style dotted
101     in_buffer("/sdo {[18 12 6 12] 0 setdash} def "); // dash dotted
102     // Mark :
103     m_markSize = 2.;
104     in_buffer("/ms 2. def /msi .5 def ");        // mark size
105     in_buffer("/cross {ms ms scale -1. -1. rm  ");
106     in_buffer ("2. 2. rl 0. -2. rm -2. 2. rl msi msi scale} def ");
107     in_buffer("/plus  {ms ms scale -1. 0. rm 2. 0. rl ");
108     in_buffer("-1. 1. rm 0. -2. rl msi msi scale} def ");
109     in_buffer("/asterisk {ms ms scale -1. 0. rm 2. 0. rl -1. 1. rm ");
110     in_buffer("0. -2. rl 0. 1. rm -0.707 -0.707 rm 1.414 1.414 rl ");
111     in_buffer("0. -1.414 rm -1.414 1.414 rl msi msi scale} def ");
112     in_buffer("/star {ms ms scale 0. 1. rm -0.6 -1.5 rl ");
113     in_buffer("1.2 0. rl -0.6 1.5 rl msi msi scale} def ");
114     // Text :
115     in_buffer("/sh {show} def ");
116     in_buffer("/df {/Courier-Bold findfont} def ");
117     in_buffer("/mf {makefont setfont} def ");
118 */
119 
120     PrintFLN("%%%%EndProlog");
121 
122     return true;
123   }
124 
125   bool close_file(){
126     if(!m_file) return false;
127     PS_RESTORE();
128     PrintFLN("%%%%Trailer");
129     PrintFLN("%%%%Pages: %d",m_pageNumber);
130     PrintFLN("%%%%EOF");
131     ::fclose(m_file);
132     m_file = 0;
133     m_fname.clear();
134     return true;
135   }
136 
137   void PS_PAGE_SCALE(float a_width,float a_height,bool a_portrait = true){
138     //NOTE : no check done on [a_width,a_height]<=0
139 
140     PS_SCALE(1/METAFILE_SCALE(),1/METAFILE_SCALE());
141     PS_TRANSLATE(m_deviceWidth/20,m_deviceHeight/30);
142 
143     float scale;
144     if(m_deviceWidth<=m_deviceHeight) {
145       scale = (a_height<=a_width?m_deviceWidth/a_width:m_deviceWidth/a_height);
146     } else {
147       scale = (a_height<=a_width?m_deviceHeight/a_width:m_deviceHeight/a_height);
148     }
149 
150    {float xtra,ytra;
151     if(a_portrait) {
152       xtra = (m_deviceWidth  - scale * a_width)/2;
153       ytra = (m_deviceHeight - scale * a_height)/2;
154     } else {
155       PS_TRANSLATE(m_deviceWidth,0);
156       PS_ROTATE(90);
157       xtra = (m_deviceHeight - scale * a_width)/2;
158       ytra = (m_deviceWidth  - scale * a_height)/2;
159     }
160     PS_TRANSLATE(xtra,ytra);}
161 
162     PS_SCALE(scale,scale);
163   }
164 
165   void PS_SCALE(float a_x,float a_y) {
166     in_buffer("%.2f %.2f scale ",a_x,a_y);
167   }
168 
169   void PS_TRANSLATE(float a_x,float a_y){
170     in_buffer("%.2f %.2f translate ",a_x,a_y);
171   }
172 
173   void PS_ROTATE(float a_x){in_buffer("%.2f rotate ",a_x);}
174 
175   void PS_SAVE(){in_buffer("gsave ");m_gsave++;}
176 
177   void PS_RESTORE(){in_buffer("grestore ");m_gsave--;}
178 
179   void PS_BEGIN_PAGE(){
180     m_pageNumber++;
181     PrintFLN("%%%%Page: %d %d",m_pageNumber,m_pageNumber);
182     PS_SAVE();
183   }
184 
185   void PS_END_PAGE(){
186     in_buffer("showpage ");
187     PS_RESTORE();
188   }
189 
190   enum rgb_nbit {
191     rgb_bw = 0,
192     rgb_2 = 2,
193     rgb_4 = 4,
194     rgb_8 = 8
195   };
196 
197   void PS_IMAGE(Uint a_width,Uint a_height,rgb_nbit a_nbit,rgb_func a_proc,void* a_tag){
198     //NOTE : no check done on [a_width,a_height] being zero.
199 
200     Uint   row,col;
201     VCol   dr,dg,db;
202     Uchar  red,green,blue,b;
203 
204     PS_SAVE();
205     in_buffer("%d %d scale ", a_width, a_height );
206     bool status = true;
207     if(a_nbit==rgb_bw) { //grey or black_white
208       in_buffer   ("/picstr %d string def ",a_width);
209       in_buffer   ("%d %d %d ",a_width,a_height,8);
210       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
211       in_buffer   ("{ currentfile picstr readhexstring pop } " );
212       PrintFLN ("image " );
213       for ( row = 0; row < a_height; row++ ) {
214         for ( col = 0; col < a_width; col++) {
215           status = a_proc(a_tag,col,row,dr,dg,db)?status:false;
216           VCol fgrey = rgb2grey(dr,dg,db);
217           Uchar grey = (Uchar) ( 255.0F * fgrey);
218           WriteByte(grey);
219         }
220       }
221       int nbhex = a_width * a_height * 2;
222       PrintFLN ("%%%% nbhex digit          :%d ",nbhex);
223       PrintFLN ("%%%% nbhex/record_length  :%d ",
224                 int(nbhex/METAFILE_RECORD_LENGTH()));
225       PrintFLN ("%%%% nbhex%%record_length :%d ",
226                 int(nbhex%METAFILE_RECORD_LENGTH()));
227 
228     } else if(a_nbit==rgb_2) {
229       int nbyte2 = (a_width   *  3)/4;
230       nbyte2 /=3;
231       nbyte2 *=3;
232       Uint col_max = (nbyte2  *  4)/3;
233       // 2 bit for r and g and b.
234       // rgbs following each other.
235       in_buffer   ("/rgbstr %d string def ",nbyte2);
236       in_buffer   ("%d %d %d ",col_max,a_height,2);
237       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
238       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
239       in_buffer   ("false 3 " );
240       PrintFLN ("colorimage " );
241       for ( row = 0; row < a_height; row++ ) {
242         for ( col = 0; col < col_max; col+=4) {
243           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
244           red     = (Uchar) ( 3.0F * dr);
245           green   = (Uchar) ( 3.0F * dg);
246           blue    = (Uchar) ( 3.0F * db);
247           b       = red;
248           b       = (b<<2)+green;
249           b       = (b<<2)+blue;
250 
251           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
252           red     = (Uchar) ( 3.0F * dr);
253           green   = (Uchar) ( 3.0F * dg);
254           blue    = (Uchar) ( 3.0F * db);
255           b       = (b<<2)+red;
256           WriteByte(b);
257 
258           b       = green;
259           b       = (b<<2)+blue;
260 
261           status  = a_proc(a_tag,col+2,row,dr,dg,db)?status:false;
262           red     = (Uchar) ( 3.0F * dr);
263           green   = (Uchar) ( 3.0F * dg);
264           blue    = (Uchar) ( 3.0F * db);
265           b     = (b<<2)+red;
266           b     = (b<<2)+green;
267           WriteByte(b);
268           b       = blue;
269 
270           status  = a_proc(a_tag,col+3,row,dr,dg,db)?status:false;
271           red     = (Uchar) ( 3.0F * dr);
272           green   = (Uchar) ( 3.0F * dg);
273           blue    = (Uchar) ( 3.0F * db);
274           b     = (b<<2)+red;
275           b     = (b<<2)+green;
276           b     = (b<<2)+blue;
277           WriteByte(b);
278         }
279       }
280 
281     } else if(a_nbit==rgb_4) {
282       int nbyte4 = (a_width  * 3)/2;
283       nbyte4 /=3;
284       nbyte4 *=3;
285       Uint col_max = (nbyte4 * 2)/3;
286       // 4 bit for r and g and b.
287       // rgbs following each other.
288       in_buffer   ("/rgbstr %d string def ",nbyte4);
289       in_buffer   ("%d %d %d ",col_max,a_height,4);
290       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",col_max,a_height,a_height);
291       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
292       in_buffer   ("false 3 " );
293       PrintFLN ("colorimage " );
294       for ( row = 0; row < a_height; row++ ) {
295         for ( col = 0; col < col_max; col+=2) {
296           status  = a_proc(a_tag,col,row,dr,dg,db)?status:false;
297           red     = (Uchar) ( 15.0F * dr);
298           green   = (Uchar) ( 15.0F * dg);
299           in_buffer ("%x%x",red,green);
300           blue    = (Uchar) ( 15.0F * db);
301 
302           status  = a_proc(a_tag,col+1,row,dr,dg,db)?status:false;
303           red     = (Uchar) ( 15.0F * dr);
304           in_buffer ("%x%x",blue,red);
305           green   = (Uchar) ( 15.0F * dg);
306           blue    = (Uchar) ( 15.0F * db);
307           in_buffer ("%x%x",green,blue);
308         }
309       }
310 
311     } else if(a_nbit==rgb_8) {
312       int nbyte8 = a_width   * 3;
313       // 8 bit for r and g and b.
314       in_buffer   ("/rgbstr %d string def ",nbyte8);
315       in_buffer   ("%d %d %d ",a_width,a_height,8);
316       in_buffer   ("[ %d 0 0 -%d 0 %d ] ",a_width,a_height,a_height);
317       in_buffer   ("{ currentfile rgbstr readhexstring pop } " );
318       in_buffer   ("false 3 " );
319       PrintFLN   ("colorimage " );
320       for ( row = 0; row < a_height; row++ ) {
321         for ( col = 0; col < a_width; col++) {
322           status     = a_proc(a_tag,col,row,dr,dg,db)?status:false;
323           red        = (Uchar) ( 255.0F * dr);
324           WriteByte (red);
325           green      = (Uchar) ( 255.0F * dg);
326           WriteByte (green);
327           blue       = (Uchar) ( 255.0F * db);
328           WriteByte (blue);
329         }
330       }
331     } else {
332       m_out << "PS_IMAGE :"
333             << " unknown rgb nbit " << a_nbit
334             << std::endl;
335     }
336     if(!status) {
337       m_out << "PS_IMAGE :"
338             << " problem to retrieve some pixel rgb."
339             << std::endl;
340     }
341     PS_RESTORE();
342   }
343 
344 protected:
345   static size_t METAFILE_RECORD_LENGTH() {return 80;}
346 
347   static float METAFILE_SCALE() {return 1.0f;}
348 
349   static char* get_date(){
350     char*  string;
351     time_t d;
352     ::time(&d);
353     string = ::ctime(&d);
354     string[24] = '\0';
355     return string;
356   }
357 
358   static VCol rgb2grey(VCol a_red,VCol a_green,VCol a_blue){
359     return (0.30f * a_red + 0.59f * a_green + 0.11f * a_blue);
360   }
361 
362   bool in_buffer(const char* a_format,...){
363     va_list args;
364     va_start(args,a_format);
365     bool status = vsprintf(m_string,2048,a_format,args);
366     va_end(args);
367     if(!status) {
368       m_out << "tools::wps::in_buffer : overflow." << std::endl;
369       return false;
370     }
371 
372     size_t length = m_string.size();
373     if(length>METAFILE_RECORD_LENGTH()) {
374       m_out << "tools::wps::in_buffer : overflow." << std::endl;
375       return false;
376     }
377 
378     size_t nlength = m_number + length;
379     if(nlength>METAFILE_RECORD_LENGTH()) {
380       m_buffer[m_number] = '\0';
381       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
382         m_out << "tools::wps::in_buffer : fprintf failed." << std::endl;
383       }
384       m_number = 0;
385       nlength = length;
386     }
387     Uchar* pointer = m_buffer + m_number;
388     ::strcpy((char*)pointer,m_string.c_str());
389     m_number = nlength;
390     return true;
391   }
392 
393   bool PrintFLN(const char* a_format,...){
394     va_list args;
395     va_start(args,a_format);
396     bool status = vsprintf(m_string,2048,a_format,args);
397     va_end(args);
398     if(!status) {
399       m_out << "tools::wps::PrintFLN : overflow." << std::endl;
400       return false;
401     }
402 
403     // put buffer in file :
404     if(m_number>0) {
405       m_buffer[m_number] = '\0';
406       if(::fprintf(m_file,"%s\n",(char*)m_buffer)<0) {
407         m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
408       }
409       m_number = 0;
410     }
411     if(::fprintf(m_file,"%s\n",m_string.c_str())<0) {
412       m_out << "tools::wps::PrintFLN : fprintf failed." << std::endl;
413     }
414 
415     return true;
416   }
417 
418   void WriteByte(Uchar a_byte){
419     Uchar h = a_byte / 16;
420     Uchar l = a_byte % 16;
421     in_buffer("%x%x",h,l);
422   }
423 
424 protected:
425   std::ostream& m_out;
426   float         m_deviceWidth;
427   float         m_deviceHeight;
428   unsigned int  m_pageNumber;
429 //double        m_markSize;
430   FILE*         m_file;
431   std::string   m_fname;
432   std::string   m_string;
433   int           m_gsave;
434   Uchar*        m_buffer;
435   size_t        m_number;
436 //struct {
437 //  int shade;
438 //  int nbit;
439 //} m_param;
440 };
441 
442 }
443 
444 #endif
445 
446 /*
447   enum {
448     shade_color = 0,
449     shade_grey = 1,
450     shade_black_white = 2
451   };
452 
453   void PS_BACKGROUND(double a_r,double a_g,double a_b,
454                      double a_width,double a_height,
455                      bool a_do_back = true){
456     PS_NEWPATH();
457     PS_MOVE       (0.,0.);
458     PS_RLINETO    (a_width,0.);
459     PS_RLINETO    (0.,a_height);
460     PS_RLINETO    (-a_width,0.);
461     PS_RLINETO    (0.,-a_height);
462     PS_CLOSEPATH();
463     if(a_do_back) {
464       PS_SAVE();
465       PS_RGB(a_r,a_g,a_b);
466       PS_FILL();
467       PS_RESTORE();
468     }
469     in_buffer("clip ");
470   }
471 
472   void PS_RGB(double a_r,double a_g,double a_b){
473     if(m_param.shade==shade_color)
474       in_buffer("%.2f %.2f %.2f rgb ",a_r,a_g,a_b);
475     else if(m_param.shade==shade_grey)
476       in_buffer("%.2f setgray ",rgb2grey(a_r,a_g,a_b));
477     else if(m_param.shade==shade_black_white)
478       in_buffer("0. setgray ",rgb2grey(a_r,a_g,a_b));
479   }
480 
481   void PS_LINE_WIDTH(int a_width){in_buffer("%.1f lw ",float(a_width));}
482 
483   void PS_NEWPATH() {in_buffer("n ");}
484   void PS_STROKE() {in_buffer("s ");}
485   void PS_FILL() {in_buffer("f ");}
486   void PS_CLOSEPATH() {in_buffer("cl ");}
487   void PS_CAP(double a_x) {in_buffer ("%1d lc ",a_x);}
488   void PS_RLINETO(double a_x,double a_y) {
489     in_buffer ("%.2f %.2f rl ",a_x,a_y);
490   }
491   void PS_MOVE(double a_x,double a_y) {
492     in_buffer ("%.2f %.2f m ",a_x,a_y);
493   }
494 
495   void PS_FRAME(double a_r,double a_g,double a_b,
496                 double a_width,double a_height){
497     PS_NEWPATH   ();
498     PS_MOVE      (0.,0.);
499     PS_RLINETO   (a_width,0.);
500     PS_RLINETO   (0.,a_height);
501     PS_RLINETO   (-a_width,0.);
502     PS_RLINETO   (0.,-a_height);
503     PS_CLOSEPATH ();
504     PS_RGB       (a_r,a_g,a_b);
505     PS_LINE_WIDTH(1);
506     PS_CAP       (1);
507     in_buffer    ("ss ");
508     PS_STROKE();
509   }
510 */