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