#ifdef WIN32
#pragma optimize("",off)
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "Riostream.h"
#include "TROOT.h"
#include "TColor.h"
#include "TVirtualPad.h"
#include "TPoints.h"
#include "TSVG.h"
#include "TStyle.h"
#include "TMath.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "TClass.h"
ClassImp(TSVG)
/*
<a href="http://www.w3.org/Graphics/SVG/Overview.htm8"><b>SVG</b></a> is a
language for describing two-dimensional graphics in XML. <b>SVG</b> allows for
three types of graphic objects: vector graphic shapes, images and text.
Graphical objects can be grouped, styled, transformed and composed into
previously rendered objects. The feature set includes nested transformations,
clipping paths, alpha masks, filter effects and template objects. <b>SVG</b>
drawings can be interactive and dynamic. Animations can be defined and
triggered either declaratively or via scripting.
<p>
The way to access <b>SVG</b> in <b>ROOT</b> (in my private version only) is the
following:
<PRE>
   <A HREF="html/TSVG.html">TSVG</A> mysvg("myfile.svg")
   object->Draw();
   mysvg.Close();
</PRE>
The result is the ASCII file <tt>myfile.svg</tt>, it is best viewed with
Internet Explorer and you need the
<a href="http://www.adobe.com/svg/viewer/install/main.html">Adobe <b>SVG</b>
Viewer</a>. To zoom using the Adobe <b>SVG</b> Viewer, position the mouse over
the area you want to zoom and click the right button. To define the zoom area,
use Control+drag to mark the boundaries of the zoom area. To pan, use Alt+drag.
By clicking with the right mouse button on the <b>SVG</b> graphics you will get
a pop-up menu giving other ways to interact with the image.
<p>
<b>SVG</b> files can be used directly in compressed mode to minimize the time
transfer over the network. Compressed <b>SVG</b> files should be created using
<tt>gzip</tt> on a normal ASCII <b>SVG</b> file and should then be renamed
using the file extension <tt>.svgz</tt>.
*/
//End_Html
TSVG::TSVG() : TVirtualPS()
{
   
   fStream = 0;
   fType   = 0;
   gVirtualPS = this;
}
TSVG::TSVG(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
{
   
   
   
   
   
   
   
   fStream = 0;
   Open(fname, wtype);
}
void TSVG::Open(const char *fname, Int_t wtype)
{
   
   if (fStream) {
      Warning("Open", "SVG file already open");
      return;
   }
   fLenBuffer = 0;
   fType      = abs(wtype);
   SetLineScale(gStyle->GetLineScalePS());
   gStyle->GetPaperSize(fXsize, fYsize);
   Float_t xrange, yrange;
   if (gPad) {
      Double_t ww = gPad->GetWw();
      Double_t wh = gPad->GetWh();
      ww *= gPad->GetWNDC();
      wh *= gPad->GetHNDC();
      Double_t ratio = wh/ww;
      xrange = fXsize;
      yrange = fXsize*ratio;
      if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
      fXsize = xrange; fYsize = yrange;
   }
   
   fStream   = new ofstream(fname,ios::out);
   if (fStream == 0) {
      printf("ERROR in TSVG::Open: Cannot open file:%s\n",fname);
      return;
   }
   gVirtualPS = this;
   for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
   fBoundingBox = kFALSE;
   fRange       = kFALSE;
   
   Range(fXsize, fYsize);
   NewPage();
}
TSVG::~TSVG()
{
   
   Close();
}
void TSVG::Close(Option_t *)
{
   
   if (!gVirtualPS) return;
   if (!fStream) return;
   if (gPad) gPad->Update();
   PrintStr("</svg>@");
   
   if (fStream) { fStream->close(); delete fStream; fStream = 0;}
   gVirtualPS = 0;
}
void TSVG::On()
{
   
   
   
   if (!fType) {
      Error("On", "no SVG file open");
      Off();
      return;
   }
   gVirtualPS = this;
}
void TSVG::Off()
{
   
   gVirtualPS = 0;
}
void TSVG::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t  y2)
{
   
   static Double_t x[4], y[4];
   Int_t ix1 = XtoSVG(x1);
   Int_t ix2 = XtoSVG(x2);
   Int_t iy1 = YtoSVG(y1);
   Int_t iy2 = YtoSVG(y2);
   Int_t fillis = fFillStyle/1000;
   Int_t fillsi = fFillStyle%1000;
   if (fillis == 3 || fillis == 2) {
      if (fillsi > 99) {
         x[0] = x1;   y[0] = y1;
         x[1] = x2;   y[1] = y1;
         x[2] = x2;   y[2] = y2;
         x[3] = x1;   y[3] = y2;
         return;
      }
      if (fillsi > 0 && fillsi < 26) {
         x[0] = x1;   y[0] = y1;
         x[1] = x2;   y[1] = y1;
         x[2] = x2;   y[2] = y2;
         x[3] = x1;   y[3] = y2;
         DrawPS(-4, &x[0], &y[0]);
      }
      if (fillsi == -3) {
         PrintStr("@");
         PrintFast(9,"<rect x=\"");
         WriteInteger(ix1, 0);
         PrintFast(5,"\" y=\"");
         WriteInteger(iy2, 0);
         PrintFast(9,"\" width=\"");
         WriteInteger(ix2-ix1, 0);
         PrintFast(10,"\" height=\"");
         WriteInteger(iy1-iy2, 0);
         PrintFast(7,"\" fill=");
         SetColor(5);
         PrintFast(2,"/>");
      }
   }
   if (fillis == 1) {
      PrintStr("@");
      PrintFast(9,"<rect x=\"");
      WriteInteger(ix1, 0);
      PrintFast(5,"\" y=\"");
      WriteInteger(iy2, 0);
      PrintFast(9,"\" width=\"");
      WriteInteger(ix2-ix1, 0);
      PrintFast(10,"\" height=\"");
      WriteInteger(iy1-iy2, 0);
      PrintFast(7,"\" fill=");
      SetColor(fFillColor);
      PrintFast(2,"/>");
   }
   if (fillis == 0) {
      PrintStr("@");
      PrintFast(9,"<rect x=\"");
      WriteInteger(ix1, 0);
      PrintFast(5,"\" y=\"");
      WriteInteger(iy2, 0);
      PrintFast(9,"\" width=\"");
      WriteInteger(ix2-ix1, 0);
      PrintFast(10,"\" height=\"");
      WriteInteger(iy1-iy2, 0);
      PrintFast(21,"\" fill=\"none\" stroke=");
      SetColor(fLineColor);
      PrintFast(2,"/>");
   }
}
void TSVG::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)
{
   
   
   
   
   
   
   
   static Int_t xps[7], yps[7];
   Int_t i, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
   
   xps[0] = XtoSVG(xl);          yps[0] = YtoSVG(yl);
   xps[1] = xps[0] + border;     yps[1] = yps[0] - border;
   xps[2] = xps[1];              yps[2] = YtoSVG(yt) + border;
   xps[3] = XtoSVG(xt) - border; yps[3] = yps[2];
   xps[4] = XtoSVG(xt);          yps[4] = YtoSVG(yt);
   xps[5] = xps[0];              yps[5] = yps[4];
   xps[6] = xps[0];              yps[6] = yps[0];
   ixd0 = xps[0];
   iyd0 = yps[0];
   PrintStr("@");
   PrintFast(10,"<path d=\"M");
   WriteInteger(ixd0, 0);
   PrintFast(1,",");
   WriteInteger(iyd0, 0);
   idx = 0;
   idy = 0;
   for (i=1; i<7; i++) {
      ixdi = xps[i];
      iydi = yps[i];
      ix   = ixdi - ixd0;
      iy   = iydi - iyd0;
      ixd0 = ixdi;
      iyd0 = iydi;
      if( ix && iy) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( idy ) { MovePS(0,idy); idy = 0; }
         MovePS(ix,iy);
         continue;
      }
      if ( ix ) {
         if( idy )  { MovePS(0,idy); idy = 0; }
         if( !idx ) { idx = ix; continue;}
         if( ix*idx > 0 ) {
            idx += ix;
         } else {
            MovePS(idx,0);
            idx  = ix;
         }
         continue;
      }
      if( iy ) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( !idy) { idy = iy; continue;}
         if( iy*idy > 0 ) {
            idy += iy;
         } else {
            MovePS(0,idy);
            idy  = iy;
         }
      }
   }
   if( idx ) MovePS(idx,0);
   if( idy ) MovePS(0,idy);
   PrintFast(8,"z\" fill=");
   if (mode == -1) {
      SetColor(dark);
   } else {
      SetColor(light);
   }
   PrintFast(2,"/>");
   
   xps[0] = XtoSVG(xl);          yps[0] = YtoSVG(yl);
   xps[1] = xps[0] + border;     yps[1] = yps[0] - border;
   xps[2] = XtoSVG(xt) - border; yps[2] = yps[1];
   xps[3] = xps[2];              yps[3] = YtoSVG(yt) + border;
   xps[4] = XtoSVG(xt);          yps[4] = YtoSVG(yt);
   xps[5] = xps[4];              yps[5] = yps[0];
   xps[6] = xps[0];              yps[6] = yps[0];
   ixd0 = xps[0];
   iyd0 = yps[0];
   PrintStr("@");
   PrintFast(10,"<path d=\"M");
   WriteInteger(ixd0, 0);
   PrintFast(1,",");
   WriteInteger(iyd0, 0);
   idx = 0;
   idy = 0;
   for (i=1;i<7;i++) {
      ixdi = xps[i];
      iydi = yps[i];
      ix   = ixdi - ixd0;
      iy   = iydi - iyd0;
      ixd0 = ixdi;
      iyd0 = iydi;
      if( ix && iy) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( idy ) { MovePS(0,idy); idy = 0; }
         MovePS(ix,iy);
         continue;
      }
      if ( ix ) {
         if( idy )  { MovePS(0,idy); idy = 0; }
         if( !idx ) { idx = ix; continue;}
         if( ix*idx > 0 ) {
            idx += ix;
         } else {
            MovePS(idx,0);
            idx  = ix;
         }
         continue;
      }
      if( iy ) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( !idy) { idy = iy; continue;}
         if( iy*idy > 0 ) {
            idy += iy;
         } else {
            MovePS(0,idy);
            idy  = iy;
         }
      }
   }
   if( idx ) MovePS(idx,0);
   if( idy ) MovePS(0,idy);
   PrintFast(8,"z\" fill=");
   if (mode == -1) {
      SetColor(light);
   } else {
      SetColor(dark);
   }
   PrintFast(2,"/>");
}
void TSVG::DrawPolyLine(Int_t nn, TPoints *xy)
{
   
   
   
   
   
   
   
   
   Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
   if (nn > 0) {
      n = nn;
   } else {
      n = -nn;
   }
   ixd0 = XtoSVG(xy[0].GetX());
   iyd0 = YtoSVG(xy[0].GetY());
   if( n <= 1) {
      if( n == 0) return;
      return;
   }
   PrintFast(2," m");
   idx = 0;
   idy = 0;
   for (Int_t i=1;i<n;i++) {
      ixdi = XtoSVG(xy[i].GetX());
      iydi = YtoSVG(xy[i].GetY());
      ix   = ixdi - ixd0;
      iy   = iydi - iyd0;
      ixd0 = ixdi;
      iyd0 = iydi;
      if( ix && iy) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( idy ) { MovePS(0,idy); idy = 0; }
         MovePS(ix,iy);
         continue;
      }
      if ( ix ) {
         if( idy )  { MovePS(0,idy); idy = 0; }
         if( !idx ) { idx = ix; continue;}
         if( ix*idx > 0 ) {
            idx += ix;
         } else {
            MovePS(idx,0);
            idx  = ix;
         }
         continue;
      }
      if( iy ) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( !idy) { idy = iy; continue;}
         if( iy*idy > 0 ) {
            idy += iy;
         } else {
            MovePS(0,idy);
            idy  = iy;
         }
      }
   }
   if( idx ) MovePS(idx,0);
   if( idy ) MovePS(0,idy);
   if (nn > 0 ) {
   } else {
   }
}
void TSVG::DrawPolyLineNDC(Int_t nn, TPoints *xy)
{
   
   
   
   
   
   
   
   
   Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
   if (nn > 0) {
      n = nn;
   } else {
      n = -nn;
   }
   ixd0 = UtoSVG(xy[0].GetX());
   iyd0 = VtoSVG(xy[0].GetY());
   if( n <= 1) {
      if( n == 0) return;
      return;
   }
   idx = 0;
   idy = 0;
   for (Int_t i=1;i<n;i++) {
      ixdi = UtoSVG(xy[i].GetX());
      iydi = VtoSVG(xy[i].GetY());
      ix   = ixdi - ixd0;
      iy   = iydi - iyd0;
      ixd0 = ixdi;
      iyd0 = iydi;
      if( ix && iy) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( idy ) { MovePS(0,idy); idy = 0; }
         MovePS(ix,iy);
         continue;
      }
      if ( ix ) {
         if( idy )  { MovePS(0,idy); idy = 0; }
         if( !idx ) { idx = ix; continue;}
         if( ix*idx > 0 ) {
            idx += ix;
         } else {
            MovePS(idx,0);
            idx  = ix;
         }
         continue;
      }
      if( iy ) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( !idy) { idy = iy; continue;}
         if( iy*idy > 0 ) {
            idy += iy;
         } else {
            MovePS(0,idy);
            idy  = iy;
         }
      }
   }
   if( idx ) MovePS(idx,0);
   if( idy ) MovePS(0,idy);
   if (nn > 0 ) {
      if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
   } else {
   }
}
void TSVG::DrawPolyMarker(Int_t n, Float_t *xw, Float_t *yw)
{
   
   Int_t ms = abs(fMarkerStyle);
   if (ms >= 6 && ms <= 19) ms = 20;
   if (ms == 4) ms = 24;
   
   
   Double_t msize = 0.23*fMarkerSize*TMath::Max(fXsize,fYsize)/20;
   if (ms == 6) msize *= 0.2;
   if (ms == 7) msize *= 0.3;
   Double_t m  = CMtoSVG(msize);
   Double_t m2 = m/2;
   Double_t m3 = m/3;
   Double_t m6 = m/6;
   
   PrintStr("@");
   if ((ms > 19 && ms < 24) || ms == 29) {
      PrintStr("<g stroke=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(" stroke-width=\"");
      WriteInteger(fLineWidth,0);
      PrintStr("\" fill=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(">");
   } else {
      PrintStr("<g stroke=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(" stroke-width=\"");
      WriteInteger(fLineWidth,0);
      PrintStr("\" fill=\"none\"");
      PrintStr(">");
   }
   Double_t ix,iy;
   for (Int_t i=0;i<n;i++) {
      ix = XtoSVG(xw[i]);
      iy = YtoSVG(yw[i]);
      PrintStr("@");
      
      if (ms == 1) {
         PrintStr("<line x1=\"");
         WriteInteger(int(ix-1),0); 
         PrintStr("\" y1=\"");
         WriteInteger(int(iy),0);
         PrintStr("\" x2=\"");
         WriteInteger(int(ix),0);  
         PrintStr("\" y2=\""); 
         WriteInteger(int(iy),0);
         PrintStr("\"/>");      
      
      } else if (ms == 2) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\""); 
         WriteReal(iy);
         PrintStr("\"/>");
 
         PrintStr("<line x1=\"");
         WriteReal(ix);    
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix);    
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 5) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
 
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy+m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy-m2);
         PrintStr("\"/>");
      
      } else if (ms == 3 || ms == 31) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\""); 
         WriteReal(iy);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix);    
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix);    
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
 
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy+m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy-m2);
         PrintStr("\"/>");
      
      } else if (ms == 24 || ms == 20) {
         PrintStr("<circle cx=\"");
         WriteReal(ix);
         PrintStr("\" cy=\"");
         WriteReal(iy);
         PrintStr("\" r=\"");
         WriteReal(m2);
         PrintStr("\" fill=\"none\"");
         PrintStr("/>");
      
      } else if (ms == 25 || ms == 21) {
         PrintStr("<rect x=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y=\"");
         WriteReal(iy-m2);
         PrintStr("\" width=\"");
         WriteReal(m);
         PrintStr("\" height=\"");
         WriteReal(m);
         PrintStr("\" fill=\"none\"");
         PrintStr("/>");
      
      } else if (ms == 26 || ms == 22) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 23) {
         PrintStr("<polygon points=\"");
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 27) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
         PrintStr("\"/>");
      
      } else if (ms == 28) {
         PrintStr("<polygon points=\"");
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
         PrintStr("\"/>");
      } else if (ms == 29 || ms == 30) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
         WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
         WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
         WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
         WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
         WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
         PrintStr("\"/>");
      } else {
         PrintStr("<line x1=\"");
         WriteInteger(int(ix-1),0); 
         PrintStr("\" y1=\"");
         WriteInteger(int(iy),0);
         PrintStr("\" x2=\"");
         WriteInteger(int(ix),0);  
         PrintStr("\" y2=\""); 
         WriteInteger(int(iy),0);
         PrintStr("\"/>");
      }
   }
   PrintStr("@");
   PrintStr("</g>");
}
void TSVG::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
{
   
   Int_t ms = abs(fMarkerStyle);
   if (ms >= 6 && ms <= 19) ms = 20;
   if (ms == 4) ms = 24;
   
   
   Double_t msize = 0.23*fMarkerSize*TMath::Max(fXsize,fYsize)/20;
   if (ms == 6) msize *= 0.2;
   if (ms == 7) msize *= 0.3;
   Double_t m  = CMtoSVG(msize);
   Double_t m2 = m/2;
   Double_t m3 = m/3;
   Double_t m6 = m/6;
   
   PrintStr("@");
   if ((ms > 19 && ms < 24) || ms == 29) {
      PrintStr("<g stroke=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(" stroke-width=\"");
      WriteInteger(fLineWidth,0);
      PrintStr("\" fill=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(">");
   } else {
      PrintStr("<g stroke=");
      SetColor(Int_t(fMarkerColor));
      PrintStr(" stroke-width=\"");
      WriteInteger(fLineWidth,0);
      PrintStr("\" fill=\"none\"");
      PrintStr(">");
   }
   Double_t ix,iy;
   for (Int_t i=0;i<n;i++) {
      ix = XtoSVG(xw[i]);
      iy = YtoSVG(yw[i]);
      PrintStr("@");
      
      if (ms == 1) {
         PrintStr("<line x1=\"");
         WriteInteger(int(ix-1),0); 
         PrintStr("\" y1=\"");
         WriteInteger(int(iy),0);
         PrintStr("\" x2=\"");
         WriteInteger(int(ix),0);  
         PrintStr("\" y2=\""); 
         WriteInteger(int(iy),0);
         PrintStr("\"/>");      
      
      } else if (ms == 2) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\""); 
         WriteReal(iy);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix);    
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix);    
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 5) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy+m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy-m2);
         PrintStr("\"/>");
      
      } else if (ms == 3 || ms == 31) {
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\""); 
         WriteReal(iy);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix);    
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix);    
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy-m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy+m2);
         PrintStr("\"/>");
         PrintStr("<line x1=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y1=\"");
         WriteReal(iy+m2);
         PrintStr("\" x2=\"");
         WriteReal(ix+m2); 
         PrintStr("\" y2=\"");
         WriteReal(iy-m2);
         PrintStr("\"/>");
      
      } else if (ms == 24 || ms == 20) {
         PrintStr("<circle cx=\"");
         WriteReal(ix);
         PrintStr("\" cy=\"");
         WriteReal(iy);
         PrintStr("\" r=\"");
         WriteReal(m2);
         PrintStr("\"/>");
      
      } else if (ms == 25 || ms == 21) {
         PrintStr("<rect x=\"");
         WriteReal(ix-m2); 
         PrintStr("\" y=\"");
         WriteReal(iy-m2);
         PrintStr("\" width=\"");
         WriteReal(m);
         PrintStr("\" height=\"");
         WriteReal(m);
         PrintStr("\"/>");
      
      } else if (ms == 26 || ms == 22) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 23) {
         PrintStr("<polygon points=\"");
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         PrintStr("\"/>");
      
      } else if (ms == 27) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
         PrintStr("\"/>");
      
      } else if (ms == 28) {
         PrintStr("<polygon points=\"");
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
         WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
         WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
         PrintStr("\"/>");
      } else if (ms == 29 || ms == 30) {
         PrintStr("<polygon points=\"");
         WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
         WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
         WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
         WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
         WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
         WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
         WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
         WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
         PrintStr("\"/>");
      } else {
         PrintStr("<line x1=\"");
         WriteInteger(int(ix-1),0); 
         PrintStr("\" y1=\"");
         WriteInteger(int(iy),0);
         PrintStr("\" x2=\"");
         WriteInteger(int(ix),0);  
         PrintStr("\" y2=\""); 
         WriteInteger(int(iy),0);
         PrintStr("\"/>");
      }
   }
   PrintStr("@");
   PrintStr("</g>");
}
void TSVG::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
{
   
   
   
   
   
   Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
   fais = fasi = 0;
   if (nn > 0) {
      n = nn;
   } else {
      n = -nn;
      fais = fFillStyle/1000;
      fasi = fFillStyle%1000;
      if (fais == 3 || fais == 2) {
         if (fasi > 100 && fasi <125) {
            return;
         }
         if (fasi > 0 && fasi < 26) {
         }
      }
   }
   if( n <= 1) {
      Error("DrawPS", "Two points are needed");
      return;
   }
   ixd0 = XtoSVG(xw[0]);
   iyd0 = YtoSVG(yw[0]);
   PrintStr("@");
   PrintFast(10,"<path d=\"M");
   WriteInteger(ixd0, 0);
   PrintFast(1,",");
   WriteInteger(iyd0, 0);
   idx = idy = 0;
   for (Int_t i=1;i<n;i++) {
      ixdi = XtoSVG(xw[i]);
      iydi = YtoSVG(yw[i]);
      ix   = ixdi - ixd0;
      iy   = iydi - iyd0;
      ixd0 = ixdi;
      iyd0 = iydi;
      if( ix && iy) {
         if( idx ) { MovePS(idx,0); idx = 0; }
         if( idy ) { MovePS(0,idy); idy = 0; }
         MovePS(ix,iy);
      } else if ( ix ) {
         if( idy )  { MovePS(0,idy); idy = 0;}
         if( !idx ) { idx = ix;}
         else if( TMath::Sign(ix,idx) == ix )       idx += ix;
         else { MovePS(idx,0);  idx  = ix;}
      } else if( iy ) {
         if( idx ) { MovePS(idx,0); idx = 0;}
         if( !idy) { idy = iy;}
         else if( TMath::Sign(iy,idy) == iy)         idy += iy;
         else { MovePS(0,idy);    idy  = iy;}
      }
   }
   if (idx) MovePS(idx,0);
   if (idy) MovePS(0,idy);
   if (nn > 0 ) {
      if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(1,"z");
      PrintFast(21,"\" fill=\"none\" stroke=");
      SetColor(fLineColor);
      if(fLineWidth > 1.) {
         PrintFast(15," stroke-width=\"");
         WriteInteger(Int_t(fLineWidth), 0);
         PrintFast(1,"\"");
      }
      if (fLineStyle > 1) {
         PrintFast(19," stroke-dasharray=\"");
         TString st = (TString)gStyle->GetLineStyleString(fLineStyle);
         TObjArray *tokens = st.Tokenize(" ");
         for (Int_t j = 0; j<tokens->GetEntries(); j++) {
            Int_t it;
            sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
            if (j>0) PrintFast(1,",");
            WriteInteger((Int_t)(it/4));
         }
         delete tokens;
         PrintFast(1,"\"");
      }
      PrintFast(2,"/>");
   } else {
      PrintFast(8,"z\" fill=");
      if (fais == 0) {
         PrintFast(14,"\"none\" stroke=");
         SetColor(fFillColor);
      } else {
         SetColor(fFillColor);
      }
      PrintFast(2,"/>");
   }
}
void TSVG::Initialize()
{
   
   
   
   
   PrintStr("<title>@");
   PrintStr(GetName());
   PrintStr("@");
   PrintStr("</title>@");
   
   PrintStr("<desc>@");
   PrintFast(22,"Creator: ROOT Version ");
   PrintStr(gROOT->GetVersion());
   PrintStr("@");
   PrintFast(14,"CreationDate: ");
   TDatime t;
   PrintStr(t.AsString());
   
   Int_t nh = strlen(gStyle->GetHeaderPS());
   if (nh) {
      PrintFast(nh,gStyle->GetHeaderPS());
   }
   PrintStr("</desc>@");
   
   PrintStr("<defs>@");
   PrintStr("</defs>@");
}
void TSVG::MovePS(Int_t ix, Int_t iy)
{
   
   
   
   
   if (ix != 0 && iy != 0)  {
      PrintFast(1,"l");
      WriteInteger(ix, 0);
      PrintFast(1,",");
      WriteInteger(iy, 0);
   } else if (ix != 0)  {
      PrintFast(1,"h");
      WriteInteger(ix, 0);
   } else if (iy != 0)  {
      PrintFast(1,"v");
      WriteInteger(iy, 0);
   }
}
void TSVG::NewPage()
{
   
   
   
   
   if (gPad) {
      Double_t ww   = gPad->GetWw();
      Double_t wh   = gPad->GetWh();
      fYsize        = fXsize*wh/ww;
   } else {
      fYsize = 27;
   }
   
   if(!fBoundingBox) {
      PrintStr("@<svg viewBox=\"0 0");
      WriteInteger(CMtoSVG(fXsize));
      fYsizeSVG = CMtoSVG(fYsize);
      WriteInteger(fYsizeSVG);
      PrintStr("\" xmlns=\"http://www.w3.org/2000/svg\">");
      PrintStr("@");
      Initialize();
      fBoundingBox  = kTRUE;
   }
}
void TSVG::Range(Float_t xsize, Float_t ysize)
{
   
   Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
   fXsize = xsize;
   fYsize = ysize;
   xps = xsize;
   yps = ysize;
   if( xsize <= xps && ysize < yps) {
      if ( xps > yps ) xymax = xps;
      else             xymax = yps;
      xncm  = xsize/xymax;
      yncm  = ysize/xymax;
      dxwn  = ((xps/xymax)-xncm)/2;
      dywn  = ((yps/xymax)-yncm)/2;
   } else {
      if (xps/yps < 1) xwkwn = xps/yps;
      else             xwkwn = 1;
      if (yps/xps < 1) ywkwn = yps/xps;
      else             ywkwn = 1;
      if (xsize < ysize)  {
         xncm = ywkwn*xsize/ysize;
         yncm = ywkwn;
         dxwn = (xwkwn-xncm)/2;
         dywn = 0;
         if( dxwn < 0) {
            xncm = xwkwn;
            dxwn = 0;
            yncm = xwkwn*ysize/xsize;
            dywn = (ywkwn-yncm)/2;
         }
      } else {
         xncm = xwkwn;
         yncm = xwkwn*ysize/xsize;
         dxwn = 0;
         dywn = (ywkwn-yncm)/2;
         if( dywn < 0) {
            yncm = ywkwn;
            dywn = 0;
            xncm = ywkwn*xsize/ysize;
            dxwn = (xwkwn-xncm)/2;
         }
      }
   }
   fRange = kTRUE;
}
void TSVG::SetFillColor( Color_t cindex )
{
   
   fFillColor = cindex;
   if (gStyle->GetFillColor() <= 0) cindex = 0;
}
void TSVG::SetLineColor( Color_t cindex )
{
   
   fLineColor = cindex;
}
void TSVG::SetLineStyle(Style_t linestyle)
{
   
   
   
   
   
   
   fLineStyle = linestyle;
}
void TSVG::SetLineWidth(Width_t linewidth)
{
   
   fLineWidth = linewidth;
}
void TSVG::SetMarkerColor( Color_t cindex )
{
   
   fMarkerColor = cindex;
}
void TSVG::SetColor(Int_t color)
{
   
   if (color < 0) color = 0;
   TColor *col = gROOT->GetColor(color);
   if (col) {
      SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
   } else {
      SetColor(1., 1., 1.);
   }
}
void TSVG::SetColor(Float_t r, Float_t g, Float_t b)
{
   
   
   
   
   
   if (r <= 0. && g <= 0. && b <= 0. ) {
      PrintFast(7,"\"black\"");
   } else if (r >= 1. && g >= 1. && b >= 1. ) {
      PrintFast(7,"\"white\"");
   } else {
      char str[12];
      sprintf(str,"\"#%2.2x%2.2x%2.2x\"",Int_t(255.*r)
                                        ,Int_t(255.*g)
                                        ,Int_t(255.*b));
      PrintStr(str);
   }
}
void TSVG::SetTextColor( Color_t cindex )
{
   
   fTextColor = cindex;
}
void TSVG::Text(Double_t xx, Double_t yy, const char *chars)
{
   
   
   
   
   
   static const char *fontFamily[] = {
   "Times", "Times", "Times",
   "Helvetica", "Helvetica", "Helvetica", "Helvetica",
   "Courier", "Courier", "Courier", "Courier",
   "Symbol","Times", "ZapfDingbats"};
   static const char *fontWeight[] = {
   "normal", "bold", "bold",
   "normal", "normal", "bold", "bold",
   "normal", "normal", "bold", "bold",
   "normal","normal", "normal"};
   static const char *fontStyle[] = {
   "italic", "normal", "italic",
   "normal", "oblique", "normal", "oblique",
   "normal", "oblique", "normal", "oblique",
   "normal","normal", "normal"};
   Int_t ix    = XtoSVG(xx);
   Int_t iy    = YtoSVG(yy);
   Int_t txalh = fTextAlign/10;
   if (txalh <1) txalh = 1; if (txalh > 3) txalh = 3;
   Int_t txalv = fTextAlign%10;
   if (txalv <1) txalv = 1; if (txalv > 3) txalv = 3;
   Double_t     wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
   Double_t     hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
   Float_t fontrap = 1.09; 
   Float_t ftsize;
   Int_t font  = abs(fTextFont)/10;
   Int_t ifont = font-1;
   if (font > 42 || font < 1) font = 1;
   if (wh < hh) {
      ftsize = fTextSize*fXsize*gPad->GetAbsWNDC();
   } else {
      ftsize = fTextSize*fYsize*gPad->GetAbsHNDC();
   }
   Int_t fontsize = CMtoSVG(ftsize/fontrap);
   if( fontsize <= 0) return;
   if (txalv == 3) iy = iy+fontsize;
   if (txalv == 2) iy = iy+(fontsize/2);
   if (fTextAngle != 0.) {
      PrintStr("@");
      PrintFast(21,"<g transform=\"rotate(");
      WriteInteger(-Int_t(fTextAngle), 0);
      PrintFast(1,",");
      WriteInteger(ix, 0);
      PrintFast(1,",");
      WriteInteger(iy, 0);
      PrintFast(3,")\">");
   }
   PrintStr("@");
   PrintFast(9,"<text x=\"");
   WriteInteger(ix, 0);
   PrintFast(5,"\" y=\"");
   WriteInteger(iy, 0);
   PrintFast(1,"\"");
   if (txalh == 2) {
      PrintFast(21," text-anchor=\"middle\"");
   } else if (txalh == 3) {
      PrintFast(18," text-anchor=\"end\"");
   }
   PrintFast(6," fill=");
   SetColor(Int_t(fTextColor));
   PrintFast(12," font-size=\"");
   WriteInteger(fontsize, 0);
   PrintFast(15,"\" font-family=\"");
   PrintStr(fontFamily[ifont]);
   if (strcmp(fontWeight[ifont],"normal")) {
      PrintFast(15,"\" font-weight=\"");
      PrintStr(fontWeight[ifont]);
   }
   if (strcmp(fontStyle[ifont],"normal")) {
      PrintFast(14,"\" font-style=\"");
      PrintStr(fontStyle[ifont]);
   }
   PrintFast(2,"\">");
   PrintStr("@");
   if (font == 12 && chars[0] >= '\xA3' && chars[0] <= '\xF2') {
      char str[8];
      sprintf(str,"&#x%2.2x;", chars[0] & 255);
      PrintStr(str);
   } else {
      Int_t len=strlen(chars);
      for (Int_t i=0; i<len;i++) {
         if (chars[i]!='\n') {
            if (chars[i]=='<') {
               PrintFast(4,"<");
            } else if (chars[i]=='>') {
               PrintFast(4,">");
            } else if (chars[i]=='&') {
               PrintFast(5,"&");
            } else {
               PrintFast(1,&chars[i]);
            }
         }
      }
   }
   PrintStr("@");
   PrintFast(7,"</text>");
   if (fTextAngle != 0.) {
      PrintStr("@");
      PrintFast(4,"</g>");
   }
}
void TSVG::TextNDC(Double_t u, Double_t v, const char *chars)
{
   
   Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
   Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
   Text(x, y, chars);
}
Int_t TSVG::UtoSVG(Double_t u)
{
   
   Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
   return Int_t(0.5 + 72*cm/2.54);
}
Int_t TSVG::VtoSVG(Double_t v)
{
   
   Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
   return Int_t(0.5 + 72*cm/2.54);
}
Int_t TSVG::XtoSVG(Double_t x)
{
   
   Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
   return  UtoSVG(u);
}
Int_t TSVG::YtoSVG(Double_t y)
{
   
   Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
   return  fYsizeSVG-VtoSVG(v);
}
void TSVG::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t,
                          Double_t)
{
   
   Warning("TSVG::CellArrayBegin", "not yet implemented");
}
void TSVG::CellArrayFill(Int_t, Int_t, Int_t)
{
   
   Warning("TSVG::CellArrayFill", "not yet implemented");
}
void TSVG::CellArrayEnd()
{
   
   Warning("TSVG::CellArrayEnd", "not yet implemented");
}
void TSVG::DrawPS(Int_t, Float_t *, Float_t *)
{
   
   Warning("TSVG::DrawPS", "not yet implemented");
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.