#include "TGPicture.h"
#include "TGResourcePool.h"
#include "THashTable.h"
#include "TSystem.h"
#include "TGWindow.h"
#include "TVirtualX.h"
#include "TImage.h"
#include <stdlib.h>
TGGC *TGSelectedPicture::fgSelectedGC = 0;
ClassImp(TGPicture)
ClassImp(TGSelectedPicture)
ClassImp(TGPicturePool)
TGPicturePool::TGPicturePool(const TGPicturePool& pp) :
TObject(pp),
fClient(pp.fClient),
fPath(pp.fPath),
fPicList(pp.fPicList)
{
}
TGPicturePool& TGPicturePool::operator=(const TGPicturePool& pp)
{
if(this!=&pp) {
TObject::operator=(pp);
fClient=pp.fClient;
fPath=pp.fPath;
fPicList=pp.fPicList;
}
return *this;
}
const TGPicture *TGPicturePool::GetPicture(const char *name)
{
if (!fPicList)
fPicList = new THashTable(50);
TString pname = name;
pname.Strip();
TString ext = strrchr(pname, '.');
ext.ToLower();
if (ext.Length()) {
char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
pname = pxname;
delete [] pxname;
}
TGPicture *pic = (TGPicture *)fPicList->FindObject(pname);
if (pic && !pic->IsScaled()) {
if (pic->fPic == kNone)
return 0;
pic->AddReference();
return pic;
}
char *picnam = gSystem->Which(fPath, pname, kReadPermission);
if (!picnam) {
pic = new TGPicture(pname);
pic->fAttributes.fColormap = fClient->GetDefaultColormap();
pic->fAttributes.fCloseness = 40000;
pic->fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
fPicList->Add(pic);
return 0;
}
TImage *img = TImage::Open(picnam);
if (!img) {
pic = new TGPicture(pname);
pic->fAttributes.fColormap = fClient->GetDefaultColormap();
pic->fAttributes.fCloseness = 40000;
pic->fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
fPicList->Add(pic);
delete [] picnam;
return 0;
}
pic = new TGPicture(pname, img->GetPixmap(), img->GetMask());
delete [] picnam;
delete img;
fPicList->Add(pic);
return pic;
}
const TGPicture *TGPicturePool::GetPicture(const char *name,
UInt_t new_width, UInt_t new_height)
{
if (!fPicList)
fPicList = new THashTable(50);
TString pname = name;
pname.Strip();
TString ext = strrchr(pname, '.');
ext.ToLower();
if (ext.Length()) {
char *pxname = gSystem->ExpandPathName(gSystem->UnixPathName(pname));
pname = pxname;
delete [] pxname;
}
const char *hname = TGPicture::HashName(pname, new_width, new_height);
TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
if (pic && pic->GetWidth() == new_width && pic->GetHeight() == new_height) {
if (pic->fPic == kNone)
return 0;
pic->AddReference();
return pic;
}
char *picnam = gSystem->Which(fPath, pname, kReadPermission);
if (!picnam) {
pic = new TGPicture(hname, kTRUE);
pic->fAttributes.fColormap = fClient->GetDefaultColormap();
pic->fAttributes.fCloseness = 40000;
pic->fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
pic->fAttributes.fWidth = new_width;
pic->fAttributes.fHeight = new_height;
fPicList->Add(pic);
return 0;
}
TImage *img = TImage::Open(picnam);
if (!img) {
pic = new TGPicture(hname, kTRUE);
pic->fAttributes.fColormap = fClient->GetDefaultColormap();
pic->fAttributes.fCloseness = 40000;
pic->fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
pic->fAttributes.fWidth = new_width;
pic->fAttributes.fHeight = new_height;
fPicList->Add(pic);
delete [] picnam;
return 0;
}
img->Scale(new_width, new_height);
pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
delete [] picnam;
delete img;
fPicList->Add(pic);
return pic;
}
const TGPicture *TGPicturePool::GetPicture(const char *name, Pixmap_t pxmap,
Pixmap_t mask)
{
if (!fPicList)
fPicList = new THashTable(50);
Int_t xy;
UInt_t w, h;
gVirtualX->GetWindowSize(pxmap, xy, xy, w, h);
const char *hname = TGPicture::HashName(name, w, h);
TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
if (pic) {
pic->AddReference();
return pic;
}
pic = new TGPicture(hname, pxmap, mask);
fPicList->Add(pic);
return pic;
}
const TGPicture *TGPicturePool::GetPicture(const char *name, char **xpm)
{
UInt_t w, h;
if (!xpm || !*xpm) {
return 0;
}
if (!fPicList) {
fPicList = new THashTable(50);
}
char *ptr = xpm[0];
while (isspace((int)*ptr)) ++ptr;
w = atoi(ptr);
while (isspace((int)*ptr)) ++ptr;
h = atoi(ptr);
const char *hname = TGPicture::HashName(name, w, h);
TGPicture *pic = (TGPicture *)fPicList->FindObject(hname);
if (pic) {
pic->AddReference();
return pic;
}
TImage *img = TImage::Open(xpm);
if (!img) {
pic = new TGPicture(hname, kTRUE);
pic->fAttributes.fColormap = fClient->GetDefaultColormap();
pic->fAttributes.fCloseness = 40000;
pic->fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
pic->fAttributes.fWidth = w;
pic->fAttributes.fHeight = h;
fPicList->Add(pic);
return 0;
}
pic = new TGPicture(hname, img->GetPixmap(), img->GetMask());
delete img;
return pic;
}
void TGPicturePool::FreePicture(const TGPicture *fpic)
{
if (!fPicList) return;
TGPicture *pic = (TGPicture *)fPicList->FindObject(fpic);
if (pic) {
if (pic->RemoveReference() == 0) {
fPicList->Remove(pic);
delete pic;
}
}
}
TGPicturePool::~TGPicturePool()
{
if (fPicList) {
fPicList->Delete();
delete fPicList;
}
}
void TGPicturePool::Print(Option_t *) const
{
if (fPicList)
fPicList->Print();
else
Info("Print", "no pictures in picture pool");
}
TGPicture::TGPicture(const char *name, Pixmap_t pxmap, Pixmap_t mask)
{
fName = name;
fScaled = kFALSE;
fPic = pxmap;
fMask = mask;
Int_t xy;
fAttributes.fColormap = gClient->GetDefaultColormap();
fAttributes.fCloseness = 40000;
fAttributes.fMask = kPASize | kPAColormap | kPACloseness;
fAttributes.fPixels = 0;
fAttributes.fDepth = 0;
fAttributes.fNpixels = 0;
fAttributes.fXHotspot = 0;
fAttributes.fYHotspot = 0;
gVirtualX->GetWindowSize(fPic, xy, xy, fAttributes.fWidth, fAttributes.fHeight);
SetRefCount(1);
}
void TGPicture::Draw(Handle_t id, GContext_t gc, Int_t x, Int_t y) const
{
GCValues_t gcv;
gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
gcv.fClipMask = fMask;
gcv.fClipXOrigin = x;
gcv.fClipYOrigin = y;
gVirtualX->ChangeGC(gc, &gcv);
gVirtualX->CopyArea(fPic, id, gc, 0, 0, fAttributes.fWidth, fAttributes.fHeight,
x, y);
gcv.fMask = kGCClipMask;
gcv.fClipMask = kNone;
gVirtualX->ChangeGC(gc, &gcv);
}
TGPicture::~TGPicture()
{
if (fPic != kNone)
gVirtualX->DeletePixmap(fPic);
if (fMask != kNone)
gVirtualX->DeletePixmap(fMask);
if (fAttributes.fPixels)
delete [] fAttributes.fPixels;
}
const char *TGPicture::HashName(const char *name, Int_t width, Int_t height)
{
static TString hashName;
hashName.Form("%s__%dx%d", name, width, height);
return hashName.Data();
}
void TGPicture::Print(Option_t *) const
{
Printf("TGPicture: %s,%sref cnt = %u %d", GetName(),
fScaled ? " scaled, " : " ", References(), fPic);
}
TGSelectedPicture::TGSelectedPicture(const TGClient *client, const TGPicture *p) :
TGPicture("")
{
GCValues_t gcv;
UInt_t w, h;
fClient = client;
Window_t root = fClient->GetDefaultRoot()->GetId();
w = p->GetWidth();
h = p->GetHeight();
fPic = gVirtualX->CreatePixmap(root, w, h);
fMask = p->GetMask();
fAttributes.fWidth = w;
fAttributes.fHeight = h;
gVirtualX->CopyArea(p->GetPicture(), fPic, GetSelectedGC()(), 0, 0, w, h, 0, 0);
gcv.fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin;
gcv.fClipMask = p->GetMask();
gcv.fClipXOrigin = 0;
gcv.fClipYOrigin = 0;
GetSelectedGC().SetAttributes(&gcv);
gVirtualX->FillRectangle(fPic, GetSelectedGC()(), 0, 0, w, h);
GetSelectedGC().SetClipMask(kNone);
}
TGSelectedPicture::~TGSelectedPicture()
{
fMask = kNone;
}
TGGC &TGSelectedPicture::GetSelectedGC()
{
if (!fgSelectedGC) {
fgSelectedGC = new TGGC(*gClient->GetResourcePool()->GetFrameGC());
fgSelectedGC->SetForeground(gClient->GetResourcePool()->GetSelectedBgndColor());
fgSelectedGC->SetBackground(gClient->GetResourcePool()->GetBlackColor());
fgSelectedGC->SetFillStyle(kFillStippled);
fgSelectedGC->SetStipple(gClient->GetResourcePool()->GetCheckeredBitmap());
}
return *fgSelectedGC;
}