Geant4  10.02.p01
SbPainterPS.cc
Go to the documentation of this file.
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);
55 SbPainterPS::SbPainterPS(
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 }
80 SbPainterPS::~SbPainterPS(
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 }
95 void SbPainterPS::beginTraversal (
96 )
99 {
100  if(fFile==NULL) openFileForWriting(NULL);
101  if(fFile==NULL) return;
102  putBeginPageInStream();
103  putPageScaleInStream((float)fWindowWidth,(float)fWindowHeight);
104  putSaveStateInStream();
105 }
107 void SbPainterPS::endTraversal(
108 )
111 {
112  if(fFile==NULL) return;
113  putFrameInStream(0.0,0.0,0.0,(float)fWindowWidth,(float)fWindowHeight);
114  putRestoreStateInStream();
115  putEndPageInStream();
116 }
118 void SbPainterPS::clearColorBuffer(
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 */
292 void SbPainterPS::setColorScheme(
293  int aShade
294 )
297 {
298  fParams.shade = aShade;
299 }
301 void SbPainterPS::setOrientation(
302  int aPortrait
303 )
306 {
307  fParams.portrait = aPortrait;
308 }
310 void SbPainterPS::setBackgroundDrawn(
311  int aDoback
312 )
315 {
316  fParams.doBack = aDoback;
317 }
319 void SbPainterPS::setBitsPerPixel(
320  int aNbit
321 )
324 {
325  if( (aNbit==2) || (aNbit==4) || (aNbit==8) )
326  fParams.nbit = aNbit;
327  else
328  fParams.nbit = 2;
329 }
331 void SbPainterPS::setLineWidth(
332  int aWidth
333 )
336 {
337  fParams.lineWidth = (float)aWidth;
338 }
342 void SbPainterPS::setFileName(
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 }
360 void* SbPainterPS::getStream(
361 )
364 {
365  return fFile;
366 }
368 void SbPainterPS::openFileForWriting(
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;
391  fBufferPointer[METAFILE_RECORD_LENGTH] = '\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 :
405  putSaveStateInStream ();
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 }
442 void SbPainterPS::closeStream(
443 )
446 {
447  if(fFile==NULL) return;
448  putRestoreStateInStream ();
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 }
458 void SbPainterPS::putInStreamF(
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) {
477  fBufferPointer[fBufferCount] = '\0';
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 }
489 void SbPainterPS::printFLN(
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) {
503  fBufferPointer[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 }
515 void SbPainterPS::printV(
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 }
538 void SbPainterPS::putPageScaleInStream(
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;
553  if(fDeviceWidth<=fDeviceHeight)
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 {
565  putTranslationInStream(fDeviceWidth,0.);
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 }
578 void SbPainterPS::putSaveStateInStream(
579 )
582 {
583  putInStreamF("gsave ");
584  fGSave++;
585 }
587 void SbPainterPS::putRestoreStateInStream(
588 )
591 {
592  putInStreamF("grestore ");
593  fGSave--;
594 }
596 void SbPainterPS::putTranslationInStream(
597  float aX
598 ,float aY
599 )
602 {
603  putInStreamF("%.2f %.2f translate ",aX,aY);
604 }
606 void SbPainterPS::putScaleInStream(
607  float aX
608 ,float aY
609 )
612 {
613  putInStreamF("%.2f %.2f scale ",aX,aY);
614 }
616 void SbPainterPS::putBeginPageInStream(
617 )
620 {
621  fPageNumber++;
622  printFLN("%%%%Page: %d %d",fPageNumber,fPageNumber);
623  putSaveStateInStream();
624 }
626 void SbPainterPS::putEndPageInStream (
627 )
630 {
631  putInStreamF("showpage ");
632  putRestoreStateInStream();
633 }
635 void SbPainterPS::putRGB_InStream (
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 }
651 void SbPainterPS::putLineWidthInStream(
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 }
668 void SbPainterPS::putMarkerSizeInStream (
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 */
707 void SbPainterPS::putBackgroundInStream (
708  float aR
709 ,float aG
710 ,float aB
711 ,float aWidth
712 ,float aHeight
713 )
716 {
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) {
725  // Back :
726  putSaveStateInStream();
727  putRGB_InStream(aR,aG,aB);
728  putFillInStream();
729  putRestoreStateInStream();
730  }
731  // Clip :
732  putInStreamF("clip ");
733 }
735 void SbPainterPS::putFrameInStream (
736  float aR
737 ,float aG
738 ,float aB
739 ,float aWidth
740 ,float aHeight
741 )
744 {
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);
754  putCapInStream(1);
755  putInStreamF("ss ");
756  putStrokeInStream();
757 }
759 float SbPainterPS::convertRGB_ToGrey (
760  float aRed
761 ,float aGreen
762 ,float aBlue
763 )
766 {
767  return (0.3F * aRed + 0.59F * aGreen + 0.11F * aBlue);
768 }
770 void SbPainterPS::putRotateInStream(
771  float aX
772 )
775 {
776  putInStreamF("%.2f rotate ",aX);
777 }
779 void SbPainterPS::putNewPathInStream(
780 )
783 {
784  putInStreamF("n ");
785 }
787 void SbPainterPS::putStrokeInStream(
788 )
791 {
792  putInStreamF("s ");
793 }
795 void SbPainterPS::putFillInStream(
796 )
799 {
800  putInStreamF("f ");
801 }
803 void SbPainterPS::putClosePathInStream(
804 )
807 {
808  putInStreamF("cl ");
809 }
811 void SbPainterPS::putCapInStream(
812  int aX
813 )
816 {
817  putInStreamF("%1d lc ",aX);
818 }
820 void SbPainterPS::putLineToInStream(
821  float aX
822 ,float aY
823 )
826 {
827  putInStreamF ("%.2f %.2f rl ",aX,aY);
828 }
830 void SbPainterPS::putMoveInStream(
831  float aX
832 ,float aY
833 )
836 {
837  putInStreamF ("%.2f %.2f m ",aX,aY);
838 }
840 void SbPainterPS::putCircleInStream(
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 */
871 void SbPainterPS::putImageInStream (
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 
882  putSaveStateInStream ();
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 retreive some pixel rgb.\n");
1015  putRestoreStateInStream();
1016 }
1018 void SbPainterPS::writeByte (
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
Definition: test07.cc:36
Definition: test07.cc:36
Color
Definition: test07.cc:36
#define STRDUP(str)
#define STRDEL(str)