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