TSVG.cxx

Go to the documentation of this file.
00001 // @(#)root/postscript:$Id: TSVG.cxx 37106 2010-11-30 15:27:44Z couet $
00002 // Author: Olivier Couet
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #ifdef WIN32
00013 #pragma optimize("",off)
00014 #endif
00015 
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <ctype.h>
00019 
00020 #include "Riostream.h"
00021 #include "TROOT.h"
00022 #include "TColor.h"
00023 #include "TVirtualPad.h"
00024 #include "TPoints.h"
00025 #include "TSVG.h"
00026 #include "TStyle.h"
00027 #include "TMath.h"
00028 #include "TObjString.h"
00029 #include "TObjArray.h"
00030 #include "TClass.h"
00031 
00032 ClassImp(TSVG)
00033 
00034 
00035 //______________________________________________________________________________
00036 /*Begin_Html
00037 <center><h2>TSVG: Graphics interface to SVG</h2></center>
00038 <a href="http://www.w3.org/Graphics/SVG/Overview.htm8"><b>SVG</b></a>
00039 (Scalable Vector Graphics) is a language for describing two-dimensional
00040 graphics in XML. <b>SVG</b> allows high quality vector graphics in
00041 HTML pages.
00042 <p>
00043 To print a ROOT canvas "c1" into an <b>SVG</b> file simply do:
00044 <PRE>
00045    c1->Print("c1.svg");
00046 </PRE>
00047 The result is the ASCII file <tt>c1.svg</tt>.
00048 <p>
00049 It can be open direclty using a web browser or included in a html document
00050 the following way:
00051 <pre>
00052 &lt;embed width="95%" height="500" src="c1.svg" /&gt;>
00053 </pre>
00054 It is best viewed with Internet Explorer and you need the
00055 <a href="http://www.adobe.com/svg/viewer/install/main.html">Adobe <b>SVG</b>
00056 Viewer</a>.
00057 <p>
00058 To zoom using the Adobe <b>SVG</b> Viewer, position the mouse over
00059 the area you want to zoom and click the right button.
00060 <p>
00061 To define the zoom area,
00062 use Control+drag to mark the boundaries of the zoom area.
00063 <p>
00064 To pan, use Alt+drag.
00065 By clicking with the right mouse button on the <b>SVG</b> graphics you will get
00066 a pop-up menu giving other ways to interact with the image.
00067 <p>
00068 <b>SVG</b> files can be used directly in compressed mode to minimize the time
00069 transfer over the network. Compressed <b>SVG</b> files should be created using
00070 <tt>gzip</tt> on a normal ASCII <b>SVG</b> file and should then be renamed
00071 using the file extension <tt>.svgz</tt>.
00072 End_Html */
00073 
00074 
00075 //______________________________________________________________________________
00076 TSVG::TSVG() : TVirtualPS()
00077 {
00078    // Default SVG constructor
00079 
00080    fStream      = 0;
00081    fType        = 0;
00082    gVirtualPS   = this;
00083    fBoundingBox = kFALSE;
00084    fRange       = kFALSE;
00085    fXsize       = 0.;
00086    fYsize       = 0.;
00087    fYsizeSVG    = 0;
00088 }
00089 
00090 
00091 //______________________________________________________________________________
00092 TSVG::TSVG(const char *fname, Int_t wtype) : TVirtualPS(fname, wtype)
00093 {
00094    // Initialize the SVG interface
00095    //
00096    //  fname : SVG file name
00097    //  wtype : SVG workstation type. Not used in the SVG driver. But as TSVG
00098    //          inherits from TVirtualPS it should be kept. Anyway it is not
00099    //          necessary to specify this parameter at creation time because it
00100    //          has a default value (which is ignore in the SVG case).
00101 
00102    fStream = 0;
00103    Open(fname, wtype);
00104 }
00105 
00106 
00107 //______________________________________________________________________________
00108 void TSVG::Open(const char *fname, Int_t wtype)
00109 {
00110    // Open a SVG file
00111 
00112    if (fStream) {
00113       Warning("Open", "SVG file already open");
00114       return;
00115    }
00116 
00117    fLenBuffer = 0;
00118    fType      = abs(wtype);
00119    SetLineScale(gStyle->GetLineScalePS());
00120    gStyle->GetPaperSize(fXsize, fYsize);
00121    Float_t xrange, yrange;
00122    if (gPad) {
00123       Double_t ww = gPad->GetWw();
00124       Double_t wh = gPad->GetWh();
00125       ww *= gPad->GetWNDC();
00126       wh *= gPad->GetHNDC();
00127       Double_t ratio = wh/ww;
00128       xrange = fXsize;
00129       yrange = fXsize*ratio;
00130       if (yrange > fYsize) { yrange = fYsize; xrange = yrange/ratio;}
00131       fXsize = xrange; fYsize = yrange;
00132    }
00133 
00134    // Open OS file
00135    fStream   = new ofstream(fname,ios::out);
00136    if (fStream == 0) {
00137       printf("ERROR in TSVG::Open: Cannot open file:%s\n",fname);
00138       return;
00139    }
00140 
00141    gVirtualPS = this;
00142 
00143    for (Int_t i=0;i<fSizBuffer;i++) fBuffer[i] = ' ';
00144 
00145    fBoundingBox = kFALSE;
00146 
00147    fRange       = kFALSE;
00148 
00149    // Set a default range
00150    Range(fXsize, fYsize);
00151 
00152    NewPage();
00153 }
00154 
00155 
00156 //______________________________________________________________________________
00157 TSVG::~TSVG()
00158 {
00159    // Default SVG destructor
00160 
00161    Close();
00162 }
00163 
00164 
00165 //______________________________________________________________________________
00166 void TSVG::Close(Option_t *)
00167 {
00168    // Close a SVG file
00169    if (!gVirtualPS) return;
00170    if (!fStream) return;
00171    if (gPad) gPad->Update();
00172    PrintStr("</svg>@");
00173 
00174    // Close file stream
00175    if (fStream) { fStream->close(); delete fStream; fStream = 0;}
00176 
00177    gVirtualPS = 0;
00178 }
00179 
00180 
00181 //______________________________________________________________________________
00182 void TSVG::On()
00183 {
00184    // Activate an already open SVG file
00185 
00186    // fType is used to know if the SVG file is open. Unlike TPostScript, TSVG
00187    // has no "workstation type". In fact there is only one SVG type.
00188 
00189    if (!fType) {
00190       Error("On", "no SVG file open");
00191       Off();
00192       return;
00193    }
00194    gVirtualPS = this;
00195 }
00196 
00197 
00198 //______________________________________________________________________________
00199 void TSVG::Off()
00200 {
00201    // Deactivate an already open SVG file
00202 
00203    gVirtualPS = 0;
00204 }
00205 
00206 
00207 //______________________________________________________________________________
00208 void TSVG::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t  y2)
00209 {
00210    // Draw a Box
00211 
00212    static Double_t x[4], y[4];
00213    Int_t ix1 = XtoSVG(x1);
00214    Int_t ix2 = XtoSVG(x2);
00215    Int_t iy1 = YtoSVG(y1);
00216    Int_t iy2 = YtoSVG(y2);
00217    Int_t fillis = fFillStyle/1000;
00218    Int_t fillsi = fFillStyle%1000;
00219 
00220    if (fillis == 3 || fillis == 2) {
00221       if (fillsi > 99) {
00222          x[0] = x1;   y[0] = y1;
00223          x[1] = x2;   y[1] = y1;
00224          x[2] = x2;   y[2] = y2;
00225          x[3] = x1;   y[3] = y2;
00226          return;
00227       }
00228       if (fillsi > 0 && fillsi < 26) {
00229          x[0] = x1;   y[0] = y1;
00230          x[1] = x2;   y[1] = y1;
00231          x[2] = x2;   y[2] = y2;
00232          x[3] = x1;   y[3] = y2;
00233          DrawPS(-4, &x[0], &y[0]);
00234       }
00235       if (fillsi == -3) {
00236          PrintStr("@");
00237          PrintFast(9,"<rect x=\"");
00238          WriteInteger(ix1, 0);
00239          PrintFast(5,"\" y=\"");
00240          WriteInteger(iy2, 0);
00241          PrintFast(9,"\" width=\"");
00242          WriteInteger(ix2-ix1, 0);
00243          PrintFast(10,"\" height=\"");
00244          WriteInteger(iy1-iy2, 0);
00245          PrintFast(7,"\" fill=");
00246          SetColor(5);
00247          PrintFast(2,"/>");
00248       }
00249    }
00250    if (fillis == 1) {
00251       PrintStr("@");
00252       PrintFast(9,"<rect x=\"");
00253       WriteInteger(ix1, 0);
00254       PrintFast(5,"\" y=\"");
00255       WriteInteger(iy2, 0);
00256       PrintFast(9,"\" width=\"");
00257       WriteInteger(ix2-ix1, 0);
00258       PrintFast(10,"\" height=\"");
00259       WriteInteger(iy1-iy2, 0);
00260       PrintFast(7,"\" fill=");
00261       SetColor(fFillColor);
00262       PrintFast(2,"/>");
00263    }
00264    if (fillis == 0) {
00265       PrintStr("@");
00266       PrintFast(9,"<rect x=\"");
00267       WriteInteger(ix1, 0);
00268       PrintFast(5,"\" y=\"");
00269       WriteInteger(iy2, 0);
00270       PrintFast(9,"\" width=\"");
00271       WriteInteger(ix2-ix1, 0);
00272       PrintFast(10,"\" height=\"");
00273       WriteInteger(iy1-iy2, 0);
00274       PrintFast(21,"\" fill=\"none\" stroke=");
00275       SetColor(fLineColor);
00276       PrintFast(2,"/>");
00277    }
00278 }
00279 
00280 
00281 //______________________________________________________________________________
00282 void TSVG::DrawFrame(Double_t xl, Double_t yl, Double_t xt, Double_t  yt,
00283                             Int_t mode, Int_t border, Int_t dark, Int_t light)
00284 {
00285    // Draw a Frame around a box
00286    //
00287    // mode = -1  the box looks as it is behind the screen
00288    // mode =  1  the box looks as it is in front of the screen
00289    // border is the border size in already pre-computed SVG units dark is the
00290    // color for the dark part of the frame light is the color for the light
00291    // part of the frame
00292 
00293    static Int_t xps[7], yps[7];
00294    Int_t i, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00295 
00296    //- Draw top&left part of the box
00297 
00298    xps[0] = XtoSVG(xl);          yps[0] = YtoSVG(yl);
00299    xps[1] = xps[0] + border;     yps[1] = yps[0] - border;
00300    xps[2] = xps[1];              yps[2] = YtoSVG(yt) + border;
00301    xps[3] = XtoSVG(xt) - border; yps[3] = yps[2];
00302    xps[4] = XtoSVG(xt);          yps[4] = YtoSVG(yt);
00303    xps[5] = xps[0];              yps[5] = yps[4];
00304    xps[6] = xps[0];              yps[6] = yps[0];
00305 
00306    ixd0 = xps[0];
00307    iyd0 = yps[0];
00308    PrintStr("@");
00309    PrintFast(10,"<path d=\"M");
00310    WriteInteger(ixd0, 0);
00311    PrintFast(1,",");
00312    WriteInteger(iyd0, 0);
00313 
00314    idx = 0;
00315    idy = 0;
00316    for (i=1; i<7; i++) {
00317       ixdi = xps[i];
00318       iydi = yps[i];
00319       ix   = ixdi - ixd0;
00320       iy   = iydi - iyd0;
00321       ixd0 = ixdi;
00322       iyd0 = iydi;
00323       if( ix && iy) {
00324          if( idx ) { MovePS(idx,0); idx = 0; }
00325          if( idy ) { MovePS(0,idy); idy = 0; }
00326          MovePS(ix,iy);
00327          continue;
00328       }
00329       if ( ix ) {
00330          if( idy )  { MovePS(0,idy); idy = 0; }
00331          if( !idx ) { idx = ix; continue;}
00332          if( ix*idx > 0 ) {
00333             idx += ix;
00334          } else {
00335             MovePS(idx,0);
00336             idx  = ix;
00337          }
00338          continue;
00339       }
00340       if( iy ) {
00341          if( idx ) { MovePS(idx,0); idx = 0; }
00342          if( !idy) { idy = iy; continue;}
00343          if( iy*idy > 0 ) {
00344             idy += iy;
00345          } else {
00346             MovePS(0,idy);
00347             idy  = iy;
00348          }
00349       }
00350    }
00351    if( idx ) MovePS(idx,0);
00352    if( idy ) MovePS(0,idy);
00353    PrintFast(8,"z\" fill=");
00354    if (mode == -1) {
00355       SetColor(dark);
00356    } else {
00357       SetColor(light);
00358    }
00359    PrintFast(2,"/>");
00360 
00361    //- Draw bottom&right part of the box
00362    xps[0] = XtoSVG(xl);          yps[0] = YtoSVG(yl);
00363    xps[1] = xps[0] + border;     yps[1] = yps[0] - border;
00364    xps[2] = XtoSVG(xt) - border; yps[2] = yps[1];
00365    xps[3] = xps[2];              yps[3] = YtoSVG(yt) + border;
00366    xps[4] = XtoSVG(xt);          yps[4] = YtoSVG(yt);
00367    xps[5] = xps[4];              yps[5] = yps[0];
00368    xps[6] = xps[0];              yps[6] = yps[0];
00369 
00370    ixd0 = xps[0];
00371    iyd0 = yps[0];
00372    PrintStr("@");
00373    PrintFast(10,"<path d=\"M");
00374    WriteInteger(ixd0, 0);
00375    PrintFast(1,",");
00376    WriteInteger(iyd0, 0);
00377 
00378    idx = 0;
00379    idy = 0;
00380    for (i=1;i<7;i++) {
00381       ixdi = xps[i];
00382       iydi = yps[i];
00383       ix   = ixdi - ixd0;
00384       iy   = iydi - iyd0;
00385       ixd0 = ixdi;
00386       iyd0 = iydi;
00387       if( ix && iy) {
00388          if( idx ) { MovePS(idx,0); idx = 0; }
00389          if( idy ) { MovePS(0,idy); idy = 0; }
00390          MovePS(ix,iy);
00391          continue;
00392       }
00393       if ( ix ) {
00394          if( idy )  { MovePS(0,idy); idy = 0; }
00395          if( !idx ) { idx = ix; continue;}
00396          if( ix*idx > 0 ) {
00397             idx += ix;
00398          } else {
00399             MovePS(idx,0);
00400             idx  = ix;
00401          }
00402          continue;
00403       }
00404       if( iy ) {
00405          if( idx ) { MovePS(idx,0); idx = 0; }
00406          if( !idy) { idy = iy; continue;}
00407          if( iy*idy > 0 ) {
00408             idy += iy;
00409          } else {
00410             MovePS(0,idy);
00411             idy  = iy;
00412          }
00413       }
00414    }
00415    if( idx ) MovePS(idx,0);
00416    if( idy ) MovePS(0,idy);
00417    PrintFast(8,"z\" fill=");
00418    if (mode == -1) {
00419       SetColor(light);
00420    } else {
00421       SetColor(dark);
00422    }
00423    PrintFast(2,"/>");
00424 }
00425 
00426 
00427 //______________________________________________________________________________
00428 void TSVG::DrawPolyLine(Int_t nn, TPoints *xy)
00429 {
00430    // Draw a PolyLine
00431    //
00432    //  Draw a polyline through  the points  xy.
00433    //  If NN=1 moves only to point x,y.
00434    //  If NN=0 the x,y are  written  in the SVG        file
00435    //     according to the current transformation.
00436    //  If NN>0 the line is clipped as a line.
00437    //  If NN<0 the line is clipped as a fill area.
00438 
00439    Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00440 
00441    if (nn > 0) {
00442       n = nn;
00443 ///     SetLineStyle(fLineStyle);
00444 ///     SetLineWidth(fLineWidth);
00445 ///     SetColor(Int_t(fLineColor));
00446    } else {
00447       n = -nn;
00448 ///     SetLineStyle(1);
00449 ///     SetLineWidth(1);
00450 ///     SetColor(Int_t(fLineColor));
00451    }
00452 
00453    ixd0 = XtoSVG(xy[0].GetX());
00454    iyd0 = YtoSVG(xy[0].GetY());
00455 ///  WriteInteger(ixd0);
00456 ///  WriteInteger(iyd0);
00457    if( n <= 1) {
00458       if( n == 0) return;
00459 ///     PrintFast(2," m");
00460       return;
00461    }
00462 
00463    PrintFast(2," m");
00464    idx = 0;
00465    idy = 0;
00466    for (Int_t i=1;i<n;i++) {
00467       ixdi = XtoSVG(xy[i].GetX());
00468       iydi = YtoSVG(xy[i].GetY());
00469       ix   = ixdi - ixd0;
00470       iy   = iydi - iyd0;
00471       ixd0 = ixdi;
00472       iyd0 = iydi;
00473       if( ix && iy) {
00474          if( idx ) { MovePS(idx,0); idx = 0; }
00475          if( idy ) { MovePS(0,idy); idy = 0; }
00476          MovePS(ix,iy);
00477          continue;
00478       }
00479       if ( ix ) {
00480          if( idy )  { MovePS(0,idy); idy = 0; }
00481          if( !idx ) { idx = ix; continue;}
00482          if( ix*idx > 0 ) {
00483             idx += ix;
00484          } else {
00485             MovePS(idx,0);
00486             idx  = ix;
00487          }
00488          continue;
00489       }
00490       if( iy ) {
00491          if( idx ) { MovePS(idx,0); idx = 0; }
00492          if( !idy) { idy = iy; continue;}
00493          if( iy*idy > 0 ) {
00494             idy += iy;
00495          } else {
00496             MovePS(0,idy);
00497             idy  = iy;
00498          }
00499       }
00500    }
00501    if( idx ) MovePS(idx,0);
00502    if( idy ) MovePS(0,idy);
00503 
00504    if (nn > 0 ) {
00505 ///     if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00506 ///     PrintFast(2," s");
00507    } else {
00508 ///     PrintFast(2," f");
00509    }
00510 }
00511 
00512 
00513 //______________________________________________________________________________
00514 void TSVG::DrawPolyLineNDC(Int_t nn, TPoints *xy)
00515 {
00516    // Draw a PolyLine in NDC space
00517    //
00518    //  Draw a polyline through  the points  xy.
00519    //  If NN=1 moves only to point x,y.
00520    //  If NN=0 the x,y are  written  in the SVG        file
00521    //     according to the current transformation.
00522    //  If NN>0 the line is clipped as a line.
00523    //  If NN<0 the line is clipped as a fill area.
00524 
00525    Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy;
00526 
00527    if (nn > 0) {
00528       n = nn;
00529 ///     SetLineStyle(fLineStyle);
00530 ///     SetLineWidth(fLineWidth);
00531 ///     SetColor(Int_t(fLineColor));
00532    } else {
00533       n = -nn;
00534 ///     SetLineStyle(1);
00535 ///     SetLineWidth(1);
00536 ///     SetColor(Int_t(fLineColor));
00537    }
00538 
00539    ixd0 = UtoSVG(xy[0].GetX());
00540    iyd0 = VtoSVG(xy[0].GetY());
00541 ///  WriteInteger(ixd0);
00542 ///  WriteInteger(iyd0);
00543    if( n <= 1) {
00544       if( n == 0) return;
00545 ///     PrintFast(2," m");
00546       return;
00547    }
00548 
00549 ///  PrintFast(2," m");
00550    idx = 0;
00551    idy = 0;
00552    for (Int_t i=1;i<n;i++) {
00553       ixdi = UtoSVG(xy[i].GetX());
00554       iydi = VtoSVG(xy[i].GetY());
00555       ix   = ixdi - ixd0;
00556       iy   = iydi - iyd0;
00557       ixd0 = ixdi;
00558       iyd0 = iydi;
00559       if( ix && iy) {
00560          if( idx ) { MovePS(idx,0); idx = 0; }
00561          if( idy ) { MovePS(0,idy); idy = 0; }
00562          MovePS(ix,iy);
00563          continue;
00564       }
00565       if ( ix ) {
00566          if( idy )  { MovePS(0,idy); idy = 0; }
00567          if( !idx ) { idx = ix; continue;}
00568          if( ix*idx > 0 ) {
00569             idx += ix;
00570          } else {
00571             MovePS(idx,0);
00572             idx  = ix;
00573          }
00574          continue;
00575       }
00576       if( iy ) {
00577          if( idx ) { MovePS(idx,0); idx = 0; }
00578          if( !idy) { idy = iy; continue;}
00579          if( iy*idy > 0 ) {
00580             idy += iy;
00581          } else {
00582             MovePS(0,idy);
00583             idy  = iy;
00584          }
00585       }
00586    }
00587    if( idx ) MovePS(idx,0);
00588    if( idy ) MovePS(0,idy);
00589 
00590    if (nn > 0 ) {
00591       if (xy[0].GetX() == xy[n-1].GetX() && xy[0].GetY() == xy[n-1].GetY()) PrintFast(3," cl");
00592 ///     PrintFast(2," s");
00593    } else {
00594 ///     PrintFast(2," f");
00595    }
00596 }
00597 
00598 
00599 //______________________________________________________________________________
00600 void TSVG::DrawPolyMarker(Int_t n, Float_t *xw, Float_t *yw)
00601 {
00602    // Paint PolyMarker
00603 
00604    Int_t ms = abs(fMarkerStyle);
00605 
00606    if (ms >= 6 && ms <= 19) ms = 20;
00607    if (ms == 4) ms = 24;
00608 
00609    // Define the marker size
00610    Float_t msize  = fMarkerSize;
00611    if (fMarkerStyle == 1) msize = 0.01;
00612    if (fMarkerStyle == 6) msize = 0.02;
00613    if (fMarkerStyle == 7) msize = 0.04;
00614 
00615    const Int_t kBASEMARKER = 8;
00616    Float_t sbase = msize*kBASEMARKER;
00617    Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
00618    msize = CMtoSVG(s2x * fXsize);
00619 
00620    Double_t m  = msize;
00621    Double_t m2 = m/2;
00622    Double_t m3 = m/3;
00623    Double_t m6 = m/6;
00624 
00625    // Draw the marker according to the type
00626    PrintStr("@");
00627    if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
00628       PrintStr("<g stroke=");
00629       SetColor(Int_t(fMarkerColor));
00630       PrintStr(" stroke-width=\"");
00631       WriteInteger(fLineWidth,0);
00632       PrintStr("\" fill=");
00633       SetColor(Int_t(fMarkerColor));
00634       PrintStr(">");
00635    } else {
00636       PrintStr("<g stroke=");
00637       SetColor(Int_t(fMarkerColor));
00638       PrintStr(" stroke-width=\"");
00639       WriteInteger(fLineWidth,0);
00640       PrintStr("\" fill=\"none\"");
00641       PrintStr(">");
00642    }
00643    Double_t ix,iy;
00644    for (Int_t i=0;i<n;i++) {
00645       ix = XtoSVG(xw[i]);
00646       iy = YtoSVG(yw[i]);
00647       PrintStr("@");
00648       // Dot (.)
00649       if (ms == 1) {
00650          PrintStr("<line x1=\"");
00651          WriteInteger(int(ix-1),0);
00652          PrintStr("\" y1=\"");
00653          WriteInteger(int(iy),0);
00654          PrintStr("\" x2=\"");
00655          WriteInteger(int(ix),0);
00656          PrintStr("\" y2=\"");
00657          WriteInteger(int(iy),0);
00658          PrintStr("\"/>");
00659       // Plus (+)
00660       } else if (ms == 2) {
00661          PrintStr("<line x1=\"");
00662          WriteReal(ix-m2);
00663          PrintStr("\" y1=\"");
00664          WriteReal(iy);
00665          PrintStr("\" x2=\"");
00666          WriteReal(ix+m2);
00667          PrintStr("\" y2=\"");
00668          WriteReal(iy);
00669          PrintStr("\"/>");
00670 
00671          PrintStr("<line x1=\"");
00672          WriteReal(ix);
00673          PrintStr("\" y1=\"");
00674          WriteReal(iy-m2);
00675          PrintStr("\" x2=\"");
00676          WriteReal(ix);
00677          PrintStr("\" y2=\"");
00678          WriteReal(iy+m2);
00679          PrintStr("\"/>");
00680       // X shape (X)
00681       } else if (ms == 5) {
00682          PrintStr("<line x1=\"");
00683          WriteReal(ix-m2);
00684          PrintStr("\" y1=\"");
00685          WriteReal(iy-m2);
00686          PrintStr("\" x2=\"");
00687          WriteReal(ix+m2);
00688          PrintStr("\" y2=\"");
00689          WriteReal(iy+m2);
00690          PrintStr("\"/>");
00691 
00692          PrintStr("<line x1=\"");
00693          WriteReal(ix-m2);
00694          PrintStr("\" y1=\"");
00695          WriteReal(iy+m2);
00696          PrintStr("\" x2=\"");
00697          WriteReal(ix+m2);
00698          PrintStr("\" y2=\"");
00699          WriteReal(iy-m2);
00700          PrintStr("\"/>");
00701       // Asterisk shape (*)
00702       } else if (ms == 3 || ms == 31) {
00703          PrintStr("<line x1=\"");
00704          WriteReal(ix-m2);
00705          PrintStr("\" y1=\"");
00706          WriteReal(iy);
00707          PrintStr("\" x2=\"");
00708          WriteReal(ix+m2);
00709          PrintStr("\" y2=\"");
00710          WriteReal(iy);
00711          PrintStr("\"/>");
00712 
00713          PrintStr("<line x1=\"");
00714          WriteReal(ix);
00715          PrintStr("\" y1=\"");
00716          WriteReal(iy-m2);
00717          PrintStr("\" x2=\"");
00718          WriteReal(ix);
00719          PrintStr("\" y2=\"");
00720          WriteReal(iy+m2);
00721          PrintStr("\"/>");
00722 
00723          PrintStr("<line x1=\"");
00724          WriteReal(ix-m2);
00725          PrintStr("\" y1=\"");
00726          WriteReal(iy-m2);
00727          PrintStr("\" x2=\"");
00728          WriteReal(ix+m2);
00729          PrintStr("\" y2=\"");
00730          WriteReal(iy+m2);
00731          PrintStr("\"/>");
00732 
00733          PrintStr("<line x1=\"");
00734          WriteReal(ix-m2);
00735          PrintStr("\" y1=\"");
00736          WriteReal(iy+m2);
00737          PrintStr("\" x2=\"");
00738          WriteReal(ix+m2);
00739          PrintStr("\" y2=\"");
00740          WriteReal(iy-m2);
00741          PrintStr("\"/>");
00742       // Circle
00743       } else if (ms == 24 || ms == 20) {
00744          PrintStr("<circle cx=\"");
00745          WriteReal(ix);
00746          PrintStr("\" cy=\"");
00747          WriteReal(iy);
00748          PrintStr("\" r=\"");
00749          WriteReal(m2);
00750          PrintStr("\" fill=\"none\"");
00751          PrintStr("/>");
00752       // Square
00753       } else if (ms == 25 || ms == 21) {
00754          PrintStr("<rect x=\"");
00755          WriteReal(ix-m2);
00756          PrintStr("\" y=\"");
00757          WriteReal(iy-m2);
00758          PrintStr("\" width=\"");
00759          WriteReal(m);
00760          PrintStr("\" height=\"");
00761          WriteReal(m);
00762          PrintStr("\" fill=\"none\"");
00763          PrintStr("/>");
00764       // Down triangle
00765       } else if (ms == 26 || ms == 22) {
00766          PrintStr("<polygon points=\"");
00767          WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
00768          WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
00769          WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
00770          PrintStr("\"/>");
00771       // Up triangle
00772       } else if (ms == 23 || ms == 32) {
00773          PrintStr("<polygon points=\"");
00774          WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
00775          WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
00776          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
00777          PrintStr("\"/>");
00778       // Diamond
00779       } else if (ms == 27 || ms == 33) {
00780          PrintStr("<polygon points=\"");
00781          WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
00782          WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
00783          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
00784          WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
00785          PrintStr("\"/>");
00786       // Cross
00787       } else if (ms == 28 || ms == 34) {
00788          PrintStr("<polygon points=\"");
00789          WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
00790          WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
00791          WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
00792          WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
00793          WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
00794          WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
00795          WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
00796          WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
00797          WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
00798          WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
00799          WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
00800          WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
00801          PrintStr("\"/>");
00802       } else if (ms == 29 || ms == 30) {
00803          PrintStr("<polygon points=\"");
00804          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
00805          WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
00806          WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
00807          WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
00808          WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
00809          WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
00810          WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
00811          WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
00812          WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
00813          WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
00814          PrintStr("\"/>");
00815       } else {
00816          PrintStr("<line x1=\"");
00817          WriteInteger(int(ix-1),0);
00818          PrintStr("\" y1=\"");
00819          WriteInteger(int(iy),0);
00820          PrintStr("\" x2=\"");
00821          WriteInteger(int(ix),0);
00822          PrintStr("\" y2=\"");
00823          WriteInteger(int(iy),0);
00824          PrintStr("\"/>");
00825       }
00826    }
00827    PrintStr("@");
00828    PrintStr("</g>");
00829 }
00830 
00831 
00832 //______________________________________________________________________________
00833 void TSVG::DrawPolyMarker(Int_t n, Double_t *xw, Double_t *yw)
00834 {
00835    // Paint PolyMarker
00836 
00837    Int_t ms = abs(fMarkerStyle);
00838 
00839    if (ms >= 6 && ms <= 19) ms = 20;
00840    if (ms == 4) ms = 24;
00841 
00842    // Define the marker size
00843    Float_t msize  = fMarkerSize;
00844    if (fMarkerStyle == 1) msize = 0.01;
00845    if (fMarkerStyle == 6) msize = 0.02;
00846    if (fMarkerStyle == 7) msize = 0.04;
00847 
00848    const Int_t kBASEMARKER = 8;
00849    Float_t sbase = msize*kBASEMARKER;
00850    Float_t s2x = sbase / Float_t(gPad->GetWw() * gPad->GetAbsWNDC());
00851    msize = CMtoSVG(s2x * fXsize);
00852 
00853    Double_t m  = msize;
00854    Double_t m2 = m/2;
00855    Double_t m3 = m/3;
00856    Double_t m6 = m/6;
00857 
00858    // Draw the marker according to the type
00859    PrintStr("@");
00860    if ((ms > 19 && ms < 24) || ms == 29 || ms == 33 || ms == 34) {
00861       PrintStr("<g stroke=");
00862       SetColor(Int_t(fMarkerColor));
00863       PrintStr(" stroke-width=\"");
00864       WriteInteger(fLineWidth,0);
00865       PrintStr("\" fill=");
00866       SetColor(Int_t(fMarkerColor));
00867       PrintStr(">");
00868    } else {
00869       PrintStr("<g stroke=");
00870       SetColor(Int_t(fMarkerColor));
00871       PrintStr(" stroke-width=\"");
00872       WriteInteger(fLineWidth,0);
00873       PrintStr("\" fill=\"none\"");
00874       PrintStr(">");
00875    }
00876    Double_t ix,iy;
00877    for (Int_t i=0;i<n;i++) {
00878       ix = XtoSVG(xw[i]);
00879       iy = YtoSVG(yw[i]);
00880       PrintStr("@");
00881       // Dot (.)
00882       if (ms == 1) {
00883          PrintStr("<line x1=\"");
00884          WriteInteger(int(ix-1),0);
00885          PrintStr("\" y1=\"");
00886          WriteInteger(int(iy),0);
00887          PrintStr("\" x2=\"");
00888          WriteInteger(int(ix),0);
00889          PrintStr("\" y2=\"");
00890          WriteInteger(int(iy),0);
00891          PrintStr("\"/>");
00892       // Plus (+)
00893       } else if (ms == 2) {
00894          PrintStr("<line x1=\"");
00895          WriteReal(ix-m2);
00896          PrintStr("\" y1=\"");
00897          WriteReal(iy);
00898          PrintStr("\" x2=\"");
00899          WriteReal(ix+m2);
00900          PrintStr("\" y2=\"");
00901          WriteReal(iy);
00902          PrintStr("\"/>");
00903 
00904          PrintStr("<line x1=\"");
00905          WriteReal(ix);
00906          PrintStr("\" y1=\"");
00907          WriteReal(iy-m2);
00908          PrintStr("\" x2=\"");
00909          WriteReal(ix);
00910          PrintStr("\" y2=\"");
00911          WriteReal(iy+m2);
00912          PrintStr("\"/>");
00913       // X shape (X)
00914       } else if (ms == 5) {
00915          PrintStr("<line x1=\"");
00916          WriteReal(ix-m2);
00917          PrintStr("\" y1=\"");
00918          WriteReal(iy-m2);
00919          PrintStr("\" x2=\"");
00920          WriteReal(ix+m2);
00921          PrintStr("\" y2=\"");
00922          WriteReal(iy+m2);
00923          PrintStr("\"/>");
00924 
00925          PrintStr("<line x1=\"");
00926          WriteReal(ix-m2);
00927          PrintStr("\" y1=\"");
00928          WriteReal(iy+m2);
00929          PrintStr("\" x2=\"");
00930          WriteReal(ix+m2);
00931          PrintStr("\" y2=\"");
00932          WriteReal(iy-m2);
00933          PrintStr("\"/>");
00934       // Asterisk shape (*)
00935       } else if (ms == 3 || ms == 31) {
00936          PrintStr("<line x1=\"");
00937          WriteReal(ix-m2);
00938          PrintStr("\" y1=\"");
00939          WriteReal(iy);
00940          PrintStr("\" x2=\"");
00941          WriteReal(ix+m2);
00942          PrintStr("\" y2=\"");
00943          WriteReal(iy);
00944          PrintStr("\"/>");
00945 
00946          PrintStr("<line x1=\"");
00947          WriteReal(ix);
00948          PrintStr("\" y1=\"");
00949          WriteReal(iy-m2);
00950          PrintStr("\" x2=\"");
00951          WriteReal(ix);
00952          PrintStr("\" y2=\"");
00953          WriteReal(iy+m2);
00954          PrintStr("\"/>");
00955 
00956          PrintStr("<line x1=\"");
00957          WriteReal(ix-m2);
00958          PrintStr("\" y1=\"");
00959          WriteReal(iy-m2);
00960          PrintStr("\" x2=\"");
00961          WriteReal(ix+m2);
00962          PrintStr("\" y2=\"");
00963          WriteReal(iy+m2);
00964          PrintStr("\"/>");
00965 
00966          PrintStr("<line x1=\"");
00967          WriteReal(ix-m2);
00968          PrintStr("\" y1=\"");
00969          WriteReal(iy+m2);
00970          PrintStr("\" x2=\"");
00971          WriteReal(ix+m2);
00972          PrintStr("\" y2=\"");
00973          WriteReal(iy-m2);
00974          PrintStr("\"/>");
00975       // Circle
00976       } else if (ms == 24 || ms == 20) {
00977          PrintStr("<circle cx=\"");
00978          WriteReal(ix);
00979          PrintStr("\" cy=\"");
00980          WriteReal(iy);
00981          PrintStr("\" r=\"");
00982          WriteReal(m2);
00983          PrintStr("\"/>");
00984       // Square
00985       } else if (ms == 25 || ms == 21) {
00986          PrintStr("<rect x=\"");
00987          WriteReal(ix-m2);
00988          PrintStr("\" y=\"");
00989          WriteReal(iy-m2);
00990          PrintStr("\" width=\"");
00991          WriteReal(m);
00992          PrintStr("\" height=\"");
00993          WriteReal(m);
00994          PrintStr("\"/>");
00995       // Down triangle
00996       } else if (ms == 26 || ms == 22) {
00997          PrintStr("<polygon points=\"");
00998          WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
00999          WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m2);
01000          WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m2);
01001          PrintStr("\"/>");
01002       // Up triangle
01003       } else if (ms == 23 || ms == 32) {
01004          PrintStr("<polygon points=\"");
01005          WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m2);
01006          WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m2);
01007          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
01008          PrintStr("\"/>");
01009       // Diamond
01010       } else if (ms == 27 || ms == 33) {
01011          PrintStr("<polygon points=\"");
01012          WriteReal(ix); PrintStr(","); WriteReal(iy-m2);
01013          WriteReal(ix+m3); PrintStr(","); WriteReal(iy);
01014          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
01015          WriteReal(ix-m3); PrintStr(","); WriteReal(iy);
01016          PrintStr("\"/>");
01017       // Cross
01018       } else if (ms == 28 || ms == 34) {
01019          PrintStr("<polygon points=\"");
01020          WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m6);
01021          WriteReal(ix-m6); PrintStr(","); WriteReal(iy-m2);
01022          WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m2);
01023          WriteReal(ix+m6); PrintStr(","); WriteReal(iy-m6);
01024          WriteReal(ix+m2); PrintStr(","); WriteReal(iy-m6);
01025          WriteReal(ix+m2); PrintStr(","); WriteReal(iy+m6);
01026          WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m6);
01027          WriteReal(ix+m6); PrintStr(","); WriteReal(iy+m2);
01028          WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m2);
01029          WriteReal(ix-m6); PrintStr(","); WriteReal(iy+m6);
01030          WriteReal(ix-m2); PrintStr(","); WriteReal(iy+m6);
01031          WriteReal(ix-m2); PrintStr(","); WriteReal(iy-m6);
01032          PrintStr("\"/>");
01033       } else if (ms == 29 || ms == 30) {
01034          PrintStr("<polygon points=\"");
01035          WriteReal(ix); PrintStr(","); WriteReal(iy+m2);
01036          WriteReal(ix+0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
01037          WriteReal(ix+0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
01038          WriteReal(ix+0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
01039          WriteReal(ix+0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
01040          WriteReal(ix); PrintStr(","); WriteReal(iy-0.19098*m);
01041          WriteReal(ix-0.29389*m); PrintStr(","); WriteReal(iy-0.40451*m);
01042          WriteReal(ix-0.181635*m); PrintStr(","); WriteReal(iy-0.05902*m);
01043          WriteReal(ix-0.47552*m); PrintStr(","); WriteReal(iy+0.15451*m);
01044          WriteReal(ix-0.112255*m); PrintStr(","); WriteReal(iy+0.15451*m);
01045          PrintStr("\"/>");
01046       } else {
01047          PrintStr("<line x1=\"");
01048          WriteInteger(int(ix-1),0);
01049          PrintStr("\" y1=\"");
01050          WriteInteger(int(iy),0);
01051          PrintStr("\" x2=\"");
01052          WriteInteger(int(ix),0);
01053          PrintStr("\" y2=\"");
01054          WriteInteger(int(iy),0);
01055          PrintStr("\"/>");
01056       }
01057    }
01058    PrintStr("@");
01059    PrintStr("</g>");
01060 }
01061 
01062 
01063 //______________________________________________________________________________
01064 void TSVG::DrawPS(Int_t nn, Double_t *xw, Double_t *yw)
01065 {
01066    // This function defines a path with xw and yw and draw it according the
01067    // value of nn:
01068    //
01069    //  If nn>0 a line is drawn.
01070    //  If nn<0 a closed polygon is drawn.
01071 
01072 ///static Float_t dyhatch[24] = {.0075,.0075,.0075,.0075,.0075,.0075,.0075,.0075,
01073 ///                              .01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,.01  ,
01074 ///                              .015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015 ,.015};
01075 ///static Float_t anglehatch[24] = {180, 90,135, 45,150, 30,120, 60,
01076 ///                                 180, 90,135, 45,150, 30,120, 60,
01077 ///                                 180, 90,135, 45,150, 30,120, 60};
01078    Int_t  n, ixd0, iyd0, idx, idy, ixdi, iydi, ix, iy, fais, fasi;
01079    fais = fasi = 0;
01080 
01081    if (nn > 0) {
01082       n = nn;
01083    } else {
01084       n = -nn;
01085       fais = fFillStyle/1000;
01086       fasi = fFillStyle%1000;
01087       if (fais == 3 || fais == 2) {
01088          if (fasi > 100 && fasi <125) {
01089 ///        DrawHatch(dyhatch[fasi-101],anglehatch[fasi-101], n, xw, yw);
01090             return;
01091          }
01092          if (fasi > 0 && fasi < 26) {
01093 ///        SetFillPatterns(fasi, Int_t(fFillColor));
01094          }
01095       }
01096    }
01097 
01098    if( n <= 1) {
01099       Error("DrawPS", "Two points are needed");
01100       return;
01101    }
01102 
01103    ixd0 = XtoSVG(xw[0]);
01104    iyd0 = YtoSVG(yw[0]);
01105 
01106    PrintStr("@");
01107    PrintFast(10,"<path d=\"M");
01108    WriteInteger(ixd0, 0);
01109    PrintFast(1,",");
01110    WriteInteger(iyd0, 0);
01111 
01112    idx = idy = 0;
01113    for (Int_t i=1;i<n;i++) {
01114       ixdi = XtoSVG(xw[i]);
01115       iydi = YtoSVG(yw[i]);
01116       ix   = ixdi - ixd0;
01117       iy   = iydi - iyd0;
01118       ixd0 = ixdi;
01119       iyd0 = iydi;
01120       if( ix && iy) {
01121          if( idx ) { MovePS(idx,0); idx = 0; }
01122          if( idy ) { MovePS(0,idy); idy = 0; }
01123          MovePS(ix,iy);
01124       } else if ( ix ) {
01125          if( idy )  { MovePS(0,idy); idy = 0;}
01126          if( !idx ) { idx = ix;}
01127          else if( TMath::Sign(ix,idx) == ix )       idx += ix;
01128          else { MovePS(idx,0);  idx  = ix;}
01129       } else if( iy ) {
01130          if( idx ) { MovePS(idx,0); idx = 0;}
01131          if( !idy) { idy = iy;}
01132          else if( TMath::Sign(iy,idy) == iy)         idy += iy;
01133          else { MovePS(0,idy);    idy  = iy;}
01134       }
01135    }
01136    if (idx) MovePS(idx,0);
01137    if (idy) MovePS(0,idy);
01138 
01139    if (nn > 0 ) {
01140       if (xw[0] == xw[n-1] && yw[0] == yw[n-1]) PrintFast(1,"z");
01141       PrintFast(21,"\" fill=\"none\" stroke=");
01142       SetColor(fLineColor);
01143       if(fLineWidth > 1.) {
01144          PrintFast(15," stroke-width=\"");
01145          WriteInteger(Int_t(fLineWidth), 0);
01146          PrintFast(1,"\"");
01147       }
01148       if (fLineStyle > 1) {
01149          PrintFast(19," stroke-dasharray=\"");
01150          TString st = (TString)gStyle->GetLineStyleString(fLineStyle);
01151          TObjArray *tokens = st.Tokenize(" ");
01152          for (Int_t j = 0; j<tokens->GetEntries(); j++) {
01153             Int_t it;
01154             sscanf(((TObjString*)tokens->At(j))->GetName(), "%d", &it);
01155             if (j>0) PrintFast(1,",");
01156             WriteInteger((Int_t)(it/4));
01157          }
01158          delete tokens;
01159          PrintFast(1,"\"");
01160       }
01161       PrintFast(2,"/>");
01162    } else {
01163       PrintFast(8,"z\" fill=");
01164       if (fais == 0) {
01165          PrintFast(14,"\"none\" stroke=");
01166          SetColor(fFillColor);
01167 ///      } else if (fais == 3 || fais == 2) {
01168 ///        if (fasi > 0 && fasi < 26) {
01169 ///           Put SVG patterns here
01170       } else {
01171          SetColor(fFillColor);
01172       }
01173       PrintFast(2,"/>");
01174    }
01175 }
01176 
01177 
01178 //______________________________________________________________________________
01179 void TSVG::Initialize()
01180 {
01181    // Initialize the SVG file. The main task of the function is to ouput the
01182    // SVG header file which consist in <title>, <desc> and <defs>. The
01183    // HeaderPS provided by the user program is written in the <defs> part.
01184 
01185    // Title
01186    PrintStr("<title>@");
01187    PrintStr(GetName());
01188    PrintStr("@");
01189    PrintStr("</title>@");
01190 
01191    // Description
01192    PrintStr("<desc>@");
01193    PrintFast(22,"Creator: ROOT Version ");
01194    PrintStr(gROOT->GetVersion());
01195    PrintStr("@");
01196    PrintFast(14,"CreationDate: ");
01197    TDatime t;
01198    PrintStr(t.AsString());
01199    //Check a special header is defined in the current style
01200    Int_t nh = strlen(gStyle->GetHeaderPS());
01201    if (nh) {
01202       PrintFast(nh,gStyle->GetHeaderPS());
01203    }
01204    PrintStr("</desc>@");
01205 
01206    // Definitions
01207    PrintStr("<defs>@");
01208    PrintStr("</defs>@");
01209 
01210 }
01211 
01212 
01213 //______________________________________________________________________________
01214 void TSVG::MovePS(Int_t ix, Int_t iy)
01215 {
01216    // Move to a new position (ix, iy). The move is done in relative coordinates
01217    // which allows to have short numbers which decrease the size of the file.
01218    // This function use the full power of the SVG's paths by using the
01219    // horizontal and vertical move whenever it is possible.
01220 
01221    if (ix != 0 && iy != 0)  {
01222       PrintFast(1,"l");
01223       WriteInteger(ix);
01224       PrintFast(1,",");
01225       WriteInteger(iy);
01226    } else if (ix != 0)  {
01227       PrintFast(1,"h");
01228       WriteInteger(ix);
01229    } else if (iy != 0)  {
01230       PrintFast(1,"v");
01231       WriteInteger(iy);
01232    }
01233 }
01234 
01235 
01236 //______________________________________________________________________________
01237 void TSVG::NewPage()
01238 {
01239    // Start the SVG page. This function initialize the pad conversion
01240    // coefficients and ouput the <svg> directive which is close later in the
01241    // the function Close.
01242 
01243    // Compute pad conversion coefficients
01244    if (gPad) {
01245       Double_t ww   = gPad->GetWw();
01246       Double_t wh   = gPad->GetWh();
01247       fYsize        = fXsize*wh/ww;
01248    } else {
01249       fYsize = 27;
01250    }
01251 
01252    // <svg> directive. It defines the viewBox.
01253    if(!fBoundingBox) {
01254       PrintStr("@<?xml version=\"1.0\" standalone=\"no\"?>");
01255       PrintStr("@<svg width=\"");
01256       WriteInteger(CMtoSVG(fXsize), 0);
01257       PrintStr("\" height=\"");
01258       fYsizeSVG = CMtoSVG(fYsize);
01259       WriteInteger(fYsizeSVG, 0);
01260       PrintStr("\" viewBox=\"0 0");
01261       WriteInteger(CMtoSVG(fXsize));
01262       WriteInteger(fYsizeSVG);
01263       PrintStr("\" xmlns=\"http://www.w3.org/2000/svg\">");
01264       PrintStr("@");
01265       Initialize();
01266       fBoundingBox  = kTRUE;
01267    }
01268 }
01269 
01270 
01271 //______________________________________________________________________________
01272 void TSVG::Range(Float_t xsize, Float_t ysize)
01273 {
01274    // Set the range for the paper in centimetres
01275 
01276    Float_t xps, yps, xncm, yncm, dxwn, dywn, xwkwn, ywkwn, xymax;
01277 
01278    fXsize = xsize;
01279    fYsize = ysize;
01280 
01281    xps = xsize;
01282    yps = ysize;
01283 
01284    if( xsize <= xps && ysize < yps) {
01285       if ( xps > yps ) xymax = xps;
01286       else             xymax = yps;
01287       xncm  = xsize/xymax;
01288       yncm  = ysize/xymax;
01289       dxwn  = ((xps/xymax)-xncm)/2;
01290       dywn  = ((yps/xymax)-yncm)/2;
01291    } else {
01292       if (xps/yps < 1) xwkwn = xps/yps;
01293       else             xwkwn = 1;
01294       if (yps/xps < 1) ywkwn = yps/xps;
01295       else             ywkwn = 1;
01296 
01297       if (xsize < ysize)  {
01298          xncm = ywkwn*xsize/ysize;
01299          yncm = ywkwn;
01300          dxwn = (xwkwn-xncm)/2;
01301          dywn = 0;
01302          if( dxwn < 0) {
01303             xncm = xwkwn;
01304             dxwn = 0;
01305             yncm = xwkwn*ysize/xsize;
01306             dywn = (ywkwn-yncm)/2;
01307          }
01308       } else {
01309          xncm = xwkwn;
01310          yncm = xwkwn*ysize/xsize;
01311          dxwn = 0;
01312          dywn = (ywkwn-yncm)/2;
01313          if( dywn < 0) {
01314             yncm = ywkwn;
01315             dywn = 0;
01316             xncm = ywkwn*xsize/ysize;
01317             dxwn = (xwkwn-xncm)/2;
01318          }
01319       }
01320    }
01321    fRange = kTRUE;
01322 }
01323 
01324 
01325 //______________________________________________________________________________
01326 void TSVG::SetFillColor( Color_t cindex )
01327 {
01328    // Set color index for fill areas
01329 
01330    fFillColor = cindex;
01331    if (gStyle->GetFillColor() <= 0) cindex = 0;
01332 }
01333 
01334 
01335 //______________________________________________________________________________
01336 void TSVG::SetLineColor( Color_t cindex )
01337 {
01338    // Set color index for lines
01339 
01340    fLineColor = cindex;
01341 }
01342 
01343 
01344 //______________________________________________________________________________
01345 void TSVG::SetLineStyle(Style_t linestyle)
01346 {
01347    // Change the line style
01348    //
01349    // linestyle = 2 dashed
01350    //           = 3 dotted
01351    //           = 4 dash-dotted
01352    //           = else solid (1 in is used most of the time)
01353 
01354    fLineStyle = linestyle;
01355 }
01356 
01357 
01358 //______________________________________________________________________________
01359 void TSVG::SetLineWidth(Width_t linewidth)
01360 {
01361    // Set the lines width.
01362 
01363    fLineWidth = linewidth;
01364 }
01365 
01366 
01367 //______________________________________________________________________________
01368 void TSVG::SetMarkerColor( Color_t cindex )
01369 {
01370    // Set color index for markers.
01371 
01372    fMarkerColor = cindex;
01373 }
01374 
01375 
01376 //______________________________________________________________________________
01377 void TSVG::SetColor(Int_t color)
01378 {
01379    // Set color with its color index
01380 
01381    if (color < 0) color = 0;
01382    TColor *col = gROOT->GetColor(color);
01383    if (col) {
01384       SetColor(col->GetRed(), col->GetGreen(), col->GetBlue());
01385    } else {
01386       SetColor(1., 1., 1.);
01387    }
01388 }
01389 
01390 
01391 //______________________________________________________________________________
01392 void TSVG::SetColor(Float_t r, Float_t g, Float_t b)
01393 {
01394    // Set color with its R G B components
01395    //
01396    //  r: % of red in [0,1]
01397    //  g: % of green in [0,1]
01398    //  b: % of blue in [0,1]
01399 
01400    if (r <= 0. && g <= 0. && b <= 0. ) {
01401       PrintFast(7,"\"black\"");
01402    } else if (r >= 1. && g >= 1. && b >= 1. ) {
01403       PrintFast(7,"\"white\"");
01404    } else {
01405       char str[12];
01406       snprintf(str,12,"\"#%2.2x%2.2x%2.2x\"",Int_t(255.*r)
01407                                             ,Int_t(255.*g)
01408                                             ,Int_t(255.*b));
01409       PrintStr(str);
01410    }
01411 }
01412 
01413 
01414 //______________________________________________________________________________
01415 void TSVG::SetTextColor( Color_t cindex )
01416 {
01417    // Set color index for text
01418 
01419    fTextColor = cindex;
01420 }
01421 
01422 
01423 //______________________________________________________________________________
01424 void TSVG::Text(Double_t xx, Double_t yy, const char *chars)
01425 {
01426    // Draw text
01427    //
01428    // xx: x position of the text
01429    // yy: y position of the text
01430    // chars: text to be drawn
01431 
01432    static const char *fontFamily[] = {
01433    "Times"    , "Times"    , "Times",
01434    "Helvetica", "Helvetica", "Helvetica"   , "Helvetica",
01435    "Courier"  , "Courier"  , "Courier"     , "Courier",
01436    "Times"    ,"Times"     , "ZapfDingbats", "Times"};
01437 
01438    static const char *fontWeight[] = {
01439    "normal", "bold", "bold",
01440    "normal", "normal", "bold"  , "bold",
01441    "normal", "normal", "bold"  , "bold",
01442    "normal", "normal", "normal", "normal"};
01443 
01444    static const char *fontStyle[] = {
01445    "italic", "normal" , "italic",
01446    "normal", "oblique", "normal", "oblique",
01447    "normal", "oblique", "normal", "oblique",
01448    "normal", "normal" , "normal", "italic"};
01449 
01450    Int_t ix    = XtoSVG(xx);
01451    Int_t iy    = YtoSVG(yy);
01452    Int_t txalh = fTextAlign/10;
01453    if (txalh <1) txalh = 1; if (txalh > 3) txalh = 3;
01454    Int_t txalv = fTextAlign%10;
01455    if (txalv <1) txalv = 1; if (txalv > 3) txalv = 3;
01456 
01457    Double_t     wh = (Double_t)gPad->XtoPixel(gPad->GetX2());
01458    Double_t     hh = (Double_t)gPad->YtoPixel(gPad->GetY1());
01459    Float_t fontrap = 1.09; //scale down compared to X11
01460    Float_t ftsize;
01461 
01462    Int_t font  = abs(fTextFont)/10;
01463    Int_t ifont = font-1;
01464    if (font > 42 || font < 1) font = 1;
01465    if (wh < hh) {
01466       ftsize = fTextSize*fXsize*gPad->GetAbsWNDC();
01467    } else {
01468       ftsize = fTextSize*fYsize*gPad->GetAbsHNDC();
01469    }
01470 
01471    Int_t fontsize = CMtoSVG(ftsize/fontrap);
01472    if( fontsize <= 0) return;
01473 
01474    if (txalv == 3) iy = iy+fontsize;
01475    if (txalv == 2) iy = iy+(fontsize/2);
01476 
01477    if (fTextAngle != 0.) {
01478       PrintStr("@");
01479       PrintFast(21,"<g transform=\"rotate(");
01480       WriteInteger(-Int_t(fTextAngle), 0);
01481       PrintFast(1,",");
01482       WriteInteger(ix, 0);
01483       PrintFast(1,",");
01484       WriteInteger(iy, 0);
01485       PrintFast(3,")\">");
01486    }
01487 
01488    PrintStr("@");
01489    PrintFast(9,"<text x=\"");
01490    WriteInteger(ix, 0);
01491    PrintFast(5,"\" y=\"");
01492    WriteInteger(iy, 0);
01493    PrintFast(1,"\"");
01494    if (txalh == 2) {
01495       PrintFast(21," text-anchor=\"middle\"");
01496    } else if (txalh == 3) {
01497       PrintFast(18," text-anchor=\"end\"");
01498    }
01499    PrintFast(6," fill=");
01500    SetColor(Int_t(fTextColor));
01501    PrintFast(12," font-size=\"");
01502    WriteInteger(fontsize, 0);
01503    PrintFast(15,"\" font-family=\"");
01504    PrintStr(fontFamily[ifont]);
01505    if (strcmp(fontWeight[ifont],"normal")) {
01506       PrintFast(15,"\" font-weight=\"");
01507       PrintStr(fontWeight[ifont]);
01508    }
01509    if (strcmp(fontStyle[ifont],"normal")) {
01510       PrintFast(14,"\" font-style=\"");
01511       PrintStr(fontStyle[ifont]);
01512    }
01513    PrintFast(2,"\">");
01514    PrintStr("@");
01515    if (font == 12 || font == 15) {
01516       Int_t ichar = chars[0]+848;
01517       Int_t ic    = ichar;
01518 
01519       // Math Symbols
01520       if (ic == 755) ichar = 8804;
01521       if (ic == 759) ichar = 9827;
01522       if (ic == 760) ichar = 9830;
01523       if (ic == 761) ichar = 9829;
01524       if (ic == 762) ichar = 9824;
01525       if (ic == 766) ichar = 8594;
01526       if (ic == 776) ichar =  247;
01527       if (ic == 757) ichar = 8734;
01528       if (ic == 758) ichar =  402;
01529       if (ic == 771) ichar = 8805;
01530       if (ic == 774) ichar = 8706;
01531       if (ic == 775) ichar = 8226;
01532       if (ic == 779) ichar = 8776;
01533       if (ic == 805) ichar = 8719;
01534       if (ic == 821) ichar = 8721;
01535       if (ic == 834) ichar = 8747;
01536       if (ic == 769) ichar =  177;
01537 
01538       // Greek characters
01539       if (ic == 918) ichar = 934;
01540       if (ic == 919) ichar = 915;
01541       if (ic == 920) ichar = 919;
01542       if (ic == 923) ichar = 922;
01543       if (ic == 924) ichar = 923;
01544       if (ic == 925) ichar = 924;
01545       if (ic == 926) ichar = 925;
01546       if (ic == 929) ichar = 920;
01547       if (ic == 930) ichar = 929;
01548       if (ic == 936) ichar = 926;
01549       if (ic == 915) ichar = 935;
01550       if (ic == 937) ichar = 936;
01551       if (ic == 935) ichar = 937;
01552       if (ic == 938) ichar = 918;
01553       if (ic == 951) ichar = 947;
01554       if (ic == 798) ichar = 949;
01555       if (ic == 970) ichar = 950;
01556       if (ic == 952) ichar = 951;
01557       if (ic == 961) ichar = 952;
01558       if (ic == 955) ichar = 954;
01559       if (ic == 956) ichar = 955;
01560       if (ic == 957) ichar = 956;
01561       if (ic == 958) ichar = 957;
01562       if (ic == 968) ichar = 958;
01563       if (ic == 934) ichar = 962;
01564       if (ic == 962) ichar = 961;
01565       if (ic == 966) ichar = 969;
01566       if (ic == 950) ichar = 966;
01567       if (ic == 947) ichar = 967;
01568       if (ic == 969) ichar = 968;
01569       if (ic == 967) ichar = 969;
01570       if (ic == 954) ichar = 966;
01571       if (ic == 922) ichar = 952;
01572       if (ic == 753) ichar = 965;
01573       PrintStr(Form("&#%4.4d;",ichar));
01574    } else {
01575       Int_t len=strlen(chars);
01576       for (Int_t i=0; i<len;i++) {
01577          if (chars[i]!='\n') {
01578             if (chars[i]=='<') {
01579                PrintFast(4,"&lt;");
01580             } else if (chars[i]=='>') {
01581                PrintFast(4,"&gt;");
01582             } else if (chars[i]=='&') {
01583                PrintFast(5,"&amp;");
01584             } else {
01585                PrintFast(1,&chars[i]);
01586             }
01587          }
01588       }
01589    }
01590    PrintStr("@");
01591    PrintFast(7,"</text>");
01592 
01593    if (fTextAngle != 0.) {
01594       PrintStr("@");
01595       PrintFast(4,"</g>");
01596    }
01597 }
01598 
01599 
01600 //______________________________________________________________________________
01601 void TSVG::TextNDC(Double_t u, Double_t v, const char *chars)
01602 {
01603    // Write a string of characters in NDC
01604 
01605    Double_t x = gPad->GetX1() + u*(gPad->GetX2() - gPad->GetX1());
01606    Double_t y = gPad->GetY1() + v*(gPad->GetY2() - gPad->GetY1());
01607    Text(x, y, chars);
01608 }
01609 
01610 
01611 //______________________________________________________________________________
01612 Int_t TSVG::UtoSVG(Double_t u)
01613 {
01614    // Convert U from NDC coordinate to SVG
01615 
01616    Double_t cm = fXsize*(gPad->GetAbsXlowNDC() + u*gPad->GetAbsWNDC());
01617    return Int_t(0.5 + 72*cm/2.54);
01618 }
01619 
01620 
01621 //______________________________________________________________________________
01622 Int_t TSVG::VtoSVG(Double_t v)
01623 {
01624    // Convert V from NDC coordinate to SVG
01625 
01626    Double_t cm = fYsize*(gPad->GetAbsYlowNDC() + v*gPad->GetAbsHNDC());
01627    return Int_t(0.5 + 72*cm/2.54);
01628 }
01629 
01630 
01631 //______________________________________________________________________________
01632 Int_t TSVG::XtoSVG(Double_t x)
01633 {
01634    // Convert X from world coordinate to SVG
01635 
01636    Double_t u = (x - gPad->GetX1())/(gPad->GetX2() - gPad->GetX1());
01637    return  UtoSVG(u);
01638 }
01639 
01640 
01641 //______________________________________________________________________________
01642 Int_t TSVG::YtoSVG(Double_t y)
01643 {
01644    // Convert Y from world coordinate to SVG
01645 
01646    Double_t v = (y - gPad->GetY1())/(gPad->GetY2() - gPad->GetY1());
01647    return  fYsizeSVG-VtoSVG(v);
01648 }
01649 
01650 
01651 //______________________________________________________________________________
01652 void TSVG::CellArrayBegin(Int_t, Int_t, Double_t, Double_t, Double_t,
01653                           Double_t)
01654 {
01655    // Begin the Cell Array painting
01656    Warning("TSVG::CellArrayBegin", "not yet implemented");
01657 }
01658 
01659 
01660 //______________________________________________________________________________
01661 void TSVG::CellArrayFill(Int_t, Int_t, Int_t)
01662 {
01663    // Paint the Cell Array
01664    Warning("TSVG::CellArrayFill", "not yet implemented");
01665 }
01666 
01667 
01668 //______________________________________________________________________________
01669 void TSVG::CellArrayEnd()
01670 {
01671    // End the Cell Array painting
01672    Warning("TSVG::CellArrayEnd", "not yet implemented");
01673 }
01674 
01675 
01676 //______________________________________________________________________________
01677 void TSVG::DrawPS(Int_t, Float_t *, Float_t *)
01678 {
01679    // Not needed in SVG case
01680    Warning("TSVG::DrawPS", "not yet implemented");
01681 }

Generated on Tue Jul 5 14:14:31 2011 for ROOT_528-00b_version by  doxygen 1.5.1