Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
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 <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19 
20 #include "Riostream.h"
21 #include "TROOT.h"
22 #include "TColor.h"
23 #include "TVirtualPad.h"
24 #include "TPoints.h"
25 #include "TSVG.h"
26 #include "TStyle.h"
27 #include "TMath.h"
28 #include "TObjString.h"
29 #include "TObjArray.h"
30 #include "TClass.h"
31 
32 ClassImp(TSVG);
33 
34 /** \class TSVG
35 \ingroup PS
36 
37 \brief Interface to SVG
38 
39 [SVG](http://www.w3.org/Graphics/SVG/Overview.htm8)
40 (Scalable Vector Graphics) is a language for describing
41 two-dimensional graphics in XML. SVG allows high quality vector graphics in
42 HTML pages.
43 
44 To print a ROOT canvas "c1" into an SVG file simply do:
45 ~~~ {.cpp}
46  c1->Print("c1.svg");
47 ~~~
48 The result is the ASCII file `c1.svg`.
49 
50 It can be open directly using a web browser or included in a html document
51 the following way:
52 ~~~ {.cpp}
53 <embed width="95%" height="500" src="c1.svg">
54 ~~~
55 It is best viewed with Internet Explorer and you need the
56 [Adobe SVG Viewer](http://www.adobe.com/svg/viewer/install/main.html)
57 
58 To zoom using the Adobe SVG Viewer, position the mouse over
59 the area you want to zoom and click the right button.
60 
61 To define the zoom area,
62 use Control+drag to mark the boundaries of the zoom area.
63 
64 To pan, use Alt+drag.
65 By clicking with the right mouse button on the SVG graphics you will get
66 a pop-up menu giving other ways to interact with the image.
67 
68 SVG files can be used directly in compressed mode to minimize the time
69 transfer over the network. Compressed SVG files should be created using
70 `gzip` on a normal ASCII SVG file and should then be renamed
71 using the file extension `.svgz`.
72 */
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 /// Default SVG constructor
76 
77 TSVG::TSVG() : TVirtualPS()
78 {
79  fStream = 0;
80  fType = 0;
81  gVirtualPS = this;
82  fBoundingBox = kFALSE;
83  fRange = kFALSE;
84  fXsize = 0.;
85  fYsize = 0.;
86  fYsizeSVG = 0;
87  SetTitle("SVG");
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Initialize the SVG interface
92 ///
93 /// - fname : SVG file name
94 /// - wtype : SVG workstation type. Not used in the SVG driver. But as TSVG
95 /// inherits from TVirtualPS it should be kept. Anyway it is not
96 /// necessary to specify this parameter at creation time because it
97 /// has a default value (which is ignore in the SVG case).
98 
99 TSVG::TSVG(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
100 {
101  fStream = 0;
102  SetTitle("SVG");
103  Open(fname, wtype);
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Open a SVG file
108 
109 void TSVG::Open(const char *fname, Int_t wtype)
110 {
111  if (fStream) {
112  Warning("Open", "SVG file already open");
113  return;
114  }
115 
116  fLenBuffer = 0;
117  fType = abs(wtype);
118  SetLineScale(gStyle->GetLineScalePS());
119  gStyle->GetPaperSize(fXsize, fYsize);
120  Float_t xrange, yrange;
121  if (gPad) {
122  Double_t ww = gPad->GetWw();
123  Double_t wh = gPad->GetWh();
124  ww *= gPad->GetWNDC();
125  wh *= gPad->GetHNDC();
126  Double_t ratio = wh/ww;
127  xrange = fXsize;
128  yrange = fXsize*ratio;
129  if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
130  fXsize = xrange; fYsize = yrange;
131  }
132 
133  // Open OS file
134  fStream = new std::ofstream(fname,std::ios::out);
135  if (fStream == 0 || !fStream->good()) {
136  printf("ERROR in TSVG::Open: Cannot open file:%s\n",fname);
137  if (fStream == 0) return;
138  }
139 
140  gVirtualPS = this;
141 
142  for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
143 
144  fBoundingBox = kFALSE;
145 
146  fRange = kFALSE;
147 
148  // Set a default range
149  Range(fXsize, fYsize);
150 
151  NewPage();
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Default SVG destructor
156 
157 TSVG::~TSVG()
158 {
159  Close();
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Close a SVG file
164 
165 void TSVG::Close(Option_t *)
166 {
167  if (!gVirtualPS) return;
168  if (!fStream) return;
169  if (gPad) gPad->Update();
170  PrintStr("</svg>@");
171 
172  // Close file stream
173  if (fStream) { fStream->close(); delete fStream; fStream = 0;}
174 
175  gVirtualPS = 0;
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////
179 /// Activate an already open SVG file
180 
181 void TSVG::On()
182 {
183  // fType is used to know if the SVG file is open. Unlike TPostScript, TSVG
184  // has no "workstation type". In fact there is only one SVG type.
185 
186  if (!fType) {
187  Error("On", "no SVG file open");
188  Off();
189  return;
190  }
191  gVirtualPS = this;
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Deactivate an already open SVG file
196 
197 void TSVG::Off()
198 {
199  gVirtualPS = 0;
200 }
201 
202 ////////////////////////////////////////////////////////////////////////////////
203 /// Draw a Box
204 
205 void TSVG::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
206 {
207  static Double_t x[4], y[4];
208  Double_t ix1 = XtoSVG(TMath::Min(x1,x2));
209  Double_t ix2 = XtoSVG(TMath::Max(x1,x2));
210  Double_t iy1 = YtoSVG(TMath::Min(y1,y2));
211  Double_t iy2 = YtoSVG(TMath::Max(y1,y2));
212  Int_t fillis = fFillStyle/1000;
213  Int_t fillsi = fFillStyle%1000;
214 
215  if (fillis == 3 || fillis == 2) {
216  if (fillsi > 99) {
217  x[0] = x1; y[0] = y1;
218  x[1] = x2; y[1] = y1;
219  x[2] = x2; y[2] = y2;
220  x[3] = x1; y[3] = y2;
221  return;
222  }
223  if (fillsi > 0 && fillsi < 26) {
224  x[0] = x1; y[0] = y1;
225  x[1] = x2; y[1] = y1;
226  x[2] = x2; y[2] = y2;
227  x[3] = x1; y[3] = y2;
228  DrawPS(-4, &x[0], &y[0]);
229  }
230  if (fillsi == -3) {
231  PrintStr("@");
232  PrintFast(9,"<rect x=\"");
233  WriteReal(ix1, kFALSE);
234  PrintFast(5,"\" y=\"");
235  WriteReal(iy2, kFALSE);
236  PrintFast(9,"\" width=\"");
237  WriteReal(ix2-ix1, kFALSE);
238  PrintFast(10,"\" height=\"");
239  WriteReal(iy1-iy2, kFALSE);
240  PrintFast(7,"\" fill=");
241  SetColorAlpha(5);
242  PrintFast(2,"/>");
243  }
244  }
245  if (fillis == 1) {
246  PrintStr("@");
247  PrintFast(9,"<rect x=\"");
248  WriteReal(ix1, kFALSE);
249  PrintFast(5,"\" y=\"");
250  WriteReal(iy2, kFALSE);
251  PrintFast(9,"\" width=\"");
252  WriteReal(ix2-ix1, kFALSE);
253  PrintFast(10,"\" height=\"");
254  WriteReal(iy1-iy2, kFALSE);
255  PrintFast(7,"\" fill=");
256  SetColorAlpha(fFillColor);
257  PrintFast(2,"/>");
258  }
259  if (fillis == 0) {
260  if (fLineWidth<=0) return;
261  PrintStr("@");
262  PrintFast(9,"<rect x=\"");
263  WriteReal(ix1, kFALSE);
264  PrintFast(5,"\" y=\"");
265  WriteReal(iy2, kFALSE);
266  PrintFast(9,"\" width=\"");
267  WriteReal(ix2-ix1, kFALSE);
268  PrintFast(10,"\" height=\"");
269  WriteReal(iy1-iy2, kFALSE);
270  PrintFast(21,"\" fill=\"none\" stroke=");
271  SetColorAlpha(fLineColor);
272  PrintFast(2,"/>");
273  }
274 }
275 
276 ////////////////////////////////////////////////////////////////////////////////
277 /// Draw a Frame around a box
278 ///
279 /// - mode = -1 the box looks as it is behind the screen
280 /// - mode = 1 the box looks as it is in front of the screen
281 /// - border is the border size in already pre-computed SVG units dark is the
282 /// color for the dark part of the frame light is the color for the light
283 /// part of the frame
284 
285 void TSVG::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t yt,
286  Int_t mode, Int_t border, Int_t dark, Int_t light)
287 {
288  static Double_t xps[7], yps[7];
289  Int_t i;
290  Double_t ixd0, iyd0, ixdi, iydi, ix, iy;
291  Int_t idx, idy;
292 
293  //- Draw top&left part of the box
294 
295  xps[0] = XtoSVG(xl); yps[0] = YtoSVG(yl);
296  xps[1] = xps[0] + border; yps[1] = yps[0] - border;
297  xps[2] = xps[1]; yps[2] = YtoSVG(yt) + border;
298  xps[3] = XtoSVG(xt) - border; yps[3] = yps[2];
299  xps[4] = XtoSVG(xt); yps[4] = YtoSVG(yt);
300  xps[5] = xps[0]; yps[5] = yps[4];
301  xps[6] = xps[0]; yps[6] = yps[0];
302 
303  ixd0 = xps[0];
304  iyd0 = yps[0];
305  PrintStr("@");
306  PrintFast(10,"<path d=\"M");
307  WriteReal(ixd0, kFALSE);
308  PrintFast(1,",");
309  WriteReal(iyd0, kFALSE);
310 
311  idx = 0;
312  idy = 0;
313  for (i=1; i<7; i++) {
314  ixdi = xps[i];
315  iydi = yps[i];
316  ix = ixdi - ixd0;
317  iy = iydi - iyd0;
318  ixd0 = ixdi;
319  iyd0 = iydi;
320  if( ix && iy) {
321  if( idx ) { MovePS(idx,0); idx = 0; }
322  if( idy ) { MovePS(0,idy); idy = 0; }
323  MovePS(ix,iy);
324  continue;
325  }
326  if ( ix ) {
327  if( idy ) { MovePS(0,idy); idy = 0; }
328  if( !idx ) { idx = ix; continue;}
329  if( ix*idx > 0 ) {
330  idx += ix;
331  } else {
332  MovePS(idx,0);
333  idx = ix;
334  }
335  continue;
336  }
337  if( iy ) {
338  if( idx ) { MovePS(idx,0); idx = 0; }
339  if( !idy) { idy = iy; continue;}
340  if( iy*idy > 0 ) {
341  idy += iy;
342  } else {
343  MovePS(0,idy);
344  idy = iy;
345  }
346  }
347  }
348  if( idx ) MovePS(idx,0);
349  if( idy ) MovePS(0,idy);
350  PrintFast(8,"z\" fill=");
351  if (mode == -1) {
352  SetColorAlpha(dark);
353  } else {
354  SetColorAlpha(light);
355  }
356  PrintFast(2,"/>");
357 
358  //- Draw bottom&right part of the box
359  xps[0] = XtoSVG(xl); yps[0] = YtoSVG(yl);
360  xps[1] = xps[0] + border; yps[1] = yps[0] - border;
361  xps[2] = XtoSVG(xt) - border; yps[2] = yps[1];
362  xps[3] = xps[2]; yps[3] = YtoSVG(yt) + border;
363  xps[4] = XtoSVG(xt); yps[4] = YtoSVG(yt);
364  xps[5] = xps[4]; yps[5] = yps[0];
365  xps[6] = xps[0]; yps[6] = yps[0];
366 
367  ixd0 = xps[0];
368  iyd0 = yps[0];
369  PrintStr("@");
370  PrintFast(10,"<path d=\"M");
371  WriteReal(ixd0, kFALSE);
372  PrintFast(1,",");
373  WriteReal(iyd0, kFALSE);
374 
375  idx = 0;
376  idy = 0;
377  for (i=1;i<7;i++) {
378  ixdi = xps[i];
379  iydi = yps[i];
380  ix = ixdi - ixd0;
381  iy = iydi - iyd0;
382  ixd0 = ixdi;
383  iyd0 = iydi;
384  if( ix && iy) {
385  if( idx ) { MovePS(idx,0); idx = 0; }
386  if( idy ) { MovePS(0,idy); idy = 0; }
387  MovePS(ix,iy);
388  continue;
389  }
390  if ( ix ) {
391  if( idy ) { MovePS(0,idy); idy = 0; }
392  if( !idx ) { idx = ix; continue;}
393  if( ix*idx > 0 ) {
394  idx += ix;
395  } else {
396  MovePS(idx,0);
397  idx = ix;
398  }
399  continue;
400  }
401  if( iy ) {
402  if( idx ) { MovePS(idx,0); idx = 0; }
403  if( !idy) { idy = iy; continue;}
404  if( iy*idy > 0 ) {
405  idy += iy;
406  } else {
407  MovePS(0,idy);
408  idy = iy;
409  }
410  }
411  }
412  if( idx ) MovePS(idx,0);
413  if( idy ) MovePS(0,idy);
414  PrintFast(8,"z\" fill=");
415  if (mode == -1) {
416  SetColorAlpha(light);
417  } else {
418  SetColorAlpha(dark);
419  }
420  PrintFast(2,"/>");
421 }
422 
423 ////////////////////////////////////////////////////////////////////////////////
424 /// Draw a PolyLine
425 ///
426 /// Draw a polyline through the points xy.
427 /// - If NN=1 moves only to point x,y.
428 /// - If NN=0 the x,y are written in the SVG file
429 /// according to the current transformation.
430 /// - If NN>0 the line is clipped as a line.
431 /// - If NN<0 the line is clipped as a fill area.
432 
433 void TSVG::DrawPolyLine(Int_t nn, TPoints *xy)
434 {
435  Int_t n, idx, idy;
436  Double_t ixd0, iyd0, ixdi, iydi, ix, iy;
437 
438  if (nn > 0) {
439  n = nn;
440  } else {
441  n = -nn;
442  }
443 
444  ixd0 = XtoSVG(xy[0].GetX());
445  iyd0 = YtoSVG(xy[0].GetY());
446  if( n <= 1) return;
447 
448  PrintFast(2," m");
449  idx = 0;
450  idy = 0;
451  for (Int_t i=1;i<n;i++) {
452  ixdi = XtoSVG(xy[i].GetX());
453  iydi = YtoSVG(xy[i].GetY());
454  ix = ixdi - ixd0;
455  iy = iydi - iyd0;
456  ixd0 = ixdi;
457  iyd0 = iydi;
458  if( ix && iy) {
459  if( idx ) { MovePS(idx,0); idx = 0; }
460  if( idy ) { MovePS(0,idy); idy = 0; }
461  MovePS(ix,iy);
462  continue;
463  }
464  if ( ix ) {
465  if( idy ) { MovePS(0,idy); idy = 0; }
466  if( !idx ) { idx = ix; continue;}
467  if( ix*idx > 0 ) {
468  idx += ix;
469  } else {
470  MovePS(idx,0);
471  idx = ix;
472  }
473  continue;
474  }
475  if( iy ) {
476  if( idx ) { MovePS(idx,0); idx = 0; }
477  if( !idy) { idy = iy; continue;}
478  if( iy*idy > 0 ) {
479  idy += iy;
480  } else {
481  MovePS(0,idy);
482  idy = iy;
483  }
484  }
485  }
486  if( idx ) MovePS(idx,0);
487  if( idy ) MovePS(0,idy);
488 
489  if (nn > 0 ) {
490  } else {
491  }
492 }
493 
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Draw a PolyLine in NDC space
496 ///
497 /// Draw a polyline through the points xy.
498 /// --If NN=1 moves only to point x,y.
499 /// --If NN=0 the x,y are written in the SVG file
500 /// according to the current transformation.
501 /// --If NN>0 the line is clipped as a line.
502 /// - If NN<0 the line is clipped as a fill area.
503 
504 void TSVG::DrawPolyLineNDC(Int_t nn, TPoints *xy)
505 {
506  Int_t n, idx, idy;
507  Double_t ixd0, iyd0, ixdi, iydi, ix, iy;
508 
509  if (nn > 0) {
510  n = nn;
511  } else {
512  n = -nn;
513  }
514 
515  ixd0 = UtoSVG(xy[0].GetX());
516  iyd0 = VtoSVG(xy[0].GetY());
517  if( n <= 1) return;
518 
519  idx = 0;
520  idy = 0;
521  for (Int_t i=1;i<n;i++) {
522  ixdi = UtoSVG(xy[i].GetX());
523  iydi = VtoSVG(xy[i].GetY());
524  ix = ixdi - ixd0;
525  iy = iydi - iyd0;
526  ixd0 = ixdi;
527  iyd0 = iydi;
528  if( ix && iy) {
529  if( idx ) { MovePS(idx,0); idx = 0; }
530  if( idy ) { MovePS(0,idy); idy = 0; }
531  MovePS(ix,iy);
532  continue;
533  }
534  if ( ix ) {
535  if( idy ) { MovePS(0,idy); idy = 0; }
536  if( !idx ) { idx = ix; continue;}
537  if( ix*idx > 0 ) {
538  idx += ix;
539  } else {
540  MovePS(idx,0);
541  idx = ix;
542  }
543  continue;
544  }
545  if( iy ) {
546  if( idx ) { MovePS(idx,0); idx = 0; }
547  if( !idy) { idy = iy; continue;}
548  if( iy*idy > 0 ) {
549  idy += iy;
550  } else {
551  MovePS(0,idy);
552  idy = iy;
553  }
554  }
555  }
556  if( idx ) MovePS(idx,0);
557  if( idy ) MovePS(0,idy);
558 
559  if (nn > 0 ) {
560  if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
561  } else {
562  }
563 }
564 
565 ////////////////////////////////////////////////////////////////////////////////
566 /// Paint PolyMarker
567 
568 void TSVG::DrawPolyMarker(Int_t n, Float_t *xw, Float_t *yw)
569 {
570  Int_t ms = abs(fMarkerStyle);
571 
572  if (ms >= 6 && ms <= 19) ms = 20;
573  if (ms == 4) ms = 24;
574 
575  // Define the marker size
576  Float_t msize = fMarkerSize;
577  if (fMarkerStyle == 1) msize = 0.01;
578  if (fMarkerStyle == 6) msize = 0.02;
579  if (fMarkerStyle == 7) msize = 0.04;
580 
581  const Int_t kBASEMARKER = 8;
582  Float_t sbase = msize*kBASEMARKER;
583  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
584  msize = this->UtoSVG(s2x) - this->UtoSVG(0);
585 
586  Double_t m = msize;
587  Double_t m2 = m/2.;
588  Double_t m3 = m/3.;
589  Double_t m6 = m/6.;
590  Double_t m8 = m/8.;
591  Double_t m4 = m/4.;
592  Double_t m0 = m/10.;
593 
594  // Draw the marker according to the type
595  PrintStr("@");
596  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
597  ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
598  ms == 47 || ms == 48 || ms == 49) {
599  PrintStr("<g fill=");
600  SetColorAlpha(Int_t(fMarkerColor));
601  PrintStr(">");
602  } else {
603  PrintStr("<g stroke=");
604  SetColorAlpha(Int_t(fMarkerColor));
605  PrintStr(" stroke-width=\"");
606  WriteReal(fLineWidth, kFALSE);
607  PrintStr("\" fill=\"none\"");
608  PrintStr(">");
609  }
610  Double_t ix,iy;
611  for (Int_t i=0;i<n;i++) {
612  ix = XtoSVG(xw[i]);
613  iy = YtoSVG(yw[i]);
614  PrintStr("@");
615  // Dot (.)
616  if (ms == 1) {
617  PrintStr("<line x1=\"");
618  WriteReal(ix-1, kFALSE);
619  PrintStr("\" y1=\"");
620  WriteReal(iy, kFALSE);
621  PrintStr("\" x2=\"");
622  WriteReal(ix, kFALSE);
623  PrintStr("\" y2=\"");
624  WriteReal(iy, kFALSE);
625  PrintStr("\"/>");
626  // Plus (+)
627  } else if (ms == 2) {
628  PrintStr("<line x1=\"");
629  WriteReal(ix-m2, kFALSE);
630  PrintStr("\" y1=\"");
631  WriteReal(iy, kFALSE);
632  PrintStr("\" x2=\"");
633  WriteReal(ix+m2, kFALSE);
634  PrintStr("\" y2=\"");
635  WriteReal(iy, kFALSE);
636  PrintStr("\"/>");
637 
638  PrintStr("<line x1=\"");
639  WriteReal(ix, kFALSE);
640  PrintStr("\" y1=\"");
641  WriteReal(iy-m2, kFALSE);
642  PrintStr("\" x2=\"");
643  WriteReal(ix, kFALSE);
644  PrintStr("\" y2=\"");
645  WriteReal(iy+m2, kFALSE);
646  PrintStr("\"/>");
647  // X shape (X)
648  } else if (ms == 5) {
649  PrintStr("<line x1=\"");
650  WriteReal(ix-m2, kFALSE);
651  PrintStr("\" y1=\"");
652  WriteReal(iy-m2, kFALSE);
653  PrintStr("\" x2=\"");
654  WriteReal(ix+m2, kFALSE);
655  PrintStr("\" y2=\"");
656  WriteReal(iy+m2, kFALSE);
657  PrintStr("\"/>");
658 
659  PrintStr("<line x1=\"");
660  WriteReal(ix-m2, kFALSE);
661  PrintStr("\" y1=\"");
662  WriteReal(iy+m2, kFALSE);
663  PrintStr("\" x2=\"");
664  WriteReal(ix+m2, kFALSE);
665  PrintStr("\" y2=\"");
666  WriteReal(iy-m2, kFALSE);
667  PrintStr("\"/>");
668  // Asterisk shape (*)
669  } else if (ms == 3 || ms == 31) {
670  PrintStr("<line x1=\"");
671  WriteReal(ix-m2, kFALSE);
672  PrintStr("\" y1=\"");
673  WriteReal(iy, kFALSE);
674  PrintStr("\" x2=\"");
675  WriteReal(ix+m2, kFALSE);
676  PrintStr("\" y2=\"");
677  WriteReal(iy, kFALSE);
678  PrintStr("\"/>");
679 
680  PrintStr("<line x1=\"");
681  WriteReal(ix, kFALSE);
682  PrintStr("\" y1=\"");
683  WriteReal(iy-m2, kFALSE);
684  PrintStr("\" x2=\"");
685  WriteReal(ix, kFALSE);
686  PrintStr("\" y2=\"");
687  WriteReal(iy+m2, kFALSE);
688  PrintStr("\"/>");
689 
690  PrintStr("<line x1=\"");
691  WriteReal(ix-m2, kFALSE);
692  PrintStr("\" y1=\"");
693  WriteReal(iy-m2, kFALSE);
694  PrintStr("\" x2=\"");
695  WriteReal(ix+m2, kFALSE);
696  PrintStr("\" y2=\"");
697  WriteReal(iy+m2, kFALSE);
698  PrintStr("\"/>");
699 
700  PrintStr("<line x1=\"");
701  WriteReal(ix-m2, kFALSE);
702  PrintStr("\" y1=\"");
703  WriteReal(iy+m2, kFALSE);
704  PrintStr("\" x2=\"");
705  WriteReal(ix+m2, kFALSE);
706  PrintStr("\" y2=\"");
707  WriteReal(iy-m2, kFALSE);
708  PrintStr("\"/>");
709  // Circle
710  } else if (ms == 24 || ms == 20) {
711  PrintStr("<circle cx=\"");
712  WriteReal(ix, kFALSE);
713  PrintStr("\" cy=\"");
714  WriteReal(iy, kFALSE);
715  PrintStr("\" r=\"");
716  if (m2<=0) m2=1;
717  WriteReal(m2, kFALSE);
718  PrintStr("\" fill=\"none\"");
719  PrintStr("/>");
720  // Square
721  } else if (ms == 25 || ms == 21) {
722  PrintStr("<rect x=\"");
723  WriteReal(ix-m2, kFALSE);
724  PrintStr("\" y=\"");
725  WriteReal(iy-m2, kFALSE);
726  PrintStr("\" width=\"");
727  WriteReal(m, kFALSE);
728  PrintStr("\" height=\"");
729  WriteReal(m, kFALSE);
730  PrintStr("\" fill=\"none\"");
731  PrintStr("/>");
732  // Down triangle
733  } else if (ms == 26 || ms == 22) {
734  PrintStr("<polygon points=\"");
735  WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
736  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
737  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
738  PrintStr("\"/>");
739  // Up triangle
740  } else if (ms == 23 || ms == 32) {
741  PrintStr("<polygon points=\"");
742  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
743  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
744  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
745  PrintStr("\"/>");
746  // Diamond
747  } else if (ms == 27 || ms == 33) {
748  PrintStr("<polygon points=\"");
749  WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
750  WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
751  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
752  WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
753  PrintStr("\"/>");
754  // Cross
755  } else if (ms == 28 || ms == 34) {
756  PrintStr("<polygon points=\"");
757  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
758  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
759  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
760  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
761  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
762  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
763  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
764  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
765  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
766  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
767  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
768  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
769  PrintStr("\"/>");
770  } else if (ms == 29 || ms == 30) {
771  PrintStr("<polygon points=\"");
772  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
773  WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
774  WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
775  WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
776  WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
777  WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
778  WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
779  WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
780  WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
781  WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
782  PrintStr("\"/>");
783  } else if (ms == 35) {
784  PrintStr("<polygon points=\"");
785  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
786  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
787  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
788  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
789  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
790  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
791  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
792  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
793  PrintStr("\"/>");
794  } else if (ms == 36) {
795  PrintStr("<polygon points=\"");
796  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
797  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
798  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
799  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
800  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
801  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
802  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
803  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
804  PrintStr("\"/>");
805  } else if (ms == 37 || ms == 39) {
806  PrintStr("<polygon points=\"");
807  WriteReal(ix ); PrintStr(","); WriteReal(iy );
808  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
809  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
810  WriteReal(ix ); PrintStr(","); WriteReal(iy );
811  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
812  WriteReal(ix-m2); PrintStr(","); WriteReal(iy);
813  WriteReal(ix ); PrintStr(","); WriteReal(iy );
814  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
815  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
816  WriteReal(ix ); PrintStr(","); WriteReal(iy );
817  PrintStr("\"/>");
818  } else if (ms == 38) {
819  PrintStr("<polygon points=\"");
820  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
821  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
822  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
823  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
824  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
825  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
826  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
827  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
828  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
829  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
830  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
831  WriteReal(ix ); PrintStr(","); WriteReal(iy );
832  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
833  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
834  WriteReal(ix ); PrintStr(","); WriteReal(iy);
835  PrintStr("\"/>");
836  } else if (ms == 40 || ms == 41) {
837  PrintStr("<polygon points=\"");
838  WriteReal(ix ); PrintStr(","); WriteReal(iy );
839  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
840  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
841  WriteReal(ix ); PrintStr(","); WriteReal(iy );
842  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
843  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
844  WriteReal(ix ); PrintStr(","); WriteReal(iy );
845  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
846  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
847  WriteReal(ix ); PrintStr(","); WriteReal(iy );
848  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
849  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
850  WriteReal(ix ); PrintStr(","); WriteReal(iy );
851  PrintStr("\"/>");
852  } else if (ms == 42 || ms == 43) {
853  PrintStr("<polygon points=\"");
854  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
855  WriteReal(ix-m8); PrintStr(","); WriteReal(iy+m8);
856  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
857  WriteReal(ix-m8); PrintStr(","); WriteReal(iy-m8);
858  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
859  WriteReal(ix+m8); PrintStr(","); WriteReal(iy-m8);
860  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
861  WriteReal(ix+m8); PrintStr(","); WriteReal(iy+m8);
862  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
863  PrintStr("\"/>");
864  } else if (ms == 44) {
865  PrintStr("<polygon points=\"");
866  WriteReal(ix ); PrintStr(","); WriteReal(iy );
867  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
868  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
869  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
870  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
871  WriteReal(ix ); PrintStr(","); WriteReal(iy );
872  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
873  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
874  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
875  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
876  WriteReal(ix ); PrintStr(","); WriteReal(iy );
877  PrintStr("\"/>");
878  } else if (ms == 45) {
879  PrintStr("<polygon points=\"");
880  WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
881  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
882  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
883  WriteReal(ix-m0); PrintStr(","); WriteReal(iy+m0);
884  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
885  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
886  WriteReal(ix-m0); PrintStr(","); WriteReal(iy-m0);
887  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
888  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
889  WriteReal(ix+m0); PrintStr(","); WriteReal(iy-m0);
890  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
891  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
892  WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
893  PrintStr("\"/>");
894  } else if (ms == 46 || ms == 47) {
895  PrintStr("<polygon points=\"");
896  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
897  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
898  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
899  WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
900  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
901  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
902  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
903  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
904  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
905  WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
906  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
907  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
908  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
909  PrintStr("\"/>");
910  } else if (ms == 48) {
911  PrintStr("<polygon points=\"");
912  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*1.01);
913  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
914  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
915  WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
916  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
917  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
918  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
919  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
920  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
921  WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
922  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
923  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
924  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
925  WriteReal(ix+m4*0.99); PrintStr(","); WriteReal(iy );
926  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4*0.99);
927  WriteReal(ix-m4*0.99); PrintStr(","); WriteReal(iy );
928  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
929  PrintStr("\"/>");
930  } else if (ms == 49) {
931  PrintStr("<polygon points=\"");
932  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*1.01);
933  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
934  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
935  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
936  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
937  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
938  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
939  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
940  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
941  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
942  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
943  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
944  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*0.99);
945  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
946  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
947  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
948  PrintStr("\"/>");
949  } else {
950  PrintStr("<line x1=\"");
951  WriteReal(ix-1, kFALSE);
952  PrintStr("\" y1=\"");
953  WriteReal(iy, kFALSE);
954  PrintStr("\" x2=\"");
955  WriteReal(ix, kFALSE);
956  PrintStr("\" y2=\"");
957  WriteReal(iy, kFALSE);
958  PrintStr("\"/>");
959  }
960  }
961  PrintStr("@");
962  PrintStr("</g>");
963 }
964 
965 ////////////////////////////////////////////////////////////////////////////////
966 /// Paint PolyMarker
967 
968 void TSVG::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
969 {
970  Int_t ms = abs(fMarkerStyle);
971 
972  if (ms >= 6 && ms <= 19) ms = 20;
973  if (ms == 4) ms = 24;
974 
975  // Define the marker size
976  Float_t msize = fMarkerSize;
977  if (fMarkerStyle == 1) msize = 0.01;
978  if (fMarkerStyle == 6) msize = 0.02;
979  if (fMarkerStyle == 7) msize = 0.04;
980 
981  const Int_t kBASEMARKER = 8;
982  Float_t sbase = msize*kBASEMARKER;
983  Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
984  msize = this->UtoSVG(s2x) - this->UtoSVG(0);
985 
986  Double_t m = msize;
987  Double_t m2 = m/2;
988  Double_t m3 = m/3;
989  Double_t m6 = m/6;
990  Double_t m4 = m/4.;
991  Double_t m8 = m/8.;
992  Double_t m0 = m/10.;
993 
994  // Draw the marker according to the type
995  PrintStr("@");
996  if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34 ||
997  ms == 39 || ms == 41 || ms == 43 || ms == 45 ||
998  ms == 47 || ms == 48 || ms == 49) {
999  PrintStr("<g fill=");
1000  SetColorAlpha(Int_t(fMarkerColor));
1001  PrintStr(">");
1002  } else {
1003  PrintStr("<g stroke=");
1004  SetColorAlpha(Int_t(fMarkerColor));
1005  PrintStr(" stroke-width=\"");
1006  WriteReal(fLineWidth, kFALSE);
1007  PrintStr("\" fill=\"none\"");
1008  PrintStr(">");
1009  }
1010  Double_t ix,iy;
1011  for (Int_t i=0;i<n;i++) {
1012  ix = XtoSVG(xw[i]);
1013  iy = YtoSVG(yw[i]);
1014  PrintStr("@");
1015  // Dot (.)
1016  if (ms == 1) {
1017  PrintStr("<line x1=\"");
1018  WriteReal(ix-1, kFALSE);
1019  PrintStr("\" y1=\"");
1020  WriteReal(iy, kFALSE);
1021  PrintStr("\" x2=\"");
1022  WriteReal(ix, kFALSE);
1023  PrintStr("\" y2=\"");
1024  WriteReal(iy, kFALSE);
1025  PrintStr("\"/>");
1026  // Plus (+)
1027  } else if (ms == 2) {
1028  PrintStr("<line x1=\"");
1029  WriteReal(ix-m2, kFALSE);
1030  PrintStr("\" y1=\"");
1031  WriteReal(iy, kFALSE);
1032  PrintStr("\" x2=\"");
1033  WriteReal(ix+m2, kFALSE);
1034  PrintStr("\" y2=\"");
1035  WriteReal(iy, kFALSE);
1036  PrintStr("\"/>");
1037 
1038  PrintStr("<line x1=\"");
1039  WriteReal(ix, kFALSE);
1040  PrintStr("\" y1=\"");
1041  WriteReal(iy-m2, kFALSE);
1042  PrintStr("\" x2=\"");
1043  WriteReal(ix, kFALSE);
1044  PrintStr("\" y2=\"");
1045  WriteReal(iy+m2, kFALSE);
1046  PrintStr("\"/>");
1047  // X shape (X)
1048  } else if (ms == 5) {
1049  PrintStr("<line x1=\"");
1050  WriteReal(ix-m2, kFALSE);
1051  PrintStr("\" y1=\"");
1052  WriteReal(iy-m2, kFALSE);
1053  PrintStr("\" x2=\"");
1054  WriteReal(ix+m2, kFALSE);
1055  PrintStr("\" y2=\"");
1056  WriteReal(iy+m2, kFALSE);
1057  PrintStr("\"/>");
1058 
1059  PrintStr("<line x1=\"");
1060  WriteReal(ix-m2, kFALSE);
1061  PrintStr("\" y1=\"");
1062  WriteReal(iy+m2, kFALSE);
1063  PrintStr("\" x2=\"");
1064  WriteReal(ix+m2, kFALSE);
1065  PrintStr("\" y2=\"");
1066  WriteReal(iy-m2, kFALSE);
1067  PrintStr("\"/>");
1068  // Asterisk shape (*)
1069  } else if (ms == 3 || ms == 31) {
1070  PrintStr("<line x1=\"");
1071  WriteReal(ix-m2, kFALSE);
1072  PrintStr("\" y1=\"");
1073  WriteReal(iy, kFALSE);
1074  PrintStr("\" x2=\"");
1075  WriteReal(ix+m2, kFALSE);
1076  PrintStr("\" y2=\"");
1077  WriteReal(iy, kFALSE);
1078  PrintStr("\"/>");
1079 
1080  PrintStr("<line x1=\"");
1081  WriteReal(ix, kFALSE);
1082  PrintStr("\" y1=\"");
1083  WriteReal(iy-m2, kFALSE);
1084  PrintStr("\" x2=\"");
1085  WriteReal(ix, kFALSE);
1086  PrintStr("\" y2=\"");
1087  WriteReal(iy+m2, kFALSE);
1088  PrintStr("\"/>");
1089 
1090  PrintStr("<line x1=\"");
1091  WriteReal(ix-m2, kFALSE);
1092  PrintStr("\" y1=\"");
1093  WriteReal(iy-m2, kFALSE);
1094  PrintStr("\" x2=\"");
1095  WriteReal(ix+m2, kFALSE);
1096  PrintStr("\" y2=\"");
1097  WriteReal(iy+m2, kFALSE);
1098  PrintStr("\"/>");
1099 
1100  PrintStr("<line x1=\"");
1101  WriteReal(ix-m2, kFALSE);
1102  PrintStr("\" y1=\"");
1103  WriteReal(iy+m2, kFALSE);
1104  PrintStr("\" x2=\"");
1105  WriteReal(ix+m2, kFALSE);
1106  PrintStr("\" y2=\"");
1107  WriteReal(iy-m2, kFALSE);
1108  PrintStr("\"/>");
1109  // Circle
1110  } else if (ms == 24 || ms == 20) {
1111  PrintStr("<circle cx=\"");
1112  WriteReal(ix, kFALSE);
1113  PrintStr("\" cy=\"");
1114  WriteReal(iy, kFALSE);
1115  PrintStr("\" r=\"");
1116  if (m2<=0) m2=1;
1117  WriteReal(m2, kFALSE);
1118  PrintStr("\"/>");
1119  // Square
1120  } else if (ms == 25 || ms == 21) {
1121  PrintStr("<rect x=\"");
1122  WriteReal(ix-m2, kFALSE);
1123  PrintStr("\" y=\"");
1124  WriteReal(iy-m2, kFALSE);
1125  PrintStr("\" width=\"");
1126  WriteReal(m, kFALSE);
1127  PrintStr("\" height=\"");
1128  WriteReal(m, kFALSE);
1129  PrintStr("\"/>");
1130  // Down triangle
1131  } else if (ms == 26 || ms == 22) {
1132  PrintStr("<polygon points=\"");
1133  WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
1134  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
1135  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
1136  PrintStr("\"/>");
1137  // Up triangle
1138  } else if (ms == 23 || ms == 32) {
1139  PrintStr("<polygon points=\"");
1140  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
1141  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
1142  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
1143  PrintStr("\"/>");
1144  // Diamond
1145  } else if (ms == 27 || ms == 33) {
1146  PrintStr("<polygon points=\"");
1147  WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
1148  WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
1149  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
1150  WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
1151  PrintStr("\"/>");
1152  // Cross
1153  } else if (ms == 28 || ms == 34) {
1154  PrintStr("<polygon points=\"");
1155  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
1156  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
1157  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
1158  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
1159  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
1160  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
1161  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
1162  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
1163  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
1164  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
1165  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
1166  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
1167  PrintStr("\"/>");
1168  } else if (ms == 29 || ms == 30) {
1169  PrintStr("<polygon points=\"");
1170  WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
1171  WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
1172  WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
1173  WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
1174  WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
1175  WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
1176  WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
1177  WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
1178  WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
1179  WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
1180  PrintStr("\"/>");
1181  } else if (ms == 35) {
1182  PrintStr("<polygon points=\"");
1183  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
1184  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
1185  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
1186  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
1187  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
1188  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
1189  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
1190  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
1191  PrintStr("\"/>");
1192  } else if (ms == 36) {
1193  PrintStr("<polygon points=\"");
1194  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
1195  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
1196  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
1197  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
1198  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
1199  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
1200  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
1201  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
1202  PrintStr("\"/>");
1203  } else if (ms == 37 || ms == 39) {
1204  PrintStr("<polygon points=\"");
1205  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1206  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1207  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1208  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1209  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1210  WriteReal(ix-m2); PrintStr(","); WriteReal(iy);
1211  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1212  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
1213  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1214  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1215  PrintStr("\"/>");
1216  } else if (ms == 38) {
1217  PrintStr("<polygon points=\"");
1218  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
1219  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1220  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1221  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1222  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1223  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1224  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1225  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1226  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1227  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
1228  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
1229  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1230  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
1231  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
1232  WriteReal(ix ); PrintStr(","); WriteReal(iy);
1233  PrintStr("\"/>");
1234  } else if (ms == 40 || ms == 41) {
1235  PrintStr("<polygon points=\"");
1236  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1237  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1238  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1239  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1240  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1241  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1242  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1243  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1244  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1245  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1246  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1247  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1248  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1249  PrintStr("\"/>");
1250  } else if (ms == 42 || ms == 43) {
1251  PrintStr("<polygon points=\"");
1252  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
1253  WriteReal(ix-m8); PrintStr(","); WriteReal(iy+m8);
1254  WriteReal(ix-m2); PrintStr(","); WriteReal(iy );
1255  WriteReal(ix-m8); PrintStr(","); WriteReal(iy-m8);
1256  WriteReal(ix ); PrintStr(","); WriteReal(iy-m2);
1257  WriteReal(ix+m8); PrintStr(","); WriteReal(iy-m8);
1258  WriteReal(ix+m2); PrintStr(","); WriteReal(iy );
1259  WriteReal(ix+m8); PrintStr(","); WriteReal(iy+m8);
1260  WriteReal(ix ); PrintStr(","); WriteReal(iy+m2);
1261  PrintStr("\"/>");
1262  } else if (ms == 44) {
1263  PrintStr("<polygon points=\"");
1264  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1265  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1266  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1267  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1268  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1269  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1270  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1271  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1272  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1273  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1274  WriteReal(ix ); PrintStr(","); WriteReal(iy );
1275  PrintStr("\"/>");
1276  } else if (ms == 45) {
1277  PrintStr("<polygon points=\"");
1278  WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
1279  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1280  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1281  WriteReal(ix-m0); PrintStr(","); WriteReal(iy+m0);
1282  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1283  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1284  WriteReal(ix-m0); PrintStr(","); WriteReal(iy-m0);
1285  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1286  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1287  WriteReal(ix+m0); PrintStr(","); WriteReal(iy-m0);
1288  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1289  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1290  WriteReal(ix+m0); PrintStr(","); WriteReal(iy+m0);
1291  PrintStr("\"/>");
1292  } else if (ms == 46 || ms == 47) {
1293  PrintStr("<polygon points=\"");
1294  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
1295  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1296  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1297  WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
1298  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1299  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1300  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
1301  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1302  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1303  WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
1304  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1305  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1306  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4);
1307  PrintStr("\"/>");
1308  } else if (ms == 48) {
1309  PrintStr("<polygon points=\"");
1310  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*1.01);
1311  WriteReal(ix-m4); PrintStr(","); WriteReal(iy+m2);
1312  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m4);
1313  WriteReal(ix-m4); PrintStr(","); WriteReal(iy );
1314  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m4);
1315  WriteReal(ix-m4); PrintStr(","); WriteReal(iy-m2);
1316  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4);
1317  WriteReal(ix+m4); PrintStr(","); WriteReal(iy-m2);
1318  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m4);
1319  WriteReal(ix+m4); PrintStr(","); WriteReal(iy );
1320  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m4);
1321  WriteReal(ix+m4); PrintStr(","); WriteReal(iy+m2);
1322  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
1323  WriteReal(ix+m4*0.99); PrintStr(","); WriteReal(iy );
1324  WriteReal(ix ); PrintStr(","); WriteReal(iy-m4*0.99);
1325  WriteReal(ix-m4*0.99); PrintStr(","); WriteReal(iy );
1326  WriteReal(ix ); PrintStr(","); WriteReal(iy+m4*0.99);
1327  PrintStr("\"/>");
1328  } else if (ms == 49) {
1329  PrintStr("<polygon points=\"");
1330  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*1.01);
1331  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
1332  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
1333  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
1334  WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
1335  WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
1336  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
1337  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
1338  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
1339  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
1340  WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
1341  WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
1342  WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6*0.99);
1343  WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
1344  WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
1345  WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
1346  PrintStr("\"/>");
1347  } else {
1348  PrintStr("<line x1=\"");
1349  WriteReal(ix-1, kFALSE);
1350  PrintStr("\" y1=\"");
1351  WriteReal(iy, kFALSE);
1352  PrintStr("\" x2=\"");
1353  WriteReal(ix, kFALSE);
1354  PrintStr("\" y2=\"");
1355  WriteReal(iy, kFALSE);
1356  PrintStr("\"/>");
1357  }
1358  }
1359  PrintStr("@");
1360  PrintStr("</g>");
1361 }
1362 
1363 ////////////////////////////////////////////////////////////////////////////////
1364 /// This function defines a path with xw and yw and draw it according the
1365 /// value of nn:
1366 ///
1367 /// - If nn>0 a line is drawn.
1368 /// - If nn<0 a closed polygon is drawn.
1369 
1370 void TSVG::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
1371 {
1372  Int_t n, fais, fasi;
1373  Double_t ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
1374  fais = fasi = 0;
1375 
1376  if (nn > 0) {
1377  if (fLineWidth<=0) return;
1378  n = nn;
1379  } else {
1380  n = -nn;
1381  fais = fFillStyle/1000;
1382  fasi = fFillStyle%1000;
1383  if (fais == 3 || fais == 2) {
1384  if (fasi > 100 && fasi <125) {
1385  return;
1386  }
1387  if (fasi > 0 && fasi < 26) {
1388  }
1389  }
1390  }
1391 
1392  if( n <= 1) {
1393  Error("DrawPS", "Two points are needed");
1394  return;
1395  }
1396 
1397  ixd0 = XtoSVG(xw[0]);
1398  iyd0 = YtoSVG(yw[0]);
1399 
1400  PrintStr("@");
1401  PrintFast(10,"<path d=\"M");
1402  WriteReal(ixd0, kFALSE);
1403  PrintFast(1,",");
1404  WriteReal(iyd0, kFALSE);
1405 
1406  idx = idy = 0;
1407  for (Int_t i=1;i<n;i++) {
1408  ixdi = XtoSVG(xw[i]);
1409  iydi = YtoSVG(yw[i]);
1410  ix = ixdi - ixd0;
1411  iy = iydi - iyd0;
1412  ixd0 = ixdi;
1413  iyd0 = iydi;
1414  if( ix && iy) {
1415  if( idx ) { MovePS(idx,0); idx = 0; }
1416  if( idy ) { MovePS(0,idy); idy = 0; }
1417  MovePS(ix,iy);
1418  } else if ( ix ) {
1419  if( idy ) { MovePS(0,idy); idy = 0;}
1420  if( !idx ) { idx = ix;}
1421  else if( TMath::Sign(ix,idx) == ix ) idx += ix;
1422  else { MovePS(idx,0); idx = ix;}
1423  } else if( iy ) {
1424  if( idx ) { MovePS(idx,0); idx = 0;}
1425  if( !idy) { idy = iy;}
1426  else if( TMath::Sign(iy,idy) == iy) idy += iy;
1427  else { MovePS(0,idy); idy = iy;}
1428  }
1429  }
1430  if (idx) MovePS(idx,0);
1431  if (idy) MovePS(0,idy);
1432 
1433  if (nn > 0 ) {
1434  if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(1,"z");
1435  PrintFast(21,"\" fill=\"none\" stroke=");
1436  SetColorAlpha(fLineColor);
1437  if(fLineWidth > 1.) {
1438  PrintFast(15," stroke-width=\"");
1439  WriteReal(fLineWidth, kFALSE);
1440  PrintFast(1,"\"");
1441  }
1442  if (fLineStyle > 1) {
1443  PrintFast(19," stroke-dasharray=\"");
1444  TString st = (TString)gStyle->GetLineStyleString(fLineStyle);
1445  TObjArray *tokens = st.Tokenize(" ");
1446  for (Int_t j = 0; j<tokens->GetEntries(); j++) {
1447  Int_t it;
1448  sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
1449  if (j>0) PrintFast(1,",");
1450  WriteReal(it/4);
1451  }
1452  delete tokens;
1453  PrintFast(1,"\"");
1454  }
1455  PrintFast(2,"/>");
1456  } else {
1457  PrintFast(8,"z\" fill=");
1458  if (fais == 0) {
1459  PrintFast(14,"\"none\" stroke=");
1460  SetColorAlpha(fFillColor);
1461  } else {
1462  SetColorAlpha(fFillColor);
1463  }
1464  PrintFast(2,"/>");
1465  }
1466 }
1467 
1468 ////////////////////////////////////////////////////////////////////////////////
1469 /// Initialize the SVG file. The main task of the function is to output the
1470 /// SVG header file which consist in <title>, <desc> and <defs>. The
1471 /// HeaderPS provided by the user program is written in the <defs> part.
1472 
1473 void TSVG::Initialize()
1474 {
1475  // Title
1476  PrintStr("<title>@");
1477  PrintStr(GetName());
1478  PrintStr("@");
1479  PrintStr("</title>@");
1480 
1481  // Description
1482  PrintStr("<desc>@");
1483  PrintFast(22,"Creator: ROOT Version ");
1484  PrintStr(gROOT->GetVersion());
1485  PrintStr("@");
1486  PrintFast(14,"CreationDate: ");
1487  TDatime t;
1488  PrintStr(t.AsString());
1489  //Check a special header is defined in the current style
1490  Int_t nh = strlen(gStyle->GetHeaderPS());
1491  if (nh) {
1492  PrintFast(nh,gStyle->GetHeaderPS());
1493  }
1494  PrintStr("</desc>@");
1495 
1496  // Definitions
1497  PrintStr("<defs>@");
1498  PrintStr("</defs>@");
1499 
1500 }
1501 
1502 ////////////////////////////////////////////////////////////////////////////////
1503 /// Move to a new position (ix, iy). The move is done in relative coordinates
1504 /// which allows to have short numbers which decrease the size of the file.
1505 /// This function use the full power of the SVG's paths by using the
1506 /// horizontal and vertical move whenever it is possible.
1507 
1508 void TSVG::MovePS(Double_t ix, Double_t iy)
1509 {
1510  if (ix != 0 && iy != 0) {
1511  PrintFast(1,"l");
1512  WriteReal(ix);
1513  PrintFast(1,",");
1514  WriteReal(iy);
1515  } else if (ix != 0) {
1516  PrintFast(1,"h");
1517  WriteReal(ix);
1518  } else if (iy != 0) {
1519  PrintFast(1,"v");
1520  WriteReal(iy);
1521  }
1522 }
1523 
1524 ////////////////////////////////////////////////////////////////////////////////
1525 /// Start the SVG page. This function initialize the pad conversion
1526 /// coefficients and output the <svg> directive which is close later in the
1527 /// the function Close.
1528 
1529 void TSVG::NewPage()
1530 {
1531  // Compute pad conversion coefficients
1532  if (gPad) {
1533  Double_t ww = gPad->GetWw();
1534  Double_t wh = gPad->GetWh();
1535  fYsize = fXsize*wh/ww;
1536  } else {
1537  fYsize = 27;
1538  }
1539 
1540  // <svg> directive. It defines the viewBox.
1541  if(!fBoundingBox) {
1542  PrintStr("@<?xml version=\"1.0\" standalone=\"no\"?>");
1543  PrintStr("@<svg width=\"");
1544  WriteReal(CMtoSVG(fXsize), kFALSE);
1545  PrintStr("\" height=\"");
1546  fYsizeSVG = CMtoSVG(fYsize);
1547  WriteReal(fYsizeSVG, kFALSE);
1548  PrintStr("\" viewBox=\"0 0");
1549  WriteReal(CMtoSVG(fXsize));
1550  WriteReal(fYsizeSVG);
1551  PrintStr("\" xmlns=\"http://www.w3.org/2000/svg\" shape-rendering=\"crispEdges\">");
1552  PrintStr("@");
1553  Initialize();
1554  fBoundingBox = kTRUE;
1555  }
1556 }
1557 
1558 ////////////////////////////////////////////////////////////////////////////////
1559 /// Set the range for the paper in centimetres
1560 
1561 void TSVG::Range(Float_t xsize, Float_t ysize)
1562 {
1563  Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
1564 
1565  fXsize = xsize;
1566  fYsize = ysize;
1567 
1568  xps = xsize;
1569  yps = ysize;
1570 
1571  if( xsize <= xps && ysize < yps) {
1572  if ( xps > yps ) xymax = xps;
1573  else xymax = yps;
1574  xncm = xsize/xymax;
1575  yncm = ysize/xymax;
1576  dxwn = ((xps/xymax)-xncm)/2;
1577  dywn = ((yps/xymax)-yncm)/2;
1578  } else {
1579  if (xps/yps < 1) xwkwn = xps/yps;
1580  else xwkwn = 1;
1581  if (yps/xps < 1) ywkwn = yps/xps;
1582  else ywkwn = 1;
1583 
1584  if (xsize < ysize) {
1585  xncm = ywkwn*xsize/ysize;
1586  yncm = ywkwn;
1587  dxwn = (xwkwn-xncm)/2;
1588  dywn = 0;
1589  if( dxwn < 0) {
1590  xncm = xwkwn;
1591  dxwn = 0;
1592  yncm = xwkwn*ysize/xsize;
1593  dywn = (ywkwn-yncm)/2;
1594  }
1595  } else {
1596  xncm = xwkwn;
1597  yncm = xwkwn*ysize/xsize;
1598  dxwn = 0;
1599  dywn = (ywkwn-yncm)/2;
1600  if( dywn < 0) {
1601  yncm = ywkwn;
1602  dywn = 0;
1603  xncm = ywkwn*xsize/ysize;
1604  dxwn = (xwkwn-xncm)/2;
1605  }
1606  }
1607  }
1608  fRange = kTRUE;
1609 }
1610 
1611 ////////////////////////////////////////////////////////////////////////////////
1612 /// Set color index for fill areas
1613 
1614 void TSVG::SetFillColor( Color_t cindex )
1615 {
1616  fFillColor = cindex;
1617  if (gStyle->GetFillColor() <= 0) cindex = 0;
1618 }
1619 
1620 ////////////////////////////////////////////////////////////////////////////////
1621 /// Set color index for lines
1622 
1623 void TSVG::SetLineColor( Color_t cindex )
1624 {
1625  fLineColor = cindex;
1626 }
1627 
1628 ////////////////////////////////////////////////////////////////////////////////
1629 /// Change the line style
1630 ///
1631 /// - linestyle = 2 dashed
1632 /// - linestyle = 3 dotted
1633 /// - linestyle = 4 dash-dotted
1634 /// - linestyle = else solid (1 in is used most of the time)
1635 
1636 void TSVG::SetLineStyle(Style_t linestyle)
1637 {
1638  fLineStyle = linestyle;
1639 }
1640 
1641 ////////////////////////////////////////////////////////////////////////////////
1642 /// Set the lines width.
1643 
1644 void TSVG::SetLineWidth(Width_t linewidth)
1645 {
1646  fLineWidth = linewidth;
1647 }
1648 
1649 ////////////////////////////////////////////////////////////////////////////////
1650 /// Set color index for markers.
1651 
1652 void TSVG::SetMarkerColor( Color_t cindex )
1653 {
1654  fMarkerColor = cindex;
1655 }
1656 
1657 ////////////////////////////////////////////////////////////////////////////////
1658 /// Set RGBa color with its color index
1659 
1660 void TSVG::SetColorAlpha(Int_t color)
1661 {
1662  if (color < 0) color = 0;
1663  TColor *col = gROOT->GetColor(color);
1664  if (col) {
1665  SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1666  Float_t a = col->GetAlpha();
1667  if (a<1.) PrintStr(Form(" fill-opacity=\"%3.2f\" stroke-opacity=\"%3.2f\"",a,a));
1668  } else {
1669  SetColor(1., 1., 1.);
1670  }
1671 }
1672 
1673 ////////////////////////////////////////////////////////////////////////////////
1674 /// Set RGB (without alpha channel) color with its color index
1675 
1676 void TSVG::SetColor(Int_t color)
1677 {
1678  if (color < 0) color = 0;
1679  TColor *col = gROOT->GetColor(color);
1680  if (col) {
1681  SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
1682  } else {
1683  SetColor(1., 1., 1.);
1684  }
1685 }
1686 
1687 ////////////////////////////////////////////////////////////////////////////////
1688 /// Set color with its R G B components
1689 ///
1690 /// - r: % of red in [0,1]
1691 /// --g: % of green in [0,1]
1692 /// - b: % of blue in [0,1]
1693 
1694 void TSVG::SetColor(Float_t r, Float_t g, Float_t b)
1695 {
1696  if (r <= 0. && g <= 0. && b <= 0. ) {
1697  PrintFast(7,"\"black\"");
1698  } else if (r >= 1. && g >= 1. && b >= 1. ) {
1699  PrintFast(7,"\"white\"");
1700  } else {
1701  char str[12];
1702  snprintf(str,12,"\"#%2.2x%2.2x%2.2x\"",Int_t(255.*r)
1703  ,Int_t(255.*g)
1704  ,Int_t(255.*b));
1705  PrintStr(str);
1706  }
1707 }
1708 
1709 ////////////////////////////////////////////////////////////////////////////////
1710 /// Set color index for text
1711 
1712 void TSVG::SetTextColor( Color_t cindex )
1713 {
1714  fTextColor = cindex;
1715 }
1716 
1717 ////////////////////////////////////////////////////////////////////////////////
1718 /// Draw text
1719 ///
1720 /// - xx: x position of the text
1721 /// - yy: y position of the text
1722 /// - chars: text to be drawn
1723 
1724 void TSVG::Text(Double_t xx, Double_t yy, const char *chars)
1725 {
1726  static const char *fontFamily[] = {
1727  "Times" , "Times" , "Times",
1728  "Helvetica", "Helvetica", "Helvetica" , "Helvetica",
1729  "Courier" , "Courier" , "Courier" , "Courier",
1730  "Times" ,"Times" , "ZapfDingbats", "Times"};
1731 
1732  static const char *fontWeight[] = {
1733  "normal", "bold", "bold",
1734  "normal", "normal", "bold" , "bold",
1735  "normal", "normal", "bold" , "bold",
1736  "normal", "normal", "normal", "normal"};
1737 
1738  static const char *fontStyle[] = {
1739  "italic", "normal" , "italic",
1740  "normal", "oblique", "normal", "oblique",
1741  "normal", "oblique", "normal", "oblique",
1742  "normal", "normal" , "normal", "italic"};
1743 
1744  Double_t ix = XtoSVG(xx);
1745  Double_t iy = YtoSVG(yy);
1746  Double_t txalh = fTextAlign/10;
1747  if (txalh <1) txalh = 1; else if (txalh > 3) txalh = 3;
1748  Double_t txalv = fTextAlign%10;
1749  if (txalv <1) txalv = 1; else if (txalv > 3) txalv = 3;
1750 
1751  Double_t wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
1752  Double_t hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
1753  Float_t fontrap = 1.09; //scale down compared to X11
1754  Float_t ftsize;
1755 
1756  Int_t font = abs(fTextFont)/10;
1757  if (font > 42 || font < 1) font = 1;
1758  if (wh < hh) {
1759  ftsize = fTextSize*fXsize*gPad->GetAbsWNDC();
1760  } else {
1761  ftsize = fTextSize*fYsize*gPad->GetAbsHNDC();
1762  }
1763  Int_t ifont = font-1;
1764 
1765  Double_t fontsize = CMtoSVG(ftsize/fontrap);
1766  if( fontsize <= 0) return;
1767 
1768  if (txalv == 3) iy = iy+fontsize;
1769  if (txalv == 2) iy = iy+(fontsize/2);
1770 
1771  if (fTextAngle != 0.) {
1772  PrintStr("@");
1773  PrintFast(21,"<g transform=\"rotate(");
1774  WriteReal(-fTextAngle, kFALSE);
1775  PrintFast(1,",");
1776  WriteReal(ix, kFALSE);
1777  PrintFast(1,",");
1778  WriteReal(iy, kFALSE);
1779  PrintFast(3,")\">");
1780  }
1781 
1782  PrintStr("@");
1783  PrintFast(30,"<text xml:space=\"preserve\" x=\"");
1784  WriteReal(ix, kFALSE);
1785  PrintFast(5,"\" y=\"");
1786  WriteReal(iy, kFALSE);
1787  PrintFast(1,"\"");
1788  if (txalh == 2) {
1789  PrintFast(21," text-anchor=\"middle\"");
1790  } else if (txalh == 3) {
1791  PrintFast(18," text-anchor=\"end\"");
1792  }
1793  PrintFast(6," fill=");
1794  SetColorAlpha(Int_t(fTextColor));
1795  PrintFast(12," font-size=\"");
1796  WriteReal(fontsize, kFALSE);
1797  PrintFast(15,"\" font-family=\"");
1798  PrintStr(fontFamily[ifont]);
1799  if (strcmp(fontWeight[ifont],"normal")) {
1800  PrintFast(15,"\" font-weight=\"");
1801  PrintStr(fontWeight[ifont]);
1802  }
1803  if (strcmp(fontStyle[ifont],"normal")) {
1804  PrintFast(14,"\" font-style=\"");
1805  PrintStr(fontStyle[ifont]);
1806  }
1807  PrintFast(2,"\">");
1808 
1809  if (font == 12 || font == 15) {
1810  Int_t ichar = chars[0]+848;
1811  Int_t ic = ichar;
1812 
1813  // Math Symbols (cf: http://www.fileformat.info/info/unicode/category/Sm/list.htm)
1814  if (ic == 755) ichar = 8804;
1815  if (ic == 759) ichar = 9827;
1816  if (ic == 760) ichar = 9830;
1817  if (ic == 761) ichar = 9829;
1818  if (ic == 762) ichar = 9824;
1819  if (ic == 766) ichar = 8594;
1820  if (ic == 776) ichar = 247;
1821  if (ic == 757) ichar = 8734;
1822  if (ic == 758) ichar = 402;
1823  if (ic == 771) ichar = 8805;
1824  if (ic == 774) ichar = 8706;
1825  if (ic == 775) ichar = 8226;
1826  if (ic == 779) ichar = 8776;
1827  if (ic == 805) ichar = 8719;
1828  if (ic == 821) ichar = 8721;
1829  if (ic == 834) ichar = 8747;
1830  if (ic == 769) ichar = 177;
1831  if (ic == 772) ichar = 215;
1832  if (ic == 768) ichar = 176;
1833  if (ic == 791) ichar = 8745;
1834  if (ic == 793) ichar = 8835; // SUPERSET OF
1835  if (ic == 794) ichar = 8839; // SUPERSET OF OR EQUAL TO
1836  if (ic == 795) ichar = 8836; // NOT A SUBSET OF
1837  if (ic == 796) ichar = 8834;
1838  if (ic == 893) ichar = 8722;
1839  if (ic == 803) ichar = 169; // COPYRIGHT SIGN
1840  if (ic == 819) ichar = 169; // COPYRIGHT SIGN
1841  if (ic == 804) ichar = 8482;
1842  if (ic == 770) ichar = 34;
1843  if (ic == 823) ichar = 10072;
1844  if (ic == 781) ichar = 10072;
1845  if (ic == 824) ichar = 9117; // LEFT PARENTHESIS LOWER HOOK
1846  if (ic == 822) ichar = 9115; // LEFT PARENTHESIS UPPER HOOK
1847  if (ic == 767) ichar = 8595; // DOWNWARDS ARROW
1848  if (ic == 763) ichar = 8596; // LEFT RIGHT ARROW
1849  if (ic == 764) ichar = 8592; // LEFTWARDS ARROW
1850  if (ic == 788) ichar = 8855; // CIRCLED TIMES
1851  if (ic == 784) ichar = 8501;
1852  if (ic == 777) ichar = 8800;
1853  if (ic == 797) ichar = 8838;
1854  if (ic == 800) ichar = 8736;
1855  if (ic == 812) ichar = 8656; // LEFTWARDS DOUBLE ARROW
1856  if (ic == 817) ichar = 60; // LESS-THAN SIGN
1857  if (ic == 833) ichar = 62; // GREATER-THAN SIGN
1858  if (ic == 778) ichar = 8803; // STRICTLY EQUIVALENT TO
1859  if (ic == 809) ichar = 8743; // LOGICAL AND
1860  if (ic == 802) ichar = 9415; // CIRCLED LATIN CAPITAL LETTER R
1861  if (ic == 780) ichar = 8230; // HORIZONTAL ELLIPSIS
1862  if (ic == 801) ichar = 8711; // NABLA
1863  if (ic == 783) ichar = 8629; // DOWNWARDS ARROW WITH CORNER LEFTWARDS
1864  if (ic == 782) ichar = 8213;
1865  if (ic == 799) ichar = 8713;
1866  if (ic == 792) ichar = 8746;
1867  if (ic == 828) ichar = 9127;
1868  if (ic == 765) ichar = 8593; // UPWARDS ARROW
1869  if (ic == 789) ichar = 8853; // CIRCLED PLUS
1870  if (ic == 813) ichar = 8657; // UPWARDS DOUBLE ARROW
1871  if (ic == 773) ichar = 8733; // PROPORTIONAL TO
1872  if (ic == 790) ichar = 8709; // EMPTY SET
1873  if (ic == 810) ichar = 8744;
1874  if (ic == 756) ichar = 8260;
1875  if (ic == 807) ichar = 8231;
1876  if (ic == 808) ichar = 8989; // TOP RIGHT CORNER
1877  if (ic == 814) ichar = 8658; // RIGHTWARDS DOUBLE ARROW
1878  if (ic == 806) ichar = 8730; // SQUARE ROOT
1879  if (ic == 827) ichar = 9123;
1880  if (ic == 829) ichar = 9128;
1881  if (ic == 786) ichar = 8476;
1882  if (ic == 785) ichar = 8465;
1883  if (ic == 787) ichar = 8472;
1884 
1885  // Greek characters
1886  if (ic == 918) ichar = 934;
1887  if (ic == 919) ichar = 915;
1888  if (ic == 920) ichar = 919;
1889  if (ic == 923) ichar = 922;
1890  if (ic == 924) ichar = 923;
1891  if (ic == 925) ichar = 924;
1892  if (ic == 926) ichar = 925;
1893  if (ic == 929) ichar = 920;
1894  if (ic == 930) ichar = 929;
1895  if (ic == 936) ichar = 926;
1896  if (ic == 915) ichar = 935;
1897  if (ic == 937) ichar = 936;
1898  if (ic == 935) ichar = 937;
1899  if (ic == 938) ichar = 918;
1900  if (ic == 951) ichar = 947;
1901  if (ic == 798) ichar = 949;
1902  if (ic == 970) ichar = 950;
1903  if (ic == 952) ichar = 951;
1904  if (ic == 961) ichar = 952;
1905  if (ic == 955) ichar = 954;
1906  if (ic == 956) ichar = 955;
1907  if (ic == 957) ichar = 956;
1908  if (ic == 958) ichar = 957;
1909  if (ic == 968) ichar = 958;
1910  if (ic == 934) ichar = 962;
1911  if (ic == 962) ichar = 961;
1912  if (ic == 966) ichar = 969;
1913  if (ic == 950) ichar = 966;
1914  if (ic == 947) ichar = 967;
1915  if (ic == 969) ichar = 968;
1916  if (ic == 967) ichar = 969;
1917  if (ic == 954) ichar = 966;
1918  if (ic == 922) ichar = 952;
1919  if (ic == 753) ichar = 965;
1920  PrintStr(Form("&#%4.4d;",ichar));
1921  } else {
1922  Int_t len=strlen(chars);
1923  for (Int_t i=0; i<len;i++) {
1924  if (chars[i]!='\n') {
1925  if (chars[i]=='<') {
1926  PrintFast(4,"&lt;");
1927  } else if (chars[i]=='>') {
1928  PrintFast(4,"&gt;");
1929  } else if (chars[i]=='\305') {
1930  PrintFast(7,"&#8491;"); // ANGSTROM SIGN
1931  } else if (chars[i]=='\345') {
1932  PrintFast(6,"&#229;");
1933  } else if (chars[i]=='&') {
1934  PrintFast(5,"&amp;");
1935  } else {
1936  PrintFast(1,&chars[i]);
1937  }
1938  }
1939  }
1940  }
1941 
1942  PrintFast(7,"</text>");
1943 
1944  if (fTextAngle != 0.) {
1945  PrintStr("@");
1946  PrintFast(4,"</g>");
1947  }
1948 }
1949 
1950 ////////////////////////////////////////////////////////////////////////////////
1951 /// Write a string of characters in NDC
1952 
1953 void TSVG::TextNDC(Double_t u, Double_t v, const char *chars)
1954 {
1955  Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
1956  Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
1957  Text(x, y, chars);
1958 }
1959 
1960 ////////////////////////////////////////////////////////////////////////////////
1961 /// Convert U from NDC coordinate to SVG
1962 
1963 Double_t TSVG::UtoSVG(Double_t u)
1964 {
1965  Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
1966  return 0.5 + 72*cm/2.54;
1967 }
1968 
1969 ////////////////////////////////////////////////////////////////////////////////
1970 /// Convert V from NDC coordinate to SVG
1971 
1972 Double_t TSVG::VtoSVG(Double_t v)
1973 {
1974  Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
1975  return 0.5 + 72*cm/2.54;
1976 }
1977 
1978 ////////////////////////////////////////////////////////////////////////////////
1979 /// Convert X from world coordinate to SVG
1980 
1981 Double_t TSVG::XtoSVG(Double_t x)
1982 {
1983  Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
1984  return UtoSVG(u);
1985 }
1986 
1987 ////////////////////////////////////////////////////////////////////////////////
1988 /// Convert Y from world coordinate to SVG
1989 
1990 Double_t TSVG::YtoSVG(Double_t y)
1991 {
1992  Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
1993  return fYsizeSVG-VtoSVG(v);
1994 }
1995 
1996 ////////////////////////////////////////////////////////////////////////////////
1997 /// Begin the Cell Array painting
1998 
1999 void TSVG::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t,
2000  Double_t)
2001 {
2002  Warning("TSVG::CellArrayBegin", "not yet implemented");
2003 }
2004 
2005 ////////////////////////////////////////////////////////////////////////////////
2006 /// Paint the Cell Array
2007 
2008 void TSVG::CellArrayFill(Int_t, Int_t, Int_t)
2009 {
2010  Warning("TSVG::CellArrayFill", "not yet implemented");
2011 }
2012 
2013 ////////////////////////////////////////////////////////////////////////////////
2014 /// End the Cell Array painting
2015 
2016 void TSVG::CellArrayEnd()
2017 {
2018  Warning("TSVG::CellArrayEnd", "not yet implemented");
2019 }
2020 
2021 ////////////////////////////////////////////////////////////////////////////////
2022 /// Not needed in SVG case
2023 
2024 void TSVG::DrawPS(Int_t, Float_t *, Float_t *)
2025 {
2026  Warning("TSVG::DrawPS", "not yet implemented");
2027 }