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 */