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);