Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
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 \brief 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 `TPostScript`.
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 
96 Int_t TPDF::fgLineJoin = 0;
97 
98 ClassImp(TPDF);
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Default PDF constructor
102 
103 TPDF::TPDF() : TVirtualPS()
104 {
105  fStream = 0;
106  fCompress = kFALSE;
107  fPageNotEmpty = kFALSE;
108  gVirtualPS = this;
109  fRed = 0.;
110  fGreen = 0.;
111  fBlue = 0.;
112  fAlpha = 1.;
113  fXsize = 0.;
114  fYsize = 0.;
115  fType = 0;
116  fPageFormat = 0;
117  fPageOrientation = 0;
118  fStartStream = 0;
119  fLineScale = 0.;
120  fObjPosSize = 0;
121  fObjPos = 0;
122  fNbObj = 0;
123  fNbPage = 0;
124  fRange = kFALSE;
125  SetTitle("PDF");
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// Initialize the PDF interface
130 ///
131 /// - fname : PDF file name
132 /// - wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
133 /// inherits from TVirtualPS it should be kept. Anyway it is not
134 /// necessary to specify this parameter at creation time because it
135 /// has a default value (which is ignore in the PDF case).
136 
137 TPDF::TPDF(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
138 {
139  fStream = 0;
140  fCompress = kFALSE;
141  fPageNotEmpty = kFALSE;
142  fRed = 0.;
143  fGreen = 0.;
144  fBlue = 0.;
145  fAlpha = 1.;
146  fXsize = 0.;
147  fYsize = 0.;
148  fType = 0;
149  fPageFormat = 0;
150  fPageOrientation = 0;
151  fStartStream = 0;
152  fLineScale = 0.;
153  fObjPosSize = 0;
154  fNbObj = 0;
155  fNbPage = 0;
156  fRange = kFALSE;
157  SetTitle("PDF");
158  Open(fname, wtype);
159 }
160 
161 ////////////////////////////////////////////////////////////////////////////////
162 /// Default PDF destructor
163 
164 TPDF::~TPDF()
165 {
166  Close();
167 
168  if (fObjPos) delete [] fObjPos;
169 }
170 
171 ////////////////////////////////////////////////////////////////////////////////
172 /// Begin the Cell Array painting
173 
174 void TPDF::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t,
175  Double_t)
176 {
177  Warning("TPDF::CellArrayBegin", "not yet implemented");
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// Paint the Cell Array
182 
183 void TPDF::CellArrayFill(Int_t, Int_t, Int_t)
184 {
185  Warning("TPDF::CellArrayFill", "not yet implemented");
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// End the Cell Array painting
190 
191 void TPDF::CellArrayEnd()
192 {
193  Warning("TPDF::CellArrayEnd", "not yet implemented");
194 }
195 
196 ////////////////////////////////////////////////////////////////////////////////
197 /// Close a PDF file
198 
199 void TPDF::Close(Option_t *)
200 {
201  Int_t i;
202 
203  if (!gVirtualPS) return;
204  if (!fStream) return;
205  if (gPad) gPad->Update();
206 
207  // Close the currently opened page
208  WriteCompressedBuffer();
209  PrintStr("endstream@");
210  Int_t streamLength = fNByte-fStartStream-10;
211  PrintStr("endobj@");
212  NewObject(4*(fNbPage-1)+kObjFirstPage+2);
213  WriteInteger(streamLength, 0);
214  PrintStr("@");
215  PrintStr("endobj@");
216  NewObject(4*(fNbPage-1)+kObjFirstPage+3);
217  PrintStr("<<@");
218  if (!strstr(GetTitle(),"PDF")) {
219  PrintStr("/Title (");
220  PrintStr(GetTitle());
221  PrintStr(")@");
222  } else {
223  PrintStr("/Title (Page");
224  WriteInteger(fNbPage);
225  PrintStr(")@");
226  }
227  PrintStr("/Dest [");
228  WriteInteger(4*(fNbPage-1)+kObjFirstPage);
229  PrintStr(" 0 R /XYZ null null 0]@");
230  PrintStr("/Parent");
231  WriteInteger(kObjContents);
232  PrintStr(" 0 R");
233  PrintStr("@");
234  if (fNbPage > 1) {
235  PrintStr("/Prev");
236  WriteInteger(4*(fNbPage-2)+kObjFirstPage+3);
237  PrintStr(" 0 R");
238  PrintStr("@");
239  }
240  PrintStr(">>@");
241 
242  NewObject(kObjOutlines);
243  PrintStr("<<@");
244  PrintStr("/Type /Outlines@");
245  PrintStr("/Count");
246  WriteInteger(fNbPage+1);
247  PrintStr("@");
248  PrintStr("/First");
249  WriteInteger(kObjContents);
250  PrintStr(" 0 R");
251  PrintStr("@");
252  PrintStr("/Last");
253  WriteInteger(kObjContents);
254  PrintStr(" 0 R");
255  PrintStr("@");
256  PrintStr(">>@");
257  PrintStr("endobj@");
258 
259  NewObject(kObjContents);
260  PrintStr("<<@");
261  PrintStr("/Title (Contents)@");
262  PrintStr("/Dest [");
263  WriteInteger(kObjFirstPage);
264  PrintStr(" 0 R /XYZ null null 0]@");
265  PrintStr("/Count");
266  WriteInteger(fNbPage);
267  PrintStr("@");
268  PrintStr("/Parent");
269  WriteInteger(kObjOutlines);
270  PrintStr(" 0 R");
271  PrintStr("@");
272  PrintStr("/First");
273  WriteInteger(kObjFirstPage+3);
274  PrintStr(" 0 R");
275  PrintStr("@");
276  PrintStr("/Last");
277  WriteInteger(4*(fNbPage-1)+kObjFirstPage+3);
278  PrintStr(" 0 R");
279  PrintStr("@");
280  PrintStr(">>@");
281 
282  // List of all the pages
283  NewObject(kObjPages);
284  PrintStr("<<@");
285  PrintStr("/Type /Pages@");
286  PrintStr("/Count");
287  WriteInteger(fNbPage);
288  PrintStr("@");
289  PrintStr("/Kids [");
290  for (i=1; i<=fNbPage; i++) {
291  WriteInteger(4*(i-1)+kObjFirstPage);
292  PrintStr(" 0 R");
293  }
294  PrintStr(" ]");
295  PrintStr("@");
296  PrintStr(">>@");
297  PrintStr("endobj@");
298 
299  NewObject(kObjTransList);
300  PrintStr("<<@");
301  for (i=0; i<(int)fAlphas.size(); i++) {
302  PrintStr(
303  Form("/ca%3.2f << /Type /ExtGState /ca %3.2f >> /CA%3.2f << /Type /ExtGState /CA %3.2f >>@",
304  fAlphas[i],fAlphas[i],fAlphas[i],fAlphas[i]));
305  }
306  PrintStr(">>@");
307  PrintStr("endobj@");
308  if (fAlphas.size()) fAlphas.clear();
309 
310  // Cross-Reference Table
311  Int_t refInd = fNByte;
312  PrintStr("xref@");
313  PrintStr("0");
314  WriteInteger(fNbObj+1);
315  PrintStr("@");
316  PrintStr("0000000000 65535 f @");
317  char str[21];
318  for (i=0; i<fNbObj; i++) {
319  snprintf(str,21,"%10.10d 00000 n @",fObjPos[i]);
320  PrintStr(str);
321  }
322 
323  // Trailer
324  PrintStr("trailer@");
325  PrintStr("<<@");
326  PrintStr("/Size");
327  WriteInteger(fNbObj+1);
328  PrintStr("@");
329  PrintStr("/Root");
330  WriteInteger(kObjRoot);
331  PrintStr(" 0 R");
332  PrintStr("@");
333  PrintStr("/Info");
334  WriteInteger(kObjInfo);
335  PrintStr(" 0 R@");
336  PrintStr(">>@");
337  PrintStr("startxref@");
338  WriteInteger(refInd, 0);
339  PrintStr("@");
340  PrintStr("%%EOF@");
341 
342  // Close file stream
343  if (fStream) { fStream->close(); delete fStream; fStream = 0;}
344 
345  gVirtualPS = 0;
346 }
347 
348 ////////////////////////////////////////////////////////////////////////////////
349 /// Draw a Box
350 
351 void TPDF::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
352 {
353  static Double_t x[4], y[4];
354  Double_t ix1 = XtoPDF(x1);
355  Double_t ix2 = XtoPDF(x2);
356  Double_t iy1 = YtoPDF(y1);
357  Double_t iy2 = YtoPDF(y2);
358  Int_t fillis = fFillStyle/1000;
359  Int_t fillsi = fFillStyle%1000;
360 
361  if (fillis == 3 || fillis == 2) {
362  if (fillsi > 99) {
363  x[0] = x1; y[0] = y1;
364  x[1] = x2; y[1] = y1;
365  x[2] = x2; y[2] = y2;
366  x[3] = x1; y[3] = y2;
367  return;
368  }
369  if (fillsi > 0 && fillsi < 26) {
370  x[0] = x1; y[0] = y1;
371  x[1] = x2; y[1] = y1;
372  x[2] = x2; y[2] = y2;
373  x[3] = x1; y[3] = y2;
374  DrawPS(-4, &x[0], &y[0]);
375  }
376  if (fillsi == -3) {
377  SetColor(5);
378  if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
379  WriteReal(ix1);
380  WriteReal(iy1);
381  WriteReal(ix2 - ix1);
382  WriteReal(iy2 - iy1);
383  if (fAlpha == 1) PrintFast(8," re b* Q");
384  else PrintFast(6," re f*");
385  }
386  }
387  if (fillis == 1) {
388  SetColor(fFillColor);
389  if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
390  WriteReal(ix1);
391  WriteReal(iy1);
392  WriteReal(ix2 - ix1);
393  WriteReal(iy2 - iy1);
394  if (fAlpha == 1) PrintFast(8," re b* Q");
395  else PrintFast(6," re f*");
396  }
397  if (fillis == 0) {
398  if (fLineWidth<=0) return;
399  SetColor(fLineColor);
400  WriteReal(ix1);
401  WriteReal(iy1);
402  WriteReal(ix2 - ix1);
403  WriteReal(iy2 - iy1);
404  PrintFast(5," re S");
405  }
406 }
407 
408 ////////////////////////////////////////////////////////////////////////////////
409 /// Draw a Frame around a box
410 ///
411 /// - mode = -1 box looks as it is behind the screen
412 /// - mode = 1 box looks as it is in front of the screen
413 /// - border is the border size in already precomputed PDF units
414 /// - dark is the color for the dark part of the frame
415 /// - light is the color for the light part of the frame
416 
417 void TPDF::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt,
418  Int_t mode, Int_t border, Int_t dark, Int_t light)
419 {
420  static Double_t xps[7], yps[7];
421  Int_t i;
422 
423  // Draw top&left part of the box
424  if (mode == -1) SetColor(dark);
425  else SetColor(light);
426  xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
427  xps[1] = xps[0] + border; yps[1] = yps[0] + border;
428  xps[2] = xps[1]; yps[2] = YtoPDF(yt) - border;
429  xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
430  xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
431  xps[5] = xps[0]; yps[5] = yps[4];
432  xps[6] = xps[0]; yps[6] = yps[0];
433 
434  MoveTo(xps[0], yps[0]);
435  for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
436  PrintFast(3," f*");
437 
438  // Draw bottom&right part of the box
439  if (mode == -1) SetColor(light);
440  else SetColor(dark);
441  xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
442  xps[1] = xps[0] + border; yps[1] = yps[0] + border;
443  xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
444  xps[3] = xps[2]; yps[3] = YtoPDF(yt) - border;
445  xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
446  xps[5] = xps[4]; yps[5] = yps[0];
447  xps[6] = xps[0]; yps[6] = yps[0];
448 
449  MoveTo(xps[0], yps[0]);
450  for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
451  PrintFast(3," f*");
452 }
453 
454 ////////////////////////////////////////////////////////////////////////////////
455 /// Draw Fill area with hatch styles
456 
457 void TPDF::DrawHatch(Float_t, Float_t, Int_t, Float_t *, Float_t *)
458 {
459  Warning("DrawHatch", "hatch fill style not yet implemented");
460 }
461 
462 ////////////////////////////////////////////////////////////////////////////////
463 /// Draw Fill area with hatch styles
464 
465 void TPDF::DrawHatch(Float_t, Float_t, Int_t, Double_t *, Double_t *)
466 {
467  Warning("DrawHatch", "hatch fill style not yet implemented");
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// Draw a PolyLine
472 ///
473 /// Draw a polyline through the points xy.
474 ///
475 /// - If NN=1 moves only to point x,y.
476 /// - If NN=0 the x,y are written in the PDF file
477 /// according to the current transformation.
478 /// - If NN>0 the line is clipped as a line.
479 /// - If NN<0 the line is clipped as a fill area.
480 
481 void TPDF::DrawPolyLine(Int_t nn, TPoints *xy)
482 {
483  Int_t n;
484 
485  Style_t linestylesav = fLineStyle;
486  Width_t linewidthsav = fLineWidth;
487 
488  if (nn > 0) {
489  if (fLineWidth<=0) return;
490  n = nn;
491  SetLineStyle(fLineStyle);
492  SetLineWidth(fLineWidth);
493  SetColor(Int_t(fLineColor));
494  } else {
495  n = -nn;
496  SetLineStyle(1);
497  SetLineWidth(1);
498  SetColor(Int_t(fLineColor));
499  }
500 
501  WriteReal(XtoPDF(xy[0].GetX()));
502  WriteReal(YtoPDF(xy[0].GetY()));
503  if (n <= 1) {
504  if (n == 0) return;
505  PrintFast(2," m");
506  return;
507  }
508 
509  PrintFast(2," m");
510 
511  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
512 
513  if (nn > 0) {
514  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
515  PrintFast(2," S");
516  } else {
517  PrintFast(3," f*");
518  }
519 
520  SetLineStyle(linestylesav);
521  SetLineWidth(linewidthsav);
522 }
523 
524 ////////////////////////////////////////////////////////////////////////////////
525 /// Draw a PolyLine in NDC space
526 ///
527 /// Draw a polyline through the points xy.
528 ///
529 /// - If NN=1 moves only to point x,y.
530 /// - If NN=0 the x,y are written in the PDF file
531 /// according to the current transformation.
532 /// - If NN>0 the line is clipped as a line.
533 /// - If NN<0 the line is clipped as a fill area.
534 
535 void TPDF::DrawPolyLineNDC(Int_t nn, TPoints *xy)
536 {
537  Int_t n;
538 
539  Style_t linestylesav = fLineStyle;
540  Width_t linewidthsav = fLineWidth;
541 
542  if (nn > 0) {
543  if (fLineWidth<=0) return;
544  n = nn;
545  SetLineStyle(fLineStyle);
546  SetLineWidth(fLineWidth);
547  SetColor(Int_t(fLineColor));
548  } else {
549  n = -nn;
550  SetLineStyle(1);
551  SetLineWidth(1);
552  SetColor(Int_t(fLineColor));
553  }
554 
555  WriteReal(UtoPDF(xy[0].GetX()));
556  WriteReal(VtoPDF(xy[0].GetY()));
557  if (n <= 1) {
558  if (n == 0) return;
559  PrintFast(2," m");
560  return;
561  }
562 
563  PrintFast(2," m");
564 
565  for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
566 
567  if (nn > 0) {
568  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
569  PrintFast(2," S");
570  } else {
571  PrintFast(3," f*");
572  }
573 
574  SetLineStyle(linestylesav);
575  SetLineWidth(linewidthsav);
576 }
577 
578 ////////////////////////////////////////////////////////////////////////////////
579 /// Draw markers at the n WC points xw, yw
580 
581 void TPDF::DrawPolyMarker(Int_t n, Float_t *xw, Float_t *yw)
582 {
583  Style_t linestylesav = fLineStyle;
584  Width_t linewidthsav = fLineWidth;
585  SetLineStyle(1);
586  SetLineWidth(1);
587  SetColor(Int_t(fMarkerColor));
588  Int_t ms = abs(fMarkerStyle);
589 
590  if (ms >= 6 && ms <= 19) ms = 20;
591  if (ms == 4) ms = 24;
592 
593  // Define the marker size
594  Float_t msize = fMarkerSize;
595  if (fMarkerStyle == 1) {
596  msize = 1.;
597  } else if (fMarkerStyle == 6) {
598  msize = 1.;
599  } else if (fMarkerStyle == 7) {
600  msize = 1.5;
601  } else {
602  const Int_t kBASEMARKER = 8;
603  Float_t sbase = msize*kBASEMARKER;
604  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
605  msize = this->UtoPDF(s2x) - this->UtoPDF(0);
606  }
607 
608  Double_t m = msize;
609  Double_t m2 = m/2;
610  Double_t m3 = m/3;
611  Double_t m4 = m2*1.333333333333;
612  Double_t m6 = m/6;
613  Double_t m0 = m/10.;
614  Double_t m8 = m/4;
615  Double_t m9 = m/8;
616 
617  // Draw the marker according to the type
618  Double_t ix,iy;
619  for (Int_t i=0;i<n;i++) {
620  ix = XtoPDF(xw[i]);
621  iy = YtoPDF(yw[i]);
622  // Dot (.)
623  if (ms == 1) {
624  MoveTo(ix-1, iy);
625  LineTo(ix , iy);
626  // Plus (+)
627  } else if (ms == 2) {
628  MoveTo(ix-m2, iy);
629  LineTo(ix+m2, iy);
630  MoveTo(ix , iy-m2);
631  LineTo(ix , iy+m2);
632  // X shape (X)
633  } else if (ms == 5) {
634  MoveTo(ix-m2, iy-m2);
635  LineTo(ix+m2, iy+m2);
636  MoveTo(ix-m2, iy+m2);
637  LineTo(ix+m2, iy-m2);
638  // Asterisk shape (*)
639  } else if (ms == 3 || ms == 31) {
640  MoveTo(ix-m2, iy);
641  LineTo(ix+m2, iy);
642  MoveTo(ix , iy-m2);
643  LineTo(ix , iy+m2);
644  MoveTo(ix-m2, iy-m2);
645  LineTo(ix+m2, iy+m2);
646  MoveTo(ix-m2, iy+m2);
647  LineTo(ix+m2, iy-m2);
648  // Circle
649  } else if (ms == 24 || ms == 20) {
650  MoveTo(ix-m2, iy);
651  WriteReal(ix-m2); WriteReal(iy+m4);
652  WriteReal(ix+m2); WriteReal(iy+m4);
653  WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
654  WriteReal(ix+m2); WriteReal(iy-m4);
655  WriteReal(ix-m2); WriteReal(iy-m4);
656  WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
657  // Square
658  } else if (ms == 25 || ms == 21) {
659  WriteReal(ix-m2); WriteReal(iy-m2);
660  WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
661  // Down triangle
662  } else if (ms == 23 || ms == 32) {
663  MoveTo(ix , iy-m2);
664  LineTo(ix+m2, iy+m2);
665  LineTo(ix-m2, iy+m2);
666  PrintFast(2," h");
667  // Up triangle
668  } else if (ms == 26 || ms == 22) {
669  MoveTo(ix-m2, iy-m2);
670  LineTo(ix+m2, iy-m2);
671  LineTo(ix , iy+m2);
672  PrintFast(2," h");
673  } else if (ms == 27 || ms == 33) {
674  MoveTo(ix , iy-m2);
675  LineTo(ix+m3, iy);
676  LineTo(ix , iy+m2);
677  LineTo(ix-m3, iy) ;
678  PrintFast(2," h");
679  } else if (ms == 28 || ms == 34) {
680  MoveTo(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  LineTo(ix+m6, iy+m6);
687  LineTo(ix+m6, iy+m2);
688  LineTo(ix-m6, iy+m2);
689  LineTo(ix-m6, iy+m6);
690  LineTo(ix-m2, iy+m6);
691  LineTo(ix-m2, iy-m6);
692  PrintFast(2," h");
693  } else if (ms == 29 || ms == 30) {
694  MoveTo(ix , iy+m2);
695  LineTo(ix+0.112255*m, iy+0.15451*m);
696  LineTo(ix+0.47552*m , iy+0.15451*m);
697  LineTo(ix+0.181635*m, iy-0.05902*m);
698  LineTo(ix+0.29389*m , iy-0.40451*m);
699  LineTo(ix , iy-0.19098*m);
700  LineTo(ix-0.29389*m , iy-0.40451*m);
701  LineTo(ix-0.181635*m, iy-0.05902*m);
702  LineTo(ix-0.47552*m , iy+0.15451*m);
703  LineTo(ix-0.112255*m, iy+0.15451*m);
704  PrintFast(2," h");
705  } else if (ms == 35 ) {
706  // diamond with cross
707  MoveTo(ix-m2, iy );
708  LineTo(ix , iy-m2);
709  LineTo(ix+m2, iy );
710  LineTo(ix , iy+m2);
711  LineTo(ix-m2, iy );
712  LineTo(ix+m2, iy );
713  LineTo(ix , iy+m2);
714  LineTo(ix , iy-m2);
715  PrintFast(2," h");
716  } else if (ms == 36 ) {
717  // square with diagonal cross
718  MoveTo(ix-m2, iy-m2);
719  LineTo(ix+m2, iy-m2);
720  LineTo(ix+m2, iy+m2);
721  LineTo(ix-m2, iy+m2);
722  LineTo(ix-m2, iy-m2);
723  LineTo(ix+m2, iy+m2);
724  LineTo(ix-m2, iy+m2);
725  LineTo(ix+m2, iy-m2);
726  PrintFast(2," h");
727  } else if (ms == 37 || ms == 39 ) {
728  // square with cross
729  MoveTo(ix , iy );
730  LineTo(ix-m8, iy+m2);
731  LineTo(ix-m2, iy );
732  LineTo(ix , iy );
733  LineTo(ix-m8, iy-m2);
734  LineTo(ix+m8, iy-m2);
735  LineTo(ix , iy );
736  LineTo(ix+m2, iy );
737  LineTo(ix+m8, iy+m2);
738  LineTo(ix , iy );
739  PrintFast(2," h");
740  } else if (ms == 38 ) {
741  // + shaped marker with octagon
742  MoveTo(ix-m2, iy );
743  LineTo(ix-m2, iy-m8);
744  LineTo(ix-m8, iy-m2);
745  LineTo(ix+m8, iy-m2);
746  LineTo(ix+m2, iy-m8);
747  LineTo(ix+m2, iy+m8);
748  LineTo(ix+m8, iy+m2);
749  LineTo(ix-m8, iy+m2);
750  LineTo(ix-m2, iy+m8);
751  LineTo(ix-m2, iy );
752  LineTo(ix+m2, iy );
753  LineTo(ix , iy );
754  LineTo(ix , iy-m2);
755  LineTo(ix , iy+m2);
756  LineTo(ix , iy);
757  PrintFast(2," h");
758  } else if (ms == 40 || ms == 41 ) {
759  // four triangles X
760  MoveTo(ix , iy );
761  LineTo(ix+m8, iy+m2);
762  LineTo(ix+m2, iy+m8);
763  LineTo(ix , iy );
764  LineTo(ix+m2, iy-m8);
765  LineTo(ix+m8, iy-m2);
766  LineTo(ix , iy );
767  LineTo(ix-m8, iy-m2);
768  LineTo(ix-m2, iy-m8);
769  LineTo(ix , iy );
770  LineTo(ix-m2, iy+m8);
771  LineTo(ix-m8, iy+m2);
772  LineTo(ix , iy );
773  PrintFast(2," h");
774  } else if (ms == 42 || ms == 43 ) {
775  // double diamonds
776  MoveTo(ix , iy+m2);
777  LineTo(ix-m9, iy+m9);
778  LineTo(ix-m2, iy );
779  LineTo(ix-m9, iy-m9);
780  LineTo(ix , iy-m2);
781  LineTo(ix+m9, iy-m9);
782  LineTo(ix+m2, iy );
783  LineTo(ix+m9, iy+m9);
784  LineTo(ix , iy+m2);
785  PrintFast(2," h");
786  } else if (ms == 44 ) {
787  // open four triangles plus
788  MoveTo(ix , iy );
789  LineTo(ix+m8, iy+m2);
790  LineTo(ix-m8, iy+m2);
791  LineTo(ix+m8, iy-m2);
792  LineTo(ix-m8, iy-m2);
793  LineTo(ix , iy );
794  LineTo(ix+m2, iy+m8);
795  LineTo(ix+m2, iy-m8);
796  LineTo(ix-m2, iy+m8);
797  LineTo(ix-m2, iy-m8);
798  LineTo(ix , iy );
799  PrintFast(2," h");
800  } else if (ms == 45 ) {
801  // filled four triangles plus
802  MoveTo(ix+m0, iy+m0);
803  LineTo(ix+m8, iy+m2);
804  LineTo(ix-m8, iy+m2);
805  LineTo(ix-m0, iy+m0);
806  LineTo(ix-m2, iy+m8);
807  LineTo(ix-m2, iy-m8);
808  LineTo(ix-m0, iy-m0);
809  LineTo(ix-m8, iy-m2);
810  LineTo(ix+m8, iy-m2);
811  LineTo(ix+m0, iy-m0);
812  LineTo(ix+m2, iy-m8);
813  LineTo(ix+m2, iy+m8);
814  LineTo(ix+m0, iy+m0);
815  PrintFast(2," h");
816  } else if (ms == 46 || ms == 47 ) {
817  // four triangles X
818  MoveTo(ix , iy+m8);
819  LineTo(ix-m8, iy+m2);
820  LineTo(ix-m2, iy+m8);
821  LineTo(ix-m8, iy );
822  LineTo(ix-m2, iy-m8);
823  LineTo(ix-m8, iy-m2);
824  LineTo(ix , iy-m8);
825  LineTo(ix+m8, iy-m2);
826  LineTo(ix+m2, iy-m8);
827  LineTo(ix+m8, iy );
828  LineTo(ix+m2, iy+m8);
829  LineTo(ix+m8, iy+m2);
830  LineTo(ix , iy+m8);
831  PrintFast(2," h");
832  } else if (ms == 48 ) {
833  // four filled squares X
834  MoveTo(ix , iy+m8*1.01);
835  LineTo(ix-m8, iy+m2);
836  LineTo(ix-m2, iy+m8);
837  LineTo(ix-m8, iy );
838  LineTo(ix-m2, iy-m8);
839  LineTo(ix-m8, iy-m2);
840  LineTo(ix , iy-m8);
841  LineTo(ix+m8, iy-m2);
842  LineTo(ix+m2, iy-m8);
843  LineTo(ix+m8, iy );
844  LineTo(ix+m2, iy+m8);
845  LineTo(ix+m8, iy+m2);
846  LineTo(ix , iy+m8*0.99);
847  LineTo(ix+m8*0.99, iy );
848  LineTo(ix , iy-m8*0.99);
849  LineTo(ix-m8*0.99, iy );
850  LineTo(ix , iy+m8*0.99);
851  PrintFast(2," h");
852  } else if (ms == 49 ) {
853  // four filled squares plus
854  MoveTo(ix-m6, iy-m6*1.01);
855  LineTo(ix-m6, iy-m2);
856  LineTo(ix+m6, iy-m2);
857  LineTo(ix+m6, iy-m6);
858  LineTo(ix+m2, iy-m6);
859  LineTo(ix+m2, iy+m6);
860  LineTo(ix+m6, iy+m6);
861  LineTo(ix+m6, iy+m2);
862  LineTo(ix-m6, iy+m2);
863  LineTo(ix-m6, iy+m6);
864  LineTo(ix-m2, iy+m6);
865  LineTo(ix-m2, iy-m6);
866  LineTo(ix-m6, iy-m6*0.99);
867  LineTo(ix-m6, iy+m6);
868  LineTo(ix+m6, iy+m6);
869  LineTo(ix+m6, iy-m6);
870  PrintFast(2," h");
871  } else {
872  MoveTo(ix-m6, iy-m6);
873  LineTo(ix-m6, iy-m2);
874  }
875 
876  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
877  ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
878  ms == 47 || ms == 48 || ms == 49) {
879  PrintFast(2," f");
880  } else {
881  PrintFast(2," S");
882  }
883  }
884 
885  SetLineStyle(linestylesav);
886  SetLineWidth(linewidthsav);
887 }
888 
889 ////////////////////////////////////////////////////////////////////////////////
890 /// Draw markers at the n WC points xw, yw
891 
892 void TPDF::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
893 {
894  Style_t linestylesav = fLineStyle;
895  Width_t linewidthsav = fLineWidth;
896  SetLineStyle(1);
897  SetLineWidth(1);
898  SetColor(Int_t(fMarkerColor));
899  Int_t ms = abs(fMarkerStyle);
900 
901  if (ms >= 6 && ms <= 19) ms = 20;
902  if (ms == 4) ms = 24;
903 
904  // Define the marker size
905  Float_t msize = fMarkerSize;
906  if (fMarkerStyle == 1) {
907  msize = 1.;
908  } else if (fMarkerStyle == 6) {
909  msize = 1.5;
910  } else if (fMarkerStyle == 7) {
911  msize = 3.;
912  } else {
913  const Int_t kBASEMARKER = 8;
914  Float_t sbase = msize*kBASEMARKER;
915  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
916  msize = this->UtoPDF(s2x) - this->UtoPDF(0);
917  }
918 
919  Double_t m = msize;
920  Double_t m2 = m/2;
921  Double_t m3 = m/3;
922  Double_t m4 = m2*1.333333333333;
923  Double_t m6 = m/6;
924  Double_t m8 = m/4;
925  Double_t m9 = m/8;
926 
927  // Draw the marker according to the type
928  Double_t ix,iy;
929  for (Int_t i=0;i<n;i++) {
930  ix = XtoPDF(xw[i]);
931  iy = YtoPDF(yw[i]);
932  // Dot (.)
933  if (ms == 1) {
934  MoveTo(ix-1, iy);
935  LineTo(ix , iy);
936  // Plus (+)
937  } else if (ms == 2) {
938  MoveTo(ix-m2, iy);
939  LineTo(ix+m2, iy);
940  MoveTo(ix , iy-m2);
941  LineTo(ix , iy+m2);
942  // X shape (X)
943  } else if (ms == 5) {
944  MoveTo(ix-m2, iy-m2);
945  LineTo(ix+m2, iy+m2);
946  MoveTo(ix-m2, iy+m2);
947  LineTo(ix+m2, iy-m2);
948  // Asterisk shape (*)
949  } else if (ms == 3 || ms == 31) {
950  MoveTo(ix-m2, iy);
951  LineTo(ix+m2, iy);
952  MoveTo(ix , iy-m2);
953  LineTo(ix , iy+m2);
954  MoveTo(ix-m2, iy-m2);
955  LineTo(ix+m2, iy+m2);
956  MoveTo(ix-m2, iy+m2);
957  LineTo(ix+m2, iy-m2);
958  // Circle
959  } else if (ms == 24 || ms == 20) {
960  MoveTo(ix-m2, iy);
961  WriteReal(ix-m2); WriteReal(iy+m4);
962  WriteReal(ix+m2); WriteReal(iy+m4);
963  WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
964  WriteReal(ix+m2); WriteReal(iy-m4);
965  WriteReal(ix-m2); WriteReal(iy-m4);
966  WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
967  // Square
968  } else if (ms == 25 || ms == 21) {
969  WriteReal(ix-m2); WriteReal(iy-m2);
970  WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
971  // Down triangle
972  } else if (ms == 23 || ms == 32) {
973  MoveTo(ix , iy-m2);
974  LineTo(ix+m2, iy+m2);
975  LineTo(ix-m2, iy+m2);
976  PrintFast(2," h");
977  // Up triangle
978  } else if (ms == 26 || ms == 22) {
979  MoveTo(ix-m2, iy-m2);
980  LineTo(ix+m2, iy-m2);
981  LineTo(ix , iy+m2);
982  PrintFast(2," h");
983  } else if (ms == 27 || ms == 33) {
984  MoveTo(ix , iy-m2);
985  LineTo(ix+m3, iy);
986  LineTo(ix , iy+m2);
987  LineTo(ix-m3, iy) ;
988  PrintFast(2," h");
989  } else if (ms == 28 || ms == 34) {
990  MoveTo(ix-m6, iy-m6);
991  LineTo(ix-m6, iy-m2);
992  LineTo(ix+m6, iy-m2);
993  LineTo(ix+m6, iy-m6);
994  LineTo(ix+m2, iy-m6);
995  LineTo(ix+m2, iy+m6);
996  LineTo(ix+m6, iy+m6);
997  LineTo(ix+m6, iy+m2);
998  LineTo(ix-m6, iy+m2);
999  LineTo(ix-m6, iy+m6);
1000  LineTo(ix-m2, iy+m6);
1001  LineTo(ix-m2, iy-m6);
1002  PrintFast(2," h");
1003  } else if (ms == 29 || ms == 30) {
1004  MoveTo(ix , iy-m2);
1005  LineTo(ix-0.112255*m, iy-0.15451*m);
1006  LineTo(ix-0.47552*m , iy-0.15451*m);
1007  LineTo(ix-0.181635*m, iy+0.05902*m);
1008  LineTo(ix-0.29389*m , iy+0.40451*m);
1009  LineTo(ix , iy+0.19098*m);
1010  LineTo(ix+0.29389*m , iy+0.40451*m);
1011  LineTo(ix+0.181635*m, iy+0.05902*m);
1012  LineTo(ix+0.47552*m , iy-0.15451*m);
1013  LineTo(ix+0.112255*m, iy-0.15451*m);
1014  PrintFast(2," h");
1015  } else if (ms == 35 ) {
1016  MoveTo(ix-m2, iy );
1017  LineTo(ix , iy-m2);
1018  LineTo(ix+m2, iy );
1019  LineTo(ix , iy+m2);
1020  LineTo(ix-m2, iy );
1021  LineTo(ix+m2, iy );
1022  LineTo(ix , iy+m2);
1023  LineTo(ix , iy-m2);
1024  PrintFast(2," h");
1025  } else if (ms == 36 ) {
1026  MoveTo(ix-m2, iy-m2);
1027  LineTo(ix+m2, iy-m2);
1028  LineTo(ix+m2, iy+m2);
1029  LineTo(ix-m2, iy+m2);
1030  LineTo(ix-m2, iy-m2);
1031  LineTo(ix+m2, iy+m2);
1032  LineTo(ix-m2, iy+m2);
1033  LineTo(ix+m2, iy-m2);
1034  PrintFast(2," h");
1035  } else if (ms == 37 || ms == 39 ) {
1036  MoveTo(ix , iy );
1037  LineTo(ix-m8, iy+m2);
1038  LineTo(ix-m2, iy );
1039  LineTo(ix , iy );
1040  LineTo(ix-m8, iy-m2);
1041  LineTo(ix+m8, iy-m2);
1042  LineTo(ix , iy );
1043  LineTo(ix+m2, iy );
1044  LineTo(ix+m8, iy+m2);
1045  LineTo(ix , iy );
1046  PrintFast(2," h");
1047  } else if (ms == 38 ) {
1048  MoveTo(ix-m2, iy );
1049  LineTo(ix-m2, iy-m8);
1050  LineTo(ix-m8, iy-m2);
1051  LineTo(ix+m8, iy-m2);
1052  LineTo(ix+m2, iy-m8);
1053  LineTo(ix+m2, iy+m8);
1054  LineTo(ix+m8, iy+m2);
1055  LineTo(ix-m8, iy+m2);
1056  LineTo(ix-m2, iy+m8);
1057  LineTo(ix-m2, iy );
1058  LineTo(ix+m2, iy );
1059  LineTo(ix , iy );
1060  LineTo(ix , iy-m2);
1061  LineTo(ix , iy+m2);
1062  LineTo(ix , iy );
1063  PrintFast(2," h");
1064  } else if (ms == 40 || ms == 41 ) {
1065  MoveTo(ix , iy );
1066  LineTo(ix+m8, iy+m2);
1067  LineTo(ix+m2, iy+m8);
1068  LineTo(ix , iy );
1069  LineTo(ix+m2, iy-m8);
1070  LineTo(ix+m8, iy-m2);
1071  LineTo(ix , iy );
1072  LineTo(ix-m8, iy-m2);
1073  LineTo(ix-m2, iy-m8);
1074  LineTo(ix , iy );
1075  LineTo(ix-m2, iy+m8);
1076  LineTo(ix-m8, iy+m2);
1077  LineTo(ix , iy );
1078  PrintFast(2," h");
1079  } else if (ms == 42 || ms == 43 ) {
1080  MoveTo(ix , iy+m2);
1081  LineTo(ix-m9, iy+m9);
1082  LineTo(ix-m2, iy );
1083  LineTo(ix-m9, iy-m9);
1084  LineTo(ix , iy-m2);
1085  LineTo(ix+m9, iy-m9);
1086  LineTo(ix+m2, iy );
1087  LineTo(ix+m9, iy+m9);
1088  LineTo(ix , iy+m2);
1089  PrintFast(2," h");
1090  } else if (ms == 44 ) {
1091  MoveTo(ix , iy );
1092  LineTo(ix+m8, iy+m2);
1093  LineTo(ix-m8, iy+m2);
1094  LineTo(ix+m8, iy-m2);
1095  LineTo(ix-m8, iy-m2);
1096  LineTo(ix , iy );
1097  LineTo(ix+m2, iy+m8);
1098  LineTo(ix+m2, iy-m8);
1099  LineTo(ix-m2, iy+m8);
1100  LineTo(ix-m2, iy-m8);
1101  LineTo(ix , iy );
1102  PrintFast(2," h");
1103  } else if (ms == 45 ) {
1104  MoveTo(ix+m6/2., iy+m6/2.);
1105  LineTo(ix+m8, iy+m2);
1106  LineTo(ix-m8, iy+m2);
1107  LineTo(ix-m6/2., iy+m6/2.);
1108  LineTo(ix-m2, iy+m8);
1109  LineTo(ix-m2, iy-m8);
1110  LineTo(ix-m6/2., iy-m6/2.);
1111  LineTo(ix-m8, iy-m2);
1112  LineTo(ix+m8, iy-m2);
1113  LineTo(ix+m6/2., iy-m6/2.);
1114  LineTo(ix+m2, iy-m8);
1115  LineTo(ix+m2, iy+m8);
1116  LineTo(ix+m6/2., iy+m6/2.);
1117  PrintFast(2," h");
1118  } else if (ms == 46 || ms == 47 ) {
1119  MoveTo(ix , iy+m8);
1120  LineTo(ix-m8, iy+m2);
1121  LineTo(ix-m2, iy+m8);
1122  LineTo(ix-m8, iy );
1123  LineTo(ix-m2, iy-m8);
1124  LineTo(ix-m8, iy-m2);
1125  LineTo(ix , iy-m8);
1126  LineTo(ix+m8, iy-m2);
1127  LineTo(ix+m2, iy-m8);
1128  LineTo(ix+m8, iy );
1129  LineTo(ix+m2, iy+m8);
1130  LineTo(ix+m8, iy+m2);
1131  LineTo(ix , iy+m8);
1132  PrintFast(2," h");
1133  } else if (ms == 48 ) {
1134  MoveTo(ix , iy+m8*1.005);
1135  LineTo(ix-m8, iy+m2);
1136  LineTo(ix-m2, iy+m8);
1137  LineTo(ix-m8, iy );
1138  LineTo(ix-m2, iy-m8);
1139  LineTo(ix-m8, iy-m2);
1140  LineTo(ix , iy-m8);
1141  LineTo(ix+m8, iy-m2);
1142  LineTo(ix+m2, iy-m8);
1143  LineTo(ix+m8, iy );
1144  LineTo(ix+m2, iy+m8);
1145  LineTo(ix+m8, iy+m2);
1146  LineTo(ix , iy+m8*0.995);
1147  LineTo(ix+m8*0.995, iy );
1148  LineTo(ix , iy-m8*0.995);
1149  LineTo(ix-m8*0.995, iy );
1150  LineTo(ix , iy+m8*0.995);
1151  PrintFast(2," h");
1152  } else if (ms == 49 ) {
1153  MoveTo(ix-m6, iy-m6*1.01);
1154  LineTo(ix-m6, iy-m2);
1155  LineTo(ix+m6, iy-m2);
1156  LineTo(ix+m6, iy-m6);
1157  LineTo(ix+m2, iy-m6);
1158  LineTo(ix+m2, iy+m6);
1159  LineTo(ix+m6, iy+m6);
1160  LineTo(ix+m6, iy+m2);
1161  LineTo(ix-m6, iy+m2);
1162  LineTo(ix-m6, iy+m6);
1163  LineTo(ix-m2, iy+m6);
1164  LineTo(ix-m2, iy-m6);
1165  LineTo(ix-m6, iy-m6*0.99);
1166  LineTo(ix-m6, iy+m6);
1167  LineTo(ix+m6, iy+m6);
1168  LineTo(ix+m6, iy-m6);
1169  MoveTo(ix-m6, iy-m6*1.01);
1170  PrintFast(2," h");
1171  } else {
1172  MoveTo(ix-1, iy);
1173  LineTo(ix , iy);
1174  }
1175  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
1176  ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
1177  ms == 47 || ms == 48 || ms == 49) {
1178  PrintFast(2," f");
1179  } else {
1180  PrintFast(2," S");
1181  }
1182  }
1183 
1184  SetLineStyle(linestylesav);
1185  SetLineWidth(linewidthsav);
1186 }
1187 
1188 ////////////////////////////////////////////////////////////////////////////////
1189 /// Draw a PolyLine
1190 ///
1191 /// Draw a polyline through the points xw,yw.
1192 ///
1193 /// - If nn=1 moves only to point xw,yw.
1194 /// - If nn=0 the XW(1) and YW(1) are written in the PDF file
1195 /// according to the current NT.
1196 /// - If nn>0 the line is clipped as a line.
1197 /// - If nn<0 the line is clipped as a fill area.
1198 
1199 void TPDF::DrawPS(Int_t nn, Float_t *xw, Float_t *yw)
1200 {
1201  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1202  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1203  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1204  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1205  180, 90,135, 45,150, 30,120, 60,
1206  180, 90,135, 45,150, 30,120, 60};
1207  Int_t n = 0, fais = 0 , fasi = 0;
1208 
1209  Style_t linestylesav = fLineStyle;
1210  Width_t linewidthsav = fLineWidth;
1211 
1212  if (nn > 0) {
1213  if (fLineWidth<=0) return;
1214  n = nn;
1215  SetLineStyle(fLineStyle);
1216  SetLineWidth(fLineWidth);
1217  SetColor(Int_t(fLineColor));
1218  }
1219  if (nn < 0) {
1220  n = -nn;
1221  SetLineStyle(1);
1222  SetLineWidth(1);
1223  SetColor(Int_t(fFillColor));
1224  fais = fFillStyle/1000;
1225  fasi = fFillStyle%1000;
1226  if (fais == 3 || fais == 2) {
1227  if (fasi > 100 && fasi <125) {
1228  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1229  SetLineStyle(linestylesav);
1230  SetLineWidth(linewidthsav);
1231  return;
1232  }
1233  if (fasi > 0 && fasi < 26) {
1234  SetFillPatterns(fasi, Int_t(fFillColor));
1235  }
1236  }
1237  }
1238 
1239  WriteReal(XtoPDF(xw[0]));
1240  WriteReal(YtoPDF(yw[0]));
1241  if (n <= 1) {
1242  if (n == 0) return;
1243  PrintFast(2," m");
1244  return;
1245  }
1246 
1247  PrintFast(2," m");
1248 
1249  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1250 
1251  if (nn > 0) {
1252  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1253  PrintFast(2," S");
1254  } else {
1255  if (fais == 0) {PrintFast(2," s"); return;}
1256  if (fais == 3 || fais == 2) {
1257  if (fasi > 0 && fasi < 26) {
1258  PrintFast(3," f*");
1259  fRed = -1;
1260  fGreen = -1;
1261  fBlue = -1;
1262  fAlpha = -1.;
1263  }
1264  SetLineStyle(linestylesav);
1265  SetLineWidth(linewidthsav);
1266  return;
1267  }
1268  PrintFast(3," f*");
1269  }
1270 
1271  SetLineStyle(linestylesav);
1272  SetLineWidth(linewidthsav);
1273 }
1274 
1275 ////////////////////////////////////////////////////////////////////////////////
1276 /// Draw a PolyLine
1277 ///
1278 /// Draw a polyline through the points xw,yw.
1279 ///
1280 /// - If nn=1 moves only to point xw,yw.
1281 /// - If nn=0 the xw(1) and YW(1) are written in the PDF file
1282 /// according to the current NT.
1283 /// - If nn>0 the line is clipped as a line.
1284 /// - If nn<0 the line is clipped as a fill area.
1285 
1286 void TPDF::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
1287 {
1288  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1289  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1290  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1291  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1292  180, 90,135, 45,150, 30,120, 60,
1293  180, 90,135, 45,150, 30,120, 60};
1294  Int_t n = 0, fais = 0, fasi = 0;
1295 
1296  Style_t linestylesav = fLineStyle;
1297  Width_t linewidthsav = fLineWidth;
1298 
1299  if (nn > 0) {
1300  if (fLineWidth<=0) return;
1301  n = nn;
1302  SetLineStyle(fLineStyle);
1303  SetLineWidth(fLineWidth);
1304  SetColor(Int_t(fLineColor));
1305  }
1306  if (nn < 0) {
1307  n = -nn;
1308  SetLineStyle(1);
1309  SetLineWidth(1);
1310  SetColor(Int_t(fFillColor));
1311  fais = fFillStyle/1000;
1312  fasi = fFillStyle%1000;
1313  if (fais == 3 || fais == 2) {
1314  if (fasi > 100 && fasi <125) {
1315  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1316  SetLineStyle(linestylesav);
1317  SetLineWidth(linewidthsav);
1318  return;
1319  }
1320  if (fasi > 0 && fasi < 26) {
1321  SetFillPatterns(fasi, Int_t(fFillColor));
1322  }
1323  }
1324  }
1325 
1326  WriteReal(XtoPDF(xw[0]));
1327  WriteReal(YtoPDF(yw[0]));
1328  if (n <= 1) {
1329  if (n == 0) return;
1330  PrintFast(2," m");
1331  return;
1332  }
1333 
1334  PrintFast(2," m");
1335 
1336  for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1337 
1338  if (nn > 0) {
1339  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1340  PrintFast(2," S");
1341  } else {
1342  if (fais == 0) {PrintFast(2," s"); return;}
1343  if (fais == 3 || fais == 2) {
1344  if (fasi > 0 && fasi < 26) {
1345  PrintFast(3," f*");
1346  fRed = -1;
1347  fGreen = -1;
1348  fBlue = -1;
1349  fAlpha = -1.;
1350  }
1351  SetLineStyle(linestylesav);
1352  SetLineWidth(linewidthsav);
1353  return;
1354  }
1355  PrintFast(3," f*");
1356  }
1357 
1358  SetLineStyle(linestylesav);
1359  SetLineWidth(linewidthsav);
1360 }
1361 
1362 ////////////////////////////////////////////////////////////////////////////////
1363 /// Font encoding
1364 
1365 void TPDF::FontEncode()
1366 {
1367  static const char *sdtfonts[] = {
1368  "/Times-Italic" , "/Times-Bold" , "/Times-BoldItalic",
1369  "/Helvetica" , "/Helvetica-Oblique" , "/Helvetica-Bold" ,
1370  "/Helvetica-BoldOblique", "/Courier" , "/Courier-Oblique" ,
1371  "/Courier-Bold" , "/Courier-BoldOblique", "/Symbol" ,
1372  "/Times-Roman" , "/ZapfDingbats" , "/Symbol"};
1373 
1374  for (Int_t i=0; i<kNumberOfFonts; i++) {
1375  NewObject(kObjFont+i);
1376  PrintStr("<<@");
1377  PrintStr("/Type /Font@");
1378  PrintStr("/Subtype /Type1@");
1379  PrintStr("/Name /F");
1380  WriteInteger(i+1,0);
1381  PrintStr("@");
1382  PrintStr("/BaseFont ");
1383  PrintStr(sdtfonts[i]);
1384  PrintStr("@");
1385  if (i!=11 && i!=13 && i!=14) {
1386  PrintStr("/Encoding /WinAnsiEncoding");
1387  PrintStr("@");
1388  }
1389  PrintStr(">>@");
1390  PrintStr("endobj@");
1391  }
1392 }
1393 
1394 ////////////////////////////////////////////////////////////////////////////////
1395 /// Draw a line to a new position
1396 
1397 void TPDF::LineTo(Double_t x, Double_t y)
1398 {
1399  WriteReal(x);
1400  WriteReal(y);
1401  PrintFast(2," l");
1402 }
1403 
1404 ////////////////////////////////////////////////////////////////////////////////
1405 /// Move to a new position
1406 
1407 void TPDF::MoveTo(Double_t x, Double_t y)
1408 {
1409  WriteReal(x);
1410  WriteReal(y);
1411  PrintFast(2," m");
1412 }
1413 
1414 ////////////////////////////////////////////////////////////////////////////////
1415 /// Create a new object in the PDF file
1416 
1417 void TPDF::NewObject(Int_t n)
1418 {
1419  if (!fObjPos || n >= fObjPosSize) {
1420  Int_t newN = TMath::Max(2*fObjPosSize,n+1);
1421  Int_t *saveo = new Int_t [newN];
1422  if (fObjPos && fObjPosSize) {
1423  memcpy(saveo,fObjPos,fObjPosSize*sizeof(Int_t));
1424  memset(&saveo[fObjPosSize],0,(newN-fObjPosSize)*sizeof(Int_t));
1425  delete [] fObjPos;
1426  }
1427  fObjPos = saveo;
1428  fObjPosSize = newN;
1429  }
1430  fObjPos[n-1] = fNByte;
1431  fNbObj = TMath::Max(fNbObj,n);
1432  WriteInteger(n, 0);
1433  PrintStr(" 0 obj");
1434  PrintStr("@");
1435 }
1436 
1437 ////////////////////////////////////////////////////////////////////////////////
1438 /// Start a new PDF page.
1439 
1440 void TPDF::NewPage()
1441 {
1442  if (!fPageNotEmpty) return;
1443 
1444  // Compute pad conversion coefficients
1445  if (gPad) {
1446  Double_t ww = gPad->GetWw();
1447  Double_t wh = gPad->GetWh();
1448  fYsize = fXsize*wh/ww;
1449  } else {
1450  fYsize = 27;
1451  }
1452 
1453  fNbPage++;
1454 
1455  if (fNbPage>1) {
1456  // Close the currently opened page
1457  WriteCompressedBuffer();
1458  PrintStr("endstream@");
1459  Int_t streamLength = fNByte-fStartStream-10;
1460  PrintStr("endobj@");
1461  NewObject(4*(fNbPage-2)+kObjFirstPage+2);
1462  WriteInteger(streamLength, 0);
1463  PrintStr("@");
1464  PrintStr("endobj@");
1465  NewObject(4*(fNbPage-2)+kObjFirstPage+3);
1466  PrintStr("<<@");
1467  if (!strstr(GetTitle(),"PDF")) {
1468  PrintStr("/Title (");
1469  PrintStr(GetTitle());
1470  PrintStr(")@");
1471  } else {
1472  PrintStr("/Title (Page");
1473  WriteInteger(fNbPage-1);
1474  PrintStr(")@");
1475  }
1476  PrintStr("/Dest [");
1477  WriteInteger(4*(fNbPage-2)+kObjFirstPage);
1478  PrintStr(" 0 R /XYZ null null 0]@");
1479  PrintStr("/Parent");
1480  WriteInteger(kObjContents);
1481  PrintStr(" 0 R");
1482  PrintStr("@");
1483  PrintStr("/Next");
1484  WriteInteger(4*(fNbPage-1)+kObjFirstPage+3);
1485  PrintStr(" 0 R");
1486  PrintStr("@");
1487  if (fNbPage>2) {
1488  PrintStr("/Prev");
1489  WriteInteger(4*(fNbPage-3)+kObjFirstPage+3);
1490  PrintStr(" 0 R");
1491  PrintStr("@");
1492  }
1493  PrintStr(">>@");
1494  }
1495 
1496  // Start a new page
1497  NewObject(4*(fNbPage-1)+kObjFirstPage);
1498  PrintStr("<<@");
1499  PrintStr("/Type /Page@");
1500  PrintStr("@");
1501  PrintStr("/Parent");
1502  WriteInteger(kObjPages);
1503  PrintStr(" 0 R");
1504  PrintStr("@");
1505 
1506  Double_t xlow=0, ylow=0, xup=1, yup=1;
1507  if (gPad) {
1508  xlow = gPad->GetAbsXlowNDC();
1509  xup = xlow + gPad->GetAbsWNDC();
1510  ylow = gPad->GetAbsYlowNDC();
1511  yup = ylow + gPad->GetAbsHNDC();
1512  }
1513 
1514  PrintStr("/MediaBox [");
1515  Double_t width, height;
1516  switch (fPageFormat) {
1517  case 100 :
1518  width = 8.5*2.54;
1519  height = 11.*2.54;
1520  break;
1521  case 200 :
1522  width = 8.5*2.54;
1523  height = 14.*2.54;
1524  break;
1525  case 300 :
1526  width = 11.*2.54;
1527  height = 17.*2.54;
1528  break;
1529  default :
1530  width = 21.0*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1531  height = 29.7*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1532  };
1533  WriteReal(CMtoPDF(fXsize*xlow));
1534  WriteReal(CMtoPDF(fYsize*ylow));
1535  WriteReal(CMtoPDF(width));
1536  WriteReal(CMtoPDF(height));
1537  PrintStr("]");
1538  PrintStr("@");
1539 
1540  Double_t xmargin = CMtoPDF(0.7);
1541  Double_t ymargin = 0;
1542  if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
1543  if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
1544 
1545  PrintStr("/CropBox [");
1546  if (fPageOrientation == 1) {
1547  WriteReal(xmargin);
1548  WriteReal(ymargin);
1549  WriteReal(xmargin+CMtoPDF(fXsize*xup));
1550  WriteReal(ymargin+CMtoPDF(fYsize*yup));
1551  }
1552  if (fPageOrientation == 2) {
1553  WriteReal(xmargin);
1554  WriteReal(CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin);
1555  WriteReal(xmargin+CMtoPDF(fYsize*yup));
1556  WriteReal(CMtoPDF(height)-xmargin);
1557  }
1558  PrintStr("]");
1559  PrintStr("@");
1560 
1561  if (fPageOrientation == 1) PrintStr("/Rotate 0@");
1562  if (fPageOrientation == 2) PrintStr("/Rotate 90@");
1563 
1564  PrintStr("/Resources");
1565  WriteInteger(kObjPageResources);
1566  PrintStr(" 0 R");
1567  PrintStr("@");
1568 
1569  PrintStr("/Contents");
1570  WriteInteger(4*(fNbPage-1)+kObjFirstPage+1);
1571  PrintStr(" 0 R@");
1572  PrintStr(">>@");
1573  PrintStr("endobj@");
1574 
1575  NewObject(4*(fNbPage-1)+kObjFirstPage+1);
1576  PrintStr("<<@");
1577  PrintStr("/Length");
1578  WriteInteger(4*(fNbPage-1)+kObjFirstPage+2);
1579  PrintStr(" 0 R@");
1580  PrintStr("/Filter [/FlateDecode]@");
1581  PrintStr(">>@");
1582  PrintStr("stream@");
1583  fStartStream = fNByte;
1584  fCompress = kTRUE;
1585 
1586  // Force the line width definition next time TPDF::SetLineWidth will be called.
1587  fLineWidth = -1;
1588 
1589  // Force the color definition next time TPDF::SetColor will be called.
1590  fRed = -1;
1591  fGreen = -1;
1592  fBlue = -1;
1593  fAlpha = -1.;
1594 
1595  PrintStr("1 0 0 1");
1596  if (fPageOrientation == 2) {
1597  ymargin = CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin;
1598  xmargin = xmargin+CMtoPDF(fYsize*yup);
1599  }
1600  WriteReal(xmargin);
1601  WriteReal(ymargin);
1602  PrintStr(" cm");
1603  if (fPageOrientation == 2) PrintStr(" 0 1 -1 0 0 0 cm");
1604  if (fgLineJoin) {
1605  WriteInteger(fgLineJoin);
1606  PrintFast(2," j");
1607  }
1608 }
1609 
1610 ////////////////////////////////////////////////////////////////////////////////
1611 /// Deactivate an already open PDF file
1612 
1613 void TPDF::Off()
1614 {
1615  gVirtualPS = 0;
1616 }
1617 
1618 ////////////////////////////////////////////////////////////////////////////////
1619 /// Activate an already open PDF file
1620 
1621 void TPDF::On()
1622 {
1623  // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
1624  // has no "workstation type".
1625 
1626  if (!fType) {
1627  Error("On", "no PDF file open");
1628  Off();
1629  return;
1630  }
1631  gVirtualPS = this;
1632 }
1633 
1634 ////////////////////////////////////////////////////////////////////////////////
1635 /// Open a PDF file
1636 
1637 void TPDF::Open(const char *fname, Int_t wtype)
1638 {
1639  Int_t i;
1640 
1641  if (fStream) {
1642  Warning("Open", "PDF file already open");
1643  return;
1644  }
1645 
1646  fLenBuffer = 0;
1647  fRed = -1;
1648  fGreen = -1;
1649  fBlue = -1;
1650  fAlpha = -1.;
1651  fType = abs(wtype);
1652  SetLineJoin(gStyle->GetJoinLinePS());
1653  SetLineScale(gStyle->GetLineScalePS()/4.);
1654  gStyle->GetPaperSize(fXsize, fYsize);
1655  Float_t xrange, yrange;
1656  if (gPad) {
1657  Double_t ww = gPad->GetWw();
1658  Double_t wh = gPad->GetWh();
1659  if (fType == 113) {
1660  ww *= gPad->GetWNDC();
1661  wh *= gPad->GetHNDC();
1662  }
1663  Double_t ratio = wh/ww;
1664  xrange = fXsize;
1665  yrange = fXsize*ratio;
1666  if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
1667  fXsize = xrange; fYsize = yrange;
1668  }
1669 
1670  // Open OS file
1671  fStream = new std::ofstream();
1672 #ifdef R__WIN32
1673  fStream->open(fname, std::ofstream::out | std::ofstream::binary);
1674 #else
1675  fStream->open(fname, std::ofstream::out);
1676 #endif
1677  if (fStream == 0 || !fStream->good()) {
1678  printf("ERROR in TPDF::Open: Cannot open file:%s\n",fname);
1679  if (fStream == 0) return;
1680  }
1681 
1682  gVirtualPS = this;
1683 
1684  for (i=0; i<fSizBuffer; i++) fBuffer[i] = ' ';
1685 
1686  // The page orientation is last digit of PDF workstation type
1687  // orientation = 1 for portrait
1688  // orientation = 2 for landscape
1689  fPageOrientation = fType%10;
1690  if (fPageOrientation < 1 || fPageOrientation > 2) {
1691  Error("Open", "Invalid page orientation %d", fPageOrientation);
1692  return;
1693  }
1694 
1695  // format = 0-99 is the European page format (A4,A3 ...)
1696  // format = 100 is the US format 8.5x11.0 inch
1697  // format = 200 is the US format 8.5x14.0 inch
1698  // format = 300 is the US format 11.0x17.0 inch
1699  fPageFormat = fType/1000;
1700  if (fPageFormat == 0) fPageFormat = 4;
1701  if (fPageFormat == 99) fPageFormat = 0;
1702 
1703  fRange = kFALSE;
1704 
1705  // Set a default range
1706  Range(fXsize, fYsize);
1707 
1708  fObjPos = 0;
1709  fObjPosSize = 0;
1710  fNbObj = 0;
1711  fNbPage = 0;
1712 
1713  PrintStr("%PDF-1.4@");
1714  PrintStr("%\342\343\317\323");
1715  PrintStr("@");
1716 
1717  NewObject(kObjRoot);
1718  PrintStr("<<@");
1719  PrintStr("/Type /Catalog@");
1720  PrintStr("/Pages");
1721  WriteInteger(kObjPages);
1722  PrintStr(" 0 R@");
1723  PrintStr("/Outlines");
1724  WriteInteger(kObjOutlines);
1725  PrintStr(" 0 R@");
1726  PrintStr("/PageMode /UseOutlines@");
1727  PrintStr(">>@");
1728  PrintStr("endobj@");
1729 
1730  NewObject(kObjInfo);
1731  PrintStr("<<@");
1732  PrintStr("/Creator (ROOT Version ");
1733  PrintStr(gROOT->GetVersion());
1734  PrintStr(")");
1735  PrintStr("@");
1736  PrintStr("/CreationDate (");
1737  TDatime t;
1738  char str[17];
1739  snprintf(str,17,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
1740  t.GetYear() , t.GetMonth(),
1741  t.GetDay() , t.GetHour(),
1742  t.GetMinute(), t.GetSecond());
1743  PrintStr(str);
1744  PrintStr(")");
1745  PrintStr("@");
1746  PrintStr("/Title (");
1747  if (strlen(GetName())<=80) PrintStr(GetName());
1748  PrintStr(")");
1749  PrintStr("@");
1750  PrintStr("/Keywords (ROOT)@");
1751  PrintStr(">>@");
1752  PrintStr("endobj@");
1753 
1754  NewObject(kObjPageResources);
1755  PrintStr("<<@");
1756  PrintStr("/ProcSet [/PDF /Text]@");
1757 
1758  PrintStr("/Font@");
1759  PrintStr("<<@");
1760  for (i=0; i<kNumberOfFonts; i++) {
1761  PrintStr(" /F");
1762  WriteInteger(i+1,0);
1763  WriteInteger(kObjFont+i);
1764  PrintStr(" 0 R");
1765  }
1766  PrintStr("@");
1767  PrintStr(">>@");
1768 
1769  PrintStr("/ExtGState");
1770  WriteInteger(kObjTransList);
1771  PrintStr(" 0 R @");
1772  if (fAlphas.size()) fAlphas.clear();
1773 
1774  PrintStr("/ColorSpace << /Cs8");
1775  WriteInteger(kObjColorSpace);
1776  PrintStr(" 0 R >>");
1777  PrintStr("@");
1778  PrintStr("/Pattern");
1779  WriteInteger(kObjPatternList);
1780  PrintStr(" 0 R");
1781  PrintStr("@");
1782  PrintStr(">>@");
1783  PrintStr("endobj@");
1784 
1785  FontEncode();
1786  PatternEncode();
1787 
1788  NewPage();
1789  fPageNotEmpty = kFALSE;
1790 }
1791 
1792 ////////////////////////////////////////////////////////////////////////////////
1793 /// Patterns encoding
1794 
1795 void TPDF::PatternEncode()
1796 {
1797  Int_t patternNb = kObjPattern;
1798 
1799  NewObject(kObjColorSpace);
1800  if (gStyle->GetColorModelPS()) {
1801  PrintStr("[/Pattern /DeviceCMYK]@");
1802  } else {
1803  PrintStr("[/Pattern /DeviceRGB]@");
1804  }
1805  PrintStr("endobj@");
1806  NewObject(kObjPatternResourses);
1807  PrintStr("<</ProcSet[/PDF]>>@");
1808  PrintStr("endobj@");
1809 
1810  NewObject(kObjPatternList);
1811  PrintStr("<<@");
1812  PrintStr(" /P01");
1813  WriteInteger(patternNb++);
1814  PrintStr(" 0 R");
1815  PrintStr(" /P02");
1816  WriteInteger(patternNb++);
1817  PrintStr(" 0 R");
1818  PrintStr(" /P03");
1819  WriteInteger(patternNb++);
1820  PrintStr(" 0 R");
1821  PrintStr(" /P04");
1822  WriteInteger(patternNb++);
1823  PrintStr(" 0 R");
1824  PrintStr(" /P05");
1825  WriteInteger(patternNb++);
1826  PrintStr(" 0 R");
1827  PrintStr(" /P06");
1828  WriteInteger(patternNb++);
1829  PrintStr(" 0 R");
1830  PrintStr(" /P07");
1831  WriteInteger(patternNb++);
1832  PrintStr(" 0 R");
1833  PrintStr(" /P08");
1834  WriteInteger(patternNb++);
1835  PrintStr(" 0 R");
1836  PrintStr(" /P09");
1837  WriteInteger(patternNb++);
1838  PrintStr(" 0 R");
1839  PrintStr(" /P10");
1840  WriteInteger(patternNb++);
1841  PrintStr(" 0 R");
1842  PrintStr(" /P11");
1843  WriteInteger(patternNb++);
1844  PrintStr(" 0 R");
1845  PrintStr(" /P12");
1846  WriteInteger(patternNb++);
1847  PrintStr(" 0 R");
1848  PrintStr(" /P13");
1849  WriteInteger(patternNb++);
1850  PrintStr(" 0 R");
1851  PrintStr(" /P14");
1852  WriteInteger(patternNb++);
1853  PrintStr(" 0 R");
1854  PrintStr(" /P15");
1855  WriteInteger(patternNb++);
1856  PrintStr(" 0 R");
1857  PrintStr(" /P16");
1858  WriteInteger(patternNb++);
1859  PrintStr(" 0 R");
1860  PrintStr(" /P17");
1861  WriteInteger(patternNb++);
1862  PrintStr(" 0 R");
1863  PrintStr(" /P18");
1864  WriteInteger(patternNb++);
1865  PrintStr(" 0 R");
1866  PrintStr(" /P19");
1867  WriteInteger(patternNb++);
1868  PrintStr(" 0 R");
1869  PrintStr(" /P20");
1870  WriteInteger(patternNb++);
1871  PrintStr(" 0 R");
1872  PrintStr(" /P21");
1873  WriteInteger(patternNb++);
1874  PrintStr(" 0 R");
1875  PrintStr(" /P22");
1876  WriteInteger(patternNb++);
1877  PrintStr(" 0 R");
1878  PrintStr(" /P23");
1879  WriteInteger(patternNb++);
1880  PrintStr(" 0 R");
1881  PrintStr(" /P24");
1882  WriteInteger(patternNb++);
1883  PrintStr(" 0 R");
1884  PrintStr(" /P25");
1885  WriteInteger(patternNb++);
1886  PrintStr(" 0 R@");
1887  PrintStr(">>@");
1888  PrintStr("endobj@");
1889 
1890  patternNb = kObjPattern;
1891 
1892  // P01
1893  NewObject(patternNb++);
1894  PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
1895  WriteInteger(kObjPatternResourses);
1896  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 98 4]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
1897  PrintStr("@");
1898  fStream->write("stream",6); fNByte += 6;
1899  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);
1900  fNByte += 93;
1901  PrintStr("endstream@");
1902  PrintStr("endobj@");
1903 
1904  // P02
1905  NewObject(patternNb++);
1906  PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
1907  WriteInteger(kObjPatternResourses);
1908  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 4]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
1909  PrintStr("@");
1910  fStream->write("stream",6); fNByte += 6;
1911  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);
1912  fNByte += 94;
1913  PrintStr("endstream@");
1914  PrintStr("endobj@");
1915 
1916  // P03
1917  NewObject(patternNb++);
1918  PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
1919  WriteInteger(kObjPatternResourses);
1920  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 16]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
1921  PrintStr("@");
1922  fStream->write("stream",6); fNByte += 6;
1923  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);
1924  fNByte += 95;
1925  PrintStr("endstream@");
1926  PrintStr("endobj@");
1927 
1928  // P04
1929  NewObject(patternNb++);
1930  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1931  WriteInteger(kObjPatternResourses);
1932  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 63/Filter/FlateDecode>>");
1933  PrintStr("@");
1934  fStream->write("stream",6); fNByte += 6;
1935  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);
1936  fNByte += 65;
1937  PrintStr("endstream@");
1938  PrintStr("endobj@");
1939 
1940  // P05
1941  NewObject(patternNb++);
1942  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1943  WriteInteger(kObjPatternResourses);
1944  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
1945  PrintStr("@");
1946  fStream->write("stream",6); fNByte += 6;
1947  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);
1948  fNByte += 68;
1949  PrintStr("endstream@");
1950  PrintStr("endobj@");
1951 
1952  // P06
1953  NewObject(patternNb++);
1954  PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
1955  WriteInteger(kObjPatternResourses);
1956  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
1957  PrintStr("@");
1958  fStream->write("stream",6); fNByte += 6;
1959  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);
1960  fNByte += 68;
1961  PrintStr("endstream@");
1962  PrintStr("endobj@");
1963 
1964  // P07
1965  NewObject(patternNb++);
1966  PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
1967  WriteInteger(kObjPatternResourses);
1968  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
1969  PrintStr("@");
1970  fStream->write("stream",6); fNByte += 6;
1971  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);
1972  fNByte += 70;
1973  PrintStr("endstream@");
1974  PrintStr("endobj@");
1975 
1976  // P08
1977  NewObject(patternNb++);
1978  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1979  WriteInteger(kObjPatternResourses);
1980  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
1981  PrintStr("@");
1982  fStream->write("stream",6); fNByte += 6;
1983  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);
1984  fNByte += 141;
1985  PrintStr("endstream@");
1986  PrintStr("endobj@");
1987 
1988  // P09
1989  NewObject(patternNb++);
1990  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
1991  WriteInteger(kObjPatternResourses);
1992  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
1993  PrintStr("@");
1994  fStream->write("stream",6); fNByte += 6;
1995  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);
1996  fNByte += 110;
1997  PrintStr("endstream@");
1998  PrintStr("endobj@");
1999 
2000  // P10
2001  NewObject(patternNb++);
2002  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2003  WriteInteger(kObjPatternResourses);
2004  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 93/Filter/FlateDecode>>");
2005  PrintStr("@");
2006  fStream->write("stream",6); fNByte += 6;
2007  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);
2008  fNByte += 95;
2009  PrintStr("endstream@");
2010  PrintStr("endobj@");
2011 
2012  // P11
2013  NewObject(patternNb++);
2014  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2015  WriteInteger(kObjPatternResourses);
2016  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 164/Filter/FlateDecode>>");
2017  PrintStr("@");
2018  fStream->write("stream",6); fNByte += 6;
2019  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);
2020  fNByte += 166;
2021  PrintStr("endstream@");
2022  PrintStr("endobj@");
2023 
2024  // P12
2025  NewObject(patternNb++);
2026  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2027  WriteInteger(kObjPatternResourses);
2028  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
2029  PrintStr("@");
2030  fStream->write("stream",6); fNByte += 6;
2031  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);
2032  fNByte += 228;
2033  PrintStr("endstream@");
2034  PrintStr("endobj@");
2035 
2036  // P13
2037  NewObject(patternNb++);
2038  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2039  WriteInteger(kObjPatternResourses);
2040  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2041  PrintStr("@");
2042  fStream->write("stream",6); fNByte += 6;
2043  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);
2044  fNByte += 71;
2045  PrintStr("endstream@");
2046  PrintStr("endobj@");
2047 
2048  // P14
2049  NewObject(patternNb++);
2050  PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
2051  WriteInteger(kObjPatternResourses);
2052  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
2053  PrintStr("@");
2054  fStream->write("stream",6); fNByte += 6;
2055  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);
2056  fNByte += 116;
2057  PrintStr("endstream@");
2058  PrintStr("endobj@");
2059 
2060  // P15
2061  NewObject(patternNb++);
2062  PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
2063  WriteInteger(kObjPatternResourses);
2064  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
2065  PrintStr("@");
2066  fStream->write("stream",6); fNByte += 6;
2067  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);
2068  fNByte += 220;
2069  PrintStr("endstream@");
2070  PrintStr("endobj@");
2071 
2072  // P16
2073  NewObject(patternNb++);
2074  PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
2075  WriteInteger(kObjPatternResourses);
2076  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
2077  PrintStr("@");
2078  fStream->write("stream",6); fNByte += 6;
2079  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);
2080  fNByte += 125;
2081  PrintStr("endstream@");
2082  PrintStr("endobj@");
2083 
2084  // P17
2085  NewObject(patternNb++);
2086  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2087  WriteInteger(kObjPatternResourses);
2088  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2089  PrintStr("@");
2090  fStream->write("stream",6); fNByte += 6;
2091  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);
2092  fNByte += 68;
2093  PrintStr("endstream@");
2094  PrintStr("endobj@");
2095 
2096  // P18
2097  NewObject(patternNb++);
2098  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2099  WriteInteger(kObjPatternResourses);
2100  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2101  PrintStr("@");
2102  fStream->write("stream",6); fNByte += 6;
2103  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);
2104  fNByte += 71;
2105  PrintStr("endstream@");
2106  PrintStr("endobj@");
2107 
2108  // P19
2109  NewObject(patternNb++);
2110  PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
2111  WriteInteger(kObjPatternResourses);
2112  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
2113  PrintStr("@");
2114  fStream->write("stream",6); fNByte += 6;
2115  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);
2116  fNByte += 151;
2117  PrintStr("endstream@");
2118  PrintStr("endobj@");
2119 
2120  // P20
2121  NewObject(patternNb++);
2122  PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
2123  WriteInteger(kObjPatternResourses);
2124  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
2125  PrintStr("@");
2126  fStream->write("stream",6); fNByte += 6;
2127  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);
2128  fNByte += 124;
2129  PrintStr("endstream@");
2130  PrintStr("endobj@");
2131 
2132  // P21
2133  NewObject(patternNb++);
2134  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2135  WriteInteger(kObjPatternResourses);
2136  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
2137  PrintStr("@");
2138  fStream->write("stream",6); fNByte += 6;
2139  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);
2140  fNByte += 119;
2141  PrintStr("endstream@");
2142  PrintStr("endobj@");
2143 
2144  // P22
2145  NewObject(patternNb++);
2146  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2147  WriteInteger(kObjPatternResourses);
2148  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
2149  PrintStr("@");
2150  fStream->write("stream",6); fNByte += 6;
2151  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);
2152  fNByte += 120;
2153  PrintStr("endstream@");
2154  PrintStr("endobj@");
2155 
2156  // P23
2157  NewObject(patternNb++);
2158  PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2159  WriteInteger(kObjPatternResourses);
2160  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
2161  PrintStr("@");
2162  fStream->write("stream",6); fNByte += 6;
2163  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);
2164  fNByte += 171;
2165  PrintStr("endstream@");
2166  PrintStr("endobj@");
2167 
2168  // P24
2169  NewObject(patternNb++);
2170  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2171  WriteInteger(kObjPatternResourses);
2172  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
2173  PrintStr("@");
2174  fStream->write("stream",6); fNByte += 6;
2175  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);
2176  fNByte += 282;
2177  PrintStr("endstream@");
2178  PrintStr("endobj@");
2179 
2180  // P25
2181  NewObject(patternNb++);
2182  PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2183  WriteInteger(kObjPatternResourses);
2184  PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
2185  PrintStr("@");
2186  fStream->write("stream",6); fNByte += 6;
2187  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);
2188  fNByte += 56;
2189  PrintStr("endstream@");
2190  PrintStr("endobj@");
2191 }
2192 
2193 ////////////////////////////////////////////////////////////////////////////////
2194 /// Output the string str in the output buffer
2195 
2196 void TPDF::PrintStr(const char *str)
2197 {
2198  Int_t len = strlen(str);
2199  if (len == 0) return;
2200  fPageNotEmpty = kTRUE;
2201 
2202  if (fCompress) {
2203  if (fLenBuffer+len >= fSizBuffer) {
2204  fBuffer = TStorage::ReAllocChar(fBuffer, 2*fSizBuffer, fSizBuffer);
2205  fSizBuffer = 2*fSizBuffer;
2206  }
2207  strcpy(fBuffer + fLenBuffer, str);
2208  fLenBuffer += len;
2209  return;
2210  }
2211 
2212  TVirtualPS::PrintStr(str);
2213 }
2214 
2215 ////////////////////////////////////////////////////////////////////////////////
2216 /// Fast version of Print
2217 
2218 void TPDF::PrintFast(Int_t len, const char *str)
2219 {
2220  fPageNotEmpty = kTRUE;
2221  if (fCompress) {
2222  if (fLenBuffer+len >= fSizBuffer) {
2223  fBuffer = TStorage::ReAllocChar(fBuffer, 2*fSizBuffer, fSizBuffer);
2224  fSizBuffer = 2*fSizBuffer;
2225  }
2226  strcpy(fBuffer + fLenBuffer, str);
2227  fLenBuffer += len;
2228  return;
2229  }
2230 
2231  TVirtualPS::PrintFast(len, str);
2232 }
2233 
2234 ////////////////////////////////////////////////////////////////////////////////
2235 /// Set the range for the paper in centimetres
2236 
2237 void TPDF::Range(Float_t xsize, Float_t ysize)
2238 {
2239  Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
2240 
2241  fXsize = xsize;
2242  fYsize = ysize;
2243 
2244  xps = xsize;
2245  yps = ysize;
2246 
2247  if (xsize <= xps && ysize < yps) {
2248  if ( xps > yps) xymax = xps;
2249  else xymax = yps;
2250  xncm = xsize/xymax;
2251  yncm = ysize/xymax;
2252  dxwn = ((xps/xymax)-xncm)/2;
2253  dywn = ((yps/xymax)-yncm)/2;
2254  } else {
2255  if (xps/yps < 1) xwkwn = xps/yps;
2256  else xwkwn = 1;
2257  if (yps/xps < 1) ywkwn = yps/xps;
2258  else ywkwn = 1;
2259 
2260  if (xsize < ysize) {
2261  xncm = ywkwn*xsize/ysize;
2262  yncm = ywkwn;
2263  dxwn = (xwkwn-xncm)/2;
2264  dywn = 0;
2265  if (dxwn < 0) {
2266  xncm = xwkwn;
2267  dxwn = 0;
2268  yncm = xwkwn*ysize/xsize;
2269  dywn = (ywkwn-yncm)/2;
2270  }
2271  } else {
2272  xncm = xwkwn;
2273  yncm = xwkwn*ysize/xsize;
2274  dxwn = 0;
2275  dywn = (ywkwn-yncm)/2;
2276  if (dywn < 0) {
2277  yncm = ywkwn;
2278  dywn = 0;
2279  xncm = ywkwn*xsize/ysize;
2280  dxwn = (xwkwn-xncm)/2;
2281  }
2282  }
2283  }
2284  fRange = kTRUE;
2285 }
2286 
2287 ////////////////////////////////////////////////////////////////////////////////
2288 /// Set the alpha channel value.
2289 
2290 void TPDF::SetAlpha(Float_t a)
2291 {
2292  if (a == fAlpha) return;
2293  fAlpha = a;
2294  if (fAlpha <= 0.000001) fAlpha = 0;
2295 
2296  Bool_t known = kFALSE;
2297  for (int i=0; i<(int)fAlphas.size(); i++) {
2298  if (fAlpha == fAlphas[i]) {
2299  known = kTRUE;
2300  break;
2301  }
2302  }
2303  if (!known) fAlphas.push_back(fAlpha);
2304  PrintStr(Form(" /ca%3.2f gs /CA%3.2f gs",fAlpha,fAlpha));
2305 }
2306 
2307 ////////////////////////////////////////////////////////////////////////////////
2308 /// Set color with its color index.
2309 
2310 void TPDF::SetColor(Int_t color)
2311 {
2312  if (color < 0) color = 0;
2313  TColor *col = gROOT->GetColor(color);
2314 
2315  if (col) {
2316  SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
2317  SetAlpha(col->GetAlpha());
2318  } else {
2319  SetColor(1., 1., 1.);
2320  SetAlpha(1.);
2321  }
2322 }
2323 
2324 ////////////////////////////////////////////////////////////////////////////////
2325 /// Set color with its R G B components:
2326 ///
2327 /// - r: % of red in [0,1]
2328 /// - g: % of green in [0,1]
2329 /// - b: % of blue in [0,1]
2330 
2331 void TPDF::SetColor(Float_t r, Float_t g, Float_t b)
2332 {
2333  if (r == fRed && g == fGreen && b == fBlue) return;
2334 
2335  fRed = r;
2336  fGreen = g;
2337  fBlue = b;
2338  if (fRed <= 0.000001) fRed = 0;
2339  if (fGreen <= 0.000001) fGreen = 0;
2340  if (fBlue <= 0.000001) fBlue = 0;
2341 
2342  if (gStyle->GetColorModelPS()) {
2343  Double_t colCyan, colMagenta, colYellow;
2344  Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
2345  if (colBlack==1) {
2346  colCyan = 0;
2347  colMagenta = 0;
2348  colYellow = 0;
2349  } else {
2350  colCyan = (1-fRed-colBlack)/(1-colBlack);
2351  colMagenta = (1-fGreen-colBlack)/(1-colBlack);
2352  colYellow = (1-fBlue-colBlack)/(1-colBlack);
2353  }
2354  if (colCyan <= 0.000001) colCyan = 0;
2355  if (colMagenta <= 0.000001) colMagenta = 0;
2356  if (colYellow <= 0.000001) colYellow = 0;
2357  if (colBlack <= 0.000001) colBlack = 0;
2358  WriteReal(colCyan);
2359  WriteReal(colMagenta);
2360  WriteReal(colYellow);
2361  WriteReal(colBlack);
2362  PrintFast(2," K");
2363  WriteReal(colCyan);
2364  WriteReal(colMagenta);
2365  WriteReal(colYellow);
2366  WriteReal(colBlack);
2367  PrintFast(2," k");
2368  } else {
2369  WriteReal(fRed);
2370  WriteReal(fGreen);
2371  WriteReal(fBlue);
2372  PrintFast(3," RG");
2373  WriteReal(fRed);
2374  WriteReal(fGreen);
2375  WriteReal(fBlue);
2376  PrintFast(3," rg");
2377  }
2378 }
2379 
2380 ////////////////////////////////////////////////////////////////////////////////
2381 /// Set color index for fill areas
2382 
2383 void TPDF::SetFillColor( Color_t cindex )
2384 {
2385  fFillColor = cindex;
2386  if (gStyle->GetFillColor() <= 0) cindex = 0;
2387 }
2388 
2389 ////////////////////////////////////////////////////////////////////////////////
2390 /// Set the fill patterns (1 to 25) for fill areas
2391 
2392 void TPDF::SetFillPatterns(Int_t ipat, Int_t color)
2393 {
2394  char cpat[10];
2395  TColor *col = gROOT->GetColor(color);
2396  if (!col) return;
2397  PrintStr(" /Cs8 cs");
2398  Double_t colRed = col->GetRed();
2399  Double_t colGreen = col->GetGreen();
2400  Double_t colBlue = col->GetBlue();
2401  if (gStyle->GetColorModelPS()) {
2402  Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
2403  if (colBlack==1) {
2404  WriteReal(0);
2405  WriteReal(0);
2406  WriteReal(0);
2407  WriteReal(colBlack);
2408  } else {
2409  Double_t colCyan = (1-colRed-colBlack)/(1-colBlack);
2410  Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
2411  Double_t colYellow = (1-colBlue-colBlack)/(1-colBlack);
2412  WriteReal(colCyan);
2413  WriteReal(colMagenta);
2414  WriteReal(colYellow);
2415  WriteReal(colBlack);
2416  }
2417  } else {
2418  WriteReal(colRed);
2419  WriteReal(colGreen);
2420  WriteReal(colBlue);
2421  }
2422  snprintf(cpat,10," /P%2.2d scn", ipat);
2423  PrintStr(cpat);
2424 }
2425 
2426 ////////////////////////////////////////////////////////////////////////////////
2427 /// Set color index for lines
2428 
2429 void TPDF::SetLineColor( Color_t cindex )
2430 {
2431  fLineColor = cindex;
2432 }
2433 
2434 ////////////////////////////////////////////////////////////////////////////////
2435 /// Set the value of the global parameter TPDF::fgLineJoin.
2436 /// This parameter determines the appearance of joining lines in a PDF
2437 /// output.
2438 /// It takes one argument which may be:
2439 /// - 0 (miter join)
2440 /// - 1 (round join)
2441 /// - 2 (bevel join)
2442 /// The default value is 0 (miter join).
2443 ///
2444 /// \image html postscript_1.png
2445 ///
2446 /// To change the line join behaviour just do:
2447 /// ~~~ {.cpp}
2448 /// gStyle->SetJoinLinePS(2); // Set the PDF line join to bevel.
2449 /// ~~~
2450 
2451 void TPDF::SetLineJoin( Int_t linejoin )
2452 {
2453  fgLineJoin = linejoin;
2454 }
2455 
2456 ////////////////////////////////////////////////////////////////////////////////
2457 /// Change the line style
2458 ///
2459 /// - linestyle = 2 dashed
2460 /// - linestyle = 3 dotted
2461 /// - linestyle = 4 dash-dotted
2462 /// - linestyle = else solid (1 in is used most of the time)
2463 
2464 void TPDF::SetLineStyle(Style_t linestyle)
2465 {
2466  if ( linestyle == fLineStyle) return;
2467  fLineStyle = linestyle;
2468  TString st = (TString)gStyle->GetLineStyleString(linestyle);
2469  PrintFast(2," [");
2470  TObjArray *tokens = st.Tokenize(" ");
2471  for (Int_t j = 0; j<tokens->GetEntries(); j++) {
2472  Int_t it;
2473  sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2474  WriteInteger((Int_t)(it/4));
2475  }
2476  delete tokens;
2477  PrintFast(5,"] 0 d");
2478 }
2479 
2480 ////////////////////////////////////////////////////////////////////////////////
2481 /// Change the line width
2482 
2483 void TPDF::SetLineWidth(Width_t linewidth)
2484 {
2485  if (linewidth == fLineWidth) return;
2486  fLineWidth = linewidth;
2487  if (fLineWidth!=0) {
2488  WriteReal(fLineScale*fLineWidth);
2489  PrintFast(2," w");
2490  }
2491 }
2492 
2493 ////////////////////////////////////////////////////////////////////////////////
2494 /// Set color index for markers.
2495 
2496 void TPDF::SetMarkerColor( Color_t cindex )
2497 {
2498  fMarkerColor = cindex;
2499 }
2500 
2501 ////////////////////////////////////////////////////////////////////////////////
2502 /// Set color index for text
2503 
2504 void TPDF::SetTextColor( Color_t cindex )
2505 {
2506  fTextColor = cindex;
2507 }
2508 
2509 ////////////////////////////////////////////////////////////////////////////////
2510 /// Draw text
2511 ///
2512 /// - xx: x position of the text
2513 /// - yy: y position of the text
2514 /// - chars: text to be drawn
2515 
2516 void TPDF::Text(Double_t xx, Double_t yy, const char *chars)
2517 {
2518  if (fTextSize <= 0) return;
2519 
2520  const Double_t kDEGRAD = TMath::Pi()/180.;
2521  char str[8];
2522  Double_t x = xx;
2523  Double_t y = yy;
2524 
2525  // Font and text size
2526  Int_t font = abs(fTextFont)/10;
2527  if (font > kNumberOfFonts || font < 1) font = 1;
2528 
2529  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2530  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2531  Float_t tsize, ftsize;
2532  if (wh < hh) {
2533  tsize = fTextSize*wh;
2534  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2535  ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2536  } else {
2537  tsize = fTextSize*hh;
2538  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2539  ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2540  }
2541  Double_t fontsize = 72*(ftsize)/2.54;
2542  if (fontsize <= 0) return;
2543 
2544  // Text color
2545  SetColor(Int_t(fTextColor));
2546 
2547  // Clipping
2548  PrintStr(" q");
2549  Double_t x1 = XtoPDF(gPad->GetX1());
2550  Double_t x2 = XtoPDF(gPad->GetX2());
2551  Double_t y1 = YtoPDF(gPad->GetY1());
2552  Double_t y2 = YtoPDF(gPad->GetY2());
2553  WriteReal(x1);
2554  WriteReal(y1);
2555  WriteReal(x2 - x1);
2556  WriteReal(y2 - y1);
2557  PrintStr(" re W n");
2558 
2559  // Start the text
2560  if (!fCompress) PrintStr("@");
2561 
2562  // Text alignment
2563  Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2564  Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2565  Int_t txalh = fTextAlign/10;
2566  if (txalh < 1) txalh = 1; else if (txalh > 3) txalh = 3;
2567  Int_t txalv = fTextAlign%10;
2568  if (txalv < 1) txalv = 1; else if (txalv > 3) txalv = 3;
2569  if (txalv == 3) {
2570  y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2571  x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2572  } else if (txalv == 2) {
2573  y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2574  x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2575  }
2576 
2577  if (txalh > 1) {
2578  TText t;
2579  UInt_t w=0, h;
2580  t.SetTextSize(fTextSize);
2581  t.SetTextFont(fTextFont);
2582  t.GetTextExtent(w, h, chars);
2583  Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2584  Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
2585  if (txalh == 2) {
2586  x = x-(twx/2)*TMath::Cos(kDEGRAD*fTextAngle);
2587  y = y-(twy/2)*TMath::Sin(kDEGRAD*fTextAngle);
2588  }
2589  if (txalh == 3) {
2590  x = x-twx*TMath::Cos(kDEGRAD*fTextAngle);
2591  y = y-twy*TMath::Sin(kDEGRAD*fTextAngle);
2592  }
2593  }
2594 
2595  // Text angle
2596  if (fTextAngle == 0) {
2597  PrintStr(" 1 0 0 1");
2598  WriteReal(XtoPDF(x));
2599  WriteReal(YtoPDF(y));
2600  } else if (fTextAngle == 90) {
2601  PrintStr(" 0 1 -1 0");
2602  WriteReal(XtoPDF(x));
2603  WriteReal(YtoPDF(y));
2604  } else if (fTextAngle == 270) {
2605  PrintStr(" 0 -1 1 0");
2606  WriteReal(XtoPDF(x));
2607  WriteReal(YtoPDF(y));
2608  } else {
2609  WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
2610  WriteReal(TMath::Sin(kDEGRAD*fTextAngle));
2611  WriteReal(-TMath::Sin(kDEGRAD*fTextAngle));
2612  WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
2613  WriteReal(XtoPDF(x));
2614  WriteReal(YtoPDF(y));
2615  }
2616  PrintStr(" cm");
2617 
2618  // Symbol Italic tan(15) = .26794
2619  if (font == 15) PrintStr(" 1 0 0.26794 1 0 0 cm");
2620 
2621  PrintStr(" BT");
2622 
2623  snprintf(str,8," /F%d",font);
2624  PrintStr(str);
2625  WriteReal(fontsize);
2626  PrintStr(" Tf");
2627 
2628  const Int_t len=strlen(chars);
2629 
2630  // Calculate the individual character placements.
2631  // Otherwise, if a string is printed in one line the kerning is not
2632  // performed. In order to measure the precise character positions we need to
2633  // trick FreeType into rendering high-resolution characters otherwise it will
2634  // stick to the screen pixel grid which is far worse than we can achieve on
2635  // print.
2636  const Float_t scale = 16.0;
2637  // Save current text attributes.
2638  TText saveAttText;
2639  saveAttText.TAttText::operator=(*this);
2640  TText t;
2641  t.SetTextSize(fTextSize * scale);
2642  t.SetTextFont(fTextFont);
2643  UInt_t wa1=0, wa0=0;
2644  t.GetTextAdvance(wa0, chars, kFALSE);
2645  t.GetTextAdvance(wa1, chars);
2646  t.TAttText::Modify();
2647  Bool_t kerning;
2648  if (wa0-wa1 != 0) kerning = kTRUE;
2649  else kerning = kFALSE;
2650  Int_t *charDeltas = 0;
2651  if (kerning) {
2652  charDeltas = new Int_t[len];
2653  for (Int_t i = 0;i < len;i++) {
2654  UInt_t ww=0;
2655  t.GetTextAdvance(ww, chars + i);
2656  charDeltas[i] = wa1 - ww;
2657  }
2658  for (Int_t i = len - 1;i > 0;i--) {
2659  charDeltas[i] -= charDeltas[i-1];
2660  }
2661  char tmp[2];
2662  tmp[1] = 0;
2663  for (Int_t i = 1;i < len;i++) {
2664  tmp[0] = chars[i-1];
2665  UInt_t width=0;
2666  t.GetTextAdvance(width, &tmp[0], kFALSE);
2667  Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
2668  wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
2669  charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
2670  }
2671  }
2672  // Restore text attributes.
2673  saveAttText.TAttText::Modify();
2674 
2675  // Output the text. Escape some characters if needed
2676  if (kerning) PrintStr(" [");
2677  else PrintStr(" (");
2678 
2679  for (Int_t i=0; i<len;i++) {
2680  if (chars[i]!='\n') {
2681  if (kerning) PrintStr("(");
2682  if (chars[i]=='(' || chars[i]==')') {
2683  snprintf(str,8,"\\%c",chars[i]);
2684  } else {
2685  snprintf(str,8,"%c",chars[i]);
2686  }
2687  PrintStr(str);
2688  if (kerning) {
2689  PrintStr(") ");
2690  if (i < len-1) {
2691  WriteInteger(charDeltas[i+1]);
2692  }
2693  }
2694  }
2695  }
2696 
2697  if (kerning) PrintStr("] TJ ET Q");
2698  else PrintStr(") Tj ET Q");
2699  if (!fCompress) PrintStr("@");
2700  if (kerning) delete [] charDeltas;
2701 }
2702 
2703 ////////////////////////////////////////////////////////////////////////////////
2704 /// Write a string of characters
2705 ///
2706 /// This method writes the string chars into a PDF file
2707 /// at position xx,yy in world coordinates.
2708 
2709 void TPDF::Text(Double_t, Double_t, const wchar_t *)
2710 {
2711 }
2712 
2713 ////////////////////////////////////////////////////////////////////////////////
2714 /// Write a string of characters in NDC
2715 
2716 void TPDF::TextNDC(Double_t u, Double_t v, const char *chars)
2717 {
2718  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2719  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2720  Text(x, y, chars);
2721 }
2722 
2723 ////////////////////////////////////////////////////////////////////////////////
2724 /// Write a string of characters in NDC
2725 
2726 void TPDF::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2727 {
2728  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2729  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2730  Text(x, y, chars);
2731 }
2732 
2733 ////////////////////////////////////////////////////////////////////////////////
2734 /// Convert U from NDC coordinate to PDF
2735 
2736 Double_t TPDF::UtoPDF(Double_t u)
2737 {
2738  Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2739  return 72*cm/2.54;
2740 }
2741 
2742 ////////////////////////////////////////////////////////////////////////////////
2743 /// Convert V from NDC coordinate to PDF
2744 
2745 Double_t TPDF::VtoPDF(Double_t v)
2746 {
2747  Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2748  return 72*cm/2.54;
2749 }
2750 
2751 ////////////////////////////////////////////////////////////////////////////////
2752 /// Convert X from world coordinate to PDF
2753 
2754 Double_t TPDF::XtoPDF(Double_t x)
2755 {
2756  Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2757  return UtoPDF(u);
2758 }
2759 
2760 ////////////////////////////////////////////////////////////////////////////////
2761 /// Convert Y from world coordinate to PDF
2762 
2763 Double_t TPDF::YtoPDF(Double_t y)
2764 {
2765  Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2766  return VtoPDF(v);
2767 }
2768 
2769 ////////////////////////////////////////////////////////////////////////////////
2770 /// Write the buffer in a compressed way
2771 
2772 void TPDF::WriteCompressedBuffer()
2773 {
2774  z_stream stream;
2775  int err;
2776  char *out = new char[2*fLenBuffer];
2777 
2778  stream.next_in = (Bytef*)fBuffer;
2779  stream.avail_in = (uInt)fLenBuffer;
2780  stream.next_out = (Bytef*)out;
2781  stream.avail_out = (uInt)2*fLenBuffer;
2782  stream.zalloc = (alloc_func)0;
2783  stream.zfree = (free_func)0;
2784  stream.opaque = (voidpf)0;
2785 
2786  err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2787  if (err != Z_OK) {
2788  Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
2789  return;
2790  }
2791 
2792  err = deflate(&stream, Z_FINISH);
2793  if (err != Z_STREAM_END) {
2794  deflateEnd(&stream);
2795  Error("WriteCompressedBuffer", "error in deflate (zlib)");
2796  return;
2797  }
2798 
2799  err = deflateEnd(&stream);
2800 
2801  fStream->write(out, stream.total_out);
2802 
2803  fNByte += stream.total_out;
2804  fStream->write("\n",1); fNByte++;
2805  fLenBuffer = 0;
2806  delete [] out;
2807  fCompress = kFALSE;
2808 }
2809 
2810 ////////////////////////////////////////////////////////////////////////////////
2811 /// Write a Real number to the file.
2812 /// This method overwrites TVirtualPS::WriteReal. Some PDF reader like
2813 /// Acrobat do not work when a PDF file contains reals with exponent. This
2814 /// method writes the real number "z" using the format "%f" instead of the
2815 /// format "%g" when writing it with "%g" generates a number with exponent.
2816 
2817 void TPDF::WriteReal(Float_t z, Bool_t space)
2818 {
2819  char str[15];
2820  if (space) {
2821  snprintf(str,15," %g", z);
2822  if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
2823  } else {
2824  snprintf(str,15,"%g", z);
2825  if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15,"%10.8f", z);
2826  }
2827  PrintStr(str);
2828 }