ROOT logo
// @(#)root/gl:$Id$
// Author:  Olivier Couet, Timur Pocheptsov(vertex merge)  06/05/2009

/*************************************************************************
 * Copyright (C) 1995-2009, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include <algorithm>
#include <cassert>
#include <limits>
#include <memory>
#include <vector>

#include "TPadPainter.h"
#include "TVirtualX.h"
#include "TCanvas.h"
#include "TPoint.h"
#include "TError.h"
#include "TImage.h"
#include "TROOT.h"
#include "TMath.h"
#include "TPad.h"

namespace {

//All asserts were commented, since ROOT's build system does not
//use -DNDEBUG for gpad module (with --build=release).

typedef std::vector<TPoint>::size_type size_type;

template<typename T>
void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys,
                   std::vector<TPoint> &dst);
inline
void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
                  SCoord_t yMax, SCoord_t yLast);

inline
size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
                              SCoord_t xMax, SCoord_t xLast, size_type first);
   
template<typename T>
void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
                                std::vector<TPoint> &dst);
   
void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst);

template<class T>
void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys);

template<typename T>
void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys);

template<class T>
void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys);


}

ClassImp(TPadPainter)


//______________________________________________________________________________
TPadPainter::TPadPainter()
{
   //Empty ctor. We need it only because of explicit copy ctor.
}

/*
Line/fill/etc. attributes can be set inside TPad, but not only where:
many of them are set by base sub-objects of 2d primitives
(2d primitives usually inherit TAttLine or TAttFill etc.).  And these sub-objects
call gVirtualX->SetLineWidth ... etc. So, if I save some attributes in my painter,
it will be mess - at any moment I do not know, where to take line attribute - from
gVirtualX or from my own member. So! All attributed, _ALL_ go to/from gVirtualX.
*/


//______________________________________________________________________________
Color_t TPadPainter::GetLineColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineColor();
}


//______________________________________________________________________________
Style_t TPadPainter::GetLineStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineStyle();
}


//______________________________________________________________________________
Width_t TPadPainter::GetLineWidth() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetLineWidth();
}


//______________________________________________________________________________
void TPadPainter::SetLineColor(Color_t lcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineColor(lcolor);
}


//______________________________________________________________________________
void TPadPainter::SetLineStyle(Style_t lstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineStyle(lstyle);
}


//______________________________________________________________________________
void TPadPainter::SetLineWidth(Width_t lwidth)
{
   // Delegate to gVirtualX.

   gVirtualX->SetLineWidth(lwidth);
}


//______________________________________________________________________________
Color_t TPadPainter::GetFillColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillColor();
}


//______________________________________________________________________________
Style_t TPadPainter::GetFillStyle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetFillStyle();
}


//______________________________________________________________________________
Bool_t TPadPainter::IsTransparent() const
{
   // Delegate to gVirtualX.

   //IsTransparent is implemented as inline function in TAttFill.
   return gVirtualX->IsTransparent();
}


//______________________________________________________________________________
void TPadPainter::SetFillColor(Color_t fcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillColor(fcolor);
}


//______________________________________________________________________________
void TPadPainter::SetFillStyle(Style_t fstyle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetFillStyle(fstyle);
}


//______________________________________________________________________________
void TPadPainter::SetOpacity(Int_t percent)
{
   // Delegate to gVirtualX.

   gVirtualX->SetOpacity(percent);
}


//______________________________________________________________________________
Short_t TPadPainter::GetTextAlign() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAlign();
}


//______________________________________________________________________________
Float_t TPadPainter::GetTextAngle() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextAngle();
}


//______________________________________________________________________________
Color_t TPadPainter::GetTextColor() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextColor();
}


//______________________________________________________________________________
Font_t TPadPainter::GetTextFont() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextFont();
}


//______________________________________________________________________________
Float_t TPadPainter::GetTextSize() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextSize();
}


//______________________________________________________________________________
Float_t TPadPainter::GetTextMagnitude() const
{
   // Delegate to gVirtualX.

   return gVirtualX->GetTextMagnitude();
}


//______________________________________________________________________________
void TPadPainter::SetTextAlign(Short_t align)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAlign(align);
}


//______________________________________________________________________________
void TPadPainter::SetTextAngle(Float_t tangle)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextAngle(tangle);
}


//______________________________________________________________________________
void TPadPainter::SetTextColor(Color_t tcolor)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextColor(tcolor);
}


//______________________________________________________________________________
void TPadPainter::SetTextFont(Font_t tfont)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextFont(tfont);
}


//______________________________________________________________________________
void TPadPainter::SetTextSize(Float_t tsize)
{
   // Delegate to gVirtualX.
   
   gVirtualX->SetTextSize(tsize);
}


//______________________________________________________________________________
void TPadPainter::SetTextSizePixels(Int_t npixels)
{
   // Delegate to gVirtualX.

   gVirtualX->SetTextSizePixels(npixels);
}


//______________________________________________________________________________
Int_t TPadPainter::CreateDrawable(UInt_t w, UInt_t h)
{
   // Create a gVirtualX Pixmap.

   return gVirtualX->OpenPixmap(Int_t(w), Int_t(h));
}


//______________________________________________________________________________
void TPadPainter::ClearDrawable()
{
   // Clear the current gVirtualX window.

   gVirtualX->ClearWindow();
}


//______________________________________________________________________________
void TPadPainter::CopyDrawable(Int_t id, Int_t px, Int_t py)
{
   // Copy a gVirtualX pixmap.

   gVirtualX->CopyPixmap(id, px, py);
}


//______________________________________________________________________________
void TPadPainter::DestroyDrawable()
{
   // Close the current gVirtualX pixmap.

   gVirtualX->ClosePixmap();
}


//______________________________________________________________________________
void TPadPainter::SelectDrawable(Int_t device)
{
   // Select the window in which the graphics will go.

   gVirtualX->SelectWindow(device);
}

//______________________________________________________________________________
void TPadPainter::DrawPixels(const unsigned char * /*pixelData*/, UInt_t /*width*/, UInt_t /*height*/,
                             Int_t /*dstX*/, Int_t /*dstY*/, Bool_t /*enableAlphaBlending*/)
{
   //Noop, for non-gl pad TASImage calls gVirtualX->CopyArea.
}


//______________________________________________________________________________
void TPadPainter::DrawLine(Double_t x1, Double_t y1, Double_t x2, Double_t y2)
{
   // Paint a simple line.

   const Int_t px1 = gPad->XtoPixel(x1);
   const Int_t px2 = gPad->XtoPixel(x2);
   const Int_t py1 = gPad->YtoPixel(y1);
   const Int_t py2 = gPad->YtoPixel(y2);
   gVirtualX->DrawLine(px1, py1, px2, py2);
}


//______________________________________________________________________________
void TPadPainter::DrawLineNDC(Double_t u1, Double_t v1, Double_t u2, Double_t v2)
{
   // Paint a simple line in normalized coordinates.

   const Int_t px1 = gPad->UtoPixel(u1);
   const Int_t py1 = gPad->VtoPixel(v1);
   const Int_t px2 = gPad->UtoPixel(u2);
   const Int_t py2 = gPad->VtoPixel(v2);
   gVirtualX->DrawLine(px1, py1, px2, py2);
}


