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 kObjImageList = 51; // Image XObject name dictionary
93const Int_t kObjFirstPage = 52; // First page object
94
95// Number of fonts
97
100
101
102////////////////////////////////////////////////////////////////////////////////
103/// Default PDF constructor
104
106{
108 SetTitle("PDF");
109 gVirtualPS = this;
110}
111
112////////////////////////////////////////////////////////////////////////////////
113/// Initialize the PDF interface
114///
115/// - fname : PDF file name
116/// - wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
117/// inherits from TVirtualPS it should be kept. Anyway it is not
118/// necessary to specify this parameter at creation time because it
119/// has a default value (which is ignore in the PDF case).
120
122{
124 SetTitle("PDF");
125 Open(fname, wtype);
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Default PDF destructor
130
132{
133 Close();
134}
135
136////////////////////////////////////////////////////////////////////////////////
137/// Begin the Cell Array painting.
138///
139/// The W x H cells fill a rectangle whose top-left corner is at world
140/// coordinates (x1, y1); (x2 - x1) is the per-cell width and (y2 - y1) is
141/// the per-cell vertical step (the image extends downward from y1 by
142/// H * (y2 - y1)). The pixel data is collected via CellArrayFill in
143/// top-to-bottom, left-to-right order and emitted as a PDF image XObject
144/// in CellArrayEnd.
145
147{
148 if (W <= 0 || H <= 0) {
149 fCellArrayW = 0;
150 fCellArrayH = 0;
151 fCellArrayRGB.clear();
152 return;
153 }
154
155 fCellArrayW = W;
156 fCellArrayH = H;
157
159 Double_t xRight = XtoPDF(x1 + (x2 - x1) * W);
161 Double_t yBot = YtoPDF(y1 - (y2 - y1) * H);
162
167
168 fCellArrayRGB.clear();
169 fCellArrayRGB.reserve(3 * std::size_t(W) * std::size_t(H));
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Paint the Cell Array: append one RGB pixel to the in-flight buffer.
174
176{
177 if (fCellArrayW <= 0 || fCellArrayH <= 0)
178 return;
179 auto clamp = [](Int_t v) -> unsigned char {
180 if (v < 0)
181 return 0;
182 if (v > 255)
183 return 255;
184 return static_cast<unsigned char>(v);
185 };
186 fCellArrayRGB.push_back(clamp(r));
187 fCellArrayRGB.push_back(clamp(g));
188 fCellArrayRGB.push_back(clamp(b));
189}
190
191////////////////////////////////////////////////////////////////////////////////
192/// End the Cell Array painting.
193///
194/// The RGB buffer accumulated by CellArrayFill is Flate-compressed and stored
195/// as a PDF image XObject (actually emitted later, in Close). The page content
196/// stream only receives the placement matrix and a "/ImN Do" operator that
197/// paints that XObject. This is both smaller and structurally cleaner than an
198/// inline image: the pixel data is compressed once, kept out of the page
199/// content stream, and could be reused across pages.
200
202{
203 if (fCellArrayW <= 0 || fCellArrayH <= 0 || fCellArrayRGB.empty()) {
204 fCellArrayW = 0;
205 fCellArrayH = 0;
206 fCellArrayRGB.clear();
207 return;
208 }
209
210 const std::size_t expected = 3 * std::size_t(fCellArrayW) * std::size_t(fCellArrayH);
211 if (fCellArrayRGB.size() < expected) {
212 // Pad with black if the caller delivered fewer pixels than declared.
213 fCellArrayRGB.resize(expected, 0);
214 } else if (fCellArrayRGB.size() > expected) {
215 fCellArrayRGB.resize(expected);
216 }
217
218 // Flate-compress the pixels now, so only the compressed form is buffered
219 // until Close. compress2 emits a zlib stream, exactly what the PDF
220 // /FlateDecode filter consumes.
222 img.fW = fCellArrayW;
223 img.fH = fCellArrayH;
224 uLongf bound = compressBound(static_cast<uLong>(fCellArrayRGB.size()));
225 img.fData.resize(bound);
227 int zerr = compress2(img.fData.data(), &destLen, fCellArrayRGB.data(), static_cast<uLong>(fCellArrayRGB.size()),
229 if (zerr == Z_OK) {
230 img.fData.resize(destLen);
231 img.fFlate = kTRUE;
232 } else {
233 // Fall back to storing the raw samples uncompressed.
234 img.fData = fCellArrayRGB;
235 img.fFlate = kFALSE;
236 }
237 fImageObjects.push_back(std::move(img));
238 const Int_t imageId = static_cast<Int_t>(fImageObjects.size()); // 1-based /ImN
239
240 // Paint the image XObject. Its unit square (0,0)-(1,1) is mapped onto the
241 // image rectangle by this cm matrix. Operator separators must be real
242 // newlines: '@' is only translated when fCompress is false, and a page
243 // content stream is written with fCompress true.
244 PrintStr("\nq ");
246 WriteReal(0.);
247 WriteReal(0.);
251 PrintStr(" cm /Im");
253 PrintStr(" Do Q\n");
254
255 fCellArrayW = 0;
256 fCellArrayH = 0;
257 fCellArrayRGB.clear();
258 fCellArrayRGB.shrink_to_fit();
259}
260
261////////////////////////////////////////////////////////////////////////////////
262/// Close a PDF file
263
265{
266 if (!gVirtualPS || !fStream)
267 return;
268
269 if (gPad)
270 gPad->Update();
271
272 // Close the currently opened page
274 PrintStr("endstream@");
276 EndObject();
279 PrintStr("@");
280 EndObject();
282 PrintStr("<<@");
283 if (!strstr(GetTitle(),"PDF")) {
284 PrintStr("/Title (");
286 PrintStr(")@");
287 } else {
288 PrintStr("/Title (Page");
290 PrintStr(")@");
291 }
292 PrintStr("/Dest [");
294 PrintStr(" 0 R /XYZ null null 0]@");
295 PrintStr("/Parent");
297 PrintStr(" 0 R");
298 PrintStr("@");
299 if (fNbPage > 1) {
300 PrintStr("/Prev");
302 PrintStr(" 0 R");
303 PrintStr("@");
304 }
305 PrintStr(">>@");
306 EndObject();
308 PrintStr("@");
310 PrintStr("<<@");
311 PrintStr("/Type /Outlines@");
312 PrintStr("/Count");
314 PrintStr("@");
315 PrintStr("/First");
317 PrintStr(" 0 R");
318 PrintStr("@");
319 PrintStr("/Last");
321 PrintStr(" 0 R");
322 PrintStr("@");
323 PrintStr(">>@");
324 EndObject();
325
327 PrintStr("<<@");
328 PrintStr("/Title (Contents)@");
329 PrintStr("/Dest [");
331 PrintStr(" 0 R /XYZ null null 0]@");
332 PrintStr("/Count");
334 PrintStr("@");
335 PrintStr("/Parent");
337 PrintStr(" 0 R");
338 PrintStr("@");
339 PrintStr("/First");
341 PrintStr(" 0 R");
342 PrintStr("@");
343 PrintStr("/Last");
345 PrintStr(" 0 R");
346 PrintStr("@");
347 PrintStr(">>@");
348 EndObject();
349
350 // List of all the pages
352 PrintStr("<<@");
353 PrintStr("/Type /Pages@");
354 PrintStr("/Count");
356 PrintStr("@");
357 PrintStr("/Kids [");
358 for (std::size_t i = 0; i < fPageObjects.size(); i++) {
360 PrintStr(" 0 R");
361 }
362 PrintStr(" ]");
363 PrintStr("@");
364 PrintStr(">>@");
365 EndObject();
366
367 if (!fPageObjects.empty())
368 fPageObjects.clear();
369 if (!fUrls.empty())
370 fUrls.clear();
371 if (!fRectX1.empty())
372 fRectX1.clear();
373 if (!fRectY1.empty())
374 fRectY1.clear();
375 if (!fRectX2.empty())
376 fRectX2.clear();
377 if (!fRectY2.empty())
378 fRectY2.clear();
379
380 // List of transparencies
382 PrintStr("<<@");
383 for (std::size_t i = 0; i < fAlphas.size(); i++) {
384 PrintStr(
385 TString::Format("/ca%3.2f << /Type /ExtGState /ca %3.2f >> /CA%3.2f << /Type /ExtGState /CA %3.2f >>@",
386 fAlphas[i],fAlphas[i],fAlphas[i],fAlphas[i]));
387 }
388 PrintStr(">>@");
389 EndObject();
390 if (!fAlphas.empty())
391 fAlphas.clear();
392
393 // Image XObjects. They are emitted here, once every page's content stream
394 // has been closed, because a PDF object cannot be opened while another one
395 // (the page content stream) is still open. Each page's /Resources refers to
396 // kObjImageList, the name dictionary written just after the images.
397 std::vector<Int_t> imageObjNum;
398 imageObjNum.reserve(fImageObjects.size());
399 for (const auto &img : fImageObjects) {
400 Int_t n = static_cast<Int_t>(fObjPos.size()) + 1;
401 imageObjNum.push_back(n);
402 NewObject(n);
403 PrintStr("<<@");
404 PrintStr("/Type /XObject@");
405 PrintStr("/Subtype /Image@");
406 PrintStr("/Width");
407 WriteInteger(img.fW);
408 PrintStr("@");
409 PrintStr("/Height");
410 WriteInteger(img.fH);
411 PrintStr("@");
412 PrintStr("/ColorSpace /DeviceRGB@");
413 PrintStr("/BitsPerComponent 8@");
414 if (img.fFlate)
415 PrintStr("/Filter /FlateDecode@");
416 PrintStr("/Length");
417 WriteInteger(static_cast<Int_t>(img.fData.size()));
418 PrintStr("@");
419 PrintStr(">>@");
420 PrintStr("stream@");
421 if (!img.fData.empty()) {
422 fStream->write(reinterpret_cast<const char *>(img.fData.data()), img.fData.size());
423 fNByte += img.fData.size();
424 }
425 PrintStr("@endstream@");
426 EndObject();
427 }
428
429 // Name dictionary mapping /ImN to the XObjects above. Always written, even
430 // when empty, because kObjImageList is referenced by every page's
431 // /Resources and so must exist in the cross-reference table.
433 PrintStr("<<@");
434 for (std::size_t i = 0; i < imageObjNum.size(); ++i) {
435 PrintStr(" /Im");
436 WriteInteger(static_cast<Int_t>(i) + 1, kFALSE);
438 PrintStr(" 0 R");
439 }
440 PrintStr("@>>@");
441 EndObject();
442 fImageObjects.clear();
443
444 // Cross-Reference Table
446 PrintStr("xref@");
447 PrintStr("0");
448 WriteInteger(fObjPos.size() + 1);
449 PrintStr("@");
450 PrintStr("0000000000 65535 f @");
451 char str[21];
452 for (std::size_t i = 0; i < fObjPos.size(); ++i) {
453 snprintf(str,21,"%10.10d 00000 n @", fObjPos[i]);
454 PrintStr(str);
455 }
456
457 // Trailer
458 PrintStr("trailer@");
459 PrintStr("<<@");
460 PrintStr("/Size");
461 WriteInteger(fObjPos.size() + 1);
462 PrintStr("@");
463 PrintStr("/Root");
465 PrintStr(" 0 R");
466 PrintStr("@");
467 PrintStr("/Info");
469 PrintStr(" 0 R@");
470 PrintStr(">>@");
471 PrintStr("startxref@");
472 WriteInteger(refInd, false);
473 PrintStr("@");
474 PrintStr("%%EOF@");
475
476 // Close file stream
477 CloseStream();
478
479 gVirtualPS = nullptr;
480}
481
482////////////////////////////////////////////////////////////////////////////////
483/// Draw a Box
484
486{
487 static Double_t x[4], y[4];
492 Int_t fillis = fFillStyle/1000;
493 Int_t fillsi = fFillStyle%1000;
494
495 if (fillis == 3 || fillis == 2) {
496 if (fillsi > 99) {
497 x[0] = x1; y[0] = y1;
498 x[1] = x2; y[1] = y1;
499 x[2] = x2; y[2] = y2;
500 x[3] = x1; y[3] = y2;
501 return;
502 }
503 if (fillsi > 0 && fillsi < 26) {
504 x[0] = x1; y[0] = y1;
505 x[1] = x2; y[1] = y1;
506 x[2] = x2; y[2] = y2;
507 x[3] = x1; y[3] = y2;
508 DrawPS(-4, &x[0], &y[0]);
509 }
510 if (fillsi == -3) {
511 SetColor(5);
512 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
513 WriteReal(ix1);
514 WriteReal(iy1);
515 WriteReal(ix2 - ix1);
516 WriteReal(iy2 - iy1);
517 if (fAlpha == 1) PrintFast(8," re b* Q");
518 else PrintFast(6," re f*");
519 }
520 }
521 if (fillis == 1) {
523 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
524 WriteReal(ix1);
525 WriteReal(iy1);
526 WriteReal(ix2 - ix1);
527 WriteReal(iy2 - iy1);
528 if (fAlpha == 1) PrintFast(8," re b* Q");
529 else PrintFast(6," re f*");
530 }
531 if (fillis == 0) {
532 if (fLineWidth<=0) return;
534 WriteReal(ix1);
535 WriteReal(iy1);
536 WriteReal(ix2 - ix1);
537 WriteReal(iy2 - iy1);
538 PrintFast(5," re S");
539 }
540}
541
542////////////////////////////////////////////////////////////////////////////////
543/// Draw a Frame around a box
544///
545/// - mode = -1 box looks as it is behind the screen
546/// - mode = 1 box looks as it is in front of the screen
547/// - border is the border size in already precomputed PDF units
548/// - dark is the color for the dark part of the frame
549/// - light is the color for the light part of the frame
550
552 Int_t mode, Int_t border, Int_t dark, Int_t light)
553{
554 static Double_t xps[7], yps[7];
555 Int_t i;
556
557 // Draw top&left part of the box
558 if (mode == -1) SetColor(dark);
559 else SetColor(light);
560 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
561 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
562 xps[2] = xps[1]; yps[2] = YtoPDF(yt) - border;
563 xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
564 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
565 xps[5] = xps[0]; yps[5] = yps[4];
566 xps[6] = xps[0]; yps[6] = yps[0];
567
568 MoveTo(xps[0], yps[0]);
569 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
570 PrintFast(3," f*");
571
572 // Draw bottom&right part of the box
573 if (mode == -1) SetColor(light);
574 else SetColor(dark);
575 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
576 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
577 xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
578 xps[3] = xps[2]; yps[3] = YtoPDF(yt) - border;
579 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
580 xps[5] = xps[4]; yps[5] = yps[0];
581 xps[6] = xps[0]; yps[6] = yps[0];
582
583 MoveTo(xps[0], yps[0]);
584 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
585 PrintFast(3," f*");
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Draw Fill area with hatch styles
590
592{
593 Warning("DrawHatch", "hatch fill style not yet implemented");
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// Draw Fill area with hatch styles
598
600{
601 Warning("DrawHatch", "hatch fill style not yet implemented");
602}
603
604////////////////////////////////////////////////////////////////////////////////
605/// Draw a PolyLine
606///
607/// Draw a polyline through the points xy.
608///
609/// - If NN=1 moves only to point x,y.
610/// - If NN=0 the x,y are written in the PDF file
611/// according to the current transformation.
612/// - If NN>0 the line is clipped as a line.
613/// - If NN<0 the line is clipped as a fill area.
614
616{
617 Int_t n;
618
621
622 if (nn > 0) {
623 if (fLineWidth<=0) return;
624 n = nn;
628 } else {
629 n = -nn;
630 SetLineStyle(1);
631 SetLineWidth(1);
633 }
634
635 WriteReal(XtoPDF(xy[0].GetX()));
636 WriteReal(YtoPDF(xy[0].GetY()));
637 if (n <= 1) {
638 if (n == 0) return;
639 PrintFast(2," m");
640 return;
641 }
642
643 PrintFast(2," m");
644
645 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
646
647 if (nn > 0) {
648 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
649 PrintFast(2," S");
650 } else {
651 PrintFast(3," f*");
652 }
653
656}
657
658////////////////////////////////////////////////////////////////////////////////
659/// Draw a PolyLine in NDC space
660///
661/// Draw a polyline through the points xy.
662///
663/// - If NN=1 moves only to point x,y.
664/// - If NN=0 the x,y are written in the PDF file
665/// according to the current transformation.
666/// - If NN>0 the line is clipped as a line.
667/// - If NN<0 the line is clipped as a fill area.
668
670{
671 Int_t n;
672
675
676 if (nn > 0) {
677 if (fLineWidth<=0) return;
678 n = nn;
682 } else {
683 n = -nn;
684 SetLineStyle(1);
685 SetLineWidth(1);
687 }
688
689 WriteReal(UtoPDF(xy[0].GetX()));
690 WriteReal(VtoPDF(xy[0].GetY()));
691 if (n <= 1) {
692 if (n == 0) return;
693 PrintFast(2," m");
694 return;
695 }
696
697 PrintFast(2," m");
698
699 for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
700
701 if (nn > 0) {
702 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
703 PrintFast(2," S");
704 } else {
705 PrintFast(3," f*");
706 }
707
710}
711
712////////////////////////////////////////////////////////////////////////////////
713/// Draw markers at the n WC points xw, yw
714
716{
720 SetLineStyle(1);
724
725 if (ms == 4)
726 ms = 24;
727 else if (ms >= 6 && ms <= 8)
728 ms = 20;
729 else if (ms >= 9 && ms <= 19)
730 ms = 1;
731
732 // Define the marker size
734 if (fMarkerStyle == 1 || (fMarkerStyle >= 9 && fMarkerStyle <= 19)) {
735 msize = 1.;
736 } else if (fMarkerStyle == 6) {
737 msize = 1.;
738 } else if (fMarkerStyle == 7) {
739 msize = 1.5;
740 } else {
741 const Int_t kBASEMARKER = 8;
743 Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
744 msize = this->UtoPDF(s2x) - this->UtoPDF(0);
745 }
746
747 Double_t m = msize;
748 Double_t m2 = m/2;
749 Double_t m3 = m/3;
750 Double_t m4 = m2*1.333333333333;
751 Double_t m6 = m/6;
752 Double_t m0 = m/10.;
753 Double_t m8 = m/4;
754 Double_t m9 = m/8;
755
756 // Draw the marker according to the type
757 Double_t ix,iy;
758 for (Int_t i=0;i<n;i++) {
759 ix = XtoPDF(xw[i]);
760 iy = YtoPDF(yw[i]);
761 // Dot (.)
762 if (ms == 1) {
763 MoveTo(ix-1, iy);
764 LineTo(ix , iy);
765 // Plus (+)
766 } else if (ms == 2) {
767 MoveTo(ix-m2, iy);
768 LineTo(ix+m2, iy);
769 MoveTo(ix , iy-m2);
770 LineTo(ix , iy+m2);
771 // X shape (X)
772 } else if (ms == 5) {
773 MoveTo(ix-m2*0.707, iy-m2*0.707);
774 LineTo(ix+m2*0.707, iy+m2*0.707);
775 MoveTo(ix-m2*0.707, iy+m2*0.707);
776 LineTo(ix+m2*0.707, iy-m2*0.707);
777 // Asterisk shape (*)
778 } else if (ms == 3 || ms == 31) {
779 MoveTo(ix-m2, iy);
780 LineTo(ix+m2, iy);
781 MoveTo(ix , iy-m2);
782 LineTo(ix , iy+m2);
783 MoveTo(ix-m2*0.707, iy-m2*0.707);
784 LineTo(ix+m2*0.707, iy+m2*0.707);
785 MoveTo(ix-m2*0.707, iy+m2*0.707);
786 LineTo(ix+m2*0.707, iy-m2*0.707);
787 // Circle
788 } else if (ms == 24 || ms == 20) {
789 MoveTo(ix-m2, iy);
790 WriteReal(ix-m2); WriteReal(iy+m4);
791 WriteReal(ix+m2); WriteReal(iy+m4);
792 WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
793 WriteReal(ix+m2); WriteReal(iy-m4);
794 WriteReal(ix-m2); WriteReal(iy-m4);
795 WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
796 // Square
797 } else if (ms == 25 || ms == 21) {
798 WriteReal(ix-m2); WriteReal(iy-m2);
799 WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
800 // Down triangle
801 } else if (ms == 23 || ms == 32) {
802 MoveTo(ix , iy-m2);
803 LineTo(ix+m2, iy+m2);
804 LineTo(ix-m2, iy+m2);
805 PrintFast(2," h");
806 // Up triangle
807 } else if (ms == 26 || ms == 22) {
808 MoveTo(ix-m2, iy-m2);
809 LineTo(ix+m2, iy-m2);
810 LineTo(ix , iy+m2);
811 PrintFast(2," h");
812 } else if (ms == 27 || ms == 33) {
813 MoveTo(ix , iy-m2);
814 LineTo(ix+m3, iy);
815 LineTo(ix , iy+m2);
816 LineTo(ix-m3, iy) ;
817 PrintFast(2," h");
818 } else if (ms == 28 || ms == 34) {
819 MoveTo(ix-m6, iy-m6);
820 LineTo(ix-m6, iy-m2);
821 LineTo(ix+m6, iy-m2);
822 LineTo(ix+m6, iy-m6);
823 LineTo(ix+m2, iy-m6);
824 LineTo(ix+m2, iy+m6);
825 LineTo(ix+m6, iy+m6);
826 LineTo(ix+m6, iy+m2);
827 LineTo(ix-m6, iy+m2);
828 LineTo(ix-m6, iy+m6);
829 LineTo(ix-m2, iy+m6);
830 LineTo(ix-m2, iy-m6);
831 PrintFast(2," h");
832 } else if (ms == 29 || ms == 30) {
833 MoveTo(ix , iy+m2);
834 LineTo(ix+0.112255*m, iy+0.15451*m);
835 LineTo(ix+0.47552*m , iy+0.15451*m);
836 LineTo(ix+0.181635*m, iy-0.05902*m);
837 LineTo(ix+0.29389*m , iy-0.40451*m);
838 LineTo(ix , iy-0.19098*m);
839 LineTo(ix-0.29389*m , iy-0.40451*m);
840 LineTo(ix-0.181635*m, iy-0.05902*m);
841 LineTo(ix-0.47552*m , iy+0.15451*m);
842 LineTo(ix-0.112255*m, iy+0.15451*m);
843 PrintFast(2," h");
844 } else if (ms == 35 ) {
845 // diamond with cross
846 MoveTo(ix-m2, iy );
847 LineTo(ix , iy-m2);
848 LineTo(ix+m2, iy );
849 LineTo(ix , iy+m2);
850 LineTo(ix-m2, iy );
851 LineTo(ix+m2, iy );
852 LineTo(ix , iy+m2);
853 LineTo(ix , iy-m2);
854 PrintFast(2," h");
855 } else if (ms == 36 ) {
856 // square with diagonal cross
857 MoveTo(ix-m2, iy-m2);
858 LineTo(ix+m2, iy-m2);
859 LineTo(ix+m2, iy+m2);
860 LineTo(ix-m2, iy+m2);
861 LineTo(ix-m2, iy-m2);
862 LineTo(ix+m2, iy+m2);
863 LineTo(ix-m2, iy+m2);
864 LineTo(ix+m2, iy-m2);
865 PrintFast(2," h");
866 } else if (ms == 37 || ms == 39 ) {
867 // square with cross
868 MoveTo(ix , iy );
869 LineTo(ix-m8, iy+m2);
870 LineTo(ix-m2, iy );
871 LineTo(ix , iy );
872 LineTo(ix-m8, iy-m2);
873 LineTo(ix+m8, iy-m2);
874 LineTo(ix , iy );
875 LineTo(ix+m2, iy );
876 LineTo(ix+m8, iy+m2);
877 LineTo(ix , iy );
878 PrintFast(2," h");
879 } else if (ms == 38 ) {
880 // + shaped marker with octagon
881 MoveTo(ix-m2, iy );
882 LineTo(ix-m2, iy-m8);
883 LineTo(ix-m8, iy-m2);
884 LineTo(ix+m8, iy-m2);
885 LineTo(ix+m2, iy-m8);
886 LineTo(ix+m2, iy+m8);
887 LineTo(ix+m8, iy+m2);
888 LineTo(ix-m8, iy+m2);
889 LineTo(ix-m2, iy+m8);
890 LineTo(ix-m2, iy );
891 LineTo(ix+m2, iy );
892 LineTo(ix , iy );
893 LineTo(ix , iy-m2);
894 LineTo(ix , iy+m2);
895 LineTo(ix , iy);
896 PrintFast(2," h");
897 } else if (ms == 40 || ms == 41 ) {
898 // four triangles X
899 MoveTo(ix , iy );
900 LineTo(ix+m8, iy+m2);
901 LineTo(ix+m2, iy+m8);
902 LineTo(ix , iy );
903 LineTo(ix+m2, iy-m8);
904 LineTo(ix+m8, iy-m2);
905 LineTo(ix , iy );
906 LineTo(ix-m8, iy-m2);
907 LineTo(ix-m2, iy-m8);
908 LineTo(ix , iy );
909 LineTo(ix-m2, iy+m8);
910 LineTo(ix-m8, iy+m2);
911 LineTo(ix , iy );
912 PrintFast(2," h");
913 } else if (ms == 42 || ms == 43 ) {
914 // double diamonds
915 MoveTo(ix , iy+m2);
916 LineTo(ix-m9, iy+m9);
917 LineTo(ix-m2, iy );
918 LineTo(ix-m9, iy-m9);
919 LineTo(ix , iy-m2);
920 LineTo(ix+m9, iy-m9);
921 LineTo(ix+m2, iy );
922 LineTo(ix+m9, iy+m9);
923 LineTo(ix , iy+m2);
924 PrintFast(2," h");
925 } else if (ms == 44 ) {
926 // open four triangles plus
927 MoveTo(ix , iy );
928 LineTo(ix+m8, iy+m2);
929 LineTo(ix-m8, iy+m2);
930 LineTo(ix+m8, iy-m2);
931 LineTo(ix-m8, iy-m2);
932 LineTo(ix , iy );
933 LineTo(ix+m2, iy+m8);
934 LineTo(ix+m2, iy-m8);
935 LineTo(ix-m2, iy+m8);
936 LineTo(ix-m2, iy-m8);
937 LineTo(ix , iy );
938 PrintFast(2," h");
939 } else if (ms == 45 ) {
940 // filled four triangles plus
941 MoveTo(ix+m0, iy+m0);
942 LineTo(ix+m8, iy+m2);
943 LineTo(ix-m8, iy+m2);
944 LineTo(ix-m0, iy+m0);
945 LineTo(ix-m2, iy+m8);
946 LineTo(ix-m2, iy-m8);
947 LineTo(ix-m0, iy-m0);
948 LineTo(ix-m8, iy-m2);
949 LineTo(ix+m8, iy-m2);
950 LineTo(ix+m0, iy-m0);
951 LineTo(ix+m2, iy-m8);
952 LineTo(ix+m2, iy+m8);
953 LineTo(ix+m0, iy+m0);
954 PrintFast(2," h");
955 } else if (ms == 46 || ms == 47 ) {
956 // four triangles X
957 MoveTo(ix , iy+m8);
958 LineTo(ix-m8, iy+m2);
959 LineTo(ix-m2, iy+m8);
960 LineTo(ix-m8, iy );
961 LineTo(ix-m2, iy-m8);
962 LineTo(ix-m8, iy-m2);
963 LineTo(ix , iy-m8);
964 LineTo(ix+m8, iy-m2);
965 LineTo(ix+m2, iy-m8);
966 LineTo(ix+m8, iy );
967 LineTo(ix+m2, iy+m8);
968 LineTo(ix+m8, iy+m2);
969 LineTo(ix , iy+m8);
970 PrintFast(2," h");
971 } else if (ms == 48 ) {
972 // four filled squares X
973 MoveTo(ix , iy+m8*1.01);
974 LineTo(ix-m8, iy+m2);
975 LineTo(ix-m2, iy+m8);
976 LineTo(ix-m8, iy );
977 LineTo(ix-m2, iy-m8);
978 LineTo(ix-m8, iy-m2);
979 LineTo(ix , iy-m8);
980 LineTo(ix+m8, iy-m2);
981 LineTo(ix+m2, iy-m8);
982 LineTo(ix+m8, iy );
983 LineTo(ix+m2, iy+m8);
984 LineTo(ix+m8, iy+m2);
985 LineTo(ix , iy+m8*0.99);
986 LineTo(ix+m8*0.99, iy );
987 LineTo(ix , iy-m8*0.99);
988 LineTo(ix-m8*0.99, iy );
989 LineTo(ix , iy+m8*0.99);
990 PrintFast(2," h");
991 } else if (ms == 49 ) {
992 // four filled squares plus
993 MoveTo(ix-m6, iy-m6*1.01);
994 LineTo(ix-m6, iy-m2);
995 LineTo(ix+m6, iy-m2);
996 LineTo(ix+m6, iy-m6);
997 LineTo(ix+m2, iy-m6);
998 LineTo(ix+m2, iy+m6);
999 LineTo(ix+m6, iy+m6);
1000 LineTo(ix+m6, iy+m2);
1001 LineTo(ix-m6, iy+m2);
1002 LineTo(ix-m6, iy+m6);
1003 LineTo(ix-m2, iy+m6);
1004 LineTo(ix-m2, iy-m6);
1005 LineTo(ix-m6, iy-m6*0.99);
1006 LineTo(ix-m6, iy+m6);
1007 LineTo(ix+m6, iy+m6);
1008 LineTo(ix+m6, iy-m6);
1009 PrintFast(2," h");
1010 } else {
1011 MoveTo(ix-m6, iy-m6);
1012 LineTo(ix-m6, iy-m2);
1013 }
1014
1015 if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
1016 ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
1017 ms == 47 || ms == 48 || ms == 49) {
1018 PrintFast(2," f");
1019 } else {
1020 PrintFast(2," S");
1021 }
1022 }
1023
1026}
1027
1028////////////////////////////////////////////////////////////////////////////////
1029/// Draw markers at the n WC points xw, yw
1030
1032{
1036 SetLineStyle(1);
1040
1041 if (ms == 4)
1042 ms = 24;
1043 else if (ms >= 6 && ms <= 8)
1044 ms = 20;
1045 else if (ms >= 9 && ms <= 19)
1046 ms = 1;
1047
1048 // Define the marker size
1050 if (fMarkerStyle == 1 || (fMarkerStyle >= 9 && fMarkerStyle <= 19)) {
1051 msize = 1.;
1052 } else if (fMarkerStyle == 6) {
1053 msize = 1.5;
1054 } else if (fMarkerStyle == 7) {
1055 msize = 3.;
1056 } else {
1057 const Int_t kBASEMARKER = 8;
1059 Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
1060 msize = this->UtoPDF(s2x) - this->UtoPDF(0);
1061 }
1062
1063 Double_t m = msize;
1064 Double_t m2 = m/2;
1065 Double_t m3 = m/3;
1066 Double_t m4 = m2*1.333333333333;
1067 Double_t m6 = m/6;
1068 Double_t m8 = m/4;
1069 Double_t m9 = m/8;
1070
1071 // Draw the marker according to the type
1072 Double_t ix,iy;
1073 for (Int_t i=0;i<n;i++) {
1074 ix = XtoPDF(xw[i]);
1075 iy = YtoPDF(yw[i]);
1076 // Dot (.)
1077 if (ms == 1) {
1078 MoveTo(ix-1, iy);
1079 LineTo(ix , iy);
1080 // Plus (+)
1081 } else if (ms == 2) {
1082 MoveTo(ix-m2, iy);
1083 LineTo(ix+m2, iy);
1084 MoveTo(ix , iy-m2);
1085 LineTo(ix , iy+m2);
1086 // X shape (X)
1087 } else if (ms == 5) {
1088 MoveTo(ix-m2*0.707, iy-m2*0.707);
1089 LineTo(ix+m2*0.707, iy+m2*0.707);
1090 MoveTo(ix-m2*0.707, iy+m2*0.707);
1091 LineTo(ix+m2*0.707, iy-m2*0.707);
1092 // Asterisk shape (*)
1093 } else if (ms == 3 || ms == 31) {
1094 MoveTo(ix-m2, iy);
1095 LineTo(ix+m2, iy);
1096 MoveTo(ix , iy-m2);
1097 LineTo(ix , iy+m2);
1098 MoveTo(ix-m2*0.707, iy-m2*0.707);
1099 LineTo(ix+m2*0.707, iy+m2*0.707);
1100 MoveTo(ix-m2*0.707, iy+m2*0.707);
1101 LineTo(ix+m2*0.707, iy-m2*0.707);
1102 // Circle
1103 } else if (ms == 24 || ms == 20) {
1104 MoveTo(ix-m2, iy);
1105 WriteReal(ix-m2); WriteReal(iy+m4);
1106 WriteReal(ix+m2); WriteReal(iy+m4);
1107 WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
1108 WriteReal(ix+m2); WriteReal(iy-m4);
1109 WriteReal(ix-m2); WriteReal(iy-m4);
1110 WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
1111 // Square
1112 } else if (ms == 25 || ms == 21) {
1113 WriteReal(ix-m2); WriteReal(iy-m2);
1114 WriteReal(m) ; WriteReal(m) ; PrintFast(3," re");
1115 // Down triangle
1116 } else if (ms == 23 || ms == 32) {
1117 MoveTo(ix , iy-m2);
1118 LineTo(ix+m2, iy+m2);
1119 LineTo(ix-m2, iy+m2);
1120 PrintFast(2," h");
1121 // Up triangle
1122 } else if (ms == 26 || ms == 22) {
1123 MoveTo(ix-m2, iy-m2);
1124 LineTo(ix+m2, iy-m2);
1125 LineTo(ix , iy+m2);
1126 PrintFast(2," h");
1127 } else if (ms == 27 || ms == 33) {
1128 MoveTo(ix , iy-m2);
1129 LineTo(ix+m3, iy);
1130 LineTo(ix , iy+m2);
1131 LineTo(ix-m3, iy) ;
1132 PrintFast(2," h");
1133 } else if (ms == 28 || ms == 34) {
1134 MoveTo(ix-m6, iy-m6);
1135 LineTo(ix-m6, iy-m2);
1136 LineTo(ix+m6, iy-m2);
1137 LineTo(ix+m6, iy-m6);
1138 LineTo(ix+m2, iy-m6);
1139 LineTo(ix+m2, iy+m6);
1140 LineTo(ix+m6, iy+m6);
1141 LineTo(ix+m6, iy+m2);
1142 LineTo(ix-m6, iy+m2);
1143 LineTo(ix-m6, iy+m6);
1144 LineTo(ix-m2, iy+m6);
1145 LineTo(ix-m2, iy-m6);
1146 PrintFast(2," h");
1147 } else if (ms == 29 || ms == 30) {
1148 MoveTo(ix , iy-m2);
1149 LineTo(ix-0.112255*m, iy-0.15451*m);
1150 LineTo(ix-0.47552*m , iy-0.15451*m);
1151 LineTo(ix-0.181635*m, iy+0.05902*m);
1152 LineTo(ix-0.29389*m , iy+0.40451*m);
1153 LineTo(ix , iy+0.19098*m);
1154 LineTo(ix+0.29389*m , iy+0.40451*m);
1155 LineTo(ix+0.181635*m, iy+0.05902*m);
1156 LineTo(ix+0.47552*m , iy-0.15451*m);
1157 LineTo(ix+0.112255*m, iy-0.15451*m);
1158 PrintFast(2," h");
1159 } else if (ms == 35 ) {
1160 MoveTo(ix-m2, iy );
1161 LineTo(ix , iy-m2);
1162 LineTo(ix+m2, iy );
1163 LineTo(ix , iy+m2);
1164 LineTo(ix-m2, iy );
1165 LineTo(ix+m2, iy );
1166 LineTo(ix , iy+m2);
1167 LineTo(ix , iy-m2);
1168 PrintFast(2," h");
1169 } else if (ms == 36 ) {
1170 MoveTo(ix-m2, iy-m2);
1171 LineTo(ix+m2, iy-m2);
1172 LineTo(ix+m2, iy+m2);
1173 LineTo(ix-m2, iy+m2);
1174 LineTo(ix-m2, iy-m2);
1175 LineTo(ix+m2, iy+m2);
1176 LineTo(ix-m2, iy+m2);
1177 LineTo(ix+m2, iy-m2);
1178 PrintFast(2," h");
1179 } else if (ms == 37 || ms == 39 ) {
1180 MoveTo(ix , iy );
1181 LineTo(ix-m8, iy+m2);
1182 LineTo(ix-m2, iy );
1183 LineTo(ix , iy );
1184 LineTo(ix-m8, iy-m2);
1185 LineTo(ix+m8, iy-m2);
1186 LineTo(ix , iy );
1187 LineTo(ix+m2, iy );
1188 LineTo(ix+m8, iy+m2);
1189 LineTo(ix , iy );
1190 PrintFast(2," h");
1191 } else if (ms == 38 ) {
1192 MoveTo(ix-m2, iy );
1193 LineTo(ix-m2, iy-m8);
1194 LineTo(ix-m8, iy-m2);
1195 LineTo(ix+m8, iy-m2);
1196 LineTo(ix+m2, iy-m8);
1197 LineTo(ix+m2, iy+m8);
1198 LineTo(ix+m8, iy+m2);
1199 LineTo(ix-m8, iy+m2);
1200 LineTo(ix-m2, iy+m8);
1201 LineTo(ix-m2, iy );
1202 LineTo(ix+m2, iy );
1203 LineTo(ix , iy );
1204 LineTo(ix , iy-m2);
1205 LineTo(ix , iy+m2);
1206 LineTo(ix , iy );
1207 PrintFast(2," h");
1208 } else if (ms == 40 || ms == 41 ) {
1209 MoveTo(ix , iy );
1210 LineTo(ix+m8, iy+m2);
1211 LineTo(ix+m2, iy+m8);
1212 LineTo(ix , iy );
1213 LineTo(ix+m2, iy-m8);
1214 LineTo(ix+m8, iy-m2);
1215 LineTo(ix , iy );
1216 LineTo(ix-m8, iy-m2);
1217 LineTo(ix-m2, iy-m8);
1218 LineTo(ix , iy );
1219 LineTo(ix-m2, iy+m8);
1220 LineTo(ix-m8, iy+m2);
1221 LineTo(ix , iy );
1222 PrintFast(2," h");
1223 } else if (ms == 42 || ms == 43 ) {
1224 MoveTo(ix , iy+m2);
1225 LineTo(ix-m9, iy+m9);
1226 LineTo(ix-m2, iy );
1227 LineTo(ix-m9, iy-m9);
1228 LineTo(ix , iy-m2);
1229 LineTo(ix+m9, iy-m9);
1230 LineTo(ix+m2, iy );
1231 LineTo(ix+m9, iy+m9);
1232 LineTo(ix , iy+m2);
1233 PrintFast(2," h");
1234 } else if (ms == 44 ) {
1235 MoveTo(ix , iy );
1236 LineTo(ix+m8, iy+m2);
1237 LineTo(ix-m8, iy+m2);
1238 LineTo(ix+m8, iy-m2);
1239 LineTo(ix-m8, iy-m2);
1240 LineTo(ix , iy );
1241 LineTo(ix+m2, iy+m8);
1242 LineTo(ix+m2, iy-m8);
1243 LineTo(ix-m2, iy+m8);
1244 LineTo(ix-m2, iy-m8);
1245 LineTo(ix , iy );
1246 PrintFast(2," h");
1247 } else if (ms == 45 ) {
1248 MoveTo(ix+m6/2., iy+m6/2.);
1249 LineTo(ix+m8, iy+m2);
1250 LineTo(ix-m8, iy+m2);
1251 LineTo(ix-m6/2., iy+m6/2.);
1252 LineTo(ix-m2, iy+m8);
1253 LineTo(ix-m2, iy-m8);
1254 LineTo(ix-m6/2., iy-m6/2.);
1255 LineTo(ix-m8, iy-m2);
1256 LineTo(ix+m8, iy-m2);
1257 LineTo(ix+m6/2., iy-m6/2.);
1258 LineTo(ix+m2, iy-m8);
1259 LineTo(ix+m2, iy+m8);
1260 LineTo(ix+m6/2., iy+m6/2.);
1261 PrintFast(2," h");
1262 } else if (ms == 46 || ms == 47 ) {
1263 MoveTo(ix , iy+m8);
1264 LineTo(ix-m8, iy+m2);
1265 LineTo(ix-m2, iy+m8);
1266 LineTo(ix-m8, iy );
1267 LineTo(ix-m2, iy-m8);
1268 LineTo(ix-m8, iy-m2);
1269 LineTo(ix , iy-m8);
1270 LineTo(ix+m8, iy-m2);
1271 LineTo(ix+m2, iy-m8);
1272 LineTo(ix+m8, iy );
1273 LineTo(ix+m2, iy+m8);
1274 LineTo(ix+m8, iy+m2);
1275 LineTo(ix , iy+m8);
1276 PrintFast(2," h");
1277 } else if (ms == 48 ) {
1278 MoveTo(ix , iy+m8*1.005);
1279 LineTo(ix-m8, iy+m2);
1280 LineTo(ix-m2, iy+m8);
1281 LineTo(ix-m8, iy );
1282 LineTo(ix-m2, iy-m8);
1283 LineTo(ix-m8, iy-m2);
1284 LineTo(ix , iy-m8);
1285 LineTo(ix+m8, iy-m2);
1286 LineTo(ix+m2, iy-m8);
1287 LineTo(ix+m8, iy );
1288 LineTo(ix+m2, iy+m8);
1289 LineTo(ix+m8, iy+m2);
1290 LineTo(ix , iy+m8*0.995);
1291 LineTo(ix+m8*0.995, iy );
1292 LineTo(ix , iy-m8*0.995);
1293 LineTo(ix-m8*0.995, iy );
1294 LineTo(ix , iy+m8*0.995);
1295 PrintFast(2," h");
1296 } else if (ms == 49 ) {
1297 MoveTo(ix-m6, iy-m6*1.01);
1298 LineTo(ix-m6, iy-m2);
1299 LineTo(ix+m6, iy-m2);
1300 LineTo(ix+m6, iy-m6);
1301 LineTo(ix+m2, iy-m6);
1302 LineTo(ix+m2, iy+m6);
1303 LineTo(ix+m6, iy+m6);
1304 LineTo(ix+m6, iy+m2);
1305 LineTo(ix-m6, iy+m2);
1306 LineTo(ix-m6, iy+m6);
1307 LineTo(ix-m2, iy+m6);
1308 LineTo(ix-m2, iy-m6);
1309 LineTo(ix-m6, iy-m6*0.99);
1310 LineTo(ix-m6, iy+m6);
1311 LineTo(ix+m6, iy+m6);
1312 LineTo(ix+m6, iy-m6);
1313 MoveTo(ix-m6, iy-m6*1.01);
1314 PrintFast(2," h");
1315 } else {
1316 MoveTo(ix-1, iy);
1317 LineTo(ix , iy);
1318 }
1319 if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
1320 ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
1321 ms == 47 || ms == 48 || ms == 49) {
1322 PrintFast(2," f");
1323 } else {
1324 PrintFast(2," S");
1325 }
1326 }
1327
1330}
1331
1332////////////////////////////////////////////////////////////////////////////////
1333/// Draw a PolyLine
1334///
1335/// Draw a polyline through the points xw,yw.
1336///
1337/// - If nn=1 moves only to point xw,yw.
1338/// - If nn=0 the XW(1) and YW(1) are written in the PDF file
1339/// according to the current NT.
1340/// - If nn>0 the line is clipped as a line.
1341/// - If nn<0 the line is clipped as a fill area.
1342
1344{
1345 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1346 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1347 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1348 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1349 180, 90,135, 45,150, 30,120, 60,
1350 180, 90,135, 45,150, 30,120, 60};
1351 Int_t n = 0, fais = 0 , fasi = 0;
1352
1355
1356 if (nn > 0) {
1357 if (fLineWidth<=0) return;
1358 n = nn;
1362 }
1363 if (nn < 0) {
1364 n = -nn;
1365 SetLineStyle(1);
1366 SetLineWidth(1);
1368 fais = fFillStyle/1000;
1369 fasi = fFillStyle%1000;
1370 if (fais == 3 || fais == 2) {
1371 if (fasi > 100 && fasi <125) {
1372 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1375 return;
1376 }
1377 if (fasi > 0 && fasi < 26) {
1379 }
1380 }
1381 }
1382
1383 WriteReal(XtoPDF(xw[0]));
1384 WriteReal(YtoPDF(yw[0]));
1385 if (n <= 1) {
1386 if (n == 0) return;
1387 PrintFast(2," m");
1388 return;
1389 }
1390
1391 PrintFast(2," m");
1392
1393 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1394
1395 if (nn > 0) {
1396 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1397 PrintFast(2," S");
1398 } else {
1399 if (fais == 0) {PrintFast(2," s"); return;}
1400 if (fais == 3 || fais == 2) {
1401 if (fasi > 0 && fasi < 26) {
1402 PrintFast(3," f*");
1403 fRed = -1;
1404 fGreen = -1;
1405 fBlue = -1;
1406 fAlpha = -1.;
1407 }
1410 return;
1411 }
1412 PrintFast(3," f*");
1413 }
1414
1417}
1418
1419////////////////////////////////////////////////////////////////////////////////
1420/// Draw a PolyLine
1421///
1422/// Draw a polyline through the points xw,yw.
1423///
1424/// - If nn=1 moves only to point xw,yw.
1425/// - If nn=0 the xw(1) and YW(1) are written in the PDF file
1426/// according to the current NT.
1427/// - If nn>0 the line is clipped as a line.
1428/// - If nn<0 the line is clipped as a fill area.
1429
1431{
1432 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
1433 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
1434 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
1435 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
1436 180, 90,135, 45,150, 30,120, 60,
1437 180, 90,135, 45,150, 30,120, 60};
1438 Int_t n = 0, fais = 0, fasi = 0;
1439
1442
1443 if (nn > 0) {
1444 if (fLineWidth<=0) return;
1445 n = nn;
1449 }
1450 if (nn < 0) {
1451 n = -nn;
1452 SetLineStyle(1);
1453 SetLineWidth(1);
1455 fais = fFillStyle/1000;
1456 fasi = fFillStyle%1000;
1457 if (fais == 3 || fais == 2) {
1458 if (fasi > 100 && fasi <125) {
1459 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
1462 return;
1463 }
1464 if (fasi > 0 && fasi < 26) {
1466 }
1467 }
1468 }
1469
1470 WriteReal(XtoPDF(xw[0]));
1471 WriteReal(YtoPDF(yw[0]));
1472 if (n <= 1) {
1473 if (n == 0) return;
1474 PrintFast(2," m");
1475 return;
1476 }
1477
1478 PrintFast(2," m");
1479
1480 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
1481
1482 if (nn > 0) {
1483 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
1484 PrintFast(2," S");
1485 } else {
1486 if (fais == 0) {PrintFast(2," s"); return;}
1487 if (fais == 3 || fais == 2) {
1488 if (fasi > 0 && fasi < 26) {
1489 PrintFast(3," f*");
1490 fRed = -1;
1491 fGreen = -1;
1492 fBlue = -1;
1493 fAlpha = -1.;
1494 }
1497 return;
1498 }
1499 PrintFast(3," f*");
1500 }
1501
1504}
1505
1506////////////////////////////////////////////////////////////////////////////////
1507/// Close the current opened object
1508
1510{
1511 if (!fObjectIsOpen)
1512 Warning("EndObject", "No Object currently opened.");
1514
1515 PrintStr("endobj@");
1516}
1517
1518////////////////////////////////////////////////////////////////////////////////
1519/// Font encoding
1520
1522{
1523 static const char *sdtfonts[] = {
1524 "/Times-Italic" , "/Times-Bold" , "/Times-BoldItalic",
1525 "/Helvetica" , "/Helvetica-Oblique" , "/Helvetica-Bold" ,
1526 "/Helvetica-BoldOblique", "/Courier" , "/Courier-Oblique" ,
1527 "/Courier-Bold" , "/Courier-BoldOblique", "/Symbol" ,
1528 "/Times-Roman" , "/ZapfDingbats" , "/Symbol"};
1529
1530 for (Int_t i=0; i<kNumberOfFonts; i++) {
1532 PrintStr("<<@");
1533 PrintStr("/Type /Font@");
1534 PrintStr("/Subtype /Type1@");
1535 PrintStr("/Name /F");
1536 WriteInteger(i+1,false);
1537 PrintStr("@");
1538 PrintStr("/BaseFont ");
1539 PrintStr(sdtfonts[i]);
1540 PrintStr("@");
1541 if (i!=11 && i!=13 && i!=14) {
1542 PrintStr("/Encoding /WinAnsiEncoding");
1543 PrintStr("@");
1544 }
1545 PrintStr(">>@");
1546 EndObject();
1547 }
1548}
1549
1550////////////////////////////////////////////////////////////////////////////////
1551/// Draw a line to a new position
1552
1554{
1555 WriteReal(x);
1556 WriteReal(y);
1557 PrintFast(2," l");
1558}
1559
1560////////////////////////////////////////////////////////////////////////////////
1561/// Move to a new position
1562
1564{
1565 WriteReal(x);
1566 WriteReal(y);
1567 PrintFast(2," m");
1568}
1569
1570////////////////////////////////////////////////////////////////////////////////
1571/// Create a new object in the PDF file
1572
1574{
1575 if (fObjectIsOpen)
1576 Warning("NewObject", "An Object is already open.");
1578 if (n > (Int_t) fObjPos.size())
1579 fObjPos.resize(n, 0); // filling new elements with 0
1580 if (n > 0)
1581 fObjPos[n-1] = fNByte;
1582 else
1583 Error("NewObject", "Wrong id %d is specified.", n);
1584 WriteInteger(n, false);
1585 PrintStr(" 0 obj");
1586 PrintStr("@");
1587}
1588
1589////////////////////////////////////////////////////////////////////////////////
1590/// Start a new PDF page.
1591
1593{
1594 if (!fPageNotEmpty) return;
1595
1596 // Compute pad conversion coefficients
1597 if (gPad) {
1598 Double_t ww = gPad->GetWw();
1599 Double_t wh = gPad->GetWh();
1600 fYsize = fXsize*wh/ww;
1601 } else {
1602 fYsize = 27;
1603 }
1604
1605 fNbPage++;
1606 fA = 1.;
1607 fB = 0.;
1608 fC = 0.;
1609 fD = 1.;
1610 fE = 0.;
1611 fF = 0.;
1612
1613 if (fNbPage>1) {
1614 // Close the currently opened page
1616 PrintStr("endstream@");
1618 EndObject();
1620 WriteInteger(streamLength, false);
1621 PrintStr("@");
1622 EndObject();
1624 PrintStr("<<@");
1625 if (!strstr(GetTitle(),"PDF")) {
1626 PrintStr("/Title (");
1627 PrintStr(GetTitle());
1628 PrintStr(")@");
1629 } else {
1630 PrintStr("/Title (Page");
1632 PrintStr(")@");
1633 }
1634 PrintStr("/Dest [");
1636 PrintStr(" 0 R /XYZ null null 0]@");
1637 PrintStr("/Parent");
1639 PrintStr(" 0 R");
1640 PrintStr("@");
1641 PrintStr("/Next");
1643 PrintStr(" 0 R");
1644 PrintStr("@");
1645 if (fNbPage>2) {
1646 PrintStr("/Prev");
1648 PrintStr(" 0 R");
1649 PrintStr("@");
1650 }
1651 PrintStr(">>@");
1652 EndObject();
1654 fCurrentPage = fCurrentPage + fNbUrl + 4; // object number of the next page
1655 fNbUrl = 1;
1656 }
1657
1658 // Start a new page
1659 PrintStr("@");
1661 fPageObjects.push_back(fCurrentPage);
1662 PrintStr("<<@");
1663 PrintStr("/Type /Page@");
1664 PrintStr("@");
1665 PrintStr("/Parent");
1667 PrintStr(" 0 R");
1668 PrintStr("@");
1669
1670 Double_t xlow=0, ylow=0, xup=1, yup=1;
1671 if (gPad) {
1672 xlow = gPad->GetAbsXlowNDC();
1673 xup = xlow + gPad->GetAbsWNDC();
1674 ylow = gPad->GetAbsYlowNDC();
1675 yup = ylow + gPad->GetAbsHNDC();
1676 }
1677
1678 PrintStr("/MediaBox [");
1680 switch (fPageFormat) {
1681 case 100 :
1682 width = 8.5*2.54;
1683 height = 11.*2.54;
1684 break;
1685 case 200 :
1686 width = 8.5*2.54;
1687 height = 14.*2.54;
1688 break;
1689 case 300 :
1690 width = 11.*2.54;
1691 height = 17.*2.54;
1692 break;
1693 default :
1696 };
1697 WriteReal(CMtoPDF(fXsize*xlow));
1698 WriteReal(CMtoPDF(fYsize*ylow));
1701 PrintStr("]");
1702 PrintStr("@");
1703
1704 Double_t xmargin = CMtoPDF(0.7);
1705 Double_t ymargin = 0;
1706 if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
1707 if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
1708
1709 PrintStr("/CropBox [");
1710 if (fPageOrientation == 1) {
1715 }
1716 if (fPageOrientation == 2) {
1721 }
1722 PrintStr("]");
1723 PrintStr("@");
1724
1725 if (fPageOrientation == 1) PrintStr("/Rotate 0@");
1726 if (fPageOrientation == 2) PrintStr("/Rotate 90@");
1727
1728 PrintStr("/Resources");
1730 PrintStr(" 0 R");
1731 PrintStr("@");
1732
1733 PrintStr("/Contents");
1735 PrintStr(" 0 R@");
1736
1737 PrintStr("/Annots");
1739 PrintStr(" 0 R");
1740 PrintStr("@");
1741
1742 PrintStr(">>@");
1743 EndObject();
1744
1746 PrintStr("<<@");
1747 PrintStr("/Length");
1749 PrintStr(" 0 R@");
1750 PrintStr("/Filter [/FlateDecode]@");
1751 PrintStr(">>@");
1752 PrintStr("stream@");
1754 fCompress = kTRUE;
1755
1756 // Force the line width definition next time TPDF::SetLineWidth will be called.
1757 fLineWidth = -1;
1758
1759 // Force the color definition next time TPDF::SetColor will be called.
1760 fRed = -1;
1761 fGreen = -1;
1762 fBlue = -1;
1763 fAlpha = -1.;
1764
1765 if (fPageOrientation == 2) {
1768 }
1769
1770 WriteCM(1, 0, 0, 1, xmargin, ymargin);
1771 if (fPageOrientation == 2)
1772 WriteCM(0, 1, -1, 0, 0, 0);
1773 if (fgLineJoin) {
1775 PrintFast(2," j");
1776 }
1777 if (fgLineCap) {
1779 PrintFast(2," J");
1780 }
1781}
1782
1783////////////////////////////////////////////////////////////////////////////////
1784/// Deactivate an already open PDF file
1785
1787{
1788 gVirtualPS = nullptr;
1789}
1790
1791////////////////////////////////////////////////////////////////////////////////
1792/// Activate an already open PDF file
1793
1795{
1796 // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
1797 // has no "workstation type".
1798
1799 if (!fType) {
1800 Error("On", "no PDF file open");
1801 Off();
1802 return;
1803 }
1804 gVirtualPS = this;
1805}
1806
1807////////////////////////////////////////////////////////////////////////////////
1808/// Open a PDF file
1809
1810void TPDF::Open(const char *fname, Int_t wtype)
1811{
1812 if (fStream) {
1813 Warning("Open", "PDF file already open");
1814 return;
1815 }
1816
1817 fLenBuffer = 0;
1818 fRed = -1;
1819 fGreen = -1;
1820 fBlue = -1;
1821 fAlpha = -1.;
1822 fType = abs(wtype);
1828 if (gPad) {
1829 Double_t ww = gPad->GetWw();
1830 Double_t wh = gPad->GetWh();
1831 if (fType == 113) {
1832 ww *= gPad->GetWNDC();
1833 wh *= gPad->GetHNDC();
1834 }
1835 Double_t ratio = wh/ww;
1836 xrange = fXsize;
1837 yrange = fXsize*ratio;
1838 if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
1840 }
1841
1842 // Open OS file
1843 if (!OpenStream(fname, kTRUE)) {
1844 Error("Open", "Cannot open file: %s", fname);
1845 return;
1846 }
1847
1848 gVirtualPS = this;
1849
1850 ClearBuffer();
1851
1852 // The page orientation is last digit of PDF workstation type
1853 // orientation = 1 for portrait
1854 // orientation = 2 for landscape
1857 Error("Open", "Invalid page orientation %d", fPageOrientation);
1858 return;
1859 }
1860
1861 // format = 0-99 is the European page format (A4,A3 ...)
1862 // format = 100 is the US format 8.5x11.0 inch
1863 // format = 200 is the US format 8.5x14.0 inch
1864 // format = 300 is the US format 11.0x17.0 inch
1865 fPageFormat = fType/1000;
1866 if (fPageFormat == 0) fPageFormat = 4;
1867 if (fPageFormat == 99) fPageFormat = 0;
1868
1869 fRange = kFALSE;
1870
1871 // Set a default range
1873
1874 fObjPos.clear();
1875 fNbPage = 0;
1876 fUrl = kFALSE;
1877
1878 PrintStr("%PDF-1.4@");
1879 PrintStr("%\342\343\317\323");
1880 PrintStr("@");
1881
1883 PrintStr("<<@");
1884 PrintStr("/Type /Catalog@");
1885 PrintStr("/Pages");
1887 PrintStr(" 0 R@");
1888 PrintStr("/Outlines");
1890 PrintStr(" 0 R@");
1891 PrintStr("/PageMode /UseOutlines@");
1892 PrintStr(">>@");
1893 EndObject();
1894
1896 PrintStr("<<@");
1897 PrintStr("/Creator (ROOT Version ");
1898 PrintStr(gROOT->GetVersion());
1899 PrintStr(")");
1900 PrintStr("@");
1901 PrintStr("/CreationDate (");
1902 TDatime t;
1903 Int_t toff = t.Convert(kFALSE) - t.Convert(kTRUE); // time zone and dst offset
1904 toff = toff/60;
1905 char str[24];
1906 snprintf(str,24,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%c%2.2d'%2.2d'",
1907 t.GetYear() , t.GetMonth(),
1908 t.GetDay() , t.GetHour(),
1909 t.GetMinute(), t.GetSecond(),
1910 toff < 0 ? '-' : '+',
1911 // TMath::Abs(toff/60), TMath::Abs(toff%60)); // format-truncation warning
1912 TMath::Abs(toff/60) & 0x3F, TMath::Abs(toff%60) & 0x3F); // now 2 digits
1913 PrintStr(str);
1914 PrintStr(")");
1915 PrintStr("@");
1916 PrintStr("/ModDate (");
1917 PrintStr(str);
1918 PrintStr(")");
1919 PrintStr("@");
1920 PrintStr("/Title (");
1921 if (strlen(GetName())<=80) PrintStr(GetName());
1922 PrintStr(")");
1923 PrintStr("@");
1924 PrintStr("/Keywords (ROOT)@");
1925 PrintStr(">>@");
1926 EndObject();
1927
1929 PrintStr("<<@");
1930 PrintStr("/ProcSet [/PDF /Text]@");
1931
1932 PrintStr("/Font@");
1933 PrintStr("<<@");
1934 for (Int_t i=0; i<kNumberOfFonts; i++) {
1935 PrintStr(" /F");
1936 WriteInteger(i+1,false);
1938 PrintStr(" 0 R");
1939 }
1940 PrintStr("@");
1941 PrintStr(">>@");
1942
1943 PrintStr("/ExtGState");
1945 PrintStr(" 0 R @");
1946 if (!fAlphas.empty()) fAlphas.clear();
1947
1948 PrintStr("/ColorSpace << /Cs8");
1950 PrintStr(" 0 R >>");
1951 PrintStr("@");
1952 PrintStr("/Pattern");
1954 PrintStr(" 0 R");
1955 PrintStr("@");
1956 PrintStr("/XObject");
1958 PrintStr(" 0 R");
1959 PrintStr("@");
1960 PrintStr(">>@");
1961 EndObject();
1962
1963 FontEncode();
1964 PatternEncode();
1965
1966 NewPage();
1968}
1969
1970
1971////////////////////////////////////////////////////////////////////////////////
1972/// Ensure that required space in the buffer is available
1973
1975{
1976 if (required_size >= fSizBuffer) {
1977 // increase buffer size by integer factor, normally 2
1978 Int_t mult = (required_size + 1) / fSizBuffer + 1;
1981 }
1982}
1983
1984////////////////////////////////////////////////////////////////////////////////
1985/// Output the string str in the output buffer
1986
1987void TPDF::PrintStr(const char *str)
1988{
1989 Int_t len = strlen(str);
1990 if (len == 0) return;
1992
1993 if (fCompress) {
1995 strcpy(fBuffer + fLenBuffer, str);
1996 fLenBuffer += len;
1997 } else {
1999 }
2000}
2001
2002////////////////////////////////////////////////////////////////////////////////
2003/// Fast version of Print
2004
2005void TPDF::PrintFast(Int_t len, const char *str)
2006{
2008 if (fCompress) {
2010 strcpy(fBuffer + fLenBuffer, str);
2011 fLenBuffer += len;
2012 } else {
2014 }
2015}
2016
2017////////////////////////////////////////////////////////////////////////////////
2018/// Set the range for the paper in centimetres
2019
2021{
2022 fXsize = xsize;
2023 fYsize = ysize;
2024 fRange = kTRUE;
2025}
2026
2027////////////////////////////////////////////////////////////////////////////////
2028/// Set the alpha channel value.
2029
2031{
2032 if (a == fAlpha) return;
2033 fAlpha = a;
2034 if (fAlpha <= 0.000001) fAlpha = 0;
2035
2036 Bool_t known = kFALSE;
2037 for (int i=0; i<(int)fAlphas.size(); i++) {
2038 if (fAlpha == fAlphas[i]) {
2039 known = kTRUE;
2040 break;
2041 }
2042 }
2043 if (!known) fAlphas.push_back(fAlpha);
2044 PrintStr(TString::Format(" /ca%3.2f gs /CA%3.2f gs",fAlpha,fAlpha));
2045}
2046
2047////////////////////////////////////////////////////////////////////////////////
2048/// Set color with its color index.
2049
2051{
2052 if (color < 0) color = 0;
2053 TColor *col = gROOT->GetColor(color);
2054
2055 if (col) {
2056 SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
2057 SetAlpha(col->GetAlpha());
2058 } else {
2059 SetColor(1., 1., 1.);
2060 SetAlpha(1.);
2061 }
2062}
2063
2064////////////////////////////////////////////////////////////////////////////////
2065/// Set color with its R G B components:
2066///
2067/// - r: % of red in [0,1]
2068/// - g: % of green in [0,1]
2069/// - b: % of blue in [0,1]
2070
2072{
2073 if (r == fRed && g == fGreen && b == fBlue) return;
2074
2075 fRed = r;
2076 fGreen = g;
2077 fBlue = b;
2078 if (fRed <= 0.000001) fRed = 0;
2079 if (fGreen <= 0.000001) fGreen = 0;
2080 if (fBlue <= 0.000001) fBlue = 0;
2081
2082 if (gStyle->GetColorModelPS()) {
2085 if (colBlack==1) {
2086 colCyan = 0;
2087 colMagenta = 0;
2088 colYellow = 0;
2089 } else {
2090 colCyan = (1-fRed-colBlack)/(1-colBlack);
2092 colYellow = (1-fBlue-colBlack)/(1-colBlack);
2093 }
2094 if (colCyan <= 0.000001) colCyan = 0;
2095 if (colMagenta <= 0.000001) colMagenta = 0;
2096 if (colYellow <= 0.000001) colYellow = 0;
2097 if (colBlack <= 0.000001) colBlack = 0;
2102 PrintFast(2," K");
2107 PrintFast(2," k");
2108 } else {
2109 WriteReal(fRed);
2112 PrintFast(3," RG");
2113 WriteReal(fRed);
2116 PrintFast(3," rg");
2117 }
2118}
2119
2120////////////////////////////////////////////////////////////////////////////////
2121/// Set color index for fill areas
2122
2127
2128////////////////////////////////////////////////////////////////////////////////
2129/// Set the fill patterns (1 to 25) for fill areas
2130
2132{
2133 char cpat[10];
2134 TColor *col = gROOT->GetColor(color);
2135 if (!col) return;
2136 PrintStr(" /Cs8 cs");
2137 Double_t colRed = col->GetRed();
2138 Double_t colGreen = col->GetGreen();
2139 Double_t colBlue = col->GetBlue();
2140 if (gStyle->GetColorModelPS()) {
2142 if (colBlack==1) {
2143 WriteReal(0);
2144 WriteReal(0);
2145 WriteReal(0);
2147 } else {
2155 }
2156 } else {
2160 }
2161
2162 if (fPageOrientation == 2) {
2163 switch (ipat) {
2164 case 4: ipat = 5; break;
2165 case 5: ipat = 4; break;
2166 case 6: ipat = 7; break;
2167 case 7: ipat = 6; break;
2168 case 17: ipat = 18; break;
2169 case 18: ipat = 17; break;
2170 case 20: ipat = 16; break;
2171 case 16: ipat = 20; break;
2172 case 21: ipat = 22; break;
2173 case 22: ipat = 21; break;
2174 }
2175 }
2176 snprintf(cpat,10," /P%2.2d scn", ipat);
2177 PrintStr(cpat);
2178}
2179
2180////////////////////////////////////////////////////////////////////////////////
2181/// Set color index for lines
2182
2187
2188////////////////////////////////////////////////////////////////////////////////
2189/// Set the value of the global parameter TPDF::fgLineJoin.
2190/// This parameter determines the appearance of joining lines in a PDF
2191/// output.
2192/// It takes one argument which may be:
2193/// - 0 (miter join)
2194/// - 1 (round join)
2195/// - 2 (bevel join)
2196/// The default value is 0 (miter join).
2197///
2198/// \image html postscript_1.png
2199///
2200/// To change the line join behaviour just do:
2201/// ~~~ {.cpp}
2202/// gStyle->SetJoinLinePS(2); // Set the PDF line join to bevel.
2203/// ~~~
2204
2206{
2208 if (fgLineJoin<0) fgLineJoin=0;
2209 if (fgLineJoin>2) fgLineJoin=2;
2210}
2211
2212////////////////////////////////////////////////////////////////////////////////
2213/// Set the value of the global parameter TPDF::fgLineCap.
2214/// This parameter determines the appearance of line caps in a PDF
2215/// output.
2216/// It takes one argument which may be:
2217/// - 0 (butt caps)
2218/// - 1 (round caps)
2219/// - 2 (projecting caps)
2220/// The default value is 0 (butt caps).
2221///
2222/// \image html postscript_2.png
2223///
2224/// To change the line cap behaviour just do:
2225/// ~~~ {.cpp}
2226/// gStyle->SetCapLinePS(2); // Set the PDF line cap to projecting.
2227/// ~~~
2228
2230{
2232 if (fgLineCap<0) fgLineCap=0;
2233 if (fgLineCap>2) fgLineCap=2;
2234}
2235
2236////////////////////////////////////////////////////////////////////////////////
2237/// Change the line style
2238///
2239/// - linestyle = 2 dashed
2240/// - linestyle = 3 dotted
2241/// - linestyle = 4 dash-dotted
2242/// - linestyle = else solid (1 in is used most of the time)
2243
2245{
2246 if ( linestyle == fLineStyle) return;
2249 PrintFast(2," [");
2250 TObjArray *tokens = st.Tokenize(" ");
2251 for (Int_t j = 0; j<tokens->GetEntries(); j++) {
2252 Int_t it;
2253 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
2254 WriteInteger((Int_t)(it/4));
2255 }
2256 delete tokens;
2257 PrintFast(5,"] 0 d");
2258}
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// Change the line width
2262
2264{
2265 if (linewidth == fLineWidth) return;
2267 if (fLineWidth!=0) {
2269 PrintFast(2," w");
2270 }
2271}
2272
2273////////////////////////////////////////////////////////////////////////////////
2274/// Set color index for markers.
2275
2280
2281////////////////////////////////////////////////////////////////////////////////
2282/// Set color index for text
2283
2288
2289////////////////////////////////////////////////////////////////////////////////
2290/// Draw text
2291///
2292/// - xx: x position of the text
2293/// - yy: y position of the text
2294/// - chars: text to be drawn
2295
2297{
2298 if (fTextSize <= 0) return;
2299
2300 const Double_t kDEGRAD = TMath::Pi()/180.;
2301 char str[8];
2302 Double_t x = xx;
2303 Double_t y = yy;
2304
2305 // Font and text size
2306 Int_t font = abs(fTextFont)/10;
2307 if (font > kNumberOfFonts || font < 1) font = 1;
2308
2309 Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
2310 Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
2312 if (wh < hh) {
2313 tsize = fTextSize*wh;
2314 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2315 ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
2316 } else {
2317 tsize = fTextSize*hh;
2318 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
2319 ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
2320 }
2321 Double_t fontsize = 72*(ftsize)/2.54;
2322 if (fontsize <= 0) return;
2323
2324 // Text color
2326
2327 // Clipping
2328 PrintStr(" q");
2329 Double_t x1 = XtoPDF(gPad->GetX1());
2330 Double_t x2 = XtoPDF(gPad->GetX2());
2331 Double_t y1 = YtoPDF(gPad->GetY1());
2332 Double_t y2 = YtoPDF(gPad->GetY2());
2333 WriteReal(x1);
2334 WriteReal(y1);
2335 WriteReal(x2 - x1);
2336 WriteReal(y2 - y1);
2337 PrintStr(" re W n");
2338
2339 // Start the text
2340 if (!fCompress) PrintStr("@");
2341
2342 // Text alignment
2343 Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
2344 Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
2345 Int_t txalh = fTextAlign/10;
2346 if (txalh < 1) txalh = 1; else if (txalh > 3) txalh = 3;
2347 Int_t txalv = fTextAlign%10;
2348 if (txalv < 1) txalv = 1; else if (txalv > 3) txalv = 3;
2349 if (txalv == 3) {
2352 } else if (txalv == 2) {
2355 }
2356
2357 if (txalh > 1) {
2358 TText t;
2359 UInt_t w=0, h;
2362 t.GetTextExtent(w, h, chars);
2363 Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
2364 Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
2365 if (txalh == 2) {
2368 }
2369 if (txalh == 3) {
2372 }
2373 }
2374
2375 // Text angle
2376 Double_t a, b, c, d, e, f;
2377 if (fTextAngle == 0) {
2378 a = 1;
2379 b = 0;
2380 c = 0;
2381 d = 1;
2382 e = XtoPDF(x);
2383 f = YtoPDF(y);
2384 } else if (fTextAngle == 90) {
2385 a = 0;
2386 b = 1;
2387 c = -1;
2388 d = 0;
2389 e = XtoPDF(x);
2390 f = YtoPDF(y);
2391 } else if (fTextAngle == 270) {
2392 a = 0;
2393 b = -1;
2394 c = 1;
2395 d = 0;
2396 e = XtoPDF(x);
2397 f = YtoPDF(y);
2398 } else {
2403 e = XtoPDF(x);
2404 f = YtoPDF(y);
2405 }
2406 WriteCM(a, b, c, d, e, f, kFALSE);
2407
2408 // Symbol Italic tan(15) = .26794
2409 if (font == 15)
2410 WriteCM(1, 0, 0.26794, 1, 0, 0, kFALSE);
2411
2412 if (fUrl)
2413 ComputeRect(chars, fontsize, a, b, c, d, e, f);
2414
2415 PrintStr(" BT");
2416
2417 snprintf(str,8," /F%d",font);
2418 PrintStr(str);
2420 PrintStr(" Tf");
2421
2422 const Int_t len=strlen(chars);
2423
2424 // Calculate the individual character placements.
2425 // Otherwise, if a string is printed in one line the kerning is not
2426 // performed. In order to measure the precise character positions we need to
2427 // trick FreeType into rendering high-resolution characters otherwise it will
2428 // stick to the screen pixel grid which is far worse than we can achieve on
2429 // print.
2430 const Float_t scale = 16.0;
2431 // Save current text attributes.
2433 saveAttText.TAttText::operator=(*this);
2434 TText t;
2437 UInt_t wa1=0, wa0=0;
2440 t.TAttText::Modify();
2442 if (wa0-wa1 != 0) kerning = kTRUE;
2443 else kerning = kFALSE;
2444 Int_t *charDeltas = nullptr;
2445 if (kerning) {
2446 charDeltas = new Int_t[len];
2447 for (Int_t i = 0;i < len;i++) {
2448 UInt_t ww=0;
2449 t.GetTextAdvance(ww, chars + i);
2450 charDeltas[i] = wa1 - ww;
2451 }
2452 for (Int_t i = len - 1;i > 0;i--) {
2453 charDeltas[i] -= charDeltas[i-1];
2454 }
2455 char tmp[2];
2456 tmp[1] = 0;
2457 for (Int_t i = 1;i < len;i++) {
2458 tmp[0] = chars[i-1];
2459 UInt_t width=0;
2460 t.GetTextAdvance(width, &tmp[0], kFALSE);
2461 Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
2462 wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
2463 charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
2464 }
2465 }
2466 // Restore text attributes.
2467 saveAttText.TAttText::Modify();
2468
2469 // Output the text. Escape some characters if needed
2470 if (kerning) PrintStr(" [");
2471 else PrintStr(" (");
2472
2473 for (Int_t i=0; i<len;i++) {
2474 if (chars[i]!='\n') {
2475 if (kerning) PrintStr("(");
2476 if (chars[i]=='(' || chars[i]==')') {
2477 snprintf(str,8,"\\%c",chars[i]);
2478 } else {
2479 snprintf(str,8,"%c",chars[i]);
2480 }
2481 PrintStr(str);
2482 if (kerning) {
2483 PrintStr(") ");
2484 if (i < len-1) {
2486 }
2487 }
2488 }
2489 }
2490
2491 if (kerning) PrintStr("] TJ ET Q");
2492 else PrintStr(") Tj ET Q");
2493 if (!fCompress) PrintStr("@");
2494 if (kerning) delete [] charDeltas;
2495}
2496
2497////////////////////////////////////////////////////////////////////////////////
2498/// Write a string of characters
2499///
2500/// This method writes the string chars into a PDF file
2501/// at position xx,yy in world coordinates.
2502
2503void TPDF::Text(Double_t, Double_t, const wchar_t *)
2504{
2505}
2506
2507////////////////////////////////////////////////////////////////////////////////
2508/// Draw text with URL. Same as Text.
2509///
2510
2511void TPDF::TextUrl(Double_t x, Double_t y, const char *chars, const char *url)
2512{
2513 fUrl = kTRUE;
2514 Text(x, y, chars);
2515 fNbUrl++;
2516 fUrls.push_back(url);
2517 fUrl = kFALSE;
2518}
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// Write a string of characters in NDC
2522
2524{
2525 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2526 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2527 Text(x, y, chars);
2528}
2529
2530////////////////////////////////////////////////////////////////////////////////
2531/// Write a string of characters in NDC
2532
2533void TPDF::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2534{
2535 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2536 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2537 Text(x, y, chars);
2538}
2539
2540////////////////////////////////////////////////////////////////////////////////
2541/// Convert U from NDC coordinate to PDF
2542
2544{
2545 Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2546 return 72*cm/2.54;
2547}
2548
2549////////////////////////////////////////////////////////////////////////////////
2550/// Convert V from NDC coordinate to PDF
2551
2553{
2554 Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2555 return 72*cm/2.54;
2556}
2557
2558////////////////////////////////////////////////////////////////////////////////
2559/// Convert X from world coordinate to PDF
2560
2562{
2563 Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2564 return UtoPDF(u);
2565}
2566
2567////////////////////////////////////////////////////////////////////////////////
2568/// Convert Y from world coordinate to PDF
2569
2571{
2572 Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2573 return VtoPDF(v);
2574}
2575
2576////////////////////////////////////////////////////////////////////////////////
2577/// Write the buffer in a compressed way
2578
2580{
2581 z_stream stream;
2582 int err;
2583 char *out = new char[2*fLenBuffer];
2584
2585 stream.next_in = (Bytef*)fBuffer;
2586 stream.avail_in = (uInt)fLenBuffer;
2587 stream.next_out = (Bytef*)out;
2588 stream.avail_out = (uInt)2*fLenBuffer;
2589 stream.zalloc = (alloc_func)nullptr;
2590 stream.zfree = (free_func)nullptr;
2591 stream.opaque = (voidpf)nullptr;
2592
2593 err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2594 if (err != Z_OK) {
2595 Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
2596 delete [] out;
2597 return;
2598 }
2599
2600 err = deflate(&stream, Z_FINISH);
2601 if (err != Z_STREAM_END) {
2602 deflateEnd(&stream);
2603 Error("WriteCompressedBuffer", "error in deflate (zlib)");
2604 delete [] out;
2605 return;
2606 }
2607
2608 err = deflateEnd(&stream);
2609 if (err != Z_OK) {
2610 Error("WriteCompressedBuffer", "error in deflateEnd (zlib)");
2611 }
2612
2613 fStream->write(out, stream.total_out);
2614
2615 fNByte += stream.total_out;
2616 fStream->write("\n",1); fNByte++;
2617 fLenBuffer = 0;
2618 delete [] out;
2619 fCompress = kFALSE;
2620}
2621
2622////////////////////////////////////////////////////////////////////////////////
2623/// Write a Real number to the file.
2624/// This method overwrites TVirtualPS::WriteReal. Some PDF reader like
2625/// Acrobat do not work when a PDF file contains reals with exponent. This
2626/// method writes the real number "z" using the format "%f" instead of the
2627/// format "%g" when writing it with "%g" generates a number with exponent.
2628
2630{
2631 char str[15];
2632 if (space) {
2633 snprintf(str,15," %g", z);
2634 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
2635 } else {
2636 snprintf(str,15,"%g", z);
2637 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15,"%10.8f", z);
2638 }
2639 PrintStr(str);
2640}
2641
2642////////////////////////////////////////////////////////////////////////////////
2643/// Patterns encoding
2644
2646{
2648
2650 if (gStyle->GetColorModelPS()) {
2651 PrintStr("[/Pattern /DeviceCMYK]@");
2652 } else {
2653 PrintStr("[/Pattern /DeviceRGB]@");
2654 }
2655 EndObject();
2657 PrintStr("<</ProcSet[/PDF]>>@");
2658 EndObject();
2659
2661 PrintStr("<<@");
2662 PrintStr(" /P01");
2664 PrintStr(" 0 R");
2665 PrintStr(" /P02");
2667 PrintStr(" 0 R");
2668 PrintStr(" /P03");
2670 PrintStr(" 0 R");
2671 PrintStr(" /P04");
2673 PrintStr(" 0 R");
2674 PrintStr(" /P05");
2676 PrintStr(" 0 R");
2677 PrintStr(" /P06");
2679 PrintStr(" 0 R");
2680 PrintStr(" /P07");
2682 PrintStr(" 0 R");
2683 PrintStr(" /P08");
2685 PrintStr(" 0 R");
2686 PrintStr(" /P09");
2688 PrintStr(" 0 R");
2689 PrintStr(" /P10");
2691 PrintStr(" 0 R");
2692 PrintStr(" /P11");
2694 PrintStr(" 0 R");
2695 PrintStr(" /P12");
2697 PrintStr(" 0 R");
2698 PrintStr(" /P13");
2700 PrintStr(" 0 R");
2701 PrintStr(" /P14");
2703 PrintStr(" 0 R");
2704 PrintStr(" /P15");
2706 PrintStr(" 0 R");
2707 PrintStr(" /P16");
2709 PrintStr(" 0 R");
2710 PrintStr(" /P17");
2712 PrintStr(" 0 R");
2713 PrintStr(" /P18");
2715 PrintStr(" 0 R");
2716 PrintStr(" /P19");
2718 PrintStr(" 0 R");
2719 PrintStr(" /P20");
2721 PrintStr(" 0 R");
2722 PrintStr(" /P21");
2724 PrintStr(" 0 R");
2725 PrintStr(" /P22");
2727 PrintStr(" 0 R");
2728 PrintStr(" /P23");
2730 PrintStr(" 0 R");
2731 PrintStr(" /P24");
2733 PrintStr(" 0 R");
2734 PrintStr(" /P25");
2736 PrintStr(" 0 R@");
2737 PrintStr(">>@");
2738 EndObject();
2739
2741
2742 // P01
2744 PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
2746 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 98 4]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
2747 PrintStr("@");
2748 fStream->write("stream",6); fNByte += 6;
2749 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);
2750 fNByte += 93;
2751 PrintStr("endstream@");
2752 EndObject();
2753
2754 // P02
2756 PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
2758 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 4]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
2759 PrintStr("@");
2760 fStream->write("stream",6); fNByte += 6;
2761 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);
2762 fNByte += 94;
2763 PrintStr("endstream@");
2764 EndObject();
2765
2766 // P03
2768 PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
2770 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 16]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
2771 PrintStr("@");
2772 fStream->write("stream",6); fNByte += 6;
2773 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);
2774 fNByte += 95;
2775 PrintStr("endstream@");
2776 EndObject();
2777
2778 // P04
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 63/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\020\035k\240\220\002V\231\313\005S\233\303\025\314\025\310\005\020`\0\344\270\r\274\n", 65);
2786 fNByte += 65;
2787 PrintStr("endstream@");
2788 EndObject();
2789
2790 // P05
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 66/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\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);
2798 fNByte += 68;
2799 PrintStr("endstream@");
2800 EndObject();
2801
2802 // P06
2804 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2806 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2807 PrintStr("@");
2808 fStream->write("stream",6); fNByte += 6;
2809 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);
2810 fNByte += 68;
2811 PrintStr("endstream@");
2812 EndObject();
2813
2814 // P07
2816 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2818 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
2819 PrintStr("@");
2820 fStream->write("stream",6); fNByte += 6;
2821 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);
2822 fNByte += 70;
2823 PrintStr("endstream@");
2824 EndObject();
2825
2826 // P08
2828 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2830 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
2831 PrintStr("@");
2832 fStream->write("stream",6); fNByte += 6;
2833 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);
2834 fNByte += 141;
2835 PrintStr("endstream@");
2836 EndObject();
2837
2838 // P09
2840 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2842 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
2843 PrintStr("@");
2844 fStream->write("stream",6); fNByte += 6;
2845 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);
2846 fNByte += 110;
2847 PrintStr("endstream@");
2848 EndObject();
2849
2850 // P10
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 93/Filter/FlateDecode>>");
2855 PrintStr("@");
2856 fStream->write("stream",6); fNByte += 6;
2857 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);
2858 fNByte += 95;
2859 PrintStr("endstream@");
2860 EndObject();
2861
2862 // P11
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 164/Filter/FlateDecode>>");
2867 PrintStr("@");
2868 fStream->write("stream",6); fNByte += 6;
2869 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);
2870 fNByte += 166;
2871 PrintStr("endstream@");
2872 EndObject();
2873
2874 // P12
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 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
2879 PrintStr("@");
2880 fStream->write("stream",6); fNByte += 6;
2881 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);
2882 fNByte += 228;
2883 PrintStr("endstream@");
2884 EndObject();
2885
2886 // P13
2888 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2890 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2891 PrintStr("@");
2892 fStream->write("stream",6); fNByte += 6;
2893 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);
2894 fNByte += 71;
2895 PrintStr("endstream@");
2896 EndObject();
2897
2898 // P14
2900 PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
2902 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
2903 PrintStr("@");
2904 fStream->write("stream",6); fNByte += 6;
2905 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);
2906 fNByte += 116;
2907 PrintStr("endstream@");
2908 EndObject();
2909
2910 // P15
2912 PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
2914 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
2915 PrintStr("@");
2916 fStream->write("stream",6); fNByte += 6;
2917 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);
2918 fNByte += 220;
2919 PrintStr("endstream@");
2920 EndObject();
2921
2922 // P16
2924 PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
2926 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
2927 PrintStr("@");
2928 fStream->write("stream",6); fNByte += 6;
2929 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);
2930 fNByte += 125;
2931 PrintStr("endstream@");
2932 EndObject();
2933
2934 // P17
2936 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2938 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2939 PrintStr("@");
2940 fStream->write("stream",6); fNByte += 6;
2941 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);
2942 fNByte += 68;
2943 PrintStr("endstream@");
2944 EndObject();
2945
2946 // P18
2948 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2950 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2951 PrintStr("@");
2952 fStream->write("stream",6); fNByte += 6;
2953 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);
2954 fNByte += 71;
2955 PrintStr("endstream@");
2956 EndObject();
2957
2958 // P19
2960 PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
2962 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
2963 PrintStr("@");
2964 fStream->write("stream",6); fNByte += 6;
2965 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);
2966 fNByte += 151;
2967 PrintStr("endstream@");
2968 EndObject();
2969
2970 // P20
2972 PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
2974 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
2975 PrintStr("@");
2976 fStream->write("stream",6); fNByte += 6;
2977 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);
2978 fNByte += 124;
2979 PrintStr("endstream@");
2980 EndObject();
2981
2982 // P21
2984 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2986 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
2987 PrintStr("@");
2988 fStream->write("stream",6); fNByte += 6;
2989 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);
2990 fNByte += 119;
2991 PrintStr("endstream@");
2992 EndObject();
2993
2994 // P22
2996 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2998 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
2999 PrintStr("@");
3000 fStream->write("stream",6); fNByte += 6;
3001 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);
3002 fNByte += 120;
3003 PrintStr("endstream@");
3004 EndObject();
3005
3006 // P23
3008 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
3010 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
3011 PrintStr("@");
3012 fStream->write("stream",6); fNByte += 6;
3013 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);
3014 fNByte += 171;
3015 PrintStr("endstream@");
3016 EndObject();
3017
3018 // P24
3020 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
3022 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
3023 PrintStr("@");
3024 fStream->write("stream",6); fNByte += 6;
3025 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);
3026 fNByte += 282;
3027 PrintStr("endstream@");
3028 EndObject();
3029
3030 // P25
3032 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
3034 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
3035 PrintStr("@");
3036 fStream->write("stream",6); fNByte += 6;
3037 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);
3038 fNByte += 56;
3039 PrintStr("endstream@");
3040 EndObject();
3041}
3042
3043////////////////////////////////////////////////////////////////////////////////
3044/// Write and Accumulate (if `acc` is true) the Current Transformation Matrix (CTM)
3045///
3046/// The Current Transformation Matrix (CTM, not CMT) is defined by the six parameters
3047/// `a` `b` `c` `d` `e` `f` passed to the PDF `cm` operator (see the PDF Reference Guide
3048/// page 156 [1] for details).
3049///
3050/// To correctly define the \Rect fields of the Annots created for each #url, one must keep
3051/// track of the current CTM and apply it to the last transformation matrix used for the
3052/// text (for example rotations).
3053///
3054/// [1] https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf
3055
3057{
3058 WriteReal(a);
3059 WriteReal(b);
3060 WriteReal(c);
3061 WriteReal(d);
3062 WriteReal(e);
3063 WriteReal(f);
3064 PrintStr(" cm");
3065
3066 // accumulate in CTM ---
3067 if (acc) {
3068 Double_t na, nb, nc, nd, ne, nf;
3069 na = fA * a + fC * b;
3070 nb = fB * a + fD * b;
3071 nc = fA * c + fC * d;
3072 nd = fB * c + fD * d;
3073 ne = fA * e + fC * f + fE;
3074 nf = fB * e + fD * f + fF;
3075 fA = na;
3076 fB = nb;
3077 fC = nc;
3078 fD = nd;
3079 fE = ne;
3080 fF = nf;
3081 }
3082}
3083
3084////////////////////////////////////////////////////////////////////////////////
3085/// Write the annotation objects containing the URLs
3086
3088{
3089 int i;
3091 PrintStr("@");
3092 PrintStr("[");
3093 for (i = 0; i < fNbUrl - 1; i++) {
3094 WriteInteger(fCurrentPage + 5 + i);
3095 PrintStr(" 0 R");
3096 }
3097 PrintStr(" ]@");
3098 EndObject();
3099 for (i = 0; i < fNbUrl - 1; i++) {
3100 NewObject(fCurrentPage + 5 + i);
3101 PrintStr("<<@");
3102 PrintStr("/Type /Annot@");
3103 PrintStr("/Subtype /Link@");
3104 PrintStr("/Rect [");
3106 WriteReal(fRectY1[i]);
3107 WriteReal(fRectX2[i]);
3108 WriteReal(fRectY2[i]);
3109 PrintStr("]@");
3110 PrintStr("/Border [0 0 0]@");
3111 PrintStr("/A << /S /URI /URI (");
3112 PrintStr(fUrls[i].c_str());
3113 PrintStr(") >>@");
3114 PrintStr(">>@");
3115 EndObject();
3116 }
3117 if (!fUrls.empty())
3118 fUrls.clear();
3119 if (!fRectX1.empty())
3120 fRectX1.clear();
3121 if (!fRectY1.empty())
3122 fRectY1.clear();
3123 if (!fRectX2.empty())
3124 fRectX2.clear();
3125 if (!fRectY2.empty())
3126 fRectY2.clear();
3127}
3128
3129////////////////////////////////////////////////////////////////////////////////
3130/// Compute the Rect for url
3131
3134{
3135 double W = 0.52 * fontsize * strlen(chars);
3136 double ascent = 0.72 * fontsize;
3137 double descent = 0.22 * fontsize;
3138
3139 int ax = fTextAlign / 10;
3140 int ay = fTextAlign % 10;
3141 double xShift = 0;
3142 double yShift = 0;
3143 if (ax == 2)
3144 xShift = -W / 2.0;
3145 if (ax == 3)
3146 xShift = -W;
3147 if (ay == 2)
3148 yShift = -(ascent - descent) / 2.0;
3149 if (ay == 3)
3150 yShift = -ascent;
3151 double x1 = xShift;
3152 double x2 = xShift + W;
3153 double y1 = -descent + yShift;
3154 double y2 = ascent + yShift;
3155
3156 Double_t A, B, C, D, E, F;
3157 A = fA * a + fC * b;
3158 B = fB * a + fD * b;
3159 C = fA * c + fC * d;
3160 D = fB * c + fD * d;
3161 E = fA * e + fC * f + fE;
3162 F = fB * e + fD * f + fF;
3163
3164 double bx1 = A * x1 + C * y1 + E;
3165 double by1 = B * x1 + D * y1 + F;
3166 double bx2 = A * x2 + C * y1 + E;
3167 double by2 = B * x2 + D * y1 + F;
3168 double bx3 = A * x2 + C * y2 + E;
3169 double by3 = B * x2 + D * y2 + F;
3170 double bx4 = A * x1 + C * y2 + E;
3171 double by4 = B * x1 + D * y2 + F;
3172
3173 double xmin = bx1;
3174 double xmax = bx1;
3175 double ymin = by1;
3176 double ymax = by1;
3177
3178 if (bx2 < xmin)
3179 xmin = bx2;
3180 if (bx3 < xmin)
3181 xmin = bx3;
3182 if (bx4 < xmin)
3183 xmin = bx4;
3184 if (bx2 > xmax)
3185 xmax = bx2;
3186 if (bx3 > xmax)
3187 xmax = bx3;
3188 if (bx4 > xmax)
3189 xmax = bx4;
3190 if (by2 < ymin)
3191 ymin = by2;
3192 if (by3 < ymin)
3193 ymin = by3;
3194 if (by4 < ymin)
3195 ymin = by4;
3196 if (by2 > ymax)
3197 ymax = by2;
3198 if (by3 > ymax)
3199 ymax = by3;
3200 if (by4 > ymax)
3201 ymax = by4;
3202
3203 fRectX1.push_back(xmin);
3204 fRectY1.push_back(ymin);
3205 fRectX2.push_back(xmax);
3206 fRectY2.push_back(ymax);
3207}
#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
short Style_t
Style number (short)
Definition RtypesCore.h:96
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Width_t
Line width (short)
Definition RtypesCore.h:98
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
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
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t cindex
Option_t Option_t SetLineWidth
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint xy
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t width
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
Option_t Option_t TPoint TPoint const char y1
float xmin
float ymin
float xmax
float ymax
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 Float_t kScale
Definition TPDF.cxx:77
const Int_t kObjColorSpace
Definition TPDF.cxx:87
const Int_t kNumberOfFonts
Definition TPDF.cxx:96
const Int_t kObjPattern
Definition TPDF.cxx:91
const Int_t kObjContents
Definition TPDF.cxx:85
const Int_t kObjFirstPage
Definition TPDF.cxx:93
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 kObjImageList
Definition TPDF.cxx:92
const Int_t kObjTransList
Definition TPDF.cxx:90
const Int_t kObjOutlines
Definition TPDF.cxx:82
#define gROOT
Definition TROOT.h:417
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
R__EXTERN TVirtualPS * 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 Width_t GetMarkerLineWidth(Style_t style)
Internal helper function that returns the line width of the given marker style (0 = filled marker)
Size_t fMarkerSize
Marker size.
Definition TAttMarker.h:26
Style_t fMarkerStyle
Marker style.
Definition TAttMarker.h:25
static Style_t GetMarkerStyleBase(Style_t style)
Internal helper function that returns the corresponding marker style with line width 1 for the given ...
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
The color creation and management class.
Definition TColor.h:22
Float_t GetRed() const
Definition TColor.h:61
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
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
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:2244
void Off()
Deactivate an already open PDF file.
Definition TPDF.cxx:1786
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:2276
Double_t fCellArrayHpdf
! PDF height of the image
Definition TPDF.h:76
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:2050
Double_t YtoPDF(Double_t y)
Convert Y from world coordinate to PDF.
Definition TPDF.cxx:2570
void Open(const char *filename, Int_t type=-111) override
Open a PDF file.
Definition TPDF.cxx:1810
void Close(Option_t *opt="") override
Close a PDF file.
Definition TPDF.cxx:264
std::vector< Int_t > fObjPos
Objects position.
Definition TPDF.h:46
TPDF()
Default PDF constructor.
Definition TPDF.cxx:105
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimetres.
Definition TPDF.cxx:2020
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:1553
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:2229
Double_t XtoPDF(Double_t x)
Convert X from world coordinate to PDF.
Definition TPDF.cxx:2561
void WriteReal(Float_t r, Bool_t space=kTRUE) override
Write a Real number to the file.
Definition TPDF.cxx:2629
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:2205
Double_t CMtoPDF(Double_t u)
Definition TPDF.h:104
void CellArrayEnd() override
End the Cell Array painting.
Definition TPDF.cxx:201
Double_t fCellArrayWpdf
! PDF width of the image
Definition TPDF.h:75
void NewPage() override
Start a new PDF page.
Definition TPDF.cxx:1592
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:2123
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:1794
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:485
void SetLineColor(Color_t cindex=1) override
Set color index for lines.
Definition TPDF.cxx:2183
std::vector< unsigned char > fCellArrayRGB
! Pixel buffer (3 bytes per pixel, top-to-bottom)
Definition TPDF.h:77
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:3132
void FontEncode()
Font encoding.
Definition TPDF.cxx:1521
Bool_t fCompress
True when fBuffer must be compressed.
Definition TPDF.h:57
static Int_t fgLineCap
Appearance of line caps.
Definition TPDF.h:91
void TextUrl(Double_t x, Double_t y, const char *string, const char *url) override
Draw text with URL.
Definition TPDF.cxx:2511
void DrawPS(Int_t n, Float_t *xw, Float_t *yw) override
Draw a PolyLine.
Definition TPDF.cxx:1343
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:2543
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:2030
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:715
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:1563
void SetLineScale(Float_t scale=1)
Definition TPDF.h:138
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:551
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: append one RGB pixel to the in-flight buffer.
Definition TPDF.cxx:175
~TPDF() override
Default PDF destructor.
Definition TPDF.cxx:131
void WriteUrlObjects()
Write the annotation objects containing the URLs.
Definition TPDF.cxx:3087
void EnsureBufferSize(Int_t required_size)
Ensure that required space in the buffer is available.
Definition TPDF.cxx:1974
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:1509
Int_t fCellArrayW
! Cell array width in cells
Definition TPDF.h:71
void PrintStr(const char *string="") override
Output the string str in the output buffer.
Definition TPDF.cxx:1987
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:2131
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:3056
void SetTextColor(Color_t cindex=1) override
Set color index for text.
Definition TPDF.cxx:2284
void DrawPolyLineNDC(Int_t n, TPoints *uv)
Draw a PolyLine in NDC space.
Definition TPDF.cxx:669
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:146
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:591
void SetLineWidth(Width_t linewidth=1) override
Change the line width.
Definition TPDF.cxx:2263
Double_t VtoPDF(Double_t v)
Convert V from NDC coordinate to PDF.
Definition TPDF.cxx:2552
std::vector< PDFImage > fImageObjects
! Embedded image XObjects, flushed in Close()
Definition TPDF.h:88
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:1573
void DrawPolyLine(Int_t n, TPoints *xy)
Draw a PolyLine.
Definition TPDF.cxx:615
Double_t fCellArrayXpdf
! PDF x of the image's left edge
Definition TPDF.h:73
void Text(Double_t x, Double_t y, const char *string) override
Draw text.
Definition TPDF.cxx:2296
void PatternEncode()
Patterns encoding.
Definition TPDF.cxx:2645
Double_t fCellArrayYpdfBot
! PDF y of the image's bottom edge
Definition TPDF.h:74
Double_t fF
"f" value of the Current Transformation Matrix (CTM)
Definition TPDF.h:66
Int_t fCellArrayH
! Cell array height in cells
Definition TPDF.h:72
void WriteCompressedBuffer()
Write the buffer in a compressed way.
Definition TPDF.cxx:2579
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
Definition TPDF.cxx:2523
static Int_t fgLineJoin
Appearance of joining lines.
Definition TPDF.h:90
void PrintFast(Int_t nch, const char *string="") override
Fast version of Print.
Definition TPDF.cxx:2005
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
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
Int_t GetJoinLinePS() const
Returns the line join method used for PostScript, PDF and SVG output. See TPostScript::SetLineJoin fo...
Definition TStyle.h:289
Int_t GetColorModelPS() const
Definition TStyle.h:198
const char * GetLineStyleString(Int_t i=1) const
Return line style string (used by PostScript).
Definition TStyle.cxx:1167
Int_t GetCapLinePS() const
Returns the line cap method used for PostScript, PDF and SVG output. See TPostScript::SetLineCap for ...
Definition TStyle.h:290
void GetPaperSize(Float_t &xsize, Float_t &ysize) const
Set paper size for PostScript output.
Definition TStyle.cxx:1184
Float_t GetLineScalePS() const
Definition TStyle.h:291
Base class for several text objects.
Definition TText.h:22
virtual void GetTextExtent(UInt_t &w, UInt_t &h, const char *text) const
Return text extent for string text.
Definition TText.cxx:545
virtual void GetTextAdvance(UInt_t &a, const char *text, const Bool_t kern=kTRUE) const
Return text advance for string text if kern is true (default) kerning is taken into account.
Definition TText.cxx:562
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition TVirtualPS.h:30
Int_t fSizBuffer
Definition TVirtualPS.h:39
Int_t fLenBuffer
Definition TVirtualPS.h:38
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
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.
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)
#define H(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
A bitmap embedded as a PDF image XObject.
Definition TPDF.h:82
TMarker m
Definition textangle.C:8