#include "TGClient.h"
#include "TGGC.h"
#include "TVirtualX.h"
#include "THashTable.h"
#include "TColor.h"
#include "TROOT.h"
#include "Riostream.h"
#include <string.h>
ClassImp(TGGC)
TGGC::TGGC(GCValues_t *values, Bool_t)
{
   
   if (values) {
      fValues = *values;
      fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
      if (values->fMask & kGCDashList) {
         if (values->fDashLen > (Int_t)sizeof(fValues.fDashes))
            Warning("TGGC", "dash list can have only up to %d elements",
                    sizeof(fValues.fDashes));
         fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)sizeof(fValues.fDashes));
         gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
                              fValues.fDashLen);
      }
   } else {
      memset(&fValues, 0, sizeof(GCValues_t));
      fContext = 0;
   }
   SetRefCount(1);
}
TGGC::TGGC(GCValues_t *values)
{
   
   
   if (!values) {
      memset(&fValues, 0, sizeof(GCValues_t));
      fContext = 0;
      SetRefCount(1);
      return;
   }
   if (gClient)
      gClient->GetGC(values, kTRUE);
   else {
      fContext = 0;
      Error("TGGC", "TGClient not yet initialized, should never happen");
   }
}
TGGC::TGGC(const TGGC &g) : TObject(g), TRefCnt()
{
   
   fValues = g.fValues;
   if (g.fContext) {
      fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
      if (fValues.fMask & kGCDashList)
         gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
                              fValues.fDashLen);
   } else
      fContext = 0;
   SetRefCount(1);
   if (gClient)
      gClient->GetGCPool()->fList->Add(this);
}
TGGC::~TGGC()
{
   
   if (gClient)
      gClient->GetGCPool()->ForceFreeGC(this);
   if (fContext)
      gVirtualX->DeleteGC(fContext);
}
TGGC &TGGC::operator=(const TGGC &rhs)
{
   
   if (this != &rhs) {
      if (!fContext && gClient) {
         TGGC *gc = gClient->GetGCPool()->FindGC(this);
         if (!gc)
            gClient->GetGCPool()->fList->Add(this);
      }
      if (fContext)
         gVirtualX->DeleteGC(fContext);
      TObject::operator=(rhs);
      fValues  = rhs.fValues;
      fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
      if (fValues.fMask & kGCDashList)
         gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
                              fValues.fDashLen);
   }
   return *this;
}
GContext_t TGGC::operator()() const
{
   
   return fContext;
}
void TGGC::UpdateValues(GCValues_t *values)
{
   
   fValues.fMask |= values->fMask;
   for (Mask_t bit = 1; bit <= fValues.fMask; bit <<= 1) {
      switch (bit & values->fMask) {
         default:
         case 0:
            continue;
         case kGCFunction:
            fValues.fFunction = values->fFunction;
            break;
         case kGCPlaneMask:
            fValues.fPlaneMask = values->fPlaneMask;
            break;
         case kGCForeground:
            fValues.fForeground = values->fForeground;
            break;
         case kGCBackground:
            fValues.fBackground = values->fBackground;
            break;
         case kGCLineWidth:
            fValues.fLineWidth = values->fLineWidth;
            break;
         case kGCLineStyle:
            fValues.fLineStyle = values->fLineStyle;
            break;
         case kGCCapStyle:
            fValues.fCapStyle = values->fCapStyle;
            break;
         case kGCJoinStyle:
            fValues.fJoinStyle = values->fJoinStyle;
            break;
         case kGCFillStyle:
            fValues.fFillStyle = values->fFillStyle;
            break;
         case kGCFillRule:
            fValues.fFillRule = values->fFillRule;
            break;
         case kGCTile:
            fValues.fTile = values->fTile;
            break;
         case kGCStipple:
            fValues.fStipple = values->fStipple;
            break;
         case kGCTileStipXOrigin:
            fValues.fTsXOrigin = values->fTsXOrigin;
            break;
         case kGCTileStipYOrigin:
            fValues.fTsYOrigin = values->fTsYOrigin;
            break;
         case kGCFont:
            fValues.fFont = values->fFont;
            break;
         case kGCSubwindowMode:
            fValues.fSubwindowMode = values->fSubwindowMode;
            break;
         case kGCGraphicsExposures:
            fValues.fGraphicsExposures = values->fGraphicsExposures;
            break;
         case kGCClipXOrigin:
            fValues.fClipXOrigin = values->fClipXOrigin;
            break;
         case kGCClipYOrigin:
            fValues.fClipYOrigin = values->fClipYOrigin;
            break;
         case kGCClipMask:
            fValues.fClipMask = values->fClipMask;
            break;
         case kGCDashOffset:
            fValues.fDashOffset = values->fDashOffset;
            break;
         case kGCDashList:
            if (values->fDashLen > (Int_t)sizeof(fValues.fDashes))
               Warning("UpdateValues", "dash list can have only up to %d elements",
                       sizeof(fValues.fDashes));
            fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)sizeof(fValues.fDashes));
            memcpy(fValues.fDashes, values->fDashes, fValues.fDashLen);
            break;
         case kGCArcMode:
            fValues.fArcMode = values->fArcMode;
            break;
      }
   }
}
void TGGC::SetAttributes(GCValues_t *values)
{
   
   if (!fContext && gClient) {
      TGGC *gc = gClient->GetGCPool()->FindGC(this);
      if (!gc)
         gClient->GetGCPool()->fList->Add(this);
   }
   if (fContext)
      gVirtualX->ChangeGC(fContext, values);
   else
      fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
   UpdateValues(values);
   if (values->fMask & kGCDashList)
      gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
                           fValues.fDashLen);
}
void TGGC::SetFunction(EGraphicsFunction v)
{
   
   GCValues_t values;
   values.fFunction = v;
   values.fMask     = kGCFunction;
   SetAttributes(&values);
}
void TGGC::SetPlaneMask(ULong_t v)
{
   
   GCValues_t values;
   values.fPlaneMask = v;
   values.fMask      = kGCPlaneMask;
   SetAttributes(&values);
}
void TGGC::SetForeground(ULong_t v)
{
   
   GCValues_t values;
   values.fForeground = v;
   values.fMask       = kGCForeground;
   SetAttributes(&values);
}
void TGGC::SetBackground(ULong_t v)
{
   
   GCValues_t values;
   values.fBackground = v;
   values.fMask       = kGCBackground;
   SetAttributes(&values);
}
void TGGC::SetLineWidth(Int_t v)
{
   
   GCValues_t values;
   values.fLineWidth = v;
   values.fMask      = kGCLineWidth;
   SetAttributes(&values);
}
void TGGC::SetLineStyle(Int_t v)
{
   
   GCValues_t values;
   values.fLineStyle = v;
   values.fMask      = kGCLineStyle;
   SetAttributes(&values);
}
void TGGC::SetCapStyle(Int_t v)
{
   
   GCValues_t values;
   values.fCapStyle = v;
   values.fMask     = kGCCapStyle;
   SetAttributes(&values);
}
void TGGC::SetJoinStyle(Int_t v)
{
   
   GCValues_t values;
   values.fJoinStyle = v;
   values.fMask      = kGCJoinStyle;
   SetAttributes(&values);
}
void TGGC::SetFillStyle(Int_t v)
{
   
   
   GCValues_t values;
   values.fFillStyle = v;
   values.fMask      = kGCFillStyle;
   SetAttributes(&values);
}
void TGGC::SetFillRule(Int_t v)
{
   
   GCValues_t values;
   values.fFillRule = v;
   values.fMask     = kGCFillRule;
   SetAttributes(&values);
}
void TGGC::SetTile(Pixmap_t v)
{
   
   GCValues_t values;
   values.fTile = v;
   values.fMask = kGCTile;
   SetAttributes(&values);
}
void TGGC::SetStipple(Pixmap_t v)
{
   
   GCValues_t values;
   values.fStipple = v;
   values.fMask    = kGCStipple;
   SetAttributes(&values);
}
void TGGC::SetTileStipXOrigin(Int_t v)
{
   
   GCValues_t values;
   values.fTsXOrigin = v;
   values.fMask      = kGCTileStipXOrigin;
   SetAttributes(&values);
}
void TGGC::SetTileStipYOrigin(Int_t v)
{
   
   GCValues_t values;
   values.fTsYOrigin = v;
   values.fMask      = kGCTileStipYOrigin;
   SetAttributes(&values);
}
void TGGC::SetFont(FontH_t v)
{
   
   GCValues_t values;
   values.fFont = v;
   values.fMask = kGCFont;
   SetAttributes(&values);
}
void TGGC::SetSubwindowMode(Int_t v)
{
   
   GCValues_t values;
   values.fSubwindowMode = v;
   values.fMask          = kGCSubwindowMode;
   SetAttributes(&values);
}
void TGGC::SetGraphicsExposures(Bool_t v)
{
   
   GCValues_t values;
   values.fGraphicsExposures = v;
   values.fMask              = kGCGraphicsExposures;
   SetAttributes(&values);
}
void TGGC::SetClipXOrigin(Int_t v)
{
   
   GCValues_t values;
   values.fClipXOrigin = v;
   values.fMask        = kGCClipXOrigin;
   SetAttributes(&values);
}
void TGGC::SetClipYOrigin(Int_t v)
{
   
   GCValues_t values;
   values.fClipYOrigin = v;
   values.fMask        = kGCClipYOrigin;
   SetAttributes(&values);
}
void TGGC::SetClipMask(Pixmap_t v)
{
   
   GCValues_t values;
   values.fClipMask = v;
   values.fMask     = kGCClipMask;
   SetAttributes(&values);
}
void TGGC::SetDashOffset(Int_t v)
{
   
   GCValues_t values;
   values.fDashOffset = v;
   values.fMask       = kGCDashOffset;
   SetAttributes(&values);
}
void TGGC::SetDashList(const char v[], Int_t len)
{
   
   GCValues_t values;
   if (len > (Int_t)sizeof(values.fDashes))
      Warning("SetDashList", "dash list can have only up to %d elements",
              sizeof(values.fDashes));
   values.fDashLen = TMath::Min(len, (Int_t)sizeof(values.fDashes));
   memcpy(values.fDashes, v, values.fDashLen);
   values.fMask    = kGCDashList;
   SetAttributes(&values);
}
void TGGC::SetArcMode(Int_t v)
{
   
   GCValues_t values;
   values.fArcMode = v;
   values.fMask    = kGCArcMode;
   SetAttributes(&values);
}
void TGGC::Print(Option_t *) const
{
   
   Printf("TGGC: mask = %lx, handle = %lx, ref cnt = %u", fValues.fMask,
          fContext, References());
}
TString TGGC::GetMaskString() const
{
   
   TString mask;
   Mask_t fmask = GetMask();
   if (fmask & kGCFunction) {
      if (mask.Length() == 0) mask  = "kGCFunction";
      else                    mask += " | kGCFunction";
   }
   if (fmask & kGCPlaneMask) {
      if (mask.Length() == 0) mask  = "kGCPlaneMask";
      else                    mask += " | kGCPlaneMask";
   }
   if (fmask & kGCForeground) {
      if (mask.Length() == 0) mask  = "kGCForeground";
      else                    mask += " | kGCForeground";
   }
   if (fmask & kGCBackground) {
      if (mask.Length() == 0) mask  = "kGCBackground";
      else                    mask += " | kGCBackground";
   }
   if (fmask & kGCLineWidth) {
      if (mask.Length() == 0) mask  = "kGCLineWidth";
      else                    mask += " | kGCLineWidth";
   }
   if (fmask & kGCLineStyle) {
      if (mask.Length() == 0) mask  = "kGCLineStyle";
      else                    mask += " | kGCLineStyle";
   }
   if (fmask & kGCCapStyle) {
      if (mask.Length() == 0) mask  = "kGCCapStyle";
      else                    mask += " | kGCCapStyle";
   }
   if (fmask & kGCJoinStyle) {
      if (mask.Length() == 0) mask  = "kGCJoinStyle";
      else                    mask += " | kGCJoinStyle";
   }
   if (fmask & kGCFillStyle) {
      if (mask.Length() == 0) mask  = "kGCFillStyle";
      else                    mask += " | kGCFillStyle";
   }
   if (fmask & kGCFillRule) {
      if (mask.Length() == 0) mask  = "kGCFillRule";
      else                    mask += " | kGCFillRule";
   }
   if (fmask & kGCTile) {
      if (mask.Length() == 0) mask  = "kGCTile";
      else                    mask += " | kGCTile";
   }
   if (fmask & kGCStipple) {
      if (mask.Length() == 0) mask  = "kGCStipple";
      else                    mask += " | kGCStipple";
   }
   if (fmask & kGCTileStipXOrigin) {
      if (mask.Length() == 0) mask  = "kGCTileStipXOrigin";
      else                    mask += " | kGCTileStipXOrigin";
   }
   if (fmask & kGCTileStipYOrigin) {
      if (mask.Length() == 0) mask  = "kGCTileStipYOrigin";
      else                    mask += " | kGCTileStipYOrigin";
   }
   if (fmask & kGCFont) {
      if (mask.Length() == 0) mask  = "kGCFont";
      else                    mask += " | kGCFont";
   }
   if (fmask & kGCSubwindowMode) {
      if (mask.Length() == 0) mask  = "kGCSubwindowMode";
      else                    mask += " | kGCSubwindowMode";
   }
   if (fmask & kGCGraphicsExposures) {
      if (mask.Length() == 0) mask  = "kGCGraphicsExposures";
      else                    mask += " | kGCGraphicsExposures";
   }
   if (fmask & kGCClipXOrigin) {
      if (mask.Length() == 0) mask  = "kGCClipXOrigin";
      else                    mask += " | kGCClipXOrigin";
   }
   if (fmask & kGCClipYOrigin) {
      if (mask.Length() == 0) mask  = "kGCClipYOrigin";
      else                    mask += " | kGCClipYOrigin";
   }
   if (fmask & kGCClipMask) {
      if (mask.Length() == 0) mask  = "kGCClipMask";
      else                    mask += " | kGCClipMask";
   }
   if (fmask & kGCDashOffset) {
      if (mask.Length() == 0) mask  = "kGCDashOffset";
      else                    mask += " | kGCDashOffset";
   }
   if (fmask & kGCDashList) {
      if (mask.Length() == 0) mask  = "kGCDashList";
      else                    mask += " | kGCDashList";
   }
   if (fmask & kGCArcMode) {
      if (mask.Length() == 0) mask  = "kGCArcMode";
      else                    mask += " | kGCArcMode";
   }
   return mask;
}
void TGGC::SavePrimitive(ostream &out, Option_t *option )
{
   
   if (gROOT->ClassSaved(TGGC::Class())) {
      out << endl;
   } else {
      
      out << endl;
      out << "   TGGC   *uGC;           // will reflect user GC changes" << endl;
   }
   Mask_t fmask = GetMask();
   const char *colorname;
   char valname[50];
   char quote ='"';
   ULong_t color;
   sprintf(valname,"val%s",option);
   out << "   // graphics context changes" << endl;
   
   out << "   GCValues_t " << valname << ";" << endl;
   out << "   " << valname << ".fMask = " << GetMaskString() << ";" << endl;
   for (Mask_t bit = 1; bit <= fmask; bit <<= 1) {
      switch (bit & fmask) {
         default:
         case 0:
            continue;
         case kGCFunction:
            out << "   " << valname << ".fFunction = ";
            switch (GetFunction()) {
               case kGXclear:
                  out << "kGXclear";
                  break;
               case kGXand:
                  out << "kGXand";
                  break;
               case kGXandReverse:
                  out << "kGXandReverse";
                  break;
               case kGXcopy:
                  out << "kGXcopy";
                  break;
               case kGXandInverted:
                  out << "kGXandInverted";
                  break;
               case kGXnoop:
                  out << "kGXnoop";
                  break;
               case kGXxor:
                  out << "kGXxor";
                  break;
               case kGXor:
                  out << "kGXor";
                  break;
               case kGXnor:
                  out << "kGXnor";
                  break;
               case kGXequiv:
                  out << "kGXequiv";
                  break;
               case kGXinvert:
                  out << "kGXinvert";
                  break;
               case kGXorReverse:
                  out << "kGXorReverse";
                  break;
               case kGXcopyInverted:
                  out << "kGXcopyInverted";
                  break;
               case kGXorInverted:
                  out << "kGXorInverted";
                  break;
               case kGXnand:
                  out << "kGXnand";
                  break;
               case kGXset:
                  out << "kGXset";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCPlaneMask:
            out << "   " << valname << ".fPlaneMask = " << GetPlaneMask() << ";" << endl;
            break;
         case kGCForeground:
            color = GetForeground();
            colorname = TColor::PixelAsHexString(color);
            out << "   gClient->GetColorByName(" << quote << colorname << quote
                << "," << valname << ".fForeground);" << endl;
            break;
         case kGCBackground:
            color = GetBackground();
            colorname = TColor::PixelAsHexString(color);
            out << "   gClient->GetColorByName(" << quote << colorname << quote
                << "," << valname << ".fBackground);" << endl;
            break;
         case kGCLineWidth:
            out << "   " << valname << ".fLineWidth = " << GetLineWidth() << ";" << endl;
            break;
         case kGCLineStyle:
            out << "   " << valname << ".fLineStyle = ";
            switch (GetLineStyle()) {
               case kLineSolid:
                  out << "kLineSolid";
                  break;
               case kLineOnOffDash:
                  out << "kLineOnOffDash";
                  break;
               case kLineDoubleDash:
                  out << "kLineDoubleDash";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCCapStyle:
            out << "   " << valname << ".fCapStyle = ";
            switch (GetCapStyle()) {
               case kCapNotLast:
                  out << "kCapNotLast";
                  break;
               case kCapButt:
                  out << "kCapButt";
                  break;
               case kCapRound:
                  out << "kCapRound";
                  break;
               case kCapProjecting:
                  out << "kCapProjecting";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCJoinStyle:
            out << "   " << valname << ".fJoinStyle = ";
            switch (GetJoinStyle()) {
               case kJoinMiter:
                  out << "kJoinMiter";
                  break;
               case kJoinRound:
                  out << "kJoinRound";
                  break;
               case kJoinBevel:
                  out << "kJoinBevel";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCFillStyle:
            out << "   " << valname << ".fFillStyle = ";
            switch (GetFillStyle()) {
               case kFillSolid:
                  out << "kFillSolid";
                  break;
               case kFillTiled:
                  out << "kFillTiled";
                  break;
               case kFillStippled:
                  out << "kFillStippled";
                  break;
               case kFillOpaqueStippled:
                  out << "kFillOpaqueStippled";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCFillRule:
            out << "   " << valname << ".fFillRule = ";
            switch (GetFillRule()) {
               case kEvenOddRule:
                  out << "kEvenOddRule";
                  break;
               case kWindingRule:
                  out << "kWindingRule";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCTile:
            out << "   " << valname << ".fTile = " << GetTile() << ";" << endl;
            break;
         case kGCStipple:
            out << "   " << valname << ".fStipple = " << GetStipple() << ";" << endl;
            break;
         case kGCTileStipXOrigin:
            out << "   " << valname << ".fTsXOrigin = " << GetTileStipXOrigin() << ";" << endl;
            break;
         case kGCTileStipYOrigin:
            out << "   " << valname << ".fTsYOrigin = " << GetTileStipYOrigin() << ";" << endl;
            break;
         case kGCFont:
            out << "   " << valname << ".fFont = ufont->GetFontHandle();" << endl;
            break;
         case kGCSubwindowMode:
            out << "   " << valname << ".fSubwindowMode = ";
            switch (GetSubwindowMode()) {
               case kClipByChildren:
                  out << "kClipByChildren";
                  break;
               case kIncludeInferiors:
                  out << "kIncludeInferiors";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCGraphicsExposures:
            out << "   " << valname << ".fGraphicsExposures = ";
            switch (GetGraphicsExposures()) {
               case kTRUE:
                  out << "kTRUE";
                  break;
               case kFALSE:
                  out << "kFALSE";
                  break;
            }
            out << ";" << endl;
            break;
         case kGCClipXOrigin:
            out << "   " << valname << ".fClipXOrigin = " << GetClipXOrigin() << ";" << endl;
            break;
         case kGCClipYOrigin:
            out << "   " << valname << ".fClipYOrigin = " << GetClipYOrigin() << ";" << endl;
            break;
         case kGCClipMask:
            out << "   " << valname << ".fClipMask = " << GetClipMask() << ";" << endl;
            break;
         case kGCDashOffset:
            out << "   " << valname << ".fDashOffset = " << GetDashOffset() << ";" << endl;
            break;
         case kGCDashList:
            if (GetDashLen() > (Int_t)sizeof(GetDashes()))
               Warning("TGGC::SavePrimitive", "dash list can have only up to %d elements",
                       sizeof(GetDashes()));
            out << "   " << valname << ".fDashLen = "
                << TMath::Min(GetDashLen(),(Int_t)sizeof(GetDashes())) << ";" << endl;
            out << "   memcpy(GetDashes()," << valname << ".fDashes,"
                                            << valname << ".fDashLen);" << endl;
            break;
         case kGCArcMode:
            out << "   " << valname << ".fArcMode = ";
            switch (GetArcMode()) {
               case kArcChord:
                  out << "kArcChord";
                  break;
               case kArcPieSlice:
                  out << "kArcPieSlice";
                  break;
            }
            out << ";" << endl;
            break;
      }
   }
   out << "   uGC = gClient->GetGC(&" << valname << ", kTRUE);" << endl;
}
ClassImp(TGGCPool)
TGGCPool::TGGCPool(TGClient *client)
{
   
   fClient = client;
   fList   = new THashTable;
   fList->SetOwner();
}
TGGCPool::~TGGCPool()
{
   
   delete fList;
}
void TGGCPool::ForceFreeGC(const TGGC *gct)
{
   
   TGGC *gc = (TGGC *) fList->FindObject(gct);
   if (gc) {
      if (gc->References() > 1)
         Error("ForceFreeGC", "removed a shared graphics context\n",
               "best to use graphics contexts via the TGGCPool()");
      fList->Remove(gc);
   }
}
void TGGCPool::FreeGC(const TGGC *gct)
{
   
   TGGC *gc = (TGGC *) fList->FindObject(gct);
   if (gc) {
      if (gc->RemoveReference() == 0) {
         fList->Remove(gc);
         delete gc;
      }
   }
}
void TGGCPool::FreeGC(GContext_t gct)
{
   
   TIter next(fList);
   while (TGGC *gc = (TGGC *) next()) {
      if (gc->fContext == gct) {
         if (gc->RemoveReference() == 0) {
            fList->Remove(gc);
            delete gc;
            return;
         }
      }
   }
}
TGGC *TGGCPool::FindGC(const TGGC *gct)
{
   
   return (TGGC*) fList->FindObject(gct);
}
TGGC *TGGCPool::FindGC(GContext_t gct)
{
   
   
   TIter next(fList);
   while (TGGC *gc = (TGGC *) next()) {
      if (gc->fContext == gct)
         return gc;
   }
   return 0;
}
TGGC *TGGCPool::GetGC(GContext_t gct)
{
   
   GCValues_t gval;
   gVirtualX->GetGCValues(gct, gval);
   return GetGC(&gval, kTRUE);
}
TGGC *TGGCPool::GetGC(GCValues_t *values, Bool_t rw)
{
   
   
   
   
   TGGC *gc, *best_match = 0;
   Int_t matching_bits, best_matching_bits = -1;
   Bool_t exact = kFALSE;
   if (!values)
      rw = kTRUE;
   if (!rw) {
      
      
      TIter next(fList);
      while ((gc = (TGGC *) next())) {
         matching_bits = MatchGC(gc, values);
         if (matching_bits > best_matching_bits) {
            best_matching_bits = matching_bits;
            best_match = gc;
            if ((gc->fValues.fMask & values->fMask) == values->fMask) {
               exact = kTRUE;
               break;
            }
         }
      }
      if (best_match) {
         if (gDebug > 0)
            Printf("<TGGCPool::GetGC>: %smatching GC found\n", exact ? "exact " : "");
         best_match->AddReference();
         if (!exact) {
            
            UpdateGC(best_match, values);
         }
         return best_match;
      }
   }
   gc = new TGGC(values, kTRUE);
   fList->Add(gc);
   return gc;
}
Int_t TGGCPool::MatchGC(const TGGC *gc, GCValues_t *values)
{
   
   
   
   Mask_t bit, common_bits;
   Int_t  matching_bits = -1;
   Bool_t match = kFALSE;
   const GCValues_t *gcv = &gc->fValues;
   common_bits = values->fMask & gcv->fMask;
   if (common_bits == 0) return 0;  
                                    
   
   
   
   
   if (gcv->fMask & kGCTile)
      if ((gcv->fTile != kNone) && !(values->fMask & kGCTile)) return -1;
   if (values->fMask & kGCTile)
      if ((values->fTile != kNone) && !(gcv->fMask & kGCTile)) return -1;
   if (gcv->fMask & kGCStipple)
      if ((gcv->fStipple != kNone) && !(values->fMask & kGCStipple)) return -1;
   if (values->fMask & kGCStipple)
      if ((values->fStipple != kNone) && !(gcv->fMask & kGCStipple)) return -1;
   for (bit = 1; bit <= common_bits; bit <<= 1) {
      switch (bit & common_bits) {
         default:
         case 0:
            continue;
         case kGCFunction:
            match = (values->fFunction == gcv->fFunction);
            break;
         case kGCPlaneMask:
            match = (values->fPlaneMask == gcv->fPlaneMask);
            break;
         case kGCForeground:
            match = (values->fForeground == gcv->fForeground);
            break;
         case kGCBackground:
            match = (values->fBackground == gcv->fBackground);
            break;
         case kGCLineWidth:
            match = (values->fLineWidth == gcv->fLineWidth);
            break;
         case kGCLineStyle:
            match = (values->fLineStyle == gcv->fLineStyle);
            break;
         case kGCCapStyle:
            match = (values->fCapStyle == gcv->fCapStyle);
            break;
         case kGCJoinStyle:
            match = (values->fJoinStyle == gcv->fJoinStyle);
            break;
         case kGCFillStyle:
            match = (values->fFillStyle == gcv->fFillStyle);
            break;
         case kGCFillRule:
            match = (values->fFillRule == gcv->fFillRule);
            break;
         case kGCTile:
            match = (values->fTile == gcv->fTile);
            break;
         case kGCStipple:
            match = (values->fStipple == gcv->fStipple);
            break;
         case kGCTileStipXOrigin:
            match = (values->fTsXOrigin == gcv->fTsXOrigin);
            break;
         case kGCTileStipYOrigin:
            match = (values->fTsYOrigin == gcv->fTsYOrigin);
            break;
         case kGCFont:
            match = (values->fFont == gcv->fFont);
            break;
         case kGCSubwindowMode:
            match = (values->fSubwindowMode == gcv->fSubwindowMode);
            break;
         case kGCGraphicsExposures:
            match = (values->fGraphicsExposures == gcv->fGraphicsExposures);
            break;
         case kGCClipXOrigin:
            match = (values->fClipXOrigin == gcv->fClipXOrigin);
            break;
         case kGCClipYOrigin:
            match = (values->fClipYOrigin == gcv->fClipYOrigin);
            break;
         case kGCClipMask:
            match = (values->fClipMask == gcv->fClipMask);
            break;
         case kGCDashOffset:
            match = (values->fDashOffset == gcv->fDashOffset);
            break;
         case kGCDashList:
            if (values->fDashLen == gcv->fDashLen)
               match = (strncmp(values->fDashes, gcv->fDashes, gcv->fDashLen) == 0);
            break;
         case kGCArcMode:
            match = (values->fArcMode == gcv->fArcMode);
            break;
      }
      if (!match)
         return -1;
      matching_bits++;
      match = kFALSE;
   }
   return matching_bits;
}
void TGGCPool::UpdateGC(TGGC *gc, GCValues_t *values)
{
   
   gc->SetAttributes(values);
}
void TGGCPool::Print(Option_t *) const
{
   
   fList->Print();
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.