//______________________________________________________________________________
void TPadPainter::DrawBox(Double_t x1, Double_t y1, Double_t x2, Double_t y2, EBoxMode mode)
{
   // Paint a simple box.

   Int_t px1 = gPad->XtoPixel(x1);
   Int_t px2 = gPad->XtoPixel(x2);
   Int_t py1 = gPad->YtoPixel(y1);
   Int_t py2 = gPad->YtoPixel(y2);

   // Box width must be at least one pixel (WTF is this code???)
   if (TMath::Abs(px2 - px1) < 1)
      px2 = px1 + 1;
   if (TMath::Abs(py1 - py2) < 1)
      py1 = py2 + 1;

   gVirtualX->DrawBox(px1, py1, px2, py2, (TVirtualX::EBoxMode)mode);
}

//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t nPoints, const Double_t *xs, const Double_t *ys)
{
   //Paint filled area.
   if (nPoints < 3) {
      ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
      return;
   }
   
   //assert(xs != 0 && "DrawFillArea, parameter 'xs' is null");
   //assert(ys != 0 && "DrawFillArea, parameter 'ys' is null");
   
   DrawFillAreaAux(gPad, nPoints, xs, ys);
}


//______________________________________________________________________________
void TPadPainter::DrawFillArea(Int_t nPoints, const Float_t *xs, const Float_t *ys)
{
   //Paint filled area.
   if (nPoints < 3) {
      ::Error("TPadPainter::DrawFillArea", "invalid number of points %d", nPoints);
      return;
   }
   
   //assert(xs != 0 && "DrawFillArea, parameter 'xs' is null");
   //assert(ys != 0 && "DrawFillArea, parameter 'ys' is null");
   
   DrawFillAreaAux(gPad, nPoints, xs, ys);
}

//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Double_t *xs, const Double_t *ys)
{
   if (n < 2) {
      ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
      return;
   }

   //assert(xs != 0 && "DrawPolyLine, parameter 'xs' is null");
   //assert(ys != 0 && "DrawPolyLine, parameter 'ys' is null");

   DrawPolyLineAux(gPad, n, xs, ys);
}


//______________________________________________________________________________
void TPadPainter::DrawPolyLine(Int_t n, const Float_t *xs, const Float_t *ys)
{
   //Paint polyline.
   if (n < 2) {
      ::Error("TPadPainter::DrawPolyLine", "invalid number of points");
      return;
   }
   
   //assert(xs != 0 && "DrawPolyLine, parameter 'xs' is null");
   //assert(ys != 0 && "DrawPolyLine, parameter 'ys' is null");
   
   DrawPolyLineAux(gPad, n, xs, ys);
}


//______________________________________________________________________________
void TPadPainter::DrawPolyLineNDC(Int_t n, const Double_t *u, const Double_t *v)
{
   //Paint polyline in normalized coordinates.
   if (n < 2) {
      ::Error("TPadPainter::DrawPolyLineNDC", "invalid number of points %d", n);
      return;
   }

   //assert(u != 0 && "DrawPolyLineNDC, parameter 'u' is null");
   //assert(v != 0 && "DrawPolyLineNDC, parameter 'v' is null");

   std::vector<TPoint> xy(n);

   for (Int_t i = 0; i < n; ++i) {
      xy[i].fX = (SCoord_t)gPad->UtoPixel(u[i]);
      xy[i].fY = (SCoord_t)gPad->VtoPixel(v[i]);
   }

   gVirtualX->DrawPolyLine(n, &xy[0]);
}


//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Double_t *x, const Double_t *y)
{
   //Paint polymarker.
   if (n < 1) {
      ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
      return;
   }
   
   DrawPolyMarkerAux(gPad, n, x, y);
}


//______________________________________________________________________________
void TPadPainter::DrawPolyMarker(Int_t n, const Float_t *x, const Float_t *y)
{
   //Paint polymarker.   
   if (n < 1) {
      ::Error("TPadPainter::DrawPolyMarker", "invalid number of points %d", n);
      return;
   }
   
   DrawPolyMarkerAux(gPad, n, x, y);
}


//______________________________________________________________________________
void TPadPainter::DrawText(Double_t x, Double_t y, const char *text, ETextMode mode)
{
   //Paint text.
   const Int_t px = gPad->XtoPixel(x);
   const Int_t py = gPad->YtoPixel(y);
   const Double_t angle = GetTextAngle();
   const Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}


//______________________________________________________________________________
void TPadPainter::DrawText(Double_t x, Double_t y, const wchar_t *text, ETextMode mode)
{
   //That's a special version working with wchar_t and required by TMathText (who uses utf-8(?))
   const Int_t px = gPad->XtoPixel(x);
   const Int_t py = gPad->YtoPixel(y);
   const Double_t angle = GetTextAngle();
   const Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}


//______________________________________________________________________________
void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const char *text, ETextMode mode)
{
   // Paint text in normalized coordinates.
   const Int_t px = gPad->UtoPixel(u);
   const Int_t py = gPad->VtoPixel(v);
   const Double_t angle = GetTextAngle();
   const Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}


//______________________________________________________________________________
void TPadPainter::SaveImage(TVirtualPad *pad, const char *fileName, Int_t type) const
{
   // Save the image displayed in the canvas pointed by "pad" into a 
   // binary file.
   //assert(pad != 0 && "SaveImage, parameter 'pad' is null");
   //assert(fileName != 0 && "SaveImage, parameter 'fileName' is null");
   
   // Save the image displayed in the canvas pointed by "pad" into a
   // binary file.
   if (gVirtualX->InheritsFrom("TGCocoa") && !gROOT->IsBatch() &&
      pad->GetCanvas() && pad->GetCanvas()->GetCanvasID() != -1) {
      //
      TCanvas * const canvas = pad->GetCanvas();
      //Copy pixmaps etc.
      canvas->Flush();
      //
      const UInt_t w = canvas->GetWw();
      const UInt_t h = canvas->GetWh();
      //
      const unsigned char * const pixelData =
                                  gVirtualX->GetColorBits(canvas->GetCanvasID(), 0, 0, w, h);
      //
      if (pixelData) {
         const std::auto_ptr<TImage> image(TImage::Create());
         if (image.get()) {
            image->DrawRectangle(0, 0, w, h);
            if (unsigned char *argb = (unsigned char *)image->GetArgbArray()) {
               //Ohhh.
               if (sizeof(UInt_t) == 4) {
                  //I know for sure the data returned from TGCocoa::GetColorBits,
                  //it's 4 * w * h bytes with what TASImage considers to be argb.
                  std::copy(pixelData, pixelData + 4 * w * h, argb);
               } else {
                  //A bit paranoid, don't you think so?
                  //Will Quartz/TASImage work at all on such a fancy platform? ;)
                  const unsigned shift = std::numeric_limits<unsigned char>::digits;
                  //
                  unsigned *dstPixel = (unsigned *)argb, *end = dstPixel + w * h;
                  const unsigned char *srcPixel = pixelData;
                  for (;dstPixel != end; ++dstPixel, srcPixel += 4) {
                     //Looks fishy but should work, trust me :)
                     *dstPixel = srcPixel[0] & (srcPixel[1] << shift) &
                                               (srcPixel[2] << 2 * shift) &
                                               (srcPixel[3] << 3 * shift);
                  }
               }
               image->WriteImage(fileName, (TImage::EImageFileTypes)type);
               //
               delete [] pixelData;
               return;
            }
         }
         //
         delete [] pixelData;
      }
   }
 
   if (type == TImage::kGif) {
      gVirtualX->WriteGIF((char*)fileName);
   } else {
      const std::auto_ptr<TImage> img(TImage::Create());
      if (img.get()) {
         img->FromPad(pad);
         img->WriteImage(fileName, (TImage::EImageFileTypes)type);
      }
   }
}


