#include "TGString.h"
#include "TVirtualX.h"
#include "ctype.h"
ClassImp(TGString)
ClassImp(TGHotString)
TGString::TGString(const TGString *s) : TString(s->Data())
{
}
void TGString::Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
gVirtualX->DrawString(id, gc, x, y, Data(), Length());
}
void TGString::DrawWrapped(Drawable_t id, GContext_t gc,
Int_t x, Int_t y, UInt_t w, FontStruct_t font)
{
const char *p = Data();
const char *prev = p;
const char *chunk = p;
int tw, th, len = Length();
tw = gVirtualX->TextWidth(font, p, len);
if (tw <= (int)w) {
gVirtualX->DrawString(id, gc, x, y, p, len);
return;
}
int max_ascent, max_descent;
gVirtualX->GetFontProperties(font, max_ascent, max_descent);
th = max_ascent + max_descent + 1;
while(1) {
p = strchr(p, ' ');
if (p == 0) {
if (chunk) gVirtualX->DrawString(id, gc, x, y, chunk, strlen(chunk));
break;
}
tw = gVirtualX->TextWidth(font, chunk, p-chunk);
if (tw > (int)w) {
if (prev == chunk)
prev = ++p;
else
p = prev;
gVirtualX->DrawString(id, gc, x, y, chunk, prev-chunk-1);
chunk = prev;
y += th;
} else {
prev = ++p;
}
}
}
Int_t TGString::GetLines(FontStruct_t font, UInt_t w)
{
const char *p = Data();
const char *prev = p;
const char *chunk = p;
int tw, nlines, len = Length();
nlines = 1;
tw = gVirtualX->TextWidth(font, p, len);
if (tw <= (int)w) return nlines;
while(1) {
p = strchr(p, ' ');
if (p == 0) break;
tw = gVirtualX->TextWidth(font, chunk, p-chunk);
if (tw > (int)w) {
if (prev == chunk)
chunk = prev = ++p;
else
p = chunk = prev;
++nlines;
} else {
prev = ++p;
}
}
return nlines;
}
TGHotString::TGHotString(const char *s) : TGString()
{
fLastGC = 0;
fOff1 = fOff2 = 0;
fHotChar = 0;
fHotPos = 0;
if (!s) return;
char *dup = StrDup(s);
char *p;
for (p = dup; *p; p++) {
if (*p == '&') {
if (p[1] == '&') {
for (char *tmp = p; *tmp; tmp++)
tmp[0] = tmp[1];
continue;
}
fHotPos = (p - dup) + 1;
fHotChar = tolower(p[1]);
for (; *p; p++) p[0] = p[1];
break;
}
}
Append(dup);
delete [] dup;
}
void TGHotString::Draw(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
gVirtualX->DrawString(id, gc, x, y, Data(), Length());
DrawHotChar(id, gc, x, y);
}
void TGHotString::DrawWrapped(Drawable_t id, GContext_t gc,
Int_t x, Int_t y, UInt_t w, FontStruct_t font)
{
const char *p = Data();
const char *prev = p;
const char *chunk = p;
int tw, th, len = Length();
tw = gVirtualX->TextWidth(font, p, len);
if (tw <= (int)w) {
gVirtualX->DrawString(id, gc, x, y, p, len);
DrawHotChar(id, gc, x, y);
return;
}
int max_ascent, max_descent;
gVirtualX->GetFontProperties(font, max_ascent, max_descent);
th = max_ascent + max_descent + 1;
int pcnt = 0;
while(1) {
p = strchr(p, ' ');
if (p == 0) {
if (chunk) {
gVirtualX->DrawString(id, gc, x, y, chunk, strlen(chunk));
if (fHotPos > pcnt && fHotPos <= pcnt+(int)strlen(chunk))
DrawHotChar(id, gc, x, y);
}
break;
}
tw = gVirtualX->TextWidth(font, chunk, p-chunk);
if (tw > (int)w) {
if (prev == chunk)
prev = ++p;
else
p = prev;
gVirtualX->DrawString(id, gc, x, y, chunk, prev-chunk-1);
if (fHotPos > pcnt && fHotPos <= pcnt+prev-chunk-1)
DrawHotChar(id, gc, x, y);
pcnt = prev-chunk-1;
chunk = prev;
y += th;
} else {
prev = ++p;
}
}
}
void TGHotString::DrawHotChar(Drawable_t id, GContext_t gc, Int_t x, Int_t y)
{
if (fHotPos > 0) {
if (fLastGC != gc) {
GCValues_t gcval;
FontStruct_t font;
font = gVirtualX->GetGCFont(gc);
if (font) {
fOff1 = gVirtualX->TextWidth(font, Data(), fHotPos-1);
fOff2 = gVirtualX->TextWidth(font, Data(), fHotPos) - 1;
}
else {
gcval.fMask = kGCFont;
gVirtualX->GetGCValues(gc, gcval);
font = gVirtualX->GetFontStruct(gcval.fFont);
fOff1 = gVirtualX->TextWidth(font, Data(), fHotPos-1);
fOff2 = gVirtualX->TextWidth(font, Data(), fHotPos) - 1;
gVirtualX->FreeFontStruct(font);
}
fLastGC = gc;
}
gVirtualX->DrawLine(id, gc, x+fOff1, y+1, x+fOff2, y+1);
}
}