ROOT  6.06/09
Reference Guide
TPDF.cxx
Go to the documentation of this file.
1 // @(#)root/postscript:$Id: TPDF.cxx,v 1.0
2 // Author: Olivier Couet
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TPDF
13 \ingroup PS
14 
15 Interface to PDF.
16 
17 Like PostScript, PDF is a vector graphics output format allowing a very high
18 graphics output quality. The functionalities provided by this class are very
19 similar to those provided by <tt>TPostScript</tt>.
20 
21 Compare to PostScript output, the PDF files are usually smaller because some
22 parts of them can be compressed.
23 
24 PDF also allows to define table of contents. This facility can be used in ROOT.
25 The following example shows how to proceed:
26 ~~~ {.cpp}
27 {
28  TCanvas* canvas = new TCanvas("canvas");
29  TH1F* histo = new TH1F("histo","test 1",10,0.,10.);
30  histo->SetFillColor(2);
31  histo->Fill(2.);
32  histo->Draw();
33  canvas->Print("plots.pdf(","Title:One bin filled");
34  histo->Fill(4.);
35  histo->Draw();
36  canvas->Print("plots.pdf","Title:Two bins filled");
37  histo->Fill(6.);
38  histo->Draw();
39  canvas->Print("plots.pdf","Title:Three bins filled");
40  histo->Fill(8.);
41  histo->Draw();
42  canvas->Print("plots.pdf","Title:Four bins filled");
43  histo->Fill(8.);
44  histo->Draw();
45  canvas->Print("plots.pdf)","Title:The fourth bin content is 2");
46 }
47 ~~~
48 Each character string following the keyword "Title:" makes a new entry in
49 the table of contents.
50 */
51 
52 #ifdef WIN32
53 #pragma optimize("",off)
54 #endif
55 
56 #include <stdlib.h>
57 #include <string.h>
58 #include <ctype.h>
59 
60 #include "Riostream.h"
61 #include "TROOT.h"
62 #include "TColor.h"
63 #include "TVirtualPad.h"
64 #include "TPoints.h"
65 #include "TPDF.h"
66 #include "TStyle.h"
67 #include "TMath.h"
68 #include "TStorage.h"
69 #include "TText.h"
70 #include "zlib.h"
71 #include "TObjString.h"
72 #include "TClass.h"
73 #include "TObjArray.h"
74 
75 // To scale fonts to the same size as the old TT version
76 const Float_t kScale = 0.93376068;
77 
78 // Objects numbers
79 const Int_t kObjRoot = 1; // Root object
80 const Int_t kObjInfo = 2; // Info object
81 const Int_t kObjOutlines = 3; // Outlines object
82 const Int_t kObjPages = 4; // Pages object (pages index)
83 const Int_t kObjPageResources = 5; // Pages Resources object
84 const Int_t kObjContents = 6; // Table of content
85 const Int_t kObjFont = 7; // First Font object (14 in total)
86 const Int_t kObjColorSpace = 22; // ColorSpace object
87 const Int_t kObjPatternResourses = 23; // Pattern Resources object
88 const Int_t kObjPatternList = 24; // Pattern list object
89 const Int_t kObjTransList = 25; // List of transparencies
90 const Int_t kObjPattern = 26; // First pattern object (25 in total)
91 const Int_t kObjFirstPage = 51; // First page object
92 
93 // Number of fonts
94 const Int_t kNumberOfFonts = 15;
95 
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Default PDF constructor
100 
101 TPDF::TPDF() : TVirtualPS()
102 {
103  fStream = 0;
104  fCompress = kFALSE;
105  fPageNotEmpty = kFALSE;
106  gVirtualPS = this;
107  fRed = 0.;
108  fGreen = 0.;
109  fBlue = 0.;
110  fAlpha = 1.;
111  fXsize = 0.;
112  fYsize = 0.;
113  fType = 0;
114  fPageFormat = 0;
115  fPageOrientation = 0;
116  fStartStream = 0;
117  fLineScale = 0.;
118  fObjPosSize = 0;
119  fObjPos = 0;
120  fNbObj = 0;
121  fNbPage = 0;
122  fRange = kFALSE;
123  SetTitle("PDF");
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Initialize the PDF interface
128 ///
129 /// - fname : PDF file name
130 /// - wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
131 /// inherits from TVirtualPS it should be kept. Anyway it is not
132 /// necessary to specify this parameter at creation time because it
133 /// has a default value (which is ignore in the PDF case).
134 
135 TPDF::TPDF(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
136 {
137  fStream = 0;
138  fCompress = kFALSE;
140  fRed = 0.;
141  fGreen = 0.;
142  fBlue = 0.;
143  fAlpha = 1.;
144  fXsize = 0.;
145  fYsize = 0.;
146  fType = 0;
147  fPageFormat = 0;
148  fPageOrientation = 0;
149  fStartStream = 0;
150  fLineScale = 0.;
151  fObjPosSize = 0;
152  fNbObj = 0;
153  fNbPage = 0;
154  fRange = kFALSE;
155  SetTitle("PDF");
156  Open(fname, wtype);
157 }
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 /// Default PDF destructor
161 
163 {
164  Close();
165 
166  if (fObjPos) delete [] fObjPos;
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// Begin the Cell Array painting
171 
173  Double_t)
174 {
175  Warning("TPDF::CellArrayBegin", "not yet implemented");
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// Paint the Cell Array
180 
182 {
183  Warning("TPDF::CellArrayFill", "not yet implemented");
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// End the Cell Array painting
188 
190 {
191  Warning("TPDF::CellArrayEnd", "not yet implemented");
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Close a PDF file
196 
198 {
199  Int_t i;
200 
201  if (!gVirtualPS) return;
202  if (!fStream) return;
203  if (gPad) gPad->Update();
204 
205  // Close the currently opened page
207  PrintStr("endstream@");
208  Int_t streamLength = fNByte-fStartStream-10;
209  PrintStr("endobj@");
211  WriteInteger(streamLength, 0);
212  PrintStr("@");
213  PrintStr("endobj@");
215  PrintStr("<<@");
216  if (!strstr(GetTitle(),"PDF")) {
217  PrintStr("/Title (");
218  PrintStr(GetTitle());
219  PrintStr(")@");
220  } else {
221  PrintStr("/Title (Page");
223  PrintStr(")@");
224  }
225  PrintStr("/Dest [");
227  PrintStr(" 0 R /XYZ null null 0]@");
228  PrintStr("/Parent");
230  PrintStr(" 0 R");
231  PrintStr("@");
232  if (fNbPage > 1) {
233  PrintStr("/Prev");
235  PrintStr(" 0 R");
236  PrintStr("@");
237  }
238  PrintStr(">>@");
239 
241  PrintStr("<<@");
242  PrintStr("/Type /Outlines@");
243  PrintStr("/Count");
245  PrintStr("@");
246  PrintStr("/First");
248  PrintStr(" 0 R");
249  PrintStr("@");
250  PrintStr("/Last");
252  PrintStr(" 0 R");
253  PrintStr("@");
254  PrintStr(">>@");
255  PrintStr("endobj@");
256 
258  PrintStr("<<@");
259  PrintStr("/Title (Contents)@");
260  PrintStr("/Dest [");
262  PrintStr(" 0 R /XYZ null null 0]@");
263  PrintStr("/Count");
265  PrintStr("@");
266  PrintStr("/Parent");
268  PrintStr(" 0 R");
269  PrintStr("@");
270  PrintStr("/First");
272  PrintStr(" 0 R");
273  PrintStr("@");
274  PrintStr("/Last");
276  PrintStr(" 0 R");
277  PrintStr("@");
278  PrintStr(">>@");
279 
280  // List of all the pages
282  PrintStr("<<@");
283  PrintStr("/Type /Pages@");
284  PrintStr("/Count");
286  PrintStr("@");
287  PrintStr("/Kids [");
288  for (i=1; i<=fNbPage; i++) {
289  WriteInteger(4*(i-1)+kObjFirstPage);
290  PrintStr(" 0 R");
291  }
292  PrintStr(" ]");
293  PrintStr("@");
294  PrintStr(">>@");
295  PrintStr("endobj@");
296 
298  PrintStr("<<@");
299  for (i=0; i<(int)fAlphas.size(); i++) {
300  PrintStr(
301  Form("/ca%3.2f << /Type /ExtGState /ca %3.2f >> /CA%3.2f << /Type /ExtGState /CA %3.2f >>@",
302  fAlphas[i],fAlphas[i],fAlphas[i],fAlphas[i]));
303  }
304  PrintStr(">>@");
305  PrintStr("endobj@");
306  if (fAlphas.size()) fAlphas.clear();
307 
308  // Cross-Reference Table
309  Int_t refInd = fNByte;
310  PrintStr("xref@");
311  PrintStr("0");
312  WriteInteger(fNbObj+1);
313  PrintStr("@");
314  PrintStr("0000000000 65535 f @");
315  char str[21];
316  for (i=0; i<fNbObj; i++) {
317  snprintf(str,21,"%10.10d 00000 n @",fObjPos[i]);
318  PrintStr(str);
319  }
320 
321  // Trailer
322  PrintStr("trailer@");
323  PrintStr("<<@");
324  PrintStr("/Size");
325  WriteInteger(fNbObj+1);
326  PrintStr("@");
327  PrintStr("/Root");
329  PrintStr(" 0 R");
330  PrintStr("@");
331  PrintStr("/Info");
333  PrintStr(" 0 R@");
334  PrintStr(">>@");
335  PrintStr("startxref@");
336  WriteInteger(refInd, 0);
337  PrintStr("@");
338  PrintStr("%%EOF@");
339 
340  // Close file stream
341  if (fStream) { fStream->close(); delete fStream; fStream = 0;}
342 
343  gVirtualPS = 0;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 /// Draw a Box
348 
350 {
351  static Double_t x[4], y[4];
352  Double_t ix1 = XtoPDF(x1);
353  Double_t ix2 = XtoPDF(x2);
354  Double_t iy1 = YtoPDF(y1);
355  Double_t iy2 = YtoPDF(y2);
356  Int_t fillis = fFillStyle/1000;
357  Int_t fillsi = fFillStyle%1000;
358 
359  if (fillis == 3 || fillis == 2) {
360  if (fillsi > 99) {
361  x[0] = x1; y[0] = y1;
362  x[1] = x2; y[1] = y1;
363  x[2] = x2; y[2] = y2;
364  x[3] = x1; y[3] = y2;
365  return;
366  }
367  if (fillsi > 0 && fillsi < 26) {
368  x[0] = x1; y[0] = y1;
369  x[1] = x2; y[1] = y1;
370  x[2] = x2; y[2] = y2;
371  x[3] = x1; y[3] = y2;
372  DrawPS(-4, &x[0], &y[0]);
373  }
374  if (fillsi == -3) {
375  SetColor(5);
376  if (fAlpha == 1) PrintFast(17," q 0.002 w [] 0 d");
377  WriteReal(ix1);
378  WriteReal(iy1);
379  WriteReal(ix2 - ix1);
380  WriteReal(iy2 - iy1);
381  if (fAlpha == 1) PrintFast(8," re b* Q");
382  else PrintFast(6," re f*");
383  }
384  }
385  if (fillis == 1) {
387  if (fAlpha == 1) PrintFast(17," q 0.002 w [] 0 d");
388  WriteReal(ix1);
389  WriteReal(iy1);
390  WriteReal(ix2 - ix1);
391  WriteReal(iy2 - iy1);
392  if (fAlpha == 1) PrintFast(8," re b* Q");
393  else PrintFast(6," re f*");
394  }
395  if (fillis == 0) {
396  if (fLineWidth<=0) return;
398  WriteReal(ix1);
399  WriteReal(iy1);
400  WriteReal(ix2 - ix1);
401  WriteReal(iy2 - iy1);
402  PrintFast(5," re S");
403  }
404 }
405 
406 ////////////////////////////////////////////////////////////////////////////////
407 /// Draw a Frame around a box
408 ///
409 /// - mode = -1 box looks as it is behind the screen
410 /// - mode = 1 box looks as it is in front of the screen
411 /// - border is the border size in already precomputed PDF units
412 /// - dark is the color for the dark part of the frame
413 /// - light is the color for the light part of the frame
414 
416  Int_t mode, Int_t border, Int_t dark, Int_t light)
417 {
418  static Double_t xps[7], yps[7];
419  Int_t i;
420 
421  // Draw top&left part of the box
422  if (mode == -1) SetColor(dark);
423  else SetColor(light);
424  xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
425  xps[1] = xps[0] + border; yps[1] = yps[0] + border;
426  xps[2] = xps[1]; yps[2] = YtoPDF(yt) - border;
427  xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
428  xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
429  xps[5] = xps[0]; yps[5] = yps[4];
430  xps[6] = xps[0]; yps[6] = yps[0];
431 
432  MoveTo(xps[0], yps[0]);
433  for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
434  PrintFast(3," f*");
435 
436  // Draw bottom&right part of the box
437  if (mode == -1) SetColor(light);
438  else SetColor(dark);
439  xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
440  xps[1] = xps[0] + border; yps[1] = yps[0] + border;
441  xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
442  xps[3] = xps[2]; yps[3] = YtoPDF(yt) - border;
443  xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
444  xps[5] = xps[4]; yps[5] = yps[0];
445  xps[6] = xps[0]; yps[6] = yps[0];
446 
447  MoveTo(xps[0], yps[0]);
448  for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
449  PrintFast(3," f*");
450 }
451 
452 ////////////////////////////////////////////////////////////////////////////////
453 /// Draw Fill area with hatch styles
454 
456 {
457  Warning("DrawHatch", "hatch fill style not yet implemented");
458 }
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 /// Draw Fill area with hatch styles
462 
464 {
465  Warning("DrawHatch", "hatch fill style not yet implemented");
466 }
467 
468 ////////////////////////////////////////////////////////////////////////////////
469 /// Draw a PolyLine
470 ///
471 /// Draw a polyline through the points xy.
472 ///
473 /// - If NN=1 moves only to point x,y.
474 /// - If NN=0 the x,y are written in the PDF file
475 /// according to the current transformation.
476 /// - If NN>0 the line is clipped as a line.
477 /// - If NN<0 the line is clipped as a fill area.
478 
480 {
481  Int_t n;
482 
483  Style_t linestylesav = fLineStyle;
484  Width_t linewidthsav = fLineWidth;
485 
486  if (nn > 0) {
487  if (fLineWidth<=0) return;
488  n = nn;
492  } else {
493  n = -nn;
494  SetLineStyle(1);
495  SetLineWidth(1);
497  }
498 
499  WriteReal(XtoPDF(xy[0].GetX()));
500  WriteReal(YtoPDF(xy[0].GetY()));
501  if (n <= 1) {
502  if (n == 0) return;
503  PrintFast(2," m");
504  return;
505  }
506 
507  PrintFast(2," m");
508 
509  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
510 
511  if (nn > 0) {
512  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
513  PrintFast(2," S");
514  } else {
515  PrintFast(3," f*");
516  }
517 
518  SetLineStyle(linestylesav);
519  SetLineWidth(linewidthsav);
520 }
521 
522 ////////////////////////////////////////////////////////////////////////////////
523 /// Draw a PolyLine in NDC space
524 ///
525 /// Draw a polyline through the points xy.
526 /// If NN=1 moves only to point x,y.
527 /// If NN=0 the x,y are written in the PDF file
528 /// according to the current transformation.
529 /// If NN>0 the line is clipped as a line.
530 /// If NN<0 the line is clipped as a fill area.
531 
533 {
534  Int_t n;
535 
536  Style_t linestylesav = fLineStyle;
537  Width_t linewidthsav = fLineWidth;
538 
539  if (nn > 0) {
540  if (fLineWidth<=0) return;
541  n = nn;
545  } else {
546  n = -nn;
547  SetLineStyle(1);
548  SetLineWidth(1);
550  }
551 
552  WriteReal(UtoPDF(xy[0].GetX()));
553  WriteReal(VtoPDF(xy[0].GetY()));
554  if (n <= 1) {
555  if (n == 0) return;
556  PrintFast(2," m");
557  return;
558  }
559 
560  PrintFast(2," m");
561 
562  for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
563 
564  if (nn > 0) {
565  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
566  PrintFast(2," S");
567  } else {
568  PrintFast(3," f*");
569  }
570 
571  SetLineStyle(linestylesav);
572  SetLineWidth(linewidthsav);
573 }
574 
575 ////////////////////////////////////////////////////////////////////////////////
576 /// Draw markers at the n WC points xw, yw
577 
579 {
580  Style_t linestylesav = fLineStyle;
581  Width_t linewidthsav = fLineWidth;
582  SetLineStyle(1);
583  SetLineWidth(1);
585  Int_t ms = abs(fMarkerStyle);
586 
587  if (ms >= 6 && ms <= 19) ms = 20;
588  if (ms == 4) ms = 24;
589 
590  // Define the marker size
591  Float_t msize = fMarkerSize;
592  if (fMarkerStyle == 1) {
593  msize = 1.;
594  } else if (fMarkerStyle == 6) {
595  msize = 1.;
596  } else if (fMarkerStyle == 7) {
597  msize = 1.5;
598  } else {
599  const Int_t kBASEMARKER = 8;
600  Float_t sbase = msize*kBASEMARKER;
601  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
602  msize = this->UtoPDF(s2x) - this->UtoPDF(0);
603  }
604 
605  Double_t m = msize;
606  Double_t m2 = m/2;
607  Double_t m3 = m/3;
608  Double_t m4 = m2*1.333333333333;
609  Double_t m6 = m/6;
610 
611  // Draw the marker according to the type
612  Double_t ix,iy;
613  for (Int_t i=0;i<n;i++) {
614  ix = XtoPDF(xw[i]);
615  iy = YtoPDF(yw[i]);
616  // Dot (.)
617  if (ms == 1) {
618  MoveTo(ix-1, iy);
619  LineTo(ix , iy);
620  // Plus (+)
621  } else if (ms == 2) {
622  MoveTo(ix-m2, iy);
623  LineTo(ix+m2, iy);
624  MoveTo(ix , iy-m2);
625  LineTo(ix , iy+m2);
626  // X shape (X)
627  } else if (ms == 5) {
628  MoveTo(ix-m2, iy-m2);
629  LineTo(ix+m2, iy+m2);
630  MoveTo(ix-m2, iy+m2);
631  LineTo(ix+m2, iy-m2);
632  // Asterisk shape (*)
633  } else if (ms == 3 || ms == 31) {
634  MoveTo(ix-m2, iy);
635  LineTo(ix+m2, iy);
636  MoveTo(ix , iy-m2);
637  LineTo(ix , iy+m2);
638  MoveTo(ix-m2, iy-m2);
639  LineTo(ix+m2, iy+m2);
640  MoveTo(ix-m2, iy+m2);
641  LineTo(ix+m2, iy-m2);
642  // Circle
643  } else if (ms == 24 || ms == 20) {
644  MoveTo(ix-m2, iy);
645  WriteReal(ix-m2); WriteReal(iy+m4);
646  WriteReal(ix+m2); WriteReal(iy+m4);
647  WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
648  WriteReal(ix+m2); WriteReal(iy-m4);
649  WriteReal(ix-m2); WriteReal(iy-m4);
650  WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
651  // Square
652  } else if (ms == 25 || ms == 21) {
653  WriteReal(ix-m2); WriteReal(iy-m2);
654  WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
655  // Down triangle
656  } else if (ms == 23 || ms == 32) {
657  MoveTo(ix , iy-m2);
658  LineTo(ix+m2, iy+m2);
659  LineTo(ix-m2, iy+m2);
660  PrintFast(2," h");
661  // Up triangle
662  } else if (ms == 26 || ms == 22) {
663  MoveTo(ix-m2, iy-m2);
664  LineTo(ix+m2, iy-m2);
665  LineTo(ix , iy+m2);
666  PrintFast(2," h");
667  } else if (ms == 27 || ms == 33) {
668  MoveTo(ix , iy-m2);
669  LineTo(ix+m3, iy);
670  LineTo(ix , iy+m2);
671  LineTo(ix-m3, iy) ;
672  PrintFast(2," h");
673  } else if (ms == 28 || ms == 34) {
674  MoveTo(ix-m6, iy-m6);
675  LineTo(ix-m6, iy-m2);
676  LineTo(ix+m6, iy-m2);
677  LineTo(ix+m6, iy-m6);
678  LineTo(ix+m2, iy-m6);
679  LineTo(ix+m2, iy+m6);
680  LineTo(ix+m6, iy+m6);
681  LineTo(ix+m6, iy+m2);
682  LineTo(ix-m6, iy+m2);
683  LineTo(ix-m6, iy+m6);
684  LineTo(ix-m2, iy+m6);
685  LineTo(ix-m2, iy-m6);
686  PrintFast(2," h");
687  } else if (ms == 29 || ms == 30) {
688  MoveTo(ix , iy+m2);
689  LineTo(ix+0.112255*m, iy+0.15451*m);
690  LineTo(ix+0.47552*m , iy+0.15451*m);
691  LineTo(ix+0.181635*m, iy-0.05902*m);
692  LineTo(ix+0.29389*m , iy-0.40451*m);
693  LineTo(ix , iy-0.19098*m);
694  LineTo(ix-0.29389*m , iy-0.40451*m);
695  LineTo(ix-0.181635*m, iy-0.05902*m);
696  LineTo(ix-0.47552*m , iy+0.15451*m);
697  LineTo(ix-0.112255*m, iy+0.15451*m);
698  PrintFast(2," h");
699  } else {
700  MoveTo(ix-1, iy);
701  LineTo(ix , iy);
702  }
703  }
704 
705  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
706  PrintFast(2," f");
707  } else {
708  PrintFast(2," S");
709  }
710 
711  SetLineStyle(linestylesav);
712  SetLineWidth(linewidthsav);
713 }
714 
715 ////////////////////////////////////////////////////////////////////////////////
716 /// Draw markers at the n WC points xw, yw
717 
719 {
720  Style_t linestylesav = fLineStyle;
721  Width_t linewidthsav = fLineWidth;
722  SetLineStyle(1);
723  SetLineWidth(1);
725  Int_t ms = abs(fMarkerStyle);
726 
727  if (ms >= 6 && ms <= 19) ms = 20;
728  if (ms == 4) ms = 24;
729 
730  // Define the marker size
731  Float_t msize = fMarkerSize;
732  if (fMarkerStyle == 1) {
733  msize = 1.;
734  } else if (fMarkerStyle == 6) {
735  msize = 1.5;
736  } else if (fMarkerStyle == 7) {
737  msize = 3.;
738  } else {
739  const Int_t kBASEMARKER = 8;
740  Float_t sbase = msize*kBASEMARKER;
741  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
742  msize = this->UtoPDF(s2x) - this->UtoPDF(0);
743  }
744 
745  Double_t m = msize;
746  Double_t m2 = m/2;
747  Double_t m3 = m/3;
748  Double_t m4 = m2*1.333333333333;
749  Double_t m6 = m/6;
750 
751  // Draw the marker according to the type
752  Double_t ix,iy;
753  for (Int_t i=0;i<n;i++) {
754  ix = XtoPDF(xw[i]);
755  iy = YtoPDF(yw[i]);
756  // Dot (.)
757  if (ms == 1) {
758  MoveTo(ix-1, iy);
759  LineTo(ix , iy);
760  // Plus (+)
761  } else if (ms == 2) {
762  MoveTo(ix-m2, iy);
763  LineTo(ix+m2, iy);
764  MoveTo(ix , iy-m2);
765  LineTo(ix , iy+m2);
766  // X shape (X)
767  } else if (ms == 5) {
768  MoveTo(ix-m2, iy-m2);
769  LineTo(ix+m2, iy+m2);
770  MoveTo(ix-m2, iy+m2);
771  LineTo(ix+m2, iy-m2);
772  // Asterisk shape (*)
773  } else if (ms == 3 || ms == 31) {
774  MoveTo(ix-m2, iy);
775  LineTo(ix+m2, iy);
776  MoveTo(ix , iy-m2);
777  LineTo(ix , iy+m2);
778  MoveTo(ix-m2, iy-m2);
779  LineTo(ix+m2, iy+m2);
780  MoveTo(ix-m2, iy+m2);
781  LineTo(ix+m2, iy-m2);
782  // Circle
783  } else if (ms == 24 || ms == 20) {
784  MoveTo(ix-m2, iy);
785  WriteReal(ix-m2); WriteReal(iy+m4);
786  WriteReal(ix+m2); WriteReal(iy+m4);
787  WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
788  WriteReal(ix+m2); WriteReal(iy-m4);
789  WriteReal(ix-m2); WriteReal(iy-m4);
790  WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
791  // Square
792  } else if (ms == 25 || ms == 21) {
793  WriteReal(ix-m2); WriteReal(iy-m2);
794  WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
795  // Down triangle
796  } else if (ms == 23 || ms == 32) {
797  MoveTo(ix , iy-m2);
798  LineTo(ix+m2, iy+m2);
799  LineTo(ix-m2, iy+m2);
800  PrintFast(2," h");
801  // Up triangle
802  } else if (ms == 26 || ms == 22) {
803  MoveTo(ix-m2, iy-m2);
804  LineTo(ix+m2, iy-m2);
805  LineTo(ix , iy+m2);
806  PrintFast(2," h");
807  } else if (ms == 27 || ms == 33) {
808  MoveTo(ix , iy-m2);
809  LineTo(ix+m3, iy);
810  LineTo(ix , iy+m2);
811  LineTo(ix-m3, iy) ;
812  PrintFast(2," h");
813  } else if (ms == 28 || ms == 34) {
814  MoveTo(ix-m6, iy-m6);
815  LineTo(ix-m6, iy-m2);
816  LineTo(ix+m6, iy-m2);
817  LineTo(ix+m6, iy-m6);
818  LineTo(ix+m2, iy-m6);
819  LineTo(ix+m2, iy+m6);
820  LineTo(ix+m6, iy+m6);
821  LineTo(ix+m6, iy+m2);
822  LineTo(ix-m6, iy+m2);
823  LineTo(ix-m6, iy+m6);
824  LineTo(ix-m2, iy+m6);
825  LineTo(ix-m2, iy-m6);
826  PrintFast(2," h");
827  } else if (ms == 29 || ms == 30) {
828  MoveTo(ix , iy+m2);
829  LineTo(ix+0.112255*m, iy+0.15451*m);
830  LineTo(ix+0.47552*m , iy+0.15451*m);
831  LineTo(ix+0.181635*m, iy-0.05902*m);
832  LineTo(ix+0.29389*m , iy-0.40451*m);
833  LineTo(ix , iy-0.19098*m);
834  LineTo(ix-0.29389*m , iy-0.40451*m);
835  LineTo(ix-0.181635*m, iy-0.05902*m);
836  LineTo(ix-0.47552*m , iy+0.15451*m);
837  LineTo(ix-0.112255*m, iy+0.15451*m);
838  PrintFast(2," h");
839  } else {
840  MoveTo(ix-1, iy);
841  LineTo(ix , iy);
842  }
843  }
844 
845  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
846  PrintFast(2," f");
847  } else {
848  PrintFast(2," S");
849  }
850 
851  SetLineStyle(linestylesav);
852  SetLineWidth(linewidthsav);
853 }
854 
855 ////////////////////////////////////////////////////////////////////////////////
856 /// Draw a PolyLine
857 ///
858 /// Draw a polyline through the points xw,yw.
859 /// - If nn=1 moves only to point xw,yw.
860 /// - If nn=0 the XW(1) and YW(1) are written in the PDF file
861 /// according to the current NT.
862 /// - If nn>0 the line is clipped as a line.
863 /// - If nn<0 the line is clipped as a fill area.
864 
865 void TPDF::DrawPS(Int_t nn, Float_t *xw, Float_t *yw)
866 {
867  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
868  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
869  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
870  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
871  180, 90,135, 45,150, 30,120, 60,
872  180, 90,135, 45,150, 30,120, 60};
873  Int_t n = 0, fais = 0 , fasi = 0;
874 
875  Style_t linestylesav = fLineStyle;
876  Width_t linewidthsav = fLineWidth;
877 
878  if (nn > 0) {
879  if (fLineWidth<=0) return;
880  n = nn;
884  }
885  if (nn < 0) {
886  n = -nn;
887  SetLineStyle(1);
888  SetLineWidth(1);
890  fais = fFillStyle/1000;
891  fasi = fFillStyle%1000;
892  if (fais == 3 || fais == 2) {
893  if (fasi > 100 && fasi <125) {
894  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
895  SetLineStyle(linestylesav);
896  SetLineWidth(linewidthsav);
897  return;
898  }
899  if (fasi > 0 && fasi < 26) {
901  }
902  }
903  }
904 
905  WriteReal(XtoPDF(xw[0]));
906  WriteReal(YtoPDF(yw[0]));
907  if (n <= 1) {
908  if (n == 0) return;
909  PrintFast(2," m");
910  return;
911  }
912 
913  PrintFast(2," m");
914 
915  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
916 
917  if (nn > 0) {
918  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
919  PrintFast(2," S");
920  } else {
921  if (fais == 0) {PrintFast(2," s"); return;}
922  if (fais == 3 || fais == 2) {
923  if (fasi > 0 && fasi < 26) {
924  PrintFast(3," f*");
925  fRed = -1;
926  fGreen = -1;
927  fBlue = -1;
928  fAlpha = -1.;
929  }
930  SetLineStyle(linestylesav);
931  SetLineWidth(linewidthsav);
932  return;
933  }
934  PrintFast(3," f*");
935  }
936 
937  SetLineStyle(linestylesav);
938  SetLineWidth(linewidthsav);
939 }
940 
941 ////////////////////////////////////////////////////////////////////////////////
942 /// Draw a PolyLine
943 ///
944 /// Draw a polyline through the points xw,yw.
945 ///
946 /// - If nn=1 moves only to point xw,yw.
947 /// - If nn=0 the xw(1) and YW(1) are written in the PDF file
948 /// according to the current NT.
949 /// - If nn>0 the line is clipped as a line.
950 /// - If nn<0 the line is clipped as a fill area.
951 
953 {
954  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
955  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
956  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
957  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
958  180, 90,135, 45,150, 30,120, 60,
959  180, 90,135, 45,150, 30,120, 60};
960  Int_t n = 0, fais = 0, fasi = 0;
961 
962  Style_t linestylesav = fLineStyle;
963  Width_t linewidthsav = fLineWidth;
964 
965  if (nn > 0) {
966  if (fLineWidth<=0) return;
967  n = nn;
971  }
972  if (nn < 0) {
973  n = -nn;
974  SetLineStyle(1);
975  SetLineWidth(1);
977  fais = fFillStyle/1000;
978  fasi = fFillStyle%1000;
979  if (fais == 3 || fais == 2) {
980  if (fasi > 100 && fasi <125) {
981  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
982  SetLineStyle(linestylesav);
983  SetLineWidth(linewidthsav);
984  return;
985  }
986  if (fasi > 0 && fasi < 26) {
988  }
989  }
990  }
991 
992  WriteReal(XtoPDF(xw[0]));
993  WriteReal(YtoPDF(yw[0]));
994  if (n <= 1) {
995  if (n == 0) return;
996  PrintFast(2," m");
997  return;
998  }
999 
1000  PrintFast(2," m");
1001 
1002  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1003 
1004  if (nn > 0) {
1005  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1006  PrintFast(2," S");
1007  } else {
1008  if (fais == 0) {PrintFast(2," s"); return;}
1009  if (fais == 3 || fais == 2) {
1010  if (fasi > 0 && fasi < 26) {
1011  PrintFast(3," f*");
1012  fRed = -1;
1013  fGreen = -1;
1014  fBlue = -1;
1015  fAlpha = -1.;
1016  }
1017  SetLineStyle(linestylesav);
1018  SetLineWidth(linewidthsav);
1019  return;
1020  }
1021  PrintFast(3," f*");
1022  }
1023 
1024  SetLineStyle(linestylesav);
1025  SetLineWidth(linewidthsav);
1026 }
1027 
1028 ////////////////////////////////////////////////////////////////////////////////
1029 /// Font encoding
1030 
1032 {
1033  static const char *sdtfonts[] = {
1034  "/Times-Italic" , "/Times-Bold" , "/Times-BoldItalic",
1035  "/Helvetica" , "/Helvetica-Oblique" , "/Helvetica-Bold" ,
1036  "/Helvetica-BoldOblique", "/Courier" , "/Courier-Oblique" ,
1037  "/Courier-Bold" , "/Courier-BoldOblique", "/Symbol" ,
1038  "/Times-Roman" , "/ZapfDingbats" , "/Symbol"};
1039 
1040  for (Int_t i=0; i<kNumberOfFonts; i++) {
1041  NewObject(kObjFont+i);
1042  PrintStr("<<@");
1043  PrintStr("/Type /Font@");
1044  PrintStr("/Subtype /Type1@");
1045  PrintStr("/Name /F");
1046  WriteInteger(i+1,0);
1047  PrintStr("@");
1048  PrintStr("/BaseFont ");
1049  PrintStr(sdtfonts[i]);
1050  PrintStr("@");
1051  if (i!=11 && i!=13 && i!=14) {
1052  PrintStr("/Encoding /WinAnsiEncoding");
1053  PrintStr("@");
1054  }
1055  PrintStr(">>@");
1056  PrintStr("endobj@");
1057  }
1058 }
1059 
1060 ////////////////////////////////////////////////////////////////////////////////
1061 /// Draw a line to a new position
1062 
1064 {
1065  WriteReal(x);
1066  WriteReal(y);
1067  PrintFast(2," l");
1068 }
1069 
1070 ////////////////////////////////////////////////////////////////////////////////
1071 /// Move to a new position
1072 
1074 {
1075  WriteReal(x);
1076  WriteReal(y);
1077  PrintFast(2," m");
1078 }
1079 
1080 ////////////////////////////////////////////////////////////////////////////////
1081 /// Create a new object in the PDF file
1082 
1084 {
1085  if (!fObjPos || n >= fObjPosSize) {
1086  Int_t newN = TMath::Max(2*fObjPosSize,n+1);
1087  Int_t *saveo = new Int_t [newN];
1088  if (fObjPos && fObjPosSize) {
1089  memcpy(saveo,fObjPos,fObjPosSize*sizeof(Int_t));
1090  memset(&saveo[fObjPosSize],0,(newN-fObjPosSize)*sizeof(Int_t));
1091  delete [] fObjPos;
1092  }
1093  fObjPos = saveo;
1094  fObjPosSize = newN;
1095  }
1096  fObjPos[n-1] = fNByte;
1097  fNbObj = TMath::Max(fNbObj,n);
1098  WriteInteger(n, 0);
1099  PrintStr(" 0 obj");
1100  PrintStr("@");
1101 }
1102 
1103 ////////////////////////////////////////////////////////////////////////////////
1104 /// Start a new PDF page.
1105 
1107 {
1108  if (!fPageNotEmpty) return;
1109 
1110  // Compute pad conversion coefficients
1111  if (gPad) {
1112  Double_t ww = gPad->GetWw();
1113  Double_t wh = gPad->GetWh();
1114  fYsize = fXsize*wh/ww;
1115  } else {
1116  fYsize = 27;
1117  }
1118 
1119  fNbPage++;
1120 
1121  if (fNbPage>1) {
1122  // Close the currently opened page
1124  PrintStr("endstream@");
1125  Int_t streamLength = fNByte-fStartStream-10;
1126  PrintStr("endobj@");
1127  NewObject(4*(fNbPage-2)+kObjFirstPage+2);
1128  WriteInteger(streamLength, 0);
1129  PrintStr("@");
1130  PrintStr("endobj@");
1131  NewObject(4*(fNbPage-2)+kObjFirstPage+3);
1132  PrintStr("<<@");
1133  if (!strstr(GetTitle(),"PDF")) {
1134  PrintStr("/Title (");
1135  PrintStr(GetTitle());
1136  PrintStr(")@");
1137  } else {
1138  PrintStr("/Title (Page");
1139  WriteInteger(fNbPage-1);
1140  PrintStr(")@");
1141  }
1142  PrintStr("/Dest [");
1144  PrintStr(" 0 R /XYZ null null 0]@");
1145  PrintStr("/Parent");
1147  PrintStr(" 0 R");
1148  PrintStr("@");
1149  PrintStr("/Next");
1151  PrintStr(" 0 R");
1152  PrintStr("@");
1153  if (fNbPage>2) {
1154  PrintStr("/Prev");
1156  PrintStr(" 0 R");
1157  PrintStr("@");
1158  }
1159  PrintStr(">>@");
1160  }
1161 
1162  // Start a new page
1164  PrintStr("<<@");
1165  PrintStr("/Type /Page@");
1166  PrintStr("@");
1167  PrintStr("/Parent");
1169  PrintStr(" 0 R");
1170  PrintStr("@");
1171 
1172  Double_t xlow=0, ylow=0, xup=1, yup=1;
1173  if (gPad) {
1174  xlow = gPad->GetAbsXlowNDC();
1175  xup = xlow + gPad->GetAbsWNDC();
1176  ylow = gPad->GetAbsYlowNDC();
1177  yup = ylow + gPad->GetAbsHNDC();
1178  }
1179 
1180  PrintStr("/MediaBox [");
1181  Double_t width, height;
1182  switch (fPageFormat) {
1183  case 100 :
1184  width = 8.5*2.54;
1185  height = 11.*2.54;
1186  break;
1187  case 200 :
1188  width = 8.5*2.54;
1189  height = 14.*2.54;
1190  break;
1191  case 300 :
1192  width = 11.*2.54;
1193  height = 17.*2.54;
1194  break;
1195  default :
1196  width = 21.0*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1197  height = 29.7*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1198  };
1199  WriteReal(CMtoPDF(fXsize*xlow));
1200  WriteReal(CMtoPDF(fYsize*ylow));
1201  WriteReal(CMtoPDF(width));
1202  WriteReal(CMtoPDF(height));
1203  PrintStr("]");
1204  PrintStr("@");
1205 
1206  Double_t xmargin = CMtoPDF(0.7);
1207  Double_t ymargin = 0;
1208  if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
1209  if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
1210 
1211  PrintStr("/CropBox [");
1212  if (fPageOrientation == 1) {
1213  WriteReal(xmargin);
1214  WriteReal(ymargin);
1215  WriteReal(xmargin+CMtoPDF(fXsize*xup));
1216  WriteReal(ymargin+CMtoPDF(fYsize*yup));
1217  }
1218  if (fPageOrientation == 2) {
1219  WriteReal(xmargin);
1220  WriteReal(CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin);
1221  WriteReal(xmargin+CMtoPDF(fYsize*yup));
1222  WriteReal(CMtoPDF(height)-xmargin);
1223  }
1224  PrintStr("]");
1225  PrintStr("@");
1226 
1227  if (fPageOrientation == 1) PrintStr("/Rotate 0@");
1228  if (fPageOrientation == 2) PrintStr("/Rotate 90@");
1229 
1230  PrintStr("/Resources");
1232  PrintStr(" 0 R");
1233  PrintStr("@");
1234 
1235  PrintStr("/Contents");
1237  PrintStr(" 0 R@");
1238  PrintStr(">>@");
1239  PrintStr("endobj@");
1240 
1241  NewObject(4*(fNbPage-1)+kObjFirstPage+1);
1242  PrintStr("<<@");
1243  PrintStr("/Length");
1245  PrintStr(" 0 R@");
1246  PrintStr("/Filter [/FlateDecode]@");
1247  PrintStr(">>@");
1248  PrintStr("stream@");
1249  fStartStream = fNByte;
1250  fCompress = kTRUE;
1251 
1252  // Force the line width definition next time TPDF::SetLineWidth will be called.
1253  fLineWidth = -1;
1254 
1255  // Force the color definition next time TPDF::SetColor will be called.
1256  fRed = -1;
1257  fGreen = -1;
1258  fBlue = -1;
1259  fAlpha = -1.;
1260 
1261  PrintStr("1 0 0 1");
1262  if (fPageOrientation == 2) {
1263  ymargin = CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin;
1264  xmargin = xmargin+CMtoPDF(fYsize*yup);
1265  }
1266  WriteReal(xmargin);
1267  WriteReal(ymargin);
1268  PrintStr(" cm");
1269  if (fPageOrientation == 2) PrintStr(" 0 1 -1 0 0 0 cm");
1270 }
1271 
1272 ////////////////////////////////////////////////////////////////////////////////
1273 /// Deactivate an already open PDF file
1274 
1276 {
1277  gVirtualPS = 0;
1278 }
1279 
1280 ////////////////////////////////////////////////////////////////////////////////
1281 /// Activate an already open PDF file
1282 
1283 void TPDF::On()
1284 {
1285  // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
1286  // has no "workstation type".
1287 
1288  if (!fType) {
1289  Error("On", "no PDF file open");
1290  Off();
1291  return;
1292  }
1293  gVirtualPS = this;
1294 }
1295 
1296 ////////////////////////////////////////////////////////////////////////////////
1297 /// Open a PDF file
1298 
1299 void TPDF::Open(const char *fname, Int_t wtype)
1300 {
1301  Int_t i;
1302 
1303  if (fStream) {
1304  Warning("Open", "PDF file already open");
1305  return;
1306  }
1307 
1308  fLenBuffer = 0;
1309  fRed = -1;
1310  fGreen = -1;
1311  fBlue = -1;
1312  fAlpha = -1.;
1313  fType = abs(wtype);
1316  Float_t xrange, yrange;
1317  if (gPad) {
1318  Double_t ww = gPad->GetWw();
1319  Double_t wh = gPad->GetWh();
1320  if (fType == 113) {
1321  ww *= gPad->GetWNDC();
1322  wh *= gPad->GetHNDC();
1323  }
1324  Double_t ratio = wh/ww;
1325  xrange = fXsize;
1326  yrange = fXsize*ratio;
1327  if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
1328  fXsize = xrange; fYsize = yrange;
1329  }
1330 
1331  // Open OS file
1332  fStream = new std::ofstream();
1333 #ifdef R__WIN32
1334  fStream->open(fname, std::ofstream::out | std::ofstream::binary);
1335 #else
1336  fStream->open(fname, std::ofstream::out);
1337 #endif
1338  if (fStream == 0 || !fStream->good()) {
1339  printf("ERROR in TPDF::Open: Cannot open file:%s\n",fname);
1340  if (fStream == 0) return;
1341  }
1342 
1343  gVirtualPS = this;
1344 
1345  for (i=0; i<fSizBuffer; i++) fBuffer[i] = ' ';
1346 
1347  // The page orientation is last digit of PDF workstation type
1348  // orientation = 1 for portrait
1349  // orientation = 2 for landscape
1350  fPageOrientation = fType%10;
1351  if (fPageOrientation < 1 || fPageOrientation > 2) {
1352  Error("Open", "Invalid page orientation %d", fPageOrientation);
1353  return;
1354  }
1355 
1356  // format = 0-99 is the European page format (A4,A3 ...)
1357  // format = 100 is the US format 8.5x11.0 inch
1358  // format = 200 is the US format 8.5x14.0 inch
1359  // format = 300 is the US format 11.0x17.0 inch
1360  fPageFormat = fType/1000;
1361  if (fPageFormat == 0) fPageFormat = 4;
1362  if (fPageFormat == 99) fPageFormat = 0;
1363 
1364  fRange = kFALSE;
1365 
1366  // Set a default range
1367  Range(fXsize, fYsize);
1368 
1369  fObjPos = 0;
1370  fObjPosSize = 0;
1371  fNbObj = 0;
1372  fNbPage = 0;
1373 
1374  PrintStr("%PDF-1.4@");
1375  PrintStr("%\342\343\317\323");
1376  PrintStr("@");
1377 
1379  PrintStr("<<@");
1380  PrintStr("/Type /Catalog@");
1381  PrintStr("/Pages");
1383  PrintStr(" 0 R@");
1384  PrintStr("/Outlines");
1386  PrintStr(" 0 R@");
1387  PrintStr("/PageMode /UseOutlines@");
1388  PrintStr(">>@");
1389  PrintStr("endobj@");
1390 
1392  PrintStr("<<@");
1393  PrintStr("/Creator (ROOT Version ");
1394  PrintStr(gROOT->GetVersion());
1395  PrintStr(")");
1396  PrintStr("@");
1397  PrintStr("/CreationDate (");
1398  TDatime t;
1399  char str[17];
1400  snprintf(str,17,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
1401  t.GetYear() , t.GetMonth(),
1402  t.GetDay() , t.GetHour(),
1403  t.GetMinute(), t.GetSecond());
1404  PrintStr(str);
1405  PrintStr(")");
1406  PrintStr("@");
1407  PrintStr("/Title (");
1408  if (strlen(GetName())<=80) PrintStr(GetName());
1409  PrintStr(")");
1410  PrintStr("@");
1411  PrintStr("/Keywords (ROOT)@");
1412  PrintStr(">>@");
1413  PrintStr("endobj@");
1414 
1416  PrintStr("<<@");
1417  PrintStr("/ProcSet [/PDF /Text]@");
1418 
1419  PrintStr("/Font@");
1420  PrintStr("<<@");
1421  for (i=0; i<kNumberOfFonts; i++) {
1422  PrintStr(" /F");
1423  WriteInteger(i+1,0);
1425  PrintStr(" 0 R");
1426  }
1427  PrintStr("@");
1428  PrintStr(">>@");
1429 
1430  PrintStr("/ExtGState");
1432  PrintStr(" 0 R @");
1433  if (fAlphas.size()) fAlphas.clear();
1434 
1435  PrintStr("/ColorSpace << /Cs8");
1437  PrintStr(" 0 R >>");
1438  PrintStr("@");
1439  PrintStr("/Pattern");
1441  PrintStr(" 0 R");
1442  PrintStr("@");
1443  PrintStr(">>@");
1444  PrintStr("endobj@");
1445 
1446  FontEncode();
1447  PatternEncode();
1448 
1449  NewPage();
1451 }
1452 
1453 ////////////////////////////////////////////////////////////////////////////////
1454 /// Patterns encoding
1455 
1457 {
1458  Int_t patternNb = kObjPattern;
1459 
1461  if (gStyle->GetColorModelPS()) {
1462  PrintStr("[/Pattern /DeviceCMYK]@");
1463  } else {
1464  PrintStr("[/Pattern /DeviceRGB]@");
1465  }
1466  PrintStr("endobj@");
1468  PrintStr("<</ProcSet[/PDF]>>@");
1469  PrintStr("endobj@");
1470 
1472  PrintStr("<<@");
1473  PrintStr(" /P01");
1474  WriteInteger(patternNb++);
1475  PrintStr(" 0 R");
1476  PrintStr(" /P02");
1477  WriteInteger(patternNb++);
1478  PrintStr(" 0 R");
1479  PrintStr(" /P03");
1480  WriteInteger(patternNb++);
1481  PrintStr(" 0 R");
1482  PrintStr(" /P04");
1483  WriteInteger(patternNb++);
1484  PrintStr(" 0 R");
1485  PrintStr(" /P05");
1486  WriteInteger(patternNb++);
1487  PrintStr(" 0 R");
1488  PrintStr(" /P06");
1489  WriteInteger(patternNb++);
1490  PrintStr(" 0 R");
1491  PrintStr(" /P07");
1492  WriteInteger(patternNb++);
1493  PrintStr(" 0 R");
1494  PrintStr(" /P08");
1495  WriteInteger(patternNb++);
1496  PrintStr(" 0 R");
1497  PrintStr(" /P09");
1498  WriteInteger(patternNb++);
1499  PrintStr(" 0 R");
1500  PrintStr(" /P10");
1501  WriteInteger(patternNb++);
1502  PrintStr(" 0 R");
1503  PrintStr(" /P11");
1504  WriteInteger(patternNb++);
1505  PrintStr(" 0 R");
1506  PrintStr(" /P12");
1507  WriteInteger(patternNb++);
1508  PrintStr(" 0 R");
1509  PrintStr(" /P13");
1510  WriteInteger(patternNb++);
1511  PrintStr(" 0 R");
1512  PrintStr(" /P14");
1513  WriteInteger(patternNb++);
1514  PrintStr(" 0 R");
1515  PrintStr(" /P15");
1516  WriteInteger(patternNb++);
1517  PrintStr(" 0 R");
1518  PrintStr(" /P16");
1519  WriteInteger(patternNb++);
1520  PrintStr(" 0 R");
1521  PrintStr(" /P17");
1522  WriteInteger(patternNb++);
1523  PrintStr(" 0 R");
1524  PrintStr(" /P18");
1525  WriteInteger(patternNb++);
1526  PrintStr(" 0 R");
1527  PrintStr(" /P19");
1528  WriteInteger(patternNb++);
1529  PrintStr(" 0 R");
1530  PrintStr(" /P20");
1531  WriteInteger(patternNb++);
1532  PrintStr(" 0 R");
1533  PrintStr(" /P21");
1534  WriteInteger(patternNb++);
1535  PrintStr(" 0 R");
1536  PrintStr(" /P22");
1537  WriteInteger(patternNb++);
1538  PrintStr(" 0 R");
1539  PrintStr(" /P23");
1540  WriteInteger(patternNb++);
1541  PrintStr(" 0 R");
1542  PrintStr(" /P24");
1543  WriteInteger(patternNb++);
1544  PrintStr(" 0 R");
1545  PrintStr(" /P25");
1546  WriteInteger(patternNb++);
1547  PrintStr(" 0 R@");
1548  PrintStr(">>@");
1549  PrintStr("endobj@");
1550 
1551  patternNb = kObjPattern;
1552 
1553  // P01
1554  NewObject(patternNb++);
1555  PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
1557  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 98 4]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
1558  PrintStr("@");
1559  fStream->write("stream",6); fNByte += 6;
1560  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301P\241\034(\254\340\253\020m\250\020k\240\220\302e\244`\242\220\313ei\t\244r\200\272\215A\034\v \225\003\2241\202\310\030\201e\f!2\206@N0W \027@\200\001\0|c\024\357\n", 93);
1561  fNByte += 93;
1562  PrintStr("endstream@");
1563  PrintStr("endobj@");
1564 
1565  // P02
1566  NewObject(patternNb++);
1567  PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
1569  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 4]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
1570  PrintStr("@");
1571  fStream->write("stream",6); fNByte += 6;
1572  fStream->write("\r\nH\211$\2121\n\2000\024C\367\234\"G\370\277\025\321+\b\016\342\340P\334tP\252\240\213\3277\332!\204\274\227\v\316\2150\032\335J\356\025\023O\241Np\247\363\021f\317\344\214\234\215\v\002+\036h\033U\326/~\243Ve\231PL\370\215\027\343\032#\006\274\002\f\0\242`\025:\n", 94);
1573  fNByte += 94;
1574  PrintStr("endstream@");
1575  PrintStr("endobj@");
1576 
1577  // P03
1578  NewObject(patternNb++);
1579  PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
1581  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 16]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
1582  PrintStr("@");
1583  fStream->write("stream",6); fNByte += 6;
1584  fStream->write("\r\nH\211$\2121\n\2000\024C\367\234\"G\370\261(\366\n\202\20388\210\233\016J\025t\361\372\376\332!\204\274\227\033\342N\030\215\262\222g\303\304\313Q\347\360\240\370:f\317Y\f\\\214+**\360Dls'\177\306\274\032\257\344\256.\252\376\215\212\221\217\021\003>\001\006\0\317\243\025\254\n", 95);
1585  fNByte += 95;
1586  PrintStr("endstream@");
1587  PrintStr("endobj@");
1588 
1589  // P04
1590  NewObject(patternNb++);
1591  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1593  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 63/Filter/FlateDecode>>");
1594  PrintStr("@");
1595  fStream->write("stream",6); fNByte += 6;
1596  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002V\231\313\005S\233\303\025\314\025\310\005\020`\0\344\270\r\274\n", 65);
1597  fNByte += 65;
1598  PrintStr("endstream@");
1599  PrintStr("endobj@");
1600 
1601  // P05
1602  NewObject(patternNb++);
1603  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1605  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
1606  PrintStr("@");
1607  fStream->write("stream",6); fNByte += 6;
1608  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302\005Q\223\313\005\"\r\024r\270\202\271\002\271\0\002\f\0\344\320\r\274\n", 68);
1609  fNByte += 68;
1610  PrintStr("endstream@");
1611  PrintStr("endobj@");
1612 
1613  // P06
1614  NewObject(patternNb++);
1615  PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
1617  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
1618  PrintStr("@");
1619  fStream->write("stream",6); fNByte += 6;
1620  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302e\nR\232\v\242@js\270\202\271\002\271\0\002\f\0\345X\r\305\n", 68);
1621  fNByte += 68;
1622  PrintStr("endstream@");
1623  PrintStr("endobj@");
1624 
1625  // P07
1626  NewObject(patternNb++);
1627  PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
1629  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
1630  PrintStr("@");
1631  fStream->write("stream",6); fNByte += 6;
1632  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\345\002)\0042r\270\202\271\002\271\0\002\f\0\345=\r\305\n", 70);
1633  fNByte += 70;
1634  PrintStr("endstream@");
1635  PrintStr("endobj@");
1636 
1637  // P08
1638  NewObject(patternNb++);
1639  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1641  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
1642  PrintStr("@");
1643  fStream->write("stream",6); fNByte += 6;
1644  fStream->write("\r\nH\211D\217\261\016\3020\fDw\177\305\315L6Q\225|\003\022C\305\300Puk+\201\032$\272\360\373\330\265\323\016\271\330\367\234\344\"x\201\030\214\252\232\030+%\353VZ.jd\367\205\003x\241({]\311\324]\323|\342\006\033J\201:\306\325\230Jg\226J\261\275D\257#\337=\220\260\354k\233\351\211\217Z75\337\020\374\324\306\035\303\310\230\342x=\303\371\275\307o\332s\331\223\224\240G\330\a\365\364\027`\0\nX1}\n",141);
1645  fNByte += 141;
1646  PrintStr("endstream@");
1647  PrintStr("endobj@");
1648 
1649  // P09
1650  NewObject(patternNb++);
1651  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1653  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
1654  PrintStr("@");
1655  fStream->write("stream",6); fNByte += 6;
1656  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\005RFFz&\020\002,d\240\220\314en\256g\0065\b,\001b\230\202$\240\232\214@\362\246`\2169H\336\024\2426\231\v&\200,\n\326\030\314\025\310\005\020`\0\f@\036\227\n", 110);
1657  fNByte += 110;
1658  PrintStr("endstream@");
1659  PrintStr("endobj@");
1660 
1661  // P10
1662  NewObject(patternNb++);
1663  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1665  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 93/Filter/FlateDecode>>");
1666  PrintStr("@");
1667  fStream->write("stream",6); fNByte += 6;
1668  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\345\002)\0042r\200\332\r\241\\C \017dN.\027L\312\0\302\205\2535\205j6\205X\224\303\025\314\025\310\005\020`\0\2127\031\t\n", 95);
1669  fNByte += 95;
1670  PrintStr("endstream@");
1671  PrintStr("endobj@");
1672 
1673  // P11
1674  NewObject(patternNb++);
1675  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1677  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 164/Filter/FlateDecode>>");
1678  PrintStr("@");
1679  fStream->write("stream",6); fNByte += 6;
1680  fStream->write("\r\nH\211\\\2171\016\3020\fEw\237\342\037\301ip\223^\001\211\001u`@l0\200(\022,\\\037;v\204\332\241\211\336\373\337V\363\246\204;\210\301H\354\337\347F'\274T\355U>\220\360U\215\003\316\027\306\2655\027=\a\306\223\304I\002m\332\330\356&\030\325\333fZ\275F\337\205\235\265O\270\032\004\331\214\336\305\270\004\227`\357i\256\223\342;]\344\255(!\372\356\205j\030\377K\335\220\344\377\210\274\306\022\330\337T{\214,\212;\301\3508\006\346\206\021O=\216|\212|\246#\375\004\030\0\216FF\207\n", 166);
1681  fNByte += 166;
1682  PrintStr("endstream@");
1683  PrintStr("endobj@");
1684 
1685  // P12
1686  NewObject(patternNb++);
1687  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1689  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
1690  PrintStr("@");
1691  fStream->write("stream",6); fNByte += 6;
1692  fStream->write("\r\nH\211<P;n\3030\f\335y\n\236 \220DK\242\256P\240C\321\241C\221\311\311\220\242\016\220.\275~D\221/\203I\342}\370(?(\363\215)q\342\234\374\373\273\322\027\337'\3646\301\037\316\374?a~\347\357s\342\313\2045\361A9\237\322fc\231\200\236F\263\301\334;\211\017\207\rN\311\252S\\\227{\247\006w\207\244\303\255p+(\205\333\360e/v\356a\315\317\360\272\320b|w\276\203o\340k\b\004\027\v$b\226\235,\242\254t(\024\nu\305Vm\313\021\375\327\272\257\227fuf\226ju\356\222x\030\024\313\261S\215\377\341\274,\203\254\253Z\\\262A\262\205eD\350\210\320\201\225\212\320\036\241\355\025\372JE,\2266\344\366\310U\344\016HFx>\351\203\236\002\f\0d}e\216\n", 228);
1693  fNByte += 228;
1694  PrintStr("endstream@");
1695  PrintStr("endobj@");
1696 
1697  // P13
1698  NewObject(patternNb++);
1699  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1701  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
1702  PrintStr("@");
1703  fStream->write("stream",6); fNByte += 6;
1704  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002V\231\313\005S\233\303\005\241!\" ~0W \027@\200\001\0\331\227\020\253\n", 71);
1705  fNByte += 71;
1706  PrintStr("endstream@");
1707  PrintStr("endobj@");
1708 
1709  // P14
1710  NewObject(patternNb++);
1711  PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
1713  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
1714  PrintStr("@");
1715  fStream->write("stream",6); fNByte += 6;
1716  fStream->write("\r\nH\2114\214=\n\2000\f\205\367\234\342\035!-\241\364\f\202\20388\210\233\016J+\350\342\365M\3723\224\327\367}I\036r8A\f\206\343\372\336\203\026\334\212\006\205\027\004\237b\214X7\306\256\33032\331\240~\022y[\315\026\206\222\372\330}\264\036\253\217\335\353\240\030\b%\223\245o=X\227\346\245\355K\341\345@\3613M\364\v0\0\207o\"\261\n", 116);
1717  fNByte += 116;
1718  PrintStr("endstream@");
1719  PrintStr("endobj@");
1720 
1721  // P15
1722  NewObject(patternNb++);
1723  PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
1725  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
1726  PrintStr("@");
1727  fStream->write("stream",6); fNByte += 6;
1728  fStream->write("\r\nH\211<\2211\016\3020\fEw\237\302'@\211c\267w@b@\f\f\210\2510\200(\022,\\\037\347\307\256Z\325\221\375\337\377\225\363\241\312\017\246\302\205'\274\337;\235\371\355\215\275\267\236\\\371\307\265\360\201/\327\3027o\233\361J\262\233\247~\362g\336\211zur!A]{\035}\031S\343\006p\241\226dKI\v\326\202\265\3153\331)X)\335fE\205M\235\373\327\r*\374\026\252\022\216u\223\200\361I\211\177\031\022\001#``\342GI\211\004c\221gi\246\231\247\221\247\231\247\233$XM3\315<\215<\315<K\211e\036#\215a4\366\344\035lm\214Z\314b\211Xj\337K\\\201$\332\325\v\365\2659\204\362\242\274'\v\221\r\321\211\216\364\027`\0\212'_\215\n", 220);
1729  fNByte += 220;
1730  PrintStr("endstream@");
1731  PrintStr("endobj@");
1732 
1733  // P16
1734  NewObject(patternNb++);
1735  PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
1737  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
1738  PrintStr("@");
1739  fStream->write("stream",6); fNByte += 6;
1740  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302ej\240\0D\271 \332\314X\317B\301\330\002H\230\233*\030\231\202\310d.CC=#\020\v*\rV\235\214\254\v\210r@\264\261\031P\241\031H5D\253\021H\267\005\3104 \v\344\016\260\002\020\003lB0W \027@\200\001\0hU \305\n", 125);
1741  fNByte += 125;
1742  PrintStr("endstream@");
1743  PrintStr("endobj@");
1744 
1745  // P17
1746  NewObject(patternNb++);
1747  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1749  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
1750  PrintStr("@");
1751  fStream->write("stream",6); fNByte += 6;
1752  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020md\242\020k\240\220\002V\234\313\005S\236\303\025\314\025\310\005\020`\0\r\351\016B\n", 68);
1753  fNByte += 68;
1754  PrintStr("endstream@");
1755  PrintStr("endobj@");
1756 
1757  // P18
1758  NewObject(patternNb++);
1759  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1761  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
1762  PrintStr("@");
1763  fStream->write("stream",6); fNByte += 6;
1764  fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020md\242\020k\240\220\302\005Q\226\313\005\"\r\024r\270\202\271\002\271\0\002\f\0\016\001\016B\n", 71);
1765  fNByte += 71;
1766  PrintStr("endstream@");
1767  PrintStr("endobj@");
1768 
1769  // P19
1770  NewObject(patternNb++);
1771  PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
1773  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
1774  PrintStr("@");
1775  fStream->write("stream",6); fNByte += 6;
1776  fStream->write("\r\nH\211L\216;\016\302@\fD{\237bN\020\331+6a\257\200D\201((P\252@\001R\220\240\341\372\370\263\216(\326\266f\336\330\373&\301\003\304`\b\307\373\334\351\202\227J\a\025\237\020|U\306\021\327\231q\243\306\250\214\325\372T\006\336\367\032\262\326\205\3124\264b\243$\"n.\244=\314\250!\2139\033\327\022i=\323\317\2518\332T}\347.\202\346W\373\372j\315\221\344\266\213=\237\241\344\034\361\264!\236w\344\177\271o8\323\211~\002\f\0\366\3026\233\n", 151);
1777  fNByte += 151;
1778  PrintStr("endstream@");
1779  PrintStr("endobj@");
1780 
1781  // P20
1782  NewObject(patternNb++);
1783  PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
1785  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
1786  PrintStr("@");
1787  fStream->write("stream",6); fNByte += 6;
1788  fStream->write("\r\nH\211<L;\016\2030\f\335}\212w\002\344$M\2323 1 \006\006\304\224vhU\220`\341\372<\aT\311\366\263\336o\023\207\017D\241pz\355\376\226\021+\251\226\344\027\017\034\244\321a\232\025/\211\n\316r\343ORh\262}\317\210\344\032o\310)\302\2233\245\252[m\274\332\313\277!$\332\371\371\210`N\242\267$\217\263\246\252W\257\245\006\351\345\024`\0o\347 \305\n", 124);
1789  fNByte += 124;
1790  PrintStr("endstream@");
1791  PrintStr("endobj@");
1792 
1793  // P21
1794  NewObject(patternNb++);
1795  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1797  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
1798  PrintStr("@");
1799  fStream->write("stream",6); fNByte += 6;
1800  fStream->write("\r\nH\211D\2151\n\2000\fE\367\234\342\037!)\224\336Ap\020\a\aq\323A\251\202.^\337$-\025\022^\372\033^n\022\354 \006CX\274\237\215&\\\032u\032\036\020\274\032\243\307\2740V]\027\234\024\242\"\033\2642En\324\312\224bc\262\\\230\377\301\332WM\224\212(U\221\375\265\301\025\016?\350\317P\215\221\033\213o\244\201>\001\006\0\031I'f\n", 119);
1801  fNByte += 119;
1802  PrintStr("endstream@");
1803  PrintStr("endobj@");
1804 
1805  // P22
1806  NewObject(patternNb++);
1807  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1809  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
1810  PrintStr("@");
1811  fStream->write("stream",6); fNByte += 6;
1812  fStream->write("\r\nH\211<\215=\n\204P\f\204\373\234b\216\220<\b\357\016\302\026ba!vZ(\273\v\332x}\223\274\237\"|\223a\230\271Hp\200\030\fa\211\273w\232\3617k0\363\204\3401\033\037,+c#\3170~\2244\304\327EV\243r\247\272oOcr\337\323]H\t\226\252\334\252r\255\362\257\213(\t\304\250\326\315T\267\032\275q\242\221^\001\006\0\272\367(&\n", 120);
1813  fNByte += 120;
1814  PrintStr("endstream@");
1815  PrintStr("endobj@");
1816 
1817  // P23
1818  NewObject(patternNb++);
1819  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1821  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
1822  PrintStr("@");
1823  fStream->write("stream",6); fNByte += 6;
1824  fStream->write("\r\nH\211<\220\273\n\0021\020E\373\371\212[[M\326\331\354\344\027\004\v\261\260\020;\025\224D\320\306\337w\036\254p\363\230\223\341$\344M\005\017\020\203Q8\307\347F'\274\f\355\f>Q\3605\214=\316\005\v.\214kt\217\230;)\324\366\245Fa\213e\320v\212r\022X\006\211Fi\3242\250J\224\302\020\367h\212\254I\\\325R\225o\03143\346U\235@a\t[\202Za\tA\202E`\351~O\002\235`\351~S\202\306h.m\253\264)\232K\217t\310\017q\354\a\353\247\364\377C\356\033\372\t0\0\bm:\375\n", 171);
1825  fNByte += 171;
1826  PrintStr("endstream@");
1827  PrintStr("endobj@");
1828 
1829  // P24
1830  NewObject(patternNb++);
1831  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1833  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
1834  PrintStr("@");
1835  fStream->write("stream",6); fNByte += 6;
1836  fStream->write("\r\nH\211DQ9N\004A\f\314\373\025\216\211\326\343v\037_@\"@\004\004\210\f\220@\003\022$|\177\335\345j\220v\345\251\303\343*\215\312\273\024\275\\d\375?\361dM\3162\306\337\214\337Y\336n\240m\217\036\301y\343\\<,i\250\0038F\035)\347l\322\026o\377\023\353|[\254\177\343\005;\315\317ky\224\257\240n\203\374\020\225\337\240\345N\236T\272<_\344\245\304^\3238\030\tc\236E\233xO\034\363\204>\251\317\324\233\023{\352\235\376\336S\357Fl\251\017\372\207\247>xoh&_\366Ud\331\253\314D\023\332\241\211\016\205\246\235\326\236*\275\307\204z8!s\031\335\306\\\306C\306\\\225\376\312\\\225\307\252\246\356\364\273Q\347\271:\371\341l\177\311e\210\3571\211\251#\374\302H\037:\342c\241\323\2617\320 \034\250\0\302\323a{\005%\302a\373(Zx\313\026\213@\215p\324}\026=\274e\217E8s\326}\026M\036\312}\271\n0\0\215\263\207\016\n", 282);
1837  fNByte += 282;
1838  PrintStr("endstream@");
1839  PrintStr("endobj@");
1840 
1841  // P25
1842  NewObject(patternNb++);
1843  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
1845  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
1846  PrintStr("@");
1847  fStream->write("stream",6); fNByte += 6;
1848  fStream->write("\r\nH\2112T\310T\3402P0P\310\34526P\0\242\034.s\004m\016\242\r\r\f\024@\030\302\002\321iZP\305`M\346\310\212\201R\0\001\006\0\206\322\017\200\n", 56);
1849  fNByte += 56;
1850  PrintStr("endstream@");
1851  PrintStr("endobj@");
1852 }
1853 
1854 ////////////////////////////////////////////////////////////////////////////////
1855 /// Output the string str in the output buffer
1856 
1857 void TPDF::PrintStr(const char *str)
1858 {
1859  Int_t len = strlen(str);
1860  if (len == 0) return;
1861  fPageNotEmpty = kTRUE;
1862 
1863  if (fCompress) {
1864  if (fLenBuffer+len >= fSizBuffer) {
1866  fSizBuffer = 2*fSizBuffer;
1867  }
1868  strcpy(fBuffer + fLenBuffer, str);
1869  fLenBuffer += len;
1870  return;
1871  }
1872 
1873  TVirtualPS::PrintStr(str);
1874 }
1875 
1876 ////////////////////////////////////////////////////////////////////////////////
1877 /// Fast version of Print
1878 
1879 void TPDF::PrintFast(Int_t len, const char *str)
1880 {
1881  fPageNotEmpty = kTRUE;
1882  if (fCompress) {
1883  if (fLenBuffer+len >= fSizBuffer) {
1885  fSizBuffer = 2*fSizBuffer;
1886  }
1887  strcpy(fBuffer + fLenBuffer, str);
1888  fLenBuffer += len;
1889  return;
1890  }
1891 
1892  TVirtualPS::PrintFast(len, str);
1893 }
1894 
1895 ////////////////////////////////////////////////////////////////////////////////
1896 /// Set the range for the paper in centimetres
1897 
1898 void TPDF::Range(Float_t xsize, Float_t ysize)
1899 {
1900  Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
1901 
1902  fXsize = xsize;
1903  fYsize = ysize;
1904 
1905  xps = xsize;
1906  yps = ysize;
1907 
1908  if (xsize <= xps && ysize < yps) {
1909  if ( xps > yps) xymax = xps;
1910  else xymax = yps;
1911  xncm = xsize/xymax;
1912  yncm = ysize/xymax;
1913  dxwn = ((xps/xymax)-xncm)/2;
1914  dywn = ((yps/xymax)-yncm)/2;
1915  } else {
1916  if (xps/yps < 1) xwkwn = xps/yps;
1917  else xwkwn = 1;
1918  if (yps/xps < 1) ywkwn = yps/xps;
1919  else ywkwn = 1;
1920 
1921  if (xsize < ysize) {
1922  xncm = ywkwn*xsize/ysize;
1923  yncm = ywkwn;
1924  dxwn = (xwkwn-xncm)/2;
1925  dywn = 0;
1926  if (dxwn < 0) {
1927  xncm = xwkwn;
1928  dxwn = 0;
1929  yncm = xwkwn*ysize/xsize;
1930  dywn = (ywkwn-yncm)/2;
1931  }
1932  } else {
1933  xncm = xwkwn;
1934  yncm = xwkwn*ysize/xsize;
1935  dxwn = 0;
1936  dywn = (ywkwn-yncm)/2;
1937  if (dywn < 0) {
1938  yncm = ywkwn;
1939  dywn = 0;
1940  xncm = ywkwn*xsize/ysize;
1941  dxwn = (xwkwn-xncm)/2;
1942  }
1943  }
1944  }
1945  fRange = kTRUE;
1946 }
1947 
1948 ////////////////////////////////////////////////////////////////////////////////
1949 /// Set the alpha channel value.
1950 
1952 {
1953  if (a == fAlpha) return;
1954  fAlpha = a;
1955  if (fAlpha <= 0.000001) fAlpha = 0;
1956 
1957  Bool_t known = kFALSE;
1958  for (int i=0; i<(int)fAlphas.size(); i++) {
1959  if (fAlpha == fAlphas[i]) {
1960  known = kTRUE;
1961  break;
1962  }
1963  }
1964  if (!known) fAlphas.push_back(fAlpha);
1965  PrintStr(Form(" /ca%3.2f gs /CA%3.2f gs",fAlpha,fAlpha));
1966 }
1967 
1968 ////////////////////////////////////////////////////////////////////////////////
1969 /// Set color with its color index.
1970 
1972 {
1973  if (color < 0) color = 0;
1974  TColor *col = gROOT->GetColor(color);
1975 
1976  if (col) {
1977  SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1978  SetAlpha(col->GetAlpha());
1979  } else {
1980  SetColor(1., 1., 1.);
1981  SetAlpha(1.);
1982  }
1983 }
1984 
1985 ////////////////////////////////////////////////////////////////////////////////
1986 /// Set color with its R G B components:
1987 ///
1988 /// - r: % of red in [0,1]
1989 /// - g: % of green in [0,1]
1990 /// - b: % of blue in [0,1]
1991 
1993 {
1994  if (r == fRed && g == fGreen && b == fBlue) return;
1995 
1996  fRed = r;
1997  fGreen = g;
1998  fBlue = b;
1999  if (fRed <= 0.000001) fRed = 0;
2000  if (fGreen <= 0.000001) fGreen = 0;
2001  if (fBlue <= 0.000001) fBlue = 0;
2002 
2003  if (gStyle->GetColorModelPS()) {
2004  Double_t colCyan, colMagenta, colYellow;
2005  Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
2006  if (colBlack==1) {
2007  colCyan = 0;
2008  colMagenta = 0;
2009  colYellow = 0;
2010  } else {
2011  colCyan = (1-fRed-colBlack)/(1-colBlack);
2012  colMagenta = (1-fGreen-colBlack)/(1-colBlack);
2013  colYellow = (1-fBlue-colBlack)/(1-colBlack);
2014  }
2015  if (colCyan <= 0.000001) colCyan = 0;
2016  if (colMagenta <= 0.000001) colMagenta = 0;
2017  if (colYellow <= 0.000001) colYellow = 0;
2018  if (colBlack <= 0.000001) colBlack = 0;
2019  WriteReal(colCyan);
2020  WriteReal(colMagenta);
2021  WriteReal(colYellow);
2022  WriteReal(colBlack);
2023  PrintFast(2," K");
2024  WriteReal(colCyan);
2025  WriteReal(colMagenta);
2026  WriteReal(colYellow);
2027  WriteReal(colBlack);
2028  PrintFast(2," k");
2029  } else {
2030  WriteReal(fRed);
2031  WriteReal(fGreen);
2032  WriteReal(fBlue);
2033  PrintFast(3," RG");
2034  WriteReal(fRed);
2035  WriteReal(fGreen);
2036  WriteReal(fBlue);
2037  PrintFast(3," rg");
2038  }
2039 }
2040 
2041 ////////////////////////////////////////////////////////////////////////////////
2042 /// Set color index for fill areas
2043 
2045 {
2046  fFillColor = cindex;
2047  if (gStyle->GetFillColor() <= 0) cindex = 0;
2048 }
2049 
2050 ////////////////////////////////////////////////////////////////////////////////
2051 /// Set the fill patterns (1 to 25) for fill areas
2052 
2054 {
2055  char cpat[10];
2056  TColor *col = gROOT->GetColor(color);
2057  if (!col) return;
2058  PrintStr(" /Cs8 cs");
2059  Double_t colRed = col->GetRed();
2060  Double_t colGreen = col->GetGreen();
2061  Double_t colBlue = col->GetBlue();
2062  if (gStyle->GetColorModelPS()) {
2063  Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
2064  if (colBlack==1) {
2065  WriteReal(0);
2066  WriteReal(0);
2067  WriteReal(0);
2068  WriteReal(colBlack);
2069  } else {
2070  Double_t colCyan = (1-colRed-colBlack)/(1-colBlack);
2071  Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
2072  Double_t colYellow = (1-colBlue-colBlack)/(1-colBlack);
2073  WriteReal(colCyan);
2074  WriteReal(colMagenta);
2075  WriteReal(colYellow);
2076  WriteReal(colBlack);
2077  }
2078  } else {
2079  WriteReal(colRed);
2080  WriteReal(colGreen);
2081  WriteReal(colBlue);
2082  }
2083  snprintf(cpat,10," /P%2.2d scn", ipat);
2084  PrintStr(cpat);
2085 }
2086 
2087 ////////////////////////////////////////////////////////////////////////////////
2088 /// Set color index for lines
2089 
2091 {
2092  fLineColor = cindex;
2093 }
2094 
2095 ////////////////////////////////////////////////////////////////////////////////
2096 /// Change the line style
2097 ///
2098 /// - linestyle = 2 dashed
2099 /// - linestyle = 3 dotted
2100 /// - linestyle = 4 dash-dotted
2101 /// - linestyle = else solid (1 in is used most of the time)
2102 
2104 {
2105  if ( linestyle == fLineStyle) return;
2106  fLineStyle = linestyle;
2107  TString st = (TString)gStyle->GetLineStyleString(linestyle);
2108  PrintFast(2," [");
2109  TObjArray *tokens = st.Tokenize(" ");
2110  for (Int_t j = 0; j<tokens->GetEntries(); j++) {
2111  Int_t it;
2112  sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2113  WriteInteger((Int_t)(it/4));
2114  }
2115  delete tokens;
2116  PrintFast(5,"] 0 d");
2117 }
2118 
2119 ////////////////////////////////////////////////////////////////////////////////
2120 /// Change the line width
2121 
2123 {
2124  if (linewidth == fLineWidth) return;
2125  fLineWidth = linewidth;
2126  if (fLineWidth!=0) {
2128  PrintFast(2," w");
2129  }
2130 }
2131 
2132 ////////////////////////////////////////////////////////////////////////////////
2133 /// Set color index for markers.
2134 
2136 {
2137  fMarkerColor = cindex;
2138 }
2139 
2140 ////////////////////////////////////////////////////////////////////////////////
2141 /// Set color index for text
2142 
2144 {
2145  fTextColor = cindex;
2146 }
2147 
2148 ////////////////////////////////////////////////////////////////////////////////
2149 /// Draw text
2150 ///
2151 /// - xx: x position of the text
2152 /// - yy: y position of the text
2153 /// - chars: text to be drawn
2154 
2155 void TPDF::Text(Double_t xx, Double_t yy, const char *chars)
2156 {
2157  if (fTextSize <= 0) return;
2158 
2159  const Double_t kDEGRAD = TMath::Pi()/180.;
2160  char str[8];
2161  Double_t x = xx;
2162  Double_t y = yy;
2163 
2164  // Font and text size
2165  Int_t font = abs(fTextFont)/10;
2166  if (font > kNumberOfFonts || font < 1) font = 1;
2167 
2168  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2169  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2170  Float_t tsize, ftsize;
2171  if (wh < hh) {
2172  tsize = fTextSize*wh;
2173  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2174  ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2175  } else {
2176  tsize = fTextSize*hh;
2177  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2178  ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2179  }
2180  Double_t fontsize = 72*(ftsize)/2.54;
2181  if (fontsize <= 0) return;
2182 
2183  // Text color
2185 
2186  // Clipping
2187  PrintStr(" q");
2188  Double_t x1 = XtoPDF(gPad->GetX1());
2189  Double_t x2 = XtoPDF(gPad->GetX2());
2190  Double_t y1 = YtoPDF(gPad->GetY1());
2191  Double_t y2 = YtoPDF(gPad->GetY2());
2192  WriteReal(x1);
2193  WriteReal(y1);
2194  WriteReal(x2 - x1);
2195  WriteReal(y2 - y1);
2196  PrintStr(" re W n");
2197 
2198  // Start the text
2199  if (!fCompress) PrintStr("@");
2200 
2201  // Text alignment
2202  Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2203  Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2204  Int_t txalh = fTextAlign/10;
2205  if (txalh < 1) txalh = 1; else if (txalh > 3) txalh = 3;
2206  Int_t txalv = fTextAlign%10;
2207  if (txalv < 1) txalv = 1; else if (txalv > 3) txalv = 3;
2208  if (txalv == 3) {
2209  y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2210  x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2211  } else if (txalv == 2) {
2212  y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2213  x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2214  }
2215 
2216  if (txalh > 1) {
2217  TText t;
2218  UInt_t w=0, h;
2221  t.GetTextExtent(w, h, chars);
2222  Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2223  Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
2224  if (txalh == 2) {
2225  x = x-(twx/2)*TMath::Cos(kDEGRAD*fTextAngle);
2226  y = y-(twy/2)*TMath::Sin(kDEGRAD*fTextAngle);
2227  }
2228  if (txalh == 3) {
2229  x = x-twx*TMath::Cos(kDEGRAD*fTextAngle);
2230  y = y-twy*TMath::Sin(kDEGRAD*fTextAngle);
2231  }
2232  }
2233 
2234  // Text angle
2235  if (fTextAngle == 0) {
2236  PrintStr(" 1 0 0 1");
2237  WriteReal(XtoPDF(x));
2238  WriteReal(YtoPDF(y));
2239  } else if (fTextAngle == 90) {
2240  PrintStr(" 0 1 -1 0");
2241  WriteReal(XtoPDF(x));
2242  WriteReal(YtoPDF(y));
2243  } else if (fTextAngle == 270) {
2244  PrintStr(" 0 -1 1 0");
2245  WriteReal(XtoPDF(x));
2246  WriteReal(YtoPDF(y));
2247  } else {
2248  WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
2249  WriteReal(TMath::Sin(kDEGRAD*fTextAngle));
2250  WriteReal(-TMath::Sin(kDEGRAD*fTextAngle));
2251  WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
2252  WriteReal(XtoPDF(x));
2253  WriteReal(YtoPDF(y));
2254  }
2255  PrintStr(" cm");
2256 
2257  // Symbol Italic tan(15) = .26794
2258  if (font == 15) PrintStr(" 1 0 0.26794 1 0 0 cm");
2259 
2260  PrintStr(" BT");
2261 
2262  snprintf(str,8," /F%d",font);
2263  PrintStr(str);
2264  WriteReal(fontsize);
2265  PrintStr(" Tf");
2266 
2267  const Int_t len=strlen(chars);
2268 
2269  // Calculate the individual character placements.
2270  // Otherwise, if a string is printed in one line the kerning is not
2271  // performed. In order to measure the precise character positions we need to
2272  // trick FreeType into rendering high-resolution characters otherwise it will
2273  // stick to the screen pixel grid which is far worse than we can achieve on
2274  // print.
2275  const Float_t scale = 16.0;
2276  // Save current text attributes.
2277  TText saveAttText;
2278  saveAttText.TAttText::operator=(*this);
2279  TText t;
2280  t.SetTextSize(fTextSize * scale);
2282  UInt_t wa1=0, wa0=0;
2283  t.GetTextAdvance(wa0, chars, kFALSE);
2284  t.GetTextAdvance(wa1, chars);
2285  t.TAttText::Modify();
2286  Bool_t kerning;
2287  if (wa0-wa1 != 0) kerning = kTRUE;
2288  else kerning = kFALSE;
2289  Int_t *charDeltas = 0;
2290  if (kerning) {
2291  charDeltas = new Int_t[len];
2292  for (Int_t i = 0;i < len;i++) {
2293  UInt_t ww=0;
2294  t.GetTextAdvance(ww, chars + i);
2295  charDeltas[i] = wa1 - ww;
2296  }
2297  for (Int_t i = len - 1;i > 0;i--) {
2298  charDeltas[i] -= charDeltas[i-1];
2299  }
2300  char tmp[2];
2301  tmp[1] = 0;
2302  for (Int_t i = 1;i < len;i++) {
2303  tmp[0] = chars[i-1];
2304  UInt_t width=0;
2305  t.GetTextAdvance(width, &tmp[0], kFALSE);
2306  Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
2307  wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
2308  charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
2309  }
2310  }
2311  // Restore text attributes.
2312  saveAttText.TAttText::Modify();
2313 
2314  // Output the text. Escape some characters if needed
2315  if (kerning) PrintStr(" [");
2316  else PrintStr(" (");
2317 
2318  for (Int_t i=0; i<len;i++) {
2319  if (chars[i]!='\n') {
2320  if (kerning) PrintStr("(");
2321  if (chars[i]=='(' || chars[i]==')') {
2322  snprintf(str,8,"\\%c",chars[i]);
2323  } else {
2324  snprintf(str,8,"%c",chars[i]);
2325  }
2326  PrintStr(str);
2327  if (kerning) {
2328  PrintStr(") ");
2329  if (i < len-1) {
2330  WriteInteger(charDeltas[i+1]);
2331  }
2332  }
2333  }
2334  }
2335 
2336  if (kerning) PrintStr("] TJ ET Q");
2337  else PrintStr(") Tj ET Q");
2338  if (!fCompress) PrintStr("@");
2339  if (kerning) delete [] charDeltas;
2340 }
2341 
2342 ////////////////////////////////////////////////////////////////////////////////
2343 /// Write a string of characters
2344 ///
2345 /// This method writes the string chars into a PostScript file
2346 /// at position xx,yy in world coordinates.
2347 
2348 void TPDF::Text(Double_t, Double_t, const wchar_t *)
2349 {
2350 }
2351 
2352 ////////////////////////////////////////////////////////////////////////////////
2353 /// Write a string of characters in NDC
2354 
2355 void TPDF::TextNDC(Double_t u, Double_t v, const char *chars)
2356 {
2357  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2358  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2359  Text(x, y, chars);
2360 }
2361 
2362 ////////////////////////////////////////////////////////////////////////////////
2363 /// Write a string of characters in NDC
2364 
2365 void TPDF::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2366 {
2367  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2368  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2369  Text(x, y, chars);
2370 }
2371 
2372 ////////////////////////////////////////////////////////////////////////////////
2373 /// Convert U from NDC coordinate to PDF
2374 
2376 {
2377  Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2378  return 72*cm/2.54;
2379 }
2380 
2381 ////////////////////////////////////////////////////////////////////////////////
2382 /// Convert V from NDC coordinate to PDF
2383 
2385 {
2386  Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2387  return 72*cm/2.54;
2388 }
2389 
2390 ////////////////////////////////////////////////////////////////////////////////
2391 /// Convert X from world coordinate to PDF
2392 
2394 {
2395  Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2396  return UtoPDF(u);
2397 }
2398 
2399 ////////////////////////////////////////////////////////////////////////////////
2400 /// Convert Y from world coordinate to PDF
2401 
2403 {
2404  Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2405  return VtoPDF(v);
2406 }
2407 
2408 ////////////////////////////////////////////////////////////////////////////////
2409 /// Write the buffer in a compressed way
2410 
2412 {
2413  z_stream stream;
2414  int err;
2415  char *out = new char[2*fLenBuffer];
2416 
2417  stream.next_in = (Bytef*)fBuffer;
2418  stream.avail_in = (uInt)fLenBuffer;
2419  stream.next_out = (Bytef*)out;
2420  stream.avail_out = (uInt)2*fLenBuffer;
2421  stream.zalloc = (alloc_func)0;
2422  stream.zfree = (free_func)0;
2423  stream.opaque = (voidpf)0;
2424 
2425  err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2426  if (err != Z_OK) {
2427  Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
2428  return;
2429  }
2430 
2431  err = deflate(&stream, Z_FINISH);
2432  if (err != Z_STREAM_END) {
2433  deflateEnd(&stream);
2434  Error("WriteCompressedBuffer", "error in deflate (zlib)");
2435  return;
2436  }
2437 
2438  err = deflateEnd(&stream);
2439 
2440  fStream->write(out, stream.total_out);
2441 
2442  fNByte += stream.total_out;
2443  fStream->write("\n",1); fNByte++;
2444  fLenBuffer = 0;
2445  delete [] out;
2446  fCompress = kFALSE;
2447 }
2448 
2449 ////////////////////////////////////////////////////////////////////////////////
2450 /// Write a Real number to the file.
2451 /// This method overwrites TVirtualPS::WriteReal. Some PDF reader like
2452 /// Acrobat do not work when a PDF file contains reals with exponent. This
2453 /// method writes the real number "z" using the format "%f" instead of the
2454 /// format "%g" when writing it with "%g" generates a number with exponent.
2455 
2457 {
2458  char str[15];
2459  if (space) {
2460  snprintf(str,15," %g", z);
2461  if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
2462  } else {
2463  snprintf(str,15,"%g", z);
2464  if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15,"%10.8f", z);
2465  }
2466  PrintStr(str);
2467 }
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw a Box.
Definition: TPDF.cxx:349
const char * GetLineStyleString(Int_t i=1) const
Return line style string (used by PostScript).
Definition: TStyle.cxx:787
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
void DrawPS(Int_t n, Float_t *xw, Float_t *yw)
Draw a PolyLine.
Definition: TPDF.cxx:865
const Int_t kObjPattern
Definition: TPDF.cxx:90
void MoveTo(Double_t x, Double_t y)
Move to a new position.
Definition: TPDF.cxx:1073
char * fBuffer
Definition: TVirtualPS.h:52
An array of TObjects.
Definition: TObjArray.h:39
Int_t GetMonth() const
Definition: TDatime.h:68
void On()
Activate an already open PDF file.
Definition: TPDF.cxx:1283
const Int_t kObjInfo
Definition: TPDF.cxx:80
void WriteCompressedBuffer()
Write the buffer in a compressed way.
Definition: TPDF.cxx:2411
short Style_t
Definition: RtypesCore.h:76
const Int_t kNumberOfFonts
Definition: TPDF.cxx:94
Float_t fXsize
Definition: TPDF.h:40
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
void DrawHatch(Float_t dy, Float_t angle, Int_t n, Float_t *x, Float_t *y)
Draw Fill area with hatch styles.
Definition: TPDF.cxx:455
Float_t fYsize
Definition: TPDF.h:41
const Float_t kScale
Definition: TPDF.cxx:76
const char Option_t
Definition: RtypesCore.h:62
void SetColor(Int_t color=1)
Set color with its color index.
Definition: TPDF.cxx:1971
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
void FontEncode()
Font encoding.
Definition: TPDF.cxx:1031
TH1 * h
Definition: legend2.C:5
Bool_t fRange
Definition: TPDF.h:53
Size_t fMarkerSize
Definition: TAttMarker.h:37
#define gROOT
Definition: TROOT.h:340
Int_t fType
Definition: TPDF.h:42
Int_t fStartStream
Definition: TPDF.h:45
Basic string class.
Definition: TString.h:137
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
Definition: TVirtualPS.cxx:167
void GetPaperSize(Float_t &xsize, Float_t &ysize) const
Set paper size for PostScript output.
Definition: TStyle.cxx:805
Float_t GetLineScalePS() const
Definition: TStyle.h:295
void SetTextColor(Color_t cindex=1)
Set color index for text.
Definition: TPDF.cxx:2143
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
Int_t fObjPosSize
Definition: TPDF.h:48
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
TArc * a
Definition: textangle.C:12
const Bool_t kFALSE
Definition: Rtypes.h:92
Float_t fAlpha
Definition: TPDF.h:38
Float_t GetGreen() const
Definition: TColor.h:61
const Int_t kObjOutlines
Definition: TPDF.cxx:81
Bool_t fPageNotEmpty
Definition: TPDF.h:51
Double_t CMtoPDF(Double_t u)
Definition: TPDF.h:64
const Int_t kObjColorSpace
Definition: TPDF.cxx:86
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
Int_t fNbObj
Definition: TPDF.h:49
std::vector< float > fAlphas
Definition: TPDF.h:39
virtual void SetTextFont(Font_t tfont=62)
Definition: TAttText.h:59
Bool_t fCompress
Definition: TPDF.h:52
const Int_t kObjPatternList
Definition: TPDF.cxx:88
static const double x2[5]
Double_t x[n]
Definition: legend1.C:17
Int_t GetDay() const
Definition: TDatime.h:69
Float_t fBlue
Definition: TPDF.h:37
virtual void PrintStr(const char *string="")
Output the string str in the output buffer.
Definition: TVirtualPS.cxx:69
Int_t fNbPage
Definition: TPDF.h:50
static char * ReAllocChar(char *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition: TStorage.cxx:259
Int_t fPageFormat
Definition: TPDF.h:43
void Text(Double_t x, Double_t y, const char *string)
Draw text.
Definition: TPDF.cxx:2155
Double_t XtoPDF(Double_t x)
Convert X from world coordinate to PDF.
Definition: TPDF.cxx:2393
Float_t GetBlue() const
Definition: TColor.h:62
void Close(Option_t *opt="")
Close a PDF file.
Definition: TPDF.cxx:197
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
Definition: vector.h:450
const Int_t kObjRoot
Definition: TPDF.cxx:79
Base class for several text objects.
Definition: TText.h:42
void NewObject(Int_t n)
Create a new object in the PDF file.
Definition: TPDF.cxx:1083
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
void Off()
Deactivate an already open PDF file.
Definition: TPDF.cxx:1275
void SetAlpha(Float_t alpha=1.)
Set the alpha channel value.
Definition: TPDF.cxx:1951
void NewPage()
Start a new PDF page.
Definition: TPDF.cxx:1106
char * out
Definition: TBase64.cxx:29
short Color_t
Definition: RtypesCore.h:79
void CellArrayFill(Int_t r, Int_t g, Int_t b)
Paint the Cell Array.
Definition: TPDF.cxx:181
Int_t GetColorModelPS() const
Definition: TStyle.h:206
void PrintFast(Int_t nch, const char *string="")
Fast version of Print.
Definition: TPDF.cxx:1879
Style_t fMarkerStyle
Definition: TAttMarker.h:36
TCanvas * kerning()
Definition: kerning.C:1
void SetLineStyle(Style_t linestyle=1)
Change the line style.
Definition: TPDF.cxx:2103
Float_t fRed
Definition: TPDF.h:35
Double_t YtoPDF(Double_t y)
Convert Y from world coordinate to PDF.
Definition: TPDF.cxx:2402
Float_t fTextAngle
Definition: TAttText.h:35
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimetres.
Definition: TPDF.cxx:1898
Style_t fLineStyle
Definition: TAttLine.h:36
const Int_t kObjPatternResourses
Definition: TPDF.cxx:87
ROOT::R::TRInterface & r
Definition: Object.C:4
void DrawPolyLine(Int_t n, TPoints *xy)
Draw a PolyLine.
Definition: TPDF.cxx:479
SVector< double, 2 > v
Definition: Dict.h:5
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
const Int_t kObjContents
Definition: TPDF.cxx:84
Int_t fSizBuffer
Definition: TVirtualPS.h:49
Color_t fLineColor
Definition: TAttLine.h:35
ClassImp(TPDF) TPDF
Default PDF constructor.
Definition: TPDF.cxx:96
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
Definition: TPDF.cxx:2355
Int_t GetHour() const
Definition: TDatime.h:71
unsigned int UInt_t
Definition: RtypesCore.h:42
Width_t fLineWidth
Definition: TAttLine.h:37
TMarker * m
Definition: textangle.C:8
char * Form(const char *fmt,...)
Double_t VtoPDF(Double_t v)
Convert V from NDC coordinate to PDF.
Definition: TPDF.cxx:2384
void SetMarkerColor(Color_t cindex=1)
Set color index for markers.
Definition: TPDF.cxx:2135
Int_t GetSecond() const
Definition: TDatime.h:73
virtual void GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
Return text extent for string text.
Definition: TText.cxx:583
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
std::ofstream * fStream
Definition: TVirtualPS.h:51
Font_t fTextFont
Definition: TAttText.h:39
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
Double_t Cos(Double_t)
Definition: TMath.h:424
short Width_t
Definition: RtypesCore.h:78
PyObject * fType
Int_t GetYear() const
Definition: TDatime.h:67
Double_t Pi()
Definition: TMath.h:44
2-D graphics point (world coordinates).
Definition: TPoints.h:29
void DrawPolyLineNDC(Int_t n, TPoints *uv)
Draw a PolyLine in NDC space.
Definition: TPDF.cxx:532
virtual void WriteReal(Float_t r, Bool_t space=kTRUE)
Write a Real number to the file.
Definition: TPDF.cxx:2456
static const double x1[5]
Int_t GetMinute() const
Definition: TDatime.h:72
const Int_t kObjPageResources
Definition: TPDF.cxx:83
void SetLineWidth(Width_t linewidth=1)
Change the line width.
Definition: TPDF.cxx:2122
double Double_t
Definition: RtypesCore.h:55
const Int_t kObjTransList
Definition: TPDF.cxx:89
const Int_t kObjPages
Definition: TPDF.cxx:82
virtual void PrintFast(Int_t nch, const char *string="")
Fast version of Print.
Definition: TVirtualPS.cxx:100
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Double_t y[n]
Definition: legend1.C:17
Double_t UtoPDF(Double_t u)
Convert U from NDC coordinate to PDF.
Definition: TPDF.cxx:2375
Float_t fGreen
Definition: TPDF.h:36
The color creation and management class.
Definition: TColor.h:23
Float_t GetRed() const
Definition: TColor.h:60
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:493
void SetLineScale(Float_t scale=1)
Definition: TPDF.h:94
Float_t fTextSize
Definition: TAttText.h:36
void DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt, Int_t mode, Int_t border, Int_t dark, Int_t light)
Draw a Frame around a box.
Definition: TPDF.cxx:415
void CellArrayEnd()
End the Cell Array painting.
Definition: TPDF.cxx:189
Float_t fLineScale
Definition: TPDF.h:46
void DrawPolyMarker(Int_t n, Float_t *x, Float_t *y)
Draw markers at the n WC points xw, yw.
Definition: TPDF.cxx:578
Int_t * fObjPos
Definition: TPDF.h:47
void SetFillColor(Color_t cindex=1)
Set color index for fill areas.
Definition: TPDF.cxx:2044
const Int_t kObjFont
Definition: TPDF.cxx:85
Int_t fLenBuffer
Definition: TVirtualPS.h:48
void CellArrayBegin(Int_t W, Int_t H, Double_t x1, Double_t x2, Double_t y1, Double_t y2)
Begin the Cell Array painting.
Definition: TPDF.cxx:172
Int_t fPageOrientation
Definition: TPDF.h:44
Color_t fFillColor
Definition: TAttFill.h:35
void Open(const char *filename, Int_t type=-111)
Open a PDF file.
Definition: TPDF.cxx:1299
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
void PatternEncode()
Patterns encoding.
Definition: TPDF.cxx:1456
Double_t Sin(Double_t)
Definition: TMath.h:421
void SetLineColor(Color_t cindex=1)
Set color index for lines.
Definition: TPDF.cxx:2090
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:91
void LineTo(Double_t x, Double_t y)
Draw a line to a new position.
Definition: TPDF.cxx:1063
virtual ~TPDF()
Default PDF destructor.
Definition: TPDF.cxx:162
Float_t GetAlpha() const
Definition: TColor.h:66
#define gPad
Definition: TVirtualPad.h:288
virtual void GetTextAdvance(UInt_t &a, const char *text, const Bool_t kern=kTRUE) const
Return text advance for string text if kern is true (default) kerning is taken into account...
Definition: TText.cxx:611
Interface to PDF.
Definition: TPDF.h:32
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition: TVirtualPS.h:40
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
const Bool_t kTRUE
Definition: Rtypes.h:91
Color_t fMarkerColor
Definition: TAttMarker.h:35
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
const Int_t kObjFirstPage
Definition: TPDF.cxx:91
Color_t fTextColor
Definition: TAttText.h:38
const Int_t n
Definition: legend1.C:16
void SetFillPatterns(Int_t ipat, Int_t color)
Set the fill patterns (1 to 25) for fill areas.
Definition: TPDF.cxx:2053
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:39
Int_t fNByte
Definition: TVirtualPS.h:47
Style_t fFillStyle
Definition: TAttFill.h:36
Short_t fTextAlign
Definition: TAttText.h:37
void PrintStr(const char *string="")
Output the string str in the output buffer.
Definition: TPDF.cxx:1857
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904