TGGC.cxx

Go to the documentation of this file.
00001 // @(#)root/gui:$Id: TGGC.cxx 34286 2010-07-01 20:38:57Z rdm $
00002 // Author: Fons Rademakers   20/9/2000
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 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TGGC and TGGCPool                                                    //
00015 //                                                                      //
00016 // Encapsulate a graphics context used in the low level graphics.       //
00017 // TGGCPool provides a pool of graphics contexts.                       //
00018 //                                                                      //
00019 //////////////////////////////////////////////////////////////////////////
00020 
00021 #include "TGClient.h"
00022 #include "TGGC.h"
00023 #include "TVirtualX.h"
00024 #include "THashTable.h"
00025 #include "TColor.h"
00026 #include "TROOT.h"
00027 #include "Riostream.h"
00028 #include <string.h>
00029 
00030 
00031 ClassImp(TGGC)
00032 
00033 //______________________________________________________________________________
00034 TGGC::TGGC(GCValues_t *values, Bool_t)
00035 {
00036    // Create a graphics context (only called via TGGCPool::GetGC()).
00037 
00038    fContext = 0;
00039    if (values) {
00040       fValues = *values;
00041       fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
00042       if (values->fMask & kGCDashList) {
00043          if (values->fDashLen > (Int_t)sizeof(fValues.fDashes))
00044             Warning("TGGC", "dash list can have only up to %ld elements",
00045                     (Long_t)sizeof(fValues.fDashes));
00046          fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)sizeof(fValues.fDashes));
00047          gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
00048                               fValues.fDashLen);
00049       }
00050    } else {
00051       memset(&fValues, 0, sizeof(GCValues_t));
00052       fContext = 0;
00053    }
00054    SetRefCount(1);
00055 }
00056 
00057 //______________________________________________________________________________
00058 TGGC::TGGC(GCValues_t *values)
00059 {
00060    // Create a graphics context, registers GC in GCPool.
00061 
00062    fContext = 0;
00063    // case of default ctor at program startup before gClient exists
00064    if (!values) {
00065       memset(&fValues, 0, sizeof(GCValues_t));
00066       fContext = 0;
00067       SetRefCount(1);
00068       return;
00069    }
00070 
00071    if (gClient)
00072       gClient->GetGC(values, kTRUE);
00073    else {
00074       fContext = 0;
00075       Error("TGGC", "TGClient not yet initialized, should never happen");
00076    }
00077 }
00078 
00079 //______________________________________________________________________________
00080 TGGC::TGGC(const TGGC &g) : TObject(g), TRefCnt()
00081 {
00082    // Copy a graphics context.
00083 
00084    fValues = g.fValues;
00085    if (g.fContext) {
00086       fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
00087       if (fValues.fMask & kGCDashList)
00088          gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
00089                               fValues.fDashLen);
00090    } else
00091       fContext = 0;
00092    SetRefCount(1);
00093 
00094    if (gClient)
00095       gClient->GetGCPool()->fList->Add(this);
00096 }
00097 
00098 //______________________________________________________________________________
00099 TGGC::~TGGC()
00100 {
00101    // Delete graphics context.
00102 
00103    if (gClient)
00104       gClient->GetGCPool()->ForceFreeGC(this);
00105 
00106    if (fContext)
00107       gVirtualX->DeleteGC(fContext);
00108 }
00109 
00110 //______________________________________________________________________________
00111 TGGC &TGGC::operator=(const TGGC &rhs)
00112 {
00113    // Graphics context assignment operator.
00114 
00115    if (this != &rhs) {
00116       if (!fContext && gClient) {
00117          TGGC *gc = gClient->GetGCPool()->FindGC(this);
00118          if (!gc)
00119             gClient->GetGCPool()->fList->Add(this);
00120       }
00121       if (fContext)
00122          gVirtualX->DeleteGC(fContext);
00123       TObject::operator=(rhs);
00124       fValues  = rhs.fValues;
00125       fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
00126       if (fValues.fMask & kGCDashList)
00127          gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
00128                               fValues.fDashLen);
00129    }
00130    return *this;
00131 }
00132 
00133 //______________________________________________________________________________
00134 GContext_t TGGC::operator()() const
00135 {
00136    // Not inline due to a bug in g++ 2.96 20000731 (Red Hat Linux 7.0).
00137 
00138    return fContext;
00139 }
00140 
00141 //______________________________________________________________________________
00142 void TGGC::UpdateValues(GCValues_t *values)
00143 {
00144    // Update values + mask.
00145 
00146    fValues.fMask |= values->fMask;
00147 
00148    for (Mask_t bit = 1; bit <= fValues.fMask; bit <<= 1) {
00149       switch (bit & values->fMask) {
00150          default:
00151          case 0:
00152             continue;
00153          case kGCFunction:
00154             fValues.fFunction = values->fFunction;
00155             break;
00156          case kGCPlaneMask:
00157             fValues.fPlaneMask = values->fPlaneMask;
00158             break;
00159          case kGCForeground:
00160             fValues.fForeground = values->fForeground;
00161             break;
00162          case kGCBackground:
00163             fValues.fBackground = values->fBackground;
00164             break;
00165          case kGCLineWidth:
00166             fValues.fLineWidth = values->fLineWidth;
00167             break;
00168          case kGCLineStyle:
00169             fValues.fLineStyle = values->fLineStyle;
00170             break;
00171          case kGCCapStyle:
00172             fValues.fCapStyle = values->fCapStyle;
00173             break;
00174          case kGCJoinStyle:
00175             fValues.fJoinStyle = values->fJoinStyle;
00176             break;
00177          case kGCFillStyle:
00178             fValues.fFillStyle = values->fFillStyle;
00179             break;
00180          case kGCFillRule:
00181             fValues.fFillRule = values->fFillRule;
00182             break;
00183          case kGCTile:
00184             fValues.fTile = values->fTile;
00185             break;
00186          case kGCStipple:
00187             fValues.fStipple = values->fStipple;
00188             break;
00189          case kGCTileStipXOrigin:
00190             fValues.fTsXOrigin = values->fTsXOrigin;
00191             break;
00192          case kGCTileStipYOrigin:
00193             fValues.fTsYOrigin = values->fTsYOrigin;
00194             break;
00195          case kGCFont:
00196             fValues.fFont = values->fFont;
00197             break;
00198          case kGCSubwindowMode:
00199             fValues.fSubwindowMode = values->fSubwindowMode;
00200             break;
00201          case kGCGraphicsExposures:
00202             fValues.fGraphicsExposures = values->fGraphicsExposures;
00203             break;
00204          case kGCClipXOrigin:
00205             fValues.fClipXOrigin = values->fClipXOrigin;
00206             break;
00207          case kGCClipYOrigin:
00208             fValues.fClipYOrigin = values->fClipYOrigin;
00209             break;
00210          case kGCClipMask:
00211             fValues.fClipMask = values->fClipMask;
00212             break;
00213          case kGCDashOffset:
00214             fValues.fDashOffset = values->fDashOffset;
00215             break;
00216          case kGCDashList:
00217             if (values->fDashLen > (Int_t)sizeof(fValues.fDashes))
00218                Warning("UpdateValues", "dash list can have only up to %ld elements",
00219                        (Long_t)sizeof(fValues.fDashes));
00220             fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)sizeof(fValues.fDashes));
00221             memcpy(fValues.fDashes, values->fDashes, fValues.fDashLen);
00222             break;
00223          case kGCArcMode:
00224             fValues.fArcMode = values->fArcMode;
00225             break;
00226       }
00227    }
00228 }
00229 
00230 //______________________________________________________________________________
00231 void TGGC::SetAttributes(GCValues_t *values)
00232 {
00233    // Set attributes as specified in the values structure.
00234 
00235    if (!fContext && gClient) {
00236       TGGC *gc = gClient->GetGCPool()->FindGC(this);
00237       if (!gc)
00238          gClient->GetGCPool()->fList->Add(this);
00239    }
00240 
00241    if (fContext)
00242       gVirtualX->ChangeGC(fContext, values);
00243    else
00244       fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
00245    UpdateValues(values);
00246    if (values->fMask & kGCDashList)
00247       gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
00248                            fValues.fDashLen);
00249 }
00250 
00251 //______________________________________________________________________________
00252 void TGGC::SetFunction(EGraphicsFunction v)
00253 {
00254    // Set graphics context drawing function.
00255 
00256    GCValues_t values;
00257    values.fFunction = v;
00258    values.fMask     = kGCFunction;
00259    SetAttributes(&values);
00260 }
00261 
00262 //______________________________________________________________________________
00263 void TGGC::SetPlaneMask(ULong_t v)
00264 {
00265    // Set plane mask.
00266 
00267    GCValues_t values;
00268    values.fPlaneMask = v;
00269    values.fMask      = kGCPlaneMask;
00270    SetAttributes(&values);
00271 }
00272 
00273 //______________________________________________________________________________
00274 void TGGC::SetForeground(ULong_t v)
00275 {
00276    // Set foreground color.
00277 
00278    GCValues_t values;
00279    values.fForeground = v;
00280    values.fMask       = kGCForeground;
00281    SetAttributes(&values);
00282 }
00283 
00284 //______________________________________________________________________________
00285 void TGGC::SetBackground(ULong_t v)
00286 {
00287    // Set background color.
00288 
00289    GCValues_t values;
00290    values.fBackground = v;
00291    values.fMask       = kGCBackground;
00292    SetAttributes(&values);
00293 }
00294 
00295 //______________________________________________________________________________
00296 void TGGC::SetLineWidth(Int_t v)
00297 {
00298    // Set line width.
00299 
00300    GCValues_t values;
00301    values.fLineWidth = v;
00302    values.fMask      = kGCLineWidth;
00303    SetAttributes(&values);
00304 }
00305 
00306 //______________________________________________________________________________
00307 void TGGC::SetLineStyle(Int_t v)
00308 {
00309    // Set line style (kLineSolid, kLineOnOffDash, kLineDoubleDash).
00310 
00311    GCValues_t values;
00312    values.fLineStyle = v;
00313    values.fMask      = kGCLineStyle;
00314    SetAttributes(&values);
00315 }
00316 
00317 //______________________________________________________________________________
00318 void TGGC::SetCapStyle(Int_t v)
00319 {
00320    // Set cap style (kCapNotLast, kCapButt, kCapRound, kCapProjecting).
00321 
00322    GCValues_t values;
00323    values.fCapStyle = v;
00324    values.fMask     = kGCCapStyle;
00325    SetAttributes(&values);
00326 }
00327 
00328 //______________________________________________________________________________
00329 void TGGC::SetJoinStyle(Int_t v)
00330 {
00331    // Set line join style (kJoinMiter, kJoinRound, kJoinBevel).
00332 
00333    GCValues_t values;
00334    values.fJoinStyle = v;
00335    values.fMask      = kGCJoinStyle;
00336    SetAttributes(&values);
00337 }
00338 
00339 //______________________________________________________________________________
00340 void TGGC::SetFillStyle(Int_t v)
00341 {
00342    // Set fill style (kFillSolid, kFillTiled, kFillStippled,
00343    // kFillOpaeueStippled).
00344 
00345    GCValues_t values;
00346    values.fFillStyle = v;
00347    values.fMask      = kGCFillStyle;
00348    SetAttributes(&values);
00349 }
00350 
00351 //______________________________________________________________________________
00352 void TGGC::SetFillRule(Int_t v)
00353 {
00354    // Set fill rule (kEvenOddRule, kWindingRule).
00355 
00356    GCValues_t values;
00357    values.fFillRule = v;
00358    values.fMask     = kGCFillRule;
00359    SetAttributes(&values);
00360 }
00361 
00362 //______________________________________________________________________________
00363 void TGGC::SetTile(Pixmap_t v)
00364 {
00365    // Set tile pixmap for tiling operations.
00366 
00367    GCValues_t values;
00368    values.fTile = v;
00369    values.fMask = kGCTile;
00370    SetAttributes(&values);
00371 }
00372 
00373 //______________________________________________________________________________
00374 void TGGC::SetStipple(Pixmap_t v)
00375 {
00376    // Set 1 plane pixmap for stippling.
00377 
00378    GCValues_t values;
00379    values.fStipple = v;
00380    values.fMask    = kGCStipple;
00381    SetAttributes(&values);
00382 }
00383 
00384 //______________________________________________________________________________
00385 void TGGC::SetTileStipXOrigin(Int_t v)
00386 {
00387    // X offset for tile or stipple operations.
00388 
00389    GCValues_t values;
00390    values.fTsXOrigin = v;
00391    values.fMask      = kGCTileStipXOrigin;
00392    SetAttributes(&values);
00393 }
00394 
00395 //______________________________________________________________________________
00396 void TGGC::SetTileStipYOrigin(Int_t v)
00397 {
00398    // Y offset for tile or stipple operations.
00399 
00400    GCValues_t values;
00401    values.fTsYOrigin = v;
00402    values.fMask      = kGCTileStipYOrigin;
00403    SetAttributes(&values);
00404 }
00405 
00406 //______________________________________________________________________________
00407 void TGGC::SetFont(FontH_t v)
00408 {
00409    // Set font.
00410 
00411    GCValues_t values;
00412    values.fFont = v;
00413    values.fMask = kGCFont;
00414    SetAttributes(&values);
00415 }
00416 
00417 //______________________________________________________________________________
00418 void TGGC::SetSubwindowMode(Int_t v)
00419 {
00420    // Set sub window mode (kClipByChildren, kIncludeInferiors).
00421 
00422    GCValues_t values;
00423    values.fSubwindowMode = v;
00424    values.fMask          = kGCSubwindowMode;
00425    SetAttributes(&values);
00426 }
00427 
00428 //______________________________________________________________________________
00429 void TGGC::SetGraphicsExposures(Bool_t v)
00430 {
00431    // True if graphics exposure should be generated.
00432 
00433    GCValues_t values;
00434    values.fGraphicsExposures = v;
00435    values.fMask              = kGCGraphicsExposures;
00436    SetAttributes(&values);
00437 }
00438 
00439 //______________________________________________________________________________
00440 void TGGC::SetClipXOrigin(Int_t v)
00441 {
00442    // X origin for clipping.
00443 
00444    GCValues_t values;
00445    values.fClipXOrigin = v;
00446    values.fMask        = kGCClipXOrigin;
00447    SetAttributes(&values);
00448 }
00449 
00450 //______________________________________________________________________________
00451 void TGGC::SetClipYOrigin(Int_t v)
00452 {
00453    // Y origin for clipping.
00454 
00455    GCValues_t values;
00456    values.fClipYOrigin = v;
00457    values.fMask        = kGCClipYOrigin;
00458    SetAttributes(&values);
00459 }
00460 
00461 //______________________________________________________________________________
00462 void TGGC::SetClipMask(Pixmap_t v)
00463 {
00464    // Bitmap for clipping.
00465 
00466    GCValues_t values;
00467    values.fClipMask = v;
00468    values.fMask     = kGCClipMask;
00469    SetAttributes(&values);
00470 }
00471 
00472 //______________________________________________________________________________
00473 void TGGC::SetDashOffset(Int_t v)
00474 {
00475    // Patterned/dashed line offset.
00476 
00477    GCValues_t values;
00478    values.fDashOffset = v;
00479    values.fMask       = kGCDashOffset;
00480    SetAttributes(&values);
00481 }
00482 
00483 //______________________________________________________________________________
00484 void TGGC::SetDashList(const char v[], Int_t len)
00485 {
00486    // Set dash pattern. First use SetDashOffset() if not 0.
00487 
00488    GCValues_t values;
00489    if (len > (Int_t)sizeof(values.fDashes))
00490       Warning("SetDashList", "dash list can have only up to %ld elements",
00491               (Long_t)sizeof(values.fDashes));
00492    values.fDashLen = TMath::Min(len, (Int_t)sizeof(values.fDashes));
00493    memcpy(values.fDashes, v, values.fDashLen);
00494    values.fMask    = kGCDashList;
00495    SetAttributes(&values);
00496 }
00497 
00498 //______________________________________________________________________________
00499 void TGGC::SetArcMode(Int_t v)
00500 {
00501    // Set arc mode (kArcChord, kArcPieSlice).
00502 
00503    GCValues_t values;
00504    values.fArcMode = v;
00505    values.fMask    = kGCArcMode;
00506    SetAttributes(&values);
00507 }
00508 
00509 //______________________________________________________________________________
00510 void TGGC::Print(Option_t *) const
00511 {
00512    // Print graphics contexts info.
00513 
00514    Printf("TGGC: mask = %x, handle = %lx, ref cnt = %u", fValues.fMask,
00515           fContext, References());
00516 }
00517 
00518 //______________________________________________________________________________
00519 TString TGGC::GetMaskString() const
00520 {
00521    // Returns GC mask as a string - used in SavePrimitive().
00522 
00523    TString mask;
00524 
00525    Mask_t fmask = GetMask();
00526 
00527    if (fmask & kGCFunction) {
00528       if (mask.Length() == 0) mask  = "kGCFunction";
00529       else                    mask += " | kGCFunction";
00530    }
00531    if (fmask & kGCPlaneMask) {
00532       if (mask.Length() == 0) mask  = "kGCPlaneMask";
00533       else                    mask += " | kGCPlaneMask";
00534    }
00535    if (fmask & kGCForeground) {
00536       if (mask.Length() == 0) mask  = "kGCForeground";
00537       else                    mask += " | kGCForeground";
00538    }
00539    if (fmask & kGCBackground) {
00540       if (mask.Length() == 0) mask  = "kGCBackground";
00541       else                    mask += " | kGCBackground";
00542    }
00543    if (fmask & kGCLineWidth) {
00544       if (mask.Length() == 0) mask  = "kGCLineWidth";
00545       else                    mask += " | kGCLineWidth";
00546    }
00547    if (fmask & kGCLineStyle) {
00548       if (mask.Length() == 0) mask  = "kGCLineStyle";
00549       else                    mask += " | kGCLineStyle";
00550    }
00551    if (fmask & kGCCapStyle) {
00552       if (mask.Length() == 0) mask  = "kGCCapStyle";
00553       else                    mask += " | kGCCapStyle";
00554    }
00555    if (fmask & kGCJoinStyle) {
00556       if (mask.Length() == 0) mask  = "kGCJoinStyle";
00557       else                    mask += " | kGCJoinStyle";
00558    }
00559    if (fmask & kGCFillStyle) {
00560       if (mask.Length() == 0) mask  = "kGCFillStyle";
00561       else                    mask += " | kGCFillStyle";
00562    }
00563    if (fmask & kGCFillRule) {
00564       if (mask.Length() == 0) mask  = "kGCFillRule";
00565       else                    mask += " | kGCFillRule";
00566    }
00567    if (fmask & kGCTile) {
00568       if (mask.Length() == 0) mask  = "kGCTile";
00569       else                    mask += " | kGCTile";
00570    }
00571    if (fmask & kGCStipple) {
00572       if (mask.Length() == 0) mask  = "kGCStipple";
00573       else                    mask += " | kGCStipple";
00574    }
00575    if (fmask & kGCTileStipXOrigin) {
00576       if (mask.Length() == 0) mask  = "kGCTileStipXOrigin";
00577       else                    mask += " | kGCTileStipXOrigin";
00578    }
00579    if (fmask & kGCTileStipYOrigin) {
00580       if (mask.Length() == 0) mask  = "kGCTileStipYOrigin";
00581       else                    mask += " | kGCTileStipYOrigin";
00582    }
00583    if (fmask & kGCFont) {
00584       if (mask.Length() == 0) mask  = "kGCFont";
00585       else                    mask += " | kGCFont";
00586    }
00587    if (fmask & kGCSubwindowMode) {
00588       if (mask.Length() == 0) mask  = "kGCSubwindowMode";
00589       else                    mask += " | kGCSubwindowMode";
00590    }
00591    if (fmask & kGCGraphicsExposures) {
00592       if (mask.Length() == 0) mask  = "kGCGraphicsExposures";
00593       else                    mask += " | kGCGraphicsExposures";
00594    }
00595    if (fmask & kGCClipXOrigin) {
00596       if (mask.Length() == 0) mask  = "kGCClipXOrigin";
00597       else                    mask += " | kGCClipXOrigin";
00598    }
00599    if (fmask & kGCClipYOrigin) {
00600       if (mask.Length() == 0) mask  = "kGCClipYOrigin";
00601       else                    mask += " | kGCClipYOrigin";
00602    }
00603    if (fmask & kGCClipMask) {
00604       if (mask.Length() == 0) mask  = "kGCClipMask";
00605       else                    mask += " | kGCClipMask";
00606    }
00607    if (fmask & kGCDashOffset) {
00608       if (mask.Length() == 0) mask  = "kGCDashOffset";
00609       else                    mask += " | kGCDashOffset";
00610    }
00611    if (fmask & kGCDashList) {
00612       if (mask.Length() == 0) mask  = "kGCDashList";
00613       else                    mask += " | kGCDashList";
00614    }
00615    if (fmask & kGCArcMode) {
00616       if (mask.Length() == 0) mask  = "kGCArcMode";
00617       else                    mask += " | kGCArcMode";
00618    }
00619    return mask;
00620 }
00621 
00622 //______________________________________________________________________________
00623 void TGGC::SavePrimitive(ostream &out, Option_t *option /*= ""*/)
00624 {
00625    // Save graphics context info as a C++ statement(s) on output stream out
00626 
00627    if (gROOT->ClassSaved(TGGC::Class())) {
00628       out << endl;
00629    } else {
00630       //  declare graphics context object to reflect required user changes
00631       out << endl;
00632       out << "   TGGC   *uGC;           // will reflect user GC changes" << endl;
00633    }
00634 
00635    Mask_t fmask = GetMask();
00636 
00637    const char *colorname;
00638    TString valname;
00639    char quote ='"';
00640    ULong_t color;
00641 
00642    valname = TString::Format("val%s", option);
00643 
00644    out << "   // graphics context changes" << endl;
00645    //out << "   TGGC *uGC" << option << ";" << endl;
00646    out << "   GCValues_t " << valname.Data() << ";" << endl;
00647    out << "   " << valname.Data() << ".fMask = " << GetMaskString() << ";" << endl;
00648 
00649    for (Mask_t bit = 1; bit <= fmask; bit <<= 1) {
00650       switch (bit & fmask) {
00651          default:
00652          case 0:
00653             continue;
00654          case kGCFunction:
00655             out << "   " << valname.Data() << ".fFunction = ";
00656             switch (GetFunction()) {
00657                case kGXclear:
00658                   out << "kGXclear";
00659                   break;
00660                case kGXand:
00661                   out << "kGXand";
00662                   break;
00663                case kGXandReverse:
00664                   out << "kGXandReverse";
00665                   break;
00666                case kGXcopy:
00667                   out << "kGXcopy";
00668                   break;
00669                case kGXandInverted:
00670                   out << "kGXandInverted";
00671                   break;
00672                case kGXnoop:
00673                   out << "kGXnoop";
00674                   break;
00675                case kGXxor:
00676                   out << "kGXxor";
00677                   break;
00678                case kGXor:
00679                   out << "kGXor";
00680                   break;
00681                case kGXnor:
00682                   out << "kGXnor";
00683                   break;
00684                case kGXequiv:
00685                   out << "kGXequiv";
00686                   break;
00687                case kGXinvert:
00688                   out << "kGXinvert";
00689                   break;
00690                case kGXorReverse:
00691                   out << "kGXorReverse";
00692                   break;
00693                case kGXcopyInverted:
00694                   out << "kGXcopyInverted";
00695                   break;
00696                case kGXorInverted:
00697                   out << "kGXorInverted";
00698                   break;
00699                case kGXnand:
00700                   out << "kGXnand";
00701                   break;
00702                case kGXset:
00703                   out << "kGXset";
00704                   break;
00705             }
00706             out << ";" << endl;
00707             break;
00708          case kGCPlaneMask:
00709             out << "   " << valname.Data() << ".fPlaneMask = " << GetPlaneMask() << ";" << endl;
00710             break;
00711          case kGCForeground:
00712             color = GetForeground();
00713             colorname = TColor::PixelAsHexString(color);
00714             out << "   gClient->GetColorByName(" << quote << colorname << quote
00715                 << "," << valname.Data() << ".fForeground);" << endl;
00716             break;
00717          case kGCBackground:
00718             color = GetBackground();
00719             colorname = TColor::PixelAsHexString(color);
00720             out << "   gClient->GetColorByName(" << quote << colorname << quote
00721                 << "," << valname.Data() << ".fBackground);" << endl;
00722             break;
00723          case kGCLineWidth:
00724             out << "   " << valname.Data() << ".fLineWidth = " << GetLineWidth() << ";" << endl;
00725             break;
00726          case kGCLineStyle:
00727             out << "   " << valname.Data() << ".fLineStyle = ";
00728             switch (GetLineStyle()) {
00729                case kLineSolid:
00730                   out << "kLineSolid";
00731                   break;
00732                case kLineOnOffDash:
00733                   out << "kLineOnOffDash";
00734                   break;
00735                case kLineDoubleDash:
00736                   out << "kLineDoubleDash";
00737                   break;
00738             }
00739             out << ";" << endl;
00740             break;
00741          case kGCCapStyle:
00742             out << "   " << valname.Data() << ".fCapStyle = ";
00743             switch (GetCapStyle()) {
00744                case kCapNotLast:
00745                   out << "kCapNotLast";
00746                   break;
00747                case kCapButt:
00748                   out << "kCapButt";
00749                   break;
00750                case kCapRound:
00751                   out << "kCapRound";
00752                   break;
00753                case kCapProjecting:
00754                   out << "kCapProjecting";
00755                   break;
00756             }
00757             out << ";" << endl;
00758             break;
00759          case kGCJoinStyle:
00760             out << "   " << valname.Data() << ".fJoinStyle = ";
00761             switch (GetJoinStyle()) {
00762                case kJoinMiter:
00763                   out << "kJoinMiter";
00764                   break;
00765                case kJoinRound:
00766                   out << "kJoinRound";
00767                   break;
00768                case kJoinBevel:
00769                   out << "kJoinBevel";
00770                   break;
00771             }
00772             out << ";" << endl;
00773             break;
00774          case kGCFillStyle:
00775             out << "   " << valname.Data() << ".fFillStyle = ";
00776             switch (GetFillStyle()) {
00777                case kFillSolid:
00778                   out << "kFillSolid";
00779                   break;
00780                case kFillTiled:
00781                   out << "kFillTiled";
00782                   break;
00783                case kFillStippled:
00784                   out << "kFillStippled";
00785                   break;
00786                case kFillOpaqueStippled:
00787                   out << "kFillOpaqueStippled";
00788                   break;
00789             }
00790             out << ";" << endl;
00791             break;
00792          case kGCFillRule:
00793             out << "   " << valname.Data() << ".fFillRule = ";
00794             switch (GetFillRule()) {
00795                case kEvenOddRule:
00796                   out << "kEvenOddRule";
00797                   break;
00798                case kWindingRule:
00799                   out << "kWindingRule";
00800                   break;
00801             }
00802             out << ";" << endl;
00803             break;
00804          case kGCTile:
00805             out << "   " << valname.Data() << ".fTile = " << GetTile() << ";" << endl;
00806             break;
00807          case kGCStipple:
00808             out << "   " << valname.Data() << ".fStipple = " << GetStipple() << ";" << endl;
00809             break;
00810          case kGCTileStipXOrigin:
00811             out << "   " << valname.Data() << ".fTsXOrigin = " << GetTileStipXOrigin() << ";" << endl;
00812             break;
00813          case kGCTileStipYOrigin:
00814             out << "   " << valname.Data() << ".fTsYOrigin = " << GetTileStipYOrigin() << ";" << endl;
00815             break;
00816          case kGCFont:
00817             out << "   " << valname.Data() << ".fFont = ufont->GetFontHandle();" << endl;
00818             break;
00819          case kGCSubwindowMode:
00820             out << "   " << valname.Data() << ".fSubwindowMode = ";
00821             switch (GetSubwindowMode()) {
00822                case kClipByChildren:
00823                   out << "kClipByChildren";
00824                   break;
00825                case kIncludeInferiors:
00826                   out << "kIncludeInferiors";
00827                   break;
00828             }
00829             out << ";" << endl;
00830             break;
00831          case kGCGraphicsExposures:
00832             out << "   " << valname.Data() << ".fGraphicsExposures = ";
00833             if (GetGraphicsExposures())
00834                out << "kTRUE";
00835             else
00836                out << "kFALSE";
00837             out << ";" << endl;
00838             break;
00839          case kGCClipXOrigin:
00840             out << "   " << valname.Data() << ".fClipXOrigin = " << GetClipXOrigin() << ";" << endl;
00841             break;
00842          case kGCClipYOrigin:
00843             out << "   " << valname.Data() << ".fClipYOrigin = " << GetClipYOrigin() << ";" << endl;
00844             break;
00845          case kGCClipMask:
00846             out << "   " << valname.Data() << ".fClipMask = " << GetClipMask() << ";" << endl;
00847             break;
00848          case kGCDashOffset:
00849             out << "   " << valname.Data() << ".fDashOffset = " << GetDashOffset() << ";" << endl;
00850             break;
00851          case kGCDashList:
00852             if (GetDashLen() > (Int_t)sizeof(GetDashes()))
00853                Warning("TGGC::SavePrimitive", "dash list can have only up to %ld elements",
00854                        (Long_t)sizeof(GetDashes()));
00855             out << "   " << valname.Data() << ".fDashLen = "
00856                 << TMath::Min(GetDashLen(),(Int_t)sizeof(GetDashes())) << ";" << endl;
00857             out << "   memcpy(GetDashes()," << valname.Data() << ".fDashes,"
00858                                             << valname.Data() << ".fDashLen);" << endl;
00859             break;
00860          case kGCArcMode:
00861             out << "   " << valname.Data() << ".fArcMode = ";
00862             switch (GetArcMode()) {
00863                case kArcChord:
00864                   out << "kArcChord";
00865                   break;
00866                case kArcPieSlice:
00867                   out << "kArcPieSlice";
00868                   break;
00869             }
00870             out << ";" << endl;
00871             break;
00872       }
00873    }
00874    out << "   uGC = gClient->GetGC(&" << valname.Data() << ", kTRUE);" << endl;
00875 }
00876 
00877 
00878 ClassImp(TGGCPool)
00879 
00880 //______________________________________________________________________________
00881 TGGCPool::TGGCPool(TGClient *client)
00882 {
00883    // Create graphics context pool.
00884 
00885    fClient = client;
00886    fList   = new THashTable;
00887    fList->SetOwner();
00888 }
00889 
00890 //______________________________________________________________________________
00891 TGGCPool::~TGGCPool()
00892 {
00893    // Delete graphics context pool.
00894 
00895    delete fList;
00896 }
00897 
00898 //______________________________________________________________________________
00899 void TGGCPool::ForceFreeGC(const TGGC *gct)
00900 {
00901    // Force remove graphics context from list. Is only called via ~TGGC().
00902 
00903    TGGC *gc = (TGGC *) fList->FindObject(gct);
00904 
00905    if (gc) {
00906       if (gc->References() > 1)
00907          Error("ForceFreeGC", "removed a shared graphics context\n"
00908                "best to use graphics contexts via the TGGCPool()");
00909       fList->Remove(gc);
00910    }
00911 }
00912 
00913 //______________________________________________________________________________
00914 void TGGCPool::FreeGC(const TGGC *gct)
00915 {
00916    // Delete graphics context if it is not used anymore.
00917 
00918    TGGC *gc = (TGGC *) fList->FindObject(gct);
00919 
00920    if (gc) {
00921       if (gc->RemoveReference() == 0) {
00922          fList->Remove(gc);
00923          delete gc;
00924       }
00925    }
00926 }
00927 
00928 //______________________________________________________________________________
00929 void TGGCPool::FreeGC(GContext_t gct)
00930 {
00931    // Delete graphics context if it is not used anymore.
00932 
00933    TIter next(fList);
00934 
00935    while (TGGC *gc = (TGGC *) next()) {
00936       if (gc->fContext == gct) {
00937          if (gc->RemoveReference() == 0) {
00938             fList->Remove(gc);
00939             delete gc;
00940             return;
00941          }
00942       }
00943    }
00944 }
00945 
00946 //______________________________________________________________________________
00947 TGGC *TGGCPool::FindGC(const TGGC *gct)
00948 {
00949    // Find graphics context. Returns 0 in case gc is not found.
00950 
00951    return (TGGC*) fList->FindObject(gct);
00952 }
00953 
00954 //______________________________________________________________________________
00955 TGGC *TGGCPool::FindGC(GContext_t gct)
00956 {
00957    // Find graphics context based on its GContext_t handle. Returns 0
00958    // in case gc is not found.
00959 
00960    TIter next(fList);
00961 
00962    while (TGGC *gc = (TGGC *) next()) {
00963       if (gc->fContext == gct)
00964          return gc;
00965    }
00966    return 0;
00967 }
00968 
00969 //______________________________________________________________________________
00970 TGGC *TGGCPool::GetGC(GContext_t gct)
00971 {
00972    // returns graphics context based on its GContext_t handle.
00973 
00974    GCValues_t gval;
00975    gVirtualX->GetGCValues(gct, gval);
00976    return GetGC(&gval, kTRUE);
00977 }
00978 
00979 //______________________________________________________________________________
00980 TGGC *TGGCPool::GetGC(GCValues_t *values, Bool_t rw)
00981 {
00982    // Get the best matching graphics context depending on values.
00983    // If rw is false only a readonly, not modifiable graphics context
00984    // is returned. If rw is true a new modifiable graphics context is
00985    // returned.
00986 
00987    TGGC *gc, *best_match = 0;
00988    Int_t matching_bits, best_matching_bits = -1;
00989    Bool_t exact = kFALSE;
00990 
00991    if (!values)
00992       rw = kTRUE;
00993 
00994    if (!rw) {
00995 
00996       // First, try to find an exact matching GC.
00997       // If no one found, then use the closest one.
00998 
00999       TIter next(fList);
01000 
01001       while ((gc = (TGGC *) next())) {
01002          matching_bits = MatchGC(gc, values);
01003          if (matching_bits > best_matching_bits) {
01004             best_matching_bits = matching_bits;
01005             best_match = gc;
01006             if ((gc->fValues.fMask & values->fMask) == values->fMask) {
01007                exact = kTRUE;
01008                break;
01009             }
01010          }
01011       }
01012 
01013       if (best_match) {
01014          if (gDebug > 0)
01015             Printf("<TGGCPool::GetGC>: %smatching GC found\n", exact ? "exact " : "");
01016          best_match->AddReference();
01017          if (!exact) {
01018             // add missing values to the best_match'ing GC...
01019             UpdateGC(best_match, values);
01020          }
01021          return best_match;
01022       }
01023    }
01024 
01025    gc = new TGGC(values, kTRUE);
01026 
01027    fList->Add(gc);
01028 
01029    return gc;
01030 }
01031 
01032 //______________________________________________________________________________
01033 Int_t TGGCPool::MatchGC(const TGGC *gc, GCValues_t *values)
01034 {
01035    // Try to find matching graphics context. On success returns the amount
01036    // of matching bits (which may be zero if masks have no common bits),
01037    // -1 on failure (when there are common bits but not a single match).
01038 
01039    Mask_t bit, common_bits;
01040    Int_t  matching_bits = -1;
01041    Bool_t match = kFALSE;
01042    const GCValues_t *gcv = &gc->fValues;
01043 
01044    common_bits = values->fMask & gcv->fMask;
01045 
01046    if (common_bits == 0) return 0;  // no common bits, a possible
01047                                     // candidate anyway.
01048 
01049    // Careful, check first the tile and stipple mask bits, as these
01050    // influence nearly all other GC functions... (do the same for
01051    // some other such bits as GCFunction, etc...). Perhaps we should
01052    // allow only exact GC matches.
01053 
01054    if (gcv->fMask & kGCTile)
01055       if ((gcv->fTile != kNone) && !(values->fMask & kGCTile)) return -1;
01056    if (values->fMask & kGCTile)
01057       if ((values->fTile != kNone) && !(gcv->fMask & kGCTile)) return -1;
01058    if (gcv->fMask & kGCStipple)
01059       if ((gcv->fStipple != kNone) && !(values->fMask & kGCStipple)) return -1;
01060    if (values->fMask & kGCStipple)
01061       if ((values->fStipple != kNone) && !(gcv->fMask & kGCStipple)) return -1;
01062 
01063    for (bit = 1; bit <= common_bits; bit <<= 1) {
01064       switch (bit & common_bits) {
01065          default:
01066          case 0:
01067             continue;
01068          case kGCFunction:
01069             match = (values->fFunction == gcv->fFunction);
01070             break;
01071          case kGCPlaneMask:
01072             match = (values->fPlaneMask == gcv->fPlaneMask);
01073             break;
01074          case kGCForeground:
01075             match = (values->fForeground == gcv->fForeground);
01076             break;
01077          case kGCBackground:
01078             match = (values->fBackground == gcv->fBackground);
01079             break;
01080          case kGCLineWidth:
01081             match = (values->fLineWidth == gcv->fLineWidth);
01082             break;
01083          case kGCLineStyle:
01084             match = (values->fLineStyle == gcv->fLineStyle);
01085             break;
01086          case kGCCapStyle:
01087             match = (values->fCapStyle == gcv->fCapStyle);
01088             break;
01089          case kGCJoinStyle:
01090             match = (values->fJoinStyle == gcv->fJoinStyle);
01091             break;
01092          case kGCFillStyle:
01093             match = (values->fFillStyle == gcv->fFillStyle);
01094             break;
01095          case kGCFillRule:
01096             match = (values->fFillRule == gcv->fFillRule);
01097             break;
01098          case kGCTile:
01099             match = (values->fTile == gcv->fTile);
01100             break;
01101          case kGCStipple:
01102             match = (values->fStipple == gcv->fStipple);
01103             break;
01104          case kGCTileStipXOrigin:
01105             match = (values->fTsXOrigin == gcv->fTsXOrigin);
01106             break;
01107          case kGCTileStipYOrigin:
01108             match = (values->fTsYOrigin == gcv->fTsYOrigin);
01109             break;
01110          case kGCFont:
01111             match = (values->fFont == gcv->fFont);
01112             break;
01113          case kGCSubwindowMode:
01114             match = (values->fSubwindowMode == gcv->fSubwindowMode);
01115             break;
01116          case kGCGraphicsExposures:
01117             match = (values->fGraphicsExposures == gcv->fGraphicsExposures);
01118             break;
01119          case kGCClipXOrigin:
01120             match = (values->fClipXOrigin == gcv->fClipXOrigin);
01121             break;
01122          case kGCClipYOrigin:
01123             match = (values->fClipYOrigin == gcv->fClipYOrigin);
01124             break;
01125          case kGCClipMask:
01126             match = (values->fClipMask == gcv->fClipMask);
01127             break;
01128          case kGCDashOffset:
01129             match = (values->fDashOffset == gcv->fDashOffset);
01130             break;
01131          case kGCDashList:
01132             if (values->fDashLen == gcv->fDashLen)
01133                match = (strncmp(values->fDashes, gcv->fDashes, gcv->fDashLen) == 0);
01134             break;
01135          case kGCArcMode:
01136             match = (values->fArcMode == gcv->fArcMode);
01137             break;
01138       }
01139       if (!match)
01140          return -1;
01141       matching_bits++;
01142       match = kFALSE;
01143    }
01144 
01145    return matching_bits;
01146 }
01147 
01148 //______________________________________________________________________________
01149 void TGGCPool::UpdateGC(TGGC *gc, GCValues_t *values)
01150 {
01151    // Update graphics context with the values spcified in values->fMask.
01152 
01153    gc->SetAttributes(values);
01154 }
01155 
01156 //______________________________________________________________________________
01157 void TGGCPool::Print(Option_t *) const
01158 {
01159    // List all graphics contexts in the pool.
01160 
01161    fList->Print();
01162 }

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