TPostScript.cxx

Go to the documentation of this file.
00001 // @(#)root/postscript:$Id: TPostScript.cxx 35554 2010-09-21 16:07:54Z couet $
00002 // Author: Rene Brun, Olivier Couet, Pierre Juillot, Oleksandr Grebenyuk
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>TPostScript: Graphics interface to PostScript</h2></center>
00016 This code was initially developed in the context of HIGZ and PAW
00017 by Olivier Couet and Pierre Juillot. It has been converted to a C++ class by
00018 Rene Brun.
00019 
00020 <P>To generate a Postscript (or encapsulated ps) file corresponding to
00021 a single image in a canvas, you can:
00022 
00023 <UL>
00024 <LI>Select the <B>Print PostScript</B> item in the canvas <B>File</B> menu.
00025 By default, a Postscript file with the name of the canvas.ps is generated.
00026 
00027 <br>
00028 <LI>Click in the canvas area, near the edges, with the right mouse button
00029 and select the <B>Print</B> item. You can select the name of the Postscript
00030 file. If the file name is xxx.ps, you will generate a Postscript file named
00031 xxx.ps. If the file name is xxx.eps, you generate an encapsulated Postscript
00032 file instead.
00033 <br>
00034 
00035 <LI>In your program (or macro), you can type:
00036 
00037 <P><TT><B>
00038 c1-&gt;Print(&quot;xxx.ps&quot;)</B> or <B>c1-&gt;Print(&quot;xxx.eps&quot;)
00039 </B></TT>
00040 
00041 <P>This will generate a file corresponding to the picture in the canvas
00042 pointed by <tt><B>c1</B></tt>.
00043 
00044 <P><TT><B>pad1-&gt;Print(&quot;xxx.ps&quot;)</B></TT>
00045 
00046 <P>prints only the picture in the pad pointed by <tt><B>pad1</B></tt>. The size
00047 of the Postscript picture, by default, is computed to keep the aspect ratio
00048 of the picture on the screen, where the size along x is always 20cm. You
00049 can set the size of the PostScript picture before generating the picture
00050 with a command such as:
00051 
00052 <PRE>
00053    TPostScript myps(&quot;myfile.ps&quot;,111)
00054    myps.Range(xsize,ysize);
00055    object-&gt;Draw();
00056    myps.Close();
00057 </PRE>
00058 
00059 <P>You can set the default paper size with:
00060 <PRE>
00061    gStyle-&gt;SetPaperSize(xsize,ysize);
00062 </PRE>
00063 <P>You can resume writing again in this file with <tt><B>myps.Open();</B></tt>.
00064 Note that you may have several Postscript files opened simultaneously.
00065 </UL>
00066 
00067 <H2>Output type</H2>
00068 
00069 The output type allows to define how the PostScript output will looks like.
00070 It allows to define the page format (A4, Legal etc..), the orientation
00071 (Portrait, Landscape) and the number of images (zones) per page.
00072 The output type has the following form:
00073 <pre>
00074                         [Format][Nx][Ny][Type]
00075 </pre>
00076 Where:
00077 <ul>
00078    <li> Format : Is an integer between 0 and 99 defining the page format.
00079         Example:
00080    <br> Format = 3 the paper is in the standard A3 format.
00081    <br> Format = n (1<n<98) is an An format.
00082    <br> Format = 4 and Format=0 are the same and define an A4 page.
00083    <br> The A0 format is selected by Format=99.
00084    <br> The US format Letter is selected by Format = 100.
00085    <br> The US format Legal is selected by Format = 200.
00086    <br> The US format Ledger is selected by Format = 300.
00087 
00088    <li> Nx, Ny : Specify respectively the number of zones on the x and y axis.
00089    Nx and Ny are integers between 1 and 9.
00090 
00091    <li> Type : Can be equal to:
00092    <ul>
00093    <li> 1 : Portrait mode with a small margin at the bottom of the page.
00094    <li> 2 : Landscape mode with a small margin at the bottom of the page.
00095    <li> 4 : Portrait mode with a large margin at the bottom of the page.
00096    <li> 5 : Landscape mode with a large margin at the bottom of the page.
00097             The large margin is useful for some PostScript printers (very often
00098             for the colour printers) as they need more space to grip the paper
00099             for mechanical reasons. Note that some PostScript colour printers
00100             can also use the so called special A4 format permitting the full
00101             usage of the A4 area; in this case larger margins are not necessary
00102             and Type=1 or 2 can be used.
00103    <li> 3 : Encapsulated PostScript. This Type permits the generation of files
00104             which can be included in other documents, for example in LaTeX
00105             files.
00106    </ul>
00107 </ul>
00108 
00109 <H2>Making several pictures in the same Postscript file: case 1</H2>
00110 <P>The following macro is an example illustrating how to open a Postscript
00111 file and draw several pictures. The generation of a new Postscript page
00112 is automatic when <tt><B>TCanvas::Clear</B></tt> is called by
00113 <tt><b>object-&gt;Draw()</b></tt>.
00114 <PRE>
00115 {
00116    TFile f(&quot;hsimple.root&quot;);
00117    TCanvas c1(&quot;c1&quot;,&quot;canvas&quot;,800,600);
00118 
00119    <b>// select postscript output type</b>
00120    <b>// type = 111   portrait  ps</b>
00121    <b>// type = 112   landscape ps</b>
00122    <b>// type = 113   eps</b>
00123    Int_t type = 111;
00124 
00125    <b>// create a postscript file and set the paper size</b>
00126    TPostScript ps(&quot;test.ps&quot;,type);
00127    ps.Range(16,24);  //set x,y of printed page
00128 
00129    <b>// draw 3 histograms from file hsimple.root on separate pages</b>
00130    hpx-&gt;Draw();
00131    c1.Update();      //force drawing in a macro
00132    hprof-&gt;Draw();
00133    c1.Update();
00134    hpx-&gt;Draw(&quot;lego1&quot;);
00135    c1.Update();
00136    ps.Close();
00137 }
00138 </PRE>
00139 
00140 <H2>Making several pictures in the same Postscript file: case 2</H2>
00141 <P>This example shows 2 pages. The canvas is divided.
00142 <tt><B>TPostScript::NewPage</B></tt> must be called before starting a new
00143 picture.<tt><b>object-&gt;Draw</b></tt> does not clear the canvas in this case
00144 because we clear only the pads and not the main canvas.
00145 Note that <tt><b>c1-&gt;Update</b></tt> must be called at the end of the first
00146 picture.
00147 <PRE>
00148 {
00149    TFile *f1 = new TFile("hsimple.root");
00150    TCanvas *c1 = new TCanvas("c1");
00151    TPostScript *ps = new TPostScript("file.ps",112);
00152    c1-&gt;Divide(2,1);
00153 <b>// picture 1</b>
00154    ps-&gt;NewPage();
00155    c1-&gt;cd(1);
00156    hpx-&gt;Draw();
00157    c1-&gt;cd(2);
00158    hprof-&gt;Draw();
00159    c1-&gt;Update();
00160 
00161 <b>// picture 2</b>
00162    ps-&gt;NewPage();
00163    c1-&gt;cd(1);
00164    hpxpy-&gt;Draw();
00165    c1-&gt;cd(2);
00166    ntuple-&gt;Draw("px");
00167    c1-&gt;Update();
00168    ps-&gt;Close();
00169 
00170 <b>// invoke Postscript viewer</b>
00171    gSystem-&gt;Exec("gs file.ps");
00172 }
00173 </PRE>
00174 
00175 <H2>Making several pictures in the same Postscript file: case 3</H2>
00176 <b>This is the recommended way</b>. If the Postscript file name finishes with
00177 "(", the file remains opened (it is not closed). If the Postscript file name
00178 finishes with ")" and the file has been opened with "(", the file is closed.
00179 <P>Example:
00180 <PRE>
00181 {
00182    TCanvas c1("c1");
00183    h1.Draw();
00184    c1.Print("c1.ps(");  // write canvas and keep the ps file open
00185    h2.Draw();
00186    c1.Print("c1.ps");   // canvas is added to "c1.ps"
00187    h3.Draw();
00188    c1.Print("c1.ps)");  // canvas is added to "c1.ps" and ps file is closed
00189 }
00190 </PRE>
00191 The <tt>TCanvas::Print("file.ps(")</tt> mechanism is very useful, but it can
00192 be a little inconvenient to have the action of opening/closing a file being
00193 atomic with printing a page. Particularly if pages are being generated in some
00194 loop one needs to detect the special cases of first and last page and then
00195 munge the argument to Print() accordingly.
00196 <BR>The "[" and "]" can be used instead of "(" and ")" as shown below.
00197 <P>Example:
00198 <PRE>
00199    c1.Print("file.ps[");        // No actual print, just open file.ps
00200 
00201    for (int i=0; i<10; ++i) {
00202       // fill canvas for context i
00203       // ...
00204 
00205       c1.Print("file.ps");      // Actually print canvas to the file
00206    }
00207 
00208    c1.Print("file.ps]");        // No actual print, just close the file
00209 </PRE>
00210 
00211 <H2>Color Model</H2>
00212 TPostScript support two color model RGB and CMYK. CMY and CMYK models are
00213 subtractive color models unlike RGB which is an additive. They are mainly
00214 used for printing purposes. CMY means Cyan Magenta Yellow to convert RGB
00215 to CMY it is enough to do: C=1-R, M=1-G and Y=1-B. CMYK has one more
00216 component K (black). The conversion from RGB to CMYK is:
00217 <PRE>
00218  Double_t Black   = TMath::Min(TMath::Min(1-Red,1-Green),1-Blue);
00219  Double_t Cyan    = (1-Red-Black)/(1-Black);
00220  Double_t Magenta = (1-Green-Black)/(1-Black);
00221  Double_t Yellow  = (1-Blue-Black)/(1-Black);
00222 </PRE>
00223 CMYK add the black component which allows to have a better quality for black
00224 printing. PostScript support the CMYK model.
00225 <br>
00226 To change the color model use gStyle->SetColorModelPS(c).
00227 <ul>
00228 <li> c = 0 means TPostScript will use RGB color model (default)
00229 <li> c = 1 means TPostScript will use CMYK color model
00230 </ul>
00231 End_Html */
00232 
00233 #ifdef WIN32
00234 #pragma optimize("",off)
00235 #endif
00236 
00237 #include <stdlib.h>
00238 #include <string.h>
00239 #include <ctype.h>
00240 
00241 #include "Riostream.h"
00242 #include "TROOT.h"
00243 #include "TColor.h"
00244 #include "TVirtualPad.h"
00245 #include "TPoints.h"
00246 #include "TPostScript.h"
00247 #include "TStyle.h"
00248 #include "TMath.h"
00249 #include "TText.h"
00250 #include "TSystem.h"
00251 
00252 // to scale fonts to the same size as the old TT version
00253 const Float_t kScale = 0.93376068;
00254 
00255 const char   kBackslash = '\\';
00256 const Int_t  kLatex = BIT(10);
00257 
00258 Int_t TPostScript::fgLineJoin = 0;
00259 
00260 ClassImp(TPostScript)
00261 
00262 
00263 //______________________________________________________________________________
00264 TPostScript::TPostScript() : TVirtualPS()
00265 {
00266    // Default PostScript constructor
00267 
00268    fStream          = 0;
00269    fType            = 0;
00270    gVirtualPS       = this;
00271    fBlue            = 0.;
00272    fBoundingBox     = kFALSE;
00273    fClear           = kFALSE;
00274    fClip            = 0;
00275    fClipStatus      = kFALSE;
00276    fCurrentColor    = 0;
00277    fDXC             = 0.;
00278    fDYC             = 0.;
00279    fFX              = 0.;
00280    fFY              = 0.;
00281    fGreen           = 0.;
00282    fIXzone          = 0;
00283    fIYzone          = 0;
00284    fLastCellBlue    = 0;
00285    fLastCellGreen   = 0;
00286    fLastCellRed     = 0;
00287    fLineJoin        = 0;
00288    fLineScale       = 0.;
00289    fMarkerSizeCur   = 0.;
00290    fMaxLines        = 0;
00291    fMaxsize         = 0;
00292    fMode            = 0;
00293    fNBSameColorCell = 0;
00294    fNXzone          = 0;
00295    fNYzone          = 0;
00296    fNbCellLine      = 0;
00297    fNbCellW         = 0;
00298    fNbinCT          = 0;
00299    fNpages          = 0;
00300    fRange           = kFALSE;
00301    fRed             = 0.;
00302    fSave            = 0;
00303    fX1v             = 0.;
00304    fX1w             = 0.;
00305    fX2v             = 0.;
00306    fX2w             = 0.;
00307    fXC              = 0.;
00308    fXVP1            = 0.;
00309    fXVP2            = 0.;
00310    fXVS1            = 0.;
00311    fXVS2            = 0.;
00312    fXsize           = 0.;
00313    fY1v             = 0.;
00314    fY1w             = 0.;
00315    fY2v             = 0.;
00316    fY2w             = 0.;
00317    fYC              = 0.;
00318    fYVP1            = 0.;
00319    fYVP2            = 0.;
00320    fYVS1            = 0.;
00321    fYVS2            = 0.;
00322    fYsize           = 0.;
00323    fZone            = kFALSE;
00324    for (Int_t i=0; i<32; i++) fPatterns[i]=0;
00325 }
00326 
00327 
00328 //______________________________________________________________________________
00329 TPostScript::TPostScript(const char *fname, Int_t wtype)
00330             :TVirtualPS(fname, wtype)
00331 {
00332    // Initialize the PostScript interface
00333    //
00334    //  fname : PostScript file name
00335    //  wtype : PostScript workstation type
00336    //
00337    //
00338    //  The possible workstation types are:
00339    //     111 ps  Portrait
00340    //     112 ps  Landscape
00341    //     113 eps
00342 
00343    fStream = 0;
00344    Open(fname, wtype);
00345 }
00346 
00347 
00348 //______________________________________________________________________________
00349 void TPostScript::Open(const char *fname, Int_t wtype)
00350 {
00351    // Open a PostScript file
00352    if (fStream) {
00353       Warning("Open", "postscript file already open");
00354       return;
00355    }
00356 
00357    fMarkerSizeCur = 0;
00358    fCurrentColor  = 0;
00359    fRed           = -1;
00360    fGreen         = -1;
00361    fBlue          = -1;
00362    fLenBuffer     = 0;
00363    fClip          = 0;
00364    fType          = abs(wtype);
00365    fClear         = kTRUE;
00366    fZone          = kFALSE;
00367    fSave          = 0;
00368    SetLineScale(gStyle->GetLineScalePS());
00369    gStyle->GetPaperSize(fXsize, fYsize);
00370    fMode          = fType%10;
00371    Float_t xrange, yrange;
00372    if (gPad) {
00373       Double_t ww = gPad->GetWw();
00374       Double_t wh = gPad->GetWh();
00375       if (fType == 113) {
00376          ww *= gPad->GetWNDC();
00377          wh *= gPad->GetHNDC();
00378       }
00379       Double_t ratio = wh/ww;
00380       if (fType == 112) {
00381          xrange = fYsize;
00382          yrange = xrange*ratio;
00383          if (yrange > fXsize) { yrange = fXsize; xrange = yrange/ratio;}
00384       } else {
00385          xrange = fXsize;
00386          yrange = fXsize*ratio;
00387          if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
00388       }
00389       fXsize = xrange; fYsize = yrange;
00390    }
00391 
00392    // open OS file
00393    fStream = new ofstream(fname,ios::out);
00394    if (fStream == 0 || gSystem->AccessPathName(fname,kWritePermission)) {
00395       printf("ERROR in TPostScript::Open: Cannot open file:%s\n",fname);
00396       return;
00397    }
00398    gVirtualPS = this;
00399 
00400    for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
00401    if( fType == 113) {
00402       fBoundingBox = kFALSE;
00403       PrintStr("%!PS-Adobe-2.0 EPSF-2.0@");
00404    } else {
00405       fBoundingBox = kTRUE;
00406       PrintStr("%!PS-Adobe-2.0@");
00407       Initialize();
00408    }
00409 
00410    fClipStatus = kFALSE;
00411    fRange      = kFALSE;
00412 
00413    // Set a default range
00414    Range(fXsize, fYsize);
00415 
00416    fPrinted    = kFALSE;
00417    if (fType == 113) NewPage();
00418 }
00419 
00420 
00421 //______________________________________________________________________________
00422 TPostScript::~TPostScript()
00423 {
00424    // Default PostScript destructor
00425 
00426    Close();
00427 }
00428 
00429 
00430 //______________________________________________________________________________
00431 void TPostScript::Close(Option_t *)
00432 {
00433    // Close a PostScript file
00434 
00435    if (!gVirtualPS) return;
00436    if (!fStream) return;
00437    if (gPad) gPad->Update();
00438    if( fMode != 3) {
00439       SaveRestore(-1);
00440       if( fPrinted ) { PrintStr("showpage@"); SaveRestore(-1);}
00441       PrintStr("@");
00442       PrintStr("%%Trailer@");
00443       PrintStr("%%Pages: ");
00444       WriteInteger(fNpages);
00445       PrintStr("@");
00446       while (fSave > 0) { SaveRestore(-1); }
00447    } else {
00448       PrintStr("@");
00449       while (fSave > 0) { SaveRestore(-1); }
00450       PrintStr("showpage@");
00451       PrintStr("end@");
00452    }
00453    PrintStr("@");
00454    PrintStr("%%EOF@");
00455 
00456    // Close file stream
00457 
00458    if (fStream) { fStream->close(); delete fStream; fStream = 0;}
00459 
00460    gVirtualPS = 0;
00461 }
00462 
00463 
00464 //______________________________________________________________________________
00465 void TPostScript::On()
00466 {
00467    // Activate an already open PostScript file
00468 
00469    if (!fType) {
00470       Error("On", "no postscript file open");
00471       Off();
00472       return;
00473    }
00474    gVirtualPS = this;
00475 }
00476 
00477 
00478 //______________________________________________________________________________
00479 void TPostScript::Off()
00480 {
00481    // Deactivate an already open PostScript file
00482 
00483    gVirtualPS = 0;
00484 }
00485 
00486 
00487 //______________________________________________________________________________
00488 void TPostScript::CellArrayBegin(Int_t W, Int_t /*H*/, Double_t x1, Double_t x2,
00489                                  Double_t y1, Double_t y2)
00490 {
00491    // Draw a Cell Array
00492    //
00493    // Drawing a PostScript Cell Array is in fact done thanks to three
00494    // procedures: CellArrayBegin, CellArrayFill, and CellArrayEnd.
00495    //
00496    // CellArrayBegin: Initiate the Cell Array by writing the necessary
00497    //                 PostScript procedures and the initial values of the
00498    //                 required parameters. The input parameters are:
00499    //                 W: number of boxes along the width.
00500    //                 H: number of boxes along the height
00501    //                 x1,x2,y1,y2: First box coordinates.
00502    // CellArrayFill:  Is called for each box of the Cell Array. The first
00503    //                 box is the top left one and the last box is the
00504    //                 bottom right one. The input parameters are the Red,
00505    //                 Green, and Blue components of the box colour. These
00506    //                 Levels are between 0 and 255.
00507    // CellArrayEnd:   Finishes the Cell Array.
00508    //
00509    // PostScript cannot handle arrays larger than 65535. So the Cell Array
00510    // is drawn in several pieces.
00511 
00512    Int_t ix1 = XtoPS(x1);
00513    Int_t iy1 = YtoPS(y1);
00514 
00515    Float_t wt = (288/2.54)*gPad->GetAbsWNDC()*
00516                 fXsize*((x2 - x1)/(gPad->GetX2()-gPad->GetX1()));
00517    Float_t ht = (288/2.54)*gPad->GetAbsHNDC()*
00518                 fYsize*((y2 - y1)/(gPad->GetY2()-gPad->GetY1()));
00519 
00520    fLastCellRed     = 300;
00521    fLastCellGreen   = 300;
00522    fLastCellBlue    = 300;
00523    fNBSameColorCell = 0;
00524 
00525    fNbinCT = 0;
00526    fNbCellW = W;
00527    fNbCellLine = 0;
00528    fMaxLines = 40000/(3*fNbCellW);
00529 
00530    // Define some paremeters
00531    PrintStr("@/WT"); WriteReal(wt)          ; PrintStr(" def"); // Cells width
00532    PrintStr(" /HT"); WriteReal(ht)          ; PrintStr(" def"); // Cells height
00533    PrintStr(" /XS"); WriteInteger(ix1)      ; PrintStr(" def"); // X start
00534    PrintStr(" /YY"); WriteInteger(iy1)      ; PrintStr(" def"); // Y start
00535    PrintStr(" /NX"); WriteInteger(W)        ; PrintStr(" def"); // Number of columns
00536    PrintStr(" /NY"); WriteInteger(fMaxLines); PrintStr(" def"); // Number of lines
00537 
00538    // This PS procedure draws one cell.
00539    PrintStr(" /DrawCell ");
00540    PrintStr(   "{WT HT XX YY bf");
00541    PrintStr(   " /NBBD NBBD 1 add def");
00542    PrintStr(   " NBBD NBB eq {exit} if");
00543    PrintStr(   " /XX WT XX add def");
00544    PrintStr(   " IX NX eq ");
00545    PrintStr(      "{/YY YY HT sub def");
00546    PrintStr(      " /XX XS def");
00547    PrintStr(      " /IX 0 def} if");
00548    PrintStr(   " /IX IX 1 add def} def");
00549 
00550    // This PS procedure draws fMaxLines line. It takes care of duplicated
00551    // colors. Values "n" greater than 300 mean than the previous color
00552    // should be duplicated n-300 times.
00553    PrintStr(" /DrawCT ");
00554    PrintStr(   "{/NBB NX NY mul def");
00555    PrintStr(   " /XX XS def");
00556    PrintStr(   " /IX 1 def");
00557    PrintStr(   " /NBBD 0 def");
00558    PrintStr(   " /RC 0 def /GC 1 def /BC 2 def");
00559    PrintStr(   " 1 1 NBB ");
00560    PrintStr(      "{/NB CT RC get def");
00561    PrintStr(      " NB 301 ge ");
00562    PrintStr(         "{/NBL NB 300 sub def");
00563    PrintStr(         " 1 1 NBL ");
00564    PrintStr(            "{DrawCell}");
00565    PrintStr(         " for");
00566    PrintStr(         " /RC RC 1 add def");
00567    PrintStr(         " /GC RC 1 add def");
00568    PrintStr(         " /BC RC 2 add def}");
00569    PrintStr(         "{CT RC get 255 div CT GC get 255 div CT BC get 255 div setrgbcolor");
00570    PrintStr(         " DrawCell");
00571    PrintStr(         " /RC RC 3 add def");
00572    PrintStr(         " /GC GC 3 add def");
00573    PrintStr(         " /BC BC 3 add def} ifelse NBBD NBB eq {exit} if} for");
00574    PrintStr(         " /YY YY HT sub def clear} def");
00575 
00576    PrintStr(" /CT [");
00577 }
00578 
00579 
00580 //______________________________________________________________________________
00581 void TPostScript::CellArrayFill(Int_t r, Int_t g, Int_t b)
00582 {
00583    // Paint the Cell Array
00584 
00585    if (fLastCellRed == r && fLastCellGreen == g && fLastCellBlue == b) {
00586       fNBSameColorCell++;
00587    } else {
00588       if (fNBSameColorCell != 0 ) {
00589          WriteInteger(fNBSameColorCell+300);
00590          fNBSameColorCell = 0;
00591       }
00592       WriteInteger(r);
00593       WriteInteger(g);
00594       WriteInteger(b);
00595       fLastCellRed = r;
00596       fLastCellGreen = g;
00597       fLastCellBlue = b;
00598    }
00599 
00600    fNbinCT++;
00601    if (fNbinCT == fNbCellW) {
00602       fNbCellLine++;
00603       fNbinCT = 0;
00604    }
00605 
00606    if (fNbCellLine == fMaxLines) {
00607       if (fNBSameColorCell != 0) WriteInteger(fNBSameColorCell+300);
00608       PrintStr("] def DrawCT /CT [");
00609       fNbCellLine = 0;
00610       fLastCellRed = 300;
00611       fLastCellGreen = 300;
00612       fLastCellBlue = 300;
00613       fNBSameColorCell = 0;
00614       fNbinCT = 0;
00615    }
00616 }
00617 
00618 
00619 //______________________________________________________________________________
00620 void TPostScript::CellArrayEnd()
00621 {
00622    // End the Cell Array painting
00623 
00624    if (fNBSameColorCell != 0 ) WriteInteger(fNBSameColorCell+300);
00625    PrintStr("] def /NY");
00626    WriteInteger(fNbCellLine);
00627    PrintStr(" def DrawCT ");
00628 }
00629 
00630 
00631 //______________________________________________________________________________
00632 void TPostScript::DefineMarkers()
00633 {
00634    // Define the markers
00635 
00636    PrintStr("/mp {newpath /y exch def /x exch def} def@");
00637    PrintStr("/side {[w .77 mul w .23 mul] .385 w mul sd w 0 l currentpoint t -144 r} def@");
00638    PrintStr("/mr {mp x y w2 0 360 arc} def /m24 {mr s} def /m20 {mr f} def@");
00639    PrintStr("/mb {mp x y w2 add m w2 neg 0 d 0 w neg d w 0 d 0 w d cl} def@");
00640    PrintStr("/mt {mp x y w2 add m w2 neg w neg d w 0 d cl} def@");
00641    PrintStr("/m21 {mb f} def /m25 {mb s} def /m22 {mt f} def /m26{mt s} def@");
00642    PrintStr("/m23 {mp x y w2 sub m w2 w d w neg 0 d cl f} def@");
00643    PrintStr("/m27 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl s} def@");
00644    PrintStr("/m28 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
00645    PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
00646    PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
00647    PrintStr(" 0 w3 neg d w3 neg 0 d cl s } def@");
00648    PrintStr("/m29 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
00649    PrintStr(" 4 {side} repeat cl fill gr} def@");
00650    PrintStr("/m30 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
00651    PrintStr(" 4 {side} repeat cl s gr} def@");
00652    PrintStr("/m31 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d");
00653    PrintStr(" x w2 sub y w2 add m w w neg d x w2 sub y w2");
00654    PrintStr(" sub m w w d s} def@");
00655    PrintStr("/m32 {mp x y w2 sub m w2 w d w neg 0 d cl s} def@");
00656    PrintStr("/m33 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl f} def@");
00657    PrintStr("/m34 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
00658    PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
00659    PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
00660    PrintStr(" 0 w3 neg d w3 neg 0 d cl f } def@");
00661    PrintStr("/m2 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d s} def@");
00662    PrintStr("/m5 {mp x w2 sub y w2 sub m w w d x w2 sub y w2 add m w w neg d s} def@");
00663 }
00664 
00665 
00666 //______________________________________________________________________________
00667 void TPostScript::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t  y2)
00668 {
00669    // Draw a Box
00670 
00671    static Double_t x[4], y[4];
00672    Int_t ix1 = XtoPS(x1);
00673    Int_t ix2 = XtoPS(x2);
00674    Int_t iy1 = YtoPS(y1);
00675    Int_t iy2 = YtoPS(y2);
00676    Int_t fillis = fFillStyle/1000;
00677    Int_t fillsi = fFillStyle%1000;
00678 
00679    if (fillis == 3 || fillis == 2) {
00680       if (fillsi > 99) {
00681          x[0] = x1;   y[0] = y1;
00682          x[1] = x2;   y[1] = y1;
00683          x[2] = x2;   y[2] = y2;
00684          x[3] = x1;   y[3] = y2;
00685          return;
00686       }
00687       if (fillsi > 0 && fillsi < 26) {
00688          x[0] = x1;   y[0] = y1;
00689          x[1] = x2;   y[1] = y1;
00690          x[2] = x2;   y[2] = y2;
00691          x[3] = x1;   y[3] = y2;
00692          DrawPS(-4, &x[0], &y[0]);
00693       }
00694       if (fillsi == -3) {
00695          SetColor(5);
00696          WriteInteger(ix2 - ix1);
00697          WriteInteger(iy2 - iy1);
00698          WriteInteger(ix1);
00699          WriteInteger(iy1);
00700          PrintFast(3," bf");
00701       }
00702    }
00703    if (fillis == 1) {
00704       SetColor(fFillColor);
00705       WriteInteger(ix2 - ix1);
00706       WriteInteger(iy2 - iy1);
00707       WriteInteger(ix1);
00708       WriteInteger(iy1);
00709       PrintFast(3," bf");
00710    }
00711    if (fillis == 0) {
00712       SetColor(fLineColor);
00713       WriteInteger(ix2 - ix1);
00714       WriteInteger(iy2 - iy1);
00715       WriteInteger(ix1);
00716       WriteInteger(iy1);
00717       PrintFast(3," bl");
00718    }
00719 }
00720 
00721 
00722 //______________________________________________________________________________
00723 void TPostScript::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t  yt,
00724                             Int_t mode, Int_t border, Int_t dark, Int_t light)
00725 {
00726    // Draw a Frame around a box
00727    //
00728    // mode = -1  box looks as it is behind the screen
00729    // mode =  1  box looks as it is in front of the screen
00730    // border is the border size in already precomputed PostScript units
00731    // dark  is the color for the dark part of the frame
00732    // light is the color for the light part of the frame
00733 
00734    static Int_t xps[7], yps[7];
00735    Int_t i, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00736 
00737    // Draw top&left part of the box
00738    if (mode == -1) SetColor(dark);
00739    else            SetColor(light);
00740    Int_t bordPS = 4*border;
00741    xps[0] = XtoPS(xl);          yps[0] = YtoPS(yl);
00742    xps[1] = xps[0] + bordPS;    yps[1] = yps[0] + bordPS;
00743    xps[2] = xps[1];             yps[2] = YtoPS(yt) - bordPS;
00744    xps[3] = XtoPS(xt) - bordPS; yps[3] = yps[2];
00745    xps[4] = XtoPS(xt);          yps[4] = YtoPS(yt);
00746    xps[5] = xps[0];             yps[5] = yps[4];
00747    xps[6] = xps[0];             yps[6] = yps[0];
00748 
00749    ixd0 = xps[0];
00750    iyd0 = yps[0];
00751    WriteInteger(ixd0);
00752    WriteInteger(iyd0);
00753 
00754    PrintFast(2," m");
00755    idx = 0;
00756    idy = 0;
00757    for (i=1;i<7;i++) {
00758       ixdi = xps[i];
00759       iydi = yps[i];
00760       ix   = ixdi - ixd0;
00761       iy   = iydi - iyd0;
00762       ixd0 = ixdi;
00763       iyd0 = iydi;
00764       if( ix && iy) {
00765          if( idx ) { MovePS(idx,0); idx = 0; }
00766          if( idy ) { MovePS(0,idy); idy = 0; }
00767          MovePS(ix,iy);
00768          continue;
00769       }
00770       if ( ix ) {
00771          if( idy )  { MovePS(0,idy); idy = 0; }
00772          if( !idx ) { idx = ix; continue;}
00773          if( ix*idx > 0 )       idx += ix;
00774          else { MovePS(idx,0);  idx  = ix; }
00775          continue;
00776       }
00777       if( iy ) {
00778          if( idx ) { MovePS(idx,0); idx = 0; }
00779          if( !idy) { idy = iy; continue;}
00780          if( iy*idy > 0 )         idy += iy;
00781          else { MovePS(0,idy);    idy  = iy; }
00782       }
00783    }
00784    if( idx ) MovePS(idx,0);
00785    if( idy ) MovePS(0,idy);
00786    PrintFast(2," f");
00787 
00788    // Draw bottom&right part of the box
00789    if (mode == -1) SetColor(light);
00790    else            SetColor(dark);
00791    xps[0] = XtoPS(xl);          yps[0] = YtoPS(yl);
00792    xps[1] = xps[0] + bordPS;    yps[1] = yps[0] + bordPS;
00793    xps[2] = XtoPS(xt) - bordPS; yps[2] = yps[1];
00794    xps[3] = xps[2];             yps[3] = YtoPS(yt) - bordPS;
00795    xps[4] = XtoPS(xt);          yps[4] = YtoPS(yt);
00796    xps[5] = xps[4];             yps[5] = yps[0];
00797    xps[6] = xps[0];             yps[6] = yps[0];
00798 
00799    ixd0 = xps[0];
00800    iyd0 = yps[0];
00801    WriteInteger(ixd0);
00802    WriteInteger(iyd0);
00803 
00804    PrintFast(2," m");
00805    idx = 0;
00806    idy = 0;
00807    for (i=1;i<7;i++) {
00808       ixdi = xps[i];
00809       iydi = yps[i];
00810       ix   = ixdi - ixd0;
00811       iy   = iydi - iyd0;
00812       ixd0 = ixdi;
00813       iyd0 = iydi;
00814       if( ix && iy) {
00815          if( idx ) { MovePS(idx,0); idx = 0; }
00816          if( idy ) { MovePS(0,idy); idy = 0; }
00817          MovePS(ix,iy);
00818          continue;
00819       }
00820       if ( ix ) {
00821          if( idy )  { MovePS(0,idy); idy = 0; }
00822          if( !idx ) { idx = ix; continue;}
00823          if( ix*idx > 0 )       idx += ix;
00824          else { MovePS(idx,0);  idx  = ix; }
00825          continue;
00826       }
00827       if( iy ) {
00828          if( idx ) { MovePS(idx,0); idx = 0; }
00829          if( !idy) { idy = iy; continue;}
00830          if( iy*idy > 0 )         idy += iy;
00831          else { MovePS(0,idy);    idy  = iy; }
00832       }
00833    }
00834    if( idx ) MovePS(idx,0);
00835    if( idy ) MovePS(0,idy);
00836    PrintFast(2," f");
00837 }
00838 
00839 
00840 //______________________________________________________________________________
00841 void TPostScript::DrawPolyLine(Int_t nn, TPoints *xy)
00842 {
00843    // Draw a PolyLine
00844    //
00845    //  Draw a polyline through  the points xy.
00846    //  If nn=1 moves only to point x,y.
00847    //  If nn=0 the x,y are  written  in the PostScript file
00848    //          according to the current transformation.
00849    //  If nn>0 the line is clipped as a line.
00850    //  If nn<0 the line is clipped as a fill area.
00851 
00852    Int_t  i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00853    Style_t linestylesav = fLineStyle;
00854    Width_t linewidthsav = fLineWidth;
00855    if (nn > 0) {
00856       n = nn;
00857       SetLineStyle(fLineStyle);
00858       SetLineWidth(fLineWidth);
00859       SetColor(Int_t(fLineColor));
00860    } else {
00861       n = -nn;
00862       SetLineStyle(1);
00863       SetLineWidth(1);
00864       SetColor(Int_t(fLineColor));
00865    }
00866 
00867    ixd0 = XtoPS(xy[0].GetX());
00868    iyd0 = YtoPS(xy[0].GetY());
00869    WriteInteger(ixd0);
00870    WriteInteger(iyd0);
00871    if( n <= 1) {
00872       if( n == 0) goto END;
00873       PrintFast(2," m");
00874       goto END;
00875    }
00876 
00877    PrintFast(2," m");
00878    idx = 0;
00879    idy = 0;
00880    for (i=1;i<n;i++) {
00881       ixdi = XtoPS(xy[i].GetX());
00882       iydi = YtoPS(xy[i].GetY());
00883       ix   = ixdi - ixd0;
00884       iy   = iydi - iyd0;
00885       ixd0 = ixdi;
00886       iyd0 = iydi;
00887       if( ix && iy) {
00888          if( idx ) { MovePS(idx,0); idx = 0; }
00889          if( idy ) { MovePS(0,idy); idy = 0; }
00890          MovePS(ix,iy);
00891          continue;
00892       }
00893       if ( ix ) {
00894          if( idy )  { MovePS(0,idy); idy = 0; }
00895          if( !idx ) { idx = ix; continue;}
00896          if( ix*idx > 0 )       idx += ix;
00897          else { MovePS(idx,0);  idx  = ix; }
00898          continue;
00899       }
00900       if( iy ) {
00901          if( idx ) { MovePS(idx,0); idx = 0; }
00902          if( !idy) { idy = iy; continue;}
00903          if( iy*idy > 0 )         idy += iy;
00904          else { MovePS(0,idy);    idy  = iy; }
00905       }
00906    }
00907    if( idx ) MovePS(idx,0);
00908    if( idy ) MovePS(0,idy);
00909 
00910    if (nn > 0 ) {
00911       if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00912       PrintFast(2," s");
00913    } else {
00914       PrintFast(2," f");
00915    }
00916 END:
00917    if (nn < 0) {
00918       SetLineStyle(linestylesav);
00919       SetLineWidth(linewidthsav);
00920    }
00921 }
00922 
00923 
00924 //______________________________________________________________________________
00925 void TPostScript::DrawPolyLineNDC(Int_t nn, TPoints *xy)
00926 {
00927    // Draw a PolyLine in NDC space
00928    //
00929    //  Draw a polyline through the points xy.
00930    //  If nn=1 moves only to point x,y.
00931    //  If nn=0 the x,y are  written  in the PostScript file
00932    //          according to the current transformation.
00933    //  If nn>0 the line is clipped as a line.
00934    //  If nn<0 the line is clipped as a fill area.
00935 
00936    Int_t  i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00937    Style_t linestylesav = fLineStyle;
00938    Width_t linewidthsav = fLineWidth;
00939    if (nn > 0) {
00940       n = nn;
00941       SetLineStyle(fLineStyle);
00942       SetLineWidth(fLineWidth);
00943       SetColor(Int_t(fLineColor));
00944    } else {
00945       n = -nn;
00946       SetLineStyle(1);
00947       SetLineWidth(1);
00948       SetColor(Int_t(fLineColor));
00949    }
00950 
00951    ixd0 = UtoPS(xy[0].GetX());
00952    iyd0 = VtoPS(xy[0].GetY());
00953    WriteInteger(ixd0);
00954    WriteInteger(iyd0);
00955    if( n <= 1) {
00956       if( n == 0) goto END;
00957       PrintFast(2," m");
00958       goto END;
00959    }
00960 
00961    PrintFast(2," m");
00962    idx = 0;
00963    idy = 0;
00964    for (i=1;i<n;i++) {
00965       ixdi = UtoPS(xy[i].GetX());
00966       iydi = VtoPS(xy[i].GetY());
00967       ix   = ixdi - ixd0;
00968       iy   = iydi - iyd0;
00969       ixd0 = ixdi;
00970       iyd0 = iydi;
00971       if( ix && iy) {
00972          if( idx ) { MovePS(idx,0); idx = 0; }
00973          if( idy ) { MovePS(0,idy); idy = 0; }
00974          MovePS(ix,iy);
00975          continue;
00976       }
00977       if ( ix ) {
00978          if( idy )  { MovePS(0,idy); idy = 0; }
00979          if( !idx ) { idx = ix; continue;}
00980          if( ix*idx > 0 )       idx += ix;
00981          else { MovePS(idx,0);  idx  = ix; }
00982          continue;
00983       }
00984       if( iy ) {
00985          if( idx ) { MovePS(idx,0); idx = 0; }
00986          if( !idy) { idy = iy; continue;}
00987          if( iy*idy > 0 )         idy += iy;
00988          else { MovePS(0,idy);    idy  = iy; }
00989       }
00990    }
00991    if( idx ) MovePS(idx,0);
00992    if( idy ) MovePS(0,idy);
00993 
00994    if (nn > 0 ) {
00995       if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00996       PrintFast(2," s");
00997    } else {
00998       PrintFast(2," f");
00999    }
01000 END:
01001    if (nn < 0) {
01002       SetLineStyle(linestylesav);
01003       SetLineWidth(linewidthsav);
01004    }
01005 }
01006 
01007 
01008 //______________________________________________________________________________
01009 void TPostScript::DrawPolyMarker(Int_t n, Float_t *x, Float_t *y)
01010 {
01011    // Draw markers at the n WC points x, y
01012 
01013    Int_t i, np, markerstyle;
01014    Float_t markersize;
01015    static char chtemp[10];
01016 
01017    if (!fMarkerSize) return;
01018    Style_t linestylesav = fLineStyle;
01019    Width_t linewidthsav = fLineWidth;
01020    SetLineStyle(1);
01021    SetLineWidth(1);
01022    SetColor(Int_t(fMarkerColor));
01023    markerstyle = abs(fMarkerStyle);
01024    if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
01025    if (markerstyle == 1) strlcpy(chtemp, " m20",10);
01026    if (markerstyle == 2) strlcpy(chtemp, " m2",10);
01027    if (markerstyle == 3) strlcpy(chtemp, " m31",10);
01028    if (markerstyle == 4) strlcpy(chtemp, " m24",10);
01029    if (markerstyle == 5) strlcpy(chtemp, " m5",10);
01030    if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
01031    if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
01032    if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
01033 
01034    // Set the PostScript marker size
01035    if (markerstyle == 1) {
01036       markersize = 2.;
01037    } else if (markerstyle == 6) {
01038       markersize = 4.;
01039    } else if (markerstyle == 7) {
01040       markersize = 8.;
01041    } else {
01042       Float_t symbolsize  = fMarkerSize;
01043       const Int_t kBASEMARKER = 8;
01044       Float_t sbase = symbolsize*kBASEMARKER;
01045       Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
01046       markersize = this->UtoPS(s2x) - this->UtoPS(0);
01047    }
01048 
01049    if (fMarkerSizeCur != markersize) {
01050       fMarkerSizeCur = markersize;
01051       PrintFast(3," /w");
01052       WriteInteger(Int_t(markersize+0.5));
01053       PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
01054    }
01055 
01056    WriteInteger(XtoPS(x[0]));
01057    WriteInteger(YtoPS(y[0]));
01058    if (n == 1) {
01059       PrintStr(chtemp);
01060       SetLineStyle(linestylesav);
01061       SetLineWidth(linewidthsav);
01062       return;
01063    }
01064    np = 1;
01065    for (i=1;i<n;i++) {
01066       WriteInteger(XtoPS(x[i]));
01067       WriteInteger(YtoPS(y[i]));
01068       np++;
01069       if (np == 100 || i == n-1) {
01070          WriteInteger(np);
01071          PrintFast(2," {");
01072          PrintStr(chtemp);
01073          PrintFast(3,"} R");
01074          np = 0;
01075       }
01076    }
01077    SetLineStyle(linestylesav);
01078    SetLineWidth(linewidthsav);
01079 }
01080 
01081 
01082 //______________________________________________________________________________
01083 void TPostScript::DrawPolyMarker(Int_t n, Double_t *x, Double_t *y)
01084 {
01085    // Draw markers at the n WC points x, y
01086 
01087    Int_t i, np, markerstyle;
01088    Float_t markersize;
01089    static char chtemp[10];
01090 
01091    if (!fMarkerSize) return;
01092    Style_t linestylesav = fLineStyle;
01093    Width_t linewidthsav = fLineWidth;
01094    SetLineStyle(1);
01095    SetLineWidth(1);
01096    SetColor(Int_t(fMarkerColor));
01097    markerstyle = abs(fMarkerStyle);
01098    if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
01099    if (markerstyle == 1) strlcpy(chtemp, " m20",10);
01100    if (markerstyle == 2) strlcpy(chtemp, " m2",10);
01101    if (markerstyle == 3) strlcpy(chtemp, " m31",10);
01102    if (markerstyle == 4) strlcpy(chtemp, " m24",10);
01103    if (markerstyle == 5) strlcpy(chtemp, " m5",10);
01104    if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
01105    if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
01106    if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
01107 
01108    // Set the PostScript marker size
01109    if (markerstyle == 1) {
01110       markersize = 2.;
01111    } else if (markerstyle == 6) {
01112       markersize = 4.;
01113    } else if (markerstyle == 7) {
01114       markersize = 8.;
01115    } else {
01116       Float_t symbolsize  = fMarkerSize;
01117       const Int_t kBASEMARKER = 8;
01118       Float_t sbase = symbolsize*kBASEMARKER;
01119       Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
01120       markersize = this->UtoPS(s2x) - this->UtoPS(0);
01121    }
01122 
01123    if (fMarkerSizeCur != markersize) {
01124       fMarkerSizeCur = markersize;
01125       PrintFast(3," /w");
01126       WriteInteger(Int_t(markersize+0.5));
01127       PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
01128    }
01129 
01130    WriteInteger(XtoPS(x[0]));
01131    WriteInteger(YtoPS(y[0]));
01132    if (n == 1) {
01133       PrintStr(chtemp);
01134       SetLineStyle(linestylesav);
01135       SetLineWidth(linewidthsav);
01136       return;
01137    }
01138    np = 1;
01139    for (i=1;i<n;i++) {
01140       WriteInteger(XtoPS(x[i]));
01141       WriteInteger(YtoPS(y[i]));
01142       np++;
01143       if (np == 100 || i == n-1) {
01144          WriteInteger(np);
01145          PrintFast(2," {");
01146          PrintStr(chtemp);
01147          PrintFast(3,"} R");
01148          np = 0;
01149       }
01150    }
01151    SetLineStyle(linestylesav);
01152    SetLineWidth(linewidthsav);
01153 }
01154 
01155 
01156 //______________________________________________________________________________
01157 void TPostScript::DrawPS(Int_t nn, Float_t *xw, Float_t *yw)
01158 {
01159    // Draw a PolyLine
01160    //
01161    //  Draw a polyline through the points xw,yw.
01162    //  If nn=1 moves only to point xw,yw.
01163    //  If nn=0 the XW(1) and YW(1) are  written  in the PostScript file
01164    //          according to the current NT.
01165    //  If nn>0 the line is clipped as a line.
01166    //  If nn<0 the line is clipped as a fill area.
01167 
01168    static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
01169                                  .01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,
01170                                  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
01171    static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
01172                                     180, 90,135, 45,150, 30,120, 60,
01173                                     180, 90,135, 45,150, 30,120, 60};
01174    Int_t  i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
01175    fais = fasi = n = 0;
01176    Int_t jxd0 = XtoPS(xw[0]);
01177    Int_t jyd0 = YtoPS(yw[0]);
01178    Style_t linestylesav = fLineStyle;
01179    Width_t linewidthsav = fLineWidth;
01180 
01181    if (nn > 0) {
01182       n = nn;
01183       SetLineStyle(fLineStyle);
01184       SetLineWidth(fLineWidth);
01185       SetColor(Int_t(fLineColor));
01186    }
01187    if (nn < 0) {
01188       n = -nn;
01189       SetLineStyle(1);
01190       SetLineWidth(1);
01191       SetColor(Int_t(fFillColor));
01192       fais = fFillStyle/1000;
01193       fasi = fFillStyle%1000;
01194       if (fais == 3 || fais == 2) {
01195          if (fasi > 100 && fasi <125) {
01196             DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
01197             goto END;
01198          }
01199          if (fasi > 0 && fasi < 26) {
01200             SetFillPatterns(fasi, Int_t(fFillColor));
01201          }
01202       }
01203    }
01204 
01205    ixd0 = jxd0;
01206    iyd0 = jyd0;
01207    WriteInteger(ixd0);
01208    WriteInteger(iyd0);
01209    if( n <= 1) {
01210       if( n == 0) goto END;
01211       PrintFast(2," m");
01212       goto END;
01213    }
01214 
01215    PrintFast(2," m");
01216    idx = idy = 0;
01217    for (i=1;i<n;i++) {
01218       ixdi = XtoPS(xw[i]);
01219       iydi = YtoPS(yw[i]);
01220       ix   = ixdi - ixd0;
01221       iy   = iydi - iyd0;
01222       ixd0 = ixdi;
01223       iyd0 = iydi;
01224       if( ix && iy) {
01225          if( idx ) { MovePS(idx,0); idx = 0; }
01226          if( idy ) { MovePS(0,idy); idy = 0; }
01227          MovePS(ix,iy);
01228       } else if ( ix ) {
01229          if( idy )  { MovePS(0,idy); idy = 0;}
01230          if( !idx ) { idx = ix;}
01231          else if( TMath::Sign(ix,idx) == ix )       idx += ix;
01232          else { MovePS(idx,0);  idx  = ix;}
01233       } else if( iy ) {
01234          if( idx ) { MovePS(idx,0); idx = 0;}
01235          if( !idy) { idy = iy;}
01236          else if( TMath::Sign(iy,idy) == iy)         idy += iy;
01237          else { MovePS(0,idy);    idy  = iy;}
01238       }
01239    }
01240    if (idx) MovePS(idx,0);
01241    if (idy) MovePS(0,idy);
01242 
01243    if (nn > 0 ) {
01244       if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
01245       PrintFast(2," s");
01246    } else {
01247       if (fais == 0) {PrintFast(5," cl s"); goto END;}
01248       if (fais == 3 || fais == 2) {
01249          if (fasi > 0 && fasi < 26) {
01250             PrintFast(3," FA");
01251             fRed   = -1;
01252             fGreen = -1;
01253             fBlue  = -1;
01254          }
01255          goto END;
01256       }
01257       PrintFast(2," f");
01258    }
01259 END:
01260    if (nn < 0) {
01261       SetLineStyle(linestylesav);
01262       SetLineWidth(linewidthsav);
01263    }
01264 }
01265 
01266 
01267 //______________________________________________________________________________
01268 void TPostScript::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
01269 {
01270    // Draw a PolyLine
01271    //
01272    // Draw a polyline through  the points xw,yw.
01273    // If nn=1 moves only to point xw,yw.
01274    // If nn=0 the xw(1) and YW(1) are  written  in the PostScript file
01275    //         according to the current NT.
01276    // If nn>0 the line is clipped as a line.
01277    // If nn<0 the line is clipped as a fill area.
01278 
01279    static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
01280                                  .01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,
01281                                  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
01282    static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
01283                                     180, 90,135, 45,150, 30,120, 60,
01284                                     180, 90,135, 45,150, 30,120, 60};
01285    Int_t  i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
01286    fais = fasi = n = 0;
01287    Int_t jxd0 = XtoPS(xw[0]);
01288    Int_t jyd0 = YtoPS(yw[0]);
01289    Style_t linestylesav = fLineStyle;
01290    Width_t linewidthsav = fLineWidth;
01291 
01292    if (nn > 0) {
01293       n = nn;
01294       SetLineStyle(fLineStyle);
01295       SetLineWidth(fLineWidth);
01296       SetColor(Int_t(fLineColor));
01297    }
01298    if (nn < 0) {
01299       n = -nn;
01300       SetLineStyle(1);
01301       SetLineWidth(1);
01302       SetColor(Int_t(fFillColor));
01303       fais = fFillStyle/1000;
01304       fasi = fFillStyle%1000;
01305       if (fais == 3 || fais == 2) {
01306          if (fasi > 100 && fasi <125) {
01307             DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
01308             goto END;
01309          }
01310          if (fasi > 0 && fasi < 26) {
01311             SetFillPatterns(fasi, Int_t(fFillColor));
01312          }
01313       }
01314    }
01315 
01316    ixd0 = jxd0;
01317    iyd0 = jyd0;
01318    WriteInteger(ixd0);
01319    WriteInteger(iyd0);
01320    if( n <= 1) {
01321       if( n == 0) goto END;
01322       PrintFast(2," m");
01323       goto END;
01324    }
01325 
01326    PrintFast(2," m");
01327    idx = idy = 0;
01328    for (i=1;i<n;i++) {
01329       ixdi = XtoPS(xw[i]);
01330       iydi = YtoPS(yw[i]);
01331       ix   = ixdi - ixd0;
01332       iy   = iydi - iyd0;
01333       ixd0 = ixdi;
01334       iyd0 = iydi;
01335       if( ix && iy) {
01336          if( idx ) { MovePS(idx,0); idx = 0; }
01337          if( idy ) { MovePS(0,idy); idy = 0; }
01338          MovePS(ix,iy);
01339       } else if ( ix ) {
01340          if( idy )  { MovePS(0,idy); idy = 0;}
01341          if( !idx ) { idx = ix;}
01342          else if( TMath::Sign(ix,idx) == ix )       idx += ix;
01343          else { MovePS(idx,0);  idx  = ix;}
01344       } else if( iy ) {
01345          if( idx ) { MovePS(idx,0); idx = 0;}
01346          if( !idy) { idy = iy;}
01347          else if( TMath::Sign(iy,idy) == iy)         idy += iy;
01348          else { MovePS(0,idy);    idy  = iy;}
01349       }
01350    }
01351    if (idx) MovePS(idx,0);
01352    if (idy) MovePS(0,idy);
01353 
01354    if (nn > 0 ) {
01355       if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
01356       PrintFast(2," s");
01357    } else {
01358       if (fais == 0) {PrintFast(5," cl s"); goto END;}
01359       if (fais == 3 || fais == 2) {
01360          if (fasi > 0 && fasi < 26) {
01361             PrintFast(3," FA");
01362             fRed   = -1;
01363             fGreen = -1;
01364             fBlue  = -1;
01365          }
01366          goto END;
01367       }
01368       PrintFast(2," f");
01369    }
01370 END:
01371    if (nn < 0) {
01372       SetLineStyle(linestylesav);
01373       SetLineWidth(linewidthsav);
01374    }
01375 }
01376 
01377 
01378 //______________________________________________________________________________
01379 void TPostScript::DrawHatch(Float_t, Float_t, Int_t, Float_t *, Float_t *)
01380 {
01381    // Draw Fill area with hatch styles
01382 
01383    Warning("DrawHatch", "hatch fill style not yet implemented");
01384 }
01385 
01386 
01387 //______________________________________________________________________________
01388 void TPostScript::DrawHatch(Float_t, Float_t, Int_t, Double_t *, Double_t *)
01389 {
01390    // Draw Fill area with hatch styles
01391 
01392    Warning("DrawHatch", "hatch fill style not yet implemented");
01393 }
01394 
01395 
01396 //______________________________________________________________________________
01397 void TPostScript::FontEncode()
01398 {
01399    // Font Reencoding
01400 
01401    PrintStr("/reEncode ");
01402    PrintStr("{exch findfont");
01403    PrintStr(" dup length dict begin");
01404    PrintStr(" {1 index /FID eq ");
01405    PrintStr(" {pop pop}");
01406    PrintStr(" {def} ifelse");
01407    PrintStr(" } forall");
01408    PrintStr(" /Encoding exch def");
01409    PrintStr(" currentdict end");
01410    PrintStr(" dup /FontName get exch");
01411    PrintStr(" definefont pop");
01412    PrintStr(" } def");
01413    PrintStr(" [/Times-Bold /Times-Italic /Times-BoldItalic /Helvetica");
01414    PrintStr(" /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique");
01415    PrintStr(" /Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique");
01416    PrintStr(" /Times-Roman /AvantGarde-Book /AvantGarde-BookOblique");
01417    PrintStr(" /AvantGarde-Demi /AvantGarde-DemiOblique /Bookman-Demi");
01418    PrintStr(" /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic");
01419    PrintStr(" /Helvetica-Narrow /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique");
01420    PrintStr(" /Helvetica-Narrow-Oblique /NewCenturySchlbk-Roman /NewCenturySchlbk-Bold");
01421    PrintStr(" /NewCenturySchlbk-BoldItalic /NewCenturySchlbk-Italic");
01422    PrintStr(" /Palatino-Bold /Palatino-BoldItalic /Palatino-Italic /Palatino-Roman");
01423    PrintStr(" ] {ISOLatin1Encoding reEncode } forall");
01424 }
01425 
01426 
01427 //______________________________________________________________________________
01428 void TPostScript::Initialize()
01429 {
01430    // PostScript Initialisation
01431    //
01432    // This routine initialize the following PostScript procedures:
01433    //
01434    // +------------+------------------+-----------------------------------+
01435    // | Macro Name | Input parameters |            Explanation            |
01436    // +------------+------------------+-----------------------------------+
01437    // |     l      | x y              | Draw a line to the x y position   |
01438    // +------------+------------------+-----------------------------------+
01439    // |     m      | x y              | Move to the position x y          |
01440    // +------------+------------------+-----------------------------------+
01441    // |     box    | dx dy x y        | Define a box                      |
01442    // +------------+------------------+-----------------------------------+
01443    // |     bl     | dx dy x y        | Draw a line box                   |
01444    // +------------+------------------+-----------------------------------+
01445    // |     bf     | dx dy x y        | Draw a filled box                 |
01446    // +------------+------------------+-----------------------------------+
01447    // |     t      | x y              | Translate                         |
01448    // +------------+------------------+-----------------------------------+
01449    // |     r      | angle            | Rotate                            |
01450    // +------------+------------------+-----------------------------------+
01451    // |     rl     | i j              | Roll the stack                    |
01452    // +------------+------------------+-----------------------------------+
01453    // |     d      | x y              | Draw a relative line to x y       |
01454    // +------------+------------------+-----------------------------------+
01455    // |     X      | x                | Draw a relative line to x (y=0)   |
01456    // +------------+------------------+-----------------------------------+
01457    // |     Y      | y                | Draw a relative line to y (x=0)   |
01458    // +------------+------------------+-----------------------------------+
01459    // |     rm     | x y              | Move relatively to x y            |
01460    // +------------+------------------+-----------------------------------+
01461    // |     gr     |                  | Restore the graphic context       |
01462    // +------------+------------------+-----------------------------------+
01463    // |     lw     | lwidth           | Set line width to lwidth          |
01464    // +------------+------------------+-----------------------------------+
01465    // |     sd     | [] 0             | Set dash line define by []        |
01466    // +------------+------------------+-----------------------------------+
01467    // |     s      |                  | Stroke mode                       |
01468    // +------------+------------------+-----------------------------------+
01469    // |     c      | r g b            | Set rgb color to r g b            |
01470    // +------------+------------------+-----------------------------------+
01471    // |     cl     |                  | Close path                        |
01472    // +------------+------------------+-----------------------------------+
01473    // |     f      |                  | Fill the last describe path       |
01474    // +------------+------------------+-----------------------------------+
01475    // |     mXX    | x y              | Draw the marker type XX at (x,y)  |
01476    // +------------+------------------+-----------------------------------+
01477    // |     Zone   | ix iy            | Define the current zone           |
01478    // +------------+------------------+-----------------------------------+
01479    // |     black  |                  | The color is black                |
01480    // +------------+------------------+-----------------------------------+
01481    // |     C      | dx dy x y        | Clipping on                       |
01482    // +------------+------------------+-----------------------------------+
01483    // |     NC     |                  | Clipping off                      |
01484    // +------------+------------------+-----------------------------------+
01485    // |     R      |                  | repeat                            |
01486    // +------------+------------------+-----------------------------------+
01487    // |     ita    |                  | Used to make the symbols italic   |
01488    // +------------+------------------+-----------------------------------+
01489    // |     K      |                  | kshow                             |
01490    // +------------+------------------+-----------------------------------+
01491 
01492    Double_t rpxmin, rpymin, width, heigth;
01493    rpxmin = rpymin = width = heigth = 0;
01494    Int_t format;
01495    fNpages=1;
01496    for (Int_t i=0;i<32;i++) fPatterns[i]=0;
01497 
01498    // Mode is last digit of PostScript Workstation type
01499    //    mode=1,2 for portrait/landscape black and white
01500    //    mode=3 for Encapsulated PostScript File
01501    //    mode=4 for portrait colour
01502    //    mode=5 for lanscape colour
01503    Int_t atype = abs(fType);
01504    fMode       = atype%10;
01505    if( fMode <= 0 || fMode > 5) {
01506       Error("Initialize", "invalid file type %d", fMode);
01507       return;
01508    }
01509 
01510    // fNXzone (fNYzone) is the total number of windows in x (y)
01511    fNXzone = (atype%1000)/100;
01512    fNYzone = (atype%100)/10;
01513    if( fNXzone <= 0 ) fNXzone = 1;
01514    if( fNYzone <= 0 ) fNYzone = 1;
01515    fIXzone = 1;
01516    fIYzone = 1;
01517 
01518    // format = 0-99 is the European page format (A4,A3 ...)
01519    // format = 100 is the US format  8.5x11.0 inch
01520    // format = 200 is the US format  8.5x14.0 inch
01521    // format = 300 is the US format 11.0x17.0 inch
01522    format = atype/1000;
01523    if( format == 0 )  format = 4;
01524    if( format == 99 ) format = 0;
01525 
01526    PrintStr("%%Title: ");
01527    const char *pstitle = gStyle->GetTitlePS();
01528    if (gPad && !strlen(pstitle)) pstitle = gPad->GetMother()->GetTitle();
01529    if (strlen(GetName())<=80) PrintStr(GetName());
01530    if(!strlen(pstitle) && fMode != 3) {;
01531       PrintFast(2," (");
01532       if ( format <= 99 ) {;
01533          PrintFast(2," A");
01534          WriteInteger(format);
01535          PrintFast(1,")");
01536       }
01537       else {
01538          if ( format == 100 ) PrintFast(8," Letter)");
01539          if ( format == 200 ) PrintFast(7," Legal)");
01540          if ( format == 300 ) PrintFast(8," Ledger)");
01541       }
01542       PrintStr("@");
01543       PrintStr("%%Pages: (atend)@");
01544    }
01545    else {
01546          if (!strchr(pstitle,'\n')) {
01547          PrintFast(2,": ");
01548          PrintStr(pstitle);
01549       }
01550       PrintStr("@");
01551    }
01552 
01553    PrintFast(24,"%%Creator: ROOT Version ");
01554    PrintStr(gROOT->GetVersion());
01555    PrintStr("@");
01556    PrintFast(16,"%%CreationDate: ");
01557    TDatime t;
01558    PrintStr(t.AsString());
01559    PrintStr("@");
01560 
01561    if ( fMode == 1 || fMode == 4) PrintStr("%%Orientation: Portrait@");
01562    if ( fMode == 2 || fMode == 5) PrintStr("%%Orientation: Landscape@");
01563 
01564    PrintStr("%%EndComments@");
01565    PrintStr("%%BeginProlog@");
01566 
01567    if( fMode == 3)PrintStr("80 dict begin@");
01568 
01569    // Initialization of PostScript procedures
01570    PrintStr("/s {stroke} def /l {lineto} def /m {moveto} def /t {translate} def@");
01571    PrintStr("/r {rotate} def /rl {roll}  def /R {repeat} def@");
01572    PrintStr("/d {rlineto} def /rm {rmoveto} def /gr {grestore} def /f {eofill} def@");
01573    if (gStyle->GetColorModelPS()) {
01574       PrintStr("/c {setcmykcolor} def /black {0 0 0 1 setcmykcolor} def /sd {setdash} def@");
01575    } else {
01576       PrintStr("/c {setrgbcolor} def /black {0 setgray} def /sd {setdash} def@");
01577    }
01578    PrintStr("/cl {closepath} def /sf {scalefont setfont} def /lw {setlinewidth} def@");
01579    PrintStr("/box {m dup 0 exch d exch 0 d 0 exch neg d cl} def@");
01580    PrintStr("/NC{systemdict begin initclip end}def/C{NC box clip newpath}def@");
01581    PrintStr("/bl {box s} def /bf {box f} def /Y { 0 exch d} def /X { 0 d} def @");
01582    PrintStr("/K {{pop pop 0 moveto} exch kshow} bind def@");
01583    PrintStr("/ita {/ang 15 def gsave [1 0 ang dup sin exch cos div 1 0 0] concat} def @");
01584 
01585    DefineMarkers();
01586    FontEncode();
01587 
01588    // mode=1 for portrait black/white
01589    if (fMode == 1)  {
01590       rpxmin = 0.7;
01591       rpymin = TMath::Sqrt(2.)*rpxmin;
01592       switch (format) {
01593          case 100 :
01594             width  = (8.5*2.54)-2.*rpxmin;
01595             heigth = (11.*2.54)-2.*rpymin;
01596             break;
01597          case 200 :
01598             width  = (8.5*2.54)-2.*rpxmin;
01599             heigth = (14.*2.54)-2.*rpymin;
01600             break;
01601          case 300 :
01602             width  = (11.*2.54)-2.*rpxmin;
01603             heigth = (17.*2.54)-2.*rpymin;
01604             break;
01605          default  :
01606             width  = 21.0-2.*rpxmin;
01607             heigth = 29.7-2.*rpymin;
01608       };
01609    }
01610 
01611    // mode=2 for landscape black/white
01612    if (fMode == 2)  {
01613       rpymin = 0.7;
01614       rpxmin = TMath::Sqrt(2.)*rpymin;
01615       switch (format) {
01616          case 100 :
01617             width  = (11.*2.54)-2.*rpxmin;
01618             heigth = (8.5*2.54)-2.*rpymin;
01619          case 200 :
01620             width  = (14.*2.54)-2.*rpxmin;
01621             heigth = (8.5*2.54)-2.*rpymin;
01622          case 300 :
01623             width  = (17.*2.54)-2.*rpxmin;
01624             heigth = (11.*2.54)-2.*rpymin;
01625          default  :
01626             width  = 29.7-2.*rpxmin;
01627             heigth = 21-2.*rpymin;
01628       };
01629    }
01630 
01631    // mode=3 encapsulated PostScript
01632    if (fMode == 3)  {
01633       width   = 20;
01634       heigth  = 20;
01635       format  = 4;
01636       fNXzone = 1;
01637       fNYzone = 1;
01638    }
01639 
01640    // mode=4 for portrait colour
01641    if (fMode == 4)  {
01642       rpxmin = 0.7;
01643       rpymin = 3.4;
01644       switch (format) {
01645          case 100 :
01646             width  = (8.5*2.54)-2.*rpxmin;
01647             heigth = (11.*2.54)-2.*rpymin;
01648          case 200 :
01649             width  = (8.5*2.54)-2.*rpxmin;
01650             heigth = (14.*2.54)-2.*rpymin;
01651          case 300 :
01652             width  = (11.*2.54)-2.*rpxmin;
01653             heigth = (17.*2.54)-2.*rpymin;
01654          default  :
01655             width  = (21.0-2*rpxmin);
01656             heigth = (29.7-2.*rpymin);
01657       };
01658    }
01659 
01660    // mode=5 for lanscape colour
01661    if (fMode == 5)  {
01662       rpxmin = 3.4;
01663       rpymin = 0.7;
01664       switch (format) {
01665          case 100 :
01666             width  = (11.*2.54)-2.*rpxmin;
01667             heigth = (8.5*2.54)-2.*rpymin;
01668          case 200 :
01669             width  = (14.*2.54)-2.*rpxmin;
01670             heigth = (8.5*2.54)-2.*rpymin;
01671          case 300 :
01672             width  = (17.*2.54)-2.*rpxmin;
01673             heigth = (11.*2.54)-2.*rpymin;
01674          default  :
01675             width  = (29.7-2*rpxmin);
01676             heigth = (21-2.*rpymin);
01677       };
01678    }
01679 
01680    Double_t value = 0;
01681    if       (format <  100) value = 21*TMath::Power(TMath::Sqrt(2.), 4-format);
01682    else  if (format == 100) value = 8.5*2.54;
01683    else  if (format == 200) value = 8.5*2.54;
01684    else  if (format == 300) value = 11.*2.54;
01685    if       (format >= 100) format = 4;
01686 
01687    // Compute size (in points) of the window for each picture = f(fNXzone,fNYzone)
01688    Double_t sizex = width/Double_t(fNXzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
01689    Double_t sizey = heigth/Double_t(fNYzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
01690    Int_t npx      = 4*CMtoPS(sizex);
01691    Int_t npy      = 4*CMtoPS(sizey);
01692    if (sizex > sizey) fMaxsize = CMtoPS(sizex);
01693    else               fMaxsize = CMtoPS(sizey);
01694 
01695    // Procedure Zone
01696    if (fMode != 3)  {
01697       PrintFast(33,"/Zone {/iy exch def /ix exch def ");
01698       PrintFast(10," ix 1 sub ");
01699       WriteInteger(npx);
01700       PrintFast(5," mul ");
01701       WriteReal(Float_t(fNYzone));
01702       PrintFast(8," iy sub ");
01703       WriteInteger(npy);
01704       PrintStr(" mul t} def@");
01705    }
01706 
01707    PrintStr("%%EndProlog@");
01708    PrintStr("%%BeginSetup@");
01709    PrintStr("%%EndSetup@");
01710    PrintFast(8,"newpath ");
01711    SaveRestore(1);
01712    if (fMode == 1 || fMode == 4)  {
01713       WriteInteger(CMtoPS(rpxmin));
01714       WriteInteger(CMtoPS(rpymin));
01715       PrintFast(2," t");
01716    }
01717    if (fMode == 2 || fMode == 5)  {
01718       PrintFast(7," 90 r 0");
01719       WriteInteger(CMtoPS(-value));
01720       PrintFast(3," t ");
01721       WriteInteger(CMtoPS(rpxmin));
01722       WriteInteger(CMtoPS(rpymin));
01723       PrintFast(2," t");
01724    }
01725 
01726    PrintFast(15," .25 .25 scale ");
01727    if (fMode != 3) {
01728       SaveRestore(1);
01729       PrintStr("@");
01730       PrintStr("%%Page: 1 1@");
01731       SaveRestore(1);
01732    }
01733 
01734    //Check is user has defined a special header in the current style
01735    Int_t nh = strlen(gStyle->GetHeaderPS());
01736    if (nh) {
01737       PrintFast(nh,gStyle->GetHeaderPS());
01738       if (fMode != 3) SaveRestore(1);
01739    }
01740 }
01741 
01742 
01743 //______________________________________________________________________________
01744 void TPostScript::MovePS(Int_t ix, Int_t iy)
01745 {
01746    // Move to a new position
01747 
01748    if (ix != 0 && iy != 0)  {
01749       WriteInteger(ix);
01750       WriteInteger(iy);
01751       PrintFast(2," d");
01752    } else if (ix != 0)  {
01753       WriteInteger(ix);
01754       PrintFast(2," X");
01755    } else if (iy != 0)  {
01756       WriteInteger(iy);
01757       PrintFast(2," Y");
01758    }
01759 }
01760 
01761 
01762 //______________________________________________________________________________
01763 void TPostScript::NewPage()
01764 {
01765    // Move to a new PostScript page
01766 
01767    //   Compute pad conversion coefficients
01768    if (gPad) {
01769 //     if (!gPad->GetPadPaint()) gPad->Update();
01770       Double_t ww   = gPad->GetWw();
01771       Double_t wh   = gPad->GetWh();
01772       fYsize       = fXsize*wh/ww;
01773    } else fYsize = 27;
01774 
01775    if(fType  == 113 && !fBoundingBox) {
01776       Bool_t psave = fPrinted;
01777       PrintStr("@%%BoundingBox: ");
01778       Double_t xlow=0, ylow=0, xup=1, yup=1;
01779       if (gPad) {
01780          xlow = gPad->GetAbsXlowNDC();
01781          xup  = xlow + gPad->GetAbsWNDC();
01782          ylow = gPad->GetAbsYlowNDC();
01783          yup  = ylow + gPad->GetAbsHNDC();
01784       }
01785       WriteInteger(CMtoPS(fXsize*xlow));
01786       WriteInteger(CMtoPS(fYsize*ylow));
01787       WriteInteger(CMtoPS(fXsize*xup));
01788       WriteInteger(CMtoPS(fYsize*yup));
01789       PrintStr("@");
01790       Initialize();
01791       fBoundingBox  = kTRUE;
01792       fPrinted      = psave;
01793    }
01794    if (fPrinted) {
01795       if (fSave) SaveRestore(-1);
01796       fClear    = kTRUE;
01797       fPrinted  = kFALSE;
01798    }
01799    Zone();
01800 }
01801 
01802 
01803 //______________________________________________________________________________
01804 void TPostScript::Range(Float_t xsize, Float_t ysize)
01805 {
01806    // Set the range for the paper in centimeters
01807 
01808    Float_t xps=0, yps=0, xncm=0, yncm=0, dxwn=0, dywn=0, xwkwn=0, ywkwn=0, xymax=0;
01809 
01810    fXsize = xsize;
01811    fYsize = ysize;
01812    if( fType != 113) { xps = fXsize;  yps = fYsize; }
01813    else {              xps = xsize;   yps = ysize; }
01814 
01815    if( xsize <= xps && ysize < yps) {
01816       if ( xps > yps ) xymax = xps;
01817       else             xymax = yps;
01818       xncm  = xsize/xymax;
01819       yncm  = ysize/xymax;
01820       dxwn  = ((xps/xymax)-xncm)/2;
01821       dywn  = ((yps/xymax)-yncm)/2;
01822    } else {
01823       if (xps/yps < 1) xwkwn = xps/yps;
01824       else             xwkwn = 1;
01825       if (yps/xps < 1) ywkwn = yps/xps;
01826       else             ywkwn = 1;
01827 
01828       if (xsize < ysize)  {
01829          xncm = ywkwn*xsize/ysize;
01830          yncm = ywkwn;
01831          dxwn = (xwkwn-xncm)/2;
01832          dywn = 0;
01833          if( dxwn < 0) {
01834             xncm = xwkwn;
01835             dxwn = 0;
01836             yncm = xwkwn*ysize/xsize;
01837             dywn = (ywkwn-yncm)/2;
01838          }
01839       } else {
01840          xncm = xwkwn;
01841          yncm = xwkwn*ysize/xsize;
01842          dxwn = 0;
01843          dywn = (ywkwn-yncm)/2;
01844          if( dywn < 0) {
01845             yncm = ywkwn;
01846             dywn = 0;
01847             xncm = ywkwn*xsize/ysize;
01848             dxwn = (xwkwn-xncm)/2;
01849          }
01850       }
01851    }
01852    fXVP1  = dxwn;
01853    fXVP2  = xncm+dxwn;
01854    fYVP1  = dywn;
01855    fYVP2  = yncm+dywn;
01856    fRange = kTRUE;
01857 }
01858 
01859 
01860 //______________________________________________________________________________
01861 void TPostScript::SaveRestore(Int_t flag)
01862 {
01863    // Compute number of gsaves for restore
01864    // This allows to write the correct number of grestore at the
01865    // end of the PS file.
01866 
01867    if (flag == 1) { PrintFast(7," gsave ");  fSave++; }
01868    else           { PrintFast(4," gr ");     fSave--; }
01869 }
01870 
01871 
01872 //______________________________________________________________________________
01873 void TPostScript::SetFillColor( Color_t cindex )
01874 {
01875    // Set color index for fill areas
01876 
01877    fFillColor = cindex;
01878    if (gStyle->GetFillColor() <= 0) cindex = 0;
01879    SetColor(Int_t(cindex));
01880 }
01881 
01882 
01883 //______________________________________________________________________________
01884 void TPostScript::SetFillPatterns(Int_t ipat, Int_t color)
01885 {
01886    // Patterns definition
01887    //
01888    // Define the pattern ipat in the current PS file. ipat can vary from
01889    // 1 to 25. Together with the pattern, the color (color) in which the
01890    // pattern has to be drawn is also required. A pattern is defined in the
01891    // current PS file only the first time it is used. Some level 2
01892    // Postscript functions are used, so on level 1 printers, patterns will
01893    // not work. This is not a big problem because patterns are
01894    // defined only if they are used, so if they are not used a PS level 1
01895    // file will not be polluted by level 2 features, and in any case the old
01896    // patterns used a lot of memory which made them almost unusable on old
01897    // level 1 printers. Finally we should say that level 1 devices are
01898    // becoming very rare. The official PostScript is now level 3 !
01899 
01900    char cdef[28];
01901    char cpat[5];
01902    snprintf(cpat,5," P%2.2d", ipat);
01903 
01904    // fPatterns is used as an array of chars. If fPatterns[ipat] != 0 the
01905    // pattern number ipat as already be defined is this file and it
01906    // is not necessary to redefine it. fPatterns is set to zero in Initialize.
01907    // The pattern number 26 allows to know if the macro "cs" has already
01908    // been defined in the current file (see label 200).
01909    if (fPatterns[ipat] == 0) {
01910 
01911    // Define the Patterns. Line width must be 1
01912    // Setting fLineWidth to -1 will force the line width definition next time
01913    // TPostScript::SetLineWidth will be called.
01914       fLineWidth = -1;
01915       PrintFast(5," 1 lw");
01916       PrintStr(" << /PatternType 1 /PaintType 2 /TilingType 1");
01917       switch (ipat) {
01918          case 1 :
01919             PrintStr(" /BBox [ 0 0 100 100 ]");
01920             PrintStr(" /XStep 98 /YStep 4");
01921             PrintStr(" /PaintProc { begin gsave");
01922             PrintStr(" [1] 0 sd 2 4 m 99 4 l s 1 3 m 98 3 l s");
01923             PrintStr(" 2 2 m 99 2 l s 1 1 m 98 1 l s");
01924             PrintStr(" gr end } >> [ 4.0 0 0 4.0 0 0 ]");
01925             break;
01926          case 2 :
01927             PrintStr(" /BBox [ 0 0 100 100 ]");
01928             PrintStr(" /XStep 96 /YStep 4");
01929             PrintStr(" /PaintProc { begin gsave");
01930             PrintStr(" [1 3] 0 sd 2 4 m 98 4 l s 0 3 m 96 3 l s");
01931             PrintStr(" 2 2 m 98 2 l s 0 1 m 96 1 l s");
01932             PrintStr(" gr end } >> [ 3.0 0 0 3.0 0 0 ]");
01933             break;
01934          case 3 :
01935             PrintStr(" /BBox [ 0 0 100 100 ]");
01936             PrintStr(" /XStep 96 /YStep 16");
01937             PrintStr(" /PaintProc { begin gsave");
01938             PrintStr(" [1 3] 0 sd 2 13 m 98 13 l s 0 9 m 96 9 l s");
01939             PrintStr(" 2 5 m 98 5 l s 0 1 m 96 1 l s");
01940             PrintStr(" gr end } >> [ 2.0 0 0 2.0 0 0 ]");
01941             break;
01942          case 4 :
01943             PrintStr(" /BBox [ 0 0 100 100 ]");
01944             PrintStr(" /XStep 100 /YStep 100");
01945             PrintStr(" /PaintProc { begin gsave");
01946             PrintStr(" 0 0 m 100 100 l s");
01947             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
01948             break;
01949          case 5 :
01950             PrintStr(" /BBox [ 0 0 100 100 ]");
01951             PrintStr(" /XStep 100 /YStep 100");
01952             PrintStr(" /PaintProc { begin gsave");
01953             PrintStr(" 0 100 m 100 0 l s");
01954             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
01955             break;
01956          case 6 :
01957             PrintStr(" /BBox [ 0 0 100 100 ]");
01958             PrintStr(" /XStep 100 /YStep 100");
01959             PrintStr(" /PaintProc { begin gsave");
01960             PrintStr(" 50 0 m 50 100 l s");
01961             PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
01962             break;
01963          case 7 :
01964             PrintStr(" /BBox [ 0 0 100 100 ]");
01965             PrintStr(" /XStep 100 /YStep 100");
01966             PrintStr(" /PaintProc { begin gsave");
01967             PrintStr(" 0 50 m 100 50 l s");
01968             PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
01969             break;
01970          case 8 :
01971             PrintStr(" /BBox [ 0 0 101 101 ]");
01972             PrintStr(" /XStep 100 /YStep 100");
01973             PrintStr(" /PaintProc { begin gsave");
01974             PrintStr(" 0 0 m 0 30 l 30 0 l f 0 70 m 0 100 l 30 100 l f");
01975             PrintStr(" 70 100 m 100 100 l 100 70 l f 70 0 m 100 0 l");
01976             PrintStr(" 100 30 l f 50 20 m 20 50 l 50 80 l 80 50 l f");
01977             PrintStr(" 50 80 m 30 100 l s 20 50 m 0 30 l s 50 20 m");
01978             PrintStr(" 70 0 l s 80 50 m 100 70 l s");
01979             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
01980             break;
01981          case 9 :
01982             PrintStr(" /BBox [ 0 0 100 100 ]");
01983             PrintStr(" /XStep 100 /YStep 100");
01984             PrintStr(" /PaintProc { begin gsave");
01985             PrintStr(" 0 50 m 50 50 50 180 360 arc");
01986             PrintStr(" 0 50 m 0 100 50 270 360 arc");
01987             PrintStr(" 50 100 m 100 100 50 180 270 arc s");
01988             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
01989             break;
01990          case 10 :
01991             PrintStr(" /BBox [ 0 0 100 100 ]");
01992             PrintStr(" /XStep 100 /YStep 100");
01993             PrintStr(" /PaintProc { begin gsave");
01994             PrintStr(" 0 50 m 100 50 l 1 1 m 100 1 l");
01995             PrintStr(" 0 0 m 0 50 l 100 0 m 100 50 l");
01996             PrintStr(" 50 50 m 50 100 l s");
01997             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
01998             break;
01999          case 11 :
02000             PrintStr(" /BBox [ 0 0 100 100 ]");
02001             PrintStr(" /XStep 100 /YStep 100");
02002             PrintStr(" /PaintProc { begin gsave");
02003             PrintStr(" 0 0 m 0 20 l 50 0 m 50 20 l");
02004             PrintStr(" 100 0 m 100 20 l 0 80 m 0 100 l");
02005             PrintStr(" 50 80 m 50 100 l 100 80 m 100 100 l");
02006             PrintStr(" 25 30 m 25 70 l 75 30 m 75 70 l");
02007             PrintStr(" 0 100 m 20 85 l 50 100 m 30 85 l");
02008             PrintStr(" 50 100 m 70 85 l 100 100 m 80 85 l");
02009             PrintStr(" 0 0 m 20 15 l 50 0 m 30 15 l");
02010             PrintStr(" 50 0 m 70 15 l 100 0 m 80 15 l");
02011             PrintStr(" 5 35 m 45 65 l 5 65 m 45 35 l");
02012             PrintStr(" 55 35 m 95 65 l 55 65 m 95 35 l s");
02013             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02014             break;
02015          case 12 :
02016             PrintStr(" /BBox [ 0 0 100 100 ]");
02017             PrintStr(" /XStep 100 /YStep 100");
02018             PrintStr(" /PaintProc { begin gsave");
02019             PrintStr(" 0 80 m 0 100 20 270 360 arc");
02020             PrintStr(" 30 100 m 50 100 20 180 360 arc");
02021             PrintStr(" 80 100 m 100 100 20 180 270 arc");
02022             PrintStr(" 20 0 m 0 0 20 0 90 arc");
02023             PrintStr(" 70 0 m 50 0 20 0 180 arc");
02024             PrintStr(" 100 20 m 100 0 20 90 180 arc");
02025             PrintStr(" 45 50 m 25 50 20 0 360 arc");
02026             PrintStr(" 95 50 m 75 50 20 0 360 arc s");
02027             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02028             break;
02029          case 13 :
02030             PrintStr(" /BBox [ 0 0 100 100 ]");
02031             PrintStr(" /XStep 100 /YStep 100");
02032             PrintStr(" /PaintProc { begin gsave");
02033             PrintStr(" 0 0 m 100 100 l 0 100 m 100 0 l s");
02034             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
02035             break;
02036          case 14 :
02037             PrintStr(" /BBox [ 0 0 100 100 ]");
02038             PrintStr(" /XStep 80 /YStep 80");
02039             PrintStr(" /PaintProc { begin gsave");
02040             PrintStr(" 0 20 m 100 20 l 20 0 m 20 100 l");
02041             PrintStr(" 0 80 m 100 80 l 80 0 m 80 100 l");
02042             PrintStr(" 20 40 m 60 40 l 60 20 m 60 60 l");
02043             PrintStr(" 40 40 m 40 80 l 40 60 m 80 60 l s");
02044             PrintStr(" gr end } >> [ 0.60 0 0 0.60 0 0 ]");
02045             break;
02046          case 15 :
02047             PrintStr(" /BBox [ 0 0 60 60 ]");
02048             PrintStr(" /XStep 60 /YStep 60");
02049             PrintStr(" /PaintProc { begin gsave");
02050             PrintStr(" 0 55 m 0 60 5 270 360 arc");
02051             PrintStr(" 25 60 m 30 60 5 180 360 arc");
02052             PrintStr(" 55 60 m 60 60 5 180 270 arc");
02053             PrintStr(" 20 30 m 15 30 5 0 360 arc");
02054             PrintStr(" 50 30 m 45 30 5 0 360");
02055             PrintStr(" arc 5 0 m 0 0 5 0 90 arc");
02056             PrintStr(" 35 0 m 30 0 5 0 180 arc");
02057             PrintStr(" 60 5 m 60 0 5 90 180 arc s");
02058             PrintStr(" gr end } >> [ 0.41 0 0 0.41 0 0 ]");
02059             break;
02060          case 16 :
02061             PrintStr(" /BBox [ 0 0 100 100 ]");
02062             PrintStr(" /XStep 100 /YStep 100");
02063             PrintStr(" /PaintProc { begin gsave");
02064             PrintStr(" 50 50 m 25 50 25 0 180 arc s");
02065             PrintStr(" 50 50 m 75 50 25 180 360 arc s");
02066             PrintStr(" gr end } >> [ 0.4 0 0 0.2 0 0 ]");
02067             break;
02068          case 17 :
02069             PrintStr(" /BBox [ 0 0 100 100 ]");
02070             PrintStr(" /XStep 100 /YStep 100");
02071             PrintStr(" /PaintProc { begin gsave");
02072             PrintStr(" [24] 0 setdash 0 0 m 100 100 l s");
02073             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
02074             break;
02075          case 18 :
02076             PrintStr(" /BBox [ 0 0 100 100 ]");
02077             PrintStr(" /XStep 100 /YStep 100");
02078             PrintStr(" /PaintProc { begin gsave");
02079             PrintStr(" [24] 0 setdash 0 100 m 100 0 l s");
02080             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
02081             break;
02082          case 19 :
02083             PrintStr(" /BBox [ 0 0 100 100 ]");
02084             PrintStr(" /XStep 100 /YStep 100");
02085             PrintStr(" /PaintProc { begin gsave");
02086             PrintStr(" 90 50 m 50 50 40 0 360 arc");
02087             PrintStr(" 0 50 m 0 100 50 270 360 arc");
02088             PrintStr(" 50 0 m 0 0 50 0 90 arc");
02089             PrintStr(" 100 50 m 100 0 50 90 180 arc");
02090             PrintStr(" 50 100 m 100 100 50 180 270 arc s");
02091             PrintStr(" gr end } >> [ 0.47 0 0 0.47 0 0 ]");
02092             break;
02093          case 20 :
02094             PrintStr(" /BBox [ 0 0 100 100 ]");
02095             PrintStr(" /XStep 100 /YStep 100");
02096             PrintStr(" /PaintProc { begin gsave");
02097             PrintStr(" 50 50 m 50 75 25 270 450 arc s");
02098             PrintStr(" 50 50 m 50 25 25 90  270 arc s");
02099             PrintStr(" gr end } >> [ 0.2 0 0 0.4 0 0 ]");
02100             break;
02101          case 21 :
02102             PrintStr(" /BBox [ 0 0 101 101 ]");
02103             PrintStr(" /XStep 100 /YStep 100");
02104             PrintStr(" /PaintProc { begin gsave");
02105             PrintStr(" 1 1 m 25 1 l 25 25 l 50 25 l 50 50 l");
02106             PrintStr(" 75 50 l 75 75 l 100 75 l 100 100 l");
02107             PrintStr(" 50 1 m 75 1 l 75 25 l 100 25 l 100 50 l");
02108             PrintStr(" 0 50 m 25 50 l 25 75 l 50 75 l 50 100 l s");
02109             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02110             break;
02111          case 22 :
02112             PrintStr(" /BBox [ 0 0 101 101 ]");
02113             PrintStr(" /XStep 100 /YStep 100");
02114             PrintStr(" /PaintProc { begin gsave");
02115             PrintStr(" 1 100 m 25 100 l 25 75 l 50 75 l 50 50 l");
02116             PrintStr(" 75 50 l 75 25 l 100 25 l 100 1 l");
02117             PrintStr(" 50 100 m 75 100 l 75 75 l 100 75 l 100 50 l");
02118             PrintStr(" 0 50 m 25 50 l 25 25 l 50 25 l 50 1 l s");
02119             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02120             break;
02121          case 23 :
02122             PrintStr(" /BBox [ 0 0 100 100 ]");
02123             PrintStr(" /XStep 100 /YStep 100");
02124             PrintStr(" /PaintProc { begin gsave");
02125             PrintStr(" [1 7] 0 sd 0 8 50 { dup dup m 2 mul 0 l s } for");
02126             PrintStr(" 0 8 50 { dup dup 2 mul 100 m 50 add exch 50");
02127             PrintStr(" add l s } for 100 0 m 100 100 l 50 50 l f");
02128             PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
02129             break;
02130          case 24 :
02131             PrintStr(" /BBox [ 0 0 100 100 ]");
02132             PrintStr(" /XStep 100 /YStep 100");
02133             PrintStr(" /PaintProc { begin gsave");
02134             PrintStr(" 100 100 m 100 36 l 88 36 l 88 88 l f");
02135             PrintStr(" 100 0 m 100 12 l 56 12 l 50 0 l f");
02136             PrintStr(" 0 0 m 48 0 l 48 48 l 50 48 l 56 60 l");
02137             PrintStr(" 36 60 l 36 12 l 0 12 l f [1 7] 0 sd");
02138             PrintStr(" 61 8 87 { dup dup dup 12 exch m 88 exch l s");
02139             PrintStr(" 16 exch 4 sub m 88 exch 4 sub l s } for");
02140             PrintStr(" 13 8 35 { dup dup dup 0 exch m 36 exch l s");
02141             PrintStr(" 4 exch 4 sub m 36 exch 4 sub l s } for");
02142             PrintStr(" 37 8 59 { dup dup dup 12 exch m 36 exch l s");
02143             PrintStr(" 16 exch 4 sub m 36 exch 4 sub l s } for");
02144             PrintStr(" 13 8 60 { dup dup dup 56 exch m 100 exch l s");
02145             PrintStr(" 60 exch 4 sub m 100 exch 4 sub l s } for");
02146             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02147             break;
02148          case 25 :
02149             PrintStr(" /BBox [ 0 0 101 101 ]");
02150             PrintStr(" /XStep 100 /YStep 100");
02151             PrintStr(" /PaintProc { begin gsave");
02152             PrintStr(" 0 0 m 30 30 l 70 30 l 70 70 l 100 100 l 100 0 l");
02153             PrintStr(" f 30 30 m 30 70 l 70 70 l f");
02154             PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
02155       };
02156       snprintf(cdef,28," makepattern /%s exch def",&cpat[1]);
02157       PrintStr(cdef);
02158       fPatterns[ipat] = 1;
02159    }
02160 
02161    // Define the macro cs and FA if they are not yet defined.
02162    if (fPatterns[26] == 0) {
02163       if (gStyle->GetColorModelPS()) {
02164          PrintStr(" /cs {[/Pattern /DeviceCMYK] setcolorspace} def");
02165          PrintStr(" /FA {f [/DeviceCMYK] setcolorspace} def");
02166       } else {
02167          PrintStr(" /cs {[/Pattern /DeviceRGB] setcolorspace} def");
02168          PrintStr(" /FA {f [/DeviceRGB] setcolorspace} def");
02169       }
02170       fPatterns[26] = 1;
02171    }
02172 
02173    // Activate the pattern.
02174    PrintFast(3," cs");
02175    TColor *col = gROOT->GetColor(color);
02176    if (col) {
02177       Double_t colRed   = col->GetRed();
02178       Double_t colGreen = col->GetGreen();
02179       Double_t colBlue  = col->GetBlue();
02180       if (gStyle->GetColorModelPS()) {
02181          Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
02182          if (colBlack==1) {
02183             WriteReal(0);
02184             WriteReal(0);
02185             WriteReal(0);
02186             WriteReal(colBlack);
02187          } else {
02188             Double_t colCyan    = (1-colRed-colBlack)/(1-colBlack);
02189             Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
02190             Double_t colYellow  = (1-colBlue-colBlack)/(1-colBlack);
02191             WriteReal(colCyan);
02192             WriteReal(colMagenta);
02193             WriteReal(colYellow);
02194             WriteReal(colBlack);
02195          }
02196       } else {
02197          WriteReal(colRed);
02198          WriteReal(colGreen);
02199          WriteReal(colBlue);
02200       }
02201    }
02202    PrintFast(4,cpat);
02203    PrintFast(9," setcolor");
02204 }
02205 
02206 
02207 //______________________________________________________________________________
02208 void TPostScript::SetLineColor( Color_t cindex )
02209 {
02210    // Set color index for lines
02211 
02212    fLineColor = cindex;
02213    SetColor(Int_t(cindex));
02214 }
02215 
02216 
02217 //______________________________________________________________________________
02218 void TPostScript::SetLineJoin( Int_t linejoin )
02219 {
02220    // Set the value of the global parameter TPostScript::fgLineJoin.
02221    // This parameter determines the appearance of joining lines in a PostScript
02222    // output.
02223    // It takes one argument which may be:
02224    //   - 0 (miter join)
02225    //   - 1 (round join)
02226    //   - 2 (bevel join)
02227    // The default value is 0 (miter join).
02228    //
02229    //Begin_Html
02230    /*
02231    <img src="gif/linejoin.gif">
02232    */
02233    //End_Html
02234    //
02235    // To change the line join behaviour just do:
02236    // TPostScript::SetLineJoin(2); // Set the PS line join to bevel.
02237 
02238    fgLineJoin = linejoin;
02239 }
02240 
02241 
02242 //______________________________________________________________________________
02243 void TPostScript::SetLineStyle(Style_t linestyle)
02244 {
02245    // Change the line style
02246    //
02247    //   linestyle = 2 dashed
02248    //             = 3  dotted
02249    //             = 4  dash-dotted
02250    //              else = solid
02251    //
02252    // See TStyle::SetLineStyleString for style definition
02253 
02254    if ( linestyle == fLineStyle) return;
02255    fLineStyle = linestyle;
02256    const char *st = gStyle->GetLineStyleString(linestyle);
02257    PrintFast(1,"[");
02258    Int_t nch = strlen(st);
02259    PrintFast(nch,st);
02260    PrintFast(6,"] 0 sd");
02261 }
02262 
02263 
02264 //______________________________________________________________________________
02265 void TPostScript::SetLineWidth(Width_t linewidth)
02266 {
02267    // Change the line width
02268 
02269    if ( linewidth == fLineWidth) return;
02270    fLineWidth = linewidth;
02271    WriteInteger(Int_t(fLineScale*fLineWidth));
02272    PrintFast(3," lw");
02273 }
02274 
02275 
02276 //______________________________________________________________________________
02277 void TPostScript::SetMarkerColor( Color_t cindex )
02278 {
02279    // Set color index for markers
02280 
02281    fMarkerColor = cindex;
02282    SetColor(Int_t(cindex));
02283 }
02284 
02285 
02286 //______________________________________________________________________________
02287 void TPostScript::SetColor(Int_t color)
02288 {
02289    // Set the current color.
02290 
02291    if (color < 0) color = 0;
02292    fCurrentColor = color;
02293    TColor *col = gROOT->GetColor(color);
02294    if (col)
02295       SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
02296    else
02297       SetColor(1., 1., 1.);
02298 }
02299 
02300 
02301 //______________________________________________________________________________
02302 void TPostScript::SetColor(Float_t r, Float_t g, Float_t b)
02303 {
02304    // Set directly current color (don't go via TColor).
02305 
02306    if (r == fRed && g == fGreen && b == fBlue) return;
02307 
02308    fRed   = r;
02309    fGreen = g;
02310    fBlue  = b;
02311 
02312    if (fRed <= 0 && fGreen <= 0 && fBlue <= 0 ) {
02313       PrintFast(6," black");
02314    } else {
02315       if (gStyle->GetColorModelPS()) {
02316          Double_t colBlack   = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
02317          Double_t colCyan    = (1-fRed-colBlack)/(1-colBlack);
02318          Double_t colMagenta = (1-fGreen-colBlack)/(1-colBlack);
02319          Double_t colYellow  = (1-fBlue-colBlack)/(1-colBlack);
02320          WriteReal(colCyan);
02321          WriteReal(colMagenta);
02322          WriteReal(colYellow);
02323          WriteReal(colBlack);
02324       } else {
02325          WriteReal(fRed);
02326          WriteReal(fGreen);
02327          WriteReal(fBlue);
02328       }
02329       PrintFast(2," c");
02330    }
02331 }
02332 
02333 
02334 //______________________________________________________________________________
02335 void TPostScript::SetTextColor( Color_t cindex )
02336 {
02337    // Set color index for text
02338 
02339    fTextColor = cindex;
02340 
02341    SetColor( Int_t(cindex) );
02342 }
02343 
02344 
02345 //______________________________________________________________________________
02346 void TPostScript::Text(Double_t xx, Double_t yy, const char *chars)
02347 {
02348    // Write a string of characters
02349    //
02350    // This routine writes the string chars into a PostScript file
02351    // at position xx,yy in world coordinates.
02352 
02353    static const char *psfont[] = {
02354     "/Times-Italic"         , "/Times-Bold"         , "/Times-BoldItalic",
02355     "/Helvetica"            , "/Helvetica-Oblique"  , "/Helvetica-Bold"  ,
02356     "/Helvetica-BoldOblique", "/Courier"            , "/Courier-Oblique" ,
02357     "/Courier-Bold"         , "/Courier-BoldOblique", "/Symbol"          ,
02358     "/Times-Roman"          , "/ZapfDingbats"       , "/Symbol"};
02359 
02360    const Double_t kDEGRAD = TMath::Pi()/180.;
02361    Double_t x = xx;
02362    Double_t y = yy;
02363    if (!gPad) return;
02364 
02365    // Compute the font size. Exit if it is 0
02366    // The font size is computed from the TTF size to get exactly the same
02367    // size on the screen and in the PostScript file.
02368    Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
02369    Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
02370    Float_t tsize, ftsize;
02371 
02372    if (wh < hh) {
02373       tsize         = fTextSize*wh;
02374       Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
02375       ftsize        = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
02376    } else {
02377       tsize         = fTextSize*hh;
02378       Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
02379       ftsize        = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
02380    }
02381    Double_t fontsize = 4*(72*(ftsize)/2.54);
02382    if( fontsize <= 0) return;
02383 
02384    Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
02385    Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
02386 
02387    Int_t font = abs(fTextFont)/10;
02388    if( font > 15 || font < 1) font = 1;
02389 
02390    // Text color.
02391    SetColor(Int_t(fTextColor));
02392 
02393    // Text alignment.
02394    Int_t txalh = fTextAlign/10;
02395    if (txalh <1) txalh = 1; if (txalh > 3) txalh = 3;
02396    Int_t txalv = fTextAlign%10;
02397    if (txalv <1) txalv = 1; if (txalv > 3) txalv = 3;
02398    if (txalv == 3) {
02399       y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
02400       x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
02401    } else if (txalv == 2) {
02402       y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
02403       x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
02404    }
02405 
02406    UInt_t w,w0;
02407    Bool_t kerning;
02408    // In order to measure the precise character positions we need to trick
02409    // FreeType into rendering high-resolution characters otherwise it will
02410    // stick to the screen pixel grid, which is far worse than we can achieve
02411    // on print.
02412    const Float_t scale = 16.0;
02413    // Save current text attributes.
02414    TText saveAttText;
02415    saveAttText.TAttText::operator=(*this);
02416    const Int_t len=strlen(chars);
02417    Int_t *charWidthsCumul = 0;
02418    TText t;
02419    t.SetTextSize(fTextSize * scale);
02420    t.SetTextFont(fTextFont);
02421    t.GetTextAdvance(w, chars);
02422    t.GetTextAdvance(w0, chars, kFALSE);
02423    t.TAttText::Modify();
02424    if (w0-w != 0) kerning = kTRUE;
02425    else        kerning = kFALSE;
02426    if (kerning) {
02427       // Calculate the individual character placements.
02428       charWidthsCumul = new Int_t[len];
02429       for (Int_t i = len - 1;i >= 0;i--) {
02430          UInt_t ww;
02431          t.GetTextAdvance(ww, chars + i);
02432          Double_t wwl = (gPad->AbsPixeltoX(ww)-gPad->AbsPixeltoX(0));
02433          charWidthsCumul[i] = (Int_t)((XtoPS(wwl) - XtoPS(0)) / scale);
02434       }
02435    }
02436    // Restore text attributes.
02437    saveAttText.TAttText::Modify();
02438 
02439    Double_t charsLength = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
02440    Int_t psCharsLength = (Int_t)((XtoPS(charsLength)-XtoPS(0)) / scale);
02441 
02442    // Text angle.
02443    Int_t psangle = Int_t(0.5 + fTextAngle);
02444 
02445    // Save context.
02446    PrintStr("@");
02447    SaveRestore(1);
02448 
02449    // Clipping
02450    Int_t xc1 = XtoPS(gPad->GetX1());
02451    Int_t xc2 = XtoPS(gPad->GetX2());
02452    Int_t yc1 = YtoPS(gPad->GetY1());
02453    Int_t yc2 = YtoPS(gPad->GetY2());
02454    WriteInteger(xc2 - xc1);
02455    WriteInteger(yc2 - yc1);
02456    WriteInteger(xc1);
02457    WriteInteger(yc1);
02458    PrintStr(" C");
02459 
02460    // Output text position and angle.
02461    WriteReal(((XtoPS(x * scale) - XtoPS(0)) / scale) + XtoPS(0));
02462    WriteReal(((YtoPS(y * scale) - YtoPS(0)) / scale) + YtoPS(0));
02463    PrintStr(Form(" t %d r ", psangle));
02464    if(txalh == 2) PrintStr(Form(" %d 0 t ", -psCharsLength/2));
02465    if(txalh == 3) PrintStr(Form(" %d 0 t ", -psCharsLength));
02466    PrintStr(psfont[font-1]);
02467    if (font != 15) {
02468      PrintStr(Form(" findfont %g sf 0 0 m ",fontsize));
02469    } else {
02470      PrintStr(Form(" findfont %g sf 0 0 m ita ",fontsize));
02471    }
02472 
02473    if (kerning) {
02474       PrintStr("@");
02475       // Output individual character placements
02476       for (Int_t i = len-1; i >= 1; i--) {
02477          WriteInteger(charWidthsCumul[0] - charWidthsCumul[i]);
02478       }
02479       delete [] charWidthsCumul;
02480       PrintStr("@");
02481    }
02482 
02483    // Output text.
02484    PrintStr("(");
02485 
02486    // Inside a PostScript string, the new line (if needed to break up long lines) must be escaped by a backslash.
02487    const char *crsave = fImplicitCREsc;
02488    fImplicitCREsc = "\\";
02489 
02490    char str[8];
02491    for (Int_t i=0; i<len;i++) {
02492       if (chars[i]!='\n') {
02493          if (chars[i]=='(' || chars[i]==')' || chars[i]=='\\') {
02494             snprintf(str,8,"\\%c",chars[i]);
02495             PrintStr(str);
02496          } else if ((chars[i]=='-') && (font != 12)) {
02497             PrintStr("\\255");
02498          } else {
02499             snprintf(str,8,"%c",chars[i]);
02500             PrintFast(1,str);
02501          }
02502       }
02503    }
02504    PrintStr(")");
02505    fImplicitCREsc = crsave;
02506 
02507    if (kerning) {
02508       if (font != 15) PrintStr(" K NC");
02509       else            PrintStr(" K gr NC");
02510    } else {
02511       if (font != 15) PrintStr(" show NC");
02512       else            PrintStr(" show gr NC");
02513    }
02514 
02515    SaveRestore(-1);
02516 }
02517 
02518 
02519 //______________________________________________________________________________
02520 void TPostScript::TextNDC(Double_t u, Double_t v, const char *chars)
02521 {
02522    // Write a string of characters in NDC
02523 
02524    Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
02525    Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
02526    Text(x, y, chars);
02527 }
02528 
02529 
02530 //______________________________________________________________________________
02531 Int_t TPostScript::UtoPS(Double_t u)
02532 {
02533    // Convert U from NDC coordinate to PostScript
02534 
02535    Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
02536    return Int_t(0.5 + 288*cm/2.54);
02537 }
02538 
02539 
02540 //______________________________________________________________________________
02541 Int_t TPostScript::VtoPS(Double_t v)
02542 {
02543    // Convert V from NDC coordinate to PostScript
02544 
02545    Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
02546    return Int_t(0.5 + 288*cm/2.54);
02547 }
02548 
02549 
02550 //______________________________________________________________________________
02551 Int_t TPostScript::XtoPS(Double_t x)
02552 {
02553    // Convert X from world coordinate to PostScript
02554 
02555    Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
02556    return  UtoPS(u);
02557 }
02558 
02559 
02560 //______________________________________________________________________________
02561 Int_t TPostScript::YtoPS(Double_t y)
02562 {
02563    // Convert Y from world coordinate to PostScript
02564 
02565    Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
02566    return  VtoPS(v);
02567 }
02568 
02569 
02570 //______________________________________________________________________________
02571 void TPostScript::Zone()
02572 {
02573    // Initialize the PostScript page in zones
02574 
02575    if( !fClear )return;
02576    fClear = kFALSE;
02577 
02578    // When Zone has been called, fZone is TRUE
02579    fZone = kTRUE;
02580 
02581    if( fIYzone > fNYzone) {
02582       fIYzone=1;
02583       if( fMode != 3) {
02584          PrintStr("@showpage");
02585          SaveRestore(-1);
02586          fNpages++;
02587          PrintStr("@%%Page:");
02588          WriteInteger(fNpages);
02589          WriteInteger(fNpages);
02590          PrintStr("@");
02591       } else {
02592          PrintFast(9," showpage");
02593          SaveRestore(-1);
02594       }
02595    }
02596 
02597    // No grestore the first time
02598    if( fMode != 3) {
02599       if( fIXzone != 1 || fIYzone != 1) SaveRestore(-1);
02600       SaveRestore(1);
02601       PrintStr("@");
02602       WriteInteger(fIXzone);
02603       WriteInteger(fIYzone);
02604       PrintFast(5," Zone");
02605       PrintStr("@");
02606       fIXzone++;
02607       if( fIXzone > fNXzone) { fIXzone=1; fIYzone++; }
02608    }
02609 
02610    // Picture Initialisation
02611    SaveRestore(1);
02612    if (fgLineJoin) {
02613       WriteInteger(fgLineJoin);
02614       PrintFast(12," setlinejoin");
02615    }
02616    PrintFast(6," 0 0 t");
02617    fRed     = -1;
02618    fGreen   = -1;
02619    fBlue    = -1;
02620    fPrinted = kFALSE;
02621    fLineColor  = -1;
02622    fLineStyle  = -1;
02623    fLineWidth  = -1;
02624    fFillColor  = -1;
02625    fFillStyle  = -1;
02626    fMarkerSizeCur = -1;
02627 }

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