36 TGGC::TGGC(GCValues_t *values, Bool_t)
41 fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
42 if (values->fMask & kGCDashList) {
43 if (values->fDashLen > (Int_t)
sizeof(fValues.fDashes))
44 Warning(
"TGGC",
"dash list can have only up to %ld elements",
45 (Long_t)
sizeof(fValues.fDashes));
46 fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)
sizeof(fValues.fDashes));
47 gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
60 TGGC::TGGC(GCValues_t *values)
72 gClient->GetGC(values, kTRUE);
75 Error(
"TGGC",
"TGClient not yet initialized, should never happen");
82 TGGC::TGGC(
const TGGC &g) : TObject(g), TRefCnt()
86 fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
87 if (fValues.fMask & kGCDashList)
88 gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
95 gClient->GetGCPool()->fList->Add(
this);
104 gClient->GetGCPool()->ForceFreeGC(
this);
107 gVirtualX->DeleteGC(fContext);
113 TGGC &TGGC::operator=(
const TGGC &rhs)
116 if (!fContext && gClient) {
117 TGGC *gc = gClient->GetGCPool()->FindGC(
this);
119 gClient->GetGCPool()->fList->Add(
this);
122 gVirtualX->DeleteGC(fContext);
123 TObject::operator=(rhs);
124 fValues = rhs.fValues;
125 fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), &fValues);
126 if (fValues.fMask & kGCDashList)
127 gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
136 GContext_t TGGC::operator()()
const
144 void TGGC::UpdateValues(GCValues_t *values)
146 fValues.fMask |= values->fMask;
148 for (Mask_t bit = 1; bit <= fValues.fMask; bit <<= 1) {
149 switch (bit & values->fMask) {
154 fValues.fFunction = values->fFunction;
157 fValues.fPlaneMask = values->fPlaneMask;
160 fValues.fForeground = values->fForeground;
163 fValues.fBackground = values->fBackground;
166 fValues.fLineWidth = values->fLineWidth;
169 fValues.fLineStyle = values->fLineStyle;
172 fValues.fCapStyle = values->fCapStyle;
175 fValues.fJoinStyle = values->fJoinStyle;
178 fValues.fFillStyle = values->fFillStyle;
181 fValues.fFillRule = values->fFillRule;
184 fValues.fTile = values->fTile;
187 fValues.fStipple = values->fStipple;
189 case kGCTileStipXOrigin:
190 fValues.fTsXOrigin = values->fTsXOrigin;
192 case kGCTileStipYOrigin:
193 fValues.fTsYOrigin = values->fTsYOrigin;
196 fValues.fFont = values->fFont;
198 case kGCSubwindowMode:
199 fValues.fSubwindowMode = values->fSubwindowMode;
201 case kGCGraphicsExposures:
202 fValues.fGraphicsExposures = values->fGraphicsExposures;
205 fValues.fClipXOrigin = values->fClipXOrigin;
208 fValues.fClipYOrigin = values->fClipYOrigin;
211 fValues.fClipMask = values->fClipMask;
214 fValues.fDashOffset = values->fDashOffset;
217 if (values->fDashLen > (Int_t)
sizeof(fValues.fDashes))
218 Warning(
"UpdateValues",
"dash list can have only up to %ld elements",
219 (Long_t)
sizeof(fValues.fDashes));
220 fValues.fDashLen = TMath::Min(values->fDashLen, (Int_t)
sizeof(fValues.fDashes));
221 memcpy(fValues.fDashes, values->fDashes, fValues.fDashLen);
224 fValues.fArcMode = values->fArcMode;
233 void TGGC::SetAttributes(GCValues_t *values)
235 if (!fContext && gClient) {
236 TGGC *gc = gClient->GetGCPool()->FindGC(
this);
238 gClient->GetGCPool()->fList->Add(
this);
242 gVirtualX->ChangeGC(fContext, values);
244 fContext = gVirtualX->CreateGC(gVirtualX->GetDefaultRootWindow(), values);
245 UpdateValues(values);
246 if (values->fMask & kGCDashList)
247 gVirtualX->SetDashes(fContext, fValues.fDashOffset, fValues.fDashes,
254 void TGGC::SetFunction(EGraphicsFunction v)
257 values.fFunction = v;
258 values.fMask = kGCFunction;
259 SetAttributes(&values);
265 void TGGC::SetPlaneMask(ULong_t v)
268 values.fPlaneMask = v;
269 values.fMask = kGCPlaneMask;
270 SetAttributes(&values);
276 void TGGC::SetForeground(ULong_t v)
279 values.fForeground = v;
280 values.fMask = kGCForeground;
281 SetAttributes(&values);
287 void TGGC::SetBackground(ULong_t v)
290 values.fBackground = v;
291 values.fMask = kGCBackground;
292 SetAttributes(&values);
298 void TGGC::SetLineWidth(Int_t v)
301 values.fLineWidth = v;
302 values.fMask = kGCLineWidth;
303 SetAttributes(&values);
309 void TGGC::SetLineStyle(Int_t v)
312 values.fLineStyle = v;
313 values.fMask = kGCLineStyle;
314 SetAttributes(&values);
320 void TGGC::SetCapStyle(Int_t v)
323 values.fCapStyle = v;
324 values.fMask = kGCCapStyle;
325 SetAttributes(&values);
331 void TGGC::SetJoinStyle(Int_t v)
334 values.fJoinStyle = v;
335 values.fMask = kGCJoinStyle;
336 SetAttributes(&values);
343 void TGGC::SetFillStyle(Int_t v)
346 values.fFillStyle = v;
347 values.fMask = kGCFillStyle;
348 SetAttributes(&values);
354 void TGGC::SetFillRule(Int_t v)
357 values.fFillRule = v;
358 values.fMask = kGCFillRule;
359 SetAttributes(&values);
365 void TGGC::SetTile(Pixmap_t v)
369 values.fMask = kGCTile;
370 SetAttributes(&values);
376 void TGGC::SetStipple(Pixmap_t v)
380 values.fMask = kGCStipple;
381 SetAttributes(&values);
387 void TGGC::SetTileStipXOrigin(Int_t v)
390 values.fTsXOrigin = v;
391 values.fMask = kGCTileStipXOrigin;
392 SetAttributes(&values);
398 void TGGC::SetTileStipYOrigin(Int_t v)
401 values.fTsYOrigin = v;
402 values.fMask = kGCTileStipYOrigin;
403 SetAttributes(&values);
409 void TGGC::SetFont(FontH_t v)
413 values.fMask = kGCFont;
414 SetAttributes(&values);
420 void TGGC::SetSubwindowMode(Int_t v)
423 values.fSubwindowMode = v;
424 values.fMask = kGCSubwindowMode;
425 SetAttributes(&values);
431 void TGGC::SetGraphicsExposures(Bool_t v)
434 values.fGraphicsExposures = v;
435 values.fMask = kGCGraphicsExposures;
436 SetAttributes(&values);
442 void TGGC::SetClipXOrigin(Int_t v)
445 values.fClipXOrigin = v;
446 values.fMask = kGCClipXOrigin;
447 SetAttributes(&values);
453 void TGGC::SetClipYOrigin(Int_t v)
456 values.fClipYOrigin = v;
457 values.fMask = kGCClipYOrigin;
458 SetAttributes(&values);
464 void TGGC::SetClipMask(Pixmap_t v)
467 values.fClipMask = v;
468 values.fMask = kGCClipMask;
469 SetAttributes(&values);
475 void TGGC::SetDashOffset(Int_t v)
478 values.fDashOffset = v;
479 values.fMask = kGCDashOffset;
480 SetAttributes(&values);
486 void TGGC::SetDashList(
const char v[], Int_t len)
489 if (len > (Int_t)
sizeof(values.fDashes))
490 Warning(
"SetDashList",
"dash list can have only up to %ld elements",
491 (Long_t)
sizeof(values.fDashes));
492 values.fDashLen = TMath::Min(len, (Int_t)
sizeof(values.fDashes));
493 memcpy(values.fDashes, v, values.fDashLen);
494 values.fMask = kGCDashList;
495 SetAttributes(&values);
501 void TGGC::SetArcMode(Int_t v)
505 values.fMask = kGCArcMode;
506 SetAttributes(&values);
512 void TGGC::Print(Option_t *)
const
514 Printf(
"TGGC: mask = %x, handle = %lx, ref cnt = %u", fValues.fMask,
515 fContext, References());
521 TString TGGC::GetMaskString()
const
525 Mask_t fmask = GetMask();
527 if (fmask & kGCFunction) {
528 if (mask.Length() == 0) mask =
"kGCFunction";
529 else mask +=
" | kGCFunction";
531 if (fmask & kGCPlaneMask) {
532 if (mask.Length() == 0) mask =
"kGCPlaneMask";
533 else mask +=
" | kGCPlaneMask";
535 if (fmask & kGCForeground) {
536 if (mask.Length() == 0) mask =
"kGCForeground";
537 else mask +=
" | kGCForeground";
539 if (fmask & kGCBackground) {
540 if (mask.Length() == 0) mask =
"kGCBackground";
541 else mask +=
" | kGCBackground";
543 if (fmask & kGCLineWidth) {
544 if (mask.Length() == 0) mask =
"kGCLineWidth";
545 else mask +=
" | kGCLineWidth";
547 if (fmask & kGCLineStyle) {
548 if (mask.Length() == 0) mask =
"kGCLineStyle";
549 else mask +=
" | kGCLineStyle";
551 if (fmask & kGCCapStyle) {
552 if (mask.Length() == 0) mask =
"kGCCapStyle";
553 else mask +=
" | kGCCapStyle";
555 if (fmask & kGCJoinStyle) {
556 if (mask.Length() == 0) mask =
"kGCJoinStyle";
557 else mask +=
" | kGCJoinStyle";
559 if (fmask & kGCFillStyle) {
560 if (mask.Length() == 0) mask =
"kGCFillStyle";
561 else mask +=
" | kGCFillStyle";
563 if (fmask & kGCFillRule) {
564 if (mask.Length() == 0) mask =
"kGCFillRule";
565 else mask +=
" | kGCFillRule";
567 if (fmask & kGCTile) {
568 if (mask.Length() == 0) mask =
"kGCTile";
569 else mask +=
" | kGCTile";
571 if (fmask & kGCStipple) {
572 if (mask.Length() == 0) mask =
"kGCStipple";
573 else mask +=
" | kGCStipple";
575 if (fmask & kGCTileStipXOrigin) {
576 if (mask.Length() == 0) mask =
"kGCTileStipXOrigin";
577 else mask +=
" | kGCTileStipXOrigin";
579 if (fmask & kGCTileStipYOrigin) {
580 if (mask.Length() == 0) mask =
"kGCTileStipYOrigin";
581 else mask +=
" | kGCTileStipYOrigin";
583 if (fmask & kGCFont) {
584 if (mask.Length() == 0) mask =
"kGCFont";
585 else mask +=
" | kGCFont";
587 if (fmask & kGCSubwindowMode) {
588 if (mask.Length() == 0) mask =
"kGCSubwindowMode";
589 else mask +=
" | kGCSubwindowMode";
591 if (fmask & kGCGraphicsExposures) {
592 if (mask.Length() == 0) mask =
"kGCGraphicsExposures";
593 else mask +=
" | kGCGraphicsExposures";
595 if (fmask & kGCClipXOrigin) {
596 if (mask.Length() == 0) mask =
"kGCClipXOrigin";
597 else mask +=
" | kGCClipXOrigin";
599 if (fmask & kGCClipYOrigin) {
600 if (mask.Length() == 0) mask =
"kGCClipYOrigin";
601 else mask +=
" | kGCClipYOrigin";
603 if (fmask & kGCClipMask) {
604 if (mask.Length() == 0) mask =
"kGCClipMask";
605 else mask +=
" | kGCClipMask";
607 if (fmask & kGCDashOffset) {
608 if (mask.Length() == 0) mask =
"kGCDashOffset";
609 else mask +=
" | kGCDashOffset";
611 if (fmask & kGCDashList) {
612 if (mask.Length() == 0) mask =
"kGCDashList";
613 else mask +=
" | kGCDashList";
615 if (fmask & kGCArcMode) {
616 if (mask.Length() == 0) mask =
"kGCArcMode";
617 else mask +=
" | kGCArcMode";
625 void TGGC::SavePrimitive(std::ostream &out, Option_t *option )
627 if (gROOT->ClassSaved(TGGC::Class())) {
632 out <<
" TGGC *uGC; // will reflect user GC changes" << std::endl;
635 Mask_t fmask = GetMask();
637 const char *colorname;
642 valname = TString::Format(
"val%s", option);
644 out <<
" // graphics context changes" << std::endl;
646 out <<
" GCValues_t " << valname.Data() <<
";" << std::endl;
647 out <<
" " << valname.Data() <<
".fMask = " << GetMaskString() <<
";" << std::endl;
649 for (Mask_t bit = 1; bit <= fmask; bit <<= 1) {
650 switch (bit & fmask) {
655 out <<
" " << valname.Data() <<
".fFunction = ";
656 switch (GetFunction()) {
664 out <<
"kGXandReverse";
670 out <<
"kGXandInverted";
691 out <<
"kGXorReverse";
693 case kGXcopyInverted:
694 out <<
"kGXcopyInverted";
697 out <<
"kGXorInverted";
706 out <<
";" << std::endl;
709 out <<
" " << valname.Data() <<
".fPlaneMask = " << GetPlaneMask() <<
";" << std::endl;
712 color = GetForeground();
713 colorname = TColor::PixelAsHexString(color);
714 out <<
" gClient->GetColorByName(" << quote << colorname << quote
715 <<
"," << valname.Data() <<
".fForeground);" << std::endl;
718 color = GetBackground();
719 colorname = TColor::PixelAsHexString(color);
720 out <<
" gClient->GetColorByName(" << quote << colorname << quote
721 <<
"," << valname.Data() <<
".fBackground);" << std::endl;
724 out <<
" " << valname.Data() <<
".fLineWidth = " << GetLineWidth() <<
";" << std::endl;
727 out <<
" " << valname.Data() <<
".fLineStyle = ";
728 switch (GetLineStyle()) {
733 out <<
"kLineOnOffDash";
735 case kLineDoubleDash:
736 out <<
"kLineDoubleDash";
739 out <<
";" << std::endl;
742 out <<
" " << valname.Data() <<
".fCapStyle = ";
743 switch (GetCapStyle()) {
745 out <<
"kCapNotLast";
754 out <<
"kCapProjecting";
757 out <<
";" << std::endl;
760 out <<
" " << valname.Data() <<
".fJoinStyle = ";
761 switch (GetJoinStyle()) {
772 out <<
";" << std::endl;
775 out <<
" " << valname.Data() <<
".fFillStyle = ";
776 switch (GetFillStyle()) {
784 out <<
"kFillStippled";
786 case kFillOpaqueStippled:
787 out <<
"kFillOpaqueStippled";
790 out <<
";" << std::endl;
793 out <<
" " << valname.Data() <<
".fFillRule = ";
794 switch (GetFillRule()) {
796 out <<
"kEvenOddRule";
799 out <<
"kWindingRule";
802 out <<
";" << std::endl;
805 out <<
" " << valname.Data() <<
".fTile = " << GetTile() <<
";" << std::endl;
808 out <<
" " << valname.Data() <<
".fStipple = " << GetStipple() <<
";" << std::endl;
810 case kGCTileStipXOrigin:
811 out <<
" " << valname.Data() <<
".fTsXOrigin = " << GetTileStipXOrigin() <<
";" << std::endl;
813 case kGCTileStipYOrigin:
814 out <<
" " << valname.Data() <<
".fTsYOrigin = " << GetTileStipYOrigin() <<
";" << std::endl;
817 out <<
" " << valname.Data() <<
".fFont = ufont->GetFontHandle();" << std::endl;
819 case kGCSubwindowMode:
820 out <<
" " << valname.Data() <<
".fSubwindowMode = ";
821 switch (GetSubwindowMode()) {
822 case kClipByChildren:
823 out <<
"kClipByChildren";
825 case kIncludeInferiors:
826 out <<
"kIncludeInferiors";
829 out <<
";" << std::endl;
831 case kGCGraphicsExposures:
832 out <<
" " << valname.Data() <<
".fGraphicsExposures = ";
833 if (GetGraphicsExposures())
837 out <<
";" << std::endl;
840 out <<
" " << valname.Data() <<
".fClipXOrigin = " << GetClipXOrigin() <<
";" << std::endl;
843 out <<
" " << valname.Data() <<
".fClipYOrigin = " << GetClipYOrigin() <<
";" << std::endl;
846 out <<
" " << valname.Data() <<
".fClipMask = " << GetClipMask() <<
";" << std::endl;
849 out <<
" " << valname.Data() <<
".fDashOffset = " << GetDashOffset() <<
";" << std::endl;
852 if (GetDashLen() > (Int_t)
sizeof(GetDashes()))
853 Warning(
"TGGC::SavePrimitive",
"dash list can have only up to %ld elements",
854 (Long_t)
sizeof(GetDashes()));
855 out <<
" " << valname.Data() <<
".fDashLen = "
856 << TMath::Min(GetDashLen(),(Int_t)
sizeof(GetDashes())) <<
";" << std::endl;
857 out <<
" memcpy(GetDashes()," << valname.Data() <<
".fDashes,"
858 << valname.Data() <<
".fDashLen);" << std::endl;
861 out <<
" " << valname.Data() <<
".fArcMode = ";
862 switch (GetArcMode()) {
867 out <<
"kArcPieSlice";
870 out <<
";" << std::endl;
874 out <<
" uGC = gClient->GetGC(&" << valname.Data() <<
", kTRUE);" << std::endl;
883 TGGCPool::TGGCPool(TGClient *client)
886 fList =
new THashTable;
893 TGGCPool::~TGGCPool()
901 void TGGCPool::ForceFreeGC(
const TGGC *gct)
903 TGGC *gc = (TGGC *) fList->FindObject(gct);
906 if (gc->References() > 1)
907 Error(
"ForceFreeGC",
"removed a shared graphics context\n"
908 "best to use graphics contexts via the TGGCPool()");
916 void TGGCPool::FreeGC(
const TGGC *gct)
918 TGGC *gc = (TGGC *) fList->FindObject(gct);
921 if (gc->RemoveReference() == 0) {
931 void TGGCPool::FreeGC(GContext_t gct)
935 while (TGGC *gc = (TGGC *) next()) {
936 if (gc->fContext == gct) {
937 if (gc->RemoveReference() == 0) {
949 TGGC *TGGCPool::FindGC(
const TGGC *gct)
951 return (TGGC*) fList->FindObject(gct);
958 TGGC *TGGCPool::FindGC(GContext_t gct)
962 while (TGGC *gc = (TGGC *) next()) {
963 if (gc->fContext == gct)
972 TGGC *TGGCPool::GetGC(GContext_t gct)
975 gVirtualX->GetGCValues(gct, gval);
976 return GetGC(&gval, kTRUE);
985 TGGC *TGGCPool::GetGC(GCValues_t *values, Bool_t rw)
987 TGGC *gc, *best_match = 0;
988 Int_t matching_bits, best_matching_bits = -1;
989 Bool_t exact = kFALSE;
1001 while ((gc = (TGGC *) next())) {
1002 matching_bits = MatchGC(gc, values);
1003 if (matching_bits > best_matching_bits) {
1004 best_matching_bits = matching_bits;
1006 if ((gc->fValues.fMask & values->fMask) == values->fMask) {
1015 Printf(
"<TGGCPool::GetGC>: %smatching GC found\n", exact ?
"exact " :
"");
1016 best_match->AddReference();
1019 UpdateGC(best_match, values);
1025 gc =
new TGGC(values, kTRUE);
1037 Int_t TGGCPool::MatchGC(
const TGGC *gc, GCValues_t *values)
1039 Mask_t bit, common_bits;
1040 Int_t matching_bits = -1;
1041 Bool_t match = kFALSE;
1042 const GCValues_t *gcv = &gc->fValues;
1044 common_bits = values->fMask & gcv->fMask;
1046 if (common_bits == 0)
return 0;
1054 if (gcv->fMask & kGCTile)
1055 if ((gcv->fTile != kNone) && !(values->fMask & kGCTile))
return -1;
1056 if (values->fMask & kGCTile)
1057 if ((values->fTile != kNone) && !(gcv->fMask & kGCTile))
return -1;
1058 if (gcv->fMask & kGCStipple)
1059 if ((gcv->fStipple != kNone) && !(values->fMask & kGCStipple))
return -1;
1060 if (values->fMask & kGCStipple)
1061 if ((values->fStipple != kNone) && !(gcv->fMask & kGCStipple))
return -1;
1063 for (bit = 1; bit <= common_bits; bit <<= 1) {
1064 switch (bit & common_bits) {
1069 match = (values->fFunction == gcv->fFunction);
1072 match = (values->fPlaneMask == gcv->fPlaneMask);
1075 match = (values->fForeground == gcv->fForeground);
1078 match = (values->fBackground == gcv->fBackground);
1081 match = (values->fLineWidth == gcv->fLineWidth);
1084 match = (values->fLineStyle == gcv->fLineStyle);
1087 match = (values->fCapStyle == gcv->fCapStyle);
1090 match = (values->fJoinStyle == gcv->fJoinStyle);
1093 match = (values->fFillStyle == gcv->fFillStyle);
1096 match = (values->fFillRule == gcv->fFillRule);
1099 match = (values->fTile == gcv->fTile);
1102 match = (values->fStipple == gcv->fStipple);
1104 case kGCTileStipXOrigin:
1105 match = (values->fTsXOrigin == gcv->fTsXOrigin);
1107 case kGCTileStipYOrigin:
1108 match = (values->fTsYOrigin == gcv->fTsYOrigin);
1111 match = (values->fFont == gcv->fFont);
1113 case kGCSubwindowMode:
1114 match = (values->fSubwindowMode == gcv->fSubwindowMode);
1116 case kGCGraphicsExposures:
1117 match = (values->fGraphicsExposures == gcv->fGraphicsExposures);
1119 case kGCClipXOrigin:
1120 match = (values->fClipXOrigin == gcv->fClipXOrigin);
1122 case kGCClipYOrigin:
1123 match = (values->fClipYOrigin == gcv->fClipYOrigin);
1126 match = (values->fClipMask == gcv->fClipMask);
1129 match = (values->fDashOffset == gcv->fDashOffset);
1132 if (values->fDashLen == gcv->fDashLen)
1133 match = (strncmp(values->fDashes, gcv->fDashes, gcv->fDashLen) == 0);
1136 match = (values->fArcMode == gcv->fArcMode);
1145 return matching_bits;
1151 void TGGCPool::UpdateGC(TGGC *gc, GCValues_t *values)
1153 gc->SetAttributes(values);
1159 void TGGCPool::Print(Option_t *)
const