Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSVG.cxx
Go to the documentation of this file.
1// @(#)root/postscript:$Id$
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#ifdef WIN32
13#pragma optimize("",off)
14#endif
15
16#include <cstdlib>
17#include <cstring>
18#include <cctype>
19#include <cmath>
20#include <fstream>
21
22#include "TROOT.h"
23#include "TDatime.h"
24#include "TColor.h"
25#include "TVirtualPad.h"
26#include "TPoints.h"
27#include "TSVG.h"
28#include "TStyle.h"
29#include "TMath.h"
30#include "TObjString.h"
31#include "TObjArray.h"
32#include "snprintf.h"
33
36
37const Double_t kEpsilon = 1e-9;
38
39/** \class TSVG
40\ingroup PS
41
42\brief Interface to SVG
43
44[SVG](http://www.w3.org/Graphics/SVG/Overview.htm8)
45(Scalable Vector Graphics) is a language for describing
46two-dimensional graphics in XML. SVG allows high quality vector graphics in
47HTML pages.
48
49To print a ROOT canvas "c1" into an SVG file simply do:
50~~~ {.cpp}
51 c1->Print("c1.svg");
52~~~
53The result is the ASCII file `c1.svg`.
54
55It can be open directly using a web browser or included in a html document
56the following way:
57~~~ {.cpp}
58<embed width="95%" height="500" src="c1.svg">
59~~~
60It is best viewed with Internet Explorer and you need the
61[Adobe SVG Viewer](http://www.adobe.com/svg/viewer/install/main.html)
62
63To zoom using the Adobe SVG Viewer, position the mouse over
64the area you want to zoom and click the right button.
65
66To define the zoom area,
67use Control+drag to mark the boundaries of the zoom area.
68
69To pan, use Alt+drag.
70By clicking with the right mouse button on the SVG graphics you will get
71a pop-up menu giving other ways to interact with the image.
72
73SVG files can be used directly in compressed mode to minimize the time
74transfer over the network. Compressed SVG files should be created using
75`gzip` on a normal ASCII SVG file and should then be renamed
76using the file extension `.svgz`.
77*/
78
79////////////////////////////////////////////////////////////////////////////////
80/// Default SVG constructor
81
83{
84 fStream = nullptr;
85 fType = 0;
87 gVirtualPS = this;
89 fRange = kFALSE;
90 fXsize = 0.;
91 fYsize = 0.;
92 fYsizeSVG = 0;
93 SetTitle("SVG");
94}
95
96////////////////////////////////////////////////////////////////////////////////
97/// Initialize the SVG interface
98///
99/// - fname : SVG file name
100/// - wtype : SVG workstation type. Not used in the SVG driver. But as TSVG
101/// inherits from TVirtualPS it should be kept. Anyway it is not
102/// necessary to specify this parameter at creation time because it
103/// has a default value (which is ignore in the SVG case).
104
106{
107 fStream = nullptr;
108 SetTitle("SVG");
110 Open(fname, wtype);
111}
112
113////////////////////////////////////////////////////////////////////////////////
114/// Open a SVG file
115
116void TSVG::Open(const char *fname, Int_t wtype)
117{
118 if (fStream) {
119 Warning("Open", "SVG file already open");
120 return;
121 }
122
123 fLenBuffer = 0;
124 fType = abs(wtype);
130 if (gPad) {
131 Double_t ww = gPad->GetWw();
132 Double_t wh = gPad->GetWh();
133 ww *= gPad->GetWNDC();
134 wh *= gPad->GetHNDC();
135 Double_t ratio = wh/ww;
136 xrange = fXsize;
137 yrange = fXsize*ratio;
138 if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
140 }
141
142 // Open OS file
143 fStream = new std::ofstream(fname,std::ios::out);
144 if (!fStream || !fStream->good()) {
145 printf("ERROR in TSVG::Open: Cannot open file:%s\n",fname);
146 if (!fStream) return;
147 }
148
149 gVirtualPS = this;
150
151 for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
152
154
155 fRange = kFALSE;
156
157 // Set a default range
159
160 NewPage();
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Default SVG destructor
165
167{
168 Close();
169}
170
171////////////////////////////////////////////////////////////////////////////////
172/// Close a SVG file
173
175{
176 if (!gVirtualPS) return;
177 if (!fStream) return;
178 if (gPad) gPad->Update();
179 PrintStr("</svg>@");
180
181 // Close file stream
182 if (fStream) { fStream->close(); delete fStream; fStream = nullptr;}
183
184 gVirtualPS = nullptr;
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Activate an already open SVG file
189
191{
192 // fType is used to know if the SVG file is open. Unlike TPostScript, TSVG
193 // has no "workstation type". In fact there is only one SVG type.
194
195 if (!fType) {
196 Error("On", "no SVG file open");
197 Off();
198 return;
199 }
200 gVirtualPS = this;
201}
202
203////////////////////////////////////////////////////////////////////////////////
204/// Deactivate an already open SVG file
205
207{
208 gVirtualPS = nullptr;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Draw a Box
213
215{
216 static Double_t x[4], y[4];
221 Int_t fillis = fFillStyle/1000;
222 Int_t fillsi = fFillStyle%1000;
223
224 if (fillis == 3 || fillis == 2) {
225 if (fillsi > 99) {
226 x[0] = x1; y[0] = y1;
227 x[1] = x2; y[1] = y1;
228 x[2] = x2; y[2] = y2;
229 x[3] = x1; y[3] = y2;
230 return;
231 }
232 if (fillsi > 0 && fillsi < 26) {
233 x[0] = x1; y[0] = y1;
234 x[1] = x2; y[1] = y1;
235 x[2] = x2; y[2] = y2;
236 x[3] = x1; y[3] = y2;
237 DrawPS(-4, &x[0], &y[0]);
238 }
239 if (fillsi == -3) {
240 PrintStr("@");
241 PrintFast(9,"<rect x=\"");
243 PrintFast(5,"\" y=\"");
245 PrintFast(9,"\" width=\"");
247 PrintFast(10,"\" height=\"");
249 PrintFast(7,"\" fill=");
251 PrintFast(2,"/>");
252 }
253 }
254 if (fillis == 1) {
255 PrintStr("@");
256 PrintFast(9,"<rect x=\"");
258 PrintFast(5,"\" y=\"");
260 PrintFast(9,"\" width=\"");
262 PrintFast(10,"\" height=\"");
264 PrintFast(7,"\" fill=");
266 PrintFast(2,"/>");
267 }
268 if (fillis == 0) {
269 if (fLineWidth<=0) return;
270 PrintStr("@");
271 PrintFast(9,"<rect x=\"");
273 PrintFast(5,"\" y=\"");
275 PrintFast(9,"\" width=\"");
277 PrintFast(10,"\" height=\"");
279 PrintFast(21,"\" fill=\"none\" stroke=");
281 PrintFast(2,"/>");
282 }
283}
284
285////////////////////////////////////////////////////////////////////////////////
286/// Print a svg path statement for specified points
287
289{
290 Double_t idx = 0, idy = 0;
291
292 Double_t ixd0 = convert ? XtoSVG(xps[0]) : xps[0];
293 Double_t iyd0 = convert ? YtoSVG(yps[0]) : yps[0];
295
296 PrintFast(1,"M");
298 PrintFast(1,",");
300
301 for (Int_t i = 1; i < n; i++) {
302 Double_t ixdi = convert ? XtoSVG(xps[i]) : xps[i];
303 Double_t iydi = convert ? YtoSVG(yps[i]) : yps[i];
304 Double_t ix = ixdi - ixd0;
305 Double_t iy = iydi - iyd0;
306
307 if (fCompact && (TMath::Abs(ix) < kEpsilon))
308 ix = 0;
309 if (fCompact && (TMath::Abs(iy) < kEpsilon))
310 iy = 0;
311
312 ixd0 = ixdi;
313 iyd0 = iydi;
314 if(ix && iy) {
315 if(idx) {
316 MovePS(idx, 0);
317 idx = 0;
318 }
319 if(idy) {
320 MovePS(0, idy);
321 idy = 0;
322 }
323 MovePS(ix, iy);
324 continue;
325 }
326 if (ix) {
327 if(idy) {
328 MovePS(0, idy);
329 idy = 0;
330 }
331 if(!idx || (ix*idx > 0)) {
332 idx += ix;
333 } else {
334 MovePS(idx, 0);
335 idx = ix;
336 }
337 continue;
338 }
339 if(iy) {
340 if(idx) {
341 MovePS(idx, 0);
342 idx = 0;
343 }
344 if(!idy || (iy*idy > 0)) {
345 idy += iy;
346 } else {
347 MovePS(0, idy);
348 idy = iy;
349 }
350 }
351 }
352 if(idx)
353 MovePS(idx, 0);
354 if(idy)
355 MovePS(0, idy);
356
358 PrintFast(1, "z");
359}
360
361////////////////////////////////////////////////////////////////////////////////
362/// Draw a Frame around a box
363///
364/// - mode = -1 the box looks as it is behind the screen
365/// - mode = 1 the box looks as it is in front of the screen
366/// - border is the border size in already pre-computed SVG units dark is the
367/// color for the dark part of the frame light is the color for the light
368/// part of the frame
369
371 Int_t mode, Int_t border, Int_t dark, Int_t light)
372{
373 Double_t xps[7], yps[7];
374
375 //- Draw top&left part of the box
376 xps[0] = XtoSVG(xl); yps[0] = YtoSVG(yl);
377 xps[1] = xps[0] + border; yps[1] = yps[0] - border;
378 xps[2] = xps[1]; yps[2] = YtoSVG(yt) + border;
379 xps[3] = XtoSVG(xt) - border; yps[3] = yps[2];
380 xps[4] = XtoSVG(xt); yps[4] = YtoSVG(yt);
381 xps[5] = xps[0]; yps[5] = yps[4];
382 xps[6] = xps[0]; yps[6] = yps[0];
383
384 PrintStr("@");
385 PrintFast(9,"<path d=\"");
386 PrintPath(kFALSE, 7, xps, yps);
387 PrintFast(7,"\" fill=");
388
389 SetColorAlpha(mode == -1 ? dark : light);
390
391 if (fgLineJoin)
392 PrintStr(TString::Format(" stroke-linejoin=\"%s\"", fgLineJoin == 1 ? "round" : "bevel"));
393 if (fgLineCap)
394 PrintStr(TString::Format(" stroke-linecap=\"%s\"", fgLineCap == 1 ? "round" : "square"));
395 PrintFast(2,"/>");
396
397 //- Draw bottom&right part of the box
398 xps[0] = XtoSVG(xl); yps[0] = YtoSVG(yl);
399 xps[1] = xps[0] + border; yps[1] = yps[0] - border;
400 xps[2] = XtoSVG(xt) - border; yps[2] = yps[1];
401 xps[3] = xps[2]; yps[3] = YtoSVG(yt) + border;
402 xps[4] = XtoSVG(xt); yps[4] = YtoSVG(yt);
403 xps[5] = xps[4]; yps[5] = yps[0];
404 xps[6] = xps[0]; yps[6] = yps[0];
405
406 PrintStr("@");
407 PrintFast(9,"<path d=\"");
408 PrintPath(kFALSE, 7, xps, yps);
409 PrintFast(7,"\" fill=");
410 SetColorAlpha(mode == -1 ? light : dark);
411 if (fgLineJoin)
412 PrintStr(TString::Format(" stroke-linejoin=\"%s\"", fgLineJoin == 1 ? "round" : "bevel"));
413 if (fgLineCap)
414 PrintStr(TString::Format(" stroke-linecap=\"%s\"", fgLineCap == 1 ? "round" : "square"));
415 PrintFast(2,"/>");
416}
417
418////////////////////////////////////////////////////////////////////////////////
419/// Draw a PolyLine
420///
421/// Draw a polyline through the points xy.
422/// - If NN=1 moves only to point x,y.
423/// - If NN=0 the x,y are written in the SVG file
424/// according to the current transformation.
425/// - If NN>0 the line is clipped as a line.
426/// - If NN<0 the line is clipped as a fill area.
427
429{
430 Warning("DrawPolyLine", "not implemented");
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// Draw a PolyLine in NDC space
435///
436/// Draw a polyline through the points xy.
437/// --If NN=1 moves only to point x,y.
438/// --If NN=0 the x,y are written in the SVG file
439/// according to the current transformation.
440/// --If NN>0 the line is clipped as a line.
441/// - If NN<0 the line is clipped as a fill area.
442
444{
445 Warning("DrawPolyLineNDC", "not implemented");
446}
447
448////////////////////////////////////////////////////////////////////////////////
449/// Implementation of polymarker printing
450
451template<class T>
453{
456
457 if (ms == 4)
458 ms = 24;
459 else if (ms >= 6 && ms <= 8)
460 ms = 20;
461 else if (ms >= 9 && ms <= 19)
462 ms = 1;
463
464 // Define the marker size
466 if (fMarkerStyle == 1 || (fMarkerStyle >= 9 && fMarkerStyle <= 19)) msize = 0.01;
467 if (fMarkerStyle == 6) msize = 0.02;
468 if (fMarkerStyle == 7) msize = 0.04;
469
470 const Int_t kBASEMARKER = 8;
472 Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
473 msize = this->UtoSVG(s2x) - this->UtoSVG(0);
474
475 Double_t m = msize;
476 Double_t m2 = m/2;
477 Double_t m3 = m/3;
478 Double_t m6 = m/6;
479 Double_t m4 = m/4.;
480 Double_t m8 = m/8.;
481 Double_t m0 = m/10.;
482
483 // Draw the marker according to the type
484 PrintStr("@");
485 if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
486 ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
487 ms == 47 || ms == 48 || ms == 49) {
488 PrintStr("<g fill=");
490 PrintStr(">");
491 } else {
492 PrintStr("<g stroke=");
494 PrintStr(" stroke-width=\"");
496 PrintStr("\" fill=\"none\"");
497 if (fgLineJoin)
498 PrintStr(TString::Format(" stroke-linejoin=\"%s\"", fgLineJoin == 1 ? "round" : "bevel"));
499 if (fgLineCap)
500 PrintStr(TString::Format(" stroke-linecap=\"%s\"", fgLineCap == 1 ? "round" : "square"));
501 PrintStr(">");
502 }
503 for (Int_t i = 0; i < n; i++) {
504 Double_t ix = XtoSVG(xw[i]);
505 Double_t iy = YtoSVG(yw[i]);
506 PrintStr("@");
507 // Dot (.)
508 if (ms == 1) {
509 PrintStr("<line x1=\"");
510 WriteReal(ix-1, kFALSE);
511 PrintStr("\" y1=\"");
512 WriteReal(iy, kFALSE);
513 PrintStr("\" x2=\"");
514 WriteReal(ix, kFALSE);
515 PrintStr("\" y2=\"");
516 WriteReal(iy, kFALSE);
517 PrintStr("\"/>");
518 // Plus (+)
519 } else if (ms == 2) {
520 PrintStr("<line x1=\"");
521 WriteReal(ix-m2, kFALSE);
522 PrintStr("\" y1=\"");
523 WriteReal(iy, kFALSE);
524 PrintStr("\" x2=\"");
525 WriteReal(ix+m2, kFALSE);
526 PrintStr("\" y2=\"");
527 WriteReal(iy, kFALSE);
528 PrintStr("\"/>");
529
530 PrintStr("<line x1=\"");
531 WriteReal(ix, kFALSE);
532 PrintStr("\" y1=\"");
533 WriteReal(iy-m2, kFALSE);
534 PrintStr("\" x2=\"");
535 WriteReal(ix, kFALSE);
536 PrintStr("\" y2=\"");
537 WriteReal(iy+m2, kFALSE);
538 PrintStr("\"/>");
539 // X shape (X)
540 } else if (ms == 5) {
541 PrintStr("<line x1=\"");
542 WriteReal(ix-m2*0.707, kFALSE);
543 PrintStr("\" y1=\"");
544 WriteReal(iy-m2*0.707, kFALSE);
545 PrintStr("\" x2=\"");
546 WriteReal(ix+m2*0.707, kFALSE);
547 PrintStr("\" y2=\"");
548 WriteReal(iy+m2*0.707, kFALSE);
549 PrintStr("\"/>");
550
551 PrintStr("<line x1=\"");
552 WriteReal(ix-m2*0.707, kFALSE);
553 PrintStr("\" y1=\"");
554 WriteReal(iy+m2*0.707, kFALSE);
555 PrintStr("\" x2=\"");
556 WriteReal(ix+m2*0.707, kFALSE);
557 PrintStr("\" y2=\"");
558 WriteReal(iy-m2*0.707, kFALSE);
559 PrintStr("\"/>");
560 // Asterisk shape (*)
561 } else if (ms == 3 || ms == 31) {
562 PrintStr("<line x1=\"");
563 WriteReal(ix-m2, kFALSE);
564 PrintStr("\" y1=\"");
565 WriteReal(iy, kFALSE);
566 PrintStr("\" x2=\"");
567 WriteReal(ix+m2, kFALSE);
568 PrintStr("\" y2=\"");
569 WriteReal(iy, kFALSE);
570 PrintStr("\"/>");
571
572 PrintStr("<line x1=\"");
573 WriteReal(ix, kFALSE);
574 PrintStr("\" y1=\"");
575 WriteReal(iy-m2, kFALSE);
576 PrintStr("\" x2=\"");
577 WriteReal(ix, kFALSE);
578 PrintStr("\" y2=\"");
579 WriteReal(iy+m2, kFALSE);
580 PrintStr("\"/>");
581
582 PrintStr("<line x1=\"");
583 WriteReal(ix-m2*0.707, kFALSE);
584 PrintStr("\" y1=\"");
585 WriteReal(iy-m2*0.707, kFALSE);
586 PrintStr("\" x2=\"");
587 WriteReal(ix+m2*0.707, kFALSE);
588 PrintStr("\" y2=\"");
589 WriteReal(iy+m2*0.707, kFALSE);
590 PrintStr("\"/>");
591
592 PrintStr("<line x1=\"");
593 WriteReal(ix-m2*0.707, kFALSE);
594 PrintStr("\" y1=\"");
595 WriteReal(iy+m2*0.707, kFALSE);
596 PrintStr("\" x2=\"");
597 WriteReal(ix+m2*0.707, kFALSE);
598 PrintStr("\" y2=\"");
599 WriteReal(iy-m2*0.707, kFALSE);
600 PrintStr("\"/>");
601 // Circle
602 } else if (ms == 24 || ms == 20) {
603 PrintStr("<circle cx=\"");
604 WriteReal(ix, kFALSE);
605 PrintStr("\" cy=\"");
606 WriteReal(iy, kFALSE);
607 PrintStr("\" r=\"");
608 if (m2<=0) m2=1;
609 WriteReal(m2, kFALSE);
610 PrintStr("\"/>");
611 // Square
612 } else if (ms == 25 || ms == 21) {
613 PrintStr("<rect x=\"");
614 WriteReal(ix-m2, kFALSE);
615 PrintStr("\" y=\"");
616 WriteReal(iy-m2, kFALSE);
617 PrintStr("\" width=\"");
619 PrintStr("\" height=\"");
621 PrintStr("\"/>");
622 // Down triangle
623 } else if (ms == 26 || ms == 22) {
624 PrintStr("<polygon points=\"");
625 WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
626 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
627 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
628 PrintStr("\"/>");
629 // Up triangle
630 } else if (ms == 23 || ms == 32) {
631 PrintStr("<polygon points=\"");
632 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
633 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
634 WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
635 PrintStr("\"/>");
636 // Diamond
637 } else if (ms == 27 || ms == 33) {
638 PrintStr("<polygon points=\"");
639 WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
640 WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
641 WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
642 WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
643 PrintStr("\"/>");
644 // Cross
645 } else if (ms == 28 || ms == 34) {
646 PrintStr("<polygon points=\"");
647 WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
648 WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
649 WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
650 WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
651 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
652 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
653 WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
654 WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
655 WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
656 WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
657 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
658 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
659 PrintStr("\"/>");
660 } else if (ms == 29 || ms == 30) {
661 PrintStr("<polygon points=\"");
662 WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
663 WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
664 WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
665 WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
666 WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
667 WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
668 WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
669 WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
670 WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
671 WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
672 PrintStr("\"/>");
673 } else if (ms == 35) {
674 PrintStr("<polygon points=\"");
675 WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
676 WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
677 WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
678 WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
679 WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
680 WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
681 WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
682 WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
683 PrintStr("\"/>");
684 } else if (ms == 36) {
685 PrintStr("<polygon points=\"");
686 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
687 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
688 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
689 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
690 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
691 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
692 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
693 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
694 PrintStr("\"/>");
695 } else if (ms == 37 || ms == 39) {
696 PrintStr("<polygon points=\"");
697 WriteReal(ix ); PrintStr(","); WriteReal(iy );
698 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
699 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
700 WriteReal(ix ); PrintStr(","); WriteReal(iy );
701 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
702 WriteReal(ix-m2); PrintStr(","); WriteReal(iy);
703 WriteReal(ix ); PrintStr(","); WriteReal(iy );
704 WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
705 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
706 WriteReal(ix ); PrintStr(","); WriteReal(iy );
707 PrintStr("\"/>");
708 } else if (ms == 38) {
709 PrintStr("<polygon points=\"");
710 WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
711 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
712 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
713 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
714 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
715 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
716 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
717 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
718 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
719 WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
720 WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
721 WriteReal(ix ); PrintStr(","); WriteReal(iy );
722 WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
723 WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
724 WriteReal(ix ); PrintStr(","); WriteReal(iy);
725 PrintStr("\"/>");
726 } else if (ms == 40 || ms == 41) {
727 PrintStr("<polygon points=\"");
728 WriteReal(ix ); PrintStr(","); WriteReal(iy );
729 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
730 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
731 WriteReal(ix ); PrintStr(","); WriteReal(iy );
732 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
733 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
734 WriteReal(ix ); PrintStr(","); WriteReal(iy );
735 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
736 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
737 WriteReal(ix ); PrintStr(","); WriteReal(iy );
738 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
739 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
740 WriteReal(ix ); PrintStr(","); WriteReal(iy );
741 PrintStr("\"/>");
742 } else if (ms == 42 || ms == 43) {
743 PrintStr("<polygon points=\"");
744 WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
745 WriteReal(ix-m8); PrintStr(","); WriteReal(iy+m8);
746 WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
747 WriteReal(ix-m8); PrintStr(","); WriteReal(iy-m8);
748 WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
749 WriteReal(ix+m8); PrintStr(","); WriteReal(iy-m8);
750 WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
751 WriteReal(ix+m8); PrintStr(","); WriteReal(iy+m8);
752 WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
753 PrintStr("\"/>");
754 } else if (ms == 44) {
755 PrintStr("<polygon points=\"");
756 WriteReal(ix ); PrintStr(","); WriteReal(iy );
757 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
758 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
759 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
760 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
761 WriteReal(ix ); PrintStr(","); WriteReal(iy );
762 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
763 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
764 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
765 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
766 WriteReal(ix ); PrintStr(","); WriteReal(iy );
767 PrintStr("\"/>");
768 } else if (ms == 45) {
769 PrintStr("<polygon points=\"");
770 WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
771 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
772 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
773 WriteReal(ix-m0); PrintStr(","); WriteReal(iy+m0);
774 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
775 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
776 WriteReal(ix-m0); PrintStr(","); WriteReal(iy-m0);
777 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
778 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
779 WriteReal(ix+m0); PrintStr(","); WriteReal(iy-m0);
780 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
781 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
782 WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
783 PrintStr("\"/>");
784 } else if (ms == 46 || ms == 47) {
785 PrintStr("<polygon points=\"");
786 WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
787 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
788 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
789 WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
790 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
791 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
792 WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
793 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
794 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
795 WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
796 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
797 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
798 WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
799 PrintStr("\"/>");
800 } else if (ms == 48) {
801 PrintStr("<polygon points=\"");
802 WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*1.01);
803 WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
804 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
805 WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
806 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
807 WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
808 WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
809 WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
810 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
811 WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
812 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
813 WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
814 WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
815 WriteReal(ix+m4*0.99); PrintStr(","); WriteReal(iy );
816 WriteReal(ix ); PrintStr(","); WriteReal(iy-m4*0.99);
817 WriteReal(ix-m4*0.99); PrintStr(","); WriteReal(iy );
818 WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
819 PrintStr("\"/>");
820 } else if (ms == 49) {
821 PrintStr("<polygon points=\"");
822 WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*1.01);
823 WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
824 WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
825 WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
826 WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
827 WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
828 WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
829 WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
830 WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
831 WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
832 WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
833 WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
834 WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*0.99);
835 WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
836 WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
837 WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
838 PrintStr("\"/>");
839 } else {
840 PrintStr("<line x1=\"");
841 WriteReal(ix-1, kFALSE);
842 PrintStr("\" y1=\"");
843 WriteReal(iy, kFALSE);
844 PrintStr("\" x2=\"");
845 WriteReal(ix, kFALSE);
846 PrintStr("\" y2=\"");
847 WriteReal(iy, kFALSE);
848 PrintStr("\"/>");
849 }
850 }
851 PrintStr("@");
852 PrintStr("</g>");
853}
854
855////////////////////////////////////////////////////////////////////////////////
856/// Paint PolyMarker
857
862
863
864////////////////////////////////////////////////////////////////////////////////
865/// Paint PolyMarker
866
871
872////////////////////////////////////////////////////////////////////////////////
873/// This function defines a path with xw and yw and draw it according the
874/// value of nn:
875///
876/// - If nn>0 a line is drawn.
877/// - If nn<0 a closed polygon is drawn.
878
880{
881 Int_t n, fais = 0, fasi = 0;
882
883 if (nn > 0) {
884 if (fLineWidth <= 0)
885 return;
886 n = nn;
887 } else {
888 n = -nn;
889 fais = fFillStyle/1000;
890 fasi = fFillStyle%1000;
891 if (fais == 3 || fais == 2) {
892 if (fasi > 100 && fasi <125) {
893 return;
894 }
895 if (fasi > 0 && fasi < 26) {
896 }
897 }
898 }
899
900 if(n <= 1) {
901 Error("DrawPS", "Two points are needed");
902 return;
903 }
904
905 PrintStr("@");
906 PrintFast(9,"<path d=\"");
907
908 PrintPath(kTRUE, n, xw, yw, nn < 0);
909
910 if (nn > 0) {
911 PrintFast(21,"\" fill=\"none\" stroke=");
913 if(fLineWidth > 1.) {
914 PrintFast(15," stroke-width=\"");
916 PrintFast(1,"\"");
917 }
918 if (fLineStyle > 1) {
919 PrintFast(19," stroke-dasharray=\"");
921 TObjArray *tokens = st.Tokenize(" ");
922 for (Int_t j = 0; j<tokens->GetEntries(); j++) {
923 Int_t it;
924 sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
925 if (j>0) PrintFast(1,",");
926 WriteReal(it/4);
927 }
928 delete tokens;
929 PrintFast(1,"\"");
930 }
931 } else {
932 PrintFast(7,"\" fill=");
933 if (fais == 0) {
934 PrintFast(14,"\"none\" stroke=");
936 } else {
938 }
939 }
940 if (fgLineJoin)
941 PrintStr(TString::Format(" stroke-linejoin=\"%s\"", fgLineJoin == 1 ? "round" : "bevel"));
942 if (fgLineCap)
943 PrintStr(TString::Format(" stroke-linecap=\"%s\"", fgLineCap == 1 ? "round" : "square"));
944 PrintFast(2,"/>");
945}
946
947////////////////////////////////////////////////////////////////////////////////
948/// Initialize the SVG file. The main task of the function is to output the
949/// SVG header file which consist in `<title>`, `<desc>` and `<defs>`. The
950/// HeaderPS provided by the user program is written in the `<defs>` part.
951
953{
954 // Title
955 PrintStr("<title>@");
956 PrintStr(GetName());
957 PrintStr("@");
958 PrintStr("</title>@");
959
960 if (fCompact)
961 return;
962
963 // Description
964 PrintStr("<desc>@");
965 PrintFast(22,"Creator: ROOT Version ");
966 PrintStr(gROOT->GetVersion());
967 PrintStr("@");
968 PrintFast(14,"CreationDate: ");
969 TDatime t;
970 PrintStr(t.AsString());
971 //Check a special header is defined in the current style
973 if (nh) {
975 }
976 PrintStr("</desc>@");
977
978 // Definitions
979 PrintStr("<defs>@");
980 PrintStr("</defs>@");
981
982}
983
984////////////////////////////////////////////////////////////////////////////////
985/// Write float value into output stream
986/// In compact form try to store only first 2-3 significant digits
987
989{
990 if (fCompact) {
991 auto a = std::abs(r);
992 if (a > 10)
993 TVirtualPS::WriteInteger(std::lround(r), space);
994 else if (a < 0.005)
995 TVirtualPS::WriteReal(r, space);
996 else {
997 char str[15];
998 snprintf(str, 15, (a > 1) ? "%3.1f" : "%5.3f", r);
999 if(space)
1000 PrintFast(1," ");
1001 PrintStr(str);
1002 }
1003 } else
1004 TVirtualPS::WriteReal(r, space);
1005}
1006
1007////////////////////////////////////////////////////////////////////////////////
1008/// Move to a new position (ix, iy). The move is done in relative coordinates
1009/// which allows to have short numbers which decrease the size of the file.
1010/// This function use the full power of the SVG's paths by using the
1011/// horizontal and vertical move whenever it is possible.
1012
1014{
1015 if (ix != 0 && iy != 0) {
1016 PrintFast(1,"l");
1017 WriteReal(ix);
1018 PrintFast(1,",");
1019 WriteReal(iy);
1020 } else if (ix != 0) {
1021 PrintFast(1,"h");
1022 WriteReal(ix);
1023 } else if (iy != 0) {
1024 PrintFast(1,"v");
1025 WriteReal(iy);
1026 }
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030/// Start the SVG page. This function initialize the pad conversion
1031/// coefficients and output the `<svg>` directive which is close later in the
1032/// the function Close.
1033
1035{
1036 // Compute pad conversion coefficients
1037 if (gPad) {
1038 Double_t ww = gPad->GetWw();
1039 Double_t wh = gPad->GetWh();
1040 fYsize = fXsize*wh/ww;
1041 } else {
1042 fYsize = 27;
1043 }
1044
1045 // <svg> directive. It defines the viewBox.
1046 if(!fBoundingBox) {
1047 PrintStr("@<?xml version=\"1.0\" standalone=\"no\"?>");
1048 PrintStr("@<svg width=\"");
1050 PrintStr("\" height=\"");
1053 PrintStr("\" viewBox=\"0 0");
1056 PrintStr("\" xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"crispEdges\">");
1057 PrintStr("@");
1058 Initialize();
1060 }
1061}
1062
1063////////////////////////////////////////////////////////////////////////////////
1064/// Set the range for the paper in centimetres
1065
1067{
1068 fXsize = xsize;
1069 fYsize = ysize;
1070 fRange = kTRUE;
1071}
1072
1073////////////////////////////////////////////////////////////////////////////////
1074/// Set color index for fill areas
1075
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// Set color index for lines
1083
1088
1089////////////////////////////////////////////////////////////////////////////////
1090/// Set the value of the global parameter TSVG::fgLineJoin.
1091/// This parameter determines the appearance of joining lines in a SVG
1092/// output.
1093/// It takes one argument which may be:
1094/// - 0 (miter join)
1095/// - 1 (round join)
1096/// - 2 (bevel join)
1097/// The default value is 0 (miter join).
1098///
1099/// \image html postscript_1.png
1100///
1101/// To change the line join behaviour just do:
1102/// ~~~ {.cpp}
1103/// gStyle->SetJoinLinePS(2); // Set the PS line join to bevel.
1104/// ~~~
1105
1107{
1109 if (fgLineJoin<0) fgLineJoin=0;
1110 if (fgLineJoin>2) fgLineJoin=2;
1111}
1112
1113////////////////////////////////////////////////////////////////////////////////
1114/// Set the value of the global parameter TSVG::fgLineCap.
1115/// This parameter determines the appearance of line caps in a SVG
1116/// output.
1117/// It takes one argument which may be:
1118/// - 0 (butt caps)
1119/// - 1 (round caps)
1120/// - 2 (projecting caps)
1121/// The default value is 0 (butt caps).
1122///
1123/// \image html postscript_2.png
1124///
1125/// To change the line cap behaviour just do:
1126/// ~~~ {.cpp}
1127/// gStyle->SetCapLinePS(2); // Set the PS line cap to projecting.
1128/// ~~~
1129
1131{
1133 if (fgLineCap<0) fgLineCap=0;
1134 if (fgLineCap>2) fgLineCap=2;
1135}
1136
1137////////////////////////////////////////////////////////////////////////////////
1138/// Change the line style
1139///
1140/// - linestyle = 2 dashed
1141/// - linestyle = 3 dotted
1142/// - linestyle = 4 dash-dotted
1143/// - linestyle = else solid (1 in is used most of the time)
1144
1149
1150////////////////////////////////////////////////////////////////////////////////
1151/// Set the lines width.
1152
1157
1158////////////////////////////////////////////////////////////////////////////////
1159/// Set color index for markers.
1160
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// Set RGBa color with its color index
1168
1170{
1171 if (color < 0)
1172 color = 0;
1173 TColor *col = gROOT->GetColor(color);
1174 if (col) {
1175 SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1176 Float_t a = col->GetAlpha();
1177 if ((a < 1.) && fill)
1178 PrintStr(TString::Format(" fill-opacity=\"%3.2f\"",a));
1179 if ((a < 1.) && stroke)
1180 PrintStr(TString::Format(" stroke-opacity=\"%3.2f\"",a));
1181 } else {
1182 SetColor(1., 1., 1.);
1183 }
1184}
1185
1186////////////////////////////////////////////////////////////////////////////////
1187/// Set RGB (without alpha channel) color with its color index
1188
1190{
1191 if (color < 0) color = 0;
1192 TColor *col = gROOT->GetColor(color);
1193 if (col) {
1194 SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1195 } else {
1196 SetColor(1., 1., 1.);
1197 }
1198}
1199
1200////////////////////////////////////////////////////////////////////////////////
1201/// Set color with its R G B components
1202///
1203/// - r: % of red in [0,1]
1204/// --g: % of green in [0,1]
1205/// - b: % of blue in [0,1]
1206
1208{
1209 if (r <= 0. && g <= 0. && b <= 0. ) {
1210 PrintFast(7,"\"black\"");
1211 } else if (r >= 1. && g >= 1. && b >= 1. ) {
1212 PrintFast(7,"\"white\"");
1213 } else {
1214 char str[12];
1215 snprintf(str,12,"\"#%2.2x%2.2x%2.2x\"",Int_t(255.*r)
1216 ,Int_t(255.*g)
1217 ,Int_t(255.*b));
1218 PrintStr(str);
1219 }
1220}
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// Set color index for text
1224
1229
1230////////////////////////////////////////////////////////////////////////////////
1231/// Draw text
1232///
1233/// - xx: x position of the text
1234/// - yy: y position of the text
1235/// - chars: text to be drawn
1236
1238{
1239 static const char *fontFamily[] = {
1240 "Times" , "Times" , "Times",
1241 "Helvetica", "Helvetica", "Helvetica" , "Helvetica",
1242 "Courier" , "Courier" , "Courier" , "Courier",
1243 "Times" ,"Times" , "ZapfDingbats", "Times"};
1244
1245 static const char *fontWeight[] = {
1246 "normal", "bold", "bold",
1247 "normal", "normal", "bold" , "bold",
1248 "normal", "normal", "bold" , "bold",
1249 "normal", "normal", "normal", "normal"};
1250
1251 static const char *fontStyle[] = {
1252 "italic", "normal" , "italic",
1253 "normal", "oblique", "normal", "oblique",
1254 "normal", "oblique", "normal", "oblique",
1255 "normal", "normal" , "normal", "italic"};
1256
1257 Double_t ix = XtoSVG(xx);
1258 Double_t iy = YtoSVG(yy);
1260 if (txalh <1) txalh = 1; else if (txalh > 3) txalh = 3;
1262 if (txalv <1) txalv = 1; else if (txalv > 3) txalv = 3;
1263
1264 Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
1265 Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
1266 Float_t fontrap = 1.09; //scale down compared to X11
1268
1269 Int_t font = abs(fTextFont)/10;
1270 if (font > 15 || font < 1)
1271 font = 1;
1272 if (wh < hh) {
1273 ftsize = fTextSize*fXsize*gPad->GetAbsWNDC();
1274 } else {
1275 ftsize = fTextSize*fYsize*gPad->GetAbsHNDC();
1276 }
1277 Int_t ifont = font-1;
1278
1280 if( fontsize <= 0) return;
1281
1282 if (txalv == 3) iy = iy+fontsize;
1283 if (txalv == 2) iy = iy+(fontsize/2);
1284
1285 if (fTextAngle != 0.) {
1286 PrintStr("@");
1287 PrintFast(21,"<g transform=\"rotate(");
1289 PrintFast(1,",");
1290 WriteReal(ix, kFALSE);
1291 PrintFast(1,",");
1292 WriteReal(iy, kFALSE);
1293 PrintFast(3,")\">");
1294 }
1295
1296 PrintStr("@");
1297 PrintFast(30,"<text xml:space=\"preserve\" x=\"");
1298 WriteReal(ix, kFALSE);
1299 PrintFast(5,"\" y=\"");
1300 WriteReal(iy, kFALSE);
1301 PrintFast(1,"\"");
1302 if (txalh == 2) {
1303 PrintFast(21," text-anchor=\"middle\"");
1304 } else if (txalh == 3) {
1305 PrintFast(18," text-anchor=\"end\"");
1306 }
1307 PrintFast(6," fill=");
1309 PrintFast(12," font-size=\"");
1311 PrintFast(15,"\" font-family=\"");
1313 if (strcmp(fontWeight[ifont],"normal")) {
1314 PrintFast(15,"\" font-weight=\"");
1316 }
1317 if (strcmp(fontStyle[ifont],"normal")) {
1318 PrintFast(14,"\" font-style=\"");
1320 }
1321 PrintFast(2,"\">");
1322
1323 if (font == 12 || font == 15) {
1324 Int_t ichar = chars[0]+848;
1325 Int_t ic = ichar;
1326
1327 // Math Symbols (cf: http://www.fileformat.info/info/unicode/category/Sm/list.htm)
1328 if (ic == 755) ichar = 8804;
1329 if (ic == 759) ichar = 9827;
1330 if (ic == 760) ichar = 9830;
1331 if (ic == 761) ichar = 9829;
1332 if (ic == 762) ichar = 9824;
1333 if (ic == 766) ichar = 8594;
1334 if (ic == 776) ichar = 247;
1335 if (ic == 757) ichar = 8734;
1336 if (ic == 758) ichar = 402;
1337 if (ic == 771) ichar = 8805;
1338 if (ic == 774) ichar = 8706;
1339 if (ic == 775) ichar = 8226;
1340 if (ic == 779) ichar = 8776;
1341 if (ic == 805) ichar = 8719;
1342 if (ic == 821) ichar = 8721;
1343 if (ic == 834) ichar = 8747;
1344 if (ic == 769) ichar = 177;
1345 if (ic == 772) ichar = 215;
1346 if (ic == 768) ichar = 176;
1347 if (ic == 791) ichar = 8745;
1348 if (ic == 793) ichar = 8835; // SUPERSET OF
1349 if (ic == 794) ichar = 8839; // SUPERSET OF OR EQUAL TO
1350 if (ic == 795) ichar = 8836; // NOT A SUBSET OF
1351 if (ic == 796) ichar = 8834;
1352 if (ic == 893) ichar = 8722;
1353 if (ic == 803) ichar = 169; // COPYRIGHT SIGN
1354 if (ic == 819) ichar = 169; // COPYRIGHT SIGN
1355 if (ic == 804) ichar = 8482;
1356 if (ic == 770) ichar = 34;
1357 if (ic == 823) ichar = 10072;
1358 if (ic == 781) ichar = 10072;
1359 if (ic == 824) ichar = 9117; // LEFT PARENTHESIS LOWER HOOK
1360 if (ic == 822) ichar = 9115; // LEFT PARENTHESIS UPPER HOOK
1361 if (ic == 767) ichar = 8595; // DOWNWARDS ARROW
1362 if (ic == 763) ichar = 8596; // LEFT RIGHT ARROW
1363 if (ic == 764) ichar = 8592; // LEFTWARDS ARROW
1364 if (ic == 788) ichar = 8855; // CIRCLED TIMES
1365 if (ic == 784) ichar = 8501;
1366 if (ic == 777) ichar = 8800;
1367 if (ic == 797) ichar = 8838;
1368 if (ic == 800) ichar = 8736;
1369 if (ic == 812) ichar = 8656; // LEFTWARDS DOUBLE ARROW
1370 if (ic == 817) ichar = 60; // LESS-THAN SIGN
1371 if (ic == 833) ichar = 62; // GREATER-THAN SIGN
1372 if (ic == 778) ichar = 8803; // STRICTLY EQUIVALENT TO
1373 if (ic == 809) ichar = 8743; // LOGICAL AND
1374 if (ic == 802) ichar = 9415; // CIRCLED LATIN CAPITAL LETTER R
1375 if (ic == 780) ichar = 8230; // HORIZONTAL ELLIPSIS
1376 if (ic == 801) ichar = 8711; // NABLA
1377 if (ic == 783) ichar = 8629; // DOWNWARDS ARROW WITH CORNER LEFTWARDS
1378 if (ic == 782) ichar = 8213;
1379 if (ic == 799) ichar = 8713;
1380 if (ic == 792) ichar = 8746;
1381 if (ic == 828) ichar = 9127;
1382 if (ic == 765) ichar = 8593; // UPWARDS ARROW
1383 if (ic == 789) ichar = 8853; // CIRCLED PLUS
1384 if (ic == 813) ichar = 8657; // UPWARDS DOUBLE ARROW
1385 if (ic == 773) ichar = 8733; // PROPORTIONAL TO
1386 if (ic == 790) ichar = 8709; // EMPTY SET
1387 if (ic == 810) ichar = 8744;
1388 if (ic == 756) ichar = 8260;
1389 if (ic == 807) ichar = 8231;
1390 if (ic == 808) ichar = 8989; // TOP RIGHT CORNER
1391 if (ic == 814) ichar = 8658; // RIGHTWARDS DOUBLE ARROW
1392 if (ic == 806) ichar = 8730; // SQUARE ROOT
1393 if (ic == 827) ichar = 9123;
1394 if (ic == 829) ichar = 9128;
1395 if (ic == 786) ichar = 8476;
1396 if (ic == 785) ichar = 8465;
1397 if (ic == 787) ichar = 8472;
1398
1399 // Greek characters
1400 if (ic == 918) ichar = 934;
1401 if (ic == 919) ichar = 915;
1402 if (ic == 920) ichar = 919;
1403 if (ic == 923) ichar = 922;
1404 if (ic == 924) ichar = 923;
1405 if (ic == 925) ichar = 924;
1406 if (ic == 926) ichar = 925;
1407 if (ic == 929) ichar = 920;
1408 if (ic == 930) ichar = 929;
1409 if (ic == 936) ichar = 926;
1410 if (ic == 915) ichar = 935;
1411 if (ic == 937) ichar = 936;
1412 if (ic == 935) ichar = 937;
1413 if (ic == 938) ichar = 918;
1414 if (ic == 951) ichar = 947;
1415 if (ic == 798) ichar = 949;
1416 if (ic == 970) ichar = 950;
1417 if (ic == 952) ichar = 951;
1418 if (ic == 961) ichar = 952;
1419 if (ic == 955) ichar = 954;
1420 if (ic == 956) ichar = 955;
1421 if (ic == 957) ichar = 956;
1422 if (ic == 958) ichar = 957;
1423 if (ic == 968) ichar = 958;
1424 if (ic == 934) ichar = 962;
1425 if (ic == 962) ichar = 961;
1426 if (ic == 966) ichar = 969;
1427 if (ic == 950) ichar = 966;
1428 if (ic == 947) ichar = 967;
1429 if (ic == 969) ichar = 968;
1430 if (ic == 967) ichar = 969;
1431 if (ic == 954) ichar = 966;
1432 if (ic == 922) ichar = 952;
1433 if (ic == 753) ichar = 965;
1434 PrintStr(Form("&#%4.4d;",ichar));
1435 } else {
1437 for (Int_t i=0; i<len;i++) {
1438 if (chars[i]!='\n') {
1439 if (chars[i]=='<') {
1440 PrintFast(4,"&lt;");
1441 } else if (chars[i]=='>') {
1442 PrintFast(4,"&gt;");
1443 } else if (chars[i]=='\305') {
1444 PrintFast(7,"&#8491;"); // ANGSTROM SIGN
1445 } else if (chars[i]=='\345') {
1446 PrintFast(6,"&#229;");
1447 } else if (chars[i]=='&') {
1448 PrintFast(5,"&amp;");
1449 } else {
1450 PrintFast(1,&chars[i]);
1451 }
1452 }
1453 }
1454 }
1455
1456 PrintStr("@");
1457 PrintFast(7,"</text>");
1458
1459 if (fTextAngle != 0.) {
1460 PrintStr("@");
1461 PrintFast(4,"</g>");
1462 }
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466/// Write a string of characters in NDC
1467
1469{
1470 Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
1471 Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
1472 Text(x, y, chars);
1473}
1474
1475////////////////////////////////////////////////////////////////////////////////
1476/// Convert U from NDC coordinate to SVG
1477
1479{
1480 Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
1481 return 0.5 + 72*cm/2.54;
1482}
1483
1484////////////////////////////////////////////////////////////////////////////////
1485/// Convert V from NDC coordinate to SVG
1486
1488{
1489 Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
1490 return 0.5 + 72*cm/2.54;
1491}
1492
1493////////////////////////////////////////////////////////////////////////////////
1494/// Convert X from world coordinate to SVG
1495
1497{
1498 Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
1499 return UtoSVG(u);
1500}
1501
1502////////////////////////////////////////////////////////////////////////////////
1503/// Convert Y from world coordinate to SVG
1504
1506{
1507 Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
1508 return fYsizeSVG-VtoSVG(v);
1509}
1510
1511////////////////////////////////////////////////////////////////////////////////
1512/// Begin the Cell Array painting
1513
1515 Double_t)
1516{
1517 Warning("TSVG::CellArrayBegin", "not yet implemented");
1518}
1519
1520////////////////////////////////////////////////////////////////////////////////
1521/// Paint the Cell Array
1522
1524{
1525 Warning("TSVG::CellArrayFill", "not yet implemented");
1526}
1527
1528////////////////////////////////////////////////////////////////////////////////
1529/// End the Cell Array painting
1530
1532{
1533 Warning("TSVG::CellArrayEnd", "not yet implemented");
1534}
1535
1536////////////////////////////////////////////////////////////////////////////////
1537/// Not needed in SVG case
1538
1540{
1541 Warning("TSVG::DrawPS", "not yet implemented");
1542}
#define b(i)
Definition RSha256.hxx:100
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
short Style_t
Style number (short)
Definition RtypesCore.h:96
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Color_t
Color number (short)
Definition RtypesCore.h:99
short Width_t
Line width (short)
Definition RtypesCore.h:98
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t cindex
Option_t Option_t 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 TPoint const char mode
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
#define gROOT
Definition TROOT.h:411
const Double_t kEpsilon
Definition TSVG.cxx:37
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2495
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
R__EXTERN TVirtualPS * gVirtualPS
Definition TVirtualPS.h:81
#define gPad
#define snprintf
Definition civetweb.c:1579
Style_t fFillStyle
Fill area style.
Definition TAttFill.h:24
Color_t fFillColor
Fill area color.
Definition TAttFill.h:23
Width_t fLineWidth
Line width.
Definition TAttLine.h:25
Style_t fLineStyle
Line style.
Definition TAttLine.h:24
Color_t fLineColor
Line color.
Definition TAttLine.h:23
Color_t fMarkerColor
Marker color.
Definition TAttMarker.h:23
static Width_t GetMarkerLineWidth(Style_t style)
Internal helper function that returns the line width of the given marker style (0 = filled marker)
Size_t fMarkerSize
Marker size.
Definition TAttMarker.h:25
Style_t fMarkerStyle
Marker style.
Definition TAttMarker.h:24
static Style_t GetMarkerStyleBase(Style_t style)
Internal helper function that returns the corresponding marker style with line width 1 for the given ...
Color_t fTextColor
Text color.
Definition TAttText.h:26
Float_t fTextAngle
Text angle.
Definition TAttText.h:23
Font_t fTextFont
Text font.
Definition TAttText.h:27
Short_t fTextAlign
Text alignment.
Definition TAttText.h:25
Float_t fTextSize
Text size.
Definition TAttText.h:24
The color creation and management class.
Definition TColor.h:22
Float_t GetRed() const
Definition TColor.h:61
static Int_t GetColor(const char *hexcolor)
Static method returning color number for color specified by hex color string of form: "#rrggbb",...
Definition TColor.cxx:1926
Float_t GetAlpha() const
Definition TColor.h:67
Float_t GetBlue() const
Definition TColor.h:63
Float_t GetGreen() const
Definition TColor.h:62
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition TDatime.h:37
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition TDatime.cxx:101
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
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:1057
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
2-D graphics point (world coordinates).
Definition TPoints.h:19
static Int_t fgLineJoin
Appearance of joining lines.
Definition TSVG.h:31
void PrintPolyMarker(Int_t n, T *x, T *y)
Implementation of polymarker printing.
Definition TSVG.cxx:452
Double_t UtoSVG(Double_t u)
Convert U from NDC coordinate to SVG.
Definition TSVG.cxx:1478
void MovePS(Double_t x, Double_t y)
Move to a new position (ix, iy).
Definition TSVG.cxx:1013
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 TSVG.cxx:370
void DrawPolyLineNDC(Int_t, TPoints *)
Draw a PolyLine in NDC space.
Definition TSVG.cxx:443
Double_t fYsizeSVG
Page's Y size in SVG units.
Definition TSVG.h:29
void DrawPolyMarker(Int_t n, Float_t *x, Float_t *y) override
Paint PolyMarker.
Definition TSVG.cxx:858
void Close(Option_t *opt="") override
Close a SVG file.
Definition TSVG.cxx:174
void DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2) override
Draw a Box.
Definition TSVG.cxx:214
Bool_t fRange
True when a range has been defined.
Definition TSVG.h:28
void Text(Double_t x, Double_t y, const char *string) override
Draw text.
Definition TSVG.cxx:1237
Double_t YtoSVG(Double_t y)
Convert Y from world coordinate to SVG.
Definition TSVG.cxx:1505
void SetFillColor(Color_t cindex=1) override
Set color index for fill areas.
Definition TSVG.cxx:1076
void SetLineWidth(Width_t linewidth=1) override
Set the lines width.
Definition TSVG.cxx:1153
void Initialize()
Initialize the SVG file.
Definition TSVG.cxx:952
void DrawPS(Int_t n, Float_t *xw, Float_t *yw) override
Not needed in SVG case.
Definition TSVG.cxx:1539
void CellArrayEnd() override
End the Cell Array painting.
Definition TSVG.cxx:1531
void CellArrayFill(Int_t r, Int_t g, Int_t b) override
Paint the Cell Array.
Definition TSVG.cxx:1523
void NewPage() override
Start the SVG page.
Definition TSVG.cxx:1034
void SetColor(Int_t color=1)
Set RGB (without alpha channel) color with its color index.
Definition TSVG.cxx:1189
Int_t fType
Workstation type used to know if the SVG is open.
Definition TSVG.h:25
void SetLineCap(Int_t linecap=0)
Set the value of the global parameter TSVG::fgLineCap.
Definition TSVG.cxx:1130
void DrawPolyLine(Int_t, TPoints *)
Draw a PolyLine.
Definition TSVG.cxx:428
void Off()
Deactivate an already open SVG file.
Definition TSVG.cxx:206
void Range(Float_t xrange, Float_t yrange)
Set the range for the paper in centimetres.
Definition TSVG.cxx:1066
void SetLineScale(Float_t=3)
Definition TSVG.h:74
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 TSVG.cxx:1514
void SetLineStyle(Style_t linestyle=1) override
Change the line style.
Definition TSVG.cxx:1145
void On()
Activate an already open SVG file.
Definition TSVG.cxx:190
TSVG()
Default SVG constructor.
Definition TSVG.cxx:82
void SetTextColor(Color_t cindex=1) override
Set color index for text.
Definition TSVG.cxx:1225
Double_t CMtoSVG(Double_t u)
Definition TSVG.h:47
Double_t XtoSVG(Double_t x)
Convert X from world coordinate to SVG.
Definition TSVG.cxx:1496
Bool_t fCompact
True when the SVG header is printed.
Definition TSVG.h:26
Bool_t fBoundingBox
True when the SVG header is printed.
Definition TSVG.h:27
Float_t fXsize
Page size along X.
Definition TSVG.h:23
void SetMarkerColor(Color_t cindex=1) override
Set color index for markers.
Definition TSVG.cxx:1161
Float_t fYsize
Page size along Y.
Definition TSVG.h:24
void TextNDC(Double_t u, Double_t v, const char *string)
Write a string of characters in NDC.
Definition TSVG.cxx:1468
~TSVG() override
Default SVG destructor.
Definition TSVG.cxx:166
void SetLineColor(Color_t cindex=1) override
Set color index for lines.
Definition TSVG.cxx:1084
void SetColorAlpha(Int_t color=1, Bool_t fill=kTRUE, Bool_t stroke=kTRUE)
Set RGBa color with its color index.
Definition TSVG.cxx:1169
void SetLineJoin(Int_t linejoin=0)
Set the value of the global parameter TSVG::fgLineJoin.
Definition TSVG.cxx:1106
void PrintPath(Bool_t convert, Int_t n, Double_t *xs, Double_t *ys, Bool_t close_path=kTRUE)
Print a svg path statement for specified points.
Definition TSVG.cxx:288
void Open(const char *filename, Int_t type=-111) override
Open a SVG file.
Definition TSVG.cxx:116
void WriteReal(Float_t r, Bool_t space=kTRUE) override
Write float value into output stream In compact form try to store only first 2-3 significant digits.
Definition TSVG.cxx:988
static Int_t fgLineCap
Appearance of line caps.
Definition TSVG.h:32
Double_t VtoSVG(Double_t v)
Convert V from NDC coordinate to SVG.
Definition TSVG.cxx:1487
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2384
Int_t GetJoinLinePS() const
Returns the line join method used for PostScript, PDF and SVG output. See TPostScript::SetLineJoin fo...
Definition TStyle.h:289
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
const char * GetHeaderPS() const
Definition TStyle.h:286
Float_t GetLineScalePS() const
Definition TStyle.h:291
TVirtualPS is an abstract interface to Postscript, PDF, SVG.
Definition TVirtualPS.h:30
Int_t fSizBuffer
Definition TVirtualPS.h:39
Int_t fLenBuffer
Definition TVirtualPS.h:38
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
virtual void PrintStr(const char *string="")
Output the string str in the output buffer.
virtual void PrintFast(Int_t nch, const char *string="")
Fast version of Print.
std::ofstream * fStream
Definition TVirtualPS.h:41
char * fBuffer
Definition TVirtualPS.h:42
virtual void WriteReal(Float_t r, Bool_t space=kTRUE)
Write a Real number to the file.
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:251
Double_t Floor(Double_t x)
Rounds x downward, returning the largest integral value that is not greater than x.
Definition TMath.h:691
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:199
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124
TMarker m
Definition textangle.C:8