//______________________________________________________________________________
void TPadPainter::DrawTextNDC(Double_t u, Double_t v, const wchar_t *text, ETextMode mode)
{
   // Paint text in normalized coordinates.

   const Int_t px = gPad->UtoPixel(u);
   const Int_t py = gPad->VtoPixel(v);
   const Double_t angle = GetTextAngle();
   const Double_t mgn = GetTextMagnitude();
   gVirtualX->DrawText(px, py, angle, mgn, text, (TVirtualX::ETextMode)mode);
}

//Aux. private functions.
namespace {

//______________________________________________________________________________
template<typename T>
void ConvertPoints(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
                   std::vector<TPoint> &dst)
{
   //I'm using 'pad' pointer to get rid of this damned gPad.
   //Unfortunately, TPadPainter itself still has to use it.
   //But at least this code does not have to be fixed.

   if (!nPoints)
      return;

   //assert(pad != 0 && "ConvertPoints, parameter 'pad' is null");
   //assert(x != 0 && "ConvertPoints, parameter 'x' is null");
   //assert(y != 0 && "ConvertPoints, parameter 'y' is null");

   dst.resize(nPoints);
   
   for (unsigned i = 0; i < nPoints; ++i) {
      dst[i].fX = (SCoord_t)pad->XtoPixel(x[i]);
      dst[i].fY = (SCoord_t)pad->YtoPixel(y[i]);
   }
}

//______________________________________________________________________________
inline void MergePointsX(std::vector<TPoint> &points, unsigned nMerged, SCoord_t yMin,
                         SCoord_t yMax, SCoord_t yLast)
{
   //assert(points.size() != 0 &&
   //         "MergePointsX, parameter 'points' is an empty vector, should contain at least 1 point already");
   //assert(nMerged > 1 && "MergePointsX, nothing to merge");
   
   const SCoord_t firstPointX = points.back().fX;
   const SCoord_t firstPointY = points.back().fY;
   
   if (nMerged == 2) {
      points.push_back(TPoint(firstPointX, yLast));//We have not merge anything.
   } else if (nMerged == 3) {
      yMin == firstPointY ? points.push_back(TPoint(firstPointX, yMax)) :
                            points.push_back(TPoint(firstPointX, yMin));
      points.push_back(TPoint(firstPointX, yLast));
   } else {
      points.push_back(TPoint(firstPointX, yMin));
      points.push_back(TPoint(firstPointX, yMax));
      points.push_back(TPoint(firstPointX, yLast));
   }
}

//______________________________________________________________________________
inline size_type MergePointsInplaceY(std::vector<TPoint> &dst, size_type nMerged, SCoord_t xMin,
                                     SCoord_t xMax, SCoord_t xLast, size_type first)
{
   //assert(nMerged > 1 && "MergePointsInplaceY, nothing to merge");
   //assert(first < dst.size() && "MergePointsInplaceY, parameter 'first' is out of range");
   //assert(dst.size() - first >= nMerged && "MergePointsInplaceY, invalid index 'first + nMerged'");
   
   //Indices below are _valid_ - see asserts above.
   
   const TPoint &firstPoint = dst[first];//This point is never updated.
   
   if (nMerged == 2) {
      dst[first + 1].fX = xLast;
      dst[first + 1].fY = firstPoint.fY;
   } else if (nMerged == 3) {
      dst[first + 1].fX = xMin == firstPoint.fX ? xMax : xMin;
      dst[first + 1].fY = firstPoint.fY;
      dst[first + 2].fX = xLast;
      dst[first + 2].fY = firstPoint.fY;
   } else {
      dst[first + 1].fX = xMin;
      dst[first + 1].fY = firstPoint.fY;
      dst[first + 2].fX = xMax;
      dst[first + 2].fY = firstPoint.fY;
      dst[first + 3].fX = xLast;
      dst[first + 3].fY = firstPoint.fY;
      nMerged = 4;//Adjust the shift.
   }
   
   return nMerged;
}

//______________________________________________________________________________
template<typename T>
void ConvertPointsAndMergePassX(TVirtualPad *pad, unsigned nPoints, const T *x, const T *y,
                                std::vector<TPoint> &dst)
{
   //I'm using 'pad' pointer to get rid of this damned gPad.
   //Unfortunately, TPadPainter itself still has to use it.
   //But at least this code does not have to be fixed.

   //assert(pad != 0 && "ConvertPointsAndMergePassX, parameter 'pad' is null");
   //assert(x != 0 && "ConvertPointsAndMergePassX, parameter 'x' is null");
   //assert(y != 0 && "ConvertPointsAndMergePassX, parameter 'y' is null");

   //The "first" pass along X axis.
   TPoint currentPoint;
   SCoord_t yMin = 0, yMax = 0, yLast = 0;
   unsigned nMerged = 0;
   
   //The first pass along X.
   for (unsigned i = 0; i < nPoints;) {
      currentPoint.fX = (SCoord_t)pad->XtoPixel(x[i]);
      currentPoint.fY = (SCoord_t)pad->YtoPixel(y[i]);
      
      yMin = currentPoint.fY;
      yMax = yMin;

      dst.push_back(currentPoint);
      bool merged = false;
      nMerged = 1;
      
      for (unsigned j = i + 1; j < nPoints; ++j) {
         const SCoord_t newX = pad->XtoPixel(x[j]);

         if (newX == currentPoint.fX) {
            yLast = pad->YtoPixel(y[j]);
            yMin = TMath::Min(yMin, yLast);
            yMax = TMath::Max(yMax, yLast);//We continue.
            ++nMerged;
         } else {
            if (nMerged > 1)
               MergePointsX(dst, nMerged, yMin, yMax, yLast);
            merged = true;
            break;
         }
      }
      
      if (!merged && nMerged > 1)
         MergePointsX(dst, nMerged, yMin, yMax, yLast);
      
      i += nMerged;
   }
}

//______________________________________________________________________________
void ConvertPointsAndMergeInplacePassY(std::vector<TPoint> &dst)
{
   //assert(dst.size() != 0 && "ConvertPointsAndMergeInplacePassY, nothing to merge");

   //This pass is a bit more complicated, since we have
   //to 'compact' in-place.

   size_type i = 0;
   for (size_type j = 1, nPoints = dst.size(); i < nPoints;) {
      //i is always less than j, so i is always valid here.
      const TPoint &currentPoint = dst[i];
      
      SCoord_t xMin = currentPoint.fX;
      SCoord_t xMax = xMin;
      SCoord_t xLast = 0;
      
      bool merged = false;
      size_type nMerged = 1;
      
      for (; j < nPoints; ++j) {
         const TPoint &nextPoint = dst[j];
         
         if (nextPoint.fY == currentPoint.fY) {
            xLast = nextPoint.fX;
            xMin = TMath::Min(xMin, xLast);
            xMax = TMath::Max(xMax, xLast);
            ++nMerged;//and we continue ...
         } else {
            if (nMerged > 1)
               nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
            merged = true;
            break;
         }
      }
      
      if (!merged && nMerged > 1)
         nMerged = MergePointsInplaceY(dst, nMerged, xMin, xMax, xLast, i);
      
      i += nMerged;
      
      if (j < nPoints) {
         dst[i] = dst[j];
         ++j;
      } else
        break;
   }

   dst.resize(i);
}

//______________________________________________________________________________
template<typename T>
void ConvertPointsAndMerge(TVirtualPad *pad, unsigned threshold, unsigned nPoints, const T *x,
                           const T *y, std::vector<TPoint> &dst)
{
   //This is a quite simple algorithm, using the fact, that after conversion many subsequent vertices
   //can have the same 'x' or 'y' coordinate and this part of a polygon will look like a line
   //on the screen.
   //Please NOTE: even if there are some problems (like invalid polygons), the algorithm can be
   //fixed (I'm not sure at the moment if it's important) and remembering the order
   //of yMin/yMax or xMin/xMax (see aux. functions above) -
   //this should help if there's any problems.

   //I'm using 'pad' pointer to get rid of this damned gPad.
   //Unfortunately, TPadPainter itself still has to use it.
   //But at least this code does not have to be fixed.

   if (!nPoints)
      return;

   //assert(pad != 0 && "ConvertPointsAndMerge, parameter 'pad' is null");
   //assert(threshold != 0 && "ConvertPointsAndMerge, parameter 'threshold' must be > 0");
   //assert(x != 0 && "ConvertPointsAndMerge, parameter 'x' is null");
   //assert(y != 0 && "ConvertPointsAndMerge, parameter 'y' is null");

   dst.clear();
   dst.reserve(threshold);

   ConvertPointsAndMergePassX(pad, nPoints, x, y, dst);
   
   if (dst.size() < threshold)
      return;

   ConvertPointsAndMergeInplacePassY(dst);
}

//______________________________________________________________________________
template<class T>
void DrawFillAreaAux(TVirtualPad *pad, Int_t nPoints, const T *xs, const T *ys)
{
   //assert(pad != 0 && "DrawFillAreaAux, parameter 'pad' is null");
   //assert(nPoints > 2 && "DrawFillAreaAux, invalid number of points");
   //assert(xs != 0 && "DrawFillAreaAux, parameter 'xs' is null");
   //assert(ys != 0 && "DrawFillAreaAux, parameter 'ys' is null");
   
   std::vector<TPoint> xy;
   
   const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
                                 pad->GetWh() * pad->GetAbsHNDC())) * 2;

   if (threshold <= 0) {
      //Ooops, pad is invisible or something really bad and stupid happened.
      ::Error("DrawFillAreaAux", "invalid pad's geometry");
      return;
   }

   if (nPoints < threshold)
      ConvertPoints(gPad, nPoints, xs, ys, xy);
   else
      ConvertPointsAndMerge(gPad, threshold, nPoints, xs, ys, xy);

   //We close the 'polygon' and it'll be rendered as a polyline by gVirtualX.
   if (!gVirtualX->GetFillStyle())
      xy.push_back(xy.front());
   
   if (xy.size() > 2)
      gVirtualX->DrawFillArea(xy.size(), &xy[0]);
}

