TPDF.cxx

Go to the documentation of this file.
00001 // @(#)root/postscript:$Id: TPDF.cxx,v 1.0
00002 // Author: Olivier Couet
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 
00013 //______________________________________________________________________________
00014 /* Begin_Html
00015 <center><h2>TPDF: Graphics interface to PDF</h2></center>
00016 Like PostScript, PDF is a vector graphics output format allowing a very high
00017 graphics output quality. The functionnalities provided by this class are very
00018 similar to those provided by <tt>TPostScript</tt>.
00019 <p>
00020 Compare to PostScript output, the PDF files are usually smaller because some
00021 parts of them can be compressed.
00022 <p>
00023 PDF also allows to define table of contents. This facility can be used in ROOT.
00024 The following example shows how to proceed:
00025 <pre>
00026 {
00027    TCanvas* canvas = new TCanvas("canvas");
00028    TH1F* histo = new TH1F("histo","test 1",10,0.,10.);
00029    histo->SetFillColor(2);
00030    histo->Fill(2.);
00031    histo->Draw();
00032    canvas->Print("plots.pdf(","Title:One bin filled");
00033    histo->Fill(4.);
00034    histo->Draw();
00035    canvas->Print("plots.pdf","Title:Two bins filled");
00036    histo->Fill(6.);
00037    histo->Draw();
00038    canvas->Print("plots.pdf","Title:Three bins filled");
00039    histo->Fill(8.);
00040    histo->Draw();
00041    canvas->Print("plots.pdf","Title:Four bins filled");
00042    histo->Fill(8.);
00043    histo->Draw();
00044    canvas->Print("plots.pdf)","Title:The fourth bin content is 2");
00045 }
00046 </pre>
00047 Each character string following the keyword "Title:" makes a new entry in
00048 the table of contents.
00049 End_Html */
00050 
00051 #ifdef WIN32
00052 #pragma optimize("",off)
00053 #endif
00054 
00055 #include <stdlib.h>
00056 #include <string.h>
00057 #include <ctype.h>
00058 
00059 #include "Riostream.h"
00060 #include "TROOT.h"
00061 #include "TColor.h"
00062 #include "TVirtualPad.h"
00063 #include "TPoints.h"
00064 #include "TPDF.h"
00065 #include "TStyle.h"
00066 #include "TMath.h"
00067 #include "TStorage.h"
00068 #include "TText.h"
00069 #include "zlib.h"
00070 #include "TObjString.h"
00071 #include "TClass.h"
00072 #include "TObjArray.h"
00073 
00074 // To scale fonts to the same size as the old TT version
00075 const Float_t kScale = 0.93376068;
00076 
00077 // Objects numbers
00078 const Int_t kObjRoot             =  1; // Root object
00079 const Int_t kObjInfo             =  2; // Info object
00080 const Int_t kObjOutlines         =  3; // Outlines object
00081 const Int_t kObjPages            =  4; // Pages object (pages index)
00082 const Int_t kObjPageResources    =  5; // Pages Resources object
00083 const Int_t kObjContents         =  6; // Table of content
00084 const Int_t kObjFont             =  7; // First Font object (14 in total)
00085 const Int_t kObjColorSpace       = 22; // ColorSpace object
00086 const Int_t kObjPatternResourses = 23; // Pattern Resources object
00087 const Int_t kObjPatternList      = 24; // Pattern list object
00088 const Int_t kObjPattern          = 25; // Pattern object
00089 const Int_t kObjFirstPage        = 50; // First page object
00090 
00091 // Number of fonts
00092 const Int_t kNumberOfFonts = 15;
00093 
00094 ClassImp(TPDF)
00095 
00096 
00097 //______________________________________________________________________________
00098 //
00099 // PDF driver
00100 //
00101 
00102 
00103 //______________________________________________________________________________
00104 TPDF::TPDF() : TVirtualPS()
00105 {
00106    // Default PDF constructor
00107 
00108    fStream          = 0;
00109    fCompress        = kFALSE;
00110    fPageNotEmpty    = kFALSE;
00111    gVirtualPS       = this;
00112    fRed             = 0.;
00113    fGreen           = 0.;
00114    fBlue            = 0.;
00115    fXsize           = 0.;
00116    fYsize           = 0.;
00117    fType            = 0;
00118    fPageFormat      = 0;
00119    fPageOrientation = 0;
00120    fStartStream     = 0;
00121    fLineScale       = 0.;
00122    fObjPosSize      = 0;
00123    fNbObj           = 0;
00124    fNbPage          = 0;
00125    fRange           = kFALSE;
00126    SetTitle("PDF");
00127 }
00128 
00129 
00130 //______________________________________________________________________________
00131 TPDF::TPDF(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
00132 {
00133    // Initialize the PDF interface
00134    //
00135    //  fname : PDF file name
00136    //  wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
00137    //          inherits from TVirtualPS it should be kept. Anyway it is not
00138    //          necessary to specify this parameter at creation time because it
00139    //          has a default value (which is ignore in the PDF case).
00140 
00141    fStream          = 0;
00142    fCompress        = kFALSE;
00143    fPageNotEmpty    = kFALSE;
00144    fRed             = 0.;
00145    fGreen           = 0.;
00146    fBlue            = 0.;
00147    fXsize           = 0.;
00148    fYsize           = 0.;
00149    fType            = 0;
00150    fPageFormat      = 0;
00151    fPageOrientation = 0;
00152    fStartStream     = 0;
00153    fLineScale       = 0.;
00154    fObjPosSize      = 0;
00155    fNbObj           = 0;
00156    fNbPage          = 0;
00157    fRange           = kFALSE;
00158    SetTitle("PDF");
00159    Open(fname, wtype);
00160 }
00161 
00162 
00163 //______________________________________________________________________________
00164 TPDF::~TPDF()
00165 {
00166    // Default PDF destructor
00167 
00168    Close();
00169 
00170    if (fObjPos) delete [] fObjPos;
00171 }
00172 
00173 
00174 //______________________________________________________________________________
00175 void TPDF::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t,
00176                           Double_t)
00177 {
00178    // Begin the Cell Array painting
00179    Warning("TPDF::CellArrayBegin", "not yet implemented");
00180 }
00181 
00182 
00183 //______________________________________________________________________________
00184 void TPDF::CellArrayFill(Int_t, Int_t, Int_t)
00185 {
00186    // Paint the Cell Array
00187    Warning("TPDF::CellArrayFill", "not yet implemented");
00188 }
00189 
00190 
00191 //______________________________________________________________________________
00192 void TPDF::CellArrayEnd()
00193 {
00194    // End the Cell Array painting
00195    Warning("TPDF::CellArrayEnd", "not yet implemented");
00196 }
00197 
00198 
00199 //______________________________________________________________________________
00200 void TPDF::Close(Option_t *)
00201 {
00202    // Close a PDF file
00203 
00204    Int_t i;
00205 
00206    if (!gVirtualPS) return;
00207    if (!fStream) return;
00208    if (gPad) gPad->Update();
00209 
00210    // Close the currently opened page
00211    WriteCompressedBuffer();
00212    PrintStr("endstream@");
00213    Int_t streamLength = fNByte-fStartStream-10;
00214    PrintStr("endobj@");
00215    NewObject(4*(fNbPage-1)+kObjFirstPage+2);
00216    WriteInteger(streamLength, 0);
00217    PrintStr("@");
00218    PrintStr("endobj@");
00219    NewObject(4*(fNbPage-1)+kObjFirstPage+3);
00220    PrintStr("<<@");
00221    if (!strstr(GetTitle(),"PDF")) {
00222       PrintStr("/Title (");
00223       PrintStr(GetTitle());
00224       PrintStr(")@");
00225    } else {
00226       PrintStr("/Title (Page");
00227       WriteInteger(fNbPage);
00228       PrintStr(")@");
00229    }
00230    PrintStr("/Dest [");
00231    WriteInteger(4*(fNbPage-1)+kObjFirstPage);
00232    PrintStr(" 0 R /XYZ null null 0]@");
00233    PrintStr("/Parent");
00234    WriteInteger(kObjContents);
00235    PrintStr(" 0 R");
00236    PrintStr("@");
00237    if (fNbPage > 1) {
00238       PrintStr("/Prev");
00239       WriteInteger(4*(fNbPage-2)+kObjFirstPage+3);
00240       PrintStr(" 0 R");
00241       PrintStr("@");
00242    }
00243    PrintStr(">>@");
00244 
00245    NewObject(kObjOutlines);
00246    PrintStr("<<@");
00247    PrintStr("/Type /Outlines@");
00248    PrintStr("/Count");
00249    WriteInteger(fNbPage+1);
00250    PrintStr("@");
00251    PrintStr("/First");
00252    WriteInteger(kObjContents);
00253    PrintStr(" 0 R");
00254    PrintStr("@");
00255    PrintStr("/Last");
00256    WriteInteger(kObjContents);
00257    PrintStr(" 0 R");
00258    PrintStr("@");
00259    PrintStr(">>@");
00260    PrintStr("endobj@");
00261 
00262    NewObject(kObjContents);
00263    PrintStr("<<@");
00264    PrintStr("/Title (Contents)@");
00265    PrintStr("/Dest [");
00266    WriteInteger(kObjFirstPage);
00267    PrintStr(" 0 R /XYZ null null 0]@");
00268    PrintStr("/Count");
00269    WriteInteger(fNbPage);
00270    PrintStr("@");
00271    PrintStr("/Parent");
00272    WriteInteger(kObjOutlines);
00273    PrintStr(" 0 R");
00274    PrintStr("@");
00275    PrintStr("/First");
00276    WriteInteger(kObjFirstPage+3);
00277    PrintStr(" 0 R");
00278    PrintStr("@");
00279    PrintStr("/Last");
00280    WriteInteger(4*(fNbPage-1)+kObjFirstPage+3);
00281    PrintStr(" 0 R");
00282    PrintStr("@");
00283    PrintStr(">>@");
00284 
00285    // List of all the pages
00286    NewObject(kObjPages);
00287    PrintStr("<<@");
00288    PrintStr("/Type /Pages@");
00289    PrintStr("/Count");
00290    WriteInteger(fNbPage);
00291    PrintStr("@");
00292    PrintStr("/Kids [");
00293    for (i=1; i<=fNbPage; i++) {
00294       WriteInteger(4*(i-1)+kObjFirstPage);
00295       PrintStr(" 0 R");
00296    }
00297    PrintStr(" ]");
00298    PrintStr("@");
00299    PrintStr(">>@");
00300    PrintStr("endobj@");
00301 
00302    // Cross-Reference Table
00303    Int_t refInd = fNByte;
00304    PrintStr("xref@");
00305    PrintStr("0");
00306    WriteInteger(fNbObj+1);
00307    PrintStr("@");
00308    PrintStr("0000000000 65535 f @");
00309    char str[21];
00310    for (i=0; i<fNbObj; i++) {
00311       snprintf(str,21,"%10.10d 00000 n @",fObjPos[i]);
00312       PrintStr(str);
00313    }
00314 
00315    // Trailer
00316    PrintStr("trailer@");
00317    PrintStr("<<@");
00318    PrintStr("/Size");
00319    WriteInteger(fNbObj+1);
00320    PrintStr("@");
00321    PrintStr("/Root");
00322    WriteInteger(kObjRoot);
00323    PrintStr(" 0 R");
00324    PrintStr("@");
00325    PrintStr("/Info");
00326    WriteInteger(kObjInfo);
00327    PrintStr(" 0 R@");
00328    PrintStr(">>@");
00329    PrintStr("startxref@");
00330    WriteInteger(refInd, 0);
00331    PrintStr("@");
00332    PrintStr("%%EOF@");
00333 
00334    // Close file stream
00335    if (fStream) { fStream->close(); delete fStream; fStream = 0;}
00336 
00337    gVirtualPS = 0;
00338 }
00339 
00340 
00341 //______________________________________________________________________________
00342 void TPDF::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t  y2)
00343 {
00344    // Draw a Box
00345 
00346    static Double_t x[4], y[4];
00347    Double_t ix1 = XtoPDF(x1);
00348    Double_t ix2 = XtoPDF(x2);
00349    Double_t iy1 = YtoPDF(y1);
00350    Double_t iy2 = YtoPDF(y2);
00351    Int_t fillis = fFillStyle/1000;
00352    Int_t fillsi = fFillStyle%1000;
00353 
00354    if (fillis == 3 || fillis == 2) {
00355       if (fillsi > 99) {
00356          x[0] = x1;   y[0] = y1;
00357          x[1] = x2;   y[1] = y1;
00358          x[2] = x2;   y[2] = y2;
00359          x[3] = x1;   y[3] = y2;
00360          return;
00361       }
00362       if (fillsi > 0 && fillsi < 26) {
00363          x[0] = x1;   y[0] = y1;
00364          x[1] = x2;   y[1] = y1;
00365          x[2] = x2;   y[2] = y2;
00366          x[3] = x1;   y[3] = y2;
00367          DrawPS(-4, &x[0], &y[0]);
00368       }
00369       if (fillsi == -3) {
00370          SetColor(5);
00371          WriteReal(ix1);
00372          WriteReal(iy1);
00373          WriteReal(ix2 - ix1);
00374          WriteReal(iy2 - iy1);
00375          PrintFast(6," re f*");
00376       }
00377    }
00378    if (fillis == 1) {
00379       SetColor(fFillColor);
00380       WriteReal(ix1);
00381       WriteReal(iy1);
00382       WriteReal(ix2 - ix1);
00383       WriteReal(iy2 - iy1);
00384       PrintFast(6," re f*");
00385    }
00386    if (fillis == 0) {
00387       SetColor(fLineColor);
00388       WriteReal(ix1);
00389       WriteReal(iy1);
00390       WriteReal(ix2 - ix1);
00391       WriteReal(iy2 - iy1);
00392       PrintFast(5," re S");
00393    }
00394 }
00395 
00396 
00397 //______________________________________________________________________________
00398 void TPDF::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t  yt,
00399                             Int_t mode, Int_t border, Int_t dark, Int_t light)
00400 {
00401    // Draw a Frame around a box
00402    //
00403    // mode = -1  box looks as it is behind the screen
00404    // mode =  1  box looks as it is in front of the screen
00405    // border is the border size in already precomputed PDF units
00406    // dark  is the color for the dark part of the frame
00407    // light is the color for the light part of the frame
00408 
00409    static Double_t xps[7], yps[7];
00410    Int_t i;
00411 
00412    // Draw top&left part of the box
00413    if (mode == -1) SetColor(dark);
00414    else            SetColor(light);
00415    xps[0] = XtoPDF(xl);          yps[0] = YtoPDF(yl);
00416    xps[1] = xps[0] + border;     yps[1] = yps[0] + border;
00417    xps[2] = xps[1];              yps[2] = YtoPDF(yt) - border;
00418    xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
00419    xps[4] = XtoPDF(xt);          yps[4] = YtoPDF(yt);
00420    xps[5] = xps[0];              yps[5] = yps[4];
00421    xps[6] = xps[0];              yps[6] = yps[0];
00422 
00423    MoveTo(xps[0], yps[0]);
00424    for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
00425    PrintFast(3," f*");
00426 
00427    // Draw bottom&right part of the box
00428    if (mode == -1) SetColor(light);
00429    else            SetColor(dark);
00430    xps[0] = XtoPDF(xl);          yps[0] = YtoPDF(yl);
00431    xps[1] = xps[0] + border;     yps[1] = yps[0] + border;
00432    xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
00433    xps[3] = xps[2];              yps[3] = YtoPDF(yt) - border;
00434    xps[4] = XtoPDF(xt);          yps[4] = YtoPDF(yt);
00435    xps[5] = xps[4];              yps[5] = yps[0];
00436    xps[6] = xps[0];              yps[6] = yps[0];
00437 
00438    MoveTo(xps[0], yps[0]);
00439    for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
00440    PrintFast(3," f*");
00441 }
00442 
00443 
00444 //______________________________________________________________________________
00445 void TPDF::DrawHatch(Float_t, Float_t, Int_t, Float_t *, Float_t *)
00446 {
00447    // Draw Fill area with hatch styles
00448 
00449    Warning("DrawHatch", "hatch fill style not yet implemented");
00450 }
00451 
00452 
00453 //______________________________________________________________________________
00454 void TPDF::DrawHatch(Float_t, Float_t, Int_t, Double_t *, Double_t *)
00455 {
00456    // Draw Fill area with hatch styles
00457 
00458    Warning("DrawHatch", "hatch fill style not yet implemented");
00459 }
00460 
00461 
00462 //______________________________________________________________________________
00463 void TPDF::DrawPolyLine(Int_t nn, TPoints *xy)
00464 {
00465    // Draw a PolyLine
00466    //
00467    //  Draw a polyline through  the points xy.
00468    //  If NN=1 moves only to point x,y.
00469    //  If NN=0 the x,y are  written  in the PDF file
00470    //     according to the current transformation.
00471    //  If NN>0 the line is clipped as a line.
00472    //  If NN<0 the line is clipped as a fill area.
00473 
00474    Int_t  n;
00475 
00476    Style_t linestylesav = fLineStyle;
00477    Width_t linewidthsav = fLineWidth;
00478 
00479    if (nn > 0) {
00480       n = nn;
00481       SetLineStyle(fLineStyle);
00482       SetLineWidth(fLineWidth);
00483       SetColor(Int_t(fLineColor));
00484    } else {
00485       n = -nn;
00486       SetLineStyle(1);
00487       SetLineWidth(1);
00488       SetColor(Int_t(fLineColor));
00489    }
00490 
00491    WriteReal(XtoPDF(xy[0].GetX()));
00492    WriteReal(YtoPDF(xy[0].GetY()));
00493    if( n <= 1) {
00494       if( n == 0) return;
00495       PrintFast(2," m");
00496       return;
00497    }
00498 
00499    PrintFast(2," m");
00500 
00501    for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
00502 
00503    if (nn > 0 ) {
00504       if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00505       PrintFast(2," S");
00506    } else {
00507       PrintFast(3," f*");
00508    }
00509 
00510    SetLineStyle(linestylesav);
00511    SetLineWidth(linewidthsav);
00512 }
00513 
00514 
00515 //______________________________________________________________________________
00516 void TPDF::DrawPolyLineNDC(Int_t nn, TPoints *xy)
00517 {
00518    // Draw a PolyLine in NDC space
00519    //
00520    //  Draw a polyline through  the points  xy.
00521    //  If NN=1 moves only to point x,y.
00522    //  If NN=0 the x,y are  written  in the PDF        file
00523    //     according to the current transformation.
00524    //  If NN>0 the line is clipped as a line.
00525    //  If NN<0 the line is clipped as a fill area.
00526 
00527    Int_t  n;
00528 
00529    Style_t linestylesav = fLineStyle;
00530    Width_t linewidthsav = fLineWidth;
00531 
00532    if (nn > 0) {
00533       n = nn;
00534       SetLineStyle(fLineStyle);
00535       SetLineWidth(fLineWidth);
00536       SetColor(Int_t(fLineColor));
00537    } else {
00538       n = -nn;
00539       SetLineStyle(1);
00540       SetLineWidth(1);
00541       SetColor(Int_t(fLineColor));
00542    }
00543 
00544    WriteReal(UtoPDF(xy[0].GetX()));
00545    WriteReal(VtoPDF(xy[0].GetY()));
00546    if( n <= 1) {
00547       if( n == 0) return;
00548       PrintFast(2," m");
00549       return;
00550    }
00551 
00552    PrintFast(2," m");
00553 
00554    for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
00555 
00556    if (nn > 0 ) {
00557       if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00558       PrintFast(2," S");
00559    } else {
00560       PrintFast(3," f*");
00561    }
00562 
00563    SetLineStyle(linestylesav);
00564    SetLineWidth(linewidthsav);
00565 }
00566 
00567 
00568 //______________________________________________________________________________
00569 void TPDF::DrawPolyMarker(Int_t n, Float_t *xw, Float_t *yw)
00570 {
00571    // Draw markers at the n WC points xw, yw
00572 
00573    Style_t linestylesav = fLineStyle;
00574    Width_t linewidthsav = fLineWidth;
00575    SetLineStyle(1);
00576    SetLineWidth(1);
00577    SetColor(Int_t(fMarkerColor));
00578    Int_t ms = abs(fMarkerStyle);
00579 
00580    if (ms >= 6 && ms <= 19) ms = 20;
00581    if (ms == 4) ms = 24;
00582 
00583    // Define the marker size
00584    Float_t msize  = fMarkerSize;
00585    if (fMarkerStyle == 1) {
00586      msize = 1.;
00587    } else if (fMarkerStyle == 6) {
00588      msize = 1.5;
00589    } else if (fMarkerStyle == 7) {
00590      msize = 3.;
00591    } else {
00592       const Int_t kBASEMARKER = 8;
00593       Float_t sbase = msize*kBASEMARKER;
00594       Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
00595       msize = this->UtoPDF(s2x) - this->UtoPDF(0);
00596    }
00597 
00598    Double_t m  = msize;
00599    Double_t m2 = m/2;
00600    Double_t m3 = m/3;
00601    Double_t m4 = m2*1.333333333333;
00602    Double_t m6 = m/6;
00603 
00604    // Draw the marker according to the type
00605    Double_t ix,iy;
00606    for (Int_t i=0;i<n;i++) {
00607       ix = XtoPDF(xw[i]);
00608       iy = YtoPDF(yw[i]);
00609       // Dot (.)
00610       if (ms == 1) {
00611          MoveTo(ix-1, iy);
00612          LineTo(ix  , iy);
00613       // Plus (+)
00614       } else if (ms == 2) {
00615          MoveTo(ix-m2, iy);
00616          LineTo(ix+m2, iy);
00617          MoveTo(ix   , iy-m2);
00618          LineTo(ix   , iy+m2);
00619       // X shape (X)
00620       } else if (ms == 5) {
00621          MoveTo(ix-m2, iy-m2);
00622          LineTo(ix+m2, iy+m2);
00623          MoveTo(ix-m2, iy+m2);
00624          LineTo(ix+m2, iy-m2);
00625       // Asterisk shape (*)
00626       } else if (ms == 3 || ms == 31) {
00627          MoveTo(ix-m2, iy);
00628          LineTo(ix+m2, iy);
00629          MoveTo(ix   , iy-m2);
00630          LineTo(ix   , iy+m2);
00631          MoveTo(ix-m2, iy-m2);
00632          LineTo(ix+m2, iy+m2);
00633          MoveTo(ix-m2, iy+m2);
00634          LineTo(ix+m2, iy-m2);
00635       // Circle
00636       } else if (ms == 24 || ms == 20) {
00637          MoveTo(ix-m2, iy);
00638          WriteReal(ix-m2); WriteReal(iy+m4);
00639          WriteReal(ix+m2); WriteReal(iy+m4);
00640          WriteReal(ix+m2); WriteReal(iy)   ; PrintFast(2," c");
00641          WriteReal(ix+m2); WriteReal(iy-m4);
00642          WriteReal(ix-m2); WriteReal(iy-m4);
00643          WriteReal(ix-m2); WriteReal(iy)   ; PrintFast(4," c h");
00644       // Square
00645       } else if (ms == 25 || ms == 21) {
00646          WriteReal(ix-m2); WriteReal(iy-m2);
00647          WriteReal(m)    ; WriteReal(m)    ; PrintFast(3," re");
00648       // Down triangle
00649       } else if (ms == 23 || ms == 32) {
00650          MoveTo(ix   , iy-m2);
00651          LineTo(ix+m2, iy+m2);
00652          LineTo(ix-m2, iy+m2);
00653          PrintFast(2," h");
00654       // Up triangle
00655       } else if (ms == 26 || ms == 22) {
00656          MoveTo(ix-m2, iy-m2);
00657          LineTo(ix+m2, iy-m2);
00658          LineTo(ix   , iy+m2);
00659          PrintFast(2," h");
00660       } else if (ms == 27 || ms == 33) {
00661          MoveTo(ix   , iy-m2);
00662          LineTo(ix+m3, iy);
00663          LineTo(ix   , iy+m2);
00664          LineTo(ix-m3, iy)   ;
00665          PrintFast(2," h");
00666       } else if (ms == 28 || ms == 34) {
00667          MoveTo(ix-m6, iy-m6);
00668          LineTo(ix-m6, iy-m2);
00669          LineTo(ix+m6, iy-m2);
00670          LineTo(ix+m6, iy-m6);
00671          LineTo(ix+m2, iy-m6);
00672          LineTo(ix+m2, iy+m6);
00673          LineTo(ix+m6, iy+m6);
00674          LineTo(ix+m6, iy+m2);
00675          LineTo(ix-m6, iy+m2);
00676          LineTo(ix-m6, iy+m6);
00677          LineTo(ix-m2, iy+m6);
00678          LineTo(ix-m2, iy-m6);
00679          PrintFast(2," h");
00680       } else if (ms == 29 || ms == 30) {
00681          MoveTo(ix           , iy+m2);
00682          LineTo(ix+0.112255*m, iy+0.15451*m);
00683          LineTo(ix+0.47552*m , iy+0.15451*m);
00684          LineTo(ix+0.181635*m, iy-0.05902*m);
00685          LineTo(ix+0.29389*m , iy-0.40451*m);
00686          LineTo(ix           , iy-0.19098*m);
00687          LineTo(ix-0.29389*m , iy-0.40451*m);
00688          LineTo(ix-0.181635*m, iy-0.05902*m);
00689          LineTo(ix-0.47552*m , iy+0.15451*m);
00690          LineTo(ix-0.112255*m, iy+0.15451*m);
00691          PrintFast(2," h");
00692       } else {
00693          MoveTo(ix-1, iy);
00694          LineTo(ix  , iy);
00695       }
00696    }
00697 
00698    if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
00699       PrintFast(2," f");
00700    } else {
00701       PrintFast(2," S");
00702    }
00703 
00704    SetLineStyle(linestylesav);
00705    SetLineWidth(linewidthsav);
00706 }
00707 
00708 
00709 //______________________________________________________________________________
00710 void TPDF::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
00711 {
00712    // Draw markers at the n WC points xw, yw
00713 
00714    Style_t linestylesav = fLineStyle;
00715    Width_t linewidthsav = fLineWidth;
00716    SetLineStyle(1);
00717    SetLineWidth(1);
00718    SetColor(Int_t(fMarkerColor));
00719    Int_t ms = abs(fMarkerStyle);
00720 
00721    if (ms >= 6 && ms <= 19) ms = 20;
00722    if (ms == 4) ms = 24;
00723 
00724    // Define the marker size
00725    Float_t msize  = fMarkerSize;
00726    if (fMarkerStyle == 1) {
00727      msize = 1.;
00728    } else if (fMarkerStyle == 6) {
00729      msize = 1.5;
00730    } else if (fMarkerStyle == 7) {
00731      msize = 3.;
00732    } else {
00733       const Int_t kBASEMARKER = 8;
00734       Float_t sbase = msize*kBASEMARKER;
00735       Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
00736       msize = this->UtoPDF(s2x) - this->UtoPDF(0);
00737    }
00738 
00739    Double_t m  = msize;
00740    Double_t m2 = m/2;
00741    Double_t m3 = m/3;
00742    Double_t m4 = m2*1.333333333333;
00743    Double_t m6 = m/6;
00744 
00745    // Draw the marker according to the type
00746    Double_t ix,iy;
00747    for (Int_t i=0;i<n;i++) {
00748       ix = XtoPDF(xw[i]);
00749       iy = YtoPDF(yw[i]);
00750       // Dot (.)
00751       if (ms == 1) {
00752          MoveTo(ix-1, iy);
00753          LineTo(ix  , iy);
00754       // Plus (+)
00755       } else if (ms == 2) {
00756          MoveTo(ix-m2, iy);
00757          LineTo(ix+m2, iy);
00758          MoveTo(ix   , iy-m2);
00759          LineTo(ix   , iy+m2);
00760       // X shape (X)
00761       } else if (ms == 5) {
00762          MoveTo(ix-m2, iy-m2);
00763          LineTo(ix+m2, iy+m2);
00764          MoveTo(ix-m2, iy+m2);
00765          LineTo(ix+m2, iy-m2);
00766       // Asterisk shape (*)
00767       } else if (ms == 3 || ms == 31) {
00768          MoveTo(ix-m2, iy);
00769          LineTo(ix+m2, iy);
00770          MoveTo(ix   , iy-m2);
00771          LineTo(ix   , iy+m2);
00772          MoveTo(ix-m2, iy-m2);
00773          LineTo(ix+m2, iy+m2);
00774          MoveTo(ix-m2, iy+m2);
00775          LineTo(ix+m2, iy-m2);
00776       // Circle
00777       } else if (ms == 24 || ms == 20) {
00778          MoveTo(ix-m2, iy);
00779          WriteReal(ix-m2); WriteReal(iy+m4);
00780          WriteReal(ix+m2); WriteReal(iy+m4);
00781          WriteReal(ix+m2); WriteReal(iy)   ; PrintFast(2," c");
00782          WriteReal(ix+m2); WriteReal(iy-m4);
00783          WriteReal(ix-m2); WriteReal(iy-m4);
00784          WriteReal(ix-m2); WriteReal(iy)   ; PrintFast(4," c h");
00785       // Square
00786       } else if (ms == 25 || ms == 21) {
00787          WriteReal(ix-m2); WriteReal(iy-m2);
00788          WriteReal(m)    ; WriteReal(m)    ; PrintFast(3," re");
00789       // Down triangle
00790       } else if (ms == 23 || ms == 32) {
00791          MoveTo(ix   , iy-m2);
00792          LineTo(ix+m2, iy+m2);
00793          LineTo(ix-m2, iy+m2);
00794          PrintFast(2," h");
00795       // Up triangle
00796       } else if (ms == 26 || ms == 22) {
00797          MoveTo(ix-m2, iy-m2);
00798          LineTo(ix+m2, iy-m2);
00799          LineTo(ix   , iy+m2);
00800          PrintFast(2," h");
00801       } else if (ms == 27 || ms == 33) {
00802          MoveTo(ix   , iy-m2);
00803          LineTo(ix+m3, iy);
00804          LineTo(ix   , iy+m2);
00805          LineTo(ix-m3, iy)   ;
00806          PrintFast(2," h");
00807       } else if (ms == 28 || ms == 34) {
00808          MoveTo(ix-m6, iy-m6);
00809          LineTo(ix-m6, iy-m2);
00810          LineTo(ix+m6, iy-m2);
00811          LineTo(ix+m6, iy-m6);
00812          LineTo(ix+m2, iy-m6);
00813          LineTo(ix+m2, iy+m6);
00814          LineTo(ix+m6, iy+m6);
00815          LineTo(ix+m6, iy+m2);
00816          LineTo(ix-m6, iy+m2);
00817          LineTo(ix-m6, iy+m6);
00818          LineTo(ix-m2, iy+m6);
00819          LineTo(ix-m2, iy-m6);
00820          PrintFast(2," h");
00821       } else if (ms == 29 || ms == 30) {
00822          MoveTo(ix           , iy+m2);
00823          LineTo(ix+0.112255*m, iy+0.15451*m);
00824          LineTo(ix+0.47552*m , iy+0.15451*m);
00825          LineTo(ix+0.181635*m, iy-0.05902*m);
00826          LineTo(ix+0.29389*m , iy-0.40451*m);
00827          LineTo(ix           , iy-0.19098*m);
00828          LineTo(ix-0.29389*m , iy-0.40451*m);
00829          LineTo(ix-0.181635*m, iy-0.05902*m);
00830          LineTo(ix-0.47552*m , iy+0.15451*m);
00831          LineTo(ix-0.112255*m, iy+0.15451*m);
00832          PrintFast(2," h");
00833       } else {
00834          MoveTo(ix-1, iy);
00835          LineTo(ix  , iy);
00836       }
00837    }
00838 
00839    if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
00840       PrintFast(2," f");
00841    } else {
00842       PrintFast(2," S");
00843    }
00844 
00845    SetLineStyle(linestylesav);
00846    SetLineWidth(linewidthsav);
00847 }
00848 
00849 
00850 //______________________________________________________________________________
00851 void TPDF::DrawPS(Int_t nn, Float_t *xw, Float_t *yw)
00852 {
00853    // Draw a PolyLine
00854    //
00855    //  Draw a polyline through the points xw,yw.
00856    //  If nn=1 moves only to point xw,yw.
00857    //  If nn=0 the XW(1) and YW(1) are  written  in the PDF file
00858    //          according to the current NT.
00859    //  If nn>0 the line is clipped as a line.
00860    //  If nn<0 the line is clipped as a fill area.
00861 
00862    static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
00863                                  .01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,
00864                                  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
00865    static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
00866                                     180, 90,135, 45,150, 30,120, 60,
00867                                     180, 90,135, 45,150, 30,120, 60};
00868    Int_t  n = 0, fais = 0 , fasi = 0;
00869 
00870    Style_t linestylesav = fLineStyle;
00871    Width_t linewidthsav = fLineWidth;
00872 
00873    if (nn > 0) {
00874       n = nn;
00875       SetLineStyle(fLineStyle);
00876       SetLineWidth(fLineWidth);
00877       SetColor(Int_t(fLineColor));
00878    }
00879    if (nn < 0) {
00880       n = -nn;
00881       SetLineStyle(1);
00882       SetLineWidth(1);
00883       SetColor(Int_t(fFillColor));
00884       fais = fFillStyle/1000;
00885       fasi = fFillStyle%1000;
00886       if (fais == 3 || fais == 2) {
00887          if (fasi > 100 && fasi <125) {
00888             DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
00889             SetLineStyle(linestylesav);
00890             SetLineWidth(linewidthsav);
00891             return;
00892          }
00893          if (fasi > 0 && fasi < 26) {
00894             SetFillPatterns(fasi, Int_t(fFillColor));
00895          }
00896       }
00897    }
00898 
00899    WriteReal(XtoPDF(xw[0]));
00900    WriteReal(YtoPDF(yw[0]));
00901    if( n <= 1) {
00902       if( n == 0) return;
00903       PrintFast(2," m");
00904       return;
00905    }
00906 
00907    PrintFast(2," m");
00908 
00909    for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
00910 
00911    if (nn > 0 ) {
00912       if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
00913       PrintFast(2," S");
00914    } else {
00915       if (fais == 0) {PrintFast(2," s"); return;}
00916       if (fais == 3 || fais == 2) {
00917          if (fasi > 0 && fasi < 26) {
00918             PrintFast(3," f*");
00919             fRed   = -1;
00920             fGreen = -1;
00921             fBlue  = -1;
00922          }
00923          SetLineStyle(linestylesav);
00924          SetLineWidth(linewidthsav);
00925          return;
00926       }
00927       PrintFast(3," f*");
00928    }
00929 
00930    SetLineStyle(linestylesav);
00931    SetLineWidth(linewidthsav);
00932 }
00933 
00934 
00935 //______________________________________________________________________________
00936 void TPDF::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
00937 {
00938    // Draw a PolyLine
00939    //
00940    // Draw a polyline through  the points xw,yw.
00941    // If nn=1 moves only to point xw,yw.
00942    // If nn=0 the xw(1) and YW(1) are  written  in the PDF file
00943    //         according to the current NT.
00944    // If nn>0 the line is clipped as a line.
00945    // If nn<0 the line is clipped as a fill area.
00946 
00947    static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
00948                                  .01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,
00949                                  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
00950    static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
00951                                     180, 90,135, 45,150, 30,120, 60,
00952                                     180, 90,135, 45,150, 30,120, 60};
00953    Int_t  n = 0, fais = 0, fasi = 0;
00954 
00955    Style_t linestylesav = fLineStyle;
00956    Width_t linewidthsav = fLineWidth;
00957 
00958    if (nn > 0) {
00959       n = nn;
00960       SetLineStyle(fLineStyle);
00961       SetLineWidth(fLineWidth);
00962       SetColor(Int_t(fLineColor));
00963    }
00964    if (nn < 0) {
00965       n = -nn;
00966       SetLineStyle(1);
00967       SetLineWidth(1);
00968       SetColor(Int_t(fFillColor));
00969       fais = fFillStyle/1000;
00970       fasi = fFillStyle%1000;
00971       if (fais == 3 || fais == 2) {
00972          if (fasi > 100 && fasi <125) {
00973             DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
00974             SetLineStyle(linestylesav);
00975             SetLineWidth(linewidthsav);
00976             return;
00977          }
00978          if (fasi > 0 && fasi < 26) {
00979             SetFillPatterns(fasi, Int_t(fFillColor));
00980          }
00981       }
00982    }
00983 
00984    WriteReal(XtoPDF(xw[0]));
00985    WriteReal(YtoPDF(yw[0]));
00986    if( n <= 1) {
00987       if( n == 0) return;
00988       PrintFast(2," m");
00989       return;
00990    }
00991 
00992    PrintFast(2," m");
00993 
00994    for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
00995 
00996    if (nn > 0 ) {
00997       if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
00998       PrintFast(2," S");
00999    } else {
01000       if (fais == 0) {PrintFast(2," s"); return;}
01001       if (fais == 3 || fais == 2) {
01002          if (fasi > 0 && fasi < 26) {
01003             PrintFast(3," f*");
01004             fRed   = -1;
01005             fGreen = -1;
01006             fBlue  = -1;
01007          }
01008          SetLineStyle(linestylesav);
01009          SetLineWidth(linewidthsav);
01010          return;
01011       }
01012       PrintFast(3," f*");
01013    }
01014 
01015    SetLineStyle(linestylesav);
01016    SetLineWidth(linewidthsav);
01017 }
01018 
01019 
01020 //______________________________________________________________________________
01021 void TPDF::FontEncode()
01022 {
01023    // Font encoding
01024 
01025    static const char *sdtfonts[] = {
01026    "/Times-Italic"         , "/Times-Bold"         , "/Times-BoldItalic",
01027    "/Helvetica"            , "/Helvetica-Oblique"  , "/Helvetica-Bold"  ,
01028    "/Helvetica-BoldOblique", "/Courier"            , "/Courier-Oblique" ,
01029    "/Courier-Bold"         , "/Courier-BoldOblique", "/Symbol"          ,
01030    "/Times-Roman"          , "/ZapfDingbats"       , "/Symbol"};
01031 
01032    for (Int_t i=0; i<kNumberOfFonts; i++) {
01033       NewObject(kObjFont+i);
01034       PrintStr("<<@");
01035       PrintStr("/Type /Font@");
01036       PrintStr("/Subtype /Type1@");
01037       PrintStr("/Name /F");
01038       WriteInteger(i+1,0);
01039       PrintStr("@");
01040       PrintStr("/BaseFont ");
01041       PrintStr(sdtfonts[i]);
01042       PrintStr("@");
01043       if (i!=11 && i!=13 && i!=14) {
01044          PrintStr("/Encoding /WinAnsiEncoding");
01045          PrintStr("@");
01046       }
01047       PrintStr(">>@");
01048       PrintStr("endobj@");
01049    }
01050 }
01051 
01052 
01053 //______________________________________________________________________________
01054 void TPDF::LineTo(Double_t x, Double_t y)
01055 {
01056    // Draw a line to a new position
01057 
01058    WriteReal(x);
01059    WriteReal(y);
01060    PrintFast(2," l");
01061 }
01062 
01063 
01064 //______________________________________________________________________________
01065 void TPDF::MoveTo(Double_t x, Double_t y)
01066 {
01067    // Move to a new position
01068 
01069    WriteReal(x);
01070    WriteReal(y);
01071    PrintFast(2," m");
01072 }
01073 
01074 
01075 //______________________________________________________________________________
01076 void TPDF::NewObject(Int_t n)
01077 {
01078    // Create a new object in the PDF file
01079 
01080    if (!fObjPos || n >= fObjPosSize) {
01081       Int_t newN = TMath::Max(2*fObjPosSize,n+1);
01082       Int_t *saveo = new Int_t [newN];
01083       if (fObjPos && fObjPosSize) {
01084          memcpy(saveo,fObjPos,fObjPosSize*sizeof(Int_t));
01085          memset(&saveo[fObjPosSize],0,(newN-fObjPosSize)*sizeof(Int_t));
01086          delete [] fObjPos;
01087       }
01088       fObjPos     = saveo;
01089       fObjPosSize = newN;
01090    }
01091    fObjPos[n-1] = fNByte;
01092    fNbObj       = TMath::Max(fNbObj,n);
01093    WriteInteger(n, 0);
01094    PrintStr(" 0 obj");
01095    PrintStr("@");
01096 }
01097 
01098 
01099 //______________________________________________________________________________
01100 void TPDF::NewPage()
01101 {
01102    // Start a new PDF page.
01103 
01104    if(!fPageNotEmpty)return;
01105 
01106    // Compute pad conversion coefficients
01107    if (gPad) {
01108       Double_t ww   = gPad->GetWw();
01109       Double_t wh   = gPad->GetWh();
01110       fYsize        = fXsize*wh/ww;
01111    } else {
01112       fYsize = 27;
01113    }
01114 
01115    fNbPage++;
01116 
01117    if (fNbPage>1) {
01118       // Close the currently opened page
01119       WriteCompressedBuffer();
01120       PrintStr("endstream@");
01121       Int_t streamLength = fNByte-fStartStream-10;
01122       PrintStr("endobj@");
01123       NewObject(4*(fNbPage-2)+kObjFirstPage+2);
01124       WriteInteger(streamLength, 0);
01125       PrintStr("@");
01126       PrintStr("endobj@");
01127       NewObject(4*(fNbPage-2)+kObjFirstPage+3);
01128       PrintStr("<<@");
01129       if (!strstr(GetTitle(),"PDF")) {
01130          PrintStr("/Title (");
01131          PrintStr(GetTitle());
01132          PrintStr(")@");
01133       } else {
01134          PrintStr("/Title (Page");
01135          WriteInteger(fNbPage-1);
01136          PrintStr(")@");
01137       }
01138       PrintStr("/Dest [");
01139       WriteInteger(4*(fNbPage-2)+kObjFirstPage);
01140       PrintStr(" 0 R /XYZ null null 0]@");
01141       PrintStr("/Parent");
01142       WriteInteger(kObjContents);
01143       PrintStr(" 0 R");
01144       PrintStr("@");
01145       PrintStr("/Next");
01146       WriteInteger(4*(fNbPage-1)+kObjFirstPage+3);
01147       PrintStr(" 0 R");
01148       PrintStr("@");
01149       if (fNbPage>2) {
01150          PrintStr("/Prev");
01151          WriteInteger(4*(fNbPage-3)+kObjFirstPage+3);
01152          PrintStr(" 0 R");
01153          PrintStr("@");
01154       }
01155       PrintStr(">>@");
01156    }
01157 
01158    // Start a new page
01159    NewObject(4*(fNbPage-1)+kObjFirstPage);
01160    PrintStr("<<@");
01161    PrintStr("/Type /Page@");
01162    PrintStr("@");
01163    PrintStr("/Parent");
01164    WriteInteger(kObjPages);
01165    PrintStr(" 0 R");
01166    PrintStr("@");
01167 
01168    Double_t xlow=0, ylow=0, xup=1, yup=1;
01169    if (gPad) {
01170       xlow = gPad->GetAbsXlowNDC();
01171       xup  = xlow + gPad->GetAbsWNDC();
01172       ylow = gPad->GetAbsYlowNDC();
01173       yup  = ylow + gPad->GetAbsHNDC();
01174    }
01175 
01176    PrintStr("/MediaBox [");
01177    Double_t width, height;
01178    switch (fPageFormat) {
01179       case 100 :
01180          width  = 8.5*2.54;
01181          height = 11.*2.54;
01182          break;
01183       case 200 :
01184          width  = 8.5*2.54;
01185          height = 14.*2.54;
01186          break;
01187       case 300 :
01188          width  = 11.*2.54;
01189          height = 17.*2.54;
01190          break;
01191       default  :
01192          width  = 21.0*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
01193          height = 29.7*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
01194    };
01195    WriteReal(CMtoPDF(fXsize*xlow));
01196    WriteReal(CMtoPDF(fYsize*ylow));
01197    WriteReal(CMtoPDF(width));
01198    WriteReal(CMtoPDF(height));
01199    PrintStr("]");
01200    PrintStr("@");
01201 
01202    Double_t xmargin = CMtoPDF(0.7);
01203    Double_t ymargin = 0;
01204    if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
01205    if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
01206 
01207    PrintStr("/CropBox [");
01208    if (fPageOrientation == 1) {
01209       WriteReal(xmargin);
01210       WriteReal(ymargin);
01211       WriteReal(xmargin+CMtoPDF(fXsize*xup));
01212       WriteReal(ymargin+CMtoPDF(fYsize*yup));
01213    }
01214    if (fPageOrientation == 2) {
01215       WriteReal(xmargin);
01216       WriteReal(CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin);
01217       WriteReal(xmargin+CMtoPDF(fYsize*yup));
01218       WriteReal(CMtoPDF(height)-xmargin);
01219    }
01220    PrintStr("]");
01221    PrintStr("@");
01222 
01223    if (fPageOrientation == 1) PrintStr("/Rotate 0@");
01224    if (fPageOrientation == 2) PrintStr("/Rotate 90@");
01225 
01226    PrintStr("/Resources");
01227    WriteInteger(kObjPageResources);
01228    PrintStr(" 0 R");
01229    PrintStr("@");
01230 
01231    PrintStr("/Contents");
01232    WriteInteger(4*(fNbPage-1)+kObjFirstPage+1);
01233    PrintStr(" 0 R@");
01234    PrintStr(">>@");
01235    PrintStr("endobj@");
01236 
01237    NewObject(4*(fNbPage-1)+kObjFirstPage+1);
01238    PrintStr("<<@");
01239    PrintStr("/Length");
01240    WriteInteger(4*(fNbPage-1)+kObjFirstPage+2);
01241    PrintStr(" 0 R@");
01242    PrintStr("/Filter [/FlateDecode]@");
01243    PrintStr(">>@");
01244    PrintStr("stream@");
01245    fStartStream = fNByte;
01246    fCompress = kTRUE;
01247 
01248    // Force the line width definition next time TPDF::SetLineWidth will be called.
01249    fLineWidth = -1;
01250 
01251    PrintStr("1 0 0 1");
01252    if (fPageOrientation == 2) {
01253       ymargin = CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin;
01254       xmargin = xmargin+CMtoPDF(fYsize*yup);
01255    }
01256    WriteReal(xmargin);
01257    WriteReal(ymargin);
01258    PrintStr(" cm");
01259    if (fPageOrientation == 2) PrintStr(" 0 1 -1 0 0 0 cm");
01260 }
01261 
01262 
01263 //______________________________________________________________________________
01264 void TPDF::Off()
01265 {
01266    // Deactivate an already open PDF file
01267 
01268    gVirtualPS = 0;
01269 }
01270 
01271 
01272 //______________________________________________________________________________
01273 void TPDF::On()
01274 {
01275    // Activate an already open PDF file
01276 
01277    // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
01278    // has no "workstation type".
01279 
01280    if (!fType) {
01281       Error("On", "no PDF file open");
01282       Off();
01283       return;
01284    }
01285    gVirtualPS = this;
01286 }
01287 
01288 
01289 //______________________________________________________________________________
01290 void TPDF::Open(const char *fname, Int_t wtype)
01291 {
01292    // Open a PDF file
01293 
01294    Int_t i;
01295 
01296    if (fStream) {
01297       Warning("Open", "PDF file already open");
01298       return;
01299    }
01300 
01301    fLenBuffer = 0;
01302    fRed       = -1;
01303    fGreen     = -1;
01304    fBlue      = -1;
01305    fType      = abs(wtype);
01306    SetLineScale(gStyle->GetLineScalePS()/4.);
01307    gStyle->GetPaperSize(fXsize, fYsize);
01308    Float_t xrange, yrange;
01309    if (gPad) {
01310       Double_t ww = gPad->GetWw();
01311       Double_t wh = gPad->GetWh();
01312       if (fType == 113) {
01313          ww *= gPad->GetWNDC();
01314          wh *= gPad->GetHNDC();
01315       }
01316       Double_t ratio = wh/ww;
01317       xrange = fXsize;
01318       yrange = fXsize*ratio;
01319       if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
01320       fXsize = xrange; fYsize = yrange;
01321    }
01322 
01323    // Open OS file
01324    fStream = new ofstream();
01325 #ifdef R__WIN32
01326       fStream->open(fname, ofstream::out | ofstream::binary);
01327 #else
01328       fStream->open(fname, ofstream::out);
01329 #endif
01330    if (fStream == 0) {
01331       printf("ERROR in TPDF::Open: Cannot open file:%s\n",fname);
01332       return;
01333    }
01334 
01335    gVirtualPS = this;
01336 
01337    for (i=0; i<fSizBuffer; i++) fBuffer[i] = ' ';
01338 
01339    // The page orientation is last digit of PDF workstation type
01340    //  orientation = 1 for portrait
01341    //  orientation = 2 for landscape
01342    fPageOrientation = fType%10;
01343    if( fPageOrientation < 1 || fPageOrientation > 2) {
01344       Error("Open", "Invalid page orientation %d", fPageOrientation);
01345       return;
01346    }
01347 
01348    // format = 0-99 is the European page format (A4,A3 ...)
01349    // format = 100 is the US format  8.5x11.0 inch
01350    // format = 200 is the US format  8.5x14.0 inch
01351    // format = 300 is the US format 11.0x17.0 inch
01352    fPageFormat = fType/1000;
01353    if( fPageFormat == 0 )  fPageFormat = 4;
01354    if( fPageFormat == 99 ) fPageFormat = 0;
01355 
01356    fRange = kFALSE;
01357 
01358    // Set a default range
01359    Range(fXsize, fYsize);
01360 
01361    fObjPos = 0;
01362    fObjPosSize = 0;
01363    fNbObj = 0;
01364    fNbPage = 0;
01365 
01366    PrintStr("%PDF-1.4@");
01367    PrintStr("%\342\343\317\323");
01368    PrintStr("@");
01369 
01370    NewObject(kObjRoot);
01371    PrintStr("<<@");
01372    PrintStr("/Type /Catalog@");
01373    PrintStr("/Pages");
01374    WriteInteger(kObjPages);
01375    PrintStr(" 0 R@");
01376    PrintStr("/Outlines");
01377    WriteInteger(kObjOutlines);
01378    PrintStr(" 0 R@");
01379    PrintStr("/PageMode /UseOutlines@");
01380    PrintStr(">>@");
01381    PrintStr("endobj@");
01382 
01383    NewObject(kObjInfo);
01384    PrintStr("<<@");
01385    PrintStr("/Creator (ROOT Version ");
01386    PrintStr(gROOT->GetVersion());
01387    PrintStr(")");
01388    PrintStr("@");
01389    PrintStr("/CreationDate (");
01390    TDatime t;
01391    char str[17];
01392    snprintf(str,17,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d",
01393                 t.GetYear()  , t.GetMonth(),
01394                 t.GetDay()   , t.GetHour(),
01395                 t.GetMinute(), t.GetSecond());
01396    PrintStr(str);
01397    PrintStr(")");
01398    PrintStr("@");
01399    PrintStr("/Title (");
01400    if (strlen(GetName())<=80) PrintStr(GetName());
01401    PrintStr(")");
01402    PrintStr("@");
01403    PrintStr("/Keywords (ROOT)@");
01404    PrintStr(">>@");
01405    PrintStr("endobj@");
01406 
01407    NewObject(kObjPageResources);
01408    PrintStr("<<@");
01409    PrintStr("/ProcSet [/PDF /Text]@");
01410 
01411    PrintStr("/Font@");
01412    PrintStr("<<@");
01413    for (i=0; i<kNumberOfFonts; i++) {
01414       PrintStr(" /F");
01415       WriteInteger(i+1,0);
01416       WriteInteger(kObjFont+i);
01417       PrintStr(" 0 R");
01418    }
01419    PrintStr("@");
01420    PrintStr(">>@");
01421 
01422    PrintStr("/ColorSpace << /Cs8");
01423    WriteInteger(kObjColorSpace);
01424    PrintStr(" 0 R >>");
01425    PrintStr("@");
01426    PrintStr("/Pattern");
01427    WriteInteger(kObjPatternList);
01428    PrintStr(" 0 R");
01429    PrintStr("@");
01430    PrintStr(">>@");
01431    PrintStr("endobj@");
01432 
01433    FontEncode();
01434    PatternEncode();
01435 
01436    NewPage();
01437    fPageNotEmpty = kFALSE;
01438 }
01439 
01440 //______________________________________________________________________________
01441 void TPDF::PatternEncode()
01442 {
01443    // Patterns encoding
01444 
01445    Int_t patternNb = kObjPattern;
01446 
01447    NewObject(kObjColorSpace);
01448    if (gStyle->GetColorModelPS()) {
01449       PrintStr("[/Pattern /DeviceCMYK]@");
01450    } else {
01451       PrintStr("[/Pattern /DeviceRGB]@");
01452    }
01453    PrintStr("endobj@");
01454    NewObject(kObjPatternResourses);
01455    PrintStr("<</ProcSet[/PDF]>>@");
01456    PrintStr("endobj@");
01457 
01458    NewObject(kObjPatternList);
01459    PrintStr("<<@");
01460    PrintStr(" /P01");
01461    WriteInteger(patternNb++);
01462    PrintStr(" 0 R");
01463    PrintStr(" /P02");
01464    WriteInteger(patternNb++);
01465    PrintStr(" 0 R");
01466    PrintStr(" /P03");
01467    WriteInteger(patternNb++);
01468    PrintStr(" 0 R");
01469    PrintStr(" /P04");
01470    WriteInteger(patternNb++);
01471    PrintStr(" 0 R");
01472    PrintStr(" /P05");
01473    WriteInteger(patternNb++);
01474    PrintStr(" 0 R");
01475    PrintStr(" /P06");
01476    WriteInteger(patternNb++);
01477    PrintStr(" 0 R");
01478    PrintStr(" /P07");
01479    WriteInteger(patternNb++);
01480    PrintStr(" 0 R");
01481    PrintStr(" /P08");
01482    WriteInteger(patternNb++);
01483    PrintStr(" 0 R");
01484    PrintStr(" /P09");
01485    WriteInteger(patternNb++);
01486    PrintStr(" 0 R");
01487    PrintStr(" /P10");
01488    WriteInteger(patternNb++);
01489    PrintStr(" 0 R");
01490    PrintStr(" /P11");
01491    WriteInteger(patternNb++);
01492    PrintStr(" 0 R");
01493    PrintStr(" /P12");
01494    WriteInteger(patternNb++);
01495    PrintStr(" 0 R");
01496    PrintStr(" /P13");
01497    WriteInteger(patternNb++);
01498    PrintStr(" 0 R");
01499    PrintStr(" /P14");
01500    WriteInteger(patternNb++);
01501    PrintStr(" 0 R");
01502    PrintStr(" /P15");
01503    WriteInteger(patternNb++);
01504    PrintStr(" 0 R");
01505    PrintStr(" /P16");
01506    WriteInteger(patternNb++);
01507    PrintStr(" 0 R");
01508    PrintStr(" /P17");
01509    WriteInteger(patternNb++);
01510    PrintStr(" 0 R");
01511    PrintStr(" /P18");
01512    WriteInteger(patternNb++);
01513    PrintStr(" 0 R");
01514    PrintStr(" /P19");
01515    WriteInteger(patternNb++);
01516    PrintStr(" 0 R");
01517    PrintStr(" /P20");
01518    WriteInteger(patternNb++);
01519    PrintStr(" 0 R");
01520    PrintStr(" /P21");
01521    WriteInteger(patternNb++);
01522    PrintStr(" 0 R");
01523    PrintStr(" /P22");
01524    WriteInteger(patternNb++);
01525    PrintStr(" 0 R");
01526    PrintStr(" /P23");
01527    WriteInteger(patternNb++);
01528    PrintStr(" 0 R");
01529    PrintStr(" /P24");
01530    WriteInteger(patternNb++);
01531    PrintStr(" 0 R");
01532    PrintStr(" /P25");
01533    WriteInteger(patternNb++);
01534    PrintStr(" 0 R@");
01535    PrintStr(">>@");
01536    PrintStr("endobj@");
01537 
01538    patternNb = kObjPattern;
01539 
01540    // P01
01541    NewObject(patternNb++);
01542    PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
01543    WriteInteger(kObjPatternResourses);
01544    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
01545    PrintStr("@");
01546    fStream->write("stream",6); fNByte += 6;
01547    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);
01548    fNByte += 93;
01549    PrintStr("endstream@");
01550    PrintStr("endobj@");
01551 
01552    // P02
01553    NewObject(patternNb++);
01554    PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
01555    WriteInteger(kObjPatternResourses);
01556    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
01557    PrintStr("@");
01558    fStream->write("stream",6); fNByte += 6;
01559    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);
01560    fNByte += 94;
01561    PrintStr("endstream@");
01562    PrintStr("endobj@");
01563 
01564    // P03
01565    NewObject(patternNb++);
01566    PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
01567    WriteInteger(kObjPatternResourses);
01568    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
01569    PrintStr("@");
01570    fStream->write("stream",6); fNByte += 6;
01571    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);
01572    fNByte += 95;
01573    PrintStr("endstream@");
01574    PrintStr("endobj@");
01575 
01576    // P04
01577    NewObject(patternNb++);
01578    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01579    WriteInteger(kObjPatternResourses);
01580    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 63/Filter/FlateDecode>>");
01581    PrintStr("@");
01582    fStream->write("stream",6); fNByte += 6;
01583    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);
01584    fNByte += 65;
01585    PrintStr("endstream@");
01586    PrintStr("endobj@");
01587 
01588    // P05
01589    NewObject(patternNb++);
01590    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01591    WriteInteger(kObjPatternResourses);
01592    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
01593    PrintStr("@");
01594    fStream->write("stream",6); fNByte += 6;
01595    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);
01596    fNByte += 68;
01597    PrintStr("endstream@");
01598    PrintStr("endobj@");
01599 
01600    // P06
01601    NewObject(patternNb++);
01602    PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
01603    WriteInteger(kObjPatternResourses);
01604    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
01605    PrintStr("@");
01606    fStream->write("stream",6); fNByte += 6;
01607    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);
01608    fNByte += 68;
01609    PrintStr("endstream@");
01610    PrintStr("endobj@");
01611 
01612    // P07
01613    NewObject(patternNb++);
01614    PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
01615    WriteInteger(kObjPatternResourses);
01616    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
01617    PrintStr("@");
01618    fStream->write("stream",6); fNByte += 6;
01619    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);
01620    fNByte += 70;
01621    PrintStr("endstream@");
01622    PrintStr("endobj@");
01623 
01624    // P08
01625    NewObject(patternNb++);
01626    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01627    WriteInteger(kObjPatternResourses);
01628    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
01629    PrintStr("@");
01630    fStream->write("stream",6); fNByte += 6;
01631    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);
01632    fNByte += 141;
01633    PrintStr("endstream@");
01634    PrintStr("endobj@");
01635 
01636    // P09
01637    NewObject(patternNb++);
01638    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01639    WriteInteger(kObjPatternResourses);
01640    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
01641    PrintStr("@");
01642    fStream->write("stream",6); fNByte += 6;
01643    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);
01644    fNByte += 110;
01645    PrintStr("endstream@");
01646    PrintStr("endobj@");
01647 
01648    // P10
01649    NewObject(patternNb++);
01650    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01651    WriteInteger(kObjPatternResourses);
01652    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 93/Filter/FlateDecode>>");
01653    PrintStr("@");
01654    fStream->write("stream",6); fNByte += 6;
01655    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);
01656    fNByte += 95;
01657    PrintStr("endstream@");
01658    PrintStr("endobj@");
01659 
01660    // P11
01661    NewObject(patternNb++);
01662    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01663    WriteInteger(kObjPatternResourses);
01664    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 164/Filter/FlateDecode>>");
01665    PrintStr("@");
01666    fStream->write("stream",6); fNByte += 6;
01667    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);
01668    fNByte += 166;
01669    PrintStr("endstream@");
01670    PrintStr("endobj@");
01671 
01672    // P12
01673    NewObject(patternNb++);
01674    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01675    WriteInteger(kObjPatternResourses);
01676    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
01677    PrintStr("@");
01678    fStream->write("stream",6); fNByte += 6;
01679    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);
01680    fNByte += 228;
01681    PrintStr("endstream@");
01682    PrintStr("endobj@");
01683 
01684    // P13
01685    NewObject(patternNb++);
01686    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01687    WriteInteger(kObjPatternResourses);
01688    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
01689    PrintStr("@");
01690    fStream->write("stream",6); fNByte += 6;
01691    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);
01692    fNByte += 71;
01693    PrintStr("endstream@");
01694    PrintStr("endobj@");
01695 
01696    // P14
01697    NewObject(patternNb++);
01698    PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
01699    WriteInteger(kObjPatternResourses);
01700    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
01701    PrintStr("@");
01702    fStream->write("stream",6); fNByte += 6;
01703    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);
01704    fNByte += 116;
01705    PrintStr("endstream@");
01706    PrintStr("endobj@");
01707 
01708    // P15
01709    NewObject(patternNb++);
01710    PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
01711    WriteInteger(kObjPatternResourses);
01712    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
01713    PrintStr("@");
01714    fStream->write("stream",6); fNByte += 6;
01715    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);
01716    fNByte += 220;
01717    PrintStr("endstream@");
01718    PrintStr("endobj@");
01719 
01720    // P16
01721    NewObject(patternNb++);
01722    PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
01723    WriteInteger(kObjPatternResourses);
01724    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
01725    PrintStr("@");
01726    fStream->write("stream",6); fNByte += 6;
01727    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);
01728    fNByte += 125;
01729    PrintStr("endstream@");
01730    PrintStr("endobj@");
01731 
01732    // P17
01733    NewObject(patternNb++);
01734    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01735    WriteInteger(kObjPatternResourses);
01736    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
01737    PrintStr("@");
01738    fStream->write("stream",6); fNByte += 6;
01739    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);
01740    fNByte += 68;
01741    PrintStr("endstream@");
01742    PrintStr("endobj@");
01743 
01744    // P18
01745    NewObject(patternNb++);
01746    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01747    WriteInteger(kObjPatternResourses);
01748    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
01749    PrintStr("@");
01750    fStream->write("stream",6); fNByte += 6;
01751    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);
01752    fNByte += 71;
01753    PrintStr("endstream@");
01754    PrintStr("endobj@");
01755 
01756    // P19
01757    NewObject(patternNb++);
01758    PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
01759    WriteInteger(kObjPatternResourses);
01760    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
01761    PrintStr("@");
01762    fStream->write("stream",6); fNByte += 6;
01763    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);
01764    fNByte += 151;
01765    PrintStr("endstream@");
01766    PrintStr("endobj@");
01767 
01768    // P20
01769    NewObject(patternNb++);
01770    PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
01771    WriteInteger(kObjPatternResourses);
01772    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
01773    PrintStr("@");
01774    fStream->write("stream",6); fNByte += 6;
01775    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);
01776    fNByte += 124;
01777    PrintStr("endstream@");
01778    PrintStr("endobj@");
01779 
01780    // P21
01781    NewObject(patternNb++);
01782    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01783    WriteInteger(kObjPatternResourses);
01784    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
01785    PrintStr("@");
01786    fStream->write("stream",6); fNByte += 6;
01787    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);
01788    fNByte += 119;
01789    PrintStr("endstream@");
01790    PrintStr("endobj@");
01791 
01792    // P22
01793    NewObject(patternNb++);
01794    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01795    WriteInteger(kObjPatternResourses);
01796    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
01797    PrintStr("@");
01798    fStream->write("stream",6); fNByte += 6;
01799    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);
01800    fNByte += 120;
01801    PrintStr("endstream@");
01802    PrintStr("endobj@");
01803 
01804    // P23
01805    NewObject(patternNb++);
01806    PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
01807    WriteInteger(kObjPatternResourses);
01808    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
01809    PrintStr("@");
01810    fStream->write("stream",6); fNByte += 6;
01811    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);
01812    fNByte += 171;
01813    PrintStr("endstream@");
01814    PrintStr("endobj@");
01815 
01816    // P24
01817    NewObject(patternNb++);
01818    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01819    WriteInteger(kObjPatternResourses);
01820    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
01821    PrintStr("@");
01822    fStream->write("stream",6); fNByte += 6;
01823    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);
01824    fNByte += 282;
01825    PrintStr("endstream@");
01826    PrintStr("endobj@");
01827 
01828    // P25
01829    NewObject(patternNb++);
01830    PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
01831    WriteInteger(kObjPatternResourses);
01832    PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
01833    PrintStr("@");
01834    fStream->write("stream",6); fNByte += 6;
01835    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);
01836    fNByte += 56;
01837    PrintStr("endstream@");
01838    PrintStr("endobj@");
01839 }
01840 
01841 //______________________________________________________________________________
01842 void TPDF::PrintStr(const char *str)
01843 {
01844    // Output the string str in the output buffer
01845 
01846    Int_t len = strlen(str);
01847    if (len == 0) return;
01848    fPageNotEmpty = kTRUE;
01849 
01850    if (fCompress) {
01851       if (fLenBuffer+len >= fSizBuffer) {
01852          fBuffer  = TStorage::ReAllocChar(fBuffer, 2*fSizBuffer, fSizBuffer);
01853          fSizBuffer = 2*fSizBuffer;
01854       }
01855       strcpy(fBuffer + fLenBuffer, str);
01856       fLenBuffer += len;
01857       return;
01858    }
01859 
01860    TVirtualPS::PrintStr(str);
01861 }
01862 
01863 
01864 //______________________________________________________________________________
01865 void TPDF::PrintFast(Int_t len, const char *str)
01866 {
01867    // Fast version of Print
01868 
01869    fPageNotEmpty = kTRUE;
01870    if (fCompress) {
01871       if (fLenBuffer+len >= fSizBuffer) {
01872          fBuffer  = TStorage::ReAllocChar(fBuffer, 2*fSizBuffer, fSizBuffer);
01873          fSizBuffer = 2*fSizBuffer;
01874       }
01875       strcpy(fBuffer + fLenBuffer, str);
01876       fLenBuffer += len;
01877       return;
01878    }
01879 
01880    TVirtualPS::PrintFast(len, str);
01881 }
01882 
01883 
01884 //______________________________________________________________________________
01885 void TPDF::Range(Float_t xsize, Float_t ysize)
01886 {
01887    // Set the range for the paper in centimetres
01888 
01889    Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
01890 
01891    fXsize = xsize;
01892    fYsize = ysize;
01893 
01894    xps = xsize;
01895    yps = ysize;
01896 
01897    if( xsize <= xps && ysize < yps) {
01898       if ( xps > yps ) xymax = xps;
01899       else             xymax = yps;
01900       xncm  = xsize/xymax;
01901       yncm  = ysize/xymax;
01902       dxwn  = ((xps/xymax)-xncm)/2;
01903       dywn  = ((yps/xymax)-yncm)/2;
01904    } else {
01905       if (xps/yps < 1) xwkwn = xps/yps;
01906       else             xwkwn = 1;
01907       if (yps/xps < 1) ywkwn = yps/xps;
01908       else             ywkwn = 1;
01909 
01910       if (xsize < ysize)  {
01911          xncm = ywkwn*xsize/ysize;
01912          yncm = ywkwn;
01913          dxwn = (xwkwn-xncm)/2;
01914          dywn = 0;
01915          if( dxwn < 0) {
01916             xncm = xwkwn;
01917             dxwn = 0;
01918             yncm = xwkwn*ysize/xsize;
01919             dywn = (ywkwn-yncm)/2;
01920          }
01921       } else {
01922          xncm = xwkwn;
01923          yncm = xwkwn*ysize/xsize;
01924          dxwn = 0;
01925          dywn = (ywkwn-yncm)/2;
01926          if( dywn < 0) {
01927             yncm = ywkwn;
01928             dywn = 0;
01929             xncm = ywkwn*xsize/ysize;
01930             dxwn = (xwkwn-xncm)/2;
01931          }
01932       }
01933    }
01934    fRange = kTRUE;
01935 }
01936 
01937 
01938 //______________________________________________________________________________
01939 void TPDF::SetColor(Int_t color)
01940 {
01941    // Set color with its color index
01942 
01943    if (color < 0) color = 0;
01944    TColor *col = gROOT->GetColor(color);
01945    if (col) {
01946       SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
01947    } else {
01948       SetColor(1., 1., 1.);
01949    }
01950 }
01951 
01952 
01953 //______________________________________________________________________________
01954 void TPDF::SetColor(Float_t r, Float_t g, Float_t b)
01955 {
01956    // Set color with its R G B components
01957    //
01958    //  r: % of red in [0,1]
01959    //  g: % of green in [0,1]
01960    //  b: % of blue in [0,1]
01961 
01962    if (r == fRed && g == fGreen && b == fBlue) return;
01963 
01964    fRed   = r;
01965    fGreen = g;
01966    fBlue  = b;
01967    if (fRed   <= 0.000001) fRed   = 0;
01968    if (fGreen <= 0.000001) fGreen = 0;
01969    if (fBlue  <= 0.000001) fBlue  = 0;
01970 
01971    if (gStyle->GetColorModelPS()) {
01972       Double_t colCyan, colMagenta, colYellow;
01973       Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
01974       if (colBlack==1) {
01975          colCyan    = 0;
01976          colMagenta = 0;
01977          colYellow  = 0;
01978       } else {
01979          colCyan    = (1-fRed-colBlack)/(1-colBlack);
01980          colMagenta = (1-fGreen-colBlack)/(1-colBlack);
01981          colYellow  = (1-fBlue-colBlack)/(1-colBlack);
01982       }
01983       if (colCyan    <= 0.000001) colCyan    = 0;
01984       if (colMagenta <= 0.000001) colMagenta = 0;
01985       if (colYellow  <= 0.000001) colYellow  = 0;
01986       if (colBlack   <= 0.000001) colBlack   = 0;
01987       WriteReal(colCyan);
01988       WriteReal(colMagenta);
01989       WriteReal(colYellow);
01990       WriteReal(colBlack);
01991       PrintFast(2," K");
01992       WriteReal(colCyan);
01993       WriteReal(colMagenta);
01994       WriteReal(colYellow);
01995       WriteReal(colBlack);
01996       PrintFast(2," k");
01997    } else {
01998       WriteReal(fRed);
01999       WriteReal(fGreen);
02000       WriteReal(fBlue);
02001       PrintFast(3," RG");
02002       WriteReal(fRed);
02003       WriteReal(fGreen);
02004       WriteReal(fBlue);
02005       PrintFast(3," rg");
02006    }
02007 }
02008 
02009 
02010 //______________________________________________________________________________
02011 void TPDF::SetFillColor( Color_t cindex )
02012 {
02013    // Set color index for fill areas
02014 
02015    fFillColor = cindex;
02016    if (gStyle->GetFillColor() <= 0) cindex = 0;
02017 }
02018 
02019 
02020 //______________________________________________________________________________
02021 void TPDF::SetFillPatterns(Int_t ipat, Int_t color)
02022 {
02023    // Set the fill patterns (1 to 25) for fill areas
02024 
02025    char cpat[10];
02026    PrintStr(" /Cs8 cs");
02027    TColor *col = gROOT->GetColor(color);
02028    Double_t colRed   = col->GetRed();
02029    Double_t colGreen = col->GetGreen();
02030    Double_t colBlue  = col->GetBlue();
02031    if (gStyle->GetColorModelPS()) {
02032       Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
02033       if (colBlack==1) {
02034          WriteReal(0);
02035          WriteReal(0);
02036          WriteReal(0);
02037          WriteReal(colBlack);
02038       } else {
02039          Double_t colCyan    = (1-colRed-colBlack)/(1-colBlack);
02040          Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
02041          Double_t colYellow  = (1-colBlue-colBlack)/(1-colBlack);
02042          WriteReal(colCyan);
02043          WriteReal(colMagenta);
02044          WriteReal(colYellow);
02045          WriteReal(colBlack);
02046       }
02047    } else {
02048       WriteReal(colRed);
02049       WriteReal(colGreen);
02050       WriteReal(colBlue);
02051    }
02052    snprintf(cpat,10," /P%2.2d scn", ipat);
02053    PrintStr(cpat);
02054 }
02055 
02056 
02057 //______________________________________________________________________________
02058 void TPDF::SetLineColor( Color_t cindex )
02059 {
02060    // Set color index for lines
02061 
02062    fLineColor = cindex;
02063 }
02064 
02065 
02066 //______________________________________________________________________________
02067 void TPDF::SetLineStyle(Style_t linestyle)
02068 {
02069    // Change the line style
02070    //
02071    // linestyle = 2 dashed
02072    //           = 3 dotted
02073    //           = 4 dash-dotted
02074    //           = else solid (1 in is used most of the time)
02075 
02076    if ( linestyle == fLineStyle) return;
02077    fLineStyle = linestyle;
02078    TString st = (TString)gStyle->GetLineStyleString(linestyle);
02079    PrintFast(2," [");
02080    TObjArray *tokens = st.Tokenize(" ");
02081    for (Int_t j = 0; j<tokens->GetEntries(); j++) {
02082       Int_t it;
02083       sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
02084       WriteInteger((Int_t)(it/4));
02085    }
02086    delete tokens;
02087    PrintFast(5,"] 0 d");
02088 }
02089 
02090 
02091 //______________________________________________________________________________
02092 void TPDF::SetLineWidth(Width_t linewidth)
02093 {
02094    // Change the line width
02095 
02096    if (linewidth == fLineWidth) return;
02097    fLineWidth = linewidth;
02098    WriteReal(fLineScale*fLineWidth);
02099    PrintFast(2," w");
02100 }
02101 
02102 
02103 //______________________________________________________________________________
02104 void TPDF::SetMarkerColor( Color_t cindex )
02105 {
02106    // Set color index for markers.
02107 
02108    fMarkerColor = cindex;
02109 }
02110 
02111 
02112 //______________________________________________________________________________
02113 void TPDF::SetTextColor( Color_t cindex )
02114 {
02115    // Set color index for text
02116 
02117    fTextColor = cindex;
02118 }
02119 
02120 
02121 //______________________________________________________________________________
02122 void TPDF::Text(Double_t xx, Double_t yy, const char *chars)
02123 {
02124    // Draw text
02125    //
02126    // xx: x position of the text
02127    // yy: y position of the text
02128    // chars: text to be drawn
02129 
02130    if (fTextSize <= 0) return;
02131 
02132    const Double_t kDEGRAD = TMath::Pi()/180.;
02133    char str[8];
02134    Double_t x = xx;
02135    Double_t y = yy;
02136 
02137    // Text color
02138    SetColor(Int_t(fTextColor));
02139 
02140    // Clipping
02141    PrintStr(" q");
02142    Double_t x1 = XtoPDF(gPad->GetX1());
02143    Double_t x2 = XtoPDF(gPad->GetX2());
02144    Double_t y1 = YtoPDF(gPad->GetY1());
02145    Double_t y2 = YtoPDF(gPad->GetY2());
02146    WriteReal(x1);
02147    WriteReal(y1);
02148    WriteReal(x2 - x1);
02149    WriteReal(y2 - y1);
02150    PrintStr(" re W n");
02151 
02152    // Start the text
02153    if (!fCompress) PrintStr("@");
02154 
02155    // Font and text size
02156    Int_t font = abs(fTextFont)/10;
02157    if( font > kNumberOfFonts || font < 1) font = 1;
02158 
02159    Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
02160    Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
02161    Float_t tsize, ftsize;
02162    if (wh < hh) {
02163       tsize = fTextSize*wh;
02164       Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
02165       ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
02166    } else {
02167       tsize = fTextSize*hh;
02168       Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
02169       ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
02170    }
02171    Double_t fontsize = 72*(ftsize)/2.54;
02172    if( fontsize <= 0) return;
02173 
02174    // Text alignment
02175    Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
02176    Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
02177    Int_t txalh = fTextAlign/10;
02178    if (txalh < 1) txalh = 1; if (txalh > 3) txalh = 3;
02179    Int_t txalv = fTextAlign%10;
02180    if (txalv < 1) txalv = 1; if (txalv > 3) txalv = 3;
02181    if( txalv == 3) {
02182       y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
02183       x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
02184    } else if( txalv == 2) {
02185       y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
02186       x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
02187    }
02188 
02189    if (txalh > 1) {
02190       TText t;
02191       UInt_t w, h;
02192       t.SetTextSize(fTextSize);
02193       t.SetTextFont(fTextFont);
02194       t.GetTextExtent(w, h, chars);
02195       Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
02196       Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
02197       if(txalh == 2){
02198          x = x-(twx/2)*TMath::Cos(kDEGRAD*fTextAngle);
02199          y = y-(twy/2)*TMath::Sin(kDEGRAD*fTextAngle);
02200       }
02201       if(txalh == 3){
02202          x = x-twx*TMath::Cos(kDEGRAD*fTextAngle);
02203          y = y-twy*TMath::Sin(kDEGRAD*fTextAngle);
02204       }
02205    }
02206 
02207    // Symbol Italic tan(15) = .26794
02208    if (font == 15) {
02209       Float_t tanAlpha = 0.26794;
02210       Float_t dx = - tanAlpha * YtoPDF(y);
02211       PrintStr(" q 1 0");
02212       WriteReal(tanAlpha);
02213       PrintStr(" 1");
02214       WriteReal(dx);
02215       PrintStr(" 0 cm");
02216    }
02217 
02218    PrintStr(" BT");
02219 
02220    snprintf(str,8," /F%d",font);
02221    PrintStr(str);
02222    WriteReal(fontsize);
02223    PrintStr(" Tf");
02224 
02225    // Text angle
02226    if(fTextAngle == 0) {
02227       WriteReal(XtoPDF(x));
02228       WriteReal(YtoPDF(y));
02229       PrintStr(" Td");
02230    } else if (fTextAngle == 90) {
02231       PrintStr(" 0 1 -1 0");
02232       WriteReal(XtoPDF(x));
02233       WriteReal(YtoPDF(y));
02234       PrintStr(" Tm");
02235    } else if (fTextAngle == 270) {
02236       PrintStr(" 0 -1 1 0");
02237       WriteReal(XtoPDF(x));
02238       WriteReal(YtoPDF(y));
02239       PrintStr(" Tm");
02240    } else {
02241       WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
02242       WriteReal(TMath::Sin(kDEGRAD*fTextAngle));
02243       WriteReal(-TMath::Sin(kDEGRAD*fTextAngle));
02244       WriteReal(TMath::Cos(kDEGRAD*fTextAngle));
02245       WriteReal(XtoPDF(x));
02246       WriteReal(YtoPDF(y));
02247       PrintStr(" Tm");
02248    }
02249 
02250    const Int_t len=strlen(chars);
02251 
02252    // Calculate the individual character placements.
02253    // Otherwise, if a string is printed in one line the kerning is not
02254    // performed. In order to measure the precise character positions we need to
02255    // trick FreeType into rendering high-resolution characters otherwise it will
02256    // stick to the screen pixel grid which is far worse than we can achieve on
02257    // print.
02258    const Float_t scale = 16.0;
02259    // Save current text attributes.
02260    TText saveAttText;
02261    saveAttText.TAttText::operator=(*this);
02262    TText t;
02263    t.SetTextSize(fTextSize * scale);
02264    t.SetTextFont(fTextFont);
02265    UInt_t wa1, wa0;
02266    t.GetTextAdvance(wa0, chars, kFALSE);
02267    t.GetTextAdvance(wa1, chars);
02268    t.TAttText::Modify();
02269    Bool_t kerning;
02270    if (wa0-wa1 != 0) kerning = kTRUE;
02271    else              kerning = kFALSE;
02272    Int_t *charDeltas = 0;
02273    if (kerning) {
02274         charDeltas = new Int_t[len];
02275         for (Int_t i = 0;i < len;i++) {
02276             UInt_t ww;
02277             t.GetTextAdvance(ww, chars + i);
02278             charDeltas[i] = wa1 - ww;
02279         }
02280         for (Int_t i = len - 1;i > 0;i--) {
02281             charDeltas[i] -= charDeltas[i-1];
02282         }
02283         char tmp[2];
02284         tmp[1] = 0;
02285         for (Int_t i = 1;i < len;i++) {
02286             tmp[0] = chars[i-1];
02287             UInt_t width;
02288             t.GetTextAdvance(width, &tmp[0], kFALSE);
02289             Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
02290             wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
02291             charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
02292         }
02293    }
02294    // Restore text attributes.
02295    saveAttText.TAttText::Modify();
02296 
02297    // Ouput the text. Escape some characters if needed
02298    if (kerning) PrintStr(" [");
02299    else         PrintStr(" (");
02300 
02301    for (Int_t i=0; i<len;i++) {
02302       if (chars[i]!='\n') {
02303          if (kerning) PrintStr("(");
02304          if (chars[i]=='(' || chars[i]==')') {
02305             snprintf(str,8,"\\%c",chars[i]);
02306          } else {
02307             snprintf(str,8,"%c",chars[i]);
02308          }
02309          PrintStr(str);
02310          if (kerning) {
02311             PrintStr(") ");
02312             if (i < len-1) {
02313                WriteInteger(charDeltas[i+1]);
02314             }
02315          }
02316       }
02317    }
02318 
02319    if (kerning) PrintStr("] TJ ET Q");
02320    else         PrintStr(") Tj ET Q");
02321    if (font == 15) PrintStr(" Q");
02322    if (!fCompress) PrintStr("@");
02323    if (kerning) delete [] charDeltas;
02324 }
02325 
02326 
02327 //______________________________________________________________________________
02328 void TPDF::TextNDC(Double_t u, Double_t v, const char *chars)
02329 {
02330    // Write a string of characters in NDC
02331 
02332    Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
02333    Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
02334    Text(x, y, chars);
02335 }
02336 
02337 
02338 //______________________________________________________________________________
02339 Double_t TPDF::UtoPDF(Double_t u)
02340 {
02341    // Convert U from NDC coordinate to PDF
02342 
02343    Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
02344    return 72*cm/2.54;
02345 }
02346 
02347 
02348 //______________________________________________________________________________
02349 Double_t TPDF::VtoPDF(Double_t v)
02350 {
02351    // Convert V from NDC coordinate to PDF
02352 
02353    Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
02354    return 72*cm/2.54;
02355 }
02356 
02357 
02358 //______________________________________________________________________________
02359 Double_t TPDF::XtoPDF(Double_t x)
02360 {
02361    // Convert X from world coordinate to PDF
02362 
02363    Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
02364    return  UtoPDF(u);
02365 }
02366 
02367 
02368 //______________________________________________________________________________
02369 Double_t TPDF::YtoPDF(Double_t y)
02370 {
02371    // Convert Y from world coordinate to PDF
02372 
02373    Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
02374    return  VtoPDF(v);
02375 }
02376 
02377 
02378 //______________________________________________________________________________
02379 void TPDF::WriteCompressedBuffer()
02380 {
02381    // Write the buffer in a compressed way
02382 
02383    z_stream stream;
02384    int err;
02385    char *out = new char[2*fLenBuffer];
02386 
02387    stream.next_in   = (Bytef*)fBuffer;
02388    stream.avail_in  = (uInt)fLenBuffer;
02389    stream.next_out  = (Bytef*)out;
02390    stream.avail_out = (uInt)2*fLenBuffer;
02391    stream.zalloc    = (alloc_func)0;
02392    stream.zfree     = (free_func)0;
02393    stream.opaque    = (voidpf)0;
02394 
02395    err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
02396    if (err != Z_OK) {
02397       Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
02398       return;
02399    }
02400 
02401    err = deflate(&stream, Z_FINISH);
02402    if (err != Z_STREAM_END) {
02403       deflateEnd(&stream);
02404       Error("WriteCompressedBuffer", "error in deflate (zlib)");
02405       return;
02406    }
02407 
02408    err = deflateEnd(&stream);
02409 
02410    fStream->write(out, stream.total_out);
02411 
02412    fNByte += stream.total_out;
02413    fStream->write("\n",1); fNByte++;
02414    fLenBuffer = 0;
02415    delete [] out;
02416    fCompress = kFALSE;
02417 }
02418 
02419 //______________________________________________________________________________
02420 void TPDF::WriteReal(Float_t z)
02421 {
02422    // Write a Real number to the file.
02423    // This method overwrites TVirtualPS::WriteReal. Some PDF reader like
02424    // Acrobat do not work when a PDF file contains reals with exponent. This
02425    // method writes the real number "z" using the format "%f" instead of the
02426    // format "%g" when writing it with "%g" generates a number with exponent.
02427 
02428    char str[15];
02429    snprintf(str,15," %g", z);
02430    if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
02431    PrintStr(str);
02432 }

Generated on Tue Jul 5 14:14:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1