#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)
TSVG::TSVG() : TVirtualPS()
{
fStream = 0;
fType = 0;
gVirtualPS = this;
fBoundingBox = kFALSE;
fRange = kFALSE;
fXsize = 0.;
fYsize = 0.;
fYsizeSVG = 0;
}
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 || !fStream->good()) {
printf("ERROR in TSVG::Open: Cannot open file:%s\n",fname);
if (fStream == 0) 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;
Float_t msize = fMarkerSize;
if (fMarkerStyle == 1) msize = 0.01;
if (fMarkerStyle == 6) msize = 0.02;
if (fMarkerStyle == 7) msize = 0.04;
const Int_t kBASEMARKER = 8;
Float_t sbase = msize*kBASEMARKER;
Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
msize = CMtoSVG(s2x * fXsize);
Double_t m = msize;
Double_t m2 = m/2;
Double_t m3 = m/3;
Double_t m6 = m/6;
PrintStr("@");
if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
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 || ms == 32) {
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 || ms == 33) {
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 || ms == 34) {
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;
Float_t msize = fMarkerSize;
if (fMarkerStyle == 1) msize = 0.01;
if (fMarkerStyle == 6) msize = 0.02;
if (fMarkerStyle == 7) msize = 0.04;
const Int_t kBASEMARKER = 8;
Float_t sbase = msize*kBASEMARKER;
Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
msize = CMtoSVG(s2x * fXsize);
Double_t m = msize;
Double_t m2 = m/2;
Double_t m3 = m/3;
Double_t m6 = m/6;
PrintStr("@");
if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
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 || ms == 32) {
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 || ms == 33) {
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 || ms == 34) {
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);
PrintFast(1,",");
WriteInteger(iy);
} else if (ix != 0) {
PrintFast(1,"h");
WriteInteger(ix);
} else if (iy != 0) {
PrintFast(1,"v");
WriteInteger(iy);
}
}
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("@<?xml version=\"1.0\" standalone=\"no\"?>");
PrintStr("@<svg width=\"");
WriteInteger(CMtoSVG(fXsize), 0);
PrintStr("\" height=\"");
fYsizeSVG = CMtoSVG(fYsize);
WriteInteger(fYsizeSVG, 0);
PrintStr("\" viewBox=\"0 0");
WriteInteger(CMtoSVG(fXsize));
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];
snprintf(str,12,"\"#%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",
"Times" ,"Times" , "ZapfDingbats", "Times"};
static const char *fontWeight[] = {
"normal", "bold", "bold",
"normal", "normal", "bold" , "bold",
"normal", "normal", "bold" , "bold",
"normal", "normal", "normal", "normal"};
static const char *fontStyle[] = {
"italic", "normal" , "italic",
"normal", "oblique", "normal", "oblique",
"normal", "oblique", "normal", "oblique",
"normal", "normal" , "normal", "italic"};
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 || font == 15) {
Int_t ichar = chars[0]+848;
Int_t ic = ichar;
if (ic == 755) ichar = 8804;
if (ic == 759) ichar = 9827;
if (ic == 760) ichar = 9830;
if (ic == 761) ichar = 9829;
if (ic == 762) ichar = 9824;
if (ic == 766) ichar = 8594;
if (ic == 776) ichar = 247;
if (ic == 757) ichar = 8734;
if (ic == 758) ichar = 402;
if (ic == 771) ichar = 8805;
if (ic == 774) ichar = 8706;
if (ic == 775) ichar = 8226;
if (ic == 779) ichar = 8776;
if (ic == 805) ichar = 8719;
if (ic == 821) ichar = 8721;
if (ic == 834) ichar = 8747;
if (ic == 769) ichar = 177;
if (ic == 772) ichar = 215;
if (ic == 918) ichar = 934;
if (ic == 919) ichar = 915;
if (ic == 920) ichar = 919;
if (ic == 923) ichar = 922;
if (ic == 924) ichar = 923;
if (ic == 925) ichar = 924;
if (ic == 926) ichar = 925;
if (ic == 929) ichar = 920;
if (ic == 930) ichar = 929;
if (ic == 936) ichar = 926;
if (ic == 915) ichar = 935;
if (ic == 937) ichar = 936;
if (ic == 935) ichar = 937;
if (ic == 938) ichar = 918;
if (ic == 951) ichar = 947;
if (ic == 798) ichar = 949;
if (ic == 970) ichar = 950;
if (ic == 952) ichar = 951;
if (ic == 961) ichar = 952;
if (ic == 955) ichar = 954;
if (ic == 956) ichar = 955;
if (ic == 957) ichar = 956;
if (ic == 958) ichar = 957;
if (ic == 968) ichar = 958;
if (ic == 934) ichar = 962;
if (ic == 962) ichar = 961;
if (ic == 966) ichar = 969;
if (ic == 950) ichar = 966;
if (ic == 947) ichar = 967;
if (ic == 969) ichar = 968;
if (ic == 967) ichar = 969;
if (ic == 954) ichar = 966;
if (ic == 922) ichar = 952;
if (ic == 753) ichar = 965;
PrintStr(Form("&#%4.4d;",ichar));
} 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");
}