TGX11TTF.cxx

Go to the documentation of this file.
00001 // @(#)root/x11ttf:$Id: TGX11TTF.cxx 31653 2009-12-08 13:23:07Z couet $
00002 // Author: Valeriy Onuchin (Xft support)  02/10/07
00003 // Author: Olivier Couet     01/10/02
00004 // Author: Fons Rademakers   21/11/98
00005 
00006 /*************************************************************************
00007  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00008  * All rights reserved.                                                  *
00009  *                                                                       *
00010  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00011  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00012  *************************************************************************/
00013 
00014 //////////////////////////////////////////////////////////////////////////
00015 //                                                                      //
00016 // TGX11TTF                                                             //
00017 //                                                                      //
00018 // Interface to low level X11 (Xlib). This class gives access to basic  //
00019 // X11 graphics via the parent class TGX11. However, all text and font  //
00020 // handling is done via the Freetype TrueType library. When the         //
00021 // shared library containing this class is loaded the global gVirtualX  //
00022 // is redirected to point to this class.                                //
00023 //                                                                      //
00024 //////////////////////////////////////////////////////////////////////////
00025 
00026 #include <stdlib.h>
00027 
00028 #include "TGX11TTF.h"
00029 #include "TClass.h"
00030 #include "TEnv.h"
00031 
00032 #ifdef R__HAS_XFT
00033 
00034 #include "THashTable.h"
00035 #include "TRefCnt.h"
00036 #include <X11/Xft/Xft.h>
00037 
00038 /////////////////////////  xft font data //////////////////////////////////////
00039 class TXftFontData : public TNamed, public TRefCnt {
00040 public:
00041    XFontStruct   *fFontStruct;   // fontstruct
00042    XftFont       *fXftFont;      // xft font
00043 
00044    TXftFontData(FontStruct_t font, XftFont *xftfont, const char *name) :
00045       TNamed(name, ""), TRefCnt(), fXftFont(xftfont)
00046    {
00047       SetRefCount(1);
00048       fFontStruct = (XFontStruct*)font;
00049    }
00050 
00051    ~TXftFontData()
00052    {
00053       if (fFontStruct) ((TGX11*)gVirtualX)->DeleteFont((FontStruct_t)fFontStruct);
00054       if (fXftFont) XftFontClose((Display*)gVirtualX->GetDisplay(), fXftFont);
00055    }
00056 };
00057 
00058 
00059 /////////////////// hash table //////////////////////////////////////////////
00060 class TXftFontHash {
00061 public:
00062    THashTable  *fList;  // hash table
00063 
00064    TXftFontHash() { fList = new THashTable(50); }
00065 
00066    TXftFontData *FindByName(const char *name)
00067    {
00068       return (TXftFontData*)fList->FindObject(name);
00069    }
00070 
00071    TXftFontData *FindByStruct(FontStruct_t font)
00072    {
00073       TIter next(fList);
00074       TXftFontData *d = 0;
00075 
00076       while ((d = (TXftFontData*) next())) {
00077          if (d->fFontStruct == (XFontStruct*)font) {
00078             return d;
00079          }
00080       }
00081       return 0;
00082    }
00083 
00084    TXftFontData *FindByHandle(FontH_t id)
00085    {
00086       TIter next(fList);
00087       TXftFontData *d = 0;
00088 
00089       while ((d = (TXftFontData*) next())) {
00090          if (d->fFontStruct->fid == id) {
00091             return d;
00092          }
00093       }
00094       return 0;
00095    }
00096 
00097    void AddFont(TXftFontData *data)
00098    {
00099       fList->Add(data);
00100    }
00101 
00102    void FreeFont(TXftFontData *data)
00103    {
00104       if (data->RemoveReference() > 0)  return;
00105       fList->Remove(data);
00106       delete data;
00107    }
00108 };
00109 #endif  // R__HAS_XFT
00110 
00111 //////////////////////////////////////////////////////////////////////////
00112 //                                                                      //
00113 // TTFX11Init                                                           //
00114 //                                                                      //
00115 // Small utility class that takes care of switching the current         //
00116 // gVirtualX to the new TGX11TTF class as soon as the shared library    //
00117 // containing this class is loaded.                                     //
00118 //                                                                      //
00119 //////////////////////////////////////////////////////////////////////////
00120 
00121 class TTFX11Init {
00122 public:
00123    TTFX11Init() { TGX11TTF::Activate(); }
00124 };
00125 static TTFX11Init gTTFX11Init;
00126 
00127 
00128 ClassImp(TGX11TTF)
00129 
00130 //______________________________________________________________________________
00131 TGX11TTF::TGX11TTF(const TGX11 &org) : TGX11(org)
00132 {
00133    // Create copy of TGX11 but now use TrueType fonts.
00134 
00135    SetName("X11TTF");
00136    SetTitle("ROOT interface to X11 with TrueType fonts");
00137 
00138    if (!TTF::fgInit) TTF::Init();
00139 
00140    fHasTTFonts = kTRUE;
00141    fAlign.x = 0;
00142    fAlign.y = 0;
00143 
00144 #ifdef R__HAS_XFT
00145    fXftFontHash = 0;
00146    if (gEnv->GetValue("X11.UseXft", 0)) {
00147       fXftFontHash = new TXftFontHash();
00148    }
00149 #endif
00150 }
00151 
00152 //______________________________________________________________________________
00153 void TGX11TTF::Activate()
00154 {
00155    // Static method setting TGX11TTF as the acting gVirtualX.
00156 
00157    if (gVirtualX && !strcmp(gVirtualX->IsA()->GetName(), "TGX11")) {
00158       TGX11 *oldg = (TGX11 *) gVirtualX;
00159       gVirtualX = new TGX11TTF(*oldg);
00160       delete oldg;
00161    }
00162 }
00163 
00164 //______________________________________________________________________________
00165 Bool_t TGX11TTF::Init(void *display)
00166 {
00167    // Initialize X11 system. Returns kFALSE in case of failure.
00168 
00169    Bool_t r = TGX11::Init(display);
00170 
00171    if (fDepth > 8) {
00172       TTF::SetSmoothing(kTRUE);
00173    } else {
00174       TTF::SetSmoothing(kFALSE);
00175    }
00176 
00177    return r;
00178 }
00179 
00180 //______________________________________________________________________________
00181 void TGX11TTF::Align(void)
00182 {
00183    // Compute alignment variables. The alignment is done on the horizontal string
00184    // then the rotation is applied on the alignment variables.
00185    // SetRotation and LayoutGlyphs should have been called before.
00186 
00187    EAlign align = (EAlign) fTextAlign;
00188 
00189    // vertical alignment
00190    if (align == kTLeft || align == kTCenter || align == kTRight) {
00191       fAlign.y = TTF::fgAscent;
00192    } else if (align == kMLeft || align == kMCenter || align == kMRight) {
00193       fAlign.y = TTF::fgAscent/2;
00194    } else {
00195       fAlign.y = 0;
00196    }
00197 
00198    // horizontal alignment
00199    if (align == kTRight || align == kMRight || align == kBRight) {
00200       fAlign.x = TTF::fgWidth;
00201    } else if (align == kTCenter || align == kMCenter || align == kBCenter) {
00202       fAlign.x = TTF::fgWidth/2;
00203    } else {
00204       fAlign.x = 0;
00205    }
00206 
00207    FT_Vector_Transform(&fAlign, TTF::fgRotMatrix);
00208    fAlign.x = fAlign.x >> 6;
00209    fAlign.y = fAlign.y >> 6;
00210 }
00211 
00212 //______________________________________________________________________________
00213 void TGX11TTF::DrawImage(FT_Bitmap *source, ULong_t fore, ULong_t back,
00214                          XImage *xim, Int_t bx, Int_t by)
00215 {
00216    // Draw FT_Bitmap bitmap to xim image at position bx,by using specified
00217    // foreground color.
00218 
00219    UChar_t d = 0, *s = source->buffer;
00220 
00221    if (TTF::fgSmoothing) {
00222 
00223       static XColor col[5];
00224       XColor  *bcol = 0, *bc;
00225       Int_t    x, y;
00226 
00227       // background kClear, i.e. transparent, we take as background color
00228       // the average of the rgb values of all pixels covered by this character
00229       if (back == (ULong_t) -1 && (UInt_t)source->width) {
00230          ULong_t r, g, b;
00231          Int_t   dots, dotcnt;
00232          const Int_t maxdots = 50000;
00233 
00234          dots = Int_t(source->width * source->rows);
00235          dots = dots > maxdots ? maxdots : dots;
00236          bcol = new XColor[dots];
00237          if (!bcol) return;
00238          bc = bcol;
00239          dotcnt = 0;
00240          for (y = 0; y < (int) source->rows; y++) {
00241             for (x = 0; x < (int) source->width; x++, bc++) {
00242 ///               bc->pixel = XGetPixel(xim, bx + x, by - c->TTF::fgAscent + y);
00243                bc->pixel = XGetPixel(xim, bx + x, by + y);
00244                bc->flags = DoRed | DoGreen | DoBlue;
00245                if (++dotcnt >= maxdots) break;
00246             }
00247          }
00248          QueryColors(fColormap, bcol, dots);
00249          r = g = b = 0;
00250          bc = bcol;
00251          dotcnt = 0;
00252          for (y = 0; y < (int) source->rows; y++) {
00253             for (x = 0; x < (int) source->width; x++, bc++) {
00254                r += bc->red;
00255                g += bc->green;
00256                b += bc->blue;
00257                if (++dotcnt >= maxdots) break;
00258             }
00259          }
00260          if (dots != 0) {
00261             r /= dots;
00262             g /= dots;
00263             b /= dots;
00264          }
00265          bc = &col[0];
00266          if (bc->red == r && bc->green == g && bc->blue == b)
00267             bc->pixel = back;
00268          else {
00269             bc->pixel = ~back;
00270             bc->red   = (UShort_t) r;
00271             bc->green = (UShort_t) g;
00272             bc->blue  = (UShort_t) b;
00273          }
00274       }
00275       delete [] bcol;
00276 
00277       // if fore or background have changed from previous character
00278       // recalculate the 3 smooting colors (interpolation between fore-
00279       // and background colors)
00280       if (fore != col[4].pixel || back != col[0].pixel) {
00281          col[4].pixel = fore;
00282          col[4].flags = DoRed|DoGreen|DoBlue;
00283          if (back != (ULong_t) -1) {
00284             col[3].pixel = back;
00285             col[3].flags = DoRed | DoGreen | DoBlue;
00286             QueryColors(fColormap, &col[3], 2);
00287             col[0] = col[3];
00288          } else {
00289             QueryColors(fColormap, &col[4], 1);
00290          }
00291 
00292          // interpolate between fore and backgound colors
00293          for (x = 3; x > 0; x--) {
00294             col[x].red   = (col[4].red  *x + col[0].red  *(4-x)) /4;
00295             col[x].green = (col[4].green*x + col[0].green*(4-x)) /4;
00296             col[x].blue  = (col[4].blue *x + col[0].blue *(4-x)) /4;
00297             if (!AllocColor(fColormap, &col[x])) {
00298                Warning("DrawImage", "cannot allocate smoothing color");
00299                col[x].pixel = col[x+1].pixel;
00300             }
00301          }
00302       }
00303 
00304       // put smoothed character, character pixmap values are an index
00305       // into the 5 colors used for aliasing (4 = foreground, 0 = background)
00306       for (y = 0; y < (int) source->rows; y++) {
00307          for (x = 0; x < (int) source->width; x++) {
00308             d = *s++ & 0xff;
00309             d = ((d + 10) * 5) / 256;
00310             if (d > 4) d = 4;
00311             if (d && x < (int) source->width) {
00312                ULong_t p = col[d].pixel;
00313                XPutPixel(xim, bx + x, by + y, p);
00314             }
00315          }
00316       }
00317    } else {
00318       // no smoothing, just put character using foreground color
00319       UChar_t* row=s;
00320       for (int y = 0; y < (int) source->rows; y++) {
00321          int n = 0;
00322          s = row;
00323          for (int x = 0; x < (int) source->width; x++) {
00324             if (n == 0) d = *s++;
00325             if (TESTBIT(d,7-n))
00326                XPutPixel(xim, bx + x, by + y, fore);
00327             if (++n == (int) kBitsPerByte) n = 0;
00328          }
00329          row += source->pitch;
00330       }
00331    }
00332 }
00333 
00334 //______________________________________________________________________________
00335 void TGX11TTF::DrawText(Int_t x, Int_t y, Float_t angle, Float_t mgn,
00336                         const char *text, ETextMode mode)
00337 {
00338    // Draw text using TrueType fonts. If TrueType fonts are not available the
00339    // text is drawn with TGX11::DrawText.
00340 
00341    if (!fHasTTFonts) {
00342       TGX11::DrawText(x, y, angle, mgn, text, mode);
00343    } else {
00344       if (!TTF::fgInit) TTF::Init();
00345       TTF::SetRotationMatrix(angle);
00346       TTF::PrepareString(text);
00347       TTF::LayoutGlyphs();
00348       Align();
00349       RenderString(x, y, mode);
00350    }
00351 }
00352 
00353 //______________________________________________________________________________
00354 XImage *TGX11TTF::GetBackground(Int_t x, Int_t y, UInt_t w, UInt_t h)
00355 {
00356    // Get the background of the current window in an XImage.
00357 
00358    Window_t cws = GetCurrentWindow();
00359    UInt_t width;
00360    UInt_t height;
00361    Int_t xy;
00362    gVirtualX->GetWindowSize(cws, xy, xy, width, height);
00363 
00364    if (x < 0) {
00365       w += x;
00366       x  = 0;
00367    }
00368    if (y < 0) {
00369       h += y;
00370       y  = 0;
00371    }
00372 
00373    if (x+w > width)  w = width - x;
00374    if (y+h > height) h = height - y;
00375 
00376    return XGetImage(fDisplay, cws, x, y, w, h, AllPlanes, ZPixmap);
00377 }
00378 
00379 //______________________________________________________________________________
00380 Bool_t TGX11TTF::IsVisible(Int_t x, Int_t y, UInt_t w, UInt_t h)
00381 {
00382    // Test if there is really something to render.
00383 
00384    Window_t cws = GetCurrentWindow();
00385    UInt_t width;
00386    UInt_t height;
00387    Int_t xy;
00388    gVirtualX->GetWindowSize(cws, xy, xy, width, height);
00389 
00390    // If w or h is 0, very likely the string is only blank characters
00391    if ((int)w == 0 || (int)h == 0)  return kFALSE;
00392 
00393    // If string falls outside window, there is probably no need to draw it.
00394    if (x + (int)w <= 0 || x >= (int)width)  return kFALSE;
00395    if (y + (int)h <= 0 || y >= (int)height) return kFALSE;
00396 
00397    return kTRUE;
00398 }
00399 
00400 //______________________________________________________________________________
00401 void TGX11TTF::RenderString(Int_t x, Int_t y, ETextMode mode)
00402 {
00403    // Perform the string rendering in the pad.
00404    // LayoutGlyphs should have been called before.
00405 
00406    TTGlyph* glyph = TTF::fgGlyphs;
00407 
00408    // compute the size and position of the XImage that will contain the text
00409    Int_t Xoff = 0; if (TTF::GetBox().xMin < 0) Xoff = -TTF::GetBox().xMin;
00410    Int_t Yoff = 0; if (TTF::GetBox().yMin < 0) Yoff = -TTF::GetBox().yMin;
00411    Int_t w    = TTF::GetBox().xMax + Xoff;
00412    Int_t h    = TTF::GetBox().yMax + Yoff;
00413    Int_t x1   = x-Xoff-fAlign.x;
00414    Int_t y1   = y+Yoff+fAlign.y-h;
00415 
00416    if (!IsVisible(x1, y1, w, h)) return;
00417 
00418    // create the XImage that will contain the text
00419    UInt_t depth = fDepth;
00420    XImage *xim  = 0;
00421    xim = XCreateImage(fDisplay, fVisual,
00422                       depth, ZPixmap, 0, 0, w, h,
00423                       depth == 24 ? 32 : (depth==15?16:depth), 0);
00424 
00425    // use malloc since Xlib will use free() in XDestroyImage
00426    xim->data = (char *) malloc(xim->bytes_per_line * h);
00427    memset(xim->data, 0, xim->bytes_per_line * h);
00428 
00429    ULong_t   bg;
00430    XGCValues values;
00431    XGetGCValues(fDisplay, *GetGC(3), GCForeground | GCBackground, &values);
00432 
00433    // get the background
00434    if (mode == kClear) {
00435       // if mode == kClear we need to get an image of the background
00436       XImage *bim = GetBackground(x1, y1, w, h);
00437       if (!bim) {
00438          Error("DrawText", "error getting background image");
00439          return;
00440       }
00441 
00442       // and copy it into the text image
00443       Int_t xo = 0, yo = 0;
00444       if (x1 < 0) xo = -x1;
00445       if (y1 < 0) yo = -y1;
00446 
00447       for (int yp = 0; yp < (int) bim->height; yp++) {
00448          for (int xp = 0; xp < (int) bim->width; xp++) {
00449             ULong_t pixel = XGetPixel(bim, xp, yp);
00450             XPutPixel(xim, xo+xp, yo+yp, pixel);
00451          }
00452       }
00453       XDestroyImage(bim);
00454       bg = (ULong_t) -1;
00455    } else {
00456       // if mode == kOpaque its simple, we just draw the background
00457       XAddPixel(xim, values.background);
00458       bg = values.background;
00459    }
00460 
00461    // paint the glyphs in the XImage
00462    glyph = TTF::fgGlyphs;
00463    for (int n = 0; n < TTF::fgNumGlyphs; n++, glyph++) {
00464       if (FT_Glyph_To_Bitmap(&glyph->fImage,
00465                              TTF::fgSmoothing ? ft_render_mode_normal
00466                                               : ft_render_mode_mono,
00467                              0, 1 )) continue;
00468       FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph->fImage;
00469       FT_Bitmap*     source = &bitmap->bitmap;
00470       Int_t          bx, by;
00471 
00472       bx = bitmap->left+Xoff;
00473       by = h - bitmap->top-Yoff;
00474       DrawImage(source, values.foreground, bg, xim, bx, by);
00475    }
00476 
00477    // put the Ximage on the screen
00478    Window_t cws = GetCurrentWindow();
00479    GC *gc = GetGC(6);      // gGCpxmp
00480    XPutImage(fDisplay, cws, *gc, xim, 0, 0, x1, y1, w, h);
00481    XDestroyImage(xim);
00482 }
00483 
00484 //______________________________________________________________________________
00485 void TGX11TTF::SetTextFont(Font_t fontnumber)
00486 {
00487    // Set specified font.
00488 
00489    fTextFont = fontnumber;
00490    if (!fHasTTFonts) {
00491       TGX11::SetTextFont(fontnumber);
00492    } else {
00493       TTF::SetTextFont(fontnumber);
00494    }
00495 }
00496 
00497 //______________________________________________________________________________
00498 Int_t TGX11TTF::SetTextFont(char *fontname, ETextSetMode mode)
00499 {
00500    // Set text font to specified name.
00501    // mode       : loading flag
00502    // mode=0     : search if the font exist (kCheck)
00503    // mode=1     : search the font and load it if it exists (kLoad)
00504    // font       : font name
00505    //
00506    // Set text font to specified name. This function returns 0 if
00507    // the specified font is found, 1 if not.
00508 
00509    if (!fHasTTFonts) {
00510       return TGX11::SetTextFont(fontname, mode);
00511    } else {
00512       return TTF::SetTextFont(fontname);
00513    }
00514 }
00515 
00516 //______________________________________________________________________________
00517 void TGX11TTF::SetTextSize(Float_t textsize)
00518 {
00519    // Set current text size.
00520 
00521    fTextSize = textsize;
00522    if (!fHasTTFonts) {
00523       TGX11::SetTextSize(textsize);
00524    } else {
00525       TTF::SetTextSize(textsize);
00526    }
00527 }
00528 
00529 #ifdef R__HAS_XFT
00530 
00531 ///////////////////////////// Xft font methods /////////////////////////////////
00532 //______________________________________________________________________________
00533 FontStruct_t TGX11TTF::LoadQueryFont(const char *font_name)
00534 {
00535    // Parses an XLFD name and opens a font.
00536 
00537    if (!fXftFontHash) {
00538       return TGX11::LoadQueryFont(font_name);
00539    }
00540 
00541    TXftFontData *data = fXftFontHash->FindByName(font_name);
00542 
00543    // already loaded
00544    if (data) {
00545       data->AddReference();
00546       return (FontStruct_t)data->fFontStruct;
00547    }
00548 
00549    // load both X11 and Xft fonts
00550    FontStruct_t font = TGX11::LoadQueryFont(font_name);
00551 
00552    if (!font) {
00553       return font;
00554    }
00555 
00556    XftFont *xftfont = XftFontOpenXlfd(fDisplay, fScreenNumber, font_name);
00557 
00558    data = new TXftFontData(font, xftfont, font_name);
00559    fXftFontHash->AddFont(data);
00560 
00561    return font;
00562 }
00563 
00564 //______________________________________________________________________________
00565 void TGX11TTF::DeleteFont(FontStruct_t fs)
00566 {
00567    // Explicitely delete font structure obtained with LoadQueryFont().
00568 
00569    if (!fXftFontHash) {
00570       TGX11::DeleteFont(fs);
00571       return;
00572    }
00573 
00574    TXftFontData *data = fXftFontHash->FindByStruct(fs);
00575 
00576    if (!data) {
00577       TGX11::DeleteFont(fs);
00578       return;
00579    }
00580 
00581    fXftFontHash->FreeFont(data);
00582 }
00583 
00584 //______________________________________________________________________________
00585 Int_t TGX11TTF::TextWidth(FontStruct_t font, const char *s, Int_t len)
00586 {
00587    // Return lenght of string in pixels. Size depends on font
00588 
00589    if (!fXftFontHash) {
00590       return TGX11::TextWidth(font, s, len);
00591    }
00592 
00593    TXftFontData *data = fXftFontHash->FindByStruct(font);
00594 
00595    if (!data) {
00596       return TGX11::TextWidth(font, s, len);
00597    }
00598 
00599    XftFont *xftfont = data->fXftFont;
00600 
00601    if (!xftfont) {
00602       return TGX11::TextWidth(font, s, len);
00603    }
00604 
00605    XGlyphInfo glyph_info;
00606    XftTextExtents8(fDisplay, xftfont, (XftChar8 *)s, len, &glyph_info);
00607 
00608    return glyph_info.xOff;
00609 }
00610 
00611 //______________________________________________________________________________
00612 void TGX11TTF::GetFontProperties(FontStruct_t font, Int_t &max_ascent, Int_t &max_descent)
00613 {
00614    //  Return some font properties
00615 
00616    if (!fXftFontHash) {
00617       TGX11::GetFontProperties(font, max_ascent, max_descent);
00618       return;
00619    }
00620 
00621    TXftFontData *data = fXftFontHash->FindByStruct(font);
00622 
00623    if (!data) {
00624       TGX11::GetFontProperties(font, max_ascent, max_descent);
00625       return;
00626    }
00627 
00628    XftFont *xftfont = data->fXftFont;
00629 
00630    if (!xftfont) {
00631       TGX11::GetFontProperties(font, max_ascent, max_descent);
00632       return;
00633    }
00634 
00635    max_ascent = xftfont->ascent;
00636    max_descent = xftfont->descent;
00637 }
00638 
00639 //______________________________________________________________________________
00640 void TGX11TTF::DrawString(Drawable_t xwindow, GContext_t gc, Int_t x, Int_t y,
00641                           const char *text, Int_t len)
00642 {
00643    // Draw text string
00644 
00645    XftDraw  *xftdraw;
00646    XftColor  xftcolor;
00647    XColor    xcolor;
00648    XftFont  *xftfont;
00649 
00650    if (!xwindow)  {
00651       return;
00652    }
00653 
00654    if (!gc) {
00655       return;
00656    }
00657 
00658    if (!text || (len < 1) || !strlen(text)) {
00659       return;
00660    }
00661 
00662    if (!fXftFontHash) {
00663       TGX11::DrawString(xwindow, gc, x, y, text, len);
00664       return;
00665    }
00666 
00667    GCValues_t gval;
00668    gval.fMask = kGCForeground | kGCBackground | kGCFont;  // retrieve GC values
00669    GetGCValues(gc, gval);
00670 
00671    TXftFontData *data = fXftFontHash->FindByHandle(gval.fFont);
00672 
00673    // no XftFont data
00674    if (!data) {
00675       TGX11::DrawString(xwindow, gc, x, y, text, len);
00676       return;
00677    }
00678 
00679    xftfont = data->fXftFont;
00680 
00681    // no Xft font
00682    if (!xftfont) {
00683       TGX11::DrawString(xwindow, gc, x, y, text, len);
00684       return;
00685    }
00686 
00687    // dummies
00688    Window droot;
00689    Int_t dx,dy;
00690    UInt_t bwidth, width, height, depth;
00691 
00692    // check if drawable is bitmap
00693    XGetGeometry(fDisplay, (Drawable)xwindow, &droot, &dx, &dy,
00694                 &width, &height, &bwidth, &depth);
00695 
00696    if (depth <= 1) {
00697       TGX11::DrawString(xwindow, gc, x, y, text, len);
00698       return;
00699    }
00700 
00701    memset(&xcolor, 0, sizeof(xcolor));
00702    xcolor.pixel = gval.fForeground;
00703 
00704    XQueryColor(fDisplay, fColormap, &xcolor);
00705 
00706    // create  XftDraw
00707    xftdraw = XftDrawCreate(fDisplay, (Drawable)xwindow, fVisual, fColormap);
00708 
00709    if (!xftdraw) {
00710       //Warning("could not create an XftDraw");
00711       TGX11::DrawString(xwindow, gc, x, y, text, len);
00712       return;
00713    }
00714 
00715    xftcolor.color.red = xcolor.red;
00716    xftcolor.color.green = xcolor.green;
00717    xftcolor.color.blue = xcolor.blue;
00718    xftcolor.color.alpha = 0xffff;
00719    xftcolor.pixel = gval.fForeground;
00720 
00721    XftDrawString8(xftdraw, &xftcolor, xftfont, x, y, (XftChar8 *)text, len);
00722 
00723    // cleanup
00724    XftDrawDestroy(xftdraw);
00725 }
00726 
00727 #endif // R__HAS_XFT

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