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