26 #ifdef G4VIS_BUILD_OI_DRIVER 
   35 #include <HEPVis/SbPainterPS.h> 
   38 #define STRDUP(str)  ((str) != NULL ? (::strcpy((char*)::malloc((unsigned)::strlen(str) + 1), str)) : (char*)NULL) 
   39 #define STRDEL(str) {if((str)!=NULL) {::free(str);str=NULL;}} 
   49 #define METAFILE_DEFAULT "out.ps" 
   50 #define METAFILE_SCALE 1. 
   52 static char* GetDate();
 
   53 static double ConvertRGB_ToGrey(
double,
double,
double);
 
   55 SbPainterPS::SbPainterPS(
 
   57 :fDeviceWidth((8.5-1.) * 72. * METAFILE_SCALE) 
 
   58 ,fDeviceHeight(11.     * 72. * METAFILE_SCALE) 
 
   69   fParams.shade = 
Color;
 
   73   fParams.lineWidth = -1.;
 
   74   fBufferPointer[0] = 
'\0';
 
   76   ::setlocale(LC_NUMERIC,
"USA");
 
   80 SbPainterPS::~SbPainterPS(
 
   85   if(fFile!=NULL) closeStream ();
 
   86   if(fBufferString!=NULL) 
::free(fBufferString);
 
   89     ::printf(
"SbPainterPS : bad gsave/grestore balance : %d.\n",fGSave);
 
   95 void SbPainterPS::beginTraversal (
 
  100   if(fFile==NULL) openFileForWriting(NULL);
 
  101   if(fFile==NULL) 
return;
 
  102   putBeginPageInStream();
 
  103   putPageScaleInStream((
float)fWindowWidth,(
float)fWindowHeight);
 
  104   putSaveStateInStream();
 
  107 void SbPainterPS::endTraversal(
 
  112   if(fFile==NULL) 
return;
 
  113   putFrameInStream(0.0,0.0,0.0,(
float)fWindowWidth,(
float)fWindowHeight);
 
  114   putRestoreStateInStream();
 
  115   putEndPageInStream();
 
  118 void SbPainterPS::clearColorBuffer(
 
  126   if(fFile==NULL) 
return;
 
  127   putBackgroundInStream(aRed,aGreen,aBlue,
 
  128                            (
float)fWindowWidth,(
float)fWindowHeight);
 
  292 void SbPainterPS::setColorScheme(
 
  298   fParams.shade = aShade;
 
  301 void SbPainterPS::setOrientation(
 
  307   fParams.portrait = aPortrait;
 
  310 void SbPainterPS::setBackgroundDrawn(
 
  316   fParams.doBack = aDoback;
 
  319 void SbPainterPS::setBitsPerPixel(
 
  325   if( (aNbit==2) || (aNbit==4) || (aNbit==8) )
 
  326     fParams.nbit = aNbit;
 
  331 void SbPainterPS::setLineWidth(
 
  337   fParams.lineWidth = (float)aWidth;
 
  342 void SbPainterPS::setFileName(
 
  349   fFileName = 
STRDUP(aString);
 
  352 const char* SbPainterPS::getFileName(
 
  360 void* SbPainterPS::getStream(
 
  368 void SbPainterPS::openFileForWriting(
 
  374   if(fFile!=NULL) closeStream ();
 
  375   if( (aString==NULL) || (*aString==
'\0') ) {
 
  376     if( (fFileName==NULL) || (*fFileName==
'\0') ) { 
 
  377       fFile = ::fopen(METAFILE_DEFAULT,
"wb");
 
  379       fFileName = 
STRDUP(METAFILE_DEFAULT);
 
  381       fFile = ::fopen(fFileName,
"wb");
 
  384     fFile = ::fopen(aString,
"wb");
 
  386     fFileName = 
STRDUP(aString);
 
  388   if(fFile==NULL) 
return;
 
  391   fBufferPointer[METAFILE_RECORD_LENGTH] = 
'\0';
 
  394   printFLN   (
"%%!PS-Adobe-2.0");
 
  395   printFLN   (
"%%%%Creator: HEPVis::SbPainterPS.");
 
  396   printFLN(
"%%%%CreationDate: %s",GetDate());
 
  397   printFLN(
"%%%%Title: %s",fFileName);
 
  398   printFLN(
"%%%%Pages: (atend)");
 
  399   printFLN(
"%%%%BoundingBox: 0 0 %d %d",
 
  400            (
int)fDeviceWidth,(
int)fDeviceHeight);
 
  401   printFLN(
"%%%%DocumentFonts: Courier-Bold");
 
  402   printFLN(
"%%%%DocumentPaperSizes: a4");
 
  403   printFLN(
"%%%%EndComments");
 
  405   putSaveStateInStream      ();
 
  407   putInStreamF(
"/n {newpath} def ");
 
  408   putInStreamF(
"/cl {closepath} def ");
 
  409   putInStreamF(
"/s {stroke} def ");
 
  410   putInStreamF(
"/f {fill} def ");
 
  412   putInStreamF(
"/m  {moveto} def ");
 
  413   putInStreamF(
"/rm {rmoveto} def ");
 
  414   putInStreamF(
"/rl {rlineto} def ");
 
  416   putInStreamF(
"/lc {setlinecap} def ");
 
  417   putInStreamF(
"/lw {setlinewidth} def ");
 
  418   putInStreamF(
"/rgb {setrgbcolor} def ");
 
  419   putInStreamF(
"/ss {[] 0 setdash} def ") ;            
 
  420   putInStreamF(
"/sd {[12 6] 0 setdash} def ");         
 
  421   putInStreamF(
"/so {[6 12] 0 setdash} def ");         
 
  422   putInStreamF(
"/sdo {[18 12 6 12] 0 setdash} def ");  
 
  425   putInStreamF(
"/ms 2. def /msi .5 def ");        
 
  426   putInStreamF(
"/cross {ms ms scale -1. -1. rm  ");
 
  427   putInStreamF(
"2. 2. rl 0. -2. rm -2. 2. rl msi msi scale} def ");
 
  428   putInStreamF(
"/plus  {ms ms scale -1. 0. rm 2. 0. rl ");
 
  429   putInStreamF(
"-1. 1. rm 0. -2. rl msi msi scale} def ");
 
  430   putInStreamF(
"/asterisk {ms ms scale -1. 0. rm 2. 0. rl -1. 1. rm ");
 
  431   putInStreamF(
"0. -2. rl 0. 1. rm -0.707 -0.707 rm 1.414 1.414 rl ");
 
  432   putInStreamF(
"0. -1.414 rm -1.414 1.414 rl msi msi scale} def ");
 
  433   putInStreamF(
"/triangle {ms ms scale 0. 1. rm -0.6 -1.5 rl ");
 
  434   putInStreamF(
"1.2 0. rl -0.6 1.5 rl msi msi scale} def ");
 
  436   putInStreamF(
"/sh {show} def ");
 
  437   putInStreamF(
"/df {/Courier-Bold findfont} def ");
 
  438   putInStreamF(
"/mf {makefont setfont} def ");
 
  439   printFLN(
"%%%%EndProlog");
 
  442 void SbPainterPS::closeStream(
 
  447   if(fFile==NULL) 
return;
 
  448   putRestoreStateInStream    ();
 
  449   printFLN(
"%%%%Trailer");
 
  450   printFLN(
"%%%%Pages: %d",fPageNumber);
 
  452   if(fFile!=NULL) ::fclose(fFile);
 
  458 void SbPainterPS::putInStreamF(
 
  465   if(fFile==NULL) 
return;
 
  467   va_start(args,aFormat);
 
  468   printV(aFormat,args);
 
  470   int length = ::strlen(fBufferString);
 
  471   if(length>METAFILE_RECORD_LENGTH) {
 
  472     ::printf(
"SoPostScript::putInStreamF overflow\n");
 
  475   int nlength = fBufferCount + length;
 
  476   if(nlength>METAFILE_RECORD_LENGTH) {
 
  477       fBufferPointer[fBufferCount] = 
'\0';
 
  478       if(::fprintf(fFile,
"%s\n",(
char*)fBufferPointer)<0) {
 
  479         ::printf(
"SoPostScript::putInStreamF fprintf error\n");
 
  484   unsigned char* pointer = fBufferPointer + fBufferCount;
 
  485   ::strcpy((
char*)pointer,fBufferString);
 
  486   fBufferCount = nlength;
 
  489 void SbPainterPS::printFLN(
 
  496   if(fFile==NULL) 
return;
 
  498   va_start(args,aFormat);
 
  499   printV(aFormat,args);
 
  503     fBufferPointer[fBufferCount] = 
'\0';
 
  504     if(::fprintf (fFile,
"%s\n",(
char*)fBufferPointer)<0) {
 
  505       ::printf(
"SbPainterPS::printFLN fprintf error\n");
 
  510   if(::fprintf (fFile,
"%s\n",fBufferString)<0) {
 
  511     ::printf(
"SbPainterPS::printFLN fprintf error\n");
 
  515 void SbPainterPS::printV(
 
  523   if(fBufferString==NULL) {
 
  524     fBufferString = (
char*)::
malloc(MAX_STR * 
sizeof(
char));
 
  525     if(fBufferString==NULL) 
return;
 
  527   fBufferString[MAX_STR-1]  = 
'\0';
 
  528   ::vsprintf(fBufferString,This,aArgs);
 
  529   if(fBufferString[MAX_STR-1]!=
'\0') {
 
  530     ::printf(
"SbPainterPS::printV overflow\n");
 
  531     fBufferString[0] = 
'\0';
 
  538 void SbPainterPS::putPageScaleInStream(
 
  545   if(aWidth <=0.) aWidth  = 100.;
 
  546   if(aHeight<=0.) aHeight = 100.;
 
  548   putScaleInStream (1./METAFILE_SCALE,1./METAFILE_SCALE);
 
  549   putTranslationInStream ((
float)(fDeviceWidth/20.),
 
  550                           (
float)(fDeviceHeight/30.));
 
  553   if(fDeviceWidth<=fDeviceHeight)
 
  554     scale = (aHeight<=aWidth ? 
 
  555              fDeviceWidth /aWidth  : fDeviceWidth /aHeight );
 
  557     scale = (aHeight<=aWidth ? 
 
  558              fDeviceHeight /aWidth : fDeviceHeight /aHeight );
 
  561   if(fParams.portrait==1) {
 
  562     xtra = (fDeviceWidth  - scale * aWidth)/2;
 
  563     ytra = (fDeviceHeight - scale * aHeight)/2;
 
  565     putTranslationInStream(fDeviceWidth,0.);
 
  566     putRotateInStream(90);
 
  567     xtra = (fDeviceHeight  - scale * aWidth)/2;
 
  568     ytra = (fDeviceWidth   - scale * aHeight)/2;
 
  570   putTranslationInStream (xtra,ytra);
 
  572   putScaleInStream (scale,scale);
 
  578 void SbPainterPS::putSaveStateInStream(
 
  583   putInStreamF(
"gsave ");
 
  587 void SbPainterPS::putRestoreStateInStream(
 
  592   putInStreamF(
"grestore ");
 
  596 void SbPainterPS::putTranslationInStream(
 
  603   putInStreamF(
"%.2f %.2f translate ",aX,aY);
 
  606 void SbPainterPS::putScaleInStream(
 
  613   putInStreamF(
"%.2f %.2f scale ",aX,aY);
 
  616 void SbPainterPS::putBeginPageInStream(
 
  622   printFLN(
"%%%%Page: %d %d",fPageNumber,fPageNumber);
 
  623   putSaveStateInStream();
 
  626 void SbPainterPS::putEndPageInStream (
 
  631   putInStreamF(
"showpage ");
 
  632   putRestoreStateInStream();
 
  635 void SbPainterPS::putRGB_InStream (
 
  643   if(fParams.shade==
Color)       
 
  644     putInStreamF(
"%.2f %.2f %.2f rgb ",aR,aG,aB);
 
  645   else if(fParams.shade==Grey)
 
  646     putInStreamF(
"%.2f setgray ",convertRGB_ToGrey(aR,aG,aB));
 
  647   else if(fParams.shade==BlackWhite)  
 
  648     putInStreamF(
"0. setgray ",convertRGB_ToGrey(aR,aG,aB));
 
  651 void SbPainterPS::putLineWidthInStream(
 
  657   if(fParams.lineWidth<0.) {
 
  659       putInStreamF(
"%.1f lw ",0.5); 
 
  661       putInStreamF(
"%.1f lw ",(
float)(aWidth));
 
  664     putInStreamF(
"%.1f lw ",fParams.lineWidth); 
 
  668 void SbPainterPS::putMarkerSizeInStream (
 
  674   if(aSize==fMarkerSize) 
return;
 
  676   putInStreamF(
"/ms %g def /msi %g def ",aSize,1./aSize);
 
  707 void SbPainterPS::putBackgroundInStream (
 
  717   putNewPathInStream(); 
 
  718   putMoveInStream(0.,0.);
 
  719   putLineToInStream(aWidth,0.);
 
  720   putLineToInStream(0.,aHeight);
 
  721   putLineToInStream(-aWidth,0.);
 
  722   putLineToInStream(0.,-aHeight);
 
  723   putClosePathInStream();
 
  724   if(fParams.doBack==1) {
 
  726     putSaveStateInStream();
 
  727     putRGB_InStream(aR,aG,aB);
 
  729     putRestoreStateInStream();
 
  732   putInStreamF(
"clip ");
 
  735 void SbPainterPS::putFrameInStream (
 
  745   putNewPathInStream(); 
 
  746   putMoveInStream(0.,0.);
 
  747   putLineToInStream(aWidth,0.);
 
  748   putLineToInStream(0.,aHeight);
 
  749   putLineToInStream(-aWidth,0.);
 
  750   putLineToInStream(0.,-aHeight);
 
  751   putClosePathInStream();
 
  752   putRGB_InStream(aR,aG,aB);
 
  753   putLineWidthInStream(1);
 
  759 float SbPainterPS::convertRGB_ToGrey (
 
  767   return (0.3F * aRed + 0.59F * aGreen + 0.11F * aBlue);
 
  770 void SbPainterPS::putRotateInStream(
 
  776   putInStreamF(
"%.2f  rotate ",aX);
 
  779 void SbPainterPS::putNewPathInStream(
 
  787 void SbPainterPS::putStrokeInStream(
 
  795 void SbPainterPS::putFillInStream(
 
  803 void SbPainterPS::putClosePathInStream(
 
  811 void SbPainterPS::putCapInStream(
 
  817   putInStreamF(
"%1d lc ",aX);
 
  820 void SbPainterPS::putLineToInStream(
 
  827   putInStreamF (
"%.2f %.2f rl ",aX,aY);
 
  830 void SbPainterPS::putMoveInStream(
 
  837   putInStreamF (
"%.2f %.2f m ",aX,aY);
 
  840 void SbPainterPS::putCircleInStream(
 
  848   putInStreamF(
"%.2f %.2f %.2f 0 360 arc s ",aX,aY,aR);
 
  871 void SbPainterPS::putImageInStream (
 
  873 ,
unsigned int aHeight
 
  874 ,GetRGB_Function aProc
 
  879   if((aWidth<=0)||(aHeight<=0)) 
return;
 
  882   putSaveStateInStream      ();
 
  883   putInStreamF     (
"%d %d scale ", aWidth, aHeight ); 
 
  886   unsigned int row,col,col_max;
 
  888   typedef unsigned char Uchar;
 
  890   if(fParams.shade!=0) { 
 
  891     putInStreamF   (
"/picstr %d string def ",aWidth); 
 
  892     putInStreamF   (
"%d %d %d ",aWidth,aHeight,8); 
 
  893     putInStreamF   (
"[ %d 0 0 -%d 0 %d ] ",aWidth,aHeight,aHeight); 
 
  894     putInStreamF   (
"{ currentfile picstr readhexstring pop } " );
 
  895     printFLN (
"image " );
 
  896     for ( row = 0; row < aHeight; row++ ){
 
  897       for ( col = 0; col < aWidth; col++){ 
 
  900         status    = aProc(col,row,dr,dg,db)==0 ? 0 : status;
 
  901         fgrey     = ConvertRGB_ToGrey(dr,dg,db);
 
  902         grey      = (Uchar) ( 255. * fgrey);
 
  906     nbhex     = aWidth * aHeight * 2; 
 
  907     printFLN (
"%%%% nbhex digit          :%d ",nbhex); 
 
  908     printFLN (
"%%%% nbhex/record_length  :%d ",nbhex/METAFILE_RECORD_LENGTH); 
 
  909     printFLN (
"%%%% nbhex%%record_length :%d ",nbhex%METAFILE_RECORD_LENGTH); 
 
  910   }
else if(fParams.nbit==2){ 
 
  912     nbyte2    = (aWidth   *  3)/4;
 
  915     col_max   = (nbyte2  *  4)/3;
 
  918     putInStreamF   (
"/rgbstr %d string def ",nbyte2); 
 
  919     putInStreamF   (
"%d %d %d ",col_max,aHeight,2); 
 
  920     putInStreamF   (
"[ %d 0 0 -%d 0 %d ] ",col_max,aHeight,aHeight); 
 
  921     putInStreamF   (
"{ currentfile rgbstr readhexstring pop } " );
 
  922     putInStreamF   (
"false 3 " );
 
  923     printFLN (
"colorimage " );
 
  924     for ( row = 0; row < aHeight; row++ ){
 
  925       for ( col = 0; col < col_max; col+=4){
 
  926         status  = aProc(col,row,dr,dg,db)==0 ? 0 : status;
 
  927         red     = (Uchar) ( 3. * dr);
 
  928         green   = (Uchar) ( 3. * dg);
 
  929         blue    = (Uchar) ( 3. * db);
 
  933         status  = aProc(col+1,row,dr,dg,db)==0 ? 0 : status;
 
  934         red     = (Uchar) ( 3. * dr);
 
  935         green   = (Uchar) ( 3. * dg);
 
  936         blue    = (Uchar) ( 3. * db);
 
  942         status  = aProc(col+2,row,dr,dg,db)==0 ? 0 : status;
 
  943         red     = (Uchar) ( 3. * dr);
 
  944         green   = (Uchar) ( 3. * dg);
 
  945         blue    = (Uchar) ( 3. * db);
 
  951         status  = aProc(col+3,row,dr,dg,db)==0 ? 0 : status;
 
  952         red     = (Uchar) ( 3. * dr);
 
  953         green   = (Uchar) ( 3. * dg);
 
  954         blue    = (Uchar) ( 3. * db);
 
  961   }
else if(fParams.nbit==4){ 
 
  963     nbyte4    = (aWidth  * 3)/2;
 
  966     col_max   = (nbyte4 * 2)/3;
 
  969     putInStreamF   (
"/rgbstr %d string def ",nbyte4); 
 
  970     putInStreamF   (
"%d %d %d ",col_max,aHeight,4); 
 
  971     putInStreamF   (
"[ %d 0 0 -%d 0 %d ] ",col_max,aHeight,aHeight); 
 
  972     putInStreamF   (
"{ currentfile rgbstr readhexstring pop } " );
 
  973     putInStreamF   (
"false 3 " );
 
  974     printFLN (
"colorimage " );
 
  975     for ( row = 0; row < aHeight; row++ ){
 
  976       for ( col = 0; col < col_max; col+=2){
 
  977         status  = aProc(col,row,dr,dg,db)==0 ? 0 : status;
 
  978         red     = (Uchar) ( 15. * dr);
 
  979         green   = (Uchar) ( 15. * dg);
 
  980         putInStreamF (
"%x%x",red,green);
 
  981         blue    = (Uchar) ( 15. * db);
 
  983         status  = aProc(col+1,row,dr,dg,db)==0 ? 0 : status;
 
  984         red     = (Uchar) ( 15. * dr);
 
  985         putInStreamF (
"%x%x",blue,red);
 
  986         green   = (Uchar) ( 15. * dg);
 
  987         blue    = (Uchar) ( 15. * db);
 
  988         putInStreamF (
"%x%x",green,blue);
 
  995     putInStreamF   (
"/rgbstr %d string def ",nbyte8); 
 
  996     putInStreamF   (
"%d %d %d ",aWidth,aHeight,8); 
 
  997     putInStreamF   (
"[ %d 0 0 -%d 0 %d ] ",aWidth,aHeight,aHeight); 
 
  998     putInStreamF   (
"{ currentfile rgbstr readhexstring pop } " );
 
  999     putInStreamF   (
"false 3 " );
 
 1000     printFLN   (
"colorimage " );
 
 1001     for ( row = 0; row < aHeight; row++ ){
 
 1002       for ( col = 0; col < aWidth; col++){
 
 1003         status     = aProc(col,row,dr,dg,db)==0 ? 0 : status;
 
 1004         red        = (Uchar) ( 255. * dr);
 
 1006         green      = (Uchar) ( 255. * dg);
 
 1008         blue       = (Uchar) ( 255. * db);
 
 1014     ::printf(
"SbPainterPS::putImageInStream: problem to retreive some pixel rgb.\n");
 
 1015   putRestoreStateInStream();
 
 1018 void SbPainterPS::writeByte (
 
 1019  unsigned char a_byte
 
 1024   unsigned char h = a_byte / 16;
 
 1025   unsigned char l = a_byte % 16;
 
 1026   putInStreamF (
"%x%x",h,l);
 
 1039   char* 
string = ctime(&d);
 
 1044 double ConvertRGB_ToGrey(
 
 1052   return (0.30 * a_red + 0.59 * a_green + 0.11 * a_blue);
 
void * malloc(size_t __size)