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