ROOT  6.06/09
Reference Guide
TPostScript.cxx
Go to the documentation of this file.
1 // @(#)root/postscript:$Id$
2 // Author: Rene Brun, Olivier Couet, Pierre Juillot, Oleksandr Grebenyuk, Yue Shi Lai
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TPostScript
13 \ingroup PS
14 
15 Interface to PostScript.
16 
17 To generate a Postscript (or encapsulated ps) file corresponding to
18 a single image in a canvas, you can:
19 
20  - Select the <B>Print PostScript</B> item in the canvas <B>File</B> menu.
21  By default, a Postscript file with the name of the canvas.ps is generated.
22  - Click in the canvas area, near the edges, with the right mouse button
23  and select the <B>Print</B> item. You can select the name of the Postscript
24  file. If the file name is xxx.ps, you will generate a Postscript file named
25  xxx.ps. If the file name is xxx.eps, you generate an encapsulated Postscript
26  file instead.
27  - In your program (or macro), you can type:
28 ~~~ {.cpp}
29  c1->Print("xxx.ps")</B> or <B>c1->Print("xxx.eps").
30 ~~~
31  This will generate a file corresponding to the picture in the canvas
32  pointed by `c1`.
33 ~~~ {.cpp}
34  pad1->Print("xxx.ps");
35 ~~~
36  prints only the picture in the pad pointed by `pad1`.
37 
38 The size of the Postscript picture, by default, is computed to keep the aspect
39 ratio of the picture on the screen, where the size along x is always 20cm. You
40 can set the size of the PostScript picture before generating the picture
41 with a command such as:
42 
43 ~~~ {.cpp}
44  TPostScript myps("myfile.ps",111)
45  myps.Range(xsize,ysize);
46  object->Draw();
47  myps.Close();
48 ~~~
49 You can set the default paper size with:
50  ~~~ {.cpp}
51  gStyle->SetPaperSize(xsize,ysize);
52  ~~~
53 You can resume writing again in this file with `myps.Open();`.
54 Note that you may have several Postscript files opened simultaneously.
55 
56  ## Output type
57 
58 The output type allows to define how the PostScript output will looks like.
59 It allows to define the page format (A4, Legal etc..), the orientation
60 (Portrait, Landscape) and the number of images (zones) per page.
61 The output type has the following form:
62 
63 ~~~ {.cpp}
64  [Format][Nx][Ny][Type]
65 ~~~
66 
67 Where:
68 
69  - Format : Is an integer between 0 and 99 defining the page format:
70 ~~~ {.cpp}
71  Format = 3 the paper is in the standard A3 format.
72  Format = n (1<n<98) is an An format.
73  Format = 4 and Format=0 are the same and define an A4 page.
74  The A0 format is selected by Format=99.
75  The US format Letter is selected by Format = 100.
76  The US format Legal is selected by Format = 200.
77  The US format Ledger is selected by Format = 300.
78 ~~~
79  - Nx, Ny : Specify respectively the number of zones on the x and y axis.
80  Nx and Ny are integers between 1 and 9.
81  - Type : Can be equal to:
82  - 1 : Portrait mode with a small margin at the bottom of the page.
83  - 2 : Landscape mode with a small margin at the bottom of the page.
84  - 4 : Portrait mode with a large margin at the bottom of the page.
85  - 5 : Landscape mode with a large margin at the bottom of the page.
86  The large margin is useful for some PostScript printers (very often
87  for the colour printers) as they need more space to grip the paper
88  for mechanical reasons. Note that some PostScript colour printers
89  can also use the so called special A4 format permitting the full
90  usage of the A4 area; in this case larger margins are not necessary
91  and Type=1 or 2 can be used.
92  - 3 : Encapsulated PostScript. This Type permits the generation of files
93  which can be included in other documents, for example in LaTeX files.
94 
95 ## Making several pictures in the same Postscript file: case 1
96 
97 The following macro is an example illustrating how to open a Postscript
98 file and draw several pictures. The generation of a new Postscript page
99 is automatic when `TCanvas::Clear` is called by `object->Draw()`.
100 
101  ~~~ {.cpp}
102  {
103  TFile f("hsimple.root");
104  TCanvas c1("c1","canvas",800,600);
105 
106  // select postscript output type
107  // type = 111 portrait ps
108  // type = 112 landscape ps
109  // type = 113 eps
110  Int_t type = 111;
111 
112  // create a postscript file and set the paper size
113  TPostScript ps("test.ps",type);
114  ps.Range(16,24); //set x,y of printed page
115 
116  // draw 3 histograms from file hsimple.root on separate pages
117  hpx->Draw();
118  c1.Update(); //force drawing in a macro
119  hprof->Draw();
120  c1.Update();
121  hpx->Draw("lego1");
122  c1.Update();
123  ps.Close();
124  }
125  ~~~
126 
127 ## Making several pictures in the same Postscript file: case 2
128 
129 This example shows 2 pages. The canvas is divided.
130 `TPostScript::NewPage` must be called before starting a new
131 picture.`object->Draw` does not clear the canvas in this case
132 because we clear only the pads and not the main canvas.
133 Note that `c1->Update` must be called at the end of the first picture.
134 
135 ~~~ {.cpp}
136  {
137  TFile *f1 = new TFile("hsimple.root");
138  TCanvas *c1 = new TCanvas("c1");
139  TPostScript *ps = new TPostScript("file.ps",112);
140  c1->Divide(2,1);
141  // picture 1
142  ps->NewPage();
143  c1->cd(1);
144  hpx->Draw();
145  c1->cd(2);
146  hprof->Draw();
147  c1->Update();
148 
149  // picture 2
150  ps->NewPage();
151  c1->cd(1);
152  hpxpy->Draw();
153  c1->cd(2);
154  ntuple->Draw("px");
155  c1->Update();
156  ps->Close();
157 
158  // invoke Postscript viewer
159  gSystem->Exec("gs file.ps");
160  }
161  ~~~
162 
163 ## Making several pictures in the same Postscript file: case 3
164 This is the recommended way. If the Postscript file name finishes with
165 "(", the file remains opened (it is not closed). If the Postscript file name
166 finishes with ")" and the file has been opened with "(", the file is closed.
167 
168 Example:
169  ~~~ {.cpp}
170  {
171  TCanvas c1("c1");
172  h1.Draw();
173  c1.Print("c1.ps("); // write canvas and keep the ps file open
174  h2.Draw();
175  c1.Print("c1.ps"); // canvas is added to "c1.ps"
176  h3.Draw();
177  c1.Print("c1.ps)"); // canvas is added to "c1.ps" and ps file is closed
178  }
179  ~~~
180 The `TCanvas::Print("file.ps(")` mechanism is very useful, but it can
181 be a little inconvenient to have the action of opening/closing a file being
182 atomic with printing a page. Particularly if pages are being generated in some
183 loop one needs to detect the special cases of first and last page and then
184 munge the argument to Print() accordingly.
185 The "[" and "]" can be used instead of "(" and ")" as shown below.
186 
187 Example:
188  ~~~ {.cpp}
189  c1.Print("file.ps["); // No actual print, just open file.ps
190 
191  for (int i=0; i<10; ++i) {
192  // fill canvas for context i
193  // ...
194 
195  c1.Print("file.ps"); // Actually print canvas to the file
196  }
197 
198  c1.Print("file.ps]"); // No actual print, just close the file
199  ~~~
200 
201  ## Color Model
202 
203 TPostScript support two color model RGB and CMYK. CMY and CMYK models are
204 subtractive color models unlike RGB which is an additive. They are mainly
205 used for printing purposes. CMY means Cyan Magenta Yellow to convert RGB
206 to CMY it is enough to do: C=1-R, M=1-G and Y=1-B. CMYK has one more
207 component K (black). The conversion from RGB to CMYK is:
208 
209  ~~~ {.cpp}
210  Double_t Black = TMath::Min(TMath::Min(1-Red,1-Green),1-Blue);
211  Double_t Cyan = (1-Red-Black)/(1-Black);
212  Double_t Magenta = (1-Green-Black)/(1-Black);
213  Double_t Yellow = (1-Blue-Black)/(1-Black);
214  ~~~
215 CMYK add the black component which allows to have a better quality for black
216 printing. PostScript support the CMYK model.
217 
218 To change the color model use gStyle->SetColorModelPS(c).
219 
220  - c = 0 means TPostScript will use RGB color model (default)
221  - c = 1 means TPostScript will use CMYK color model
222 */
223 
224 #ifdef WIN32
225 #pragma optimize("",off)
226 #endif
227 
228 #include <stdlib.h>
229 #include <string.h>
230 #include <ctype.h>
231 #include <wchar.h>
232 
233 #include "Riostream.h"
234 #include "Byteswap.h"
235 #include "TROOT.h"
236 #include "TColor.h"
237 #include "TVirtualPad.h"
238 #include "TPoints.h"
239 #include "TPostScript.h"
240 #include "TStyle.h"
241 #include "TMath.h"
242 #include "TText.h"
243 #include "TSystem.h"
244 #include "TEnv.h"
245 
246 #include "../../../graf2d/mathtext/inc/fontembed.h"
247 
248 // to scale fonts to the same size as the old TT version
249 const Float_t kScale = 0.93376068;
250 
251 // Array defining if a font must be embedded or not.
252 static Bool_t MustEmbed[32];
253 
255 
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Default PostScript constructor
260 
262 {
263  fStream = 0;
264  fType = 0;
265  gVirtualPS = this;
266  fBlue = 0.;
267  fBoundingBox = kFALSE;
268  fClear = kFALSE;
269  fClip = 0;
270  fClipStatus = kFALSE;
271  fCurrentColor = 0;
272  fDXC = 0.;
273  fDYC = 0.;
274  fFX = 0.;
275  fFY = 0.;
276  fGreen = 0.;
277  fIXzone = 0;
278  fIYzone = 0;
279  fLastCellBlue = 0;
280  fLastCellGreen = 0;
281  fLastCellRed = 0;
282  fLineJoin = 0;
283  fLineScale = 0.;
284  fMarkerSizeCur = 0.;
285  fMaxLines = 0;
286  fMaxsize = 0;
287  fMode = 0;
288  fNBSameColorCell = 0;
289  fNXzone = 0;
290  fNYzone = 0;
291  fNbCellLine = 0;
292  fNbCellW = 0;
293  fNbinCT = 0;
294  fNpages = 0;
295  fRange = kFALSE;
296  fRed = 0.;
297  fSave = 0;
298  fX1v = 0.;
299  fX1w = 0.;
300  fX2v = 0.;
301  fX2w = 0.;
302  fXC = 0.;
303  fXVP1 = 0.;
304  fXVP2 = 0.;
305  fXVS1 = 0.;
306  fXVS2 = 0.;
307  fXsize = 0.;
308  fY1v = 0.;
309  fY1w = 0.;
310  fY2v = 0.;
311  fY2w = 0.;
312  fYC = 0.;
313  fYVP1 = 0.;
314  fYVP2 = 0.;
315  fYVS1 = 0.;
316  fYVS2 = 0.;
317  fYsize = 0.;
318  fZone = kFALSE;
319  fFileName = "";
320  fFontEmbed = kFALSE;
321  Int_t i;
322  for (i=0; i<32; i++) fPatterns[i] = 0;
323  for (i=0; i<32; i++) MustEmbed[i] = kFALSE;
324  SetTitle("PS");
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Initialize the PostScript interface
329 ///
330 /// - fname : PostScript file name
331 /// - wtype : PostScript workstation type
332 ///
333 ///
334 /// The possible workstation types are:
335 /// - 111 ps Portrait
336 /// - 112 ps Landscape
337 /// - 113 eps
338 
339 TPostScript::TPostScript(const char *fname, Int_t wtype)
340 :TVirtualPS(fname, wtype)
341 {
342  fStream = 0;
343  SetTitle("PS");
344  Open(fname, wtype);
345 }
346 
347 ////////////////////////////////////////////////////////////////////////////////
348 /// Open a PostScript file
349 
350 void TPostScript::Open(const char *fname, Int_t wtype)
351 {
352  if (fStream) {
353  Warning("Open", "postscript file already open");
354  return;
355  }
356 
357  fMarkerSizeCur = 0;
358  fCurrentColor = 0;
359  fRed = -1;
360  fGreen = -1;
361  fBlue = -1;
362  fLenBuffer = 0;
363  fClip = 0;
364  fType = abs(wtype);
365  fClear = kTRUE;
366  fZone = kFALSE;
367  fSave = 0;
368  fFontEmbed = kFALSE;
371  fMode = fType%10;
372  Float_t xrange, yrange;
373  if (gPad) {
374  Double_t ww = gPad->GetWw();
375  Double_t wh = gPad->GetWh();
376  if (fType == 113) {
377  ww *= gPad->GetWNDC();
378  wh *= gPad->GetHNDC();
379  }
380  Double_t ratio = wh/ww;
381  if (fType == 112) {
382  xrange = fYsize;
383  yrange = xrange*ratio;
384  if (yrange > fXsize) { yrange = fXsize; xrange = yrange/ratio;}
385  } else {
386  xrange = fXsize;
387  yrange = fXsize*ratio;
388  if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
389  }
390  fXsize = xrange; fYsize = yrange;
391  }
392 
393  // Open OS file
394  fFileName = fname;
395  fStream = new std::ofstream(fFileName.Data(),std::ios::out);
397  printf("ERROR in TPostScript::Open: Cannot open file:%s\n",fFileName.Data());
398  return;
399  }
400  gVirtualPS = this;
401 
402  for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
403  if( fType == 113) {
405  PrintStr("%!PS-Adobe-2.0 EPSF-2.0@");
406  } else {
408  PrintStr("%!PS-Adobe-2.0@");
409  Initialize();
410  }
411 
413  fRange = kFALSE;
414 
415  // Set a default range
416  Range(fXsize, fYsize);
417 
418  fPrinted = kFALSE;
419  if (fType == 113) NewPage();
420 }
421 
422 ////////////////////////////////////////////////////////////////////////////////
423 /// Default PostScript destructor
424 
426 {
427  Close();
428 }
429 
430 ////////////////////////////////////////////////////////////////////////////////
431 /// Close a PostScript file
432 
434 {
435  if (!gVirtualPS) return;
436  if (!fStream) return;
437  if (gPad) gPad->Update();
438  if( fMode != 3) {
439  SaveRestore(-1);
440  if( fPrinted ) { PrintStr("showpage@"); SaveRestore(-1);}
441  PrintStr("@");
442  PrintStr("%%Trailer@");
443  PrintStr("%%Pages: ");
445  PrintStr("@");
446  while (fSave > 0) { SaveRestore(-1); }
447  } else {
448  PrintStr("@");
449  while (fSave > 0) { SaveRestore(-1); }
450  PrintStr("showpage@");
451  PrintStr("end@");
452  }
453  PrintStr("@");
454  PrintStr("%%EOF@");
455 
456  // Embed the fonts previously used by TMathText
457  if (!fFontEmbed) {
458  // Close the file fFileName
459  if (fStream) {
460  PrintStr("@");
461  fStream->close(); delete fStream; fStream = 0;
462  }
463 
464  // Rename the file fFileName
465  TString tmpname = Form("%s_tmp_%d",fFileName.Data(),gSystem->GetPid());
466  if (gSystem->Rename( fFileName.Data() , tmpname.Data())) {
467  Error("Text", "Cannot open temporary file: %s\n", tmpname.Data());
468  return;
469  }
470 
471  // Reopen the file fFileName
472  fStream = new std::ofstream(fFileName.Data(),std::ios::out);
474  Error("Text", "Cannot open file: %s\n", fFileName.Data());
475  return;
476  }
477 
478  // Embed the fonts at the right place
479  FILE *sg = fopen(tmpname.Data(),"r");
480  if (sg == 0) {
481  Error("Text", "Cannot open file: %s\n", tmpname.Data());
482  return;
483  }
484  char line[255];
485  while (fgets(line,255,sg)) {
486  if (strstr(line,"EndComments")) PrintStr("%%DocumentNeededResources: ProcSet (FontSetInit)@");
487  fStream->write(line,strlen(line));
488  if (!fFontEmbed && strstr(line,"m5")) {
489  FontEmbed();
490  PrintStr("@");
491  }
492  }
493  fclose(sg);
494  if (gSystem->Unlink(tmpname.Data())) return;
495  }
496 
497  fFontEmbed = kFALSE;
498 
499  // Close file stream
500 
501  if (fStream) { fStream->close(); delete fStream; fStream = 0;}
502 
503  gVirtualPS = 0;
504 }
505 
506 ////////////////////////////////////////////////////////////////////////////////
507 /// Activate an already open PostScript file
508 
510 {
511  if (!fType) {
512  Error("On", "no postscript file open");
513  Off();
514  return;
515  }
516  gVirtualPS = this;
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////
520 /// Deactivate an already open PostScript file
521 
523 {
524  gVirtualPS = 0;
525 }
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 /// Draw a Cell Array
529 ///
530 /// Drawing a PostScript Cell Array is in fact done thanks to three
531 /// procedures: CellArrayBegin, CellArrayFill, and CellArrayEnd.
532 ///
533 /// - CellArrayBegin: Initiate the Cell Array by writing the necessary
534 /// PostScript procedures and the initial values of the
535 /// required parameters. The input parameters are:
536 /// - W: number of boxes along the width.
537 /// - H: number of boxes along the height
538 /// - x1,x2,y1,y2: First box coordinates.
539 /// - CellArrayFill: Is called for each box of the Cell Array. The first
540 /// box is the top left one and the last box is the
541 /// bottom right one. The input parameters are the Red,
542 /// Green, and Blue components of the box colour. These
543 /// Levels are between 0 and 255.
544 /// - CellArrayEnd: Finishes the Cell Array.
545 ///
546 /// PostScript cannot handle arrays larger than 65535. So the Cell Array
547 /// is drawn in several pieces.
548 
550  Double_t y1, Double_t y2)
551 {
552  Int_t ix1 = XtoPS(x1);
553  Int_t iy1 = YtoPS(y1);
554 
555  Float_t wt = (288/2.54)*gPad->GetAbsWNDC()*
556  fXsize*((x2 - x1)/(gPad->GetX2()-gPad->GetX1()));
557  Float_t ht = (288/2.54)*gPad->GetAbsHNDC()*
558  fYsize*((y2 - y1)/(gPad->GetY2()-gPad->GetY1()));
559 
560  fLastCellRed = 300;
561  fLastCellGreen = 300;
562  fLastCellBlue = 300;
563  fNBSameColorCell = 0;
564 
565  fNbinCT = 0;
566  fNbCellW = W;
567  fNbCellLine = 0;
568  fMaxLines = 40000/(3*fNbCellW);
569 
570  // Define some parameters
571  PrintStr("@/WT"); WriteReal(wt) ; PrintStr(" def"); // Cells width
572  PrintStr(" /HT"); WriteReal(ht) ; PrintStr(" def"); // Cells height
573  PrintStr(" /XS"); WriteInteger(ix1) ; PrintStr(" def"); // X start
574  PrintStr(" /YY"); WriteInteger(iy1) ; PrintStr(" def"); // Y start
575  PrintStr(" /NX"); WriteInteger(W) ; PrintStr(" def"); // Number of columns
576  PrintStr(" /NY"); WriteInteger(fMaxLines); PrintStr(" def"); // Number of lines
577 
578  // This PS procedure draws one cell.
579  PrintStr(" /DrawCell ");
580  PrintStr( "{WT HT XX YY bf");
581  PrintStr( " /NBBD NBBD 1 add def");
582  PrintStr( " NBBD NBB eq {exit} if");
583  PrintStr( " /XX WT XX add def");
584  PrintStr( " IX NX eq ");
585  PrintStr( "{/YY YY HT sub def");
586  PrintStr( " /XX XS def");
587  PrintStr( " /IX 0 def} if");
588  PrintStr( " /IX IX 1 add def} def");
589 
590  // This PS procedure draws fMaxLines line. It takes care of duplicated
591  // colors. Values "n" greater than 300 mean than the previous color
592  // should be duplicated n-300 times.
593  PrintStr(" /DrawCT ");
594  PrintStr( "{/NBB NX NY mul def");
595  PrintStr( " /XX XS def");
596  PrintStr( " /IX 1 def");
597  PrintStr( " /NBBD 0 def");
598  PrintStr( " /RC 0 def /GC 1 def /BC 2 def");
599  PrintStr( " 1 1 NBB ");
600  PrintStr( "{/NB CT RC get def");
601  PrintStr( " NB 301 ge ");
602  PrintStr( "{/NBL NB 300 sub def");
603  PrintStr( " 1 1 NBL ");
604  PrintStr( "{DrawCell}");
605  PrintStr( " for");
606  PrintStr( " /RC RC 1 add def");
607  PrintStr( " /GC RC 1 add def");
608  PrintStr( " /BC RC 2 add def}");
609  PrintStr( "{CT RC get 255 div CT GC get 255 div CT BC get 255 div setrgbcolor");
610  PrintStr( " DrawCell");
611  PrintStr( " /RC RC 3 add def");
612  PrintStr( " /GC GC 3 add def");
613  PrintStr( " /BC BC 3 add def} ifelse NBBD NBB eq {exit} if} for");
614  PrintStr( " /YY YY HT sub def clear} def");
615 
616  PrintStr(" /CT [");
617 }
618 
619 ////////////////////////////////////////////////////////////////////////////////
620 /// Paint the Cell Array
621 
623 {
624  if (fLastCellRed == r && fLastCellGreen == g && fLastCellBlue == b) {
626  } else {
627  if (fNBSameColorCell != 0 ) {
629  fNBSameColorCell = 0;
630  }
631  WriteInteger(r);
632  WriteInteger(g);
633  WriteInteger(b);
634  fLastCellRed = r;
635  fLastCellGreen = g;
636  fLastCellBlue = b;
637  }
638 
639  fNbinCT++;
640  if (fNbinCT == fNbCellW) {
641  fNbCellLine++;
642  fNbinCT = 0;
643  }
644 
645  if (fNbCellLine == fMaxLines) {
647  PrintStr("] def DrawCT /CT [");
648  fNbCellLine = 0;
649  fLastCellRed = 300;
650  fLastCellGreen = 300;
651  fLastCellBlue = 300;
652  fNBSameColorCell = 0;
653  fNbinCT = 0;
654  }
655 }
656 
657 ////////////////////////////////////////////////////////////////////////////////
658 /// End the Cell Array painting
659 
661 {
663  PrintStr("] def /NY");
665  PrintStr(" def DrawCT ");
666 }
667 
668 ////////////////////////////////////////////////////////////////////////////////
669 /// Define the markers
670 
672 {
673  PrintStr("/mp {newpath /y exch def /x exch def} def@");
674  PrintStr("/side {[w .77 mul w .23 mul] .385 w mul sd w 0 l currentpoint t -144 r} def@");
675  PrintStr("/mr {mp x y w2 0 360 arc} def /m24 {mr s} def /m20 {mr f} def@");
676  PrintStr("/mb {mp x y w2 add m w2 neg 0 d 0 w neg d w 0 d 0 w d cl} def@");
677  PrintStr("/mt {mp x y w2 add m w2 neg w neg d w 0 d cl} def@");
678  PrintStr("/m21 {mb f} def /m25 {mb s} def /m22 {mt f} def /m26{mt s} def@");
679  PrintStr("/m23 {mp x y w2 sub m w2 w d w neg 0 d cl f} def@");
680  PrintStr("/m27 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl s} def@");
681  PrintStr("/m28 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
682  PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
683  PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
684  PrintStr(" 0 w3 neg d w3 neg 0 d cl s } def@");
685  PrintStr("/m29 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
686  PrintStr(" 4 {side} repeat cl fill gr} def@");
687  PrintStr("/m30 {mp gsave x w2 sub y w2 add w3 sub m currentpoint t");
688  PrintStr(" 4 {side} repeat cl s gr} def@");
689  PrintStr("/m31 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d");
690  PrintStr(" x w2 sub y w2 add m w w neg d x w2 sub y w2");
691  PrintStr(" sub m w w d s} def@");
692  PrintStr("/m32 {mp x y w2 sub m w2 w d w neg 0 d cl s} def@");
693  PrintStr("/m33 {mp x y w2 add m w3 neg w2 neg d w3 w2 neg d w3 w2 d cl f} def@");
694  PrintStr("/m34 {mp x w2 sub y w2 sub w3 add m w3 0 d ");
695  PrintStr(" 0 w3 neg d w3 0 d 0 w3 d w3 0 d ");
696  PrintStr(" 0 w3 d w3 neg 0 d 0 w3 d w3 neg 0 d");
697  PrintStr(" 0 w3 neg d w3 neg 0 d cl f } def@");
698  PrintStr("/m2 {mp x y w2 sub m 0 w d x w2 sub y m w 0 d s} def@");
699  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@");
700 }
701 
702 ////////////////////////////////////////////////////////////////////////////////
703 /// Draw a Box
704 
706 {
707  static Double_t x[4], y[4];
708  Int_t ix1 = XtoPS(x1);
709  Int_t ix2 = XtoPS(x2);
710  Int_t iy1 = YtoPS(y1);
711  Int_t iy2 = YtoPS(y2);
712  Int_t fillis = fFillStyle/1000;
713  Int_t fillsi = fFillStyle%1000;
714 
715  if (fillis == 3 || fillis == 2) {
716  if (fillsi > 99) {
717  x[0] = x1; y[0] = y1;
718  x[1] = x2; y[1] = y1;
719  x[2] = x2; y[2] = y2;
720  x[3] = x1; y[3] = y2;
721  return;
722  }
723  if (fillsi > 0 && fillsi < 26) {
724  x[0] = x1; y[0] = y1;
725  x[1] = x2; y[1] = y1;
726  x[2] = x2; y[2] = y2;
727  x[3] = x1; y[3] = y2;
728  DrawPS(-4, &x[0], &y[0]);
729  }
730  if (fillsi == -3) {
731  SetColor(5);
732  WriteInteger(ix2 - ix1);
733  WriteInteger(iy2 - iy1);
734  WriteInteger(ix1);
735  WriteInteger(iy1);
736  PrintFast(3," bf");
737  }
738  }
739  if (fillis == 1) {
741  WriteInteger(ix2 - ix1);
742  WriteInteger(iy2 - iy1);
743  WriteInteger(ix1);
744  WriteInteger(iy1);
745  PrintFast(3," bf");
746  }
747  if (fillis == 0) {
748  if (fLineWidth<=0) return;
750  WriteInteger(ix2 - ix1);
751  WriteInteger(iy2 - iy1);
752  WriteInteger(ix1);
753  WriteInteger(iy1);
754  PrintFast(3," bl");
755  }
756 }
757 
758 ////////////////////////////////////////////////////////////////////////////////
759 /// Draw a Frame around a box
760 ///
761 /// - mode = -1 box looks as it is behind the screen
762 /// - mode = 1 box looks as it is in front of the screen
763 /// - border is the border size in already precomputed PostScript units
764 /// - dark is the color for the dark part of the frame
765 /// - light is the color for the light part of the frame
766 
768  Int_t mode, Int_t border, Int_t dark, Int_t light)
769 {
770  static Int_t xps[7], yps[7];
771  Int_t i, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
772 
773  // Draw top&left part of the box
774  if (mode == -1) SetColor(dark);
775  else SetColor(light);
776  Int_t bordPS = 4*border;
777  xps[0] = XtoPS(xl); yps[0] = YtoPS(yl);
778  xps[1] = xps[0] + bordPS; yps[1] = yps[0] + bordPS;
779  xps[2] = xps[1]; yps[2] = YtoPS(yt) - bordPS;
780  xps[3] = XtoPS(xt) - bordPS; yps[3] = yps[2];
781  xps[4] = XtoPS(xt); yps[4] = YtoPS(yt);
782  xps[5] = xps[0]; yps[5] = yps[4];
783  xps[6] = xps[0]; yps[6] = yps[0];
784 
785  ixd0 = xps[0];
786  iyd0 = yps[0];
787  WriteInteger(ixd0);
788  WriteInteger(iyd0);
789 
790  PrintFast(2," m");
791  idx = 0;
792  idy = 0;
793  for (i=1;i<7;i++) {
794  ixdi = xps[i];
795  iydi = yps[i];
796  ix = ixdi - ixd0;
797  iy = iydi - iyd0;
798  ixd0 = ixdi;
799  iyd0 = iydi;
800  if( ix && iy) {
801  if( idx ) { MovePS(idx,0); idx = 0; }
802  if( idy ) { MovePS(0,idy); idy = 0; }
803  MovePS(ix,iy);
804  continue;
805  }
806  if ( ix ) {
807  if( idy ) { MovePS(0,idy); idy = 0; }
808  if( !idx ) { idx = ix; continue;}
809  if( ix*idx > 0 ) idx += ix;
810  else { MovePS(idx,0); idx = ix; }
811  continue;
812  }
813  if( iy ) {
814  if( idx ) { MovePS(idx,0); idx = 0; }
815  if( !idy) { idy = iy; continue;}
816  if( iy*idy > 0 ) idy += iy;
817  else { MovePS(0,idy); idy = iy; }
818  }
819  }
820  if( idx ) MovePS(idx,0);
821  if( idy ) MovePS(0,idy);
822  PrintFast(2," f");
823 
824  // Draw bottom&right part of the box
825  if (mode == -1) SetColor(light);
826  else SetColor(dark);
827  xps[0] = XtoPS(xl); yps[0] = YtoPS(yl);
828  xps[1] = xps[0] + bordPS; yps[1] = yps[0] + bordPS;
829  xps[2] = XtoPS(xt) - bordPS; yps[2] = yps[1];
830  xps[3] = xps[2]; yps[3] = YtoPS(yt) - bordPS;
831  xps[4] = XtoPS(xt); yps[4] = YtoPS(yt);
832  xps[5] = xps[4]; yps[5] = yps[0];
833  xps[6] = xps[0]; yps[6] = yps[0];
834 
835  ixd0 = xps[0];
836  iyd0 = yps[0];
837  WriteInteger(ixd0);
838  WriteInteger(iyd0);
839 
840  PrintFast(2," m");
841  idx = 0;
842  idy = 0;
843  for (i=1;i<7;i++) {
844  ixdi = xps[i];
845  iydi = yps[i];
846  ix = ixdi - ixd0;
847  iy = iydi - iyd0;
848  ixd0 = ixdi;
849  iyd0 = iydi;
850  if( ix && iy) {
851  if( idx ) { MovePS(idx,0); idx = 0; }
852  if( idy ) { MovePS(0,idy); idy = 0; }
853  MovePS(ix,iy);
854  continue;
855  }
856  if ( ix ) {
857  if( idy ) { MovePS(0,idy); idy = 0; }
858  if( !idx ) { idx = ix; continue;}
859  if( ix*idx > 0 ) idx += ix;
860  else { MovePS(idx,0); idx = ix; }
861  continue;
862  }
863  if( iy ) {
864  if( idx ) { MovePS(idx,0); idx = 0; }
865  if( !idy) { idy = iy; continue;}
866  if( iy*idy > 0 ) idy += iy;
867  else { MovePS(0,idy); idy = iy; }
868  }
869  }
870  if( idx ) MovePS(idx,0);
871  if( idy ) MovePS(0,idy);
872  PrintFast(2," f");
873 }
874 
875 ////////////////////////////////////////////////////////////////////////////////
876 /// Draw a PolyLine
877 ///
878 /// Draw a polyline through the points xy.
879 /// - If nn=1 moves only to point x,y.
880 /// - If nn=0 the x,y are written in the PostScript file
881 /// according to the current transformation.
882 /// - If nn>0 the line is clipped as a line.
883 /// - If nn<0 the line is clipped as a fill area.
884 
886 {
887  Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
888  Style_t linestylesav = fLineStyle;
889  Width_t linewidthsav = fLineWidth;
890  if (nn > 0) {
891  if (fLineWidth<=0) return;
892  n = nn;
896  } else {
897  n = -nn;
898  SetLineStyle(1);
899  SetLineWidth(1);
901  }
902 
903  ixd0 = XtoPS(xy[0].GetX());
904  iyd0 = YtoPS(xy[0].GetY());
905  WriteInteger(ixd0);
906  WriteInteger(iyd0);
907  if( n <= 1) {
908  if( n == 0) goto END;
909  PrintFast(2," m");
910  goto END;
911  }
912 
913  PrintFast(2," m");
914  idx = 0;
915  idy = 0;
916  for (i=1;i<n;i++) {
917  ixdi = XtoPS(xy[i].GetX());
918  iydi = YtoPS(xy[i].GetY());
919  ix = ixdi - ixd0;
920  iy = iydi - iyd0;
921  ixd0 = ixdi;
922  iyd0 = iydi;
923  if( ix && iy) {
924  if( idx ) { MovePS(idx,0); idx = 0; }
925  if( idy ) { MovePS(0,idy); idy = 0; }
926  MovePS(ix,iy);
927  continue;
928  }
929  if ( ix ) {
930  if( idy ) { MovePS(0,idy); idy = 0; }
931  if( !idx ) { idx = ix; continue;}
932  if( ix*idx > 0 ) idx += ix;
933  else { MovePS(idx,0); idx = ix; }
934  continue;
935  }
936  if( iy ) {
937  if( idx ) { MovePS(idx,0); idx = 0; }
938  if( !idy) { idy = iy; continue;}
939  if( iy*idy > 0 ) idy += iy;
940  else { MovePS(0,idy); idy = iy; }
941  }
942  }
943  if( idx ) MovePS(idx,0);
944  if( idy ) MovePS(0,idy);
945 
946  if (nn > 0 ) {
947  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
948  PrintFast(2," s");
949  } else {
950  PrintFast(2," f");
951  }
952 END:
953  if (nn < 0) {
954  SetLineStyle(linestylesav);
955  SetLineWidth(linewidthsav);
956  }
957 }
958 
959 ////////////////////////////////////////////////////////////////////////////////
960 /// Draw a PolyLine in NDC space
961 ///
962 /// Draw a polyline through the points xy.
963 /// - If nn=1 moves only to point x,y.
964 /// - If nn=0 the x,y are written in the PostScript file
965 /// according to the current transformation.
966 /// - If nn>0 the line is clipped as a line.
967 /// - If nn<0 the line is clipped as a fill area.
968 
970 {
971  Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
972  Style_t linestylesav = fLineStyle;
973  Width_t linewidthsav = fLineWidth;
974  if (nn > 0) {
975  if (fLineWidth<=0) return;
976  n = nn;
980  } else {
981  n = -nn;
982  SetLineStyle(1);
983  SetLineWidth(1);
985  }
986 
987  ixd0 = UtoPS(xy[0].GetX());
988  iyd0 = VtoPS(xy[0].GetY());
989  WriteInteger(ixd0);
990  WriteInteger(iyd0);
991  if( n <= 1) {
992  if( n == 0) goto END;
993  PrintFast(2," m");
994  goto END;
995  }
996 
997  PrintFast(2," m");
998  idx = 0;
999  idy = 0;
1000  for (i=1;i<n;i++) {
1001  ixdi = UtoPS(xy[i].GetX());
1002  iydi = VtoPS(xy[i].GetY());
1003  ix = ixdi - ixd0;
1004  iy = iydi - iyd0;
1005  ixd0 = ixdi;
1006  iyd0 = iydi;
1007  if( ix && iy) {
1008  if( idx ) { MovePS(idx,0); idx = 0; }
1009  if( idy ) { MovePS(0,idy); idy = 0; }
1010  MovePS(ix,iy);
1011  continue;
1012  }
1013  if ( ix ) {
1014  if( idy ) { MovePS(0,idy); idy = 0; }
1015  if( !idx ) { idx = ix; continue;}
1016  if( ix*idx > 0 ) idx += ix;
1017  else { MovePS(idx,0); idx = ix; }
1018  continue;
1019  }
1020  if( iy ) {
1021  if( idx ) { MovePS(idx,0); idx = 0; }
1022  if( !idy) { idy = iy; continue;}
1023  if( iy*idy > 0 ) idy += iy;
1024  else { MovePS(0,idy); idy = iy; }
1025  }
1026  }
1027  if( idx ) MovePS(idx,0);
1028  if( idy ) MovePS(0,idy);
1029 
1030  if (nn > 0 ) {
1031  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
1032  PrintFast(2," s");
1033  } else {
1034  PrintFast(2," f");
1035  }
1036 END:
1037  if (nn < 0) {
1038  SetLineStyle(linestylesav);
1039  SetLineWidth(linewidthsav);
1040  }
1041 }
1042 
1043 ////////////////////////////////////////////////////////////////////////////////
1044 /// Draw markers at the n WC points x, y
1045 
1047 {
1048  Int_t i, np, markerstyle;
1049  Float_t markersize;
1050  static char chtemp[10];
1051 
1052  if (!fMarkerSize) return;
1053  Style_t linestylesav = fLineStyle;
1054  Width_t linewidthsav = fLineWidth;
1055  SetLineStyle(1);
1056  SetLineWidth(1);
1058  markerstyle = abs(fMarkerStyle);
1059  if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
1060  if (markerstyle == 1) strlcpy(chtemp, " m20",10);
1061  if (markerstyle == 2) strlcpy(chtemp, " m2",10);
1062  if (markerstyle == 3) strlcpy(chtemp, " m31",10);
1063  if (markerstyle == 4) strlcpy(chtemp, " m24",10);
1064  if (markerstyle == 5) strlcpy(chtemp, " m5",10);
1065  if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
1066  if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
1067  if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
1068 
1069  // Set the PostScript marker size
1070  if (markerstyle == 1) {
1071  markersize = 2.;
1072  } else if (markerstyle == 6) {
1073  markersize = 4.;
1074  } else if (markerstyle == 7) {
1075  markersize = 8.;
1076  } else {
1077  Float_t symbolsize = fMarkerSize;
1078  const Int_t kBASEMARKER = 8;
1079  Float_t sbase = symbolsize*kBASEMARKER;
1080  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
1081  markersize = this->UtoPS(s2x) - this->UtoPS(0);
1082  }
1083 
1084  if (fMarkerSizeCur != markersize) {
1085  fMarkerSizeCur = markersize;
1086  PrintFast(3," /w");
1087  WriteInteger(Int_t(markersize+0.5));
1088  PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
1089  }
1090 
1091  WriteInteger(XtoPS(x[0]));
1092  WriteInteger(YtoPS(y[0]));
1093  if (n == 1) {
1094  PrintStr(chtemp);
1095  SetLineStyle(linestylesav);
1096  SetLineWidth(linewidthsav);
1097  return;
1098  }
1099  np = 1;
1100  for (i=1;i<n;i++) {
1101  WriteInteger(XtoPS(x[i]));
1102  WriteInteger(YtoPS(y[i]));
1103  np++;
1104  if (np == 100 || i == n-1) {
1105  WriteInteger(np);
1106  PrintFast(2," {");
1107  PrintStr(chtemp);
1108  PrintFast(3,"} R");
1109  np = 0;
1110  }
1111  }
1112  SetLineStyle(linestylesav);
1113  SetLineWidth(linewidthsav);
1114 }
1115 
1116 ////////////////////////////////////////////////////////////////////////////////
1117 /// Draw markers at the n WC points x, y
1118 
1120 {
1121  Int_t i, np, markerstyle;
1122  Float_t markersize;
1123  static char chtemp[10];
1124 
1125  if (!fMarkerSize) return;
1126  Style_t linestylesav = fLineStyle;
1127  Width_t linewidthsav = fLineWidth;
1128  SetLineStyle(1);
1129  SetLineWidth(1);
1131  markerstyle = abs(fMarkerStyle);
1132  if (markerstyle <= 0) strlcpy(chtemp, " m20",10);
1133  if (markerstyle == 1) strlcpy(chtemp, " m20",10);
1134  if (markerstyle == 2) strlcpy(chtemp, " m2",10);
1135  if (markerstyle == 3) strlcpy(chtemp, " m31",10);
1136  if (markerstyle == 4) strlcpy(chtemp, " m24",10);
1137  if (markerstyle == 5) strlcpy(chtemp, " m5",10);
1138  if (markerstyle >= 6 && markerstyle <= 19) strlcpy(chtemp, " m20",10);
1139  if (markerstyle >= 20 && markerstyle <= 34 ) snprintf(chtemp,10," m%d", markerstyle);
1140  if (markerstyle >= 35) strlcpy(chtemp, " m20",10);
1141 
1142  // Set the PostScript marker size
1143  if (markerstyle == 1) {
1144  markersize = 2.;
1145  } else if (markerstyle == 6) {
1146  markersize = 4.;
1147  } else if (markerstyle == 7) {
1148  markersize = 8.;
1149  } else {
1150  Float_t symbolsize = fMarkerSize;
1151  const Int_t kBASEMARKER = 8;
1152  Float_t sbase = symbolsize*kBASEMARKER;
1153  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
1154  markersize = this->UtoPS(s2x) - this->UtoPS(0);
1155  }
1156 
1157  if (fMarkerSizeCur != markersize) {
1158  fMarkerSizeCur = markersize;
1159  PrintFast(3," /w");
1160  WriteInteger(Int_t(markersize+0.5));
1161  PrintFast(40," def /w2 {w 2 div} def /w3 {w 3 div} def");
1162  }
1163 
1164  WriteInteger(XtoPS(x[0]));
1165  WriteInteger(YtoPS(y[0]));
1166  if (n == 1) {
1167  PrintStr(chtemp);
1168  SetLineStyle(linestylesav);
1169  SetLineWidth(linewidthsav);
1170  return;
1171  }
1172  np = 1;
1173  for (i=1;i<n;i++) {
1174  WriteInteger(XtoPS(x[i]));
1175  WriteInteger(YtoPS(y[i]));
1176  np++;
1177  if (np == 100 || i == n-1) {
1178  WriteInteger(np);
1179  PrintFast(2," {");
1180  PrintStr(chtemp);
1181  PrintFast(3,"} R");
1182  np = 0;
1183  }
1184  }
1185  SetLineStyle(linestylesav);
1186  SetLineWidth(linewidthsav);
1187 }
1188 
1189 ////////////////////////////////////////////////////////////////////////////////
1190 /// Draw a PolyLine
1191 ///
1192 /// Draw a polyline through the points xw,yw.
1193 /// - If nn=1 moves only to point xw,yw.
1194 /// - If nn=0 the XW(1) and YW(1) are written in the PostScript file
1195 /// according to the current NT.
1196 /// - If nn>0 the line is clipped as a line.
1197 /// - If nn<0 the line is clipped as a fill area.
1198 
1200 {
1201  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1202  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1203  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1204  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1205  180, 90,135, 45,150, 30,120, 60,
1206  180, 90,135, 45,150, 30,120, 60};
1207  Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
1208  fais = fasi = n = 0;
1209  Int_t jxd0 = XtoPS(xw[0]);
1210  Int_t jyd0 = YtoPS(yw[0]);
1211  Style_t linestylesav = fLineStyle;
1212  Width_t linewidthsav = fLineWidth;
1213 
1214  if (nn > 0) {
1215  if (fLineWidth<=0) return;
1216  n = nn;
1220  }
1221  if (nn < 0) {
1222  n = -nn;
1223  SetLineStyle(1);
1224  SetLineWidth(1);
1226  fais = fFillStyle/1000;
1227  fasi = fFillStyle%1000;
1228  if (fais == 3 || fais == 2) {
1229  if (fasi > 100 && fasi <125) {
1230  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1231  goto END;
1232  }
1233  if (fasi > 0 && fasi < 26) {
1235  }
1236  }
1237  }
1238 
1239  ixd0 = jxd0;
1240  iyd0 = jyd0;
1241  WriteInteger(ixd0);
1242  WriteInteger(iyd0);
1243  if( n <= 1) {
1244  if( n == 0) goto END;
1245  PrintFast(2," m");
1246  goto END;
1247  }
1248 
1249  PrintFast(2," m");
1250  idx = idy = 0;
1251  for (i=1;i<n;i++) {
1252  ixdi = XtoPS(xw[i]);
1253  iydi = YtoPS(yw[i]);
1254  ix = ixdi - ixd0;
1255  iy = iydi - iyd0;
1256  ixd0 = ixdi;
1257  iyd0 = iydi;
1258  if( ix && iy) {
1259  if( idx ) { MovePS(idx,0); idx = 0; }
1260  if( idy ) { MovePS(0,idy); idy = 0; }
1261  MovePS(ix,iy);
1262  } else if ( ix ) {
1263  if( idy ) { MovePS(0,idy); idy = 0;}
1264  if( !idx ) { idx = ix;}
1265  else if( TMath::Sign(ix,idx) == ix ) idx += ix;
1266  else { MovePS(idx,0); idx = ix;}
1267  } else if( iy ) {
1268  if( idx ) { MovePS(idx,0); idx = 0;}
1269  if( !idy) { idy = iy;}
1270  else if( TMath::Sign(iy,idy) == iy) idy += iy;
1271  else { MovePS(0,idy); idy = iy;}
1272  }
1273  }
1274  if (idx) MovePS(idx,0);
1275  if (idy) MovePS(0,idy);
1276 
1277  if (nn > 0 ) {
1278  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
1279  PrintFast(2," s");
1280  } else {
1281  if (fais == 0) {PrintFast(5," cl s"); goto END;}
1282  if (fais == 3 || fais == 2) {
1283  if (fasi > 0 && fasi < 26) {
1284  PrintFast(3," FA");
1285  fRed = -1;
1286  fGreen = -1;
1287  fBlue = -1;
1288  }
1289  goto END;
1290  }
1291  PrintFast(2," f");
1292  }
1293 END:
1294  if (nn < 0) {
1295  SetLineStyle(linestylesav);
1296  SetLineWidth(linewidthsav);
1297  }
1298 }
1299 
1300 ////////////////////////////////////////////////////////////////////////////////
1301 /// Draw a PolyLine
1302 ///
1303 /// Draw a polyline through the points xw,yw.
1304 /// - If nn=1 moves only to point xw,yw.
1305 /// - If nn=0 the xw(1) and YW(1) are written in the PostScript file
1306 /// --- according to the current NT.
1307 /// - If nn>0 the line is clipped as a line.
1308 /// - If nn<0 the line is clipped as a fill area.
1309 
1311 {
1312  static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1313  .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1314  .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1315  static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1316  180, 90,135, 45,150, 30,120, 60,
1317  180, 90,135, 45,150, 30,120, 60};
1318  Int_t i, n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
1319  fais = fasi = n = 0;
1320  Int_t jxd0 = XtoPS(xw[0]);
1321  Int_t jyd0 = YtoPS(yw[0]);
1322  Style_t linestylesav = fLineStyle;
1323  Width_t linewidthsav = fLineWidth;
1324 
1325  if (nn > 0) {
1326  if (fLineWidth<=0) return;
1327  n = nn;
1331  }
1332  if (nn < 0) {
1333  n = -nn;
1334  SetLineStyle(1);
1335  SetLineWidth(1);
1337  fais = fFillStyle/1000;
1338  fasi = fFillStyle%1000;
1339  if (fais == 3 || fais == 2) {
1340  if (fasi > 100 && fasi <125) {
1341  DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1342  goto END;
1343  }
1344  if (fasi > 0 && fasi < 26) {
1346  }
1347  }
1348  }
1349 
1350  ixd0 = jxd0;
1351  iyd0 = jyd0;
1352  WriteInteger(ixd0);
1353  WriteInteger(iyd0);
1354  if( n <= 1) {
1355  if( n == 0) goto END;
1356  PrintFast(2," m");
1357  goto END;
1358  }
1359 
1360  PrintFast(2," m");
1361  idx = idy = 0;
1362  for (i=1;i<n;i++) {
1363  ixdi = XtoPS(xw[i]);
1364  iydi = YtoPS(yw[i]);
1365  ix = ixdi - ixd0;
1366  iy = iydi - iyd0;
1367  ixd0 = ixdi;
1368  iyd0 = iydi;
1369  if( ix && iy) {
1370  if( idx ) { MovePS(idx,0); idx = 0; }
1371  if( idy ) { MovePS(0,idy); idy = 0; }
1372  MovePS(ix,iy);
1373  } else if ( ix ) {
1374  if( idy ) { MovePS(0,idy); idy = 0;}
1375  if( !idx ) { idx = ix;}
1376  else if( TMath::Sign(ix,idx) == ix ) idx += ix;
1377  else { MovePS(idx,0); idx = ix;}
1378  } else if( iy ) {
1379  if( idx ) { MovePS(idx,0); idx = 0;}
1380  if( !idy) { idy = iy;}
1381  else if( TMath::Sign(iy,idy) == iy) idy += iy;
1382  else { MovePS(0,idy); idy = iy;}
1383  }
1384  }
1385  if (idx) MovePS(idx,0);
1386  if (idy) MovePS(0,idy);
1387 
1388  if (nn > 0 ) {
1389  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(3," cl");
1390  PrintFast(2," s");
1391  } else {
1392  if (fais == 0) {PrintFast(5," cl s"); goto END;}
1393  if (fais == 3 || fais == 2) {
1394  if (fasi > 0 && fasi < 26) {
1395  PrintFast(3," FA");
1396  fRed = -1;
1397  fGreen = -1;
1398  fBlue = -1;
1399  }
1400  goto END;
1401  }
1402  PrintFast(2," f");
1403  }
1404 END:
1405  if (nn < 0) {
1406  SetLineStyle(linestylesav);
1407  SetLineWidth(linewidthsav);
1408  }
1409 }
1410 
1411 ////////////////////////////////////////////////////////////////////////////////
1412 /// Draw Fill area with hatch styles
1413 
1415 {
1416  Warning("DrawHatch", "hatch fill style not yet implemented");
1417 }
1418 
1419 ////////////////////////////////////////////////////////////////////////////////
1420 /// Draw Fill area with hatch styles
1421 
1423 {
1424  Warning("DrawHatch", "hatch fill style not yet implemented");
1425 }
1426 
1427 ////////////////////////////////////////////////////////////////////////////////
1428 
1430 {
1431  std::ifstream font_file(filename, std::ios::binary);
1432 
1433  // We cannot read directly using iostream iterators due to
1434  // signedness
1435  font_file.seekg(0, std::ios::end);
1436 
1437  const size_t font_file_length = font_file.tellg();
1438 
1439  font_file.seekg(0, std::ios::beg);
1440 
1441  std::vector<unsigned char> font_data(font_file_length, '\0');
1442 
1443  font_file.read(reinterpret_cast<char *>(&font_data[0]),
1444  font_file_length);
1445 
1446  std::string font_name;
1447  std::string postscript_string =
1448  mathtext::font_embed_postscript_t::font_embed_type_1(
1449  font_name, font_data);
1450 
1451  if (!postscript_string.empty()) {
1452  PrintRaw(postscript_string.size(), postscript_string.data());
1453  PrintStr("@");
1454 
1455  return true;
1456  }
1457 
1458  return false;
1459 }
1460 
1461 ////////////////////////////////////////////////////////////////////////////////
1462 
1464 {
1465  std::ifstream font_file(filename, std::ios::binary);
1466 
1467  // We cannot read directly using iostream iterators due to
1468  // signedness
1469  font_file.seekg(0, std::ios::end);
1470 
1471  const size_t font_file_length = font_file.tellg();
1472 
1473  font_file.seekg(0, std::ios::beg);
1474 
1475  std::vector<unsigned char> font_data(font_file_length, '\0');
1476 
1477  font_file.read(reinterpret_cast<char *>(&font_data[0]), font_file_length);
1478 
1479  std::string font_name;
1480  std::string postscript_string =
1481  mathtext::font_embed_postscript_t::font_embed_type_2(font_name, font_data);
1482 
1483  if (!postscript_string.empty()) {
1484  PrintRaw(postscript_string.size(), postscript_string.data());
1485  PrintStr("@");
1486 
1487  return true;
1488  }
1489 
1490  return false;
1491 }
1492 
1493 ////////////////////////////////////////////////////////////////////////////////
1494 
1496 {
1497  std::ifstream font_file(filename, std::ios::binary);
1498 
1499  // We cannot read directly using iostream iterators due to signedness
1500 
1501  font_file.seekg(0, std::ios::end);
1502 
1503  const size_t font_file_length = font_file.tellg();
1504 
1505  font_file.seekg(0, std::ios::beg);
1506 
1507  std::vector<unsigned char> font_data(font_file_length, '\0');
1508 
1509  font_file.read(reinterpret_cast<char *>(&font_data[0]), font_file_length);
1510 
1511  std::string font_name;
1512  std::string postscript_string =
1513  mathtext::font_embed_postscript_t::font_embed_type_42(font_name, font_data);
1514 
1515  if (!postscript_string.empty()) {
1516  PrintRaw(postscript_string.size(), postscript_string.data());
1517  PrintStr("@");
1518 
1519  return true;
1520  }
1521  fprintf(stderr, "%s:%d:\n", __FILE__, __LINE__);
1522 
1523  return false;
1524 }
1525 
1526 ////////////////////////////////////////////////////////////////////////////////
1527 /// Embed font in PS file.
1528 
1530 {
1531  static const char *fonttable[32][2] = {
1532  { "Root.TTFont.0", "FreeSansBold.otf" },
1533  { "Root.TTFont.1", "FreeSerifItalic.otf" },
1534  { "Root.TTFont.2", "FreeSerifBold.otf" },
1535  { "Root.TTFont.3", "FreeSerifBoldItalic.otf" },
1536  { "Root.TTFont.4", "FreeSans.otf" },
1537  { "Root.TTFont.5", "FreeSansOblique.otf" },
1538  { "Root.TTFont.6", "FreeSansBold.otf" },
1539  { "Root.TTFont.7", "FreeSansBoldOblique.otf" },
1540  { "Root.TTFont.8", "FreeMono.otf" },
1541  { "Root.TTFont.9", "FreeMonoOblique.otf" },
1542  { "Root.TTFont.10", "FreeMonoBold.otf" },
1543  { "Root.TTFont.11", "FreeMonoBoldOblique.otf" },
1544  { "Root.TTFont.12", "symbol.ttf" },
1545  { "Root.TTFont.13", "FreeSerif.otf" },
1546  { "Root.TTFont.14", "wingding.ttf" },
1547  { "Root.TTFont.15", "symbol.ttf" },
1548  { "Root.TTFont.STIXGen", "STIXGeneral.otf" },
1549  { "Root.TTFont.STIXGenIt", "STIXGeneralItalic.otf" },
1550  { "Root.TTFont.STIXGenBd", "STIXGeneralBol.otf" },
1551  { "Root.TTFont.STIXGenBdIt", "STIXGeneralBolIta.otf" },
1552  { "Root.TTFont.STIXSiz1Sym", "STIXSiz1Sym.otf" },
1553  { "Root.TTFont.STIXSiz1SymBd", "STIXSiz1SymBol.otf" },
1554  { "Root.TTFont.STIXSiz2Sym", "STIXSiz2Sym.otf" },
1555  { "Root.TTFont.STIXSiz2SymBd", "STIXSiz2SymBol.otf" },
1556  { "Root.TTFont.STIXSiz3Sym", "STIXSiz3Sym.otf" },
1557  { "Root.TTFont.STIXSiz3SymBd", "STIXSiz3SymBol.otf" },
1558  { "Root.TTFont.STIXSiz4Sym", "STIXSiz4Sym.otf" },
1559  { "Root.TTFont.STIXSiz4SymBd", "STIXSiz4SymBol.otf" },
1560  { "Root.TTFont.STIXSiz5Sym", "STIXSiz5Sym.otf" },
1561  { "Root.TTFont.ME", "DroidSansFallback.ttf" },
1562  { "Root.TTFont.CJKMing", "DroidSansFallback.ttf" },
1563  { "Root.TTFont.CJKCothic", "DroidSansFallback.ttf" }
1564  };
1565 
1566  PrintStr("%%IncludeResource: ProcSet (FontSetInit)@");
1567 
1568  // try to load font (font must be in Root.TTFontPath resource)
1569  const char *ttpath = gEnv->GetValue("Root.TTFontPath",
1570 #ifdef TTFFONTDIR
1571  TTFFONTDIR
1572 #else // TTFFONTDIR
1573  "$(ROOTSYS)/fonts"
1574 #endif // TTFFONTDIR
1575  );
1576 
1577  for (Int_t fontid = 1; fontid < 30; fontid++) {
1578  if (fontid != 15 && MustEmbed[fontid-1]) {
1579  const char *filename = gEnv->GetValue(
1580  fonttable[fontid][0], fonttable[fontid][1]);
1581  char *ttfont = gSystem->Which(ttpath, filename, kReadPermission);
1582  if (!ttfont) {
1583  Error("TPostScript::FontEmbed",
1584  "font %d (filename `%s') not found in path",
1585  fontid, filename);
1586  } else {
1587  if (FontEmbedType2(ttfont)) {
1588  // nothing
1589  } else if(FontEmbedType1(ttfont)) {
1590  // nothing
1591  } else if(FontEmbedType42(ttfont)) {
1592  // nothing
1593  } else {
1594  Error("TPostScript::FontEmbed",
1595  "failed to embed font %d (filename `%s')",
1596  fontid, filename);
1597  }
1598  delete [] ttfont;
1599  }
1600  }
1601  }
1602  PrintStr("%%IncludeResource: font Times-Roman@");
1603  PrintStr("%%IncludeResource: font Times-Italic@");
1604  PrintStr("%%IncludeResource: font Times-Bold@");
1605  PrintStr("%%IncludeResource: font Times-BoldItalic@");
1606  PrintStr("%%IncludeResource: font Helvetica@");
1607  PrintStr("%%IncludeResource: font Helvetica-Oblique@");
1608  PrintStr("%%IncludeResource: font Helvetica-Bold@");
1609  PrintStr("%%IncludeResource: font Helvetica-BoldOblique@");
1610  PrintStr("%%IncludeResource: font Courier@");
1611  PrintStr("%%IncludeResource: font Courier-Oblique@");
1612  PrintStr("%%IncludeResource: font Courier-Bold@");
1613  PrintStr("%%IncludeResource: font Courier-BoldOblique@");
1614  PrintStr("%%IncludeResource: font Symbol@");
1615  PrintStr("%%IncludeResource: font ZapfDingbats@");
1616 
1617  fFontEmbed = kTRUE;
1618 }
1619 
1620 ////////////////////////////////////////////////////////////////////////////////
1621 /// Font Re-encoding
1622 
1624 {
1625  PrintStr("/reEncode ");
1626  PrintStr("{exch findfont");
1627  PrintStr(" dup length dict begin");
1628  PrintStr(" {1 index /FID eq ");
1629  PrintStr(" {pop pop}");
1630  PrintStr(" {def} ifelse");
1631  PrintStr(" } forall");
1632  PrintStr(" /Encoding exch def");
1633  PrintStr(" currentdict end");
1634  PrintStr(" dup /FontName get exch");
1635  PrintStr(" definefont pop");
1636  PrintStr(" } def");
1637  PrintStr(" [/Times-Bold /Times-Italic /Times-BoldItalic /Helvetica");
1638  PrintStr(" /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique");
1639  PrintStr(" /Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique");
1640  PrintStr(" /Times-Roman /AvantGarde-Book /AvantGarde-BookOblique");
1641  PrintStr(" /AvantGarde-Demi /AvantGarde-DemiOblique /Bookman-Demi");
1642  PrintStr(" /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic");
1643  PrintStr(" /Helvetica-Narrow /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique");
1644  PrintStr(" /Helvetica-Narrow-Oblique /NewCenturySchlbk-Roman /NewCenturySchlbk-Bold");
1645  PrintStr(" /NewCenturySchlbk-BoldItalic /NewCenturySchlbk-Italic");
1646  PrintStr(" /Palatino-Bold /Palatino-BoldItalic /Palatino-Italic /Palatino-Roman");
1647  PrintStr(" ] {ISOLatin1Encoding reEncode } forall");
1648 }
1649 
1650 ////////////////////////////////////////////////////////////////////////////////
1651 /// PostScript Initialisation
1652 ///
1653 /// This method initialize the following PostScript procedures:
1654 ///
1655 /// | Macro Name | Input parameters | Explanation |
1656 /// |------------|------------------|-----------------------------------|
1657 /// | l | x y | Draw a line to the x y position |
1658 /// | m | x y | Move to the position x y |
1659 /// | box | dx dy x y | Define a box |
1660 /// | bl | dx dy x y | Draw a line box |
1661 /// | bf | dx dy x y | Draw a filled box |
1662 /// | t | x y | Translate |
1663 /// | r | angle | Rotate |
1664 /// | rl | i j | Roll the stack |
1665 /// | d | x y | Draw a relative line to x y |
1666 /// | X | x | Draw a relative line to x (y=0) |
1667 /// | Y | y | Draw a relative line to y (x=0) |
1668 /// | rm | x y | Move relatively to x y |
1669 /// | gr | | Restore the graphic context |
1670 /// | lw | lwidth | Set line width to lwidth |
1671 /// | sd | [] 0 | Set dash line define by [] |
1672 /// | s | | Stroke mode |
1673 /// | c | r g b | Set rgb color to r g b |
1674 /// | cl | | Close path |
1675 /// | f | | Fill the last describe path |
1676 /// | mXX | x y | Draw the marker type XX at (x,y) |
1677 /// | Zone | ix iy | Define the current zone |
1678 /// | black | | The color is black |
1679 /// | C | dx dy x y | Clipping on |
1680 /// | NC | | Clipping off |
1681 /// | R | | repeat |
1682 /// | ita | | Used to make the symbols italic |
1683 /// | K | | kshow |
1684 
1686 {
1687  Double_t rpxmin, rpymin, width, heigth;
1688  rpxmin = rpymin = width = heigth = 0;
1689  Int_t format;
1690  fNpages=1;
1691  for (Int_t i=0;i<32;i++) fPatterns[i]=0;
1692 
1693  // Mode is last digit of PostScript Workstation type
1694  // mode=1,2 for portrait/landscape black and white
1695  // mode=3 for Encapsulated PostScript File
1696  // mode=4 for portrait colour
1697  // mode=5 for lanscape colour
1698  Int_t atype = abs(fType);
1699  fMode = atype%10;
1700  if( fMode <= 0 || fMode > 5) {
1701  Error("Initialize", "invalid file type %d", fMode);
1702  return;
1703  }
1704 
1705  // fNXzone (fNYzone) is the total number of windows in x (y)
1706  fNXzone = (atype%1000)/100;
1707  fNYzone = (atype%100)/10;
1708  if( fNXzone <= 0 ) fNXzone = 1;
1709  if( fNYzone <= 0 ) fNYzone = 1;
1710  fIXzone = 1;
1711  fIYzone = 1;
1712 
1713  // format = 0-99 is the European page format (A4,A3 ...)
1714  // format = 100 is the US format 8.5x11.0 inch
1715  // format = 200 is the US format 8.5x14.0 inch
1716  // format = 300 is the US format 11.0x17.0 inch
1717  format = atype/1000;
1718  if( format == 0 ) format = 4;
1719  if( format == 99 ) format = 0;
1720 
1721  PrintStr("%%Title: ");
1722  const char *pstitle = gStyle->GetTitlePS();
1723  if (gPad && !pstitle[0]) pstitle = gPad->GetMother()->GetTitle();
1724  if (strlen(GetName())<=80) PrintStr(GetName());
1725  if(!pstitle[0] && fMode != 3) {;
1726  PrintFast(2," (");
1727  if ( format <= 99 ) {;
1728  PrintFast(2," A");
1729  WriteInteger(format);
1730  PrintFast(1,")");
1731  }
1732  else {
1733  if ( format == 100 ) PrintFast(8," Letter)");
1734  if ( format == 200 ) PrintFast(7," Legal)");
1735  if ( format == 300 ) PrintFast(8," Ledger)");
1736  }
1737  PrintStr("@");
1738  PrintStr("%%Pages: (atend)@");
1739  }
1740  else {
1741  if (!strchr(pstitle,'\n')) {
1742  PrintFast(2,": ");
1743  PrintStr(pstitle);
1744  }
1745  PrintStr("@");
1746  }
1747 
1748  PrintFast(24,"%%Creator: ROOT Version ");
1749  PrintStr(gROOT->GetVersion());
1750  PrintStr("@");
1751  PrintFast(16,"%%CreationDate: ");
1752  TDatime t;
1753  PrintStr(t.AsString());
1754  PrintStr("@");
1755 
1756  if ( fMode == 1 || fMode == 4) PrintStr("%%Orientation: Portrait@");
1757  if ( fMode == 2 || fMode == 5) PrintStr("%%Orientation: Landscape@");
1758 
1759  PrintStr("%%EndComments@");
1760  PrintStr("%%BeginProlog@");
1761 
1762  if( fMode == 3)PrintStr("80 dict begin@");
1763 
1764  // Initialisation of PostScript procedures
1765  PrintStr("/s {stroke} def /l {lineto} def /m {moveto} def /t {translate} def@");
1766  PrintStr("/r {rotate} def /rl {roll} def /R {repeat} def@");
1767  PrintStr("/d {rlineto} def /rm {rmoveto} def /gr {grestore} def /f {eofill} def@");
1768  if (gStyle->GetColorModelPS()) {
1769  PrintStr("/c {setcmykcolor} def /black {0 0 0 1 setcmykcolor} def /sd {setdash} def@");
1770  } else {
1771  PrintStr("/c {setrgbcolor} def /black {0 setgray} def /sd {setdash} def@");
1772  }
1773  PrintStr("/cl {closepath} def /sf {scalefont setfont} def /lw {setlinewidth} def@");
1774  PrintStr("/box {m dup 0 exch d exch 0 d 0 exch neg d cl} def@");
1775  PrintStr("/NC{systemdict begin initclip end}def/C{NC box clip newpath}def@");
1776  PrintStr("/bl {box s} def /bf {gsave box gsave f grestore 1 lw [] 0 sd s grestore} def /Y { 0 exch d} def /X { 0 d} def @");
1777  PrintStr("/K {{pop pop 0 moveto} exch kshow} bind def@");
1778  PrintStr("/ita {/ang 15 def gsave [1 0 ang dup sin exch cos div 1 0 0] concat} def @");
1779 
1780  DefineMarkers();
1781 
1782  FontEncode();
1783 
1784  // mode=1 for portrait black/white
1785  if (fMode == 1) {
1786  rpxmin = 0.7;
1787  rpymin = TMath::Sqrt(2.)*rpxmin;
1788  switch (format) {
1789  case 100 :
1790  width = (8.5*2.54)-2.*rpxmin;
1791  heigth = (11.*2.54)-2.*rpymin;
1792  break;
1793  case 200 :
1794  width = (8.5*2.54)-2.*rpxmin;
1795  heigth = (14.*2.54)-2.*rpymin;
1796  break;
1797  case 300 :
1798  width = (11.*2.54)-2.*rpxmin;
1799  heigth = (17.*2.54)-2.*rpymin;
1800  break;
1801  default :
1802  width = 21.0-2.*rpxmin;
1803  heigth = 29.7-2.*rpymin;
1804  };
1805  }
1806 
1807  // mode=2 for landscape black/white
1808  if (fMode == 2) {
1809  rpymin = 0.7;
1810  rpxmin = TMath::Sqrt(2.)*rpymin;
1811  switch (format) {
1812  case 100 :
1813  width = (11.*2.54)-2.*rpxmin;
1814  heigth = (8.5*2.54)-2.*rpymin;
1815  case 200 :
1816  width = (14.*2.54)-2.*rpxmin;
1817  heigth = (8.5*2.54)-2.*rpymin;
1818  case 300 :
1819  width = (17.*2.54)-2.*rpxmin;
1820  heigth = (11.*2.54)-2.*rpymin;
1821  default :
1822  width = 29.7-2.*rpxmin;
1823  heigth = 21-2.*rpymin;
1824  };
1825  }
1826 
1827  // mode=3 encapsulated PostScript
1828  if (fMode == 3) {
1829  width = 20;
1830  heigth = 20;
1831  format = 4;
1832  fNXzone = 1;
1833  fNYzone = 1;
1834  }
1835 
1836  // mode=4 for portrait colour
1837  if (fMode == 4) {
1838  rpxmin = 0.7;
1839  rpymin = 3.4;
1840  switch (format) {
1841  case 100 :
1842  width = (8.5*2.54)-2.*rpxmin;
1843  heigth = (11.*2.54)-2.*rpymin;
1844  case 200 :
1845  width = (8.5*2.54)-2.*rpxmin;
1846  heigth = (14.*2.54)-2.*rpymin;
1847  case 300 :
1848  width = (11.*2.54)-2.*rpxmin;
1849  heigth = (17.*2.54)-2.*rpymin;
1850  default :
1851  width = (21.0-2*rpxmin);
1852  heigth = (29.7-2.*rpymin);
1853  };
1854  }
1855 
1856  // mode=5 for lanscape colour
1857  if (fMode == 5) {
1858  rpxmin = 3.4;
1859  rpymin = 0.7;
1860  switch (format) {
1861  case 100 :
1862  width = (11.*2.54)-2.*rpxmin;
1863  heigth = (8.5*2.54)-2.*rpymin;
1864  case 200 :
1865  width = (14.*2.54)-2.*rpxmin;
1866  heigth = (8.5*2.54)-2.*rpymin;
1867  case 300 :
1868  width = (17.*2.54)-2.*rpxmin;
1869  heigth = (11.*2.54)-2.*rpymin;
1870  default :
1871  width = (29.7-2*rpxmin);
1872  heigth = (21-2.*rpymin);
1873  };
1874  }
1875 
1876  Double_t value = 0;
1877  if (format < 100) value = 21*TMath::Power(TMath::Sqrt(2.), 4-format);
1878  else if (format == 100) value = 8.5*2.54;
1879  else if (format == 200) value = 8.5*2.54;
1880  else if (format == 300) value = 11.*2.54;
1881  if (format >= 100) format = 4;
1882 
1883  // Compute size (in points) of the window for each picture = f(fNXzone,fNYzone)
1884  Double_t sizex = width/Double_t(fNXzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
1885  Double_t sizey = heigth/Double_t(fNYzone)*TMath::Power(TMath::Sqrt(2.), 4-format);
1886  Int_t npx = 4*CMtoPS(sizex);
1887  Int_t npy = 4*CMtoPS(sizey);
1888  if (sizex > sizey) fMaxsize = CMtoPS(sizex);
1889  else fMaxsize = CMtoPS(sizey);
1890 
1891  // Procedure Zone
1892  if (fMode != 3) {
1893  PrintFast(33,"/Zone {/iy exch def /ix exch def ");
1894  PrintFast(10," ix 1 sub ");
1895  WriteInteger(npx);
1896  PrintFast(5," mul ");
1898  PrintFast(8," iy sub ");
1899  WriteInteger(npy);
1900  PrintStr(" mul t} def@");
1901  } else {
1902  PrintStr("@");
1903  }
1904 
1905  PrintStr("%%EndProlog@");
1906  PrintStr("%%BeginSetup@");
1907  PrintStr("%%EndSetup@");
1908  PrintFast(8,"newpath ");
1909  SaveRestore(1);
1910  if (fMode == 1 || fMode == 4) {
1911  WriteInteger(CMtoPS(rpxmin));
1912  WriteInteger(CMtoPS(rpymin));
1913  PrintFast(2," t");
1914  }
1915  if (fMode == 2 || fMode == 5) {
1916  PrintFast(7," 90 r 0");
1917  WriteInteger(CMtoPS(-value));
1918  PrintFast(3," t ");
1919  WriteInteger(CMtoPS(rpxmin));
1920  WriteInteger(CMtoPS(rpymin));
1921  PrintFast(2," t");
1922  }
1923 
1924  PrintFast(15," .25 .25 scale ");
1925  if (fMode != 3) {
1926  SaveRestore(1);
1927  PrintStr("@");
1928  PrintStr("%%Page: 1 1@");
1929  SaveRestore(1);
1930  }
1931 
1932  //Check is user has defined a special header in the current style
1933  Int_t nh = strlen(gStyle->GetHeaderPS());
1934  if (nh) {
1935  PrintFast(nh,gStyle->GetHeaderPS());
1936  if (fMode != 3) SaveRestore(1);
1937  }
1938 }
1939 
1940 ////////////////////////////////////////////////////////////////////////////////
1941 /// Move to a new position
1942 
1944 {
1945  if (ix != 0 && iy != 0) {
1946  WriteInteger(ix);
1947  WriteInteger(iy);
1948  PrintFast(2," d");
1949  } else if (ix != 0) {
1950  WriteInteger(ix);
1951  PrintFast(2," X");
1952  } else if (iy != 0) {
1953  WriteInteger(iy);
1954  PrintFast(2," Y");
1955  }
1956 }
1957 
1958 ////////////////////////////////////////////////////////////////////////////////
1959 /// Move to a new PostScript page
1960 
1962 {
1963  // Compute pad conversion coefficients
1964  if (gPad) {
1965  // if (!gPad->GetPadPaint()) gPad->Update();
1966  Double_t ww = gPad->GetWw();
1967  Double_t wh = gPad->GetWh();
1968  fYsize = fXsize*wh/ww;
1969  } else fYsize = 27;
1970 
1971  if(fType == 113 && !fBoundingBox) {
1972  Bool_t psave = fPrinted;
1973  PrintStr("@%%BoundingBox: ");
1974  Double_t xlow=0, ylow=0, xup=1, yup=1;
1975  if (gPad) {
1976  xlow = gPad->GetAbsXlowNDC();
1977  xup = xlow + gPad->GetAbsWNDC();
1978  ylow = gPad->GetAbsYlowNDC();
1979  yup = ylow + gPad->GetAbsHNDC();
1980  }
1981  WriteInteger(CMtoPS(fXsize*xlow));
1982  WriteInteger(CMtoPS(fYsize*ylow));
1983  WriteInteger(CMtoPS(fXsize*xup));
1984  WriteInteger(CMtoPS(fYsize*yup));
1985  PrintStr("@");
1986  Initialize();
1987  fBoundingBox = kTRUE;
1988  fPrinted = psave;
1989  }
1990  if (fPrinted) {
1991  if (fSave) SaveRestore(-1);
1992  fClear = kTRUE;
1993  fPrinted = kFALSE;
1994  }
1995  Zone();
1996 }
1997 
1998 ////////////////////////////////////////////////////////////////////////////////
1999 /// Set the range for the paper in centimeters
2000 
2002 {
2003  Float_t xps=0, yps=0, xncm=0, yncm=0, dxwn=0, dywn=0, xwkwn=0, ywkwn=0, xymax=0;
2004 
2005  fXsize = xsize;
2006  fYsize = ysize;
2007  if( fType != 113) { xps = fXsize; yps = fYsize; }
2008  else { xps = xsize; yps = ysize; }
2009 
2010  if( xsize <= xps && ysize < yps) {
2011  if ( xps > yps ) xymax = xps;
2012  else xymax = yps;
2013  xncm = xsize/xymax;
2014  yncm = ysize/xymax;
2015  dxwn = ((xps/xymax)-xncm)/2;
2016  dywn = ((yps/xymax)-yncm)/2;
2017  } else {
2018  if (xps/yps < 1) xwkwn = xps/yps;
2019  else xwkwn = 1;
2020  if (yps/xps < 1) ywkwn = yps/xps;
2021  else ywkwn = 1;
2022 
2023  if (xsize < ysize) {
2024  xncm = ywkwn*xsize/ysize;
2025  yncm = ywkwn;
2026  dxwn = (xwkwn-xncm)/2;
2027  dywn = 0;
2028  if( dxwn < 0) {
2029  xncm = xwkwn;
2030  dxwn = 0;
2031  yncm = xwkwn*ysize/xsize;
2032  dywn = (ywkwn-yncm)/2;
2033  }
2034  } else {
2035  xncm = xwkwn;
2036  yncm = xwkwn*ysize/xsize;
2037  dxwn = 0;
2038  dywn = (ywkwn-yncm)/2;
2039  if( dywn < 0) {
2040  yncm = ywkwn;
2041  dywn = 0;
2042  xncm = ywkwn*xsize/ysize;
2043  dxwn = (xwkwn-xncm)/2;
2044  }
2045  }
2046  }
2047  fXVP1 = dxwn;
2048  fXVP2 = xncm+dxwn;
2049  fYVP1 = dywn;
2050  fYVP2 = yncm+dywn;
2051  fRange = kTRUE;
2052 }
2053 
2054 ////////////////////////////////////////////////////////////////////////////////
2055 /// Compute number of gsaves for restore
2056 /// This allows to write the correct number of grestore at the
2057 /// end of the PS file.
2058 
2060 {
2061  if (flag == 1) { PrintFast(7," gsave "); fSave++; }
2062  else { PrintFast(4," gr "); fSave--; }
2063 }
2064 
2065 ////////////////////////////////////////////////////////////////////////////////
2066 /// Set color index for fill areas
2067 
2069 {
2070  fFillColor = cindex;
2071  if (gStyle->GetFillColor() <= 0) cindex = 0;
2072  SetColor(Int_t(cindex));
2073 }
2074 
2075 ////////////////////////////////////////////////////////////////////////////////
2076 /// Patterns definition
2077 ///
2078 /// Define the pattern ipat in the current PS file. ipat can vary from
2079 /// 1 to 25. Together with the pattern, the color (color) in which the
2080 /// pattern has to be drawn is also required. A pattern is defined in the
2081 /// current PS file only the first time it is used. Some level 2
2082 /// Postscript functions are used, so on level 1 printers, patterns will
2083 /// not work. This is not a big problem because patterns are
2084 /// defined only if they are used, so if they are not used a PS level 1
2085 /// file will not be polluted by level 2 features, and in any case the old
2086 /// patterns used a lot of memory which made them almost unusable on old
2087 /// level 1 printers. Finally we should say that level 1 devices are
2088 /// becoming very rare. The official PostScript is now level 3 !
2089 
2091 {
2092  char cdef[28];
2093  char cpat[5];
2094  snprintf(cpat,5," P%2.2d", ipat);
2095 
2096  // fPatterns is used as an array of chars. If fPatterns[ipat] != 0 the
2097  // pattern number ipat as already be defined is this file and it
2098  // is not necessary to redefine it. fPatterns is set to zero in Initialize.
2099  // The pattern number 26 allows to know if the macro "cs" has already
2100  // been defined in the current file (see label 200).
2101  if (fPatterns[ipat] == 0) {
2102 
2103  // Define the Patterns. Line width must be 1
2104  // Setting fLineWidth to -1 will force the line width definition next time
2105  // TPostScript::SetLineWidth will be called.
2106  fLineWidth = -1;
2107  PrintFast(5," 1 lw");
2108  PrintStr(" << /PatternType 1 /PaintType 2 /TilingType 1");
2109  switch (ipat) {
2110  case 1 :
2111  PrintStr(" /BBox [ 0 0 98 4 ]");
2112  PrintStr(" /XStep 98 /YStep 4");
2113  PrintStr(" /PaintProc { begin gsave");
2114  PrintStr(" [1] 0 sd 2 4 m 99 4 l s 1 3 m 98 3 l s");
2115  PrintStr(" 2 2 m 99 2 l s 1 1 m 98 1 l s");
2116  PrintStr(" gr end } >> [ 4.0 0 0 4.0 0 0 ]");
2117  break;
2118  case 2 :
2119  PrintStr(" /BBox [ 0 0 96 4 ]");
2120  PrintStr(" /XStep 96 /YStep 4");
2121  PrintStr(" /PaintProc { begin gsave");
2122  PrintStr(" [1 3] 0 sd 2 4 m 98 4 l s 0 3 m 96 3 l s");
2123  PrintStr(" 2 2 m 98 2 l s 0 1 m 96 1 l s");
2124  PrintStr(" gr end } >> [ 3.0 0 0 3.0 0 0 ]");
2125  break;
2126  case 3 :
2127  PrintStr(" /BBox [ 0 0 96 16 ]");
2128  PrintStr(" /XStep 96 /YStep 16");
2129  PrintStr(" /PaintProc { begin gsave");
2130  PrintStr(" [1 3] 0 sd 2 13 m 98 13 l s 0 9 m 96 9 l s");
2131  PrintStr(" 2 5 m 98 5 l s 0 1 m 96 1 l s");
2132  PrintStr(" gr end } >> [ 2.0 0 0 2.0 0 0 ]");
2133  break;
2134  case 4 :
2135  PrintStr(" /BBox [ 0 0 100 100 ]");
2136  PrintStr(" /XStep 100 /YStep 100");
2137  PrintStr(" /PaintProc { begin gsave");
2138  PrintStr(" 0 0 m 100 100 l s");
2139  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2140  break;
2141  case 5 :
2142  PrintStr(" /BBox [ 0 0 100 100 ]");
2143  PrintStr(" /XStep 100 /YStep 100");
2144  PrintStr(" /PaintProc { begin gsave");
2145  PrintStr(" 0 100 m 100 0 l s");
2146  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2147  break;
2148  case 6 :
2149  PrintStr(" /BBox [ 0 0 100 100 ]");
2150  PrintStr(" /XStep 100 /YStep 100");
2151  PrintStr(" /PaintProc { begin gsave");
2152  PrintStr(" 50 0 m 50 100 l s");
2153  PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
2154  break;
2155  case 7 :
2156  PrintStr(" /BBox [ 0 0 100 100 ]");
2157  PrintStr(" /XStep 100 /YStep 100");
2158  PrintStr(" /PaintProc { begin gsave");
2159  PrintStr(" 0 50 m 100 50 l s");
2160  PrintStr(" gr end } >> [ 0.12 0 0 0.12 0 0 ]");
2161  break;
2162  case 8 :
2163  PrintStr(" /BBox [ 0 0 101 101 ]");
2164  PrintStr(" /XStep 100 /YStep 100");
2165  PrintStr(" /PaintProc { begin gsave");
2166  PrintStr(" 0 0 m 0 30 l 30 0 l f 0 70 m 0 100 l 30 100 l f");
2167  PrintStr(" 70 100 m 100 100 l 100 70 l f 70 0 m 100 0 l");
2168  PrintStr(" 100 30 l f 50 20 m 20 50 l 50 80 l 80 50 l f");
2169  PrintStr(" 50 80 m 30 100 l s 20 50 m 0 30 l s 50 20 m");
2170  PrintStr(" 70 0 l s 80 50 m 100 70 l s");
2171  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2172  break;
2173  case 9 :
2174  PrintStr(" /BBox [ 0 0 100 100 ]");
2175  PrintStr(" /XStep 100 /YStep 100");
2176  PrintStr(" /PaintProc { begin gsave");
2177  PrintStr(" 0 50 m 50 50 50 180 360 arc");
2178  PrintStr(" 0 50 m 0 100 50 270 360 arc");
2179  PrintStr(" 50 100 m 100 100 50 180 270 arc s");
2180  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2181  break;
2182  case 10 :
2183  PrintStr(" /BBox [ 0 0 100 100 ]");
2184  PrintStr(" /XStep 100 /YStep 100");
2185  PrintStr(" /PaintProc { begin gsave");
2186  PrintStr(" 0 50 m 100 50 l 1 1 m 100 1 l");
2187  PrintStr(" 0 0 m 0 50 l 100 0 m 100 50 l");
2188  PrintStr(" 50 50 m 50 100 l s");
2189  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2190  break;
2191  case 11 :
2192  PrintStr(" /BBox [ 0 0 100 100 ]");
2193  PrintStr(" /XStep 100 /YStep 100");
2194  PrintStr(" /PaintProc { begin gsave");
2195  PrintStr(" 0 0 m 0 20 l 50 0 m 50 20 l");
2196  PrintStr(" 100 0 m 100 20 l 0 80 m 0 100 l");
2197  PrintStr(" 50 80 m 50 100 l 100 80 m 100 100 l");
2198  PrintStr(" 25 30 m 25 70 l 75 30 m 75 70 l");
2199  PrintStr(" 0 100 m 20 85 l 50 100 m 30 85 l");
2200  PrintStr(" 50 100 m 70 85 l 100 100 m 80 85 l");
2201  PrintStr(" 0 0 m 20 15 l 50 0 m 30 15 l");
2202  PrintStr(" 50 0 m 70 15 l 100 0 m 80 15 l");
2203  PrintStr(" 5 35 m 45 65 l 5 65 m 45 35 l");
2204  PrintStr(" 55 35 m 95 65 l 55 65 m 95 35 l s");
2205  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2206  break;
2207  case 12 :
2208  PrintStr(" /BBox [ 0 0 100 100 ]");
2209  PrintStr(" /XStep 100 /YStep 100");
2210  PrintStr(" /PaintProc { begin gsave");
2211  PrintStr(" 0 80 m 0 100 20 270 360 arc");
2212  PrintStr(" 30 100 m 50 100 20 180 360 arc");
2213  PrintStr(" 80 100 m 100 100 20 180 270 arc");
2214  PrintStr(" 20 0 m 0 0 20 0 90 arc");
2215  PrintStr(" 70 0 m 50 0 20 0 180 arc");
2216  PrintStr(" 100 20 m 100 0 20 90 180 arc");
2217  PrintStr(" 45 50 m 25 50 20 0 360 arc");
2218  PrintStr(" 95 50 m 75 50 20 0 360 arc s");
2219  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2220  break;
2221  case 13 :
2222  PrintStr(" /BBox [ 0 0 100 100 ]");
2223  PrintStr(" /XStep 100 /YStep 100");
2224  PrintStr(" /PaintProc { begin gsave");
2225  PrintStr(" 0 0 m 100 100 l 0 100 m 100 0 l s");
2226  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2227  break;
2228  case 14 :
2229  PrintStr(" /BBox [ 0 0 100 100 ]");
2230  PrintStr(" /XStep 80 /YStep 80");
2231  PrintStr(" /PaintProc { begin gsave");
2232  PrintStr(" 0 20 m 100 20 l 20 0 m 20 100 l");
2233  PrintStr(" 0 80 m 100 80 l 80 0 m 80 100 l");
2234  PrintStr(" 20 40 m 60 40 l 60 20 m 60 60 l");
2235  PrintStr(" 40 40 m 40 80 l 40 60 m 80 60 l s");
2236  PrintStr(" gr end } >> [ 0.60 0 0 0.60 0 0 ]");
2237  break;
2238  case 15 :
2239  PrintStr(" /BBox [ 0 0 60 60 ]");
2240  PrintStr(" /XStep 60 /YStep 60");
2241  PrintStr(" /PaintProc { begin gsave");
2242  PrintStr(" 0 55 m 0 60 5 270 360 arc");
2243  PrintStr(" 25 60 m 30 60 5 180 360 arc");
2244  PrintStr(" 55 60 m 60 60 5 180 270 arc");
2245  PrintStr(" 20 30 m 15 30 5 0 360 arc");
2246  PrintStr(" 50 30 m 45 30 5 0 360");
2247  PrintStr(" arc 5 0 m 0 0 5 0 90 arc");
2248  PrintStr(" 35 0 m 30 0 5 0 180 arc");
2249  PrintStr(" 60 5 m 60 0 5 90 180 arc s");
2250  PrintStr(" gr end } >> [ 0.41 0 0 0.41 0 0 ]");
2251  break;
2252  case 16 :
2253  PrintStr(" /BBox [ 0 0 100 100 ]");
2254  PrintStr(" /XStep 100 /YStep 100");
2255  PrintStr(" /PaintProc { begin gsave");
2256  PrintStr(" 50 50 m 25 50 25 0 180 arc s");
2257  PrintStr(" 50 50 m 75 50 25 180 360 arc s");
2258  PrintStr(" gr end } >> [ 0.4 0 0 0.2 0 0 ]");
2259  break;
2260  case 17 :
2261  PrintStr(" /BBox [ 0 0 100 100 ]");
2262  PrintStr(" /XStep 100 /YStep 100");
2263  PrintStr(" /PaintProc { begin gsave");
2264  PrintStr(" [24] 0 setdash 0 0 m 100 100 l s");
2265  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2266  break;
2267  case 18 :
2268  PrintStr(" /BBox [ 0 0 100 100 ]");
2269  PrintStr(" /XStep 100 /YStep 100");
2270  PrintStr(" /PaintProc { begin gsave");
2271  PrintStr(" [24] 0 setdash 0 100 m 100 0 l s");
2272  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2273  break;
2274  case 19 :
2275  PrintStr(" /BBox [ 0 0 100 100 ]");
2276  PrintStr(" /XStep 100 /YStep 100");
2277  PrintStr(" /PaintProc { begin gsave");
2278  PrintStr(" 90 50 m 50 50 40 0 360 arc");
2279  PrintStr(" 0 50 m 0 100 50 270 360 arc");
2280  PrintStr(" 50 0 m 0 0 50 0 90 arc");
2281  PrintStr(" 100 50 m 100 0 50 90 180 arc");
2282  PrintStr(" 50 100 m 100 100 50 180 270 arc s");
2283  PrintStr(" gr end } >> [ 0.47 0 0 0.47 0 0 ]");
2284  break;
2285  case 20 :
2286  PrintStr(" /BBox [ 0 0 100 100 ]");
2287  PrintStr(" /XStep 100 /YStep 100");
2288  PrintStr(" /PaintProc { begin gsave");
2289  PrintStr(" 50 50 m 50 75 25 270 450 arc s");
2290  PrintStr(" 50 50 m 50 25 25 90 270 arc s");
2291  PrintStr(" gr end } >> [ 0.2 0 0 0.4 0 0 ]");
2292  break;
2293  case 21 :
2294  PrintStr(" /BBox [ 0 0 101 101 ]");
2295  PrintStr(" /XStep 100 /YStep 100");
2296  PrintStr(" /PaintProc { begin gsave");
2297  PrintStr(" 1 1 m 25 1 l 25 25 l 50 25 l 50 50 l");
2298  PrintStr(" 75 50 l 75 75 l 100 75 l 100 100 l");
2299  PrintStr(" 50 1 m 75 1 l 75 25 l 100 25 l 100 50 l");
2300  PrintStr(" 0 50 m 25 50 l 25 75 l 50 75 l 50 100 l s");
2301  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2302  break;
2303  case 22 :
2304  PrintStr(" /BBox [ 0 0 101 101 ]");
2305  PrintStr(" /XStep 100 /YStep 100");
2306  PrintStr(" /PaintProc { begin gsave");
2307  PrintStr(" 1 100 m 25 100 l 25 75 l 50 75 l 50 50 l");
2308  PrintStr(" 75 50 l 75 25 l 100 25 l 100 1 l");
2309  PrintStr(" 50 100 m 75 100 l 75 75 l 100 75 l 100 50 l");
2310  PrintStr(" 0 50 m 25 50 l 25 25 l 50 25 l 50 1 l s");
2311  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2312  break;
2313  case 23 :
2314  PrintStr(" /BBox [ 0 0 100 100 ]");
2315  PrintStr(" /XStep 100 /YStep 100");
2316  PrintStr(" /PaintProc { begin gsave");
2317  PrintStr(" [1 7] 0 sd 0 8 50 { dup dup m 2 mul 0 l s } for");
2318  PrintStr(" 0 8 50 { dup dup 2 mul 100 m 50 add exch 50");
2319  PrintStr(" add l s } for 100 0 m 100 100 l 50 50 l f");
2320  PrintStr(" gr end } >> [ 0.24 0 0 0.24 0 0 ]");
2321  break;
2322  case 24 :
2323  PrintStr(" /BBox [ 0 0 100 100 ]");
2324  PrintStr(" /XStep 100 /YStep 100");
2325  PrintStr(" /PaintProc { begin gsave");
2326  PrintStr(" 100 100 m 100 36 l 88 36 l 88 88 l f");
2327  PrintStr(" 100 0 m 100 12 l 56 12 l 50 0 l f");
2328  PrintStr(" 0 0 m 48 0 l 48 48 l 50 48 l 56 60 l");
2329  PrintStr(" 36 60 l 36 12 l 0 12 l f [1 7] 0 sd");
2330  PrintStr(" 61 8 87 { dup dup dup 12 exch m 88 exch l s");
2331  PrintStr(" 16 exch 4 sub m 88 exch 4 sub l s } for");
2332  PrintStr(" 13 8 35 { dup dup dup 0 exch m 36 exch l s");
2333  PrintStr(" 4 exch 4 sub m 36 exch 4 sub l s } for");
2334  PrintStr(" 37 8 59 { dup dup dup 12 exch m 36 exch l s");
2335  PrintStr(" 16 exch 4 sub m 36 exch 4 sub l s } for");
2336  PrintStr(" 13 8 60 { dup dup dup 56 exch m 100 exch l s");
2337  PrintStr(" 60 exch 4 sub m 100 exch 4 sub l s } for");
2338  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2339  break;
2340  case 25 :
2341  PrintStr(" /BBox [ 0 0 101 101 ]");
2342  PrintStr(" /XStep 100 /YStep 100");
2343  PrintStr(" /PaintProc { begin gsave");
2344  PrintStr(" 0 0 m 30 30 l 70 30 l 70 70 l 100 100 l 100 0 l");
2345  PrintStr(" f 30 30 m 30 70 l 70 70 l f");
2346  PrintStr(" gr end } >> [ 0.5 0 0 0.5 0 0 ]");
2347  };
2348  snprintf(cdef,28," makepattern /%s exch def",&cpat[1]);
2349  PrintStr(cdef);
2350  fPatterns[ipat] = 1;
2351  }
2352 
2353  // Define the macro cs and FA if they are not yet defined.
2354  if (fPatterns[26] == 0) {
2355  if (gStyle->GetColorModelPS()) {
2356  PrintStr(" /cs {[/Pattern /DeviceCMYK] setcolorspace} def");
2357  PrintStr(" /FA {f [/DeviceCMYK] setcolorspace} def");
2358  } else {
2359  PrintStr(" /cs {[/Pattern /DeviceRGB] setcolorspace} def");
2360  PrintStr(" /FA {f [/DeviceRGB] setcolorspace} def");
2361  }
2362  fPatterns[26] = 1;
2363  }
2364 
2365  // Activate the pattern.
2366  PrintFast(3," cs");
2367  TColor *col = gROOT->GetColor(color);
2368  if (col) {
2369  Double_t colRed = col->GetRed();
2370  Double_t colGreen = col->GetGreen();
2371  Double_t colBlue = col->GetBlue();
2372  if (gStyle->GetColorModelPS()) {
2373  Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
2374  if (colBlack==1) {
2375  WriteReal(0);
2376  WriteReal(0);
2377  WriteReal(0);
2378  WriteReal(colBlack);
2379  } else {
2380  Double_t colCyan = (1-colRed-colBlack)/(1-colBlack);
2381  Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
2382  Double_t colYellow = (1-colBlue-colBlack)/(1-colBlack);
2383  WriteReal(colCyan);
2384  WriteReal(colMagenta);
2385  WriteReal(colYellow);
2386  WriteReal(colBlack);
2387  }
2388  } else {
2389  WriteReal(colRed);
2390  WriteReal(colGreen);
2391  WriteReal(colBlue);
2392  }
2393  }
2394  PrintFast(4,cpat);
2395  PrintFast(9," setcolor");
2396 }
2397 
2398 ////////////////////////////////////////////////////////////////////////////////
2399 /// Set color index for lines
2400 
2402 {
2403  fLineColor = cindex;
2404  SetColor(Int_t(cindex));
2405 }
2406 
2407 ////////////////////////////////////////////////////////////////////////////////
2408 /// Set the value of the global parameter TPostScript::fgLineJoin.
2409 /// This parameter determines the appearance of joining lines in a PostScript
2410 /// output.
2411 /// It takes one argument which may be:
2412 /// - 0 (miter join)
2413 /// - 1 (round join)
2414 /// - 2 (bevel join)
2415 /// The default value is 0 (miter join).
2416 ///
2417 /// \image html postscript_1.png
2418 ///
2419 /// To change the line join behaviour just do:
2420 /// ~~~ {cpp}
2421 /// TPostScript::SetLineJoin(2); // Set the PS line join to bevel.
2422 /// ~~~
2423 
2425 {
2426  fgLineJoin = linejoin;
2427 }
2428 
2429 ////////////////////////////////////////////////////////////////////////////////
2430 /// Change the line style
2431 ///
2432 /// - linestyle = 2 dashed
2433 /// - linestyle = 3 dotted
2434 /// - linestyle = 4 dash-dotted
2435 /// - linestyle = else = solid
2436 ///
2437 /// See TStyle::SetLineStyleString for style definition
2438 
2440 {
2441  if ( linestyle == fLineStyle) return;
2442  fLineStyle = linestyle;
2443  const char *st = gStyle->GetLineStyleString(linestyle);
2444  PrintFast(1,"[");
2445  Int_t nch = strlen(st);
2446  PrintFast(nch,st);
2447  PrintFast(6,"] 0 sd");
2448 }
2449 
2450 ////////////////////////////////////////////////////////////////////////////////
2451 /// Change the line width
2452 
2454 {
2455  if ( linewidth == fLineWidth) return;
2456  fLineWidth = linewidth;
2457  if (fLineWidth!=0) {
2459  PrintFast(3," lw");
2460  }
2461 }
2462 
2463 ////////////////////////////////////////////////////////////////////////////////
2464 /// Set color index for markers
2465 
2467 {
2468  fMarkerColor = cindex;
2469  SetColor(Int_t(cindex));
2470 }
2471 
2472 ////////////////////////////////////////////////////////////////////////////////
2473 /// Set the current color.
2474 
2476 {
2477  if (color < 0) color = 0;
2478  fCurrentColor = color;
2479  TColor *col = gROOT->GetColor(color);
2480  if (col)
2481  SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
2482  else
2483  SetColor(1., 1., 1.);
2484 }
2485 
2486 ////////////////////////////////////////////////////////////////////////////////
2487 /// Set directly current color (don't go via TColor).
2488 
2490 {
2491  if (r == fRed && g == fGreen && b == fBlue) return;
2492 
2493  fRed = r;
2494  fGreen = g;
2495  fBlue = b;
2496 
2497  if (fRed <= 0 && fGreen <= 0 && fBlue <= 0 ) {
2498  PrintFast(6," black");
2499  } else {
2500  if (gStyle->GetColorModelPS()) {
2501  Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
2502  Double_t colCyan = (1-fRed-colBlack)/(1-colBlack);
2503  Double_t colMagenta = (1-fGreen-colBlack)/(1-colBlack);
2504  Double_t colYellow = (1-fBlue-colBlack)/(1-colBlack);
2505  WriteReal(colCyan);
2506  WriteReal(colMagenta);
2507  WriteReal(colYellow);
2508  WriteReal(colBlack);
2509  } else {
2510  WriteReal(fRed);
2511  WriteReal(fGreen);
2512  WriteReal(fBlue);
2513  }
2514  PrintFast(2," c");
2515  }
2516 }
2517 
2518 ////////////////////////////////////////////////////////////////////////////////
2519 /// Set color index for text
2520 
2522 {
2523  fTextColor = cindex;
2524 
2525  SetColor( Int_t(cindex) );
2526 }
2527 
2528 ////////////////////////////////////////////////////////////////////////////////
2529 /// Write a string of characters
2530 ///
2531 /// This method writes the string chars into a PostScript file
2532 /// at position xx,yy in world coordinates.
2533 
2534 void TPostScript::Text(Double_t xx, Double_t yy, const char *chars)
2535 {
2536  static const char *psfont[31][2] = {
2537  { "Root.PSFont.1", "/Times-Italic" },
2538  { "Root.PSFont.2", "/Times-Bold" },
2539  { "Root.PSFont.3", "/Times-BoldItalic" },
2540  { "Root.PSFont.4", "/Helvetica" },
2541  { "Root.PSFont.5", "/Helvetica-Oblique" },
2542  { "Root.PSFont.6", "/Helvetica-Bold" },
2543  { "Root.PSFont.7", "/Helvetica-BoldOblique" },
2544  { "Root.PSFont.8", "/Courrier" },
2545  { "Root.PSFont.9", "/Courrier-Oblique" },
2546  { "Root.PSFont.10", "/Courrier-Bold" },
2547  { "Root.PSFont.11", "/Courrier-BoldOblique" },
2548  { "Root.PSFont.12", "/Symbol" },
2549  { "Root.PSFont.13", "/Times-Roman" },
2550  { "Root.PSFont.14", "/ZapfDingbats" },
2551  { "Root.PSFont.15", "/Symbol" },
2552  { "Root.PSFont.STIXGen", "/STIXGeneral" },
2553  { "Root.PSFont.STIXGenIt", "/STIXGeneral-Italic" },
2554  { "Root.PSFont.STIXGenBd", "/STIXGeneral-Bold" },
2555  { "Root.PSFont.STIXGenBdIt", "/STIXGeneral-BoldItalic" },
2556  { "Root.PSFont.STIXSiz1Sym", "/STIXSize1Symbols" },
2557  { "Root.PSFont.STIXSiz1SymBd", "/STIXSize1Symbols-Bold" },
2558  { "Root.PSFont.STIXSiz2Sym", "/STIXSize2Symbols" },
2559  { "Root.PSFont.STIXSiz2SymBd", "/STIXSize2Symbols-Bold" },
2560  { "Root.PSFont.STIXSiz3Sym", "/STIXSize3Symbols" },
2561  { "Root.PSFont.STIXSiz3SymBd", "/STIXSize3Symbols-Bold" },
2562  { "Root.PSFont.STIXSiz4Sym", "/STIXSize4Symbols" },
2563  { "Root.PSFont.STIXSiz4SymBd", "/STIXSize4Symbols-Bold" },
2564  { "Root.PSFont.STIXSiz5Sym", "/STIXSize5Symbols" },
2565  { "Root.PSFont.ME", "/DroidSansFallback" },
2566  { "Root.PSFont.CJKMing", "/DroidSansFallback" },
2567  { "Root.PSFont.CJKGothic", "/DroidSansFallback" }
2568  };
2569 
2570  const Double_t kDEGRAD = TMath::Pi()/180.;
2571  Double_t x = xx;
2572  Double_t y = yy;
2573  if (!gPad) return;
2574 
2575  // Compute the font size. Exit if it is 0
2576  // The font size is computed from the TTF size to get exactly the same
2577  // size on the screen and in the PostScript file.
2578  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2579  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2580  Float_t tsize, ftsize;
2581 
2582  if (wh < hh) {
2583  tsize = fTextSize*wh;
2584  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2585  ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2586  } else {
2587  tsize = fTextSize*hh;
2588  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2589  ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2590  }
2591  Double_t fontsize = 4*(72*(ftsize)/2.54);
2592  if( fontsize <= 0) return;
2593 
2594  Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2595  Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2596 
2597  Int_t font = abs(fTextFont)/10;
2598  if( font > 31 || font < 1) font = 1;
2599 
2600  // Text color.
2602 
2603  // Text alignment.
2604  Int_t txalh = fTextAlign/10;
2605  if (txalh <1) txalh = 1; else if (txalh > 3) txalh = 3;
2606  Int_t txalv = fTextAlign%10;
2607  if (txalv <1) txalv = 1; else if (txalv > 3) txalv = 3;
2608  if (txalv == 3) {
2609  y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2610  x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2611  } else if (txalv == 2) {
2612  y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2613  x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2614  }
2615 
2616  UInt_t w = 0, w0 = 0;
2617  Bool_t kerning;
2618  // In order to measure the precise character positions we need to trick
2619  // FreeType into rendering high-resolution characters otherwise it will
2620  // stick to the screen pixel grid, which is far worse than we can achieve
2621  // on print.
2622  const Float_t scale = 16.0;
2623  // Save current text attributes.
2624  TText saveAttText;
2625  saveAttText.TAttText::operator=(*this);
2626  const Int_t len=strlen(chars);
2627  Int_t *charWidthsCumul = 0;
2628  TText t;
2629  t.SetTextSize(fTextSize * scale);
2631  t.GetTextAdvance(w, chars);
2632  t.GetTextAdvance(w0, chars, kFALSE);
2633  t.TAttText::Modify();
2634  if (w0-w != 0) kerning = kTRUE;
2635  else kerning = kFALSE;
2636  if (kerning) {
2637  // Calculate the individual character placements.
2638  charWidthsCumul = new Int_t[len];
2639  for (Int_t i = len - 1;i >= 0;i--) {
2640  UInt_t ww = 0;
2641  t.GetTextAdvance(ww, chars + i);
2642  Double_t wwl = (gPad->AbsPixeltoX(ww)-gPad->AbsPixeltoX(0));
2643  charWidthsCumul[i] = (Int_t)((XtoPS(wwl) - XtoPS(0)) / scale);
2644  }
2645  }
2646  // Restore text attributes.
2647  saveAttText.TAttText::Modify();
2648 
2649  Double_t charsLength = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2650  Int_t psCharsLength = (Int_t)((XtoPS(charsLength)-XtoPS(0)) / scale);
2651 
2652  // Text angle.
2653  Int_t psangle = Int_t(0.5 + fTextAngle);
2654 
2655  // Save context.
2656  PrintStr("@");
2657  SaveRestore(1);
2658 
2659  // Clipping
2660  Int_t xc1 = XtoPS(gPad->GetX1());
2661  Int_t xc2 = XtoPS(gPad->GetX2());
2662  Int_t yc1 = YtoPS(gPad->GetY1());
2663  Int_t yc2 = YtoPS(gPad->GetY2());
2664  WriteInteger(xc2 - xc1);
2665  WriteInteger(yc2 - yc1);
2666  WriteInteger(xc1);
2667  WriteInteger(yc1);
2668  PrintStr(" C");
2669 
2670  // Output text position and angle. The text position is computed
2671  // using Double_t to avoid precision problems.
2672  Double_t vx = (x - gPad->GetX1())/(gPad->GetX2()-gPad->GetX1());
2673  Double_t cmx = fXsize*(gPad->GetAbsXlowNDC()+vx*gPad->GetAbsWNDC());
2674  WriteReal((288.*cmx)/2.54);
2675  Double_t vy = (y - gPad->GetY1())/(gPad->GetY2()-gPad->GetY1());
2676  Double_t cmy = fYsize*(gPad->GetAbsYlowNDC()+vy*gPad->GetAbsHNDC());
2677  WriteReal((288.*cmy)/2.54);
2678  PrintStr(Form(" t %d r ", psangle));
2679  if(txalh == 2) PrintStr(Form(" %d 0 t ", -psCharsLength/2));
2680  if(txalh == 3) PrintStr(Form(" %d 0 t ", -psCharsLength));
2681  PrintStr(gEnv->GetValue(psfont[font-1][0], psfont[font-1][1]));
2682  if (font != 15) {
2683  PrintStr(Form(" findfont %g sf 0 0 m ",fontsize));
2684  } else {
2685  PrintStr(Form(" findfont %g sf 0 0 m ita ",fontsize));
2686  }
2687 
2688  if (kerning) {
2689  PrintStr("@");
2690  // Output individual character placements
2691  for (Int_t i = len-1; i >= 1; i--) {
2692  WriteInteger(charWidthsCumul[0] - charWidthsCumul[i]);
2693  }
2694  delete [] charWidthsCumul;
2695  PrintStr("@");
2696  }
2697 
2698  // Output text.
2699  PrintStr("(");
2700 
2701  // Inside a PostScript string, the new line (if needed to break up long lines) must be escaped by a backslash.
2702  const char *crsave = fImplicitCREsc;
2703  fImplicitCREsc = "\\";
2704 
2705  char str[8];
2706  for (Int_t i=0; i<len;i++) {
2707  if (chars[i]!='\n') {
2708  if (chars[i]=='(' || chars[i]==')' || chars[i]=='\\') {
2709  snprintf(str,8,"\\%c",chars[i]);
2710  PrintStr(str);
2711  } else if ((chars[i]=='-') && (font != 12)) {
2712  PrintStr("\\255");
2713  } else {
2714  snprintf(str,8,"%c",chars[i]);
2715  PrintFast(1,str);
2716  }
2717  }
2718  }
2719  PrintStr(")");
2720  fImplicitCREsc = crsave;
2721 
2722  if (kerning) {
2723  if (font != 15) PrintStr(" K NC");
2724  else PrintStr(" K gr NC");
2725  } else {
2726  if (font != 15) PrintStr(" show NC");
2727  else PrintStr(" show gr NC");
2728  }
2729 
2730  SaveRestore(-1);
2731 }
2732 
2733 ////////////////////////////////////////////////////////////////////////////////
2734 /// Write a string of characters
2735 ///
2736 /// This method writes the string chars into a PostScript file
2737 /// at position xx,yy in world coordinates.
2738 
2739 void TPostScript::Text(Double_t xx, Double_t yy, const wchar_t *chars)
2740 {
2741  static const char *psfont[31][2] = {
2742  { "Root.PSFont.1", "/FreeSerifItalic" },
2743  { "Root.PSFont.2", "/FreeSerifBold" },
2744  { "Root.PSFont.3", "/FreeSerifBoldItalic" },
2745  { "Root.PSFont.4", "/FreeSans" },
2746  { "Root.PSFont.5", "/FreeSansOblique" },
2747  { "Root.PSFont.6", "/FreeSansBold" },
2748  { "Root.PSFont.7", "/FreeSansBoldOblique" },
2749  { "Root.PSFont.8", "/FreeMono" },
2750  { "Root.PSFont.9", "/FreeMonoOblique" },
2751  { "Root.PSFont.10", "/FreeMonoBold" },
2752  { "Root.PSFont.11", "/FreeMonoBoldOblique" },
2753  { "Root.PSFont.12", "/SymbolMT" },
2754  { "Root.PSFont.13", "/FreeSerif" },
2755  { "Root.PSFont.14", "/Wingdings-Regular" },
2756  { "Root.PSFont.15", "/SymbolMT" },
2757  { "Root.PSFont.STIXGen", "/STIXGeneral" },
2758  { "Root.PSFont.STIXGenIt", "/STIXGeneral-Italic" },
2759  { "Root.PSFont.STIXGenBd", "/STIXGeneral-Bold" },
2760  { "Root.PSFont.STIXGenBdIt", "/STIXGeneral-BoldItalic" },
2761  { "Root.PSFont.STIXSiz1Sym", "/STIXSize1Symbols" },
2762  { "Root.PSFont.STIXSiz1SymBd", "/STIXSize1Symbols-Bold" },
2763  { "Root.PSFont.STIXSiz2Sym", "/STIXSize2Symbols" },
2764  { "Root.PSFont.STIXSiz2SymBd", "/STIXSize2Symbols-Bold" },
2765  { "Root.PSFont.STIXSiz3Sym", "/STIXSize3Symbols" },
2766  { "Root.PSFont.STIXSiz3SymBd", "/STIXSize3Symbols-Bold" },
2767  { "Root.PSFont.STIXSiz4Sym", "/STIXSize4Symbols" },
2768  { "Root.PSFont.STIXSiz4SymBd", "/STIXSize4Symbols-Bold" },
2769  { "Root.PSFont.STIXSiz5Sym", "/STIXSize5Symbols" },
2770  { "Root.PSFont.ME", "/DroidSansFallback" },
2771  { "Root.PSFont.CJKMing", "/DroidSansFallback" },
2772  { "Root.PSFont.CJKGothic", "/DroidSansFallback" }
2773  };
2774 
2775  Int_t len = wcslen(chars);
2776  if (len<=0) return;
2777 
2778  const Double_t kDEGRAD = TMath::Pi()/180.;
2779  Double_t x = xx;
2780  Double_t y = yy;
2781  if (!gPad) return;
2782 
2783  // Compute the font size. Exit if it is 0
2784  // The font size is computed from the TTF size to get exactly the same
2785  // size on the screen and in the PostScript file.
2786  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2787  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2788  Float_t tsize, ftsize;
2789 
2790  if (wh < hh) {
2791  tsize = fTextSize*wh;
2792  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2793  ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2794  } else {
2795  tsize = fTextSize*hh;
2796  Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2797  ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2798  }
2799  Double_t fontsize = 4*(72*(ftsize)/2.54);
2800  if( fontsize <= 0) return;
2801 
2802  Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2803  Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2804 
2805  Int_t font = abs(fTextFont)/10;
2806  if( font > 29 || font < 1) font = 1;
2807 
2808  // Text color.
2810 
2811  // Text alignment.
2812  Int_t txalh = fTextAlign/10;
2813  if (txalh <1) txalh = 1; else if (txalh > 3) txalh = 3;
2814  Int_t txalv = fTextAlign%10;
2815  if (txalv <1) txalv = 1; else if (txalv > 3) txalv = 3;
2816  if (txalv == 3) {
2817  y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2818  x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2819  } else if (txalv == 2) {
2820  y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2821  x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2822  }
2823  UInt_t w = 0, h = 0;
2824 
2825  TText t;
2828  t.GetTextExtent(w, h, chars);
2829  Double_t charsLength = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2830  Int_t psCharsLength = XtoPS(charsLength)-XtoPS(0);
2831 
2832  // Text angle.
2833  Int_t psangle = Int_t(0.5 + fTextAngle);
2834 
2835  // Save context.
2836  PrintStr("@");
2837  SaveRestore(1);
2838 
2839  // Clipping
2840  Int_t xc1 = XtoPS(gPad->GetX1());
2841  Int_t xc2 = XtoPS(gPad->GetX2());
2842  Int_t yc1 = YtoPS(gPad->GetY1());
2843  Int_t yc2 = YtoPS(gPad->GetY2());
2844  WriteInteger(xc2 - xc1);
2845  WriteInteger(yc2 - yc1);
2846  WriteInteger(xc1);
2847  WriteInteger(yc1);
2848  PrintStr(" C");
2849 
2850  // Output text position and angle.
2851  WriteInteger(XtoPS(x));
2852  WriteInteger(YtoPS(y));
2853  PrintStr(Form(" t %d r ", psangle));
2854  if(txalh == 2) PrintStr(Form(" %d 0 t ", -psCharsLength/2));
2855  if(txalh == 3) PrintStr(Form(" %d 0 t ", -psCharsLength));
2856  MustEmbed[font-1] = kTRUE; // This font will be embedded in the file at EOF time.
2857  PrintStr(gEnv->GetValue(psfont[font-1][0], psfont[font-1][1]));
2858  PrintStr(Form(" findfont %g sf 0 0 m ",fontsize));
2859 
2860  // Output text.
2861  if (len > 1) PrintStr(Form("%d ", len));
2862  for(Int_t i = 0; i < len; i++) {
2863  // Adobe Glyph Naming Convention
2864  // http://www.adobe.com/devnet/opentype/archives/glyph.html
2865 #include "AdobeGlyphList.h"
2866  const wchar_t *lower = std::lower_bound(
2868  chars[i]);
2869  if(lower < adobe_glyph_ucs + nadobe_glyph &&
2870  *lower == chars[i]) {
2871  // Named glyph from AGL 1.2
2872  const unsigned long index =
2873  lower - adobe_glyph_ucs;
2874  PrintStr(Form("/%s ", adobe_glyph_name[index]));
2875  }
2876  else if((unsigned int)chars[i] < 0xffff) {
2877  // Unicode BMP
2878  PrintStr(Form("/uni%04X ",
2879  (unsigned int)chars[i]));
2880  }
2881  else {
2882  // Unicode supplemental planes
2883  PrintStr(Form("/u%04X ",
2884  (unsigned int)chars[i]));
2885  }
2886  }
2887  if(len > 1) {
2888  PrintStr("{glyphshow} repeat ");
2889  }
2890  else {
2891  PrintStr("glyphshow ");
2892  }
2893 
2894  PrintStr("NC");
2895 
2896  SaveRestore(-1);
2897 }
2898 
2899 ////////////////////////////////////////////////////////////////////////////////
2900 /// Write a string of characters in NDC
2901 
2902 void TPostScript::TextNDC(Double_t u, Double_t v, const char *chars)
2903 {
2904  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2905  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2906  Text(x, y, chars);
2907 }
2908 
2909 ////////////////////////////////////////////////////////////////////////////////
2910 /// Write a string of characters in NDC
2911 
2912 void TPostScript::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2913 {
2914  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2915  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2916  Text(x, y, chars);
2917 }
2918 
2919 ////////////////////////////////////////////////////////////////////////////////
2920 /// Convert U from NDC coordinate to PostScript
2921 
2923 {
2924  Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2925  return Int_t(0.5 + 288*cm/2.54);
2926 }
2927 
2928 ////////////////////////////////////////////////////////////////////////////////
2929 /// Convert V from NDC coordinate to PostScript
2930 
2932 {
2933  Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2934  return Int_t(0.5 + 288*cm/2.54);
2935 }
2936 
2937 ////////////////////////////////////////////////////////////////////////////////
2938 /// Convert X from world coordinate to PostScript
2939 
2941 {
2942  Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2943  return UtoPS(u);
2944 }
2945 
2946 ////////////////////////////////////////////////////////////////////////////////
2947 /// Convert Y from world coordinate to PostScript
2948 
2950 {
2951  Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2952  return VtoPS(v);
2953 }
2954 
2955 ////////////////////////////////////////////////////////////////////////////////
2956 /// Initialize the PostScript page in zones
2957 
2959 {
2960  if( !fClear )return;
2961  fClear = kFALSE;
2962 
2963  // When Zone has been called, fZone is TRUE
2964  fZone = kTRUE;
2965 
2966  if( fIYzone > fNYzone) {
2967  fIYzone=1;
2968  if( fMode != 3) {
2969  PrintStr("@showpage");
2970  SaveRestore(-1);
2971  fNpages++;
2972  PrintStr("@%%Page:");
2975  PrintStr("@");
2976  } else {
2977  PrintFast(9," showpage");
2978  SaveRestore(-1);
2979  }
2980  }
2981 
2982  // No grestore the first time
2983  if( fMode != 3) {
2984  if( fIXzone != 1 || fIYzone != 1) SaveRestore(-1);
2985  SaveRestore(1);
2986  PrintStr("@");
2989  PrintFast(5," Zone");
2990  PrintStr("@");
2991  fIXzone++;
2992  if( fIXzone > fNXzone) { fIXzone=1; fIYzone++; }
2993  }
2994 
2995  // Picture Initialisation
2996  SaveRestore(1);
2997  if (fgLineJoin) {
2999  PrintFast(12," setlinejoin");
3000  }
3001  PrintFast(6," 0 0 t");
3002  fRed = -1;
3003  fGreen = -1;
3004  fBlue = -1;
3005  fPrinted = kFALSE;
3006  fLineColor = -1;
3007  fLineStyle = -1;
3008  fLineWidth = -1;
3009  fFillColor = -1;
3010  fFillStyle = -1;
3011  fMarkerSizeCur = -1;
3012 }
Interface to PostScript.
Definition: TPostScript.h:31
virtual ~TPostScript()
Default PostScript destructor.
const char * GetLineStyleString(Int_t i=1) const
Return line style string (used by PostScript).
Definition: TStyle.cxx:787
void DrawPolyLine(Int_t n, TPoints *xy)
Draw a PolyLine.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1265
static Bool_t MustEmbed[32]
const char * GetHeaderPS() const
Definition: TStyle.h:292
Int_t fNBSameColorCell
Definition: TPostScript.h:88
char * fBuffer
Definition: TVirtualPS.h:52
void Text(Double_t x, Double_t y, const char *string)
Write a string of characters.
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:711
Float_t fXsize
Definition: TPostScript.h:56
Float_t fYVP2
Definition: TPostScript.h:51
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:155
short Style_t
Definition: RtypesCore.h:76
Bool_t fClear
Definition: TPostScript.h:76
TLine * line
void On()
Activate an already open PostScript file.
float Float_t
Definition: RtypesCore.h:53
void DrawPolyLineNDC(Int_t n, TPoints *uv)
Draw a PolyLine in NDC space.
const char Option_t
Definition: RtypesCore.h:62
Int_t CMtoPS(Double_t u)
Definition: TPostScript.h:104
void DefineMarkers()
Define the markers.
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
void CellArrayFill(Int_t r, Int_t g, Int_t b)
Paint the Cell Array.
Float_t fYsize
Definition: TPostScript.h:57
TH1 * h
Definition: legend2.C:5
Float_t fXVP2
Definition: TPostScript.h:49
const char * fImplicitCREsc
Definition: TVirtualPS.h:53
Size_t fMarkerSize
Definition: TAttMarker.h:37
Bool_t fBoundingBox
Definition: TPostScript.h:75
static const char * filename()
Int_t fCurrentColor
Definition: TPostScript.h:70
#define gROOT
Definition: TROOT.h:340
Basic string class.
Definition: TString.h:137
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
Definition: TVirtualPS.cxx:167
void GetPaperSize(Float_t &xsize, Float_t &ysize) const
Set paper size for PostScript output.
Definition: TStyle.cxx:805
Float_t GetLineScalePS() const
Definition: TStyle.h:295
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
static const unsigned long nadobe_glyph
Definition: AdobeGlyphList.h:1
Int_t fLastCellRed
Definition: TPostScript.h:85
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Float_t fMarkerSizeCur
Definition: TPostScript.h:69
const Bool_t kFALSE
Definition: Rtypes.h:92
void DrawPS(Int_t n, Float_t *xw, Float_t *yw)
Draw a PolyLine.
Float_t GetGreen() const
Definition: TColor.h:61
Int_t fNXzone
Definition: TPostScript.h:65
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1511
char fPatterns[32]
Definition: TPostScript.h:80
Bool_t fFontEmbed
Definition: TPostScript.h:90
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Draw a Box.
void FontEmbed()
Embed font in PS file.
bool FontEmbedType42(const char *filename)
static std::string format(double x, double y, int digits, int width)
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
virtual void WriteReal(Float_t r, Bool_t space=kTRUE)
Write a Real number to the file.
Definition: TVirtualPS.cxx:182
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition: TSystem.cxx:1319
Int_t fType
Definition: TPostScript.h:72
void SetLineStyle(Style_t linestyle=1)
Change the line style.
const char * Data() const
Definition: TString.h:349
virtual void SetTextFont(Font_t tfont=62)
Definition: TAttText.h:59
Int_t fSave
Definition: TPostScript.h:64
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1346
static const double x2[5]
Float_t fMaxsize
Definition: TPostScript.h:58
Int_t fNpages
Definition: TPostScript.h:71
Double_t x[n]
Definition: legend1.C:17
void SetLineWidth(Width_t linewidth=1)
Change the line width.
void Open(const char *filename, Int_t type=-111)
Open a PostScript file.
static Int_t fgLineJoin
Definition: TPostScript.h:92
virtual void PrintStr(const char *string="")
Output the string str in the output buffer.
Definition: TVirtualPS.cxx:69
TString fFileName
Definition: TPostScript.h:89
Int_t fNYzone
Definition: TPostScript.h:66
bool FontEmbedType2(const char *filename)
Float_t GetBlue() const
Definition: TColor.h:62
Int_t fNbCellW
Definition: TPostScript.h:82
Bool_t fClipStatus
Definition: TPostScript.h:77
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
Definition: vector.h:450
Base class for several text objects.
Definition: TText.h:42
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Int_t fIYzone
Definition: TPostScript.h:68
Int_t fNbCellLine
Definition: TPostScript.h:83
char * out
Definition: TBase64.cxx:29
short Color_t
Definition: RtypesCore.h:79
Int_t GetColorModelPS() const
Definition: TStyle.h:206
void DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt, Int_t mode, Int_t border, Int_t dark, Int_t light)
Draw a Frame around a box.
Style_t fMarkerStyle
Definition: TAttMarker.h:36
TCanvas * kerning()
Definition: kerning.C:1
void CellArrayEnd()
End the Cell Array painting.
void MovePS(Int_t x, Int_t y)
Move to a new position.
Int_t UtoPS(Double_t u)
Convert U from NDC coordinate to PostScript.
Float_t fTextAngle
Definition: TAttText.h:35
Style_t fLineStyle
Definition: TAttLine.h:36
ROOT::R::TRInterface & r
Definition: Object.C:4
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimeters.
SVector< double, 2 > v
Definition: Dict.h:5
XPoint xy[kMAXMK]
Definition: TGX11.cxx:122
Int_t fSizBuffer
Definition: TVirtualPS.h:49
Color_t fLineColor
Definition: TAttLine.h:35
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
void DrawPolyMarker(Int_t n, Float_t *x, Float_t *y)
Draw markers at the n WC points x, y.
virtual Color_t GetFillColor() const
Definition: TAttFill.h:43
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
unsigned int UInt_t
Definition: RtypesCore.h:42
Width_t fLineWidth
Definition: TAttLine.h:37
Float_t fXVP1
Definition: TPostScript.h:48
char * Form(const char *fmt,...)
Int_t fLastCellBlue
Definition: TPostScript.h:87
void DrawHatch(Float_t dy, Float_t angle, Int_t n, Float_t *x, Float_t *y)
Draw Fill area with hatch styles.
void SetMarkerColor(Color_t cindex=1)
Set color index for markers.
virtual void GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
Return text extent for string text.
Definition: TText.cxx:583
Bool_t fPrinted
Definition: TVirtualPS.h:50
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
void SetLineJoin(Int_t linejoin=0)
Set the value of the global parameter TPostScript::fgLineJoin.
std::ofstream * fStream
Definition: TVirtualPS.h:51
const Float_t kScale
void FontEncode()
Font Re-encoding.
Float_t fRed
Definition: TPostScript.h:59
Font_t fTextFont
Definition: TAttText.h:39
Bool_t fRange
Definition: TPostScript.h:78
Double_t Cos(Double_t)
Definition: TMath.h:424
short Width_t
Definition: RtypesCore.h:78
void CellArrayBegin(Int_t W, Int_t H, Double_t x1, Double_t x2, Double_t y1, Double_t y2)
Draw a Cell Array.
PyObject * fType
Double_t Pi()
Definition: TMath.h:44
2-D graphics point (world coordinates).
Definition: TPoints.h:29
void SaveRestore(Int_t flag)
Compute number of gsaves for restore This allows to write the correct number of grestore at the end o...
Int_t YtoPS(Double_t y)
Convert Y from world coordinate to PostScript.
virtual void PrintRaw(Int_t len, const char *str)
Print a raw.
Definition: TVirtualPS.cxx:197
Int_t fNbinCT
Definition: TPostScript.h:81
static const double x1[5]
void Off()
Deactivate an already open PostScript file.
void SetFillPatterns(Int_t ipat, Int_t color)
Patterns definition.
double Double_t
Definition: RtypesCore.h:55
virtual void PrintFast(Int_t nch, const char *string="")
Fast version of Print.
Definition: TVirtualPS.cxx:100
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Bool_t fZone
Definition: TPostScript.h:79
bool FontEmbedType1(const char *filename)
Double_t y[n]
Definition: legend1.C:17
Int_t fIXzone
Definition: TPostScript.h:67
The color creation and management class.
Definition: TColor.h:23
Float_t GetRed() const
Definition: TColor.h:60
Float_t fTextSize
Definition: TAttText.h:36
void Zone()
Initialize the PostScript page in zones.
void SetColor(Int_t color=1)
Set the current color.
Int_t fLenBuffer
Definition: TVirtualPS.h:48
static const char * adobe_glyph_name[nadobe_glyph]
void SetLineScale(Float_t scale=3)
Definition: TPostScript.h:136
Int_t VtoPS(Double_t v)
Convert V from NDC coordinate to PostScript.
void Close(Option_t *opt="")
Close a PostScript file.
void SetFillColor(Color_t cindex=1)
Set color index for fill areas.
Color_t fFillColor
Definition: TAttFill.h:35
Double_t Sin(Double_t)
Definition: TMath.h:421
Int_t fClip
Definition: TPostScript.h:74
void Initialize()
PostScript Initialisation.
ClassImp(TPostScript) TPostScript
Default PostScript constructor.
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:91
#define gPad
Definition: TVirtualPad.h:288
Int_t fMode
Definition: TPostScript.h:73
Int_t fLastCellGreen
Definition: TPostScript.h:86
void NewPage()
Move to a new PostScript page.
virtual void GetTextAdvance(UInt_t &a, const char *text, const Bool_t kern=kTRUE) const
Return text advance for string text if kern is true (default) kerning is taken into account...
Definition: TText.cxx:611
Float_t fLineScale
Definition: TPostScript.h:62
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition: TVirtualPS.h:40
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
Int_t XtoPS(Double_t x)
Convert X from world coordinate to PostScript.
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:99
const Bool_t kTRUE
Definition: Rtypes.h:91
Color_t fMarkerColor
Definition: TAttMarker.h:35
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
float value
Definition: math.cpp:443
const char * GetTitlePS() const
Definition: TStyle.h:293
Color_t fTextColor
Definition: TAttText.h:38
void SetTextColor(Color_t cindex=1)
Set color index for text.
const Int_t n
Definition: legend1.C:16
void SetLineColor(Color_t cindex=1)
Set color index for lines.
Float_t fGreen
Definition: TPostScript.h:60
Float_t fYVP1
Definition: TPostScript.h:50
static const float lower
Definition: main.cpp:48
Int_t fMaxLines
Definition: TPostScript.h:84
Float_t fBlue
Definition: TPostScript.h:61
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:39
Style_t fFillStyle
Definition: TAttFill.h:36
Short_t fTextAlign
Definition: TAttText.h:37
static const wchar_t adobe_glyph_ucs[nadobe_glyph]
Definition: AdobeGlyphList.h:2
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904