//______________________________________________________________________________
template<typename T>
void DrawPolyLineAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
{
   //assert(pad != 0 && "DrawPolyLineAux, parameter 'pad' is null");
   //assert(nPoints > 1 && "DrawPolyLineAux, invalid number of points");
   //assert(xs != 0 && "DrawPolyLineAux, parameter 'xs' is null");
   //assert(ys != 0 && "DrawPolyLineAux, parameter 'ys' is null");
   
   std::vector<TPoint> xy;

   const Int_t threshold = Int_t(TMath::Min(pad->GetWw() * pad->GetAbsWNDC(),
                                            pad->GetWh() * pad->GetAbsHNDC())) * 2;

   if (threshold <= 0) {//Ooops, pad is invisible or something really bad and stupid happened.
      ::Error("DrawPolyLineAux", "invalid pad's geometry");
      return;
   }

   if (nPoints < (unsigned)threshold)
      ConvertPoints(pad, nPoints, xs, ys, xy);
   else
      ConvertPointsAndMerge(pad, threshold, nPoints, xs, ys, xy);

   if (xy.size() > 1)
      gVirtualX->DrawPolyLine(xy.size(), &xy[0]);
   
}

//______________________________________________________________________________
template<class T>
void DrawPolyMarkerAux(TVirtualPad *pad, unsigned nPoints, const T *xs, const T *ys)
{
   //assert(pad != 0 && "DrawPolyMarkerAux, parameter 'pad' is null");
   //assert(nPoints != 0 && "DrawPolyMarkerAux, invalid number of points");
   //assert(xs != 0 && "DrawPolyMarkerAux, parameter 'xs' is null");
   //assert(ys != 0 && "DrawPolyMarkerAux, parameter 'ys' is null");

   std::vector<TPoint> xy(nPoints);

   for (unsigned i = 0; i < nPoints; ++i) {
      xy[i].fX = (SCoord_t)pad->XtoPixel(xs[i]);
      xy[i].fY = (SCoord_t)pad->YtoPixel(ys[i]);
   }

   gVirtualX->DrawPolyMarker(nPoints, &xy[0]);
}

}
 TPadPainter.cxx:1
 TPadPainter.cxx:2
 TPadPainter.cxx:3
 TPadPainter.cxx:4
 TPadPainter.cxx:5
 TPadPainter.cxx:6
 TPadPainter.cxx:7
 TPadPainter.cxx:8
 TPadPainter.cxx:9
 TPadPainter.cxx:10
 TPadPainter.cxx:11
 TPadPainter.cxx:12
 TPadPainter.cxx:13
 TPadPainter.cxx:14
 TPadPainter.cxx:15
 TPadPainter.cxx:16
 TPadPainter.cxx:17
 TPadPainter.cxx:18
 TPadPainter.cxx:19
 TPadPainter.cxx:20
 TPadPainter.cxx:21
 TPadPainter.cxx:22
 TPadPainter.cxx:23
 TPadPainter.cxx:24
 TPadPainter.cxx:25
 TPadPainter.cxx:26
 TPadPainter.cxx:27
 TPadPainter.cxx:28
 TPadPainter.cxx:29
 TPadPainter.cxx:30
 TPadPainter.cxx:31
 TPadPainter.cxx:32
 TPadPainter.cxx:33
 TPadPainter.cxx:34
 TPadPainter.cxx:35
 TPadPainter.cxx:36
 TPadPainter.cxx:37
 TPadPainter.cxx:38
 TPadPainter.cxx:39
 TPadPainter.cxx:40
 TPadPainter.cxx:41
 TPadPainter.cxx:42
 TPadPainter.cxx:43
 TPadPainter.cxx:44
 TPadPainter.cxx:45
 TPadPainter.cxx:46
 TPadPainter.cxx:47
 TPadPainter.cxx:48
 TPadPainter.cxx:49
 TPadPainter.cxx:50
 TPadPainter.cxx:51
 TPadPainter.cxx:52
 TPadPainter.cxx:53
 TPadPainter.cxx:54
 TPadPainter.cxx:55
 TPadPainter.cxx:56
 TPadPainter.cxx:57
 TPadPainter.cxx:58
 TPadPainter.cxx:59
 TPadPainter.cxx:60
 TPadPainter.cxx:61
 TPadPainter.cxx:62
 TPadPainter.cxx:63
 TPadPainter.cxx:64
 TPadPainter.cxx:65
 TPadPainter.cxx:66
 TPadPainter.cxx:67
 TPadPainter.cxx:68
 TPadPainter.cxx:69
 TPadPainter.cxx:70
 TPadPainter.cxx:71
 TPadPainter.cxx:72
 TPadPainter.cxx:73
 TPadPainter.cxx:74
 TPadPainter.cxx:75
 TPadPainter.cxx:76
 TPadPainter.cxx:77
 TPadPainter.cxx:78
 TPadPainter.cxx:79
 TPadPainter.cxx:80
 TPadPainter.cxx:81
 TPadPainter.cxx:82
 TPadPainter.cxx:83
 TPadPainter.cxx:84
 TPadPainter.cxx:85
 TPadPainter.cxx:86
 TPadPainter.cxx:87
 TPadPainter.cxx:88
 TPadPainter.cxx:89
 TPadPainter.cxx:90
 TPadPainter.cxx:91
 TPadPainter.cxx:92
 TPadPainter.cxx:93
 TPadPainter.cxx:94
 TPadPainter.cxx:95
 TPadPainter.cxx:96
 TPadPainter.cxx:97
 TPadPainter.cxx:98
 TPadPainter.cxx:99
 TPadPainter.cxx:100
 TPadPainter.cxx:101
 TPadPainter.cxx:102
 TPadPainter.cxx:103
 TPadPainter.cxx:104
 TPadPainter.cxx:105
 TPadPainter.cxx:106
 TPadPainter.cxx:107
 TPadPainter.cxx:108
 TPadPainter.cxx:109
 TPadPainter.cxx:110
 TPadPainter.cxx:111
 TPadPainter.cxx:112
 TPadPainter.cxx:113
 TPadPainter.cxx:114
 TPadPainter.cxx:115
 TPadPainter.cxx:116
 TPadPainter.cxx:117
 TPadPainter.cxx:118
 TPadPainter.cxx:119
 TPadPainter.cxx:120
 TPadPainter.cxx:121
 TPadPainter.cxx:122
 TPadPainter.cxx:123
 TPadPainter.cxx:124
 TPadPainter.cxx:125
 TPadPainter.cxx:126
 TPadPainter.cxx:127
 TPadPainter.cxx:128
 TPadPainter.cxx:129
 TPadPainter.cxx:130
 TPadPainter.cxx:131
 TPadPainter.cxx:132
 TPadPainter.cxx:133
 TPadPainter.cxx:134
 TPadPainter.cxx:135
 TPadPainter.cxx:136
 TPadPainter.cxx:137
 TPadPainter.cxx:138
 TPadPainter.cxx:139
 TPadPainter.cxx:140
 TPadPainter.cxx:141
 TPadPainter.cxx:142
 TPadPainter.cxx:143
 TPadPainter.cxx:144
 TPadPainter.cxx:145
 TPadPainter.cxx:146
 TPadPainter.cxx:147
 TPadPainter.cxx:148
 TPadPainter.cxx:149
 TPadPainter.cxx:150
 TPadPainter.cxx:151
 TPadPainter.cxx:152
 TPadPainter.cxx:153
 TPadPainter.cxx:154
 TPadPainter.cxx:155
 TPadPainter.cxx:156
 TPadPainter.cxx:157
 TPadPainter.cxx:158
 TPadPainter.cxx:159
 TPadPainter.cxx:160
 TPadPainter.cxx:161
 TPadPainter.cxx:162
 TPadPainter.cxx:163
 TPadPainter.cxx:164
 TPadPainter.cxx:165
 TPadPainter.cxx:166
 TPadPainter.cxx:167
 TPadPainter.cxx:168
 TPadPainter.cxx:169
 TPadPainter.cxx:170
 TPadPainter.cxx:171
 TPadPainter.cxx:172
 TPadPainter.cxx:173
 TPadPainter.cxx:174
 TPadPainter.cxx:175
 TPadPainter.cxx:176
 TPadPainter.cxx:177
 TPadPainter.cxx:178
 TPadPainter.cxx:179
 TPadPainter.cxx:180
 TPadPainter.cxx:181
 TPadPainter.cxx:182
 TPadPainter.cxx:183
 TPadPainter.cxx:184
 TPadPainter.cxx:185
 TPadPainter.cxx:186
 TPadPainter.cxx:187
 TPadPainter.cxx:188
 TPadPainter.cxx:189
 TPadPainter.cxx:190
 TPadPainter.cxx:191
 TPadPainter.cxx:192
 TPadPainter.cxx:193
 TPadPainter.cxx:194
 TPadPainter.cxx:195
 TPadPainter.cxx:196
 TPadPainter.cxx:197
 TPadPainter.cxx:198
 TPadPainter.cxx:199
 TPadPainter.cxx:200
 TPadPainter.cxx:201
 TPadPainter.cxx:202
 TPadPainter.cxx:203
 TPadPainter.cxx:204
 TPadPainter.cxx:205
 TPadPainter.cxx:206
 TPadPainter.cxx:207
 TPadPainter.cxx:208
 TPadPainter.cxx:209
 TPadPainter.cxx:210
 TPadPainter.cxx:211
 TPadPainter.cxx:212
 TPadPainter.cxx:213
 TPadPainter.cxx:214
 TPadPainter.cxx:215
 TPadPainter.cxx:216
 TPadPainter.cxx:217
 TPadPainter.cxx:218
 TPadPainter.cxx:219
 TPadPainter.cxx:220
 TPadPainter.cxx:221
 TPadPainter.cxx:222
 TPadPainter.cxx:223
 TPadPainter.cxx:224
 TPadPainter.cxx:225
 TPadPainter.cxx:226
 TPadPainter.cxx:227
 TPadPainter.cxx:228
 TPadPainter.cxx:229
 TPadPainter.cxx:230
 TPadPainter.cxx:231
 TPadPainter.cxx:232
 TPadPainter.cxx:233
 TPadPainter.cxx:234
 TPadPainter.cxx:235
 TPadPainter.cxx:236
 TPadPainter.cxx:237
 TPadPainter.cxx:238
 TPadPainter.cxx:239
 TPadPainter.cxx:240
 TPadPainter.cxx:241
 TPadPainter.cxx:242
 TPadPainter.cxx:243
 TPadPainter.cxx:244
 TPadPainter.cxx:245
 TPadPainter.cxx:246
 TPadPainter.cxx:247
 TPadPainter.cxx:248
 TPadPainter.cxx:249
 TPadPainter.cxx:250
 TPadPainter.cxx:251
 TPadPainter.cxx:252
 TPadPainter.cxx:253
 TPadPainter.cxx:254
 TPadPainter.cxx:255
 TPadPainter.cxx:256
 TPadPainter.cxx:257
 TPadPainter.cxx:258
 TPadPainter.cxx:259
 TPadPainter.cxx:260
 TPadPainter.cxx:261
 TPadPainter.cxx:262
 TPadPainter.cxx:263
 TPadPainter.cxx:264
 TPadPainter.cxx:265
 TPadPainter.cxx:266
 TPadPainter.cxx:267
 TPadPainter.cxx:268
 TPadPainter.cxx:269
 TPadPainter.cxx:270
 TPadPainter.cxx:271
 TPadPainter.cxx:272
 TPadPainter.cxx:273
 TPadPainter.cxx:274
 TPadPainter.cxx:275
 TPadPainter.cxx:276
 TPadPainter.cxx:277
 TPadPainter.cxx:278
 TPadPainter.cxx:279
 TPadPainter.cxx:280
 TPadPainter.cxx:281
 TPadPainter.cxx:282
 TPadPainter.cxx:283
 TPadPainter.cxx:284
 TPadPainter.cxx:285
 TPadPainter.cxx:286
 TPadPainter.cxx:287
 TPadPainter.cxx:288
 TPadPainter.cxx:289
 TPadPainter.cxx:290
 TPadPainter.cxx:291
 TPadPainter.cxx:292
 TPadPainter.cxx:293
 TPadPainter.cxx:294
 TPadPainter.cxx:295
 TPadPainter.cxx:296
 TPadPainter.cxx:297
 TPadPainter.cxx:298
 TPadPainter.cxx:299
 TPadPainter.cxx:300
 TPadPainter.cxx:301
 TPadPainter.cxx:302
 TPadPainter.cxx:303
 TPadPainter.cxx:304
 TPadPainter.cxx:305
 TPadPainter.cxx:306
 TPadPainter.cxx:307
 TPadPainter.cxx:308
 TPadPainter.cxx:309
 TPadPainter.cxx:310
 TPadPainter.cxx:311
 TPadPainter.cxx:312
 TPadPainter.cxx:313
 TPadPainter.cxx:314
 TPadPainter.cxx:315
 TPadPainter.cxx:316
 TPadPainter.cxx:317
 TPadPainter.cxx:318
 TPadPainter.cxx:319
 TPadPainter.cxx:320
 TPadPainter.cxx:321
 TPadPainter.cxx:322
 TPadPainter.cxx:323
 TPadPainter.cxx:324
 TPadPainter.cxx:325
 TPadPainter.cxx:326
 TPadPainter.cxx:327
 TPadPainter.cxx:328
 TPadPainter.cxx:329
 TPadPainter.cxx:330
 TPadPainter.cxx:331
 TPadPainter.cxx:332
 TPadPainter.cxx:333
 TPadPainter.cxx:334
 TPadPainter.cxx:335
 TPadPainter.cxx:336
 TPadPainter.cxx:337
 TPadPainter.cxx:338
 TPadPainter.cxx:339
 TPadPainter.cxx:340
 TPadPainter.cxx:341
 TPadPainter.cxx:342
 TPadPainter.cxx:343
 TPadPainter.cxx:344
 TPadPainter.cxx:345
 TPadPainter.cxx:346
 TPadPainter.cxx:347
 TPadPainter.cxx:348
 TPadPainter.cxx:349
 TPadPainter.cxx:350
 TPadPainter.cxx:351
 TPadPainter.cxx:352
 TPadPainter.cxx:353
 TPadPainter.cxx:354
 TPadPainter.cxx:355
 TPadPainter.cxx:356
 TPadPainter.cxx:357
 TPadPainter.cxx:358
 TPadPainter.cxx:359
 TPadPainter.cxx:360
 TPadPainter.cxx:361
 TPadPainter.cxx:362
 TPadPainter.cxx:363
 TPadPainter.cxx:364
 TPadPainter.cxx:365
 TPadPainter.cxx:366
 TPadPainter.cxx:367
 TPadPainter.cxx:368
 TPadPainter.cxx:369
 TPadPainter.cxx:370
 TPadPainter.cxx:371
 TPadPainter.cxx:372
 TPadPainter.cxx:373
 TPadPainter.cxx:374
 TPadPainter.cxx:375
 TPadPainter.cxx:376
 TPadPainter.cxx:377
 TPadPainter.cxx:378
 TPadPainter.cxx:379
 TPadPainter.cxx:380
 TPadPainter.cxx:381
 TPadPainter.cxx:382
 TPadPainter.cxx:383
 TPadPainter.cxx:384
 TPadPainter.cxx:385
 TPadPainter.cxx:386
 TPadPainter.cxx:387
 TPadPainter.cxx:388
 TPadPainter.cxx:389
 TPadPainter.cxx:390
 TPadPainter.cxx:391
 TPadPainter.cxx:392
 TPadPainter.cxx:393
 TPadPainter.cxx:394
 TPadPainter.cxx:395
 TPadPainter.cxx:396
 TPadPainter.cxx:397
 TPadPainter.cxx:398
 TPadPainter.cxx:399
 TPadPainter.cxx:400
 TPadPainter.cxx:401
 TPadPainter.cxx:402
 TPadPainter.cxx:403
 TPadPainter.cxx:404
 TPadPainter.cxx:405
 TPadPainter.cxx:406
 TPadPainter.cxx:407
 TPadPainter.cxx:408
 TPadPainter.cxx:409
 TPadPainter.cxx:410
 TPadPainter.cxx:411
 TPadPainter.cxx:412
 TPadPainter.cxx:413
 TPadPainter.cxx:414
 TPadPainter.cxx:415
 TPadPainter.cxx:416
 TPadPainter.cxx:417
 TPadPainter.cxx:418
 TPadPainter.cxx:419
 TPadPainter.cxx:420
 TPadPainter.cxx:421
 TPadPainter.cxx:422
 TPadPainter.cxx:423
 TPadPainter.cxx:424
 TPadPainter.cxx:425
 TPadPainter.cxx:426
 TPadPainter.cxx:427
 TPadPainter.cxx:428
 TPadPainter.cxx:429
 TPadPainter.cxx:430
 TPadPainter.cxx:431
 TPadPainter.cxx:432
 TPadPainter.cxx:433
 TPadPainter.cxx:434
 TPadPainter.cxx:435
 TPadPainter.cxx:436
 TPadPainter.cxx:437
 TPadPainter.cxx:438
 TPadPainter.cxx:439
 TPadPainter.cxx:440
 TPadPainter.cxx:441
 TPadPainter.cxx:442
 TPadPainter.cxx:443
 TPadPainter.cxx:444
 TPadPainter.cxx:445
 TPadPainter.cxx:446
 TPadPainter.cxx:447
 TPadPainter.cxx:448
 TPadPainter.cxx:449
 TPadPainter.cxx:450
 TPadPainter.cxx:451
 TPadPainter.cxx:452
 TPadPainter.cxx:453
 TPadPainter.cxx:454
 TPadPainter.cxx:455
 TPadPainter.cxx:456
 TPadPainter.cxx:457
 TPadPainter.cxx:458
 TPadPainter.cxx:459
 TPadPainter.cxx:460
 TPadPainter.cxx:461
 TPadPainter.cxx:462
 TPadPainter.cxx:463
 TPadPainter.cxx:464
 TPadPainter.cxx:465
 TPadPainter.cxx:466
 TPadPainter.cxx:467
 TPadPainter.cxx:468
 TPadPainter.cxx:469
 TPadPainter.cxx:470
 TPadPainter.cxx:471
 TPadPainter.cxx:472
 TPadPainter.cxx:473
 TPadPainter.cxx:474
 TPadPainter.cxx:475
 TPadPainter.cxx:476
 TPadPainter.cxx:477
 TPadPainter.cxx:478
 TPadPainter.cxx:479
 TPadPainter.cxx:480
 TPadPainter.cxx:481
 TPadPainter.cxx:482
 TPadPainter.cxx:483
 TPadPainter.cxx:484
 TPadPainter.cxx:485
 TPadPainter.cxx:486
 TPadPainter.cxx:487
 TPadPainter.cxx:488
 TPadPainter.cxx:489
 TPadPainter.cxx:490
 TPadPainter.cxx:491
 TPadPainter.cxx:492
 TPadPainter.cxx:493
 TPadPainter.cxx:494
 TPadPainter.cxx:495
 TPadPainter.cxx:496
 TPadPainter.cxx:497
 TPadPainter.cxx:498
 TPadPainter.cxx:499
 TPadPainter.cxx:500
 TPadPainter.cxx:501
 TPadPainter.cxx:502
 TPadPainter.cxx:503
 TPadPainter.cxx:504
 TPadPainter.cxx:505
 TPadPainter.cxx:506
 TPadPainter.cxx:507
 TPadPainter.cxx:508
 TPadPainter.cxx:509
 TPadPainter.cxx:510
 TPadPainter.cxx:511
 TPadPainter.cxx:512
 TPadPainter.cxx:513
 TPadPainter.cxx:514
 TPadPainter.cxx:515
 TPadPainter.cxx:516
 TPadPainter.cxx:517
 TPadPainter.cxx:518
 TPadPainter.cxx:519
 TPadPainter.cxx:520
 TPadPainter.cxx:521
 TPadPainter.cxx:522
 TPadPainter.cxx:523
 TPadPainter.cxx:524
 TPadPainter.cxx:525
 TPadPainter.cxx:526
 TPadPainter.cxx:527
 TPadPainter.cxx:528
 TPadPainter.cxx:529
 TPadPainter.cxx:530
 TPadPainter.cxx:531
 TPadPainter.cxx:532
 TPadPainter.cxx:533
 TPadPainter.cxx:534
 TPadPainter.cxx:535
 TPadPainter.cxx:536
 TPadPainter.cxx:537
 TPadPainter.cxx:538
 TPadPainter.cxx:539
 TPadPainter.cxx:540
 TPadPainter.cxx:541
 TPadPainter.cxx:542
 TPadPainter.cxx:543
 TPadPainter.cxx:544
 TPadPainter.cxx:545
 TPadPainter.cxx:546
 TPadPainter.cxx:547
 TPadPainter.cxx:548
 TPadPainter.cxx:549
 TPadPainter.cxx:550
 TPadPainter.cxx:551
 TPadPainter.cxx:552
 TPadPainter.cxx:553
 TPadPainter.cxx:554
 TPadPainter.cxx:555
 TPadPainter.cxx:556
 TPadPainter.cxx:557
 TPadPainter.cxx:558
 TPadPainter.cxx:559
 TPadPainter.cxx:560
 TPadPainter.cxx:561
 TPadPainter.cxx:562
 TPadPainter.cxx:563
 TPadPainter.cxx:564
 TPadPainter.cxx:565
 TPadPainter.cxx:566
 TPadPainter.cxx:567
 TPadPainter.cxx:568
 TPadPainter.cxx:569
 TPadPainter.cxx:570
 TPadPainter.cxx:571
 TPadPainter.cxx:572
 TPadPainter.cxx:573
 TPadPainter.cxx:574
 TPadPainter.cxx:575
 TPadPainter.cxx:576
 TPadPainter.cxx:577
 TPadPainter.cxx:578
 TPadPainter.cxx:579
 TPadPainter.cxx:580
 TPadPainter.cxx:581
 TPadPainter.cxx:582
 TPadPainter.cxx:583
 TPadPainter.cxx:584
 TPadPainter.cxx:585
 TPadPainter.cxx:586
 TPadPainter.cxx:587
 TPadPainter.cxx:588
 TPadPainter.cxx:589
 TPadPainter.cxx:590
 TPadPainter.cxx:591
 TPadPainter.cxx:592
 TPadPainter.cxx:593
 TPadPainter.cxx:594
 TPadPainter.cxx:595
 TPadPainter.cxx:596
 TPadPainter.cxx:597
 TPadPainter.cxx:598
 TPadPainter.cxx:599
 TPadPainter.cxx:600
 TPadPainter.cxx:601
 TPadPainter.cxx:602
 TPadPainter.cxx:603
 TPadPainter.cxx:604
 TPadPainter.cxx:605
 TPadPainter.cxx:606
 TPadPainter.cxx:607
 TPadPainter.cxx:608
 TPadPainter.cxx:609
 TPadPainter.cxx:610
 TPadPainter.cxx:611
 TPadPainter.cxx:612
 TPadPainter.cxx:613
 TPadPainter.cxx:614
 TPadPainter.cxx:615
 TPadPainter.cxx:616
 TPadPainter.cxx:617
 TPadPainter.cxx:618
 TPadPainter.cxx:619
 TPadPainter.cxx:620
 TPadPainter.cxx:621
 TPadPainter.cxx:622
 TPadPainter.cxx:623
 TPadPainter.cxx:624
 TPadPainter.cxx:625
 TPadPainter.cxx:626
 TPadPainter.cxx:627
 TPadPainter.cxx:628
 TPadPainter.cxx:629
 TPadPainter.cxx:630
 TPadPainter.cxx:631
 TPadPainter.cxx:632
 TPadPainter.cxx:633
 TPadPainter.cxx:634
 TPadPainter.cxx:635
 TPadPainter.cxx:636
 TPadPainter.cxx:637
 TPadPainter.cxx:638
 TPadPainter.cxx:639
 TPadPainter.cxx:640
 TPadPainter.cxx:641
 TPadPainter.cxx:642
 TPadPainter.cxx:643
 TPadPainter.cxx:644
 TPadPainter.cxx:645
 TPadPainter.cxx:646
 TPadPainter.cxx:647
 TPadPainter.cxx:648
 TPadPainter.cxx:649
 TPadPainter.cxx:650
 TPadPainter.cxx:651
 TPadPainter.cxx:652
 TPadPainter.cxx:653
 TPadPainter.cxx:654
 TPadPainter.cxx:655
 TPadPainter.cxx:656
 TPadPainter.cxx:657
 TPadPainter.cxx:658
 TPadPainter.cxx:659
 TPadPainter.cxx:660
 TPadPainter.cxx:661
 TPadPainter.cxx:662
 TPadPainter.cxx:663
 TPadPainter.cxx:664
 TPadPainter.cxx:665
 TPadPainter.cxx:666
 TPadPainter.cxx:667
 TPadPainter.cxx:668
 TPadPainter.cxx:669
 TPadPainter.cxx:670
 TPadPainter.cxx:671
 TPadPainter.cxx:672
 TPadPainter.cxx:673
 TPadPainter.cxx:674
 TPadPainter.cxx:675
 TPadPainter.cxx:676
 TPadPainter.cxx:677
 TPadPainter.cxx:678
 TPadPainter.cxx:679
 TPadPainter.cxx:680
 TPadPainter.cxx:681
 TPadPainter.cxx:682
 TPadPainter.cxx:683
 TPadPainter.cxx:684
 TPadPainter.cxx:685
 TPadPainter.cxx:686
 TPadPainter.cxx:687
 TPadPainter.cxx:688
 TPadPainter.cxx:689
 TPadPainter.cxx:690
 TPadPainter.cxx:691
 TPadPainter.cxx:692
 TPadPainter.cxx:693
 TPadPainter.cxx:694
 TPadPainter.cxx:695
 TPadPainter.cxx:696
 TPadPainter.cxx:697
 TPadPainter.cxx:698
 TPadPainter.cxx:699
 TPadPainter.cxx:700
 TPadPainter.cxx:701
 TPadPainter.cxx:702
 TPadPainter.cxx:703
 TPadPainter.cxx:704
 TPadPainter.cxx:705
 TPadPainter.cxx:706
 TPadPainter.cxx:707
 TPadPainter.cxx:708
 TPadPainter.cxx:709
 TPadPainter.cxx:710
 TPadPainter.cxx:711
 TPadPainter.cxx:712
 TPadPainter.cxx:713
 TPadPainter.cxx:714
 TPadPainter.cxx:715
 TPadPainter.cxx:716
 TPadPainter.cxx:717
 TPadPainter.cxx:718
 TPadPainter.cxx:719
 TPadPainter.cxx:720
 TPadPainter.cxx:721
 TPadPainter.cxx:722
 TPadPainter.cxx:723
 TPadPainter.cxx:724
 TPadPainter.cxx:725
 TPadPainter.cxx:726
 TPadPainter.cxx:727
 TPadPainter.cxx:728
 TPadPainter.cxx:729
 TPadPainter.cxx:730
 TPadPainter.cxx:731
 TPadPainter.cxx:732
 TPadPainter.cxx:733
 TPadPainter.cxx:734
 TPadPainter.cxx:735
 TPadPainter.cxx:736
 TPadPainter.cxx:737
 TPadPainter.cxx:738
 TPadPainter.cxx:739
 TPadPainter.cxx:740
 TPadPainter.cxx:741
 TPadPainter.cxx:742
 TPadPainter.cxx:743
 TPadPainter.cxx:744
 TPadPainter.cxx:745
 TPadPainter.cxx:746
 TPadPainter.cxx:747
 TPadPainter.cxx:748
 TPadPainter.cxx:749
 TPadPainter.cxx:750
 TPadPainter.cxx:751
 TPadPainter.cxx:752
 TPadPainter.cxx:753
 TPadPainter.cxx:754
 TPadPainter.cxx:755
 TPadPainter.cxx:756
 TPadPainter.cxx:757
 TPadPainter.cxx:758
 TPadPainter.cxx:759
 TPadPainter.cxx:760
 TPadPainter.cxx:761
 TPadPainter.cxx:762
 TPadPainter.cxx:763
 TPadPainter.cxx:764
 TPadPainter.cxx:765
 TPadPainter.cxx:766
 TPadPainter.cxx:767
 TPadPainter.cxx:768
 TPadPainter.cxx:769
 TPadPainter.cxx:770
 TPadPainter.cxx:771
 TPadPainter.cxx:772
 TPadPainter.cxx:773
 TPadPainter.cxx:774
 TPadPainter.cxx:775
 TPadPainter.cxx:776
 TPadPainter.cxx:777
 TPadPainter.cxx:778
 TPadPainter.cxx:779
 TPadPainter.cxx:780
 TPadPainter.cxx:781
 TPadPainter.cxx:782
 TPadPainter.cxx:783
 TPadPainter.cxx:784
 TPadPainter.cxx:785
 TPadPainter.cxx:786
 TPadPainter.cxx:787
 TPadPainter.cxx:788
 TPadPainter.cxx:789
 TPadPainter.cxx:790
 TPadPainter.cxx:791
 TPadPainter.cxx:792
 TPadPainter.cxx:793
 TPadPainter.cxx:794
 TPadPainter.cxx:795
 TPadPainter.cxx:796
 TPadPainter.cxx:797
 TPadPainter.cxx:798
 TPadPainter.cxx:799
 TPadPainter.cxx:800
 TPadPainter.cxx:801
 TPadPainter.cxx:802
 TPadPainter.cxx:803
 TPadPainter.cxx:804
 TPadPainter.cxx:805
 TPadPainter.cxx:806
 TPadPainter.cxx:807
 TPadPainter.cxx:808
 TPadPainter.cxx:809
 TPadPainter.cxx:810
 TPadPainter.cxx:811
 TPadPainter.cxx:812
 TPadPainter.cxx:813
 TPadPainter.cxx:814
 TPadPainter.cxx:815
 TPadPainter.cxx:816
 TPadPainter.cxx:817
 TPadPainter.cxx:818
 TPadPainter.cxx:819
 TPadPainter.cxx:820
 TPadPainter.cxx:821
 TPadPainter.cxx:822
 TPadPainter.cxx:823
 TPadPainter.cxx:824
 TPadPainter.cxx:825
 TPadPainter.cxx:826
 TPadPainter.cxx:827
 TPadPainter.cxx:828
 TPadPainter.cxx:829
 TPadPainter.cxx:830
 TPadPainter.cxx:831
 TPadPainter.cxx:832
 TPadPainter.cxx:833
 TPadPainter.cxx:834
 TPadPainter.cxx:835
 TPadPainter.cxx:836
 TPadPainter.cxx:837
 TPadPainter.cxx:838
 TPadPainter.cxx:839
 TPadPainter.cxx:840
 TPadPainter.cxx:841
 TPadPainter.cxx:842
 TPadPainter.cxx:843
 TPadPainter.cxx:844
 TPadPainter.cxx:845
 TPadPainter.cxx:846
 TPadPainter.cxx:847
 TPadPainter.cxx:848
 TPadPainter.cxx:849
 TPadPainter.cxx:850
 TPadPainter.cxx:851
 TPadPainter.cxx:852
 TPadPainter.cxx:853
 TPadPainter.cxx:854
 TPadPainter.cxx:855
 TPadPainter.cxx:856
 TPadPainter.cxx:857
 TPadPainter.cxx:858
 TPadPainter.cxx:859
 TPadPainter.cxx:860
 TPadPainter.cxx:861
 TPadPainter.cxx:862
 TPadPainter.cxx:863
 TPadPainter.cxx:864
 TPadPainter.cxx:865
 TPadPainter.cxx:866
 TPadPainter.cxx:867
 TPadPainter.cxx:868
 TPadPainter.cxx:869
 TPadPainter.cxx:870
 TPadPainter.cxx:871
 TPadPainter.cxx:872
 TPadPainter.cxx:873
 TPadPainter.cxx:874
 TPadPainter.cxx:875
 TPadPainter.cxx:876
 TPadPainter.cxx:877
 TPadPainter.cxx:878
 TPadPainter.cxx:879
 TPadPainter.cxx:880
 TPadPainter.cxx:881
 TPadPainter.cxx:882
 TPadPainter.cxx:883
 TPadPainter.cxx:884
 TPadPainter.cxx:885
 TPadPainter.cxx:886
 TPadPainter.cxx:887
 TPadPainter.cxx:888
 TPadPainter.cxx:889
 TPadPainter.cxx:890
 TPadPainter.cxx:891
 TPadPainter.cxx:892
 TPadPainter.cxx:893
 TPadPainter.cxx:894
 TPadPainter.cxx:895
 TPadPainter.cxx:896
 TPadPainter.cxx:897
 TPadPainter.cxx:898
 TPadPainter.cxx:899
 TPadPainter.cxx:900
 TPadPainter.cxx:901
 TPadPainter.cxx:902
 TPadPainter.cxx:903
 TPadPainter.cxx:904
 TPadPainter.cxx:905
 TPadPainter.cxx:906
 TPadPainter.cxx:907
 TPadPainter.cxx:908
 TPadPainter.cxx:909
 TPadPainter.cxx:910
 TPadPainter.cxx:911
 TPadPainter.cxx:912
 TPadPainter.cxx:913
 TPadPainter.cxx:914
 TPadPainter.cxx:915
 TPadPainter.cxx:916
 TPadPainter.cxx:917
 TPadPainter.cxx:918
 TPadPainter.cxx:919
 TPadPainter.cxx:920
 TPadPainter.cxx:921
 TPadPainter.cxx:922
 TPadPainter.cxx:923
 TPadPainter.cxx:924
 TPadPainter.cxx:925
 TPadPainter.cxx:926
 TPadPainter.cxx:927
 TPadPainter.cxx:928
 TPadPainter.cxx:929
 TPadPainter.cxx:930
 TPadPainter.cxx:931