Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TPDF.cxx
Go to the documentation of this file.
1// @(#)root/postscript:$Id: TPDF.cxx,v 1.0
2// Author: Olivier Couet
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 TPDF
13\ingroup PS
14
15\brief Interface to PDF.
16
17Like PostScript, PDF is a vector graphics output format allowing a very high
18graphics output quality. The functionalities provided by this class are very
19similar to those provided by `TPostScript`.
20
21Compare to PostScript output, the PDF files are usually smaller because some
22parts of them can be compressed.
23
24PDF also allows to define table of contents. This facility can be used in ROOT.
25The following example shows how to proceed:
26~~~ {.cpp}
27{
28 TCanvas* canvas = new TCanvas("canvas");
29 TH1F* histo = new TH1F("histo","test 1",10,0.,10.);
30 histo->SetFillColor(2);
31 histo->Fill(2.);
32 histo->Draw();
33 canvas->Print("plots.pdf(","Title:One bin filled");
34 histo->Fill(4.);
35 histo->Draw();
36 canvas->Print("plots.pdf","Title:Two bins filled");
37 histo->Fill(6.);
38 histo->Draw();
39 canvas->Print("plots.pdf","Title:Three bins filled");
40 histo->Fill(8.);
41 histo->Draw();
42 canvas->Print("plots.pdf","Title:Four bins filled");
43 histo->Fill(8.);
44 histo->Draw();
45 canvas->Print("plots.pdf)","Title:The fourth bin content is 2");
46}
47~~~
48Each character string following the keyword "Title:" makes a new entry in
49the table of contents.
50*/
51
52#ifdef WIN32
53#pragma optimize("",off)
54#endif
55
56#include <cstdlib>
57#include <cstring>
58#include <cctype>
59#include <fstream>
60
61#include "TROOT.h"
62#include "TDatime.h"
63#include "TColor.h"
64#include "TVirtualPad.h"
65#include "TPoints.h"
66#include "TPDF.h"
67#include "TStyle.h"
68#include "TMath.h"
69#include "TStorage.h"
70#include "TText.h"
71#include "zlib.h"
72#include "TObjString.h"
73#include "TObjArray.h"
74#include "snprintf.h"
75
76// To scale fonts to the same size as the old TT version
77const Float_t kScale = 0.93376068;
78
79// Objects numbers
80const Int_t kObjRoot = 1; // Root object
81const Int_t kObjInfo = 2; // Info object
82const Int_t kObjOutlines = 3; // Outlines object
83const Int_t kObjPages = 4; // Pages object (pages index)
84const Int_t kObjPageResources = 5; // Pages Resources object
85const Int_t kObjContents = 6; // Table of content
86const Int_t kObjFont = 7; // First Font object (14 in total)
87const Int_t kObjColorSpace = 22; // ColorSpace object
88const Int_t kObjPatternResourses = 23; // Pattern Resources object
89const Int_t kObjPatternList = 24; // Pattern list object
90const Int_t kObjTransList = 25; // List of transparencies
91const Int_t kObjPattern = 26; // First pattern object (25 in total)
92const Int_t kObjFirstPage = 51; // First page object
93
94// Number of fonts
96
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Default PDF constructor
103
105{
107 SetTitle("PDF");
108 gVirtualPS = this;
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Initialize the PDF interface
113///
114/// - fname : PDF file name
115/// - wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
116/// inherits from TVirtualPS it should be kept. Anyway it is not
117/// necessary to specify this parameter at creation time because it
118/// has a default value (which is ignore in the PDF case).
119
120TPDF::TPDF(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
121{
123 SetTitle("PDF");
124 Open(fname, wtype);
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Default PDF destructor
129
131{
132 Close();
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Begin the Cell Array painting
137
139 Double_t)
140{
141 Warning("CellArrayBegin", "not yet implemented");
142}
143
144////////////////////////////////////////////////////////////////////////////////
145/// Paint the Cell Array
146
148{
149 Warning("CellArrayFill", "not yet implemented");
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// End the Cell Array painting
154
156{
157 Warning("CellArrayEnd", "not yet implemented");
158}
159
160////////////////////////////////////////////////////////////////////////////////
161/// Close a PDF file
162
164{
165 if (!gVirtualPS || !fStream)
166 return;
167
168 if (gPad)
169 gPad->Update();
170
171 // Close the currently opened page
173 PrintStr("endstream@");
174 Int_t streamLength = fNByte-fStartStream-10;
175 EndObject();
177 WriteInteger(streamLength, false);
178 PrintStr("@");
179 EndObject();
181 PrintStr("<<@");
182 if (!strstr(GetTitle(),"PDF")) {
183 PrintStr("/Title (");
185 PrintStr(")@");
186 } else {
187 PrintStr("/Title (Page");
189 PrintStr(")@");
190 }
191 PrintStr("/Dest [");
193 PrintStr(" 0 R /XYZ null null 0]@");
194 PrintStr("/Parent");
196 PrintStr(" 0 R");
197 PrintStr("@");
198 if (fNbPage > 1) {
199 PrintStr("/Prev");
201 PrintStr(" 0 R");
202 PrintStr("@");
203 }
204 PrintStr(">>@");
205 EndObject();
207 PrintStr("@");
209 PrintStr("<<@");
210 PrintStr("/Type /Outlines@");
211 PrintStr("/Count");
213 PrintStr("@");
214 PrintStr("/First");
216 PrintStr(" 0 R");
217 PrintStr("@");
218 PrintStr("/Last");
220 PrintStr(" 0 R");
221 PrintStr("@");
222 PrintStr(">>@");
223 EndObject();
224
226 PrintStr("<<@");
227 PrintStr("/Title (Contents)@");
228 PrintStr("/Dest [");
230 PrintStr(" 0 R /XYZ null null 0]@");
231 PrintStr("/Count");
233 PrintStr("@");
234 PrintStr("/Parent");
236 PrintStr(" 0 R");
237 PrintStr("@");
238 PrintStr("/First");
240 PrintStr(" 0 R");
241 PrintStr("@");
242 PrintStr("/Last");
244 PrintStr(" 0 R");
245 PrintStr("@");
246 PrintStr(">>@");
247 EndObject();
248
249 // List of all the pages
251 PrintStr("<<@");
252 PrintStr("/Type /Pages@");
253 PrintStr("/Count");
255 PrintStr("@");
256 PrintStr("/Kids [");
257 for (std::size_t i = 0; i < fPageObjects.size(); i++) {
259 PrintStr(" 0 R");
260 }
261 PrintStr(" ]");
262 PrintStr("@");
263 PrintStr(">>@");
264 EndObject();
265
266 if (!fPageObjects.empty())
267 fPageObjects.clear();
268 if (!fUrls.empty())
269 fUrls.clear();
270 if (!fRectX1.empty())
271 fRectX1.clear();
272 if (!fRectY1.empty())
273 fRectY1.clear();
274 if (!fRectX2.empty())
275 fRectX2.clear();
276 if (!fRectY2.empty())
277 fRectY2.clear();
278
279 // List of transparencies
281 PrintStr("<<@");
282 for (std::size_t i = 0; i < fAlphas.size(); i++) {
283 PrintStr(
284 TString::Format("/ca%3.2f << /Type /ExtGState /ca %3.2f >> /CA%3.2f << /Type /ExtGState /CA %3.2f >>@",
285 fAlphas[i],fAlphas[i],fAlphas[i],fAlphas[i]));
286 }
287 PrintStr(">>@");
288 EndObject();
289 if (!fAlphas.empty())
290 fAlphas.clear();
291
292 // Cross-Reference Table
293 Int_t refInd = fNByte;
294 PrintStr("xref@");
295 PrintStr("0");
296 WriteInteger(fObjPos.size() + 1);
297 PrintStr("@");
298 PrintStr("0000000000 65535 f @");
299 char str[21];
300 for (std::size_t i = 0; i < fObjPos.size(); ++i) {
301 snprintf(str,21,"%10.10d 00000 n @", fObjPos[i]);
302 PrintStr(str);
303 }
304
305 // Trailer
306 PrintStr("trailer@");
307 PrintStr("<<@");
308 PrintStr("/Size");
309 WriteInteger(fObjPos.size() + 1);
310 PrintStr("@");
311 PrintStr("/Root");
313 PrintStr(" 0 R");
314 PrintStr("@");
315 PrintStr("/Info");
317 PrintStr(" 0 R@");
318 PrintStr(">>@");
319 PrintStr("startxref@");
320 WriteInteger(refInd, false);
321 PrintStr("@");
322 PrintStr("%%EOF@");
323
324 // Close file stream
325 CloseStream();
326
327 gVirtualPS = nullptr;
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Draw a Box
332
334{
335 static Double_t x[4], y[4];
336 Double_t ix1 = XtoPDF(x1);
337 Double_t ix2 = XtoPDF(x2);
338 Double_t iy1 = YtoPDF(y1);
339 Double_t iy2 = YtoPDF(y2);
340 Int_t fillis = fFillStyle/1000;
341 Int_t fillsi = fFillStyle%1000;
342
343 if (fillis == 3 || fillis == 2) {
344 if (fillsi > 99) {
345 x[0] = x1; y[0] = y1;
346 x[1] = x2; y[1] = y1;
347 x[2] = x2; y[2] = y2;
348 x[3] = x1; y[3] = y2;
349 return;
350 }
351 if (fillsi > 0 && fillsi < 26) {
352 x[0] = x1; y[0] = y1;
353 x[1] = x2; y[1] = y1;
354 x[2] = x2; y[2] = y2;
355 x[3] = x1; y[3] = y2;
356 DrawPS(-4, &x[0], &y[0]);
357 }
358 if (fillsi == -3) {
359 SetColor(5);
360 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
361 WriteReal(ix1);
362 WriteReal(iy1);
363 WriteReal(ix2 - ix1);
364 WriteReal(iy2 - iy1);
365 if (fAlpha == 1) PrintFast(8," re b* Q");
366 else PrintFast(6," re f*");
367 }
368 }
369 if (fillis == 1) {
371 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
372 WriteReal(ix1);
373 WriteReal(iy1);
374 WriteReal(ix2 - ix1);
375 WriteReal(iy2 - iy1);
376 if (fAlpha == 1) PrintFast(8," re b* Q");
377 else PrintFast(6," re f*");
378 }
379 if (fillis == 0) {
380 if (fLineWidth<=0) return;
382 WriteReal(ix1);
383 WriteReal(iy1);
384 WriteReal(ix2 - ix1);
385 WriteReal(iy2 - iy1);
386 PrintFast(5," re S");
387 }
388}
389
390////////////////////////////////////////////////////////////////////////////////
391/// Draw a Frame around a box
392///
393/// - mode = -1 box looks as it is behind the screen
394/// - mode = 1 box looks as it is in front of the screen
395/// - border is the border size in already precomputed PDF units
396/// - dark is the color for the dark part of the frame
397/// - light is the color for the light part of the frame
398
400 Int_t mode, Int_t border, Int_t dark, Int_t light)
401{
402 static Double_t xps[7], yps[7];
403 Int_t i;
404
405 // Draw top&left part of the box
406 if (mode == -1) SetColor(dark);
407 else SetColor(light);
408 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
409 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
410 xps[2] = xps[1]; yps[2] = YtoPDF(yt) - border;
411 xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
412 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
413 xps[5] = xps[0]; yps[5] = yps[4];
414 xps[6] = xps[0]; yps[6] = yps[0];
415
416 MoveTo(xps[0], yps[0]);
417 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
418 PrintFast(3," f*");
419
420 // Draw bottom&right part of the box
421 if (mode == -1) SetColor(light);
422 else SetColor(dark);
423 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
424 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
425 xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
426 xps[3] = xps[2]; yps[3] = YtoPDF(yt) - border;
427 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
428 xps[5] = xps[4]; yps[5] = yps[0];
429 xps[6] = xps[0]; yps[6] = yps[0];
430
431 MoveTo(xps[0], yps[0]);
432 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
433 PrintFast(3," f*");
434}
435
436////////////////////////////////////////////////////////////////////////////////
437/// Draw Fill area with hatch styles
438
440{
441 Warning("DrawHatch", "hatch fill style not yet implemented");
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Draw Fill area with hatch styles
446
448{
449 Warning("DrawHatch", "hatch fill style not yet implemented");
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Draw a PolyLine
454///
455/// Draw a polyline through the points xy.
456///
457/// - If NN=1 moves only to point x,y.
458/// - If NN=0 the x,y are written in the PDF file
459/// according to the current transformation.
460/// - If NN>0 the line is clipped as a line.
461/// - If NN<0 the line is clipped as a fill area.
462
464{
465 Int_t n;
466
467 Style_t linestylesav = fLineStyle;
468 Width_t linewidthsav = fLineWidth;
469
470 if (nn > 0) {
471 if (fLineWidth<=0) return;
472 n = nn;
476 } else {
477 n = -nn;
478 SetLineStyle(1);
479 SetLineWidth(1);
481 }
482
483 WriteReal(XtoPDF(xy[0].GetX()));
484 WriteReal(YtoPDF(xy[0].GetY()));
485 if (n <= 1) {
486 if (n == 0) return;
487 PrintFast(2," m");
488 return;
489 }
490
491 PrintFast(2," m");
492
493 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
494
495 if (nn > 0) {
496 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
497 PrintFast(2," S");
498 } else {
499 PrintFast(3," f*");
500 }
501
502 SetLineStyle(linestylesav);
503 SetLineWidth(linewidthsav);
504}
505
506////////////////////////////////////////////////////////////////////////////////
507/// Draw a PolyLine in NDC space
508///
509/// Draw a polyline through the points xy.
510///
511/// - If NN=1 moves only to point x,y.
512/// - If NN=0 the x,y are written in the PDF file
513/// according to the current transformation.
514/// - If NN>0 the line is clipped as a line.
515/// - If NN<0 the line is clipped as a fill area.
516
518{
519 Int_t n;
520
521 Style_t linestylesav = fLineStyle;
522 Width_t linewidthsav = fLineWidth;
523
524 if (nn > 0) {
525 if (fLineWidth<=0) return;
526 n = nn;
530 } else {
531 n = -nn;
532 SetLineStyle(1);
533 SetLineWidth(1);
535 }
536
537 WriteReal(UtoPDF(xy[0].GetX()));
538 WriteReal(VtoPDF(xy[0].GetY()));
539 if (n <= 1) {
540 if (n == 0) return;
541 PrintFast(2," m");
542 return;
543 }
544
545 PrintFast(2," m");
546
547 for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
548
549 if (nn > 0) {
550 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
551 PrintFast(2," S");
552 } else {
553 PrintFast(3," f*");
554 }
555
556 SetLineStyle(linestylesav);
557 SetLineWidth(linewidthsav);
558}
559
560////////////////////////////////////////////////////////////////////////////////
561/// Draw markers at the n WC points xw, yw
562
564{
566 Style_t linestylesav = fLineStyle;
567 Width_t linewidthsav = fLineWidth;
568 SetLineStyle(1);
572
573 if (ms == 4)
574 ms = 24;
575 else if (ms >= 6 && ms <= 8)
576 ms = 20;
577 else if (ms >= 9 && ms <= 19)
578 ms = 1;
579
580 // Define the marker size
582 if (fMarkerStyle == 1 || (fMarkerStyle >= 9 && fMarkerStyle <= 19)) {
583 msize = 1.;
584 } else if (fMarkerStyle == 6) {
585 msize = 1.;
586 } else if (fMarkerStyle == 7) {
587 msize = 1.5;
588 } else {
589 const Int_t kBASEMARKER = 8;
590 Float_t sbase = msize*kBASEMARKER;
591 Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
592 msize = this->UtoPDF(s2x) - this->UtoPDF(0);
593 }
594
595 Double_t m = msize;
596 Double_t m2 = m/2;
597 Double_t m3 = m/3;
598 Double_t m4 = m2*1.333333333333;
599 Double_t m6 = m/6;
600 Double_t m0 = m/10.;
601 Double_t m8 = m/4;
602 Double_t m9 = m/8;
603
604 // Draw the marker according to the type
605 Double_t ix,iy;
606 for (Int_t i=0;i<n;i++) {
607 ix = XtoPDF(xw[i]);
608 iy = YtoPDF(yw[i]);
609 // Dot (.)
610 if (ms == 1) {
611 MoveTo(ix-1, iy);
612 LineTo(ix , iy);
613 // Plus (+)
614 } else if (ms == 2) {
615 MoveTo(ix-m2, iy);
616 LineTo(ix+m2, iy);
617 MoveTo(ix , iy-m2);
618 LineTo(ix , iy+m2);
619 // X shape (X)
620 } else if (ms == 5) {
621 MoveTo(ix-m2*0.707, iy-m2*0.707);
622 LineTo(ix+m2*0.707, iy+m2*0.707);
623 MoveTo(ix-m2*0.707, iy+m2*0.707);
624 LineTo(ix+m2*0.707, iy-m2*0.707);
625 // Asterisk shape (*)
626 } else if (ms == 3 || ms == 31) {
627 MoveTo(ix-m2, iy);
628 LineTo(ix+m2, iy);
629 MoveTo(ix , iy-m2);
630 LineTo(ix , iy+m2);
631 MoveTo(ix-m2*0.707, iy-m2*0.707);
632 LineTo(ix+m2*0.707, iy+m2*0.707);
633 MoveTo(ix-m2*0.707, iy+m2*0.707);
634 LineTo(ix+m2*0.707, iy-m2*0.707);
635 // Circle
636 } else if (ms == 24 || ms == 20) {
637 MoveTo(ix-m2, iy);
638 WriteReal(ix-m2); WriteReal(iy+m4);
639 WriteReal(ix+m2); WriteReal(iy+m4);
640 WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
641 WriteReal(ix+m2); WriteReal(iy-m4);
642 WriteReal(ix-m2); WriteReal(iy-m4);
643 WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
644 // Square
645 } else if (ms == 25 || ms == 21) {
646 WriteReal(ix-m2); WriteReal(iy-m2);
647 WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
648 // Down triangle
649 } else if (ms == 23 || ms == 32) {
650 MoveTo(ix , iy-m2);
651 LineTo(ix+m2, iy+m2);
652 LineTo(ix-m2, iy+m2);
653 PrintFast(2," h");
654 // Up triangle
655 } else if (ms == 26 || ms == 22) {
656 MoveTo(ix-m2, iy-m2);
657 LineTo(ix+m2, iy-m2);
658 LineTo(ix , iy+m2);
659 PrintFast(2," h");
660 } else if (ms == 27 || ms == 33) {
661 MoveTo(ix , iy-m2);
662 LineTo(ix+m3, iy);
663 LineTo(ix , iy+m2);
664 LineTo(ix-m3, iy) ;
665 PrintFast(2," h");
666 } else if (ms == 28 || ms == 34) {
667 MoveTo(ix-m6, iy-m6);
668 LineTo(ix-m6, iy-m2);
669 LineTo(ix+m6, iy-m2);
670 LineTo(ix+m6, iy-m6);
671 LineTo(ix+m2, iy-m6);
672 LineTo(ix+m2, iy+m6);
673 LineTo(ix+m6, iy+m6);
674 LineTo(ix+m6, iy+m2);
675 LineTo(ix-m6, iy+m2);
676 LineTo(ix-m6, iy+m6);
677 LineTo(ix-m2, iy+m6);
678 LineTo(ix-m2, iy-m6);
679 PrintFast(2," h");
680 } else if (ms == 29 || ms == 30) {
681 MoveTo(ix , iy+m2);
682 LineTo(ix+0.112255*m, iy+0.15451*m);
683 LineTo(ix+0.47552*m , iy+0.15451*m);
684 LineTo(ix+0.181635*m, iy-0.05902*m);
685 LineTo(ix+0.29389*m , iy-0.40451*m);
686 LineTo(ix , iy-0.19098*m);
687 LineTo(ix-0.29389*m , iy-0.40451*m);
688 LineTo(ix-0.181635*m, iy-0.05902*m);
689 LineTo(ix-0.47552*m , iy+0.15451*m);
690 LineTo(ix-0.112255*m, iy+0.15451*m);
691 PrintFast(2," h");
692 } else if (ms == 35 ) {
693 // diamond with cross
694 MoveTo(ix-m2, iy );
695 LineTo(ix , iy-m2);
696 LineTo(ix+m2, iy );
697 LineTo(ix , iy+m2);
698 LineTo(ix-m2, iy );
699 LineTo(ix+m2, iy );
700 LineTo(ix , iy+m2);
701 LineTo(ix , iy-m2);
702 PrintFast(2," h");
703 } else if (ms == 36 ) {
704 // square with diagonal cross
705 MoveTo(ix-m2, iy-m2);
706 LineTo(ix+m2, iy-m2);
707 LineTo(ix+m2, iy+m2);
708 LineTo(ix-m2, iy+m2);
709 LineTo(ix-m2, iy-m2);
710 LineTo(ix+m2, iy+m2);
711 LineTo(ix-m2, iy+m2);
712 LineTo(ix+m2, iy-m2);
713 PrintFast(2," h");
714 } else if (ms == 37 || ms == 39 ) {
715 // square with cross
716 MoveTo(ix , iy );
717 LineTo(ix-m8, iy+m2);
718 LineTo(ix-m2, iy );
719 LineTo(ix , iy );
720 LineTo(ix-m8, iy-m2);
721 LineTo(ix+m8, iy-m2);
722 LineTo(ix , iy );
723 LineTo(ix+m2, iy );
724 LineTo(ix+m8, iy+m2);
725 LineTo(ix , iy );
726 PrintFast(2," h");
727 } else if (ms == 38 ) {
728 // + shaped marker with octagon
729 MoveTo(ix-m2, iy );
730 LineTo(ix-m2, iy-m8);
731 LineTo(ix-m8, iy-m2);
732 LineTo(ix+m8, iy-m2);
733 LineTo(ix+m2, iy-m8);
734 LineTo(ix+m2, iy+m8);
735 LineTo(ix+m8, iy+m2);
736 LineTo(ix-m8, iy+m2);
737 LineTo(ix-m2, iy+m8);
738 LineTo(ix-m2, iy );
739 LineTo(ix+m2, iy );
740 LineTo(ix , iy );
741 LineTo(ix , iy-m2);
742 LineTo(ix , iy+m2);
743 LineTo(ix , iy);
744 PrintFast(2," h");
745 } else if (ms == 40 || ms == 41 ) {
746 // four triangles X
747 MoveTo(ix , iy );
748 LineTo(ix+m8, iy+m2);
749 LineTo(ix+m2, iy+m8);
750 LineTo(ix , iy );
751 LineTo(ix+m2, iy-m8);
752 LineTo(ix+m8, iy-m2);
753 LineTo(ix , iy );
754 LineTo(ix-m8, iy-m2);
755 LineTo(ix-m2, iy-m8);
756 LineTo(ix , iy );
757 LineTo(ix-m2, iy+m8);
758 LineTo(ix-m8, iy+m2);
759 LineTo(ix , iy );
760 PrintFast(2," h");
761 } else if (ms == 42 || ms == 43 ) {
762 // double diamonds
763 MoveTo(ix , iy+m2);
764 LineTo(ix-m9, iy+m9);
765 LineTo(ix-m2, iy );
766 LineTo(ix-m9, iy-m9);
767 LineTo(ix , iy-m2);
768 LineTo(ix+m9, iy-m9);
769 LineTo(ix+m2, iy );
770 LineTo(ix+m9, iy+m9);
771 LineTo(ix , iy+m2);
772 PrintFast(2," h");
773 } else if (ms == 44 ) {
774 // open four triangles plus
775 MoveTo(ix , iy );
776 LineTo(ix+m8, iy+m2);
777 LineTo(ix-m8, iy+m2);
778 LineTo(ix+m8, iy-m2);
779 LineTo(ix-m8, iy-m2);
780 LineTo(ix , iy );
781 LineTo(ix+m2, iy+m8);
782 LineTo(ix+m2, iy-m8);
783 LineTo(ix-m2, iy+m8);
784 LineTo(ix-m2, iy-m8);
785 LineTo(ix , iy );
786 PrintFast(2," h");
787 } else if (ms == 45 ) {
788 // filled four triangles plus
789 MoveTo(ix+m0, iy+m0);
790 LineTo(ix+m8, iy+m2);
791 LineTo(ix-m8, iy+m2);
792 LineTo(ix-m0, iy+m0);
793 LineTo(ix-m2, iy+m8);
794 LineTo(ix-m2, iy-m8);
795 LineTo(ix-m0, iy-m0);
796 LineTo(ix-m8, iy-m2);
797 LineTo(ix+m8, iy-m2);
798 LineTo(ix+m0, iy-m0);
799 LineTo(ix+m2, iy-m8);
800 LineTo(ix+m2, iy+m8);
801 LineTo(ix+m0, iy+m0);
802 PrintFast(2," h");
803 } else if (ms == 46 || ms == 47 ) {
804 // four triangles X
805 MoveTo(ix , iy+m8);
806 LineTo(ix-m8, iy+m2);
807 LineTo(ix-m2, iy+m8);
808 LineTo(ix-m8, iy );
809 LineTo(ix-m2, iy-m8);
810 LineTo(ix-m8, iy-m2);
811 LineTo(ix , iy-m8);
812 LineTo(ix+m8, iy-m2);
813 LineTo(ix+m2, iy-m8);
814 LineTo(ix+m8, iy );
815 LineTo(ix+m2, iy+m8);
816 LineTo(ix+m8, iy+m2);
817 LineTo(ix , iy+m8);
818 PrintFast(2," h");
819 } else if (ms == 48 ) {
820 // four filled squares X
821 MoveTo(ix , iy+m8*1.01);
822 LineTo(ix-m8, iy+m2);
823 LineTo(ix-m2, iy+m8);
824 LineTo(ix-m8, iy );
825 LineTo(ix-m2, iy-m8);
826 LineTo(ix-m8, iy-m2);
827 LineTo(ix , iy-m8);
828 LineTo(ix+m8, iy-m2);
829 LineTo(ix+m2, iy-m8);
830 LineTo(ix+m8, iy );
831 LineTo(ix+m2, iy+m8);
832 LineTo(ix+m8, iy+m2);
833 LineTo(ix , iy+m8*0.99);
834 LineTo(ix+m8*0.99, iy );
835 LineTo(ix , iy-m8*0.99);
836 LineTo(ix-m8*0.99, iy );
837 LineTo(ix , iy+m8*0.99);
838 PrintFast(2," h");
839 } else if (ms == 49 ) {
840 // four filled squares plus
841 MoveTo(ix-m6, iy-m6*1.01);
842 LineTo(ix-m6, iy-m2);
843 LineTo(ix+m6, iy-m2);
844 LineTo(ix+m6, iy-m6);
845 LineTo(ix+m2, iy-m6);
846 LineTo(ix+m2, iy+m6);
847 LineTo(ix+m6, iy+m6);
848 LineTo(ix+m6, iy+m2);
849 LineTo(ix-m6, iy+m2);
850 LineTo(ix-m6, iy+m6);
851 LineTo(ix-m2, iy+m6);
852 LineTo(ix-m2, iy-m6);
853 LineTo(ix-m6, iy-m6*0.99);
854 LineTo(ix-m6, iy+m6);
855 LineTo(ix+m6, iy+m6);
856 LineTo(ix+m6, iy-m6);
857 PrintFast(2," h");
858 } else {
859 MoveTo(ix-m6, iy-m6);
860 LineTo(ix-m6, iy-m2);
861 }
862
863 if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
864 ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
865 ms == 47 || ms == 48 || ms == 49) {
866 PrintFast(2," f");
867 } else {
868 PrintFast(2," S");
869 }
870 }
871
872 SetLineStyle(linestylesav);
873 SetLineWidth(linewidthsav);
874}
875
876////////////////////////////////////////////////////////////////////////////////
877/// Draw markers at the n WC points xw, yw
878
880{
882 Style_t linestylesav = fLineStyle;
883 Width_t linewidthsav = fLineWidth;
884 SetLineStyle(1);
888
889 if (ms == 4)
890 ms = 24;
891 else if (ms >= 6 && ms <= 8)
892 ms = 20;
893 else if (ms >= 9 && ms <= 19)
894 ms = 1;
895
896 // Define the marker size
898 if (fMarkerStyle == 1 || (fMarkerStyle >= 9 && fMarkerStyle <= 19)) {
899 msize = 1.;
900 } else if (fMarkerStyle == 6) {
901 msize = 1.5;
902 } else if (fMarkerStyle == 7) {
903 msize = 3.;
904 } else {
905 const Int_t kBASEMARKER = 8;
906 Float_t sbase = msize*kBASEMARKER;
907 Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
908 msize = this->UtoPDF(s2x) - this->UtoPDF(0);
909 }
910
911 Double_t m = msize;
912 Double_t m2 = m/2;
913 Double_t m3 = m/3;
914 Double_t m4 = m2*1.333333333333;
915 Double_t m6 = m/6;
916 Double_t m8 = m/4;
917 Double_t m9 = m/8;
918
919 // Draw the marker according to the type
920 Double_t ix,iy;
921 for (Int_t i=0;i<n;i++) {
922 ix = XtoPDF(xw[i]);
923 iy = YtoPDF(yw[i]);
924 // Dot (.)
925 if (ms == 1) {
926 MoveTo(ix-1, iy);
927 LineTo(ix , iy);
928 // Plus (+)
929 } else if (ms == 2) {
930 MoveTo(ix-m2, iy);
931 LineTo(ix+m2, iy);
932 MoveTo(ix , iy-m2);
933 LineTo(ix , iy+m2);
934 // X shape (X)
935 } else if (ms == 5) {
936 MoveTo(ix-m2*0.707, iy-m2*0.707);
937 LineTo(ix+m2*0.707, iy+m2*0.707);
938 MoveTo(ix-m2*0.707, iy+m2*0.707);
939 LineTo(ix+m2*0.707, iy-m2*0.707);
940 // Asterisk shape (*)
941 } else if (ms == 3 || ms == 31) {
942 MoveTo(ix-m2, iy);
943 LineTo(ix+m2, iy);
944 MoveTo(ix , iy-m2);
945 LineTo(ix , iy+m2);
946 MoveTo(ix-m2*0.707, iy-m2*0.707);
947 LineTo(ix+m2*0.707, iy+m2*0.707);
948 MoveTo(ix-m2*0.707, iy+m2*0.707);
949 LineTo(ix+m2*0.707, iy-m2*0.707);
950 // Circle
951 } else if (ms == 24 || ms == 20) {
952 MoveTo(ix-m2, iy);
953 WriteReal(ix-m2); WriteReal(iy+m4);
954 WriteReal(ix+m2); WriteReal(iy+m4);
955 WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
956 WriteReal(ix+m2); WriteReal(iy-m4);
957 WriteReal(ix-m2); WriteReal(iy-m4);
958 WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
959 // Square
960 } else if (ms == 25 || ms == 21) {
961 WriteReal(ix-m2); WriteReal(iy-m2);
962 WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
963 // Down triangle
964 } else if (ms == 23 || ms == 32) {
965 MoveTo(ix , iy-m2);
966 LineTo(ix+m2, iy+m2);
967 LineTo(ix-m2, iy+m2);
968 PrintFast(2," h");
969 // Up triangle
970 } else if (ms == 26 || ms == 22) {
971 MoveTo(ix-m2, iy-m2);
972 LineTo(ix+m2, iy-m2);
973 LineTo(ix , iy+m2);
974 PrintFast(2," h");
975 } else if (ms == 27 || ms == 33) {
976 MoveTo(ix , iy-m2);
977 LineTo(ix+m3, iy);
978 LineTo(ix , iy+m2);
979 LineTo(ix-m3, iy) ;
980 PrintFast(2," h");
981 } else if (ms == 28 || ms == 34) {
982 MoveTo(ix-m6, iy-m6);
983 LineTo(ix-m6, iy-m2);
984 LineTo(ix+m6, iy-m2);
985 LineTo(ix+m6, iy-m6);
986 LineTo(ix+m2, iy-m6);
987 LineTo(ix+m2, iy+m6);
988 LineTo(ix+m6, iy+m6);
989 LineTo(ix+m6, iy+m2);
990 LineTo(ix-m6, iy+m2);
991 LineTo(ix-m6, iy+m6);
992 LineTo(ix-m2, iy+m6);
993 LineTo(ix-m2, iy-m6);
994 PrintFast(2," h");
995 } else if (ms == 29 || ms == 30) {
996 MoveTo(ix , iy-m2);
997 LineTo(ix-0.112255*m, iy-0.15451*m);
998 LineTo(ix-0.47552*m , iy-0.15451*m);
999 LineTo(ix-0.181635*m, iy+0.05902*m);
1000 LineTo(ix-0.29389*m , iy+0.40451*m);
1001 LineTo(ix , iy+0.19098*m);
1002 LineTo(ix+0.29389*m , iy+0.40451*m);
1003 LineTo(ix+0.181635*m, iy+0.05902*m);
1004 LineTo(ix+0.47552*m , iy-0.15451*m);
1005 LineTo(ix+0.112255*m, iy-0.15451*m);
1006 PrintFast(2," h");
1007 } else if (ms == 35 ) {
1008 MoveTo(ix-m2, iy );
1009 LineTo(ix , iy-m2);
1010 LineTo(ix+m2, iy );
1011 LineTo(ix , iy+m2);
1012 LineTo(ix-m2, iy );
1013 LineTo(ix+m2, iy );
1014 LineTo(ix , iy+m2);
1015 LineTo(ix , iy-m2);
1016 PrintFast(2," h");
1017 } else if (ms == 36 ) {
1018 MoveTo(ix-m2, iy-m2);
1019 LineTo(ix+m2, iy-m2);
1020 LineTo(ix+m2, iy+m2);
1021 LineTo(ix-m2, iy+m2);
1022 LineTo(ix-m2, iy-m2);
1023 LineTo(ix+m2, iy+m2);
1024 LineTo(ix-m2, iy+m2);
1025 LineTo(ix+m2, iy-m2);
1026 PrintFast(2," h");
1027 } else if (ms == 37 || ms == 39 ) {
1028 MoveTo(ix , iy );
1029 LineTo(ix-m8, iy+m2);
1030 LineTo(ix-m2, iy );
1031 LineTo(ix , iy );
1032 LineTo(ix-m8, iy-m2);
1033 LineTo(ix+m8, iy-m2);
1034 LineTo(ix , iy );
1035 LineTo(ix+m2, iy );
1036 LineTo(ix+m8, iy+m2);
1037 LineTo(ix , iy );
1038 PrintFast(2," h");
1039 } else if (ms == 38 ) {
1040 MoveTo(ix-m2, iy );
1041 LineTo(ix-m2, iy-m8);
1042 LineTo(ix-m8, iy-m2);
1043 LineTo(ix+m8, iy-m2);
1044 LineTo(ix+m2, iy-m8);
1045 LineTo(ix+m2, iy+m8);
1046 LineTo(ix+m8, iy+m2);
1047 LineTo(ix-m8, iy+m2);
1048 LineTo(ix-m2, iy+m8);
1049 LineTo(ix-m2, iy );
1050 LineTo(ix+m2, iy );
1051 LineTo(ix , iy );
1052 LineTo(ix , iy-m2);
1053 LineTo(ix , iy+m2);
1054 LineTo(ix , iy );
1055 PrintFast(2," h");
1056 } else if (ms == 40 || ms == 41 ) {
1057 MoveTo(ix , iy );
1058 LineTo(ix+m8, iy+m2);
1059 LineTo(ix+m2, iy+m8);
1060 LineTo(ix , iy );
1061 LineTo(ix+m2, iy-m8);
1062 LineTo(ix+m8, iy-m2);
1063 LineTo(ix , iy );
1064 LineTo(ix-m8, iy-m2);
1065 LineTo(ix-m2, iy-m8);
1066 LineTo(ix , iy );
1067 LineTo(ix-m2, iy+m8);
1068 LineTo(ix-m8, iy+m2);
1069 LineTo(ix , iy );
1070 PrintFast(2," h");
1071 } else if (ms == 42 || ms == 43 ) {
1072 MoveTo(ix , iy+m2);
1073 LineTo(ix-m9, iy+m9);
1074 LineTo(ix-m2, iy );
1075 LineTo(ix-m9, iy-m9);
1076 LineTo(ix , iy-m2);
1077 LineTo(ix+m9, iy-m9);
1078 LineTo(ix+m2, iy );
1079 LineTo(ix+m9, iy+m9);
1080 LineTo(ix , iy+m2);
1081 PrintFast(2," h");
1082 } else if (ms == 44 ) {
1083 MoveTo(ix , iy );
1084 LineTo(ix+m8, iy+m2);
1085 LineTo(ix-m8, iy+m2);
1086 LineTo(ix+m8, iy-m2);
1087 LineTo(ix-m8, iy-m2);
1088 LineTo(ix , iy );
1089 LineTo(ix+m2, iy+m8);
1090 LineTo(ix+m2, iy-m8);
1091 LineTo(ix-m2, iy+m8);
1092 LineTo(ix-m2, iy-m8);
1093 LineTo(ix , iy );
1094 PrintFast(2," h");
1095 } else if (ms == 45 ) {
1096 MoveTo(ix+m6/2., iy+m6/2.);
1097 LineTo(ix+m8, iy+m2);
1098 LineTo(ix-m8, iy+m2);
1099 LineTo(ix-m6/2., iy+m6/2.);
1100 LineTo(ix-m2, iy+m8);
1101 LineTo(ix-m2, iy-m8);
1102 LineTo(ix-m6/2., iy-m6/2.);
1103 LineTo(ix-m8, iy-m2);
1104 LineTo(ix+m8, iy-m2);
1105 LineTo(ix+m6/2., iy-m6/2.);
1106 LineTo(ix+m2, iy-m8);
1107 LineTo(ix+m2, iy+m8);
1108 LineTo(ix+m6/2., iy+m6/2.);
1109 PrintFast(2," h");
1110 } else if (ms == 46 || ms == 47 ) {
1111 MoveTo(ix , iy+m8);
1112 LineTo(ix-m8, iy+m2);
1113 LineTo(ix-m2, iy+m8);
1114 LineTo(ix-m8, iy );
1115 LineTo(ix-m2, iy-m8);
1116 LineTo(ix-m8, iy-m2);
1117 LineTo(ix , iy-m8);
1118 LineTo(ix+m8, iy-m2);
1119 LineTo(ix+m2, iy-m8);
1120 LineTo(ix+m8, iy );
1121 LineTo(ix+m2, iy+m8);
1122 LineTo(ix+m8, iy+m2);
1123 LineTo(ix , iy+m8);
1124 PrintFast(2," h");
1125 } else if (ms == 48 ) {
1126 MoveTo(ix , iy+m8*1.005);
1127 LineTo(ix-m8, iy+m2);
1128 LineTo(ix-m2, iy+m8);
1129 LineTo(ix-m8, iy );
1130 LineTo(ix-m2, iy-m8);
1131 LineTo(ix-m8, iy-m2);
1132 LineTo(ix , iy-m8);
1133 LineTo(ix+m8, iy-m2);
1134 LineTo(ix+m2, iy-m8);
1135 LineTo(ix+m8, iy );
1136 LineTo(ix+m2, iy+m8);
1137 LineTo(ix+m8, iy+m2);
1138 LineTo(ix , iy+m8*0.995);
1139 LineTo(ix+m8*0.995, iy );
1140 LineTo(ix , iy-m8*0.995);
1141 LineTo(ix-m8*0.995, iy );
1142 LineTo(ix , iy+m8*0.995);
1143 PrintFast(2," h");
1144 } else if (ms == 49 ) {
1145 MoveTo(ix-m6, iy-m6*1.01);
1146 LineTo(ix-m6, iy-m2);
1147 LineTo(ix+m6, iy-m2);
1148 LineTo(ix+m6, iy-m6);
1149 LineTo(ix+m2, iy-m6);
1150 LineTo(ix+m2, iy+m6);
1151 LineTo(ix+m6, iy+m6);
1152 LineTo(ix+m6, iy+m2);
1153 LineTo(ix-m6, iy+m2);
1154 LineTo(ix-m6, iy+m6);
1155 LineTo(ix-m2, iy+m6);
1156 LineTo(ix-m2, iy-m6);
1157 LineTo(ix-m6, iy-m6*0.99);
1158 LineTo(ix-m6, iy+m6);
1159 LineTo(ix+m6, iy+m6);
1160 LineTo(ix+m6, iy-m6);
1161 MoveTo(ix-m6, iy-m6*1.01);
1162 PrintFast(2," h");
1163 } else {
1164 MoveTo(ix-1, iy);
1165 LineTo(ix , iy);
1166 }
1167 if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
1168 ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
1169 ms == 47 || ms == 48 || ms == 49) {
1170 PrintFast(2," f");
1171 } else {
1172 PrintFast(2," S");
1173 }
1174 }
1175
1176 SetLineStyle(linestylesav);
1177 SetLineWidth(linewidthsav);
1178}
1179
1180////////////////////////////////////////////////////////////////////////////////
1181/// Draw a PolyLine
1182///
1183/// Draw a polyline through the points xw,yw.
1184///
1185/// - If nn=1 moves only to point xw,yw.
1186/// - If nn=0 the XW(1) and YW(1) are written in the PDF file
1187/// according to the current NT.
1188/// - If nn>0 the line is clipped as a line.
1189/// - If nn<0 the line is clipped as a fill area.
1190
1192{
1193 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1194 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1195 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1196 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1197 180, 90,135, 45,150, 30,120, 60,
1198 180, 90,135, 45,150, 30,120, 60};
1199 Int_t n = 0, fais = 0 , fasi = 0;
1200
1201 Style_t linestylesav = fLineStyle;
1202 Width_t linewidthsav = fLineWidth;
1203
1204 if (nn > 0) {
1205 if (fLineWidth<=0) return;
1206 n = nn;
1210 }
1211 if (nn < 0) {
1212 n = -nn;
1213 SetLineStyle(1);
1214 SetLineWidth(1);
1216 fais = fFillStyle/1000;
1217 fasi = fFillStyle%1000;
1218 if (fais == 3 || fais == 2) {
1219 if (fasi > 100 && fasi <125) {
1220 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1221 SetLineStyle(linestylesav);
1222 SetLineWidth(linewidthsav);
1223 return;
1224 }
1225 if (fasi > 0 && fasi < 26) {
1227 }
1228 }
1229 }
1230
1231 WriteReal(XtoPDF(xw[0]));
1232 WriteReal(YtoPDF(yw[0]));
1233 if (n <= 1) {
1234 if (n == 0) return;
1235 PrintFast(2," m");
1236 return;
1237 }
1238
1239 PrintFast(2," m");
1240
1241 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1242
1243 if (nn > 0) {
1244 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1245 PrintFast(2," S");
1246 } else {
1247 if (fais == 0) {PrintFast(2," s"); return;}
1248 if (fais == 3 || fais == 2) {
1249 if (fasi > 0 && fasi < 26) {
1250 PrintFast(3," f*");
1251 fRed = -1;
1252 fGreen = -1;
1253 fBlue = -1;
1254 fAlpha = -1.;
1255 }
1256 SetLineStyle(linestylesav);
1257 SetLineWidth(linewidthsav);
1258 return;
1259 }
1260 PrintFast(3," f*");
1261 }
1262
1263 SetLineStyle(linestylesav);
1264 SetLineWidth(linewidthsav);
1265}
1266
1267////////////////////////////////////////////////////////////////////////////////
1268/// Draw a PolyLine
1269///
1270/// Draw a polyline through the points xw,yw.
1271///
1272/// - If nn=1 moves only to point xw,yw.
1273/// - If nn=0 the xw(1) and YW(1) are written in the PDF file
1274/// according to the current NT.
1275/// - If nn>0 the line is clipped as a line.
1276/// - If nn<0 the line is clipped as a fill area.
1277
1279{
1280 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1281 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1282 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1283 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1284 180, 90,135, 45,150, 30,120, 60,
1285 180, 90,135, 45,150, 30,120, 60};
1286 Int_t n = 0, fais = 0, fasi = 0;
1287
1288 Style_t linestylesav = fLineStyle;
1289 Width_t linewidthsav = fLineWidth;
1290
1291 if (nn > 0) {
1292 if (fLineWidth<=0) return;
1293 n = nn;
1297 }
1298 if (nn < 0) {
1299 n = -nn;
1300 SetLineStyle(1);
1301 SetLineWidth(1);
1303 fais = fFillStyle/1000;
1304 fasi = fFillStyle%1000;
1305 if (fais == 3 || fais == 2) {
1306 if (fasi > 100 && fasi <125) {
1307 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1308 SetLineStyle(linestylesav);
1309 SetLineWidth(linewidthsav);
1310 return;
1311 }
1312 if (fasi > 0 && fasi < 26) {
1314 }
1315 }
1316 }
1317
1318 WriteReal(XtoPDF(xw[0]));
1319 WriteReal(YtoPDF(yw[0]));
1320 if (n <= 1) {
1321 if (n == 0) return;
1322 PrintFast(2," m");
1323 return;
1324 }
1325
1326 PrintFast(2," m");
1327
1328 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1329
1330 if (nn > 0) {
1331 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1332 PrintFast(2," S");
1333 } else {
1334 if (fais == 0) {PrintFast(2," s"); return;}
1335 if (fais == 3 || fais == 2) {
1336 if (fasi > 0 && fasi < 26) {
1337 PrintFast(3," f*");
1338 fRed = -1;
1339 fGreen = -1;
1340 fBlue = -1;
1341 fAlpha = -1.;
1342 }
1343 SetLineStyle(linestylesav);
1344 SetLineWidth(linewidthsav);
1345 return;
1346 }
1347 PrintFast(3," f*");
1348 }
1349
1350 SetLineStyle(linestylesav);
1351 SetLineWidth(linewidthsav);
1352}
1353
1354////////////////////////////////////////////////////////////////////////////////
1355/// Close the current opened object
1356
1358{
1359 if (!fObjectIsOpen)
1360 Warning("EndObject", "No Object currently opened.");
1362
1363 PrintStr("endobj@");
1364}
1365
1366////////////////////////////////////////////////////////////////////////////////
1367/// Font encoding
1368
1370{
1371 static const char *sdtfonts[] = {
1372 "/Times-Italic" , "/Times-Bold" , "/Times-BoldItalic",
1373 "/Helvetica" , "/Helvetica-Oblique" , "/Helvetica-Bold" ,
1374 "/Helvetica-BoldOblique", "/Courier" , "/Courier-Oblique" ,
1375 "/Courier-Bold" , "/Courier-BoldOblique", "/Symbol" ,
1376 "/Times-Roman" , "/ZapfDingbats" , "/Symbol"};
1377
1378 for (Int_t i=0; i<kNumberOfFonts; i++) {
1380 PrintStr("<<@");
1381 PrintStr("/Type /Font@");
1382 PrintStr("/Subtype /Type1@");
1383 PrintStr("/Name /F");
1384 WriteInteger(i+1,false);
1385 PrintStr("@");
1386 PrintStr("/BaseFont ");
1387 PrintStr(sdtfonts[i]);
1388 PrintStr("@");
1389 if (i!=11 && i!=13 && i!=14) {
1390 PrintStr("/Encoding /WinAnsiEncoding");
1391 PrintStr("@");
1392 }
1393 PrintStr(">>@");
1394 EndObject();
1395 }
1396}
1397
1398////////////////////////////////////////////////////////////////////////////////
1399/// Draw a line to a new position
1400
1402{
1403 WriteReal(x);
1404 WriteReal(y);
1405 PrintFast(2," l");
1406}
1407
1408////////////////////////////////////////////////////////////////////////////////
1409/// Move to a new position
1410
1412{
1413 WriteReal(x);
1414 WriteReal(y);
1415 PrintFast(2," m");
1416}
1417
1418////////////////////////////////////////////////////////////////////////////////
1419/// Create a new object in the PDF file
1420
1422{
1423 if (fObjectIsOpen)
1424 Warning("NewObject", "An Object is already open.");
1426 if (n > (Int_t) fObjPos.size())
1427 fObjPos.resize(n, 0); // filling new elements with 0
1428 if (n > 0)
1429 fObjPos[n-1] = fNByte;
1430 else
1431 Error("NewObject", "Wrong id %d is specified.", n);
1432 WriteInteger(n, false);
1433 PrintStr(" 0 obj");
1434 PrintStr("@");
1435}
1436
1437////////////////////////////////////////////////////////////////////////////////
1438/// Start a new PDF page.
1439
1441{
1442 if (!fPageNotEmpty) return;
1443
1444 // Compute pad conversion coefficients
1445 if (gPad) {
1446 Double_t ww = gPad->GetWw();
1447 Double_t wh = gPad->GetWh();
1448 fYsize = fXsize*wh/ww;
1449 } else {
1450 fYsize = 27;
1451 }
1452
1453 fNbPage++;
1454 fA = 1.;
1455 fB = 0.;
1456 fC = 0.;
1457 fD = 1.;
1458 fE = 0.;
1459 fF = 0.;
1460
1461 if (fNbPage>1) {
1462 // Close the currently opened page
1464 PrintStr("endstream@");
1465 Int_t streamLength = fNByte-fStartStream-10;
1466 EndObject();
1468 WriteInteger(streamLength, false);
1469 PrintStr("@");
1470 EndObject();
1472 PrintStr("<<@");
1473 if (!strstr(GetTitle(),"PDF")) {
1474 PrintStr("/Title (");
1475 PrintStr(GetTitle());
1476 PrintStr(")@");
1477 } else {
1478 PrintStr("/Title (Page");
1480 PrintStr(")@");
1481 }
1482 PrintStr("/Dest [");
1484 PrintStr(" 0 R /XYZ null null 0]@");
1485 PrintStr("/Parent");
1487 PrintStr(" 0 R");
1488 PrintStr("@");
1489 PrintStr("/Next");
1491 PrintStr(" 0 R");
1492 PrintStr("@");
1493 if (fNbPage>2) {
1494 PrintStr("/Prev");
1496 PrintStr(" 0 R");
1497 PrintStr("@");
1498 }
1499 PrintStr(">>@");
1500 EndObject();
1502 fCurrentPage = fCurrentPage + fNbUrl + 4; // object number of the next page
1503 fNbUrl = 1;
1504 }
1505
1506 // Start a new page
1507 PrintStr("@");
1509 fPageObjects.push_back(fCurrentPage);
1510 PrintStr("<<@");
1511 PrintStr("/Type /Page@");
1512 PrintStr("@");
1513 PrintStr("/Parent");
1515 PrintStr(" 0 R");
1516 PrintStr("@");
1517
1518 Double_t xlow=0, ylow=0, xup=1, yup=1;
1519 if (gPad) {
1520 xlow = gPad->GetAbsXlowNDC();
1521 xup = xlow + gPad->GetAbsWNDC();
1522 ylow = gPad->GetAbsYlowNDC();
1523 yup = ylow + gPad->GetAbsHNDC();
1524 }
1525
1526 PrintStr("/MediaBox [");
1527 Double_t width, height;
1528 switch (fPageFormat) {
1529 case 100 :
1530 width = 8.5*2.54;
1531 height = 11.*2.54;
1532 break;
1533 case 200 :
1534 width = 8.5*2.54;
1535 height = 14.*2.54;
1536 break;
1537 case 300 :
1538 width = 11.*2.54;
1539 height = 17.*2.54;
1540 break;
1541 default :
1542 width = 21.0*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1543 height = 29.7*TMath::Power(TMath::Sqrt(2.), 4-fPageFormat);
1544 };
1545 WriteReal(CMtoPDF(fXsize*xlow));
1546 WriteReal(CMtoPDF(fYsize*ylow));
1547 WriteReal(CMtoPDF(width));
1548 WriteReal(CMtoPDF(height));
1549 PrintStr("]");
1550 PrintStr("@");
1551
1552 Double_t xmargin = CMtoPDF(0.7);
1553 Double_t ymargin = 0;
1554 if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
1555 if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
1556
1557 PrintStr("/CropBox [");
1558 if (fPageOrientation == 1) {
1559 WriteReal(xmargin);
1560 WriteReal(ymargin);
1561 WriteReal(xmargin+CMtoPDF(fXsize*xup));
1562 WriteReal(ymargin+CMtoPDF(fYsize*yup));
1563 }
1564 if (fPageOrientation == 2) {
1565 WriteReal(xmargin);
1566 WriteReal(CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin);
1567 WriteReal(xmargin+CMtoPDF(fYsize*yup));
1568 WriteReal(CMtoPDF(height)-xmargin);
1569 }
1570 PrintStr("]");
1571 PrintStr("@");
1572
1573 if (fPageOrientation == 1) PrintStr("/Rotate 0@");
1574 if (fPageOrientation == 2) PrintStr("/Rotate 90@");
1575
1576 PrintStr("/Resources");
1578 PrintStr(" 0 R");
1579 PrintStr("@");
1580
1581 PrintStr("/Contents");
1583 PrintStr(" 0 R@");
1584
1585 PrintStr("/Annots");
1587 PrintStr(" 0 R");
1588 PrintStr("@");
1589
1590 PrintStr(">>@");
1591 EndObject();
1592
1594 PrintStr("<<@");
1595 PrintStr("/Length");
1597 PrintStr(" 0 R@");
1598 PrintStr("/Filter [/FlateDecode]@");
1599 PrintStr(">>@");
1600 PrintStr("stream@");
1602 fCompress = kTRUE;
1603
1604 // Force the line width definition next time TPDF::SetLineWidth will be called.
1605 fLineWidth = -1;
1606
1607 // Force the color definition next time TPDF::SetColor will be called.
1608 fRed = -1;
1609 fGreen = -1;
1610 fBlue = -1;
1611 fAlpha = -1.;
1612
1613 if (fPageOrientation == 2) {
1614 ymargin = CMtoPDF(height)-CMtoPDF(fXsize*xup)-xmargin;
1615 xmargin = xmargin+CMtoPDF(fYsize*yup);
1616 }
1617
1618 WriteCM(1, 0, 0, 1, xmargin, ymargin);
1619 if (fPageOrientation == 2)
1620 WriteCM(0, 1, -1, 0, 0, 0);
1621 if (fgLineJoin) {
1623 PrintFast(2," j");
1624 }
1625 if (fgLineCap) {
1627 PrintFast(2," J");
1628 }
1629}
1630
1631////////////////////////////////////////////////////////////////////////////////
1632/// Deactivate an already open PDF file
1633
1635{
1636 gVirtualPS = nullptr;
1637}
1638
1639////////////////////////////////////////////////////////////////////////////////
1640/// Activate an already open PDF file
1641
1643{
1644 // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
1645 // has no "workstation type".
1646
1647 if (!fType) {
1648 Error("On", "no PDF file open");
1649 Off();
1650 return;
1651 }
1652 gVirtualPS = this;
1653}
1654
1655////////////////////////////////////////////////////////////////////////////////
1656/// Open a PDF file
1657
1658void TPDF::Open(const char *fname, Int_t wtype)
1659{
1660 if (fStream) {
1661 Warning("Open", "PDF file already open");
1662 return;
1663 }
1664
1665 fLenBuffer = 0;
1666 fRed = -1;
1667 fGreen = -1;
1668 fBlue = -1;
1669 fAlpha = -1.;
1670 fType = abs(wtype);
1671 SetLineJoin(gStyle->GetJoinLinePS());
1672 SetLineCap(gStyle->GetCapLinePS());
1673 SetLineScale(gStyle->GetLineScalePS()/4.);
1674 gStyle->GetPaperSize(fXsize, fYsize);
1675 Float_t xrange, yrange;
1676 if (gPad) {
1677 Double_t ww = gPad->GetWw();
1678 Double_t wh = gPad->GetWh();
1679 if (fType == 113) {
1680 ww *= gPad->GetWNDC();
1681 wh *= gPad->GetHNDC();
1682 }
1683 Double_t ratio = wh/ww;
1684 xrange = fXsize;
1685 yrange = fXsize*ratio;
1686 if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
1687 fXsize = xrange; fYsize = yrange;
1688 }
1689
1690 // Open OS file
1691 if (!OpenStream(fname, kTRUE)) {
1692 Error("Open", "Cannot open file: %s", fname);
1693 return;
1694 }
1695
1696 gVirtualPS = this;
1697
1698 ClearBuffer();
1699
1700 // The page orientation is last digit of PDF workstation type
1701 // orientation = 1 for portrait
1702 // orientation = 2 for landscape
1705 Error("Open", "Invalid page orientation %d", fPageOrientation);
1706 return;
1707 }
1708
1709 // format = 0-99 is the European page format (A4,A3 ...)
1710 // format = 100 is the US format 8.5x11.0 inch
1711 // format = 200 is the US format 8.5x14.0 inch
1712 // format = 300 is the US format 11.0x17.0 inch
1713 fPageFormat = fType/1000;
1714 if (fPageFormat == 0) fPageFormat = 4;
1715 if (fPageFormat == 99) fPageFormat = 0;
1716
1717 fRange = kFALSE;
1718
1719 // Set a default range
1721
1722 fObjPos.clear();
1723 fNbPage = 0;
1724 fUrl = kFALSE;
1725
1726 PrintStr("%PDF-1.4@");
1727 PrintStr("%\342\343\317\323");
1728 PrintStr("@");
1729
1731 PrintStr("<<@");
1732 PrintStr("/Type /Catalog@");
1733 PrintStr("/Pages");
1735 PrintStr(" 0 R@");
1736 PrintStr("/Outlines");
1738 PrintStr(" 0 R@");
1739 PrintStr("/PageMode /UseOutlines@");
1740 PrintStr(">>@");
1741 EndObject();
1742
1744 PrintStr("<<@");
1745 PrintStr("/Creator (ROOT Version ");
1746 PrintStr(gROOT->GetVersion());
1747 PrintStr(")");
1748 PrintStr("@");
1749 PrintStr("/CreationDate (");
1750 TDatime t;
1751 Int_t toff = t.Convert(kFALSE) - t.Convert(kTRUE); // time zone and dst offset
1752 toff = toff/60;
1753 char str[24];
1754 snprintf(str,24,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%c%2.2d'%2.2d'",
1755 t.GetYear() , t.GetMonth(),
1756 t.GetDay() , t.GetHour(),
1757 t.GetMinute(), t.GetSecond(),
1758 toff < 0 ? '-' : '+',
1759 // TMath::Abs(toff/60), TMath::Abs(toff%60)); // format-truncation warning
1760 TMath::Abs(toff/60) & 0x3F, TMath::Abs(toff%60) & 0x3F); // now 2 digits
1761 PrintStr(str);
1762 PrintStr(")");
1763 PrintStr("@");
1764 PrintStr("/ModDate (");
1765 PrintStr(str);
1766 PrintStr(")");
1767 PrintStr("@");
1768 PrintStr("/Title (");
1769 if (strlen(GetName())<=80) PrintStr(GetName());
1770 PrintStr(")");
1771 PrintStr("@");
1772 PrintStr("/Keywords (ROOT)@");
1773 PrintStr(">>@");
1774 EndObject();
1775
1777 PrintStr("<<@");
1778 PrintStr("/ProcSet [/PDF /Text]@");
1779
1780 PrintStr("/Font@");
1781 PrintStr("<<@");
1782 for (Int_t i=0; i<kNumberOfFonts; i++) {
1783 PrintStr(" /F");
1784 WriteInteger(i+1,false);
1786 PrintStr(" 0 R");
1787 }
1788 PrintStr("@");
1789 PrintStr(">>@");
1790
1791 PrintStr("/ExtGState");
1793 PrintStr(" 0 R @");
1794 if (!fAlphas.empty()) fAlphas.clear();
1795
1796 PrintStr("/ColorSpace << /Cs8");
1798 PrintStr(" 0 R >>");
1799 PrintStr("@");
1800 PrintStr("/Pattern");
1802 PrintStr(" 0 R");
1803 PrintStr("@");
1804 PrintStr(">>@");
1805 EndObject();
1806
1807 FontEncode();
1808 PatternEncode();
1809
1810 NewPage();
1812}
1813
1814
1815////////////////////////////////////////////////////////////////////////////////
1816/// Ensure that required space in the buffer is available
1817
1819{
1820 if (required_size >= fSizBuffer) {
1821 // increase buffer size by integer factor, normally 2
1822 Int_t mult = (required_size + 1) / fSizBuffer + 1;
1824 fSizBuffer = mult*fSizBuffer;
1825 }
1826}
1827
1828////////////////////////////////////////////////////////////////////////////////
1829/// Output the string str in the output buffer
1830
1831void TPDF::PrintStr(const char *str)
1832{
1833 Int_t len = strlen(str);
1834 if (len == 0) return;
1836
1837 if (fCompress) {
1839 strcpy(fBuffer + fLenBuffer, str);
1840 fLenBuffer += len;
1841 } else {
1843 }
1844}
1845
1846////////////////////////////////////////////////////////////////////////////////
1847/// Fast version of Print
1848
1849void TPDF::PrintFast(Int_t len, const char *str)
1850{
1852 if (fCompress) {
1854 strcpy(fBuffer + fLenBuffer, str);
1855 fLenBuffer += len;
1856 } else {
1857 TVirtualPS::PrintFast(len, str);
1858 }
1859}
1860
1861////////////////////////////////////////////////////////////////////////////////
1862/// Set the range for the paper in centimetres
1863
1864void TPDF::Range(Float_t xsize, Float_t ysize)
1865{
1866 fXsize = xsize;
1867 fYsize = ysize;
1868 fRange = kTRUE;
1869}
1870
1871////////////////////////////////////////////////////////////////////////////////
1872/// Set the alpha channel value.
1873
1875{
1876 if (a == fAlpha) return;
1877 fAlpha = a;
1878 if (fAlpha <= 0.000001) fAlpha = 0;
1879
1880 Bool_t known = kFALSE;
1881 for (int i=0; i<(int)fAlphas.size(); i++) {
1882 if (fAlpha == fAlphas[i]) {
1883 known = kTRUE;
1884 break;
1885 }
1886 }
1887 if (!known) fAlphas.push_back(fAlpha);
1888 PrintStr(TString::Format(" /ca%3.2f gs /CA%3.2f gs",fAlpha,fAlpha));
1889}
1890
1891////////////////////////////////////////////////////////////////////////////////
1892/// Set color with its color index.
1893
1895{
1896 if (color < 0) color = 0;
1897 TColor *col = gROOT->GetColor(color);
1898
1899 if (col) {
1900 SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1901 SetAlpha(col->GetAlpha());
1902 } else {
1903 SetColor(1., 1., 1.);
1904 SetAlpha(1.);
1905 }
1906}
1907
1908////////////////////////////////////////////////////////////////////////////////
1909/// Set color with its R G B components:
1910///
1911/// - r: % of red in [0,1]
1912/// - g: % of green in [0,1]
1913/// - b: % of blue in [0,1]
1914
1916{
1917 if (r == fRed && g == fGreen && b == fBlue) return;
1918
1919 fRed = r;
1920 fGreen = g;
1921 fBlue = b;
1922 if (fRed <= 0.000001) fRed = 0;
1923 if (fGreen <= 0.000001) fGreen = 0;
1924 if (fBlue <= 0.000001) fBlue = 0;
1925
1926 if (gStyle->GetColorModelPS()) {
1927 Double_t colCyan, colMagenta, colYellow;
1928 Double_t colBlack = TMath::Min(TMath::Min(1-fRed,1-fGreen),1-fBlue);
1929 if (colBlack==1) {
1930 colCyan = 0;
1931 colMagenta = 0;
1932 colYellow = 0;
1933 } else {
1934 colCyan = (1-fRed-colBlack)/(1-colBlack);
1935 colMagenta = (1-fGreen-colBlack)/(1-colBlack);
1936 colYellow = (1-fBlue-colBlack)/(1-colBlack);
1937 }
1938 if (colCyan <= 0.000001) colCyan = 0;
1939 if (colMagenta <= 0.000001) colMagenta = 0;
1940 if (colYellow <= 0.000001) colYellow = 0;
1941 if (colBlack <= 0.000001) colBlack = 0;
1942 WriteReal(colCyan);
1943 WriteReal(colMagenta);
1944 WriteReal(colYellow);
1945 WriteReal(colBlack);
1946 PrintFast(2," K");
1947 WriteReal(colCyan);
1948 WriteReal(colMagenta);
1949 WriteReal(colYellow);
1950 WriteReal(colBlack);
1951 PrintFast(2," k");
1952 } else {
1953 WriteReal(fRed);
1956 PrintFast(3," RG");
1957 WriteReal(fRed);
1960 PrintFast(3," rg");
1961 }
1962}
1963
1964////////////////////////////////////////////////////////////////////////////////
1965/// Set color index for fill areas
1966
1968{
1969 fFillColor = cindex;
1970}
1971
1972////////////////////////////////////////////////////////////////////////////////
1973/// Set the fill patterns (1 to 25) for fill areas
1974
1976{
1977 char cpat[10];
1978 TColor *col = gROOT->GetColor(color);
1979 if (!col) return;
1980 PrintStr(" /Cs8 cs");
1981 Double_t colRed = col->GetRed();
1982 Double_t colGreen = col->GetGreen();
1983 Double_t colBlue = col->GetBlue();
1984 if (gStyle->GetColorModelPS()) {
1985 Double_t colBlack = TMath::Min(TMath::Min(1-colRed,1-colGreen),1-colBlue);
1986 if (colBlack==1) {
1987 WriteReal(0);
1988 WriteReal(0);
1989 WriteReal(0);
1990 WriteReal(colBlack);
1991 } else {
1992 Double_t colCyan = (1-colRed-colBlack)/(1-colBlack);
1993 Double_t colMagenta = (1-colGreen-colBlack)/(1-colBlack);
1994 Double_t colYellow = (1-colBlue-colBlack)/(1-colBlack);
1995 WriteReal(colCyan);
1996 WriteReal(colMagenta);
1997 WriteReal(colYellow);
1998 WriteReal(colBlack);
1999 }
2000 } else {
2001 WriteReal(colRed);
2002 WriteReal(colGreen);
2003 WriteReal(colBlue);
2004 }
2005
2006 if (fPageOrientation == 2) {
2007 switch (ipat) {
2008 case 4: ipat = 5; break;
2009 case 5: ipat = 4; break;
2010 case 6: ipat = 7; break;
2011 case 7: ipat = 6; break;
2012 case 17: ipat = 18; break;
2013 case 18: ipat = 17; break;
2014 case 20: ipat = 16; break;
2015 case 16: ipat = 20; break;
2016 case 21: ipat = 22; break;
2017 case 22: ipat = 21; break;
2018 }
2019 }
2020 snprintf(cpat,10," /P%2.2d scn", ipat);
2021 PrintStr(cpat);
2022}
2023
2024////////////////////////////////////////////////////////////////////////////////
2025/// Set color index for lines
2026
2028{
2029 fLineColor = cindex;
2030}
2031
2032////////////////////////////////////////////////////////////////////////////////
2033/// Set the value of the global parameter TPDF::fgLineJoin.
2034/// This parameter determines the appearance of joining lines in a PDF
2035/// output.
2036/// It takes one argument which may be:
2037/// - 0 (miter join)
2038/// - 1 (round join)
2039/// - 2 (bevel join)
2040/// The default value is 0 (miter join).
2041///
2042/// \image html postscript_1.png
2043///
2044/// To change the line join behaviour just do:
2045/// ~~~ {.cpp}
2046/// gStyle->SetJoinLinePS(2); // Set the PDF line join to bevel.
2047/// ~~~
2048
2049void TPDF::SetLineJoin( Int_t linejoin )
2050{
2051 fgLineJoin = linejoin;
2052 if (fgLineJoin<0) fgLineJoin=0;
2053 if (fgLineJoin>2) fgLineJoin=2;
2054}
2055
2056////////////////////////////////////////////////////////////////////////////////
2057/// Set the value of the global parameter TPDF::fgLineCap.
2058/// This parameter determines the appearance of line caps in a PDF
2059/// output.
2060/// It takes one argument which may be:
2061/// - 0 (butt caps)
2062/// - 1 (round caps)
2063/// - 2 (projecting caps)
2064/// The default value is 0 (butt caps).
2065///
2066/// \image html postscript_2.png
2067///
2068/// To change the line cap behaviour just do:
2069/// ~~~ {.cpp}
2070/// gStyle->SetCapLinePS(2); // Set the PDF line cap to projecting.
2071/// ~~~
2072
2074{
2075 fgLineCap = linecap;
2076 if (fgLineCap<0) fgLineCap=0;
2077 if (fgLineCap>2) fgLineCap=2;
2078}
2079
2080////////////////////////////////////////////////////////////////////////////////
2081/// Change the line style
2082///
2083/// - linestyle = 2 dashed
2084/// - linestyle = 3 dotted
2085/// - linestyle = 4 dash-dotted
2086/// - linestyle = else solid (1 in is used most of the time)
2087
2089{
2090 if ( linestyle == fLineStyle) return;
2091 fLineStyle = linestyle;
2092 TString st = (TString)gStyle->GetLineStyleString(linestyle);
2093 PrintFast(2," [");
2094 TObjArray *tokens = st.Tokenize(" ");
2095 for (Int_t j = 0; j<tokens->GetEntries(); j++) {
2096 Int_t it;
2097 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2098 WriteInteger((Int_t)(it/4));
2099 }
2100 delete tokens;
2101 PrintFast(5,"] 0 d");
2102}
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// Change the line width
2106
2108{
2109 if (linewidth == fLineWidth) return;
2110 fLineWidth = linewidth;
2111 if (fLineWidth!=0) {
2113 PrintFast(2," w");
2114 }
2115}
2116
2117////////////////////////////////////////////////////////////////////////////////
2118/// Set color index for markers.
2119
2121{
2122 fMarkerColor = cindex;
2123}
2124
2125////////////////////////////////////////////////////////////////////////////////
2126/// Set color index for text
2127
2129{
2130 fTextColor = cindex;
2131}
2132
2133////////////////////////////////////////////////////////////////////////////////
2134/// Draw text
2135///
2136/// - xx: x position of the text
2137/// - yy: y position of the text
2138/// - chars: text to be drawn
2139
2140void TPDF::Text(Double_t xx, Double_t yy, const char *chars)
2141{
2142 if (fTextSize <= 0) return;
2143
2144 const Double_t kDEGRAD = TMath::Pi()/180.;
2145 char str[8];
2146 Double_t x = xx;
2147 Double_t y = yy;
2148
2149 // Font and text size
2150 Int_t font = abs(fTextFont)/10;
2151 if (font > kNumberOfFonts || font < 1) font = 1;
2152
2153 Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2154 Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2155 Float_t tsize, ftsize;
2156 if (wh < hh) {
2157 tsize = fTextSize*wh;
2158 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2159 ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2160 } else {
2161 tsize = fTextSize*hh;
2162 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2163 ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2164 }
2165 Double_t fontsize = 72*(ftsize)/2.54;
2166 if (fontsize <= 0) return;
2167
2168 // Text color
2170
2171 // Clipping
2172 PrintStr(" q");
2173 Double_t x1 = XtoPDF(gPad->GetX1());
2174 Double_t x2 = XtoPDF(gPad->GetX2());
2175 Double_t y1 = YtoPDF(gPad->GetY1());
2176 Double_t y2 = YtoPDF(gPad->GetY2());
2177 WriteReal(x1);
2178 WriteReal(y1);
2179 WriteReal(x2 - x1);
2180 WriteReal(y2 - y1);
2181 PrintStr(" re W n");
2182
2183 // Start the text
2184 if (!fCompress) PrintStr("@");
2185
2186 // Text alignment
2187 Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2188 Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2189 Int_t txalh = fTextAlign/10;
2190 if (txalh < 1) txalh = 1; else if (txalh > 3) txalh = 3;
2191 Int_t txalv = fTextAlign%10;
2192 if (txalv < 1) txalv = 1; else if (txalv > 3) txalv = 3;
2193 if (txalv == 3) {
2194 y -= 0.8*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2195 x += 0.8*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2196 } else if (txalv == 2) {
2197 y -= 0.4*tsizey*TMath::Cos(kDEGRAD*fTextAngle);
2198 x += 0.4*tsizex*TMath::Sin(kDEGRAD*fTextAngle);
2199 }
2200
2201 if (txalh > 1) {
2202 TText t;
2203 UInt_t w=0, h;
2206 t.GetTextExtent(w, h, chars);
2207 Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2208 Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
2209 if (txalh == 2) {
2210 x = x-(twx/2)*TMath::Cos(kDEGRAD*fTextAngle);
2211 y = y-(twy/2)*TMath::Sin(kDEGRAD*fTextAngle);
2212 }
2213 if (txalh == 3) {
2214 x = x-twx*TMath::Cos(kDEGRAD*fTextAngle);
2215 y = y-twy*TMath::Sin(kDEGRAD*fTextAngle);
2216 }
2217 }
2218
2219 // Text angle
2220 Double_t a, b, c, d, e, f;
2221 if (fTextAngle == 0) {
2222 a = 1;
2223 b = 0;
2224 c = 0;
2225 d = 1;
2226 e = XtoPDF(x);
2227 f = YtoPDF(y);
2228 } else if (fTextAngle == 90) {
2229 a = 0;
2230 b = 1;
2231 c = -1;
2232 d = 0;
2233 e = XtoPDF(x);
2234 f = YtoPDF(y);
2235 } else if (fTextAngle == 270) {
2236 a = 0;
2237 b = -1;
2238 c = 1;
2239 d = 0;
2240 e = XtoPDF(x);
2241 f = YtoPDF(y);
2242 } else {
2243 a = TMath::Cos(kDEGRAD * fTextAngle);
2244 b = TMath::Sin(kDEGRAD * fTextAngle);
2245 c = -TMath::Sin(kDEGRAD * fTextAngle);
2246 d = TMath::Cos(kDEGRAD * fTextAngle);
2247 e = XtoPDF(x);
2248 f = YtoPDF(y);
2249 }
2250 WriteCM(a, b, c, d, e, f, kFALSE);
2251
2252 // Symbol Italic tan(15) = .26794
2253 if (font == 15)
2254 WriteCM(1, 0, 0.26794, 1, 0, 0, kFALSE);
2255
2256 if (fUrl)
2257 ComputeRect(chars, fontsize, a, b, c, d, e, f);
2258
2259 PrintStr(" BT");
2260
2261 snprintf(str,8," /F%d",font);
2262 PrintStr(str);
2263 WriteReal(fontsize);
2264 PrintStr(" Tf");
2265
2266 const Int_t len=strlen(chars);
2267
2268 // Calculate the individual character placements.
2269 // Otherwise, if a string is printed in one line the kerning is not
2270 // performed. In order to measure the precise character positions we need to
2271 // trick FreeType into rendering high-resolution characters otherwise it will
2272 // stick to the screen pixel grid which is far worse than we can achieve on
2273 // print.
2274 const Float_t scale = 16.0;
2275 // Save current text attributes.
2276 TText saveAttText;
2277 saveAttText.TAttText::operator=(*this);
2278 TText t;
2279 t.SetTextSize(fTextSize * scale);
2281 UInt_t wa1=0, wa0=0;
2282 t.GetTextAdvance(wa0, chars, kFALSE);
2283 t.GetTextAdvance(wa1, chars);
2284 t.TAttText::Modify();
2286 if (wa0-wa1 != 0) kerning = kTRUE;
2287 else kerning = kFALSE;
2288 Int_t *charDeltas = nullptr;
2289 if (kerning) {
2290 charDeltas = new Int_t[len];
2291 for (Int_t i = 0;i < len;i++) {
2292 UInt_t ww=0;
2293 t.GetTextAdvance(ww, chars + i);
2294 charDeltas[i] = wa1 - ww;
2295 }
2296 for (Int_t i = len - 1;i > 0;i--) {
2297 charDeltas[i] -= charDeltas[i-1];
2298 }
2299 char tmp[2];
2300 tmp[1] = 0;
2301 for (Int_t i = 1;i < len;i++) {
2302 tmp[0] = chars[i-1];
2303 UInt_t width=0;
2304 t.GetTextAdvance(width, &tmp[0], kFALSE);
2305 Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
2306 wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
2307 charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
2308 }
2309 }
2310 // Restore text attributes.
2311 saveAttText.TAttText::Modify();
2312
2313 // Output the text. Escape some characters if needed
2314 if (kerning) PrintStr(" [");
2315 else PrintStr(" (");
2316
2317 for (Int_t i=0; i<len;i++) {
2318 if (chars[i]!='\n') {
2319 if (kerning) PrintStr("(");
2320 if (chars[i]=='(' || chars[i]==')') {
2321 snprintf(str,8,"\\%c",chars[i]);
2322 } else {
2323 snprintf(str,8,"%c",chars[i]);
2324 }
2325 PrintStr(str);
2326 if (kerning) {
2327 PrintStr(") ");
2328 if (i < len-1) {
2329 WriteInteger(charDeltas[i+1]);
2330 }
2331 }
2332 }
2333 }
2334
2335 if (kerning) PrintStr("] TJ ET Q");
2336 else PrintStr(") Tj ET Q");
2337 if (!fCompress) PrintStr("@");
2338 if (kerning) delete [] charDeltas;
2339}
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// Write a string of characters
2343///
2344/// This method writes the string chars into a PDF file
2345/// at position xx,yy in world coordinates.
2346
2347void TPDF::Text(Double_t, Double_t, const wchar_t *)
2348{
2349}
2350
2351////////////////////////////////////////////////////////////////////////////////
2352/// Draw text with URL. Same as Text.
2353///
2354
2355void TPDF::TextUrl(Double_t x, Double_t y, const char *chars, const char *url)
2356{
2357 fUrl = kTRUE;
2358 Text(x, y, chars);
2359 fNbUrl++;
2360 fUrls.push_back(url);
2361 fUrl = kFALSE;
2362}
2363
2364////////////////////////////////////////////////////////////////////////////////
2365/// Write a string of characters in NDC
2366
2367void TPDF::TextNDC(Double_t u, Double_t v, const char *chars)
2368{
2369 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2370 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2371 Text(x, y, chars);
2372}
2373
2374////////////////////////////////////////////////////////////////////////////////
2375/// Write a string of characters in NDC
2376
2377void TPDF::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2378{
2379 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2380 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2381 Text(x, y, chars);
2382}
2383
2384////////////////////////////////////////////////////////////////////////////////
2385/// Convert U from NDC coordinate to PDF
2386
2388{
2389 Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2390 return 72*cm/2.54;
2391}
2392
2393////////////////////////////////////////////////////////////////////////////////
2394/// Convert V from NDC coordinate to PDF
2395
2397{
2398 Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2399 return 72*cm/2.54;
2400}
2401
2402////////////////////////////////////////////////////////////////////////////////
2403/// Convert X from world coordinate to PDF
2404
2406{
2407 Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2408 return UtoPDF(u);
2409}
2410
2411////////////////////////////////////////////////////////////////////////////////
2412/// Convert Y from world coordinate to PDF
2413
2415{
2416 Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2417 return VtoPDF(v);
2418}
2419
2420////////////////////////////////////////////////////////////////////////////////
2421/// Write the buffer in a compressed way
2422
2424{
2425 z_stream stream;
2426 int err;
2427 char *out = new char[2*fLenBuffer];
2428
2429 stream.next_in = (Bytef*)fBuffer;
2430 stream.avail_in = (uInt)fLenBuffer;
2431 stream.next_out = (Bytef*)out;
2432 stream.avail_out = (uInt)2*fLenBuffer;
2433 stream.zalloc = (alloc_func)nullptr;
2434 stream.zfree = (free_func)nullptr;
2435 stream.opaque = (voidpf)nullptr;
2436
2437 err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2438 if (err != Z_OK) {
2439 Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
2440 delete [] out;
2441 return;
2442 }
2443
2444 err = deflate(&stream, Z_FINISH);
2445 if (err != Z_STREAM_END) {
2446 deflateEnd(&stream);
2447 Error("WriteCompressedBuffer", "error in deflate (zlib)");
2448 delete [] out;
2449 return;
2450 }
2451
2452 err = deflateEnd(&stream);
2453 if (err != Z_OK) {
2454 Error("WriteCompressedBuffer", "error in deflateEnd (zlib)");
2455 }
2456
2457 fStream->write(out, stream.total_out);
2458
2459 fNByte += stream.total_out;
2460 fStream->write("\n",1); fNByte++;
2461 fLenBuffer = 0;
2462 delete [] out;
2463 fCompress = kFALSE;
2464}
2465
2466////////////////////////////////////////////////////////////////////////////////
2467/// Write a Real number to the file.
2468/// This method overwrites TVirtualPS::WriteReal. Some PDF reader like
2469/// Acrobat do not work when a PDF file contains reals with exponent. This
2470/// method writes the real number "z" using the format "%f" instead of the
2471/// format "%g" when writing it with "%g" generates a number with exponent.
2472
2474{
2475 char str[15];
2476 if (space) {
2477 snprintf(str,15," %g", z);
2478 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
2479 } else {
2480 snprintf(str,15,"%g", z);
2481 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15,"%10.8f", z);
2482 }
2483 PrintStr(str);
2484}
2485
2486////////////////////////////////////////////////////////////////////////////////
2487/// Patterns encoding
2488
2490{
2491 Int_t patternNb = kObjPattern;
2492
2494 if (gStyle->GetColorModelPS()) {
2495 PrintStr("[/Pattern /DeviceCMYK]@");
2496 } else {
2497 PrintStr("[/Pattern /DeviceRGB]@");
2498 }
2499 EndObject();
2501 PrintStr("<</ProcSet[/PDF]>>@");
2502 EndObject();
2503
2505 PrintStr("<<@");
2506 PrintStr(" /P01");
2507 WriteInteger(patternNb++);
2508 PrintStr(" 0 R");
2509 PrintStr(" /P02");
2510 WriteInteger(patternNb++);
2511 PrintStr(" 0 R");
2512 PrintStr(" /P03");
2513 WriteInteger(patternNb++);
2514 PrintStr(" 0 R");
2515 PrintStr(" /P04");
2516 WriteInteger(patternNb++);
2517 PrintStr(" 0 R");
2518 PrintStr(" /P05");
2519 WriteInteger(patternNb++);
2520 PrintStr(" 0 R");
2521 PrintStr(" /P06");
2522 WriteInteger(patternNb++);
2523 PrintStr(" 0 R");
2524 PrintStr(" /P07");
2525 WriteInteger(patternNb++);
2526 PrintStr(" 0 R");
2527 PrintStr(" /P08");
2528 WriteInteger(patternNb++);
2529 PrintStr(" 0 R");
2530 PrintStr(" /P09");
2531 WriteInteger(patternNb++);
2532 PrintStr(" 0 R");
2533 PrintStr(" /P10");
2534 WriteInteger(patternNb++);
2535 PrintStr(" 0 R");
2536 PrintStr(" /P11");
2537 WriteInteger(patternNb++);
2538 PrintStr(" 0 R");
2539 PrintStr(" /P12");
2540 WriteInteger(patternNb++);
2541 PrintStr(" 0 R");
2542 PrintStr(" /P13");
2543 WriteInteger(patternNb++);
2544 PrintStr(" 0 R");
2545 PrintStr(" /P14");
2546 WriteInteger(patternNb++);
2547 PrintStr(" 0 R");
2548 PrintStr(" /P15");
2549 WriteInteger(patternNb++);
2550 PrintStr(" 0 R");
2551 PrintStr(" /P16");
2552 WriteInteger(patternNb++);
2553 PrintStr(" 0 R");
2554 PrintStr(" /P17");
2555 WriteInteger(patternNb++);
2556 PrintStr(" 0 R");
2557 PrintStr(" /P18");
2558 WriteInteger(patternNb++);
2559 PrintStr(" 0 R");
2560 PrintStr(" /P19");
2561 WriteInteger(patternNb++);
2562 PrintStr(" 0 R");
2563 PrintStr(" /P20");
2564 WriteInteger(patternNb++);
2565 PrintStr(" 0 R");
2566 PrintStr(" /P21");
2567 WriteInteger(patternNb++);
2568 PrintStr(" 0 R");
2569 PrintStr(" /P22");
2570 WriteInteger(patternNb++);
2571 PrintStr(" 0 R");
2572 PrintStr(" /P23");
2573 WriteInteger(patternNb++);
2574 PrintStr(" 0 R");
2575 PrintStr(" /P24");
2576 WriteInteger(patternNb++);
2577 PrintStr(" 0 R");
2578 PrintStr(" /P25");
2579 WriteInteger(patternNb++);
2580 PrintStr(" 0 R@");
2581 PrintStr(">>@");
2582 EndObject();
2583
2584 patternNb = kObjPattern;
2585
2586 // P01
2587 NewObject(patternNb++);
2588 PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
2590 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 98 4]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
2591 PrintStr("@");
2592 fStream->write("stream",6); fNByte += 6;
2593 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301P\241\034(\254\340\253\020m\250\020k\240\220\302e\244`\242\220\313ei\t\244r\200\272\215A\034\v \225\003\2241\202\310\030\201e\f!2\206@N0W \027@\200\001\0|c\024\357\n", 93);
2594 fNByte += 93;
2595 PrintStr("endstream@");
2596 EndObject();
2597
2598 // P02
2599 NewObject(patternNb++);
2600 PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
2602 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 4]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
2603 PrintStr("@");
2604 fStream->write("stream",6); fNByte += 6;
2605 fStream->write("\r\nH\211$\2121\n\2000\024C\367\234\"G\370\277\025\321+\b\016\342\340P\334tP\252\240\213\3277\332!\204\274\227\v\316\2150\032\335J\356\025\023O\241Np\247\363\021f\317\344\214\234\215\v\002+\036h\033U\326/~\243Ve\231PL\370\215\027\343\032#\006\274\002\f\0\242`\025:\n", 94);
2606 fNByte += 94;
2607 PrintStr("endstream@");
2608 EndObject();
2609
2610 // P03
2611 NewObject(patternNb++);
2612 PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
2614 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 16]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
2615 PrintStr("@");
2616 fStream->write("stream",6); fNByte += 6;
2617 fStream->write("\r\nH\211$\2121\n\2000\024C\367\234\"G\370\261(\366\n\202\20388\210\233\016J\025t\361\372\376\332!\204\274\227\033\342N\030\215\262\222g\303\304\313Q\347\360\240\370:f\317Y\f\\\214+**\360Dls'\177\306\274\032\257\344\256.\252\376\215\212\221\217\021\003>\001\006\0\317\243\025\254\n", 95);
2618 fNByte += 95;
2619 PrintStr("endstream@");
2620 EndObject();
2621
2622 // P04
2623 NewObject(patternNb++);
2624 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2626 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 63/Filter/FlateDecode>>");
2627 PrintStr("@");
2628 fStream->write("stream",6); fNByte += 6;
2629 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002V\231\313\005S\233\303\025\314\025\310\005\020`\0\344\270\r\274\n", 65);
2630 fNByte += 65;
2631 PrintStr("endstream@");
2632 EndObject();
2633
2634 // P05
2635 NewObject(patternNb++);
2636 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2638 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2639 PrintStr("@");
2640 fStream->write("stream",6); fNByte += 6;
2641 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302\005Q\223\313\005\"\r\024r\270\202\271\002\271\0\002\f\0\344\320\r\274\n", 68);
2642 fNByte += 68;
2643 PrintStr("endstream@");
2644 EndObject();
2645
2646 // P06
2647 NewObject(patternNb++);
2648 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2650 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2651 PrintStr("@");
2652 fStream->write("stream",6); fNByte += 6;
2653 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302e\nR\232\v\242@js\270\202\271\002\271\0\002\f\0\345X\r\305\n", 68);
2654 fNByte += 68;
2655 PrintStr("endstream@");
2656 EndObject();
2657
2658 // P07
2659 NewObject(patternNb++);
2660 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2662 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
2663 PrintStr("@");
2664 fStream->write("stream",6); fNByte += 6;
2665 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\345\002)\0042r\270\202\271\002\271\0\002\f\0\345=\r\305\n", 70);
2666 fNByte += 70;
2667 PrintStr("endstream@");
2668 EndObject();
2669
2670 // P08
2671 NewObject(patternNb++);
2672 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2674 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
2675 PrintStr("@");
2676 fStream->write("stream",6); fNByte += 6;
2677 fStream->write("\r\nH\211D\217\261\016\3020\fDw\177\305\315L6Q\225|\003\022C\305\300Puk+\201\032$\272\360\373\330\265\323\016\271\330\367\234\344\"x\201\030\214\252\232\030+%\353VZ.jd\367\205\003x\241({]\311\324]\323|\342\006\033J\201:\306\325\230Jg\226J\261\275D\257#\337=\220\260\354k\233\351\211\217Z75\337\020\374\324\306\035\303\310\230\342x=\303\371\275\307o\332s\331\223\224\240G\330\a\365\364\027`\0\nX1}\n",141);
2678 fNByte += 141;
2679 PrintStr("endstream@");
2680 EndObject();
2681
2682 // P09
2683 NewObject(patternNb++);
2684 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2686 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
2687 PrintStr("@");
2688 fStream->write("stream",6); fNByte += 6;
2689 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\005RFFz&\020\002,d\240\220\314en\256g\0065\b,\001b\230\202$\240\232\214@\362\246`\2169H\336\024\2426\231\v&\200,\n\326\030\314\025\310\005\020`\0\f@\036\227\n", 110);
2690 fNByte += 110;
2691 PrintStr("endstream@");
2692 EndObject();
2693
2694 // P10
2695 NewObject(patternNb++);
2696 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2698 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 93/Filter/FlateDecode>>");
2699 PrintStr("@");
2700 fStream->write("stream",6); fNByte += 6;
2701 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002\02465P\310\345\002)\0042r\200\332\r\241\\C \017dN.\027L\312\0\302\205\2535\205j6\205X\224\303\025\314\025\310\005\020`\0\2127\031\t\n", 95);
2702 fNByte += 95;
2703 PrintStr("endstream@");
2704 EndObject();
2705
2706 // P11
2707 NewObject(patternNb++);
2708 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2710 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 164/Filter/FlateDecode>>");
2711 PrintStr("@");
2712 fStream->write("stream",6); fNByte += 6;
2713 fStream->write("\r\nH\211\\\2171\016\3020\fEw\237\342\037\301ip\223^\001\211\001u`@l0\200(\022,\\\037;v\204\332\241\211\336\373\337V\363\246\204;\210\301H\354\337\347F'\274T\355U>\220\360U\215\003\316\027\306\2655\027=\a\306\223\304I\002m\332\330\356&\030\325\333fZ\275F\337\205\235\265O\270\032\004\331\214\336\305\270\004\227`\357i\256\223\342;]\344\255(!\372\356\205j\030\377K\335\220\344\377\210\274\306\022\330\337T{\214,\212;\301\3508\006\346\206\021O=\216|\212|\246#\375\004\030\0\216FF\207\n", 166);
2714 fNByte += 166;
2715 PrintStr("endstream@");
2716 EndObject();
2717
2718 // P12
2719 NewObject(patternNb++);
2720 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2722 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
2723 PrintStr("@");
2724 fStream->write("stream",6); fNByte += 6;
2725 fStream->write("\r\nH\211<P;n\3030\f\335y\n\236 \220DK\242\256P\240C\321\241C\221\311\311\220\242\016\220.\275~D\221/\203I\342}\370(?(\363\215)q\342\234\374\373\273\322\027\337'\3646\301\037\316\374?a~\347\357s\342\313\2045\361A9\237\322fc\231\200\236F\263\301\334;\211\017\207\rN\311\252S\\\227{\247\006w\207\244\303\255p+(\205\333\360e/v\356a\315\317\360\272\320b|w\276\203o\340k\b\004\027\v$b\226\235,\242\254t(\024\nu\305Vm\313\021\375\327\272\257\227fuf\226ju\356\222x\030\024\313\261S\215\377\341\274,\203\254\253Z\\\262A\262\205eD\350\210\320\201\225\212\320\036\241\355\025\372JE,\2266\344\366\310U\344\016HFx>\351\203\236\002\f\0d}e\216\n", 228);
2726 fNByte += 228;
2727 PrintStr("endstream@");
2728 EndObject();
2729
2730 // P13
2731 NewObject(patternNb++);
2732 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2734 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2735 PrintStr("@");
2736 fStream->write("stream",6); fNByte += 6;
2737 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\002V\231\313\005S\233\303\005\241!\" ~0W \027@\200\001\0\331\227\020\253\n", 71);
2738 fNByte += 71;
2739 PrintStr("endstream@");
2740 EndObject();
2741
2742 // P14
2743 NewObject(patternNb++);
2744 PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
2746 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
2747 PrintStr("@");
2748 fStream->write("stream",6); fNByte += 6;
2749 fStream->write("\r\nH\2114\214=\n\2000\f\205\367\234\342\035!-\241\364\f\202\20388\210\233\016J+\350\342\365M\3723\224\327\367}I\036r8A\f\206\343\372\336\203\026\334\212\006\205\027\004\237b\214X7\306\256\33032\331\240~\022y[\315\026\206\222\372\330}\264\036\253\217\335\353\240\030\b%\223\245o=X\227\346\245\355K\341\345@\3613M\364\v0\0\207o\"\261\n", 116);
2750 fNByte += 116;
2751 PrintStr("endstream@");
2752 EndObject();
2753
2754 // P15
2755 NewObject(patternNb++);
2756 PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
2758 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
2759 PrintStr("@");
2760 fStream->write("stream",6); fNByte += 6;
2761 fStream->write("\r\nH\211<\2211\016\3020\fEw\237\302'@\211c\267w@b@\f\f\210\2510\200(\022,\\\037\347\307\256Z\325\221\375\337\377\225\363\241\312\017\246\302\205'\274\337;\235\371\355\215\275\267\236\\\371\307\265\360\201/\327\3027o\233\361J\262\233\247~\362g\336\211zur!A]{\035}\031S\343\006p\241\226dKI\v\326\202\265\3153\331)X)\335fE\205M\235\373\327\r*\374\026\252\022\216u\223\200\361I\211\177\031\022\001#``\342GI\211\004c\221gi\246\231\247\221\247\231\247\233$XM3\315<\215<\315<K\211e\036#\215a4\366\344\035lm\214Z\314b\211Xj\337K\\\201$\332\325\v\365\2659\204\362\242\274'\v\221\r\321\211\216\364\027`\0\212'_\215\n", 220);
2762 fNByte += 220;
2763 PrintStr("endstream@");
2764 EndObject();
2765
2766 // P16
2767 NewObject(patternNb++);
2768 PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
2770 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
2771 PrintStr("@");
2772 fStream->write("stream",6); fNByte += 6;
2773 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020\035k\240\220\302ej\240\0D\271 \332\314X\317B\301\330\002H\230\233*\030\231\202\310d.CC=#\020\v*\rV\235\214\254\v\210r@\264\261\031P\241\031H5D\253\021H\267\005\3104 \v\344\016\260\002\020\003lB0W \027@\200\001\0hU \305\n", 125);
2774 fNByte += 125;
2775 PrintStr("endstream@");
2776 EndObject();
2777
2778 // P17
2779 NewObject(patternNb++);
2780 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2782 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2783 PrintStr("@");
2784 fStream->write("stream",6); fNByte += 6;
2785 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020md\242\020k\240\220\002V\234\313\005S\236\303\025\314\025\310\005\020`\0\r\351\016B\n", 68);
2786 fNByte += 68;
2787 PrintStr("endstream@");
2788 EndObject();
2789
2790 // P18
2791 NewObject(patternNb++);
2792 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2794 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2795 PrintStr("@");
2796 fStream->write("stream",6); fNByte += 6;
2797 fStream->write("\r\nH\211*\3442T\310T\3402P0P04\200\340\242T\256p\205<\240\220\027P0K\301D\241\034(\254\340\253\020md\242\020k\240\220\302\005Q\226\313\005\"\r\024r\270\202\271\002\271\0\002\f\0\016\001\016B\n", 71);
2798 fNByte += 71;
2799 PrintStr("endstream@");
2800 EndObject();
2801
2802 // P19
2803 NewObject(patternNb++);
2804 PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
2806 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
2807 PrintStr("@");
2808 fStream->write("stream",6); fNByte += 6;
2809 fStream->write("\r\nH\211L\216;\016\302@\fD{\237bN\020\331+6a\257\200D\201((P\252@\001R\220\240\341\372\370\263\216(\326\266f\336\330\373&\301\003\304`\b\307\373\334\351\202\227J\a\025\237\020|U\306\021\327\231q\243\306\250\214\325\372T\006\336\367\032\262\326\205\3124\264b\243$\"n.\244=\314\250!\2139\033\327\022i=\323\317\2518\332T}\347.\202\346W\373\372j\315\221\344\266\213=\237\241\344\034\361\264!\236w\344\177\271o8\323\211~\002\f\0\366\3026\233\n", 151);
2810 fNByte += 151;
2811 PrintStr("endstream@");
2812 EndObject();
2813
2814 // P20
2815 NewObject(patternNb++);
2816 PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
2818 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
2819 PrintStr("@");
2820 fStream->write("stream",6); fNByte += 6;
2821 fStream->write("\r\nH\211<L;\016\2030\f\335}\212w\002\344$M\2323 1 \006\006\304\224vhU\220`\341\372<\aT\311\366\263\336o\023\207\017D\241pz\355\376\226\021+\251\226\344\027\017\034\244\321a\232\025/\211\n\316r\343ORh\262}\317\210\344\032o\310)\302\2233\245\252[m\274\332\313\277!$\332\371\371\210`N\242\267$\217\263\246\252W\257\245\006\351\345\024`\0o\347 \305\n", 124);
2822 fNByte += 124;
2823 PrintStr("endstream@");
2824 EndObject();
2825
2826 // P21
2827 NewObject(patternNb++);
2828 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2830 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
2831 PrintStr("@");
2832 fStream->write("stream",6); fNByte += 6;
2833 fStream->write("\r\nH\211D\2151\n\2000\fE\367\234\342\037!)\224\336Ap\020\a\aq\323A\251\202.^\337$-\025\022^\372\033^n\022\354 \006CX\274\237\215&\\\032u\032\036\020\274\032\243\307\2740V]\027\234\024\242\"\033\2642En\324\312\224bc\262\\\230\377\301\332WM\224\212(U\221\375\265\301\025\016?\350\317P\215\221\033\213o\244\201>\001\006\0\031I'f\n", 119);
2834 fNByte += 119;
2835 PrintStr("endstream@");
2836 EndObject();
2837
2838 // P22
2839 NewObject(patternNb++);
2840 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2842 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
2843 PrintStr("@");
2844 fStream->write("stream",6); fNByte += 6;
2845 fStream->write("\r\nH\211<\215=\n\204P\f\204\373\234b\216\220<\b\357\016\302\026ba!vZ(\273\v\332x}\223\274\237\"|\223a\230\271Hp\200\030\fa\211\273w\232\3617k0\363\204\3401\033\037,+c#\3170~\2244\304\327EV\243r\247\272oOcr\337\323]H\t\226\252\334\252r\255\362\257\213(\t\304\250\326\315T\267\032\275q\242\221^\001\006\0\272\367(&\n", 120);
2846 fNByte += 120;
2847 PrintStr("endstream@");
2848 EndObject();
2849
2850 // P23
2851 NewObject(patternNb++);
2852 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2854 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
2855 PrintStr("@");
2856 fStream->write("stream",6); fNByte += 6;
2857 fStream->write("\r\nH\211<\220\273\n\0021\020E\373\371\212[[M\326\331\354\344\027\004\v\261\260\020;\025\224D\320\306\337w\036\254p\363\230\223\341$\344M\005\017\020\203Q8\307\347F'\274\f\355\f>Q\3605\214=\316\005\v.\214kt\217\230;)\324\366\245Fa\213e\320v\212r\022X\006\211Fi\3242\250J\224\302\020\367h\212\254I\\\325R\225o\03143\346U\235@a\t[\202Za\tA\202E`\351~O\002\235`\351~S\202\306h.m\253\264)\232K\217t\310\017q\354\a\353\247\364\377C\356\033\372\t0\0\bm:\375\n", 171);
2858 fNByte += 171;
2859 PrintStr("endstream@");
2860 EndObject();
2861
2862 // P24
2863 NewObject(patternNb++);
2864 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2866 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
2867 PrintStr("@");
2868 fStream->write("stream",6); fNByte += 6;
2869 fStream->write("\r\nH\211DQ9N\004A\f\314\373\025\216\211\326\343v\037_@\"@\004\004\210\f\220@\003\022$|\177\335\345j\220v\345\251\303\343*\215\312\273\024\275\\d\375?\361dM\3162\306\337\214\337Y\336n\240m\217\036\301y\343\\<,i\250\0038F\035)\347l\322\026o\377\023\353|[\254\177\343\005;\315\317ky\224\257\240n\203\374\020\225\337\240\345N\236T\272<_\344\245\304^\3238\030\tc\236E\233xO\034\363\204>\251\317\324\233\023{\352\235\376\336S\357Fl\251\017\372\207\247>xoh&_\366Ud\331\253\314D\023\332\241\211\016\205\246\235\326\236*\275\307\204z8!s\031\335\306\\\306C\306\\\225\376\312\\\225\307\252\246\356\364\273Q\347\271:\371\341l\177\311e\210\3571\211\251#\374\302H\037:\342c\241\323\2617\320 \034\250\0\302\323a{\005%\302a\373(Zx\313\026\213@\215p\324}\026=\274e\217E8s\326}\026M\036\312}\271\n0\0\215\263\207\016\n", 282);
2870 fNByte += 282;
2871 PrintStr("endstream@");
2872 EndObject();
2873
2874 // P25
2875 NewObject(patternNb++);
2876 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2878 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
2879 PrintStr("@");
2880 fStream->write("stream",6); fNByte += 6;
2881 fStream->write("\r\nH\2112T\310T\3402P0P\310\34526P\0\242\034.s\004m\016\242\r\r\f\024@\030\302\002\321iZP\305`M\346\310\212\201R\0\001\006\0\206\322\017\200\n", 56);
2882 fNByte += 56;
2883 PrintStr("endstream@");
2884 EndObject();
2885}
2886
2887////////////////////////////////////////////////////////////////////////////////
2888/// Write and Accumulate (if `acc` is true) the Current Transformation Matrix (CTM)
2889///
2890/// The Current Transformation Matrix (CTM, not CMT) is defined by the six parameters
2891/// `a` `b` `c` `d` `e` `f` passed to the PDF `cm` operator (see the PDF Reference Guide
2892/// page 156 [1] for details).
2893///
2894/// To correctly define the \Rect fields of the Annots created for each #url, one must keep
2895/// track of the current CTM and apply it to the last transformation matrix used for the
2896/// text (for example rotations).
2897///
2898/// [1] https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf
2899
2901{
2902 WriteReal(a);
2903 WriteReal(b);
2904 WriteReal(c);
2905 WriteReal(d);
2906 WriteReal(e);
2907 WriteReal(f);
2908 PrintStr(" cm");
2909
2910 // accumulate in CTM ---
2911 if (acc) {
2912 Double_t na, nb, nc, nd, ne, nf;
2913 na = fA * a + fC * b;
2914 nb = fB * a + fD * b;
2915 nc = fA * c + fC * d;
2916 nd = fB * c + fD * d;
2917 ne = fA * e + fC * f + fE;
2918 nf = fB * e + fD * f + fF;
2919 fA = na;
2920 fB = nb;
2921 fC = nc;
2922 fD = nd;
2923 fE = ne;
2924 fF = nf;
2925 }
2926}
2927
2928////////////////////////////////////////////////////////////////////////////////
2929/// Write the annotation objects containing the URLs
2930
2932{
2933 int i;
2935 PrintStr("@");
2936 PrintStr("[");
2937 for (i = 0; i < fNbUrl - 1; i++) {
2938 WriteInteger(fCurrentPage + 5 + i);
2939 PrintStr(" 0 R");
2940 }
2941 PrintStr(" ]@");
2942 EndObject();
2943 for (i = 0; i < fNbUrl - 1; i++) {
2944 NewObject(fCurrentPage + 5 + i);
2945 PrintStr("<<@");
2946 PrintStr("/Type /Annot@");
2947 PrintStr("/Subtype /Link@");
2948 PrintStr("/Rect [");
2950 WriteReal(fRectY1[i]);
2951 WriteReal(fRectX2[i]);
2952 WriteReal(fRectY2[i]);
2953 PrintStr("]@");
2954 PrintStr("/Border [0 0 0]@");
2955 PrintStr("/A << /S /URI /URI (");
2956 PrintStr(fUrls[i].c_str());
2957 PrintStr(") >>@");
2958 PrintStr(">>@");
2959 EndObject();
2960 }
2961 if (!fUrls.empty())
2962 fUrls.clear();
2963 if (!fRectX1.empty())
2964 fRectX1.clear();
2965 if (!fRectY1.empty())
2966 fRectY1.clear();
2967 if (!fRectX2.empty())
2968 fRectX2.clear();
2969 if (!fRectY2.empty())
2970 fRectY2.clear();
2971}
2972
2973////////////////////////////////////////////////////////////////////////////////
2974/// Compute the Rect for url
2975
2976void TPDF::ComputeRect(const char* chars, Double_t fontsize,
2978{
2979 double W = 0.52 * fontsize * strlen(chars);
2980 double ascent = 0.72 * fontsize;
2981 double descent = 0.22 * fontsize;
2982
2983 int ax = fTextAlign / 10;
2984 int ay = fTextAlign % 10;
2985 double xShift = 0;
2986 double yShift = 0;
2987 if (ax == 2)
2988 xShift = -W / 2.0;
2989 if (ax == 3)
2990 xShift = -W;
2991 if (ay == 2)
2992 yShift = -(ascent - descent) / 2.0;
2993 if (ay == 3)
2994 yShift = -ascent;
2995 double x1 = xShift;
2996 double x2 = xShift + W;
2997 double y1 = -descent + yShift;
2998 double y2 = ascent + yShift;
2999
3000 Double_t A, B, C, D, E, F;
3001 A = fA * a + fC * b;
3002 B = fB * a + fD * b;
3003 C = fA * c + fC * d;
3004 D = fB * c + fD * d;
3005 E = fA * e + fC * f + fE;
3006 F = fB * e + fD * f + fF;
3007
3008 double bx1 = A * x1 + C * y1 + E;
3009 double by1 = B * x1 + D * y1 + F;
3010 double bx2 = A * x2 + C * y1 + E;
3011 double by2 = B * x2 + D * y1 + F;
3012 double bx3 = A * x2 + C * y2 + E;
3013 double by3 = B * x2 + D * y2 + F;
3014 double bx4 = A * x1 + C * y2 + E;
3015 double by4 = B * x1 + D * y2 + F;
3016
3017 double xmin = bx1;
3018 double xmax = bx1;
3019 double ymin = by1;
3020 double ymax = by1;
3021
3022 if (bx2 < xmin)
3023 xmin = bx2;
3024 if (bx3 < xmin)
3025 xmin = bx3;
3026 if (bx4 < xmin)
3027 xmin = bx4;
3028 if (bx2 > xmax)
3029 xmax = bx2;
3030 if (bx3 > xmax)
3031 xmax = bx3;
3032 if (bx4 > xmax)
3033 xmax = bx4;
3034 if (by2 < ymin)
3035 ymin = by2;
3036 if (by3 < ymin)
3037 ymin = by3;
3038 if (by4 < ymin)
3039 ymin = by4;
3040 if (by2 > ymax)
3041 ymax = by2;
3042 if (by3 > ymax)
3043 ymax = by3;
3044 if (by4 > ymax)
3045 ymax = by4;
3046
3047 fRectX1.push_back(xmin);
3048 fRectY1.push_back(ymin);
3049 fRectX2.push_back(xmax);
3050 fRectY2.push_back(ymax);
3051}
ROOT::R::TRInterface & r
Definition Object.C:4
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
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
float xmin
float ymin
float xmax
float ymax
Double_t err
const Int_t kObjFont
Definition TPDF.cxx:86
const Int_t kObjPatternList
Definition TPDF.cxx:89
const Int_t kObjInfo
Definition TPDF.cxx:81
const Int_t kObjRoot
Definition TPDF.cxx:80
const Int_t kObjColorSpace
Definition TPDF.cxx:87
const Int_t kNumberOfFonts
Definition TPDF.cxx:95
const Int_t kObjPattern
Definition TPDF.cxx:91
const Int_t kObjContents
Definition TPDF.cxx:85
const Int_t kObjFirstPage
Definition TPDF.cxx:92
const Int_t kObjPages
Definition TPDF.cxx:83
const Int_t kObjPageResources
Definition TPDF.cxx:84
const Int_t kObjPatternResourses
Definition TPDF.cxx:88
const Int_t kObjTransList
Definition TPDF.cxx:90
const Int_t kObjOutlines
Definition TPDF.cxx:82
#define gROOT
Definition TROOT.h:417
externTStyle * gStyle
Definition TStyle.h:442
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 GetAlpha() const
Definition TColor.h:67
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
Int_t GetMonth() const
Definition TDatime.h:66
Int_t GetDay() const
Definition TDatime.h:67
Int_t GetHour() const
Definition TDatime.h:69
Int_t GetSecond() const
Definition TDatime.h:71
Int_t GetYear() const
Definition TDatime.h:65
Int_t GetMinute() const
Definition TDatime.h:70
UInt_t Convert(Bool_t toGMT=kFALSE) const
Convert fDatime from TDatime format to the standard time_t format.
Definition TDatime.cxx:181
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
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:170
Collectable string class.
Definition TObjString.h:28
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
void SetLineStyle(Style_t linestyle=1) override
Change the line style.
Definition TPDF.cxx:2088
void Off()
Deactivate an already open PDF file.
Definition TPDF.cxx:1634
std::vector< int > fPageObjects
Page object numbers.
Definition TPDF.h:49
Int_t fCurrentPage
Object number of the current page.
Definition TPDF.h:48
void SetMarkerColor(Color_t cindex=1) override
Set color index for markers.
Definition TPDF.cxx:2120
Int_t fType
Workstation type used to know if the PDF is open.
Definition TPDF.h:41
void SetColor(Int_t color=1)
Set color with its color index.
Definition TPDF.cxx:1894
Double_t YtoPDF(Double_t y)
Convert Y from world coordinate to PDF.
Definition TPDF.cxx:2414
void Open(const char *filename, Int_t type=-111) override
Open a PDF file.
Definition TPDF.cxx:1658
void Close(Option_t *opt="") override
Close a PDF file.
Definition TPDF.cxx:163
std::vector< Int_t > fObjPos
Objects position.
Definition TPDF.h:46
TPDF()
Default PDF constructor.
Definition TPDF.cxx:104
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimetres.
Definition TPDF.cxx:1864
Double_t fD
"d" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:64
void LineTo(Double_t x, Double_t y)
Draw a line to a new position.
Definition TPDF.cxx:1401
Bool_t fUrl
True when the text has an URL.
Definition TPDF.h:59
void SetLineCap(Int_t linecap=0)
Set the value of the global parameter TPDF::fgLineCap.
Definition TPDF.cxx:2073
Double_t XtoPDF(Double_t x)
Convert X from world coordinate to PDF.
Definition TPDF.cxx:2405
void WriteReal(Float_t r, Bool_t space=kTRUE) override
Write a Real number to the file.
Definition TPDF.cxx:2473
Double_t fB
"b" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:62
void SetLineJoin(Int_t linejoin=0)
Set the value of the global parameter TPDF::fgLineJoin.
Definition TPDF.cxx:2049
Double_t CMtoPDF(Double_t u)
Definition TPDF.h:82
void CellArrayEnd() override
End the Cell Array painting.
Definition TPDF.cxx:155
void NewPage() override
Start a new PDF page.
Definition TPDF.cxx:1440
Float_t fAlpha
Per cent of transparency.
Definition TPDF.h:37
Float_t fLineScale
Line width scale factor.
Definition TPDF.h:45
void SetFillColor(Color_t cindex=1) override
Set color index for fill areas.
Definition TPDF.cxx:1967
Float_t fGreen
Per cent of green.
Definition TPDF.h:35
Int_t fNbUrl
Number of URLs in the current page.
Definition TPDF.h:60
Int_t fPageOrientation
Page orientation (Portrait, Landscape).
Definition TPDF.h:43
void On()
Activate an already open PDF file.
Definition TPDF.cxx:1642
Bool_t fObjectIsOpen
True if an object is opened.
Definition TPDF.h:55
Int_t fStartStream
Stream start.
Definition TPDF.h:44
Double_t fE
"e" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:65
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Draw a Box.
Definition TPDF.cxx:333
void SetLineColor(Color_t cindex=1) override
Set color index for lines.
Definition TPDF.cxx:2027
void ComputeRect(const char *chars, Double_t fontsize, Double_t a, Double_t b, Double_t c, Double_t d, Double_t e, Double_t f)
Compute the Rect for url.
Definition TPDF.cxx:2976
void FontEncode()
Font encoding.
Definition TPDF.cxx:1369
Bool_t fCompress
True when fBuffer must be compressed.
Definition TPDF.h:57
static Int_t fgLineCap
Appearance of line caps.
Definition TPDF.h:69
void TextUrl(Double_t x, Double_t y, const char *string, const char *url) override
Draw text with URL.
Definition TPDF.cxx:2355
void DrawPS(Int_t n, Float_t *xw, Float_t *yw) override
Draw a PolyLine.
Definition TPDF.cxx:1191
Float_t fYsize
Page size along Y.
Definition TPDF.h:40
Double_t UtoPDF(Double_t u)
Convert U from NDC coordinate to PDF.
Definition TPDF.cxx:2387
std::vector< std::string > fUrls
URLs.
Definition TPDF.h:50
std::vector< float > fRectY1
y1 /Rect coordinates for url annots
Definition TPDF.h:52
void SetAlpha(Float_t alpha=1.)
Set the alpha channel value.
Definition TPDF.cxx:1874
Float_t fRed
Per cent of red.
Definition TPDF.h:34
std::vector< float > fRectY2
y2 /Rect coordinates for url annots
Definition TPDF.h:54
Int_t fPageFormat
Page format (A4, Letter etc ...).
Definition TPDF.h:42
Bool_t fRange
True when a range has been defined.
Definition TPDF.h:58
std::vector< float > fRectX1
x1 /Rect coordinates for url annots
Definition TPDF.h:51
void DrawPolyMarker(Int_t n, Float_t *x, Float_t *y) override
Draw markers at the n WC points xw, yw.
Definition TPDF.cxx:563
std::vector< float > fRectX2
x2 /Rect coordinates for url annots
Definition TPDF.h:53
Float_t fBlue
Per cent of blue.
Definition TPDF.h:36
std::vector< float > fAlphas
List of alpha values used.
Definition TPDF.h:38
void MoveTo(Double_t x, Double_t y)
Move to a new position.
Definition TPDF.cxx:1411
void SetLineScale(Float_t scale=1)
Definition TPDF.h:116
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.
Definition TPDF.cxx:399
Double_t fC
"c" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:63
void CellArrayFill(Int_t r, Int_t g, Int_t b) override
Paint the Cell Array.
Definition TPDF.cxx:147
~TPDF() override
Default PDF destructor.
Definition TPDF.cxx:130
void WriteUrlObjects()
Write the annotation objects containing the URLs.
Definition TPDF.cxx:2931
void EnsureBufferSize(Int_t required_size)
Ensure that required space in the buffer is available.
Definition TPDF.cxx:1818
Double_t fA
"a" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:61
void EndObject()
Close the current opened object.
Definition TPDF.cxx:1357
void PrintStr(const char *string="") override
Output the string str in the output buffer.
Definition TPDF.cxx:1831
Int_t fNbPage
Number of pages.
Definition TPDF.h:47
void SetFillPatterns(Int_t ipat, Int_t color)
Set the fill patterns (1 to 25) for fill areas.
Definition TPDF.cxx:1975
void WriteCM(Double_t a, Double_t b, Double_t c, Double_t d, Double_t e, Double_t f, Bool_t acc=kTRUE)
Write and Accumulate (if acc is true) the Current Transformation Matrix (CTM).
Definition TPDF.cxx:2900
void SetTextColor(Color_t cindex=1) override
Set color index for text.
Definition TPDF.cxx:2128
void DrawPolyLineNDC(Int_t n, TPoints *uv)
Draw a PolyLine in NDC space.
Definition TPDF.cxx:517
Float_t fXsize
Page size along X.
Definition TPDF.h:39
void CellArrayBegin(Int_t W, Int_t H, Double_t x1, Double_t x2, Double_t y1, Double_t y2) override
Begin the Cell Array painting.
Definition TPDF.cxx:138
void DrawHatch(Float_t dy, Float_t angle, Int_t n, Float_t *x, Float_t *y)
Draw Fill area with hatch styles.
Definition TPDF.cxx:439
void SetLineWidth(Width_t linewidth=1) override
Change the line width.
Definition TPDF.cxx:2107
Double_t VtoPDF(Double_t v)
Convert V from NDC coordinate to PDF.
Definition TPDF.cxx:2396
Bool_t fPageNotEmpty
True if the current page is not empty.
Definition TPDF.h:56
void NewObject(Int_t n)
Create a new object in the PDF file.
Definition TPDF.cxx:1421
void DrawPolyLine(Int_t n, TPoints *xy)
Draw a PolyLine.
Definition TPDF.cxx:463
void Text(Double_t x, Double_t y, const char *string) override
Draw text.
Definition TPDF.cxx:2140
void PatternEncode()
Patterns encoding.
Definition TPDF.cxx:2489
Double_t fF
"f" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:66
void WriteCompressedBuffer()
Write the buffer in a compressed way.
Definition TPDF.cxx:2423
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
Definition TPDF.cxx:2367
static Int_t fgLineJoin
Appearance of joining lines.
Definition TPDF.h:68
void PrintFast(Int_t nch, const char *string="") override
Fast version of Print.
Definition TPDF.cxx:1849
2-D graphics point (world coordinates).
Definition TPoints.h:19
static char * ReAllocChar(char *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition TStorage.cxx:227
Basic string class.
Definition TString.h:138
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2270
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 fSizBuffer
Definition TVirtualPS.h:39
Int_t fLenBuffer
Definition TVirtualPS.h:38
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
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.
char * fBuffer
Definition TVirtualPS.h:42
Int_t fNByte
Definition TVirtualPS.h:37
void ClearBuffer()
Clear content of internal buffer.
TVirtualPS(const TVirtualPS &)=delete
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
#define F(x, y, z)
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
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
TMarker m
Definition textangle.C:8