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