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 "TPoint.h"
66#include "TPoints.h"
67#include "TPDF.h"
68#include "TStyle.h"
69#include "TMath.h"
70#include "TStorage.h"
71#include "TText.h"
72#include "zlib.h"
73#include "TObjString.h"
74#include "TObjArray.h"
75#include "snprintf.h"
76
77// To scale fonts to the same size as the old TT version
78const Float_t kScale = 0.93376068;
79
80// Objects numbers
81const Int_t kObjRoot = 1; // Root object
82const Int_t kObjInfo = 2; // Info object
83const Int_t kObjOutlines = 3; // Outlines object
84const Int_t kObjPages = 4; // Pages object (pages index)
85const Int_t kObjPageResources = 5; // Pages Resources object
86const Int_t kObjContents = 6; // Table of content
87const Int_t kObjFont = 7; // First Font object (14 in total)
88const Int_t kObjColorSpace = 22; // ColorSpace object
89const Int_t kObjPatternResourses = 23; // Pattern Resources object
90const Int_t kObjPatternList = 24; // Pattern list object
91const Int_t kObjTransList = 25; // List of transparencies
92const Int_t kObjPattern = 26; // First pattern object (25 in total)
93const Int_t kObjImageList = 51; // Image XObject name dictionary
94const Int_t kObjFirstPage = 52; // First page object
95
96// Number of fonts
98
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Default PDF constructor
105
107{
109 SetTitle("PDF");
110 gVirtualPS = this;
111}
112
113////////////////////////////////////////////////////////////////////////////////
114/// Initialize the PDF interface
115///
116/// - fname : PDF file name
117/// - wtype : PDF workstation type. Not used in the PDF driver. But as TPDF
118/// inherits from TVirtualPS it should be kept. Anyway it is not
119/// necessary to specify this parameter at creation time because it
120/// has a default value (which is ignore in the PDF case).
121
123{
125 SetTitle("PDF");
126 Open(fname, wtype);
127}
128
129////////////////////////////////////////////////////////////////////////////////
130/// Default PDF destructor
131
133{
134 Close();
135}
136
137////////////////////////////////////////////////////////////////////////////////
138/// Begin the Cell Array painting.
139///
140/// The W x H cells fill a rectangle whose top-left corner is at world
141/// coordinates (x1, y1); (x2 - x1) is the per-cell width and (y2 - y1) is
142/// the per-cell vertical step (the image extends downward from y1 by
143/// H * (y2 - y1)). The pixel data is collected via CellArrayFill in
144/// top-to-bottom, left-to-right order and emitted as a PDF image XObject
145/// in CellArrayEnd.
146
148{
149 if (W <= 0 || H <= 0) {
150 fCellArrayW = 0;
151 fCellArrayH = 0;
152 fCellArrayRGB.clear();
153 return;
154 }
155
156 fCellArrayW = W;
157 fCellArrayH = H;
158
160 Double_t xRight = XtoPDF(x1 + (x2 - x1) * W);
162 Double_t yBot = YtoPDF(y1 - (y2 - y1) * H);
163
168
169 fCellArrayRGB.clear();
170 fCellArrayRGB.reserve(3 * std::size_t(W) * std::size_t(H));
171}
172
173////////////////////////////////////////////////////////////////////////////////
174/// Paint the Cell Array: append one RGB pixel to the in-flight buffer.
175
177{
178 if (fCellArrayW <= 0 || fCellArrayH <= 0)
179 return;
180 auto clamp = [](Int_t v) -> unsigned char {
181 if (v < 0)
182 return 0;
183 if (v > 255)
184 return 255;
185 return static_cast<unsigned char>(v);
186 };
187 fCellArrayRGB.push_back(clamp(r));
188 fCellArrayRGB.push_back(clamp(g));
189 fCellArrayRGB.push_back(clamp(b));
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// End the Cell Array painting.
194///
195/// The RGB buffer accumulated by CellArrayFill is Flate-compressed and stored
196/// as a PDF image XObject (actually emitted later, in Close). The page content
197/// stream only receives the placement matrix and a "/ImN Do" operator that
198/// paints that XObject. This is both smaller and structurally cleaner than an
199/// inline image: the pixel data is compressed once, kept out of the page
200/// content stream, and could be reused across pages.
201
203{
204 if (fCellArrayW <= 0 || fCellArrayH <= 0 || fCellArrayRGB.empty()) {
205 fCellArrayW = 0;
206 fCellArrayH = 0;
207 fCellArrayRGB.clear();
208 return;
209 }
210
211 const std::size_t expected = 3 * std::size_t(fCellArrayW) * std::size_t(fCellArrayH);
212 if (fCellArrayRGB.size() < expected) {
213 // Pad with black if the caller delivered fewer pixels than declared.
214 fCellArrayRGB.resize(expected, 0);
215 } else if (fCellArrayRGB.size() > expected) {
216 fCellArrayRGB.resize(expected);
217 }
218
219 // Flate-compress the pixels now, so only the compressed form is buffered
220 // until Close. compress2 emits a zlib stream, exactly what the PDF
221 // /FlateDecode filter consumes.
223 img.fW = fCellArrayW;
224 img.fH = fCellArrayH;
225 uLongf bound = compressBound(static_cast<uLong>(fCellArrayRGB.size()));
226 img.fData.resize(bound);
228 int zerr = compress2(img.fData.data(), &destLen, fCellArrayRGB.data(), static_cast<uLong>(fCellArrayRGB.size()),
230 if (zerr == Z_OK) {
231 img.fData.resize(destLen);
232 img.fFlate = kTRUE;
233 } else {
234 // Fall back to storing the raw samples uncompressed.
235 img.fData = fCellArrayRGB;
236 img.fFlate = kFALSE;
237 }
238 fImageObjects.push_back(std::move(img));
239 const Int_t imageId = static_cast<Int_t>(fImageObjects.size()); // 1-based /ImN
240
241 // Paint the image XObject. Its unit square (0,0)-(1,1) is mapped onto the
242 // image rectangle by this cm matrix. Operator separators must be real
243 // newlines: '@' is only translated when fCompress is false, and a page
244 // content stream is written with fCompress true.
245 PrintStr("\nq ");
247 WriteReal(0.);
248 WriteReal(0.);
252 PrintStr(" cm /Im");
254 PrintStr(" Do Q\n");
255
256 fCellArrayW = 0;
257 fCellArrayH = 0;
258 fCellArrayRGB.clear();
259 fCellArrayRGB.shrink_to_fit();
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Close a PDF file
264
266{
267 if (!gVirtualPS || !fStream)
268 return;
269
270 if (gPad)
271 gPad->Update();
272
273 // Close the currently opened page
275 PrintStr("endstream@");
277 EndObject();
280 PrintStr("@");
281 EndObject();
283 PrintStr("<<@");
284 if (!strstr(GetTitle(),"PDF")) {
285 PrintStr("/Title (");
287 PrintStr(")@");
288 } else {
289 PrintStr("/Title (Page");
291 PrintStr(")@");
292 }
293 PrintStr("/Dest [");
295 PrintStr(" 0 R /XYZ null null 0]@");
296 PrintStr("/Parent");
298 PrintStr(" 0 R");
299 PrintStr("@");
300 if (fNbPage > 1) {
301 PrintStr("/Prev");
303 PrintStr(" 0 R");
304 PrintStr("@");
305 }
306 PrintStr(">>@");
307 EndObject();
309 PrintStr("@");
311 PrintStr("<<@");
312 PrintStr("/Type /Outlines@");
313 PrintStr("/Count");
315 PrintStr("@");
316 PrintStr("/First");
318 PrintStr(" 0 R");
319 PrintStr("@");
320 PrintStr("/Last");
322 PrintStr(" 0 R");
323 PrintStr("@");
324 PrintStr(">>@");
325 EndObject();
326
328 PrintStr("<<@");
329 PrintStr("/Title (Contents)@");
330 PrintStr("/Dest [");
332 PrintStr(" 0 R /XYZ null null 0]@");
333 PrintStr("/Count");
335 PrintStr("@");
336 PrintStr("/Parent");
338 PrintStr(" 0 R");
339 PrintStr("@");
340 PrintStr("/First");
342 PrintStr(" 0 R");
343 PrintStr("@");
344 PrintStr("/Last");
346 PrintStr(" 0 R");
347 PrintStr("@");
348 PrintStr(">>@");
349 EndObject();
350
351 // List of all the pages
353 PrintStr("<<@");
354 PrintStr("/Type /Pages@");
355 PrintStr("/Count");
357 PrintStr("@");
358 PrintStr("/Kids [");
359 for (std::size_t i = 0; i < fPageObjects.size(); i++) {
361 PrintStr(" 0 R");
362 }
363 PrintStr(" ]");
364 PrintStr("@");
365 PrintStr(">>@");
366 EndObject();
367
368 if (!fPageObjects.empty())
369 fPageObjects.clear();
370 if (!fUrls.empty())
371 fUrls.clear();
372 if (!fRectX1.empty())
373 fRectX1.clear();
374 if (!fRectY1.empty())
375 fRectY1.clear();
376 if (!fRectX2.empty())
377 fRectX2.clear();
378 if (!fRectY2.empty())
379 fRectY2.clear();
380
381 // List of transparencies
383 PrintStr("<<@");
384 for (std::size_t i = 0; i < fAlphas.size(); i++) {
385 PrintStr(
386 TString::Format("/ca%3.2f << /Type /ExtGState /ca %3.2f >> /CA%3.2f << /Type /ExtGState /CA %3.2f >>@",
387 fAlphas[i],fAlphas[i],fAlphas[i],fAlphas[i]));
388 }
389 PrintStr(">>@");
390 EndObject();
391 if (!fAlphas.empty())
392 fAlphas.clear();
393
394 // Image XObjects. They are emitted here, once every page's content stream
395 // has been closed, because a PDF object cannot be opened while another one
396 // (the page content stream) is still open. Each page's /Resources refers to
397 // kObjImageList, the name dictionary written just after the images.
398 std::vector<Int_t> imageObjNum;
399 imageObjNum.reserve(fImageObjects.size());
400 for (const auto &img : fImageObjects) {
401 Int_t n = static_cast<Int_t>(fObjPos.size()) + 1;
402 imageObjNum.push_back(n);
403 NewObject(n);
404 PrintStr("<<@");
405 PrintStr("/Type /XObject@");
406 PrintStr("/Subtype /Image@");
407 PrintStr("/Width");
408 WriteInteger(img.fW);
409 PrintStr("@");
410 PrintStr("/Height");
411 WriteInteger(img.fH);
412 PrintStr("@");
413 PrintStr("/ColorSpace /DeviceRGB@");
414 PrintStr("/BitsPerComponent 8@");
415 if (img.fFlate)
416 PrintStr("/Filter /FlateDecode@");
417 PrintStr("/Length");
418 WriteInteger(static_cast<Int_t>(img.fData.size()));
419 PrintStr("@");
420 PrintStr(">>@");
421 PrintStr("stream@");
422 if (!img.fData.empty()) {
423 fStream->write(reinterpret_cast<const char *>(img.fData.data()), img.fData.size());
424 fNByte += img.fData.size();
425 }
426 PrintStr("@endstream@");
427 EndObject();
428 }
429
430 // Name dictionary mapping /ImN to the XObjects above. Always written, even
431 // when empty, because kObjImageList is referenced by every page's
432 // /Resources and so must exist in the cross-reference table.
434 PrintStr("<<@");
435 for (std::size_t i = 0; i < imageObjNum.size(); ++i) {
436 PrintStr(" /Im");
437 WriteInteger(static_cast<Int_t>(i) + 1, kFALSE);
439 PrintStr(" 0 R");
440 }
441 PrintStr("@>>@");
442 EndObject();
443 fImageObjects.clear();
444
445 // Cross-Reference Table
447 PrintStr("xref@");
448 PrintStr("0");
449 WriteInteger(fObjPos.size() + 1);
450 PrintStr("@");
451 PrintStr("0000000000 65535 f @");
452 char str[21];
453 for (std::size_t i = 0; i < fObjPos.size(); ++i) {
454 snprintf(str,21,"%10.10d 00000 n @", fObjPos[i]);
455 PrintStr(str);
456 }
457
458 // Trailer
459 PrintStr("trailer@");
460 PrintStr("<<@");
461 PrintStr("/Size");
462 WriteInteger(fObjPos.size() + 1);
463 PrintStr("@");
464 PrintStr("/Root");
466 PrintStr(" 0 R");
467 PrintStr("@");
468 PrintStr("/Info");
470 PrintStr(" 0 R@");
471 PrintStr(">>@");
472 PrintStr("startxref@");
473 WriteInteger(refInd, false);
474 PrintStr("@");
475 PrintStr("%%EOF@");
476
477 // Close file stream
478 CloseStream();
479
480 gVirtualPS = nullptr;
481}
482
483////////////////////////////////////////////////////////////////////////////////
484/// Draw a Box
485
487{
488 static Double_t x[4], y[4];
493 Int_t fillis = fFillStyle/1000;
494 Int_t fillsi = fFillStyle%1000;
495
496 if (fillis == 3 || fillis == 2) {
497 if (fillsi > 99) {
498 x[0] = x1; y[0] = y1;
499 x[1] = x2; y[1] = y1;
500 x[2] = x2; y[2] = y2;
501 x[3] = x1; y[3] = y2;
502 return;
503 }
504 if (fillsi > 0 && fillsi < 26) {
505 x[0] = x1; y[0] = y1;
506 x[1] = x2; y[1] = y1;
507 x[2] = x2; y[2] = y2;
508 x[3] = x1; y[3] = y2;
509 DrawPS(-4, &x[0], &y[0]);
510 }
511 if (fillsi == -3) {
512 SetColor(5);
513 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
514 WriteReal(ix1);
515 WriteReal(iy1);
516 WriteReal(ix2 - ix1);
517 WriteReal(iy2 - iy1);
518 if (fAlpha == 1) PrintFast(8," re b* Q");
519 else PrintFast(6," re f*");
520 }
521 }
522 if (fillis == 1) {
524 if (fAlpha == 1) PrintFast(15," q 0.4 w [] 0 d");
525 WriteReal(ix1);
526 WriteReal(iy1);
527 WriteReal(ix2 - ix1);
528 WriteReal(iy2 - iy1);
529 if (fAlpha == 1) PrintFast(8," re b* Q");
530 else PrintFast(6," re f*");
531 }
532 if (fillis == 0) {
533 if (fLineWidth<=0) return;
535 WriteReal(ix1);
536 WriteReal(iy1);
537 WriteReal(ix2 - ix1);
538 WriteReal(iy2 - iy1);
539 PrintFast(5," re S");
540 }
541}
542
543////////////////////////////////////////////////////////////////////////////////
544/// Draw a Frame around a box
545///
546/// - mode = -1 box looks as it is behind the screen
547/// - mode = 1 box looks as it is in front of the screen
548/// - border is the border size in already precomputed PDF units
549/// - dark is the color for the dark part of the frame
550/// - light is the color for the light part of the frame
551
553 Int_t mode, Int_t border, Int_t dark, Int_t light)
554{
555 static Double_t xps[7], yps[7];
556 Int_t i;
557
558 // Draw top&left part of the box
559 if (mode == -1) SetColor(dark);
560 else SetColor(light);
561 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
562 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
563 xps[2] = xps[1]; yps[2] = YtoPDF(yt) - border;
564 xps[3] = XtoPDF(xt) - border; yps[3] = yps[2];
565 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
566 xps[5] = xps[0]; yps[5] = yps[4];
567 xps[6] = xps[0]; yps[6] = yps[0];
568
569 MoveTo(xps[0], yps[0]);
570 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
571 PrintFast(3," f*");
572
573 // Draw bottom&right part of the box
574 if (mode == -1) SetColor(light);
575 else SetColor(dark);
576 xps[0] = XtoPDF(xl); yps[0] = YtoPDF(yl);
577 xps[1] = xps[0] + border; yps[1] = yps[0] + border;
578 xps[2] = XtoPDF(xt) - border; yps[2] = yps[1];
579 xps[3] = xps[2]; yps[3] = YtoPDF(yt) - border;
580 xps[4] = XtoPDF(xt); yps[4] = YtoPDF(yt);
581 xps[5] = xps[4]; yps[5] = yps[0];
582 xps[6] = xps[0]; yps[6] = yps[0];
583
584 MoveTo(xps[0], yps[0]);
585 for (i=1;i<7;i++) LineTo(xps[i], yps[i]);
586 PrintFast(3," f*");
587}
588
589////////////////////////////////////////////////////////////////////////////////
590/// Draw Fill area with hatch styles
591
593{
594 Warning("DrawHatch", "hatch fill style not yet implemented");
595}
596
597////////////////////////////////////////////////////////////////////////////////
598/// Draw Fill area with hatch styles
599
601{
602 Warning("DrawHatch", "hatch fill style not yet implemented");
603}
604
605////////////////////////////////////////////////////////////////////////////////
606/// Draw a PolyLine
607///
608/// Draw a polyline through the points xy.
609///
610/// - If NN=1 moves only to point x,y.
611/// - If NN=0 the x,y are written in the PDF file
612/// according to the current transformation.
613/// - If NN>0 the line is clipped as a line.
614/// - If NN<0 the line is clipped as a fill area.
615
617{
618 Int_t n;
619
622
623 if (nn > 0) {
624 if (fLineWidth<=0) return;
625 n = nn;
629 } else {
630 n = -nn;
631 SetLineStyle(1);
632 SetLineWidth(1);
634 }
635
636 WriteReal(XtoPDF(xy[0].GetX()));
637 WriteReal(YtoPDF(xy[0].GetY()));
638 if (n <= 1) {
639 if (n == 0) return;
640 PrintFast(2," m");
641 return;
642 }
643
644 PrintFast(2," m");
645
646 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xy[i].GetX()), YtoPDF(xy[i].GetY()));
647
648 if (nn > 0) {
649 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
650 PrintFast(2," S");
651 } else {
652 PrintFast(3," f*");
653 }
654
657}
658
659////////////////////////////////////////////////////////////////////////////////
660/// Draw a PolyLine in NDC space
661///
662/// Draw a polyline through the points xy.
663///
664/// - If NN=1 moves only to point x,y.
665/// - If NN=0 the x,y are written in the PDF file
666/// according to the current transformation.
667/// - If NN>0 the line is clipped as a line.
668/// - If NN<0 the line is clipped as a fill area.
669
671{
672 Int_t n;
673
676
677 if (nn > 0) {
678 if (fLineWidth<=0) return;
679 n = nn;
683 } else {
684 n = -nn;
685 SetLineStyle(1);
686 SetLineWidth(1);
688 }
689
690 WriteReal(UtoPDF(xy[0].GetX()));
691 WriteReal(VtoPDF(xy[0].GetY()));
692 if (n <= 1) {
693 if (n == 0) return;
694 PrintFast(2," m");
695 return;
696 }
697
698 PrintFast(2," m");
699
700 for (Int_t i=1;i<n;i++) LineTo(UtoPDF(xy[i].GetX()), VtoPDF(xy[i].GetY()));
701
702 if (nn > 0) {
703 if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
704 PrintFast(2," S");
705 } else {
706 PrintFast(3," f*");
707 }
708
711}
712
713template<typename T>
715{
718
719 SetLineStyle(1);
722
723 // use extra scaling to avoid rounding effects for complex shapes
724 const Float_t sf = GetMarkerStyle() > 10 ? 0.01 : 1;
725
726 Float_t s2x = 1. / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
727 // Rescale size of marker on SVG coordinates
728 Float_t scale = UtoPDF(s2x) - UtoPDF(0);
729
730 Int_t markerSize = 0;
731 std::vector<TPoint> points;
732 auto shape = GetMarkerShape(markerSize, points, scale / sf);
733 if ((shape == kShapeDot) && (markerSize > 1))
734 shape = kShapeFilledCircle;
735
736 for (Int_t k = 0; k < n; k++) {
737 Double_t ix = XtoPDF(xw[k]);
738 Double_t iy = YtoPDF(yw[k]);
739 switch(shape) {
740 case kShapeDot:
741 MoveTo(ix-1, iy);
742 LineTo(ix , iy);
743 PrintFast(2," S");
744 break;
745 case kShapeCircle:
746 case kShapeFilledCircle: {
747 Double_t m2 = sf * markerSize * 0.5;
748 Double_t m4 = m2 * 1.333333333333;
749
750 MoveTo(ix-m2, iy);
751 WriteReal(ix-m2); WriteReal(iy+m4);
752 WriteReal(ix+m2); WriteReal(iy+m4);
753 WriteReal(ix+m2); WriteReal(iy) ; PrintFast(2," c");
754 WriteReal(ix+m2); WriteReal(iy-m4);
755 WriteReal(ix-m2); WriteReal(iy-m4);
756 WriteReal(ix-m2); WriteReal(iy) ; PrintFast(4," c h");
757 if (shape == kShapeCircle)
758 PrintFast(2," S");
759 else
760 PrintFast(2," f");
761 break;
762 }
763 case kShapePolyLine:
764 case kShapeFilledArea:
765 MoveTo(ix + sf*points[0].fX, iy - sf*points[0].fY);
766
767 for (std::size_t i = 1; i < points.size(); i++)
768 LineTo(ix + sf*points[i].fX, iy - sf*points[i].fY);
769
770 if (shape == kShapePolyLine) {
771 if (points.front() == points.back())
772 PrintFast(2," h");
773 PrintFast(2," S");
774 } else {
775 // close line and fill
776 PrintFast(4," h f");
777 }
778 break;
779 case kShapeSegments:
780 for (std::size_t i = 0; i + 1 < points.size(); i += 2) {
781 MoveTo(ix + sf*points[i].fX, iy - sf*points[i].fY);
782 LineTo(ix + sf*points[i+1].fX, iy - sf*points[i+1].fY);
783 }
784 PrintFast(2," S");
785 break;
786 case kShapeTriangles:
787 for (std::size_t i = 0; i + 2 < points.size(); i += 3) {
788 MoveTo(ix + sf*points[i].fX, iy - sf*points[i].fY);
789 LineTo(ix + sf*points[i+1].fX, iy - sf*points[i+1].fY);
790 LineTo(ix + sf*points[i+2].fX, iy - sf*points[i+2].fY);
791 PrintFast(4," h f");
792 }
793 break;
794 }
795 }
798}
799
800
801////////////////////////////////////////////////////////////////////////////////
802/// Draw markers at the n WC points xw, yw
803
808
809////////////////////////////////////////////////////////////////////////////////
810/// Draw markers at the n WC points xw, yw
811
816
817////////////////////////////////////////////////////////////////////////////////
818/// Draw a PolyLine
819///
820/// Draw a polyline through the points xw,yw.
821///
822/// - If nn=1 moves only to point xw,yw.
823/// - If nn=0 the XW(1) and YW(1) are written in the PDF file
824/// according to the current NT.
825/// - If nn>0 the line is clipped as a line.
826/// - If nn<0 the line is clipped as a fill area.
827
829{
830 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
831 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
832 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
833 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
834 180, 90,135, 45,150, 30,120, 60,
835 180, 90,135, 45,150, 30,120, 60};
836 Int_t n = 0, fais = 0 , fasi = 0;
837
840
841 if (nn > 0) {
842 if (fLineWidth<=0) return;
843 n = nn;
847 }
848 if (nn < 0) {
849 n = -nn;
850 SetLineStyle(1);
851 SetLineWidth(1);
853 fais = fFillStyle/1000;
854 fasi = fFillStyle%1000;
855 if (fais == 3 || fais == 2) {
856 if (fasi > 100 && fasi <125) {
857 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
860 return;
861 }
862 if (fasi > 0 && fasi < 26) {
864 }
865 }
866 }
867
868 WriteReal(XtoPDF(xw[0]));
869 WriteReal(YtoPDF(yw[0]));
870 if (n <= 1) {
871 if (n == 0) return;
872 PrintFast(2," m");
873 return;
874 }
875
876 PrintFast(2," m");
877
878 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
879
880 if (nn > 0) {
881 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
882 PrintFast(2," S");
883 } else {
884 if (fais == 0) {PrintFast(2," s"); return;}
885 if (fais == 3 || fais == 2) {
886 if (fasi > 0 && fasi < 26) {
887 PrintFast(3," f*");
888 fRed = -1;
889 fGreen = -1;
890 fBlue = -1;
891 fAlpha = -1.;
892 }
895 return;
896 }
897 PrintFast(3," f*");
898 }
899
902}
903
904////////////////////////////////////////////////////////////////////////////////
905/// Draw a PolyLine
906///
907/// Draw a polyline through the points xw,yw.
908///
909/// - If nn=1 moves only to point xw,yw.
910/// - If nn=0 the xw(1) and YW(1) are written in the PDF file
911/// according to the current NT.
912/// - If nn>0 the line is clipped as a line.
913/// - If nn<0 the line is clipped as a fill area.
914
916{
917 static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
918 .01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,.01 ,
919 .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
920 static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
921 180, 90,135, 45,150, 30,120, 60,
922 180, 90,135, 45,150, 30,120, 60};
923 Int_t n = 0, fais = 0, fasi = 0;
924
927
928 if (nn > 0) {
929 if (fLineWidth<=0) return;
930 n = nn;
934 }
935 if (nn < 0) {
936 n = -nn;
937 SetLineStyle(1);
938 SetLineWidth(1);
940 fais = fFillStyle/1000;
941 fasi = fFillStyle%1000;
942 if (fais == 3 || fais == 2) {
943 if (fasi > 100 && fasi <125) {
944 DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
947 return;
948 }
949 if (fasi > 0 && fasi < 26) {
951 }
952 }
953 }
954
955 WriteReal(XtoPDF(xw[0]));
956 WriteReal(YtoPDF(yw[0]));
957 if (n <= 1) {
958 if (n == 0) return;
959 PrintFast(2," m");
960 return;
961 }
962
963 PrintFast(2," m");
964
965 for (Int_t i=1;i<n;i++) LineTo(XtoPDF(xw[i]), YtoPDF(yw[i]));
966
967 if (nn > 0) {
968 if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(2," h");
969 PrintFast(2," S");
970 } else {
971 if (fais == 0) {PrintFast(2," s"); return;}
972 if (fais == 3 || fais == 2) {
973 if (fasi > 0 && fasi < 26) {
974 PrintFast(3," f*");
975 fRed = -1;
976 fGreen = -1;
977 fBlue = -1;
978 fAlpha = -1.;
979 }
982 return;
983 }
984 PrintFast(3," f*");
985 }
986
989}
990
991////////////////////////////////////////////////////////////////////////////////
992/// Close the current opened object
993
995{
996 if (!fObjectIsOpen)
997 Warning("EndObject", "No Object currently opened.");
999
1000 PrintStr("endobj@");
1001}
1002
1003////////////////////////////////////////////////////////////////////////////////
1004/// Font encoding
1005
1007{
1008 static const char *sdtfonts[] = {
1009 "/Times-Italic" , "/Times-Bold" , "/Times-BoldItalic",
1010 "/Helvetica" , "/Helvetica-Oblique" , "/Helvetica-Bold" ,
1011 "/Helvetica-BoldOblique", "/Courier" , "/Courier-Oblique" ,
1012 "/Courier-Bold" , "/Courier-BoldOblique", "/Symbol" ,
1013 "/Times-Roman" , "/ZapfDingbats" , "/Symbol"};
1014
1015 for (Int_t i=0; i<kNumberOfFonts; i++) {
1017 PrintStr("<<@");
1018 PrintStr("/Type /Font@");
1019 PrintStr("/Subtype /Type1@");
1020 PrintStr("/Name /F");
1021 WriteInteger(i+1,false);
1022 PrintStr("@");
1023 PrintStr("/BaseFont ");
1024 PrintStr(sdtfonts[i]);
1025 PrintStr("@");
1026 if (i!=11 && i!=13 && i!=14) {
1027 PrintStr("/Encoding /WinAnsiEncoding");
1028 PrintStr("@");
1029 }
1030 PrintStr(">>@");
1031 EndObject();
1032 }
1033}
1034
1035////////////////////////////////////////////////////////////////////////////////
1036/// Draw a line to a new position
1037
1039{
1040 WriteReal(x);
1041 WriteReal(y);
1042 PrintFast(2," l");
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// Move to a new position
1047
1049{
1050 WriteReal(x);
1051 WriteReal(y);
1052 PrintFast(2," m");
1053}
1054
1055////////////////////////////////////////////////////////////////////////////////
1056/// Create a new object in the PDF file
1057
1059{
1060 if (fObjectIsOpen)
1061 Warning("NewObject", "An Object is already open.");
1063 if (n > (Int_t) fObjPos.size())
1064 fObjPos.resize(n, 0); // filling new elements with 0
1065 if (n > 0)
1066 fObjPos[n-1] = fNByte;
1067 else
1068 Error("NewObject", "Wrong id %d is specified.", n);
1069 WriteInteger(n, false);
1070 PrintStr(" 0 obj");
1071 PrintStr("@");
1072}
1073
1074////////////////////////////////////////////////////////////////////////////////
1075/// Start a new PDF page.
1076
1078{
1079 if (!fPageNotEmpty) return;
1080
1081 // Compute pad conversion coefficients
1082 if (gPad) {
1083 Double_t ww = gPad->GetWw();
1084 Double_t wh = gPad->GetWh();
1085 fYsize = fXsize*wh/ww;
1086 } else {
1087 fYsize = 27;
1088 }
1089
1090 fNbPage++;
1091 fA = 1.;
1092 fB = 0.;
1093 fC = 0.;
1094 fD = 1.;
1095 fE = 0.;
1096 fF = 0.;
1097
1098 if (fNbPage>1) {
1099 // Close the currently opened page
1101 PrintStr("endstream@");
1103 EndObject();
1105 WriteInteger(streamLength, false);
1106 PrintStr("@");
1107 EndObject();
1109 PrintStr("<<@");
1110 if (!strstr(GetTitle(),"PDF")) {
1111 PrintStr("/Title (");
1112 PrintStr(GetTitle());
1113 PrintStr(")@");
1114 } else {
1115 PrintStr("/Title (Page");
1117 PrintStr(")@");
1118 }
1119 PrintStr("/Dest [");
1121 PrintStr(" 0 R /XYZ null null 0]@");
1122 PrintStr("/Parent");
1124 PrintStr(" 0 R");
1125 PrintStr("@");
1126 PrintStr("/Next");
1128 PrintStr(" 0 R");
1129 PrintStr("@");
1130 if (fNbPage>2) {
1131 PrintStr("/Prev");
1133 PrintStr(" 0 R");
1134 PrintStr("@");
1135 }
1136 PrintStr(">>@");
1137 EndObject();
1139 fCurrentPage = fCurrentPage + fNbUrl + 4; // object number of the next page
1140 fNbUrl = 1;
1141 }
1142
1143 // Start a new page
1144 PrintStr("@");
1146 fPageObjects.push_back(fCurrentPage);
1147 PrintStr("<<@");
1148 PrintStr("/Type /Page@");
1149 PrintStr("@");
1150 PrintStr("/Parent");
1152 PrintStr(" 0 R");
1153 PrintStr("@");
1154
1155 Double_t xlow=0, ylow=0, xup=1, yup=1;
1156 if (gPad) {
1157 xlow = gPad->GetAbsXlowNDC();
1158 xup = xlow + gPad->GetAbsWNDC();
1159 ylow = gPad->GetAbsYlowNDC();
1160 yup = ylow + gPad->GetAbsHNDC();
1161 }
1162
1163 PrintStr("/MediaBox [");
1165 switch (fPageFormat) {
1166 case 100 :
1167 width = 8.5*2.54;
1168 height = 11.*2.54;
1169 break;
1170 case 200 :
1171 width = 8.5*2.54;
1172 height = 14.*2.54;
1173 break;
1174 case 300 :
1175 width = 11.*2.54;
1176 height = 17.*2.54;
1177 break;
1178 default :
1181 };
1182 WriteReal(CMtoPDF(fXsize*xlow));
1183 WriteReal(CMtoPDF(fYsize*ylow));
1186 PrintStr("]");
1187 PrintStr("@");
1188
1189 Double_t xmargin = CMtoPDF(0.7);
1190 Double_t ymargin = 0;
1191 if (fPageOrientation == 1) ymargin = CMtoPDF(TMath::Sqrt(2.)*0.7);
1192 if (fPageOrientation == 2) ymargin = CMtoPDF(height)-CMtoPDF(0.7);
1193
1194 PrintStr("/CropBox [");
1195 if (fPageOrientation == 1) {
1200 }
1201 if (fPageOrientation == 2) {
1206 }
1207 PrintStr("]");
1208 PrintStr("@");
1209
1210 if (fPageOrientation == 1) PrintStr("/Rotate 0@");
1211 if (fPageOrientation == 2) PrintStr("/Rotate 90@");
1212
1213 PrintStr("/Resources");
1215 PrintStr(" 0 R");
1216 PrintStr("@");
1217
1218 PrintStr("/Contents");
1220 PrintStr(" 0 R@");
1221
1222 PrintStr("/Annots");
1224 PrintStr(" 0 R");
1225 PrintStr("@");
1226
1227 PrintStr(">>@");
1228 EndObject();
1229
1231 PrintStr("<<@");
1232 PrintStr("/Length");
1234 PrintStr(" 0 R@");
1235 PrintStr("/Filter [/FlateDecode]@");
1236 PrintStr(">>@");
1237 PrintStr("stream@");
1239 fCompress = kTRUE;
1240
1241 // Force the line width definition next time TPDF::SetLineWidth will be called.
1242 fLineWidth = -1;
1243
1244 // Force the color definition next time TPDF::SetColor will be called.
1245 fRed = -1;
1246 fGreen = -1;
1247 fBlue = -1;
1248 fAlpha = -1.;
1249
1250 if (fPageOrientation == 2) {
1253 }
1254
1255 WriteCM(1, 0, 0, 1, xmargin, ymargin);
1256 if (fPageOrientation == 2)
1257 WriteCM(0, 1, -1, 0, 0, 0);
1258 if (fgLineJoin) {
1260 PrintFast(2," j");
1261 }
1262 if (fgLineCap) {
1264 PrintFast(2," J");
1265 }
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Deactivate an already open PDF file
1270
1272{
1273 gVirtualPS = nullptr;
1274}
1275
1276////////////////////////////////////////////////////////////////////////////////
1277/// Activate an already open PDF file
1278
1280{
1281 // fType is used to know if the PDF file is open. Unlike TPostScript, TPDF
1282 // has no "workstation type".
1283
1284 if (!fType) {
1285 Error("On", "no PDF file open");
1286 Off();
1287 return;
1288 }
1289 gVirtualPS = this;
1290}
1291
1292////////////////////////////////////////////////////////////////////////////////
1293/// Open a PDF file
1294
1295void TPDF::Open(const char *fname, Int_t wtype)
1296{
1297 if (fStream) {
1298 Warning("Open", "PDF file already open");
1299 return;
1300 }
1301
1302 fLenBuffer = 0;
1303 fRed = -1;
1304 fGreen = -1;
1305 fBlue = -1;
1306 fAlpha = -1.;
1307 fType = abs(wtype);
1313 if (gPad) {
1314 Double_t ww = gPad->GetWw();
1315 Double_t wh = gPad->GetWh();
1316 if (fType == 113) {
1317 ww *= gPad->GetWNDC();
1318 wh *= gPad->GetHNDC();
1319 }
1320 Double_t ratio = wh/ww;
1321 xrange = fXsize;
1322 yrange = fXsize*ratio;
1323 if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
1325 }
1326
1327 // Open OS file
1328 if (!OpenStream(fname, kTRUE)) {
1329 Error("Open", "Cannot open file: %s", fname);
1330 return;
1331 }
1332
1333 gVirtualPS = this;
1334
1335 ClearBuffer();
1336
1337 // The page orientation is last digit of PDF workstation type
1338 // orientation = 1 for portrait
1339 // orientation = 2 for landscape
1342 Error("Open", "Invalid page orientation %d", fPageOrientation);
1343 return;
1344 }
1345
1346 // format = 0-99 is the European page format (A4,A3 ...)
1347 // format = 100 is the US format 8.5x11.0 inch
1348 // format = 200 is the US format 8.5x14.0 inch
1349 // format = 300 is the US format 11.0x17.0 inch
1350 fPageFormat = fType/1000;
1351 if (fPageFormat == 0) fPageFormat = 4;
1352 if (fPageFormat == 99) fPageFormat = 0;
1353
1354 fRange = kFALSE;
1355
1356 // Set a default range
1358
1359 fObjPos.clear();
1360 fNbPage = 0;
1361 fUrl = kFALSE;
1362
1363 PrintStr("%PDF-1.4@");
1364 PrintStr("%\342\343\317\323");
1365 PrintStr("@");
1366
1368 PrintStr("<<@");
1369 PrintStr("/Type /Catalog@");
1370 PrintStr("/Pages");
1372 PrintStr(" 0 R@");
1373 PrintStr("/Outlines");
1375 PrintStr(" 0 R@");
1376 PrintStr("/PageMode /UseOutlines@");
1377 PrintStr(">>@");
1378 EndObject();
1379
1381 PrintStr("<<@");
1382 PrintStr("/Creator (ROOT Version ");
1383 PrintStr(gROOT->GetVersion());
1384 PrintStr(")");
1385 PrintStr("@");
1386 PrintStr("/CreationDate (");
1387 TDatime t;
1388 Int_t toff = t.Convert(kFALSE) - t.Convert(kTRUE); // time zone and dst offset
1389 toff = toff/60;
1390 char str[24];
1391 snprintf(str,24,"D:%4.4d%2.2d%2.2d%2.2d%2.2d%2.2d%c%2.2d'%2.2d'",
1392 t.GetYear() , t.GetMonth(),
1393 t.GetDay() , t.GetHour(),
1394 t.GetMinute(), t.GetSecond(),
1395 toff < 0 ? '-' : '+',
1396 // TMath::Abs(toff/60), TMath::Abs(toff%60)); // format-truncation warning
1397 TMath::Abs(toff/60) & 0x3F, TMath::Abs(toff%60) & 0x3F); // now 2 digits
1398 PrintStr(str);
1399 PrintStr(")");
1400 PrintStr("@");
1401 PrintStr("/ModDate (");
1402 PrintStr(str);
1403 PrintStr(")");
1404 PrintStr("@");
1405 PrintStr("/Title (");
1406 if (strlen(GetName())<=80) PrintStr(GetName());
1407 PrintStr(")");
1408 PrintStr("@");
1409 PrintStr("/Keywords (ROOT)@");
1410 PrintStr(">>@");
1411 EndObject();
1412
1414 PrintStr("<<@");
1415 PrintStr("/ProcSet [/PDF /Text]@");
1416
1417 PrintStr("/Font@");
1418 PrintStr("<<@");
1419 for (Int_t i=0; i<kNumberOfFonts; i++) {
1420 PrintStr(" /F");
1421 WriteInteger(i+1,false);
1423 PrintStr(" 0 R");
1424 }
1425 PrintStr("@");
1426 PrintStr(">>@");
1427
1428 PrintStr("/ExtGState");
1430 PrintStr(" 0 R @");
1431 if (!fAlphas.empty()) fAlphas.clear();
1432
1433 PrintStr("/ColorSpace << /Cs8");
1435 PrintStr(" 0 R >>");
1436 PrintStr("@");
1437 PrintStr("/Pattern");
1439 PrintStr(" 0 R");
1440 PrintStr("@");
1441 PrintStr("/XObject");
1443 PrintStr(" 0 R");
1444 PrintStr("@");
1445 PrintStr(">>@");
1446 EndObject();
1447
1448 FontEncode();
1449 PatternEncode();
1450
1451 NewPage();
1453}
1454
1455
1456////////////////////////////////////////////////////////////////////////////////
1457/// Ensure that required space in the buffer is available
1458
1460{
1461 if (required_size >= fSizBuffer) {
1462 // increase buffer size by integer factor, normally 2
1463 Int_t mult = (required_size + 1) / fSizBuffer + 1;
1466 }
1467}
1468
1469////////////////////////////////////////////////////////////////////////////////
1470/// Output the string str in the output buffer
1471
1472void TPDF::PrintStr(const char *str)
1473{
1474 Int_t len = strlen(str);
1475 if (len == 0) return;
1477
1478 if (fCompress) {
1480 strcpy(fBuffer + fLenBuffer, str);
1481 fLenBuffer += len;
1482 } else {
1484 }
1485}
1486
1487////////////////////////////////////////////////////////////////////////////////
1488/// Fast version of Print
1489
1490void TPDF::PrintFast(Int_t len, const char *str)
1491{
1493 if (fCompress) {
1495 strcpy(fBuffer + fLenBuffer, str);
1496 fLenBuffer += len;
1497 } else {
1499 }
1500}
1501
1502////////////////////////////////////////////////////////////////////////////////
1503/// Set the range for the paper in centimetres
1504
1506{
1507 fXsize = xsize;
1508 fYsize = ysize;
1509 fRange = kTRUE;
1510}
1511
1512////////////////////////////////////////////////////////////////////////////////
1513/// Set the alpha channel value.
1514
1516{
1517 if (a == fAlpha) return;
1518 fAlpha = a;
1519 if (fAlpha <= 0.000001) fAlpha = 0;
1520
1521 Bool_t known = kFALSE;
1522 for (int i=0; i<(int)fAlphas.size(); i++) {
1523 if (fAlpha == fAlphas[i]) {
1524 known = kTRUE;
1525 break;
1526 }
1527 }
1528 if (!known) fAlphas.push_back(fAlpha);
1529 PrintStr(TString::Format(" /ca%3.2f gs /CA%3.2f gs",fAlpha,fAlpha));
1530}
1531
1532////////////////////////////////////////////////////////////////////////////////
1533/// Set color with its color index.
1534
1536{
1537 if (color < 0) color = 0;
1538 TColor *col = gROOT->GetColor(color);
1539
1540 if (col) {
1541 SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1542 SetAlpha(col->GetAlpha());
1543 } else {
1544 SetColor(1., 1., 1.);
1545 SetAlpha(1.);
1546 }
1547}
1548
1549////////////////////////////////////////////////////////////////////////////////
1550/// Set color with its R G B components:
1551///
1552/// - r: % of red in [0,1]
1553/// - g: % of green in [0,1]
1554/// - b: % of blue in [0,1]
1555
1557{
1558 if (r == fRed && g == fGreen && b == fBlue) return;
1559
1560 fRed = r;
1561 fGreen = g;
1562 fBlue = b;
1563 if (fRed <= 0.000001) fRed = 0;
1564 if (fGreen <= 0.000001) fGreen = 0;
1565 if (fBlue <= 0.000001) fBlue = 0;
1566
1567 if (gStyle->GetColorModelPS()) {
1570 if (colBlack==1) {
1571 colCyan = 0;
1572 colMagenta = 0;
1573 colYellow = 0;
1574 } else {
1575 colCyan = (1-fRed-colBlack)/(1-colBlack);
1577 colYellow = (1-fBlue-colBlack)/(1-colBlack);
1578 }
1579 if (colCyan <= 0.000001) colCyan = 0;
1580 if (colMagenta <= 0.000001) colMagenta = 0;
1581 if (colYellow <= 0.000001) colYellow = 0;
1582 if (colBlack <= 0.000001) colBlack = 0;
1587 PrintFast(2," K");
1592 PrintFast(2," k");
1593 } else {
1594 WriteReal(fRed);
1597 PrintFast(3," RG");
1598 WriteReal(fRed);
1601 PrintFast(3," rg");
1602 }
1603}
1604
1605////////////////////////////////////////////////////////////////////////////////
1606/// Set color index for fill areas
1607
1612
1613////////////////////////////////////////////////////////////////////////////////
1614/// Set the fill patterns (1 to 25) for fill areas
1615
1617{
1618 char cpat[10];
1619 TColor *col = gROOT->GetColor(color);
1620 if (!col) return;
1621 PrintStr(" /Cs8 cs");
1622 Double_t colRed = col->GetRed();
1623 Double_t colGreen = col->GetGreen();
1624 Double_t colBlue = col->GetBlue();
1625 if (gStyle->GetColorModelPS()) {
1627 if (colBlack==1) {
1628 WriteReal(0);
1629 WriteReal(0);
1630 WriteReal(0);
1632 } else {
1640 }
1641 } else {
1645 }
1646
1647 if (fPageOrientation == 2) {
1648 switch (ipat) {
1649 case 4: ipat = 5; break;
1650 case 5: ipat = 4; break;
1651 case 6: ipat = 7; break;
1652 case 7: ipat = 6; break;
1653 case 17: ipat = 18; break;
1654 case 18: ipat = 17; break;
1655 case 20: ipat = 16; break;
1656 case 16: ipat = 20; break;
1657 case 21: ipat = 22; break;
1658 case 22: ipat = 21; break;
1659 }
1660 }
1661 snprintf(cpat,10," /P%2.2d scn", ipat);
1662 PrintStr(cpat);
1663}
1664
1665////////////////////////////////////////////////////////////////////////////////
1666/// Set color index for lines
1667
1672
1673////////////////////////////////////////////////////////////////////////////////
1674/// Set the value of the global parameter TPDF::fgLineJoin.
1675/// This parameter determines the appearance of joining lines in a PDF
1676/// output.
1677/// It takes one argument which may be:
1678/// - 0 (miter join)
1679/// - 1 (round join)
1680/// - 2 (bevel join)
1681/// The default value is 0 (miter join).
1682///
1683/// \image html postscript_1.png
1684///
1685/// To change the line join behaviour just do:
1686/// ~~~ {.cpp}
1687/// gStyle->SetJoinLinePS(2); // Set the PDF line join to bevel.
1688/// ~~~
1689
1691{
1693 if (fgLineJoin<0) fgLineJoin=0;
1694 if (fgLineJoin>2) fgLineJoin=2;
1695}
1696
1697////////////////////////////////////////////////////////////////////////////////
1698/// Set the value of the global parameter TPDF::fgLineCap.
1699/// This parameter determines the appearance of line caps in a PDF
1700/// output.
1701/// It takes one argument which may be:
1702/// - 0 (butt caps)
1703/// - 1 (round caps)
1704/// - 2 (projecting caps)
1705/// The default value is 0 (butt caps).
1706///
1707/// \image html postscript_2.png
1708///
1709/// To change the line cap behaviour just do:
1710/// ~~~ {.cpp}
1711/// gStyle->SetCapLinePS(2); // Set the PDF line cap to projecting.
1712/// ~~~
1713
1715{
1717 if (fgLineCap<0) fgLineCap=0;
1718 if (fgLineCap>2) fgLineCap=2;
1719}
1720
1721////////////////////////////////////////////////////////////////////////////////
1722/// Change the line style
1723///
1724/// - linestyle = 2 dashed
1725/// - linestyle = 3 dotted
1726/// - linestyle = 4 dash-dotted
1727/// - linestyle = else solid (1 in is used most of the time)
1728
1730{
1731 if ( linestyle == fLineStyle) return;
1734 PrintFast(2," [");
1735 TObjArray *tokens = st.Tokenize(" ");
1736 for (Int_t j = 0; j<tokens->GetEntries(); j++) {
1737 Int_t it;
1738 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
1739 WriteInteger((Int_t)(it/4));
1740 }
1741 delete tokens;
1742 PrintFast(5,"] 0 d");
1743}
1744
1745////////////////////////////////////////////////////////////////////////////////
1746/// Change the line width
1747
1749{
1750 if (linewidth == fLineWidth) return;
1752 if (fLineWidth!=0) {
1754 PrintFast(2," w");
1755 }
1756}
1757
1758////////////////////////////////////////////////////////////////////////////////
1759/// Set color index for markers.
1760
1765
1766////////////////////////////////////////////////////////////////////////////////
1767/// Set color index for text
1768
1773
1774////////////////////////////////////////////////////////////////////////////////
1775/// Draw text
1776///
1777/// - xx: x position of the text
1778/// - yy: y position of the text
1779/// - chars: text to be drawn
1780
1782{
1783 if (fTextSize <= 0) return;
1784
1785 const Double_t kDEGRAD = TMath::Pi()/180.;
1786 char str[8];
1787 Double_t x = xx;
1788 Double_t y = yy;
1789
1790 // Font and text size
1791 Int_t font = abs(fTextFont)/10;
1792 if (font > kNumberOfFonts || font < 1) font = 1;
1793
1794 Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
1795 Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
1797 if (wh < hh) {
1798 tsize = fTextSize*wh;
1799 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
1800 ftsize = (sizeTTF*fXsize*gPad->GetAbsWNDC())/wh;
1801 } else {
1802 tsize = fTextSize*hh;
1803 Int_t sizeTTF = (Int_t)(tsize*kScale+0.5); // TTF size
1804 ftsize = (sizeTTF*fYsize*gPad->GetAbsHNDC())/hh;
1805 }
1806 Double_t fontsize = 72*(ftsize)/2.54;
1807 if (fontsize <= 0) return;
1808
1809 // Text color
1811
1812 // Clipping
1813 PrintStr(" q");
1814 Double_t x1 = XtoPDF(gPad->GetX1());
1815 Double_t x2 = XtoPDF(gPad->GetX2());
1816 Double_t y1 = YtoPDF(gPad->GetY1());
1817 Double_t y2 = YtoPDF(gPad->GetY2());
1818 WriteReal(x1);
1819 WriteReal(y1);
1820 WriteReal(x2 - x1);
1821 WriteReal(y2 - y1);
1822 PrintStr(" re W n");
1823
1824 // Start the text
1825 if (!fCompress) PrintStr("@");
1826
1827 // Text alignment
1828 Float_t tsizex = gPad->AbsPixeltoX(Int_t(tsize))-gPad->AbsPixeltoX(0);
1829 Float_t tsizey = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(Int_t(tsize));
1830 Int_t txalh = fTextAlign/10;
1831 if (txalh < 1) txalh = 1; else if (txalh > 3) txalh = 3;
1832 Int_t txalv = fTextAlign%10;
1833 if (txalv < 1) txalv = 1; else if (txalv > 3) txalv = 3;
1834 if (txalv == 3) {
1837 } else if (txalv == 2) {
1840 }
1841
1842 if (txalh > 1) {
1843 TText t;
1844 UInt_t w=0, h;
1847 t.GetTextExtent(w, h, chars);
1848 Double_t twx = gPad->AbsPixeltoX(w)-gPad->AbsPixeltoX(0);
1849 Double_t twy = gPad->AbsPixeltoY(0)-gPad->AbsPixeltoY(w);
1850 if (txalh == 2) {
1853 }
1854 if (txalh == 3) {
1857 }
1858 }
1859
1860 // Text angle
1861 Double_t a, b, c, d, e, f;
1862 if (fTextAngle == 0) {
1863 a = 1;
1864 b = 0;
1865 c = 0;
1866 d = 1;
1867 e = XtoPDF(x);
1868 f = YtoPDF(y);
1869 } else if (fTextAngle == 90) {
1870 a = 0;
1871 b = 1;
1872 c = -1;
1873 d = 0;
1874 e = XtoPDF(x);
1875 f = YtoPDF(y);
1876 } else if (fTextAngle == 270) {
1877 a = 0;
1878 b = -1;
1879 c = 1;
1880 d = 0;
1881 e = XtoPDF(x);
1882 f = YtoPDF(y);
1883 } else {
1888 e = XtoPDF(x);
1889 f = YtoPDF(y);
1890 }
1891 WriteCM(a, b, c, d, e, f, kFALSE);
1892
1893 // Symbol Italic tan(15) = .26794
1894 if (font == 15)
1895 WriteCM(1, 0, 0.26794, 1, 0, 0, kFALSE);
1896
1897 if (fUrl)
1898 ComputeRect(chars, fontsize, a, b, c, d, e, f);
1899
1900 PrintStr(" BT");
1901
1902 snprintf(str,8," /F%d",font);
1903 PrintStr(str);
1905 PrintStr(" Tf");
1906
1907 const Int_t len=strlen(chars);
1908
1909 // Calculate the individual character placements.
1910 // Otherwise, if a string is printed in one line the kerning is not
1911 // performed. In order to measure the precise character positions we need to
1912 // trick FreeType into rendering high-resolution characters otherwise it will
1913 // stick to the screen pixel grid which is far worse than we can achieve on
1914 // print.
1915 const Float_t scale = 16.0;
1916 // Save current text attributes.
1918 saveAttText.TAttText::operator=(*this);
1919 TText t;
1922 UInt_t wa1=0, wa0=0;
1925 t.TAttText::Modify();
1927 if (wa0-wa1 != 0) kerning = kTRUE;
1928 else kerning = kFALSE;
1929 Int_t *charDeltas = nullptr;
1930 if (kerning) {
1931 charDeltas = new Int_t[len];
1932 for (Int_t i = 0;i < len;i++) {
1933 UInt_t ww=0;
1934 t.GetTextAdvance(ww, chars + i);
1935 charDeltas[i] = wa1 - ww;
1936 }
1937 for (Int_t i = len - 1;i > 0;i--) {
1938 charDeltas[i] -= charDeltas[i-1];
1939 }
1940 char tmp[2];
1941 tmp[1] = 0;
1942 for (Int_t i = 1;i < len;i++) {
1943 tmp[0] = chars[i-1];
1944 UInt_t width=0;
1945 t.GetTextAdvance(width, &tmp[0], kFALSE);
1946 Double_t wwl = gPad->AbsPixeltoX(width - charDeltas[i]) - gPad->AbsPixeltoX(0);
1947 wwl -= 0.5*(gPad->AbsPixeltoX(1) - gPad->AbsPixeltoX(0)); // half a pixel ~ rounding error
1948 charDeltas[i] = (Int_t)((1000.0/Float_t(fontsize))*(XtoPDF(wwl) - XtoPDF(0))/scale);
1949 }
1950 }
1951 // Restore text attributes.
1952 saveAttText.TAttText::Modify();
1953
1954 // Output the text. Escape some characters if needed
1955 if (kerning) PrintStr(" [");
1956 else PrintStr(" (");
1957
1958 for (Int_t i=0; i<len;i++) {
1959 if (chars[i]!='\n') {
1960 if (kerning) PrintStr("(");
1961 if (chars[i]=='(' || chars[i]==')') {
1962 snprintf(str,8,"\\%c",chars[i]);
1963 } else {
1964 snprintf(str,8,"%c",chars[i]);
1965 }
1966 PrintStr(str);
1967 if (kerning) {
1968 PrintStr(") ");
1969 if (i < len-1) {
1971 }
1972 }
1973 }
1974 }
1975
1976 if (kerning) PrintStr("] TJ ET Q");
1977 else PrintStr(") Tj ET Q");
1978 if (!fCompress) PrintStr("@");
1979 if (kerning) delete [] charDeltas;
1980}
1981
1982////////////////////////////////////////////////////////////////////////////////
1983/// Write a string of characters
1984///
1985/// This method writes the string chars into a PDF file
1986/// at position xx,yy in world coordinates.
1987
1988void TPDF::Text(Double_t, Double_t, const wchar_t *)
1989{
1990}
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Draw text with URL. Same as Text.
1994///
1995
1996void TPDF::TextUrl(Double_t x, Double_t y, const char *chars, const char *url)
1997{
1998 fUrl = kTRUE;
1999 Text(x, y, chars);
2000 fNbUrl++;
2001 fUrls.push_back(url);
2002 fUrl = kFALSE;
2003}
2004
2005////////////////////////////////////////////////////////////////////////////////
2006/// Write a string of characters in NDC
2007
2009{
2010 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2011 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2012 Text(x, y, chars);
2013}
2014
2015////////////////////////////////////////////////////////////////////////////////
2016/// Write a string of characters in NDC
2017
2018void TPDF::TextNDC(Double_t u, Double_t v, const wchar_t *chars)
2019{
2020 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
2021 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
2022 Text(x, y, chars);
2023}
2024
2025////////////////////////////////////////////////////////////////////////////////
2026/// Convert U from NDC coordinate to PDF
2027
2029{
2030 Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
2031 return 72*cm/2.54;
2032}
2033
2034////////////////////////////////////////////////////////////////////////////////
2035/// Convert V from NDC coordinate to PDF
2036
2038{
2039 Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
2040 return 72*cm/2.54;
2041}
2042
2043////////////////////////////////////////////////////////////////////////////////
2044/// Convert X from world coordinate to PDF
2045
2047{
2048 Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
2049 return UtoPDF(u);
2050}
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Convert Y from world coordinate to PDF
2054
2056{
2057 Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
2058 return VtoPDF(v);
2059}
2060
2061////////////////////////////////////////////////////////////////////////////////
2062/// Write the buffer in a compressed way
2063
2065{
2066 z_stream stream;
2067 int err;
2068 char *out = new char[2*fLenBuffer];
2069
2070 stream.next_in = (Bytef*)fBuffer;
2071 stream.avail_in = (uInt)fLenBuffer;
2072 stream.next_out = (Bytef*)out;
2073 stream.avail_out = (uInt)2*fLenBuffer;
2074 stream.zalloc = (alloc_func)nullptr;
2075 stream.zfree = (free_func)nullptr;
2076 stream.opaque = (voidpf)nullptr;
2077
2078 err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
2079 if (err != Z_OK) {
2080 Error("WriteCompressedBuffer", "error in deflateInit (zlib)");
2081 delete [] out;
2082 return;
2083 }
2084
2085 err = deflate(&stream, Z_FINISH);
2086 if (err != Z_STREAM_END) {
2087 deflateEnd(&stream);
2088 Error("WriteCompressedBuffer", "error in deflate (zlib)");
2089 delete [] out;
2090 return;
2091 }
2092
2093 err = deflateEnd(&stream);
2094 if (err != Z_OK) {
2095 Error("WriteCompressedBuffer", "error in deflateEnd (zlib)");
2096 }
2097
2098 fStream->write(out, stream.total_out);
2099
2100 fNByte += stream.total_out;
2101 fStream->write("\n",1); fNByte++;
2102 fLenBuffer = 0;
2103 delete [] out;
2104 fCompress = kFALSE;
2105}
2106
2107////////////////////////////////////////////////////////////////////////////////
2108/// Write a Real number to the file.
2109/// This method overwrites TVirtualPS::WriteReal. Some PDF reader like
2110/// Acrobat do not work when a PDF file contains reals with exponent. This
2111/// method writes the real number "z" using the format "%f" instead of the
2112/// format "%g" when writing it with "%g" generates a number with exponent.
2113
2115{
2116 char str[15];
2117 if (space) {
2118 snprintf(str,15," %g", z);
2119 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15," %10.8f", z);
2120 } else {
2121 snprintf(str,15,"%g", z);
2122 if (strstr(str,"e") || strstr(str,"E")) snprintf(str,15,"%10.8f", z);
2123 }
2124 PrintStr(str);
2125}
2126
2127////////////////////////////////////////////////////////////////////////////////
2128/// Patterns encoding
2129
2131{
2133
2135 if (gStyle->GetColorModelPS()) {
2136 PrintStr("[/Pattern /DeviceCMYK]@");
2137 } else {
2138 PrintStr("[/Pattern /DeviceRGB]@");
2139 }
2140 EndObject();
2142 PrintStr("<</ProcSet[/PDF]>>@");
2143 EndObject();
2144
2146 PrintStr("<<@");
2147 PrintStr(" /P01");
2149 PrintStr(" 0 R");
2150 PrintStr(" /P02");
2152 PrintStr(" 0 R");
2153 PrintStr(" /P03");
2155 PrintStr(" 0 R");
2156 PrintStr(" /P04");
2158 PrintStr(" 0 R");
2159 PrintStr(" /P05");
2161 PrintStr(" 0 R");
2162 PrintStr(" /P06");
2164 PrintStr(" 0 R");
2165 PrintStr(" /P07");
2167 PrintStr(" 0 R");
2168 PrintStr(" /P08");
2170 PrintStr(" 0 R");
2171 PrintStr(" /P09");
2173 PrintStr(" 0 R");
2174 PrintStr(" /P10");
2176 PrintStr(" 0 R");
2177 PrintStr(" /P11");
2179 PrintStr(" 0 R");
2180 PrintStr(" /P12");
2182 PrintStr(" 0 R");
2183 PrintStr(" /P13");
2185 PrintStr(" 0 R");
2186 PrintStr(" /P14");
2188 PrintStr(" 0 R");
2189 PrintStr(" /P15");
2191 PrintStr(" 0 R");
2192 PrintStr(" /P16");
2194 PrintStr(" 0 R");
2195 PrintStr(" /P17");
2197 PrintStr(" 0 R");
2198 PrintStr(" /P18");
2200 PrintStr(" 0 R");
2201 PrintStr(" /P19");
2203 PrintStr(" 0 R");
2204 PrintStr(" /P20");
2206 PrintStr(" 0 R");
2207 PrintStr(" /P21");
2209 PrintStr(" 0 R");
2210 PrintStr(" /P22");
2212 PrintStr(" 0 R");
2213 PrintStr(" /P23");
2215 PrintStr(" 0 R");
2216 PrintStr(" /P24");
2218 PrintStr(" 0 R");
2219 PrintStr(" /P25");
2221 PrintStr(" 0 R@");
2222 PrintStr(">>@");
2223 EndObject();
2224
2226
2227 // P01
2229 PrintStr("<</Type/Pattern/Matrix[1 0 0 1 20 28]/PatternType 1/Resources");
2231 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 98 4]/XStep 98/YStep 4/Length 91/Filter/FlateDecode>>");
2232 PrintStr("@");
2233 fStream->write("stream",6); fNByte += 6;
2234 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);
2235 fNByte += 93;
2236 PrintStr("endstream@");
2237 EndObject();
2238
2239 // P02
2241 PrintStr("<</Type/Pattern/Matrix[0.75 0 0 0.75 20 28]/PatternType 1/Resources");
2243 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 4]/XStep 96/YStep 4/Length 92/Filter/FlateDecode>>@");
2244 PrintStr("@");
2245 fStream->write("stream",6); fNByte += 6;
2246 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);
2247 fNByte += 94;
2248 PrintStr("endstream@");
2249 EndObject();
2250
2251 // P03
2253 PrintStr("<</Type/Pattern/Matrix[0.5 0 0 0.5 20 28]/PatternType 1/Resources");
2255 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 96 16]/XStep 96/YStep 16/Length 93/Filter/FlateDecode>>@");
2256 PrintStr("@");
2257 fStream->write("stream",6); fNByte += 6;
2258 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);
2259 fNByte += 95;
2260 PrintStr("endstream@");
2261 EndObject();
2262
2263 // P04
2265 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2267 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 63/Filter/FlateDecode>>");
2268 PrintStr("@");
2269 fStream->write("stream",6); fNByte += 6;
2270 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);
2271 fNByte += 65;
2272 PrintStr("endstream@");
2273 EndObject();
2274
2275 // P05
2277 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2279 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2280 PrintStr("@");
2281 fStream->write("stream",6); fNByte += 6;
2282 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);
2283 fNByte += 68;
2284 PrintStr("endstream@");
2285 EndObject();
2286
2287 // P06
2289 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2291 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2292 PrintStr("@");
2293 fStream->write("stream",6); fNByte += 6;
2294 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);
2295 fNByte += 68;
2296 PrintStr("endstream@");
2297 EndObject();
2298
2299 // P07
2301 PrintStr("<</Type/Pattern/Matrix[0.03 0 0 0.03 20 28]/PatternType 1/Resources");
2303 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 68/Filter/FlateDecode>>");
2304 PrintStr("@");
2305 fStream->write("stream",6); fNByte += 6;
2306 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);
2307 fNByte += 70;
2308 PrintStr("endstream@");
2309 EndObject();
2310
2311 // P08
2313 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2315 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 139/Filter/FlateDecode>>");
2316 PrintStr("@");
2317 fStream->write("stream",6); fNByte += 6;
2318 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);
2319 fNByte += 141;
2320 PrintStr("endstream@");
2321 EndObject();
2322
2323 // P09
2325 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2327 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 108/Filter/FlateDecode>>");
2328 PrintStr("@");
2329 fStream->write("stream",6); fNByte += 6;
2330 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);
2331 fNByte += 110;
2332 PrintStr("endstream@");
2333 EndObject();
2334
2335 // P10
2337 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2339 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 93/Filter/FlateDecode>>");
2340 PrintStr("@");
2341 fStream->write("stream",6); fNByte += 6;
2342 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);
2343 fNByte += 95;
2344 PrintStr("endstream@");
2345 EndObject();
2346
2347 // P11
2349 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2351 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 164/Filter/FlateDecode>>");
2352 PrintStr("@");
2353 fStream->write("stream",6); fNByte += 6;
2354 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);
2355 fNByte += 166;
2356 PrintStr("endstream@");
2357 EndObject();
2358
2359 // P12
2361 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2363 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 226/Filter/FlateDecode>>");
2364 PrintStr("@");
2365 fStream->write("stream",6); fNByte += 6;
2366 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);
2367 fNByte += 228;
2368 PrintStr("endstream@");
2369 EndObject();
2370
2371 // P13
2373 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2375 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2376 PrintStr("@");
2377 fStream->write("stream",6); fNByte += 6;
2378 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);
2379 fNByte += 71;
2380 PrintStr("endstream@");
2381 EndObject();
2382
2383 // P14
2385 PrintStr("<</Type/Pattern/Matrix[0.15 0 0 0.15 20 28]/PatternType 1/Resources");
2387 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 80/YStep 80/Length 114/Filter/FlateDecode>>");
2388 PrintStr("@");
2389 fStream->write("stream",6); fNByte += 6;
2390 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);
2391 fNByte += 116;
2392 PrintStr("endstream@");
2393 EndObject();
2394
2395 // P15
2397 PrintStr("<</Type/Pattern/Matrix[0.102 0 0 0.102 20 28]/PatternType 1/Resources");
2399 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 60 60]/XStep 60/YStep 60/Length 218/Filter/FlateDecode>>");
2400 PrintStr("@");
2401 fStream->write("stream",6); fNByte += 6;
2402 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);
2403 fNByte += 220;
2404 PrintStr("endstream@");
2405 EndObject();
2406
2407 // P16
2409 PrintStr("<</Type/Pattern/Matrix[0.1 0 0 0.05 20 28]/PatternType 1/Resources");
2411 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 123/Filter/FlateDecode>>");
2412 PrintStr("@");
2413 fStream->write("stream",6); fNByte += 6;
2414 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);
2415 fNByte += 125;
2416 PrintStr("endstream@");
2417 EndObject();
2418
2419 // P17
2421 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2423 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 66/Filter/FlateDecode>>");
2424 PrintStr("@");
2425 fStream->write("stream",6); fNByte += 6;
2426 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);
2427 fNByte += 68;
2428 PrintStr("endstream@");
2429 EndObject();
2430
2431 // P18
2433 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2435 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 69/Filter/FlateDecode>>");
2436 PrintStr("@");
2437 fStream->write("stream",6); fNByte += 6;
2438 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);
2439 fNByte += 71;
2440 PrintStr("endstream@");
2441 EndObject();
2442
2443 // P19
2445 PrintStr("<</Type/Pattern/Matrix[0.117 0 0 0.117 20 28]/PatternType 1/Resources");
2447 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 149/Filter/FlateDecode>>");
2448 PrintStr("@");
2449 fStream->write("stream",6); fNByte += 6;
2450 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);
2451 fNByte += 151;
2452 PrintStr("endstream@");
2453 EndObject();
2454
2455 // P20
2457 PrintStr("<</Type/Pattern/Matrix[0.05 0 0 0.1 20 28]/PatternType 1/Resources");
2459 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 122/Filter/FlateDecode>>");
2460 PrintStr("@");
2461 fStream->write("stream",6); fNByte += 6;
2462 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);
2463 fNByte += 124;
2464 PrintStr("endstream@");
2465 EndObject();
2466
2467 // P21
2469 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2471 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 117/Filter/FlateDecode>>");
2472 PrintStr("@");
2473 fStream->write("stream",6); fNByte += 6;
2474 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);
2475 fNByte += 119;
2476 PrintStr("endstream@");
2477 EndObject();
2478
2479 // P22
2481 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2483 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 118/Filter/FlateDecode>>");
2484 PrintStr("@");
2485 fStream->write("stream",6); fNByte += 6;
2486 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);
2487 fNByte += 120;
2488 PrintStr("endstream@");
2489 EndObject();
2490
2491 // P23
2493 PrintStr("<</Type/Pattern/Matrix[0.06 0 0 0.06 20 28]/PatternType 1/Resources");
2495 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 169/Filter/FlateDecode>>");
2496 PrintStr("@");
2497 fStream->write("stream",6); fNByte += 6;
2498 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);
2499 fNByte += 171;
2500 PrintStr("endstream@");
2501 EndObject();
2502
2503 // P24
2505 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2507 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 100 100]/XStep 100/YStep 100/Length 280/Filter/FlateDecode>>");
2508 PrintStr("@");
2509 fStream->write("stream",6); fNByte += 6;
2510 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);
2511 fNByte += 282;
2512 PrintStr("endstream@");
2513 EndObject();
2514
2515 // P25
2517 PrintStr("<</Type/Pattern/Matrix[0.125 0 0 0.125 20 28]/PatternType 1/Resources");
2519 PrintStr(" 0 R/PaintType 2/TilingType 1/BBox[0 0 101 101]/XStep 100/YStep 100/Length 54/Filter/FlateDecode>>");
2520 PrintStr("@");
2521 fStream->write("stream",6); fNByte += 6;
2522 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);
2523 fNByte += 56;
2524 PrintStr("endstream@");
2525 EndObject();
2526}
2527
2528////////////////////////////////////////////////////////////////////////////////
2529/// Write and Accumulate (if `acc` is true) the Current Transformation Matrix (CTM)
2530///
2531/// The Current Transformation Matrix (CTM, not CMT) is defined by the six parameters
2532/// `a` `b` `c` `d` `e` `f` passed to the PDF `cm` operator (see the PDF Reference Guide
2533/// page 156 [1] for details).
2534///
2535/// To correctly define the \Rect fields of the Annots created for each #url, one must keep
2536/// track of the current CTM and apply it to the last transformation matrix used for the
2537/// text (for example rotations).
2538///
2539/// [1] https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.4.pdf
2540
2542{
2543 WriteReal(a);
2544 WriteReal(b);
2545 WriteReal(c);
2546 WriteReal(d);
2547 WriteReal(e);
2548 WriteReal(f);
2549 PrintStr(" cm");
2550
2551 // accumulate in CTM ---
2552 if (acc) {
2553 Double_t na, nb, nc, nd, ne, nf;
2554 na = fA * a + fC * b;
2555 nb = fB * a + fD * b;
2556 nc = fA * c + fC * d;
2557 nd = fB * c + fD * d;
2558 ne = fA * e + fC * f + fE;
2559 nf = fB * e + fD * f + fF;
2560 fA = na;
2561 fB = nb;
2562 fC = nc;
2563 fD = nd;
2564 fE = ne;
2565 fF = nf;
2566 }
2567}
2568
2569////////////////////////////////////////////////////////////////////////////////
2570/// Write the annotation objects containing the URLs
2571
2573{
2574 int i;
2576 PrintStr("@");
2577 PrintStr("[");
2578 for (i = 0; i < fNbUrl - 1; i++) {
2579 WriteInteger(fCurrentPage + 5 + i);
2580 PrintStr(" 0 R");
2581 }
2582 PrintStr(" ]@");
2583 EndObject();
2584 for (i = 0; i < fNbUrl - 1; i++) {
2585 NewObject(fCurrentPage + 5 + i);
2586 PrintStr("<<@");
2587 PrintStr("/Type /Annot@");
2588 PrintStr("/Subtype /Link@");
2589 PrintStr("/Rect [");
2591 WriteReal(fRectY1[i]);
2592 WriteReal(fRectX2[i]);
2593 WriteReal(fRectY2[i]);
2594 PrintStr("]@");
2595 PrintStr("/Border [0 0 0]@");
2596 PrintStr("/A << /S /URI /URI (");
2597 PrintStr(fUrls[i].c_str());
2598 PrintStr(") >>@");
2599 PrintStr(">>@");
2600 EndObject();
2601 }
2602 if (!fUrls.empty())
2603 fUrls.clear();
2604 if (!fRectX1.empty())
2605 fRectX1.clear();
2606 if (!fRectY1.empty())
2607 fRectY1.clear();
2608 if (!fRectX2.empty())
2609 fRectX2.clear();
2610 if (!fRectY2.empty())
2611 fRectY2.clear();
2612}
2613
2614////////////////////////////////////////////////////////////////////////////////
2615/// Compute the Rect for url
2616
2619{
2620 double W = 0.52 * fontsize * strlen(chars);
2621 double ascent = 0.72 * fontsize;
2622 double descent = 0.22 * fontsize;
2623
2624 int ax = fTextAlign / 10;
2625 int ay = fTextAlign % 10;
2626 double xShift = 0;
2627 double yShift = 0;
2628 if (ax == 2)
2629 xShift = -W / 2.0;
2630 if (ax == 3)
2631 xShift = -W;
2632 if (ay == 2)
2633 yShift = -(ascent - descent) / 2.0;
2634 if (ay == 3)
2635 yShift = -ascent;
2636 double x1 = xShift;
2637 double x2 = xShift + W;
2638 double y1 = -descent + yShift;
2639 double y2 = ascent + yShift;
2640
2641 Double_t A, B, C, D, E, F;
2642 A = fA * a + fC * b;
2643 B = fB * a + fD * b;
2644 C = fA * c + fC * d;
2645 D = fB * c + fD * d;
2646 E = fA * e + fC * f + fE;
2647 F = fB * e + fD * f + fF;
2648
2649 double bx1 = A * x1 + C * y1 + E;
2650 double by1 = B * x1 + D * y1 + F;
2651 double bx2 = A * x2 + C * y1 + E;
2652 double by2 = B * x2 + D * y1 + F;
2653 double bx3 = A * x2 + C * y2 + E;
2654 double by3 = B * x2 + D * y2 + F;
2655 double bx4 = A * x1 + C * y2 + E;
2656 double by4 = B * x1 + D * y2 + F;
2657
2658 double xmin = bx1;
2659 double xmax = bx1;
2660 double ymin = by1;
2661 double ymax = by1;
2662
2663 if (bx2 < xmin)
2664 xmin = bx2;
2665 if (bx3 < xmin)
2666 xmin = bx3;
2667 if (bx4 < xmin)
2668 xmin = bx4;
2669 if (bx2 > xmax)
2670 xmax = bx2;
2671 if (bx3 > xmax)
2672 xmax = bx3;
2673 if (bx4 > xmax)
2674 xmax = bx4;
2675 if (by2 < ymin)
2676 ymin = by2;
2677 if (by3 < ymin)
2678 ymin = by3;
2679 if (by4 < ymin)
2680 ymin = by4;
2681 if (by2 > ymax)
2682 ymax = by2;
2683 if (by3 > ymax)
2684 ymax = by3;
2685 if (by4 > ymax)
2686 ymax = by4;
2687
2688 fRectX1.push_back(xmin);
2689 fRectY1.push_back(ymin);
2690 fRectX2.push_back(xmax);
2691 fRectY2.push_back(ymax);
2692}
#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:97
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
short Color_t
Color number (short)
Definition RtypesCore.h:100
short Width_t
Line width (short)
Definition RtypesCore.h:99
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
double Double_t
Double 8 bytes.
Definition RtypesCore.h:74
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
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 TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
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:87
const Int_t kObjPatternList
Definition TPDF.cxx:90
const Int_t kObjInfo
Definition TPDF.cxx:82
const Int_t kObjRoot
Definition TPDF.cxx:81
const Float_t kScale
Definition TPDF.cxx:78
const Int_t kObjColorSpace
Definition TPDF.cxx:88
const Int_t kNumberOfFonts
Definition TPDF.cxx:97
const Int_t kObjPattern
Definition TPDF.cxx:92
const Int_t kObjContents
Definition TPDF.cxx:86
const Int_t kObjFirstPage
Definition TPDF.cxx:94
const Int_t kObjPages
Definition TPDF.cxx:84
const Int_t kObjPageResources
Definition TPDF.cxx:85
const Int_t kObjPatternResourses
Definition TPDF.cxx:89
const Int_t kObjImageList
Definition TPDF.cxx:93
const Int_t kObjTransList
Definition TPDF.cxx:91
const Int_t kObjOutlines
Definition TPDF.cxx:83
#define gROOT
Definition TROOT.h:417
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
R__EXTERN TVirtualPS * gVirtualPS
Definition TVirtualPS.h:88
#define gPad
Style_t fFillStyle
Fill area style.
Definition TAttFill.h:25
Color_t fFillColor
Fill area color.
Definition TAttFill.h:24
virtual Width_t GetLineWidth() const
Return the line width.
Definition TAttLine.h:38
Width_t fLineWidth
Line width.
Definition TAttLine.h:26
virtual Style_t GetLineStyle() const
Return the line style.
Definition TAttLine.h:37
Style_t fLineStyle
Line style.
Definition TAttLine.h:25
Color_t fLineColor
Line color.
Definition TAttLine.h:24
virtual Style_t GetMarkerStyle() const
Return the marker style.
Definition TAttMarker.h:35
virtual Color_t GetMarkerColor() const
Return the marker color.
Definition TAttMarker.h:34
Color_t fMarkerColor
Marker color.
Definition TAttMarker.h:25
EMarkerShape GetMarkerShape(Int_t &sz, std::vector< TPoint > &points, Float_t scale=1., UInt_t flags=0) const
Return marker shape.
static Width_t GetMarkerLineWidth(Style_t style)
Internal helper function that returns the line width of the given marker style (0 = filled marker)
@ kShapeTriangles
Definition TAttMarker.h:48
@ kShapeFilledArea
Definition TAttMarker.h:48
@ kShapeFilledCircle
Definition TAttMarker.h:48
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:1939
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:1082
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
void SetLineStyle(Style_t linestyle=1) override
Change the line style.
Definition TPDF.cxx:1729
void Off()
Deactivate an already open PDF file.
Definition TPDF.cxx:1271
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:1761
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:1535
void PrintPolyMarkerShape(Int_t n, T *x, T *y)
Definition TPDF.cxx:714
Double_t YtoPDF(Double_t y)
Convert Y from world coordinate to PDF.
Definition TPDF.cxx:2055
void Open(const char *filename, Int_t type=-111) override
Open a PDF file.
Definition TPDF.cxx:1295
void Close(Option_t *opt="") override
Close a PDF file.
Definition TPDF.cxx:265
std::vector< Int_t > fObjPos
Objects position.
Definition TPDF.h:46
TPDF()
Default PDF constructor.
Definition TPDF.cxx:106
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimetres.
Definition TPDF.cxx:1505
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:1038
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:1714
Double_t XtoPDF(Double_t x)
Convert X from world coordinate to PDF.
Definition TPDF.cxx:2046
void WriteReal(Float_t r, Bool_t space=kTRUE) override
Write a Real number to the file.
Definition TPDF.cxx:2114
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:1690
Double_t CMtoPDF(Double_t u)
Definition TPDF.h:107
void CellArrayEnd() override
End the Cell Array painting.
Definition TPDF.cxx:202
Double_t fCellArrayWpdf
! PDF width of the image
Definition TPDF.h:75
void NewPage() override
Start a new PDF page.
Definition TPDF.cxx:1077
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:1608
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:1279
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:486
void SetLineColor(Color_t cindex=1) override
Set color index for lines.
Definition TPDF.cxx:1668
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:2617
void FontEncode()
Font encoding.
Definition TPDF.cxx:1006
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:1996
void DrawPS(Int_t n, Float_t *xw, Float_t *yw) override
Draw a PolyLine.
Definition TPDF.cxx:828
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:2028
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:1515
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:804
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:1048
void SetLineScale(Float_t scale=1)
Definition TPDF.h:141
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:552
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:176
~TPDF() override
Default PDF destructor.
Definition TPDF.cxx:132
void WriteUrlObjects()
Write the annotation objects containing the URLs.
Definition TPDF.cxx:2572
void EnsureBufferSize(Int_t required_size)
Ensure that required space in the buffer is available.
Definition TPDF.cxx:1459
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:994
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:1472
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:1616
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:2541
void SetTextColor(Color_t cindex=1) override
Set color index for text.
Definition TPDF.cxx:1769
void DrawPolyLineNDC(Int_t n, TPoints *uv)
Draw a PolyLine in NDC space.
Definition TPDF.cxx:670
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:147
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:592
void SetLineWidth(Width_t linewidth=1) override
Change the line width.
Definition TPDF.cxx:1748
Double_t VtoPDF(Double_t v)
Convert V from NDC coordinate to PDF.
Definition TPDF.cxx:2037
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:1058
void DrawPolyLine(Int_t n, TPoints *xy)
Draw a PolyLine.
Definition TPDF.cxx:616
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:1781
void PatternEncode()
Patterns encoding.
Definition TPDF.cxx:2130
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:2064
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
Definition TPDF.cxx:2008
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:1490
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:2459
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
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:249
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:734
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:607
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:601
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