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