ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SbPainterPS.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SbPainterPS.cc
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 #ifdef G4VIS_BUILD_OI_DRIVER
27 
28 /*----------------------------HEPVis----------------------------------------*/
29 /* */
30 /* Node: SbPainterPS */
31 /* Author: Guy Barrand */
32 /* */
33 /*--------------------------------------------------------------------------*/
34 // this :
35 #include <HEPVis/SbPainterPS.h>
36 
37 //#include <HEPVis/SbString.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;}}
40 
41 //#define DEBUG
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include <stdarg.h>
46 #include <time.h>
47 #include <locale.h>
48 
49 #define METAFILE_DEFAULT "out.ps"
50 #define METAFILE_SCALE 1.
51 
52 static char* GetDate();
53 static double ConvertRGB_ToGrey(double,double,double);
56 )
57 :fDeviceWidth((8.5-1.) * 72. * METAFILE_SCALE) /* 540. * METAFILE_SCALE */
58 ,fDeviceHeight(11. * 72. * METAFILE_SCALE) /* 792. * METAFILE_SCALE */
59 ,fPageNumber(0)
60 ,fMarkerSize(2.)
61 ,fFile(NULL)
62 ,fFileName(NULL)
63 ,fGSave(0)
64 ,fBufferCount(0)
65 ,fBufferString(NULL)
68 {
69  fParams.shade = Color;
70  fParams.portrait = 1;
71  fParams.nbit = 2;
72  fParams.doBack = 1;
73  fParams.lineWidth = -1.;
74  fBufferPointer[0] = '\0';
75 #ifdef WIN32
76  ::setlocale(LC_NUMERIC,"USA");
77 #endif
78 }
81 )
84 {
85  if(fFile!=NULL) closeStream ();
86  if(fBufferString!=NULL) ::free(fBufferString);
87  fBufferString = NULL;
88  if(fGSave!=0) {
89  ::printf("SbPainterPS : bad gsave/grestore balance : %d.\n",fGSave);
90  }
91 }
96 )
99 {
100  if(fFile==NULL) openFileForWriting(NULL);
101  if(fFile==NULL) return;
105 }
108 )
111 {
112  if(fFile==NULL) return;
113  putFrameInStream(0.0,0.0,0.0,(float)fWindowWidth,(float)fWindowHeight);
116 }
119  float aRed
120 ,float aGreen
121 ,float aBlue
122 )
125 {
126  if(fFile==NULL) return;
127  putBackgroundInStream(aRed,aGreen,aBlue,
128  (float)fWindowWidth,(float)fWindowHeight);
129 }
130 /*
132 void SbPainterPS::drawPrimitive (
133  SbPrimitiveType aType
134 ,int aPointn
135 ,float* aXs
136 ,float* aYs
137 ,float* //aZs
138 ,const SbPainterContext& aAtb
139 )
142 {
143  if(fFile==NULL) return;
144  switch(aType) {
145  case SbPrimitivePoints:
146  drawMarkers(aPointn,
147  aXs,aYs,
148  aAtb.fRed,aAtb.fGreen,aAtb.fBlue,
149  aAtb.fMarkerStyle,aAtb.fMarkerSize);
150  break;
151  case SbPrimitiveLineStrip:
152  case SbPrimitiveLineLoop:
153  drawLines(aPointn,
154  aXs,aYs,
155  aAtb.fRed,aAtb.fGreen,aAtb.fBlue,
156  aAtb.fLineStyle,aAtb.fLineWidth);
157  break;
158  case SbPrimitivePolygon:
159  drawPolygon(aPointn,
160  aXs,aYs,
161  aAtb.fRed,aAtb.fGreen,aAtb.fBlue,
162  aAtb.fAreaStyle);
163  break;
164  default:
165  break;
166  }
167 }
169 void SbPainterPS::drawPolygon(
170  int aPointn
171 ,float* aXs
172 ,float* aYs
173 ,float aRed
174 ,float aGreen
175 ,float aBlue
176 ,const SbAreaStyle& //aStyle
177 )
180 {
181  if(fFile==NULL) return;
182  if(aPointn<=0) return;
183  putNewPathInStream();
184  putMoveInStream(aXs[0],aYs[0]);
185  for(int count=1;count<aPointn;count++) {
186  putLineToInStream(aXs[count] - aXs[count-1],
187  aYs[count] - aYs[count-1]);
188  }
189  if ( (aXs[0]==aXs[aPointn-1]) &&
190  (aYs[0]==aYs[aPointn-1]) )
191  putClosePathInStream();
192  putRGB_InStream(aRed,aGreen,aBlue);
193  putFillInStream();
194 }
196 void SbPainterPS::drawLines(
197  int aPointn
198 ,float* aXs
199 ,float* aYs
200 ,float aRed
201 ,float aGreen
202 ,float aBlue
203 ,const SbLineStyle& aStyle
204 ,int aWidth
205 )
208 {
209  if(fFile==NULL) return;
210  if(aPointn<=0) return;
211  putMoveInStream(aXs[0],aYs[0]);
212  for(int count=1;count<aPointn;count++) {
213  putLineToInStream(aXs[count] - aXs[count-1],
214  aYs[count] - aYs[count-1]);
215  }
216  if ( (aXs[0]==aXs[aPointn-1]) &&
217  (aYs[0]==aYs[aPointn-1]) )
218  putClosePathInStream();
219  putRGB_InStream(aRed,aGreen,aBlue);
220  putLineWidthInStream(aWidth);
221  putCapInStream(1);
222  putLineStyleInStream(aStyle);
223  putStrokeInStream();
224 }
226 void SbPainterPS::drawMarkers (
227  int aPointn
228 ,float* aXs
229 ,float* aYs
230 ,float aRed
231 ,float aGreen
232 ,float aBlue
233 ,const SbMarkerStyle& aStyle
234 ,int aSize
235 )
238 {
239  if(fFile==NULL) return;
240  float mark_size = (float)(aSize <=0 ? 1. : aSize);
241  mark_size *= 0.6F;
242  if(aStyle==SbMarkerCircleLine) {
243  putNewPathInStream();
244  int icount = 1;
245  for(int count=0;count<aPointn;count++) {
246  putCircleInStream(aXs[count],aYs[count],mark_size);
247 #define MAX_PATH_POINT 100
248  if(icount==MAX_PATH_POINT) {
249  putRGB_InStream(aRed,aGreen,aBlue);
250  putLineWidthInStream(1);
251  putCapInStream(1);
252  putStrokeInStream();
253  icount = 1;
254  if(count!=aPointn-1) putNewPathInStream();
255  } else {
256  icount++;
257  }
258  }
259  putRGB_InStream(aRed,aGreen,aBlue);
260  putLineWidthInStream(1);
261  putCapInStream(1);
262  putStrokeInStream();
263  } else {
264  putNewPathInStream();
265  int icount = 1;
266  for(int count=0;count<aPointn;count++) {
267  putMoveInStream(aXs[count],aYs[count]);
268  putMarkerSizeInStream(mark_size);
269  putMarkerStyleInStream(aStyle);
270  if(icount==MAX_PATH_POINT) {
271  putRGB_InStream(aRed,aGreen,aBlue);
272  putLineWidthInStream(1);
273  putCapInStream(1);
274  putStrokeInStream();
275  icount = 1;
276  if(count!=aPointn-1) putNewPathInStream();
277  } else {
278  icount++;
279  }
280  }
281  putRGB_InStream(aRed,aGreen,aBlue);
282  putLineWidthInStream(1);
283  putCapInStream(1);
284  putStrokeInStream();
285  }
286 }
287 */
293  int aShade
294 )
297 {
298  fParams.shade = aShade;
299 }
302  int aPortrait
303 )
306 {
307  fParams.portrait = aPortrait;
308 }
311  int aDoback
312 )
315 {
316  fParams.doBack = aDoback;
317 }
320  int aNbit
321 )
324 {
325  if( (aNbit==2) || (aNbit==4) || (aNbit==8) )
326  fParams.nbit = aNbit;
327  else
328  fParams.nbit = 2;
329 }
332  int aWidth
333 )
336 {
337  fParams.lineWidth = (float)aWidth;
338 }
343  const char* aString
344 )
347 {
348  STRDEL(fFileName);
349  fFileName = STRDUP(aString);
350 }
352 const char* SbPainterPS::getFileName(
353 ) const
356 {
357  return fFileName;
358 }
361 )
364 {
365  return fFile;
366 }
369  const char* aString
370 )
373 {
374  if(fFile!=NULL) closeStream ();
375  if( (aString==NULL) || (*aString=='\0') ) {
376  if( (fFileName==NULL) || (*fFileName=='\0') ) { // Take default name :
377  fFile = ::fopen(METAFILE_DEFAULT,"wb");
378  STRDEL(fFileName);
379  fFileName = STRDUP(METAFILE_DEFAULT);
380  } else {
381  fFile = ::fopen(fFileName,"wb");
382  }
383  } else {
384  fFile = ::fopen(aString,"wb");
385  STRDEL(fFileName);
386  fFileName = STRDUP(aString);
387  }
388  if(fFile==NULL) return;
389 
390  fBufferCount = 0;
392  fPageNumber = 0;
393  // Header :
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");
404  // PostScript :
406  // General :
407  putInStreamF("/n {newpath} def ");
408  putInStreamF("/cl {closepath} def ");
409  putInStreamF("/s {stroke} def ");
410  putInStreamF("/f {fill} def ");
411  // Move :
412  putInStreamF("/m {moveto} def ");
413  putInStreamF("/rm {rmoveto} def ");
414  putInStreamF("/rl {rlineto} def ");
415  // Line :
416  putInStreamF("/lc {setlinecap} def ");
417  putInStreamF("/lw {setlinewidth} def ");
418  putInStreamF("/rgb {setrgbcolor} def ");
419  putInStreamF("/ss {[] 0 setdash} def ") ; /* style solid */
420  putInStreamF("/sd {[12 6] 0 setdash} def "); /* style dashed */
421  putInStreamF("/so {[6 12] 0 setdash} def "); /* style dotted */
422  putInStreamF("/sdo {[18 12 6 12] 0 setdash} def "); /* style dash dotted */
423  // Mark :
424  fMarkerSize = 2.;
425  putInStreamF("/ms 2. def /msi .5 def "); /* mark size */
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 ");
435  // Text :
436  putInStreamF("/sh {show} def ");
437  putInStreamF("/df {/Courier-Bold findfont} def ");
438  putInStreamF("/mf {makefont setfont} def ");
439  printFLN("%%%%EndProlog");
440 }
443 )
446 {
447  if(fFile==NULL) return;
449  printFLN("%%%%Trailer");
450  printFLN("%%%%Pages: %d",fPageNumber);
451  printFLN("%%%%EOF");
452  if(fFile!=NULL) ::fclose(fFile);
453  fFile = NULL;
454  STRDEL(fFileName);
455  fFileName = NULL;
456 }
459  const char* aFormat
460 ,...
461 )
464 {
465  if(fFile==NULL) return;
466  va_list args;
467  va_start(args,aFormat);
468  printV(aFormat,args);
469  va_end(args);
470  int length = ::strlen(fBufferString);
471  if(length>METAFILE_RECORD_LENGTH) {
472  ::printf("SoPostScript::putInStreamF overflow\n");
473  return;
474  }
475  int nlength = fBufferCount + length;
476  if(nlength>METAFILE_RECORD_LENGTH) {
478  if(::fprintf(fFile,"%s\n",(char*)fBufferPointer)<0) {
479  ::printf("SoPostScript::putInStreamF fprintf error\n");
480  }
481  fBufferCount = 0;
482  nlength = length;
483  }
484  unsigned char* pointer = fBufferPointer + fBufferCount;
485  ::strcpy((char*)pointer,fBufferString);
486  fBufferCount = nlength;
487 }
490  const char* aFormat
491 ,...
492 )
495 {
496  if(fFile==NULL) return;
497  va_list args;
498  va_start(args,aFormat);
499  printV(aFormat,args);
500  va_end(args);
501 /* put buffer in file */
502  if(fBufferCount>0) {
504  if(::fprintf (fFile,"%s\n",(char*)fBufferPointer)<0) {
505  ::printf("SbPainterPS::printFLN fprintf error\n");
506  }
507  fBufferCount = 0;
508  }
509 /* put comment in file */
510  if(::fprintf (fFile,"%s\n",fBufferString)<0) {
511  ::printf("SbPainterPS::printFLN fprintf error\n");
512  }
513 }
516  const char* This
517 ,va_list aArgs
518 )
521 {
522 #define MAX_STR 2048
523  if(fBufferString==NULL) {
524  fBufferString = (char*)::malloc(MAX_STR * sizeof(char));
525  if(fBufferString==NULL) return;
526  }
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';
532  }
533 }
539  float aWidth
540 ,float aHeight
541 )
544 {
545  if(aWidth <=0.) aWidth = 100.;
546  if(aHeight<=0.) aHeight = 100.;
547 
548  putScaleInStream (1./METAFILE_SCALE,1./METAFILE_SCALE);
549  putTranslationInStream ((float)(fDeviceWidth/20.),
550  (float)(fDeviceHeight/30.));
551 
552  float scale;
554  scale = (aHeight<=aWidth ?
555  fDeviceWidth /aWidth : fDeviceWidth /aHeight );
556  else
557  scale = (aHeight<=aWidth ?
558  fDeviceHeight /aWidth : fDeviceHeight /aHeight );
559 
560  float xtra,ytra;
561  if(fParams.portrait==1) {
562  xtra = (fDeviceWidth - scale * aWidth)/2;
563  ytra = (fDeviceHeight - scale * aHeight)/2;
564  } else {
566  putRotateInStream(90);
567  xtra = (fDeviceHeight - scale * aWidth)/2;
568  ytra = (fDeviceWidth - scale * aHeight)/2;
569  }
570  putTranslationInStream (xtra,ytra);
571 
572  putScaleInStream (scale,scale);
573 }
579 )
582 {
583  putInStreamF("gsave ");
584  fGSave++;
585 }
588 )
591 {
592  putInStreamF("grestore ");
593  fGSave--;
594 }
597  float aX
598 ,float aY
599 )
602 {
603  putInStreamF("%.2f %.2f translate ",aX,aY);
604 }
607  float aX
608 ,float aY
609 )
612 {
613  putInStreamF("%.2f %.2f scale ",aX,aY);
614 }
617 )
620 {
621  fPageNumber++;
622  printFLN("%%%%Page: %d %d",fPageNumber,fPageNumber);
624 }
627 )
630 {
631  putInStreamF("showpage ");
633 }
636  float aR
637 ,float aG
638 ,float aB
639 )
642 {
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));
649 }
652  int aWidth
653 )
656 {
657  if(fParams.lineWidth<0.) {
658  if(aWidth==1) {
659  putInStreamF("%.1f lw ",0.5); // For a better rendering.
660  } else {
661  putInStreamF("%.1f lw ",(float)(aWidth));
662  }
663  } else {
664  putInStreamF("%.1f lw ",fParams.lineWidth);
665  }
666 }
669  float aSize
670 )
673 {
674  if(aSize==fMarkerSize) return;
675  fMarkerSize = aSize;
676  putInStreamF("/ms %g def /msi %g def ",aSize,1./aSize);
677 }
678 /*
680 void SbPainterPS::putMarkerStyleInStream (
681  SbMarkerStyle aStyle
682 )
685 {
686  switch (aStyle) {
687  case SbMarkerPlus:
688  putInStreamF("plus ");
689  break;
690  case SbMarkerAsterisk:
691  case SbMarkerStar:
692  putInStreamF("asterisk ");
693  break;
694  case SbMarkerCross:
695  putInStreamF("cross ");
696  break;
697  case SbMarkerTriangleUpLine:
698  putInStreamF("triangle ");
699  break;
700  default:
701  putLineToInStream(0.,0.);
702  break;
703  }
704 }
705 */
708  float aR
709 ,float aG
710 ,float aB
711 ,float aWidth
712 ,float aHeight
713 )
716 {
718  putMoveInStream(0.,0.);
719  putLineToInStream(aWidth,0.);
720  putLineToInStream(0.,aHeight);
721  putLineToInStream(-aWidth,0.);
722  putLineToInStream(0.,-aHeight);
724  if(fParams.doBack==1) {
725  // Back :
727  putRGB_InStream(aR,aG,aB);
728  putFillInStream();
730  }
731  // Clip :
732  putInStreamF("clip ");
733 }
736  float aR
737 ,float aG
738 ,float aB
739 ,float aWidth
740 ,float aHeight
741 )
744 {
746  putMoveInStream(0.,0.);
747  putLineToInStream(aWidth,0.);
748  putLineToInStream(0.,aHeight);
749  putLineToInStream(-aWidth,0.);
750  putLineToInStream(0.,-aHeight);
752  putRGB_InStream(aR,aG,aB);
754  putCapInStream(1);
755  putInStreamF("ss ");
757 }
760  float aRed
761 ,float aGreen
762 ,float aBlue
763 )
766 {
767  return (0.3F * aRed + 0.59F * aGreen + 0.11F * aBlue);
768 }
771  float aX
772 )
775 {
776  putInStreamF("%.2f rotate ",aX);
777 }
780 )
783 {
784  putInStreamF("n ");
785 }
788 )
791 {
792  putInStreamF("s ");
793 }
796 )
799 {
800  putInStreamF("f ");
801 }
804 )
807 {
808  putInStreamF("cl ");
809 }
812  int aX
813 )
816 {
817  putInStreamF("%1d lc ",aX);
818 }
821  float aX
822 ,float aY
823 )
826 {
827  putInStreamF ("%.2f %.2f rl ",aX,aY);
828 }
831  float aX
832 ,float aY
833 )
836 {
837  putInStreamF ("%.2f %.2f m ",aX,aY);
838 }
841  float aX
842 ,float aY
843 ,float aR
844 )
847 {
848  putInStreamF("%.2f %.2f %.2f 0 360 arc s ",aX,aY,aR);
849 }
850 /*
852 void SbPainterPS::putLineStyleInStream(
853  SbLineStyle aStyle
854 )
857 {
858  switch(aStyle) {
859  case SbLineSolid:putInStreamF("ss ") ;break;
860  case SbLineDashed:putInStreamF("sd ") ;break;
861  case SbLineDotted:putInStreamF("so ") ;break;
862  case SbLineDashDotted:putInStreamF("sdo ");break;
863  }
864 }
865 */
872  unsigned int aWidth
873 ,unsigned int aHeight
874 ,GetRGB_Function aProc
875 )
878 {
879  if((aWidth<=0)||(aHeight<=0)) return;
880  if(!aProc) return;
881 
883  putInStreamF ("%d %d scale ", aWidth, aHeight );
884  int status = 1;
885  int nbhex;
886  unsigned int row,col,col_max;
887  double dr,dg,db;
888  typedef unsigned char Uchar;
889  Uchar red,green,blue,b;
890  if(fParams.shade!=0) { /*grey*/
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++){
898  double fgrey;
899  Uchar grey;
900  status = aProc(col,row,dr,dg,db)==0 ? 0 : status;
901  fgrey = ConvertRGB_ToGrey(dr,dg,db);
902  grey = (Uchar) ( 255. * fgrey);
903  writeByte (grey);
904  }
905  }
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){
911  int nbyte2;
912  nbyte2 = (aWidth * 3)/4;
913  nbyte2 /=3;
914  nbyte2 *=3;
915  col_max = (nbyte2 * 4)/3;
916  /* 2 bit for r and g and b */
917  /* rgbs following each other */
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);
930  b = red;
931  b = (b<<2)+green;
932  b = (b<<2)+blue;
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);
937  b = (b<<2)+red;
938  writeByte (b);
939 
940  b = green;
941  b = (b<<2)+blue;
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);
946  b = (b<<2)+red;
947  b = (b<<2)+green;
948  writeByte (b);
949 
950  b = blue;
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);
955  b = (b<<2)+red;
956  b = (b<<2)+green;
957  b = (b<<2)+blue;
958  writeByte (b);
959  }
960  }
961  }else if(fParams.nbit==4){
962  int nbyte4;
963  nbyte4 = (aWidth * 3)/2;
964  nbyte4 /=3;
965  nbyte4 *=3;
966  col_max = (nbyte4 * 2)/3;
967  /* 4 bit for r and g and b */
968  /* rgbs following each other */
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);
982 
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);
989  }
990  }
991  }else{
992  int nbyte8;
993  nbyte8 = aWidth * 3;
994  /* 8 bit for r and g and b */
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);
1005  writeByte (red);
1006  green = (Uchar) ( 255. * dg);
1007  writeByte (green);
1008  blue = (Uchar) ( 255. * db);
1009  writeByte (blue);
1010  }
1011  }
1012  }
1013  if(status==0)
1014  ::printf("SbPainterPS::putImageInStream: problem to retrieve some pixel rgb.\n");
1016 }
1019  unsigned char a_byte
1020 )
1023 {
1024  unsigned char h = a_byte / 16;
1025  unsigned char l = a_byte % 16;
1026  putInStreamF ("%x%x",h,l);
1027 }
1031 char* GetDate (
1032 )
1034 // Return local date.
1036 {
1037  time_t d;
1038  time(&d);
1039  char* string = ctime(&d);
1040  string[24] = '\0';
1041  return string;
1042 }
1044 double ConvertRGB_ToGrey(
1045  double a_red
1046 ,double a_green
1047 ,double a_blue
1048 )
1051 {
1052  return (0.30 * a_red + 0.59 * a_green + 0.11 * a_blue);
1053 }
1054 
1055 #endif